00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kexthighscore_tab.h"
00021 #include "kexthighscore_tab.moc"
00022
00023 #include <qlayout.h>
00024 #include <qlabel.h>
00025 #include <qvgroupbox.h>
00026 #include <qgrid.h>
00027 #include <qheader.h>
00028
00029 #include <kdialogbase.h>
00030 #include <klistview.h>
00031 #include <kdebug.h>
00032 #include <kglobal.h>
00033
00034 #include "kexthighscore.h"
00035 #include "kexthighscore_internal.h"
00036
00037
00038 namespace KExtHighscore
00039 {
00040
00041
00042 PlayersCombo::PlayersCombo(QWidget *parent, const char *name)
00043 : QComboBox(parent, name)
00044 {
00045 const PlayerInfos &p = internal->playerInfos();
00046 for (uint i = 0; i<p.nbEntries(); i++)
00047 insertItem(p.prettyName(i));
00048 insertItem(QString("<") + i18n("all") + '>');
00049 connect(this, SIGNAL(activated(int)), SLOT(activatedSlot(int)));
00050 }
00051
00052 void PlayersCombo::activatedSlot(int i)
00053 {
00054 const PlayerInfos &p = internal->playerInfos();
00055 if ( i==(int)p.nbEntries() ) emit allSelected();
00056 else if ( i==(int)p.nbEntries()+1 ) emit noneSelected();
00057 else emit playerSelected(i);
00058 }
00059
00060 void PlayersCombo::load()
00061 {
00062 const PlayerInfos &p = internal->playerInfos();
00063 for (uint i = 0; i<p.nbEntries(); i++)
00064 changeItem(p.prettyName(i), i);
00065 }
00066
00067
00068 AdditionalTab::AdditionalTab(QWidget *parent, const char *name)
00069 : QWidget(parent, name)
00070 {
00071 QVBoxLayout *top = new QVBoxLayout(this, KDialogBase::marginHint(),
00072 KDialogBase::spacingHint());
00073
00074 QHBoxLayout *hbox = new QHBoxLayout(top);
00075 QLabel *label = new QLabel(i18n("Select player:"), this);
00076 hbox->addWidget(label);
00077 _combo = new PlayersCombo(this);
00078 connect(_combo, SIGNAL(playerSelected(uint)),
00079 SLOT(playerSelected(uint)));
00080 connect(_combo, SIGNAL(allSelected()), SLOT(allSelected()));
00081 hbox->addWidget(_combo);
00082 hbox->addStretch(1);
00083 }
00084
00085 void AdditionalTab::init()
00086 {
00087 uint id = internal->playerInfos().id();
00088 _combo->setCurrentItem(id);
00089 playerSelected(id);
00090 }
00091
00092 void AdditionalTab::allSelected()
00093 {
00094 display(internal->playerInfos().nbEntries());
00095 }
00096
00097 QString AdditionalTab::percent(uint n, uint total, bool withBraces)
00098 {
00099 if ( n==0 || total==0 ) return QString::null;
00100 QString s = QString("%1%").arg(100.0 * n / total, 0, 'f', 1);
00101 return (withBraces ? QString("(") + s + ")" : s);
00102 }
00103
00104 void AdditionalTab::load()
00105 {
00106 _combo->load();
00107 }
00108
00109
00110
00111 const char *StatisticsTab::COUNT_LABELS[Nb_Counts] = {
00112 I18N_NOOP("Total:"), I18N_NOOP("Won:"), I18N_NOOP("Lost:")
00113 };
00114 const char *StatisticsTab::TREND_LABELS[Nb_Trends] = {
00115 I18N_NOOP("Current:"), I18N_NOOP("Max won:"), I18N_NOOP("Max lost:")
00116 };
00117
00118 StatisticsTab::StatisticsTab(QWidget *parent)
00119 : AdditionalTab(parent, "statistics_tab")
00120 {
00121
00122 QVBoxLayout *top = static_cast<QVBoxLayout *>(layout());
00123
00124 QHBoxLayout *hbox = new QHBoxLayout(top);
00125 QVBoxLayout *vbox = new QVBoxLayout(hbox);
00126 QVGroupBox *group = new QVGroupBox(i18n("Game Counts"), this);
00127 vbox->addWidget(group);
00128 QGrid *grid = new QGrid(3, group);
00129 grid->setSpacing(KDialogBase::spacingHint());
00130 for (uint k=0; k<Nb_Counts; k++) {
00131 (void)new QLabel(i18n(COUNT_LABELS[k]), grid);
00132 _nbs[k] = new QLabel(grid);
00133 _percents[k] = new QLabel(grid);
00134 }
00135
00136 group = new QVGroupBox(i18n("Trends"), this);
00137 vbox->addWidget(group);
00138 grid = new QGrid(2, group);
00139 grid->setSpacing(KDialogBase::spacingHint());
00140 for (uint k=0; k<Nb_Trends; k++) {
00141 (void)new QLabel(i18n(TREND_LABELS[k]), grid);
00142 _trends[k] = new QLabel(grid);
00143 }
00144
00145 hbox->addStretch(1);
00146 top->addStretch(1);
00147 }
00148
00149 void StatisticsTab::load()
00150 {
00151 AdditionalTab::load();
00152 const PlayerInfos &pi = internal->playerInfos();
00153 uint nb = pi.nbEntries();
00154 _data.resize(nb+1);
00155 for (uint i=0; i<_data.size()-1; i++) {
00156 _data[i].count[Total] = pi.item("nb games")->read(i).toUInt();
00157 _data[i].count[Lost] = pi.item("nb lost games")->read(i).toUInt()
00158 + pi.item("nb black marks")->read(i).toUInt();
00159 _data[i].count[Won] = _data[i].count[Total] - _data[i].count[Lost];
00160 _data[i].trend[CurrentTrend] =
00161 pi.item("current trend")->read(i).toInt();
00162 _data[i].trend[WonTrend] = pi.item("max won trend")->read(i).toUInt();
00163 _data[i].trend[LostTrend] =
00164 -(int)pi.item("max lost trend")->read(i).toUInt();
00165 }
00166
00167 for (uint k=0; k<Nb_Counts; k++) _data[nb].count[k] = 0;
00168 for (uint k=0; k<Nb_Trends; k++) _data[nb].trend[k] = 0;
00169 for (uint i=0; i<_data.size()-1; i++) {
00170 for (uint k=0; k<Nb_Counts; k++)
00171 _data[nb].count[k] += _data[i].count[k];
00172 for (uint k=0; k<Nb_Trends; k++)
00173 _data[nb].trend[k] += _data[i].trend[k];
00174 }
00175 for (uint k=0; k<Nb_Trends; k++)
00176 _data[nb].trend[k] /= (_data.size()-1);
00177
00178 init();
00179 }
00180
00181 QString StatisticsTab::percent(const Data &d, Count count) const
00182 {
00183 if ( count==Total ) return QString::null;
00184 return AdditionalTab::percent(d.count[count], d.count[Total], true);
00185 }
00186
00187 void StatisticsTab::display(uint i)
00188 {
00189 const Data &d = _data[i];
00190 for (uint k=0; k<Nb_Counts; k++) {
00191 _nbs[k]->setText(QString::number(d.count[k]));
00192 _percents[k]->setText(percent(d, (Count)k));
00193 }
00194 for (uint k=0; k<Nb_Trends; k++) {
00195 QString s;
00196 if ( d.trend[k]>0 ) s = '+';
00197 int prec = (i==internal->playerInfos().nbEntries() ? 1 : 0);
00198 _trends[k]->setText(s + QString::number(d.trend[k], 'f', prec));
00199 }
00200 }
00201
00202
00203 HistogramTab::HistogramTab(QWidget *parent)
00204 : AdditionalTab(parent, "histogram_tab")
00205 {
00206
00207 QVBoxLayout *top = static_cast<QVBoxLayout *>(layout());
00208
00209 _list = new KListView(this);
00210 _list->setSelectionMode(QListView::NoSelection);
00211 _list->setItemMargin(3);
00212 _list->setAllColumnsShowFocus(true);
00213 _list->setSorting(-1);
00214 _list->header()->setClickEnabled(false);
00215 _list->header()->setMovingEnabled(false);
00216 top->addWidget(_list);
00217
00218 _list->addColumn(i18n("From"));
00219 _list->addColumn(i18n("To"));
00220 _list->addColumn(i18n("Count"));
00221 _list->addColumn(i18n("Percent"));
00222 for (uint i=0; i<4; i++) _list->setColumnAlignment(i, AlignRight);
00223 _list->addColumn(QString::null);
00224
00225 const Item *sitem = internal->scoreInfos().item("score")->item();
00226 const PlayerInfos &pi = internal->playerInfos();
00227 const QMemArray<uint> &sh = pi.histogram();
00228 for (uint k=1; k<pi.histoSize(); k++) {
00229 QString s1 = sitem->pretty(0, sh[k-1]);
00230 QString s2;
00231 if ( k==sh.size() ) s2 = "...";
00232 else if ( sh[k]!=sh[k-1]+1 ) s2 = sitem->pretty(0, sh[k]);
00233 (void)new KListViewItem(_list, s1, s2);
00234 }
00235 }
00236
00237 void HistogramTab::load()
00238 {
00239 AdditionalTab::load();
00240 const PlayerInfos &pi = internal->playerInfos();
00241 uint n = pi.nbEntries();
00242 uint s = pi.histoSize() - 1;
00243 _counts.resize((n+1) * s);
00244 _data.fill(0, n+1);
00245 for (uint k=0; k<s; k++) {
00246 _counts[n*s + k] = 0;
00247 for (uint i=0; i<n; i++) {
00248 uint nb = pi.item(pi.histoName(k+1))->read(i).toUInt();
00249 _counts[i*s + k] = nb;
00250 _counts[n*s + k] += nb;
00251 _data[i] += nb;
00252 _data[n] += nb;
00253 }
00254 }
00255
00256 init();
00257 }
00258
00259 void HistogramTab::display(uint i)
00260 {
00261 const PlayerInfos &pi = internal->playerInfos();
00262 QListViewItem *item = _list->firstChild();
00263 uint s = pi.histoSize() - 1;
00264 for (int k=s-1; k>=0; k--) {
00265 uint nb = _counts[i*s + k];
00266 item->setText(2, QString::number(nb));
00267 item->setText(3, percent(nb, _data[i]));
00268 uint width = (_data[i]==0 ? 0 : qRound(150.0 * nb / _data[i]));
00269 QPixmap pixmap(width, 10);
00270 pixmap.fill(blue);
00271 item->setPixmap(4, pixmap);
00272 item = item->nextSibling();
00273 }
00274 }
00275
00276 }