From fcfe09ca3306c07e537b5875cc92782481453678 Mon Sep 17 00:00:00 2001 From: Matt Brown Date: Tue, 22 Sep 2020 00:25:09 -0700 Subject: [PATCH] initial commit --- .gitignore | 89 +++++++++ .idea/codeStyles/Project.xml | 116 ++++++++++++ .idea/misc.xml | 14 ++ .idea/runConfigurations.xml | 12 ++ app/.gitignore | 1 + app/build.gradle | 32 ++++ app/proguard-rules.pro | 21 +++ .../everspinner/ExampleInstrumentedTest.java | 26 +++ app/src/main/AndroidManifest.xml | 21 +++ .../everspinner/MainActivity.java | 177 ++++++++++++++++++ .../drawable-v24/ic_launcher_foreground.xml | 30 +++ .../res/drawable/ic_launcher_background.xml | 170 +++++++++++++++++ app/src/main/res/layout/activity_main.xml | 122 ++++++++++++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3593 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 5339 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2636 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 3388 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4926 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 7472 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7909 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 11873 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 10652 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 16570 bytes app/src/main/res/values/colors.xml | 6 + app/src/main/res/values/strings.xml | 12 ++ app/src/main/res/values/styles.xml | 10 + .../everspinner/ExampleUnitTest.java | 17 ++ build.gradle | 24 +++ gradle.properties | 19 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54329 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 172 +++++++++++++++++ gradlew.bat | 84 +++++++++ settings.gradle | 2 + 36 files changed, 1193 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/runConfigurations.xml create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/com/everspysolutions/everspinner/ExampleInstrumentedTest.java create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/com/everspysolutions/everspinner/MainActivity.java create mode 100644 app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml create mode 100644 app/src/test/java/com/everspysolutions/everspinner/ExampleUnitTest.java create mode 100644 build.gradle create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..de6891a --- /dev/null +++ b/.gitignore @@ -0,0 +1,89 @@ +# Built application files +*.apk +*.aar +*.ap_ +*.aab + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ +# Uncomment the following line in case you need and you don't have the release build type files in your app +# release/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# IntelliJ +*.iml* +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/assetWizardSettings.xml +.idea/dictionaries +.idea/libraries +# Android Studio 3 in .gitignore file. +.idea/caches +.idea/modules.xml +# Comment next line if keeping position of elements in Navigation Editor is relevant for you +.idea/navEditor.xml +.idea/jarRepositories.xml + +# Keystore files +# Uncomment the following lines if you do not want to check your keystore files in. +#*.jks +#*.keystore + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild +.cxx/ + +# Google Services (e.g. APIs or Firebase) +# google-services.json + +# Freeline +freeline.py +freeline/ +freeline_project_description.json + +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md + +# Version control +vcs.xml + +# lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ +# lint/reports/ + +# Android Profiling +*.hprof diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..af0bbdd --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..591663e --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,32 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 29 + + defaultConfig { + applicationId "com.everspysolutions.everspinner" + minSdkVersion 21 + targetSdkVersion 29 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation fileTree(dir: "libs", include: ["*.jar"]) + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/src/androidTest/java/com/everspysolutions/everspinner/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/everspysolutions/everspinner/ExampleInstrumentedTest.java new file mode 100644 index 0000000..4df312f --- /dev/null +++ b/app/src/androidTest/java/com/everspysolutions/everspinner/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.everspysolutions.everspinner; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.everspysolutions.everspinner", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..41d1dfe --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/everspysolutions/everspinner/MainActivity.java b/app/src/main/java/com/everspysolutions/everspinner/MainActivity.java new file mode 100644 index 0000000..7027039 --- /dev/null +++ b/app/src/main/java/com/everspysolutions/everspinner/MainActivity.java @@ -0,0 +1,177 @@ +package com.everspysolutions.everspinner; + +import androidx.appcompat.app.AppCompatActivity; + +import android.content.Context; +import android.os.Bundle; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.view.View; +import android.widget.TextView; + +import org.w3c.dom.Text; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class MainActivity extends AppCompatActivity { + + TextView inputTextBox, outputTextBox; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + inputTextBox = (TextView) findViewById(R.id.txt_spinner_input); + outputTextBox = (TextView) findViewById(R.id.txt_spinner_output); + } + + public void onPasteClick(View view) { + this.inputTextBox.setText(((ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE)).getPrimaryClip().getItemAt(0).getText().toString()); + } + + public void onCopyClick(View view) { + ((ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText("Spun Text", this.outputTextBox.getText())); + } + + public void onSpinClick(View view) { + this.outputTextBox.setText(spinText(this.inputTextBox.getText().toString())); + } + + /* access modifiers changed from: package-private */ + public String spinText(String text) { + int selectionCount = errorCheckText(text); + if (selectionCount == -1) { + return "Error: An selection is closed '}' before it is opened '{'!"; + } + if (selectionCount == -2) { + return "Error: An selection is not closed with '}'!"; + } + return solveSelections(text); + } + + + /** + * Spins a properly formatted string of text + * @param text A string of text which is to be spun. Selections formatted similar to + * {A|B|C|{D|E}} + * @return Text with randomly chosen selections + */ + private String solveSelections(String text) { + StringBuilder sb = new StringBuilder(); + int cutStartPoint = 0; + int i = 0; + while (i < text.length()) { + if (text.charAt(i) == '{' && 0 == 0) { + sb.append(text.substring(cutStartPoint, i)); + int cutStartPoint2 = findClosingBracket(text, i); + sb.append(solveSelection(text.substring(i, cutStartPoint2 + 1))); + cutStartPoint = cutStartPoint2 + 1; + i = cutStartPoint; + } + i++; + } + sb.append(text.substring(cutStartPoint, text.length())); + return sb.toString(); + } + + /** + * Solves a single selection + * @param selection A selection formatted as {options seperated by '|'} + * @return The chosen option + */ + private String solveSelection(String selection) { + String selection2 = selection.substring(1, selection.length() - 1); + List options = new ArrayList<>(); + int lastPos = 0; + StringBuilder sb = new StringBuilder(); + int i = 0; + while (i < selection2.length()) { + char c = selection2.charAt(i); + if (c == '|') { + sb.append(selection2.substring(lastPos, i)); + options.add(sb.toString()); + sb = new StringBuilder(); + lastPos = i + 1; + } else if (c == '{') { + sb.append(selection2.substring(lastPos, i)); + int lastPos2 = findClosingBracket(selection2, i); + sb.append(solveSelection(selection2.substring(i, lastPos2 + 1))); + i = lastPos2; + lastPos = lastPos2 + 1; + } + i++; + } + sb.append(selection2.substring(lastPos, selection2.length())); + options.add(sb.toString()); + return chooseOption((String[]) options.toArray(new String[0])); + } + + /** + * Finds the closing curly bracket for a given selection. + * @param text String of text that contains a selection + * @param startPos Position of opening curly bracket in text + * @return position of closing curly bracket in text + */ + private int findClosingBracket(String text, int startPos) { + int endPos = startPos; + int counter = 1; + for (int i = startPos + 1; i < text.length(); i++) { + char c = text.charAt(i); + if (c == '{') { + counter++; + } + if (c == '}') { + counter--; + } + if (counter == 0) { + endPos = i; + } + } + return endPos; + } + + /** + * Randomly chooses an option in an array of strings + * @param options Array of possible choices + * @return Chosen option + */ + private String chooseOption(String[] options) { + Random rand = new Random(); + return options[rand.nextInt(options.length)]; + } + + /** + * Check a string of text for properly formatted selections + * @param text Arbitrary string of text + * @return -1 if there is an closing bracket unmatched with an open. -2 if there exists an + * unclosed selection. Otherwise number of selections is returned + */ + public int errorCheckText(String text) { + int openCount = 0; + int closeCount = 0; + + for (int i = 0; i < text.length(); i++) { + char c = text.charAt(i); + if (c == '{') { + openCount++; + } else if (c == '}') { + closeCount++; + openCount--; + } + // A closed bracket is unmatched with an open {}} + if (openCount < 0) { + closeCount = -1; + break; + } + } + // Unclosed open brackets exist {}{ + if (openCount > 0) { + closeCount = -2; + } + + return closeCount; + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..f482be4 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,122 @@ + + + + + + + +