Export functionality for transaction list
[novacoin.git] / src / qt / transactionview.cpp
1 #include "transactionview.h"
2
3 #include "transactionfilterproxy.h"
4 #include "transactionrecord.h"
5 #include "transactiontablemodel.h"
6 #include "guiutil.h"
7 #include "csvmodelwriter.h"
8
9 #include <QScrollBar>
10 #include <QComboBox>
11 #include <QDoubleValidator>
12 #include <QHBoxLayout>
13 #include <QVBoxLayout>
14 #include <QLineEdit>
15 #include <QTableView>
16 #include <QHeaderView>
17 #include <QPushButton>
18 #include <QFileDialog>
19 #include <QMessageBox>
20
21 #include <QDebug>
22
23 TransactionView::TransactionView(QWidget *parent) :
24     QWidget(parent), model(0), transactionProxyModel(0),
25     transactionView(0)
26 {
27     // Build filter row
28     setContentsMargins(0,0,0,0);
29
30     QHBoxLayout *hlayout = new QHBoxLayout();
31     hlayout->setContentsMargins(0,0,0,0);
32     hlayout->setSpacing(0);
33
34     hlayout->addSpacing(23);
35
36     dateWidget = new QComboBox(this);
37     dateWidget->setMaximumWidth(120);
38     dateWidget->setMinimumWidth(120);
39     dateWidget->addItem(tr("All"), All);
40     dateWidget->addItem(tr("Today"), Today);
41     dateWidget->addItem(tr("This week"), ThisWeek);
42     dateWidget->addItem(tr("This month"), ThisMonth);
43     dateWidget->addItem(tr("Last month"), LastMonth);
44     dateWidget->addItem(tr("This year"), ThisYear);
45     dateWidget->addItem(tr("Range..."), Range);
46     hlayout->addWidget(dateWidget);
47
48     typeWidget = new QComboBox(this);
49     typeWidget->setMaximumWidth(120);
50     typeWidget->setMinimumWidth(120);
51
52     typeWidget->addItem(tr("All"), TransactionFilterProxy::ALL_TYPES);
53     typeWidget->addItem(tr("Received with"), TransactionFilterProxy::TYPE(TransactionRecord::RecvWithAddress) |
54                                         TransactionFilterProxy::TYPE(TransactionRecord::RecvFromIP));
55     typeWidget->addItem(tr("Sent to"), TransactionFilterProxy::TYPE(TransactionRecord::SendToAddress) |
56                                   TransactionFilterProxy::TYPE(TransactionRecord::SendToIP));
57     typeWidget->addItem(tr("To yourself"), TransactionFilterProxy::TYPE(TransactionRecord::SendToSelf));
58     typeWidget->addItem(tr("Mined"), TransactionFilterProxy::TYPE(TransactionRecord::Generated));
59     typeWidget->addItem(tr("Other"), TransactionFilterProxy::TYPE(TransactionRecord::Other));
60
61     hlayout->addWidget(typeWidget);
62
63     addressWidget = new QLineEdit(this);
64 #if QT_VERSION >= 0x040700
65     addressWidget->setPlaceholderText("Enter address or label to search");
66 #endif
67     hlayout->addWidget(addressWidget);
68
69     amountWidget = new QLineEdit(this);
70 #if QT_VERSION >= 0x040700
71     amountWidget->setPlaceholderText("Min amount");
72 #endif
73     amountWidget->setMaximumWidth(100);
74     amountWidget->setMinimumWidth(100);
75     amountWidget->setValidator(new QDoubleValidator(0, 1e20, 8, this));
76     hlayout->addWidget(amountWidget);
77
78     QVBoxLayout *vlayout = new QVBoxLayout(this);
79     vlayout->setContentsMargins(0,0,0,0);
80     vlayout->setSpacing(0);
81     //vlayout->addLayout(hlayout2);
82
83     QTableView *view = new QTableView(this);
84     vlayout->addLayout(hlayout);
85     vlayout->addWidget(view);
86     vlayout->setSpacing(0);
87     int width = view->verticalScrollBar()->sizeHint().width();
88     // Cover scroll bar width with spacing
89     hlayout->addSpacing(width);
90     // Always show scroll bar
91     view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
92
93     transactionView = view;
94
95     connect(dateWidget, SIGNAL(activated(int)), this, SLOT(chooseDate(int)));
96     connect(typeWidget, SIGNAL(activated(int)), this, SLOT(chooseType(int)));
97     connect(addressWidget, SIGNAL(textChanged(const QString&)), this, SLOT(changedPrefix(const QString&)));
98     connect(amountWidget, SIGNAL(textChanged(const QString&)), this, SLOT(changedAmount(const QString&)));
99
100     connect(view, SIGNAL(doubleClicked(const QModelIndex&)), this, SIGNAL(doubleClicked(const QModelIndex&)));
101 }
102
103 void TransactionView::setModel(TransactionTableModel *model)
104 {
105     this->model = model;
106
107     transactionProxyModel = new TransactionFilterProxy(this);
108     transactionProxyModel->setSourceModel(model);
109     transactionProxyModel->setDynamicSortFilter(true);
110
111     transactionProxyModel->setSortRole(Qt::EditRole);
112
113     transactionView->setModel(transactionProxyModel);
114     transactionView->setAlternatingRowColors(true);
115     transactionView->setSelectionBehavior(QAbstractItemView::SelectRows);
116     transactionView->setSelectionMode(QAbstractItemView::ExtendedSelection);
117     transactionView->setSortingEnabled(true);
118     transactionView->sortByColumn(TransactionTableModel::Status, Qt::DescendingOrder);
119     transactionView->verticalHeader()->hide();
120
121     transactionView->horizontalHeader()->resizeSection(
122             TransactionTableModel::Status, 23);
123     transactionView->horizontalHeader()->resizeSection(
124             TransactionTableModel::Date, 120);
125     transactionView->horizontalHeader()->resizeSection(
126             TransactionTableModel::Type, 120);
127     transactionView->horizontalHeader()->setResizeMode(
128             TransactionTableModel::ToAddress, QHeaderView::Stretch);
129     transactionView->horizontalHeader()->resizeSection(
130             TransactionTableModel::Amount, 100);
131
132 }
133
134 void TransactionView::chooseDate(int idx)
135 {
136     QDate current = QDate::currentDate();
137     switch(dateWidget->itemData(idx).toInt())
138     {
139     case All:
140         transactionProxyModel->setDateRange(
141                 TransactionFilterProxy::MIN_DATE,
142                 TransactionFilterProxy::MAX_DATE);
143         break;
144     case Today:
145         transactionProxyModel->setDateRange(
146                 QDateTime(current),
147                 TransactionFilterProxy::MAX_DATE);
148         break;
149     case ThisWeek: {
150         // Find last monday
151         QDate startOfWeek = current.addDays(-(current.dayOfWeek()-1));
152         transactionProxyModel->setDateRange(
153                 QDateTime(startOfWeek),
154                 TransactionFilterProxy::MAX_DATE);
155
156         } break;
157     case ThisMonth:
158         transactionProxyModel->setDateRange(
159                 QDateTime(QDate(current.year(), current.month(), 1)),
160                 TransactionFilterProxy::MAX_DATE);
161         break;
162     case LastMonth:
163         transactionProxyModel->setDateRange(
164                 QDateTime(QDate(current.year(), current.month()-1, 1)),
165                 QDateTime(QDate(current.year(), current.month(), 1)));
166         break;
167     case ThisYear:
168         transactionProxyModel->setDateRange(
169                 QDateTime(QDate(current.year(), 1, 1)),
170                 TransactionFilterProxy::MAX_DATE);
171         break;
172     case Range:
173         // TODO ask specific range
174         break;
175     }
176
177 }
178
179 void TransactionView::chooseType(int idx)
180 {
181     transactionProxyModel->setTypeFilter(
182         typeWidget->itemData(idx).toInt());
183 }
184
185 void TransactionView::changedPrefix(const QString &prefix)
186 {
187     transactionProxyModel->setAddressPrefix(prefix);
188 }
189
190 void TransactionView::changedAmount(const QString &amount)
191 {
192     qint64 amount_parsed = 0;
193     if(GUIUtil::parseMoney(amount, &amount_parsed))
194     {
195         transactionProxyModel->setMinAmount(amount_parsed);
196     }
197     else
198     {
199         transactionProxyModel->setMinAmount(0);
200     }
201 }
202
203 void TransactionView::exportClicked()
204 {
205     // CSV is currently the only supported format
206     QString filename = QFileDialog::getSaveFileName(
207             this,
208             tr("Export Transaction Data"),
209             QDir::currentPath(),
210             tr("Comma separated file (*.csv)"));
211     if(!filename.endsWith(".csv"))
212     {
213         filename += ".csv";
214     }
215
216     CSVModelWriter writer(filename);
217
218     // name, column, role
219     writer.setModel(transactionProxyModel);
220     writer.addColumn("Confirmed", 0, TransactionTableModel::ConfirmedRole);
221     writer.addColumn("Date", 0, TransactionTableModel::DateRole);
222     writer.addColumn("Type", TransactionTableModel::Type, Qt::EditRole);
223     writer.addColumn("Label", 0, TransactionTableModel::LabelRole);
224     writer.addColumn("Address", 0, TransactionTableModel::AddressRole);
225     writer.addColumn("Amount", 0, TransactionTableModel::FormattedAmountRole);
226     writer.addColumn("ID", 0, TransactionTableModel::TxIDRole);
227
228     if(!writer.write())
229     {
230         QMessageBox::critical(this, tr("Error exporting"), tr("Could not write to file %1.").arg(filename),
231                               QMessageBox::Abort, QMessageBox::Abort);
232     }
233 }
234