• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • libtdegames
 

libtdegames

  • libtdegames
  • highscore
kexthighscore_gui.cpp
1/*
2 This file is part of the TDE games library
3 Copyright (C) 2001-2003 Nicolas Hadacek (hadacek@kde.org)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18*/
19
20#include "kexthighscore_gui.h"
21#include "kexthighscore_gui.moc"
22
23#include <tqlayout.h>
24#include <tqtextstream.h>
25#include <tqheader.h>
26#include <tqgrid.h>
27#include <tqvgroupbox.h>
28
29#include <tdeapplication.h>
30#include <tdemessagebox.h>
31#include <kurllabel.h>
32#include <kopenwith.h>
33#include <krun.h>
34#include <tdefiledialog.h>
35#include <tdetempfile.h>
36#include <tdeio/netaccess.h>
37#include <kiconloader.h>
38
39#include "kexthighscore_internal.h"
40#include "kexthighscore.h"
41#include "kexthighscore_tab.h"
42
43
44namespace KExtHighscore
45{
46
47//-----------------------------------------------------------------------------
48ShowItem::ShowItem(TQListView *list, bool highlight)
49 : TDEListViewItem(list), _highlight(highlight)
50{}
51
52void ShowItem::paintCell(TQPainter *p, const TQColorGroup &cg,
53 int column, int width, int align)
54{
55 TQColorGroup cgrp(cg);
56 if (_highlight) cgrp.setColor(TQColorGroup::Text, red);
57 TDEListViewItem::paintCell(p, cgrp, column, width, align);
58}
59
60//-----------------------------------------------------------------------------
61ScoresList::ScoresList(TQWidget *parent)
62 : TDEListView(parent)
63{
64 setSelectionMode(TQListView::NoSelection);
65 setItemMargin(3);
66 setAllColumnsShowFocus(true);
67 setSorting(-1);
68 header()->setClickEnabled(false);
69 header()->setMovingEnabled(false);
70}
71
72void ScoresList::addHeader(const ItemArray &items)
73{
74 addLineItem(items, 0, 0);
75}
76
77TQListViewItem *ScoresList::addLine(const ItemArray &items,
78 uint index, bool highlight)
79{
80 TQListViewItem *item = new ShowItem(this, highlight);
81 addLineItem(items, index, item);
82 return item;
83}
84
85void ScoresList::addLineItem(const ItemArray &items,
86 uint index, TQListViewItem *line)
87{
88 uint k = 0;
89 for (uint i=0; i<items.size(); i++) {
90 const ItemContainer &container = *items[i];
91 if ( !container.item()->isVisible() ) continue;
92 if (line) line->setText(k, itemText(container, index));
93 else {
94 addColumn( container.item()->label() );
95 setColumnAlignment(k, container.item()->alignment());
96 }
97 k++;
98 }
99}
100
101//-----------------------------------------------------------------------------
102HighscoresList::HighscoresList(TQWidget *parent)
103 : ScoresList(parent)
104{}
105
106TQString HighscoresList::itemText(const ItemContainer &item, uint row) const
107{
108 return item.pretty(row);
109}
110
111void HighscoresList::load(const ItemArray &items, int highlight)
112{
113 clear();
114 TQListViewItem *line = 0;
115 for (int j=items.nbEntries()-1; j>=0; j--) {
116 TQListViewItem *item = addLine(items, j, j==highlight);
117 if ( j==highlight ) line = item;
118 }
119 if (line) ensureItemVisible(line);
120}
121
122//-----------------------------------------------------------------------------
123HighscoresWidget::HighscoresWidget(TQWidget *parent)
124 : TQWidget(parent, "show_highscores_widget"),
125 _scoresUrl(0), _playersUrl(0), _statsTab(0), _histoTab(0)
126{
127 const ScoreInfos &s = internal->scoreInfos();
128 const PlayerInfos &p = internal->playerInfos();
129
130 TQVBoxLayout *vbox = new TQVBoxLayout(this, KDialogBase::spacingHint());
131
132 _tw = new TQTabWidget(this);
133 connect(_tw, TQ_SIGNAL(currentChanged(TQWidget *)), TQ_SLOT(tabChanged()));
134 vbox->addWidget(_tw);
135
136 // scores tab
137 _scoresList = new HighscoresList(_tw);
138 _scoresList->addHeader(s);
139 _tw->addTab(_scoresList, i18n("Best &Scores"));
140
141 // players tab
142 _playersList = new HighscoresList(_tw);
143 _playersList->addHeader(p);
144 _tw->addTab(_playersList, i18n("&Players"));
145
146 // statistics tab
147 if ( internal->showStatistics ) {
148 _statsTab = new StatisticsTab(_tw);
149 _tw->addTab(_statsTab, i18n("Statistics"));
150 }
151
152 // histogram tab
153 if ( p.histogram().size()!=0 ) {
154 _histoTab = new HistogramTab(_tw);
155 _tw->addTab(_histoTab, i18n("Histogram"));
156 }
157
158 // url labels
159 if ( internal->isWWHSAvailable() ) {
160 KURL url = internal->queryURL(ManagerPrivate::Scores);
161 _scoresUrl = new KURLLabel(url.url(),
162 i18n("View world-wide highscores"), this);
163 connect(_scoresUrl, TQ_SIGNAL(leftClickedURL(const TQString &)),
164 TQ_SLOT(showURL(const TQString &)));
165 vbox->addWidget(_scoresUrl);
166
167 url = internal->queryURL(ManagerPrivate::Players);
168 _playersUrl = new KURLLabel(url.url(),
169 i18n("View world-wide players"), this);
170 connect(_playersUrl, TQ_SIGNAL(leftClickedURL(const TQString &)),
171 TQ_SLOT(showURL(const TQString &)));
172 vbox->addWidget(_playersUrl);
173 }
174}
175
176void HighscoresWidget::changeTab(int i)
177{
178 if ( i!=_tw->currentPageIndex() )
179 _tw->setCurrentPage(i);
180}
181
182void HighscoresWidget::showURL(const TQString &url) const
183{
184 (void)new KRun(KURL(url));
185}
186
187void HighscoresWidget::load(int rank)
188{
189 _scoresList->load(internal->scoreInfos(), rank);
190 _playersList->load(internal->playerInfos(), internal->playerInfos().id());
191 if (_scoresUrl)
192 _scoresUrl->setURL(internal->queryURL(ManagerPrivate::Scores).url());
193 if (_playersUrl)
194 _playersUrl->setURL(internal->queryURL(ManagerPrivate::Players).url());
195 if (_statsTab) _statsTab->load();
196 if (_histoTab) _histoTab->load();
197}
198
199//-----------------------------------------------------------------------------
200HighscoresDialog::HighscoresDialog(int rank, TQWidget *parent)
201 : KDialogBase(internal->nbGameTypes()>1 ? TreeList : Plain,
202 i18n("Highscores"), Close|User1|User2, Close,
203 parent, "show_highscores", true, true,
204 KGuiItem(i18n("Configure..."), "configure"),
205 KGuiItem(i18n("Export..."))), _rank(rank), _tab(0)
206{
207 _widgets.resize(internal->nbGameTypes(), 0);
208
209 if ( internal->nbGameTypes()>1 ) {
210 for (uint i=0; i<internal->nbGameTypes(); i++) {
211 TQString title = internal->manager.gameTypeLabel(i, Manager::I18N);
212 TQString icon = internal->manager.gameTypeLabel(i, Manager::Icon);
213 TQWidget *w = addVBoxPage(title, TQString(),
214 BarIcon(icon, TDEIcon::SizeLarge));
215 if ( i==internal->gameType() ) createPage(w);
216 }
217
218 connect(this, TQ_SIGNAL(aboutToShowPage(TQWidget *)),
219 TQ_SLOT(createPage(TQWidget *)));
220 showPage(internal->gameType());
221 } else {
222 TQVBoxLayout *vbox = new TQVBoxLayout(plainPage());
223 createPage(plainPage());
224 vbox->addWidget(_widgets[0]);
225 setMainWidget(_widgets[0]);
226 }
227}
228
229void HighscoresDialog::createPage(TQWidget *page)
230{
231 internal->hsConfig().readCurrentConfig();
232 _current = page;
233 bool several = ( internal->nbGameTypes()>1 );
234 int i = (several ? pageIndex(page) : 0);
235 if ( _widgets[i]==0 ) {
236 _widgets[i] = new HighscoresWidget(page);
237 connect(_widgets[i], TQ_SIGNAL(tabChanged(int)), TQ_SLOT(tabChanged(int)));
238 }
239 uint type = internal->gameType();
240 if (several) internal->setGameType(i);
241 _widgets[i]->load(uint(i)==type ? _rank : -1);
242 if (several) setGameType(type);
243 _widgets[i]->changeTab(_tab);
244}
245
246void HighscoresDialog::slotUser1()
247{
248 if ( KExtHighscore::configure(this) )
249 createPage(_current);
250}
251
252void HighscoresDialog::slotUser2()
253{
254 KURL url = KFileDialog::getSaveURL(TQString(), TQString(), this);
255 if ( url.isEmpty() ) return;
256 if ( TDEIO::NetAccess::exists(url, true, this) ) {
257 KGuiItem gi = KStdGuiItem::save();
258 gi.setText(i18n("Overwrite"));
259 int res = KMessageBox::warningContinueCancel(this,
260 i18n("The file already exists. Overwrite?"),
261 i18n("Export"), gi);
262 if ( res==KMessageBox::Cancel ) return;
263 }
264 KTempFile tmp;
265 internal->exportHighscores(*tmp.textStream());
266 tmp.close();
267 TDEIO::NetAccess::upload(tmp.name(), url, this);
268 tmp.unlink();
269}
270
271//-----------------------------------------------------------------------------
272LastMultipleScoresList::LastMultipleScoresList(
273 const TQValueVector<Score> &scores, TQWidget *parent)
274 : ScoresList(parent), _scores(scores)
275{
276 const ScoreInfos &s = internal->scoreInfos();
277 addHeader(s);
278 for (uint i=0; i<scores.size(); i++) addLine(s, i, false);
279}
280
281void LastMultipleScoresList::addLineItem(const ItemArray &si,
282 uint index, TQListViewItem *line)
283{
284 uint k = 1; // skip "id"
285 for (uint i=0; i<si.size()-2; i++) {
286 if ( i==3 ) k = 5; // skip "date"
287 const ItemContainer *container = si[k];
288 k++;
289 if (line) line->setText(i, itemText(*container, index));
290 else {
291 addColumn( container->item()->label() );
292 setColumnAlignment(i, container->item()->alignment());
293 }
294 }
295}
296
297TQString LastMultipleScoresList::itemText(const ItemContainer &item,
298 uint row) const
299{
300 TQString name = item.name();
301 if ( name=="rank" )
302 return (_scores[row].type()==Won ? i18n("Winner") : TQString());
303 TQVariant v = _scores[row].data(name);
304 if ( name=="name" ) return v.toString();
305 return item.item()->pretty(row, v);
306}
307
308//-----------------------------------------------------------------------------
309TotalMultipleScoresList::TotalMultipleScoresList(
310 const TQValueVector<Score> &scores, TQWidget *parent)
311 : ScoresList(parent), _scores(scores)
312{
313 const ScoreInfos &s = internal->scoreInfos();
314 addHeader(s);
315 for (uint i=0; i<scores.size(); i++) addLine(s, i, false);
316}
317
318void TotalMultipleScoresList::addLineItem(const ItemArray &si,
319 uint index, TQListViewItem *line)
320{
321 const PlayerInfos &pi = internal->playerInfos();
322 uint k = 1; // skip "id"
323 for (uint i=0; i<4; i++) { // skip additional fields
324 const ItemContainer *container;
325 if ( i==2 ) container = pi.item("nb games");
326 else if ( i==3 ) container = pi.item("mean score");
327 else {
328 container = si[k];
329 k++;
330 }
331 if (line) line->setText(i, itemText(*container, index));
332 else {
333 TQString label =
334 (i==2 ? i18n("Won Games") : container->item()->label());
335 addColumn(label);
336 setColumnAlignment(i, container->item()->alignment());
337 }
338 }
339}
340
341TQString TotalMultipleScoresList::itemText(const ItemContainer &item,
342 uint row) const
343{
344 TQString name = item.name();
345 if ( name=="rank" ) return TQString::number(_scores.size()-row);
346 if ( name=="nb games" )
347 return TQString::number( _scores[row].data("nb won games").toUInt() );
348 TQVariant v = _scores[row].data(name);
349 if ( name=="name" ) return v.toString();
350 return item.item()->pretty(row, v);
351}
352
353
354//-----------------------------------------------------------------------------
355ConfigDialog::ConfigDialog(TQWidget *parent)
356 : KDialogBase(Swallow, i18n("Configure Highscores"),
357 Ok|Apply|Cancel, Cancel,
358 parent, "configure_highscores", true, true),
359 _saved(false), _WWHEnabled(0)
360{
361 TQWidget *page = 0;
362 TQTabWidget *tab = 0;
363 if ( internal->isWWHSAvailable() ) {
364 tab = new TQTabWidget(this);
365 setMainWidget(tab);
366 page = new TQWidget(tab);
367 tab->addTab(page, i18n("Main"));
368 } else {
369 page = new TQWidget(this);
370 setMainWidget(page);
371 }
372
373 TQGridLayout *pageTop =
374 new TQGridLayout(page, 2, 2, spacingHint(), spacingHint());
375
376 TQLabel *label = new TQLabel(i18n("Nickname:"), page);
377 pageTop->addWidget(label, 0, 0);
378 _nickname = new TQLineEdit(page);
379 connect(_nickname, TQ_SIGNAL(textChanged(const TQString &)),
380 TQ_SLOT(modifiedSlot()));
381 connect(_nickname, TQ_SIGNAL(textChanged(const TQString &)),
382 TQ_SLOT(nickNameChanged(const TQString &)));
383
384 _nickname->setMaxLength(16);
385 pageTop->addWidget(_nickname, 0, 1);
386
387 label = new TQLabel(i18n("Comment:"), page);
388 pageTop->addWidget(label, 1, 0);
389 _comment = new TQLineEdit(page);
390 connect(_comment, TQ_SIGNAL(textChanged(const TQString &)),
391 TQ_SLOT(modifiedSlot()));
392 _comment->setMaxLength(50);
393 pageTop->addWidget(_comment, 1, 1);
394
395 if (tab) {
396 _WWHEnabled
397 = new TQCheckBox(i18n("World-wide highscores enabled"), page);
398 connect(_WWHEnabled, TQ_SIGNAL(toggled(bool)),
399 TQ_SLOT(modifiedSlot()));
400 pageTop->addMultiCellWidget(_WWHEnabled, 2, 2, 0, 1);
401
402 // advanced tab
403 TQWidget *page = new TQWidget(tab);
404 tab->addTab(page, i18n("Advanced"));
405 TQVBoxLayout *pageTop =
406 new TQVBoxLayout(page, spacingHint(), spacingHint());
407
408 TQVGroupBox *group = new TQVGroupBox(i18n("Registration Data"), page);
409 pageTop->addWidget(group);
410 TQGrid *grid = new TQGrid(2, group);
411 grid->setSpacing(spacingHint());
412
413 label = new TQLabel(i18n("Nickname:"), grid);
414 _registeredName = new KLineEdit(grid);
415 _registeredName->setReadOnly(true);
416
417 label = new TQLabel(i18n("Key:"), grid);
418 _key = new KLineEdit(grid);
419 _key->setReadOnly(true);
420
421 KGuiItem gi = KStdGuiItem::clear();
422 gi.setText(i18n("Remove"));
423 _removeButton = new KPushButton(gi, grid);
424 connect(_removeButton, TQ_SIGNAL(clicked()), TQ_SLOT(removeSlot()));
425 }
426
427 load();
428 enableButtonOK( !_nickname->text().isEmpty() );
429 enableButtonApply(false);
430}
431
432void ConfigDialog::nickNameChanged(const TQString &text)
433{
434 enableButtonOK( !text.isEmpty() );
435}
436
437
438void ConfigDialog::modifiedSlot()
439{
440 enableButtonApply(true && !_nickname->text().isEmpty() );
441}
442
443void ConfigDialog::accept()
444{
445 if ( save() ) {
446 KDialogBase::accept();
447 kapp->config()->sync(); // safer
448 }
449}
450
451void ConfigDialog::removeSlot()
452{
453 KGuiItem gi = KStdGuiItem::clear();
454 gi.setText(i18n("Remove"));
455 int res = KMessageBox::warningContinueCancel(this,
456 i18n("This will permanently remove your "
457 "registration key. You will not be able to use "
458 "the currently registered nickname anymore."),
459 TQString(), gi);
460 if ( res==KMessageBox::Continue ) {
461 internal->playerInfos().removeKey();
462 _registeredName->clear();
463 _key->clear();
464 _removeButton->setEnabled(false);
465 _WWHEnabled->setChecked(false);
466 modifiedSlot();
467 }
468}
469
470void ConfigDialog::load()
471{
472 internal->hsConfig().readCurrentConfig();
473 const PlayerInfos &infos = internal->playerInfos();
474 _nickname->setText(infos.isAnonymous() ? TQString() : infos.name());
475 _comment->setText(infos.comment());
476 if (_WWHEnabled) {
477 _WWHEnabled->setChecked(infos.isWWEnabled());
478 if ( !infos.key().isEmpty() ) {
479 _registeredName->setText(infos.registeredName());
480 _registeredName->home(false);
481 _key->setText(infos.key());
482 _key->home(false);
483 }
484 _removeButton->setEnabled(!infos.key().isEmpty());
485 }
486}
487
488bool ConfigDialog::save()
489{
490 bool enabled = (_WWHEnabled ? _WWHEnabled->isChecked() : false);
491
492 // do not bother the user with "nickname empty" if he has not
493 // messed with nickname settings ...
494 TQString newName = _nickname->text();
495 if ( newName.isEmpty() && !internal->playerInfos().isAnonymous()
496 && !enabled ) return true;
497
498 if ( newName.isEmpty() ) {
499 KMessageBox::sorry(this, i18n("Please choose a non empty nickname."));
500 return false;
501 }
502 if ( internal->playerInfos().isNameUsed(newName) ) {
503 KMessageBox::sorry(this, i18n("Nickname already in use. Please "
504 "choose another one"));
505 return false;
506 }
507
508 int res =
509 internal->modifySettings(newName, _comment->text(), enabled, this);
510 if (res) {
511 load(); // needed to update view when "apply" is clicked
512 enableButtonApply(false);
513 }
514 _saved = true;
515 return res;
516}
517
518//-----------------------------------------------------------------------------
519AskNameDialog::AskNameDialog(TQWidget *parent)
520 : KDialogBase(Plain, i18n("Enter Your Nickname"), Ok | Cancel, Ok,
521 parent, "ask_name_dialog")
522{
523 internal->hsConfig().readCurrentConfig();
524
525 TQVBoxLayout *top =
526 new TQVBoxLayout(plainPage(), marginHint(), spacingHint());
527 TQLabel *label =
528 new TQLabel(i18n("Congratulations, you have won!"), plainPage());
529 top->addWidget(label);
530
531 TQHBoxLayout *hbox = new TQHBoxLayout(top);
532 label = new TQLabel(i18n("Enter your nickname:"), plainPage());
533 hbox->addWidget(label);
534 _edit = new TQLineEdit(plainPage());
535 _edit->setFocus();
536 connect(_edit, TQ_SIGNAL(textChanged(const TQString &)), TQ_SLOT(nameChanged()));
537 hbox->addWidget(_edit);
538
539 top->addSpacing(spacingHint());
540 _checkbox = new TQCheckBox(i18n("Do not ask again."), plainPage());
541 top->addWidget(_checkbox);
542
543 nameChanged();
544}
545
546void AskNameDialog::nameChanged()
547{
548 enableButtonOK( !name().isEmpty()
549 && !internal->playerInfos().isNameUsed(name()) );
550}
551
552} // namespace

libtdegames

Skip menu "libtdegames"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

libtdegames

Skip menu "libtdegames"
  • libtdegames
Generated for libtdegames by doxygen 1.9.4
This website is maintained by Timothy Pearson.