Warning, file /games/kdiamond/src/mainwindow.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 2008-2010 Stefan Majewsky <majewsky@gmx.net>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "mainwindow.h"
0008 #include "game.h"
0009 #include "infobar.h"
0010 #include "settings.h"
0011 #include "view.h"
0012 // KDEGames
0013 #include <kdegames_version.h>
0014 #include <KgDifficulty>
0015 #include <KGameRenderer>
0016 #include <KScoreDialog>
0017 #include <KStandardGameAction>
0018 
0019 #include <KActionCollection>
0020 #include <KActionMenu>
0021 #include <KLocalizedString>
0022 #include <KNotifyConfigWidget>
0023 #include <KStandardAction>
0024 #include <QAction>
0025 #include <QPointer>
0026 
0027 namespace KDiamond
0028 {
0029 class ThemeProvider : public KgThemeProvider
0030 {
0031 public:
0032     explicit ThemeProvider(QObject *parent = nullptr)
0033         : KgThemeProvider("Theme", parent)
0034     {
0035 #if KDEGAMES_VERSION >= QT_VERSION_CHECK(7, 4, 0)
0036         discoverThemes(QStringLiteral("themes"));
0037 #else
0038         discoverThemes("appdata", QStringLiteral("themes"));
0039 #endif
0040     }
0041 };
0042 
0043 class Renderer : public KGameRenderer
0044 {
0045 public:
0046     Renderer() : KGameRenderer(new ThemeProvider, 10)
0047     {
0048         setFrameSuffix(QStringLiteral("-%1"));
0049     }
0050 };
0051 }
0052 
0053 MainWindow::MainWindow(QWidget *parent)
0054     : KXmlGuiWindow(parent)
0055     , m_gameState(new KDiamond::GameState)
0056     , m_game(nullptr)
0057     , m_view(new KDiamond::View)
0058     , m_infoBar(nullptr)
0059     , m_newAct(new KActionMenu(QIcon::fromTheme(QStringLiteral("document-new")), i18nc("new game", "&New"), this))
0060     , m_newTimedAct(new QAction(i18n("Timed game"), this))
0061     , m_newUntimedAct(new QAction(i18n("Untimed game"), this))
0062     , m_renderer(new KDiamond::Renderer())
0063     , m_selector(m_renderer->themeProvider(), KgThemeSelector::EnableNewStuffDownload)
0064 {
0065     m_renderer->setDefaultPrimaryView(m_view);
0066     //init GUI - "New Action"
0067     m_newAct->setToolTip(i18n("Start a new game"));
0068     m_newAct->setWhatsThis(i18n("Start a new game."));
0069     actionCollection()->addAction(QStringLiteral("game_new"), m_newAct);
0070     actionCollection()->setDefaultShortcuts(m_newAct, KStandardShortcut::openNew());
0071     connect(m_newAct, &KActionMenu::triggered, this, &MainWindow::startGameDispatcher);
0072     m_newAct->addAction(m_newTimedAct);
0073     connect(m_newTimedAct, &QAction::triggered, this, &MainWindow::startGameDispatcher);
0074     m_newAct->addAction(m_newUntimedAct);
0075     connect(m_newUntimedAct, &QAction::triggered, this, &MainWindow::startGameDispatcher);
0076     //init GUI - the other actions
0077     KStandardGameAction::highscores(this, &MainWindow::showHighscores, actionCollection());
0078     m_pauseAct = KStandardGameAction::pause(this, &MainWindow::pausedAction, actionCollection());
0079     KStandardGameAction::quit(this, &QWidget::close, actionCollection());
0080     m_hintAct = KStandardGameAction::hint(nullptr, nullptr, actionCollection());
0081     KStandardAction::preferences(this, &MainWindow::showPreferences, actionCollection());
0082     KStandardAction::configureNotifications(this, &MainWindow::configureNotifications, actionCollection());
0083     //difficulty
0084     KgDifficultyGUI::init(this);
0085     connect(Kg::difficulty(), &KgDifficulty::currentLevelChanged, this, &MainWindow::startGameDispatcher);
0086     //late GUI initialisation
0087     setupGUI(QSize(300, 400)); //TODO: find better solution for a minimum size
0088     setCaption(i18nc("The application's name", "KDiamond"));
0089     setCentralWidget(m_view);
0090     //init statusbar
0091     m_infoBar = new KDiamond::InfoBar(statusBar());
0092     connect(m_gameState, &KDiamond::GameState::stateChanged, this, &MainWindow::stateChange);
0093     connect(m_gameState, &KDiamond::GameState::pointsChanged, m_infoBar, &KDiamond::InfoBar::updatePoints);
0094     connect(m_gameState, &KDiamond::GameState::leftTimeChanged, m_infoBar, &KDiamond::InfoBar::updateRemainingTime);
0095     //init game
0096     startGameDispatcher();
0097 }
0098 
0099 MainWindow::~MainWindow()
0100 {
0101     Settings::self()->save();
0102     delete m_renderer;
0103     delete m_game;
0104     delete m_gameState;
0105 }
0106 
0107 void MainWindow::startGameDispatcher()
0108 {
0109     if (sender() == m_newUntimedAct) {
0110         startGame(KDiamond::UntimedGame);
0111     } else if (sender() == m_newTimedAct) {
0112         startGame(KDiamond::NormalGame);
0113     } else
0114         //attention: this may also be used by KgDifficulty and the ctor
0115     {
0116         startGame(Settings::untimed() ? KDiamond::UntimedGame : KDiamond::NormalGame);
0117     }
0118 }
0119 
0120 void MainWindow::startGame(KDiamond::Mode mode)
0121 {
0122     //delete old board
0123     delete m_game;
0124     //start new game
0125     m_gameState->startNewGame();
0126     m_gameState->setMode(mode);
0127     m_game = new Game(m_gameState, m_renderer);
0128     connect(m_gameState, &KDiamond::GameState::stateChanged, m_game, &Game::stateChange);
0129     connect(m_gameState, &KDiamond::GameState::message, m_game, &Game::message);
0130     connect(m_game, &Game::numberMoves, m_infoBar, &KDiamond::InfoBar::updateMoves);
0131     connect(m_game, &Game::pendingAnimationsFinished, this, &MainWindow::gameIsOver);
0132     connect(m_hintAct, &QAction::triggered, m_game, &Game::showHint);
0133     m_view->setScene(m_game);
0134     //reset status bar
0135     m_infoBar->setUntimed(mode == KDiamond::UntimedGame);
0136     m_infoBar->updatePoints(0);
0137     m_infoBar->updateRemainingTime(KDiamond::GameDuration);
0138 }
0139 
0140 void MainWindow::stateChange(KDiamond::State state)
0141 {
0142     m_pauseAct->setEnabled(state != KDiamond::Finished);
0143     m_pauseAct->setChecked(state == KDiamond::Paused);
0144     m_hintAct->setEnabled(state == KDiamond::Playing);
0145 }
0146 
0147 void MainWindow::gameIsOver()
0148 {
0149     //create score info
0150     KScoreDialog::FieldInfo scoreInfo;
0151     scoreInfo[KScoreDialog::Score].setNum(m_gameState->points());
0152     scoreInfo[KScoreDialog::Custom1] = m_gameState->mode() == KDiamond::UntimedGame ? i18n("Untimed") : i18n("Timed");
0153     //report score
0154     QPointer<KScoreDialog> dialog = new KScoreDialog(KScoreDialog::Name | KScoreDialog::Score, this);
0155     dialog->addField(KScoreDialog::Custom1, i18n("Mode"), QStringLiteral("mode"));
0156     dialog->initFromDifficulty(Kg::difficulty());
0157     dialog->addScore(scoreInfo);
0158     dialog->exec();
0159     delete dialog;
0160 }
0161 
0162 void MainWindow::showHighscores()
0163 {
0164     //pause game if necessary
0165     m_gameState->setState(KDiamond::Paused);
0166     if (m_gameState->state() != KDiamond::Finished) {
0167         actionCollection()->action(QStringLiteral("game_pause"))->setChecked(true);
0168     }
0169     //show dialog
0170     QPointer<KScoreDialog> dialog = new KScoreDialog(KScoreDialog::Name | KScoreDialog::Score, this);
0171     dialog->addField(KScoreDialog::Custom1, i18n("Mode"), QStringLiteral("mode"));
0172     dialog->initFromDifficulty(Kg::difficulty());
0173     dialog->exec();
0174     delete dialog;
0175 }
0176 
0177 void MainWindow::showPreferences()
0178 {
0179     m_selector.showAsDialog();
0180 }
0181 
0182 
0183 void MainWindow::pausedAction(bool paused)
0184 {
0185     m_gameState->setState(paused ? KDiamond::Paused : KDiamond::Playing);
0186 }
0187 
0188 void MainWindow::configureNotifications()
0189 {
0190     KNotifyConfigWidget::configure(this);
0191 }
0192