• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdegames API Reference
  • KDE Home
  • Contact Us
 

libkdegames

  • sources
  • kde-4.14
  • kdegames
  • libkdegames
kgdifficulty.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright 2007 Nicolas Roffet <nicolas-kde@roffet.com> *
3  * Copyright 2007 Pino Toscano <toscano.pino@tiscali.it> *
4  * Copyright 2011-2012 Stefan Majewsky <majewsky@gmx.net> *
5  * *
6  * This program is free software; you can redistribute it and/or modify *
7  * it under the terms of the GNU Library General Public License *
8  * version 2 as published by the Free Software Foundation *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU Library General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU Library General Public *
16  * License along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19  ***************************************************************************/
20 
21 #include "kgdifficulty.h"
22 
23 #include <QtCore/QVector>
24 #include <KDE/KConfigGroup>
25 #include <KDE/KGlobal>
26 #include <KDE/KGuiItem>
27 #include <KDE/KLocale>
28 #include <KDE/KMessageBox>
29 //the following only used by KgDifficultyGUI
30 #include <KDE/KActionCollection>
31 #include <KDE/KComboBox>
32 #include <KDE/KSelectAction>
33 #include <KDE/KStatusBar>
34 #include <KDE/KXmlGuiWindow>
35 
36 //BEGIN KgDifficultyLevel
37 
38 class KgDifficultyLevel::Private
39 {
40  public:
41  bool m_isDefault;
42  int m_hardness;
43  StandardLevel m_level;
44  QByteArray m_key;
45  QString m_title;
46 
47  Private(int hardness, const QByteArray& key, const QString& title, StandardLevel level, bool isDefault);
48  static Private* fromStandardLevel(StandardLevel level, bool isDefault);
49 };
50 
51 KgDifficultyLevel::KgDifficultyLevel(int hardness, const QByteArray& key, const QString& title, bool isDefault)
52  : d(new Private(hardness, key, title, Custom, isDefault))
53 {
54 }
55 
56 KgDifficultyLevel::Private::Private(int hardness, const QByteArray& key, const QString& title, StandardLevel level, bool isDefault)
57  : m_isDefault(isDefault)
58  , m_hardness(hardness)
59  , m_level(level)
60  , m_key(key)
61  , m_title(title)
62 {
63 }
64 
65 KgDifficultyLevel::KgDifficultyLevel(StandardLevel level, bool isDefault)
66  : d(Private::fromStandardLevel(level, isDefault))
67 {
68 }
69 
70 KgDifficultyLevel::Private* KgDifficultyLevel::Private::fromStandardLevel(KgDifficultyLevel::StandardLevel level, bool isDefault)
71 {
72  Q_ASSERT_X(level != Custom,
73  "KgDifficultyLevel(StandardLevel) constructor",
74  "Custom level not allowed here"
75  );
76  //The first entry in the pair is to be used as a key so don't change it. It doesn't have to match the string to be translated
77  QPair<QByteArray, QString> data;
78  switch (level)
79  {
80  case RidiculouslyEasy:
81  data = qMakePair(QByteArray("Ridiculously Easy"), i18nc("Game difficulty level 1 out of 8", "Ridiculously Easy"));
82  break;
83  case VeryEasy:
84  data = qMakePair(QByteArray("Very Easy"), i18nc("Game difficulty level 2 out of 8", "Very Easy"));
85  break;
86  case Easy:
87  data = qMakePair(QByteArray("Easy"), i18nc("Game difficulty level 3 out of 8", "Easy"));
88  break;
89  case Medium:
90  data = qMakePair(QByteArray("Medium"), i18nc("Game difficulty level 4 out of 8", "Medium"));
91  break;
92  case Hard:
93  data = qMakePair(QByteArray("Hard"), i18nc("Game difficulty level 5 out of 8", "Hard"));
94  break;
95  case VeryHard:
96  data = qMakePair(QByteArray("Very Hard"), i18nc("Game difficulty level 6 out of 8", "Very Hard"));
97  break;
98  case ExtremelyHard:
99  data = qMakePair(QByteArray("Extremely Hard"), i18nc("Game difficulty level 7 out of 8", "Extremely Hard"));
100  break;
101  case Impossible:
102  data = qMakePair(QByteArray("Impossible"), i18nc("Game difficulty level 8 out of 8", "Impossible"));
103  break;
104  case Custom:
105  return 0;
106  }
107  return new KgDifficultyLevel::Private(level, data.first, data.second, level, isDefault);
108 }
109 
110 KgDifficultyLevel::~KgDifficultyLevel()
111 {
112  delete d;
113 }
114 
115 bool KgDifficultyLevel::isDefault() const
116 {
117  return d->m_isDefault;
118 }
119 
120 int KgDifficultyLevel::hardness() const
121 {
122  return d->m_hardness;
123 }
124 
125 QByteArray KgDifficultyLevel::key() const
126 {
127  return d->m_key;
128 }
129 
130 QString KgDifficultyLevel::title() const
131 {
132  return d->m_title;
133 }
134 
135 KgDifficultyLevel::StandardLevel KgDifficultyLevel::standardLevel() const
136 {
137  return d->m_level;
138 }
139 
140 //END KgDifficultyLevel
141 //BEGIN KgDifficulty
142 
143 class KgDifficulty::Private
144 {
145  public:
146  QList<const KgDifficultyLevel*> m_levels;
147  const KgDifficultyLevel* m_currentLevel;
148  bool m_editable, m_gameRunning;
149 
150  Private() : m_currentLevel(0), m_editable(true), m_gameRunning(false) {}
151 };
152 
153 KgDifficulty::KgDifficulty(QObject* parent)
154  : QObject(parent)
155  , d(new Private)
156 {
157  qRegisterMetaType<const KgDifficultyLevel*>();
158 }
159 
160 KgDifficulty::~KgDifficulty()
161 {
162  if (d->m_levels.isEmpty())
163  {
164  return;
165  }
166  //save current difficulty level in config file (no sync() call here; this
167  //will most likely be called at application shutdown when others are also
168  //writing to KGlobal::config(); also KConfig's dtor will sync automatically)
169  KConfigGroup cg(KGlobal::config(), "KgDifficulty");
170  cg.writeEntry("Level", currentLevel()->key());
171  //cleanup
172  while (!d->m_levels.isEmpty())
173  {
174  delete const_cast<KgDifficultyLevel*>(d->m_levels.takeFirst());
175  }
176 }
177 
178 void KgDifficulty::addLevel(KgDifficultyLevel* level)
179 {
180  //The intended use is to create the KgDifficulty object, add levels, *then*
181  //start to work with the currentLevel(). The first call to currentLevel()
182  //will load the previous selection from the config, and the level list will
183  //be considered immutable from this point.
184  Q_ASSERT_X(d->m_currentLevel == 0,
185  "KgDifficulty::addLevel",
186  "Only allowed before currentLevel() is called."
187  );
188  //ensure that list stays sorted
189  QList<const KgDifficultyLevel*>::iterator it = d->m_levels.begin();
190  while (it != d->m_levels.end() && (*it)->hardness() < level->hardness())
191  {
192  ++it;
193  }
194  d->m_levels.insert(it, level);
195  level->setParent(this);
196 }
197 
198 typedef KgDifficultyLevel::StandardLevel DS;
199 
200 void KgDifficulty::addStandardLevel(DS level, bool isDefault)
201 {
202  addLevel(new KgDifficultyLevel(level, isDefault));
203 }
204 
205 void KgDifficulty::addStandardLevelRange(DS from, DS to)
206 {
207  //every level in range != Custom, therefore no level is default
208  addStandardLevelRange(from, to, KgDifficultyLevel::Custom);
209 }
210 
211 void KgDifficulty::addStandardLevelRange(DS from, DS to, DS defaultLevel)
212 {
213  const QVector<DS> levels = QVector<DS>()
214  << KgDifficultyLevel::RidiculouslyEasy
215  << KgDifficultyLevel::VeryEasy
216  << KgDifficultyLevel::Easy
217  << KgDifficultyLevel::Medium
218  << KgDifficultyLevel::Hard
219  << KgDifficultyLevel::VeryHard
220  << KgDifficultyLevel::ExtremelyHard
221  << KgDifficultyLevel::Impossible
222  ;
223  const int fromIndex = levels.indexOf(from);
224  const int toIndex = levels.indexOf(to);
225  const int defaultLevelIndex = levels.indexOf(defaultLevel);
226  Q_ASSERT_X(fromIndex >= 0 && toIndex > fromIndex && (defaultLevelIndex == KgDifficultyLevel::Custom || (defaultLevelIndex >= fromIndex && defaultLevelIndex <= toIndex)),
227  "KgDifficulty::addStandardLevelRange",
228  "No argument may be KgDifficultyLevel::Custom."
229  );
230  for (int i = fromIndex; i <= toIndex; ++i)
231  {
232  addLevel(new KgDifficultyLevel(levels[i], levels[i] == defaultLevel));
233  }
234 }
235 
236 QList<const KgDifficultyLevel*> KgDifficulty::levels() const
237 {
238  return d->m_levels;
239 }
240 
241 const KgDifficultyLevel* KgDifficulty::currentLevel() const
242 {
243  if (d->m_currentLevel)
244  {
245  return d->m_currentLevel;
246  }
247  Q_ASSERT(!d->m_levels.isEmpty());
248  //check configuration file for saved difficulty level
249  KConfigGroup cg(KGlobal::config(), "KgDifficulty");
250  const QByteArray key = cg.readEntry("Level", QByteArray());
251  foreach (const KgDifficultyLevel* level, d->m_levels)
252  {
253  if (level->key() == key)
254  {
255  return d->m_currentLevel = level;
256  }
257  }
258  //no level predefined - look for a default level
259  foreach (const KgDifficultyLevel* level, d->m_levels)
260  {
261  if (level->isDefault())
262  {
263  return d->m_currentLevel = level;
264  }
265  }
266  //no default level predefined - easiest level is probably a sane default
267  return d->m_currentLevel = d->m_levels[0];
268 }
269 
270 bool KgDifficulty::isEditable() const
271 {
272  return d->m_editable;
273 }
274 
275 void KgDifficulty::setEditable(bool editable)
276 {
277  if (d->m_editable == editable)
278  {
279  return;
280  }
281  d->m_editable = editable;
282  emit editableChanged(editable);
283 }
284 
285 bool KgDifficulty::isGameRunning() const
286 {
287  return d->m_gameRunning;
288 }
289 
290 void KgDifficulty::setGameRunning(bool gameRunning)
291 {
292  if (d->m_gameRunning == gameRunning)
293  {
294  return;
295  }
296  d->m_gameRunning = gameRunning;
297  emit gameRunningChanged(gameRunning);
298 }
299 
300 void KgDifficulty::select(const KgDifficultyLevel* level)
301 {
302  Q_ASSERT(d->m_levels.contains(level));
303  if (d->m_currentLevel == level)
304  {
305  return;
306  }
307  //ask for confirmation if necessary
308  if (d->m_gameRunning)
309  {
310  const int result = KMessageBox::warningContinueCancel(0,
311  i18n("Changing the difficulty level will end the current game!"),
312  QString(), KGuiItem(i18n("Change the difficulty level"))
313  );
314  if (result != KMessageBox::Continue)
315  {
316  emit selectedLevelChanged(d->m_currentLevel);
317  return;
318  }
319  }
320  d->m_currentLevel = level;
321  emit selectedLevelChanged(level);
322  emit currentLevelChanged(level);
323 }
324 
325 //END KgDifficulty
326 
327 K_GLOBAL_STATIC(KgDifficulty, g_difficulty)
328 
329 KgDifficulty* Kg::difficulty()
330 {
331  return g_difficulty;
332 }
333 
334 KgDifficultyLevel::StandardLevel Kg::difficultyLevel()
335 {
336  return g_difficulty->currentLevel()->standardLevel();
337 }
338 
339 //BEGIN KgDifficultyGUI
340 
341 namespace KgDifficultyGUI
342 {
343  class Selector : public KComboBox
344  {
345  Q_OBJECT
346  private:
347  KgDifficulty* d;
348  public:
349  Selector(KgDifficulty* difficulty, QWidget* parent = 0)
350  : KComboBox(parent), d(difficulty) {}
351  Q_SIGNALS:
352  void signalSelected(int levelIndex);
353  public Q_SLOTS:
354  void slotActivated(int levelIndex)
355  {
356  d->select(d->levels().value(levelIndex));
357  }
358  void slotSelected(const KgDifficultyLevel* level)
359  {
360  emit signalSelected(d->levels().indexOf(level));
361  }
362  };
363  class Menu : public KSelectAction
364  {
365  Q_OBJECT
366  public:
367  Menu(const KIcon& i, const QString& s, QWidget* p) : KSelectAction(i,s,p){}
368  public Q_SLOTS:
369  //this whole class just because the following is not a slot
370  void setCurrentItem(int index) { KSelectAction::setCurrentItem(index); }
371  };
372 }
373 
374 void KgDifficultyGUI::init(KXmlGuiWindow* window, KgDifficulty* difficulty)
375 {
376  const bool useSingleton = !difficulty;
377  if (useSingleton)
378  difficulty = Kg::difficulty();
379 
380  //create selector (resides in status bar)
381  KgDifficultyGUI::Selector* selector = new KgDifficultyGUI::Selector(difficulty, window);
382  selector->setToolTip(i18nc("Game difficulty level", "Difficulty"));
383  QObject::connect(selector, SIGNAL(activated(int)), selector, SLOT(slotActivated(int)));
384  QObject::connect(difficulty, SIGNAL(editableChanged(bool)), selector, SLOT(setEnabled(bool)));
385  QObject::connect(difficulty, SIGNAL(selectedLevelChanged(const KgDifficultyLevel*)),
386  selector, SLOT(slotSelected(const KgDifficultyLevel*)));
387  QObject::connect(selector, SIGNAL(signalSelected(int)), selector, SLOT(setCurrentIndex(int)));
388 
389  //create menu action
390  const KIcon icon("games-difficult");
391  KSelectAction* menu = new KgDifficultyGUI::Menu(icon, i18nc("Game difficulty level", "Difficulty"), window);
392  menu->setToolTip(i18n("Set the difficulty level"));
393  menu->setWhatsThis(i18n("Set the difficulty level of the game."));
394  QObject::connect(menu, SIGNAL(triggered(int)), selector, SLOT(slotActivated(int)));
395  QObject::connect(difficulty, SIGNAL(editableChanged(bool)), menu, SLOT(setEnabled(bool)));
396  QObject::connect(selector, SIGNAL(signalSelected(int)), menu, SLOT(setCurrentItem(int)));
397 
398  //fill menu and selector
399  foreach (const KgDifficultyLevel* level, difficulty->levels())
400  {
401  selector->addItem(icon, level->title());
402  menu->addAction(level->title());
403  }
404  //initialize selection in selector
405  selector->slotSelected(difficulty->currentLevel());
406 
407  //add selector to statusbar
408  window->statusBar()->addPermanentWidget(selector);
409  //add menu action to window
410  menu->setObjectName(QLatin1String("options_game_difficulty"));
411  window->actionCollection()->addAction(menu->objectName(), menu);
412 
413  //ensure that the KgDifficulty instance gets deleted
414  if (!useSingleton && !difficulty->parent())
415  {
416  difficulty->setParent(window);
417  }
418 }
419 
420 //END KgDifficultyGUI
421 
422 #include "kgdifficulty.moc"
423 #include "moc_kgdifficulty.cpp"
KgDifficultyLevel::Custom
standardLevel() returns this for custom levels.
Definition: kgdifficulty.h:46
KgDifficulty::selectedLevelChanged
void selectedLevelChanged(const KgDifficultyLevel *level)
Emitted after every call to select(), even when the user has rejected the change. ...
KgDifficulty::setEditable
void setEditable(bool editable)
Set whether the difficulty level selection may be edited.
Definition: kgdifficulty.cpp:275
KgDifficulty::gameRunningChanged
void gameRunningChanged(bool gameRunning)
Emitted when a running game has been marked or unmarked.
QWidget
KgDifficulty::currentLevel
const KgDifficultyLevel * currentLevel() const
kgdifficulty.h
QByteArray
KgDifficulty::currentLevelChanged
void currentLevelChanged(const KgDifficultyLevel *level)
Emitted when a new difficulty level has been selected.
QVector::indexOf
int indexOf(const T &value, int from) const
KgDifficultyLevel::Hard
Definition: kgdifficulty.h:51
KgDifficultyLevel::StandardLevel
StandardLevel
Definition: kgdifficulty.h:44
KgDifficulty::addLevel
void addLevel(KgDifficultyLevel *level)
Adds a difficulty level to this instance.
Definition: kgdifficulty.cpp:178
KgDifficultyLevel::KgDifficultyLevel
KgDifficultyLevel(int hardness, const QByteArray &key, const QString &title, bool isDefault=false)
Refer to the getters' documentation for details on the params.
Definition: kgdifficulty.cpp:51
KgDifficulty::levels
QList< const KgDifficultyLevel * > levels() const
Definition: kgdifficulty.cpp:236
KgDifficultyLevel::VeryEasy
Definition: kgdifficulty.h:48
KgDifficultyLevel::Medium
Definition: kgdifficulty.h:50
Kg::difficulty
KDEGAMES_EXPORT KgDifficulty * difficulty()
Definition: kgdifficulty.cpp:329
DS
KgDifficultyLevel::StandardLevel DS
Definition: kgdifficulty.cpp:198
KgDifficulty::addStandardLevel
void addStandardLevel(KgDifficultyLevel::StandardLevel level, bool isDefault=false)
A shortcut for addLevel(new KgDifficultyLevel(level)).
Definition: kgdifficulty.cpp:200
KgDifficultyLevel::key
QByteArray key
Definition: kgdifficulty.h:39
QObject
KgDifficultyLevel::standardLevel
StandardLevel standardLevel() const
KgDifficulty::addStandardLevelRange
void addStandardLevelRange(KgDifficultyLevel::StandardLevel from, KgDifficultyLevel::StandardLevel to)
This convenience method adds a range of standard levels to this instance (including the boundaries)...
Definition: kgdifficulty.cpp:205
KgDifficulty::gameRunning
bool gameRunning
Definition: kgdifficulty.h:104
Kg::difficultyLevel
KDEGAMES_EXPORT KgDifficultyLevel::StandardLevel difficultyLevel()
A shortcut for Kg::difficulty()->currentLevel()->standardLevel().
Definition: kgdifficulty.cpp:334
KgDifficulty::isGameRunning
bool isGameRunning() const
Definition: kgdifficulty.cpp:285
QString
QList< const KgDifficultyLevel * >
QPair
QObject::setParent
void setParent(QObject *parent)
KgDifficultyLevel::title
QString title
Definition: kgdifficulty.h:40
KgDifficultyLevel::isDefault
bool isDefault() const
Definition: kgdifficulty.cpp:115
KgDifficulty::currentLevel
const KgDifficultyLevel currentLevel
Definition: kgdifficulty.h:101
KgDifficulty::editableChanged
void editableChanged(bool editable)
Emitted when the editability changes.
KgDifficultyLevel::hardness
int hardness() const
KgDifficulty::~KgDifficulty
virtual ~KgDifficulty()
Destroys this instance and all DifficultyLevel instances in it.
Definition: kgdifficulty.cpp:160
QVector
KgDifficultyLevel::Impossible
Definition: kgdifficulty.h:54
QLatin1String
KgDifficulty::editable
bool editable
Definition: kgdifficulty.h:103
KgDifficulty::setGameRunning
void setGameRunning(bool running)
KgDifficulty has optional protection against changing the difficulty level while a game is running...
Definition: kgdifficulty.cpp:290
KgDifficulty::select
void select(const KgDifficultyLevel *level)
Select a new difficulty level.
Definition: kgdifficulty.cpp:300
KgDifficulty::KgDifficulty
KgDifficulty(QObject *parent=0)
Definition: kgdifficulty.cpp:153
KgDifficultyLevel::RidiculouslyEasy
Definition: kgdifficulty.h:47
KgDifficultyGUI::init
KDEGAMES_EXPORT void init(KXmlGuiWindow *window, KgDifficulty *difficulty=0)
Install standard GUI components for the manipulation of the given KgDifficulty instance in the given ...
Definition: kgdifficulty.cpp:374
KgDifficultyLevel
Definition: kgdifficulty.h:33
KgDifficultyLevel::hardness
int hardness
Definition: kgdifficulty.h:38
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject::parent
QObject * parent() const
KgDifficultyLevel::VeryHard
Definition: kgdifficulty.h:52
KgDifficulty
KgDifficulty manages difficulty levels of a game in a standard way.
Definition: kgdifficulty.h:96
KgDifficulty::isEditable
bool isEditable() const
Definition: kgdifficulty.cpp:270
KgDifficultyLevel::key
QByteArray key() const
KgDifficultyLevel::~KgDifficultyLevel
virtual ~KgDifficultyLevel()
Definition: kgdifficulty.cpp:110
KgDifficultyLevel::ExtremelyHard
Definition: kgdifficulty.h:53
KgDifficultyLevel::title
QString title() const
KgDifficultyLevel::Easy
Definition: kgdifficulty.h:49
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:18:42 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

libkdegames

Skip menu "libkdegames"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdegames API Reference

Skip menu "kdegames API Reference"
  • granatier
  • kapman
  • kblackbox
  • kgoldrunner
  • kigo
  • kmahjongg
  • KShisen
  • ksquares
  • libkdegames
  •   highscore
  •   libkdegamesprivate
  •     kgame
  • libkmahjongg
  • palapeli
  •   libpala

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal