summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mainwindow.cc62
-rw-r--r--src/mainwindow.h6
-rw-r--r--src/solverwindow.cc118
-rw-r--r--src/solverwindow.h40
4 files changed, 130 insertions, 96 deletions
diff --git a/src/mainwindow.cc b/src/mainwindow.cc
index 873502e..7cfdf4b 100644
--- a/src/mainwindow.cc
+++ b/src/mainwindow.cc
@@ -37,6 +37,8 @@ MainWindow::MainWindow()
initActions();
initMenus();
+
+ updateTitle();
}
@@ -49,56 +51,57 @@ void MainWindow::initActions()
connect(action_new, SIGNAL(triggered()), this, SLOT(doNew()));
// Game -> Load
- action_load = new QAction(tr("&Load..."), this);
- action_load->setShortcuts(QKeySequence::Open);
- action_load->setStatusTip(tr("Load a previously saved game"));
- connect(action_load, SIGNAL(triggered()), this, SLOT(doLoad()));
+ action_open = new QAction(tr("&Open..."), this);
+ action_open->setShortcuts(QKeySequence::Open);
+ action_open->setStatusTip(tr("Open a previously saved game"));
+ connect(action_open, SIGNAL(triggered()), this, SLOT(doOpen()));
// Game -> Save
action_save = new QAction(tr("&Save"), this);
- action_load->setStatusTip(tr("Save the current game"));
+ action_save->setShortcuts(QKeySequence::Save);
+ action_save->setStatusTip(tr("Save the current game"));
connect(action_save, SIGNAL(triggered()), this, SLOT(doSave()));
// Game -> Save As
action_saveas = new QAction(tr("Save &As..."), this);
- action_load->setStatusTip(tr("Save the current game to a new file"));
+ action_saveas->setStatusTip(tr("Save the current game to a new file"));
connect(action_saveas, SIGNAL(triggered()), this, SLOT(doSaveAs()));
// Game -> Revert
action_revert = new QAction(tr("&Revert"), this);
action_revert->setStatusTip(tr("Reload the current game from file"));
- connect(action_revert, SIGNAL(triggered()), mainwindow_solverwindow, SLOT(revert()));
+ connect(action_revert, SIGNAL(triggered()), this, SLOT(doRevert()));
// Game -> Quit
action_quit = new QAction(tr("&Quit"), this);
action_quit->setShortcuts(QKeySequence::Quit);
action_quit->setStatusTip(tr("Exit the application"));
- connect(action_quit, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));
+ connect(action_quit, SIGNAL(triggered()), this, SLOT(doQuit()));
// Move -> Hint
action_hint = new QAction(tr("Hint"), this);
action_hint->setStatusTip(tr("Give a hint"));
- // TODO
+ // TODO connect()
// Move -> Step
action_step = new QAction(tr("Step"), this);
action_step->setStatusTip(tr("Solve a single cell"));
- connect(action_step, SIGNAL(triggered()), mainwindow_solverwindow, SLOT(step()));
+ connect(action_step, SIGNAL(triggered()), mainwindow_solverwindow, SLOT(doStep()));
// Move -> Step
action_guess = new QAction(tr("Guess"), this);
action_guess->setStatusTip(tr("Solve a single cell with guessing"));
- connect(action_guess, SIGNAL(triggered()), mainwindow_solverwindow, SLOT(guess()));
+ connect(action_guess, SIGNAL(triggered()), mainwindow_solverwindow, SLOT(doGuess()));
// Move -> Solve
action_solve = new QAction(tr("Solve rules"), this);
action_solve->setStatusTip(tr("Solve sudoku rules"));
- connect(action_solve, SIGNAL(triggered()), mainwindow_solverwindow, SLOT(solve()));
+ connect(action_solve, SIGNAL(triggered()), mainwindow_solverwindow, SLOT(doSolve()));
// Move -> Search
action_search = new QAction(tr("Find solution"), this);
action_search->setStatusTip(tr("Find a solution"));
- connect(action_search, SIGNAL(triggered()), mainwindow_solverwindow, SLOT(search()));
+ connect(action_search, SIGNAL(triggered()), mainwindow_solverwindow, SLOT(doSearch()));
// Move -> Validate
action_validate = new QAction(tr("Validate"), this);
@@ -110,7 +113,7 @@ void MainWindow::initMenus()
{
mainwindow_gamemenu = menuBar()->addMenu(tr("&Game"));
mainwindow_gamemenu->addAction(action_new);
- mainwindow_gamemenu->addAction(action_load);
+ mainwindow_gamemenu->addAction(action_open);
mainwindow_gamemenu->addSeparator();
mainwindow_gamemenu->addAction(action_save);
mainwindow_gamemenu->addAction(action_saveas);
@@ -133,37 +136,54 @@ void MainWindow::updateTitle()
{
if (mainwindow_solverwindow->filename().isEmpty()) {
setWindowTitle("Sudoku");
+
+ action_revert->setEnabled(false);
+
} else {
setWindowTitle(mainwindow_solverwindow->filename() + " - Sudoku");
+
+ action_revert->setEnabled(true);
}
}
void MainWindow::doNew()
{
- mainwindow_solverwindow->clear();
+ mainwindow_solverwindow->doNew();
updateTitle();
}
void MainWindow::doSave()
{
- mainwindow_solverwindow->save();
+ mainwindow_solverwindow->doSave();
updateTitle();
}
void MainWindow::doSaveAs()
{
- mainwindow_solverwindow->saveas();
+ mainwindow_solverwindow->doSaveAs();
+ updateTitle();
+}
+
+void MainWindow::doOpen()
+{
+ mainwindow_solverwindow->doOpen();
updateTitle();
}
-void MainWindow::doLoad()
+void MainWindow::doRevert()
{
- mainwindow_solverwindow->load();
+ mainwindow_solverwindow->doRevert();
updateTitle();
}
void MainWindow::doValidate()
{
- mainwindow_solverwindow->validate();
+ mainwindow_solverwindow->doValidate();
+}
+
+void MainWindow::doQuit()
+{
+ if (QMessageBox::question(this, tr("Quit"), tr("Exit the application?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ qApp->closeAllWindows();
+ }
}
- \ No newline at end of file
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 0054893..27a1f33 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -30,7 +30,7 @@ private:
// Game menu actions
QAction *action_new;
- QAction *action_load;
+ QAction *action_open;
QAction *action_save;
QAction *action_saveas;
QAction *action_revert;
@@ -47,9 +47,11 @@ private:
private slots:
void doNew();
+ void doOpen();
void doSave();
void doSaveAs();
- void doLoad();
+ void doRevert();
+ void doQuit();
void doValidate();
diff --git a/src/solverwindow.cc b/src/solverwindow.cc
index f680c59..a73eb51 100644
--- a/src/solverwindow.cc
+++ b/src/solverwindow.cc
@@ -38,13 +38,13 @@ SolverWindow::SolverWindow()
}
}
-void SolverWindow::loadFromFile(const QString & filename)
+void SolverWindow::openFromFile(const QString & filename)
{
QFile file(filename);
if (!file.open(QFile::ReadOnly | QFile::Text)) {
- QMessageBox::warning(this, tr("Open file"),
- tr("Could not open file %1:\n%2.")
+ QMessageBox::warning(this, tr("Open"),
+ tr("Could not open file \"%1\":\n%2.")
.arg(filename)
.arg(file.errorString()));
return;
@@ -77,8 +77,8 @@ void SolverWindow::saveToFile(const QString & filename)
{
QFile file(filename);
if (!file.open(QFile::WriteOnly | QFile::Text)) {
- QMessageBox::warning(this, tr("Save file"),
- tr("Cannot write file %1:\n%2.")
+ QMessageBox::warning(this, tr("Save"),
+ tr("Could not write to file \"%1\":\n%2.")
.arg(filename)
.arg(file.errorString()));
return;
@@ -116,54 +116,64 @@ void SolverWindow::saveToFile(const QString & filename)
}
-void SolverWindow::load()
+void SolverWindow::doOpen()
{
- QString filename = QFileDialog::getOpenFileName(this, tr("Open..."), HOMEDIR, "Sudoku (*.sudoku)");
+ QString filename = QFileDialog::getOpenFileName(this, tr("Open"), HOMEDIR, "Sudoku (*.sudoku)");
if (!filename.isEmpty()) {
- loadFromFile(filename);
- }
-
- return;
+ openFromFile(filename);
+ }
}
-void SolverWindow::revert()
+void SolverWindow::doRevert()
{
if (!solverwindow_filename.isEmpty()) {
- loadFromFile(solverwindow_filename);
+ QFileInfo fileinfo(solverwindow_filename);
+ if (QMessageBox::warning(this, tr("Revert?"), tr("Revert the state of the game to the previously saved file \"%1\"?").arg(fileinfo.fileName()), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ openFromFile(solverwindow_filename);
+ }
}
}
-void SolverWindow::save()
+void SolverWindow::doSave()
{
if (solverwindow_filename.isEmpty()) {
- saveas();
+ // no file name is set, use the Save As dialog
+ doSaveAs();
} else {
+ // confirm overwriting an existing file
+ QFile file (solverwindow_filename);
+ if (file.exists()) {
+ QFileInfo fileinfo(file);
+ if (QMessageBox::warning(this, tr("Overwrite file?"), tr("The file \"%1\" already exists. Do you wish to overwrite it?").arg(fileinfo.fileName()), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
+ return;
+ }
+ }
saveToFile(solverwindow_filename);
+
}
- return;
}
-void SolverWindow::saveas()
+void SolverWindow::doSaveAs()
{
+ // QFileDialog::getSaveFileName() warns about existing files
QString filename = QFileDialog::getSaveFileName(this, tr("Save as..."), HOMEDIR, "Sudoku (*.sudoku)");
+
if (!filename.isEmpty()) {
- solverwindow_filename = filename;
- saveToFile(solverwindow_filename);
+ saveToFile(filename);
}
-
- return;
}
-void SolverWindow::clear()
+void SolverWindow::doNew()
{
- Sudoku sudoku;
- solverwindow_sudokuwidget->set_values(sudoku);
-
- solverwindow_filename.clear();
+ if (QMessageBox::question(this, tr("New"), tr("Start a new game?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ Sudoku sudoku;
+ solverwindow_sudokuwidget->set_values(sudoku);
+ solverwindow_filename.clear();
+ }
}
-void SolverWindow::step()
+void SolverWindow::doStep()
{
Sudoku sudoku;
solverwindow_sudokuwidget->get_values(sudoku);
@@ -171,7 +181,7 @@ void SolverWindow::step()
Sudoku solution(sudoku);
int solved = solution.solve_rules();
if (solved == 0) {
- QMessageBox::warning(this, tr("Step"), tr("No cells to solve found"));
+ QMessageBox::warning(this, tr("Step"), tr("No more cells to solve!"));
return;
}
@@ -190,10 +200,9 @@ void SolverWindow::step()
index_current = (index_current + 1) % 81;
} while (index_current != index_start);
-
}
-void SolverWindow::guess()
+void SolverWindow::doGuess()
{
Sudoku sudoku;
solverwindow_sudokuwidget->get_values(sudoku);
@@ -201,7 +210,7 @@ void SolverWindow::guess()
Sudoku solution(sudoku);
int solved = solution.solve_search();
if (solved == 0) {
- QMessageBox::warning(this, tr("Guess"), tr("No cells to solve found"));
+ QMessageBox::warning(this, tr("Guess"), tr("No more cells to solve!"));
return;
}
@@ -220,59 +229,66 @@ void SolverWindow::guess()
index_current = (index_current + 1) % 81;
} while (index_current != index_start);
-
}
-void SolverWindow::solve()
+void SolverWindow::doSolve()
{
- // TODO messagebox, detect invalid and solved states
+ // TODO detect invalid and solved states
Sudoku sudoku;
solverwindow_sudokuwidget->get_values(sudoku);
int solved = sudoku.solve_rules();
sudoku.validate();
solverwindow_sudokuwidget->set_values(sudoku);
- qDebug() << solved << " cells solved";
+
+ if (solved == 0) {
+ QMessageBox::warning(this, tr("Solve rules"), tr("No more cells to solve!"));
+ return;
+ }
}
-void SolverWindow::search()
+void SolverWindow::doSearch()
{
- // TODO messagebox, detect invalid and solved states
+ // TODO detect invalid and solved states
Sudoku sudoku;
solverwindow_sudokuwidget->get_values(sudoku);
int iterations = sudoku.solve_search();
+ sudoku.validate();
solverwindow_sudokuwidget->set_values(sudoku);
- if (iterations > 0) {
- qDebug() << "solved in " << iterations << " iterations";
+
+ if (iterations == 0) {
+ QMessageBox::warning(this, tr("Find solution"), tr("No more cells to solve!"));
+ return;
}
}
-void SolverWindow::step_constraints()
+void SolverWindow::doValidate()
{
Sudoku sudoku;
solverwindow_sudokuwidget->get_values(sudoku);
- int solved = sudoku.solve_constraints();
+
+ bool is_valid = sudoku.validate();
solverwindow_sudokuwidget->set_values(sudoku);
- // qDebug() << solved << " cells solved";
+
+ if (is_valid) {
+ QMessageBox::information(this, tr("Validate"), tr("Sudoku is valid."));
+ } else {
+ QMessageBox::warning(this, tr("Validate"), tr("Sudoku is not valid!"));
+ }
}
-void SolverWindow::step_coverage()
+void SolverWindow::step_constraints()
{
Sudoku sudoku;
solverwindow_sudokuwidget->get_values(sudoku);
- int solved = sudoku.solve_coverage();
+ int solved = sudoku.solve_constraints();
solverwindow_sudokuwidget->set_values(sudoku);
- // qDebug() << solved << " cells solved";
}
-void SolverWindow::validate()
+void SolverWindow::step_coverage()
{
Sudoku sudoku;
solverwindow_sudokuwidget->get_values(sudoku);
- if (sudoku.validate()) {
- QMessageBox::information(this, tr("Validate"), tr("Sudoku is valid."));
- } else {
- QMessageBox::warning(this, tr("Validate"), tr("Sudoku is not valid!"));
- }
+ int solved = sudoku.solve_coverage();
solverwindow_sudokuwidget->set_values(sudoku);
}
diff --git a/src/solverwindow.h b/src/solverwindow.h
index 4520c9e..dc2e595 100644
--- a/src/solverwindow.h
+++ b/src/solverwindow.h
@@ -22,41 +22,37 @@ public:
public slots:
- void load();
- void save();
- void saveas();
- void revert();
+ void doNew();
+ void doOpen();
+ void doSave();
+ void doSaveAs();
+ void doRevert();
/**
- * @brief try to find a solution by using the rules only
+ * @brief try to solve a single cell by using the rules only
* */
- void solve();
-
+ void doStep();
/**
- * @brief try to find a solution by guessing where required
+ * @brief try to solve a single cell by guessing where required
* */
- void search();
-
+ void doGuess();
/**
- * @brief try to solve a single cell by using the rules only
+ * @brief try to find a solution by using the rules only
* */
- void step();
-
- void step_constraints();
- void step_coverage();
-
+ void doSolve();
/**
- * @brief try to solve a single cell by guessing where required
+ * @brief try to find a solution by guessing where required
* */
- void guess();
+ void doSearch();
- void clear();
-
- void validate();
+ void doValidate();
private:
+ void step_constraints();
+ void step_coverage();
+
void saveToFile(const QString & filename);
- void loadFromFile(const QString & filename);
+ void openFromFile(const QString & filename);
SudokuWidget *solverwindow_sudokuwidget;
Sudoku solverwindow_revertstate;