1 | /**************************************************************** |
2 | Copyright (c) 1998 Sandro Sigala <ssigala@globalnet.it> |
3 | Copyright (c) 2001 Waldo Bastian <bastian@kde.org> |
4 | Copyright (c) 2007 Matt Williams <matt@milliams.com> |
5 | All rights reserved. |
6 | |
7 | Permission to use, copy, modify, and distribute this software |
8 | and its documentation for any purpose and without fee is hereby |
9 | granted, provided that the above copyright notice appear in all |
10 | copies and that both that the copyright notice and this |
11 | permission notice and warranty disclaimer appear in supporting |
12 | documentation, and that the name of the author not be used in |
13 | advertising or publicity pertaining to distribution of the |
14 | software without specific, written prior permission. |
15 | |
16 | The author disclaim all warranties with regard to this |
17 | software, including all implied warranties of merchantability |
18 | and fitness. In no event shall the author be liable for any |
19 | special, indirect or consequential damages or any damages |
20 | whatsoever resulting from loss of use, data or profits, whether |
21 | in an action of contract, negligence or other tortious action, |
22 | arising out of or in connection with the use or performance of |
23 | this software. |
24 | ****************************************************************/ |
25 | |
26 | #ifndef KSCOREDIALOG_H |
27 | #define KSCOREDIALOG_H |
28 | |
29 | #include <libkdegames_export.h> |
30 | |
31 | #include <QtCore/QMap> |
32 | #include <QtCore/QFlags> |
33 | |
34 | #include <kdialog.h> |
35 | |
36 | class KLocalizedString; |
37 | class KgDifficulty; |
38 | |
39 | /** |
40 | * \class KScoreDialog kscoredialog.h <KScoreDialog> |
41 | * |
42 | * @short A simple high score implementation |
43 | * |
44 | * This class can be used both for displaying the current high scores |
45 | * and also for adding new highscores. It is the recommended way of |
46 | * implementing a simple highscore table. |
47 | * |
48 | * To display the current highscores it is simply a case of creating |
49 | * a KScoreDialog object and calling exec(). This example code will |
50 | * display the Name and Score (the score is always added automatically |
51 | * unless hidden @ref hideField since it is used for sorting) of the |
52 | * top 10 players: |
53 | * \code |
54 | * KScoreDialog ksdialog(this); |
55 | * ksdialog.exec(); |
56 | * \endcode |
57 | * |
58 | * To add a new highscore, e.g. at the end of a game you simply create an |
59 | * object with the @ref Fields you want to write (i.e. KScoreDialog::Name | |
60 | * KScoreDialog::Score), call addScore and then (optionally) display |
61 | * the dialog. |
62 | * This code will allow you to add a highscore with a Name and Score |
63 | * field. If it's the first time a player has a score on the table, they |
64 | * will be prompted for their name but subsequent times they will have |
65 | * their name filled in automatically. |
66 | * \code |
67 | * KScoreDialog ksdialog(this); |
68 | * ksdialog.addScore(playersScore); |
69 | * ksdialog.exec(); |
70 | * \endcode |
71 | * |
72 | * Or if you want to fill the name in from the code you can pass a default |
73 | * name by doing |
74 | * \code |
75 | * KScoreDialog::FieldInfo scoreInfo; |
76 | * scoreInfo[KScoreDialog::Name] = "Matt"; |
77 | * scoreInfo[KScoreDialog::Score].setNum(playersScore); |
78 | * ksdialog.addScore(scoreInfo); |
79 | * \endcode |
80 | * |
81 | * If you want to add an extra field (e.g. the number of moves taken) then |
82 | * do |
83 | * \code |
84 | * KScoreDialog::FieldInfo scoreInfo; |
85 | * scoreInfo[KScoreDialog::Name] = "Matt"; |
86 | * scoreInfo[KScoreDialog::Score].setNum(playersScore); |
87 | * |
88 | * ksdialog.addField(KScoreDialog::Custom1, "Num of Moves", "moves"); |
89 | * scoreInfo[KScoreDialog::Custom1].setNum(42); |
90 | * |
91 | * ksdialog.addScore(scoreInfo); |
92 | * \endcode |
93 | * You can define up to 5 Custom fields. |
94 | * @author Matt Williams <matt@milliams.com> |
95 | */ |
96 | class KDEGAMES_EXPORT KScoreDialog : public KDialog |
97 | { |
98 | Q_OBJECT |
99 | |
100 | public: |
101 | ///Highscore fields |
102 | enum Fields { |
103 | Name = 1 << 0, |
104 | Level = 1 << 1, |
105 | Date = 1 << 2, |
106 | Time = 1 << 3, |
107 | Score = 1 << 4, |
108 | |
109 | Custom1 = 1 << 10, ///<Field for custom information |
110 | Custom2 = 1 << 11, |
111 | Custom3 = 1 << 12, |
112 | Custom4 = 1 << 13, |
113 | Custom5 = 1 << 14, |
114 | |
115 | Max = 1 << 30 ///<Only for setting a maximum |
116 | }; |
117 | |
118 | ///Flags for setting preferences for adding scores |
119 | enum AddScoreFlag |
120 | { |
121 | AskName = 0x1, /**< Promt the player for their name */ |
122 | LessIsMore = 0x2 /**< A lower numerical score means higher placing on the table */ |
123 | }; |
124 | Q_DECLARE_FLAGS(AddScoreFlags, AddScoreFlag) |
125 | |
126 | typedef QMap<int, QString> FieldInfo; |
127 | |
128 | /** |
129 | * @param fields Bitwise OR of the @ref Fields that should be listed (Score is always present) |
130 | * @param parent passed to parent QWidget constructor. |
131 | */ |
132 | explicit KScoreDialog(int fields=Name, QWidget *parent=0); |
133 | |
134 | ~KScoreDialog(); |
135 | |
136 | /** |
137 | * The group name must be passed though I18N_NOOP() in order for the |
138 | * group name to be translated. i.e. |
139 | * \code ksdialog.setConfigGroup(I18N_NOOP("Easy")); \endcode |
140 | * If you set a group, it will be prefixed in the config file by |
141 | * 'KHighscore_' otherwise the group will simply be 'KHighscore'. |
142 | * |
143 | * @param group to use for reading/writing highscores from/to. |
144 | * @deprecated since 4.1 |
145 | */ |
146 | void KDE_DEPRECATED setConfigGroup(const QString& group = QString()); |
147 | //void setConfigGroup(const QString& group, const QString& i18nName); |
148 | |
149 | /** |
150 | * The group name must be passed though ki18n() in order for the |
151 | * group name to be translated. i.e. |
152 | * \code ksdialog.setConfigGroup(ki18n("Easy")); \endcode |
153 | * If you set a group, it will be prefixed in the config file by |
154 | * 'KHighscore_' otherwise the group will simply be 'KHighscore'. |
155 | * |
156 | * @param group to use for reading/writing highscores from/to. |
157 | */ |
158 | void setConfigGroup(const QPair<QByteArray, QString>& group); |
159 | |
160 | /** |
161 | * You must add the translations of all group names to the dialog. This |
162 | * is best done by passing the name through ki18n(). |
163 | * The group set through setConfigGroup(const KLocalizedString& group) |
164 | * will be added automatically |
165 | * |
166 | * @param group the translated group name |
167 | */ |
168 | void addLocalizedConfigGroupName(const QPair<QByteArray, QString>& group); |
169 | |
170 | /** |
171 | * You must add the translations of all group names to the dialog. This |
172 | * is best done by passing the name through ki18n(). |
173 | * The group set through setConfigGroup(const KLocalizedString& group) |
174 | * will be added automatically. |
175 | * |
176 | * This function can be used directly with KGameDifficulty::localizedLevelStrings(). |
177 | * |
178 | * @param group the list of translated group names |
179 | */ |
180 | void addLocalizedConfigGroupNames(const QMap<QByteArray, QString>& groups); |
181 | |
182 | /** |
183 | * Hide some config groups so that they are not shown on the dialog |
184 | * (but are still stored in the configuration file). |
185 | * \code |
186 | * ksdialog.setHiddenConfigGroups(QList<QByteArray>() << "Very Easy" << "Easy"); |
187 | * \endcode |
188 | * |
189 | * @param hiddenGroups the list of group names you want to hide |
190 | * |
191 | * @since KDE 4.6 |
192 | */ |
193 | void setHiddenConfigGroups(const QList<QByteArray>& hiddenGroups); |
194 | |
195 | /** |
196 | * It is a good idea giving config group weigths, otherwise tabs |
197 | * get ordered by their tab name that is not probably what you want. |
198 | * |
199 | * This function can be used directly with KGameDifficulty::levelWeights(). |
200 | * |
201 | * @param group the list of untranslated group names and their weights |
202 | * |
203 | * @since KDE 4.2 |
204 | */ |
205 | void setConfigGroupWeights(const QMap<int, QByteArray>& weights); |
206 | |
207 | /** |
208 | * @param comment to add when showing high-scores. |
209 | * The comment is only used once. |
210 | */ |
211 | void (const QString& ); |
212 | |
213 | /** |
214 | * Define an extra FieldInfo entry. |
215 | * @param field id of this field @ref Fields e.g. KScoreDialog::Custom1 |
216 | * @param header text shown in the header in the dialog for this field. e.g. "Number of Moves" |
217 | * @param key unique key used to store this field. e.g. "moves" |
218 | */ |
219 | void addField(int field, const QString& , const QString& key); |
220 | |
221 | /** |
222 | * Hide a field so that it is not shown on the table (but is still stored in the configuration file). |
223 | * @param field id of this field @ref Fields e.g. KScoreDialog::Score |
224 | */ |
225 | void hideField(int field); |
226 | |
227 | /** |
228 | * Adds a new score to the list. |
229 | * |
230 | * @param newInfo info about the score. |
231 | * @param flags set whether the user should be prompted for their name and how the scores should be sorted |
232 | * |
233 | * @returns The highscore position if the score was good enough to |
234 | * make it into the list (1 being topscore) or 0 otherwise. |
235 | */ |
236 | int addScore(const FieldInfo& newInfo = FieldInfo(), const AddScoreFlags& flags=0); |
237 | |
238 | /** |
239 | * Convenience function for ease of use. |
240 | * |
241 | * @param newScore the score of the player. |
242 | * @param flags set whether the user should be prompted for their name and how the scores should be sorted |
243 | * |
244 | * @returns The highscore position if the score was good enough to |
245 | * make it into the list (1 being topscore) or 0 otherwise. |
246 | */ |
247 | int addScore(int newScore, const AddScoreFlags& flags=0); |
248 | |
249 | /** |
250 | * @returns the current best score in the group |
251 | */ |
252 | int highScore(); |
253 | |
254 | /** |
255 | * Assume that config groups (incl. current selection) are equal to |
256 | * difficulty levels, and initialize them. This is usually equal to the |
257 | * following code using KGameDifficulty: |
258 | * @code |
259 | * addLocalizedConfigGroupNames(KGameDifficulty::localizedLevelStrings()); |
260 | * setConfigGroupWeights(KGameDifficulty::levelWeights()); |
261 | * setConfigGroup(KGameDifficulty::localizedLevelString()); |
262 | * @endcode |
263 | */ |
264 | void initFromDifficulty(const KgDifficulty* difficulty, bool setConfigGroup = true); |
265 | |
266 | ///Display the dialog as non-modal |
267 | virtual void show(); |
268 | ///Display the dialog as modal |
269 | virtual void exec(); |
270 | |
271 | private Q_SLOTS: |
272 | void slotGotReturn(); |
273 | void slotGotName(); |
274 | void slotForgetScore(); |
275 | |
276 | private: |
277 | void keyPressEvent(QKeyEvent *ev); |
278 | |
279 | private: |
280 | class KScoreDialogPrivate; |
281 | KScoreDialogPrivate* const d; |
282 | }; |
283 | Q_DECLARE_OPERATORS_FOR_FLAGS(KScoreDialog::AddScoreFlags) |
284 | |
285 | #endif //KSCOREDIALOG_H |
286 | |