diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index b6e5c8bb4..e91735824 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -1,348 +1,348 @@ // Copyright (c) 2011-2016 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #if defined(HAVE_CONFIG_H) #include #endif #include #include #include #include #include #include #include #include #include #include #include class AddressBookSortFilterProxyModel final : public QSortFilterProxyModel { const QString m_type; public: AddressBookSortFilterProxyModel(const QString &type, QObject *parent) : QSortFilterProxyModel(parent), m_type(type) { setDynamicSortFilter(true); setFilterCaseSensitivity(Qt::CaseInsensitive); setSortCaseSensitivity(Qt::CaseInsensitive); } protected: bool filterAcceptsRow(int row, const QModelIndex &parent) const { auto model = sourceModel(); auto label = model->index(row, AddressTableModel::Label, parent); if (model->data(label, AddressTableModel::TypeRole).toString() != m_type) { return false; } auto address = model->index(row, AddressTableModel::Address, parent); if (filterRegExp().indexIn(model->data(address).toString()) < 0 && filterRegExp().indexIn(model->data(label).toString()) < 0) { return false; } return true; } }; AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode _mode, Tabs _tab, QWidget *parent) : QDialog(parent), ui(new Ui::AddressBookPage), model(nullptr), mode(_mode), tab(_tab) { ui->setupUi(this); if (!platformStyle->getImagesOnButtons()) { ui->newAddress->setIcon(QIcon()); ui->copyAddress->setIcon(QIcon()); ui->deleteAddress->setIcon(QIcon()); ui->exportButton->setIcon(QIcon()); } else { ui->newAddress->setIcon(platformStyle->SingleColorIcon(":/icons/add")); ui->copyAddress->setIcon( platformStyle->SingleColorIcon(":/icons/editcopy")); ui->deleteAddress->setIcon( platformStyle->SingleColorIcon(":/icons/remove")); ui->exportButton->setIcon( platformStyle->SingleColorIcon(":/icons/export")); } switch (mode) { case ForSelection: switch (tab) { case SendingTab: setWindowTitle(tr("Choose the address to send coins to")); break; case ReceivingTab: setWindowTitle( tr("Choose the address to receive coins with")); break; } connect(ui->tableView, &QTableView::doubleClicked, this, &QDialog::accept); ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->tableView->setFocus(); ui->closeButton->setText(tr("C&hoose")); ui->exportButton->hide(); break; case ForEditing: switch (tab) { case SendingTab: setWindowTitle(tr("Sending addresses")); break; case ReceivingTab: setWindowTitle(tr("Receiving addresses")); break; } break; } switch (tab) { case SendingTab: ui->labelExplanation->setText( tr("These are your Bitcoin addresses for sending payments. " "Always check the amount and the receiving address before " "sending coins.")); ui->deleteAddress->setVisible(true); ui->newAddress->setVisible(true); break; case ReceivingTab: ui->labelExplanation->setText( tr("These are your Bitcoin addresses for receiving payments. " - "It is recommended to use a new receiving address for each " - "transaction.")); + "Use the 'Create new receiving address' button in the " + "receive tab to create new addresses.")); ui->deleteAddress->setVisible(false); ui->newAddress->setVisible(false); break; } // 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(ui->deleteAddress->text(), this); // Build context menu contextMenu = new QMenu(this); contextMenu->addAction(copyAddressAction); contextMenu->addAction(copyLabelAction); contextMenu->addAction(editAction); if (tab == SendingTab) { contextMenu->addAction(deleteAction); } contextMenu->addSeparator(); // Connect signals for context menu actions connect(copyAddressAction, &QAction::triggered, this, &AddressBookPage::on_copyAddress_clicked); connect(copyLabelAction, &QAction::triggered, this, &AddressBookPage::onCopyLabelAction); connect(editAction, &QAction::triggered, this, &AddressBookPage::onEditAction); connect(deleteAction, &QAction::triggered, this, &AddressBookPage::on_deleteAddress_clicked); connect(ui->tableView, &QWidget::customContextMenuRequested, this, &AddressBookPage::contextualMenu); connect(ui->closeButton, &QPushButton::clicked, this, &QDialog::accept); } AddressBookPage::~AddressBookPage() { delete ui; } void AddressBookPage::setModel(AddressTableModel *_model) { this->model = _model; if (!_model) { return; } auto type = tab == ReceivingTab ? AddressTableModel::Receive : AddressTableModel::Send; proxyModel = new AddressBookSortFilterProxyModel(type, this); proxyModel->setSourceModel(_model); connect(ui->searchLineEdit, &QLineEdit::textChanged, proxyModel, &QSortFilterProxyModel::setFilterWildcard); ui->tableView->setModel(proxyModel); ui->tableView->sortByColumn(0, Qt::AscendingOrder); // Set column widths ui->tableView->horizontalHeader()->setSectionResizeMode( AddressTableModel::Label, QHeaderView::Stretch); ui->tableView->horizontalHeader()->setSectionResizeMode( AddressTableModel::Address, QHeaderView::ResizeToContents); connect(ui->tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &AddressBookPage::selectionChanged); // Select row for newly created address connect(_model, &AddressTableModel::rowsInserted, this, &AddressBookPage::selectNewAddress); selectionChanged(); } void AddressBookPage::on_copyAddress_clicked() { GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Address); } void AddressBookPage::onCopyLabelAction() { GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Label); } void AddressBookPage::onEditAction() { if (!model) { return; } if (!ui->tableView->selectionModel()) { return; } QModelIndexList indexes = ui->tableView->selectionModel()->selectedRows(); if (indexes.isEmpty()) { return; } EditAddressDialog dlg(tab == SendingTab ? EditAddressDialog::EditSendingAddress : EditAddressDialog::EditReceivingAddress, this); dlg.setModel(model); QModelIndex origIndex = proxyModel->mapToSource(indexes.at(0)); dlg.loadRow(origIndex.row()); dlg.exec(); } void AddressBookPage::on_newAddress_clicked() { if (!model) { return; } if (tab == ReceivingTab) { return; } EditAddressDialog dlg(EditAddressDialog::NewSendingAddress, this); dlg.setModel(model); if (dlg.exec()) { newAddressToSelect = dlg.getAddress(); } } void AddressBookPage::on_deleteAddress_clicked() { QTableView *table = ui->tableView; if (!table->selectionModel()) { return; } QModelIndexList indexes = table->selectionModel()->selectedRows(); if (!indexes.isEmpty()) { table->model()->removeRow(indexes.at(0).row()); } } void AddressBookPage::selectionChanged() { // Set button states based on selected tab and selection QTableView *table = ui->tableView; if (!table->selectionModel()) { return; } if (table->selectionModel()->hasSelection()) { switch (tab) { case SendingTab: // In sending tab, allow deletion of selection ui->deleteAddress->setEnabled(true); ui->deleteAddress->setVisible(true); deleteAction->setEnabled(true); break; case ReceivingTab: // Deleting receiving addresses, however, is not allowed ui->deleteAddress->setEnabled(false); ui->deleteAddress->setVisible(false); deleteAction->setEnabled(false); break; } ui->copyAddress->setEnabled(true); } else { ui->deleteAddress->setEnabled(false); ui->copyAddress->setEnabled(false); } } void AddressBookPage::done(int retval) { QTableView *table = ui->tableView; if (!table->selectionModel() || !table->model()) { return; } // Figure out which address was selected, and return it QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); for (const 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::on_exportButton_clicked() { // CSV is currently the only supported format QString filename = GUIUtil::getSaveFileName(this, tr("Export Address List"), QString(), tr("Comma separated file (*.csv)"), nullptr); 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("Exporting Failed"), tr("There was an error trying to save the " "address list to %1. Please try again.") .arg(filename)); } } void AddressBookPage::contextualMenu(const QPoint &point) { QModelIndex index = ui->tableView->indexAt(point); if (index.isValid()) { contextMenu->exec(QCursor::pos()); } } void AddressBookPage::selectNewAddress(const QModelIndex &parent, int begin, int /*end*/) { QModelIndex idx = proxyModel->mapFromSource( model->index(begin, AddressTableModel::Address, parent)); if (idx.isValid() && (idx.data(Qt::EditRole).toString() == newAddressToSelect)) { // Select row of newly created address, once ui->tableView->setFocus(); ui->tableView->selectRow(idx.row()); newAddressToSelect.clear(); } } diff --git a/src/qt/forms/receivecoinsdialog.ui b/src/qt/forms/receivecoinsdialog.ui index 405bcdd96..dbec6ee7b 100644 --- a/src/qt/forms/receivecoinsdialog.ui +++ b/src/qt/forms/receivecoinsdialog.ui @@ -1,320 +1,320 @@ ReceiveCoinsDialog 0 0 776 364 0 0 QFrame::StyledPanel QFrame::Sunken An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network. &Message: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter reqMessage An optional label to associate with the new receiving address. An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network. Use this form to request payments. All fields are <b>optional</b>. An optional label to associate with the new receiving address. &Label: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter reqLabel An optional amount to request. Leave this empty or zero to not request a specific amount. &Amount: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter reqAmount 80 0 An optional amount to request. Leave this empty or zero to not request a specific amount. 150 0 - &Request payment + &Create new receiving address :/icons/receiving_addresses:/icons/receiving_addresses 0 0 Clear all fields of the form. Clear :/icons/remove:/icons/remove false Qt::Horizontal 40 20 Qt::Vertical 20 10 0 0 QFrame::StyledPanel QFrame::Raised 75 true Requested payments history Qt::CustomContextMenu false true false Show the selected request (does the same as double clicking an entry) Show :/icons/edit:/icons/edit false false Remove the selected entries from the list Remove :/icons/remove:/icons/remove false Qt::Horizontal 40 20 BitcoinAmountField QLineEdit
qt/bitcoinamountfield.h
1
reqLabel reqAmount reqMessage receiveButton clearButton recentRequestsView showRequestButton removeRequestButton