1 // Copyright (c) 2011-2016 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #include "receivecoinsdialog.h"
6 #include "ui_receivecoinsdialog.h"
8 #include "addressbookpage.h"
9 #include "addresstablemodel.h"
10 #include "bitcoinunits.h"
12 #include "optionsmodel.h"
13 #include "platformstyle.h"
14 #include "receiverequestdialog.h"
15 #include "recentrequeststablemodel.h"
16 #include "walletmodel.h"
20 #include <QItemSelection>
21 #include <QMessageBox>
23 #include <QTextDocument>
25 ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle
*_platformStyle
, QWidget
*parent
) :
27 ui(new Ui::ReceiveCoinsDialog
),
28 columnResizingFixer(0),
30 platformStyle(_platformStyle
)
34 if (!_platformStyle
->getImagesOnButtons()) {
35 ui
->clearButton
->setIcon(QIcon());
36 ui
->receiveButton
->setIcon(QIcon());
37 ui
->showRequestButton
->setIcon(QIcon());
38 ui
->removeRequestButton
->setIcon(QIcon());
40 ui
->clearButton
->setIcon(_platformStyle
->SingleColorIcon(":/icons/remove"));
41 ui
->receiveButton
->setIcon(_platformStyle
->SingleColorIcon(":/icons/receiving_addresses"));
42 ui
->showRequestButton
->setIcon(_platformStyle
->SingleColorIcon(":/icons/edit"));
43 ui
->removeRequestButton
->setIcon(_platformStyle
->SingleColorIcon(":/icons/remove"));
46 // context menu actions
47 QAction
*copyURIAction
= new QAction(tr("Copy URI"), this);
48 QAction
*copyLabelAction
= new QAction(tr("Copy label"), this);
49 QAction
*copyMessageAction
= new QAction(tr("Copy message"), this);
50 QAction
*copyAmountAction
= new QAction(tr("Copy amount"), this);
53 contextMenu
= new QMenu(this);
54 contextMenu
->addAction(copyURIAction
);
55 contextMenu
->addAction(copyLabelAction
);
56 contextMenu
->addAction(copyMessageAction
);
57 contextMenu
->addAction(copyAmountAction
);
59 // context menu signals
60 connect(ui
->recentRequestsView
, SIGNAL(customContextMenuRequested(QPoint
)), this, SLOT(showMenu(QPoint
)));
61 connect(copyURIAction
, SIGNAL(triggered()), this, SLOT(copyURI()));
62 connect(copyLabelAction
, SIGNAL(triggered()), this, SLOT(copyLabel()));
63 connect(copyMessageAction
, SIGNAL(triggered()), this, SLOT(copyMessage()));
64 connect(copyAmountAction
, SIGNAL(triggered()), this, SLOT(copyAmount()));
66 connect(ui
->clearButton
, SIGNAL(clicked()), this, SLOT(clear()));
69 void ReceiveCoinsDialog::setModel(WalletModel
*_model
)
73 if(_model
&& _model
->getOptionsModel())
75 _model
->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date
, Qt::DescendingOrder
);
76 connect(_model
->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
79 QTableView
* tableView
= ui
->recentRequestsView
;
81 tableView
->verticalHeader()->hide();
82 tableView
->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff
);
83 tableView
->setModel(_model
->getRecentRequestsTableModel());
84 tableView
->setAlternatingRowColors(true);
85 tableView
->setSelectionBehavior(QAbstractItemView::SelectRows
);
86 tableView
->setSelectionMode(QAbstractItemView::ContiguousSelection
);
87 tableView
->setColumnWidth(RecentRequestsTableModel::Date
, DATE_COLUMN_WIDTH
);
88 tableView
->setColumnWidth(RecentRequestsTableModel::Label
, LABEL_COLUMN_WIDTH
);
89 tableView
->setColumnWidth(RecentRequestsTableModel::Amount
, AMOUNT_MINIMUM_COLUMN_WIDTH
);
91 connect(tableView
->selectionModel(),
92 SIGNAL(selectionChanged(QItemSelection
, QItemSelection
)), this,
93 SLOT(recentRequestsView_selectionChanged(QItemSelection
, QItemSelection
)));
94 // Last 2 columns are set by the columnResizingFixer, when the table geometry is ready.
95 columnResizingFixer
= new GUIUtil::TableViewLastColumnResizingFixer(tableView
, AMOUNT_MINIMUM_COLUMN_WIDTH
, DATE_COLUMN_WIDTH
, this);
99 ReceiveCoinsDialog::~ReceiveCoinsDialog()
104 void ReceiveCoinsDialog::clear()
106 ui
->reqAmount
->clear();
107 ui
->reqLabel
->setText("");
108 ui
->reqMessage
->setText("");
109 ui
->reuseAddress
->setChecked(false);
113 void ReceiveCoinsDialog::reject()
118 void ReceiveCoinsDialog::accept()
123 void ReceiveCoinsDialog::updateDisplayUnit()
125 if(model
&& model
->getOptionsModel())
127 ui
->reqAmount
->setDisplayUnit(model
->getOptionsModel()->getDisplayUnit());
131 void ReceiveCoinsDialog::on_receiveButton_clicked()
133 if(!model
|| !model
->getOptionsModel() || !model
->getAddressTableModel() || !model
->getRecentRequestsTableModel())
137 QString label
= ui
->reqLabel
->text();
138 if(ui
->reuseAddress
->isChecked())
140 /* Choose existing receiving address */
141 AddressBookPage
dlg(platformStyle
, AddressBookPage::ForSelection
, AddressBookPage::ReceivingTab
, this);
142 dlg
.setModel(model
->getAddressTableModel());
145 address
= dlg
.getReturnValue();
146 if(label
.isEmpty()) /* If no label provided, use the previously used label */
148 label
= model
->getAddressTableModel()->labelForAddress(address
);
154 /* Generate new receiving address */
155 address
= model
->getAddressTableModel()->addRow(AddressTableModel::Receive
, label
, "");
157 SendCoinsRecipient
info(address
, label
,
158 ui
->reqAmount
->value(), ui
->reqMessage
->text());
159 ReceiveRequestDialog
*dialog
= new ReceiveRequestDialog(this);
160 dialog
->setAttribute(Qt::WA_DeleteOnClose
);
161 dialog
->setModel(model
->getOptionsModel());
162 dialog
->setInfo(info
);
166 /* Store request for later reference */
167 model
->getRecentRequestsTableModel()->addNewRequest(info
);
170 void ReceiveCoinsDialog::on_recentRequestsView_doubleClicked(const QModelIndex
&index
)
172 const RecentRequestsTableModel
*submodel
= model
->getRecentRequestsTableModel();
173 ReceiveRequestDialog
*dialog
= new ReceiveRequestDialog(this);
174 dialog
->setModel(model
->getOptionsModel());
175 dialog
->setInfo(submodel
->entry(index
.row()).recipient
);
176 dialog
->setAttribute(Qt::WA_DeleteOnClose
);
180 void ReceiveCoinsDialog::recentRequestsView_selectionChanged(const QItemSelection
&selected
, const QItemSelection
&deselected
)
182 // Enable Show/Remove buttons only if anything is selected.
183 bool enable
= !ui
->recentRequestsView
->selectionModel()->selectedRows().isEmpty();
184 ui
->showRequestButton
->setEnabled(enable
);
185 ui
->removeRequestButton
->setEnabled(enable
);
188 void ReceiveCoinsDialog::on_showRequestButton_clicked()
190 if(!model
|| !model
->getRecentRequestsTableModel() || !ui
->recentRequestsView
->selectionModel())
192 QModelIndexList selection
= ui
->recentRequestsView
->selectionModel()->selectedRows();
194 Q_FOREACH (const QModelIndex
& index
, selection
) {
195 on_recentRequestsView_doubleClicked(index
);
199 void ReceiveCoinsDialog::on_removeRequestButton_clicked()
201 if(!model
|| !model
->getRecentRequestsTableModel() || !ui
->recentRequestsView
->selectionModel())
203 QModelIndexList selection
= ui
->recentRequestsView
->selectionModel()->selectedRows();
204 if(selection
.empty())
206 // correct for selection mode ContiguousSelection
207 QModelIndex firstIndex
= selection
.at(0);
208 model
->getRecentRequestsTableModel()->removeRows(firstIndex
.row(), selection
.length(), firstIndex
.parent());
211 // We override the virtual resizeEvent of the QWidget to adjust tables column
212 // sizes as the tables width is proportional to the dialogs width.
213 void ReceiveCoinsDialog::resizeEvent(QResizeEvent
*event
)
215 QWidget::resizeEvent(event
);
216 columnResizingFixer
->stretchColumnWidth(RecentRequestsTableModel::Message
);
219 void ReceiveCoinsDialog::keyPressEvent(QKeyEvent
*event
)
221 if (event
->key() == Qt::Key_Return
)
223 // press return -> submit form
224 if (ui
->reqLabel
->hasFocus() || ui
->reqAmount
->hasFocus() || ui
->reqMessage
->hasFocus())
227 on_receiveButton_clicked();
232 this->QDialog::keyPressEvent(event
);
235 QModelIndex
ReceiveCoinsDialog::selectedRow()
237 if(!model
|| !model
->getRecentRequestsTableModel() || !ui
->recentRequestsView
->selectionModel())
238 return QModelIndex();
239 QModelIndexList selection
= ui
->recentRequestsView
->selectionModel()->selectedRows();
240 if(selection
.empty())
241 return QModelIndex();
242 // correct for selection mode ContiguousSelection
243 QModelIndex firstIndex
= selection
.at(0);
247 // copy column of selected row to clipboard
248 void ReceiveCoinsDialog::copyColumnToClipboard(int column
)
250 QModelIndex firstIndex
= selectedRow();
251 if (!firstIndex
.isValid()) {
254 GUIUtil::setClipboard(model
->getRecentRequestsTableModel()->data(firstIndex
.child(firstIndex
.row(), column
), Qt::EditRole
).toString());
258 void ReceiveCoinsDialog::showMenu(const QPoint
&point
)
260 if (!selectedRow().isValid()) {
263 contextMenu
->exec(QCursor::pos());
266 // context menu action: copy URI
267 void ReceiveCoinsDialog::copyURI()
269 QModelIndex sel
= selectedRow();
270 if (!sel
.isValid()) {
274 const RecentRequestsTableModel
* const submodel
= model
->getRecentRequestsTableModel();
275 const QString uri
= GUIUtil::formatBitcoinURI(submodel
->entry(sel
.row()).recipient
);
276 GUIUtil::setClipboard(uri
);
279 // context menu action: copy label
280 void ReceiveCoinsDialog::copyLabel()
282 copyColumnToClipboard(RecentRequestsTableModel::Label
);
285 // context menu action: copy message
286 void ReceiveCoinsDialog::copyMessage()
288 copyColumnToClipboard(RecentRequestsTableModel::Message
);
291 // context menu action: copy amount
292 void ReceiveCoinsDialog::copyAmount()
294 copyColumnToClipboard(RecentRequestsTableModel::Amount
);