File indexing completed on 2023-12-03 07:52:33

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