#include "ui_addressbookpage.h"
#include "addresstablemodel.h"
+#include "bitcoingui.h"
#include "editaddressdialog.h"
+#include "csvmodelwriter.h"
+#include "guiutil.h"
#include <QSortFilterProxyModel>
#include <QClipboard>
-#include <QDebug>
+#include <QMessageBox>
+#include <QMenu>
+
+#ifdef USE_QRCODE
+#include "qrcodedialog.h"
+#endif
AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
QDialog(parent),
tab(tab)
{
ui->setupUi(this);
+
+#ifdef Q_WS_MAC // Icons on push buttons are very uncommon on Mac
+ ui->newAddressButton->setIcon(QIcon());
+ ui->copyToClipboard->setIcon(QIcon());
+ ui->deleteButton->setIcon(QIcon());
+#endif
+
+#ifndef USE_QRCODE
+ ui->showQRCode->setVisible(false);
+#endif
+
switch(mode)
{
case ForSending:
- connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(on_buttonBox_accepted()));
+ connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept()));
+ ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->tableView->setFocus();
break;
case ForEditing:
- ui->buttonBox->hide();
+ ui->buttonBox->setVisible(false);
break;
}
switch(tab)
{
case SendingTab:
- ui->labelExplanation->hide();
+ ui->labelExplanation->setVisible(false);
+ ui->deleteButton->setVisible(true);
+ ui->signMessage->setVisible(false);
break;
case ReceivingTab:
+ ui->deleteButton->setVisible(false);
+ ui->signMessage->setVisible(true);
break;
}
+ ui->tableView->setTabKeyNavigation(false);
+ ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
+
+ // Context menu actions
+ QAction *copyAddressAction = new QAction(tr("Copy address"), this);
+ QAction *copyLabelAction = new QAction(tr("Copy label"), this);
+ QAction *editAction = new QAction(tr("Edit"), this);
+ deleteAction = new QAction(tr("Delete"), this);
+
+ contextMenu = new QMenu();
+ contextMenu->addAction(copyAddressAction);
+ contextMenu->addAction(copyLabelAction);
+ contextMenu->addAction(editAction);
+ contextMenu->addAction(deleteAction);
+
+ connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(on_copyToClipboard_clicked()));
+ connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(onCopyLabelAction()));
+ connect(editAction, SIGNAL(triggered()), this, SLOT(onEditAction()));
+ connect(deleteAction, SIGNAL(triggered()), this, SLOT(on_deleteButton_clicked()));
+
+ connect(ui->tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint)));
+
+ // Pass through accept action from button box
+ connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
}
AddressBookPage::~AddressBookPage()
void AddressBookPage::setModel(AddressTableModel *model)
{
this->model = model;
- // Refresh list from core
- model->updateList();
+ if(!model)
+ return;
+ proxyModel = new QSortFilterProxyModel(this);
+ proxyModel->setSourceModel(model);
+ proxyModel->setDynamicSortFilter(true);
switch(tab)
{
- case ReceivingTab: {
+ case ReceivingTab:
// Receive filter
- QSortFilterProxyModel *receive_model = new QSortFilterProxyModel(this);
- receive_model->setSourceModel(model);
- receive_model->setDynamicSortFilter(true);
- receive_model->setFilterRole(AddressTableModel::TypeRole);
- receive_model->setFilterFixedString(AddressTableModel::Receive);
- ui->tableView->setModel(receive_model);
- ui->tableView->sortByColumn(0, Qt::AscendingOrder);
- } break;
- case SendingTab: {
+ proxyModel->setFilterRole(AddressTableModel::TypeRole);
+ proxyModel->setFilterFixedString(AddressTableModel::Receive);
+ break;
+ case SendingTab:
// Send filter
- QSortFilterProxyModel *send_model = new QSortFilterProxyModel(this);
- send_model->setSourceModel(model);
- send_model->setDynamicSortFilter(true);
- send_model->setFilterRole(AddressTableModel::TypeRole);
- send_model->setFilterFixedString(AddressTableModel::Send);
- ui->tableView->setModel(send_model);
- ui->tableView->sortByColumn(0, Qt::AscendingOrder);
- } break;
+ proxyModel->setFilterRole(AddressTableModel::TypeRole);
+ proxyModel->setFilterFixedString(AddressTableModel::Send);
+ break;
}
+ ui->tableView->setModel(proxyModel);
+ ui->tableView->sortByColumn(0, Qt::AscendingOrder);
// Set column widths
ui->tableView->horizontalHeader()->resizeSection(
connect(ui->tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
this, SLOT(selectionChanged()));
- if(mode == ForSending)
- {
- // Auto-select first row when in sending mode
- ui->tableView->selectRow(0);
- }
selectionChanged();
}
-QTableView *AddressBookPage::getCurrentTable()
+void AddressBookPage::on_copyToClipboard_clicked()
{
- return ui->tableView;
+ GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Address);
}
-void AddressBookPage::on_copyToClipboard_clicked()
+void AddressBookPage::onCopyLabelAction()
+{
+ GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Label);
+}
+
+void AddressBookPage::onEditAction()
+{
+ if(!ui->tableView->selectionModel())
+ return;
+ QModelIndexList indexes = ui->tableView->selectionModel()->selectedRows();
+ if(indexes.isEmpty())
+ return;
+
+ EditAddressDialog dlg(
+ tab == SendingTab ?
+ EditAddressDialog::EditSendingAddress :
+ EditAddressDialog::EditReceivingAddress);
+ dlg.setModel(model);
+ QModelIndex origIndex = proxyModel->mapToSource(indexes.at(0));
+ dlg.loadRow(origIndex.row());
+ dlg.exec();
+}
+
+void AddressBookPage::on_signMessage_clicked()
{
- // Copy currently selected address to clipboard
- // (or nothing, if nothing selected)
- QTableView *table = getCurrentTable();
+ QTableView *table = ui->tableView;
QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
+ QString addr;
foreach (QModelIndex index, indexes)
{
QVariant address = index.data();
- QApplication::clipboard()->setText(address.toString());
+ addr = address.toString();
}
+
+ QObject *qoGUI = parent()->parent();
+ BitcoinGUI *gui = qobject_cast<BitcoinGUI *>(qoGUI);
+ if (gui)
+ gui->gotoMessagePage(addr);
}
void AddressBookPage::on_newAddressButton_clicked()
{
+ if(!model)
+ return;
EditAddressDialog dlg(
tab == SendingTab ?
EditAddressDialog::NewSendingAddress :
EditAddressDialog::NewReceivingAddress);
dlg.setModel(model);
- dlg.exec();
+ if(dlg.exec())
+ {
+ // Select row for newly created address
+ QString address = dlg.getAddress();
+ QModelIndexList lst = proxyModel->match(proxyModel->index(0,
+ AddressTableModel::Address, QModelIndex()),
+ Qt::EditRole, address, 1, Qt::MatchExactly);
+ if(!lst.isEmpty())
+ {
+ ui->tableView->setFocus();
+ ui->tableView->selectRow(lst.at(0).row());
+ }
+ }
}
void AddressBookPage::on_deleteButton_clicked()
{
- QTableView *table = getCurrentTable();
+ QTableView *table = ui->tableView;
+ if(!table->selectionModel())
+ return;
QModelIndexList indexes = table->selectionModel()->selectedRows();
if(!indexes.isEmpty())
{
}
}
-void AddressBookPage::on_buttonBox_accepted()
-{
- QTableView *table = getCurrentTable();
- QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
-
- foreach (QModelIndex index, indexes)
- {
- QVariant address = table->model()->data(index);
- returnValue = address.toString();
- }
- if(!returnValue.isEmpty())
- {
- accept();
- }
- else
- {
- reject();
- }
-}
-
void AddressBookPage::selectionChanged()
{
// Set button states based on selected tab and selection
- QTableView *table = getCurrentTable();
+ QTableView *table = ui->tableView;
+ if(!table->selectionModel())
+ return;
if(table->selectionModel()->hasSelection())
{
switch(tab)
{
case SendingTab:
+ // In sending tab, allow deletion of selection
ui->deleteButton->setEnabled(true);
+ ui->deleteButton->setVisible(true);
+ deleteAction->setEnabled(true);
+ ui->signMessage->setEnabled(false);
+ ui->signMessage->setVisible(false);
break;
case ReceivingTab:
+ // Deleting receiving addresses, however, is not allowed
ui->deleteButton->setEnabled(false);
+ ui->deleteButton->setVisible(false);
+ deleteAction->setEnabled(false);
+ ui->signMessage->setEnabled(true);
+ ui->signMessage->setVisible(true);
break;
}
ui->copyToClipboard->setEnabled(true);
+ ui->showQRCode->setEnabled(true);
}
else
{
ui->deleteButton->setEnabled(false);
+ ui->showQRCode->setEnabled(false);
ui->copyToClipboard->setEnabled(false);
+ ui->signMessage->setEnabled(false);
}
}
void AddressBookPage::done(int retval)
{
+ QTableView *table = ui->tableView;
+ if(!table->selectionModel() || !table->model())
+ return;
// When this is a tab/widget and not a model dialog, ignore "done"
if(mode == ForEditing)
return;
+
+ // Figure out which address was selected, and return it
+ QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
+
+ foreach (QModelIndex index, indexes)
+ {
+ QVariant address = table->model()->data(index);
+ returnValue = address.toString();
+ }
+
+ if(returnValue.isEmpty())
+ {
+ // If no address entry selected, return rejected
+ retval = Rejected;
+ }
+
QDialog::done(retval);
}
+
+void AddressBookPage::exportClicked()
+{
+ // CSV is currently the only supported format
+ QString filename = GUIUtil::getSaveFileName(
+ this,
+ tr("Export Address Book Data"), QString(),
+ tr("Comma separated file (*.csv)"));
+
+ if (filename.isNull()) return;
+
+ CSVModelWriter writer(filename);
+
+ // name, column, role
+ writer.setModel(proxyModel);
+ writer.addColumn("Label", AddressTableModel::Label, Qt::EditRole);
+ writer.addColumn("Address", AddressTableModel::Address, Qt::EditRole);
+
+ if(!writer.write())
+ {
+ QMessageBox::critical(this, tr("Error exporting"), tr("Could not write to file %1.").arg(filename),
+ QMessageBox::Abort, QMessageBox::Abort);
+ }
+}
+
+void AddressBookPage::on_showQRCode_clicked()
+{
+#ifdef USE_QRCODE
+ QTableView *table = ui->tableView;
+ QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
+
+ foreach (QModelIndex index, indexes)
+ {
+ QString address = index.data().toString(), label = index.sibling(index.row(), 0).data(Qt::EditRole).toString();
+
+ QRCodeDialog *dialog = new QRCodeDialog(address, label, tab == ReceivingTab, this);
+ dialog->show();
+ }
+#endif
+}
+
+void AddressBookPage::contextualMenu(const QPoint &point)
+{
+ QModelIndex index = ui->tableView->indexAt(point);
+ if(index.isValid())
+ {
+ contextMenu->exec(QCursor::pos());
+ }
+}