summaryrefslogtreecommitdiffstats
path: root/libkdegames/highscore/kexthighscore.h
blob: 5809a89639161e5abab5a48c6fdf4c37d117dad4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
/*
    This file is part of the KDE games library
    Copyright (C) 2001-2004 Nicolas Hadacek (hadacek@kde.org)

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

    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.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#ifndef KEXTHIGHSCORE_H
#define KEXTHIGHSCORE_H

#include "kexthighscore_item.h"

#include <kurl.h>
#include <kdemacros.h>

class TQTabWidget;


namespace KExtHighscore
{

class Score;
class Item;

class ManagerPrivate;
extern ManagerPrivate *internal;

/**
 * Get the current game type.
 */
KDE_EXPORT uint gameType();

/**
 * Set the current game type.
 */
KDE_EXPORT void setGameType(uint gameType);

/**
 * Configure the highscores.
 * @return true if the configuration has been modified and saved
 */
KDE_EXPORT bool configure(TQWidget *parent);

/**
 * Show the highscores lists.
 */
KDE_EXPORT void show(TQWidget *parent);

/**
 * Submit a score. See @ref Manager for usage example.
 *
 * @param widget a widget used as parent for error message box.
 */
KDE_EXPORT void submitScore(const Score &score, TQWidget *widget);

/**
 * @return the last score in the local list of highscores. The worst possible
 * score if there are less items than the maximum number.
 */
KDE_EXPORT Score lastScore();

/**
 * @return the first score in the local list of highscores (the worst possible
 * score if there is no entry).
 */
KDE_EXPORT Score firstScore();

/**
 * This class manages highscores and players entries (several players can
 * share the same highscores list if the libkdegame library is built to
 * support a common highscores file; NOTE that to correctly implement such
 * feature we probably need a locking mechanism in @ref KHighscore).
 *
 * You need one instance of this class during the application lifetime ; in
 * main() just insert 
 * \code
 *   KExtHighscore::Manager highscoresManager;
 * \endcode
 * with the needed arguments. Use the derived class if you need to
 * reimplement some of the default methods.
 *
 * This class has three functions :
 * <ul>
 * <li> Update the highscores list when new entries are submitted </li>
 * <li> Display the highscores list and the players list </li>
 * <li> Send query to an optionnal web server to support world-wide
 *      highscores </li>
 * </ul>
 *
 * The highscores and the players lists contain several items described by
 * the @ref Item class.
 *
 * The highscores list contains by default :
 * <ul>
 * <li> the player name (automatically set from the config value)</li>
 * <li> the score value </li>
 * <li> the time and date of the highscore (automatically set) </li>
 * </ul>
 * You can replace the score item (for e.g. displaying it differently) with
 * setScoreItem or add an item with addScoreItem.
 *
 * The players list contains :
 * <ul>
 * <li> the player name (as defined by the user in the configuration
 *      dialog) </li>
 * <li> the number of games played </li>
 * <li> the mean score </li>
 * <li> the best score </li>
 * <li> the best score time and date </li>
 * <li> the player comment (as defined by the user in the
 *      configuration dialog) </li>
 * </ul>
 * You can replace the best score and the mean score items
 * by calling setPlayerItem.
 *
 * To submit a new score at game end, just construct a Score, set the
 * score data and then call submitScore().
 * \code
 *     KExtHighscore::Score score(KExtHighscore::Won);
 *     score.setScore(myScore);
 *     KExtHighscore::submitScore(score, widget);
 * \endcode
 * You only need to set the score value with Score::setScore()
 * and the value of the items that you have optionnally added
 * with Score::setData() ; player name and date are set automatically.
 */
class KDE_EXPORT Manager
{
 public:
    /**
     * Constructor
     *
     * @param nbGameTypes the number of different game types (usually one).
     *        For example KMines has easy, normal and expert levels.
     * @param maxNbEntries the maximum numbers of highscores entries (by game
     *        types)
     */
    Manager(uint nbGameTypes = 1, uint maxNbEntries = 10);
    virtual ~Manager();
    
    /**
     * Set the world-wide highscores.
     * By default there is no world-wide highscores.
     *
     * Note: should be called at construction time.
     *
     * @param url the web server url
     * @param version the game version which is sent to the web server (it can
     * be useful for backward compatibility on the server side).
     */
    void setWWHighscores(const KURL &url, const TQString &version);

    /**
     * Set if the number of lost games should be track for the world-wide
     * highscores statistics. By default, there is no tracking.
     * False by default.
     *
     * Note: should be called at construction time.
     */
    void setTrackLostGames(bool track);
    
    /**
     * @since 3.3
     * Set if the number of "draw" games should be track for the world-wide
     * highscores statistics. By default, there is no tracking.
     * False by default.
     *
     * Note: should be called at construction time.
     */
    void setTrackDrawGames(bool track);

    /**
     * @since 3.3
     * Set if the statistics tab should be shown in the highscores dialog.
     * You only want to show this tab if it makes sense to lose or to win the
     * game (for e.g. it makes no sense for a tetris game but it does for a
     * minesweeper game).
     * False by default.
     *
     * Note: should be called at construction time.
     */
    void setShowStatistics(bool show);
    
    /** @obsolete */
    // KDE4 remove this
    void showStatistics(bool show) KDE_DEPRECATED;
    
    /**
     * @since 3.3
     * Set if draw games statistics should be shown (enable this if
     * draws are possible in your game).
     * False by default.
     */
    void setShowDrawGamesStatistic(bool show);

    enum ScoreTypeBound { ScoreNotBound, ScoreBound };
    /**
     * Set the ranges for the score histogram.
     *
     * Note: should be called at construction time.
     */
    void setScoreHistogram(const TQMemArray<uint> &scores, ScoreTypeBound type);

    /** 
    * Enumerate different conditions under which to show the
    * high score dialog.
    */
    enum ShowMode { AlwaysShow,          ///< Always show the dialog
                    NeverShow,           ///< Never show the dialog
                    ShowForHigherScore,  ///< Show if score has improved
                    ShowForHighestScore  ///< Only for the top spot
                  };
    /**
     * Set how the highscores dialog is shown at game end.
     * By default, the mode is ShowForHigherScore.
     *
     * Note: should be called at construction time.
     */
    void setShowMode(ShowMode mode);

    /**
     * Score type (@see setScoreType).
     * @p Normal default score (unsigned integer without upper bound)
     * @p MinuteTime score by time bound at 3599 seconds (for e.g. kmines)
     */
    enum ScoreType { Normal, MinuteTime };
    /**
     * Set score type. Helper method to quickly set the type of score.
     * By default the type is Normal.
     *
     * Note: should be called at construction time.
     */
    void setScoreType(ScoreType type);

    /**
     * Some predefined item types.
     * @p ScoreDefault default item for the score in the highscores list.
     * @p MeanScoreDefault default item for the mean score (only show one decimal and
     * 0 is shown as "--".
     * @p BestScoreDefault default item for the best score (0 is shown as "--").
     * @p ElapsedTime optionnal item for elapsed time (maximum value is 3599 seconds).
     */
    enum ItemType { ScoreDefault, MeanScoreDefault, BestScoreDefault,
                    ElapsedTime };
    /**
     * Create a predefined item.
     */
    static Item *createItem(ItemType type);

    /**
     * Replace the default score item in the highscores list by the given one.
     * @p worstScore is the worst possible score. By default it is 0.
     *
     * Note : This method should be called at construction time.
     */
    void setScoreItem(uint worstScore, Item *item);

    /**
     * Add an item in the highscores list (it will add a column to this list).
     *
     * Note : This method should be called at construction time.
     */
    void addScoreItem(const TQString &name, Item *item);

    enum PlayerItemType { MeanScore, BestScore };
    /**
     * Replace an item in the players list.
     *
     * Note : This method should be called at construction time.
     */
    void setPlayerItem(PlayerItemType type, Item *item);

    /**
     * @return true if the first score is strictly worse than the second one.
     * By default return <pre>s1.score()<s2.score()</pre>. You can reimplement
     * this method if additional items added to @ref Score can further
     * differentiate the scores (for e.g. the time spent).
     *
     * Note that you do not need to use directly this method, simply write
     * <pre>s1<s2</pre> since the operator calls this method.
     */
    virtual bool isStrictlyLess(const Score &s1, const Score &s2) const;

    /**
     * Possible type of label (@see gameTypeLabel).
     * @p Standard label used in config file.
     * @p I18N label used to display the game type.
     * @p WW label used when contacting the world-wide highscores server.
     * @p Icon label used to load the icon corresponding to the game type.
     */
    enum LabelType { Standard, I18N, WW, Icon };

    /**
     * @return the label corresponding to the game type. The default
     * implementation works only for one game type : you need to reimplement
     * this method if the number of game types is more than one.
     */
    virtual TQString gameTypeLabel(uint gameType, LabelType type) const;

 protected:
    /**
     * This method is called once for each player (ie for each user). You
     * can reimplement it to convert old style highscores to the new mechanism
     * (@see submitLegacyScore). By default this method does nothing.
     *
     * @param gameType the game type
     */
    virtual void convertLegacy(uint gameType) { Q_UNUSED(gameType); }

    /**
     * This method should be called from @ref convertLegacy. It is used
     * to submit an old highscore (it will not be send over the network).
     * For each score do something like:
     * \code
     * Score score(Won);
     * score.setScore(oldScore);
     * score.setData("name", name);
     * submitLegacyScore(score);
     * \endcode
     * Note that here you can set the player "name" and the highscore "date"
     * if they are known.
     */
    void submitLegacyScore(const Score &score) const;

    /**
     * This method is called before submitting a score to the world-wide
     * highscores server. You can reimplement this method to add an entry
     * with @ref addToQueryURL. By default this method does nothing.
     *
     * @param url the URL to query
     * @param score the score to be submitted.
     */
    virtual void additionalQueryItems(KURL &url, const Score &score) const
        { Q_UNUSED(url); Q_UNUSED(score); }

    /**
     * Add an entry to the url to be submitted (@see additionalQueryItems).
     *
     * @param url the URL to query
     * @param item the item name
     * @param content the item content
     */
    static void addToQueryURL(KURL &url, const TQString &item,
                              const TQString &content);

    friend class ManagerPrivate;

 private:
    Manager(const Manager &);
    Manager &operator =(const Manager &);
};

} // namespace

#endif