Commit 25d6e44d authored by Ian Wadham's avatar Ian Wadham

Fix the translation of game names, level names, game descriptions and hints....

Fix the translation of game names, level names, game descriptions and hints. Make translation procedures more consistent between gameplay, replays and editing. Add a UTC time-stamp in ISO format to recordings of gameplay.

svn path=/trunk/KDE/kdegames/kgoldrunner/; revision=981744
parent 1e268056
......@@ -183,10 +183,11 @@ KGrECDialog::KGrECDialog (int action, int gameIndex,
if ((action == SL_UPD_GAME) &&
(myGameList.at (defaultGame)->about.length() > 0)) {
// Display and edit the game description in its original language.
mle-> setText (myGameList.at (defaultGame)->about);
mle->setPlainText (QString::fromUtf8
(myGameList.at (defaultGame)->about.constData()));
}
else {
mle-> setText ("");
mle->setPlainText ("");
}
connect (ecKGrB, SIGNAL (clicked()), this, SLOT (ecSetKGr()));
......
......@@ -601,7 +601,7 @@ bool KGrEditor::editGame (int pGameIndex)
// Create or update the editable values.
gameData->rules = rules;
gameData->prefix = ecPrefix;
gameData->name = ecName.toUtf8();
gameData->name = ecName;
gameData->about = ec->getAboutText().toUtf8();
saveGameData (USER);
......@@ -812,9 +812,11 @@ bool KGrEditor::saveGameData (Owner o)
foreach (KGrGameData * gData, gameList) {
if (gData->owner == o) {
line.sprintf ("%03d %c %s %s\n", gData->nLevels, gData->rules,
gData->prefix.toLatin1().constData(),
gData->name.constData());
line = QString ("%1 %2 %3 %4\n")
.arg (gData->nLevels, 3, 10, QChar('0')) // int 00n
.arg (gData->rules) // char
.arg (gData->prefix) // QString
.arg (gData->name); // QString
lineC = line.toUtf8();
len = lineC.length();
for (i = 0; i < len; i++) {
......@@ -855,17 +857,15 @@ QString KGrEditor::getTitle()
KGrGameData * gameData = gameList.at(gameIndex);
QString levelNumber = QString::number(editLevel).rightJustified(3,'0');
// TODO - Make sure gameData->name.constData() results in Unicode display
// and not some weird UTF8 character stuff.
QString levelTitle = (levelName.length() <= 0)
?
i18nc ("Game name - level number.",
"%1 - %2",
gameData->name.constData(), levelNumber)
gameData->name, levelNumber)
:
i18nc ("Game name - level number - level name.",
"%1 - %2 - %3",
gameData->name.constData(), levelNumber, levelName);
gameData->name, levelNumber, levelName);
return (levelTitle);
}
......
......@@ -33,6 +33,7 @@
#include <KDebug>
#include <QStringList>
#include <QDateTime>
// TODO - Can we change over to KScoreDialog?
......@@ -792,21 +793,9 @@ bool KGrGame::playLevel (const Owner fileOwner, const QString & prefix,
// so that the player has a little time to observe how the level ended.
view->deleteAllSprites();
// If system game or ENDE, choose system dir, else choose user dir.
const QString dir = ((fileOwner == SYSTEM) || (levelNo == 0)) ?
systemDataDir : userDataDir;
initRecording();
if (playback) {
kDebug() << "loadRecording" << dir << prefix << levelNo;
loadRecording (dir, prefix, levelNo);
}
else {
KGrGameIO io (view);
// Read the level data.
if (! io.readLevelData (dir, prefix, levelNo, recording->levelData)) {
return false;
}
// Set up to record or play back: load either level-data or recording-data.
if (! initRecordingData (fileOwner, prefix, levelNo)) {
return false;
}
view->setLevel (levelNo); // Switch and render background if reqd.
......@@ -817,16 +806,11 @@ bool KGrGame::playLevel (const Owner fileOwner, const QString & prefix,
// state? And how about starting in Ready state in some cases?
setupLevelPlayer();
// If there is a name, translate the UTF-8 coded QByteArray right now.
levelName = (recording->levelData.name.size() > 0) ?
i18n ((const char *) recording->levelData.name) : "";
levelName = recording->levelName;
levelHint = recording->hint;
// Indicate on the menus whether there is a hint for this level.
int len = recording->levelData.hint.length();
emit hintAvailable (len > 0);
// If there is a hint, translate it right now.
levelHint = (len > 0) ? i18n((const char *) recording->levelData.hint) : "";
emit hintAvailable (levelHint.length() > 0);
// Re-draw the playfield frame, level title and figures.
view->setTitle (getTitle());
......@@ -1010,7 +994,7 @@ void KGrGame::goUpOneLevel()
KGrMessage::information (view, gameData->name,
i18n ("<b>CONGRATULATIONS !!!!</b>"
"<p>You have conquered the last level in the "
"<b>\"%1\"</b> game !!</p>", gameData->name.constData()));
"<b>\"%1\"</b> game !!</p>", gameData->name));
checkHighScore(); // Check if there is a high score for this game.
freeze (ProgramPause, false);
......@@ -1181,7 +1165,7 @@ QString KGrGame::getDirectory (Owner o)
QString KGrGame::getTitle()
{
int lev = (playback) ? recording->levelData.level : level;
int lev = (playback) ? recording->level : level;
KGrGameData * gameData = gameList.at (gameIndex);
if (lev == 0) {
// Generate a special title for end of game.
......@@ -1190,10 +1174,8 @@ QString KGrGame::getTitle()
// Set title string to "Game-name - NNN" or "Game-name - NNN - Level-name".
QString gameName = (playback) ? recording->gameName : gameData->name;
QString levelNumber = QString::number(level).rightJustified(3,'0');
QString levelNumber = QString::number(lev).rightJustified(3,'0');
// TODO - Make sure gameData->name.constData() results in Unicode display
// and not some weird UTF8 character stuff.
QString levelTitle = (levelName.length() <= 0)
?
i18nc ("Game name - level number.",
......@@ -1201,8 +1183,6 @@ QString KGrGame::getTitle()
:
i18nc ("Game name - level number - level name.",
"%1 - %2 - %3", gameName, levelNumber, levelName);
// TODO - This is where playback needs to get data from inside KGrRecording.
// TODO - ... or not, as the case may be.
return (levelTitle);
}
......@@ -1659,7 +1639,7 @@ void KGrGame::showHighScores()
if (! high1.exists()) {
KGrMessage::information (view, i18n ("Show High Scores"),
i18n("Sorry, there are no high scores for the \"%1\" game yet.",
gameList.at (gameIndex)->name.constData()));
gameList.at (gameIndex)->name));
return;
}
}
......@@ -1684,7 +1664,7 @@ void KGrGame::showHighScores()
QLabel * hsHeader = new QLabel (i18n (
"<center><h2>KGoldrunner Hall of Fame</h2></center>"
"<center><h3>\"%1\" Game</h3></center>",
gameList.at (gameIndex)->name.constData()),
gameList.at (gameIndex)->name),
hs);
mainLayout->addWidget (hsHeader, 10);
......@@ -1878,7 +1858,8 @@ bool KGrGame::loadGameData (Owner o)
return (result);
}
void KGrGame::initRecording()
bool KGrGame::initRecordingData (const Owner fileOwner, const QString & prefix,
const int levelNo)
{
// Initialise the recording.
if (recording) {
......@@ -1888,16 +1869,54 @@ void KGrGame::initRecording()
recording->content.fill (0, 4000);
recording->draws.fill (0, 400);
KGrGameData * gameData = gameList.at (gameIndex);
recording->owner = gameData->owner;
recording->rules = gameData->rules;
recording->prefix = gameData->prefix;
recording->gameName = gameData->name;
recording->lives = lives;
recording->score = score;
recording->speed = timeScale;
recording->controlMode = controlMode;
recording->content [0] = 0xff;
// If system game or ENDE, choose system dir, else choose user dir.
const QString dir = ((fileOwner == SYSTEM) || (levelNo == 0)) ?
systemDataDir : userDataDir;
if (playback) {
kDebug() << "loadRecording" << dir << prefix << levelNo;
if (! loadRecording (dir, prefix, levelNo)) {
return false;
}
}
else {
KGrGameIO io (view);
KGrLevelData levelData;
// Read the level data.
kDebug() << "io.readLevelData" << dir << prefix << levelNo;
if (! io.readLevelData (dir, prefix, levelNo, levelData)) {
return false;
}
recording->dateTime = QDateTime::currentDateTime()
.toUTC()
.toString (Qt::ISODate);
kDebug() << "Recording at" << recording->dateTime;
KGrGameData * gameData = gameList.at (gameIndex);
recording->owner = gameData->owner;
recording->rules = gameData->rules;
recording->prefix = gameData->prefix;
recording->gameName = gameData->name;
recording->level = levelNo;
recording->width = levelData.width;
recording->height = levelData.height;
recording->layout = levelData.layout;
// If there is a name or hint, translate the UTF-8 code right now.
recording->levelName = (levelData.name.size() > 0) ?
i18n (levelData.name.constData()) : "";
recording->hint = (levelData.hint.size() > 0) ?
i18n (levelData.hint.constData()) : "";
recording->lives = lives;
recording->score = score;
recording->speed = timeScale;
recording->controlMode = controlMode;
recording->content [0] = 0xff;
}
return true;
}
void KGrGame::saveRecording()
......@@ -1908,16 +1927,17 @@ void KGrGame::saveRecording()
KConfig config (filename, KConfig::SimpleConfig);
KConfigGroup configGroup = config.group (groupName);
configGroup.writeEntry ("DateTime", recording->dateTime);
configGroup.writeEntry ("Owner", (int) recording->owner);
configGroup.writeEntry ("Rules", (int) recording->rules);
configGroup.writeEntry ("Prefix", recording->prefix);
configGroup.writeEntry ("GameName", recording->gameName);
configGroup.writeEntry ("Level", recording->levelData.level);
configGroup.writeEntry ("Width", recording->levelData.width);
configGroup.writeEntry ("Height", recording->levelData.height);
configGroup.writeEntry ("Layout", recording->levelData.layout);
configGroup.writeEntry ("Name", recording->levelData.name);
configGroup.writeEntry ("Hint", recording->levelData.hint);
configGroup.writeEntry ("Level", recording->level);
configGroup.writeEntry ("Width", recording->width);
configGroup.writeEntry ("Height", recording->height);
configGroup.writeEntry ("Layout", recording->layout);
configGroup.writeEntry ("Name", recording->levelName);
configGroup.writeEntry ("Hint", recording->hint);
configGroup.writeEntry ("Lives", (int) recording->lives);
configGroup.writeEntry ("Score", (int) recording->score);
configGroup.writeEntry ("Speed", (int) recording->speed);
......@@ -1954,7 +1974,7 @@ void KGrGame::saveRecording()
gameGroup.sync(); // Ensure that the entry goes to disk.
}
void KGrGame::loadRecording (const QString & dir, const QString & prefix,
bool KGrGame::loadRecording (const QString & dir, const QString & prefix,
const int levelNo)
{
kDebug() << prefix << levelNo;
......@@ -1963,26 +1983,25 @@ void KGrGame::loadRecording (const QString & dir, const QString & prefix,
kDebug() << filename << groupName;
KConfig config (filename, KConfig::SimpleConfig);
KConfigGroup configGroup = config.group (groupName);
// KConfigGroup configGroup = config.group ("fred");
if (! configGroup.isValid()) {
// TODO - This does not work as a test of whether the group exists.
kDebug() << "Group:" << "fred" << "is INVALID";
return;
if (! config.hasGroup (groupName)) {
kDebug() << "Group" << groupName << "NOT FOUND";
return false;
}
KConfigGroup configGroup = config.group (groupName);
QByteArray blank ("");
recording->dateTime = configGroup.readEntry ("DateTime", "");
recording->owner = (Owner)(configGroup.readEntry
("Owner", (int)(USER)));
recording->rules = configGroup.readEntry ("Rules", (int)('T'));
recording->prefix = configGroup.readEntry ("Prefix", "");
recording->gameName = configGroup.readEntry ("GameName", blank);
recording->levelData.level = configGroup.readEntry ("Level", 1);
recording->levelData.width = configGroup.readEntry ("Width", FIELDWIDTH);
recording->levelData.height = configGroup.readEntry ("Height", FIELDHEIGHT);
recording->levelData.layout = configGroup.readEntry ("Layout", blank);
recording->levelData.name = configGroup.readEntry ("Name", blank);
recording->levelData.hint = configGroup.readEntry ("Hint", blank);
recording->level = configGroup.readEntry ("Level", 1);
recording->width = configGroup.readEntry ("Width", FIELDWIDTH);
recording->height = configGroup.readEntry ("Height", FIELDHEIGHT);
recording->layout = configGroup.readEntry ("Layout", blank);
recording->levelName = configGroup.readEntry ("Name", blank);
recording->hint = configGroup.readEntry ("Hint", blank);
recording->lives = configGroup.readEntry ("Lives", 5);
recording->score = configGroup.readEntry ("Score", 0);
recording->speed = configGroup.readEntry ("Speed", 10);
......@@ -2015,6 +2034,7 @@ void KGrGame::loadRecording (const QString & dir, const QString & prefix,
emit showLives (lives);
score = recording->score;
emit showScore (score);
return true;
}
void KGrGame::loadSounds()
......
......@@ -249,12 +249,13 @@ private:
/*********************** GAME PROPERTIES AND METHODS **********************/
/******************************************************************************/
bool loadGameData (Owner);
void initRecording ();
void saveRecording ();
void loadRecording (const QString & dir, const QString & prefix,
const int levelNo);
void loadSounds ();
bool loadGameData (Owner);
bool initRecordingData (const Owner fileOwner, const QString & prefix,
const int levelNo);
void saveRecording();
bool loadRecording (const QString & dir, const QString & prefix,
const int levelNo);
void loadSounds();
/******************************************************************************/
/********************** WORD-WRAPPED MESSAGE BOX ************************/
......
......@@ -71,6 +71,7 @@ IOStatus KGrGameIO::fetchGameListData
char c;
QByteArray textLine;
QByteArray gameName;
// Find the first line of game-data.
c = getALine (kgr3Format, textLine);
......@@ -102,7 +103,8 @@ IOStatus KGrGameIO::fetchGameListData
g->skill = fields.at (3).at (0);
c = getALine (kgr3Format, textLine);
if (c == ' ') {
g->name = removeNewline (textLine);
gameName = removeNewline (textLine);
g->name = i18n (gameName.constData());
}
}
else {
......@@ -112,7 +114,8 @@ IOStatus KGrGameIO::fetchGameListData
n = textLine.indexOf (' ', n) + 1;
n = textLine.indexOf (' ', n) + 1;
n = textLine.indexOf (' ', n) + 1;
g->name = removeNewline (textLine.right (textLine.size() - n));
gameName = removeNewline (textLine.right (textLine.size() - n));
g->name = i18n (gameName.constData());
}
// kDebug() << "Skill:" << g->skill << "Name:" << g->name;
......@@ -345,8 +348,8 @@ KGrGameData * KGrGameIO::initGameData (Owner o)
g->skill = 'N'; // Game's skill: Tutorial, Normal or Champion.
g->width = FIELDWIDTH; // Default width of layout grid (28 cells).
g->height = FIELDHEIGHT; // Default height of layout grid (20 cells).
g->name = ""; // Name of the game.
g->about = ""; // Optional text about the game.
g->name = ""; // Name of the game (translated, if System game).
g->about = ""; // Optional text about the game (untranslated).
return (g);
}
......
......@@ -88,39 +88,44 @@ public:
class KGrGameData
{
public:
Owner owner; ///< Owner of the game: "System" or "User".
Owner owner; ///< Owner of the game: "System" or "User".
int nLevels; ///< Number of levels in the game.
char rules; ///< Game's rules: KGoldrunner or Traditional.
QString prefix; ///< Game's filename prefix.
char skill; ///< Game's skill: Tutorial, Normal or Champion.
int width; ///< Width of grid, in cells.
int height; ///< Height of grid, in cells.
QByteArray name; ///< Name of the game.
QByteArray about; ///< Optional info about the game.
QString name; ///< Name of game (translated, if System game).
QByteArray about; ///< Optional info about game (untranslated).
};
/// KGrLevelData structure: contains attributes of a KGoldrunner level.
class KGrLevelData
{
public:
int level; ///< Level number.
int level; ///< Level number.
int width; ///< Width of grid, in cells.
int height; ///< Height of grid, in cells.
QByteArray layout; ///< Codes for the level layout (mandatory).
QByteArray name; ///< Level name (optional).
QByteArray hint; ///< Level hint (optional).
QByteArray layout; ///< Codes for the level layout (mandatory).
QByteArray name; ///< Level name (optional).
QByteArray hint; ///< Level hint (optional).
};
/// KGrRecording structure: contains a record of play in a KGoldrunner level.
class KGrRecording
{
public:
// TODO - Use same header data (including date/time) as Save Game does.
QString dateTime; ///< Date+time of recording (UTC in ISO format).
Owner owner; ///< Original owner, at time of recording.
char rules; ///< Rules that applied then.
char rules; ///< Rules that applied at time of recording.
QString prefix; ///< Game's filename prefix.
QByteArray gameName; ///< Name of the game.
KGrLevelData levelData; ///< The level data, at time of recording.
QString gameName; ///< Name of the game (translated at rec time).
int level; ///< Level number (at time of recording).
int width; ///< Width of grid, in cells (at rec time).
int height; ///< Height of grid, in cells (at rec time).
QByteArray layout; ///< Codes for the level layout (at rec time).
QString levelName; ///< Name of the level (translated at rec time).
QString hint; ///< Hint (translated at recording time).
long lives; ///< Number of lives at start of level.
long score; ///< Score at start of level.
int speed; ///< Speed of game during recording (normal=10).
......
......@@ -20,16 +20,16 @@
#include <stdio.h> // OBSOLESCENT - 6/1/09 - Used for testing.
#include "kgrlevelgrid.h"
KGrLevelGrid::KGrLevelGrid (QObject * parent, const KGrLevelData & theLevelData)
KGrLevelGrid::KGrLevelGrid (QObject * parent, const KGrRecording * theLevelData)
:
QObject (parent)
{
// Put a concrete wall all round the layout: left, right, top and bottom.
// This saves ever having to test for being at the edge of the layout.
int inWidth = theLevelData.width;
int inWidth = theLevelData->width;
width = inWidth + ConcreteWall * 2;
int inHeight = theLevelData.height;
int inHeight = theLevelData->height;
height = inHeight + ConcreteWall * 2;
int size = width * height;
......@@ -47,7 +47,7 @@ KGrLevelGrid::KGrLevelGrid (QObject * parent, const KGrLevelData & theLevelData)
for (int j = 0; j < inHeight; j++) {
for (int i = 0; i < inWidth; i++) {
char type = theLevelData.layout [inRow + i];
char type = theLevelData->layout [inRow + i];
switch (type) {
case HLADDER:
// Change hidden ladders to FREE, but keep a list of them.
......
......@@ -28,7 +28,7 @@ class KGrLevelGrid : public QObject
{
Q_OBJECT
public:
KGrLevelGrid (QObject * parent, const KGrLevelData & theLevelData);
KGrLevelGrid (QObject * parent, const KGrRecording * theLevelData);
~KGrLevelGrid();
inline char cellType (int i, int j) {
......
......@@ -113,11 +113,11 @@ void KGrLevelPlayer::init (KGrCanvas * view, const int mode,
playback = pPlayback;
// Create the internal model of the level-layout.
grid = new KGrLevelGrid (this, recording->levelData);
grid = new KGrLevelGrid (this, recording);
controlMode = mode; // Set mouse/keyboard/laptop control.
levelWidth = recording->levelData.width;
levelHeight = recording->levelData.height;
levelWidth = recording->width;
levelHeight = recording->height;
reappearIndex = levelWidth; // Initialise the enemy-rebirth code.
reappearPos.fill (1, levelWidth);
......
......@@ -93,7 +93,7 @@ bool KGrSLDialog::selectLevel (int & selectedGame, int & selectedLevel)
i18n ("There is no level %1 in \"%2\", "
"so you cannot play or edit it.",
selectedLevel,
myGameList.at (selectedGame)->name.constData()));
myGameList.at (selectedGame)->name));
selectedLevel = 0; // Set an invalid selection.
continue; // Re-run the dialog box.
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment