00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <QDir>
00024 #include <QFile>
00025
00026
00027 #include <kstandardgameaction.h>
00028 #include <kmessagebox.h>
00029 #include <kfiledialog.h>
00030 #include <khelpmenu.h>
00031 #include <kdebug.h>
00032 #include <kstandardaction.h>
00033 #include <kaction.h>
00034 #include <kactioncollection.h>
00035 #include <kstatusbar.h>
00036 #include <kstandarddirs.h>
00037 #include <kicon.h>
00038 #include <kmenubar.h>
00039 #include <klocale.h>
00040 #include <kcarddialog.h>
00041 #include <krandom.h>
00042 #include <kglobal.h>
00043 #include <ktoolbar.h>
00044 #include <kselectaction.h>
00045
00046
00047 #include "mainwindow.h"
00048 #include "lskatglobal.h"
00049 #include "gameview.h"
00050 #include "abstractengine.h"
00051 #include "engine_two.h"
00052 #include "display_two.h"
00053 #include "config_two.h"
00054 #include "display_intro.h"
00055 #include "deck.h"
00056 #include "player.h"
00057 #include "mouseinput.h"
00058 #include "aiinput.h"
00059 #include "namedialogwidget.h"
00060
00061
00062 #include "config-src.h"
00063
00064
00065 #define ADVANCE_PERDIOD 20
00066
00067
00068 #define ACTION(x) (actionCollection()->action(x))
00069
00070 using namespace InputDevice;
00071
00072
00073
00074 Mainwindow::Mainwindow(QWidget* parent)
00075 : KXmlGuiWindow(parent)
00076 {
00077
00078 mDeck = 0;
00079 mEngine = 0;
00080 mDisplay = 0;
00081 mView = 0;
00082
00083 #ifdef SRC_DIR
00084 kDebug() << "Found SRC_DIR =" << SRC_DIR << endl;
00085 KGlobal::dirs()->addResourceDir("data",QString(SRC_DIR)+QString("/grafix/"));
00086 QString theme = KStandardDirs::locate("data", "default.rc");
00087 kDebug() << "theme =" << theme << endl;
00088 #endif
00089
00090
00091 mThemeDirName = KGlobal::dirs()->findResourceDir("data","default.rc");
00092 kDebug() << "THEME DIR IS " << mThemeDirName << endl;
00093
00094
00095 initGUI();
00096
00097
00098 mLSkatConfig = new ConfigTwo(this);
00099 connect(mLSkatConfig, SIGNAL(signalInputType(int,InputDeviceType)),
00100 this, SLOT(setInputType(int,InputDeviceType)));
00101 mLSkatConfig->reset();
00102
00103
00104 readProperties();
00105
00106
00107
00108 long seed = KRandom::random();
00109 if (global_debug > 0) kDebug() << "Random seed " << seed << endl;
00110 mDeck = new Deck(seed, this);
00111
00112
00113 mTheme = new ThemeManager(mCardDir, mDeckGrafix, "default.rc", this);
00114
00115
00116 mCanvas = new QGraphicsScene(this);
00117 mView = new GameView(QSize(880, 675), ADVANCE_PERDIOD, mCanvas, mTheme, this);
00118
00119
00120 mGameMode = Intro;
00121 mDisplay = new DisplayIntro(mDeck, mCanvas, mTheme, ADVANCE_PERDIOD, mView);
00122 setCentralWidget(mView);
00123
00124
00125 setupGUI();
00126 toolBar()->hide();
00127 statusBar()->show();
00128 setAutoSaveSettings();
00129
00130 statusBar()->showMessage(i18n("Welcome to Skat! Please start a new game."));
00131
00132
00133 if (global_skip_intro)
00134 {
00135 menuNewLSkatGame();
00136 }
00137
00138 else if (global_demo_mode)
00139 {
00140
00141 mDisplay->start();
00142 QTimer::singleShot(12500, this,SLOT(menuNewLSkatGame()));
00143 }
00144 else
00145 {
00146
00147 mDisplay->start();
00148 }
00149
00150 }
00151
00152
00153 Mainwindow::~Mainwindow()
00154 {
00155 saveProperties();
00156 if (mEngine) delete mEngine;
00157 if (mDisplay) delete mDisplay;
00158 if (mLSkatConfig) delete mLSkatConfig;
00159 if (mDeck) delete mDeck;
00160 if (mView) delete mView;
00161 if (mCanvas) delete mCanvas;
00162 if (mTheme) delete mTheme;
00163 }
00164
00165
00166
00167 bool Mainwindow::queryExit()
00168 {
00169 if (mEngine)
00170 {
00171 mEngine->stopGame();
00172 }
00173 saveProperties();
00174 return true;
00175 }
00176
00177
00178
00179 void Mainwindow::saveProperties()
00180 {
00181 KConfig *config = KGlobal::config().data();
00182
00183
00184 KConfigGroup cfg = config->group("ProgramData");
00185 cfg.writePathEntry("carddir", mCardDir);
00186 cfg.writePathEntry("deck", mDeckGrafix);
00187 cfg.writeEntry("startplayer", mStartPlayer);
00188
00189
00190 mLSkatConfig->save(config);
00191 config->sync();
00192 }
00193
00194
00195
00196 void Mainwindow::readProperties()
00197 {
00198 KConfig *config = KGlobal::config().data();
00199
00200
00201 KConfigGroup cfg = config->group("ProgramData");
00202
00203
00204 QString dcd = KCardDialog::getDefaultCardDir();
00205 dcd = KGlobal::dirs()->findResourceDir("cards", dcd)+dcd;
00206 QString dd = KCardDialog::getDefaultDeck();
00207 dd = KGlobal::dirs()->findResourceDir("cards", dd)+dd;
00208
00209
00210 mCardDir = cfg.readPathEntry("carddir", dcd);
00211 mDeckGrafix = cfg.readPathEntry("deck", dd);
00212
00213
00214 QFile file(mDeckGrafix);
00215 if (!file.exists()) mDeckGrafix = dd;
00216 QDir dir(mCardDir);
00217 if (!dir.exists()) mCardDir = dcd;
00218
00219 if (global_debug > 0)
00220 {
00221 kDebug() << "set mDeckGrafix=" << mDeckGrafix << endl;
00222 kDebug() << "set mCardDir=" << mCardDir << endl;
00223 }
00224
00225 int no = cfg.readEntry("startplayer", 0);
00226 setStartPlayer(no);
00227 mLSkatConfig->load(config);
00228 }
00229
00230
00231
00232 AbstractInput* Mainwindow::createInput(
00233 InputDeviceType inputType,
00234 AbstractDisplay* display,
00235 AbstractEngine* engine)
00236 {
00237 AbstractInput* input = 0;
00238
00239
00240 if (global_demo_mode)
00241 {
00242 inputType = TypeAiInput;
00243 }
00244
00245
00246 if (inputType == TypeMouseInput)
00247 {
00248 MouseInput* mouseInput = new MouseInput(this);
00249 connect((QObject*)mView, SIGNAL(signalLeftMousePress(QPoint)),
00250 mouseInput, SLOT(mousePress(QPoint)));
00251 connect(mouseInput, SIGNAL(signalConvertMousePress(QPoint,int&,int&)),
00252 display, SLOT(convertMousePress(QPoint,int&,int&)));
00253 connect(mouseInput, SIGNAL(signalPlayerInput(int,int,int)),
00254 engine, SLOT(playerInput(int,int,int) ));
00255 input = mouseInput;
00256 if (global_debug > 0) kDebug() << "Create MOUSE INPUT " << endl;
00257 }
00258 else if (inputType == TypeAiInput)
00259 {
00260 AiInput* aiInput = new AiInput((EngineTwo*)engine, this);
00261 connect(aiInput, SIGNAL(signalPlayerInput(int,int,int)),
00262 engine, SLOT(playerInput(int,int,int) ));
00263 input = aiInput;
00264 if (global_debug > 0) kDebug() << "Create AI INPUT " << endl;
00265 }
00266 else
00267 {
00268 kFatal() << "Unpupported input device type " << inputType << endl;
00269 }
00270
00271 return input;
00272 }
00273
00274
00275
00276 void Mainwindow::startGame()
00277 {
00278
00279 ACTION("end_game")->setEnabled(true);
00280
00281
00282 mDeck->shuffle();
00283
00284
00285 Suite trump = mDeck->randomTrump();
00286
00287
00288 QHashIterator<int,Player*> it = mLSkatConfig->playerIterator();
00289 while(it.hasNext())
00290 {
00291 it.next();
00292 Player* player = it.value();
00293 player->setDeck(mDeck);
00294
00295 player->deal(16);
00296
00297 player->setTrump(trump);
00298 }
00299
00300
00301 mDisplay->start();
00302
00303
00304 mEngine->startGame(trump, mStartPlayer);
00305
00306
00307 setStartPlayer(1-mStartPlayer);
00308
00309
00310 }
00311
00312
00313
00314 void Mainwindow::gameOver(int )
00315 {
00316 ACTION("end_game")->setEnabled(false);
00317 statusBar()->showMessage(i18n("Game Over. Please start a new game."));
00318
00319
00320 if (global_demo_mode)
00321 {
00322 QTimer::singleShot(10000, this,SLOT(menuNewLSkatGame()));
00323 }
00324 }
00325
00326
00327
00328 void Mainwindow::nextPlayer(Player* player)
00329 {
00330 int no = player->id()+1;
00331 QString name = player->name();
00332 statusBar()->showMessage(i18nc("Player name and number","Next move for %1 (player %2)", name, no));
00333 }
00334
00335
00336
00337 void Mainwindow::initGUI()
00338 {
00339 QAction *action;
00340
00341
00342 action = KStandardGameAction::gameNew(this, SLOT(menuNewLSkatGame()), this);
00343 actionCollection()->addAction("new_game", action);
00344 ACTION("new_game")->setToolTip(i18n("Starting a new game..."));
00345 ACTION("new_game")->setWhatsThis(i18n("Start a new game."));
00346 if (global_demo_mode) action->setEnabled(false);
00347
00348
00349 action = actionCollection()->addAction("clear_statistics");
00350 ACTION("clear_statistics")->setIcon(KIcon("flag"));
00351 ACTION("clear_statistics")->setText(i18n("&Clear Statistics"));
00352 connect(ACTION("clear_statistics"), SIGNAL(triggered(bool)), this, SLOT(menuClearStatistics()));
00353 ACTION("clear_statistics")->setToolTip(i18n("Delete all time statistics..."));
00354 ACTION("clear_statistics")->setWhatsThis(i18n("Clears the all time statistics which is kept in all sessions."));
00355 if (global_demo_mode) ACTION("clear_statistics")->setEnabled(false);
00356
00357
00358 action = actionCollection()->addAction("end_game");
00359 ACTION("end_game")->setIcon(KIcon("process-stop"));
00360 ACTION("end_game")->setText(i18n("End game"));
00361 connect(ACTION("end_game"), SIGNAL(triggered(bool)), this, SLOT(menuEndGame()));
00362 ACTION("end_game")->setToolTip(i18n("Ending the current game..."));
00363 ACTION("end_game")->setWhatsThis(i18n("Aborts a currently played game. No winner will be declared."));
00364 if (global_demo_mode) ACTION("end_game")->setEnabled(false);
00365 else ACTION("end_game")->setEnabled(false);
00366
00367
00368 action = KStandardGameAction::quit(this, SLOT(close()), this);
00369 actionCollection()->addAction("game_exit", action);
00370 ACTION("game_exit")->setToolTip(i18n("Exiting..."));
00371 ACTION("game_exit")->setWhatsThis(i18n("Quits the program."));
00372
00373
00374
00375 KSelectAction* startPlayerAct = new KSelectAction(i18n("Starting Player"), this);
00376 actionCollection()->addAction("startplayer", startPlayerAct);
00377 connect(startPlayerAct, SIGNAL(triggered(int)), this, SLOT(menuStartplayer()));
00378 startPlayerAct->setToolTip(i18n("Changing starting player..."));
00379 startPlayerAct->setWhatsThis(i18n("Chooses which player begins the next game."));
00380 QStringList list;
00381 list.clear();
00382 list.append(i18n("Player &1"));
00383 list.append(i18n("Player &2"));
00384 startPlayerAct->setItems(list);
00385 if (global_demo_mode) startPlayerAct->setEnabled(false);
00386
00387
00388
00389 KSelectAction* player1Act = new KSelectAction(i18n("Player &1 Played By"), this);
00390 actionCollection()->addAction("player1", player1Act);
00391 connect(player1Act, SIGNAL(triggered(int)), this, SLOT(menuPlayer1By()));
00392 player1Act->setToolTip(i18n("Changing who plays player 1..."));
00393 player1Act->setWhatsThis(i18n("Changing who plays player 1."));
00394 list.clear();
00395 list.append(i18n("&Mouse"));
00396 list.append(i18n("&Computer"));
00397 player1Act->setItems(list);
00398 if (global_demo_mode) player1Act->setEnabled(false);
00399
00400
00401 KSelectAction* player2Act = new KSelectAction(i18n("Player &2 Played By"), this);
00402 actionCollection()->addAction("player2", player2Act);
00403 connect(player2Act, SIGNAL(triggered(int)), this, SLOT(menuPlayer2By()));
00404 player2Act->setToolTip(i18n("Changing who plays player 2..."));
00405 player2Act->setWhatsThis(i18n("Changing who plays player 2."));
00406 player2Act->setItems(list);
00407 if (global_demo_mode) player2Act->setEnabled(false);
00408
00409
00410 action = actionCollection()->addAction("select_carddeck");
00411 ACTION("select_carddeck")->setText(i18n("Select &Card Deck..."));
00412 connect(ACTION("select_carddeck"), SIGNAL(triggered(bool)), this, SLOT(menuCardDeck()));
00413 ACTION("select_carddeck")->setToolTip(i18n("Configure card decks..."));
00414 ACTION("select_carddeck")->setWhatsThis(i18n("Choose how the cards should look."));
00415
00416
00417 action = actionCollection()->addAction("change_names");
00418 ACTION("change_names")->setText(i18n("&Change Player Names"));
00419 connect(ACTION("change_names"), SIGNAL(triggered(bool)), this, SLOT(menuPlayerNames()));
00420 if (global_demo_mode) ACTION("change_names")->setEnabled(false);
00421 }
00422
00423
00424
00425 void Mainwindow::menuStartplayer()
00426 {
00427 int i=((KSelectAction *)ACTION("startplayer"))->currentItem();
00428 setStartPlayer(i);
00429 }
00430
00431
00432
00433 void Mainwindow::menuPlayer1By()
00434 {
00435 int i = ((KSelectAction *)ACTION("player1"))->currentItem();
00436 mLSkatConfig->setInputType(0, (InputDeviceType)i);
00437 }
00438
00439
00440
00441 void Mainwindow::menuPlayer2By()
00442 {
00443 int i = ((KSelectAction *)ACTION("player2"))->currentItem();
00444 mLSkatConfig->setInputType(1, (InputDeviceType)i);
00445 }
00446
00447
00448
00449 void Mainwindow::menuCardDeck()
00450 {
00451 QString s1,s2;
00452 int result;
00453
00454 KCardDialog::CardFlags flags = KCardDialog::CardFlags(KCardDialog::Both|KCardDialog::SVGCards);
00455 result=KCardDialog::getCardDeck(s1,s2, this, flags);
00456 if (result==QDialog::Accepted)
00457 {
00458 if (global_debug > 0) kDebug() << "NEW CARDDECK: " << s1 << " and " << s2 << endl;
00459 bool change = false;
00460 if (!s1.isEmpty() && s1 != mDeckGrafix)
00461 {
00462 mDeckGrafix = s1;
00463 change = true;
00464 }
00465 if (!s2.isEmpty() && s2 != mCardDir)
00466 {
00467 mCardDir = s2;
00468 change = true;
00469 }
00470 if (change)
00471 {
00472 mTheme->updateCardTheme(mCardDir, mDeckGrafix);
00473 mView->update();
00474 }
00475 }
00476 }
00477
00478
00479
00480 void Mainwindow::menuClearStatistics()
00481 {
00482 QString message;
00483 message=i18n("Do you really want to clear the all time "
00484 "statistical data?");
00485
00486 if (KMessageBox::Yes==KMessageBox::questionYesNo(this,
00487 message,
00488 QString::null,
00489 KStandardGuiItem::clear()))
00490 {
00491 QHashIterator<int,Player*> it = mLSkatConfig->playerIterator();
00492 while(it.hasNext())
00493 {
00494 it.next();
00495 Player* player = it.value();
00496 player->clear();
00497 }
00498 }
00499 }
00500
00501
00502
00503 void Mainwindow::menuEndGame()
00504 {
00505 if (mEngine)
00506 {
00507 mEngine->stopGame();
00508 }
00509
00510 }
00511
00512
00513
00514 void Mainwindow::menuNewLSkatGame()
00515 {
00516 Player* p1 = mLSkatConfig->player(0);
00517 Player* p2 = mLSkatConfig->player(1);
00518
00519
00520 if (mEngine)
00521 {
00522 mEngine->stopGame();
00523 }
00524
00525
00526 if (mGameMode != LSkat)
00527 {
00528
00529 mGameMode = LSkat;
00530
00531
00532 if (mDisplay) delete mDisplay;
00533 if (mEngine) delete mEngine;
00534
00535 mDisplay = new DisplayTwo(mDeck, mCanvas, mTheme, ADVANCE_PERDIOD, mView);
00536 mEngine = new EngineTwo(this, mDeck, (DisplayTwo*)mDisplay);
00537 connect(mEngine, SIGNAL(signalGameOver(int)), this, SLOT(gameOver(int)));
00538 connect(mEngine, SIGNAL(signalNextPlayer(Player*)), this, SLOT(nextPlayer(Player*)));
00539
00540
00541 connect(p1, SIGNAL(signalUpdate(Player*)), mDisplay, SLOT(updatePlayer(Player*)));
00542 connect(p2, SIGNAL(signalUpdate(Player*)), mDisplay, SLOT(updatePlayer(Player*)));
00543
00544 mEngine->addPlayer(0, p1);
00545 mEngine->addPlayer(1, p2);
00546 }
00547
00548
00549 AbstractInput* input1 = createInput(mLSkatConfig->inputType(0), mDisplay, mEngine);
00550 p1->setInput(input1);
00551 AbstractInput* input2 = createInput(mLSkatConfig->inputType(1), mDisplay, mEngine);
00552 p2->setInput(input2);
00553
00554 statusBar()->showMessage(i18n("Dealing cards..."));
00555
00556
00557 startGame();
00558 }
00559
00560
00561
00562 void Mainwindow::menuPlayerNames()
00563 {
00564 NameDialogWidget dlg(this);
00565 for (int i=0;i<2;i++)
00566 {
00567 Player* p = mLSkatConfig->player(i);
00568 dlg.setName(i, p->name());
00569 }
00570
00571 int result = dlg.exec();
00572
00573 if (result == QDialog::Accepted)
00574 {
00575 for (int i=0;i<2;i++)
00576 {
00577 Player* p = mLSkatConfig->player(i);
00578 p->setName(dlg.name(i));
00579 }
00580 }
00581 }
00582
00583
00584
00585 void Mainwindow::setStartPlayer(int no)
00586 {
00587 mStartPlayer = no;
00588 ((KSelectAction *)ACTION("startplayer"))->setCurrentItem(mStartPlayer);
00589 }
00590
00591
00592
00593 void Mainwindow::setInputType(int no, InputDeviceType type)
00594 {
00595 Player* p = 0;
00596
00597 if (no == 0)
00598 {
00599 ((KSelectAction *)ACTION("player1"))->setCurrentItem((int)type);
00600 p = mLSkatConfig->player(0);
00601 }
00602 else if (no == 1)
00603 {
00604 ((KSelectAction *)ACTION("player2"))->setCurrentItem((int)type);
00605 p = mLSkatConfig->player(1);
00606 }
00607
00608
00609 if (mEngine && p && mDisplay && mEngine->isGameRunning())
00610 {
00611 AbstractInput* input = createInput(type, mDisplay, mEngine);
00612 p->setInput(input);
00613 }
00614
00615 }
00616
00617
00618 #include "mainwindow.moc"