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"
19 #include <kactioncollection.h>
20 #include <kcombobox.h>
23 #include <kmessagebox.h>
24 #include <kstatusbar.h>
25 #include <kselectaction.h>
26 #include <kxmlguiwindow.h>
30 class KGameDifficultyPrivate
: public QObject
35 ~KGameDifficultyPrivate();
37 void init(KXmlGuiWindow
* window
, const QObject
* recvr
, const char* slotStandard
, const char* slotCustom
);
39 void rebuildActions();
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
);
51 * @brief Current custom difficulty level
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
;
63 KComboBox
* m_comboBox
;
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
);
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
);
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
);
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)
108 m_oldSelection
= -1; // No valid selection
109 m_level
= KGameDifficulty::NoLevel
;
112 QObject::connect(this, SIGNAL(standardLevelChanged(KGameDifficulty::standardLevel
)), recvr
, slotStandard
);
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
);
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
);
143 setSelection(newSelection
);
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
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
:
177 return qMakePair(QByteArray(), QString());
180 void KGameDifficultyPrivate::rebuildActions()
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
]);
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
) {
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
))
265 int i
= (m_customLevels
.uniqueKeys()).indexOf(key
) + a
;
266 m_menu
->setCurrentItem(i
);
267 m_comboBox
->setCurrentIndex(i
);
269 if (key
!= m_levelCustom
) {
271 emit
customLevelChanged(key
);
274 m_oldSelection
= m_menu
->currentItem();
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
)
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."));
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
)
315 if ((level
!=Custom
) && (level
!=NoLevel
)) {
316 self()->d
->m_standardLevels
.append(level
);
317 self()->d
->rebuildActions();
322 void KGameDifficulty::removeStandardLevel(standardLevel level
)
326 self()->d
->m_standardLevels
.removeAll(level
);
327 self()->d
->rebuildActions();
331 void KGameDifficulty::addCustomLevel(int key
, const QString
& appellation
)
335 self()->d
->m_customLevels
.insert(key
, appellation
);
336 self()->d
->rebuildActions();
340 void KGameDifficulty::removeCustomLevel(int key
)
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
)
363 self()->d
->setLevel(level
);
367 void KGameDifficulty::setLevelCustom(int key
)
371 self()->d
->setLevelCustom(key
);
375 int KGameDifficulty::levelCustom()
379 return self()->d
->m_levelCustom
;
383 KGameDifficulty::standardLevel
KGameDifficulty::level()
387 return self()->d
->m_level
;
391 QString
KGameDifficulty::levelString()
395 return self()->d
->standardLevelString(self()->d
->m_level
).second
;
399 QPair
<QByteArray
, QString
> KGameDifficulty::localizedLevelString()
403 return self()->d
->standardLevelString(self()->d
->m_level
);
407 QMap
<QByteArray
, QString
> KGameDifficulty::localizedLevelStrings()
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
);
425 QMap
<int, QByteArray
> KGameDifficulty::levelWeights()
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
);
442 void KGameDifficulty::setRunning(bool running
)
446 self()->d
->m_running
= running
;
450 KGameDifficulty::KGameDifficulty() : d(new KGameDifficultyPrivate())
455 KGameDifficulty
* KGameDifficulty::self()
458 instance
= new KGameDifficulty();
462 #include "kgamedifficulty.moc"