Fabcoin Core  0.16.2
P2P Digital Currency
addressbookpage.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2017 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 #if defined(HAVE_CONFIG_H)
7 #endif
8 
9 #include <addressbookpage.h>
10 #include <ui_addressbookpage.h>
11 
12 #include <addresstablemodel.h>
13 #include <fabcoingui.h>
14 #include <csvmodelwriter.h>
15 #include <editaddressdialog.h>
16 #include <guiutil.h>
17 #include <platformstyle.h>
18 #include <styleSheet.h>
19 
20 #include <QIcon>
21 #include <QMenu>
22 #include <QMessageBox>
23 #include <QSortFilterProxyModel>
24 
25 AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode _mode, Tabs _tab, QWidget *parent) :
26  QDialog(parent),
27  ui(new Ui::AddressBookPage),
28  model(0),
29  mode(_mode),
30  tab(_tab)
31 {
32  ui->setupUi(this);
33 
34  SetObjectStyleSheet(ui->tableView, StyleSheetNames::TableViewLight);
35  setStyleSheet("");
36 
37  if (!platformStyle->getImagesOnButtons()) {
38  ui->newAddress->setIcon(QIcon());
39  ui->copyAddress->setIcon(QIcon());
40  ui->deleteAddress->setIcon(QIcon());
41  ui->exportButton->setIcon(QIcon());
42  } else {
43  ui->newAddress->setIcon(platformStyle->MultiStatesIcon(":/icons/add", PlatformStyle::PushButton, 0x5a5a5d));
44  ui->copyAddress->setIcon(platformStyle->MultiStatesIcon(":/icons/editcopy", PlatformStyle::PushButton, 0x5a5a5d));
45  ui->deleteAddress->setIcon(platformStyle->MultiStatesIcon(":/icons/remove", PlatformStyle::PushButton, 0x5a5a5d));
46  ui->exportButton->setIcon(platformStyle->MultiStatesIcon(":/icons/export", PlatformStyle::PushButton));
47  }
48 
49  SetObjectStyleSheet(ui->newAddress, StyleSheetNames::ButtonWhite);
50  SetObjectStyleSheet(ui->copyAddress, StyleSheetNames::ButtonWhite);
51  SetObjectStyleSheet(ui->deleteAddress, StyleSheetNames::ButtonWhite);
52  SetObjectStyleSheet(ui->exportButton, StyleSheetNames::ButtonBlue);
53  SetObjectStyleSheet(ui->closeButton, StyleSheetNames::ButtonBlue);
54 
55  switch(mode)
56  {
57  case ForSelection:
58  switch(tab)
59  {
60  case SendingTab: setWindowTitle(tr("Choose the address to send coins to")); break;
61  case ReceivingTab: setWindowTitle(tr("Choose the address to receive coins with")); break;
62  }
63  connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept()));
64  ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
65  ui->tableView->setFocus();
66  ui->closeButton->setText(tr("C&hoose"));
67  ui->exportButton->hide();
68  break;
69  case ForEditing:
70  switch(tab)
71  {
72  case SendingTab: setWindowTitle(tr("Sending addresses")); break;
73  case ReceivingTab: setWindowTitle(tr("Receiving addresses")); break;
74  }
75  break;
76  }
77  switch(tab)
78  {
79  case SendingTab:
80  ui->labelExplanation->setText(tr("These are your Fabcoin addresses for sending payments. Always check the amount and the receiving address before sending coins."));
81  ui->deleteAddress->setVisible(true);
82  break;
83  case ReceivingTab:
84  ui->labelExplanation->setText(tr("These are your Fabcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction."));
85  ui->deleteAddress->setVisible(false);
86  break;
87  }
88 
89  // Context menu actions
90  QAction *copyAddressAction = new QAction(tr("&Copy Address"), this);
91  QAction *copyLabelAction = new QAction(tr("Copy &Label"), this);
92  QAction *editAction = new QAction(tr("&Edit"), this);
93  deleteAction = new QAction(ui->deleteAddress->text(), this);
94 
95  // Build context menu
96  contextMenu = new QMenu(this);
97  contextMenu->addAction(copyAddressAction);
98  contextMenu->addAction(copyLabelAction);
99  contextMenu->addAction(editAction);
100  if(tab == SendingTab)
101  contextMenu->addAction(deleteAction);
102  contextMenu->addSeparator();
103 
104  // Connect signals for context menu actions
105  connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(on_copyAddress_clicked()));
106  connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(onCopyLabelAction()));
107  connect(editAction, SIGNAL(triggered()), this, SLOT(onEditAction()));
108  connect(deleteAction, SIGNAL(triggered()), this, SLOT(on_deleteAddress_clicked()));
109 
110  connect(ui->tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint)));
111 
112  connect(ui->closeButton, SIGNAL(clicked()), this, SLOT(accept()));
113 }
114 
116 {
117  delete ui;
118 }
119 
121 {
122  this->model = _model;
123  if(!_model)
124  return;
125 
126  proxyModel = new QSortFilterProxyModel(this);
127  proxyModel->setSourceModel(_model);
128  proxyModel->setDynamicSortFilter(true);
129  proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
130  proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
131  switch(tab)
132  {
133  case ReceivingTab:
134  // Receive filter
135  proxyModel->setFilterRole(AddressTableModel::TypeRole);
136  proxyModel->setFilterFixedString(AddressTableModel::Receive);
137  break;
138  case SendingTab:
139  // Send filter
140  proxyModel->setFilterRole(AddressTableModel::TypeRole);
141  proxyModel->setFilterFixedString(AddressTableModel::Send);
142  break;
143  }
144  ui->tableView->setModel(proxyModel);
145  ui->tableView->sortByColumn(0, Qt::AscendingOrder);
146 
147  // Set column widths
148 #if QT_VERSION < 0x050000
149  ui->tableView->horizontalHeader()->setResizeMode(AddressTableModel::Label, QHeaderView::Stretch);
150  ui->tableView->horizontalHeader()->setResizeMode(AddressTableModel::Address, QHeaderView::ResizeToContents);
151 #else
152  ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Label, QHeaderView::Stretch);
153  ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Address, QHeaderView::ResizeToContents);
154 #endif
155 
156  connect(ui->tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
157  this, SLOT(selectionChanged()));
158 
159  // Select row for newly created address
160  connect(_model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(selectNewAddress(QModelIndex,int,int)));
161 
163 }
164 
166 {
168 }
169 
171 {
173 }
174 
176 {
177  if(!model)
178  return;
179 
180  if(!ui->tableView->selectionModel())
181  return;
182  QModelIndexList indexes = ui->tableView->selectionModel()->selectedRows();
183  if(indexes.isEmpty())
184  return;
185 
186  EditAddressDialog dlg(
187  tab == SendingTab ?
190  dlg.setModel(model);
191  QModelIndex origIndex = proxyModel->mapToSource(indexes.at(0));
192  dlg.loadRow(origIndex.row());
193  dlg.exec();
194 }
195 
197 {
198  if(!model)
199  return;
200 
201  EditAddressDialog dlg(
202  tab == SendingTab ?
205  dlg.setModel(model);
206  if(dlg.exec())
207  {
209  }
210 }
211 
213 {
214  QTableView *table = ui->tableView;
215  if(!table->selectionModel())
216  return;
217 
218  QModelIndexList indexes = table->selectionModel()->selectedRows();
219  if(!indexes.isEmpty())
220  {
221  table->model()->removeRow(indexes.at(0).row());
222  }
223 }
224 
226 {
227  // Set button states based on selected tab and selection
228  QTableView *table = ui->tableView;
229  if(!table->selectionModel())
230  return;
231 
232  if(table->selectionModel()->hasSelection())
233  {
234  switch(tab)
235  {
236  case SendingTab:
237  // In sending tab, allow deletion of selection
238  ui->deleteAddress->setEnabled(true);
239  ui->deleteAddress->setVisible(true);
240  deleteAction->setEnabled(true);
241  break;
242  case ReceivingTab:
243  // Deleting receiving addresses, however, is not allowed
244  ui->deleteAddress->setEnabled(false);
245  ui->deleteAddress->setVisible(false);
246  deleteAction->setEnabled(false);
247  break;
248  }
249  ui->copyAddress->setEnabled(true);
250  }
251  else
252  {
253  ui->deleteAddress->setEnabled(false);
254  ui->copyAddress->setEnabled(false);
255  }
256 }
257 
258 void AddressBookPage::done(int retval)
259 {
260  QTableView *table = ui->tableView;
261  if(!table->selectionModel() || !table->model())
262  return;
263 
264  // Figure out which address was selected, and return it
265  QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
266 
267  for (const QModelIndex& index : indexes) {
268  QVariant address = table->model()->data(index);
269  returnValue = address.toString();
270  }
271 
272  if(returnValue.isEmpty())
273  {
274  // If no address entry selected, return rejected
275  retval = Rejected;
276  }
277 
278  QDialog::done(retval);
279 }
280 
282 {
283  // CSV is currently the only supported format
284  QString filename = GUIUtil::getSaveFileName(this,
285  tr("Export Address List"), QString(),
286  tr("Comma separated file (*.csv)"), nullptr);
287 
288  if (filename.isNull())
289  return;
290 
291  CSVModelWriter writer(filename);
292 
293  // name, column, role
294  writer.setModel(proxyModel);
295  writer.addColumn("Label", AddressTableModel::Label, Qt::EditRole);
296  writer.addColumn("Address", AddressTableModel::Address, Qt::EditRole);
297 
298  if(!writer.write()) {
299  QMessageBox::critical(this, tr("Exporting Failed"),
300  tr("There was an error trying to save the address list to %1. Please try again.").arg(filename));
301  }
302 }
303 
304 void AddressBookPage::contextualMenu(const QPoint &point)
305 {
306  QModelIndex index = ui->tableView->indexAt(point);
307  if(index.isValid())
308  {
309  contextMenu->exec(QCursor::pos());
310  }
311 }
312 
313 void AddressBookPage::selectNewAddress(const QModelIndex &parent, int begin, int /*end*/)
314 {
315  QModelIndex idx = proxyModel->mapFromSource(model->index(begin, AddressTableModel::Address, parent));
316  if(idx.isValid() && (idx.data(Qt::EditRole).toString() == newAddressToSelect))
317  {
318  // Select row of newly created address, once
319  ui->tableView->setFocus();
320  ui->tableView->selectRow(idx.row());
321  newAddressToSelect.clear();
322  }
323 }
void on_newAddress_clicked()
Create a new address for receiving coins and / or add a new address book entry.
void onCopyLabelAction()
Copy label of currently selected address entry to clipboard (no button)
void addColumn(const QString &title, int column, int role=Qt::EditRole)
QModelIndex index(int row, int column, const QModelIndex &parent) const
QString getAddress() const
#define SetObjectStyleSheet(object, name)
Definition: styleSheet.h:10
void setModel(AddressTableModel *model)
QPushButton * newAddress
void onEditAction()
Edit currently selected address entry (no button)
AddressTableModel * model
QPushButton * copyAddress
evm_mode mode
Definition: SmartVM.cpp:47
AddressBookPage(const PlatformStyle *platformStyle, Mode mode, Tabs tab, QWidget *parent)
QSortFilterProxyModel * proxyModel
void on_exportButton_clicked()
Export button clicked.
Open address book for editing.
Open address book to pick address.
Export a Qt table model to a CSV file.
QString newAddressToSelect
Ui::AddressBookPage * ui
static const QString Send
Specifies send address.
void selectNewAddress(const QModelIndex &parent, int begin, int)
New entry/entries were added to address table.
QAction * deleteAction
QPushButton * closeButton
void setModel(AddressTableModel *model)
void done(int retval)
void setupUi(QWidget *AddressBookPage)
QPushButton * deleteAddress
void on_copyAddress_clicked()
Copy address of currently selected address entry to clipboard.
Widget that shows a list of sending or receiving addresses.
Qt model of the address book in the core.
void selectionChanged()
Set button states based on selected tab and selection.
QPushButton * exportButton
void setModel(const QAbstractItemModel *model)
QIcon MultiStatesIcon(const QString &resourcename, StateType type=NavBar, QColor color=Qt::white, QColor colorAlt=0x2d2d2d) const
Get multi-states icon.
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedSuffixOut)
Get save filename, mimics QFileDialog::getSaveFileName, except that it appends a default suffix when ...
Definition: guiutil.cpp:309
static const QString Receive
Specifies receive address.
Dialog for editing an address and associated information.
bool getImagesOnButtons() const
Definition: platformstyle.h:21
struct evm_uint160be address(struct evm_env *env)
Definition: capi.c:13
User specified label.
void copyEntryData(QAbstractItemView *view, int column, int role)
Copy a field of the currently selected entry of a view to the clipboard.
Definition: guiutil.cpp:277
void contextualMenu(const QPoint &point)
Spawn contextual menu (right mouse menu) for address book entry.
void on_deleteAddress_clicked()
Delete currently selected address entry.
bool write()
Perform export of the model to CSV.
Type of address (Send or Receive)