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).