File indexing completed on 2025-02-02 03:58:36
0001 /*************************************************************************** 0002 * Copyright 2007 Johannes Bergmeier <johannes.bergmeier@gmx.net> * 0003 * Copyright 2015 Ian Wadham <iandw.au@gmail.com> * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 0019 ***************************************************************************/ 0020 #include "welcomescreen.h" 0021 0022 0023 #include <KConfigGroup> 0024 #include <KMessageBox> 0025 #include <KSharedConfig> 0026 0027 #include "ksudokugame.h" 0028 #include "globals.h" 0029 #include "puzzle.h" 0030 0031 Q_DECLARE_METATYPE(ksudoku::GameVariant*) 0032 0033 namespace ksudoku { 0034 0035 WelcomeScreen::WelcomeScreen(QWidget* parent, GameVariantCollection* collection) 0036 : QFrame(parent), m_collection(collection) 0037 { 0038 setupUi(this); // Get gameListWidget by loading from welcomescreen.ui. 0039 0040 // Set the screen to display a multi-column list of puzzle-types, with 0041 // vertical scrolling. GameVariantDelegate::sizeHint() calculates the 0042 // number of columns and their width when it works out the size of the 0043 // item's display-area. 0044 0045 QItemDelegate* delegate = 0046 new GameVariantDelegate(this, gameListWidget->viewport()); 0047 gameListWidget->setWrapping(true); 0048 gameListWidget->setResizeMode(QListView::Adjust); 0049 gameListWidget->setUniformItemSizes(true); 0050 gameListWidget->setFlow(QListView::LeftToRight); 0051 0052 // Avoid a resize loop (with the scrollbar appearing and disappearing) 0053 // if ever the number of items and display-columns hits a bad combo. 0054 gameListWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); 0055 0056 gameListWidget->setModel(m_collection); 0057 gameListWidget->setItemDelegate(delegate); 0058 gameListWidget->setVerticalScrollMode(QListView::ScrollPerPixel); 0059 gameListWidget->setSelectionBehavior(QAbstractItemView::SelectRows); 0060 gameListWidget->setSelectionMode(QAbstractItemView::SingleSelection); 0061 0062 // Get the previous puzzle configuration. 0063 KConfigGroup gameGroup (KSharedConfig::openConfig(), QStringLiteral("KSudokuGame")); 0064 m_selectedPuzzle = gameGroup.readEntry("SelectedPuzzle", 0); 0065 m_difficulty = gameGroup.readEntry("Difficulty", (int) VeryEasy); 0066 m_symmetry = gameGroup.readEntry("Symmetry" , (int) CENTRAL); 0067 0068 // This has to be a deferred call (presumably to allow the view's setup 0069 // to complete), otherwise the selection fails to appear. 0070 QMetaObject::invokeMethod (this, "setSelectedVariant", 0071 Qt::QueuedConnection, 0072 Q_ARG (int, m_selectedPuzzle)); 0073 0074 connect(gameListWidget->selectionModel(), &QItemSelectionModel::currentChanged, this, &WelcomeScreen::onCurrentVariantChange); 0075 0076 connect(getNewGameButton, &QPushButton::clicked, this, &WelcomeScreen::getNewVariant); 0077 // TODO disabled due to missing per-game config dialog 0078 // connect(configureGameButton, SIGNAL(clicked(bool)), this, SLOT(configureVariant())); 0079 // connect(playGameButton, SIGNAL(clicked(bool)), this, SLOT(playVariant())); // Disable old create-game code. 0080 // connect(gameListWidget, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(playVariant())); // Disable old create-game code. 0081 0082 connect(startEmptyButton, &QPushButton::clicked, this, &WelcomeScreen::startEmptyGame); 0083 connect(puzzleGeneratorButton, &QPushButton::clicked, this, &WelcomeScreen::generatePuzzle); 0084 connect(gameListWidget, &QListView::doubleClicked, this, &WelcomeScreen::generatePuzzle); 0085 0086 // GHNS is not implemented yet, so don't show an unuseful button 0087 getNewGameButton->hide(); 0088 } 0089 0090 GameVariant* WelcomeScreen::selectedVariant() const { 0091 QModelIndex index = gameListWidget->currentIndex(); 0092 return m_collection->variant(index); 0093 } 0094 0095 void WelcomeScreen::setSelectedVariant(int row) { 0096 gameListWidget->setCurrentIndex(gameListWidget->model()->index(row,0)); 0097 } 0098 0099 int WelcomeScreen::difficulty() const { 0100 return m_difficulty; 0101 } 0102 0103 void WelcomeScreen::setDifficulty(int difficulty) { 0104 m_difficulty = difficulty; 0105 } 0106 0107 int WelcomeScreen::symmetry() const { 0108 return m_symmetry; 0109 } 0110 0111 void WelcomeScreen::setSymmetry(int symmetry) { 0112 m_symmetry = symmetry; 0113 } 0114 0115 void WelcomeScreen::onCurrentVariantChange() { 0116 GameVariant* variant = selectedVariant(); 0117 if(!variant) { 0118 // TODO disabled due to missing per-game config dialog 0119 // configureGameButton->setEnabled(false); 0120 // playGameButton->setEnabled(false); 0121 puzzleGeneratorButton->setEnabled(false); 0122 return; 0123 } 0124 0125 // TODO disabled due to missing per-game config dialog 0126 // configureGameButton->setEnabled(variant->canConfigure()); 0127 startEmptyButton->setEnabled(variant->canStartEmpty()); 0128 // playGameButton->setEnabled(true); 0129 puzzleGeneratorButton->setEnabled(true); 0130 } 0131 0132 void WelcomeScreen::getNewVariant() { 0133 KMessageBox::information(this, i18n("GetNewVariant not implemented"), QLatin1String("")); 0134 } 0135 0136 void WelcomeScreen::configureVariant() { 0137 GameVariant* variant = selectedVariant(); 0138 if(!variant) return; 0139 0140 variant->configure(); 0141 } 0142 0143 void WelcomeScreen::startEmptyGame() { 0144 GameVariant* variant = selectedVariant(); 0145 if(!variant) { 0146 KMessageBox::error(this, i18n("Please select a puzzle variant."), i18n("Unable to start puzzle")); 0147 return; 0148 } 0149 0150 Game game = variant->startEmpty(); 0151 if (! game.isValid()) { 0152 KMessageBox::error(this, i18n("Unable to create an empty puzzle of the chosen variant; please try another."), i18n("Unable to start puzzle")); 0153 return; 0154 } 0155 0156 Q_EMIT newGameStarted(game, variant); 0157 } 0158 0159 void WelcomeScreen::playVariant() { 0160 return; // Disable old game-creation code. 0161 GameVariant* variant = selectedVariant(); 0162 if(!variant) { 0163 KMessageBox::error(this, i18n("Please select a puzzle variant."), i18n("Unable to start puzzle")); 0164 return; 0165 } 0166 0167 Game game = variant->createGame(difficulty(), 0); 0168 if(!game.isValid()) { 0169 KMessageBox::error(this, i18n("Unable to start a puzzle of the chosen variant; please try another."), i18n("Unable to start puzzle")); 0170 return; 0171 } 0172 0173 Q_EMIT newGameStarted(game, variant); 0174 } 0175 0176 void WelcomeScreen::generatePuzzle() { 0177 GameVariant* variant = selectedVariant(); 0178 if(!variant) { 0179 KMessageBox::error(this, i18n("Please select a puzzle variant."), i18n("Unable to start puzzle")); 0180 return; 0181 } 0182 0183 Game game = variant->createGame(difficulty(), symmetry()); 0184 if(!game.isValid()) { 0185 KMessageBox::error(this, i18n("Unable to generate a puzzle of the chosen variant; please try another."), i18n("Unable to start puzzle")); 0186 return; 0187 } 0188 0189 // Save the selected puzzle configuration. 0190 QModelIndex index = gameListWidget->currentIndex(); 0191 m_selectedPuzzle = index.row(); 0192 0193 KConfigGroup gameGroup (KSharedConfig::openConfig(), QStringLiteral("KSudokuGame")); 0194 gameGroup.writeEntry("SelectedPuzzle", m_selectedPuzzle); 0195 gameGroup.writeEntry("Difficulty", m_difficulty); 0196 gameGroup.writeEntry("Symmetry" , m_symmetry); 0197 gameGroup.sync(); // Ensure that the entry goes to disk. 0198 0199 // If the user abandoned puzzle-generation, stay on the Welcome Screen 0200 // and allow the user to change the Difficulty, etc. of the puzzle. 0201 if (game.puzzle()->hasSolution()) { 0202 Q_EMIT newGameStarted(game, variant); // OK, start playing. 0203 } 0204 } 0205 0206 } 0207 0208 #include "moc_welcomescreen.cpp"