[tests] Add -blocknotify functional test
[bitcoinplatinum.git] / src / qt / transactionview.cpp
blob39dfdb587c2a6c1d0288a400d8dbb7e4551bfa8b
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 "transactionview.h"
7 #include "addresstablemodel.h"
8 #include "bitcoinunits.h"
9 #include "csvmodelwriter.h"
10 #include "editaddressdialog.h"
11 #include "guiutil.h"
12 #include "optionsmodel.h"
13 #include "platformstyle.h"
14 #include "sendcoinsdialog.h"
15 #include "transactiondescdialog.h"
16 #include "transactionfilterproxy.h"
17 #include "transactionrecord.h"
18 #include "transactiontablemodel.h"
19 #include "walletmodel.h"
21 #include "ui_interface.h"
23 #include <QComboBox>
24 #include <QDateTimeEdit>
25 #include <QDesktopServices>
26 #include <QDoubleValidator>
27 #include <QHBoxLayout>
28 #include <QHeaderView>
29 #include <QLabel>
30 #include <QLineEdit>
31 #include <QMenu>
32 #include <QPoint>
33 #include <QScrollBar>
34 #include <QSignalMapper>
35 #include <QTableView>
36 #include <QTimer>
37 #include <QUrl>
38 #include <QVBoxLayout>
40 TransactionView::TransactionView(const PlatformStyle *platformStyle, QWidget *parent) :
41 QWidget(parent), model(0), transactionProxyModel(0),
42 transactionView(0), abandonAction(0), bumpFeeAction(0), columnResizingFixer(0)
44 // Build filter row
45 setContentsMargins(0,0,0,0);
47 QHBoxLayout *hlayout = new QHBoxLayout();
48 hlayout->setContentsMargins(0,0,0,0);
50 if (platformStyle->getUseExtraSpacing()) {
51 hlayout->setSpacing(5);
52 hlayout->addSpacing(26);
53 } else {
54 hlayout->setSpacing(0);
55 hlayout->addSpacing(23);
58 watchOnlyWidget = new QComboBox(this);
59 watchOnlyWidget->setFixedWidth(24);
60 watchOnlyWidget->addItem("", TransactionFilterProxy::WatchOnlyFilter_All);
61 watchOnlyWidget->addItem(platformStyle->SingleColorIcon(":/icons/eye_plus"), "", TransactionFilterProxy::WatchOnlyFilter_Yes);
62 watchOnlyWidget->addItem(platformStyle->SingleColorIcon(":/icons/eye_minus"), "", TransactionFilterProxy::WatchOnlyFilter_No);
63 hlayout->addWidget(watchOnlyWidget);
65 dateWidget = new QComboBox(this);
66 if (platformStyle->getUseExtraSpacing()) {
67 dateWidget->setFixedWidth(121);
68 } else {
69 dateWidget->setFixedWidth(120);
71 dateWidget->addItem(tr("All"), All);
72 dateWidget->addItem(tr("Today"), Today);
73 dateWidget->addItem(tr("This week"), ThisWeek);
74 dateWidget->addItem(tr("This month"), ThisMonth);
75 dateWidget->addItem(tr("Last month"), LastMonth);
76 dateWidget->addItem(tr("This year"), ThisYear);
77 dateWidget->addItem(tr("Range..."), Range);
78 hlayout->addWidget(dateWidget);
80 typeWidget = new QComboBox(this);
81 if (platformStyle->getUseExtraSpacing()) {
82 typeWidget->setFixedWidth(121);
83 } else {
84 typeWidget->setFixedWidth(120);
87 typeWidget->addItem(tr("All"), TransactionFilterProxy::ALL_TYPES);
88 typeWidget->addItem(tr("Received with"), TransactionFilterProxy::TYPE(TransactionRecord::RecvWithAddress) |
89 TransactionFilterProxy::TYPE(TransactionRecord::RecvFromOther));
90 typeWidget->addItem(tr("Sent to"), TransactionFilterProxy::TYPE(TransactionRecord::SendToAddress) |
91 TransactionFilterProxy::TYPE(TransactionRecord::SendToOther));
92 typeWidget->addItem(tr("To yourself"), TransactionFilterProxy::TYPE(TransactionRecord::SendToSelf));
93 typeWidget->addItem(tr("Mined"), TransactionFilterProxy::TYPE(TransactionRecord::Generated));
94 typeWidget->addItem(tr("Other"), TransactionFilterProxy::TYPE(TransactionRecord::Other));
96 hlayout->addWidget(typeWidget);
98 addressWidget = new QLineEdit(this);
99 #if QT_VERSION >= 0x040700
100 addressWidget->setPlaceholderText(tr("Enter address or label to search"));
101 #endif
102 hlayout->addWidget(addressWidget);
104 amountWidget = new QLineEdit(this);
105 #if QT_VERSION >= 0x040700
106 amountWidget->setPlaceholderText(tr("Min amount"));
107 #endif
108 if (platformStyle->getUseExtraSpacing()) {
109 amountWidget->setFixedWidth(97);
110 } else {
111 amountWidget->setFixedWidth(100);
113 amountWidget->setValidator(new QDoubleValidator(0, 1e20, 8, this));
114 hlayout->addWidget(amountWidget);
116 // Delay before filtering transactions in ms
117 static const int input_filter_delay = 200;
119 QTimer* amount_typing_delay = new QTimer(this);
120 amount_typing_delay->setSingleShot(true);
121 amount_typing_delay->setInterval(input_filter_delay);
123 QTimer* prefix_typing_delay = new QTimer(this);
124 prefix_typing_delay->setSingleShot(true);
125 prefix_typing_delay->setInterval(input_filter_delay);
127 QVBoxLayout *vlayout = new QVBoxLayout(this);
128 vlayout->setContentsMargins(0,0,0,0);
129 vlayout->setSpacing(0);
131 QTableView *view = new QTableView(this);
132 vlayout->addLayout(hlayout);
133 vlayout->addWidget(createDateRangeWidget());
134 vlayout->addWidget(view);
135 vlayout->setSpacing(0);
136 int width = view->verticalScrollBar()->sizeHint().width();
137 // Cover scroll bar width with spacing
138 if (platformStyle->getUseExtraSpacing()) {
139 hlayout->addSpacing(width+2);
140 } else {
141 hlayout->addSpacing(width);
143 // Always show scroll bar
144 view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
145 view->setTabKeyNavigation(false);
146 view->setContextMenuPolicy(Qt::CustomContextMenu);
148 view->installEventFilter(this);
150 transactionView = view;
151 transactionView->setObjectName("transactionView");
153 // Actions
154 abandonAction = new QAction(tr("Abandon transaction"), this);
155 bumpFeeAction = new QAction(tr("Increase transaction fee"), this);
156 bumpFeeAction->setObjectName("bumpFeeAction");
157 QAction *copyAddressAction = new QAction(tr("Copy address"), this);
158 QAction *copyLabelAction = new QAction(tr("Copy label"), this);
159 QAction *copyAmountAction = new QAction(tr("Copy amount"), this);
160 QAction *copyTxIDAction = new QAction(tr("Copy transaction ID"), this);
161 QAction *copyTxHexAction = new QAction(tr("Copy raw transaction"), this);
162 QAction *copyTxPlainText = new QAction(tr("Copy full transaction details"), this);
163 QAction *editLabelAction = new QAction(tr("Edit label"), this);
164 QAction *showDetailsAction = new QAction(tr("Show transaction details"), this);
166 contextMenu = new QMenu(this);
167 contextMenu->setObjectName("contextMenu");
168 contextMenu->addAction(copyAddressAction);
169 contextMenu->addAction(copyLabelAction);
170 contextMenu->addAction(copyAmountAction);
171 contextMenu->addAction(copyTxIDAction);
172 contextMenu->addAction(copyTxHexAction);
173 contextMenu->addAction(copyTxPlainText);
174 contextMenu->addAction(showDetailsAction);
175 contextMenu->addSeparator();
176 contextMenu->addAction(bumpFeeAction);
177 contextMenu->addAction(abandonAction);
178 contextMenu->addAction(editLabelAction);
180 mapperThirdPartyTxUrls = new QSignalMapper(this);
182 // Connect actions
183 connect(mapperThirdPartyTxUrls, SIGNAL(mapped(QString)), this, SLOT(openThirdPartyTxUrl(QString)));
185 connect(dateWidget, SIGNAL(activated(int)), this, SLOT(chooseDate(int)));
186 connect(typeWidget, SIGNAL(activated(int)), this, SLOT(chooseType(int)));
187 connect(watchOnlyWidget, SIGNAL(activated(int)), this, SLOT(chooseWatchonly(int)));
188 connect(amountWidget, SIGNAL(textChanged(QString)), amount_typing_delay, SLOT(start()));
189 connect(amount_typing_delay, SIGNAL(timeout()), this, SLOT(changedAmount()));
190 connect(addressWidget, SIGNAL(textChanged(QString)), prefix_typing_delay, SLOT(start()));
191 connect(prefix_typing_delay, SIGNAL(timeout()), this, SLOT(changedPrefix()));
193 connect(view, SIGNAL(doubleClicked(QModelIndex)), this, SIGNAL(doubleClicked(QModelIndex)));
194 connect(view, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint)));
196 connect(bumpFeeAction, SIGNAL(triggered()), this, SLOT(bumpFee()));
197 connect(abandonAction, SIGNAL(triggered()), this, SLOT(abandonTx()));
198 connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(copyAddress()));
199 connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel()));
200 connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount()));
201 connect(copyTxIDAction, SIGNAL(triggered()), this, SLOT(copyTxID()));
202 connect(copyTxHexAction, SIGNAL(triggered()), this, SLOT(copyTxHex()));
203 connect(copyTxPlainText, SIGNAL(triggered()), this, SLOT(copyTxPlainText()));
204 connect(editLabelAction, SIGNAL(triggered()), this, SLOT(editLabel()));
205 connect(showDetailsAction, SIGNAL(triggered()), this, SLOT(showDetails()));
208 void TransactionView::setModel(WalletModel *_model)
210 this->model = _model;
211 if(_model)
213 transactionProxyModel = new TransactionFilterProxy(this);
214 transactionProxyModel->setSourceModel(_model->getTransactionTableModel());
215 transactionProxyModel->setDynamicSortFilter(true);
216 transactionProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
217 transactionProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
219 transactionProxyModel->setSortRole(Qt::EditRole);
221 transactionView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
222 transactionView->setModel(transactionProxyModel);
223 transactionView->setAlternatingRowColors(true);
224 transactionView->setSelectionBehavior(QAbstractItemView::SelectRows);
225 transactionView->setSelectionMode(QAbstractItemView::ExtendedSelection);
226 transactionView->setSortingEnabled(true);
227 transactionView->sortByColumn(TransactionTableModel::Date, Qt::DescendingOrder);
228 transactionView->verticalHeader()->hide();
230 transactionView->setColumnWidth(TransactionTableModel::Status, STATUS_COLUMN_WIDTH);
231 transactionView->setColumnWidth(TransactionTableModel::Watchonly, WATCHONLY_COLUMN_WIDTH);
232 transactionView->setColumnWidth(TransactionTableModel::Date, DATE_COLUMN_WIDTH);
233 transactionView->setColumnWidth(TransactionTableModel::Type, TYPE_COLUMN_WIDTH);
234 transactionView->setColumnWidth(TransactionTableModel::Amount, AMOUNT_MINIMUM_COLUMN_WIDTH);
236 columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(transactionView, AMOUNT_MINIMUM_COLUMN_WIDTH, MINIMUM_COLUMN_WIDTH, this);
238 if (_model->getOptionsModel())
240 // Add third party transaction URLs to context menu
241 QStringList listUrls = _model->getOptionsModel()->getThirdPartyTxUrls().split("|", QString::SkipEmptyParts);
242 for (int i = 0; i < listUrls.size(); ++i)
244 QString host = QUrl(listUrls[i].trimmed(), QUrl::StrictMode).host();
245 if (!host.isEmpty())
247 QAction *thirdPartyTxUrlAction = new QAction(host, this); // use host as menu item label
248 if (i == 0)
249 contextMenu->addSeparator();
250 contextMenu->addAction(thirdPartyTxUrlAction);
251 connect(thirdPartyTxUrlAction, SIGNAL(triggered()), mapperThirdPartyTxUrls, SLOT(map()));
252 mapperThirdPartyTxUrls->setMapping(thirdPartyTxUrlAction, listUrls[i].trimmed());
257 // show/hide column Watch-only
258 updateWatchOnlyColumn(_model->haveWatchOnly());
260 // Watch-only signal
261 connect(_model, SIGNAL(notifyWatchonlyChanged(bool)), this, SLOT(updateWatchOnlyColumn(bool)));
265 void TransactionView::chooseDate(int idx)
267 if(!transactionProxyModel)
268 return;
269 QDate current = QDate::currentDate();
270 dateRangeWidget->setVisible(false);
271 switch(dateWidget->itemData(idx).toInt())
273 case All:
274 transactionProxyModel->setDateRange(
275 TransactionFilterProxy::MIN_DATE,
276 TransactionFilterProxy::MAX_DATE);
277 break;
278 case Today:
279 transactionProxyModel->setDateRange(
280 QDateTime(current),
281 TransactionFilterProxy::MAX_DATE);
282 break;
283 case ThisWeek: {
284 // Find last Monday
285 QDate startOfWeek = current.addDays(-(current.dayOfWeek()-1));
286 transactionProxyModel->setDateRange(
287 QDateTime(startOfWeek),
288 TransactionFilterProxy::MAX_DATE);
290 } break;
291 case ThisMonth:
292 transactionProxyModel->setDateRange(
293 QDateTime(QDate(current.year(), current.month(), 1)),
294 TransactionFilterProxy::MAX_DATE);
295 break;
296 case LastMonth:
297 transactionProxyModel->setDateRange(
298 QDateTime(QDate(current.year(), current.month(), 1).addMonths(-1)),
299 QDateTime(QDate(current.year(), current.month(), 1)));
300 break;
301 case ThisYear:
302 transactionProxyModel->setDateRange(
303 QDateTime(QDate(current.year(), 1, 1)),
304 TransactionFilterProxy::MAX_DATE);
305 break;
306 case Range:
307 dateRangeWidget->setVisible(true);
308 dateRangeChanged();
309 break;
313 void TransactionView::chooseType(int idx)
315 if(!transactionProxyModel)
316 return;
317 transactionProxyModel->setTypeFilter(
318 typeWidget->itemData(idx).toInt());
321 void TransactionView::chooseWatchonly(int idx)
323 if(!transactionProxyModel)
324 return;
325 transactionProxyModel->setWatchOnlyFilter(
326 (TransactionFilterProxy::WatchOnlyFilter)watchOnlyWidget->itemData(idx).toInt());
329 void TransactionView::changedPrefix()
331 if(!transactionProxyModel)
332 return;
333 transactionProxyModel->setAddressPrefix(addressWidget->text());
336 void TransactionView::changedAmount()
338 if(!transactionProxyModel)
339 return;
340 CAmount amount_parsed = 0;
341 if (BitcoinUnits::parse(model->getOptionsModel()->getDisplayUnit(), amountWidget->text(), &amount_parsed)) {
342 transactionProxyModel->setMinAmount(amount_parsed);
344 else
346 transactionProxyModel->setMinAmount(0);
350 void TransactionView::exportClicked()
352 if (!model || !model->getOptionsModel()) {
353 return;
356 // CSV is currently the only supported format
357 QString filename = GUIUtil::getSaveFileName(this,
358 tr("Export Transaction History"), QString(),
359 tr("Comma separated file (*.csv)"), nullptr);
361 if (filename.isNull())
362 return;
364 CSVModelWriter writer(filename);
366 // name, column, role
367 writer.setModel(transactionProxyModel);
368 writer.addColumn(tr("Confirmed"), 0, TransactionTableModel::ConfirmedRole);
369 if (model && model->haveWatchOnly())
370 writer.addColumn(tr("Watch-only"), TransactionTableModel::Watchonly);
371 writer.addColumn(tr("Date"), 0, TransactionTableModel::DateRole);
372 writer.addColumn(tr("Type"), TransactionTableModel::Type, Qt::EditRole);
373 writer.addColumn(tr("Label"), 0, TransactionTableModel::LabelRole);
374 writer.addColumn(tr("Address"), 0, TransactionTableModel::AddressRole);
375 writer.addColumn(BitcoinUnits::getAmountColumnTitle(model->getOptionsModel()->getDisplayUnit()), 0, TransactionTableModel::FormattedAmountRole);
376 writer.addColumn(tr("ID"), 0, TransactionTableModel::TxIDRole);
378 if(!writer.write()) {
379 Q_EMIT message(tr("Exporting Failed"), tr("There was an error trying to save the transaction history to %1.").arg(filename),
380 CClientUIInterface::MSG_ERROR);
382 else {
383 Q_EMIT message(tr("Exporting Successful"), tr("The transaction history was successfully saved to %1.").arg(filename),
384 CClientUIInterface::MSG_INFORMATION);
388 void TransactionView::contextualMenu(const QPoint &point)
390 QModelIndex index = transactionView->indexAt(point);
391 QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
392 if (selection.empty())
393 return;
395 // check if transaction can be abandoned, disable context menu action in case it doesn't
396 uint256 hash;
397 hash.SetHex(selection.at(0).data(TransactionTableModel::TxHashRole).toString().toStdString());
398 abandonAction->setEnabled(model->transactionCanBeAbandoned(hash));
399 bumpFeeAction->setEnabled(model->transactionCanBeBumped(hash));
401 if(index.isValid())
403 contextMenu->popup(transactionView->viewport()->mapToGlobal(point));
407 void TransactionView::abandonTx()
409 if(!transactionView || !transactionView->selectionModel())
410 return;
411 QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
413 // get the hash from the TxHashRole (QVariant / QString)
414 uint256 hash;
415 QString hashQStr = selection.at(0).data(TransactionTableModel::TxHashRole).toString();
416 hash.SetHex(hashQStr.toStdString());
418 // Abandon the wallet transaction over the walletModel
419 model->abandonTransaction(hash);
421 // Update the table
422 model->getTransactionTableModel()->updateTransaction(hashQStr, CT_UPDATED, false);
425 void TransactionView::bumpFee()
427 if(!transactionView || !transactionView->selectionModel())
428 return;
429 QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
431 // get the hash from the TxHashRole (QVariant / QString)
432 uint256 hash;
433 QString hashQStr = selection.at(0).data(TransactionTableModel::TxHashRole).toString();
434 hash.SetHex(hashQStr.toStdString());
436 // Bump tx fee over the walletModel
437 if (model->bumpFee(hash)) {
438 // Update the table
439 model->getTransactionTableModel()->updateTransaction(hashQStr, CT_UPDATED, true);
443 void TransactionView::copyAddress()
445 GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::AddressRole);
448 void TransactionView::copyLabel()
450 GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::LabelRole);
453 void TransactionView::copyAmount()
455 GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::FormattedAmountRole);
458 void TransactionView::copyTxID()
460 GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxIDRole);
463 void TransactionView::copyTxHex()
465 GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxHexRole);
468 void TransactionView::copyTxPlainText()
470 GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxPlainTextRole);
473 void TransactionView::editLabel()
475 if(!transactionView->selectionModel() ||!model)
476 return;
477 QModelIndexList selection = transactionView->selectionModel()->selectedRows();
478 if(!selection.isEmpty())
480 AddressTableModel *addressBook = model->getAddressTableModel();
481 if(!addressBook)
482 return;
483 QString address = selection.at(0).data(TransactionTableModel::AddressRole).toString();
484 if(address.isEmpty())
486 // If this transaction has no associated address, exit
487 return;
489 // Is address in address book? Address book can miss address when a transaction is
490 // sent from outside the UI.
491 int idx = addressBook->lookupAddress(address);
492 if(idx != -1)
494 // Edit sending / receiving address
495 QModelIndex modelIdx = addressBook->index(idx, 0, QModelIndex());
496 // Determine type of address, launch appropriate editor dialog type
497 QString type = modelIdx.data(AddressTableModel::TypeRole).toString();
499 EditAddressDialog dlg(
500 type == AddressTableModel::Receive
501 ? EditAddressDialog::EditReceivingAddress
502 : EditAddressDialog::EditSendingAddress, this);
503 dlg.setModel(addressBook);
504 dlg.loadRow(idx);
505 dlg.exec();
507 else
509 // Add sending address
510 EditAddressDialog dlg(EditAddressDialog::NewSendingAddress,
511 this);
512 dlg.setModel(addressBook);
513 dlg.setAddress(address);
514 dlg.exec();
519 void TransactionView::showDetails()
521 if(!transactionView->selectionModel())
522 return;
523 QModelIndexList selection = transactionView->selectionModel()->selectedRows();
524 if(!selection.isEmpty())
526 TransactionDescDialog *dlg = new TransactionDescDialog(selection.at(0));
527 dlg->setAttribute(Qt::WA_DeleteOnClose);
528 dlg->show();
532 void TransactionView::openThirdPartyTxUrl(QString url)
534 if(!transactionView || !transactionView->selectionModel())
535 return;
536 QModelIndexList selection = transactionView->selectionModel()->selectedRows(0);
537 if(!selection.isEmpty())
538 QDesktopServices::openUrl(QUrl::fromUserInput(url.replace("%s", selection.at(0).data(TransactionTableModel::TxHashRole).toString())));
541 QWidget *TransactionView::createDateRangeWidget()
543 dateRangeWidget = new QFrame();
544 dateRangeWidget->setFrameStyle(QFrame::Panel | QFrame::Raised);
545 dateRangeWidget->setContentsMargins(1,1,1,1);
546 QHBoxLayout *layout = new QHBoxLayout(dateRangeWidget);
547 layout->setContentsMargins(0,0,0,0);
548 layout->addSpacing(23);
549 layout->addWidget(new QLabel(tr("Range:")));
551 dateFrom = new QDateTimeEdit(this);
552 dateFrom->setDisplayFormat("dd/MM/yy");
553 dateFrom->setCalendarPopup(true);
554 dateFrom->setMinimumWidth(100);
555 dateFrom->setDate(QDate::currentDate().addDays(-7));
556 layout->addWidget(dateFrom);
557 layout->addWidget(new QLabel(tr("to")));
559 dateTo = new QDateTimeEdit(this);
560 dateTo->setDisplayFormat("dd/MM/yy");
561 dateTo->setCalendarPopup(true);
562 dateTo->setMinimumWidth(100);
563 dateTo->setDate(QDate::currentDate());
564 layout->addWidget(dateTo);
565 layout->addStretch();
567 // Hide by default
568 dateRangeWidget->setVisible(false);
570 // Notify on change
571 connect(dateFrom, SIGNAL(dateChanged(QDate)), this, SLOT(dateRangeChanged()));
572 connect(dateTo, SIGNAL(dateChanged(QDate)), this, SLOT(dateRangeChanged()));
574 return dateRangeWidget;
577 void TransactionView::dateRangeChanged()
579 if(!transactionProxyModel)
580 return;
581 transactionProxyModel->setDateRange(
582 QDateTime(dateFrom->date()),
583 QDateTime(dateTo->date()).addDays(1));
586 void TransactionView::focusTransaction(const QModelIndex &idx)
588 if(!transactionProxyModel)
589 return;
590 QModelIndex targetIdx = transactionProxyModel->mapFromSource(idx);
591 transactionView->scrollTo(targetIdx);
592 transactionView->setCurrentIndex(targetIdx);
593 transactionView->setFocus();
596 // We override the virtual resizeEvent of the QWidget to adjust tables column
597 // sizes as the tables width is proportional to the dialogs width.
598 void TransactionView::resizeEvent(QResizeEvent* event)
600 QWidget::resizeEvent(event);
601 columnResizingFixer->stretchColumnWidth(TransactionTableModel::ToAddress);
604 // Need to override default Ctrl+C action for amount as default behaviour is just to copy DisplayRole text
605 bool TransactionView::eventFilter(QObject *obj, QEvent *event)
607 if (event->type() == QEvent::KeyPress)
609 QKeyEvent *ke = static_cast<QKeyEvent *>(event);
610 if (ke->key() == Qt::Key_C && ke->modifiers().testFlag(Qt::ControlModifier))
612 GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxPlainTextRole);
613 return true;
616 return QWidget::eventFilter(obj, event);
619 // show/hide column Watch-only
620 void TransactionView::updateWatchOnlyColumn(bool fHaveWatchOnly)
622 watchOnlyWidget->setVisible(fHaveWatchOnly);
623 transactionView->setColumnHidden(TransactionTableModel::Watchonly, !fHaveWatchOnly);