39 scene (view->gameScene()),
41 systemDataDir (theSystemDir),
42 userDataDir (theUserDir),
53 connect (timer, SIGNAL (timeout()),
this, SLOT (tick()));
57 connect (view, SIGNAL (mouseClick(
int)), SLOT (doEdit(
int)));
58 connect (view, SIGNAL (mouseLetGo(
int)), SLOT (endEdit(
int)));
78 if (! ownerOK (
USER)) {
80 i18n (
"You cannot create and save a level "
81 "until you have created a game to hold "
82 "it. Try menu item \"Create Game\"."));
87 gameIndex = pGameIndex;
100 for (i = 1; i <= levelData.
width; i++) {
101 for (j = 1; j <= levelData.
height; j++) {
102 insertEditObj (i, j,
FREE);
107 insertEditObj (1, 1,
HERO);
110 savedLevelData.
name = levelData.
name;
111 savedLevelData.
hint = levelData.
hint;
116 mouseDisabled =
false;
127 if (! ownerOK (
USER)) {
129 i18n (
"You cannot edit and save a level until you "
130 "have created a game and a level. Try menu item \"Create Game\"."));
134 gameIndex = pGameIndex;
137 mouseDisabled =
true;
141 int selectedLevel = selectLevel (
SL_UPDATE, level, gameIndex);
142 kDebug() <<
"Selected" << gameList.
at(gameIndex)->name
143 <<
"level" << selectedLevel;
144 if (selectedLevel == 0) {
145 mouseDisabled =
false;
149 if (gameList.
at(gameIndex)->owner ==
SYSTEM) {
151 i18n (
"It is OK to edit a system level, but you MUST save "
152 "the level in one of your own games. You are not just "
153 "taking a peek at the hidden ladders "
154 "and fall-through bricks, are you? :-)"));
157 loadEditLevel (selectedLevel);
158 mouseDisabled =
false;
162 void KGrEditor::loadEditLevel (
int lev)
166 kDebug() <<
"gameIndex" << gameIndex;
169 (lev == 0)) ? systemDataDir : userDataDir;
171 if (! io->
readLevelData (dir, gameList.
at(gameIndex)->prefix, lev, d)) {
182 for (i = 1; i <= levelData.
width; i++) {
183 for (j = 1; j <= levelData.
height; j++) {
185 insertEditObj (i, j, obj);
205 if (nh->exec() == QDialog::Accepted) {
225 if (editLevel == 0) {
235 int selectedLevel = selectLevel (action, editLevel, gameIndex);
236 if (selectedLevel == 0) {
244 filePath = getLevelFilePath (gameList.
at(n), selectedLevel);
245 QFile levelFile (filePath);
247 if ((action ==
SL_SAVE) && (n == N) && (selectedLevel == editLevel)) {
254 if (levelFile.exists()) {
256 i18n (
"Do you want to insert a level and "
257 "move existing levels up by one?"),
258 i18n (
"&Insert Level"), i18n (
"&Cancel"))) {
260 case 0:
if (! reNumberLevels (n, selectedLevel,
261 gameList.
at (n)->nLevels, +1)) {
265 case 1:
return false;
272 if (! levelFile.open (QIODevice::WriteOnly)) {
274 i18n (
"Cannot open file '%1' for output.", filePath));
279 for (j = 1; j <= levelData.
height; j++) {
280 for (i = 1; i <= levelData.
width; i++) {
281 levelFile.putChar (editableCell (i, j));
285 levelFile.putChar (
'\n');
289 int len1 = levelNameC.
length();
291 for (i = 0; i < len1; i++)
292 levelFile.putChar (levelNameC[i]);
293 levelFile.putChar (
'\n');
298 int len2 = levelHintC.
length();
303 levelFile.putChar (
'\n');
304 for (i = 0; i < len2; i++) {
306 levelFile.putChar (ch);
309 levelFile.putChar (
'\n');
316 gameList.
at (n)->nLevels++;
320 editLevel = selectedLevel;
330 i18n (
"You must first load a level to be moved. Use "
331 "the \"%1\" or \"%2\" menu.",
332 i18n (
"Game"), i18n (
"Editor")));
335 gameIndex = pGameIndex;
339 int fromC = gameIndex;
344 if (! ownerOK (
USER)) {
346 i18n (
"You cannot move a level until you "
347 "have created a game and at least two levels. Try "
348 "menu item \"Create Game\"."));
352 if (gameList.
at (fromC)->owner !=
USER) {
354 i18n (
"Sorry, you cannot move a system level."));
359 while ((toC == fromC) && (toL == fromL)) {
360 toL = selectLevel (action, toL, gameIndex);
367 if ((toC == fromC) && (toL == fromL)) {
369 i18n (
"You must change the level or the game or both."));
377 filePath1 = getLevelFilePath (gameList.
at (fromC), fromL);
378 filePath2 = filePath1;
379 filePath2 = filePath2.
append (
".tmp");
387 if (! reNumberLevels (toC, toL, fromL-1, +1)) {
393 if (! reNumberLevels (toC, fromL+1, toL, -1)) {
400 if (! reNumberLevels (fromC, fromL + 1,
401 gameList.
at (fromC)->nLevels, -1)) {
404 gameList.
at (fromC)->nLevels--;
407 if (! reNumberLevels (toC, toL, gameList.
at (toC)->nLevels, +1)) {
410 gameList.
at (toC)->nLevels++;
416 filePath1 = getLevelFilePath (gameList.
at (toC), toL);
428 gameIndex = pGameIndex;
430 if (! ownerOK (
USER)) {
432 i18n (
"You cannot delete a level until you "
433 "have created a game and a level. Try "
434 "menu item \"Create Game\"."));
439 int selectedLevel = selectLevel (action, level, gameIndex);
440 if (selectedLevel == 0) {
448 filePath = getLevelFilePath (gameList.
at (n), selectedLevel);
449 QFile levelFile (filePath);
452 if (levelFile.exists()) {
453 if (selectedLevel < gameList.
at (n)->nLevels) {
455 i18n (
"Do you want to delete a level and "
456 "move higher levels down by one?"),
457 i18n (
"&Delete Level"), i18n (
"&Cancel"))) {
459 case 1:
return false;
break;
462 if (! reNumberLevels (n, selectedLevel + 1,
463 gameList.
at(n)->nLevels, -1)) {
473 i18n (
"Cannot find file '%1' to be deleted.", filePath));
477 gameList.
at (n)->nLevels--;
479 if (selectedLevel <= gameList.
at (n)->nLevels) {
480 editLevel = selectedLevel;
483 editLevel = gameList.
at (n)->nLevels;
488 loadEditLevel (editLevel);
500 gameIndex = pGameIndex;
503 if (gameIndex >= 0) {
504 int selectedLevel = selectLevel (
SL_UPD_GAME, editLevel, gameIndex);
505 if (selectedLevel == 0) {
508 editLevel = selectedLevel;
515 while (ec->exec() == QDialog::Accepted) {
519 int len = ecName.
length();
522 i18n (
"You must enter a name for the game."));
527 if ((action ==
SL_CR_GAME) || (gameList.
at (n)->nLevels <= 0)) {
532 i18n (
"You must enter a filename prefix for the game."));
537 i18n (
"The filename prefix should not "
538 "be more than 5 characters."));
542 bool allAlpha =
true;
543 for (
int i = 0; i < len; i++) {
551 i18n (
"The filename prefix should be "
552 "all alphabetic characters."));
556 bool duplicatePrefix =
false;
558 int imax = gameList.
count();
559 for (
int i = 0; i < imax; i++) {
561 if ((c->
prefix == ecPrefix) && (i != n)) {
562 duplicatePrefix =
true;
567 if (duplicatePrefix) {
569 i18n (
"The filename prefix '%1' is already in use.",
585 gameList.
append (gameData);
586 gameIndex = gameList.
count() - 1;
592 gameData->
skill =
'N';
598 gameData = gameList.
at (gameIndex);
602 gameData->
rules = rules;
603 gameData->
prefix = ecPrefix;
604 gameData->
name = ecName;
620 int KGrEditor::selectLevel (
int action,
int requestedLevel,
int & requestedGame)
622 int selectedLevel = 0;
623 int selectedGame = requestedGame;
627 gameList, systemDataDir, userDataDir,
630 bool selected = sl->
selectLevel (selectedGame, selectedLevel);
634 requestedGame = selectedGame;
635 return (selectedLevel);
650 if ((shouldSave) || (levelData.
layout != savedLevelData.
layout)) {
653 i18n (
"You have not saved your work. Do "
654 "you want to save it now?"),
655 i18n (
"&Save"), i18n (
"&Do Not Save"),
656 i18n (
"&Go on editing")))
673 void KGrEditor::initEdit()
675 paintEditObj =
false;
691 void KGrEditor::insertEditObj (
int i,
int j,
char obj)
693 dbk2 << i << j << obj;
694 if ((i < 1) || (j < 1) || (i > levelData.
width) || (j > levelData.
height)) {
698 if (editableCell (i, j) ==
HERO) {
700 setEditableCell (i, j,
FREE);
707 for (
int m = 1; m <= levelData.
width; m++) {
708 for (
int n = 1; n <= levelData.
height; n++) {
709 if (editableCell (m, n) ==
HERO) {
710 setEditableCell (m, n,
FREE);
718 setEditableCell (i, j, obj);
721 char KGrEditor::editableCell (
int i,
int j)
723 return (levelData.
layout [(i - 1) + (j - 1) * levelData.
width]);
726 void KGrEditor::setEditableCell (
int i,
int j,
char type)
728 levelData.
layout [(i - 1) + (j - 1) * levelData.
width] = type;
732 void KGrEditor::showEditLevel()
736 disconnect (view, SIGNAL (mouseLetGo(
int)), 0, 0);
740 connect (view, SIGNAL (mouseLetGo(
int)), SLOT (endEdit(
int)));
743 bool KGrEditor::reNumberLevels (
int cIndex,
int first,
int last,
int inc)
760 file1 = getLevelFilePath (gameList.
at (cIndex), i);
761 file2 = getLevelFilePath (gameList.
at (cIndex), i - step);
771 bool KGrEditor::ownerOK (
Owner o)
786 bool KGrEditor::saveGameData (
Owner o)
792 i18n (
"You can only modify user games."));
796 filePath = userDataDir +
"games.dat";
801 if (! c.open (QIODevice::WriteOnly)) {
803 i18n (
"Cannot open file '%1' for output.", filePath));
814 if (gData->
owner == o) {
815 line =
QString (
"%1 %2 %3 %4\n")
822 for (i = 0; i < len; i++) {
823 c.putChar (lineC.
at (i));
830 for (i = 0; i < len; i++) {
851 if (editLevel <= 0) {
853 return (i18n (
"New Level"));
862 i18nc (
"Game name - level number.",
864 gameData->
name, levelNumber)
866 i18nc (
"Game name - level number - level name.",
868 gameData->
name, levelNumber, levelName);
874 QString filePath = userDataDir +
"levels/" + gameData->
prefix +
883 void KGrEditor::doEdit (
int button)
892 kDebug() <<
"Button" << button <<
"at" << i << j;
897 insertEditObj (i, j, editObj);
901 case Qt::RightButton:
903 insertEditObj (i, j,
FREE);
912 void KGrEditor::tick()
919 if (paintEditObj || paintAltObj) {
925 if ((i != oldI) || (j != oldJ)) {
927 insertEditObj (i, j, (paintEditObj) ? editObj :
FREE);
934 void KGrEditor::endEdit (
int button)
946 paintEditObj =
false;
947 if ((i != oldI) || (j != oldJ)) {
948 insertEditObj (i, j, editObj);
951 case Qt::RightButton:
953 if ((i != oldI) || (j != oldJ)) {
954 insertEditObj (i, j,
FREE);
962 #include "kgreditor.moc"
QByteArray hint
Level hint (optional).
void editNameAndHint()
Run a dialog in which the name and hint of a level can be edited.
int height
Height of grid, in cells.
QString & append(QChar ch)
int height
Height of grid, in cells.
The KGrGameIO class handles I/O for text-files containing KGoldrunner games and levels.
QString prefix
Game's filename prefix.
Owner owner
Owner of the game: "System" or "User".
KGrGameData structure: contains attributes of a KGoldrunner game.
static int warning(QWidget *parent, const QString &caption, const QString &text, const QString &label0, const QString &label1, const QString &label2="")
bool deleteLevelFile(int pGameIndex, int pLevel)
Delete a level from a game.
const QString getPrefix()
void setEditObj(char newEditObj)
Set the next object for the editor to paint, e.g.
const T & at(int i) const
int width
Width of grid, in cells.
void getMousePos(int &i, int &j)
Get the next grid-position at which to paint an object in the layout.
bool editGame(int pGameIndex)
Create a new game (a collection point for levels) or load the details of an existing game...
KGrEditor(KGrView *theView, const QString &theSystemDir, const QString &theUserDir, QList< KGrGameData * > &pGameList)
The constructor of KGrEditor.
QByteArray layout
Codes for the level layout (mandatory).
void setTitle(const QString &newTitle)
Set the text for the title of the current level.
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
char rules
Game's rules: KGoldrunner or Traditional.
bool readLevelData(const QString &dir, const QString &prefix, const int levelNo, KGrLevelData &d)
Find and read data for a level of a game.
QString number(int n, int base)
int count(const T &value) const
QByteArray about
Optional info about game (untranslated).
void append(const T &value)
QString fromUtf8(const char *str, int size)
bool moveLevelFile(int pGameIndex, int pLevel)
Move a level to another game or level number.
QString rightJustified(int width, QChar fill, bool truncate) const
static void information(QWidget *parent, const QString &caption, const QString &text, const QString &dontShowAgain=QString())
KGrLevelData structure: contains attributes of a KGoldrunner level.
int nLevels
Number of levels in the game.
const QString getAboutText()
bool createLevel(int pGameIndex)
Set up a blank level-layout, ready for editing.
bool saveLevelFile()
Save an edited level in a text file (*.grl) in the user's area.
const QChar at(int position) const
int width
Width of grid, in cells.
bool selectLevel(int &selectedGame, int &selectedLevel)
bool updateLevel(int pGameIndex, int pLevel)
Load and display an existing level, ready for editing.
void setLevel(unsigned int level)
Set the current level number.
bool saveOK()
Check if there are any unsaved edits and, if so, ask the user what to do.
QString name
Name of game (translated, if System game).
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
char skill
Game's skill: Tutorial, Normal or Champion.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
void mouseClick(QWidget *widget, Qt::MouseButton button, QFlags< Qt::KeyboardModifier > modifier, QPoint pos, int delay)
static bool safeRename(QWidget *theView, const QString &oldName, const QString &newName)
void paintCell(const int i, const int j, const char type)
Requests the view to display a particular type of tile at a particular cell, or make it empty and sho...
QByteArray toUtf8() const
QByteArray name
Level name (optional).