diff --git a/src/view/AccountPanel.cpp b/src/view/AccountPanel.cpp
index 1a52d12..b0748c2 100644
--- a/src/view/AccountPanel.cpp
+++ b/src/view/AccountPanel.cpp
@@ -270,12 +270,12 @@ void AccountPanel::InitStatsGrid(User* user)
_statsGrid->setItem(BALANCE, 0, new QTableWidgetItem(_("Balance")));
_statsGrid->setItem(NON_FIX, 0, new QTableWidgetItem(_("Non fix")));
- _statsGrid->setItem(CUR_CREDIT, 1, new QTableWidgetItem(_("")));
- _statsGrid->setItem(CUR_DEBIT, 1, new QTableWidgetItem(_("")));
- _statsGrid->setItem(TOTAL_CREDIT, 1, new QTableWidgetItem(_("")));
- _statsGrid->setItem(TOTAL_DEBIT, 1, new QTableWidgetItem(_("")));
- _statsGrid->setItem(BALANCE, 1, new QTableWidgetItem(_("")));
- _statsGrid->setItem(NON_FIX, 1, new QTableWidgetItem(_("")));
+ _statsGrid->setItem(CUR_CREDIT, 1, new QTableWidgetItem(""));
+ _statsGrid->setItem(CUR_DEBIT, 1, new QTableWidgetItem(""));
+ _statsGrid->setItem(TOTAL_CREDIT, 1, new QTableWidgetItem(""));
+ _statsGrid->setItem(TOTAL_DEBIT, 1, new QTableWidgetItem(""));
+ _statsGrid->setItem(BALANCE, 1, new QTableWidgetItem(""));
+ _statsGrid->setItem(NON_FIX, 1, new QTableWidgetItem(""));
_statsGrid->item(CUR_DEBIT, 0)->setFont(font);
_statsGrid->item(CUR_CREDIT, 0)->setFont(font);
diff --git a/src/view/StatsPanel.cpp b/src/view/StatsPanel.cpp
new file mode 100644
index 0000000..e92e7aa
--- /dev/null
+++ b/src/view/StatsPanel.cpp
@@ -0,0 +1,447 @@
+/*
+ Copyright 2010-2012 Grégory Soutadé
+
+ This file is part of KissCount.
+
+ KissCount is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ KissCount is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with KissCount. If not, see .
+*/
+
+#include
+#include
+#include
+
+#include "StatsPanel.hpp"
+
+StatsPanel::StatsPanel(KissCount* kiss, wxUI *parent) : KissPanel(kiss, parent) //, _plot(0), _chart(0)
+{
+ QHBoxLayout *hbox = new QHBoxLayout();
+ QVBoxLayout *vbox = new QVBoxLayout();
+ _hbox2 = new QHBoxLayout();
+ _vbox2 = new QVBoxLayout();
+ int i;
+ User* user = _kiss->GetUser();
+ std::vector::iterator accountIt;
+ std::vector::iterator categoryIt;
+ std::map > operations;
+ std::map >::iterator it;
+ int nbCategories;
+ QListWidgetItem* item;
+
+ setLayout(vbox);
+
+ _monthFrom = new QComboBox(parent);
+ for(i=0; i<12; i++)
+ _monthFrom->addItem(wxUI::months[i]);
+ _yearFrom = new QComboBox(parent);
+
+ _monthTo = new QComboBox(parent);
+ for(i=0; i<12; i++)
+ _monthTo->addItem(wxUI::months[i]);
+ _yearTo = new QComboBox(parent);
+
+ operations = _kiss->GetAllOperations();
+
+ for(i=0, it = operations.begin(); it != operations.end(); it++, i++)
+ {
+ _yearFrom->addItem(QString::number(it->first));
+ _yearTo->addItem(QString::number(it->first));
+ }
+
+ if (i) i--;
+
+ _yearFrom->setCurrentIndex(i);
+ _yearTo->setCurrentIndex(i);
+ _monthFrom->setCurrentIndex(0);
+ _monthTo->setCurrentIndex(11);
+
+ QLabel* label = new QLabel(_("From"));
+ hbox->addWidget(label);
+ hbox->addWidget(_monthFrom);
+ hbox->addWidget(_yearFrom);
+
+ label = new QLabel(_("To"));
+ hbox->addWidget(label);
+ hbox->addWidget(_monthTo);
+ hbox->addWidget(_yearTo);
+
+ connect(_yearFrom, SIGNAL(currentIndexChanged(int)), this, SLOT(OnRangeChange(int)));
+ connect(_monthFrom, SIGNAL(currentIndexChanged(int)), this, SLOT(OnRangeChange(int)));
+ connect(_yearTo, SIGNAL(currentIndexChanged(int)), this, SLOT(OnRangeChange(int)));
+ connect(_monthTo, SIGNAL(currentIndexChanged(int)), this, SLOT(OnRangeChange(int)));
+
+ _account = new QListWidget(this);
+ for(i=0, accountIt = user->_accounts.begin(); accountIt != user->_accounts.end(); accountIt++, i++)
+ {
+ item = new QListWidgetItem(accountIt->name, _account);
+ item->setCheckState (Qt::Checked);
+ }
+
+ connect(_account, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(OnAccountChange(QListWidgetItem*)));
+
+ _categories = new QString[user->GetCategoriesNumber()] ;
+ for(i=0, categoryIt = user->_categories.begin();
+ categoryIt != user->_categories.end();
+ categoryIt++, i++)
+ {
+ _categoriesIndexes[categoryIt->id] = i;
+ _categories[i] = _(categoryIt->name.toStdString().c_str()) ;
+ }
+
+ DEFAULT_FONT(font);
+
+ _statsGrid = new QTableWidget(this);
+
+ _statsGrid->setRowCount(user->GetCategoriesNumber()+1);
+ _statsGrid->setColumnCount(2);
+ _statsGrid->verticalHeader()->setHidden(true);
+ _statsGrid->horizontalHeader()->setHidden(true);
+
+ _statsGrid->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+
+ for(i=0; iGetCategoriesNumber(); i++)
+ {
+ if (i)
+ {
+ _statsGrid->setItem(i+1, 0, new QTableWidgetItem(_categories[i]));
+ _statsGrid->item(i+1, 0)->setTextAlignment(Qt::AlignLeft|Qt::AlignVCenter);
+ }
+ else
+ {
+ _statsGrid->setItem(i, 0, new QTableWidgetItem(_categories[i]));
+ _statsGrid->item(i, 0)->setTextAlignment(Qt::AlignLeft|Qt::AlignVCenter);
+ }
+ }
+
+ _statsGrid->setItem(1, 0, new QTableWidgetItem(_("Non fix")));
+ _statsGrid->setItem(1, 1, new QTableWidgetItem(""));
+ _statsGrid->item(1, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
+
+ _vbox2->addWidget(_account);
+ _vbox2->addWidget(_statsGrid);
+
+ nbCategories = (user->GetCategoriesNumber() <= wxUI::MAX_CATEGORY) ? user->GetCategoriesNumber() : wxUI::MAX_CATEGORY;
+
+ // _dataset = new CategorySimpleDataset(_categories, nbCategories);
+ // ColorScheme* colorScheme = new ColorScheme(wxUI::categoryColors, WXSIZEOF(wxUI::categoryColors));
+
+ _categoriesValues = new double[user->GetCategoriesNumber()];
+ for(i=0; iGetCategoriesNumber(); i++)
+ _categoriesValues[i] = 0.0;
+
+ _pie = new KDChart::Widget();
+ _pie->setType( KDChart::Widget::Pie );
+ QPen pen;
+ pen.setWidth(2);
+ pen.setColor(Qt::black);
+ _pie->pieDiagram()->setPen(pen);
+
+ _pie->addLegend(KDChart::Position::South);
+ KDChart::Legend* legend = _pie->legend();
+ legend->setOrientation( Qt::Vertical );
+ legend->setTitleText( _("Cost repartition") );
+ QVector< double > vec;
+ vec << 0.0;
+ _categoriesValues = new double[nbCategories];
+ for(i=0; isetDataset( i, vec, _categories[i] );
+ _pie->pieDiagram()->setBrush(i, QBrush(wxUI::categoryColors[i]));
+ legend->setText( i, _categories[i] );
+ }
+
+ _pie->setMaximumSize( 200, 400 );
+
+ KDChart::TextAttributes legendTextAttr(legend->textAttributes());
+ legendTextAttr.setFontSize(64);
+ legendTextAttr.setAutoShrink(true);
+ legend->setTextAttributes(legendTextAttr);
+
+ legendTextAttr = KDChart::TextAttributes(legend->titleTextAttributes());
+ legendTextAttr.setFontSize(64);
+ legendTextAttr.setAutoShrink(true);
+ legend->setTitleTextAttributes(legendTextAttr);
+
+ vbox->addLayout(hbox);
+ vbox->addLayout(_hbox2);
+
+ OnRangeChange(0);
+
+ layout();
+}
+
+KissPanel* StatsPanel::CreatePanel()
+{
+ return new StatsPanel(_kiss, _wxUI);
+}
+
+QPushButton* StatsPanel::GetButton()
+{
+ if (!_KissButton)
+ {
+ _KissButton = new QPushButton(QIcon(STATS_ICON), "", this);
+ _KissButton->setFixedSize(128, 128);
+ _KissButton->setIconSize(QSize(128, 128));
+ }
+
+ return _KissButton;
+}
+
+QString StatsPanel::GetToolTip()
+{
+ return _("Statistics");
+}
+
+void StatsPanel::UpdateStats(int monthFrom, int yearFrom, int monthTo, int yearTo)
+{
+ std::map > > accountAmounts;
+ std::map categories;
+ std::map > operations;
+ std::vector::iterator accountIt;
+ std::map::iterator categoriesIt;
+ std::map >::iterator accountYearIt;
+ double total, non_fix;
+ int account, size, i, a, b, percents, nbDays;
+ double *amounts;
+ QString value;
+ User* user = _kiss->GetUser();
+ QDate date;
+ bool failed;
+
+ // if (_chart)
+ {
+ // _hbox2->removeWidget(_chart);
+ _hbox2->removeItem(_vbox2);
+ // _hbox2->removeWidget(_chartCategories);
+ // delete _chart;
+ }
+
+ // first step: create plot
+ // _plot = new XYPlot();
+
+ // create dataset
+ // XYSimpleDataset *dataset = new XYSimpleDataset();
+
+ if (monthFrom == monthTo && yearFrom == yearTo)
+ {
+ date.setDate(yearFrom, monthFrom+1, 1);
+ nbDays = date.daysInMonth();
+
+ _kiss->GetMonthStats(monthFrom, yearFrom, nbDays, &operations, &categories);
+
+ // // Line on 0 all over the years
+ // amounts = new double[nbDays*2];
+ // for (a=0; aAddSerie((double *) amounts, nbDays);
+ // delete[] amounts;
+
+ // for (account = 0, i = 0, accountIt = user->_accounts.begin(); accountIt != user->_accounts.end();
+ // account++, accountIt++, i++)
+ // {
+ // if (!_account->IsChecked(account))
+ // {
+ // i-- ;
+ // continue;
+ // }
+
+ // amounts = new double[nbDays*2];
+ // size = 0;
+ // for (a=0; aid][a];
+ // }
+ // dataset->AddSerie((double *) amounts, nbDays);
+ // // set serie names to be displayed on legend
+ // dataset->SetSerieName(i+1, user->GetAccountName(accountIt->id));
+ // delete[] amounts;
+ // }
+ }
+ else
+ {
+ _kiss->GetStats(monthFrom, yearFrom, monthTo, yearTo, &accountAmounts, &categories);
+
+ // // Line on 0 all over the years
+ // size = ((yearTo - yearFrom) + 1) * 12;
+ // amounts = new double[size*2];
+ // for (a=0; a<(size/12); a++)
+ // {
+ // for(b=0; b<12; b++)
+ // {
+ // amounts[a*12*2+b*2+0] = a*12+b;
+ // amounts[a*12*2+b*2+1] = 0;
+ // }
+ // }
+
+ // dataset->AddSerie((double *) amounts, size);
+ // delete[] amounts;
+
+ for (account = 0, i = 0, accountIt = user->_accounts.begin(); accountIt != user->_accounts.end();
+ account++, accountIt++, i++)
+ {
+ if (_account->item(account)->checkState() != Qt::Checked)
+ {
+ i-- ;
+ continue;
+ }
+
+ // size = accountAmounts[accountIt->id].size();
+ // amounts = new double[size*13*2];
+ // size = 0;
+ // for(a = 0, accountYearIt = accountAmounts[accountIt->id].begin();
+ // accountYearIt != accountAmounts[accountIt->id].end();
+ // accountYearIt++, a++)
+ // {
+ // for(b = 0; b<=12; b++)
+ // {
+ // amounts[size*2+0] = a*12+b;
+ // if (!accountAmounts[accountIt->id][accountYearIt->first].count(b))
+ // {
+ // /*
+ // If previously afiled, continue to avoid to set
+ // account to 0 (only for display)
+ // */
+ // if (!b || failed) continue;
+ // /*
+ // Compute cur month value (if there are operations)
+ // as next month value
+ // */
+ // amounts[size*2+1] =
+ // accountAmounts[accountIt->id][accountYearIt->first][b-1]
+ // + _kiss->CalcAccountAmount(accountIt->id, b-1, accountYearIt->first, 0);
+ // failed = true;
+ // }
+ // else
+ // {
+ // amounts[size*2+1] = accountAmounts[accountIt->id][accountYearIt->first][b];
+ // failed = false;
+ // }
+ // size++;
+ // }
+ // }
+ // dataset->AddSerie((double *) amounts, size);
+ // // set serie names to be displayed on legend
+ // dataset->SetSerieName(i+1, user->GetAccountName(accountIt->id));
+ // delete[] amounts;
+ }
+ }
+
+ // // create line renderer and set it to dataset
+ // XYLineRenderer *renderer = new XYLineRenderer(true, true);
+ // dataset->SetRenderer(renderer);
+
+ // // add our dataset to plot
+ // _plot->AddDataset(dataset);
+
+ // // create left and bottom number axes
+ // NumberAxis *leftAxis = new NumberAxis(AXIS_LEFT);
+ // NumberAxis *bottomAxis = new NumberAxis(AXIS_BOTTOM);
+
+ // // add axes to plot
+ // _plot->AddAxis(leftAxis);
+ // _plot->AddAxis(bottomAxis);
+
+ // // link axes and dataset
+ // _plot->LinkDataVerticalAxis(0, 0);
+ // _plot->LinkDataHorizontalAxis(0, 0);
+
+ // // set legend
+ // _plot->SetLegend(new Legend(wxCENTER, wxRIGHT));
+
+ // _chart = new wxChartPanel(this);
+ // _chart->SetChart(new Chart(_plot, _("Accounts")));
+ // _chart->Fit();
+ // _chart->Layout();
+ // _chart->SetMinSize(// chart->GetSize()
+ // wxSize(750,550));
+
+ // _hbox2->Add(_chart, 0, wxGROW|wxALL, 5);
+
+ total = 0.0;
+ for(categoriesIt = categories.begin(); categoriesIt != categories.end(); categoriesIt++)
+ total += categoriesIt->second;
+
+ for(i=0, categoriesIt = categories.begin(); categoriesIt != categories.end(); categoriesIt++, i++)
+ {
+ _categoriesValues[_categoriesIndexes[categoriesIt->first]] = categoriesIt->second;
+ if (total)
+ percents = ((double) (categoriesIt->second*100))/total;
+ else
+ percents = 0;
+ value = value.sprintf("%0.2lf (%02d%%)", categoriesIt->second, percents);
+ if (i)
+ {
+ _statsGrid->setItem(_categoriesIndexes[categoriesIt->first]+1, 1, new QTableWidgetItem(value));
+ _statsGrid->item(_categoriesIndexes[categoriesIt->first]+1, 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
+ }
+ else
+ {
+ _statsGrid->setItem(_categoriesIndexes[categoriesIt->first], 1, new QTableWidgetItem(value));
+ _statsGrid->item(_categoriesIndexes[categoriesIt->first], 1)->setTextAlignment(Qt::AlignRight|Qt::AlignVCenter);
+ }
+ QVector< double > vec;
+ vec << _categoriesValues[i];
+ _pie->setDataset( i, vec, _categories[i] );
+ }
+
+ non_fix = total - _categoriesValues[0];
+
+ if (total)
+ percents = ((double) (non_fix*100))/total;
+ else
+ percents = 0;
+ value = value.sprintf("%0.2lf (%02d%%)", non_fix, percents);
+ _statsGrid->setItem(1, 1, new QTableWidgetItem(value));
+
+ _statsGrid->resizeColumnsToContents();
+
+ _hbox2->addLayout(_vbox2);
+ _hbox2->addWidget(_pie);
+
+ layout();
+}
+
+void StatsPanel::OnShow()
+{
+ _wxUI->setWindowTitle(_kiss->GetUser()->_name + _(" - ") + _("Statistics"));
+}
+
+void StatsPanel::OnRangeChange(int index)
+{
+ int monthFrom, monthTo, yearFrom, yearTo;
+
+ monthFrom = _monthFrom->currentIndex();
+ yearFrom = _yearFrom->currentText().toInt();
+ monthTo = _monthTo->currentIndex();
+ yearTo = _yearTo->currentText().toInt();
+
+ if (yearTo < yearFrom ||
+ (yearFrom == yearTo && monthFrom > monthTo))
+ {
+ QMessageBox::critical(0, _("Error"), _("Invalide date range"));
+ return;
+ }
+
+ UpdateStats(monthFrom, yearFrom, monthTo, yearTo);
+}
+
+void StatsPanel::OnAccountChange(QListWidgetItem* item)
+{
+ OnRangeChange(0);
+}
diff --git a/src/view/StatsPanel.hpp b/src/view/StatsPanel.hpp
new file mode 100644
index 0000000..fe1a971
--- /dev/null
+++ b/src/view/StatsPanel.hpp
@@ -0,0 +1,62 @@
+/*
+ Copyright 2010-2011 Grégory Soutadé
+
+ This file is part of KissCount.
+
+ KissCount is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ KissCount is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with KissCount. If not, see .
+*/
+
+#ifndef STATSPANEL_H
+#define STATSPANEL_H
+
+#include
+#include
+
+#include "view.hpp"
+#include
+
+class StatsPanel: public KissPanel
+{
+ Q_OBJECT;
+
+public:
+ StatsPanel(KissCount* kiss, wxUI *parent);
+
+ KissPanel* CreatePanel();
+ QPushButton* GetButton();
+ QString GetToolTip();
+ void OnShow();
+
+private slots:
+ void OnRangeChange(int);
+ void OnAccountChange(QListWidgetItem*);
+
+private:
+ QCalendarWidget* _calendarFrom, *_calendarTo;
+ QComboBox* _monthFrom, *_yearFrom, *_monthTo, *_yearTo;
+ QTableWidget *_statsGrid;
+ KDChart::Widget* _pie;
+ double *_categoriesValues;
+ //CategorySimpleDataset* _dataset;
+ KDChart::Widget *_plot ;
+ QString* _categories;
+ std::map _categoriesIndexes;
+ QBoxLayout *_hbox2, *_vbox2;
+ //wxChartPanel* _chart, *_chartCategories;
+ QListWidget* _account;
+
+ void UpdateStats(int monthFrom, int yearFrom, int monthTo, int yearTo);
+};
+
+#endif
diff --git a/src/view/wxUI.cpp b/src/view/wxUI.cpp
index c52b6f1..ac804f5 100644
--- a/src/view/wxUI.cpp
+++ b/src/view/wxUI.cpp
@@ -22,12 +22,11 @@
#include "AccountPanel.hpp"
#include "SearchPanel.hpp"
#include "PreferencesPanel.hpp"
-/*#include "UsersDialog.hpp"
+//#include "UsersDialog.hpp"
#include "StatsPanel.hpp"
-#include "ImportPanel.hpp"
-#include "ExportPanel.hpp"
+//#include "ImportPanel.hpp"
+//#include "ExportPanel.hpp"
-*/
#include "wxUI.hpp"
#include "view.hpp"
@@ -164,7 +163,7 @@ void wxUI::InitPanels()
int id=0;
ADD_PANEL(AccountPanel);
- // ADD_PANEL(StatsPanel, 1);
+ ADD_PANEL(StatsPanel);
ADD_PANEL(SearchPanel);
ADD_PANEL(PreferencesPanel);
// ADD_PANEL(ImportPanel, 4);