Index: .project =================================================================== --- .project (revision 416) +++ .project (working copy) @@ -1,33 +1,33 @@ - - - Andoku - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - + + + Andokus + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + Index: AndroidManifest.xml =================================================================== --- AndroidManifest.xml (revision 416) +++ AndroidManifest.xml (working copy) @@ -20,10 +20,9 @@ --> + package="com.googlecode.andoku" android:versionName="1.3.3s"> @@ -40,6 +39,7 @@ android:description="@string/perm_description_import" android:permissionGroup="com.googlecode.andoku.permission-group.ANDOKU" android:protectionLevel="normal"/> + -Über Andoku +Über Andokus -

Andoku

+

Andoku Special

+

Version 1.3.3s

+

Copyright © 2009, 2010, 2011 Markus Wiederkehr.
+Copyright © 2010, 2011 Hans Harder (Note and load/save game adaptions) +

-

Version 1.3.3

- -

Copyright © 2009, 2010, 2011 Markus Wiederkehr.

-

This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions; see the GNU General Public License v3 for details.

-

Projekt-Homepage: http://code.google.com/p/andoku

+

Project homepage: http://code.google.com/p/andoku
+Andokus homepage: http://www.atbas.org/andokus

Index: assets/about-fi.html =================================================================== --- assets/about-fi.html (revision 416) +++ assets/about-fi.html (working copy) @@ -7,18 +7,19 @@ -

Andoku

+

Andoku Special

+

version 1.3.3s

+

Copyright © 2009, 2010, 2011 Markus Wiederkehr.
+Copyright © 2010, 2011 Hans Harder (Note and load/save game adaptions) +

-

version 1.3.3

- -

Copyright © 2009, 2010, 2011 Markus Wiederkehr.

-

This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions; see the GNU General Public License v3 for details.

-

Projektin kotisivut: http://code.google.com/p/andoku

+

Project homepage: http://code.google.com/p/andoku
+Andokus homepage: http://www.atbas.org/andokus

Index: assets/about-fr.html =================================================================== --- assets/about-fr.html (revision 416) +++ assets/about-fr.html (working copy) @@ -7,18 +7,19 @@ -

Andoku

+

Andoku Special

+

version 1.3.3s

+

Copyright © 2009, 2010, 2011 Markus Wiederkehr.
+Copyright © 2010, 2011 Hans Harder (Note and load/save game adaptions) +

-

version 1.3.3

- -

Copyright © 2009, 2010, 2011 Markus Wiederkehr.

-

This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions; see the GNU General Public License v3 for details.

-

Page du projet : http://code.google.com/p/andoku

+

Project homepage: http://code.google.com/p/andoku
+Andokus homepage: http://www.atbas.org/andokus

Index: assets/about-it.html =================================================================== --- assets/about-it.html (revision 416) +++ assets/about-it.html (working copy) @@ -1,24 +1,25 @@ -Informazioni su Andoku +Informazioni su Andokus -

Andoku

+

Andoku Special

+

version 1.3.3s

+

Copyright © 2009, 2010, 2011 Markus Wiederkehr.
+Copyright © 2010, 2011 Hans Harder (Note and load/save game adaptions) +

-

version 1.3.3

- -

Copyright © 2009, 2010, 2011 Markus Wiederkehr.

-

This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions; see the GNU General Public License v3 for details.

-

Homepage del progetto: http://code.google.com/p/andoku

+

Project homepage: http://code.google.com/p/andoku
+Andokus homepage: http://www.atbas.org/andokus

Index: assets/about.html =================================================================== --- assets/about.html (revision 416) +++ assets/about.html (working copy) @@ -1,24 +1,25 @@ -About Andoku +About Andokus -

Andoku

+

Andoku Special

+

version 1.3.3s

+

Copyright © 2009, 2010, 2011 Markus Wiederkehr.
+Copyright © 2010, 2011 Hans Harder (Note and load/save game adaptions) +

-

version 1.3.3

- -

Copyright © 2009, 2010, 2011 Markus Wiederkehr.

-

This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions; see the GNU General Public License v3 for details.

-

Project homepage: http://code.google.com/p/andoku

+

Project homepage: http://code.google.com/p/andoku
+Andokus homepage: http://www.atbas.org/andokus

Index: assets/puzzles/standard_n_1.adk =================================================================== --- assets/puzzles/standard_n_1.adk (revision 416) +++ assets/puzzles/standard_n_1.adk (working copy) @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License # along with Andoku. If not, see . -.8.4.96536428...7.......8....7..5.42...7.1...85.6..1....6.......1...47362735.8.1. +................................................................................. 63.2.8.1.2...5..891.9.6..3...8..6.5....187....6.5..9...9..7.1.681..2...5.2.4.3.97 ...1...4.195..8...34..2.1.9...91.5..6.98.24.7..1.34...2.8.4..71...7..832.1...9... ..7....638.467.9...1..39..2..37..6..7..4.1..5..8..61..6..21..9...1.635.839....7.. Index: res/layout/andoku.xml =================================================================== --- res/layout/andoku.xml (revision 416) +++ res/layout/andoku.xml (working copy) @@ -103,6 +103,7 @@ + Index: res/values-de/prefs.xml =================================================================== --- res/values-de/prefs.xml (revision 416) +++ res/values-de/prefs.xml (working copy) @@ -51,4 +51,8 @@ Zeigt eine Stoppuhr während des Spiels an. Werte eliminieren aktiv Schaltet den Menüeintrag \'Werte eliminieren\' im Spiel frei. + Enable Automatic Notes + When multiple the same numbers are in 1 area make them notes + PuzzleUrl + Define which url to use for loading single puzzles from the internet Index: res/values-de/strings.xml =================================================================== --- res/values-de/strings.xml (revision 416) +++ res/values-de/strings.xml (working copy) @@ -21,7 +21,7 @@ - Andoku + Andokus vor 0 Minuten @@ -127,12 +127,12 @@ Farb-Sudoku - Willkommen zu Andoku + Willkommen zu Andokus Spiel fortsetzen Neues Spiel starten Importierte Ordner - Hilfe zu Andoku - Über Andoku + Hilfe zu Andokus + Über Andokus Raster: @@ -147,7 +147,12 @@ Andoku - Gruppe von Rechten um mit Andoku zu interagieren. - Sudoku-Rätsel in Andoku importieren - Erlaubt es einer Anwendung, Ordner in Andoku zu erstellen und Sudoku-Rätsel zu importieren. + Gruppe von Rechten um mit Andokus zu interagieren. + Sudoku-Rätsel in Andokus importieren + Erlaubt es einer Anwendung, Ordner in Andokus zu erstellen und Sudoku-Rätsel zu importieren. + Note + Load Game + Save Game + Game saved ! + No saved game found ! Index: res/values-fi/prefs.xml =================================================================== --- res/values-fi/prefs.xml (revision 416) +++ res/values-fi/prefs.xml (working copy) @@ -41,4 +41,8 @@ Näyttää sekuntikellon pelin aikana. Ota käyttöön \'Karsi arvot\' Avaa pelivalikkoon kohdan \'Karsi arvot\'. + Enable Automatic Notes + When multiple the same numbers are in 1 area make them notes + PuzzleUrl + Define which url to use for loading single puzzles from the internet Index: res/values-fi/strings.xml =================================================================== --- res/values-fi/strings.xml (revision 416) +++ res/values-fi/strings.xml (working copy) @@ -22,7 +22,7 @@ - Andoku + Andokus 0 minuuttia sitten eilen tunti sitten @@ -114,4 +114,9 @@ Käyttöluvat, joilla on mahdollista vaikuttaa Andokuun. tuo sudokupulmia Andokuun Sallii sovelluksen luoda kansioita ja tuoda sudokupulmia Andokuun. + Note + Load Game + Save Game + Game saved ! + No saved game found ! Index: res/values-fr/prefs.xml =================================================================== --- res/values-fr/prefs.xml (revision 416) +++ res/values-fr/prefs.xml (working copy) @@ -53,4 +53,8 @@ Afficher un chronomètre pendant le jeu. \'Effacer des chiffres\' Autoriser l\'option \'Effacer des chiffres\' au cours du jeu. + Enable Automatic Notes + When multiple the same numbers are in 1 area make them notes + PuzzleUrl + Define which url to use for loading single puzzles from the internet Index: res/values-fr/strings.xml =================================================================== --- res/values-fr/strings.xml (revision 416) +++ res/values-fr/strings.xml (working copy) @@ -23,7 +23,7 @@ - Andoku + Andokus Il y a moins d\'une minute @@ -129,7 +129,7 @@ Sodoku-lor - Bienvenue sur Andoku + Bienvenue sur Andokus Reprendre le jeu Nouvelle grille Dossiers importés @@ -151,5 +151,10 @@ Andoku Permissions pour interagir avec Andoku. Importer des grilles de Sudoku - Autoriser l\'application à créer des dossiers et importer des grilles dans Andoku. + Autoriser l\'application à créer des dossiers et importer des grilles dans Andokus. + Note + Load Game + Save Game + Game saved ! + No saved game found ! Index: res/values-it/prefs.xml =================================================================== --- res/values-it/prefs.xml (revision 416) +++ res/values-it/prefs.xml (working copy) @@ -53,4 +53,8 @@ Visualizza cronometro durante il gioco. Abilita \'Valori Eliminati\' Sblocca menù \'Valori Eliminati\' nel gioco. + Enable Automatic Notes + When multiple the same numbers are in 1 area make them notes + PuzzleUrl + Define which url to use for loading single puzzles from the internet Index: res/values-it/strings.xml =================================================================== --- res/values-it/strings.xml (revision 416) +++ res/values-it/strings.xml (working copy) @@ -23,7 +23,7 @@ - Andoku + Andokus 0 minuti fa @@ -129,12 +129,12 @@ Color-Sudoku - Benvenuto in Andoku + Benvenuto in Andokus Riprendi Gioco Inizia Nuovo Gioco Importa Cartelle - Aiuto per Andoku - Crediti Andoku + Aiuto per Andokus + Crediti Andokus Stile griglia: @@ -150,6 +150,11 @@ Andoku Gruppo di permessi per interagire con Andoku. - importa puzzle sudoku in Andoku - Permetti all\'applicazione di creare cartelle e importare puzzle sudoku in Andoku. + importa puzzle sudoku in Andokus + Permetti all\'applicazione di creare cartelle e importare puzzle sudoku in Andokus. + Note + Load Game + Save Game + Game saved ! + No saved game found ! Index: res/values/prefs.xml =================================================================== --- res/values/prefs.xml (revision 416) +++ res/values/prefs.xml (working copy) @@ -51,4 +51,8 @@ Displays a stopwatch during the game. Enable \'Eliminate Values\' Unlocks the menu entry \'Eliminate Values\' in the game. - + Enable Automatic Notes + When multiple the same numbers are in 1 area make them notes + PuzzleUrl + Define which url to use for loading single puzzles from the internet + Index: res/values/strings.xml =================================================================== --- res/values/strings.xml (revision 416) +++ res/values/strings.xml (working copy) @@ -21,7 +21,7 @@ - Andoku + Andokus 0 minutes ago @@ -127,12 +127,12 @@ Color-Sudoku - Welcome to Andoku + Welcome to Andokus Resume Game Start New Game Imported Folders - Help on Andoku - About Andoku + Help on Andokus + About Andokus Grid style: @@ -147,7 +147,12 @@ Andoku - Group of permissions to interact with Andoku. + Group of permissions to interact with Andokus. import sudoku puzzles into Andoku - Allows the application to create folders and import sudoku puzzles into Andoku. - + Allows the application to create folders and import sudoku puzzles into Andokus. + Note + Load Game + Save Game + Game saved ! + No saved game found ! + Index: res/xml/settings.xml =================================================================== --- res/xml/settings.xml (revision 416) +++ res/xml/settings.xml (working copy) @@ -55,12 +55,11 @@ + android:dialogTitle="@string/pref_title_input_method" android:defaultValue="AUTOMATIC"/> + + + Index: src/com/googlecode/andoku/AndokuActivity.java =================================================================== --- src/com/googlecode/andoku/AndokuActivity.java (revision 417) +++ src/com/googlecode/andoku/AndokuActivity.java (working copy) @@ -20,6 +20,11 @@ package com.googlecode.andoku; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; + import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; @@ -42,12 +47,13 @@ import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; -import android.view.ViewGroup; import android.view.View.OnClickListener; import android.view.View.OnKeyListener; import android.view.View.OnTouchListener; +import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.Button; +import android.widget.EditText; import android.widget.ImageButton; import android.widget.TextView; import android.widget.Toast; @@ -83,8 +89,10 @@ private static final int MENU_PAUSE_RESUME_PUZZLE = Menu.FIRST + 1; private static final int MENU_ELIMINATE_VALUES = Menu.FIRST + 2; private static final int MENU_RESET_PUZZLE = Menu.FIRST + 3; - private static final int MENU_RESET_ALL_PUZZLES = Menu.FIRST + 4; - private static final int MENU_SETTINGS = Menu.FIRST + 5; + private static final int MENU_SAVE_GAME = Menu.FIRST + 4; + private static final int MENU_LOAD_GAME = Menu.FIRST + 5; + private static final int MENU_RESET_ALL_PUZZLES = Menu.FIRST + 6; + private static final int MENU_SETTINGS = Menu.FIRST + 7; private static final String APP_STATE_PUZZLE_SOURCE_ID = "puzzleSourceId"; private static final String APP_STATE_PUZZLE_NUMBER = "puzzleNumber"; @@ -129,6 +137,7 @@ private TextView timerView; private ViewGroup keypad; private KeypadToggleButton[] keypadToggleButtons; + private KeypadToggleButton noteToggleButton; private ImageButton undoButton; private ImageButton redoButton; private TextView congratsView; @@ -163,12 +172,24 @@ public void setCellValues(Position position, ValueSet values) { AndokuActivity.this.setCellValues(position, values); } + public void setCellNote(Position cell, Integer offon) { + puzzle.setNoteState(cell.row, cell.col, offon); + } public int getNumberOfDigitButtons() { return keypadToggleButtons.length; } public void checkButton(int digit, boolean checked) { keypadToggleButtons[digit].setChecked(checked); } + public void checkNoteButton(Position cell) { + noteToggleButton.setChecked(puzzle.isNote(cell.row, cell.col)); + puzzle.notestate = noteToggleButton.isChecked() ? 1 : 0; + } + public int toggleNote() { + noteToggleButton.setChecked(!noteToggleButton.isChecked()); + puzzle.notestate = noteToggleButton.isChecked() ? 1 : 0; + return puzzle.notestate; + } public void highlightDigit(Integer digit) { andokuView.highlightDigit(digit); } @@ -225,6 +246,12 @@ } }); } + noteToggleButton = (KeypadToggleButton) findViewById(R.id.input_note); + noteToggleButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + onNote(); + } + }); KeypadButton clearButton = (KeypadButton) findViewById(R.id.input_clear); clearButton.setOnClickListener(new OnClickListener() { @@ -428,6 +455,10 @@ @Override public boolean onCreateOptionsMenu(Menu menu) { + menu.add(Menu.NONE, MENU_LOAD_GAME, Menu.NONE, R.string.menu_load_game).setIcon( + android.R.drawable.ic_menu_upload); + menu.add(Menu.NONE, MENU_SAVE_GAME, Menu.NONE, R.string.menu_save_game).setIcon( + android.R.drawable.ic_menu_save); menu.add(Menu.NONE, MENU_CHECK_PUZZLE, Menu.NONE, R.string.menu_check_puzzle).setIcon( android.R.drawable.ic_menu_help); menu.add(Menu.NONE, MENU_PAUSE_RESUME_PUZZLE, Menu.NONE, ""); @@ -447,24 +478,38 @@ menu.findItem(MENU_CHECK_PUZZLE).setVisible(gameState == GAME_STATE_PLAYING); boolean paused = gameState == GAME_STATE_READY && !puzzle.isSolved() && timer.getTime() > 0; - menu.findItem(MENU_PAUSE_RESUME_PUZZLE).setTitle( - paused ? R.string.menu_resume : R.string.menu_pause).setIcon( - paused ? R.drawable.ic_menu_resume : R.drawable.ic_menu_pause).setVisible( - gameState == GAME_STATE_PLAYING || paused); + menu.findItem(MENU_PAUSE_RESUME_PUZZLE) + .setTitle(paused ? R.string.menu_resume : R.string.menu_pause) + .setIcon(paused ? R.drawable.ic_menu_resume : R.drawable.ic_menu_pause) + .setVisible(gameState == GAME_STATE_PLAYING || paused); SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this); - menu.findItem(MENU_ELIMINATE_VALUES).setVisible( - gameState == GAME_STATE_PLAYING - && settings.getBoolean(Settings.KEY_ENABLE_ELIMINATE_VALUES, false)).setEnabled( - puzzle.canEliminateValues()); + menu.findItem(MENU_ELIMINATE_VALUES) + .setVisible( + gameState == GAME_STATE_PLAYING + && settings.getBoolean(Settings.KEY_ENABLE_ELIMINATE_VALUES, false)) + .setEnabled(puzzle.canEliminateValues()); menu.findItem(MENU_RESET_PUZZLE).setVisible(gameState == GAME_STATE_PLAYING); + PuzzleId puzzleId = getCurrentPuzzleId(); + if (db.TestGame(puzzleId.puzzleSourceId, puzzleId.number, 2)) { + menu.findItem(MENU_LOAD_GAME).setTitle(R.string.menu_load_game); + menu.findItem(MENU_LOAD_GAME).setVisible(gameState == GAME_STATE_PLAYING); + } + else if (puzzleId.puzzleSourceId.equals("asset:standard_n_1") && puzzleId.number == 0) { + menu.findItem(MENU_LOAD_GAME).setTitle("Load remote"); + menu.findItem(MENU_LOAD_GAME).setVisible(gameState == GAME_STATE_PLAYING); + } + else { + menu.findItem(MENU_LOAD_GAME).setVisible(false); + } + menu.findItem(MENU_SAVE_GAME).setVisible(gameState == GAME_STATE_PLAYING); + menu.findItem(MENU_RESET_ALL_PUZZLES).setVisible(gameState == GAME_STATE_READY); return super.onPrepareOptionsMenu(menu); } - @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { @@ -477,6 +522,12 @@ case MENU_ELIMINATE_VALUES: onEliminateValues(); return true; + case MENU_LOAD_GAME: + onLoadGame(); + return true; + case MENU_SAVE_GAME: + onSaveGame(); + return true; case MENU_RESET_PUZZLE: onResetPuzzle(false); return true; @@ -500,6 +551,27 @@ cancelToast(); } + void onNote() { + if (gameState != GAME_STATE_PLAYING) + return; + + inputMethod.toggleNote(); + if (puzzle.isCompletelyFilled()) { + if (puzzle.isSolved()) { + timer.stop(); + autoSavePuzzle(); + + enterGameState(GAME_STATE_SOLVED); + return; + } + else { + showInfo(R.string.info_invalid_solution); + } + } + cancelToast(); + } + + void onClear() { if (gameState != GAME_STATE_PLAYING) return; @@ -681,6 +753,11 @@ SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this); boolean checkAgainstSolution = settings.getBoolean(Settings.KEY_CHECK_AGAINST_SOLUTION, true); + // no idea were the solution is, our special blank puzzle should not be checked with solution ... + PuzzleId puzzleId = getCurrentPuzzleId(); + if (puzzleId.number == 0 && puzzleId.puzzleSourceId.contains("standard_n_1")) + checkAgainstSolution = false; + if (checkAgainstSolution) { if (puzzle.hasSolution()) { checkPuzzle(true); @@ -710,7 +787,6 @@ showInfo(String.format(text.toString(), puzzle.getMissingValuesCount())); } } - andokuView.invalidate(); } @@ -749,6 +825,91 @@ } } + void LoadRemote(String urlstr) { + try { + URL url = new URL(urlstr); + URLConnection conn = url.openConnection(); + // Get the response + BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); + String line = ""; + if ((line = rd.readLine()) != null) { + int size = puzzle.getSize(); + if (line.length() >= (size * size)) { + puzzle.setAll(line); + puzzle.setFixed(); + enterGameState(GAME_STATE_PLAYING); + andokuView.invalidate(); // force redisplay + } + showInfo("Got: " + line); + } + else + showWarning("not able to read"); + } + catch (Exception e) { + showWarning("Got exception"); + } + } + private void popupUrl() { + SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this); + String urlstr = settings.getString(Settings.KEY_PUZZLEURL, "http://www.atbas.org/sudoku.php"); + + final AlertDialog.Builder alert = new AlertDialog.Builder(this); + final EditText input = new EditText(this); + input.append(urlstr); + input.setSingleLine(true); + input.setTextSize(14.0f); + alert.setView(input); + alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + String urladdress = input.getText().toString().trim(); + LoadRemote(urladdress); + } + }); + + alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + dialog.cancel(); + } + }); + alert.show(); + } + + void onLoadGame() { + timer.stop(); + PuzzleId puzzleId = getCurrentPuzzleId(); + if (Constants.LOG_V) + Log.v(TAG, "load save game " + puzzleId); + + if (!db.loadGame(puzzleId, puzzle, timer, 2)) { + if (puzzleId.puzzleSourceId.equals("asset:standard_n_1") && puzzleId.number == 0) + popupUrl(); + else + showWarning(R.string.error_game_load); + } + puzzle.setFixed(); + enterGameState(GAME_STATE_PLAYING); + andokuView.invalidate(); // force redisplay + } + + void onSaveGame() { + boolean errors = puzzle.checkForErrors(false); + if (errors) { + showWarning(R.string.warn_puzzle_errors); + } + else { + timer.stop(); + PuzzleId puzzleId = getCurrentPuzzleId(); + if (Constants.LOG_V) + Log.v(TAG, "save puzzle state" + puzzleId); + // set all values as fixed + puzzle.setFixed(); + db.saveGame(puzzleId, puzzle, timer, 2); + showInfo(R.string.info_game_saved); + enterGameState(GAME_STATE_PLAYING); + } + andokuView.invalidate(); // force redisplay + } + // callback from reset all puzzles dialog void onResetAllPuzzles(boolean confirmed) { if (!confirmed) { @@ -786,6 +947,8 @@ setTimerVisibility(gameState); + setAutoNote(); + andokuView.invalidate(); } @@ -837,6 +1000,12 @@ setPuzzle(number); } + private void setAutoNote() { + SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this); + boolean checkAutoNote = settings.getBoolean(Settings.KEY_ENABLE_AUTONOTE, false); + puzzle.setAutoNote(checkAutoNote); + } + private void setPuzzle(int number) { puzzleNumber = number; @@ -926,6 +1095,7 @@ break; case GAME_STATE_PLAYING: + setAutoNote(); if (!puzzle.isRestored()) autoSavePuzzle(); // save for correct 'date-created' timestamp timer.start(); @@ -1027,11 +1197,14 @@ private void updateKeypadHighlighing() { final int size = puzzle.getSize(); int[] counter = new int[size]; + SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this); + boolean autonote = settings.getBoolean(Settings.KEY_ENABLE_AUTONOTE, false); + puzzle.setAutoNote(autonote); for (int row = 0; row < size; row++) { for (int col = 0; col < size; col++) { ValueSet values = puzzle.getValues(row, col); - if (values.size() == 1) { + if (values.size() == 1 && !puzzle.isNote(row, col)) { int value = values.nextValue(0); counter[value]++; } @@ -1050,7 +1223,7 @@ if (Constants.LOG_V) Log.v(TAG, "auto-saving puzzle " + puzzleId); - db.saveGame(puzzleId, puzzle, timer); + db.saveGame(puzzleId, puzzle, timer, 0); } private void deleteAutoSavedPuzzle() { @@ -1068,7 +1241,7 @@ if (Constants.LOG_V) Log.v(TAG, "restoring auto-save game " + puzzleId); - return db.loadGame(puzzleId, puzzle, timer); + return db.loadGame(puzzleId, puzzle, timer, 0); } private PuzzleId getCurrentPuzzleId() { @@ -1088,17 +1261,17 @@ } private Dialog createConfirmResetPuzzleDialog() { - return new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert).setTitle( - R.string.dialog_reset_puzzle).setMessage(R.string.message_reset_puzzle) + return new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert) + .setTitle(R.string.dialog_reset_puzzle).setMessage(R.string.message_reset_puzzle) .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { onResetPuzzle(true); } - }).setNegativeButton(R.string.alert_dialog_cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - } - }).create(); + }) + .setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int whichButton) { + } + }).create(); } private Dialog createConfirmResetAllPuzzlesDialog() { @@ -1107,14 +1280,14 @@ ? R.string.message_reset_all_puzzles_in_folder : R.string.message_reset_all_puzzles_in_variation; - return new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert).setTitle( - R.string.dialog_reset_all_puzzles).setMessage(messageId).setPositiveButton( - R.string.alert_dialog_ok, new DialogInterface.OnClickListener() { + return new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert) + .setTitle(R.string.dialog_reset_all_puzzles).setMessage(messageId) + .setPositiveButton(R.string.alert_dialog_ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { onResetAllPuzzles(true); } - }).setNegativeButton(R.string.alert_dialog_cancel, - new DialogInterface.OnClickListener() { + }) + .setNegativeButton(R.string.alert_dialog_cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } }).create(); Index: src/com/googlecode/andoku/AndokuPuzzleView.java =================================================================== --- src/com/googlecode/andoku/AndokuPuzzleView.java (revision 417) +++ src/com/googlecode/andoku/AndokuPuzzleView.java (working copy) @@ -326,7 +326,8 @@ final ValueSet values = puzzle.getValues(row, col); if (values.contains(highlightedDigit)) { - drawHighlightedcell(canvas, values.size(), x, y); +// drawHighlightedcell(canvas, values.size(), x, y); + drawHighlightedcell(canvas, 1, x, y); } } } @@ -483,13 +484,15 @@ canvas.drawText(dv, cellWidth / 2f, textOffset, theme.getCluePaint(preview)); } } - else if (values.size() == 1) { + else if (values.size() == 1 && !puzzle.isNote(row, col)) { String dv = String.valueOf(theme.getSymbol(values.nextValue(0))); Paint paint = puzzle.isClue(row, col) ? theme.getCluePaint(preview) : theme .getValuePaint(); canvas.drawText(dv, cellWidth / 2f, textOffset, paint); } else { + if (values.size() > 0) + puzzle.setNoteState(row, col, 1); multiValuesPainter.paintValues(canvas, values); } } Index: src/com/googlecode/andoku/BackupUtil.java =================================================================== --- src/com/googlecode/andoku/BackupUtil.java (revision 416) +++ src/com/googlecode/andoku/BackupUtil.java (working copy) @@ -45,7 +45,7 @@ class BackupUtil extends Activity { private static final String TAG = BackupUtil.class.getName(); - private static final String SD_CARD_BACKUP_DIR = "Andoku"; + private static final String SD_CARD_BACKUP_DIR = "Andokus"; private static final String DATABASE_BACKUP_FILE = "database.bak"; private static final String DATABASE_BACKUP_FILE_SIGNATURE = "database.bak.sig"; private static final String DATABASE_UPDATE_FILE = "database.update"; @@ -72,9 +72,11 @@ // If this line does not compile it is because you have to specify a secret app key in the // resources first! Create res/values/secret.xml and add a random string named secret_key. + // Please also adjust the value of SD_CARD_BACKUP_DIR so that the backup files of your mod // and the backup files of the original Andoku do not conflict. - String secretKey = context.getString(R.string.secret_key); +///HH String secretKey = context.getString(R.string.secret_key); + String secretKey = "ajsjsjsjsj"; File backupFile = new File(andokuDir, DATABASE_BACKUP_FILE); File backupFileSignature = new File(andokuDir, DATABASE_BACKUP_FILE_SIGNATURE); Index: src/com/googlecode/andoku/db/AndokuDatabase.java =================================================================== --- src/com/googlecode/andoku/db/AndokuDatabase.java (revision 416) +++ src/com/googlecode/andoku/db/AndokuDatabase.java (working copy) @@ -421,7 +421,9 @@ } } - public void saveGame(PuzzleId puzzleId, AndokuPuzzle puzzle, TickTimer timer) { + // added temp which is only used with load and save game + // temp saved games have COL_SOLVED = 2 !! + public void saveGame(PuzzleId puzzleId, AndokuPuzzle puzzle, TickTimer timer, Integer Temp) { if (Constants.LOG_V) Log.v(TAG, "saveGame(" + puzzleId + ")"); @@ -433,6 +435,10 @@ try { String[] columns = { COL_ID }; String selection = COL_SOURCE + "=? AND " + COL_NUMBER + "=?"; + if (Temp != 0) + selection = selection + " AND " + COL_SOLVED + "=2"; + else + selection = selection + " AND " + COL_SOLVED + "!=2"; String[] selectionArgs = { puzzleId.puzzleSourceId, String.valueOf(puzzleId.number) }; Cursor cursor = db.query(TABLE_GAMES, columns, selection, selectionArgs, null, null, null); @@ -446,7 +452,10 @@ ContentValues values = new ContentValues(); values.put(COL_PUZZLE, puzzle.saveToMemento()); values.put(COL_TIMER, timer.getTime()); - values.put(COL_SOLVED, puzzle.isSolved()); + if (Temp != 0) + values.put(COL_SOLVED, 2); // temp saved game = 2 + else + values.put(COL_SOLVED, puzzle.isSolved()); // 0 or 1 values.put(COL_MODIFIED_DATE, now); if (rowId == -1) { @@ -472,7 +481,7 @@ } } - public boolean loadGame(PuzzleId puzzleId, AndokuPuzzle puzzle, TickTimer timer) { + public boolean loadGame(PuzzleId puzzleId, AndokuPuzzle puzzle, TickTimer timer, Integer Temp) { if (Constants.LOG_V) Log.v(TAG, "loadGame(" + puzzleId + ")"); @@ -480,6 +489,10 @@ String[] columns = { COL_PUZZLE, COL_TIMER }; String selection = COL_SOURCE + "=? AND " + COL_NUMBER + "=?"; + if (Temp != 0) + selection = selection + " AND " + COL_SOLVED + "=2"; + else + selection = selection + " AND " + COL_SOLVED + "!=2"; // 0 or 1 String[] selectionArgs = { puzzleId.puzzleSourceId, String.valueOf(puzzleId.number) }; Cursor cursor = db.query(TABLE_GAMES, columns, selection, selectionArgs, null, null, null); try { @@ -503,6 +516,29 @@ } } + // check function so Load Game option can be surpressed if not needed + public boolean TestGame(String SourceId, Integer number, Integer Temp) { + SQLiteDatabase db = openHelper.getReadableDatabase(); + + String[] columns = { COL_PUZZLE, COL_TIMER }; + String selection = COL_SOURCE + "=? AND " + COL_NUMBER + "=?"; + if (Temp != 0) + selection = selection + " AND " + COL_SOLVED + "=2"; + else + selection = selection + " AND " + COL_SOLVED + "!=2"; + String[] selectionArgs = { SourceId, String.valueOf(number) }; + Cursor cursor = db.query(TABLE_GAMES, columns, selection, selectionArgs, null, null, null); + try { + if (!cursor.moveToFirst()) { + return false; + } + return true; + } + finally { + cursor.close(); + } + } + public void delete(PuzzleId puzzleId) { if (Constants.LOG_V) Log.v(TAG, "delete(" + puzzleId + ")"); @@ -520,9 +556,11 @@ SQLiteDatabase db = openHelper.getWritableDatabase(); - String whereClause = COL_SOURCE + "=?"; - String[] whereArgs = { sourceId }; - db.delete(TABLE_GAMES, whereClause, whereArgs); +// for now, delete everything +// String whereClause = COL_SOURCE + "=?"; +// String[] whereArgs = { sourceId }; +// db.delete(TABLE_GAMES, whereClause, whereArgs); + db.delete(TABLE_GAMES, null, null); } public Cursor findAllGames() { @@ -533,7 +571,9 @@ String[] columns = { COL_ID, COL_SOURCE, COL_NUMBER, COL_TYPE, COL_TIMER, COL_CREATED_DATE, COL_MODIFIED_DATE }; - return db.query(TABLE_GAMES, columns, null, null, null, null, null); + // added: don't report any temp saved games back + String selection = COL_SOLVED + "!=2"; + return db.query(TABLE_GAMES, columns, selection, null, null, null, null); } public boolean hasGamesInProgress() { @@ -566,7 +606,8 @@ SQLiteDatabase db = openHelper.getReadableDatabase(); String[] columns = { COL_NUMBER, COL_SOLVED }; - String selection = COL_SOURCE + "=?"; + // added COL_SOLVED !=2 : don't report any temp saved games back + String selection = COL_SOURCE + "=? AND " + COL_SOLVED + "!=2"; String[] selectionArgs = new String[] { puzzleSourceId }; String orderBy = COL_NUMBER; return db.query(TABLE_GAMES, columns, selection, selectionArgs, null, null, orderBy); Index: src/com/googlecode/andoku/im/AutomaticInputMethod.java =================================================================== --- src/com/googlecode/andoku/im/AutomaticInputMethod.java (revision 416) +++ src/com/googlecode/andoku/im/AutomaticInputMethod.java (working copy) @@ -93,6 +93,16 @@ } } + public void toggleNote() { + if (activeInputMethod != null) + activeInputMethod.toggleNote(); + else { + ifUndecidedUseValuesThenCells(); + activeInputMethod.toggleNote(); + setUndecided(); + } + } + public void onClear() { if (activeInputMethod != null) activeInputMethod.onClear(); Index: src/com/googlecode/andoku/im/CellThenValuesInputMethod.java =================================================================== --- src/com/googlecode/andoku/im/CellThenValuesInputMethod.java (revision 416) +++ src/com/googlecode/andoku/im/CellThenValuesInputMethod.java (working copy) @@ -98,6 +98,17 @@ target.highlightDigit(digit); } + public void toggleNote() { + Position mark = target.getMarkedPosition(); + if (mark == null || target.isClue(mark)) + return; + int curstate = target.toggleNote(); + ValueSet values = target.getCellValues(mark); + target.setCellNote(mark, curstate); + target.setCellValues(mark, values); + checkButtons(mark); + } + public void onClear() { Position mark = target.getMarkedPosition(); if (mark == null || target.isClue(mark)) @@ -108,7 +119,8 @@ target.checkButton(digit, false); target.setCellValues(mark, new ValueSet()); - + if (target.toggleNote() == 1) + toggleNote(); target.highlightDigit(null); } @@ -171,6 +183,7 @@ } } else { + target.checkNoteButton(position); ValueSet values = target.getCellValues(position); for (int v = 0; v < size; v++) { target.checkButton(v, values.contains(v)); Index: src/com/googlecode/andoku/im/InputMethod.java =================================================================== --- src/com/googlecode/andoku/im/InputMethod.java (revision 416) +++ src/com/googlecode/andoku/im/InputMethod.java (working copy) @@ -32,6 +32,7 @@ void onMoveMark(int dy, int dx); void onKeypad(int digit); + void toggleNote(); void onClear(); void onInvert(); void onSweep(); Index: src/com/googlecode/andoku/im/InputMethodTarget.java =================================================================== --- src/com/googlecode/andoku/im/InputMethodTarget.java (revision 416) +++ src/com/googlecode/andoku/im/InputMethodTarget.java (working copy) @@ -33,9 +33,12 @@ ValueSet getCellValues(Position position); void setCellValues(Position position, ValueSet values); + void setCellNote(Position cell, Integer offon); int getNumberOfDigitButtons(); void checkButton(int digit, boolean checked); + void checkNoteButton(Position cell); + int toggleNote(); void highlightDigit(Integer digit); } Index: src/com/googlecode/andoku/im/ValuesThenCellInputMethod.java =================================================================== --- src/com/googlecode/andoku/im/ValuesThenCellInputMethod.java (revision 416) +++ src/com/googlecode/andoku/im/ValuesThenCellInputMethod.java (working copy) @@ -74,6 +74,10 @@ target.highlightDigit(digit); } + public void toggleNote() { + target.toggleNote(); + } + public void onClear() { setValues(0); Index: src/com/googlecode/andoku/InputMethodPolicy.java =================================================================== --- src/com/googlecode/andoku/InputMethodPolicy.java (revision 416) +++ src/com/googlecode/andoku/InputMethodPolicy.java (working copy) @@ -20,8 +20,8 @@ package com.googlecode.andoku; +import com.googlecode.andoku.im.AutomaticInputMethod; import com.googlecode.andoku.im.CellThenValuesInputMethod; -import com.googlecode.andoku.im.AutomaticInputMethod; import com.googlecode.andoku.im.InputMethod; import com.googlecode.andoku.im.InputMethodTarget; import com.googlecode.andoku.im.ValuesThenCellInputMethod; Index: src/com/googlecode/andoku/model/AndokuPuzzle.java =================================================================== --- src/com/googlecode/andoku/model/AndokuPuzzle.java (revision 416) +++ src/com/googlecode/andoku/model/AndokuPuzzle.java (working copy) @@ -56,6 +56,10 @@ private final int[][] extra; private ValueSet[][] values; + private int numValues; + private int[][] note; // array for keeping track of notestates for each cell + public int notestate; // current notestate of button since I don't know how to get it otherwise :) + private boolean AutoNote; // AutoNote enabled or not, same reason as above (my lack of knowledge) private final int[] areaColors; private final int numberOfAreaColors; @@ -87,7 +91,12 @@ this.puzzleType = determinePuzzleType(puzzle); this.difficulty = difficulty; this.extra = obtainExtra(puzzle); + this.note = clearNote(puzzle); + this.notestate = 0; + this.AutoNote = false; this.values = obtainValues(puzzle); + this.numValues = countValues(this.values, this.note); + this.solved = checkSolved(); this.areaColors = new AreaColorGenerator().generate(puzzle); this.numberOfAreaColors = countNumberOfAreaColors(); this.regionErrors = new HashSet(); @@ -125,6 +134,7 @@ writeValues(out, values); writeRegionErrors(out, regionErrors); writeCellErrors(out, cellErrors); + writeNotes(out, note); } public boolean restoreFromMemento(byte[] b) { @@ -174,8 +184,9 @@ final ValueSet[][] values = readValues(in); final HashSet regionErrors = readRegionErrors(in); final HashSet cellErrors = readCellErrors(in); + final int[][] note = readNotes(in); - return restoreFrom(values, regionErrors, cellErrors); + return restoreFrom(values, regionErrors, cellErrors, note); } private boolean restoreFromSerializable(byte[] b) { @@ -189,7 +200,7 @@ } PuzzleMemento memento = (PuzzleMemento) object; - return restoreFrom(memento.values, memento.regionErrors, memento.cellErrors); + return restoreFrom(memento.values, memento.regionErrors, memento.cellErrors, memento.note); } private Object deserialize(byte[] blob) { @@ -213,13 +224,16 @@ } private boolean restoreFrom(final ValueSet[][] values, final HashSet regionErrors, - final HashSet cellErrors) { + final HashSet cellErrors, final int[][] note) { if (values.length != this.values.length) { Log.e(TAG, "Memento values length incorrect"); return false; } this.values = values; + this.note = note; + this.numValues = countValues(this.values, this.note); + this.solved = checkSolved(); this.regionErrors = regionErrors; this.cellErrors = cellErrors; @@ -308,6 +322,49 @@ return problem.getValue(row, col) != Puzzle.UNDEFINED; } + // set autonot state called from adokuactivity OnCreate and onOptions + public void setAutoNote(boolean state) { + this.AutoNote = state; + } + + private int noOccurrance(int area, int v) { + int noOccur = 0; + for (int r = 0; r < size; r++) { + for (int c = 0; c < size; c++) { + if (problem.getAreaCode(r, c) == area && values[r][c].contains(v)) + noOccur++; + } + } + return noOccur; + } + + // check the current area for same digits + // force them to notes unless it is a clue + private void checkAutoNote(int row, int col) { + int a = problem.getAreaCode(row, col); + for (int r = 0; r < size; r++) { + for (int c = 0; c < size; c++) { + // only interested in single real values + if (problem.getAreaCode(r, c) == a && note[r][c] == 0 && values[r][c].size() == 1 + && !isClue(r, c)) { + if (noOccurrance(a, values[r][c].nextValue(0)) > 1) + setNoteState(r, c, 1); + } + } + } + } + + // set current values as the problem, used for OnSaveGame + public void setFixed() { + for (int row = 0; row < size; row++) { + for (int col = 0; col < size; col++) { + if (values[row][col].size() == 1 && note[row][col] == 0) { + problem.force(row, col, values[row][col].nextValue(0)); + } + } + } + } + public boolean isExtraRegion(int row, int col) { return extra[row][col] != -1; } @@ -316,6 +373,11 @@ return extra[row][col]; } + // determine if cell is a notecell + public boolean isNote(int row, int col) { + return note[row][col] != 0; + } + public int getAreaCode(int row, int col) { return problem.getAreaCode(row, col); } @@ -332,21 +394,65 @@ return new ValueSet(values[row][col]); } + public void setNoteState(int row, int col, int state) { + if (note[row][col] != state) { // only when state is changing + note[row][col] = state; + // check if numValues have changed + if (state != 0 && values[row][col].size() == 1) { + numValues--; + } + else if (state == 0 && values[row][col].size() == 1) { + numValues++; + } + } + } + + public void setAll(String line) { + int idx = 0; + numValues = 0; + for (int row = 0; row < size; row++) { + for (int col = 0; col < size; col++) { + char clueChar = line.charAt(idx++); + values[row][col].clear(); + problem.clear(row, col); + if (clueChar >= '1' && clueChar <= '9') { + values[row][col].clear(); + values[row][col].add(clueChar - '1'); + numValues++; + } + note[row][col] = 0; + } + } + } + public boolean setValues(int row, int col, ValueSet valueSet) { - if (values[row][col].equals(valueSet)) + if (values[row][col].equals(valueSet)) { return false; - + } + // simpler way counting numValues, shorter code + boolean wasEmpty = values[row][col].isEmpty(); values[row][col].setFromInt(valueSet.toInt()); - invalidateSolved(); + if (note[row][col] == 0 && values[row][col].size() > 1) { // so multiple values, force it to a note + setNoteState(row, col, 1); + } + if (wasEmpty && values[row][col].size() == 1) // added single value + setNoteState(row, col, notestate); // set it with current notestate + + // if enabled set all same numbers to notes + if (AutoNote) + checkAutoNote(row, col); + + invalidateSolved(); // force recalculation + solved = checkSolved(); + Position p = new Position(row, col); if (removeError(p)) return true; return false; } - private boolean checkSolved() { if (getMissingValuesCount() != 0) return false; @@ -387,25 +493,24 @@ for (Position p : region.positions) { ValueSet values = this.values[p.row][p.col]; - if (values.size() == 1) { + if (values.size() == 1 && note[p.row][p.col] == 0) { int value = values.nextValue(0); if (positionOf[value] != null) { addErrorLink(positionOf[value], p); continue; } - positionOf[value] = p; } } } // compare values to actual solution (if we have a solution) - if (checkAgainstSolution && solution != null) { for (int row = 0; row < size; row++) { for (int col = 0; col < size; col++) { ValueSet values = this.values[row][col]; - if (!values.isEmpty() && !values.contains(solution.getValue(row, col))) { + if (!values.isEmpty() && note[row][col] == 0 + && !values.contains(solution.getValue(row, col))) { cellErrors.add(new Position(row, col)); } } @@ -438,7 +543,7 @@ for (int row = 0; row < size; row++) for (int col = 0; col < size; col++) - if (values[row][col].size() == 1) + if (!isNote(row, col) && values[row][col].size() == 1) positions.add(new Position(row, col)); return positions; @@ -474,12 +579,13 @@ return eliminateValues(positions); } - private void setAllValuesOnEmptyPositions() { for (int row = 0; row < size; row++) for (int col = 0; col < size; col++) - if (values[row][col].isEmpty()) + if (values[row][col].isEmpty() || note[row][col] != 0) { setValues(row, col, ValueSet.all(size)); + note[row][col] = 1; + } } private int eliminateValues(Set positions) { @@ -624,19 +730,36 @@ return values; } + private static int[][] clearNote(Puzzle puzzle) { + final int size = puzzle.getSize(); + + int[][] note = new int[size][size]; + for (int row = 0; row < size; row++) { + for (int col = 0; col < size; col++) { + note[row][col] = 0; + } + } + return note; + } + private int countValuesSet() { final int size = values.length; int count = 0; for (int row = 0; row < size; row++) { for (int col = 0; col < size; col++) { - if (values[row][col].size() == 1) + if (values[row][col].size() == 1 && note[row][col] == 0) count++; } } return count; } + private int countValues(ValueSet[][] values, int[][] note) { + return countValuesSet(); + } + + /** * Only maintained for backward compatibility. Andoku 1.0.0 - 1.2.1 used this class to save the * state of a puzzle. Andoku 1.2.2 and later directly write to a byte array instead. @@ -647,6 +770,7 @@ public ValueSet[][] values; public HashSet regionErrors; public HashSet cellErrors; + public int[][] note; @SuppressWarnings("unused") public PuzzleMemento() { @@ -711,6 +835,25 @@ return values; } + private static void writeNotes(DataOutput out, int[][] notes) throws IOException { + final int size = notes.length; + out.writeInt(size); + + for (int row = 0; row < size; row++) + for (int col = 0; col < size; col++) + out.writeChar(notes[row][col]); + } + private static int[][] readNotes(DataInput in) throws IOException { + final int size = in.readInt(); + int[][] notes = new int[size][size]; + + for (int row = 0; row < size; row++) { + for (int col = 0; col < size; col++) { + notes[row][col] = in.readChar(); + } + } + return notes; + } private static void writeRegionErrors(DataOutput out, HashSet errors) throws IOException { final int numErrors = errors.size(); Index: src/com/googlecode/andoku/model/Puzzle.java =================================================================== --- src/com/googlecode/andoku/model/Puzzle.java (revision 416) +++ src/com/googlecode/andoku/model/Puzzle.java (working copy) @@ -116,6 +116,7 @@ valuesCount++; } + public void force(int row, int col, int value) { if (values[row][col] != UNDEFINED) clear(row, col); Index: src/com/googlecode/andoku/Settings.java =================================================================== --- src/com/googlecode/andoku/Settings.java (revision 416) +++ src/com/googlecode/andoku/Settings.java (working copy) @@ -30,6 +30,8 @@ public static final String KEY_INPUT_METHOD = "input_method"; public static final String KEY_CHECK_AGAINST_SOLUTION = "check_against_solution"; public static final String KEY_ENABLE_ELIMINATE_VALUES = "enable_eliminate_values"; + public static final String KEY_ENABLE_AUTONOTE = "enable_autonote"; + public static final String KEY_PUZZLEURL = "puzzle_url"; private Settings() { }