Merge branch 'Sudoku-v3.0' of https://github.com/SecUSo/privacy-friendly-sudoku into Sudoku-v3.0

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
This commit is contained in:
ErikWaegerle 2020-08-22 16:52:09 +02:00
commit cb3e20966d
3 changed files with 81 additions and 27 deletions

View file

@ -34,6 +34,7 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.appcompat.app.AppCompatDelegate; import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.widget.Toolbar;
import org.secuso.privacyfriendlysudoku.controller.GameController; import org.secuso.privacyfriendlysudoku.controller.GameController;
import org.secuso.privacyfriendlysudoku.controller.Symbol; import org.secuso.privacyfriendlysudoku.controller.Symbol;
@ -42,6 +43,7 @@ import org.secuso.privacyfriendlysudoku.controller.qqwing.QQWing;
import org.secuso.privacyfriendlysudoku.game.GameDifficulty; import org.secuso.privacyfriendlysudoku.game.GameDifficulty;
import org.secuso.privacyfriendlysudoku.game.GameType; import org.secuso.privacyfriendlysudoku.game.GameType;
import org.secuso.privacyfriendlysudoku.ui.listener.IFinalizeDialogFragmentListener; import org.secuso.privacyfriendlysudoku.ui.listener.IFinalizeDialogFragmentListener;
import org.secuso.privacyfriendlysudoku.ui.listener.IImportDialogFragmentListener;
import org.secuso.privacyfriendlysudoku.ui.view.CreateSudokuSpecialButtonLayout; import org.secuso.privacyfriendlysudoku.ui.view.CreateSudokuSpecialButtonLayout;
import org.secuso.privacyfriendlysudoku.ui.view.R; import org.secuso.privacyfriendlysudoku.ui.view.R;
import org.secuso.privacyfriendlysudoku.ui.view.SudokuFieldLayout; import org.secuso.privacyfriendlysudoku.ui.view.SudokuFieldLayout;
@ -52,9 +54,10 @@ import org.secuso.privacyfriendlysudoku.ui.view.SudokuKeyboardLayout;
* IFinalizeDialogFragementListener. It is used to create custom sudokus, which are passed to the * IFinalizeDialogFragementListener. It is used to create custom sudokus, which are passed to the
* GameActivity afterwards. * GameActivity afterwards.
*/ */
public class CreateSudokuActivity extends BaseActivity implements IFinalizeDialogFragmentListener { public class CreateSudokuActivity extends BaseActivity implements IFinalizeDialogFragmentListener, IImportDialogFragmentListener {
GameController gameController; GameController gameController;
SharedPreferences sharedPref;
SudokuFieldLayout layout; SudokuFieldLayout layout;
SudokuKeyboardLayout keyboard; SudokuKeyboardLayout keyboard;
TextView viewName ; TextView viewName ;
@ -63,7 +66,7 @@ public class CreateSudokuActivity extends BaseActivity implements IFinalizeDialo
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
if(sharedPref.getBoolean("pref_keep_screen_on", true)) { if(sharedPref.getBoolean("pref_keep_screen_on", true)) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
@ -80,7 +83,19 @@ public class CreateSudokuActivity extends BaseActivity implements IFinalizeDialo
gameType, new int [boardSize], new int [boardSize], new boolean [boardSize][sectionSize]); gameType, new int [boardSize], new int [boardSize], new boolean [boardSize][sectionSize]);
gameController.loadLevel(container); gameController.loadLevel(container);
setUpLayout();
}
private void setUpLayout() {
setContentView(R.layout.activity_create_sudoku); setContentView(R.layout.activity_create_sudoku);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(getString(gameController.getGameType().getStringResID()));
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
layout = (SudokuFieldLayout)findViewById(R.id.sudokuLayout); layout = (SudokuFieldLayout)findViewById(R.id.sudokuLayout);
layout.setSettingsAndGame(sharedPref, gameController); layout.setSettingsAndGame(sharedPref, gameController);
@ -96,13 +111,16 @@ public class CreateSudokuActivity extends BaseActivity implements IFinalizeDialo
keyboard.setKeyBoard(gameController.getSize(), p.x,layout.getHeight()-p.y, orientation); keyboard.setKeyBoard(gameController.getSize(), p.x,layout.getHeight()-p.y, orientation);
specialButtonLayout = (CreateSudokuSpecialButtonLayout) findViewById(R.id.createSudokuLayout); specialButtonLayout = (CreateSudokuSpecialButtonLayout) findViewById(R.id.createSudokuLayout);
specialButtonLayout.setButtons(p.x, gameController, keyboard, getFragmentManager(), orientation, CreateSudokuActivity.this, this); specialButtonLayout.setButtons(p.x, gameController, keyboard, getFragmentManager(), orientation,
CreateSudokuActivity.this, this, this);
viewName = (TextView) findViewById(R.id.gameModeText);
viewName.setText(getString(gameController.getGameType().getStringResID()));
gameController.notifyHighlightChangedListeners(); gameController.notifyHighlightChangedListeners();
}
@Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
} }
@Override @Override
@ -186,6 +204,53 @@ public class CreateSudokuActivity extends BaseActivity implements IFinalizeDialo
} }
} }
public void onImportDialogPositiveClick(String input) {
String inputSudoku;
// a valid input needs to contain exactly one of these prefixes
String prefix1 = GameActivity.URL_SCHEME_WITHOUT_HOST + "://";
String prefix2 = GameActivity.URL_SCHEME_WITH_HOST + "://" + GameActivity.URL_HOST + "/";
/*
remove the present prefix, or, if the input contains neither of the prefixes, notify the user
that their input is not valid
*/
if (input.contains(prefix1)) {
inputSudoku = input.replace(prefix1, "");
} else if (input.contains(prefix2)) {
inputSudoku = input.replace(prefix2, "");
} else {
Toast.makeText(CreateSudokuActivity.this,
this.getString(R.string.menu_import_wrong_format_custom_sudoku) + " " + prefix1 + ", " + prefix2, Toast.LENGTH_LONG).show();
return;
}
boolean validSize = Math.sqrt(inputSudoku.length()) == gameController.getSize();
if (!validSize) {
Toast.makeText(CreateSudokuActivity.this, R.string.failed_to_verify_custom_sudoku_toast, Toast.LENGTH_LONG).show();
return;
}
//check whether or not the sudoku is valid and has a unique solution
boolean solvable = verify(gameController.getGameType(), inputSudoku);
// if the encoded sudoku is solvable, sent the code directly to the GameActivity; if not, notify the user
if (solvable) {
Toast.makeText(CreateSudokuActivity.this, R.string.finished_verifying_custom_sudoku_toast, Toast.LENGTH_LONG).show();
int boardSize = gameController.getGameType().getSize() * gameController.getGameType().getSize();
GameInfoContainer container = new GameInfoContainer(0, GameDifficulty.Unspecified,
gameController.getGameType(), new int [boardSize], new int [boardSize],
new boolean [boardSize][gameController.getGameType().getSize()]);
container.parseSetValues(inputSudoku);
gameController.loadLevel(container);
setUpLayout();
} else {
Toast.makeText(CreateSudokuActivity.this, R.string.failed_to_verify_custom_sudoku_toast, Toast.LENGTH_LONG).show();
}
}
/** /**
* Implements the onDialogNegativeClick() method of the IFinalizeDialogFragmentListener * Implements the onDialogNegativeClick() method of the IFinalizeDialogFragmentListener

View file

@ -43,8 +43,10 @@ import androidx.core.content.ContextCompat;
import org.secuso.privacyfriendlysudoku.controller.GameController; import org.secuso.privacyfriendlysudoku.controller.GameController;
import org.secuso.privacyfriendlysudoku.game.listener.IHighlightChangedListener; import org.secuso.privacyfriendlysudoku.game.listener.IHighlightChangedListener;
import org.secuso.privacyfriendlysudoku.ui.GameActivity; import org.secuso.privacyfriendlysudoku.ui.GameActivity;
import org.secuso.privacyfriendlysudoku.ui.MainActivity;
import org.secuso.privacyfriendlysudoku.ui.listener.IFinalizeDialogFragmentListener; import org.secuso.privacyfriendlysudoku.ui.listener.IFinalizeDialogFragmentListener;
import org.secuso.privacyfriendlysudoku.ui.listener.IHintDialogFragmentListener; import org.secuso.privacyfriendlysudoku.ui.listener.IHintDialogFragmentListener;
import org.secuso.privacyfriendlysudoku.ui.listener.IImportDialogFragmentListener;
import java.util.LinkedList; import java.util.LinkedList;
@ -54,6 +56,7 @@ import static org.secuso.privacyfriendlysudoku.ui.view.CreateSudokuButtonType.ge
public class CreateSudokuSpecialButtonLayout extends LinearLayout implements IHighlightChangedListener { public class CreateSudokuSpecialButtonLayout extends LinearLayout implements IHighlightChangedListener {
IFinalizeDialogFragmentListener finalizeDialogFragmentListener; IFinalizeDialogFragmentListener finalizeDialogFragmentListener;
IImportDialogFragmentListener importDialogFragmentListener;
CreateSudokuSpecialButton[] fixedButtons; CreateSudokuSpecialButton[] fixedButtons;
public int fixedButtonsCount = getSpecialButtons().size(); public int fixedButtonsCount = getSpecialButtons().size();
GameController gameController; GameController gameController;
@ -77,6 +80,8 @@ public class CreateSudokuSpecialButtonLayout extends LinearLayout implements IHi
gameController.deleteSelectedCellsValue(); gameController.deleteSelectedCellsValue();
break; break;
case Import: case Import:
MainActivity.ImportBoardDialog impDialog = new MainActivity.ImportBoardDialog();
impDialog.show(fragmentManager, "ImportDialogFragment");
break; break;
case Do: case Do:
gameController.ReDo(); gameController.ReDo();
@ -108,12 +113,14 @@ public class CreateSudokuSpecialButtonLayout extends LinearLayout implements IHi
} }
public void setButtons(int width, GameController gc, SudokuKeyboardLayout key, FragmentManager fm, public void setButtons(int width, GameController gc, SudokuKeyboardLayout key, FragmentManager fm,
int orientation, Context cxt, IFinalizeDialogFragmentListener finalizeListener) { int orientation, Context cxt, IFinalizeDialogFragmentListener finalizeListener,
IImportDialogFragmentListener importListener) {
fragmentManager = fm; fragmentManager = fm;
keyboard=key; keyboard=key;
gameController = gc; gameController = gc;
context = cxt; context = cxt;
finalizeDialogFragmentListener = finalizeListener; finalizeDialogFragmentListener = finalizeListener;
importDialogFragmentListener = importListener;
if(gameController != null) { if(gameController != null) {
gameController.registerHighlightChangedListener(this); gameController.registerHighlightChangedListener(this);
} }

View file

@ -24,25 +24,7 @@
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" android:background="?attr/colorPrimary"
android:clipChildren="false" android:clipChildren="false"
app:popupTheme="@style/AppTheme.PopupOverlay" > app:popupTheme="@style/AppTheme.PopupOverlay" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="14"
android:clipChildren="false"
android:orientation="horizontal"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:gravity="center_vertical">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/gametype_unspecified"
android:id="@+id/gameModeText"
android:layout_weight="7"/>
</LinearLayout>
</androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>