From 0fa6344f279048b056207efc1d1e7b8e568ee263 Mon Sep 17 00:00:00 2001 From: VanitasVitae Date: Tue, 15 Sep 2015 02:06:47 +0200 Subject: [PATCH] Added Dialog for plugging Plugboard/rewirable Reflectors --- CHANGELOG.txt | 11 +- app/build.gradle | 6 +- app/src/main/AndroidManifest.xml | 1 - .../enigmandroid/MainActivity.java | 69 ++++- .../enigma/EnigmaStateBundle.java | 12 +- .../enigmandroid/enigma/Enigma_D.java | 4 +- .../enigmandroid/enigma/Enigma_I.java | 8 +- .../enigmandroid/enigma/Enigma_K.java | 2 +- .../enigmandroid/enigma/Enigma_M4.java | 6 +- .../enigmandroid/enigma/Enigma_T.java | 140 +++++++++ .../enigmandroid/enigma/Plugboard.java | 163 +---------- .../enigmandroid/enigma/rotors/Reflector.java | 127 ++------ .../enigmandroid/enigma/rotors/Rotor.java | 172 ++++++++++- .../enigmandroid/layout/LayoutContainer.java | 53 ++-- .../layout/LayoutContainer_D.java | 22 +- .../layout/LayoutContainer_I.java | 26 +- .../layout/LayoutContainer_K.java | 6 - .../layout/LayoutContainer_M3.java | 21 +- .../layout/LayoutContainer_M4.java | 30 +- .../layout/LayoutContainer_T.java | 145 ++++++++++ .../layout/PluggableDialogBuilder.java | 255 ++++++++++++++++ .../layout/RingSettingsDialogBuilder.java | 4 +- app/src/main/res/drawable/button_grey.xml | 39 +++ .../{button.xml => button_orange.xml} | 0 .../main/res/layout-land/activity_main_d.xml | 26 +- .../res/layout-land/activity_main_i_m3.xml | 59 ++-- ...ivity_main_k.xml => activity_main_k_t.xml} | 2 +- .../main/res/layout-land/activity_main_m4.xml | 56 ++-- app/src/main/res/layout-land/dialog_plugs.xml | 227 +++++++++++++++ app/src/main/res/layout/activity_main_d.xml | 28 +- .../main/res/layout/activity_main_i_m3.xml | 21 +- ...ivity_main_k.xml => activity_main_k_t.xml} | 2 +- app/src/main/res/layout/activity_main_m4.xml | 21 +- app/src/main/res/layout/dialog_plugs.xml | 271 ++++++++++++++++++ .../main/res/layout/dialog_ringsettings_4.xml | 2 + app/src/main/res/values-de/strings.xml | 7 +- app/src/main/res/values/strings.xml | 7 +- .../res/values/strings_activity_settings.xml | 1 + 38 files changed, 1563 insertions(+), 489 deletions(-) create mode 100644 app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_T.java create mode 100644 app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_T.java create mode 100644 app/src/main/java/de/vanitasvitae/enigmandroid/layout/PluggableDialogBuilder.java create mode 100755 app/src/main/res/drawable/button_grey.xml rename app/src/main/res/drawable/{button.xml => button_orange.xml} (100%) rename app/src/main/res/layout-land/{activity_main_k.xml => activity_main_k_t.xml} (98%) create mode 100755 app/src/main/res/layout-land/dialog_plugs.xml rename app/src/main/res/layout/{activity_main_k.xml => activity_main_k_t.xml} (99%) create mode 100755 app/src/main/res/layout/dialog_plugs.xml diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 98f46f5..df02809 100755 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,13 +1,14 @@ CHANGELOG ENIGMANDROID v0.1.7-not-yet-released *Added Enigma K +*Added Enigma T +*Created Plugboard-/pluggable Reflector-Setting-Dialog *TODO: Add Enigma Z (Probably wont happen due to lack of information :/) -*TODO: Add Enigma T *TODO: Add Enigma G *TODO: Add Enigma R -*TODO: Rewrite Rotor-/Reflector creation +*TODO: Rework Rotor-/Reflector creation *TODO: Add multi-Enigma (select any rotor/reflector etc. Probably wont happen too soon) -*TODO: Rewrite InputPreparer using decorator pattern to allow user customization +*TODO: Rework InputPreparer using decorator pattern to allow user customization * v0.1.6-10.09.2015< @@ -15,7 +16,7 @@ v0.1.6-10.09.2015< *Updated CHANGELOG (oops) *Added Enigma D *Added rotor names to ringSettingsDialog -*Rewrote major parts of the app once again :) +*Reworked major parts of the app once again :) *Added option to break messages up into blocks v0.1.5-27.08.2015< @@ -28,7 +29,7 @@ v0.1.5-27.08.2015< v0.1.4-15.08.2015< -*Rewrite of the core implementation to follow some principals of Software Engineering +*Reworked the core implementation to follow some principals of Software Engineering *Fixed some layout issues *Fixed anomaly for step by step inputs *Added send/receive text functionality diff --git a/app/build.gradle b/app/build.gradle index dafc414..eeaa2af 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,10 +6,10 @@ android { defaultConfig { applicationId "de.vanitasvitae.enigmandroid" - minSdkVersion 15 + minSdkVersion 16 targetSdkVersion 23 - versionCode 12 - versionName "0.1.6-10.09.2015-beta" + versionCode 13 + versionName "0.1.7-not-yet-released-beta" } buildTypes { release { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e24a93d..568284b 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,7 +9,6 @@ android:theme="@style/AppTheme" > diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/MainActivity.java b/app/src/main/java/de/vanitasvitae/enigmandroid/MainActivity.java index 904f84b..0c31def 100755 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/MainActivity.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/MainActivity.java @@ -9,11 +9,14 @@ import android.content.res.Configuration; import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; +import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Toast; +import java.util.ArrayList; + import de.vanitasvitae.enigmandroid.enigma.inputPreparer.InputPreparer; import de.vanitasvitae.enigmandroid.layout.LayoutContainer; @@ -52,6 +55,7 @@ public class MainActivity extends Activity public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + Log.d("Activity","OnCreate!"); SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); this.prefMachineType = sharedPreferences.getString("prefMachineType", getResources(). getStringArray(R.array.pref_list_machine_type)[0]); @@ -77,9 +81,69 @@ public class MainActivity extends Activity } } + /** + * Unfortunately we have to overwrite this, because on orientation changes the LayoutContainer + * will reset and we would lose information about plugboard, reflector-wiring and ring settings. + * These info are we saving here. + * TODO: Find more elegant solution + * @param outState state + */ + @Override + protected void onSaveInstanceState (Bundle outState) + { + ArrayList plugboard = new ArrayList<>(); + if(layoutContainer.getState().getConfigurationPlugboard() != null) { + for (int i : layoutContainer.getState().getConfigurationPlugboard()) plugboard.add(i); + } + outState.putIntegerArrayList("plugboard",plugboard); + + ArrayList reflector = new ArrayList<>(); + if(layoutContainer.getState().getConfigurationReflector() != null) { + for (int i : layoutContainer.getState().getConfigurationReflector()) reflector.add(i); + } + outState.putIntegerArrayList("reflector", reflector); + + outState.putInt("ring1", layoutContainer.getState().getRingSettingRotor1()); + outState.putInt("ring2", layoutContainer.getState().getRingSettingRotor2()); + outState.putInt("ring3", layoutContainer.getState().getRingSettingRotor3()); + outState.putInt("ring4", layoutContainer.getState().getRingSettingRotor4()); + outState.putInt("ringR", layoutContainer.getState().getRingSettingReflector()); + + super.onSaveInstanceState(outState); + } + + /** + * Here we get back values previously saved int onSaveInstanceState + * @param savedInstanceState state + */ + @Override + protected void onRestoreInstanceState (Bundle savedInstanceState) + { + ArrayList plugboard = savedInstanceState.getIntegerArrayList("plugboard"); + if(plugboard != null && plugboard.size() != 0) { + int[] p = new int[plugboard.size()]; + for (int i = 0; i < plugboard.size(); i++) p[i] = plugboard.get(i); + layoutContainer.getState().setConfigurationPlugboard(p); + } + + ArrayList reflector = savedInstanceState.getIntegerArrayList("reflector"); + if(reflector != null && reflector.size() != 0) { + int[] r = new int[reflector.size()]; + for (int i = 0; i < reflector.size(); i++) r[i] = reflector.get(i); + layoutContainer.getState().setConfigurationReflector(r); + } + + layoutContainer.getState().setRingSettingRotor1(savedInstanceState.getInt("ring1")); + layoutContainer.getState().setRingSettingRotor2(savedInstanceState.getInt("ring2")); + layoutContainer.getState().setRingSettingRotor3(savedInstanceState.getInt("ring3")); + layoutContainer.getState().setRingSettingRotor4(savedInstanceState.getInt("ring4")); + layoutContainer.getState().setRingSettingReflector(savedInstanceState.getInt("ringR")); + } + @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); + this.updateContentView(); } private void updateContentView() @@ -99,7 +163,10 @@ public class MainActivity extends Activity this.setContentView(R.layout.activity_main_d); break; case "K": - this.setContentView(R.layout.activity_main_k); + this.setContentView(R.layout.activity_main_k_t); + break; + case "T": + this.setContentView(R.layout.activity_main_k_t); break; default: this.setContentView(R.layout.activity_main_i_m3); diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/EnigmaStateBundle.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/EnigmaStateBundle.java index a433491..1cf007b 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/EnigmaStateBundle.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/EnigmaStateBundle.java @@ -55,9 +55,9 @@ public class EnigmaStateBundle{ private int rotationReflector; private int ringSettingReflector; - private String configurationPlugboard; + private int[] configurationPlugboard; - private String configurationReflector; + private int[] configurationReflector; public int getTypeRotor1() { return typeRotor1; @@ -267,19 +267,19 @@ public class EnigmaStateBundle{ this.typeEntryWheel = typeEntryWheel; } - public String getConfigurationPlugboard() { + public int[] getConfigurationPlugboard() { return configurationPlugboard; } - public void setConfigurationPlugboard(String configurationPlugboard) { + public void setConfigurationPlugboard(int[] configurationPlugboard) { this.configurationPlugboard = configurationPlugboard; } - public String getConfigurationReflector() { + public int[] getConfigurationReflector() { return configurationReflector; } - public void setConfigurationReflector(String configurationReflector) { + public void setConfigurationReflector(int[] configurationReflector) { this.configurationReflector = configurationReflector; } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_D.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_D.java index b73961c..d781715 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_D.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_D.java @@ -76,7 +76,6 @@ public class Enigma_D extends Enigma { x = rotor1.normalize(x - rotor2.getRotation() + rotor2.getRingSetting() + rotor3.getRotation() - rotor3.getRingSetting()); x = rotor3.encryptForward(x); x = rotor1.normalize(x - rotor3.getRotation() + rotor3.getRingSetting() + reflector.getRotation() - reflector.getRingSetting()); - //TODO: CHECK //backward direction x = reflector.encrypt(x); x = rotor1.normalize(x + rotor3.getRotation() - rotor3.getRingSetting() - reflector.getRotation() + reflector.getRingSetting()); @@ -97,7 +96,8 @@ public class Enigma_D extends Enigma { this.rotor1 = Rotor.createRotor(state.getTypeRotor1(), state.getRotationRotor1(), state.getRingSettingRotor1()); this.rotor2 = Rotor.createRotor(state.getTypeRotor2(), state.getRotationRotor2(), state.getRingSettingRotor2()); this.rotor3 = Rotor.createRotor(state.getTypeRotor3(), state.getRotationRotor3(), state.getRingSettingRotor3()); - this.reflector = new Reflector.ReflectorEnigmaDKD(Plugboard.parseConfigurationString(state.getConfigurationReflector())); + this.reflector = new Reflector.ReflectorEnigmaDKD(); + this.reflector.setConfiguration(state.getConfigurationReflector()); this.reflector.setRotation(state.getRotationReflector()); this.reflector.setRingSetting(state.getRingSettingReflector()); } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_I.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_I.java index 86b1b85..2dc1d34 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_I.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_I.java @@ -1,7 +1,5 @@ package de.vanitasvitae.enigmandroid.enigma; -import android.util.Log; - import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector; import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor; @@ -80,7 +78,6 @@ public class Enigma_I extends Enigma x = rotor1.normalize(x - rotor2.getRotation() + rotor2.getRingSetting() + rotor3.getRotation() - rotor3.getRingSetting()); x = rotor3.encryptForward(x); x = rotor1.normalize(x - rotor3.getRotation() + rotor3.getRingSetting()); - //TODO: CHECK //backward direction x = reflector.encrypt(x); x = rotor1.normalize(x + rotor3.getRotation() - rotor3.getRingSetting()); @@ -97,8 +94,7 @@ public class Enigma_I extends Enigma @Override public void setState(EnigmaStateBundle state) { - plugboard.setConfiguration(Plugboard.parseConfigurationString( - state.getConfigurationPlugboard())); + plugboard.setConfiguration(state.getConfigurationPlugboard()); rotor1 = Rotor.createRotor(state.getTypeRotor1(), state.getRotationRotor1(), state.getRingSettingRotor1()); rotor2 = Rotor.createRotor(state.getTypeRotor2(), state.getRotationRotor2(), state.getRingSettingRotor2()); rotor3 = Rotor.createRotor(state.getTypeRotor3(), state.getRotationRotor3(), state.getRingSettingRotor3()); @@ -110,7 +106,7 @@ public class Enigma_I extends Enigma { EnigmaStateBundle state = new EnigmaStateBundle(); - state.setConfigurationPlugboard(plugboard.getConfigurationString()); + state.setConfigurationPlugboard(plugboard.getConfiguration()); state.setTypeRotor1(rotor1.getNumber()); state.setTypeRotor2(rotor2.getNumber()); diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_K.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_K.java index 3d480db..214d699 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_K.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_K.java @@ -120,6 +120,6 @@ public class Enigma_K extends Enigma state.setRotationReflector(reflector.getRotation()); state.setRingSettingReflector(reflector.getRingSetting()); - return state; + return state; } } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_M4.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_M4.java index 66e29c3..6d03c0d 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_M4.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_M4.java @@ -1,7 +1,5 @@ package de.vanitasvitae.enigmandroid.enigma; -import android.util.Log; - import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector; import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor; @@ -125,7 +123,7 @@ public class Enigma_M4 extends Enigma rotor3 = Rotor.createRotor(state.getTypeRotor3(), state.getRotationRotor3(), state.getRingSettingRotor3()); rotor4 = Rotor.createRotor(state.getTypeRotor4(), state.getRotationRotor4(), state.getRingSettingRotor4()); reflector = Reflector.createReflector(state.getTypeReflector()); - plugboard.setConfiguration(Plugboard.parseConfigurationString(state.getConfigurationPlugboard())); + plugboard.setConfiguration(state.getConfigurationPlugboard()); } @@ -150,7 +148,7 @@ public class Enigma_M4 extends Enigma state.setTypeReflector(reflector.getNumber()); - state.setConfigurationPlugboard(plugboard.getConfigurationString()); + state.setConfigurationPlugboard(plugboard.getConfiguration()); return state; } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_T.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_T.java new file mode 100644 index 0000000..1c4ee54 --- /dev/null +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Enigma_T.java @@ -0,0 +1,140 @@ +package de.vanitasvitae.enigmandroid.enigma; + +import android.util.Log; + +import de.vanitasvitae.enigmandroid.enigma.rotors.Reflector; +import de.vanitasvitae.enigmandroid.enigma.rotors.Rotor; + +/** + * Implementation of the Enigma machine of type T Tirpitz + * Copyright (C) 2015 Paul Schaub + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * @author vanitasvitae + */ +public class Enigma_T extends Enigma +{ + protected Rotor entryWheel; + protected Rotor rotor1; + protected Rotor rotor2; + protected Rotor rotor3; + protected Reflector reflector; + + public Enigma_T() + { + super(); + machineType = "K"; + } + + @Override + public void initialize() { + this.entryWheel = Rotor.createRotor(17,0,0); + this.rotor1 = Rotor.createRotor(18, 0, 0); + this.rotor2 = Rotor.createRotor(19, 0, 0); + this.rotor3 = Rotor.createRotor(20, 0, 0); + this.reflector = Reflector.createReflector(8); + } + + @Override + public void nextState() + { + rotor1.rotate(); + if (rotor1.isAtTurnoverPosition() || (this.doAnomaly && prefAnomaly)) + { + rotor2.rotate(); + this.doAnomaly = rotor2.doubleTurnAnomaly(); + if (rotor2.isAtTurnoverPosition()) + { + rotor3.rotate(); + } + } + } + + @Override + public char encryptChar(char k) { + nextState(); + int x = ((int) k)-65; //Cast to int and remove Unicode Offset (A=65 in Unicode.) + //Encryption + //forward direction + String log = " in: " + (char) (x+65); + x = entryWheel.encryptForward(x); + log = log + " ew: " + (char) (x+65); + x = rotor1.normalize(x + rotor1.getRotation() - rotor1.getRingSetting()); + x = rotor1.encryptForward(x); + log = log + " r1: " + (char) (x+65); + x = rotor1.normalize(x - rotor1.getRotation() + rotor1.getRingSetting() + rotor2.getRotation() - rotor2.getRingSetting()); + x = rotor2.encryptForward(x); + log = log + " r2: " + (char) (x+65); + x = rotor1.normalize(x - rotor2.getRotation() + rotor2.getRingSetting() + rotor3.getRotation() - rotor3.getRingSetting()); + x = rotor3.encryptForward(x); + log = log + " r3: " + (char) (x+65); + x = rotor1.normalize(x - rotor3.getRotation() + rotor3.getRingSetting() + reflector.getRotation() - reflector.getRingSetting()); + //backward direction + x = reflector.encrypt(x); + log = log + " ref: " + (char) (x+65); + x = rotor1.normalize(x + rotor3.getRotation() - rotor3.getRingSetting() - reflector.getRotation() + reflector.getRingSetting()); + x = rotor3.encryptBackward(x); + log = log + " r3: " + (char) (x+65); + x = rotor1.normalize(x + rotor2.getRotation() - rotor2.getRingSetting() - rotor3.getRotation() + rotor3.getRingSetting()); + x = rotor2.encryptBackward(x); + log = log + " r2: " + (char) (x+65); + x = rotor1.normalize(x + rotor1.getRotation() - rotor1.getRingSetting() - rotor2.getRotation() + rotor2.getRingSetting()); + x = rotor1.encryptBackward(x); + log = log + " r1: " + (char) (x+65); + x = rotor1.normalize(x - rotor1.getRotation() + rotor1.getRingSetting()); + x = entryWheel.encryptBackward(x); + log = log + " ew/out: " + (char) (x+65); + Log.d("EnryptionLog",log); + return (char) (x + 65); //Add Offset again, cast back to char and return + } + + @Override + public void setState(EnigmaStateBundle state) { + this.entryWheel = Rotor.createRotor(state.getTypeEntryWheel(), 0, 0); + this.rotor1 = Rotor.createRotor(state.getTypeRotor1(), state.getRotationRotor1(), state.getRingSettingRotor1()); + this.rotor2 = Rotor.createRotor(state.getTypeRotor2(), state.getRotationRotor2(), state.getRingSettingRotor2()); + this.rotor3 = Rotor.createRotor(state.getTypeRotor3(), state.getRotationRotor3(), state.getRingSettingRotor3()); + this.reflector = Reflector.createReflector(state.getTypeReflector()); + this.reflector.setRotation(state.getRotationReflector()); + this.reflector.setRingSetting(state.getRingSettingReflector()); + } + + @Override + public EnigmaStateBundle getState() + { + EnigmaStateBundle state = new EnigmaStateBundle(); + + state.setTypeRotor1(rotor1.getNumber()); + state.setTypeRotor2(rotor2.getNumber()); + state.setTypeRotor3(rotor3.getNumber()); + + state.setRotationRotor1(rotor1.getRotation()); + state.setRotationRotor2(rotor2.getRotation()); + state.setRotationRotor3(rotor3.getRotation()); + + state.setRingSettingRotor1(rotor1.getRingSetting()); + state.setRingSettingRotor2(rotor2.getRingSetting()); + state.setRingSettingRotor3(rotor3.getRingSetting()); + + state.setTypeReflector(reflector.getNumber()); + state.setRotationReflector(reflector.getRotation()); + state.setRingSettingReflector(reflector.getRingSetting()); + state.setTypeEntryWheel(entryWheel.getNumber()); + + return state; + } + + +} diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Plugboard.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Plugboard.java index 4e4abf9..affdc50 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Plugboard.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/Plugboard.java @@ -1,15 +1,5 @@ package de.vanitasvitae.enigmandroid.enigma; -import android.app.Activity; -import android.widget.Toast; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; - -import de.vanitasvitae.enigmandroid.MainActivity; -import de.vanitasvitae.enigmandroid.R; - /** * Plugboard of the enigma * Copyright (C) 2015 Paul Schaub @@ -31,159 +21,27 @@ import de.vanitasvitae.enigmandroid.R; */ public class Plugboard { - Integer[] plugs; + public static final int[] empty = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25}; + private int[] plugs; public Plugboard() { - plugs = new Integer[26]; + plugs = empty; } - public Plugboard(int[][] configuration) + public Plugboard(int[] conf) { - setConfiguration(configuration); + this.plugs = conf; } - public Plugboard(String configuration) + public void setConfiguration(int[] conf) { - setConfiguration(parseConfigurationString(configuration)); + this.plugs = conf; } - /** - * Configure the plugboard according to the given array. - * - * @param configuration two dimensional array of plugs - */ - public boolean setConfiguration(int[][] configuration) + public int[] getConfiguration() { - if(configuration != null) { - boolean validConfiguration = true; - plugs = new Integer[26]; - for (int[] p : configuration) { - if (!setPlugs(p[0], p[1])) { - validConfiguration = false; - break; - } - } - if (!validConfiguration) - { - plugs = new Integer[26]; - return false; - } - return true; - } - else - { - plugs = new Integer[26]; - return false; - } - } - - /** - * Parse configuration from input string - * input must have the following form: "" or "XY" or "XY,VW" or "XY,...,AB" - * A character must not be inside the input multiple times. Exception is ',' - * This is not catched here! - * @param input String that codes the configuration - * @return two dimensional array of plugged symbols - */ - public static int[][] parseConfigurationString(String input) - { - Activity activity = MainActivity.ActivitySingleton.getInstance().getActivity(); - //If length != 0,2,5,8... ( ,XY, XY-VW, ...) - if(((input.length()+1)%3)!=0&&input.length()!=0) - { - Toast.makeText(activity.getApplicationContext(), R.string.error_parsing_plugs, - Toast.LENGTH_LONG).show(); - return null; - } - else { - input = input.toUpperCase(); - ArrayList plugList = new ArrayList<>(); - int[] plug = new int[2]; - for (int i = 0; i < input.length(); i++) { - int c = input.charAt(i) - 65; - if (c < 0 || c > 25) { - if (i % 3 != 2) { - Toast.makeText(activity.getApplicationContext(), R.string.error_parsing_plugs, - Toast.LENGTH_LONG).show(); - return null; - } - } else { - if (i % 3 == 0) { - plug = new int[2]; - plug[0] = c; - } - if (i % 3 == 1) { - plug[1] = c; - plugList.add(plug); - } - - } - } - int[][] parsedConfiguration = new int[plugList.size()][2]; - for(int i=0; i remaining = new HashSet<>(); - for(int i=0; i<26; i++) - { - remaining.add(i); - } - while(!remaining.isEmpty()) - { - Integer x = remaining.iterator().next(); - if(!x.equals(encrypt(x))) - { - out = out + (char) (x+65) + (char) (encrypt(x)+65) +","; - remaining.remove(encrypt(x)); - } - remaining.remove(x); - } - if(out.length() != 0) out = out.substring(0,out.length()-1); - return out; - } - - /** - * Set the given plugs (connect a and b) - * Return false, if something goes wrong (plugs already used somehow) - * @param a first plug - * @param b second plug - * @return success - */ - public boolean setPlugs(int a, int b) - { - Activity activity = MainActivity.ActivitySingleton.getInstance().getActivity(); - if(a==b) - { - Toast.makeText(activity.getApplication().getApplicationContext(), - activity.getResources().getText(R.string.error_unable_to_plug_a_b).toString() - +" "+(char)(a+65)+","+(char) (b+65),Toast.LENGTH_LONG).show(); - return false; - } - if((plugs[a] != null || plugs[b] != null)) - { - if (!plugs[a].equals(b) || !plugs[b].equals(a)) { - Toast.makeText(activity.getApplication().getApplicationContext(), - activity.getResources().getText(R.string.error_plug_already_in_use).toString() - + " " + (char) (a + 65) + "," + (char) (b + 65), Toast.LENGTH_SHORT).show(); - return false; - } - return true; - } - else - { - plugs[a] = b; - plugs[b] = a; - return true; - } + return this.plugs; } /** @@ -193,7 +51,6 @@ public class Plugboard */ public int encrypt(int input) { - if(plugs[input]==null) return input; - else return plugs[input]; + return plugs[(input+plugs.length)%plugs.length]; } } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/rotors/Reflector.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/rotors/Reflector.java index e735d82..638d2ce 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/rotors/Reflector.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/rotors/Reflector.java @@ -1,10 +1,5 @@ package de.vanitasvitae.enigmandroid.enigma.rotors; -import java.sql.Ref; -import java.util.ArrayList; - -import de.vanitasvitae.enigmandroid.enigma.Plugboard; - /** * Reflector of the enigma machine. * The reflector was used to reflect the scrambled signal at the end of the wiring back to @@ -30,7 +25,9 @@ public class Reflector { protected String type; protected int number; - protected Integer[] connections; + protected int[] connections; + protected int rotation; + protected int ringSetting; /** * This constructor is not accessible from outside this class file. @@ -39,7 +36,7 @@ public class Reflector * @param type type indicator of the reflector * @param connections wiring of the reflector as Integer array */ - protected Reflector(String type, int number, Integer[] connections) + protected Reflector(String type, int number, int[] connections) { this.type = type; this.number = number; @@ -48,22 +45,22 @@ public class Reflector public int getRotation() { - return 0; + return rotation; } public int getRingSetting() { - return 0; + return ringSetting; } public void setRotation(int rotation) { - //Nope, do it yourself by overriding + this.rotation = rotation; } public void setRingSetting(int ringSetting) { - //Nopedydope + this.ringSetting = ringSetting; } /** @@ -153,7 +150,7 @@ public class Reflector { public ReflectorA() { - super("A", 1, new Integer[]{4,9,12,25,0,11,24,23,21,1,22,5,2,17,16,20,14,13,19,18,15,8,10,7,6,3}); + super("A", 1, new int[]{4,9,12,25,0,11,24,23,21,1,22,5,2,17,16,20,14,13,19,18,15,8,10,7,6,3}); } } @@ -166,7 +163,7 @@ public class Reflector { public ReflectorB() { - super("B", 2, new Integer[]{24,17,20,7,16,18,11,3,15,23,13,6,14,10,12,8,4,1,5,25,2,22,21,9,0,19}); + super("B", 2, new int[]{24,17,20,7,16,18,11,3,15,23,13,6,14,10,12,8,4,1,5,25,2,22,21,9,0,19}); } } @@ -179,7 +176,7 @@ public class Reflector { public ReflectorC() { - super("C", 3, new Integer[]{5,21,15,9,8,0,14,24,4,3,17,25,23,22,6,2,19,10,20,16,18,1,13,12,7,11}); + super("C", 3, new int[]{5,21,15,9,8,0,14,24,4,3,17,25,23,22,6,2,19,10,20,16,18,1,13,12,7,11}); } } @@ -194,7 +191,7 @@ public class Reflector { public ReflectorThinB() { - super("ThinB", 4, new Integer[]{4,13,10,16,0,20,24,22,9,8,2,14,15,1,11,12,3,23,25,21,5,19,7,17,6,18}); + super("ThinB", 4, new int[]{4,13,10,16,0,20,24,22,9,8,2,14,15,1,11,12,3,23,25,21,5,19,7,17,6,18}); } } @@ -209,7 +206,7 @@ public class Reflector { public ReflectorThinC() { - super("ThinC", 5, new Integer[]{17,3,14,1,9,13,19,10,21,4,7,12,11,5,2,22,25,0,23,6,24,8,15,18,20,16}); + super("ThinC", 5, new int[]{17,3,14,1,9,13,19,10,21,4,7,12,11,5,2,22,25,0,23,6,24,8,15,18,20,16}); } } @@ -220,102 +217,20 @@ public class Reflector */ public static class ReflectorEnigmaDKD extends Reflector { - public static final String defaultWiring = "AI,BM,CE,DT,FG,HR,JY,KS,LQ,NZ,OX,PW,UV"; - private Plugboard connections; - private int ringSetting; - private int rotation; + public static final int[] defaultWiring = {8,12,4,19,2,6,5,17,0,24,18,16,1,25,23,22,11,7,10,3,21,20,15,14,9,13}; public ReflectorEnigmaDKD() { - super("Ref-D", 6, null); - connections = new Plugboard(); - reset(); + super("Ref-D", 6, defaultWiring); } - public ReflectorEnigmaDKD(int[][] conf) + public void setConfiguration(int[] conf) { - super("Ref-D", 6, null); - connections = new Plugboard(conf); + this.connections = conf; } - public void reset() + public int[] getConfiguration() { - connections.setConfiguration(Plugboard.parseConfigurationString(defaultWiring)); - } - - public boolean setWiring(String input) - { - if(input.replace(" ","").length() != 38) - return false; - return connections.setConfiguration(Plugboard.parseConfigurationString(input)); - } - - public String getConfiguration() - { - return connections.getConfigurationString(); - } - - @Override - public int getRingSetting() - { - return this.ringSetting; - } - - @Override - public int getRotation() - { - return this.rotation; - } - - @Override - public void setRingSetting(int ringSetting) - { - this.ringSetting = ringSetting; - } - - @Override - public void setRotation(int rotation) - { - this.rotation = rotation; - } - - @Override - public int encrypt(int input) - { - return this.connections.encrypt(input); - } - - public boolean isValidConfiguration() - { - return getConfiguration().length() == 38; - } - - public static ArrayList getDuplicatePlugs(String conf) - { - String s = conf.toUpperCase().replace(" ","").replace(",",""); - ArrayList duplicates = new ArrayList<>(); - for(int i=0; i<26; i++) - { - char c = (char) (i+65); - if(s.indexOf(c) == s.lastIndexOf(c)) duplicates.add(c); - } - if(duplicates.size() == 0) return null; - return duplicates; - } - - public static ArrayList getMissingPlugs(String conf) - { - String s = conf.toUpperCase().replace(" ","").replace(",",""); - ArrayList missing = new ArrayList(); - for(int i=0; i<26; i++) - { - missing.add((char) (i + 65)); - } - for(Character c : missing) - { - if(s.indexOf(c) != -1) missing.remove(c); - } - if(missing.size() == 0) return null; - return missing; + return this.connections; } } @@ -323,7 +238,7 @@ public class Reflector { public ReflectorEnigmaK() { - super("Ref-K", 7, new Integer[]{8,12,4,19,2,6,5,17,0,24,18,16,1,25,23,22,11,7,10,3,21,20,15,14,9,13}); + super("Ref-K", 7, new int[]{8,12,4,19,2,6,5,17,0,24,18,16,1,25,23,22,11,7,10,3,21,20,15,14,9,13}); } } /** @@ -334,7 +249,7 @@ public class Reflector { public ReflectorEnigmaT() { - super("Ref-T", 8, new Integer[]{6,4,10,15,1,19,0,20,12,14,2,13,8,11,9,3,23,25,24,5,7,22,21,16,18,17}); + super("Ref-T", 8, new int[]{6,4,10,15,1,19,0,20,12,14,2,13,8,11,9,3,23,25,24,5,7,22,21,16,18,17}); } } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/rotors/Rotor.java b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/rotors/Rotor.java index 6e58479..674685f 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/rotors/Rotor.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/enigma/rotors/Rotor.java @@ -1,5 +1,7 @@ package de.vanitasvitae.enigmandroid.enigma.rotors; +import android.util.Log; + /** * Rotor super class and inner concrete implementations * The rotors were the key feature of the enigma used to scramble up input signals into @@ -78,6 +80,7 @@ public class Rotor switch (type) { case 0: return new EntryWheelDK(); + case 1: return new RotorI(rotation, ringSetting); case 2: return new RotorII(rotation, ringSetting); case 3: return new RotorIII(rotation, ringSetting); @@ -86,15 +89,28 @@ public class Rotor case 6: return new RotorVI(rotation, ringSetting); case 7: return new RotorVII(rotation, ringSetting); case 8: return new RotorVIII(rotation, ringSetting); + case 9: return new RotorBeta(rotation, ringSetting); case 10: return new RotorGamma(rotation, ringSetting); + case 11: return new RotorDI(rotation, ringSetting); case 12: return new RotorDII(rotation, ringSetting); case 13: return new RotorDIII(rotation, ringSetting); + case 14: return new RotorKI(rotation, ringSetting); case 15: return new RotorKII(rotation, ringSetting); case 16: return new RotorKIII(rotation, ringSetting); + case 17: return new EntryWheelT(); + case 18: return new RotorTI(rotation, ringSetting); + case 19: return new RotorTII(rotation, ringSetting); + case 20: return new RotorTIII(rotation, ringSetting); + case 21: return new RotorTIV(rotation, ringSetting); + case 22: return new RotorTV(rotation, ringSetting); + case 23: return new RotorTVI(rotation, ringSetting); + case 24: return new RotorTVII(rotation, ringSetting); + case 25: return new RotorTVIII(rotation, ringSetting); + default: return new RotorI(rotation, ringSetting); } } @@ -107,6 +123,7 @@ public class Rotor */ public int encryptForward(int input) { + Log.d(this.getType(),"in "+(char)(input+65)+", out "+(char) (this.connections[input]+65)); return this.connections[normalize(input)]; } @@ -224,7 +241,7 @@ public class Rotor */ public int normalize(int input) { - return (input + this.getRotorSize()) % this.getRotorSize(); + return (input+this.getRotorSize())%this.getRotorSize(); } /** @@ -539,4 +556,157 @@ public class Rotor new Integer[]{14}, ringSetting, rotation); } } + + /** + * EntryWheel as used only in the Enigma Type T Tirpitz + * K Z R O U Q H Y A I G B L W V S T D X F P N M C J E + */ + private static class EntryWheelT extends Rotor + { + public EntryWheelT() + { + super("T-ETW", 17, + new Integer[]{8,11,23,17,25,19,10,6,9,24,0,12,22,21,3,20,5,2,15,16,4,14,13,18,7,1}, + new Integer[]{10,25,17,14,20,16,7,24,0,8,6,1,11,22,21,18,19,3,23,5,15,13,12,2,9,4}, + new Integer[]{}, 0, 0); + } + @Override + public void rotate() + { + //EntryWheel doesn't rotate + } + + @Override + public boolean doubleTurnAnomaly() + { + //\forall s \in States : nope + return false; + } + } + /** + * Rotor I as used in the Enigma Type T Tirpitz + * K P T Y U E L O C V G R F Q D A N J M B S W H Z X I + * Turnover X A F L R + */ + private static class RotorTI extends Rotor + { + public RotorTI(int rotation, int ringSetting) + { + super("T-I", 18, + new Integer[]{10,15,19,24,20,4,11,14,2,21,6,17,5,16,3,0,13,9,12,1,18,22,7,25,23,8}, + new Integer[]{15,19,8,14,5,12,10,22,25,17,0,6,18,16,7,1,13,11,20,2,4,9,21,24,3,23}, + new Integer[]{23,0,5,11,17}, ringSetting, rotation); + } + } + + /** + * Rotor II as used in the Enigma Type T Tirpitz + * U P H Z L W E Q M T D J X C A K S O I G V B Y F N R + * Turnover X A G M S + */ + private static class RotorTII extends Rotor + { + public RotorTII(int rotation, int ringSetting) + { + super("T-II", 19, + new Integer[]{20,15,7,25,11,22,4,16,12,19,3,9,23,2,0,10,18,14,8,6,21,1,24,5,13,17}, + new Integer[]{14,21,13,10,6,23,19,2,18,11,15,4,8,24,17,1,7,25,16,9,0,20,5,12,22,3}, + new Integer[]{23,0,6,12,18}, ringSetting, rotation); + } + } + + /** + * Rotor III as used in the Enigma Type T Tirpitz + * Q U D L Y R F E K O N V Z A X W H M G P J B S I C T + * Turnover X A F L R + */ + private static class RotorTIII extends Rotor + { + public RotorTIII(int rotation, int ringSetting) { + super("T-III", 20, + new Integer[]{16,20,3,11,24,17,5,4,10,14,13,21,25,0,23,22,7,12,6,15,9,1,18,8,2,19}, + new Integer[]{13,21,24,2,7,6,18,16,23,20,8,3,17,10,9,19,0,5,22,25,1,11,15,14,4,12}, + new Integer[]{23,0,5,11,17}, ringSetting, rotation); + } + } + + /** + * Rotor IV as used in the Enigma Type T Tirpitz + * C I W T B K X N R E S P F L Y D A G V H Q U O J Z M + * Turnover X A G M S + */ + private static class RotorTIV extends Rotor + { + public RotorTIV(int rotation, int ringSetting) + { + super("T-IV", 21, + new Integer[]{2,8,22,19,1,10,23,13,17,4,18,15,5,11,24,3,0,6,21,7,16,20,14,9,25,12}, + new Integer[]{16,4,0,15,9,12,17,19,1,23,5,13,25,7,22,11,20,8,10,3,21,18,2,6,14,24}, + new Integer[]{23,0,6,12,18}, ringSetting, rotation); + } + } + + /** + * Rotor V as used in the Enigma Type T Tirpitz + * U A X G I S N J B V E R D Y L F Z W T P C K O H M Q + * Turnover Z D G L S + */ + private static class RotorTV extends Rotor + { + public RotorTV(int rotation, int ringSetting) + { + super("T-V", 22, + new Integer[]{20,0,23,6,8,18,13,9,1,21,4,17,3,24,11,5,25,22,19,15,2,10,14,7,12,16}, + new Integer[]{1,8,20,12,10,15,3,23,4,7,21,14,24,6,22,19,25,11,5,18,0,9,17,2,13,16}, + new Integer[]{25,3,6,11,18}, ringSetting, rotation); + } + } + + /** + * Rotor VI as used in the Enigma Type T Tirpitz + * X F U Z G A L V H C N Y S E W Q T D M R B K P I O J + * Turnover Y F J N R + */ + private static class RotorTVI extends Rotor + { + public RotorTVI(int rotation, int ringSetting) + { + super("T-VI", 23, + new Integer[]{23,5,20,25,6,0,11,21,7,2,13,24,18,4,22,16,19,3,12,17,1,10,15,8,14,9}, + new Integer[]{5,20,9,17,13,1,4,8,23,25,21,6,18,10,24,22,15,19,12,16,2,7,14,0,11,3}, + new Integer[]{24,5,9,13,17}, ringSetting, rotation); + } + } + + /** + * Rotor VII as used in the Enigma Type T Tirpitz + * B J V F T X P L N A Y O Z I K W G D Q E R U C H S M + * Turnover Z D G L S + */ + private static class RotorTVII extends Rotor + { + public RotorTVII(int rotation, int ringSetting) + { + super("T-VII", 24, + new Integer[]{1,9,21,5,19,23,15,11,13,0,24,14,25,8,10,22,6,3,16,4,17,20,2,7,18,12}, + new Integer[]{9,0,22,17,19,3,16,23,13,1,14,7,25,8,11,6,18,20,24,4,21,2,15,5,10,12}, + new Integer[]{25,3,6,11,18}, ringSetting, rotation); + } + } + + /** + * Rotor VIII as used in the Enigma Type T Tirpitz + * Y M T P N Z H W K O D A J X E L U Q V G C B I S F R + * Turnover Y F J N R + */ + private static class RotorTVIII extends Rotor + { + public RotorTVIII(int rotation, int ringSetting) + { + super("T-VIII", 25, + new Integer[]{24,12,19,15,13,25,7,22,10,14,3,0,9,23,4,11,20,16,21,6,2,1,8,18,5,17}, + new Integer[]{11,21,20,10,14,24,19,6,22,12,8,15,1,4,9,3,17,25,23,2,16,18,7,13,0,5}, + new Integer[]{24,5,9,13,17}, ringSetting, rotation); + } + } } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer.java b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer.java index 8379d20..9e7bb36 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer.java @@ -48,8 +48,17 @@ public abstract class LayoutContainer protected abstract void setLayoutState(EnigmaStateBundle state); protected abstract void refreshState(); public abstract void showRingSettingsDialog(); - protected abstract boolean isValidConfiguration(); + public LayoutContainer(EnigmaStateBundle state) + { + main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity(); + this.inputView = (EditText) main.findViewById(R.id.input); + this.outputView = (EditText) main.findViewById(R.id.output); + input = EditTextAdapter.createEditTextAdapter(inputView, main.getPrefMessageFormatting()); + output = EditTextAdapter.createEditTextAdapter(outputView, main.getPrefMessageFormatting()); + initializeLayout(); + this.state = state; + } public LayoutContainer() { main = (MainActivity) MainActivity.ActivitySingleton.getInstance().getActivity(); @@ -62,17 +71,14 @@ public abstract class LayoutContainer public void doCrypto() { - //TODO: if(inputView.getText().length()!=0) { getEnigma().setState(getState()); String message = inputView.getText().toString(); message = inputPreparer.prepareString(message); input.setText(message); - if(isValidConfiguration()) { - output.setText(getEnigma().encryptString(message)); - setLayoutState(getEnigma().getState()); - } + output.setText(getEnigma().encryptString(message)); + setLayoutState(getEnigma().getState()); } } @@ -82,6 +88,11 @@ public abstract class LayoutContainer return state; } + public void setState(EnigmaStateBundle state) + { + this.state = state; + } + public EditTextAdapter getInput() { return this.input; @@ -94,15 +105,22 @@ public abstract class LayoutContainer public static LayoutContainer createLayoutContainer(String enigmaType) { - switch (enigmaType) - { - case "I": return new LayoutContainer_I(); - case "M3": return new LayoutContainer_M3(); - case "M4": return new LayoutContainer_M4(); - case "D": return new LayoutContainer_D(); - case "K": return new LayoutContainer_K(); - default: return new LayoutContainer_I(); - } + switch (enigmaType) { + case "I": + return new LayoutContainer_I(); + case "M3": + return new LayoutContainer_M3(); + case "M4": + return new LayoutContainer_M4(); + case "D": + return new LayoutContainer_D(); + case "K": + return new LayoutContainer_K(); + case "T": + return new LayoutContainer_T(); + default: + return new LayoutContainer_I(); + } } public void setInputPreparer(InputPreparer inputPreparer) @@ -119,10 +137,5 @@ public abstract class LayoutContainer output = EditTextAdapter.createEditTextAdapter(outputView, type); output.setText(out); } - - public InputPreparer getInputPreparer() - { - return this.inputPreparer; - } } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_D.java b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_D.java index fb2e795..6272270 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_D.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_D.java @@ -1,7 +1,8 @@ package de.vanitasvitae.enigmandroid.layout; +import android.view.View; import android.widget.ArrayAdapter; -import android.widget.EditText; +import android.widget.Button; import android.widget.Spinner; import de.vanitasvitae.enigmandroid.R; @@ -37,8 +38,6 @@ public class LayoutContainer_D extends LayoutContainer protected Spinner rotor3PositionView; protected Spinner reflectorPositionView; - protected EditText reflectorWiringView; - public LayoutContainer_D() { super(); @@ -53,7 +52,13 @@ public class LayoutContainer_D extends LayoutContainer this.rotor2PositionView = (Spinner) main.findViewById(R.id.rotor2position); this.rotor3PositionView = (Spinner) main.findViewById(R.id.rotor3position); this.reflectorPositionView = (Spinner) main.findViewById(R.id.reflector_position); - this.reflectorWiringView = (EditText) main.findViewById(R.id.reflector_wiring); + Button reflectorWiring = (Button) main.findViewById(R.id.button_reflector); + reflectorWiring.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + new PluggableDialogBuilder(state).showDialogReflector(); + } + }); Character[] rotorPositionArray = new Character[26]; for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /**Fill with A..Z*/} @@ -97,7 +102,6 @@ public class LayoutContainer_D extends LayoutContainer this.rotor2PositionView.setSelection(state.getRotationRotor2()); this.rotor3PositionView.setSelection(state.getRotationRotor3()); this.reflectorPositionView.setSelection(state.getRotationReflector()); - this.reflectorWiringView.setText(state.getConfigurationReflector()); } @Override @@ -107,7 +111,6 @@ public class LayoutContainer_D extends LayoutContainer state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition()); state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition()); state.setRotationReflector(reflectorPositionView.getSelectedItemPosition()); - state.setConfigurationReflector(reflectorWiringView.getText().toString()); } public Enigma_D getEnigma() @@ -121,11 +124,4 @@ public class LayoutContainer_D extends LayoutContainer new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef(). createRingSettingsDialog(state); } - - @Override - protected boolean isValidConfiguration() - { - //if(Reflector.ReflectorEnigmaD.) //TODO: - return true; - } } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_I.java b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_I.java index ec0f05d..80902f9 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_I.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_I.java @@ -1,7 +1,8 @@ package de.vanitasvitae.enigmandroid.layout; +import android.view.View; import android.widget.ArrayAdapter; -import android.widget.EditText; +import android.widget.Button; import android.widget.Spinner; import de.vanitasvitae.enigmandroid.R; @@ -40,8 +41,6 @@ public class LayoutContainer_I extends LayoutContainer protected Spinner rotor2PositionView; protected Spinner rotor3PositionView; - protected EditText plugboardView; - public LayoutContainer_I() { super(); @@ -59,7 +58,13 @@ public class LayoutContainer_I extends LayoutContainer this.rotor2PositionView = (Spinner) main.findViewById(R.id.rotor2position); this.rotor3PositionView = (Spinner) main.findViewById(R.id.rotor3position); this.reflectorView = (Spinner) main.findViewById(R.id.reflector); - this.plugboardView = (EditText) main.findViewById(R.id.plugboard); + Button setPlugboardButton = (Button) main.findViewById(R.id.button_plugboard); + setPlugboardButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + new PluggableDialogBuilder(state).showDialogPlugboard(); + } + }); Character[] rotorPositionArray = new Character[26]; for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /**Fill with A..Z*/} @@ -112,27 +117,25 @@ public class LayoutContainer_I extends LayoutContainer protected void setLayoutState(EnigmaStateBundle state) { this.state = state; - this.rotor1View.setSelection(state.getTypeRotor1()-1); + this.rotor1View.setSelection(state.getTypeRotor1() - 1); this.rotor2View.setSelection(state.getTypeRotor2() - 1); this.rotor3View.setSelection(state.getTypeRotor3() - 1); this.reflectorView.setSelection(state.getTypeReflector() - 1); this.rotor1PositionView.setSelection(state.getRotationRotor1()); this.rotor2PositionView.setSelection(state.getRotationRotor2()); this.rotor3PositionView.setSelection(state.getRotationRotor3()); - this.plugboardView.setText(state.getConfigurationPlugboard()); } @Override protected void refreshState() { - state.setTypeRotor1(rotor1View.getSelectedItemPosition()+1); + state.setTypeRotor1(rotor1View.getSelectedItemPosition() + 1); state.setTypeRotor2(rotor2View.getSelectedItemPosition() + 1); state.setTypeRotor3(rotor3View.getSelectedItemPosition() + 1); - state.setTypeReflector(reflectorView.getSelectedItemPosition()+1); + state.setTypeReflector(reflectorView.getSelectedItemPosition() + 1); state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition()); state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition()); state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition()); - state.setConfigurationPlugboard(plugboardView.getText().toString()); } public Enigma_I getEnigma() @@ -146,9 +149,4 @@ public class LayoutContainer_I extends LayoutContainer new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRot(). createRingSettingsDialog(state); } - - @Override - protected boolean isValidConfiguration() { - return true; //TODO: - } } \ No newline at end of file diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_K.java b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_K.java index 695cb30..b3fc225 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_K.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_K.java @@ -141,10 +141,4 @@ public class LayoutContainer_K extends LayoutContainer new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef(). createRingSettingsDialog(state); } - - @Override - protected boolean isValidConfiguration() - { - return true; - } } diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_M3.java b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_M3.java index 7d6bd91..999dfd8 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_M3.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_M3.java @@ -1,7 +1,8 @@ package de.vanitasvitae.enigmandroid.layout; +import android.view.View; import android.widget.ArrayAdapter; -import android.widget.EditText; +import android.widget.Button; import android.widget.Spinner; import de.vanitasvitae.enigmandroid.R; @@ -49,7 +50,13 @@ public class LayoutContainer_M3 extends LayoutContainer_I this.rotor2PositionView = (Spinner) main.findViewById(R.id.rotor2position); this.rotor3PositionView = (Spinner) main.findViewById(R.id.rotor3position); this.reflectorView = (Spinner) main.findViewById(R.id.reflector); - this.plugboardView = (EditText) main.findViewById(R.id.plugboard); + Button setPlugboardButton = (Button) main.findViewById(R.id.button_plugboard); + setPlugboardButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + new PluggableDialogBuilder(state).showDialogPlugboard(); + } + }); Character[] rotorPositionArray = new Character[26]; for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /**Fill with A..Z*/} @@ -109,20 +116,18 @@ public class LayoutContainer_M3 extends LayoutContainer_I this.rotor1PositionView.setSelection(state.getRotationRotor1()); this.rotor2PositionView.setSelection(state.getRotationRotor2()); this.rotor3PositionView.setSelection(state.getRotationRotor3()); - this.plugboardView.setText(state.getConfigurationPlugboard()); } @Override protected void refreshState() { - state.setTypeRotor1(rotor1View.getSelectedItemPosition()+1); - state.setTypeRotor2(rotor2View.getSelectedItemPosition()+1); - state.setTypeRotor3(rotor3View.getSelectedItemPosition()+1); - state.setTypeReflector(reflectorView.getSelectedItemPosition()+2); + state.setTypeRotor1(rotor1View.getSelectedItemPosition() + 1); + state.setTypeRotor2(rotor2View.getSelectedItemPosition() + 1); + state.setTypeRotor3(rotor3View.getSelectedItemPosition() + 1); + state.setTypeReflector(reflectorView.getSelectedItemPosition() + 2); state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition()); state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition()); state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition()); - state.setConfigurationPlugboard(plugboardView.getText().toString()); } @Override diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_M4.java b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_M4.java index 7e72f11..3c8ab1e 100644 --- a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_M4.java +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_M4.java @@ -1,7 +1,8 @@ package de.vanitasvitae.enigmandroid.layout; +import android.view.View; import android.widget.ArrayAdapter; -import android.widget.EditText; +import android.widget.Button; import android.widget.Spinner; import de.vanitasvitae.enigmandroid.R; @@ -42,8 +43,6 @@ public class LayoutContainer_M4 extends LayoutContainer private Spinner rotor3PositionView; private Spinner rotor4PositionView; - private EditText plugboardView; - public LayoutContainer_M4() { super(); @@ -69,7 +68,13 @@ public class LayoutContainer_M4 extends LayoutContainer this.rotor3PositionView = (Spinner) main.findViewById(R.id.rotor3position); this.rotor4PositionView = (Spinner) main.findViewById(R.id.thin_rotor_position); this.reflectorView = (Spinner) main.findViewById(R.id.reflector); - this.plugboardView = (EditText) main.findViewById(R.id.plugboard); + Button setPlugboardButton = (Button) main.findViewById(R.id.button_plugboard); + setPlugboardButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + new PluggableDialogBuilder(state).showDialogPlugboard(); + } + }); Character[] rotorPositionArray = new Character[26]; for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /**Fill with A..Z*/} @@ -145,21 +150,19 @@ public class LayoutContainer_M4 extends LayoutContainer this.rotor2PositionView.setSelection(state.getRotationRotor2()); this.rotor3PositionView.setSelection(state.getRotationRotor3()); this.rotor4PositionView.setSelection(state.getRotationRotor4()); - this.plugboardView.setText(state.getConfigurationPlugboard()); } @Override protected void refreshState() { - state.setTypeRotor1(rotor1View.getSelectedItemPosition()+1); - state.setTypeRotor2(rotor2View.getSelectedItemPosition()+1); - state.setTypeRotor3(rotor3View.getSelectedItemPosition()+1); - state.setTypeRotor4(rotor4View.getSelectedItemPosition()+9); - state.setTypeReflector(reflectorView.getSelectedItemPosition()+4); + state.setTypeRotor1(rotor1View.getSelectedItemPosition() + 1); + state.setTypeRotor2(rotor2View.getSelectedItemPosition() + 1); + state.setTypeRotor3(rotor3View.getSelectedItemPosition() + 1); + state.setTypeRotor4(rotor4View.getSelectedItemPosition() + 9); + state.setTypeReflector(reflectorView.getSelectedItemPosition() + 4); state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition()); state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition()); state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition()); state.setRotationRotor4(rotor4PositionView.getSelectedItemPosition()); - state.setConfigurationPlugboard(plugboardView.getText().toString()); } @Override @@ -168,9 +171,4 @@ public class LayoutContainer_M4 extends LayoutContainer new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRot(). createRingSettingsDialog(state); } - - @Override - protected boolean isValidConfiguration() { - return true; //TODO: - } } \ No newline at end of file diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_T.java b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_T.java new file mode 100644 index 0000000..7eb33f6 --- /dev/null +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/LayoutContainer_T.java @@ -0,0 +1,145 @@ +package de.vanitasvitae.enigmandroid.layout; + +import android.widget.ArrayAdapter; +import android.widget.Spinner; + +import de.vanitasvitae.enigmandroid.R; +import de.vanitasvitae.enigmandroid.enigma.Enigma; +import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle; +import de.vanitasvitae.enigmandroid.enigma.Enigma_T; + +/** + * LayoutContainer for the Enigma Model K + * This class contains the layout and controls the layout elements such as spinners and stuff + * Copyright (C) 2015 Paul Schaub + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * @author vanitasvitae + */ +public class LayoutContainer_T extends LayoutContainer +{ + private Enigma_T enigma; + + protected Spinner rotor1View; + protected Spinner rotor2View; + protected Spinner rotor3View; + + protected Spinner rotor1PositionView; + protected Spinner rotor2PositionView; + protected Spinner rotor3PositionView; + protected Spinner reflectorPositionView; + + public LayoutContainer_T() + { + super(); + main.setTitle("T - EnigmAndroid"); + this.resetLayout(); + } + + @Override + public Enigma getEnigma() { + return this.enigma; + } + + @Override + protected void initializeLayout() { + this.rotor1View = (Spinner) main.findViewById(R.id.rotor1); + this.rotor2View = (Spinner) main.findViewById(R.id.rotor2); + this.rotor3View = (Spinner) main.findViewById(R.id.rotor3); + this.rotor1PositionView = (Spinner) main.findViewById(R.id.rotor1position); + this.rotor2PositionView = (Spinner) main.findViewById(R.id.rotor2position); + this.rotor3PositionView = (Spinner) main.findViewById(R.id.rotor3position); + this.reflectorPositionView = (Spinner) main.findViewById(R.id.reflector_position); + + Character[] rotorPositionArray = new Character[26]; + for(int i=0; i<26; i++) {rotorPositionArray[i] = (char) (65+i); /**Fill with A..Z*/} + + ArrayAdapter rotor1Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_8, + android.R.layout.simple_spinner_item); + rotor1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + rotor1View.setAdapter(rotor1Adapter); + ArrayAdapter rotor2Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_8, + android.R.layout.simple_spinner_item); + rotor2Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + rotor2View.setAdapter(rotor2Adapter); + ArrayAdapter rotor3Adapter = ArrayAdapter.createFromResource(main, R.array.rotors_1_8, + android.R.layout.simple_spinner_item); + rotor3Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + rotor3View.setAdapter(rotor3Adapter); + + ArrayAdapter rotor1PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(), + android.R.layout.simple_spinner_item, rotorPositionArray); + rotor1PositionAdapter.setDropDownViewResource( + android.R.layout.simple_spinner_dropdown_item); + rotor1PositionView.setAdapter(rotor1PositionAdapter); + ArrayAdapter rotor2PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(), + android.R.layout.simple_spinner_item, rotorPositionArray); + rotor2PositionAdapter.setDropDownViewResource( + android.R.layout.simple_spinner_dropdown_item); + rotor2PositionView.setAdapter(rotor2PositionAdapter); + ArrayAdapter rotor3PositionAdapter = new ArrayAdapter<>(main.getApplicationContext(), + android.R.layout.simple_spinner_item, rotorPositionArray); + rotor3PositionAdapter.setDropDownViewResource( + android.R.layout.simple_spinner_dropdown_item); + rotor3PositionView.setAdapter(rotor3PositionAdapter); + + ArrayAdapter reflectorPositionAdapter = new ArrayAdapter<>(main.getApplicationContext(), + android.R.layout.simple_spinner_item, rotorPositionArray); + reflectorPositionAdapter.setDropDownViewResource( + android.R.layout.simple_spinner_dropdown_item); + reflectorPositionView.setAdapter(reflectorPositionAdapter); + } + + @Override + public void resetLayout() { + enigma = new Enigma_T(); + setLayoutState(enigma.getState()); + output.setText(""); + input.setText(""); + } + + @Override + protected void setLayoutState(EnigmaStateBundle state) + { + this.state = state; + this.rotor1View.setSelection(state.getTypeRotor1() - 18); + this.rotor2View.setSelection(state.getTypeRotor2() - 18); + this.rotor3View.setSelection(state.getTypeRotor3() - 18); + + this.rotor1PositionView.setSelection(state.getRotationRotor1()); + this.rotor2PositionView.setSelection(state.getRotationRotor2()); + this.rotor3PositionView.setSelection(state.getRotationRotor3()); + this.reflectorPositionView.setSelection(state.getRotationReflector()); + } + + @Override + protected void refreshState() + { + state.setTypeRotor1(rotor1View.getSelectedItemPosition() + 18); + state.setTypeRotor2(rotor2View.getSelectedItemPosition() + 18); + state.setTypeRotor3(rotor3View.getSelectedItemPosition() + 18); + state.setRotationRotor1(rotor1PositionView.getSelectedItemPosition()); + state.setRotationRotor2(rotor2PositionView.getSelectedItemPosition()); + state.setRotationRotor3(rotor3PositionView.getSelectedItemPosition()); + state.setRotationReflector(reflectorPositionView.getSelectedItemPosition()); + } + + @Override + public void showRingSettingsDialog() + { + new RingSettingsDialogBuilder.RingSettingsDialogBuilderRotRotRotRef(). + createRingSettingsDialog(state); + } +} diff --git a/app/src/main/java/de/vanitasvitae/enigmandroid/layout/PluggableDialogBuilder.java b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/PluggableDialogBuilder.java new file mode 100644 index 0000000..df5a561 --- /dev/null +++ b/app/src/main/java/de/vanitasvitae/enigmandroid/layout/PluggableDialogBuilder.java @@ -0,0 +1,255 @@ +package de.vanitasvitae.enigmandroid.layout; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.DialogInterface; +import android.graphics.drawable.Drawable; +import android.view.View; +import android.view.WindowManager; +import android.widget.Button; +import android.widget.Toast; + +import java.util.ArrayList; + +import de.vanitasvitae.enigmandroid.MainActivity; +import de.vanitasvitae.enigmandroid.R; +import de.vanitasvitae.enigmandroid.enigma.EnigmaStateBundle; + +/** + * Builder for the dialog that is used to get settings for the rings + * Copyright (C) 2015 Paul Schaub + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * @author vanitasvitae + */ +public class PluggableDialogBuilder +{ + protected ArrayList