Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backup and restore settings, closes #839 #1244

Merged
merged 66 commits into from Apr 16, 2021
Merged
Show file tree
Hide file tree
Changes from 64 commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
695fdc1
Backup and restore
harshad1 Feb 17, 2021
088e7e3
Moved prefs into 'Other'
harshad1 Feb 18, 2021
7a45957
Using blacklist
harshad1 Feb 19, 2021
9892245
Merge branch 'master' into backup_and_restore
gsantner Feb 25, 2021
8ed7391
move class
gsantner Feb 25, 2021
05f7d03
reduce new strings
gsantner Feb 25, 2021
58f5997
string ids
gsantner Feb 25, 2021
2ee9e1d
Merge remote-tracking branch 'upstream/master' into backup_and_restore
harshad1 Feb 25, 2021
05bbdc8
Merge branch 'backup_and_restore' of github.com:harshad1/markor into …
harshad1 Feb 25, 2021
34a372b
Attempt to read and restore (incorrect)
harshad1 Feb 25, 2021
b87ea0d
Using a dialog to get around saving as plain text
harshad1 Feb 26, 2021
74310fb
Small fixes
harshad1 Feb 26, 2021
91cd3e1
Small fixes
harshad1 Feb 26, 2021
d413a34
Removed need for 'password set once'
harshad1 Feb 26, 2021
0208a1d
Cleanups
harshad1 Feb 26, 2021
a64527d
Export / import all settings as json
harshad1 Mar 1, 2021
b647572
Merge remote-tracking branch 'upstream/master' into backup_and_restore
harshad1 Mar 1, 2021
cdee9fb
Merge remote-tracking branch 'upstream/master' into backup_and_restore
harshad1 Mar 3, 2021
141e18b
Merge branch 'master' into backup_and_restore
harshad1 Mar 4, 2021
12d91b2
Merge branch 'master' into backup_and_restore
harshad1 Mar 7, 2021
6cf448e
include pattern fixes
harshad1 Mar 7, 2021
d1a0a05
Merge remote-tracking branch 'upstream/master' into backup_and_restore
harshad1 Mar 15, 2021
3c4ac88
Fixed storage and retrieval of format to be stable
harshad1 Mar 19, 2021
49e8dc3
Fixes
harshad1 Mar 19, 2021
1063337
Autoreformat code
gsantner Mar 20, 2021
e4ed56e
exclude everything password related, json with smaller indent = easie…
gsantner Mar 20, 2021
72a9d69
add own metadata section instead of only versioncode/name
gsantner Mar 20, 2021
34eb201
Include export date in backup filename
gsantner Mar 20, 2021
f2beda7
Added long support
harshad1 Mar 20, 2021
a0b7bf0
Merge branch 'backup_and_restore' of github.com:harshad1/markor into …
harshad1 Mar 20, 2021
29b62bd
better handling of password keys
harshad1 Mar 20, 2021
faf7989
Move backutils to opoc, part 1
gsantner Mar 21, 2021
c8349fa
various improve, only export default datetime string
gsantner Mar 21, 2021
85a4371
various improvements 2
gsantner Mar 21, 2021
de502e7
log prefix
gsantner Mar 21, 2021
4bd37b2
various
gsantner Mar 21, 2021
8170c8e
various 4
gsantner Mar 21, 2021
569c02a
sep markor settings filenames
gsantner Mar 21, 2021
7543aff
Remove remaining R. ref
gsantner Mar 21, 2021
26c371f
use shareutil timestamp method
gsantner Mar 21, 2021
104b7e3
doc
gsantner Mar 21, 2021
ffc60ef
.
gsantner Mar 21, 2021
567dffe
tr strings rework
gsantner Mar 21, 2021
b0eff3f
textformats reformat
gsantner Mar 21, 2021
f459d7e
Store search/replace & datetime dialog settings in app
gsantner Mar 21, 2021
1ab2d61
update strings
gsantner Mar 21, 2021
49b8246
revert bad change
gsantner Mar 21, 2021
ca82243
Revered key, sepearate setting key
harshad1 Mar 21, 2021
15d6ccf
Use appsettings to get password
harshad1 Mar 21, 2021
11b0c99
Merge branch 'master' into backup_and_restore
harshad1 Mar 23, 2021
ffddc97
Merge branch 'master' into backup_and_restore
gsantner Mar 23, 2021
1d64ac1
Merge branch 'master' into backup_and_restore
harshad1 Mar 24, 2021
dc03498
Centralize the get and set of default password in AppSettings.
opensource21 Mar 27, 2021
747b5dd
Switch to safer char[] for password and make convenience-method to ch…
opensource21 Mar 27, 2021
4fb18d1
Merge pull request #2 from opensource21/backup_and_restore
harshad1 Mar 27, 2021
74532db
Fixed duplication
harshad1 Mar 27, 2021
154382f
Merge branch 'master' into backup_and_restore
gsantner Mar 28, 2021
cdb50f9
Switched to commit
harshad1 Mar 29, 2021
e48062d
Removed exit
harshad1 Apr 2, 2021
42f3aa8
Re-enabled exit and removed formats guess
harshad1 Apr 7, 2021
03fe3e5
Merge branch 'master' into backup_and_restore
harshad1 Apr 7, 2021
fa990fc
Merge branch 'master' into backup_and_restore
harshad1 Apr 8, 2021
3df3b03
Switched to string keys
harshad1 Apr 8, 2021
a86a95e
Added defensive catch
harshad1 Apr 8, 2021
d0129b0
Merge branch 'master' into backup_and_restore
harshad1 Apr 11, 2021
695944f
mark untranslatable
gsantner Apr 16, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -146,20 +146,14 @@ protected void onPause() {
private void extractActionData() {
final int documentType = getIntent().getExtras().getInt(EXTRA_FORMAT_KEY);

switch (documentType) {
default:
case R.id.action_format_markdown:
_textActions = new MarkdownTextActions(this, null);
break;
case R.id.action_format_todotxt:
_textActions = new TodoTxtTextActions(this, null);
break;
case R.id.action_format_plaintext:
_textActions = new PlaintextTextActions(this, null);
break;
case R.id.action_format_zimwiki:
_textActions = new ZimWikiTextActions(this, null);
break;
if (documentType == R.string.pref_key__markdown__reorder_actions) {
_textActions = new MarkdownTextActions(this, null);
} else if (documentType == R.string.pref_key__todotxt__reorder_actions) {
_textActions = new TodoTxtTextActions(this, null);
} else if (documentType == R.string.pref_key__zimwiki__reorder_actions) {
_textActions = new ZimWikiTextActions(this, null);
} else { // Default to Plaintext
_textActions = new PlaintextTextActions(this, null);
gsantner marked this conversation as resolved.
Show resolved Hide resolved
}

final Map<String, TextActions.ActionItem> actionMap = _textActions.getActiveActionMap();
Expand Down
Expand Up @@ -446,11 +446,11 @@ public boolean onOptionsItemSelected(final MenuItem item) {

return true;
}
case R.id.action_format_zimwiki:
case R.id.action_format_keyvalue:
case R.id.action_format_todotxt:
case R.id.action_format_plaintext:
case R.id.action_format_markdown: {
case R.string.action_format_zimwiki:
case R.string.action_format_keyvalue:
case R.string.action_format_todotxt:
case R.string.action_format_plaintext:
case R.string.action_format_markdown: {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched all type formats to strings

if (_document != null) {
_document.setFormat(itemId);
applyTextFormat(itemId);
Expand Down
Expand Up @@ -19,7 +19,6 @@
import android.os.Environment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.preference.EditTextPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.support.v7.preference.PreferenceScreen;
Expand All @@ -30,8 +29,10 @@

import net.gsantner.markor.R;
import net.gsantner.markor.ui.FilesystemViewerCreator;
import net.gsantner.markor.ui.SearchOrCustomTextDialogCreator;
import net.gsantner.markor.util.ActivityUtils;
import net.gsantner.markor.util.AppSettings;
import net.gsantner.markor.util.BackupUtils;
import net.gsantner.markor.util.ContextUtils;
import net.gsantner.markor.util.PermissionChecker;
import net.gsantner.opoc.preference.FontPreferenceCompat;
Expand All @@ -45,7 +46,6 @@

import butterknife.BindView;
import butterknife.ButterKnife;
import other.de.stanetz.jpencconverter.PasswordStore;
import other.writeily.widget.WrMarkorWidgetProvider;

public class SettingsActivity extends AppActivityBase {
Expand Down Expand Up @@ -199,10 +199,10 @@ public void doUpdatePreferences() {
}

setPreferenceVisible(R.string.pref_key__is_multi_window_enabled, Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP);
setPreferenceVisible(R.string.pref_key__default_encryption_password, Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && _as.hasPasswordBeenSetOnce()) {
updateSummary(R.string.pref_key__default_encryption_password, "****");
setDialogMessage(R.string.pref_key__default_encryption_password, getString(R.string.password_already_set_setting_a_new_password_will_overwrite));

setPreferenceVisible(R.string.pref_key__set_encryption_password, Build.VERSION.SDK_INT >= Build.VERSION_CODES.M);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && _as.isDefaultPasswordSet()) {
updateSummary(R.string.pref_key__set_encryption_password, getString(R.string.hidden_password));
}


Expand Down Expand Up @@ -243,14 +243,6 @@ protected void onPreferenceChanged(SharedPreferences prefs, String key) {
boolean extraLaunchersEnabled = prefs.getBoolean(key, false);
ActivityUtils au = new ActivityUtils(getActivity());
au.applySpecialLaunchersVisibility(extraLaunchersEnabled);
} else if (eq(key, R.string.pref_key__default_encryption_password) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !TextUtils.isEmpty(prefs.getString(key, null))) {
new PasswordStore(getActivity()).storeKey(prefs.getString(key, null), key, PasswordStore.SecurityMode.NONE);
// Never delete the password, otherwise you will remove the password in PasswordStore too!
// Never remove this line, otherwise the password will be stored unencrypted forever.
// Using commit and while to ensure that the asterisk-pw is definitely written.
prefs.edit().remove(key).commit();
((EditTextPreference) findPreference(key)).setText("");
_as.setPasswordHasBeenSetOnce(true);
} else if (eq(key, R.string.pref_key__file_description_format)) {
try {
new SimpleDateFormat(prefs.getString(key, ""), Locale.getDefault());
Expand Down Expand Up @@ -377,9 +369,19 @@ public void onFsViewerConfig(FilesystemViewerData.Options dopt) {
case R.string.pref_key__markdown__reorder_actions:
case R.string.pref_key__zimwiki__reorder_actions:
case R.string.pref_key__todotxt__reorder_actions: {
Intent intent = new Intent(getActivity(), ActionOrderActivity.class);
intent.putExtra(ActionOrderActivity.EXTRA_FORMAT_KEY, (keyResId == R.string.pref_key__markdown__reorder_actions) ? R.id.action_format_markdown : (keyResId == R.string.pref_key__todotxt__reorder_actions ? R.id.action_format_todotxt : (keyResId == R.string.pref_key__zimwiki__reorder_actions ? R.id.action_format_zimwiki : R.id.action_format_plaintext)));
startActivity(intent);
startActivity(new Intent(getActivity(), ActionOrderActivity.class).putExtra(ActionOrderActivity.EXTRA_FORMAT_KEY, keyResId));
break;
}
case R.string.pref_key__set_encryption_password: {
SearchOrCustomTextDialogCreator.showSetPasswordDialog(getActivity());
break;
}
case R.string.pref_key__backup_settings: {
BackupUtils.showBackupWriteToDialog(getContext(), getFragmentManager());
break;
}
case R.string.pref_key__restore_settings: {
BackupUtils.showBackupSelectFromDialog(getContext(), getFragmentManager());
break;
}
}
Expand All @@ -395,12 +397,5 @@ public void onFsViewerConfig(FilesystemViewerData.Options dopt) {
public boolean isDividerVisible() {
return true;
}

@Override
public void onPause() {
super.onPause();
// Reset Password to ensure it's not stored as plaintext.
_as.getDefaultPreferencesEditor().remove(getContext().getString(R.string.pref_key__default_encryption_password)).commit();
}
}
}
20 changes: 14 additions & 6 deletions app/src/main/java/net/gsantner/markor/format/TextFormat.java
Expand Up @@ -36,18 +36,26 @@

public class TextFormat {
public static final int FORMAT_UNKNOWN = 0;
public static final int FORMAT_ZIMWIKI = R.id.action_format_zimwiki;
public static final int FORMAT_MARKDOWN = R.id.action_format_markdown;
public static final int FORMAT_PLAIN = R.id.action_format_plaintext;
public static final int FORMAT_TODOTXT = R.id.action_format_todotxt;
public static final int FORMAT_KEYVALUE = R.id.action_format_keyvalue;
public static final int FORMAT_ZIMWIKI = R.string.action_format_zimwiki;
public static final int FORMAT_MARKDOWN = R.string.action_format_markdown;
public static final int FORMAT_PLAIN = R.string.action_format_plaintext;
public static final int FORMAT_TODOTXT = R.string.action_format_todotxt;
public static final int FORMAT_KEYVALUE = R.string.action_format_keyvalue;

public final static MarkdownTextConverter CONVERTER_MARKDOWN = new MarkdownTextConverter();
public final static ZimWikiTextConverter CONVERTER_ZIMWIKI = new ZimWikiTextConverter();
public final static TodoTxtTextConverter CONVERTER_TODOTXT = new TodoTxtTextConverter();
public final static KeyValueConverter CONVERTER_KEYVALUE = new KeyValueConverter();
public final static PlaintextConverter CONVERTER_PLAINTEXT = new PlaintextConverter();
private final static TextConverter[] CONVERTERS = new TextConverter[]{CONVERTER_MARKDOWN, CONVERTER_TODOTXT, CONVERTER_ZIMWIKI, CONVERTER_KEYVALUE, CONVERTER_PLAINTEXT};

// Order here is used to **determine** format by it's file extension and/or content heading
private final static TextConverter[] CONVERTERS = new TextConverter[]{
CONVERTER_MARKDOWN,
CONVERTER_TODOTXT,
CONVERTER_ZIMWIKI,
CONVERTER_KEYVALUE,
CONVERTER_PLAINTEXT,
};

// Either pass file or null and absolutePath
public static boolean isTextFile(File file, String... absolutePath) {
Expand Down
Expand Up @@ -30,6 +30,7 @@
import net.gsantner.markor.ui.hleditor.HighlightingEditor;
import net.gsantner.markor.util.AppSettings;
import net.gsantner.markor.util.ContextUtils;
import net.gsantner.opoc.preference.SharedPreferencesPropertyBackend;
import net.gsantner.opoc.util.Callback;

import java.text.DateFormat;
Expand All @@ -47,10 +48,8 @@
import java.util.concurrent.atomic.AtomicReference;

public class DatetimeFormatDialog {

private static final String DATETIME_SETTINGS = "datetime_dialog_settings";
private static final String RECENT_FORMATS_STRING = "recent_formats_string";
private static final String RECENT_FORMATS_LENGTHS = "recent_formats_lengths";
private static final String RECENT_FORMATS_STRING = "datetimformat_dialog__recent_formats_string_history";
private static final String RECENT_FORMATS_LENGTHS = "datetimformat_dialog__recent_formats_lengths_history";

private static final int MAX_RECENT_FORMATS = 5;

Expand Down Expand Up @@ -299,7 +298,7 @@ private static void setToNow(final Calendar cal, boolean doIt) {
* @return List of Strings representing recently used formats
*/
private static List<String> getRecentFormats(final Activity activity) {
final SharedPreferences settings = activity.getSharedPreferences(DATETIME_SETTINGS, Context.MODE_PRIVATE);
final SharedPreferences settings = activity.getSharedPreferences(SharedPreferencesPropertyBackend.SHARED_PREF_APP, Context.MODE_PRIVATE);
final String combined = settings.getString(RECENT_FORMATS_STRING, null);
final String lengths = settings.getString(RECENT_FORMATS_LENGTHS, null);

Expand Down Expand Up @@ -346,7 +345,7 @@ private static void saveRecentFormats(final Activity activity, final List<String
lengths.add(Integer.toString(s.length()));
}

final SharedPreferences.Editor edit = activity.getSharedPreferences(DATETIME_SETTINGS, Context.MODE_PRIVATE).edit();
final SharedPreferences.Editor edit = activity.getSharedPreferences(SharedPreferencesPropertyBackend.SHARED_PREF_APP, Context.MODE_PRIVATE).edit();
edit.putString(RECENT_FORMATS_STRING, TextUtils.join("", formatSet)).apply();
edit.putString(RECENT_FORMATS_LENGTHS, TextUtils.join(",", lengths)).apply();
}
Expand Down
6 changes: 3 additions & 3 deletions app/src/main/java/net/gsantner/markor/ui/NewFileDialog.java
Expand Up @@ -45,7 +45,6 @@
import java.util.concurrent.atomic.AtomicBoolean;

import other.de.stanetz.jpencconverter.JavaPasswordbasedCryption;
import other.de.stanetz.jpencconverter.PasswordStore;

public class NewFileDialog extends DialogFragment {
public static final String FRAGMENT_TAG = "net.gsantner.markor.ui.NewFileDialog";
Expand Down Expand Up @@ -94,7 +93,7 @@ private AlertDialog.Builder makeDialog(final File basedir, final boolean allowCr
final Spinner templateSpinner = root.findViewById(R.id.new_file_dialog__template);
final String[] typeSpinnerToExtension = getResources().getStringArray(R.array.new_file_types__file_extension);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && appSettings.hasPasswordBeenSetOnce()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && appSettings.isDefaultPasswordSet()) {
encryptCheckbox.setChecked(appSettings.getNewFileDialogLastUsedEncryption());
} else {
encryptCheckbox.setVisibility(View.GONE);
Expand Down Expand Up @@ -279,7 +278,8 @@ private byte[] getTemplateContent(final Spinner templateSpinner, final File base
t = t.replace("{{ template.timestamp_date_yyyy_mm_dd }}", TodoTxtTask.DATEF_YYYY_MM_DD.format(new Date()));

if (encrypt && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
bytes = new JavaPasswordbasedCryption(Build.VERSION.SDK_INT, new SecureRandom()).encrypt(t, new PasswordStore(getContext()).loadKey(R.string.pref_key__default_encryption_password));
final char[] pass = new AppSettings(getContext()).getDefaultPassword();
bytes = new JavaPasswordbasedCryption(Build.VERSION.SDK_INT, new SecureRandom()).encrypt(t, pass);
} else {
bytes = t.getBytes();
}
Expand Down
Expand Up @@ -11,6 +11,7 @@

import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.support.v4.content.ContextCompat;
import android.text.Editable;
Expand All @@ -23,6 +24,7 @@
import android.text.style.StyleSpan;
import android.view.Gravity;
import android.view.WindowManager;
import android.widget.Toast;

import net.gsantner.markor.R;
import net.gsantner.markor.format.zimwiki.ZimWikiHighlighter;
Expand Down Expand Up @@ -441,6 +443,26 @@ public static void showPriorityDialog(Activity activity, char selectedPriority,
SearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt);
}

public static void showSetPasswordDialog(final Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
final AppSettings as = new AppSettings(activity.getApplicationContext());
final SearchOrCustomTextDialog.DialogOptions dopt = new SearchOrCustomTextDialog.DialogOptions();
baseConf(activity, dopt);
dopt.isSearchEnabled = true;
dopt.titleText = R.string.file_encryption_password;
final boolean hasPassword = as.isDefaultPasswordSet();
dopt.messageText = hasPassword ? activity.getString(R.string.password_already_set_setting_a_new_password_will_overwrite) : "";
dopt.searchHintText = hasPassword ? R.string.hidden_password : R.string.empty_string;
dopt.callback = password -> {
if (!TextUtils.isEmpty(password)) {
AppSettings.get().setDefaultPassword(password);
Toast.makeText(activity, "✔️", Toast.LENGTH_SHORT).show();
}
};
SearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt);
}
}

public static void baseConf(Activity activity, SearchOrCustomTextDialog.DialogOptions dopt) {
AppSettings as = new AppSettings(activity);
dopt.isDarkDialog = as.isDarkThemeEnabled();
Expand Down
Expand Up @@ -26,6 +26,7 @@
import android.widget.TextView;

import net.gsantner.markor.R;
import net.gsantner.opoc.preference.SharedPreferencesPropertyBackend;
import net.gsantner.opoc.util.StringUtils;

import org.json.JSONArray;
Expand All @@ -41,9 +42,7 @@
import java.util.regex.Pattern;

public class SearchReplaceDialog {

private static final String SEARCH_REPLACE_SETTINGS = "search_replace_dialog_settings";
private static final String RECENT_SEARCH_REPLACE_STRING = "recent_search_replace";
private static final String RECENT_SEARCH_REPLACE_STRING = "search_replace_dialog__recent_search_replace_history";
private static final int MAX_RECENT_SEARCH_REPLACE = 10;

private final EditText searchText;
Expand Down Expand Up @@ -289,7 +288,7 @@ private List<ReplaceGroup> loadRecentReplaces() {
final List<ReplaceGroup> recents = new ArrayList<>();

try {
final SharedPreferences settings = _activity.getSharedPreferences(SEARCH_REPLACE_SETTINGS, Context.MODE_PRIVATE);
final SharedPreferences settings = _activity.getSharedPreferences(SharedPreferencesPropertyBackend.SHARED_PREF_APP, Context.MODE_PRIVATE);
final String jsonString = settings.getString(RECENT_SEARCH_REPLACE_STRING, "");
if (jsonString.length() > 0) {
final JSONArray array = new JSONArray(jsonString);
Expand Down Expand Up @@ -335,7 +334,7 @@ private void saveRecentReplace() {
array.put(rg.toJson());
}

final SharedPreferences.Editor edit = _activity.getSharedPreferences(SEARCH_REPLACE_SETTINGS, Context.MODE_PRIVATE).edit();
final SharedPreferences.Editor edit = _activity.getSharedPreferences(SharedPreferencesPropertyBackend.SHARED_PREF_APP, Context.MODE_PRIVATE).edit();
edit.putString(RECENT_SEARCH_REPLACE_STRING, array.toString()).apply();
}

Expand Down
Expand Up @@ -59,7 +59,7 @@ public abstract class TextActions {
private int _textActionSidePadding;
protected int _indent;

private static final String ACTION_ORDER_PREF_NAME = "action_order";
public static final String ACTION_ORDER_PREF_NAME = "action_order";
private static final String ORDER_SUFFIX = "_order";
private static final String DISABLED_SUFFIX = "_disabled";

Expand Down