diff --git a/app/build.gradle b/app/build.gradle
index 7f0773d..05fc98f 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -9,8 +9,8 @@ android {
applicationId "com.verNANDo57.rulebook_educational"
minSdkVersion 22
targetSdk 32
- versionCode 115
- versionName '1.1.5'
+ versionCode 116
+ versionName '1.1.6'
multiDexEnabled true
}
@@ -46,14 +46,13 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
- implementation 'androidx.appcompat:appcompat:1.4.1'
- implementation 'com.google.android.material:material:1.6.0'
+ implementation 'androidx.appcompat:appcompat:1.5.0'
+ implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.preference:preference-ktx:1.2.0'
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0'
- implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
- implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21'
- implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.21'
+ implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
}
repositories {
mavenCentral()
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 96e99da..aa27a16 100755
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -18,8 +18,19 @@
android:fullBackupContent="true"
android:supportsRtl="true"
android:requestLegacyExternalStorage="true"
- tools:targetApi="q"
- android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|navigation">
+ tools:targetApi="s"
+ android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|navigation"
+ android:dataExtractionRules="@xml/data_extraction_rules">
+
+
+
+
= 30) {
//Check if storage permission already granted
if (!Environment.isExternalStorageManager()) {
@@ -136,7 +136,7 @@ public void checkPermission() {
builder.setTitle(getString(R.string.app_warning));
builder.setMessage(getString(R.string.app_storageAccess_warning));
builder.setIcon(R.drawable.ic_warning);
- builder.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener(){
+ builder.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//GoToSettings Intent
@@ -154,7 +154,7 @@ public void onClick(DialogInterface dialog, int which) {
alert.show();
}
//Otherwise...
- //Check if android version is Android 10 or lower
+ // Check if android version is Android 10 or lower
} else if (Build.VERSION.SDK_INT >= 23) {
//Check if storage permission already granted
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
@@ -208,4 +208,4 @@ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permis
}
}
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/verNANDo57/rulebook_educational/app/CustomActivityResult.java b/app/src/main/java/com/verNANDo57/rulebook_educational/app/CustomActivityResult.java
new file mode 100644
index 0000000..64d91f0
--- /dev/null
+++ b/app/src/main/java/com/verNANDo57/rulebook_educational/app/CustomActivityResult.java
@@ -0,0 +1,96 @@
+/*
+ * Author: VerNANDo57
+ */
+
+package com.verNANDo57.rulebook_educational.app;
+
+import android.content.Intent;
+
+import androidx.activity.result.ActivityResult;
+import androidx.activity.result.ActivityResultCaller;
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.contract.ActivityResultContract;
+import androidx.activity.result.contract.ActivityResultContracts;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+public class CustomActivityResult {
+ /**
+ * Register activity result using a {@link ActivityResultContract} and an in-place activity result callback like
+ * the default approach. You can still customise callback using {@link #launch(Object, OnActivityResult)}.
+ */
+ @NonNull
+ public static CustomActivityResult registerForActivityResult(
+ @NonNull ActivityResultCaller caller,
+ @NonNull ActivityResultContract contract,
+ @Nullable OnActivityResult onActivityResult) {
+ return new CustomActivityResult<>(caller, contract, onActivityResult);
+ }
+
+ /**
+ * Same as {@link #registerForActivityResult(ActivityResultCaller, ActivityResultContract, OnActivityResult)} except
+ * the last argument is set to {@code null}.
+ */
+ @NonNull
+ public static CustomActivityResult registerForActivityResult(
+ @NonNull ActivityResultCaller caller,
+ @NonNull ActivityResultContract contract) {
+ return registerForActivityResult(caller, contract, null);
+ }
+
+ /**
+ * Specialised method for launching new activities.
+ */
+ @NonNull
+ public static CustomActivityResult registerActivityForResult(
+ @NonNull ActivityResultCaller caller) {
+ return registerForActivityResult(caller, new ActivityResultContracts.StartActivityForResult());
+ }
+
+ /**
+ * Callback interface
+ */
+ public interface OnActivityResult {
+ /**
+ * Called after receiving a result from the target activity
+ */
+ void onActivityResult(O result);
+ }
+
+ private final ActivityResultLauncher launcher;
+ @Nullable
+ private OnActivityResult onActivityResult;
+
+ private CustomActivityResult(@NonNull ActivityResultCaller caller,
+ @NonNull ActivityResultContract contract,
+ @Nullable OnActivityResult onActivityResult) {
+ this.onActivityResult = onActivityResult;
+ this.launcher = caller.registerForActivityResult(contract, this::callOnActivityResult);
+ }
+
+ public void setOnActivityResult(@Nullable OnActivityResult onActivityResult) {
+ this.onActivityResult = onActivityResult;
+ }
+
+ /**
+ * Launch activity, same as {@link ActivityResultLauncher#launch(Object)} except that it allows a callback
+ * executed after receiving a result from the target activity.
+ */
+ public void launch(Input input, @Nullable OnActivityResult onActivityResult) {
+ if (onActivityResult != null) {
+ this.onActivityResult = onActivityResult;
+ }
+ launcher.launch(input);
+ }
+
+ /**
+ * Same as {@link #launch(Object, OnActivityResult)} with last parameter set to {@code null}.
+ */
+ public void launch(Input input) {
+ launch(input, this.onActivityResult);
+ }
+
+ private void callOnActivityResult(Result result) {
+ if (onActivityResult != null) onActivityResult.onActivityResult(result);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/verNANDo57/rulebook_educational/bookmarks/AppBookmarkUtils.java b/app/src/main/java/com/verNANDo57/rulebook_educational/bookmarks/AppBookmarkUtils.java
index 791d36f..ff1f96f 100644
--- a/app/src/main/java/com/verNANDo57/rulebook_educational/bookmarks/AppBookmarkUtils.java
+++ b/app/src/main/java/com/verNANDo57/rulebook_educational/bookmarks/AppBookmarkUtils.java
@@ -217,4 +217,4 @@ public static void undoBookmarkDeletion(Context context) {
Log.e(LOG_TAG, context.getResources().getString(R.string.app_error_file_rename));
}
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/verNANDo57/rulebook_educational/preferences/AppSettingsFragment.java b/app/src/main/java/com/verNANDo57/rulebook_educational/preferences/AppSettingsFragment.java
index aef80eb..ef7cce9 100755
--- a/app/src/main/java/com/verNANDo57/rulebook_educational/preferences/AppSettingsFragment.java
+++ b/app/src/main/java/com/verNANDo57/rulebook_educational/preferences/AppSettingsFragment.java
@@ -7,38 +7,37 @@
import android.content.DialogInterface;
import android.os.Bundle;
+import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.appcompat.content.res.AppCompatResources;
+import androidx.core.content.ContextCompat;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
-import androidx.preference.SwitchPreferenceCompat;
import com.verNANDo57.rulebook_educational.extradata.R;
+import com.verNANDo57.rulebook_educational.rules.Constants;
+import com.verNANDo57.rulebook_educational.utils.AppUtils;
+
+import java.io.File;
public class AppSettingsFragment extends PreferenceFragmentCompat
{
- RulebookApplicationSharedPreferences preferences;
+ private RulebookApplicationSharedPreferences preferences;
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
preferences = new RulebookApplicationSharedPreferences(requireContext());
setPreferencesFromResource(R.xml.preferences, rootKey);
- //Interface
- androidx.preference.Preference darktheme_switch = findPreference(PreferenceKeys.DARK_THEME_PREF);
- assert darktheme_switch != null;
- darktheme_switch.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ // Interface
+ androidx.preference.Preference darktheme_switch_pref = findPreference(PreferenceKeys.DARK_THEME_PREF);
+ assert darktheme_switch_pref != null;
+ darktheme_switch_pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
- public boolean onPreferenceClick(Preference preference) {
+ public boolean onPreferenceClick(@NonNull Preference preference) {
// setup the alert builder
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
builder.setTitle(getString(R.string.app_darkTheme_switch_summary));
- // add a list
- String[] options = {
- getString(R.string.app_darkTheme_mode_no),
- getString(R.string.app_darkTheme_mode_yes),
- getString(R.string.app_darkTheme_mode_followSystem),
- getString(R.string.app_darkTheme_mode_battery)};
int checkedItem = 0; // Dark mode: NO
if (preferences.loadRulebookDarkModeBooleanState() == AppCompatDelegate.MODE_NIGHT_YES) {
@@ -50,7 +49,7 @@ public boolean onPreferenceClick(Preference preference) {
}
//Pass the array list in Alert dialog
- builder.setSingleChoiceItems(options, checkedItem, new DialogInterface.OnClickListener() {
+ builder.setSingleChoiceItems(getResources().getStringArray(R.array.darkmode_modes), checkedItem, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
@@ -86,25 +85,65 @@ public void onClick(DialogInterface dialogInterface, int i) {
builder.setIcon(AppCompatResources.getDrawable(requireContext(), R.drawable.app_themeengine_icon));
builder.create();
builder.show();
- return true;
+ return false;
}
});
- androidx.preference.SwitchPreferenceCompat statusbar_enable = (SwitchPreferenceCompat) findPreference(PreferenceKeys.STATUSBAR_PREF);
- assert statusbar_enable != null;
- statusbar_enable.setChecked(preferences.loadRulebookStatusBarBooleanState());
- statusbar_enable.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ androidx.preference.SwitchPreferenceCompat statusbar_enable_pref = findPreference(PreferenceKeys.STATUSBAR_PREF);
+ assert statusbar_enable_pref != null;
+ statusbar_enable_pref.setChecked(preferences.loadRulebookStatusBarBooleanState());
+ statusbar_enable_pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
- public boolean onPreferenceChange(Preference preference, Object newValue) {
- if (newValue.toString().equals("true")){
- preferences.setRulebookStatusBarBooleanState(true);
- } else {
- preferences.setRulebookStatusBarBooleanState(false);
- }
- return true;
+ public boolean onPreferenceChange(@NonNull Preference preference, Object newValue) {
+ preferences.setRulebookStatusBarBooleanState(newValue.toString().equals("true"));
+ return false;
}
});
- androidx.preference.Preference noticePreference = findPreference(PreferenceKeys.NOTICE_PREF);
+ // Functionality
+ androidx.preference.SwitchPreferenceCompat use_sdcard_pref = findPreference(PreferenceKeys.USE_SDCARD_PREF);
+ assert use_sdcard_pref != null;
+ if (!AppUtils.checkIfSDCardExists()) {
+ use_sdcard_pref.setEnabled(false);
+ preferences.setRulebookUseSDCardBooleanState(false);
+ }
+ use_sdcard_pref.setChecked(preferences.loadRulebookUseSDCardBooleanState());
+ use_sdcard_pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(@NonNull Preference preference, Object newValue) {
+ preferences.setRulebookUseSDCardBooleanState(newValue.toString().equals("true"));
+ return false;
+ }
+ });
+
+ androidx.preference.Preference delete_all_data = findPreference(PreferenceKeys.DELETE_ALL_DATA);
+ assert delete_all_data != null;
+ delete_all_data.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(@NonNull Preference preference) {
+ androidx.appcompat.app.AlertDialog.Builder builder = new androidx.appcompat.app.AlertDialog.Builder(requireContext());
+ builder.setTitle(getString(R.string.app_warning));
+ builder.setIcon(ContextCompat.getDrawable(requireContext(), R.drawable.app_delete_forever));
+ builder.setMessage(getString(R.string.are_you_sure));
+ builder.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ AppUtils.removeFolderRecursive(new File(AppUtils.getStorageAbsolutePath(requireContext(), false) + Constants.RULEBOOK_APP_DIRECTORY));
+ if (AppUtils.checkIfSDCardExists()) {
+ AppUtils.removeFolderRecursive(new File(AppUtils.getStorageAbsolutePath(requireContext(), true) + Constants.RULEBOOK_APP_DIRECTORY));
+ }
+ }
+ });
+ builder.setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ });
+ androidx.appcompat.app.AlertDialog alert = builder.create();
+ alert.show();
+ return false;
+ }
+ });
}
}
diff --git a/app/src/main/java/com/verNANDo57/rulebook_educational/preferences/PreferenceKeys.java b/app/src/main/java/com/verNANDo57/rulebook_educational/preferences/PreferenceKeys.java
index 71303a0..c5fc642 100644
--- a/app/src/main/java/com/verNANDo57/rulebook_educational/preferences/PreferenceKeys.java
+++ b/app/src/main/java/com/verNANDo57/rulebook_educational/preferences/PreferenceKeys.java
@@ -5,7 +5,9 @@
package com.verNANDo57.rulebook_educational.preferences;
public interface PreferenceKeys {
- String DARK_THEME_PREF = "darktheme_switch";
- String STATUSBAR_PREF = "statusbar_enable";
- String NOTICE_PREF = "app_reboot_from_prefs";
+ String DARK_THEME_PREF = "darktheme_switch_pref";
+ String STATUSBAR_PREF = "statusbar_enable_pref";
+ String NOTICE_PREF = "notice_pref";
+ String USE_SDCARD_PREF = "use_sdcard_pref";
+ String DELETE_ALL_DATA = "delete_all_data";
}
diff --git a/app/src/main/java/com/verNANDo57/rulebook_educational/preferences/RulebookApplicationSharedPreferences.java b/app/src/main/java/com/verNANDo57/rulebook_educational/preferences/RulebookApplicationSharedPreferences.java
index 78d5350..5275927 100644
--- a/app/src/main/java/com/verNANDo57/rulebook_educational/preferences/RulebookApplicationSharedPreferences.java
+++ b/app/src/main/java/com/verNANDo57/rulebook_educational/preferences/RulebookApplicationSharedPreferences.java
@@ -10,12 +10,13 @@
import androidx.appcompat.app.AppCompatDelegate;
public class RulebookApplicationSharedPreferences {
- SharedPreferences RulebookSharedPreferences;
+ private final SharedPreferences RulebookSharedPreferences;
- public static String PREFS_FILE_NAME = "rulebookprefs";
- public static String DARK_MODE = "dark_mode";
- public static String STATUS_BAR_STATE_BOOLEAN = "status_bar";
- public static String RULEBOOK_LAUNCHED_FOR_THE_FIRST_TIME_STATE_BOOLEAN = "launched_for_the_first_time";
+ private static final String PREFS_FILE_NAME = "rulebookprefs";
+ private static final String DARK_MODE = "dark_mode";
+ private static final String STATUS_BAR_STATE_BOOLEAN = "status_bar";
+ private static final String RULEBOOK_LAUNCHED_FOR_THE_FIRST_TIME_STATE_BOOLEAN = "launched_for_the_first_time";
+ private static final String USE_SDCARD = "use_sdcard";
public RulebookApplicationSharedPreferences(Context context) {
RulebookSharedPreferences = context.getSharedPreferences(PREFS_FILE_NAME, Context.MODE_PRIVATE);
@@ -37,6 +38,11 @@ public void setRulebookIsLaunchedForTheFirstTimeBooleanState(Boolean state){
editor.putBoolean(RULEBOOK_LAUNCHED_FOR_THE_FIRST_TIME_STATE_BOOLEAN, state);
editor.apply();
}
+ public void setRulebookUseSDCardBooleanState(Boolean state){
+ SharedPreferences.Editor editor= RulebookSharedPreferences.edit();
+ editor.putBoolean(USE_SDCARD, state);
+ editor.apply();
+ }
//These methods will load
public int loadRulebookDarkModeBooleanState (){
@@ -48,4 +54,7 @@ public Boolean loadRulebookStatusBarBooleanState (){
public Boolean loadRulebookIsLaunchedForTheFirstTimeBooleanState (){
return RulebookSharedPreferences.getBoolean(RULEBOOK_LAUNCHED_FOR_THE_FIRST_TIME_STATE_BOOLEAN, true);
}
+ public Boolean loadRulebookUseSDCardBooleanState (){
+ return RulebookSharedPreferences.getBoolean(USE_SDCARD, false);
+ }
}
diff --git a/app/src/main/java/com/verNANDo57/rulebook_educational/rules/AppBaseScrollableActivity.java b/app/src/main/java/com/verNANDo57/rulebook_educational/rules/AppBaseScrollableActivity.java
index c4e0b9a..aff2290 100644
--- a/app/src/main/java/com/verNANDo57/rulebook_educational/rules/AppBaseScrollableActivity.java
+++ b/app/src/main/java/com/verNANDo57/rulebook_educational/rules/AppBaseScrollableActivity.java
@@ -6,7 +6,10 @@
import static com.verNANDo57.rulebook_educational.utils.AppUtils.LOG_TAG;
+import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
+import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
@@ -20,10 +23,14 @@
import android.widget.RelativeLayout;
import android.widget.TextView;
+import androidx.activity.result.ActivityResult;
+import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.appcompat.widget.Toolbar;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
+import androidx.core.app.ShareCompat;
import androidx.core.content.ContextCompat;
+import androidx.core.content.FileProvider;
import androidx.core.widget.NestedScrollView;
import com.google.android.material.appbar.AppBarLayout;
@@ -31,22 +38,30 @@
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.snackbar.Snackbar;
import com.verNANDo57.rulebook_educational.BottomNavAmongLessonsFragment;
+import com.verNANDo57.rulebook_educational.app.CustomActivityResult;
import com.verNANDo57.rulebook_educational.app.CustomThemeEngineAppCompatActivity;
import com.verNANDo57.rulebook_educational.bookmarks.AppBookmarkUtils;
import com.verNANDo57.rulebook_educational.extradata.R;
import com.verNANDo57.rulebook_educational.markwon.Markwon;
+import com.verNANDo57.rulebook_educational.preferences.RulebookApplicationSharedPreferences;
import com.verNANDo57.rulebook_educational.utils.AppUtils;
import org.jetbrains.annotations.NotNull;
import org.json.JSONException;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
public class AppBaseScrollableActivity extends CustomThemeEngineAppCompatActivity {
+ private Context context;
private CoordinatorLayout mRootLayout;
private RelativeLayout app_basescrollableactivity_toolbar_container;
private RelativeLayout app_basescrollableactivity_search_container;
+ private NestedScrollView app_scrollableactivity_content_scrollview;
private AppBarLayout appbar;
private Animation fade_in;
@@ -57,14 +72,20 @@ public class AppBaseScrollableActivity extends CustomThemeEngineAppCompatActivit
private String inputFileDir;
private String exportFileDir;
+ private TextView app_scrollableactivity_content_text;
private TextView app_basescrollableactivity_title;
private TextView app_basescrollableactivity_summary;
private Intent sourceIntent;
+ protected final CustomActivityResult activityLauncher = CustomActivityResult.registerActivityForResult(this);
+
+ private RulebookApplicationSharedPreferences preferences;
+
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ preferences = new RulebookApplicationSharedPreferences(this);
sourceIntent = getIntent();
fade_in = AnimationUtils.loadAnimation(this, R.anim.app_fade_in);
@@ -73,11 +94,12 @@ public void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.app_scrollable_activity);
mRootLayout = findViewById(R.id.scrollableactivity_root);
+ context = mRootLayout.getContext();
ImageView app_basescrollableactivity_icon = findViewById(R.id.app_scrollableactivity_in_scrollableactivity_icon);
app_basescrollableactivity_title = findViewById(R.id.app_scrollableactivity_in_scrollableactivity_title);
app_basescrollableactivity_summary = findViewById(R.id.app_scrollableactivity_in_scrollableactivity_summary);
- TextView app_scrollableactivity_content_in_mainrules_text = findViewById(R.id.app_scrollableactivity_content_everywhere_text);
+ app_scrollableactivity_content_text = findViewById(R.id.app_scrollableactivity_content_text);
app_basescrollableactivity_toolbar_container = findViewById(R.id.app_scrollableactivity_in_scrollableactivity_toolbarlayout_container);
app_basescrollableactivity_search_container = findViewById(R.id.app_scrollableactivity_everywhere_toolbarlayout_search_container);
@@ -117,7 +139,7 @@ public void onClick(View v) {
CollapsingToolbarLayout toolBarLayout = findViewById(R.id.toolbar_layout_in_scrollableactivity);
toolBarLayout.setTitle(" "); //should be a space, otherwise the trick will not work
appbar = findViewById(R.id.app_bar_in_scrollableactivity);
- NestedScrollView app_scrollableactivity_content_scrollview = findViewById(R.id.app_scrollableactivity_content_scrollview);
+ app_scrollableactivity_content_scrollview = findViewById(R.id.app_scrollableactivity_content_scrollview);
EditText app_wordsearch_edittext = findViewById(R.id.app_wordsearch_edittext);
Button searchword_button = findViewById(R.id.searchword_button);
@@ -126,16 +148,16 @@ public void onClick(View v) {
try {
if(sourceIntent.getStringExtra(AppUtils.EXTRA_DATA_KEY).contains("ortho_")) {
inputStream = getAssets().open("mainrules/orthography/" + sourceIntent.getStringExtra(AppUtils.EXTRA_DATA_KEY) + Constants.FILE_FORMAT);
- markwon.setMarkdown(app_scrollableactivity_content_in_mainrules_text, AppUtils.convertStreamToString(inputStream));
+ markwon.setMarkdown(app_scrollableactivity_content_text, AppUtils.convertStreamToString(inputStream));
} else if(sourceIntent.getStringExtra(AppUtils.EXTRA_DATA_KEY).contains("punct_")){
inputStream = getAssets().open("mainrules/punctuation/" + sourceIntent.getStringExtra(AppUtils.EXTRA_DATA_KEY) + Constants.FILE_FORMAT);
- markwon.setMarkdown(app_scrollableactivity_content_in_mainrules_text, AppUtils.convertStreamToString(inputStream));
+ markwon.setMarkdown(app_scrollableactivity_content_text, AppUtils.convertStreamToString(inputStream));
} else if (sourceIntent.getStringExtra(AppUtils.EXTRA_DATA_KEY).contains("dict_")) {
inputStream = getAssets().open("dictionaries/" + sourceIntent.getStringExtra(AppUtils.EXTRA_DATA_KEY) + Constants.FILE_FORMAT);
- markwon.setMarkdown(app_scrollableactivity_content_in_mainrules_text, AppUtils.convertStreamToString(inputStream));
+ markwon.setMarkdown(app_scrollableactivity_content_text, AppUtils.convertStreamToString(inputStream));
} else {
inputStream = getAssets().open("analyze_methods/" + sourceIntent.getStringExtra(AppUtils.EXTRA_DATA_KEY) + Constants.FILE_FORMAT);
- markwon.setMarkdown(app_scrollableactivity_content_in_mainrules_text, AppUtils.convertStreamToString(inputStream));
+ markwon.setMarkdown(app_scrollableactivity_content_text, AppUtils.convertStreamToString(inputStream));
}
} catch (IOException e) {
Snackbar.make(mRootLayout, getString(R.string.error_while_reading_a_file), Snackbar.LENGTH_LONG).show();
@@ -145,20 +167,25 @@ public void onClick(View v) {
searchword_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- String criteria = app_wordsearch_edittext.getText().toString();
- String fullText = app_scrollableactivity_content_in_mainrules_text.getText().toString();
+ String criteria = app_wordsearch_edittext.getText().toString().trim();
+ String fullText = app_scrollableactivity_content_text.getText().toString();
- AppUtils.resetHighLightedText(app_scrollableactivity_content_in_mainrules_text, fullText);
+ AppUtils.resetHighLightedText(context, app_scrollableactivity_content_text, fullText);
- if(criteria.equals(" ") | criteria.contains(" ") | criteria.isEmpty()){
- Snackbar.make(mRootLayout, getString(R.string.app_edittext_is_empty), Snackbar.LENGTH_LONG).show();
+ // If EditText is empty...
+ if(criteria.isEmpty()) {
+ // If so...
+ Snackbar.make(findViewById(android.R.id.content), getString(R.string.app_edittext_is_empty), Snackbar.LENGTH_LONG).show();
} else {
+ // If not, start searching...
if (fullText.contains(criteria)) {
- int indexOfCriteria = fullText.indexOf(criteria);
- int lineNumber = app_scrollableactivity_content_in_mainrules_text.getLayout().getLineForOffset(indexOfCriteria);
- AppUtils.setHighLightedText(app_scrollableactivity_content_in_mainrules_text, criteria);
-
- app_scrollableactivity_content_scrollview.scrollTo(0, app_scrollableactivity_content_in_mainrules_text.getLayout().getLineTop(lineNumber));
+ // Highlight text
+ AppUtils.setHighLightedText(context, app_scrollableactivity_content_text, criteria);
+ // Scroll to it's position
+ app_scrollableactivity_content_scrollview.scrollTo(0, app_scrollableactivity_content_text.getLayout().getLineTop(app_scrollableactivity_content_text.getLayout().getLineForOffset(fullText.indexOf(criteria))));
+ } else {
+ // If nothing was found...
+ Snackbar.make(mRootLayout, getString(R.string.app_search_nothing_found), Snackbar.LENGTH_LONG).show();
}
}
}
@@ -251,6 +278,41 @@ public boolean onOptionsItemSelected(MenuItem item) {
e.printStackTrace();
}
}
+ } else if (id == R.id.share) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(getResources().getString(R.string.app_share));
+ builder.setIcon(ContextCompat.getDrawable(this, R.drawable.app_share));
+ builder.setItems(getResources().getStringArray(R.array.share_modes), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ // The 'which' argument contains the index position
+ // of the selected item
+ switch (which) {
+ case 0:
+ try {
+ shareScreenshot();
+ } catch (IOException e) {
+ Log.e(LOG_TAG, getResources().getString(R.string.app_error_occurred));
+ e.printStackTrace();
+ }
+ break;
+ case 1:
+ try {
+ shareFile();
+ } catch (IOException e) {
+ Log.e(LOG_TAG, getResources().getString(R.string.app_error_occurred));
+ e.printStackTrace();
+ }
+ break;
+ }
+ }
+ });
+ builder.setNeutralButton(getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ dialogInterface.cancel();
+ }
+ });
+ builder.create().show();
} else if (id == R.id.save_rule) {
AppUtils.copyFileFromAssets(
getApplicationContext(),
@@ -258,8 +320,72 @@ public boolean onOptionsItemSelected(MenuItem item) {
inputFileDir,
sourceIntent.getStringExtra(AppUtils.EXTRA_DATA_KEY) + Constants.FILE_FORMAT,
exportFileDir,
- app_basescrollableactivity_title.getText() + Constants.FILE_EXPORT_FORMAT);
+ app_basescrollableactivity_title.getText() + Constants.FILE_EXPORT_FORMAT,
+ preferences.loadRulebookUseSDCardBooleanState());
}
return super.onOptionsItemSelected(item);
}
+
+ private void shareScreenshot() throws IOException {
+ // Get bitmap & compress
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ AppUtils.getBitmapFromView(context, app_scrollableactivity_content_text, app_scrollableactivity_content_text.getHeight(), app_scrollableactivity_content_text.getWidth()).compress(Bitmap.CompressFormat.JPEG, 100, bytes);
+
+ // Create screenshot file
+ File screenshotFile = new File(getApplicationContext().getFilesDir().getAbsolutePath(), "tmp_screenshot.jpg");
+ screenshotFile.createNewFile();
+
+ // Write bitmap
+ FileOutputStream fileOutputStream = new FileOutputStream(screenshotFile);
+ fileOutputStream.write(bytes.toByteArray());
+
+ // Close FileOutputStream
+ fileOutputStream.flush();
+ fileOutputStream.close();
+
+ // Share image
+ Intent sharingIntent = new ShareCompat.IntentBuilder(getApplicationContext())
+ .setType("image/jpeg")
+ .setStream(FileProvider.getUriForFile(this, "com.verNANDo57.rulebook_educational.fileprovider", screenshotFile))
+ .setChooserTitle(getResources().getString(R.string.app_share))
+ .createChooserIntent()
+ .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ activityLauncher.launch(sharingIntent, result -> {
+ screenshotFile.getAbsoluteFile().delete();
+ });
+ }
+
+ private void shareFile() throws IOException {
+ File exportRuleFile = new File(getApplicationContext().getFilesDir().getAbsolutePath(), app_basescrollableactivity_title.getText() + Constants.FILE_EXPORT_FORMAT);
+
+ // Copy the file which we're gonna share to apllication data folder (/data/data/*)
+ if (!exportRuleFile.exists()) {
+ exportRuleFile.createNewFile();
+
+ InputStream in;
+ OutputStream out;
+ in = context.getAssets().open(inputFileDir + sourceIntent.getStringExtra(AppUtils.EXTRA_DATA_KEY) + Constants.FILE_FORMAT);
+ out = new FileOutputStream(exportRuleFile);
+
+ byte[] buffer = new byte[1024];
+ int read;
+ while ((read = in.read(buffer)) != -1) {
+ out.write(buffer, 0, read);
+ }
+
+ out.flush();
+ out.close();
+ }
+
+ // Share file
+ Intent sharingIntent = new ShareCompat.IntentBuilder(getApplicationContext())
+ .setType("text/plain")
+ .setStream(FileProvider.getUriForFile(this, "com.verNANDo57.rulebook_educational.fileprovider", exportRuleFile))
+ .setChooserTitle(getResources().getString(R.string.app_share))
+ .createChooserIntent()
+ .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ activityLauncher.launch(sharingIntent, result -> {
+ exportRuleFile.getAbsoluteFile().delete();
+ });
+ }
}
diff --git a/app/src/main/java/com/verNANDo57/rulebook_educational/utils/AppUtils.java b/app/src/main/java/com/verNANDo57/rulebook_educational/utils/AppUtils.java
index b6edd42..d4030d2 100644
--- a/app/src/main/java/com/verNANDo57/rulebook_educational/utils/AppUtils.java
+++ b/app/src/main/java/com/verNANDo57/rulebook_educational/utils/AppUtils.java
@@ -8,10 +8,14 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.BackgroundColorSpan;
+import android.text.style.ForegroundColorSpan;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
@@ -36,6 +40,7 @@
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
+import java.util.Objects;
public class AppUtils {
@@ -50,19 +55,19 @@ public class AppUtils {
public static String EXTRA_DATA_TITLE = "rule_title";
public static String EXTRA_DATA_SUMMARY = "rule_summary";
- //Thanks to this method, we can read a text file
+ // Thanks to this function, we can read a text file
public static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
/**
- * use this method to highlight a text in TextView
+ * Use this function to highlight a text in TextView
*
* @param tv TextView or Edittext or Button (or derived from TextView)
* @param textToHighlight Text to highlight
*/
- public static void setHighLightedText(TextView tv, String textToHighlight) {
+ public static void setHighLightedText(Context context, TextView tv, String textToHighlight) {
String tvt = tv.getText().toString();
int ofe = tvt.indexOf(textToHighlight);
Spannable wordToSpan = new SpannableString(tv.getText());
@@ -71,14 +76,23 @@ public static void setHighLightedText(TextView tv, String textToHighlight) {
if (ofe == -1)
break;
else {
- // set color here
- wordToSpan.setSpan(new BackgroundColorSpan(0xFFFFFF00), ofe, ofe + textToHighlight.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ // Set background color
+ wordToSpan.setSpan(new BackgroundColorSpan(context.getResources().getColor(R.color.app_text)), ofe, ofe + textToHighlight.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ // Set foreground color
+ wordToSpan.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.app_custom_background)), ofe, ofe + textToHighlight.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ // Apply changes
tv.setText(wordToSpan, TextView.BufferType.SPANNABLE);
}
}
}
- public static void resetHighLightedText(TextView tv, String textToResetColor) {
+ /**
+ * Use this function to reset text color in TextView
+ *
+ * @param tv TextView or Edittext or Button (or derived from TextView)
+ * @param textToResetColor Text to reset
+ */
+ public static void resetHighLightedText(Context context, TextView tv, String textToResetColor) {
String tvt = tv.getText().toString();
int ofe = tvt.indexOf(textToResetColor);
Spannable wordToSpan = new SpannableString(tv.getText());
@@ -87,8 +101,11 @@ public static void resetHighLightedText(TextView tv, String textToResetColor) {
if (ofe == -1)
break;
else {
- // set color here
+ // Reset background color
wordToSpan.setSpan(new BackgroundColorSpan(0), ofe, ofe + textToResetColor.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ // Reset foreground color
+ wordToSpan.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.app_text)), ofe, ofe + textToResetColor.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ // Apply changes
tv.setText(wordToSpan, TextView.BufferType.SPANNABLE);
}
}
@@ -116,12 +133,12 @@ public static void copyFileUsingNIO(File sourceFile, File destinationFile) throw
}
}
- public static void copyFileFromAssets(Context context, View rootView, String inputFileDir, String inputFile, String outputFileDir, String outputFile) {
+ public static void copyFileFromAssets(Context context, View rootView, String inputFileDir, String inputFile, String outputFileDir, String outputFile, boolean useSDCard) {
try {
// Create output dir if needed
- new File(Environment.getExternalStorageDirectory().getAbsolutePath() + outputFileDir).mkdirs();
+ new File(getStorageAbsolutePath(context, useSDCard) + outputFileDir).mkdirs();
// Initialize output file
- File output = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + outputFileDir + outputFile);
+ File output = new File(getStorageAbsolutePath(context, useSDCard) + outputFileDir + outputFile);
if (!output.exists()) {
InputStream in;
OutputStream out;
@@ -134,9 +151,12 @@ public static void copyFileFromAssets(Context context, View rootView, String inp
out.write(buffer, 0, read);
}
- Snackbar.make(rootView, context.getString(R.string.app_saved) + ":" + outputFileDir + outputFile, Snackbar.LENGTH_LONG).show();
+ Snackbar.make(rootView, context.getString(R.string.app_saved) + ":" + output.getAbsolutePath(), Snackbar.LENGTH_LONG).show();
+
+ out.flush();
+ out.close();
} else {
- Snackbar.make(rootView, context.getString(R.string.app_saved_already) + ":" + outputFileDir + outputFile, Snackbar.LENGTH_LONG).show();
+ Snackbar.make(rootView, context.getString(R.string.app_saved_already) + ":" + output.getAbsolutePath(), Snackbar.LENGTH_LONG).show();
}
} catch (IOException e) {
e.printStackTrace();
@@ -145,11 +165,53 @@ public static void copyFileFromAssets(Context context, View rootView, String inp
}
}
- public static int getIconWarning() {
- return R.drawable.ic_warning;
+ /* Using this function we can get storage absolute path */
+ public static String getStorageAbsolutePath(Context context, boolean useSDCard) {
+ // Works on API 24+
+ File[] dirs = context.getExternalFilesDirs(null);
+ StringBuilder outputStorage;
+ int slashCount;
+
+ // Firstly, check if SDCard exist, to avoid issues
+ if (checkIfSDCardExists() && useSDCard) {
+ // Use SDCard if user wants to
+ outputStorage = new StringBuilder(dirs[1].getAbsolutePath());
+ slashCount = 2;
+ } else {
+ outputStorage = new StringBuilder(dirs[0].getAbsolutePath());
+ slashCount = 3;
+ }
+
+ // Process
+ int charsCounter = outputStorage.length();
+ int slashCounter = getCharCount(outputStorage, '/');
+
+ for (int i=1;slashCounter!=slashCount;i++) {
+ if(outputStorage.charAt(charsCounter - i) == '/') {
+ slashCounter = slashCounter - 1;
+ }
+ outputStorage.deleteCharAt(charsCounter-i);
+ }
+
+ return outputStorage.toString();
+ }
+
+ /* Using this function we can check, if SDCard is inserted */
+ public static boolean checkIfSDCardExists() {
+ return Environment.isExternalStorageRemovable() && Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
+ }
+
+ /* Using this function we can remove all files inside one folder */
+ public static void removeFolderRecursive(File dir) {
+ if (dir.exists() && dir.isDirectory()) {
+ for (File child : Objects.requireNonNull(dir.listFiles())) {
+ removeFolderRecursive(child);
+ }
+ }
+ dir.delete();
}
- /* Using these methods we can remove last line of any text file */
+ /* Using these functions we can remove last line of any text file */
public static void removeLastLine(String name) throws IOException {
RandomAccessFile f = new RandomAccessFile(name, "rw");
long length = f.length() - 1;
@@ -180,17 +242,18 @@ public static void removeLastLine(File file) throws IOException {
f.close();
}
- /* This method uses BufferedReader to read line by line and increases the count. */
+ /* This function uses BufferedReader to read line by line and increases the count. */
public static long countLineBufferedReader(File fileName) throws IOException {
long lines = 0;
BufferedReader reader = new BufferedReader(new FileReader(fileName));
while (reader.readLine() != null) {
lines++;
}
+ reader.close();
return lines;
}
- /* Using this method we can count occurrences of a char in a string */
+ /* Using these functions we can count occurrences of a char in a string */
public static int getCharCount(String text, char someChar) {
int count = 0;
@@ -202,8 +265,19 @@ public static int getCharCount(String text, char someChar) {
return count;
}
+ public static int getCharCount(StringBuilder stringBuilder, char someChar) {
+ int count = 0;
+
+ for (int i = 0; i < stringBuilder.length(); i++) {
+ if (stringBuilder.charAt(i) == someChar) {
+ count++;
+ }
+ }
+ return count;
+ }
+
/**
- * U can use this method to set animation to any view
+ * U can use this function to set animation to any view
* firstly, u need to define your view, then animator_mode, then [Float] move value (optional)
*/
public static int TRANSLATE_DIRECTION_RIGHT = 1;
@@ -280,7 +354,7 @@ public static float dpToPx(Context context, int dp) {
}
/**
- * This simple method have been created for fetching app's info (VerisionName or VersionCode).
+ * This simple function have been created for fetching app's info (VerisionName or VersionCode).
* It returns String, so his return value can be used instead of any string which defined in strings.xml and etc.
*
* For Example:
@@ -318,7 +392,7 @@ public static String getApplicationVersionInfo(Context context, int info_mode) {
/**
* @param context
*
- * Using this method we can find out which theme is being used.
+ * Using this function we can find out which theme is being used.
* This method is needed because of DayNight engine.
* Since user can use FOLLOW_SYSTEM or AUTO_BATTERY option, we can't just use AppCompatDelegate to find out which theme is being used.
*
@@ -345,4 +419,26 @@ public static int calculateNumberOfColumns(Context context, float columnWidthDp)
float screenWidthDp = displayMetrics.widthPixels / displayMetrics.density;
return (int) (screenWidthDp / columnWidthDp + 0.5);
}
+
+ /**
+ * Using this function we can take full screenshot of view (using bitmap)
+ * @param context - Context
+ * @param height - height of view
+ * @param width - width of view
+ * @param view - view we want take a screenshot of
+ *
+ * @return the bmp file
+ */
+ public static Bitmap getBitmapFromView(Context context, View view, int height, int width) {
+ Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+ Drawable bgDrawable = view.getBackground();
+ if (bgDrawable != null) {
+ bgDrawable.draw(canvas);
+ } else {
+ canvas.drawColor(context.getResources().getColor(R.color.app_custom_background));
+ }
+ view.draw(canvas);
+ return bitmap;
+ }
}
diff --git a/app/src/main/java/com/verNANDo57/rulebook_educational/utils/ColorUtils.java b/app/src/main/java/com/verNANDo57/rulebook_educational/utils/ColorUtils.java
index 6a943f5..8bcea1e 100644
--- a/app/src/main/java/com/verNANDo57/rulebook_educational/utils/ColorUtils.java
+++ b/app/src/main/java/com/verNANDo57/rulebook_educational/utils/ColorUtils.java
@@ -215,7 +215,7 @@ public static float[] createColorMatrixFromHex(@NonNull String hex) {
hex = hex.substring(1);
}
- float a = Float.parseFloat(new DecimalFormat("#.##").format(Integer.parseInt(hex.substring(0, 2), 16) / 255.0f)); // Alpha (Transparency in percents) [First Two
+ float a = Float.parseFloat(new DecimalFormat("#.##").format(Integer.parseInt(hex.substring(0, 2), 16) / 255.0f)); // Alpha (Transparency in percents)
float r = Float.parseFloat(new DecimalFormat("#.##").format(Integer.parseInt(hex.substring(2, 4), 16) / 255.0f)); // Red
float g = Float.parseFloat(new DecimalFormat("#.##").format(Integer.parseInt(hex.substring(4, 6), 16) / 255.0f)); // Green
float b = Float.parseFloat(new DecimalFormat("#.##").format(Integer.parseInt(hex.substring(6, 8), 16) / 255.0f)); // Blue
diff --git a/app/src/main/res/drawable-hdpi/colorpicker_alpha.png b/app/src/main/res/drawable-hdpi/colorpicker_alpha.png
deleted file mode 100644
index e3fe9c8..0000000
Binary files a/app/src/main/res/drawable-hdpi/colorpicker_alpha.png and /dev/null differ
diff --git a/app/src/main/res/drawable-hdpi/colorpicker_popup_background.9.png b/app/src/main/res/drawable-hdpi/colorpicker_popup_background.9.png
deleted file mode 100644
index f2149f9..0000000
Binary files a/app/src/main/res/drawable-hdpi/colorpicker_popup_background.9.png and /dev/null differ
diff --git a/app/src/main/res/drawable-mdpi/colorpicker_popup_background.9.png b/app/src/main/res/drawable-mdpi/colorpicker_popup_background.9.png
deleted file mode 100644
index f42bff1..0000000
Binary files a/app/src/main/res/drawable-mdpi/colorpicker_popup_background.9.png and /dev/null differ
diff --git a/app/src/main/res/drawable-xhdpi/colorpicker_alpha.png b/app/src/main/res/drawable-xhdpi/colorpicker_alpha.png
deleted file mode 100644
index c51c612..0000000
Binary files a/app/src/main/res/drawable-xhdpi/colorpicker_alpha.png and /dev/null differ
diff --git a/app/src/main/res/drawable-xhdpi/colorpicker_popup_background.9.png b/app/src/main/res/drawable-xhdpi/colorpicker_popup_background.9.png
deleted file mode 100644
index e10daaa..0000000
Binary files a/app/src/main/res/drawable-xhdpi/colorpicker_popup_background.9.png and /dev/null differ
diff --git a/app/src/main/res/drawable-xxhdpi/colorpicker_alpha.png b/app/src/main/res/drawable-xxhdpi/colorpicker_alpha.png
deleted file mode 100644
index c81fc26..0000000
Binary files a/app/src/main/res/drawable-xxhdpi/colorpicker_alpha.png and /dev/null differ
diff --git a/app/src/main/res/drawable-xxhdpi/colorpicker_popup_background.9.png b/app/src/main/res/drawable-xxhdpi/colorpicker_popup_background.9.png
deleted file mode 100644
index 4f4b0e1..0000000
Binary files a/app/src/main/res/drawable-xxhdpi/colorpicker_popup_background.9.png and /dev/null differ
diff --git a/app/src/main/res/drawable/app_bottomappbar_icon.xml b/app/src/main/res/drawable/app_bottomappbar_icon.xml
deleted file mode 100644
index d80d0a4..0000000
--- a/app/src/main/res/drawable/app_bottomappbar_icon.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/app_delete_forever.xml b/app/src/main/res/drawable/app_delete_forever.xml
new file mode 100644
index 0000000..de0e0ad
--- /dev/null
+++ b/app/src/main/res/drawable/app_delete_forever.xml
@@ -0,0 +1,10 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/app_sdcard.xml b/app/src/main/res/drawable/app_sdcard.xml
new file mode 100644
index 0000000..030f70d
--- /dev/null
+++ b/app/src/main/res/drawable/app_sdcard.xml
@@ -0,0 +1,10 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/app_share.xml b/app/src/main/res/drawable/app_share.xml
new file mode 100644
index 0000000..319d503
--- /dev/null
+++ b/app/src/main/res/drawable/app_share.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_actionmenu.xml b/app/src/main/res/drawable/ic_actionmenu.xml
new file mode 100644
index 0000000..7455542
--- /dev/null
+++ b/app/src/main/res/drawable/ic_actionmenu.xml
@@ -0,0 +1,10 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_close.xml b/app/src/main/res/drawable/ic_close.xml
index 6983e75..6a32fdf 100644
--- a/app/src/main/res/drawable/ic_close.xml
+++ b/app/src/main/res/drawable/ic_close.xml
@@ -3,7 +3,7 @@
android:height="48dp"
android:viewportWidth="192"
android:viewportHeight="192">
-
+
diff --git a/app/src/main/res/drawable/ic_home_black.xml b/app/src/main/res/drawable/ic_home.xml
similarity index 100%
rename from app/src/main/res/drawable/ic_home_black.xml
rename to app/src/main/res/drawable/ic_home.xml
diff --git a/app/src/main/res/drawable/ic_refresh.xml b/app/src/main/res/drawable/ic_refresh.xml
index 0d2b744..26aaf67 100644
--- a/app/src/main/res/drawable/ic_refresh.xml
+++ b/app/src/main/res/drawable/ic_refresh.xml
@@ -1,9 +1,9 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_save_icon.xml b/app/src/main/res/drawable/ic_save_toolbar.xml
similarity index 100%
rename from app/src/main/res/drawable/ic_save_icon.xml
rename to app/src/main/res/drawable/ic_save_toolbar.xml
diff --git a/app/src/main/res/drawable/ic_searchword.xml b/app/src/main/res/drawable/ic_searchword.xml
index ff5d56d..156c190 100644
--- a/app/src/main/res/drawable/ic_searchword.xml
+++ b/app/src/main/res/drawable/ic_searchword.xml
@@ -6,4 +6,4 @@
-
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_settings_black.xml b/app/src/main/res/drawable/ic_settings_toolbar.xml
similarity index 100%
rename from app/src/main/res/drawable/ic_settings_black.xml
rename to app/src/main/res/drawable/ic_settings_toolbar.xml
diff --git a/app/src/main/res/drawable/ic_share.xml b/app/src/main/res/drawable/ic_share.xml
new file mode 100644
index 0000000..83d671f
--- /dev/null
+++ b/app/src/main/res/drawable/ic_share.xml
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_warning.xml b/app/src/main/res/drawable/ic_warning.xml
index be3671e..d9c4779 100644
--- a/app/src/main/res/drawable/ic_warning.xml
+++ b/app/src/main/res/drawable/ic_warning.xml
@@ -1,4 +1,5 @@
-
-
\ No newline at end of file
diff --git a/app/src/main/res/font/productsans_bold.ttf b/app/src/main/res/font-v26/productsans_bold.ttf
similarity index 100%
rename from app/src/main/res/font/productsans_bold.ttf
rename to app/src/main/res/font-v26/productsans_bold.ttf
diff --git a/app/src/main/res/font/productsans_bolditalic.ttf b/app/src/main/res/font-v26/productsans_bolditalic.ttf
similarity index 100%
rename from app/src/main/res/font/productsans_bolditalic.ttf
rename to app/src/main/res/font-v26/productsans_bolditalic.ttf
diff --git a/app/src/main/res/font/productsans_italic.ttf b/app/src/main/res/font-v26/productsans_italic.ttf
similarity index 100%
rename from app/src/main/res/font/productsans_italic.ttf
rename to app/src/main/res/font-v26/productsans_italic.ttf
diff --git a/app/src/main/res/font/productsans_medium.ttf b/app/src/main/res/font-v26/productsans_medium.ttf
similarity index 100%
rename from app/src/main/res/font/productsans_medium.ttf
rename to app/src/main/res/font-v26/productsans_medium.ttf
diff --git a/app/src/main/res/font/productsans_mediumitalic.ttf b/app/src/main/res/font-v26/productsans_mediumitalic.ttf
similarity index 100%
rename from app/src/main/res/font/productsans_mediumitalic.ttf
rename to app/src/main/res/font-v26/productsans_mediumitalic.ttf
diff --git a/app/src/main/res/font/productsans_regular.ttf b/app/src/main/res/font-v26/productsans_regular.ttf
similarity index 100%
rename from app/src/main/res/font/productsans_regular.ttf
rename to app/src/main/res/font-v26/productsans_regular.ttf
diff --git a/app/src/main/res/layout/app_bottomappbar_about.xml b/app/src/main/res/layout/app_bottomappbar_about.xml
index 2497ef5..0221373 100755
--- a/app/src/main/res/layout/app_bottomappbar_about.xml
+++ b/app/src/main/res/layout/app_bottomappbar_about.xml
@@ -26,6 +26,6 @@
android:layout_height="wrap_content"
app:layout_anchor="@id/bar_in_about"
app:layout_insetEdge="none"
- app:srcCompat="@drawable/ic_home_black" />
+ app:srcCompat="@drawable/ic_home" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/app_bottomappbar_analyze_methods.xml b/app/src/main/res/layout/app_bottomappbar_analyze_methods.xml
index e652891..cd611f4 100644
--- a/app/src/main/res/layout/app_bottomappbar_analyze_methods.xml
+++ b/app/src/main/res/layout/app_bottomappbar_analyze_methods.xml
@@ -26,6 +26,6 @@
android:layout_height="wrap_content"
app:layout_insetEdge="right"
app:layout_anchor="@id/bar_in_analyze_methods"
- app:srcCompat="@drawable/ic_home_black"/>
+ app:srcCompat="@drawable/ic_home"/>
\ No newline at end of file
diff --git a/app/src/main/res/layout/app_scrollable_activity.xml b/app/src/main/res/layout/app_scrollable_activity.xml
index 0640a57..4ea523f 100644
--- a/app/src/main/res/layout/app_scrollable_activity.xml
+++ b/app/src/main/res/layout/app_scrollable_activity.xml
@@ -12,8 +12,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
- android:background="@drawable/app_collapsing_toolbar"
- android:theme="@style/AppTheme.AppBarOverlay">
+ android:background="@drawable/app_collapsing_toolbar">
-
-
diff --git a/app/src/main/res/menu/app_menu.xml b/app/src/main/res/menu/app_menu.xml
index 1bc5621..9ffd69d 100755
--- a/app/src/main/res/menu/app_menu.xml
+++ b/app/src/main/res/menu/app_menu.xml
@@ -4,7 +4,7 @@
android:layout_gravity="start">
-
diff --git a/app/src/main/res/menu/app_scrollableactivity_menu.xml b/app/src/main/res/menu/app_scrollableactivity_menu.xml
index 0e232bf..0ffc948 100644
--- a/app/src/main/res/menu/app_scrollableactivity_menu.xml
+++ b/app/src/main/res/menu/app_scrollableactivity_menu.xml
@@ -17,10 +17,17 @@
app:showAsAction="ifRoom">
+ -
+
+
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/values-night-v23/styles.xml b/app/src/main/res/values-night-v23/styles.xml
new file mode 100644
index 0000000..288a634
--- /dev/null
+++ b/app/src/main/res/values-night-v23/styles.xml
@@ -0,0 +1,43 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-night-v31/styles.xml b/app/src/main/res/values-night-v31/styles.xml
new file mode 100644
index 0000000..7c5225d
--- /dev/null
+++ b/app/src/main/res/values-night-v31/styles.xml
@@ -0,0 +1,43 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml
index 023088a..07b9994 100644
--- a/app/src/main/res/values-night/styles.xml
+++ b/app/src/main/res/values-night/styles.xml
@@ -17,14 +17,14 @@
- false
- true
- @style/AppBarBottomSheetDialogStyle
- - @font/app_rulebook_productsans_fontfamily
+ - @font/app_rulebook_productsans_fontfamily
+ - @font/app_rulebook_productsans_fontfamily
- @font/app_rulebook_productsans_fontfamily
- @style/SnackBar
- @style/SnackBarButton
- @style/SnackBarTextViewStyle
- - @style/AppTheme.PopupOverlay
+ - @style/AppTheme.PopupOverlay
- @color/app_custom_background
- - false
- @style/AppTheme.PopupOverlay
- @color/app_custom_background
- @style/AppImageButtonStyle
@@ -34,14 +34,10 @@
- @style/AppRadioButtonStyle
- @style/AppToolbarStyle
- @style/AppToolbarStyle
- - @style/AppWebViewStyleDarkTheme
+ - @style/AppWebViewStyle
- @style/NavigationViewStyle
- @color/colorAccent
-
-
-
-
diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml
index 6646c15..0841908 100644
--- a/app/src/main/res/values-v21/styles.xml
+++ b/app/src/main/res/values-v21/styles.xml
@@ -1,9 +1,10 @@
-
\ No newline at end of file
diff --git a/app/src/main/res/values-v23/styles.xml b/app/src/main/res/values-v23/styles.xml
index af16d04..fabd5fd 100644
--- a/app/src/main/res/values-v23/styles.xml
+++ b/app/src/main/res/values-v23/styles.xml
@@ -1,5 +1,46 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-v31/styles.xml b/app/src/main/res/values-v31/styles.xml
new file mode 100644
index 0000000..abf494e
--- /dev/null
+++ b/app/src/main/res/values-v31/styles.xml
@@ -0,0 +1,44 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml
new file mode 100644
index 0000000..0186d7a
--- /dev/null
+++ b/app/src/main/res/values/arrays.xml
@@ -0,0 +1,14 @@
+
+
+
+ - @string/app_darkTheme_mode_no
+ - @string/app_darkTheme_mode_yes
+ - @string/app_darkTheme_mode_followSystem
+ - @string/app_darkTheme_mode_battery
+
+
+
+ - @string/app_share_image
+ - @string/app_share_file
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index b157898..0c93c51 100755
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -13,7 +13,7 @@
Rulebook: Виды разборов
Rulebook: Словари
-
+
silvenation@gmail.com
Оценка пользователя--
/5.0 звёзд
@@ -34,7 +34,7 @@
Серийный номер:
Версия Андроида:
Разрешение экрана:
-
+
пусто
@@ -63,11 +63,19 @@
Строка состояния
Не скрывать строку состояния
+
+ Использовать карту памяти
+ Сохранять файлы на карте памяти
+
+ Стереть данные приложения
+ Удалить все сохранённые файлы
После введённых изменений для корректного отображения интерфейса может потребоваться перезапуск приложения.
Напишите что-нибудь
+ Не удалось найти
+
Правила
Настройки
О приложении
@@ -116,9 +124,10 @@
Не удалось переименовать файл
Не удалось удалить файл
Если вы не дадите приложению доступ к внутренней памяти устройства, то, к сожалению, будет невозможным что-либо сохранять. ¯\_(ツ)_/¯
-
+ Поделиться
+ Поделиться картинкой
+ Поделиться файлом
Ярлык недоступен по неизвестной причине
-
МЕНЮ
Основные
@@ -346,4 +355,4 @@
Словарь фразеологизмов
Орфоэпический словник
-
+
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 7f449ed..a3f74e4 100755
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -17,15 +17,15 @@
- true
- @style/ThemeListView
- @style/AppBarBottomSheetDialogStyle
- - @font/app_rulebook_productsans_fontfamily
+ - @font/app_rulebook_productsans_fontfamily
+ - @font/app_rulebook_productsans_fontfamily
- @font/app_rulebook_productsans_fontfamily
- @style/SnackBar
- @style/SnackBarButton
- @style/SnackBarTextViewStyle
- - @style/AppTheme.PopupOverlay
+ - @style/AppTheme.PopupOverlay
- @color/app_custom_background
- @style/AppTheme.PopupOverlay
- - true
- @color/app_custom_background
- @style/AppImageButtonStyle
- @style/AppAlertDialogThemeLight
@@ -34,9 +34,10 @@
- @style/AppRadioButtonStyle
- @style/AppToolbarStyle
- @style/AppToolbarStyle
- - @style/AppWebViewStyleLightTheme
+ - @style/AppWebViewStyle
- @style/NavigationViewStyle
- @color/colorAccent
+ - @style/AppThemeRulebook.ActionButton.OverFlow
-
@@ -60,6 +61,11 @@
- @style/ActionTitleTextStyle
- @style/ActionSummaryTextStyle
+
+
@@ -216,28 +223,28 @@
-
-
-
-
diff --git a/app/src/main/res/xml-v31/data_extraction_rules.xml b/app/src/main/res/xml-v31/data_extraction_rules.xml
new file mode 100644
index 0000000..7da4b02
--- /dev/null
+++ b/app/src/main/res/xml-v31/data_extraction_rules.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/file_paths.xml b/app/src/main/res/xml/file_paths.xml
new file mode 100644
index 0000000..5f515f3
--- /dev/null
+++ b/app/src/main/res/xml/file_paths.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index aa26773..539ce9d 100755
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -1,34 +1,44 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build.gradle b/build.gradle
index d17cfdf..86100f7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:7.2.0'
+ classpath 'com.android.tools.build:gradle:7.2.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21"
// NOTE: Do not place your application dependencies here; they belong
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index d7faaee..944e2c7 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Mon Apr 11 14:01:13 GMT+07:00 2022
+#Sat Aug 13 15:18:09 GMT+07:00 2022
distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME