5a383da2b83205c311658eaab9fb6ee91e8b0d24
[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     view->setTabKeyNavigation(false);
93
94     transactionView = view;
95
96     connect(dateWidget, SIGNAL(activated(int)), this, SLOT(chooseDate(int)));
97     connect(typeWidget, SIGNAL(activated(int)), this, SLOT(chooseType(int)));
98     connect(addressWidget, SIGNAL(textChanged(const QString&)), this, SLOT(changedPrefix(const QString&)));
99     connect(amountWidget, SIGNAL(textChanged(const QString&)), this, SLOT(changedAmount(const QString&)));
100
101     connect(view, SIGNAL(doubleClicked(const QModelIndex&)), this, SIGNAL(doubleClicked(const QModelIndex&)));
102 }
103
104 void TransactionView::setModel(TransactionTableModel *model)
105 {
106     this->model = model;
107
108     transactionProxyModel = new TransactionFilterProxy(this);
109     transactionProxyModel->setSourceModel(model);
110     transactionProxyModel->setDynamicSortFilter(true);
111
112     transactionProxyModel->setSortRole(Qt::EditRole);
113
114     transactionView->setModel(transactionProxyModel);
115     transactionView->setAlternatingRowColors(true);
116     transactionView->setSelectionBehavior(QAbstractItemView::SelectRows);
117     transactionView->setSelectionMode(QAbstractItemView::ExtendedSelection);
118     transactionView->setSortingEnabled(true);
119     transactionView->sortByColumn(TransactionTableModel::Status, Qt::DescendingOrder);
120     transactionView->verticalHeader()->hide();
121
122     transactionView->horizontalHeader()->resizeSection(
123             TransactionTableModel::Status, 23);
124     transactionView->horizontalHeader()->resizeSection(
125             TransactionTableModel::Date, 120);
126     transactionView->horizontalHeader()->resizeSection(
127             TransactionTableModel::Type, 120);
128     transactionView->horizontalHeader()->setResizeMode(
129             TransactionTableModel::ToAddress, QHeaderView::Stretch);
130     transactionView->horizontalHeader()->resizeSection(
131             TransactionTableModel::Amount, 100);
132
133 }
134
135 void TransactionView::chooseDate(int idx)
136 {
137     QDate current = QDate::currentDate();
138     switch(dateWidget->itemData(idx).toInt())
139     {
140     case All:
141         transactionProxyModel->setDateRange(
142                 TransactionFilterProxy::MIN_DATE,
143                 TransactionFilterProxy::MAX_DATE);
144         break;
145     case Today:
146         transactionProxyModel->setDateRange(
147                 QDateTime(current),
148                 TransactionFilterProxy::MAX_DATE);
149         break;
150     case ThisWeek: {
151         // Find last monday
152         QDate startOfWeek = current.addDays(-(current.dayOfWeek()-1));
153         transactionProxyModel->setDateRange(
154                 QDateTime(startOfWeek),
155                 TransactionFilterProxy::MAX_DATE);
156
157         } break;
158     case ThisMonth:
159         transactionProxyModel->setDateRange(
160                 QDateTime(QDate(current.year(), current.month(), 1)),
161                 TransactionFilterProxy::MAX_DATE);
162         break;
163     case LastMonth:
164         transactionProxyModel->setDateRange(
165                 QDateTime(QDate(current.year(), current.month()-1, 1)),
166                 QDateTime(QDate(current.year(), current.month(), 1)));
167         break;
168     case ThisYear:
169         transactionProxyModel->setDateRange(
170                 QDateTime(QDate(current.year(), 1, 1)),
171                 TransactionFilterProxy::MAX_DATE);
172         break;
173     case Range:
174         // TODO ask specific range
175         break;
176     }
177
178 }
179
180 void TransactionView::chooseType(int idx)
181 {
182     transactionProxyModel->setTypeFilter(
183         typeWidget->itemData(idx).toInt());
184 }
185
186 void TransactionView::changedPrefix(const QString &prefix)
187 {
188     transactionProxyModel->setAddressPrefix(prefix);
189 }
190
191 void TransactionView::changedAmount(const QString &amount)
192 {
193     qint64 amount_parsed = 0;
194     if(GUIUtil::parseMoney(amount, &amount_parsed))
195     {
196         transactionProxyModel->setMinAmount(amount_parsed);
197     }
198     else
199     {
200         transactionProxyModel->setMinAmount(0);
201     }
202 }
203
204 void TransactionView::exportClicked()
205 {
206     // CSV is currently the only supported format
207     QString filename = QFileDialog::getSaveFileName(
208             this,
209             tr("Export Transaction Data"),
210             QDir::currentPath(),
211             tr("Comma separated file (*.csv)"));
212     if(!filename.endsWith(".csv"))
213     {
214         filename += ".csv";
215     }
216
217     CSVModelWriter writer(filename);
218
219     // name, column, role
220     writer.setModel(transactionProxyModel);
221     writer.addColumn("Confirmed", 0, TransactionTableModel::ConfirmedRole);
222     writer.addColumn("Date", 0, TransactionTableModel::DateRole);
223     writer.addColumn("Type", TransactionTableModel::Type, Qt::EditRole);
224     writer.addColumn("Label", 0, TransactionTableModel::LabelRole);
225     writer.addColumn("Address", 0, TransactionTableModel::AddressRole);
226     writer.addColumn("Amount", 0, TransactionTableModel::FormattedAmountRole);
227     writer.addColumn("ID", 0, TransactionTableModel::TxIDRole);
228
229     if(!writer.write())
230     {
231         QMessageBox::critical(this, tr("Error exporting"), tr("Could not write to file %1.").arg(filename),
232                               QMessageBox::Abort, QMessageBox::Abort);
233     }
234 }
235