Anoncoin  0.9.4
P2P Digital Currency
addressbookpage.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2013 The Bitcoin developers
2 // Copyright (c) 2013-2014 The Anoncoin Core developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #if defined(HAVE_CONFIG_H)
8 #endif
9 
10 #include "addressbookpage.h"
11 #include "ui_addressbookpage.h"
12 
13 #include "addresstablemodel.h"
14 #include "anoncoingui.h"
15 #include "csvmodelwriter.h"
16 #include "editaddressdialog.h"
17 #include "guiutil.h"
18 
19 #include <QIcon>
20 #include <QMenu>
21 #include <QMessageBox>
22 #include <QSortFilterProxyModel>
23 
24 AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
25  QDialog(parent),
26  ui(new Ui::AddressBookPage),
27  model(0),
28  mode(mode),
29  tab(tab)
30 {
31  ui->setupUi(this);
32 
33 #ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
34  ui->newAddress->setIcon(QIcon());
35  ui->copyAddress->setIcon(QIcon());
36  ui->deleteAddress->setIcon(QIcon());
37  ui->exportButton->setIcon(QIcon());
38 #endif
39 
40  switch(mode)
41  {
42  case ForSelection:
43  switch(tab)
44  {
45  case SendingTab: setWindowTitle(tr("Choose the address to send coins to")); break;
46  case ReceivingTab: setWindowTitle(tr("Choose the address to receive coins with")); break;
47  }
48  connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept()));
49  ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
50  ui->tableView->setFocus();
51  ui->closeButton->setText(tr("C&hoose"));
52  ui->exportButton->hide();
53  break;
54  case ForEditing:
55  switch(tab)
56  {
57  case SendingTab: setWindowTitle(tr("Sending addresses")); break;
58  case ReceivingTab: setWindowTitle(tr("Receiving addresses")); break;
59  }
60  break;
61  }
62  switch(tab)
63  {
64  case SendingTab:
65  ui->labelExplanation->setText(tr("These are your Anoncoin addresses for sending payments. Always check the amount and the receiving address before sending coins."));
66  ui->deleteAddress->setVisible(true);
67  break;
68  case ReceivingTab:
69  ui->labelExplanation->setText(tr("These are your Anoncoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction."));
70  ui->deleteAddress->setVisible(false);
71  break;
72  }
73 
74  // Context menu actions
75  QAction *copyAddressAction = new QAction(tr("&Copy Address"), this);
76  QAction *copyLabelAction = new QAction(tr("Copy &Label"), this);
77  QAction *editAction = new QAction(tr("&Edit"), this);
78  deleteAction = new QAction(ui->deleteAddress->text(), this);
79 
80  // Build context menu
81  contextMenu = new QMenu();
82  contextMenu->addAction(copyAddressAction);
83  contextMenu->addAction(copyLabelAction);
84  contextMenu->addAction(editAction);
85  if(tab == SendingTab)
86  contextMenu->addAction(deleteAction);
87  contextMenu->addSeparator();
88 
89  // Connect signals for context menu actions
90  connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(on_copyAddress_clicked()));
91  connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(onCopyLabelAction()));
92  connect(editAction, SIGNAL(triggered()), this, SLOT(onEditAction()));
93  connect(deleteAction, SIGNAL(triggered()), this, SLOT(on_deleteAddress_clicked()));
94 
95  connect(ui->tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint)));
96 
97  connect(ui->closeButton, SIGNAL(clicked()), this, SLOT(accept()));
98 }
99 
101 {
102  delete ui;
103 }
104 
106 {
107  this->model = model;
108  if(!model)
109  return;
110 
111  proxyModel = new QSortFilterProxyModel(this);
112  proxyModel->setSourceModel(model);
113  proxyModel->setDynamicSortFilter(true);
114  proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
115  proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
116  switch(tab)
117  {
118  case ReceivingTab:
119  // Receive filter
120  proxyModel->setFilterRole(AddressTableModel::TypeRole);
121  proxyModel->setFilterFixedString(AddressTableModel::Receive);
122  break;
123  case SendingTab:
124  // Send filter
125  proxyModel->setFilterRole(AddressTableModel::TypeRole);
126  proxyModel->setFilterFixedString(AddressTableModel::Send);
127  break;
128  }
129  ui->tableView->setModel(proxyModel);
130  ui->tableView->sortByColumn(0, Qt::AscendingOrder);
131 
132  // Set column widths
133 #if QT_VERSION < 0x050000
134  ui->tableView->horizontalHeader()->setResizeMode(AddressTableModel::Label, QHeaderView::Stretch);
135  ui->tableView->horizontalHeader()->setResizeMode(AddressTableModel::Address, QHeaderView::ResizeToContents);
136 #else
137  ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Label, QHeaderView::Stretch);
138  ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Address, QHeaderView::ResizeToContents);
139 #endif
140 
141  connect(ui->tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
142  this, SLOT(selectionChanged()));
143 
144  // Select row for newly created address
145  connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(selectNewAddress(QModelIndex,int,int)));
146 
148 }
149 
151 {
153 }
154 
156 {
158 }
159 
161 {
162  if(!model)
163  return;
164 
165  if(!ui->tableView->selectionModel())
166  return;
167  QModelIndexList indexes = ui->tableView->selectionModel()->selectedRows();
168  if(indexes.isEmpty())
169  return;
170 
171  EditAddressDialog dlg(
172  tab == SendingTab ?
175  dlg.setModel(model);
176  QModelIndex origIndex = proxyModel->mapToSource(indexes.at(0));
177  dlg.loadRow(origIndex.row());
178  dlg.exec();
179 }
180 
182 {
183  if(!model)
184  return;
185 
186  EditAddressDialog dlg(
187  tab == SendingTab ?
190  dlg.setModel(model);
191  if(dlg.exec())
192  {
194  }
195 }
196 
198 {
199  QTableView *table = ui->tableView;
200  if(!table->selectionModel())
201  return;
202 
203  QModelIndexList indexes = table->selectionModel()->selectedRows();
204  if(!indexes.isEmpty())
205  {
206  table->model()->removeRow(indexes.at(0).row());
207  }
208 }
209 
211 {
212  // Set button states based on selected tab and selection
213  QTableView *table = ui->tableView;
214  if(!table->selectionModel())
215  return;
216 
217  if(table->selectionModel()->hasSelection())
218  {
219  switch(tab)
220  {
221  case SendingTab:
222  // In sending tab, allow deletion of selection
223  ui->deleteAddress->setEnabled(true);
224  ui->deleteAddress->setVisible(true);
225  deleteAction->setEnabled(true);
226  break;
227  case ReceivingTab:
228  // Deleting receiving addresses, however, is not allowed
229  ui->deleteAddress->setEnabled(false);
230  ui->deleteAddress->setVisible(false);
231  deleteAction->setEnabled(false);
232  break;
233  }
234  ui->copyAddress->setEnabled(true);
235  }
236  else
237  {
238  ui->deleteAddress->setEnabled(false);
239  ui->copyAddress->setEnabled(false);
240  }
241 }
242 
243 void AddressBookPage::done(int retval)
244 {
245  QTableView *table = ui->tableView;
246  if(!table->selectionModel() || !table->model())
247  return;
248 
249  // Figure out which address was selected, and return it
250  QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
251 
252  foreach (QModelIndex index, indexes)
253  {
254  QVariant address = table->model()->data(index);
255  returnValue = address.toString();
256  }
257 
258  if(returnValue.isEmpty())
259  {
260  // If no address entry selected, return rejected
261  retval = Rejected;
262  }
263 
264  QDialog::done(retval);
265 }
266 
268 {
269  // CSV is currently the only supported format
270  QString filename = GUIUtil::getSaveFileName(this,
271  tr("Export Address List"), QString(),
272  tr("Comma separated file (*.csv)"), NULL);
273 
274  if (filename.isNull())
275  return;
276 
277  CSVModelWriter writer(filename);
278 
279  // name, column, role
280  writer.setModel(proxyModel);
281  writer.addColumn("Label", AddressTableModel::Label, Qt::EditRole);
282  writer.addColumn("Address", AddressTableModel::Address, Qt::EditRole);
283 
284  if(!writer.write()) {
285  QMessageBox::critical(this, tr("Exporting Failed"),
286  tr("There was an error trying to save the address list to %1.").arg(filename));
287  }
288 }
289 
290 void AddressBookPage::contextualMenu(const QPoint &point)
291 {
292  QModelIndex index = ui->tableView->indexAt(point);
293  if(index.isValid())
294  {
295  contextMenu->exec(QCursor::pos());
296  }
297 }
298 
299 void AddressBookPage::selectNewAddress(const QModelIndex &parent, int begin, int /*end*/)
300 {
301  QModelIndex idx = proxyModel->mapFromSource(model->index(begin, AddressTableModel::Address, parent));
302  if(idx.isValid() && (idx.data(Qt::EditRole).toString() == newAddressToSelect))
303  {
304  // Select row of newly created address, once
305  ui->tableView->setFocus();
306  ui->tableView->selectRow(idx.row());
307  newAddressToSelect.clear();
308  }
309 }
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
void setModel(AddressTableModel *model)
QPushButton * newAddress
void onEditAction()
Edit currently selected address entry (no button)
AddressTableModel * model
QPushButton * copyAddress
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
AddressBookPage(Mode mode, Tabs tab, QWidget *parent)
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)
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:260
static const QString Receive
Specifies receive address.
Dialog for editing an address and associated information.
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:247
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)