• 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 
44 namespace KExtHighscore
45 {
46 
47 //-----------------------------------------------------------------------------
48 ShowItem::ShowItem(TQListView *list, bool highlight)
49  : TDEListViewItem(list), _highlight(highlight)
50 {}
51 
52 void 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 //-----------------------------------------------------------------------------
61 ScoresList::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 
72 void ScoresList::addHeader(const ItemArray &items)
73 {
74  addLineItem(items, 0, 0);
75 }
76 
77 TQListViewItem *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 
85 void 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 //-----------------------------------------------------------------------------
102 HighscoresList::HighscoresList(TQWidget *parent)
103  : ScoresList(parent)
104 {}
105 
106 TQString HighscoresList::itemText(const ItemContainer &item, uint row) const
107 {
108  return item.pretty(row);
109 }
110 
111 void 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 //-----------------------------------------------------------------------------
123 HighscoresWidget::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 
176 void HighscoresWidget::changeTab(int i)
177 {
178  if ( i!=_tw->currentPageIndex() )
179  _tw->setCurrentPage(i);
180 }
181 
182 void HighscoresWidget::showURL(const TQString &url) const
183 {
184  (void)new KRun(KURL(url));
185 }
186 
187 void 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 //-----------------------------------------------------------------------------
200 HighscoresDialog::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 
229 void 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 
246 void HighscoresDialog::slotUser1()
247 {
248  if ( KExtHighscore::configure(this) )
249  createPage(_current);
250 }
251 
252 void 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 //-----------------------------------------------------------------------------
272 LastMultipleScoresList::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 
281 void 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 
297 TQString 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 //-----------------------------------------------------------------------------
309 TotalMultipleScoresList::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 
318 void 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 
341 TQString 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 //-----------------------------------------------------------------------------
355 ConfigDialog::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 
432 void ConfigDialog::nickNameChanged(const TQString &text)
433 {
434  enableButtonOK( !text.isEmpty() );
435 }
436 
437 
438 void ConfigDialog::modifiedSlot()
439 {
440  enableButtonApply(true && !_nickname->text().isEmpty() );
441 }
442 
443 void ConfigDialog::accept()
444 {
445  if ( save() ) {
446  KDialogBase::accept();
447  kapp->config()->sync(); // safer
448  }
449 }
450 
451 void 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 
470 void 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 
488 bool 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 //-----------------------------------------------------------------------------
519 AskNameDialog::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 
546 void AskNameDialog::nameChanged()
547 {
548  enableButtonOK( !name().isEmpty()
549  && !internal->playerInfos().isNameUsed(name()) );
550 }
551 
552 } // namespace
KExtHighscore
Definition: kexthighscore.cpp:30

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.8.13
This website is maintained by Timothy Pearson.