File indexing completed on 2024-05-05 04:02:11

0001 /*
0002     SPDX-FileCopyrightText: 2008 Mathias Kraus <k.hias@gmx.de>
0003     SPDX-FileCopyrightText: 2007-2008 Thomas Gallinari <tg8187@yahoo.fr>
0004     SPDX-FileCopyrightText: 2007-2008 Pierre-Benoit Bessse <besse@gmail.com>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #include "mainwindow.h"
0010 #include "game.h"
0011 #include "gameview.h"
0012 #include "gamescene.h"
0013 #include "settings.h"
0014 #include "config/arenaselector.h"
0015 #include "config/playersettings.h"
0016 #include "config/playerselector.h"
0017 #include "ui_generalsettings.h"
0018 // KDEGames
0019 #include <KGameStandardAction>
0020 #include <KGameThemeSelector>
0021 // KF
0022 #include <KStandardGuiItem>
0023 #include <KActionCollection>
0024 #include <KMessageBox>
0025 #include <KConfigDialog>
0026 #include <KLocalizedString>
0027 #include <KToggleAction>
0028 // Qt
0029 #include <QGraphicsView>
0030 #include <QTimer>
0031 #include <QPushButton>
0032 
0033 class GeneralSettings : public QWidget
0034 {
0035 public:
0036     explicit GeneralSettings(QWidget *parent) : QWidget(parent)
0037     {
0038         ui.setupUi(this);
0039         ui.groupBox->setVisible(false);
0040         ui.kcfg_Dummy->setVisible(false); // this is only to notify changes in playerselector
0041     }
0042 private:
0043     Ui::GeneralSettings ui;
0044 };
0045 
0046 MainWindow::MainWindow()
0047 {
0048     m_settingsDialog = nullptr;
0049     // Initialize the game
0050     m_game = nullptr;
0051     m_view = nullptr;
0052     m_scene = nullptr;
0053     m_playerSettings = new PlayerSettings();
0054     m_themeProvider = new KGameThemeProvider(QByteArray("Theme"), this);
0055     m_themeProvider->discoverThemes(QStringLiteral("themes"), QStringLiteral("granatier"));
0056     // Set the window menus
0057     KGameStandardAction::gameNew(this, &MainWindow::newGame, actionCollection());
0058     //KGameStandardAction::highscores(this, &MainWindow::showHighscores, actionCollection());
0059     KStandardAction::preferences(this, &MainWindow::showSettings, actionCollection());
0060     KGameStandardAction::quit(this, &MainWindow::close, actionCollection());
0061     auto* soundAction = new KToggleAction(i18n("&Play sounds"), this);
0062     soundAction->setChecked(Settings::sounds());
0063     actionCollection()->addAction( QStringLiteral( "sounds" ), soundAction);
0064     connect(soundAction, &KToggleAction::triggered, this, &MainWindow::setSoundsEnabled);
0065     // init game
0066     initGame();
0067     // Setup the window
0068     setupGUI(Keys | Save | Create);
0069 }
0070 
0071 MainWindow::~MainWindow()
0072 {
0073     delete m_view;
0074     delete m_scene;
0075     delete m_game;
0076     delete m_playerSettings;
0077     delete m_settingsDialog;
0078 }
0079 
0080 void MainWindow::initGame()
0081 {
0082     //the focus has to be set at the beginning and also at the end to cover all possible cases
0083     //TODO: check why setting the focus only at the end doesn't work
0084     this->setFocusProxy(m_view);
0085     this->setFocus();
0086 
0087     // If a GameView instance already exists
0088     if (m_view)
0089     {
0090         // Delete the GameView instance
0091         delete m_view;
0092     }
0093 
0094     // If a GameScene instance already exists
0095     if (m_scene)
0096     {
0097         // Delete the GameScene instance
0098         delete m_scene;
0099     }
0100 
0101     // If a Game instance already exists
0102     if (m_game)
0103     {
0104         // Delete the Game instance
0105         delete m_game;
0106     }
0107     // Create a new Game instance
0108     m_game = new Game(m_playerSettings);
0109     connect(m_game, &Game::gameOver, this, &MainWindow::newGame);
0110 
0111     m_scene = new GameScene(m_game, m_themeProvider);
0112 
0113     // Create a new GameView instance
0114     m_view = new GameView(m_scene, m_game);
0115     m_view->setBackgroundBrush(Qt::black);
0116     setCentralWidget(m_view);
0117     m_game->setGameScene(dynamic_cast <GameScene*> (m_view->scene()));
0118 
0119     this->setFocusProxy(m_view);
0120     this->setFocus();
0121 }
0122 
0123 void MainWindow::newGame()
0124 {
0125     bool gameRunning;       // True if the game is running (game timer is active), false otherwise
0126 
0127     gameRunning = m_game->getTimer()->isActive();
0128     // If the game is running
0129     if (gameRunning)
0130     {
0131         // Pause the game
0132         m_game->pause();
0133     }
0134     // If the game was not over
0135     if (!m_game->getGameOver())
0136     {
0137         // Confirm before starting a new game
0138         if (KMessageBox::warningTwoActions(this,
0139                                       i18n("Are you sure you want to quit the current game?"),
0140                                       i18nc("@title:window", "New Game"),
0141                                       KGuiItem(i18nc("@action:button", "Quit Game"), QStringLiteral("window-close")),
0142                                       KStandardGuiItem::cancel())
0143             == KMessageBox::PrimaryAction)
0144         {
0145             // Start a new game
0146             initGame();
0147         }
0148         else
0149         {
0150             // If the game was running
0151             if (gameRunning)
0152             {
0153                 // Resume the game
0154                 m_game->start();
0155             }
0156         }
0157     }
0158     else
0159     {
0160         // Start a new game
0161         initGame();
0162     }
0163 }
0164 
0165 void MainWindow::setSoundsEnabled(bool p_enabled) {
0166     m_game->setSoundsEnabled(p_enabled);
0167 }
0168 
0169 void MainWindow::showSettings()
0170 {
0171     if (m_settingsDialog)//(KConfigDialog::showDialog("settings"))
0172     {
0173         delete m_settingsDialog;
0174     }
0175     auto* settingsDialog = new KConfigDialog(this, QStringLiteral("settings"), Settings::self());
0176     settingsDialog->setMinimumSize(900, 600);
0177     // General Settings
0178     settingsDialog->addPage(new GeneralSettings(settingsDialog), i18nc("General settings", "General"), QStringLiteral("games-config-options"));
0179     // Theme
0180     m_themeProvider->rediscoverThemes();
0181     m_currentThemeIdentifier = QString::fromLatin1(m_themeProvider->currentTheme()->identifier());
0182     settingsDialog->addPage(new KGameThemeSelector(m_themeProvider, KGameThemeSelector::DefaultBehavior, settingsDialog), i18n("Theme"), QStringLiteral("games-config-theme"));
0183     // Arena
0184     settingsDialog->addPage(new ArenaSelector(settingsDialog, Settings::self(), &m_tempRandomArenaModeArenaList, ArenaSelector::DefaultBehavior), i18n("Arena"), QStringLiteral("games-config-board"));
0185     // Player
0186     settingsDialog->addPage(new PlayerSelector(m_playerSettings, PlayerSelector::DefaultBehavior, settingsDialog), i18n("Player"), QStringLiteral("games-config-custom"));
0187 
0188     m_settingsDialog = settingsDialog;
0189 
0190     connect(settingsDialog, &KConfigDialog::settingsChanged, this, &MainWindow::applyNewSettings);
0191     connect(settingsDialog->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &MainWindow::settingsDialogCanceled);
0192     settingsDialog->show();
0193 }
0194 
0195 void MainWindow::applyNewSettings()
0196 {
0197     Settings::self()->setDummy(0);
0198     m_playerSettings->savePlayerSettings();
0199     if(!m_tempRandomArenaModeArenaList.isEmpty())
0200     {
0201         Settings::self()->setRandomArenaModeArenaList(m_tempRandomArenaModeArenaList);
0202     }
0203     initGame();
0204 }
0205 
0206 void MainWindow::settingsDialogCanceled()
0207 {
0208     m_playerSettings->discardUnsavedSettings();
0209     m_tempRandomArenaModeArenaList.clear();
0210     if(m_currentThemeIdentifier != QString::fromLatin1(m_themeProvider->currentTheme()->identifier()))
0211     {
0212         const QList<const KGameTheme*> themeList = m_themeProvider->themes();
0213         for(const auto& theme: themeList)
0214         {
0215             if(QString::fromLatin1(theme->identifier()) == m_currentThemeIdentifier)
0216             {
0217                 m_themeProvider->setCurrentTheme(theme);
0218                 break;
0219             }
0220         }
0221     }
0222 }
0223 
0224 void MainWindow::close()
0225 {
0226     bool gameRunning;       // True if the game is running (game timer is active), false otherwise
0227 
0228     gameRunning = m_game->getTimer()->isActive();
0229     // If the game is running
0230     if (gameRunning)
0231     {
0232         // Pause the game
0233         m_game->pause();
0234     }
0235     // Confirm before closing
0236     if(KMessageBox::warningTwoActions(this,
0237                                  i18n("Are you sure you want to quit Granatier?"),
0238                                  i18nc("To quit Granatier", "Quit"),
0239                                  KStandardGuiItem::quit(), KStandardGuiItem::cancel())
0240        == KMessageBox::PrimaryAction)
0241     {
0242         KXmlGuiWindow::close();
0243     }
0244     else
0245     {
0246         // If the game was running
0247         if (gameRunning)
0248         {
0249             // Resume the game
0250             m_game->start();
0251         }
0252     }
0253 }
0254 
0255 #include "moc_mainwindow.cpp"