Added QRCode generation functions via libqrencode. Switch on with USE_QRENCODE=1.
[novacoin.git] / src / qt / addressbookpage.cpp
1 #include "addressbookpage.h"
2 #include "ui_addressbookpage.h"
3
4 #include "addresstablemodel.h"
5 #include "editaddressdialog.h"
6 #include "csvmodelwriter.h"
7
8 #include <QSortFilterProxyModel>
9 #include <QClipboard>
10 #include <QFileDialog>
11 #include <QMessageBox>
12
13 #ifdef USE_QRCODE
14 #include "qrcodedialog.h"
15 #endif
16
17 AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
18     QDialog(parent),
19     ui(new Ui::AddressBookPage),
20     model(0),
21     mode(mode),
22     tab(tab)
23 {
24     ui->setupUi(this);
25
26 #ifdef Q_WS_MAC // Icons on push buttons are very uncommon on Mac
27     ui->newAddressButton->setIcon(QIcon());
28     ui->copyToClipboard->setIcon(QIcon());
29     ui->deleteButton->setIcon(QIcon());
30 #endif
31
32 #ifndef USE_QRCODE
33     ui->showQRCode->setVisible(false);
34 #endif
35
36     switch(mode)
37     {
38     case ForSending:
39         connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept()));
40         ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
41         ui->tableView->setFocus();
42         break;
43     case ForEditing:
44         ui->buttonBox->hide();
45         break;
46     }
47     switch(tab)
48     {
49     case SendingTab:
50         ui->labelExplanation->hide();
51         break;
52     case ReceivingTab:
53         break;
54     }
55     ui->tableView->setTabKeyNavigation(false);
56
57     connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
58 }
59
60 AddressBookPage::~AddressBookPage()
61 {
62     delete ui;
63 }
64
65 void AddressBookPage::setModel(AddressTableModel *model)
66 {
67     this->model = model;
68     if(!model)
69         return;
70     // Refresh list from core
71     model->updateList();
72
73     proxyModel = new QSortFilterProxyModel(this);
74     proxyModel->setSourceModel(model);
75     proxyModel->setDynamicSortFilter(true);
76     switch(tab)
77     {
78     case ReceivingTab:
79         // Receive filter
80         proxyModel->setFilterRole(AddressTableModel::TypeRole);
81         proxyModel->setFilterFixedString(AddressTableModel::Receive);
82         break;
83     case SendingTab:
84         // Send filter
85         proxyModel->setFilterRole(AddressTableModel::TypeRole);
86         proxyModel->setFilterFixedString(AddressTableModel::Send);
87         break;
88     }
89     ui->tableView->setModel(proxyModel);
90     ui->tableView->sortByColumn(0, Qt::AscendingOrder);
91
92     // Set column widths
93     ui->tableView->horizontalHeader()->resizeSection(
94             AddressTableModel::Address, 320);
95     ui->tableView->horizontalHeader()->setResizeMode(
96             AddressTableModel::Label, QHeaderView::Stretch);
97
98     connect(ui->tableView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
99             this, SLOT(selectionChanged()));
100
101     if(mode == ForSending)
102     {
103         // Auto-select first row when in sending mode
104         ui->tableView->selectRow(0);
105     }
106     selectionChanged();
107 }
108
109 void AddressBookPage::on_copyToClipboard_clicked()
110 {
111     // Copy currently selected address to clipboard
112     //   (or nothing, if nothing selected)
113     QTableView *table = ui->tableView;
114     if(!table->selectionModel())
115         return;
116     QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
117
118     foreach (QModelIndex index, indexes)
119     {
120         QVariant address = index.data();
121         QApplication::clipboard()->setText(address.toString());
122     }
123 }
124
125 void AddressBookPage::on_newAddressButton_clicked()
126 {
127     if(!model)
128         return;
129     EditAddressDialog dlg(
130             tab == SendingTab ?
131             EditAddressDialog::NewSendingAddress :
132             EditAddressDialog::NewReceivingAddress);
133     dlg.setModel(model);
134     if(dlg.exec())
135     {
136         // Select row for newly created address
137         QString address = dlg.getAddress();
138         QModelIndexList lst = proxyModel->match(proxyModel->index(0,
139                           AddressTableModel::Address, QModelIndex()),
140                           Qt::EditRole, address, 1, Qt::MatchExactly);
141         if(!lst.isEmpty())
142         {
143             ui->tableView->setFocus();
144             ui->tableView->selectRow(lst.at(0).row());
145         }
146     }
147 }
148
149 void AddressBookPage::on_deleteButton_clicked()
150 {
151     QTableView *table = ui->tableView;
152     if(!table->selectionModel())
153         return;
154     QModelIndexList indexes = table->selectionModel()->selectedRows();
155     if(!indexes.isEmpty())
156     {
157         table->model()->removeRow(indexes.at(0).row());
158     }
159 }
160
161 void AddressBookPage::selectionChanged()
162 {
163     // Set button states based on selected tab and selection
164     QTableView *table = ui->tableView;
165     if(!table->selectionModel())
166         return;
167
168     if(table->selectionModel()->hasSelection())
169     {
170         switch(tab)
171         {
172         case SendingTab:
173             ui->deleteButton->setEnabled(true);
174             break;
175         case ReceivingTab:
176             ui->deleteButton->setEnabled(false);
177             break;
178         }
179         ui->copyToClipboard->setEnabled(true);
180         ui->showQRCode->setEnabled(true);
181     }
182     else
183     {
184         ui->deleteButton->setEnabled(false);
185         ui->showQRCode->setEnabled(false);
186         ui->copyToClipboard->setEnabled(false);
187     }
188 }
189
190 void AddressBookPage::done(int retval)
191 {
192     QTableView *table = ui->tableView;
193     if(!table->selectionModel() || !table->model())
194         return;
195     // When this is a tab/widget and not a model dialog, ignore "done"
196     if(mode == ForEditing)
197         return;
198
199     // Figure out which address was selected, and return it
200     QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
201
202     foreach (QModelIndex index, indexes)
203     {
204         QVariant address = table->model()->data(index);
205         returnValue = address.toString();
206     }
207
208     if(returnValue.isEmpty())
209     {
210         retval = Rejected;
211     }
212
213     QDialog::done(retval);
214 }
215
216 void AddressBookPage::exportClicked()
217 {
218     // CSV is currently the only supported format
219     QString filename = QFileDialog::getSaveFileName(
220             this,
221             tr("Export Address Book Data"),
222             QDir::currentPath(),
223             tr("Comma separated file (*.csv)"));
224
225     if (filename.isNull()) return;
226
227     CSVModelWriter writer(filename);
228
229     // name, column, role
230     writer.setModel(proxyModel);
231     writer.addColumn("Label", AddressTableModel::Label, Qt::EditRole);
232     writer.addColumn("Address", AddressTableModel::Address, Qt::EditRole);
233
234     if(!writer.write())
235     {
236         QMessageBox::critical(this, tr("Error exporting"), tr("Could not write to file %1.").arg(filename),
237                               QMessageBox::Abort, QMessageBox::Abort);
238     }
239 }
240
241 void AddressBookPage::on_showQRCode_clicked()
242 {
243 #ifdef USE_QRCODE
244     QTableView *table = ui->tableView;
245     QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
246
247
248     QRCodeDialog *d;
249     foreach (QModelIndex index, indexes)
250     {
251         QString address = index.data().toString(),
252             label = index.sibling(index.row(), 0).data().toString(),
253             title = QString("%1 << %2 >>").arg(label).arg(address);
254
255         QRCodeDialog *d = new QRCodeDialog(title, address, label, tab == ReceivingTab, this);
256         d->show();
257     }
258 #endif
259 }