mirror of
https://github.com/feather-wallet/feather.git
synced 2025-02-02 03:06:34 +00:00
Account switcher
This commit is contained in:
parent
21d29fa7ee
commit
50a77307f4
19 changed files with 421 additions and 44 deletions
|
@ -41,6 +41,9 @@ AppContext::AppContext(Wallet *wallet)
|
|||
connect(this->wallet.get(), &Wallet::connectionStatusChanged, [this]{
|
||||
this->nodes->autoConnect();
|
||||
});
|
||||
connect(this->wallet.get(), &Wallet::currentSubaddressAccountChanged, [this]{
|
||||
this->updateBalance();
|
||||
});
|
||||
|
||||
connect(this, &AppContext::createTransactionError, this, &AppContext::onCreateTransactionError);
|
||||
|
||||
|
@ -54,6 +57,10 @@ AppContext::AppContext(Wallet *wallet)
|
|||
|
||||
// force trigger preferredFiat signal for history model
|
||||
this->onPreferredFiatCurrencyChanged(config()->get(Config::preferredFiatCurrency).toString());
|
||||
|
||||
connect(this->wallet->history(), &TransactionHistory::txNoteChanged, [this]{
|
||||
this->wallet->history()->refresh(this->wallet->currentSubaddressAccount());
|
||||
});
|
||||
}
|
||||
|
||||
// ################## Transaction creation ##################
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
<file>assets/images/bitcoin.png</file>
|
||||
<file>assets/images/camera_dark.png</file>
|
||||
<file>assets/images/camera_white.png</file>
|
||||
<file>assets/images/change_account.png</file>
|
||||
<file>assets/images/clock1.png</file>
|
||||
<file>assets/images/clock2.png</file>
|
||||
<file>assets/images/clock3.png</file>
|
||||
|
|
BIN
src/assets/images/change_account.png
Normal file
BIN
src/assets/images/change_account.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
107
src/dialog/AccountSwitcherDialog.cpp
Normal file
107
src/dialog/AccountSwitcherDialog.cpp
Normal file
|
@ -0,0 +1,107 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// Copyright (c) 2020-2021, The Monero Project.
|
||||
|
||||
#include "AccountSwitcherDialog.h"
|
||||
#include "ui_AccountSwitcherDialog.h"
|
||||
|
||||
#include "libwalletqt/SubaddressAccount.h"
|
||||
#include "utils/Icons.h"
|
||||
#include <QMenu>
|
||||
|
||||
AccountSwitcherDialog::AccountSwitcherDialog(QSharedPointer<AppContext> ctx, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::AccountSwitcherDialog)
|
||||
, m_ctx(std::move(ctx))
|
||||
, m_model(m_ctx->wallet->subaddressAccountModel())
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->accounts->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
m_ctx->wallet->subaddressAccount()->refresh();
|
||||
ui->accounts->setModel(m_ctx->wallet->subaddressAccountModel());
|
||||
ui->accounts->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
ui->accounts->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
ui->accounts->hideColumn(SubaddressAccountModel::Column::Address);
|
||||
ui->accounts->hideColumn(SubaddressAccountModel::Column::UnlockedBalance);
|
||||
ui->accounts->setColumnWidth(SubaddressAccountModel::Column::Label, 200);
|
||||
ui->accounts->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
ui->accounts->header()->setSectionResizeMode(SubaddressAccountModel::Label, QHeaderView::Stretch);
|
||||
|
||||
connect(ui->accounts->selectionModel(), &QItemSelectionModel::currentChanged, this, &AccountSwitcherDialog::switchAccount);
|
||||
connect(ui->accounts, &QTreeView::customContextMenuRequested, this, &AccountSwitcherDialog::showContextMenu);
|
||||
connect(ui->accounts, &QTreeView::doubleClicked, [this](QModelIndex index){
|
||||
if (!m_model) return;
|
||||
if (!(m_model->flags(index) & Qt::ItemIsEditable)) {
|
||||
this->switchAccount();
|
||||
}
|
||||
});
|
||||
|
||||
connect(ui->btn_newAccount, &QPushButton::clicked, [this]{
|
||||
m_ctx->wallet->addSubaddressAccount("New account");
|
||||
m_ctx->wallet->subaddressAccount()->refresh();
|
||||
});
|
||||
|
||||
connect(m_ctx->wallet.get(), &Wallet::currentSubaddressAccountChanged, this, &AccountSwitcherDialog::updateSelection);
|
||||
connect(m_ctx->wallet->subaddressAccount(), &SubaddressAccount::refreshFinished, this, &AccountSwitcherDialog::updateSelection);
|
||||
|
||||
this->updateSelection();
|
||||
}
|
||||
|
||||
void AccountSwitcherDialog::switchAccount() {
|
||||
QModelIndex index = ui->accounts->currentIndex();
|
||||
m_ctx->wallet->switchSubaddressAccount(index.row());
|
||||
}
|
||||
|
||||
void AccountSwitcherDialog::copyLabel() {
|
||||
auto row = this->currentEntry();
|
||||
if (!row)
|
||||
return;
|
||||
|
||||
Utils::copyToClipboard(QString::fromStdString(row->getLabel()));
|
||||
}
|
||||
|
||||
void AccountSwitcherDialog::copyBalance() {
|
||||
auto row = this->currentEntry();
|
||||
if (!row)
|
||||
return;
|
||||
|
||||
Utils::copyToClipboard(QString::fromStdString(row->getBalance()));
|
||||
}
|
||||
|
||||
void AccountSwitcherDialog::editLabel() {
|
||||
QModelIndex index = ui->accounts->currentIndex().siblingAtColumn(m_ctx->wallet->subaddressAccountModel()->Column::Label);
|
||||
ui->accounts->setCurrentIndex(index);
|
||||
ui->accounts->edit(index);
|
||||
}
|
||||
|
||||
void AccountSwitcherDialog::updateSelection() {
|
||||
qDebug() << "test";
|
||||
QModelIndex index = m_model->index(m_ctx->wallet->currentSubaddressAccount(), 0);
|
||||
ui->accounts->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
|
||||
}
|
||||
|
||||
void AccountSwitcherDialog::showContextMenu(const QPoint &point) {
|
||||
QModelIndex index = ui->accounts->currentIndex();
|
||||
if (!index.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto *menu = new QMenu(ui->accounts);
|
||||
|
||||
menu->addAction("Switch to account", this, &AccountSwitcherDialog::switchAccount);
|
||||
menu->addAction("Copy label", this, &AccountSwitcherDialog::copyLabel);
|
||||
menu->addAction("Copy balance", this, &AccountSwitcherDialog::copyBalance);
|
||||
menu->addAction("Edit label", this, &AccountSwitcherDialog::editLabel);
|
||||
|
||||
menu->popup(ui->accounts->viewport()->mapToGlobal(point));
|
||||
}
|
||||
|
||||
Monero::SubaddressAccountRow* AccountSwitcherDialog::currentEntry() {
|
||||
QModelIndex index = ui->accounts->currentIndex();
|
||||
return m_ctx->wallet->subaddressAccountModel()->entryFromIndex(index);
|
||||
}
|
||||
|
||||
AccountSwitcherDialog::~AccountSwitcherDialog() {
|
||||
delete ui;
|
||||
}
|
41
src/dialog/AccountSwitcherDialog.h
Normal file
41
src/dialog/AccountSwitcherDialog.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// Copyright (c) 2020-2021, The Monero Project.
|
||||
|
||||
#ifndef FEATHER_ACCOUNTSWITCHERDIALOG_H
|
||||
#define FEATHER_ACCOUNTSWITCHERDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "appcontext.h"
|
||||
|
||||
#include "model/SubaddressAccountModel.h"
|
||||
|
||||
namespace Ui {
|
||||
class AccountSwitcherDialog;
|
||||
}
|
||||
|
||||
class AccountSwitcherDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AccountSwitcherDialog(QSharedPointer<AppContext> ctx, QWidget *parent = nullptr);
|
||||
~AccountSwitcherDialog() override;
|
||||
|
||||
private slots:
|
||||
void showContextMenu(const QPoint& point);
|
||||
void updateSelection();
|
||||
|
||||
private:
|
||||
void switchAccount();
|
||||
void copyLabel();
|
||||
void copyBalance();
|
||||
void editLabel();
|
||||
|
||||
Monero::SubaddressAccountRow* currentEntry();
|
||||
|
||||
Ui::AccountSwitcherDialog *ui;
|
||||
QSharedPointer<AppContext> m_ctx;
|
||||
SubaddressAccountModel *m_model;
|
||||
};
|
||||
|
||||
#endif //FEATHER_ACCOUNTSWITCHERDIALOG_H
|
88
src/dialog/AccountSwitcherDialog.ui
Normal file
88
src/dialog/AccountSwitcherDialog.ui
Normal file
|
@ -0,0 +1,88 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AccountSwitcherDialog</class>
|
||||
<widget class="QDialog" name="AccountSwitcherDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>521</width>
|
||||
<height>275</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Accounts</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTreeView" name="accounts">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="headerStretchLastSection">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_newAccount">
|
||||
<property name="text">
|
||||
<string>New account</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>AccountSwitcherDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>AccountSwitcherDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
|
@ -41,6 +41,10 @@ void Coins::refresh(quint32 accountIndex)
|
|||
|
||||
m_pimpl->refresh();
|
||||
for (const auto i : m_pimpl->getAll()) {
|
||||
if (i->subaddrAccount() != accountIndex) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m_tinfo.append(new CoinsInfo(i, this));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,3 +62,8 @@ quint64 SubaddressAccount::count() const
|
|||
|
||||
return m_rows.size();
|
||||
}
|
||||
|
||||
Monero::SubaddressAccountRow* SubaddressAccount::row(int index) const
|
||||
{
|
||||
return m_rows.value(index);
|
||||
}
|
|
@ -22,6 +22,7 @@ public:
|
|||
Q_INVOKABLE void setLabel(quint32 accountIndex, const QString &label) const;
|
||||
Q_INVOKABLE void refresh() const;
|
||||
quint64 count() const;
|
||||
Monero::SubaddressAccountRow* row(int index) const;
|
||||
|
||||
signals:
|
||||
void refreshStarted() const;
|
||||
|
|
|
@ -104,7 +104,6 @@ void TransactionHistory::refresh(quint32 accountIndex)
|
|||
void TransactionHistory::setTxNote(const QString &txid, const QString ¬e)
|
||||
{
|
||||
m_pimpl->setTxNote(txid.toStdString(), note.toStdString());
|
||||
this->refresh(0); // todo: get actual account index
|
||||
emit txNoteChanged();
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ private:
|
|||
// history contains locked transfers
|
||||
mutable bool m_locked;
|
||||
|
||||
quint32 lastAccountIndex = 0;
|
||||
};
|
||||
|
||||
#endif // TRANSACTIONHISTORY_H
|
||||
|
|
|
@ -375,6 +375,8 @@ void Wallet::switchSubaddressAccount(quint32 accountIndex)
|
|||
}
|
||||
m_subaddress->refresh(m_currentSubaddressAccount);
|
||||
m_history->refresh(m_currentSubaddressAccount);
|
||||
m_coins->refresh(m_currentSubaddressAccount);
|
||||
this->subaddressModel()->setCurrentSubaddressAcount(m_currentSubaddressAccount);
|
||||
emit currentSubaddressAccountChanged();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "dialog/balancedialog.h"
|
||||
#include "dialog/WalletCacheDebugDialog.h"
|
||||
#include "dialog/UpdateDialog.h"
|
||||
#include "dialog/AccountSwitcherDialog.h"
|
||||
#include "constants.h"
|
||||
#include "libwalletqt/AddressBook.h"
|
||||
#include "utils/AsyncTask.h"
|
||||
|
@ -128,6 +129,10 @@ void MainWindow::initStatusBar() {
|
|||
connect(m_statusBtnConnectionStatusIndicator, &StatusBarButton::clicked, this, &MainWindow::showConnectionStatusDialog);
|
||||
this->statusBar()->addPermanentWidget(m_statusBtnConnectionStatusIndicator);
|
||||
|
||||
m_statusAccountSwitcher = new StatusBarButton(icons()->icon("change_account.png"), "Account switcher", this);
|
||||
connect(m_statusAccountSwitcher, &StatusBarButton::clicked, this, &MainWindow::showAccountSwitcherDialog);
|
||||
this->statusBar()->addPermanentWidget(m_statusAccountSwitcher);
|
||||
|
||||
m_statusBtnPassword = new StatusBarButton(icons()->icon("lock.svg"), "Password", this);
|
||||
connect(m_statusBtnPassword, &StatusBarButton::clicked, this, &MainWindow::showPasswordDialog);
|
||||
this->statusBar()->addPermanentWidget(m_statusBtnPassword);
|
||||
|
@ -212,6 +217,7 @@ void MainWindow::initMenu() {
|
|||
|
||||
// [Wallet]
|
||||
connect(ui->actionInformation, &QAction::triggered, this, &MainWindow::showWalletInfoDialog);
|
||||
connect(ui->actionAccount, &QAction::triggered, this, &MainWindow::showAccountSwitcherDialog);
|
||||
connect(ui->actionPassword, &QAction::triggered, this, &MainWindow::showPasswordDialog);
|
||||
connect(ui->actionSeed, &QAction::triggered, this, &MainWindow::showSeedDialog);
|
||||
connect(ui->actionKeys, &QAction::triggered, this, &MainWindow::showKeysDialog);
|
||||
|
@ -439,12 +445,13 @@ void MainWindow::onWalletOpened() {
|
|||
this->setStatusText("Wallet opened - Searching for node");
|
||||
|
||||
// receive page
|
||||
m_ctx->wallet->subaddress()->refresh( m_ctx->wallet->currentSubaddressAccount());
|
||||
m_ctx->wallet->subaddress()->refresh(m_ctx->wallet->currentSubaddressAccount());
|
||||
if (m_ctx->wallet->subaddress()->count() == 1) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
m_ctx->wallet->subaddress()->addRow(m_ctx->wallet->currentSubaddressAccount(), "");
|
||||
}
|
||||
}
|
||||
m_ctx->wallet->subaddressModel()->setCurrentSubaddressAcount(m_ctx->wallet->currentSubaddressAccount());
|
||||
|
||||
// history page
|
||||
m_ctx->wallet->history()->refresh(m_ctx->wallet->currentSubaddressAccount());
|
||||
|
@ -903,6 +910,11 @@ void MainWindow::showWalletCacheDebugDialog() {
|
|||
dialog.exec();
|
||||
}
|
||||
|
||||
void MainWindow::showAccountSwitcherDialog() {
|
||||
AccountSwitcherDialog dialog{m_ctx, this};
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
void MainWindow::showNodeExhaustedMessage() {
|
||||
// Spawning dialogs inside a lambda can cause system freezes on linux so we have to do it this way ¯\_(ツ)_/¯
|
||||
|
||||
|
|
|
@ -155,6 +155,7 @@ private slots:
|
|||
void showKeysDialog();
|
||||
void showViewOnlyDialog();
|
||||
void showWalletCacheDebugDialog();
|
||||
void showAccountSwitcherDialog();
|
||||
|
||||
void donateButtonClicked();
|
||||
void showCalcWindow();
|
||||
|
@ -230,6 +231,7 @@ private:
|
|||
ClickableLabel *m_statusLabelBalance;
|
||||
QLabel *m_statusLabelStatus;
|
||||
QLabel *m_statusLabelNetStats;
|
||||
StatusBarButton *m_statusAccountSwitcher;
|
||||
StatusBarButton *m_statusBtnConnectionStatusIndicator;
|
||||
StatusBarButton *m_statusBtnPassword;
|
||||
StatusBarButton *m_statusBtnPreferences;
|
||||
|
|
|
@ -403,6 +403,7 @@
|
|||
<addaction name="actionInformation"/>
|
||||
<addaction name="menuAdvanced"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionAccount"/>
|
||||
<addaction name="actionPassword"/>
|
||||
<addaction name="actionSeed"/>
|
||||
<addaction name="actionKeys"/>
|
||||
|
@ -742,6 +743,30 @@
|
|||
<string>t</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actiond">
|
||||
<property name="text">
|
||||
<string>d</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionPrimary_account">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Primary account</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAccount">
|
||||
<property name="text">
|
||||
<string>Account</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
#include <QDebug>
|
||||
|
||||
SubaddressAccountModel::SubaddressAccountModel(QObject *parent, SubaddressAccount *subaddressAccount)
|
||||
: QAbstractListModel(parent), m_subaddressAccount(subaddressAccount)
|
||||
: QAbstractTableModel(parent)
|
||||
, m_subaddressAccount(subaddressAccount)
|
||||
{
|
||||
connect(m_subaddressAccount, &SubaddressAccount::refreshStarted, this, &SubaddressAccountModel::startReset);
|
||||
connect(m_subaddressAccount, &SubaddressAccount::refreshFinished, this, &SubaddressAccountModel::endReset);
|
||||
|
@ -16,13 +17,26 @@ SubaddressAccountModel::SubaddressAccountModel(QObject *parent, SubaddressAccoun
|
|||
void SubaddressAccountModel::startReset(){
|
||||
beginResetModel();
|
||||
}
|
||||
|
||||
void SubaddressAccountModel::endReset(){
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
int SubaddressAccountModel::rowCount(const QModelIndex &) const
|
||||
int SubaddressAccountModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return m_subaddressAccount->count();
|
||||
if (parent.isValid()) {
|
||||
return 0;
|
||||
} else {
|
||||
return m_subaddressAccount->count();
|
||||
}
|
||||
}
|
||||
|
||||
int SubaddressAccountModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid()) {
|
||||
return 0;
|
||||
}
|
||||
return Column::COUNT;
|
||||
}
|
||||
|
||||
QVariant SubaddressAccountModel::data(const QModelIndex &index, int role) const
|
||||
|
@ -32,24 +46,12 @@ QVariant SubaddressAccountModel::data(const QModelIndex &index, int role) const
|
|||
|
||||
QVariant result;
|
||||
|
||||
bool found = m_subaddressAccount->getRow(index.row(), [&result, &role](const Monero::SubaddressAccountRow &row) {
|
||||
switch (role) {
|
||||
case SubaddressAccountAddressRole:
|
||||
result = QString::fromStdString(row.getAddress());
|
||||
break;
|
||||
case SubaddressAccountLabelRole:
|
||||
result = QString::fromStdString(row.getLabel());
|
||||
break;
|
||||
case SubaddressAccountBalanceRole:
|
||||
result = QString::fromStdString(row.getBalance());
|
||||
break;
|
||||
case SubaddressAccountUnlockedBalanceRole:
|
||||
result = QString::fromStdString(row.getUnlockedBalance());
|
||||
break;
|
||||
default:
|
||||
qCritical() << "Unimplemented role" << role;
|
||||
bool found = m_subaddressAccount->getRow(index.row(), [this, &index, &result, &role](const Monero::SubaddressAccountRow &row) {
|
||||
if (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::UserRole) {
|
||||
result = parseSubaddressAccountRow(row, index, role);
|
||||
}
|
||||
});
|
||||
|
||||
if (!found) {
|
||||
qCritical("%s: internal error: invalid index %d", __FUNCTION__, index.row());
|
||||
}
|
||||
|
@ -57,15 +59,80 @@ QVariant SubaddressAccountModel::data(const QModelIndex &index, int role) const
|
|||
return result;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> SubaddressAccountModel::roleNames() const
|
||||
QVariant SubaddressAccountModel::parseSubaddressAccountRow(const Monero::SubaddressAccountRow &row,
|
||||
const QModelIndex &index, int role) const
|
||||
{
|
||||
static QHash<int, QByteArray> roleNames;
|
||||
if (roleNames.empty())
|
||||
{
|
||||
roleNames.insert(SubaddressAccountAddressRole, "address");
|
||||
roleNames.insert(SubaddressAccountLabelRole, "label");
|
||||
roleNames.insert(SubaddressAccountBalanceRole, "balance");
|
||||
roleNames.insert(SubaddressAccountUnlockedBalanceRole, "unlockedBalance");
|
||||
switch (index.column()) {
|
||||
case Number:
|
||||
return QString("#%1").arg(QString::number(index.row()));
|
||||
case Address:
|
||||
return QString::fromStdString(row.getAddress());
|
||||
case Label:
|
||||
return QString::fromStdString(row.getLabel());
|
||||
case Balance:
|
||||
return QString::fromStdString(row.getBalance());
|
||||
case UnlockedBalance:
|
||||
return QString::fromStdString(row.getUnlockedBalance());
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
return roleNames;
|
||||
}
|
||||
|
||||
QVariant SubaddressAccountModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole) {
|
||||
return QVariant();
|
||||
}
|
||||
if (orientation == Qt::Horizontal)
|
||||
{
|
||||
switch (section) {
|
||||
case Address:
|
||||
return QString("Address");
|
||||
case Label:
|
||||
return QString("Label");
|
||||
case Balance:
|
||||
return QString("Balance");
|
||||
case UnlockedBalance:
|
||||
return QString("Spendable balance");
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool SubaddressAccountModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (index.isValid() && role == Qt::EditRole) {
|
||||
const int row = index.row();
|
||||
|
||||
switch (index.column()) {
|
||||
case Label:
|
||||
m_subaddressAccount->setLabel(row, value.toString());
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Qt::ItemFlags SubaddressAccountModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return Qt::ItemIsEnabled;
|
||||
|
||||
if (index.column() == Label)
|
||||
return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
|
||||
|
||||
return QAbstractTableModel::flags(index);
|
||||
}
|
||||
|
||||
Monero::SubaddressAccountRow* SubaddressAccountModel::entryFromIndex(const QModelIndex &index) const {
|
||||
Q_ASSERT(index.isValid() && index.row() < m_subaddressAccount->count());
|
||||
return m_subaddressAccount->row(index.row());
|
||||
}
|
|
@ -4,35 +4,44 @@
|
|||
#ifndef SUBADDRESSACCOUNTMODEL_H
|
||||
#define SUBADDRESSACCOUNTMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include "Subaddress.h"
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
class SubaddressAccount;
|
||||
|
||||
class SubaddressAccountModel : public QAbstractListModel
|
||||
class SubaddressAccountModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum SubaddressAccountRowRole {
|
||||
SubaddressAccountRole = Qt::UserRole + 1, // for the SubaddressAccountRow object;
|
||||
SubaddressAccountAddressRole,
|
||||
SubaddressAccountLabelRole,
|
||||
SubaddressAccountBalanceRole,
|
||||
SubaddressAccountUnlockedBalanceRole,
|
||||
enum Column {
|
||||
Number,
|
||||
Address,
|
||||
Label,
|
||||
Balance,
|
||||
UnlockedBalance,
|
||||
COUNT
|
||||
};
|
||||
Q_ENUM(SubaddressAccountRowRole)
|
||||
|
||||
SubaddressAccountModel(QObject *parent, SubaddressAccount *subaddressAccount);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
|
||||
Monero::SubaddressAccountRow* entryFromIndex(const QModelIndex &index) const;
|
||||
|
||||
public slots:
|
||||
void startReset();
|
||||
void endReset();
|
||||
|
||||
private:
|
||||
QVariant parseSubaddressAccountRow(const Monero::SubaddressAccountRow &row, const QModelIndex &index, int role) const;
|
||||
|
||||
SubaddressAccount *m_subaddressAccount;
|
||||
};
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
#include <QBrush>
|
||||
|
||||
SubaddressModel::SubaddressModel(QObject *parent, Subaddress *subaddress)
|
||||
: QAbstractTableModel(parent),
|
||||
m_subaddress(subaddress),
|
||||
m_showFullAddresses(false)
|
||||
: QAbstractTableModel(parent)
|
||||
, m_subaddress(subaddress)
|
||||
, m_showFullAddresses(false)
|
||||
{
|
||||
connect(m_subaddress, &Subaddress::refreshStarted, this, &SubaddressModel::startReset);
|
||||
connect(m_subaddress, &Subaddress::refreshFinished, this, &SubaddressModel::endReset);
|
||||
|
@ -143,7 +143,7 @@ bool SubaddressModel::setData(const QModelIndex &index, const QVariant &value, i
|
|||
|
||||
switch (index.column()) {
|
||||
case Label:
|
||||
m_subaddress->setLabel(0, row, value.toString()); // Todo: get actual account index
|
||||
m_subaddress->setLabel(m_currentSubaddressAcount, row, value.toString());
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
|
@ -180,6 +180,10 @@ int SubaddressModel::unusedLookahead() const {
|
|||
return m_subaddress->unusedLookahead();
|
||||
}
|
||||
|
||||
void SubaddressModel::setCurrentSubaddressAcount(quint32 accountIndex) {
|
||||
m_currentSubaddressAcount = accountIndex;
|
||||
}
|
||||
|
||||
Monero::SubaddressRow* SubaddressModel::entryFromIndex(const QModelIndex &index) const {
|
||||
Q_ASSERT(index.isValid() && index.row() < m_subaddress->count());
|
||||
return m_subaddress->row(index.row());
|
||||
|
|
|
@ -40,6 +40,7 @@ public:
|
|||
|
||||
Monero::SubaddressRow* entryFromIndex(const QModelIndex &index) const;
|
||||
|
||||
void setCurrentSubaddressAcount(quint32 accountIndex);
|
||||
int unusedLookahead() const;
|
||||
|
||||
public slots:
|
||||
|
@ -51,6 +52,7 @@ private:
|
|||
QVariant parseSubaddressRow(const Monero::SubaddressRow &subaddress, const QModelIndex &index, int role) const;
|
||||
|
||||
bool m_showFullAddresses;
|
||||
quint32 m_currentSubaddressAcount;
|
||||
};
|
||||
|
||||
#endif // SUBADDRESSMODEL_H
|
||||
|
|
Loading…
Reference in a new issue