• Skip to content
  • Skip to link menu
KDE 4.0 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kgoldrunner

kgoldrunner.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2002 Marco Krüger <grisuji@gmx.de>
00003     Copyright 2002 Ian Wadham <ianw2@optusnet.com.au>
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  */
00019 
00020 #include "kgoldrunner.h"
00021 
00022 #include <QApplication>
00023 #include <QDesktopWidget>
00024 #include <QSignalMapper>
00025 
00026 #include <kglobal.h>
00027 #include <kstatusbar.h>
00028 #include <kshortcutsdialog.h>
00029 
00030 #include <kconfig.h>
00031 #include <kconfiggroup.h>
00032 
00033 #include <kdebug.h>
00034 
00035 #include <ktoolbar.h>
00036 #include <kmenubar.h>
00037 
00038 #include <kaction.h>
00039 #include <kactioncollection.h>
00040 #include <ktoggleaction.h>
00041 #include <ktogglefullscreenaction.h>
00042 #include <kstandardaction.h>
00043 #include <kstandardgameaction.h>
00044 #include <kicon.h>
00045 #include <KMenu>
00046 #include <KCmdLineArgs>
00047 #include <KAboutData>
00048 
00049 #include "kgrobject.h"
00050 #include "kgrfigure.h"
00051 #include "kgrcanvas.h"
00052 #include "kgrdialog.h"
00053 #include "kgrgame.h"
00054 
00055 KGoldrunner::KGoldrunner()
00056       // : view (new KGrCanvas (this))
00057 {
00058 /******************************************************************************/
00059 /*************  FIND WHERE THE GAMES DATA AND HANDBOOK SHOULD BE  *************/
00060 /******************************************************************************/
00061 
00062     setObjectName ("KGoldrunner");
00063 
00064     // Avoid "saveOK()" check if an error-exit occurs during the file checks.
00065     startupOK = true;
00066 
00067     // Get directory paths for the system levels, user levels and manual.
00068     if (! getDirectories()) {
00069     fprintf (stderr, "getDirectories() FAILED\n");
00070     startupOK = false;
00071     return;             // If games directory not found, abort.
00072     }
00073 
00074     // This message is to help diagnose distribution or installation problems.
00075     printf
00076     ("The games data and handbook should be in the following locations:\n");
00077     printf ("System games: %s\nUser data:    %s\nHandbook:     %s\n",
00078     systemDataDir.myStr(), userDataDir.myStr(), systemHTMLDir.myStr());
00079 
00080 /******************************************************************************/
00081 /************************  SET PLAYFIELD AND GAME DATA  ***********************/
00082 /******************************************************************************/
00083 
00084     // Base the size of playing-area and widgets on the monitor resolution.
00085     int dw = QApplication::desktop()->width();
00086 
00087     // Need to consider the height, for widescreen displays (eg. 1280x768).
00088     int dh = QApplication::desktop()->height();
00089 
00090     double scale = 1.0;
00091     if ((dw > 800) && (dh > 600)) {         // More than 800x600.
00092     scale = 1.25;           // Scale 1.25:1.
00093     }
00094     if ((dw > 1024) && (dh > 768))  {           // More than 1024x768.
00095     scale = 1.75;           // Scale 1.75:1.
00096     }
00097     view = new KGrCanvas (this, scale, systemDataDir);
00098     game = new KGrGame (view, systemDataDir, userDataDir);
00099 
00100     // Initialise the collections of levels (i.e. the list of games).
00101     if (! game->initCollections()) {
00102     startupOK = false;
00103     return;             // If no game files, abort.
00104     }
00105 
00106     kDebug() << "Calling view->setBaseScale() ...";
00107     view->setBaseScale();       // Set scale for level-titles font.
00108 
00109     hero = game->getHero();     // Get a pointer to the hero.
00110 
00111 /******************************************************************************/
00112 /*************************  SET UP THE USER INTERFACE  ************************/
00113 /******************************************************************************/
00114 
00115     // Get catalog for translation
00116     KGlobal::locale()->insertCatalog("libkdegames");
00117 
00118     // Tell the KMainWindow that this is the main widget
00119     setCentralWidget (view);
00120 
00121     // Set up our actions (menu, toolbar and keystrokes) ...
00122     setupActions();
00123 
00124     // and a status bar.
00125     initStatusBar();
00126 
00127     // Do NOT have show/hide actions for the statusbar and toolbar in the GUI:
00128     // we need the statusbar for game scores and the toolbar is relevant only
00129     // when using the game editor and then it appears automatically.  Maybe 1%
00130     // of players would use the game editor for 5% of their time.
00131     setupGUI (static_cast<StandardWindowOption> (Default &
00132             (~StatusBar) & (~ToolBar)));
00133 
00134     // Find the theme-files and generate the Themes menu.
00135     setupThemes();
00136 
00137     // Connect the game actions to the menu and toolbar displays.
00138     connect(game, SIGNAL (quitGame()),          SLOT (close()));
00139     connect(game, SIGNAL (setEditMenu (bool)),  SLOT (setEditMenu (bool)));
00140     connect(game, SIGNAL (markRuleType (char)), SLOT (markRuleType (char)));
00141     connect(game, SIGNAL (hintAvailable(bool)), SLOT (adjustHintAction(bool)));
00142     connect(game, SIGNAL (defaultEditObj()),    SLOT (defaultEditObj()));
00143 
00144     // Apply the saved mainwindow settings, if any, and ask the mainwindow
00145     // to automatically save settings if changed: window size, toolbar
00146     // position, icon size, etc.
00147     setAutoSaveSettings();
00148 
00149     // Explicitly hide the edit toolbar - we need it in edit mode only and we
00150     // always start in play mode, even if the last session ended in edit mode.
00151     // Besides, we cannot render it until after the initial resize event(s).
00152     toolBar("editToolbar")->hide();
00153     // IDW toolBar("editToolbar")->setAllowedAreas(Qt::TopToolBarArea);
00154 
00155     // Set mouse control of the hero as the default.
00156     game->setMouseMode (true);
00157 
00158     // Paint the main widget (title, menu, status bar, blank playfield).
00159     show();
00160 
00161     // Queue a call to the "New Game" method, with default parameters. This
00162     // paints a config'd game and level, but only AFTER the main window shows.
00163     QMetaObject::invokeMethod(game, "newGame", Qt::QueuedConnection);
00164 
00165     // Show buttons to start the config'd game and level and other options.
00166     game->quickStartDialog();
00167 }
00168 
00169 KGoldrunner::~KGoldrunner()
00170 {
00171 }
00172 
00173 void KGoldrunner::setupActions()
00174 {
00175     /**************************************************************************/
00176     /******************************   GAME MENU  ******************************/
00177     /**************************************************************************/
00178 
00179     // New Game...
00180     // Load Saved Game...
00181     // --------------------------
00182 
00183     QAction * newAction =   KStandardGameAction::
00184                 gameNew (
00185                 game,
00186                 SLOT(startAnyLevel()), this);
00187     actionCollection()->addAction(newAction->objectName(), newAction);
00188     newAction->         setText (i18n("&New Game..."));
00189     QAction * loadGame =    KStandardGameAction::
00190                 load (
00191                 game, SLOT(loadGame()), this);
00192     actionCollection()->addAction(loadGame->objectName(), loadGame);
00193     loadGame->          setText (i18n("&Load Saved Game..."));
00194 
00195     // Save Game...
00196     // Save Edits... (extra copy)
00197     // --------------------------
00198 
00199     saveGame =          KStandardGameAction::
00200                 save (
00201                 game, SLOT(saveGame()), this);
00202     actionCollection()->addAction(saveGame->objectName(), saveGame);
00203     saveGame->          setText (i18n("&Save Game..."));
00204     saveGame->          setShortcut (Qt::Key_S); // Alternate key.
00205 
00206     // Pause
00207     // Show High Scores
00208     // Get a Hint
00209     // Kill the Hero
00210     // --------------------------
00211 
00212     // KAction * myPause: to get KAction::shortcut() not QAction::shortcut().
00213     myPause = KStandardGameAction::pause (this, SLOT(stopStart()), this);
00214     actionCollection()->addAction (myPause->objectName(), myPause);
00215     KShortcut pauseShortcut = myPause->shortcut();
00216     pauseShortcut.setAlternate (Qt::Key_Escape);    // Add "Esc" shortcut.
00217     myPause->setShortcut (pauseShortcut);
00218 
00219     highScore = KStandardGameAction::highscores
00220                 (game, SLOT(showHighScores()), this);
00221     actionCollection()->addAction(highScore->objectName(), highScore);
00222 
00223     hintAction = KStandardGameAction::hint
00224                 (game, SLOT(showHint()), this);
00225     actionCollection()->addAction(hintAction->objectName(), hintAction);
00226 
00227     killHero =  actionCollection()->addAction("kill_hero");
00228     killHero->setText (i18n("&Kill Hero"));
00229     killHero->setToolTip (i18n("Kill hero"));
00230     killHero->setWhatsThis (i18n("Kill the hero, in case he finds himself in "
00231                 "a situation from which he cannot escape"));
00232     killHero->setShortcut (Qt::Key_Q);
00233     connect( killHero, SIGNAL(triggered(bool)), game, SLOT(herosDead()));
00234 
00235     // Quit
00236     // --------------------------
00237 
00238     KStandardGameAction::quit (this, SLOT(close()), actionCollection());
00239 
00240     /**************************************************************************/
00241     /***************************   GAME EDITOR MENU  **************************/
00242     /**************************************************************************/
00243 
00244     // Create a Level
00245     // Edit a Level...
00246     // --------------------------
00247 
00248     QAction* createAct = actionCollection()->addAction("create_level");
00249     createAct->setText(i18n("&Create Level"));
00250     createAct->setIcon(KIcon("document-new"));
00251     createAct->setToolTip(i18n("Create level"));
00252     createAct->setWhatsThis(i18n("Create a completely new level"));
00253     connect( createAct, SIGNAL(triggered(bool)), game, SLOT(createLevel()));
00254 
00255     QAction* editAnyAct = actionCollection()->addAction("edit_any");
00256     editAnyAct->setText(i18n("&Edit Level..."));
00257     editAnyAct->setIcon(KIcon("document-open"));
00258     editAnyAct->setToolTip(i18n("Edit level..."));
00259     editAnyAct->setWhatsThis(i18n("Edit any level..."));
00260     connect( editAnyAct, SIGNAL(triggered(bool)), game, SLOT(updateLevel()));
00261 
00262     // Save Edits...
00263     // Move Level...
00264     // Delete Level...
00265     // --------------------------
00266 
00267     saveEdits = actionCollection()->addAction("save_edits");
00268     saveEdits->setText(i18n("&Save Edits..."));
00269     saveEdits->setIcon(KIcon("document-save"));
00270     saveEdits->setToolTip(i18n("Save edits..."));
00271     saveEdits->setWhatsThis(i18n("Save your level after editing..."));
00272     connect( saveEdits, SIGNAL(triggered(bool)), game, SLOT(saveLevelFile()));
00273     saveEdits->setEnabled (false);          // Nothing to save, yet.
00274 
00275     QAction* moveLevel = actionCollection()->addAction("move_level");
00276     moveLevel->setText(i18n("&Move Level..."));
00277     moveLevel->setToolTip(i18n("Move level..."));
00278     moveLevel->setWhatsThis
00279         (i18n("Change a level's number or move it to another game..."));
00280     connect( moveLevel, SIGNAL(triggered(bool)), game, SLOT(moveLevelFile()));
00281 
00282     QAction* deleteLevel = actionCollection()->addAction("delete_level");
00283     deleteLevel->setText(i18n("&Delete Level..."));
00284     deleteLevel->setToolTip(i18n("Delete level..."));
00285     deleteLevel->setWhatsThis(i18n("Delete a level..."));
00286     connect(deleteLevel,SIGNAL(triggered(bool)), game, SLOT(deleteLevelFile()));
00287 
00288     // Create a Game
00289     // Edit Game Info...
00290     // --------------------------
00291 
00292     QAction* createGame = actionCollection()->addAction("create_game");
00293     createGame->setText(i18n("Create &Game..."));
00294     createGame->setToolTip(i18n("Create game..."));
00295     createGame->setWhatsThis(i18n("Create a completely new game..."));
00296     connect( createGame, SIGNAL(triggered(bool)), this, SLOT(createGame()));
00297 
00298     QAction* editGame = actionCollection()->addAction("edit_game");
00299     editGame->setText(i18n("Edit Game &Info..."));
00300     editGame->setToolTip(i18n("Edit game info..."));
00301     editGame->setWhatsThis
00302         (i18n("Change the name, rules or description of a game..."));
00303     connect( editGame, SIGNAL(triggered(bool)), this, SLOT(editGameInfo()));
00304 
00305     /**************************************************************************/
00306     /*****************************   THEMES MENU  *****************************/
00307     /**************************************************************************/
00308 
00309     // The Themes menu is obtained AFTER calling setupGUI(), by locating an
00310     // open-ended list of theme-files and plugging the translated text-names of
00311     // the themes in place of ActionList <name="theme_list" /> in the ui.rc file.
00312 
00313     /**************************************************************************/
00314     /****************************   SETTINGS MENU  ****************************/
00315     /**************************************************************************/
00316 
00317     // Mouse Controls Hero
00318     // Keyboard Controls Hero
00319     // --------------------------
00320 
00321     setMouse = new KToggleAction(i18n("&Mouse Controls Hero"), this);
00322     setMouse->setToolTip(i18n("Mouse controls hero"));
00323     setMouse->setWhatsThis(i18n("Use the mouse to control the hero's moves"));
00324     actionCollection()->addAction("mouse_mode", setMouse);
00325     connect( setMouse, SIGNAL(triggered(bool)), this, SLOT(setMouseMode()));
00326 
00327     setKeyboard = new KToggleAction (i18n("&Keyboard Controls Hero"), this);
00328     setKeyboard->setToolTip(i18n("Keyboard controls hero"));
00329     setKeyboard->setWhatsThis
00330             (i18n("Use the keyboard to control the hero's moves"));
00331     actionCollection()->addAction("keyboard_mode", setKeyboard);
00332     connect(setKeyboard,SIGNAL(triggered(bool)), this, SLOT(setKeyBoardMode()));
00333 
00334     QActionGroup* controlGrp = new QActionGroup(this);
00335     controlGrp->addAction(setMouse);
00336     controlGrp->addAction(setKeyboard);
00337     controlGrp->setExclusive(true);
00338     setMouse->setChecked(true);
00339 
00340     // Normal Speed
00341     // Beginner Speed
00342     // Champion Speed
00343     // Increase Speed
00344     // Decrease Speed
00345     // --------------------------
00346 
00347     KToggleAction * nSpeed =    new KToggleAction (
00348                 i18n("Normal Speed"),
00349                 this);
00350     nSpeed->setToolTip(i18n("Normal speed"));
00351     nSpeed->setWhatsThis(i18n("Set normal game speed (12 units)"));
00352     actionCollection()->addAction("normal_speed", nSpeed);
00353     connect( nSpeed, SIGNAL(triggered(bool)), this, SLOT(normalSpeed()));
00354 
00355     KToggleAction * bSpeed =    new KToggleAction (
00356                 i18n("Beginner Speed"),
00357                 this);
00358     bSpeed->setToolTip(i18n("Beginner speed"));
00359     bSpeed->setWhatsThis(i18n("Set beginners' game speed (6 units)"));
00360     actionCollection()->addAction("beginner_speed", bSpeed);
00361     connect( bSpeed, SIGNAL(triggered(bool)), this, SLOT(beginSpeed()));
00362 
00363     KToggleAction * cSpeed =    new KToggleAction (
00364                 i18n("Champion Speed"),
00365                 this);
00366     cSpeed->setToolTip(i18n("Champion speed"));
00367     cSpeed->setWhatsThis(i18n("Set champions' game speed (18 units)"));
00368     actionCollection()->addAction("champion_speed", cSpeed);
00369     connect( cSpeed, SIGNAL(triggered(bool)), this, SLOT(champSpeed()));
00370 
00371     QAction * iSpeed =  actionCollection()->addAction("increase_speed");
00372     iSpeed->setText(i18n("Increase Speed"));
00373     iSpeed->setToolTip(i18n("Increase speed"));
00374     iSpeed->setWhatsThis(i18n("Increase the game speed by one unit"));
00375     iSpeed->setShortcut( Qt::Key_Plus );
00376     connect( iSpeed, SIGNAL(triggered(bool)), this, SLOT(incSpeed()));
00377 
00378     QAction * dSpeed =  actionCollection()->addAction("decrease_speed");
00379     dSpeed->setText(i18n("Decrease Speed"));
00380     dSpeed->setToolTip(i18n("Decrease speed"));
00381     dSpeed->setWhatsThis(i18n("Decrease the game speed by one unit"));
00382     dSpeed->setShortcut( Qt::Key_Minus );
00383     connect( dSpeed, SIGNAL(triggered(bool)), this, SLOT(decSpeed()));
00384 
00385     QActionGroup* speedGrp = new QActionGroup(this);
00386     speedGrp->addAction(nSpeed);
00387     speedGrp->addAction(bSpeed);
00388     speedGrp->addAction(cSpeed);
00389     nSpeed->setChecked(true);
00390 
00391     // Traditional Rules
00392     // KGoldrunner Rules
00393     // --------------------------
00394 
00395     tradRules =         new KToggleAction (
00396                 i18n("&Traditional Rules"),
00397                 this);
00398     tradRules->setToolTip(i18n("Traditional rules"));
00399     tradRules->setWhatsThis(i18n("Set Traditional rules for this game"));
00400     actionCollection()->addAction("trad_rules", tradRules);
00401     connect( tradRules, SIGNAL(triggered(bool)), this, SLOT(setTradRules()));
00402 
00403     kgrRules =          new KToggleAction (
00404                 i18n("K&Goldrunner Rules"),
00405                 this);
00406     kgrRules->setToolTip(i18n("KGoldrunner rules"));
00407     kgrRules->setWhatsThis(i18n("Set KGoldrunner rules for this game"));
00408     actionCollection()->addAction("kgr_rules", kgrRules);
00409     connect( kgrRules, SIGNAL(triggered(bool)), this, SLOT(setKGrRules()));
00410 
00411     QActionGroup* rulesGrp = new QActionGroup(this);
00412     rulesGrp->addAction(tradRules);
00413     rulesGrp->addAction(kgrRules);
00414     tradRules->setChecked (true);
00415 
00416     // FullScreen
00417     fullScreen = KStandardAction::fullScreen(this, SLOT(viewFullScreen(bool)), this, this);
00418     actionCollection()->addAction(fullScreen->objectName(), fullScreen);
00419 
00420     
00421     // Configure Shortcuts...
00422     // Configure Toolbars...
00423     // --------------------------
00424 
00425     KStandardAction::keyBindings (
00426                 this, SLOT(optionsConfigureKeys()),
00427                 actionCollection());
00428     // KStandardAction::configureToolbars (
00429                 // this, SLOT(optionsConfigureToolbars()),
00430                 // actionCollection());
00431 
00432     /**************************************************************************/
00433     /**************************   KEYSTROKE ACTIONS  **************************/
00434     /**************************************************************************/
00435 
00436     // Two-handed KB controls and alternate one-handed controls for the hero.
00437 
00438     QAction* moveUp = actionCollection()->addAction("move_up");
00439     moveUp->setText(i18n("Move Up"));
00440     moveUp->setShortcut( Qt::Key_Up );
00441     connect( moveUp, SIGNAL(triggered(bool)), this, SLOT(goUp()));
00442 
00443     QAction* moveRight = actionCollection()->addAction("move_right");
00444     moveRight->setText(i18n("Move Right"));
00445     moveRight->setShortcut( Qt::Key_Right );
00446     connect( moveRight, SIGNAL(triggered(bool)), this, SLOT(goR()));
00447 
00448     QAction* moveDown = actionCollection()->addAction("move_down");
00449     moveDown->setText(i18n("Move Down"));
00450     moveDown->setShortcut( Qt::Key_Down );
00451     connect( moveDown, SIGNAL(triggered(bool)), this, SLOT(goDown()));
00452 
00453     QAction* moveLeft = actionCollection()->addAction("move_left");
00454     moveLeft->setText(i18n("Move Left"));
00455     moveLeft->setShortcut( Qt::Key_Left );
00456     connect( moveLeft, SIGNAL(triggered(bool)), this, SLOT(goL()));
00457 
00458     QAction* stop = actionCollection()->addAction("stop");
00459     stop->setText(i18n("Stop"));
00460     stop->setShortcut( Qt::Key_Space );
00461     connect( stop, SIGNAL(triggered(bool)), this, SLOT(stop()));
00462 
00463     QAction* digRight = actionCollection()->addAction("dig_right");
00464     digRight->setText(i18n("Dig Right"));
00465     digRight->setShortcut( Qt::Key_C );
00466     connect( digRight, SIGNAL(triggered(bool)), this, SLOT(digR()));
00467 
00468     QAction* digLeft = actionCollection()->addAction("dig_left");
00469     digLeft->setText(i18n("Dig Left"));
00470     digLeft->setShortcut( Qt::Key_Z );
00471     connect( digLeft, SIGNAL(triggered(bool)), this, SLOT(digL()));
00472 
00473     // Plug actions into the gui, or accelerators will not work (KDE4)
00474     addAction(moveUp);
00475     addAction(moveDown);
00476     addAction(moveLeft);
00477     addAction(moveRight);
00478     addAction(digLeft);
00479     addAction(digRight);
00480     addAction(stop);
00481 
00482     setupEditToolbarActions();          // Uses pixmaps from "view".
00483 
00484     // Alternate one-handed controls.  Set up in "kgoldrunnerui.rc".
00485 
00486     // Key_I, "move_up"
00487     // Key_L, "move_right"
00488     // Key_K, "move_down"
00489     // Key_J, "move_left"
00490     // Key_Space, "stop" (as above)
00491     // Key_O, "dig_right"
00492     // Key_U, "dig_left"
00493 
00494     // Authors' debugging aids, effective when Pause is hit.  Options include
00495     // stepping through the animation, toggling a debug patch or log messages
00496     // on or off during gameplay and printing the states of runners or tiles.
00497 
00498     KConfigGroup gameGroup (KGlobal::config(), "Debugging");
00499     bool addDebuggingShortcuts = gameGroup.readEntry
00500             ("DebuggingShortcuts", false);  // Get debug option.
00501     if (! addDebuggingShortcuts)
00502      return;
00503 
00504     QAction* step = actionCollection()->addAction("do_step");
00505     step->setText(i18n("Step"));
00506     step->setShortcut( Qt::Key_Period );
00507     connect( step, SIGNAL(triggered(bool)), game, SLOT(doStep()) );
00508     addAction(step);
00509 
00510     QAction* bugFix = actionCollection()->addAction("bug_fix");
00511     bugFix->setText(i18n("Test Bug Fix"));
00512     bugFix->setShortcut( Qt::Key_B );
00513     connect( bugFix, SIGNAL(triggered(bool)), game, SLOT(bugFix()) );
00514     addAction(bugFix);
00515 
00516     QAction* showPos = actionCollection()->addAction("show_positions");
00517     showPos->setText(i18n("Show Positions"));
00518     showPos->setShortcut( Qt::Key_D );
00519     connect(showPos,SIGNAL(triggered(bool)), game, SLOT(showFigurePositions()));
00520     addAction(showPos);
00521 
00522     QAction* startLog = actionCollection()->addAction("logging");
00523     startLog->setText(i18n("Start Logging"));
00524     startLog->setShortcut( Qt::Key_G );
00525     connect( startLog, SIGNAL(triggered(bool)), game, SLOT(startLogging()) );
00526     addAction(startLog);
00527 
00528     QAction* showHero = actionCollection()->addAction("show_hero");
00529     showHero->setText(i18n("Show Hero"));
00530     showHero->setShortcut( Qt::Key_R );     // H is for Hint now.
00531     connect( showHero, SIGNAL(triggered(bool)), game, SLOT(showHeroState()) );
00532     addAction(showHero);
00533 
00534     QAction* showObj = actionCollection()->addAction("show_obj");
00535     showObj->setText(i18n("Show Object"));
00536     showObj->setShortcut( Qt::Key_Question );
00537     connect( showObj, SIGNAL(triggered(bool)), game, SLOT(showObjectState()) );
00538     addAction(showObj);
00539 
00540     QAction* showEnemy0 = actionCollection()->addAction("show_enemy_0");
00541     showEnemy0->setText(i18n("Show Enemy") + '0');
00542     showEnemy0->setShortcut( Qt::Key_0 );
00543     connect( showEnemy0, SIGNAL(triggered(bool)), this, SLOT(showEnemy0()) );
00544     addAction(showEnemy0);
00545 
00546     QAction* showEnemy1 = actionCollection()->addAction("show_enemy_1");
00547     showEnemy1->setText(i18n("Show Enemy") + '1');
00548     showEnemy1->setShortcut( Qt::Key_1 );
00549     connect( showEnemy1, SIGNAL(triggered(bool)), this, SLOT(showEnemy1()) );
00550     addAction(showEnemy1);
00551 
00552     QAction* showEnemy2 = actionCollection()->addAction("show_enemy_2");
00553     showEnemy2->setText(i18n("Show Enemy") + '2');
00554     showEnemy2->setShortcut( Qt::Key_2 );
00555     connect( showEnemy2, SIGNAL(triggered(bool)), this, SLOT(showEnemy2()) );
00556     addAction(showEnemy2);
00557 
00558     QAction* showEnemy3 = actionCollection()->addAction("show_enemy_3");
00559     showEnemy3->setText(i18n("Show Enemy") + '3');
00560     showEnemy3->setShortcut( Qt::Key_3 );
00561     connect( showEnemy3, SIGNAL(triggered(bool)), this, SLOT(showEnemy3()) );
00562     addAction(showEnemy3);
00563 
00564     QAction* showEnemy4 = actionCollection()->addAction("show_enemy_4");
00565     showEnemy4->setText(i18n("Show Enemy") + '4');
00566     showEnemy4->setShortcut( Qt::Key_4 );
00567     connect( showEnemy4, SIGNAL(triggered(bool)), this, SLOT(showEnemy4()) );
00568     addAction(showEnemy4);
00569 
00570     QAction* showEnemy5 = actionCollection()->addAction("show_enemy_5");
00571     showEnemy5->setText(i18n("Show Enemy") + '5');
00572     showEnemy5->setShortcut( Qt::Key_5 );
00573     connect( showEnemy5, SIGNAL(triggered(bool)), this, SLOT(showEnemy5()) );
00574     addAction(showEnemy5);
00575 
00576     QAction* showEnemy6 = actionCollection()->addAction("show_enemy_6");
00577     showEnemy6->setText(i18n("Show Enemy") + '6');
00578     showEnemy6->setShortcut( Qt::Key_6 );
00579     connect( showEnemy6, SIGNAL(triggered(bool)), this, SLOT(showEnemy6()) );
00580     addAction(showEnemy6);
00581 }
00582 
00583 void KGoldrunner::viewFullScreen(bool activation)
00584 {
00585     KToggleFullScreenAction::setFullScreen(this, activation);
00586 }
00587 
00588 void KGoldrunner::setupThemes ()
00589 {
00590     // Look for themes in files "---/share/apps/kgoldrunner/themes/*.desktop".
00591     KGlobal::dirs()->addResourceType ("theme", "data", QString(KCmdLineArgs::aboutData()->appName()) +
00592                                       QString("/themes/"));
00593 
00594     QStringList themeFilepaths = KGlobal::dirs()->findAllResources
00595     ("theme", "*.desktop", KStandardDirs::NoDuplicates); // Find files.
00596 
00597     KConfigGroup gameGroup (KGlobal::config(), "KDEGame"); // Get prev theme.
00598     
00599     // TODO change this to a ThemeName (or simply Theme) option. The theme
00600     // should be searched in the themeFilepaths defined above.
00601     QString currentThemeFilepath = gameGroup.readEntry ("ThemeFilepath", "");
00602     kDebug()<< "Config() Theme" << currentThemeFilepath;
00603 
00604     QSignalMapper * themeMapper = new QSignalMapper (this);
00605     connect (themeMapper, SIGNAL (mapped (const QString &)),
00606         this, SLOT (changeTheme (const QString &)));
00607 
00608     KToggleAction * newTheme;               // Action for a theme.
00609     QString actionName;                 // Name of the theme.
00610     QList<QAction *> themeList;             // Themes for menu.
00611     QActionGroup * themeGroup = new QActionGroup (this);
00612     themeGroup->setExclusive (true);            // Exclusive toggles.
00613 
00614     foreach (QString filepath, themeFilepaths) {    // Read each theme-file.
00615     KConfig theme (filepath, KConfig::SimpleConfig);    // Extract theme-name.
00616     KConfigGroup group = theme.group ("KDEGameTheme");  // Translated.
00617     actionName = group.readEntry ("Name", i18n("Missing Name"));
00618 
00619     newTheme = new KToggleAction (actionName, this);
00620     themeGroup->addAction (newTheme);       // Add to toggle-group.
00621 
00622     if ((currentThemeFilepath == filepath) ||   // If theme prev chosen
00623         ((currentThemeFilepath.isEmpty()) &&    // or it is the default
00624          (filepath.indexOf ("default") >= 0)) ||
00625         ((filepath == themeFilepaths.last()) &&
00626          (themeGroup->checkedAction() == 0))) { // or last in the list,
00627         if (view->changeTheme (filepath)) {     // tell graphics init.
00628         newTheme->setChecked (true);        // and mark it as chosen
00629         }
00630     }
00631 
00632     connect (newTheme, SIGNAL(triggered (bool)), themeMapper, SLOT(map ()));
00633     themeMapper->setMapping (newTheme, filepath);   // Add path to signal.
00634     themeList.append (newTheme);            // Theme --> menu list.
00635     }
00636 
00637     unplugActionList ("theme_list");
00638     plugActionList   ("theme_list", themeList);     // Insert list in menu.
00639 }
00640 
00641 /******************************************************************************/
00642 /**********************  SLOTS FOR STATUS BAR UPDATES  ************************/
00643 /******************************************************************************/
00644 
00645 void KGoldrunner::initStatusBar()
00646 {
00647     statusBar()->insertPermanentItem ("", ID_LIVES);
00648     statusBar()->insertPermanentItem ("", ID_SCORE);
00649     statusBar()->insertPermanentItem ("", ID_LEVEL);
00650     statusBar()->insertPermanentItem ("", ID_HINTAVL);
00651     statusBar()->insertPermanentItem ("", ID_MSG, 1);
00652 
00653     showLives (5);                  // Start with 5 lives.
00654     showScore (0);
00655     showLevel (0);
00656     adjustHintAction (false);
00657 
00658     // Set the PAUSE/RESUME key-names into the status bar message.
00659     pauseKeys = myPause->shortcut().toString();
00660     pauseKeys = pauseKeys.replace (';', "\" " + i18n("or") + " \"");
00661     gameFreeze (false);
00662 
00663     statusBar()->setItemFixed (ID_LIVES, -1);       // Fix current sizes.
00664     statusBar()->setItemFixed (ID_SCORE, -1);
00665     statusBar()->setItemFixed (ID_LEVEL, -1);
00666     statusBar()->setItemFixed (ID_HINTAVL, -1);
00667 
00668     connect(game, SIGNAL (showLives (long)),    SLOT (showLives (long)));
00669     connect(game, SIGNAL (showScore (long)),    SLOT (showScore (long)));
00670     connect(game, SIGNAL (showLevel (int)), SLOT (showLevel (int)));
00671     connect(game, SIGNAL (gameFreeze (bool)),   SLOT (gameFreeze (bool)));
00672 }
00673 
00674 void KGoldrunner::showLives (long newLives)
00675 {
00676     QString tmp;
00677     tmp.setNum (newLives);
00678     if (newLives < 100)
00679     tmp = tmp.rightJustified (3, '0');
00680     tmp.insert (0, i18n("   Lives: "));
00681     tmp.append ("   ");
00682     statusBar()->changeItem (tmp, ID_LIVES);
00683 }
00684 
00685 void KGoldrunner::showScore (long newScore)
00686 {
00687     QString tmp;
00688     tmp.setNum (newScore);
00689     if (newScore < 1000000)
00690     tmp = tmp.rightJustified (7, '0');
00691     tmp.insert (0, i18n("   Score: "));
00692     tmp.append ("   ");
00693     statusBar()->changeItem (tmp, ID_SCORE);
00694 }
00695 
00696 void KGoldrunner::showLevel (int newLevelNo)
00697 {
00698     QString tmp;
00699     tmp.setNum (newLevelNo);
00700     if (newLevelNo < 100)
00701     tmp = tmp.rightJustified (3, '0');
00702     tmp.insert (0, i18n("   Level: "));
00703     tmp.append ("   ");
00704     statusBar()->changeItem (tmp, ID_LEVEL);
00705 }
00706 
00707 void KGoldrunner::gameFreeze (bool on_off)
00708 {
00709     if (on_off)
00710     statusBar()->changeItem
00711             (i18n("Press \"%1\" to RESUME", pauseKeys), ID_MSG);
00712     else
00713     statusBar()->changeItem
00714             (i18n("Press \"%1\" to PAUSE", pauseKeys), ID_MSG);
00715 }
00716 
00717 void KGoldrunner::adjustHintAction (bool hintAvailable)
00718 {
00719     hintAction->setEnabled (hintAvailable);
00720 
00721     if (hintAvailable) {
00722     statusBar()->changeItem (i18n("   Has hint   "), ID_HINTAVL);
00723     }
00724     else {
00725     statusBar()->changeItem (i18n("   No hint   "), ID_HINTAVL);
00726     }
00727 }
00728 
00729 void KGoldrunner::markRuleType (char ruleType)
00730 {
00731     if (ruleType == 'T')
00732     tradRules->trigger();
00733     else
00734     kgrRules->trigger();
00735 }
00736 
00737 void KGoldrunner::setEditMenu (bool on_off)
00738 {
00739     saveEdits->setEnabled  (on_off);
00740 
00741     saveGame->setEnabled   (! on_off);
00742     hintAction->setEnabled (! on_off);
00743     killHero->setEnabled   (! on_off);
00744     highScore->setEnabled  (! on_off);
00745 
00746     if (on_off){
00747     // Set the editToolbar icons to the current tile-size.
00748     toolBar("editToolbar")->setIconSize (view->getPixmap(BRICK).size());
00749 
00750     // Set the editToolbar icons up with pixmaps of the current theme.
00751     setEditIcon ("brickbg",   BRICK);
00752     setEditIcon ("fbrickbg",  FBRICK);
00753     setEditIcon ("freebg",    FREE);
00754     setEditIcon ("nuggetbg",  NUGGET);
00755     setEditIcon ("polebg",    POLE);
00756     setEditIcon ("betonbg",   BETON);
00757     setEditIcon ("ladderbg",  LADDER);
00758     setEditIcon ("hladderbg", HLADDER);
00759     setEditIcon ("edherobg",  HERO);
00760     setEditIcon ("edenemybg", ENEMY);
00761 
00762     toolBar("editToolbar")->show();
00763     }
00764     else {
00765     toolBar("editToolbar")->hide();
00766     }
00767 }
00768 
00769 void KGoldrunner::setEditIcon (const QString & actionName, const char iconType)
00770 {
00771     ((KToggleAction *) (actionCollection()->action(actionName)))->
00772         setIcon(KIcon(view->getPixmap(iconType)));
00773 }
00774 
00775 /******************************************************************************/
00776 /*******************   SLOTS FOR MENU AND KEYBOARD ACTIONS  *******************/
00777 /******************************************************************************/
00778 
00779 // Slot to halt (pause) or restart the game play.
00780 
00781 void KGoldrunner::stopStart()
00782 {
00783     if (! (KGrObject::frozen)) {
00784     game->freeze();
00785     }
00786     else {
00787     game->unfreeze();
00788     }
00789 }
00790 
00791 void KGoldrunner::changeTheme (const QString & themeFilepath)
00792 {
00793     if (view->changeTheme (themeFilepath)) {
00794     if (game->inEditMode()) {
00795         setEditMenu (true);
00796     }
00797     }
00798     else {
00799     KGrMessage::information (this, i18n("Theme Not Loaded"),
00800         i18n("Cannot load the theme you selected.  It is not "
00801              "in the required graphics format (SVG)."));
00802     }
00803 }
00804 
00805 // Local slots to create or edit game information.
00806 
00807 void KGoldrunner::createGame()      {game->editCollection (SL_CR_GAME);}
00808 void KGoldrunner::editGameInfo()    {game->editCollection (SL_UPD_GAME);}
00809 
00810 // Local slots to set mouse or keyboard control of the hero.
00811 
00812 void KGoldrunner::setMouseMode()    {game->setMouseMode (true);}
00813 void KGoldrunner::setKeyBoardMode() {game->setMouseMode (false);}
00814 
00815 // Local slots to set game speed.
00816 
00817 void KGoldrunner::normalSpeed()     {hero->setSpeed (NSPEED);}
00818 void KGoldrunner::beginSpeed()      {hero->setSpeed (BEGINSPEED);}
00819 void KGoldrunner::champSpeed()      {hero->setSpeed (CHAMPSPEED);}
00820 void KGoldrunner::incSpeed()        {hero->setSpeed (+1);}
00821 void KGoldrunner::decSpeed()        {hero->setSpeed (-1);}
00822 
00823 // Slots to set Traditional or KGoldrunner rules.
00824 
00825 void KGoldrunner::setTradRules()
00826 {
00827     KGrFigure::variableTiming = true;
00828     KGrFigure::alwaysCollectNugget = true;
00829     KGrFigure::runThruHole = true;
00830     KGrFigure::reappearAtTop = true;
00831     KGrFigure::searchStrategy = LOW;
00832 }
00833 
00834 void KGoldrunner::setKGrRules()
00835 {
00836     KGrFigure::variableTiming = false;
00837     KGrFigure::alwaysCollectNugget = false;
00838     KGrFigure::runThruHole = false;
00839     KGrFigure::reappearAtTop = false;
00840     KGrFigure::searchStrategy = MEDIUM;
00841 }
00842 
00843 // Local slots for hero control keys.
00844 
00845 void KGoldrunner::goUp()        {setKey (KB_UP);}
00846 void KGoldrunner::goR()         {setKey (KB_RIGHT);}
00847 void KGoldrunner::goDown()      {setKey (KB_DOWN);}
00848 void KGoldrunner::goL()         {setKey (KB_LEFT);}
00849 void KGoldrunner::stop()        {setKey (KB_STOP);}
00850 void KGoldrunner::digR()        {setKey (KB_DIGRIGHT);}
00851 void KGoldrunner::digL()        {setKey (KB_DIGLEFT);}
00852 
00853 // Local slots for authors' debugging aids.
00854 
00855 void KGoldrunner::showEnemy0()      {game->showEnemyState (0);}
00856 void KGoldrunner::showEnemy1()      {game->showEnemyState (1);}
00857 void KGoldrunner::showEnemy2()      {game->showEnemyState (2);}
00858 void KGoldrunner::showEnemy3()      {game->showEnemyState (3);}
00859 void KGoldrunner::showEnemy4()      {game->showEnemyState (4);}
00860 void KGoldrunner::showEnemy5()      {game->showEnemyState (5);}
00861 void KGoldrunner::showEnemy6()      {game->showEnemyState (6);}
00862 
00863 void KGoldrunner::saveProperties(KConfigGroup & /* config - unused */)
00864 {
00865     // The 'config' object points to the session managed
00866     // config file.  Anything you write here will be available
00867     // later when this app is restored.
00868 
00869     kDebug() << "I am in KGoldrunner::saveProperties.";
00870 }
00871 
00872 void KGoldrunner::readProperties(const KConfigGroup & /* config - unused */)
00873 {
00874     // The 'config' object points to the session managed
00875     // config file.  This function is automatically called whenever
00876     // the app is being restored.  Read in here whatever you wrote
00877     // in 'saveProperties'
00878 
00879     kDebug() << "I am in KGoldrunner::readProperties.";
00880 }
00881 
00882 // void KGoldrunner::optionsShowToolbar()
00883 // {
00884     // this is all very cut and paste code for showing/hiding the
00885     // toolbar
00886     // if (m_toolbarAction->isChecked())
00887         // toolBar()->show();
00888     // else
00889         // toolBar()->hide();
00890 // }
00891 
00892 // void KGoldrunner::optionsShowStatusbar()
00893 // {
00894     // this is all very cut and paste code for showing/hiding the
00895     // statusbar
00896     // if (m_statusbarAction->isChecked())
00897         // statusBar()->show();
00898     // else
00899         // statusBar()->hide();
00900 // }
00901 
00902 void KGoldrunner::optionsConfigureKeys()
00903 {
00904     KShortcutsDialog::configure(actionCollection());
00905 
00906     // Update the PAUSE/RESUME message in the status bar.
00907     pauseKeys = myPause->shortcut().toString();
00908     pauseKeys = pauseKeys.replace (';', "\" " + i18n("or") + " \"");
00909     gameFreeze (KGrObject::frozen); // Refresh the status bar text.
00910 }
00911 
00912 // void KGoldrunner::optionsConfigureToolbars()
00913 // {
00914     // KConfigGroup cg (KGlobal::config(), autoSaveGroup());
00915     // saveMainWindowSettings (cg);
00916 // }
00917 
00918 // void KGoldrunner::newToolbarConfig()
00919 // {
00920     // this slot is called when user clicks "Ok" or "Apply" in the toolbar editor.
00921     // recreate our GUI, and re-apply the settings (e.g. "text under icons", etc.)
00922     // createGUI();
00923 
00924     // applyMainWindowSettings( KGlobal::config()->group( autoSaveGroup()) );
00925 // }
00926 
00927 // void KGoldrunner::optionsPreferences()
00928 // {
00929     // popup some sort of preference dialog, here
00930     // KGoldrunnerPreferences dlg;
00931     // if (dlg.exec())
00932     // {
00933         // redo your settings
00934     // }
00935 // }
00936 
00937 void KGoldrunner::changeStatusbar(const QString& text)
00938 {
00939     // display the text on the statusbar
00940     statusBar()->showMessage(text);
00941 }
00942 
00943 void KGoldrunner::changeCaption(const QString& text)
00944 {
00945     // display the text on the caption
00946     setCaption(text);
00947 }
00948 
00949 bool KGoldrunner::getDirectories()
00950 {
00951     bool result = true;
00952 
00953     // WHERE THINGS ARE: In the KDE 3 environment (Release 3.1.1), application
00954     // documentation and data files are in a directory structure given by
00955     // $KDEDIRS (e.g. "/usr/local/kde" or "/opt/kde3/").  Application user data
00956     // files are in a directory structure given by $KDEHOME ("$HOME/.kde").
00957     // Within those two structures, the three sub-directories will typically be
00958     // "share/doc/HTML/en/kgoldrunner/", "share/apps/kgoldrunner/system/" and
00959     // "share/apps/kgoldrunner/user/".  Note that it is necessary to have
00960     // an extra path level ("system" or "user") after "kgoldrunner", otherwise
00961     // all the KGoldrunner files have similar path names (after "apps") and
00962     // KDE always locates directories in $KDEHOME and never the released games.
00963 
00964     // The directory strings are set by KDE at run time and might change in
00965     // later releases, so use them with caution and only if something gets lost.
00966 
00967     KStandardDirs * dirs = new KStandardDirs();
00968 
00969     QString myDir = "kgoldrunner";
00970 
00971     // Find the KGoldrunner Users' Guide, English version (en).
00972     systemHTMLDir = dirs->findResourceDir ("html", "en/" + myDir + '/');
00973     if (systemHTMLDir.length() <= 0) {
00974     KGrMessage::information (this, i18n("Get Folders"),
00975         i18n("Cannot find documentation sub-folder 'en/%1/' "
00976         "in area '%2' of the KDE folder ($KDEDIRS).",
00977         myDir, dirs->resourceDirs("html").join( ":" )));
00978     // result = false;      // Don't abort if the doc is missing.
00979     }
00980     else
00981     systemHTMLDir.append ("en/" + myDir + '/');
00982 
00983     // Find the system collections in a directory of the required KDE type.
00984     systemDataDir = dirs->findResourceDir ("data", myDir + "/system/");
00985     if (systemDataDir.length() <= 0) {
00986     KGrMessage::information (this, i18n("Get Folders"),
00987     i18n("Cannot find system games sub-folder '%1/system/' "
00988     "in area '%2' of the KDE folder ($KDEDIRS).",
00989      myDir, dirs->resourceDirs ("data").join( ":" )));
00990     result = false;         // ABORT if the games data is missing.
00991     }
00992     else
00993     systemDataDir.append (myDir + "/system/");
00994 
00995     // Locate and optionally create directories for user collections and levels.
00996     bool create = true;
00997     userDataDir   = dirs->saveLocation ("data", myDir + "/user/", create);
00998     if (userDataDir.length() <= 0) {
00999     KGrMessage::information (this, i18n("Get Folders"),
01000     i18n("Cannot find or create user games sub-folder '%1/user/' "
01001     "in area '%2' of the KDE user area ($KDEHOME).",
01002      myDir, dirs->resourceDirs ("data").join( ":")));
01003     // result = false;      // Don't abort if user area is missing.
01004     }
01005     else {
01006     create = dirs->makeDir (userDataDir + "levels/");
01007     if (! create) {
01008         KGrMessage::information (this, i18n("Get Folders"),
01009         i18n("Cannot find or create 'levels/' folder in "
01010         "sub-folder '%1/user/' in the KDE user area ($KDEHOME).", myDir));
01011         // result = false;      // Don't abort if user area is missing.
01012     }
01013     }
01014 
01015     return (result);
01016 }
01017 
01018 // This method is invoked when top-level window is closed, whether by selecting
01019 // "Quit" from the menu or by clicking the "X" at the top right of the window.
01020 
01021 bool KGoldrunner::queryClose ()
01022 {
01023     // Last chance to save: user has clicked "X" widget or menu-Quit.
01024     bool cannotContinue = true;
01025     game->saveOK (cannotContinue);
01026     return (true);
01027 }
01028 
01029 void KGoldrunner::setKey (KBAction movement)
01030 {
01031     if (game->inEditMode()) return;
01032 
01033     // Using keyboard control can automatically disable mouse control.
01034     if (game->inMouseMode()) {
01035         // Halt the game while a message is displayed.
01036         game->setMessageFreeze (true);
01037 
01038         switch (KGrMessage::warning (this, i18n("Switch to Keyboard Mode"),
01039         i18n("You have pressed a key that can be used to move the "
01040         "Hero. Do you want to switch automatically to keyboard "
01041         "control? Mouse control is easier to use in the long term "
01042         "- like riding a bike rather than walking!"),
01043         i18n("Switch to &Keyboard Mode"), i18n("Stay in &Mouse Mode")))
01044         {
01045         case 0: game->setMouseMode (false); // Set internal mouse mode OFF.
01046         setMouse->setChecked (false);   // Adjust the Settings menu.
01047         setKeyboard->setChecked (true);
01048                 break;
01049         case 1: break;
01050         }
01051 
01052         // Unfreeze the game, but only if it was previously unfrozen.
01053         game->setMessageFreeze (false);
01054 
01055         if (game->inMouseMode())
01056             return;                         // Stay in Mouse Mode.
01057     }
01058 
01059     if ( game->getLevel() != 0 )
01060     {
01061       if (! hero->started )         // Start when first movement
01062           game->startPlaying();         // key is pressed ...
01063       game->heroAction (movement);
01064     }
01065 }
01066 
01067 /******************************************************************************/
01068 /**********************  MAKE A TOOLBAR FOR THE EDITOR   **********************/
01069 /******************************************************************************/
01070 
01071 void KGoldrunner::setupEditToolbarActions()
01072 {
01073     // Choose a colour that enhances visibility of the KGoldrunner pixmaps.
01074     // editToolbar->setPalette (QPalette (QColor (150, 150, 230)));
01075 
01076     QAction* ktipAct = actionCollection()->addAction ("edit_hint");
01077     ktipAct->setIcon (KIcon("games-hint"));
01078     ktipAct->setText (i18n("Edit Name/Hint"));
01079     ktipAct->setToolTip (i18n("Edit level name or hint"));
01080     ktipAct->setWhatsThis (i18n("Edit text for the name or hint of a level"));
01081     connect (ktipAct, SIGNAL(triggered(bool)), game, SLOT(editNameAndHint()));
01082 
01083     KToggleAction* freebgAct = new KToggleAction (i18n("Erase"), this);
01084     freebgAct->setToolTip (i18n("Erase"));
01085     freebgAct->setWhatsThis (i18n("Erase objects by painting empty squares"));
01086     actionCollection()->addAction ("freebg", freebgAct);
01087     connect (freebgAct, SIGNAL(triggered(bool)), this, SLOT(freeSlot()));
01088 
01089     KToggleAction* edherobgAct = new KToggleAction (i18n("Hero"), this);
01090     edherobgAct->setToolTip (i18n("Move hero"));
01091     edherobgAct->setWhatsThis (i18n("Change the hero's starting position"));
01092     actionCollection()->addAction( "edherobg", edherobgAct );
01093     connect (edherobgAct, SIGNAL(triggered(bool)), this, SLOT(edheroSlot()));
01094 
01095     KToggleAction* edenemybgAct = new KToggleAction (i18n("Enemy"), this );
01096     edenemybgAct->setToolTip (i18n("Paint enemies"));
01097     edenemybgAct->setWhatsThis
01098         (i18n("Paint enemies at their starting positions"));
01099     actionCollection()->addAction( "edenemybg", edenemybgAct );
01100     connect (edenemybgAct, SIGNAL(triggered(bool)), this, SLOT(edenemySlot()));
01101 
01102     KToggleAction* brickbgAct = new KToggleAction (i18n("Brick"), this);
01103     brickbgAct->setToolTip (i18n("Paint bricks (can dig)"));
01104     brickbgAct->setWhatsThis (i18n("Paint bricks (diggable objects)"));
01105     actionCollection()->addAction ("brickbg", brickbgAct);
01106     connect (brickbgAct, SIGNAL(triggered(bool)), this, SLOT(brickSlot()));
01107 
01108     KToggleAction* betonbgAct = new KToggleAction (i18n("Concrete"), this);
01109     betonbgAct->setToolTip (i18n("Paint concrete (cannot dig)"));
01110     betonbgAct->setWhatsThis (i18n("Paint concrete objects (not diggable)"));
01111     actionCollection()->addAction ("betonbg", betonbgAct);
01112     connect (betonbgAct, SIGNAL(triggered(bool)), this, SLOT(betonSlot()));
01113 
01114     KToggleAction* fbrickbgAct = new KToggleAction (i18n("Trap"), this);
01115     fbrickbgAct->setToolTip
01116         (i18n("Paint traps or false bricks (can fall through)"));
01117     fbrickbgAct->setWhatsThis
01118         (i18n("Paint traps or false bricks (can fall through)"));
01119     actionCollection()->addAction ("fbrickbg", fbrickbgAct);
01120     connect (fbrickbgAct, SIGNAL(triggered(bool)), this, SLOT(fbrickSlot()));
01121 
01122     KToggleAction* ladderbgAct = new KToggleAction (i18n("Ladder"), this);
01123     ladderbgAct->setToolTip (i18n("Paint ladders"));
01124     ladderbgAct->setWhatsThis (i18n("Paint ladders (ways to go up or down)"));
01125     actionCollection()->addAction ("ladderbg", ladderbgAct);
01126     connect (ladderbgAct, SIGNAL(triggered(bool)), this, SLOT(ladderSlot()));
01127 
01128     KToggleAction* hladderbgAct = new KToggleAction(i18n("Hidden Ladder"),this);
01129     hladderbgAct->setToolTip (i18n("Paint hidden ladders"));
01130     hladderbgAct->setWhatsThis
01131     (i18n("Paint hidden ladders, which appear when all the gold is gone"));
01132     actionCollection()->addAction ("hladderbg", hladderbgAct);
01133     connect (hladderbgAct, SIGNAL(triggered(bool)), this, SLOT(hladderSlot()));
01134 
01135     KToggleAction* polebgAct = new KToggleAction (i18n("Bar"), this);
01136     polebgAct->setToolTip (i18n("Paint bars or poles"));
01137     polebgAct->setWhatsThis (i18n("Paint bars or poles (can fall from these)"));
01138     actionCollection()->addAction ("polebg", polebgAct);
01139     connect (polebgAct, SIGNAL(triggered(bool)), this, SLOT(poleSlot()));
01140 
01141     KToggleAction* nuggetbgAct = new KToggleAction (i18n("Gold"), this);
01142     nuggetbgAct->setToolTip (i18n("Paint gold (or other treasure)"));
01143     nuggetbgAct->setWhatsThis (i18n("Paint gold pieces (or other treasure)"));
01144     actionCollection()->addAction ("nuggetbg", nuggetbgAct);
01145     connect (nuggetbgAct, SIGNAL(triggered(bool)), this, SLOT(nuggetSlot()));
01146 
01147     QActionGroup* editButtons = new QActionGroup(this);
01148     editButtons->setExclusive (true);
01149     editButtons->addAction (freebgAct);
01150     editButtons->addAction (edherobgAct);
01151     editButtons->addAction (edenemybgAct);
01152     editButtons->