SVN_SILENT made messages (.desktop file)
[kdegames.git] / libkdegames / kgamedifficulty.cpp
blob9fd9db1bc80cc9a0e14d54b2218a29a2dea77ba2
1 /*
2 Copyright (c) 2007, 2008 Nicolas Roffet, <nicolas-kde@roffet.com>
3 Copyright (c) 2007, Pino Toscano, <toscano.pino@tiscali.it>
5 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
7 This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.
9 You should have received a copy of the GNU Library General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
12 #include "kgamedifficulty.h"
16 #include <QMap>
19 #include <kactioncollection.h>
20 #include <kcombobox.h>
21 #include <kicon.h>
22 #include <klocale.h>
23 #include <kmessagebox.h>
24 #include <kstatusbar.h>
25 #include <kselectaction.h>
26 #include <kxmlguiwindow.h>
30 class KGameDifficultyPrivate : public QObject
32 Q_OBJECT
34 public:
35 ~KGameDifficultyPrivate();
37 void init(KXmlGuiWindow* window, const QObject* recvr, const char* slotStandard, const char* slotCustom);
39 void rebuildActions();
41 /**
42 * @return standard string for standard level
44 QPair<QByteArray, QString> standardLevelString(KGameDifficulty::standardLevel level);
46 void setLevel(KGameDifficulty::standardLevel level);
47 void setLevelCustom(int key);
50 /**
51 * @brief Current custom difficulty level
53 int m_levelCustom;
55 KGameDifficulty::standardLevel m_level;
56 QList<KGameDifficulty::standardLevel> m_standardLevels;
57 QMap<int, QString> m_customLevels;
59 KSelectAction* m_menu;
60 KGameDifficulty::onChange m_restartOnChange;
61 bool m_running;
62 int m_oldSelection;
63 KComboBox* m_comboBox;
66 public Q_SLOTS:
67 /**
68 * @brief Player wants to change the difficulty level to a standard level
70 * The difference with the methode "setSelection" is that the player may have to confirm that he agrees to end the current game (if needed).
71 * @param newSelection Selected item.
73 void changeSelection(int newSelection);
75 Q_SIGNALS:
76 /**
77 * @brief Current difficulty level changed to a standard level
79 * The game catchs this signal and restarts a game with the new standard difficulty level.
80 * @param level New standard level.
82 void standardLevelChanged(KGameDifficulty::standardLevel level);
84 /**
85 * @brief Current difficulty level changed to a custom level
87 * The game catchs this signal and restarts a game with the new standard difficulty level.
88 * @param key Custom level identifier.
90 void customLevelChanged(int key);
93 private:
94 void setSelection(int newSelection);
98 KGameDifficultyPrivate::~KGameDifficultyPrivate()
100 delete KGameDifficulty::self();
104 void KGameDifficultyPrivate::init(KXmlGuiWindow* window, const QObject* recvr, const char* slotStandard, const char* slotCustom = 0)
106 Q_ASSERT(recvr!=0);
108 m_oldSelection = -1; // No valid selection
109 m_level = KGameDifficulty::NoLevel;
110 m_running = false;
112 QObject::connect(this, SIGNAL(standardLevelChanged(KGameDifficulty::standardLevel)), recvr, slotStandard);
113 if (slotCustom!=0)
114 QObject::connect(this, SIGNAL(customLevelChanged(int)), recvr, slotCustom);
116 m_menu = new KSelectAction(KIcon("games-difficult"), i18nc("Game difficulty level", "Difficulty"), window);
117 m_menu->setToolTip(i18n("Set the difficulty level"));
118 m_menu->setWhatsThis(i18n("Set the difficulty level of the game."));
119 QObject::connect(m_menu, SIGNAL(triggered(int)), this, SLOT(changeSelection(int)));
120 m_menu->setObjectName("options_game_difficulty");
121 window->actionCollection()->addAction(m_menu->objectName(), m_menu);
123 setParent(window);
125 m_comboBox = new KComboBox(window);
126 m_comboBox->setToolTip(i18n("Difficulty"));
127 QObject::connect(m_comboBox, SIGNAL(activated(int)), this, SLOT(changeSelection(int)));
128 window->statusBar()->addPermanentWidget(m_comboBox);
130 KGameDifficulty::setRestartOnChange(KGameDifficulty::RestartOnChange);
134 void KGameDifficultyPrivate::changeSelection(int newSelection)
136 if (newSelection!=m_oldSelection) {
137 bool mayChange = true;
139 if (mayChange && (m_restartOnChange==KGameDifficulty::RestartOnChange) && m_running)
140 mayChange = ( KMessageBox::warningContinueCancel(0, i18n("Changing the difficulty level will end the current game!"), QString(), KGuiItem(i18n("Change the difficulty level"))) == KMessageBox::Continue );
142 if (mayChange) {
143 setSelection(newSelection);
144 } else {
145 // restore current level selection
146 setSelection(m_oldSelection);
151 QPair<QByteArray, QString> KGameDifficultyPrivate::standardLevelString(KGameDifficulty::standardLevel level)
153 //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
154 switch (level) {
155 case KGameDifficulty::RidiculouslyEasy:
156 return qMakePair(QByteArray("Ridiculously Easy"), i18nc("Game difficulty level 1 out of 8", "Ridiculously Easy"));
157 case KGameDifficulty::VeryEasy:
158 return qMakePair(QByteArray("Very Easy"), i18nc("Game difficulty level 2 out of 8", "Very Easy"));
159 case KGameDifficulty::Easy:
160 return qMakePair(QByteArray("Easy"), i18nc("Game difficulty level 3 out of 8", "Easy"));
161 case KGameDifficulty::Medium:
162 return qMakePair(QByteArray("Medium"), i18nc("Game difficulty level 4 out of 8", "Medium"));
163 case KGameDifficulty::Hard:
164 return qMakePair(QByteArray("Hard"), i18nc("Game difficulty level 5 out of 8", "Hard"));
165 case KGameDifficulty::VeryHard:
166 return qMakePair(QByteArray("Very Hard"), i18nc("Game difficulty level 6 out of 8", "Very Hard"));
167 case KGameDifficulty::ExtremelyHard:
168 return qMakePair(QByteArray("Extremely Hard"), i18nc("Game difficulty level 7 out of 8", "Extremely Hard"));
169 case KGameDifficulty::Impossible:
170 return qMakePair(QByteArray("Impossible"), i18nc("Game difficulty level 8 out of 8", "Impossible"));
171 case KGameDifficulty::Custom:
172 case KGameDifficulty::Configurable:
173 case KGameDifficulty::NoLevel:
174 // Do nothing
175 break;
177 return qMakePair(QByteArray(), QString());
180 void KGameDifficultyPrivate::rebuildActions()
182 m_menu->clear();
183 m_comboBox->clear();
184 qSort(m_standardLevels.begin(), m_standardLevels.end());
186 foreach(KGameDifficulty::standardLevel level, m_standardLevels) {
187 if (level!=KGameDifficulty::Configurable) {
188 m_menu->addAction(standardLevelString(level).second);
189 m_comboBox->addItem(KIcon("games-difficult"), standardLevelString(level).second);
193 if (m_customLevels.count()>0) {
194 foreach(const QString &s, m_customLevels) {
195 m_menu->addAction(s);
196 m_comboBox->addItem(KIcon("games-difficult"), s);
200 if (m_standardLevels.contains(KGameDifficulty::Configurable)) {
201 QAction* separator = new QAction(m_menu);
202 separator->setSeparator(true);
203 m_menu->addAction(separator);
205 QString s = i18nc("Name of the game difficulty level that is customized by the user by setting up different game parameters", "Custom");
206 m_menu->addAction(s);
207 m_comboBox->addItem(KIcon("games-difficult"), s);
210 // reselect the previous selected item.
211 if (m_level==KGameDifficulty::Custom)
212 KGameDifficulty::setLevelCustom(m_levelCustom);
213 else if (m_standardLevels.contains(m_level))
214 KGameDifficulty::setLevel(m_level);
217 void KGameDifficultyPrivate::setSelection(int newSelection)
219 int countWithoutConfigurable = m_standardLevels.count();
220 if (m_standardLevels.contains(KGameDifficulty::Configurable))
221 countWithoutConfigurable--;
223 if ((m_standardLevels.contains(KGameDifficulty::Configurable)) && (newSelection>m_menu->actions().count()-3))
224 KGameDifficulty::setLevel(KGameDifficulty::Configurable);
225 else if(newSelection<countWithoutConfigurable)
226 KGameDifficulty::setLevel(m_standardLevels[newSelection]);
227 else
228 KGameDifficulty::setLevelCustom((m_customLevels.uniqueKeys()).value(newSelection - countWithoutConfigurable));
230 m_oldSelection = newSelection;
234 void KGameDifficultyPrivate::setLevel(KGameDifficulty::standardLevel level)
236 if ((!m_standardLevels.contains(level)) && (level!=KGameDifficulty::Custom))
237 level = KGameDifficulty::NoLevel;
239 if (level==KGameDifficulty::Configurable) {
240 m_menu->setCurrentItem(m_menu->actions().count()-1);
241 m_comboBox->setCurrentIndex(m_comboBox->count()-1);
242 } else if (level!=KGameDifficulty::Custom) {
243 int i = m_standardLevels.indexOf(level);
244 m_menu->setCurrentItem(i);
245 m_comboBox->setCurrentIndex(i);
248 if (level != m_level) {
249 m_level = level;
250 emit standardLevelChanged(level);
253 m_oldSelection = m_menu->currentItem();
257 void KGameDifficultyPrivate::setLevelCustom(int key)
259 m_level = KGameDifficulty::Custom;
261 int a = m_standardLevels.count();
262 if (m_standardLevels.contains(KGameDifficulty::Configurable))
263 a -= 1;
265 int i = (m_customLevels.uniqueKeys()).indexOf(key) + a;
266 m_menu->setCurrentItem(i);
267 m_comboBox->setCurrentIndex(i);
269 if (key != m_levelCustom) {
270 m_levelCustom = key;
271 emit customLevelChanged(key);
274 m_oldSelection = m_menu->currentItem();
279 //---//
283 KGameDifficulty* KGameDifficulty::instance = 0;
286 KGameDifficulty::~KGameDifficulty()
288 // We do not need to delete d, because d deletes us.
292 void KGameDifficulty::init(KXmlGuiWindow* window, const QObject* recvr, const char* slotStandard, const char* slotCustom)
294 self()->d->init(window, recvr, slotStandard, slotCustom);
298 void KGameDifficulty::setRestartOnChange(onChange restart)
300 Q_ASSERT(self()->d);
302 self()->d->m_restartOnChange = restart;
303 if (restart==RestartOnChange)
304 self()->d->m_comboBox->setWhatsThis(i18n("Select the <b>difficulty</b> of the game.<br />If you change the difficulty level while a game is running, you will have to cancel it and start a new one."));
305 else
306 self()->d->m_comboBox->setWhatsThis(i18n("Select the <b>difficulty</b> of the game.<br />You can change the difficulty level during a running game."));
311 void KGameDifficulty::addStandardLevel(standardLevel level)
313 Q_ASSERT(self()->d);
315 if ((level!=Custom) && (level!=NoLevel)) {
316 self()->d->m_standardLevels.append(level);
317 self()->d->rebuildActions();
322 void KGameDifficulty::removeStandardLevel(standardLevel level)
324 Q_ASSERT(self()->d);
326 self()->d->m_standardLevels.removeAll(level);
327 self()->d->rebuildActions();
331 void KGameDifficulty::addCustomLevel(int key, const QString& appellation)
333 Q_ASSERT(self()->d);
335 self()->d->m_customLevels.insert(key, appellation);
336 self()->d->rebuildActions();
340 void KGameDifficulty::removeCustomLevel(int key)
342 Q_ASSERT(self()->d);
344 self()->d->m_customLevels.remove(key);
345 self()->d->rebuildActions();
349 void KGameDifficulty::setEnabled(bool enabled)
351 Q_ASSERT(self()->d->m_menu);
353 // TODO: Doing this never disable the combobox in the toolbar (just in the menu). It seems to be a bug in the class KSelectAction of kdelibs/kdeui/actions. To check and solve...
354 self()->d->m_menu->setEnabled(enabled);
355 self()->d->m_comboBox->setEnabled(enabled);
359 void KGameDifficulty::setLevel(standardLevel level)
361 Q_ASSERT(self()->d);
363 self()->d->setLevel(level);
367 void KGameDifficulty::setLevelCustom(int key)
369 Q_ASSERT(self()->d);
371 self()->d->setLevelCustom(key);
375 int KGameDifficulty::levelCustom()
377 Q_ASSERT(self()->d);
379 return self()->d->m_levelCustom;
383 KGameDifficulty::standardLevel KGameDifficulty::level()
385 Q_ASSERT(self()->d);
387 return self()->d->m_level;
391 QString KGameDifficulty::levelString()
393 Q_ASSERT(self()->d);
395 return self()->d->standardLevelString(self()->d->m_level).second;
399 QPair<QByteArray, QString> KGameDifficulty::localizedLevelString()
401 Q_ASSERT(self()->d);
403 return self()->d->standardLevelString(self()->d->m_level);
407 QMap<QByteArray, QString> KGameDifficulty::localizedLevelStrings()
409 Q_ASSERT(self()->d);
411 QMap<QByteArray, QString> levelStrings;
413 levelStrings.insert(self()->d->standardLevelString(RidiculouslyEasy).first, self()->d->standardLevelString(RidiculouslyEasy).second);
414 levelStrings.insert(self()->d->standardLevelString(VeryEasy).first, self()->d->standardLevelString(VeryEasy).second);
415 levelStrings.insert(self()->d->standardLevelString(Easy).first, self()->d->standardLevelString(Easy).second);
416 levelStrings.insert(self()->d->standardLevelString(Medium).first, self()->d->standardLevelString(Medium).second);
417 levelStrings.insert(self()->d->standardLevelString(Hard).first, self()->d->standardLevelString(Hard).second);
418 levelStrings.insert(self()->d->standardLevelString(VeryHard).first, self()->d->standardLevelString(VeryHard).second);
419 levelStrings.insert(self()->d->standardLevelString(ExtremelyHard).first, self()->d->standardLevelString(ExtremelyHard).second);
420 levelStrings.insert(self()->d->standardLevelString(Impossible).first, self()->d->standardLevelString(Impossible).second);
422 return levelStrings;
425 QMap<int, QByteArray> KGameDifficulty::levelWeights()
427 Q_ASSERT(self()->d);
429 QMap<int, QByteArray> weights;
430 weights.insert(RidiculouslyEasy, self()->d->standardLevelString(RidiculouslyEasy).first);
431 weights.insert(VeryEasy, self()->d->standardLevelString(VeryEasy).first);
432 weights.insert(Easy, self()->d->standardLevelString(Easy).first);
433 weights.insert(Medium, self()->d->standardLevelString(Medium).first);
434 weights.insert(Hard, self()->d->standardLevelString(Hard).first);
435 weights.insert(VeryHard, self()->d->standardLevelString(VeryHard).first);
436 weights.insert(ExtremelyHard, self()->d->standardLevelString(ExtremelyHard).first);
437 weights.insert(Impossible, self()->d->standardLevelString(Impossible).first);
439 return weights;
442 void KGameDifficulty::setRunning(bool running)
444 Q_ASSERT(self()->d);
446 self()->d->m_running = running;
450 KGameDifficulty::KGameDifficulty() : d(new KGameDifficultyPrivate())
455 KGameDifficulty* KGameDifficulty::self()
457 if (instance==0)
458 instance = new KGameDifficulty();
459 return instance;
462 #include "kgamedifficulty.moc"