Merge #11683: tests: Remove unused mininode functions {ser,deser}_int_vector(......
[bitcoinplatinum.git] / src / qt / addressbookpage.cpp
blobdda8dce391bec90afa4d5121495cad8c59ddbf6b
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 #if defined(HAVE_CONFIG_H)
6 #include <config/bitcoin-config.h>
7 #endif
9 #include <qt/addressbookpage.h>
10 #include <qt/forms/ui_addressbookpage.h>
12 #include <qt/addresstablemodel.h>
13 #include <qt/bitcoingui.h>
14 #include <qt/csvmodelwriter.h>
15 #include <qt/editaddressdialog.h>
16 #include <qt/guiutil.h>
17 #include <qt/platformstyle.h>
19 #include <QIcon>
20 #include <QMenu>
21 #include <QMessageBox>
22 #include <QSortFilterProxyModel>
24 AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode _mode, Tabs _tab, QWidget *parent) :
25 QDialog(parent),
26 ui(new Ui::AddressBookPage),
27 model(0),
28 mode(_mode),
29 tab(_tab)
31 ui->setupUi(this);
33 if (!platformStyle->getImagesOnButtons()) {
34 ui->newAddress->setIcon(QIcon());
35 ui->copyAddress->setIcon(QIcon());
36 ui->deleteAddress->setIcon(QIcon());
37 ui->exportButton->setIcon(QIcon());
38 } else {
39 ui->newAddress->setIcon(platformStyle->SingleColorIcon(":/icons/add"));
40 ui->copyAddress->setIcon(platformStyle->SingleColorIcon(":/icons/editcopy"));
41 ui->deleteAddress->setIcon(platformStyle->SingleColorIcon(":/icons/remove"));
42 ui->exportButton->setIcon(platformStyle->SingleColorIcon(":/icons/export"));
45 switch(mode)
47 case ForSelection:
48 switch(tab)
50 case SendingTab: setWindowTitle(tr("Choose the address to send coins to")); break;
51 case ReceivingTab: setWindowTitle(tr("Choose the address to receive coins with")); break;
53 connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept()));
54 ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
55 ui->tableView->setFocus();
56 ui->closeButton->setText(tr("C&hoose"));
57 ui->exportButton->hide();
58 break;
59 case ForEditing:
60 switch(tab)
62 case SendingTab: setWindowTitle(tr("Sending addresses")); break;
63 case ReceivingTab: setWindowTitle(tr("Receiving addresses")); break;
65 break;
67 switch(tab)
69 case SendingTab:
70 ui->labelExplanation->setText(tr("These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins."));
71 ui->deleteAddress->setVisible(true);
72 break;
73 case ReceivingTab:
74 ui->labelExplanation->setText(tr("These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction."));
75 ui->deleteAddress->setVisible(false);
76 break;
79 // Context menu actions
80 QAction *copyAddressAction = new QAction(tr("&Copy Address"), this);
81 QAction *copyLabelAction = new QAction(tr("Copy &Label"), this);
82 QAction *editAction = new QAction(tr("&Edit"), this);
83 deleteAction = new QAction(ui->deleteAddress->text(), this);
85 // Build context menu
86 contextMenu = new QMenu(this);
87 contextMenu->addAction(copyAddressAction);
88 contextMenu->addAction(copyLabelAction);
89 contextMenu->addAction(editAction);
90 if(tab == SendingTab)
91 contextMenu->addAction(deleteAction);
92 contextMenu->addSeparator();
94 // Connect signals for context menu actions
95 connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(on_copyAddress_clicked()));
96 connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(onCopyLabelAction()));
97 connect(editAction, SIGNAL(triggered()), this, SLOT(onEditAction()));
98 connect(deleteAction, SIGNAL(triggered()), this, SLOT(on_deleteAddress_clicked()));
100 connect(ui->tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint)));
102 connect(ui->closeButton, SIGNAL(clicked()), this, SLOT(accept()));
105 AddressBookPage::~AddressBookPage()
107 delete ui;
110 void AddressBookPage::setModel(AddressTableModel *_model)
112 this->model = _model;
113 if(!_model)
114 return;
116 proxyModel = new QSortFilterProxyModel(this);
117 proxyModel->setSourceModel(_model);
118 proxyModel->setDynamicSortFilter(true);
119 proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
120 proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
121 switch(tab)
123 case ReceivingTab:
124 // Receive filter
125 proxyModel->setFilterRole(AddressTableModel::TypeRole);
126 proxyModel->setFilterFixedString(AddressTableModel::Receive);
127 break;
128 case SendingTab:
129 // Send filter
130 proxyModel->setFilterRole(AddressTableModel::TypeRole);
131 proxyModel->setFilterFixedString(AddressTableModel::Send);
132 break;
134 ui->tableView->setModel(proxyModel);
135 ui->tableView->sortByColumn(0, Qt::AscendingOrder);
137 // Set column widths
138 #if QT_VERSION < 0x050000
139 ui->tableView->horizontalHeader()->setResizeMode(AddressTableModel::Label, QHeaderView::Stretch);
140 ui->tableView->horizontalHeader()->setResizeMode(AddressTableModel::Address, QHeaderView::ResizeToContents);
141 #else
142 ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Label, QHeaderView::Stretch);
143 ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Address, QHeaderView::ResizeToContents);
144 #endif
146 connect(ui->tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
147 this, SLOT(selectionChanged()));
149 // Select row for newly created address
150 connect(_model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(selectNewAddress(QModelIndex,int,int)));
152 selectionChanged();
155 void AddressBookPage::on_copyAddress_clicked()
157 GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Address);
160 void AddressBookPage::onCopyLabelAction()
162 GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Label);
165 void AddressBookPage::onEditAction()
167 if(!model)
168 return;
170 if(!ui->tableView->selectionModel())
171 return;
172 QModelIndexList indexes = ui->tableView->selectionModel()->selectedRows();
173 if(indexes.isEmpty())
174 return;
176 EditAddressDialog dlg(
177 tab == SendingTab ?
178 EditAddressDialog::EditSendingAddress :
179 EditAddressDialog::EditReceivingAddress, this);
180 dlg.setModel(model);
181 QModelIndex origIndex = proxyModel->mapToSource(indexes.at(0));
182 dlg.loadRow(origIndex.row());
183 dlg.exec();
186 void AddressBookPage::on_newAddress_clicked()
188 if(!model)
189 return;
191 EditAddressDialog dlg(
192 tab == SendingTab ?
193 EditAddressDialog::NewSendingAddress :
194 EditAddressDialog::NewReceivingAddress, this);
195 dlg.setModel(model);
196 if(dlg.exec())
198 newAddressToSelect = dlg.getAddress();
202 void AddressBookPage::on_deleteAddress_clicked()
204 QTableView *table = ui->tableView;
205 if(!table->selectionModel())
206 return;
208 QModelIndexList indexes = table->selectionModel()->selectedRows();
209 if(!indexes.isEmpty())
211 table->model()->removeRow(indexes.at(0).row());
215 void AddressBookPage::selectionChanged()
217 // Set button states based on selected tab and selection
218 QTableView *table = ui->tableView;
219 if(!table->selectionModel())
220 return;
222 if(table->selectionModel()->hasSelection())
224 switch(tab)
226 case SendingTab:
227 // In sending tab, allow deletion of selection
228 ui->deleteAddress->setEnabled(true);
229 ui->deleteAddress->setVisible(true);
230 deleteAction->setEnabled(true);
231 break;
232 case ReceivingTab:
233 // Deleting receiving addresses, however, is not allowed
234 ui->deleteAddress->setEnabled(false);
235 ui->deleteAddress->setVisible(false);
236 deleteAction->setEnabled(false);
237 break;
239 ui->copyAddress->setEnabled(true);
241 else
243 ui->deleteAddress->setEnabled(false);
244 ui->copyAddress->setEnabled(false);
248 void AddressBookPage::done(int retval)
250 QTableView *table = ui->tableView;
251 if(!table->selectionModel() || !table->model())
252 return;
254 // Figure out which address was selected, and return it
255 QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
257 for (const QModelIndex& index : indexes) {
258 QVariant address = table->model()->data(index);
259 returnValue = address.toString();
262 if(returnValue.isEmpty())
264 // If no address entry selected, return rejected
265 retval = Rejected;
268 QDialog::done(retval);
271 void AddressBookPage::on_exportButton_clicked()
273 // CSV is currently the only supported format
274 QString filename = GUIUtil::getSaveFileName(this,
275 tr("Export Address List"), QString(),
276 tr("Comma separated file (*.csv)"), nullptr);
278 if (filename.isNull())
279 return;
281 CSVModelWriter writer(filename);
283 // name, column, role
284 writer.setModel(proxyModel);
285 writer.addColumn("Label", AddressTableModel::Label, Qt::EditRole);
286 writer.addColumn("Address", AddressTableModel::Address, Qt::EditRole);
288 if(!writer.write()) {
289 QMessageBox::critical(this, tr("Exporting Failed"),
290 tr("There was an error trying to save the address list to %1. Please try again.").arg(filename));
294 void AddressBookPage::contextualMenu(const QPoint &point)
296 QModelIndex index = ui->tableView->indexAt(point);
297 if(index.isValid())
299 contextMenu->exec(QCursor::pos());
303 void AddressBookPage::selectNewAddress(const QModelIndex &parent, int begin, int /*end*/)
305 QModelIndex idx = proxyModel->mapFromSource(model->index(begin, AddressTableModel::Address, parent));
306 if(idx.isValid() && (idx.data(Qt::EditRole).toString() == newAddressToSelect))
308 // Select row of newly created address, once
309 ui->tableView->setFocus();
310 ui->tableView->selectRow(idx.row());
311 newAddressToSelect.clear();