summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/apps/checkbook/checkbook.cpp122
-rw-r--r--noncore/apps/checkbook/checkbook.h7
-rw-r--r--noncore/apps/checkbook/graph.cpp85
-rw-r--r--noncore/apps/checkbook/graph.h7
-rw-r--r--noncore/apps/checkbook/graphinfo.cpp45
-rw-r--r--noncore/apps/checkbook/graphinfo.h8
6 files changed, 238 insertions, 36 deletions
diff --git a/noncore/apps/checkbook/checkbook.cpp b/noncore/apps/checkbook/checkbook.cpp
index 20b42b5..77c1f57 100644
--- a/noncore/apps/checkbook/checkbook.cpp
+++ b/noncore/apps/checkbook/checkbook.cpp
@@ -232,33 +232,30 @@ QWidget *Checkbook::initTransactions()
232 232
233QWidget *Checkbook::initCharts() 233QWidget *Checkbook::initCharts()
234{ 234{
235 graphInfo = 0x0;
236
235 QWidget *control = new QWidget( mainWidget ); 237 QWidget *control = new QWidget( mainWidget );
236 238
237 QGridLayout *layout = new QGridLayout( control ); 239 QGridLayout *layout = new QGridLayout( control );
238 layout->setSpacing( 2 ); 240 layout->setSpacing( 2 );
239 layout->setMargin( 4 ); 241 layout->setMargin( 4 );
240 242
241/* 243 graphWidget = new Graph( control );
242 QLabel *label = new QLabel( control ); 244 QWhatsThis::add( graphWidget, tr( "Select the desired chart below and then click on the Draw button." ) );
243 label->setText( tr( "Graph type:" ) ); 245 layout->addMultiCellWidget( graphWidget, 0, 0, 0, 2 );
244 layout->addWidget( label, 0, 0 ); 246
245 graphList = new QComboBox( control ); 247 graphList = new QComboBox( control );
246 graphList->insertItem( tr( "By category" ) ); 248 QWhatsThis::add( graphList, tr( "Click here to select the desired chart type." ) );
247 graphList->insertItem( tr( "..." ) ); 249 graphList->insertItem( tr( "Account balance" ) );
248 graphList->insertItem( tr( "..." ) ); 250 graphList->insertItem( tr( "Withdrawals by category" ) );
249 layout->addWidget( graphList, 0, 1 ); 251 graphList->insertItem( tr( "Deposits by category" ) );
250*/
251 252
252 GraphInfo* info = new GraphInfo( GraphInfo::BarChart, 0x0, tr( "Graph Title" ), 253 layout->addMultiCellWidget( graphList, 1, 1, 0, 1 );
253 tr( "X-Axis" ), tr( "Y-Axis" ) );
254 graphWidget = new Graph( control, info );
255 QWhatsThis::add( graphWidget, tr( "Charting is not implemented yet." ) );
256 layout->addMultiCellWidget( graphWidget, 0, 0, 0, 1 );
257 254
258 QPushButton *btn = new QPushButton( Resource::loadPixmap( "checkbook/drawbtn" ), tr( "Draw" ), control ); 255 QPushButton *btn = new QPushButton( Resource::loadPixmap( "checkbook/drawbtn" ), tr( "Draw" ), control );
259 QWhatsThis::add( btn, tr( "Click here to draw the chart." ) ); 256 QWhatsThis::add( btn, tr( "Click here to draw the selected chart." ) );
260 connect( btn, SIGNAL( clicked() ), this, SLOT( slotDrawGraph() ) ); 257 connect( btn, SIGNAL( clicked() ), this, SLOT( slotDrawGraph() ) );
261 layout->addWidget( btn, 1, 1 ); 258 layout->addWidget( btn, 1, 2 );
262 259
263 return control; 260 return control;
264} 261}
@@ -367,12 +364,10 @@ void Checkbook::accept()
367 config->writeEntry( "Notes", notesEdit->text() ); 364 config->writeEntry( "Notes", notesEdit->text() );
368 365
369 // Save transactions 366 // Save transactions
370 TranInfo *tran = transactions.first();
371 int i = 1; 367 int i = 1;
372 while ( tran ) 368 for ( TranInfo *tran = transactions.first(); tran; tran = transactions.next() )
373 { 369 {
374 tran->write( config, i ); 370 tran->write( config, i );
375 tran = transactions.next();
376 i++; 371 i++;
377 } 372 }
378 config->write(); 373 config->write();
@@ -509,4 +504,93 @@ void Checkbook::slotDeleteTran()
509 504
510void Checkbook::slotDrawGraph() 505void Checkbook::slotDrawGraph()
511{ 506{
507 if ( graphInfo )
508 {
509 delete graphInfo;
510 }
511
512 switch ( graphList->currentItem() )
513 {
514 case 0 : drawBalanceChart();
515 break;
516 case 1 : drawCategoryChart( TRUE );
517 break;
518 case 2 : drawCategoryChart( FALSE );
519 break;
520 };
521
522 graphWidget->setGraphInfo( graphInfo );
523 graphWidget->drawGraph( TRUE );
524}
525
526void Checkbook::drawBalanceChart()
527{
528 DataPointList *list = new DataPointList();
529
530 float balance = startBalance;
531 float amount;
532 QString label;
533 int i = 0;
534 int count = transactions.count();
535
536 for ( TranInfo *tran = transactions.first(); tran; tran = transactions.next() )
537 {
538 i++;
539 balance -= tran->fee();
540 amount = tran->amount();
541 if ( tran->withdrawal() )
542 {
543 amount *= -1;
544 }
545 balance += amount;
546 if ( i == 1 || i == count / 2 || i == count )
547 {
548 label = tran->datestr();
549 }
550 else
551 {
552 label = "";
553 }
554 list->append( new DataPointInfo( label, balance ) );
555 }
556
557 graphInfo = new GraphInfo( GraphInfo::BarChart, list );
558}
559
560void Checkbook::drawCategoryChart( bool withdrawals )
561{
562 DataPointList *list = new DataPointList();
563
564 TranInfo *tran = transactions.first();
565 if ( tran->withdrawal() == withdrawals )
566 {
567 list->append( new DataPointInfo( tran->category(), tran->amount() ) );
568 }
569 tran = transactions.next();
570
571 DataPointInfo *cat;
572 for ( ; tran; tran = transactions.next() )
573 {
574 if ( tran->withdrawal() == withdrawals )
575 {
576 // Find category in list
577 for ( cat = list->first(); cat; cat = list->next() )
578 {
579 if ( cat->label() == tran->category() )
580 {
581 break;
582 }
583 }
584 if ( cat && cat->label() == tran->category() )
585 { // Found category, add to transaction to category total
586 cat->addToValue( tran->amount() );
587 }
588 else
589 { // Didn't find category, add category to list
590 list->append( new DataPointInfo( tran->category(), tran->amount() ) );
591 }
592 }
593 }
594
595 graphInfo = new GraphInfo( GraphInfo::PieChart, list );
512} 596}
diff --git a/noncore/apps/checkbook/checkbook.h b/noncore/apps/checkbook/checkbook.h
index 01f1115..287788a 100644
--- a/noncore/apps/checkbook/checkbook.h
+++ b/noncore/apps/checkbook/checkbook.h
@@ -36,6 +36,7 @@
36class OTabWidget; 36class OTabWidget;
37 37
38class Graph; 38class Graph;
39class GraphInfo;
39class QComboBox; 40class QComboBox;
40class QLabel; 41class QLabel;
41class QLineEdit; 42class QLineEdit;
@@ -85,9 +86,13 @@ class Checkbook : public QDialog
85 86
86 // Charts tab 87 // Charts tab
87 QWidget *initCharts(); 88 QWidget *initCharts();
88 //QComboBox *graphList; 89 GraphInfo *graphInfo;
90 QComboBox *graphList;
89 Graph *graphWidget; 91 Graph *graphWidget;
90 92
93 void drawBalanceChart();
94 void drawCategoryChart( bool = TRUE );
95
91 protected slots: 96 protected slots:
92 void accept(); 97 void accept();
93 98
diff --git a/noncore/apps/checkbook/graph.cpp b/noncore/apps/checkbook/graph.cpp
index bae92da..a0d8b78 100644
--- a/noncore/apps/checkbook/graph.cpp
+++ b/noncore/apps/checkbook/graph.cpp
@@ -29,13 +29,13 @@
29#include "graph.h" 29#include "graph.h"
30#include "graphinfo.h" 30#include "graphinfo.h"
31 31
32#include <qcolor.h>
33#include <qfontmetrics.h>
32#include <qpainter.h> 34#include <qpainter.h>
33 35
34Graph::Graph( QWidget *parent, GraphInfo *d, const QString &name, int flags ) 36Graph::Graph( QWidget *parent, GraphInfo *d, const QString &name, int flags )
35 : QWidget( parent, name, flags ) 37 : QWidget( parent, name, flags )
36{ 38{
37 setBackgroundMode( QWidget::PaletteBase );
38
39 data = d; 39 data = d;
40 40
41 graph.setOptimization( QPixmap::BestOptim ); 41 graph.setOptimization( QPixmap::BestOptim );
@@ -82,31 +82,98 @@ void Graph::initGraph()
82 { 82 {
83 case GraphInfo::BarChart : 83 case GraphInfo::BarChart :
84 { 84 {
85 drawBarChart(); 85 drawBarChart( width(), height(), data->maxValue() );
86 } 86 }
87 break; 87 break;
88 case GraphInfo::LineChart : 88 case GraphInfo::LineChart :
89 { 89 {
90 drawLineChart(); 90 //drawLineChart( p, s, min, max );
91 } 91 }
92 break; 92 break;
93 case GraphInfo::PieChart : 93 case GraphInfo::PieChart :
94 { 94 {
95 drawPieChart(); 95 drawPieChart( width(), height(), data->totalValue() );
96 } 96 }
97 }; 97 };
98} 98}
99 99
100void Graph::drawBarChart() 100void Graph::drawBarChart( int width, int height, float max )
101{
102 QPainter p( &graph );
103
104 // Try to set the font size smaller for text
105 QFont f = font();
106 f.setPointSize( 8 );
107 p.setFont( f );
108
109 int x = 0;
110 int i = 0;
111 int n = data->numberDataPoints();
112 QFontMetrics fm=fontMetrics();
113 int fh = fm.height();
114 int fw;
115
116 QColor c( 0, 0, 255);
117 p.setBrush( c );
118
119 for (DataPointInfo *dp = data->firstDataPoint(); dp; dp = data->nextDataPoint() )
120 {
121 int bw = ( width - width / 4 - x ) / ( n - i );
122 int bh = int( ( height - height / 4 - 1 ) * dp->value() / max );
123 p.drawRect( width / 8 + x, height - height / 8 - 1 - bh, bw, bh );
124 fw = fm.width( dp->label() );
125 p.drawText( width / 8 + x - fw / 2 + bw / 2, height - height / 8, fw,
126 fh + height / 8, AlignTop | AlignHCenter, dp->label() );
127 // WordBreak | AlignTop | AlignHCenter, dp->label() );
128 i++;
129 x += bw;
130 }
131}
132
133void Graph::drawLineChart( int width, int height, float max )
101{ 134{
102 //Find max value in GraphInfo->dataPoints() - make function in GraphInfo!!!
103} 135}
104 136
105void Graph::drawLineChart() 137void Graph::drawPieChart( int width, int height, float sum )
106{ 138{
139 QPainter p( &graph );
140
141 // Try to set the font size smaller for text
142 QFont f = font();
143 f.setPointSize( 8 );
144 p.setFont( f );
145
146 int n = data->numberDataPoints();
147
148 int apos = -90 * 16;
149
150 int xd = width - width / 5;
151 int yd = height - height / 5;
152
153 int i = 0;
154
155 QColor c;
156
157 for (DataPointInfo *dp = data->firstDataPoint(); dp; dp = data->nextDataPoint() )
158 {
159 c.setHsv( ( i *255) / n, 255, 255 );
160 p.setBrush( c );
161
162 int a = int( ( dp->value() * 360.0 ) / sum * 16.0 + 0.5 );
163 p.drawPie( width/10, height/10, xd, yd, -apos, -a );
164 apos += a;
165 i++;
107} 166}
108 167
109void Graph::drawPieChart() 168 double apos2 = -90 * 3.14159 / 180;
169 for (DataPointInfo *dp = data->firstDataPoint(); dp; dp = data->nextDataPoint() )
110{ 170{
171 double a = dp->value() *360 / sum * 3.14159 / 180;
172 int x = int( cos( apos2 + a/2 ) * width * 5/16 + width/2 + 0.5 );
173 int y = int( sin( apos2 + a/2 ) * height * 5/16 + height/2 + 0.5 );
174 p.drawText( x - width/8, y - height/8, width/4, height/4, WordBreak | AlignCenter,
175 dp->label() );
176 apos2 += a;
177 }
111} 178}
112 179
diff --git a/noncore/apps/checkbook/graph.h b/noncore/apps/checkbook/graph.h
index 7379be7..40b23cd 100644
--- a/noncore/apps/checkbook/graph.h
+++ b/noncore/apps/checkbook/graph.h
@@ -33,6 +33,7 @@
33#include <qwidget.h> 33#include <qwidget.h>
34 34
35class GraphInfo; 35class GraphInfo;
36class QPainter;
36 37
37class Graph : public QWidget 38class Graph : public QWidget
38{ 39{
@@ -55,9 +56,9 @@ class Graph : public QWidget
55 QPixmap graph; 56 QPixmap graph;
56 57
57 void initGraph(); 58 void initGraph();
58 void drawBarChart(); 59 void drawBarChart( int, int, float );
59 void drawLineChart(); 60 void drawLineChart( int, int, float );
60 void drawPieChart(); 61 void drawPieChart( int, int, float );
61}; 62};
62 63
63#endif 64#endif
diff --git a/noncore/apps/checkbook/graphinfo.cpp b/noncore/apps/checkbook/graphinfo.cpp
index 7b06bdb..ec6a465 100644
--- a/noncore/apps/checkbook/graphinfo.cpp
+++ b/noncore/apps/checkbook/graphinfo.cpp
@@ -38,6 +38,17 @@ GraphInfo::GraphInfo( GraphType type, DataPointList *data, const QString &title,
38 yt = ytitle; 38 yt = ytitle;
39} 39}
40 40
41GraphInfo::~GraphInfo()
42{
43 if ( d )
44 {
45 for ( DataPointInfo *data = d->first(); data; data = d->next() )
46 {
47 delete data;
48 }
49 }
50}
51
41GraphInfo::GraphType GraphInfo::graphType() 52GraphInfo::GraphType GraphInfo::graphType()
42{ 53{
43 return t; 54 return t;
@@ -58,14 +69,42 @@ void GraphInfo::setDataPoints( DataPointList *data )
58 d = data; 69 d = data;
59} 70}
60 71
61float GraphInfo::maxValue() 72DataPointInfo *GraphInfo::firstDataPoint()
62{ 73{
63 float max; 74 return( d->first() );
75}
64 76
77DataPointInfo *GraphInfo::nextDataPoint()
78{
79 return( d->next() );
65} 80}
66 81
67float GraphInfo::minValue() 82int GraphInfo::numberDataPoints()
68{ 83{
84 return( d->count() );
85}
86
87float GraphInfo::maxValue()
88{
89 float max = 0.0;
90 for ( DataPointInfo *data = d->first(); data; data = d->next() )
91 {
92 if ( data->value() > max )
93 {
94 max = data->value();
95 }
96 }
97 return max;
98}
99
100float GraphInfo::totalValue()
101{
102 float sum = 0.0;
103 for ( DataPointInfo *data = d->first(); data; data = d->next() )
104 {
105 sum += data->value();
106 }
107 return sum;
69} 108}
70 109
71void GraphInfo::setGraphTitle( const QString &title ) 110void GraphInfo::setGraphTitle( const QString &title )
diff --git a/noncore/apps/checkbook/graphinfo.h b/noncore/apps/checkbook/graphinfo.h
index 4ad1dc9..620da74 100644
--- a/noncore/apps/checkbook/graphinfo.h
+++ b/noncore/apps/checkbook/graphinfo.h
@@ -43,6 +43,8 @@ class DataPointInfo
43 const QString &label() { return l; } 43 const QString &label() { return l; }
44 float value() { return v; } 44 float value() { return v; }
45 45
46 void addToValue( float value ) { v += value; }
47
46 private: 48 private:
47 QString l; 49 QString l;
48 float v; 50 float v;
@@ -57,15 +59,19 @@ class GraphInfo
57 59
58 GraphInfo( GraphType = BarChart, DataPointList * = 0x0, 60 GraphInfo( GraphType = BarChart, DataPointList * = 0x0,
59 const QString & = 0x0, const QString & = 0x0, const QString & = 0x0 ); 61 const QString & = 0x0, const QString & = 0x0, const QString & = 0x0 );
62 ~GraphInfo();
60 63
61 GraphInfo::GraphType graphType(); 64 GraphInfo::GraphType graphType();
62 void setGraphType( GraphType ); 65 void setGraphType( GraphType );
63 66
64 DataPointList *dataPoints(); 67 DataPointList *dataPoints();
65 void setDataPoints( DataPointList * ); 68 void setDataPoints( DataPointList * );
69 DataPointInfo *firstDataPoint();
70 DataPointInfo *nextDataPoint();
71 int numberDataPoints();
66 72
67 float maxValue(); 73 float maxValue();
68 float minValue(); 74 float totalValue();
69 75
70 void setGraphTitle( const QString & ); 76 void setGraphTitle( const QString & );
71 void setXAxisTitle( const QString & ); 77 void setXAxisTitle( const QString & );