Line data Source code
1 : // Copyright (c) 2011-2014 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.
4 :
5 : #include "receivecoinsdialog.h"
6 : #include "ui_receivecoinsdialog.h"
7 :
8 : #include "addressbookpage.h"
9 : #include "addresstablemodel.h"
10 : #include "bitcoinunits.h"
11 : #include "guiutil.h"
12 : #include "optionsmodel.h"
13 : #include "platformstyle.h"
14 : #include "receiverequestdialog.h"
15 : #include "recentrequeststablemodel.h"
16 : #include "walletmodel.h"
17 :
18 : #include <QAction>
19 : #include <QCursor>
20 : #include <QItemSelection>
21 : #include <QMessageBox>
22 : #include <QScrollBar>
23 : #include <QTextDocument>
24 :
25 0 : ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *platformStyle, QWidget *parent) :
26 : QDialog(parent),
27 0 : ui(new Ui::ReceiveCoinsDialog),
28 : model(0),
29 0 : platformStyle(platformStyle)
30 : {
31 0 : ui->setupUi(this);
32 :
33 0 : if (!platformStyle->getImagesOnButtons()) {
34 0 : ui->clearButton->setIcon(QIcon());
35 0 : ui->receiveButton->setIcon(QIcon());
36 0 : ui->showRequestButton->setIcon(QIcon());
37 0 : ui->removeRequestButton->setIcon(QIcon());
38 : } else {
39 0 : ui->clearButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
40 0 : ui->receiveButton->setIcon(platformStyle->SingleColorIcon(":/icons/receiving_addresses"));
41 0 : ui->showRequestButton->setIcon(platformStyle->SingleColorIcon(":/icons/edit"));
42 0 : ui->removeRequestButton->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
43 : }
44 :
45 : // context menu actions
46 0 : QAction *copyLabelAction = new QAction(tr("Copy label"), this);
47 0 : QAction *copyMessageAction = new QAction(tr("Copy message"), this);
48 0 : QAction *copyAmountAction = new QAction(tr("Copy amount"), this);
49 :
50 : // context menu
51 0 : contextMenu = new QMenu();
52 0 : contextMenu->addAction(copyLabelAction);
53 0 : contextMenu->addAction(copyMessageAction);
54 0 : contextMenu->addAction(copyAmountAction);
55 :
56 : // context menu signals
57 0 : connect(ui->recentRequestsView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showMenu(QPoint)));
58 0 : connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel()));
59 0 : connect(copyMessageAction, SIGNAL(triggered()), this, SLOT(copyMessage()));
60 0 : connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount()));
61 :
62 0 : connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));
63 0 : }
64 :
65 0 : void ReceiveCoinsDialog::setModel(WalletModel *model)
66 : {
67 0 : this->model = model;
68 :
69 0 : if(model && model->getOptionsModel())
70 : {
71 0 : model->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date, Qt::DescendingOrder);
72 0 : connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
73 0 : updateDisplayUnit();
74 :
75 0 : QTableView* tableView = ui->recentRequestsView;
76 :
77 0 : tableView->verticalHeader()->hide();
78 0 : tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
79 0 : tableView->setModel(model->getRecentRequestsTableModel());
80 0 : tableView->setAlternatingRowColors(true);
81 0 : tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
82 0 : tableView->setSelectionMode(QAbstractItemView::ContiguousSelection);
83 0 : tableView->setColumnWidth(RecentRequestsTableModel::Date, DATE_COLUMN_WIDTH);
84 0 : tableView->setColumnWidth(RecentRequestsTableModel::Label, LABEL_COLUMN_WIDTH);
85 :
86 0 : connect(tableView->selectionModel(),
87 : SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this,
88 0 : SLOT(recentRequestsView_selectionChanged(QItemSelection, QItemSelection)));
89 : // Last 2 columns are set by the columnResizingFixer, when the table geometry is ready.
90 0 : columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH);
91 : }
92 0 : }
93 :
94 0 : ReceiveCoinsDialog::~ReceiveCoinsDialog()
95 : {
96 0 : delete ui;
97 0 : }
98 :
99 0 : void ReceiveCoinsDialog::clear()
100 : {
101 0 : ui->reqAmount->clear();
102 0 : ui->reqLabel->setText("");
103 0 : ui->reqMessage->setText("");
104 0 : ui->reuseAddress->setChecked(false);
105 0 : updateDisplayUnit();
106 0 : }
107 :
108 0 : void ReceiveCoinsDialog::reject()
109 : {
110 0 : clear();
111 0 : }
112 :
113 0 : void ReceiveCoinsDialog::accept()
114 : {
115 0 : clear();
116 0 : }
117 :
118 0 : void ReceiveCoinsDialog::updateDisplayUnit()
119 : {
120 0 : if(model && model->getOptionsModel())
121 : {
122 0 : ui->reqAmount->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
123 : }
124 0 : }
125 :
126 0 : void ReceiveCoinsDialog::on_receiveButton_clicked()
127 : {
128 0 : if(!model || !model->getOptionsModel() || !model->getAddressTableModel() || !model->getRecentRequestsTableModel())
129 0 : return;
130 :
131 : QString address;
132 0 : QString label = ui->reqLabel->text();
133 0 : if(ui->reuseAddress->isChecked())
134 : {
135 : /* Choose existing receiving address */
136 0 : AddressBookPage dlg(platformStyle, AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this);
137 0 : dlg.setModel(model->getAddressTableModel());
138 0 : if(dlg.exec())
139 : {
140 0 : address = dlg.getReturnValue();
141 0 : if(label.isEmpty()) /* If no label provided, use the previously used label */
142 : {
143 0 : label = model->getAddressTableModel()->labelForAddress(address);
144 : }
145 : } else {
146 0 : return;
147 0 : }
148 : } else {
149 : /* Generate new receiving address */
150 0 : address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, label, "");
151 : }
152 : SendCoinsRecipient info(address, label,
153 0 : ui->reqAmount->value(), ui->reqMessage->text());
154 0 : ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
155 0 : dialog->setAttribute(Qt::WA_DeleteOnClose);
156 0 : dialog->setModel(model->getOptionsModel());
157 0 : dialog->setInfo(info);
158 0 : dialog->show();
159 0 : clear();
160 :
161 : /* Store request for later reference */
162 0 : model->getRecentRequestsTableModel()->addNewRequest(info);
163 : }
164 :
165 0 : void ReceiveCoinsDialog::on_recentRequestsView_doubleClicked(const QModelIndex &index)
166 : {
167 0 : const RecentRequestsTableModel *submodel = model->getRecentRequestsTableModel();
168 0 : ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
169 0 : dialog->setModel(model->getOptionsModel());
170 0 : dialog->setInfo(submodel->entry(index.row()).recipient);
171 0 : dialog->setAttribute(Qt::WA_DeleteOnClose);
172 0 : dialog->show();
173 0 : }
174 :
175 0 : void ReceiveCoinsDialog::recentRequestsView_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
176 : {
177 : // Enable Show/Remove buttons only if anything is selected.
178 0 : bool enable = !ui->recentRequestsView->selectionModel()->selectedRows().isEmpty();
179 0 : ui->showRequestButton->setEnabled(enable);
180 0 : ui->removeRequestButton->setEnabled(enable);
181 0 : }
182 :
183 0 : void ReceiveCoinsDialog::on_showRequestButton_clicked()
184 : {
185 0 : if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
186 0 : return;
187 0 : QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
188 :
189 0 : Q_FOREACH (const QModelIndex& index, selection) {
190 0 : on_recentRequestsView_doubleClicked(index);
191 0 : }
192 : }
193 :
194 0 : void ReceiveCoinsDialog::on_removeRequestButton_clicked()
195 : {
196 0 : if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
197 0 : return;
198 0 : QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
199 0 : if(selection.empty())
200 0 : return;
201 : // correct for selection mode ContiguousSelection
202 0 : QModelIndex firstIndex = selection.at(0);
203 0 : model->getRecentRequestsTableModel()->removeRows(firstIndex.row(), selection.length(), firstIndex.parent());
204 : }
205 :
206 : // We override the virtual resizeEvent of the QWidget to adjust tables column
207 : // sizes as the tables width is proportional to the dialogs width.
208 0 : void ReceiveCoinsDialog::resizeEvent(QResizeEvent *event)
209 : {
210 0 : QWidget::resizeEvent(event);
211 0 : columnResizingFixer->stretchColumnWidth(RecentRequestsTableModel::Message);
212 0 : }
213 :
214 0 : void ReceiveCoinsDialog::keyPressEvent(QKeyEvent *event)
215 : {
216 0 : if (event->key() == Qt::Key_Return)
217 : {
218 : // press return -> submit form
219 0 : if (ui->reqLabel->hasFocus() || ui->reqAmount->hasFocus() || ui->reqMessage->hasFocus())
220 : {
221 0 : event->ignore();
222 0 : on_receiveButton_clicked();
223 0 : return;
224 : }
225 : }
226 :
227 0 : this->QDialog::keyPressEvent(event);
228 : }
229 :
230 : // copy column of selected row to clipboard
231 0 : void ReceiveCoinsDialog::copyColumnToClipboard(int column)
232 : {
233 0 : if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
234 0 : return;
235 0 : QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
236 0 : if(selection.empty())
237 0 : return;
238 : // correct for selection mode ContiguousSelection
239 0 : QModelIndex firstIndex = selection.at(0);
240 0 : GUIUtil::setClipboard(model->getRecentRequestsTableModel()->data(firstIndex.child(firstIndex.row(), column), Qt::EditRole).toString());
241 : }
242 :
243 : // context menu
244 0 : void ReceiveCoinsDialog::showMenu(const QPoint &point)
245 : {
246 0 : if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel())
247 0 : return;
248 0 : QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows();
249 0 : if(selection.empty())
250 0 : return;
251 0 : contextMenu->exec(QCursor::pos());
252 : }
253 :
254 : // context menu action: copy label
255 0 : void ReceiveCoinsDialog::copyLabel()
256 : {
257 0 : copyColumnToClipboard(RecentRequestsTableModel::Label);
258 0 : }
259 :
260 : // context menu action: copy message
261 0 : void ReceiveCoinsDialog::copyMessage()
262 : {
263 0 : copyColumnToClipboard(RecentRequestsTableModel::Message);
264 0 : }
265 :
266 : // context menu action: copy amount
267 0 : void ReceiveCoinsDialog::copyAmount()
268 : {
269 0 : copyColumnToClipboard(RecentRequestsTableModel::Amount);
270 0 : }
|