moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / ktouch / src / ktouchstatistics.cpp
blob937d65c5a94741bcf651dbbd15ea08552cc23a58
1 /***************************************************************************
2 * ktouchstatistics.cpp *
3 * -------------------- *
4 * Copyright (C) 2000 by Håvard Frøiland, 2004 by Andreas Nicolai *
5 * ghorwin@users.sourceforge.net *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 ***************************************************************************/
13 #include "ktouchstatistics.h"
14 #include "ktouchstatistics.moc"
16 #include <qlcdnumber.h>
17 #include <qslider.h>
18 #include <qlabel.h>
19 #include <qprogressbar.h>
20 #include <qradiobutton.h>
21 #include <qbuttongroup.h>
23 #include <kdebug.h>
24 #include <kpushbutton.h>
25 #include <kmessagebox.h>
26 #include <klocale.h>
28 #include <list>
29 #include <utility> // for std::min and std::max
31 #include "ktouchtrainer.h"
32 #include "ktouchchartwidget.h"
33 using std::set;
34 using std::list;
36 KTouchStatistics::KTouchStatistics(QWidget *parent, KTouchTrainer* trainer)
37 : KTouchStatisticsLayout(parent), m_trainer(trainer)
39 sessionCountSlider->setMaxValue(m_trainer->m_sessionHistory.count());
40 sessionCountSlider->setValue(m_trainer->m_sessionHistory.count());
41 chartWidget->m_trainer = trainer;
42 chartWidget->setChartType( KTouchChartWidget::CharsPerMinute );
43 connect(closeButton, SIGNAL(clicked()), this, SLOT(accept()) );
44 connect(clearButton, SIGNAL(clicked()), this, SLOT(clearHistory()) );
45 connect(sessionCountSlider, SIGNAL(valueChanged(int)), this, SLOT(updateAverageTab()) );
46 connect(chartTypeButtonGroup, SIGNAL(clicked(int)), this, SLOT(updateChartTab()) );
49 KTouchStatistics::~KTouchStatistics() {
52 void KTouchStatistics::showEvent(QShowEvent*) {
53 // adjust slider range in case some sessions have been added
54 sessionCountSlider->setMaxValue(m_trainer->m_sessionHistory.count());
55 // update the tabs
56 updateCurrentTab();
57 updateAverageTab();
58 updateChartTab();
61 void KTouchStatistics::updateCurrentTab() {
62 // general stats group
63 elapsedTimeLCD->display(static_cast<int>(m_trainer->m_session.m_elapsedTime/1000));
64 totalCharsLCD->display(static_cast<int>(m_trainer->m_session.m_totalChars) );
65 wrongCharsLCD->display(static_cast<int>(m_trainer->m_session.m_totalChars-m_trainer->m_session.m_correctChars) );
66 wordsLCD->display(static_cast<int>(m_trainer->m_session.m_words) );
67 // typing rate group
68 charSpeedLCD->display(static_cast<int>(m_trainer->m_session.charSpeed()) );
69 wordSpeedLCD->display(static_cast<int>(m_trainer->m_session.wordSpeed()) );
70 // accuracy
71 correctnessBar->setProgress(static_cast<int>(m_trainer->m_session.correctness()*100) );
72 // worst miss/hit ratio group
73 std::list<KTouchCharStats> charList( m_trainer->m_session.sortedCharStats() );
74 std::list<KTouchCharStats>::const_iterator it=charList.begin();
75 unsigned int i=0;
76 for (; i<8 && it!=charList.end(); ++i, ++it) {
77 if (it->hitMissRatio()==0)
78 break; // stop listing keys when their hit-miss-ration is zero
79 switch (i) {
80 case 0 : charLabel1->setText( it->m_char ); charProgress1->setEnabled(true);
81 charProgress1->setProgress( it->hitMissRatio() ); break;
82 case 1 : charLabel2->setText( it->m_char ); charProgress2->setEnabled(true);
83 charProgress2->setProgress( it->hitMissRatio() ); break;
84 case 2 : charLabel3->setText( it->m_char ); charProgress3->setEnabled(true);
85 charProgress3->setProgress( it->hitMissRatio() ); break;
86 case 3 : charLabel4->setText( it->m_char ); charProgress4->setEnabled(true);
87 charProgress4->setProgress( it->hitMissRatio() ); break;
88 case 4 : charLabel5->setText( it->m_char ); charProgress5->setEnabled(true);
89 charProgress5->setProgress( it->hitMissRatio() ); break;
90 case 5 : charLabel6->setText( it->m_char ); charProgress6->setEnabled(true);
91 charProgress6->setProgress( it->hitMissRatio() ); break;
92 case 6 : charLabel7->setText( it->m_char ); charProgress7->setEnabled(true);
93 charProgress7->setProgress( it->hitMissRatio() ); break;
94 case 7 : charLabel8->setText( it->m_char ); charProgress8->setEnabled(true);
95 charProgress8->setProgress( it->hitMissRatio() ); break;
98 for(; i<8; ++i) {
99 switch (i) {
100 case 0 : charLabel1->setText(" "); charProgress1->setProgress(0); charProgress1->setEnabled(false); break;
101 case 1 : charLabel2->setText(" "); charProgress2->setProgress(0); charProgress2->setEnabled(false); break;
102 case 2 : charLabel3->setText(" "); charProgress3->setProgress(0); charProgress3->setEnabled(false); break;
103 case 3 : charLabel4->setText(" "); charProgress4->setProgress(0); charProgress4->setEnabled(false); break;
104 case 4 : charLabel5->setText(" "); charProgress5->setProgress(0); charProgress5->setEnabled(false); break;
105 case 5 : charLabel6->setText(" "); charProgress6->setProgress(0); charProgress6->setEnabled(false); break;
106 case 6 : charLabel7->setText(" "); charProgress7->setProgress(0); charProgress7->setEnabled(false); break;
107 case 7 : charLabel8->setText(" "); charProgress8->setProgress(0); charProgress8->setEnabled(false); break;
112 void KTouchStatistics::updateChartTab() {
113 if (m_trainer->m_sessionHistory.size()<2) {
114 chartTypeButtonGroup->setEnabled(false);
115 chartWidget->setEraseColor( Qt::gray );
117 else {
118 chartTypeButtonGroup->setEnabled(true);
119 chartWidget->setEraseColor( Qt::white );
121 if (charSpeedButton->isChecked())
122 chartWidget->setChartType( KTouchChartWidget::CharsPerMinute );
123 else if (wordSpeedButton->isChecked())
124 chartWidget->setChartType( KTouchChartWidget::WordsPerMinute );
125 else if (accuracyButton->isChecked())
126 chartWidget->setChartType( KTouchChartWidget::Accuracy );
127 else if (timeButton->isChecked())
128 chartWidget->setChartType( KTouchChartWidget::ElapsedTime );
131 void KTouchStatistics::clearHistory() {
132 if (KMessageBox::questionYesNo(0, i18n("Do you really want to clear the session history?"))==KMessageBox::Yes) {
133 sessionCountSlider->setValue(0);
134 sessionCountSlider->setMaxValue(0);
135 m_trainer->m_sessionHistory.clear();
136 updateAverageTab();
137 updateChartTab();
141 void KTouchStatistics::updateAverageTab() {
142 if (sessionCountSlider->value()==0)
143 sessionCountLabel->setText( i18n("training session.") );
144 else
145 sessionCountLabel->setText( i18n("%1 training sessions.").arg(sessionCountSlider->value()+1));
146 KTouchTrainingSession sessionSum=m_trainer->m_session;
147 KTouchTrainingSession sessionMin=m_trainer->m_session;
148 KTouchTrainingSession sessionMax=m_trainer->m_session;
149 double charSpeedSum, charSpeedMin, charSpeedMax;
150 charSpeedSum=charSpeedMin=charSpeedMax=m_trainer->m_session.charSpeed();
151 double wordSpeedSum, wordSpeedMin, wordSpeedMax;
152 wordSpeedSum=wordSpeedMin=wordSpeedMax=m_trainer->m_session.wordSpeed();
153 double correctnessSum, correctnessMin, correctnessMax;
154 correctnessSum=correctnessMin=correctnessMax=m_trainer->m_session.correctness();
155 std::set<KTouchCharStats> charStatsSum = m_trainer->m_session.m_charStats;
156 unsigned int lastSession=m_trainer->m_sessionHistory.size()-1;
157 for (int i=0; i<sessionCountSlider->value(); ++i) {
158 const KTouchTrainingSession &session = m_trainer->m_sessionHistory[lastSession-i];
159 unsigned int elapsedTime = session.m_elapsedTime;
160 unsigned int totalChars = session.m_totalChars;
161 unsigned int correctChars = session.m_correctChars;
162 unsigned int words = session.m_words;
163 double charSpeed = session.charSpeed();
164 double wordSpeed = session.wordSpeed();
165 double correctness = session.correctness();
166 sessionSum.m_elapsedTime += elapsedTime;
167 sessionMin.m_elapsedTime = std::min(elapsedTime, sessionMin.m_elapsedTime);
168 sessionMax.m_elapsedTime = std::max(elapsedTime, sessionMax.m_elapsedTime);
169 sessionSum.m_totalChars += totalChars;
170 sessionMin.m_totalChars = std::min(totalChars, sessionMin.m_totalChars);
171 sessionMax.m_totalChars = std::max(totalChars, sessionMax.m_totalChars);
172 sessionSum.m_correctChars += correctChars;
173 sessionMin.m_correctChars = std::min(correctChars, sessionMin.m_correctChars);
174 sessionMax.m_correctChars = std::max(correctChars, sessionMax.m_correctChars);
175 sessionSum.m_words += words;
176 sessionMin.m_words = std::min(words, sessionMin.m_words);
177 sessionMax.m_words = std::max(words, sessionMax.m_words);
178 // sum up and store min/max of calculated stats
179 charSpeedSum += charSpeed;
180 charSpeedMin = std::min(charSpeed, charSpeedMin);
181 charSpeedMax = std::max(charSpeed, charSpeedMax);
182 wordSpeedSum += wordSpeed;
183 wordSpeedMin = std::min(wordSpeed, wordSpeedMin);
184 wordSpeedMax = std::max(wordSpeed, wordSpeedMax);
185 correctnessSum += correctness;
186 correctnessMin = std::min(correctness, correctnessMin);
187 correctnessMax = std::max(correctness, correctnessMax);
188 // store character stats
189 for (set<KTouchCharStats>::iterator srcIt = session.m_charStats.begin(); srcIt != session.m_charStats.end(); ++srcIt) {
190 set<KTouchCharStats>::iterator it = charStatsSum.find( KTouchCharStats(srcIt->m_char,0,0) );
191 if (it==charStatsSum.end())
192 charStatsSum.insert( *srcIt );
193 else {
194 const_cast<KTouchCharStats&>(*it).m_correctCount += srcIt->m_correctCount;
195 const_cast<KTouchCharStats&>(*it).m_wrongCount += srcIt->m_wrongCount;
199 // calculate averaged values
200 if (sessionCountSlider->value() > 0) {
201 unsigned int sessionCount = sessionCountSlider->value()+1;
202 // now calculate the average numbers
203 sessionSum.m_elapsedTime /= sessionCount;
204 sessionSum.m_totalChars /= sessionCount;
205 sessionSum.m_correctChars /= sessionCount;
206 sessionSum.m_words /= sessionCount;
207 charSpeedSum /= sessionCount;
208 wordSpeedSum /= sessionCount;
209 correctnessSum /= sessionCount;
211 // sort char stats (worst hit-miss-ratio first in list)
212 list<KTouchCharStats> charStatsList(charStatsSum.begin(), charStatsSum.end());
213 charStatsList.sort( greaterHitMissRatio );
215 // update widgets
216 charSpeedAverageLCD->display(static_cast<int>(charSpeedSum) );
217 charSpeedMinLCD->display(static_cast<int>(charSpeedMin) );
218 charSpeedMaxLCD->display(static_cast<int>(charSpeedMax) );
219 wordSpeedAverageLCD->display(static_cast<int>(wordSpeedSum) );
220 wordSpeedMinLCD->display(static_cast<int>(wordSpeedMin) );
221 wordSpeedMaxLCD->display(static_cast<int>(wordSpeedMax) );
222 correctnessAverageBar->setProgress(static_cast<int>(correctnessSum*100) );
223 correctnessMinLCD->display(static_cast<int>(correctnessMin*100) );
224 correctnessMaxLCD->display(static_cast<int>(correctnessMax*100) );
225 // update the focus characters
226 list<KTouchCharStats>::const_iterator it=charStatsList.begin();
227 unsigned int i=0;
228 for (; i<6 && it!=charStatsList.end(); ++i, ++it) {
229 if (it->hitMissRatio()==0)
230 break; // stop listing keys when their hit-miss-ration is zero
231 switch (i) {
232 case 0 : charLabel1_2->setText( it->m_char ); charProgress1_2->setEnabled(true);
233 charProgress1_2->setProgress( it->hitMissRatio() ); break;
234 case 1 : charLabel2_2->setText( it->m_char ); charProgress2_2->setEnabled(true);
235 charProgress2_2->setProgress( it->hitMissRatio() ); break;
236 case 2 : charLabel3_2->setText( it->m_char ); charProgress3_2->setEnabled(true);
237 charProgress3_2->setProgress( it->hitMissRatio() ); break;
238 case 3 : charLabel4_2->setText( it->m_char ); charProgress4_2->setEnabled(true);
239 charProgress4_2->setProgress( it->hitMissRatio() ); break;
240 case 4 : charLabel5_2->setText( it->m_char ); charProgress5_2->setEnabled(true);
241 charProgress5_2->setProgress( it->hitMissRatio() ); break;
242 case 5 : charLabel6_2->setText( it->m_char ); charProgress6_2->setEnabled(true);
243 charProgress6_2->setProgress( it->hitMissRatio() ); break;
246 for(; i<6; ++i) {
247 switch (i) {
248 case 0 : charLabel1_2->setText(" "); charProgress1_2->setProgress(0); charProgress1_2->setEnabled(false); break;
249 case 1 : charLabel2_2->setText(" "); charProgress2_2->setProgress(0); charProgress2_2->setEnabled(false); break;
250 case 2 : charLabel3_2->setText(" "); charProgress3_2->setProgress(0); charProgress3_2->setEnabled(false); break;
251 case 3 : charLabel4_2->setText(" "); charProgress4_2->setProgress(0); charProgress4_2->setEnabled(false); break;
252 case 4 : charLabel5_2->setText(" "); charProgress5_2->setProgress(0); charProgress5_2->setEnabled(false); break;
253 case 5 : charLabel6_2->setText(" "); charProgress6_2->setProgress(0); charProgress6_2->setEnabled(false); break;