Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/stefan-niedermann/nextcloud-notes.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Niedermann <info@niedermann.it>2020-06-08 23:01:56 +0300
committerStefan Niedermann <info@niedermann.it>2020-06-08 23:01:56 +0300
commit474d9c3a8a106a3bd3338410da1ec79d74897a82 (patch)
treeaf4c2c4e1836b48f01ae74199b65651378a07eb6 /app/src/main
parentaeda3b84f5a705b35896ca157fd86537def89111 (diff)
parent2e2bbb9be5cb56f9d12ddea3a464edab5976c560 (diff)
Merge branch 'master' into api-v1
# Conflicts: # app/src/androidTest/java/it/niedermann/owncloud/notes/persistence/NotesDatabaseTest.java # app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NoteEditFragment.java # app/src/main/java/it/niedermann/owncloud/notes/persistence/AbstractNotesDatabase.java # app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java # app/src/main/java/it/niedermann/owncloud/notes/util/NoteUtil.java
Diffstat (limited to 'app/src/main')
-rw-r--r--app/src/main/AndroidManifest.xml6
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/android/activity/NotesListViewActivity.java15
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/android/fragment/BaseNoteFragment.java56
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NoteEditFragment.java11
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NotePreviewFragment.java8
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NoteReadonlyFragment.java3
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/android/fragment/SearchableBaseNoteFragment.java3
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/formattinghelp/FormattingHelpActivity.java242
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/model/DBNote.java12
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/AbstractNotesDatabase.java442
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/NoteServerSyncHelper.java2
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java82
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_10_11.java31
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_11_12.java21
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_12_13.java20
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_13_14.java78
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_14_15.java83
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_15_16.java103
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_16_17.java15
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_4_5.java18
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_5_6.java14
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_6_7.java19
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_7_8.java28
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_8_9.java127
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_9_10.java26
-rw-r--r--app/src/main/java/it/niedermann/owncloud/notes/util/NoteUtil.java17
-rw-r--r--app/src/main/res/drawable/ic_baseline_help_outline_24.xml5
-rw-r--r--app/src/main/res/layout/activity_formatting_help.xml43
-rw-r--r--app/src/main/res/layout/fragment_note_edit.xml9
-rw-r--r--app/src/main/res/values-ca/strings.xml5
-rw-r--r--app/src/main/res/values-cs-rCZ/strings.xml11
-rw-r--r--app/src/main/res/values-da/strings.xml6
-rw-r--r--app/src/main/res/values-de/strings.xml11
-rw-r--r--app/src/main/res/values-el/strings.xml7
-rw-r--r--app/src/main/res/values-es/strings.xml7
-rw-r--r--app/src/main/res/values-eu/strings.xml6
-rw-r--r--app/src/main/res/values-fa/strings.xml5
-rw-r--r--app/src/main/res/values-fi-rFI/strings.xml5
-rw-r--r--app/src/main/res/values-fr/strings.xml11
-rw-r--r--app/src/main/res/values-gl/strings.xml11
-rw-r--r--app/src/main/res/values-he/strings.xml6
-rw-r--r--app/src/main/res/values-hr/strings.xml6
-rw-r--r--app/src/main/res/values-hu-rHU/strings.xml6
-rw-r--r--app/src/main/res/values-it/strings.xml11
-rw-r--r--app/src/main/res/values-ja-rJP/strings.xml6
-rw-r--r--app/src/main/res/values-lt-rLT/strings.xml5
-rw-r--r--app/src/main/res/values-nl/strings.xml7
-rw-r--r--app/src/main/res/values-pl/strings.xml11
-rw-r--r--app/src/main/res/values-pt-rBR/strings.xml7
-rw-r--r--app/src/main/res/values-ru/strings.xml6
-rw-r--r--app/src/main/res/values-sk-rSK/strings.xml11
-rw-r--r--app/src/main/res/values-sl/strings.xml6
-rw-r--r--app/src/main/res/values-sr/strings.xml6
-rw-r--r--app/src/main/res/values-sv/strings.xml6
-rw-r--r--app/src/main/res/values-tr/strings.xml7
-rw-r--r--app/src/main/res/values-zh-rCN/strings.xml5
-rw-r--r--app/src/main/res/values-zh-rTW/strings.xml4
-rw-r--r--app/src/main/res/values/strings.xml58
-rw-r--r--app/src/main/res/xml/preferences.xml30
59 files changed, 1335 insertions, 493 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index fc42c3cf..f3117ead 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -63,6 +63,12 @@
android:label="@string/app_name" />
<activity
+ android:name=".formattinghelp.FormattingHelpActivity"
+ android:label="@string/action_formatting_help"
+ android:parentActivityName=".android.activity.NotesListViewActivity"
+ android:windowSoftInputMode="stateHidden" />
+
+ <activity
android:name=".manageaccounts.ManageAccountsActivity"
android:label="@string/manage_accounts"
android:parentActivityName=".android.activity.NotesListViewActivity"
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/android/activity/NotesListViewActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/android/activity/NotesListViewActivity.java
index 6efa0ce6..3daf809a 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/android/activity/NotesListViewActivity.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/android/activity/NotesListViewActivity.java
@@ -58,6 +58,7 @@ import it.niedermann.owncloud.notes.branding.BrandedSnackbar;
import it.niedermann.owncloud.notes.branding.BrandingUtil;
import it.niedermann.owncloud.notes.databinding.ActivityNotesListViewBinding;
import it.niedermann.owncloud.notes.databinding.DrawerLayoutBinding;
+import it.niedermann.owncloud.notes.formattinghelp.FormattingHelpActivity;
import it.niedermann.owncloud.notes.model.Capabilities;
import it.niedermann.owncloud.notes.model.Category;
import it.niedermann.owncloud.notes.model.DBNote;
@@ -83,6 +84,7 @@ import static android.view.View.VISIBLE;
import static it.niedermann.owncloud.notes.branding.BrandingUtil.getSecondaryForegroundColorDependingOnTheme;
import static it.niedermann.owncloud.notes.util.ColorUtil.contrastRatioIsSufficient;
import static it.niedermann.owncloud.notes.util.SSOUtil.askForNewAccount;
+import static java.util.Arrays.asList;
public class NotesListViewActivity extends LockedActivity implements NoteClickListener, ViewProvider, MoveAccountListener, AccountSwitcherListener {
@@ -555,19 +557,18 @@ public class NotesListViewActivity extends LockedActivity implements NoteClickLi
}
private void setupNavigationMenu() {
+ final NavigationItem itemFormattingHelp = new NavigationItem("formattingHelp", getString(R.string.action_formatting_help), null, R.drawable.ic_baseline_help_outline_24);
final NavigationItem itemTrashbin = new NavigationItem("trashbin", getString(R.string.action_trashbin), null, R.drawable.ic_delete_grey600_24dp);
final NavigationItem itemSettings = new NavigationItem("settings", getString(R.string.action_settings), null, R.drawable.ic_settings_grey600_24dp);
final NavigationItem itemAbout = new NavigationItem("about", getString(R.string.simple_about), null, R.drawable.ic_info_outline_grey600_24dp);
- ArrayList<NavigationItem> itemsMenu = new ArrayList<>(3);
- itemsMenu.add(itemTrashbin);
- itemsMenu.add(itemSettings);
- itemsMenu.add(itemAbout);
-
NavigationAdapter adapterMenu = new NavigationAdapter(this, new NavigationAdapter.ClickListener() {
@Override
public void onItemClick(NavigationItem item) {
- if (itemSettings.equals(item)) {
+ if (itemFormattingHelp.equals(item)) {
+ Intent formattingHelpIntent = new Intent(getApplicationContext(), FormattingHelpActivity.class);
+ startActivity(formattingHelpIntent);
+ } else if (itemSettings.equals(item)) {
Intent settingsIntent = new Intent(getApplicationContext(), PreferencesActivity.class);
startActivityForResult(settingsIntent, server_settings);
} else if (itemAbout.equals(item)) {
@@ -583,7 +584,7 @@ public class NotesListViewActivity extends LockedActivity implements NoteClickLi
onItemClick(item);
}
});
- adapterMenu.setItems(itemsMenu);
+ adapterMenu.setItems(asList(itemFormattingHelp, itemTrashbin, itemSettings, itemAbout));
binding.navigationMenu.setAdapter(adapterMenu);
}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/BaseNoteFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/BaseNoteFragment.java
index 9dcfe7ef..3bf49023 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/BaseNoteFragment.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/BaseNoteFragment.java
@@ -3,7 +3,6 @@ package it.niedermann.owncloud.notes.android.fragment;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
-import android.content.SharedPreferences;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.graphics.Color;
@@ -14,6 +13,8 @@ import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
+import android.view.View;
+import android.widget.ScrollView;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
@@ -66,8 +67,10 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego
private SingleSignOnAccount ssoAccount;
protected DBNote note;
+ // TODO do we really need this? The reference to note is currently the same
@Nullable
private DBNote originalNote;
+ private int originalScrollY;
protected NotesDatabase db;
private NoteFragmentListener listener;
private boolean titleModified = false;
@@ -99,7 +102,7 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego
if (content == null) {
throw new IllegalArgumentException(PARAM_NOTE_ID + " is not given, argument " + PARAM_NEWNOTE + " is missing and " + PARAM_CONTENT + " is missing.");
} else {
- note = new DBNote(-1, -1, null, NoteUtil.generateNoteTitle(content), content, false, getString(R.string.category_readonly), null, DBStatus.VOID, -1, "");
+ note = new DBNote(-1, -1, null, NoteUtil.generateNoteTitle(content), content, false, getString(R.string.category_readonly), null, DBStatus.VOID, -1, "", 0);
}
} else {
note = db.getNote(localAccount.getId(), db.addNoteAndSync(ssoAccount, localAccount.getId(), cloudNote));
@@ -116,6 +119,32 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego
}
}
+ @Nullable
+ protected abstract ScrollView getScrollView();
+
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ final ScrollView scrollView = getScrollView();
+ if (scrollView != null) {
+ scrollView.getViewTreeObserver().addOnScrollChangedListener(() -> {
+ if (scrollView.getScrollY() > 0) {
+ note.setScrollY(scrollView.getScrollY());
+ }
+ });
+ }
+ }
+
+ @Override
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ final ScrollView scrollView = getScrollView();
+ if (scrollView != null) {
+ this.originalScrollY = note.getScrollY();
+ scrollView.post(() -> scrollView.scrollTo(0, originalScrollY));
+ }
+ }
+
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
@@ -269,7 +298,12 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego
if (note != null) {
String newContent = getContent();
if (note.getContent().equals(newContent)) {
- Log.v(TAG, "... not saving, since nothing has changed");
+ if (note.getScrollY() != originalScrollY) {
+ Log.v(TAG, "... only saving new scroll state, since content did not change");
+ db.updateScrollY(note.getId(), note.getScrollY());
+ } else {
+ Log.v(TAG, "... not saving, since nothing has changed");
+ }
} else {
note = db.updateNoteAndSync(ssoAccount, localAccount, note, newContent, callback);
listener.onNoteUpdated(note);
@@ -280,22 +314,6 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego
}
}
- @SuppressWarnings("WeakerAccess") //PMD...
- protected float getFontSizeFromPreferences(SharedPreferences sp) {
- final String prefValueSmall = getString(R.string.pref_value_font_size_small);
- final String prefValueMedium = getString(R.string.pref_value_font_size_medium);
- // final String prefValueLarge = getString(R.string.pref_value_font_size_large);
- String fontSize = sp.getString(getString(R.string.pref_key_font_size), prefValueMedium);
-
- if (fontSize.equals(prefValueSmall)) {
- return getResources().getDimension(R.dimen.note_font_size_small);
- } else if (fontSize.equals(prefValueMedium)) {
- return getResources().getDimension(R.dimen.note_font_size_medium);
- } else {
- return getResources().getDimension(R.dimen.note_font_size_large);
- }
- }
-
protected abstract String getContent();
/**
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NoteEditFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NoteEditFragment.java
index b1125092..1a1ab089 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NoteEditFragment.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NoteEditFragment.java
@@ -41,6 +41,7 @@ import it.niedermann.owncloud.notes.util.format.ContextBasedRangeFormattingCallb
import static androidx.core.view.ViewCompat.isAttachedToWindow;
import static it.niedermann.owncloud.notes.util.DisplayUtils.searchAndColor;
+import static it.niedermann.owncloud.notes.util.NoteUtil.getFontSizeFromPreferences;
public class NoteEditFragment extends SearchableBaseNoteFragment {
@@ -149,11 +150,11 @@ public class NoteEditFragment extends SearchableBaseNoteFragment {
requireActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
- InputMethodManager imm = (InputMethodManager) requireContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ final InputMethodManager imm = (InputMethodManager) requireContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.showSoftInput(getView(), InputMethodManager.SHOW_IMPLICIT);
} else {
- Log.w(TAG, "InputMethodManager is null");
+ Log.e(TAG, InputMethodManager.class.getSimpleName() + " is null.");
}
}
@@ -163,7 +164,7 @@ public class NoteEditFragment extends SearchableBaseNoteFragment {
binding.editContent.setText(note.getContent());
binding.editContent.setEnabled(true);
- MarkdownProcessor markdownProcessor = new MarkdownProcessor(requireContext());
+ final MarkdownProcessor markdownProcessor = new MarkdownProcessor(requireContext());
markdownProcessor.config(MarkDownUtil.getMarkDownConfiguration(binding.editContent.getContext()).build());
markdownProcessor.factory(EditFactory.create());
markdownProcessor.live(binding.editContent);
@@ -172,8 +173,8 @@ public class NoteEditFragment extends SearchableBaseNoteFragment {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
binding.editContent.setCustomInsertionActionModeCallback(new ContextBasedFormattingCallback(binding.editContent));
}
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(requireContext().getApplicationContext());
- binding.editContent.setTextSize(TypedValue.COMPLEX_UNIT_PX, getFontSizeFromPreferences(sp));
+ final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(requireContext().getApplicationContext());
+ binding.editContent.setTextSize(TypedValue.COMPLEX_UNIT_PX, getFontSizeFromPreferences(requireContext(), sp));
if (sp.getBoolean(getString(R.string.pref_key_font), false)) {
binding.editContent.setTypeface(Typeface.MONOSPACE);
}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NotePreviewFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NotePreviewFragment.java
index 8aa258b8..751cf474 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NotePreviewFragment.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NotePreviewFragment.java
@@ -48,6 +48,7 @@ import static it.niedermann.owncloud.notes.util.MarkDownUtil.CHECKBOX_UNCHECKED_
import static it.niedermann.owncloud.notes.util.MarkDownUtil.parseCompat;
import static it.niedermann.owncloud.notes.util.NoteLinksUtils.extractNoteRemoteId;
import static it.niedermann.owncloud.notes.util.NoteLinksUtils.replaceNoteLinksWithDummyUrls;
+import static it.niedermann.owncloud.notes.util.NoteUtil.getFontSizeFromPreferences;
public class NotePreviewFragment extends SearchableBaseNoteFragment implements OnRefreshListener {
@@ -117,8 +118,13 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O
* When (un)checking a checkbox in a note which contains code-blocks, the "`"-characters get stripped out in the TextView and therefore the given lineNumber is wrong
* Find number of lines starting with ``` before lineNumber
*/
+ boolean inCodefence = false;
for (int i = 0; i < lines.length; i++) {
if (lines[i].startsWith("```")) {
+ inCodefence = !inCodefence;
+ lineNumber++;
+ }
+ if (inCodefence && TextUtils.isEmpty(lines[i])) {
lineNumber++;
}
if (i == lineNumber) {
@@ -175,7 +181,7 @@ public class NotePreviewFragment extends SearchableBaseNoteFragment implements O
binding.swiperefreshlayout.setOnRefreshListener(this);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(requireActivity().getApplicationContext());
- binding.singleNoteContent.setTextSize(TypedValue.COMPLEX_UNIT_PX, getFontSizeFromPreferences(sp));
+ binding.singleNoteContent.setTextSize(TypedValue.COMPLEX_UNIT_PX, getFontSizeFromPreferences(requireContext(), sp));
if (sp.getBoolean(getString(R.string.pref_key_font), false)) {
binding.singleNoteContent.setTypeface(Typeface.MONOSPACE);
}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NoteReadonlyFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NoteReadonlyFragment.java
index fe8b5273..18607c90 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NoteReadonlyFragment.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/NoteReadonlyFragment.java
@@ -36,6 +36,7 @@ import it.niedermann.owncloud.notes.util.NoteLinksUtils;
import static androidx.core.view.ViewCompat.isAttachedToWindow;
import static it.niedermann.owncloud.notes.util.DisplayUtils.searchAndColor;
import static it.niedermann.owncloud.notes.util.MarkDownUtil.parseCompat;
+import static it.niedermann.owncloud.notes.util.NoteUtil.getFontSizeFromPreferences;
public class NoteReadonlyFragment extends SearchableBaseNoteFragment {
@@ -130,7 +131,7 @@ public class NoteReadonlyFragment extends SearchableBaseNoteFragment {
binding.swiperefreshlayout.setEnabled(false);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(requireActivity().getApplicationContext());
- binding.singleNoteContent.setTextSize(TypedValue.COMPLEX_UNIT_PX, getFontSizeFromPreferences(sp));
+ binding.singleNoteContent.setTextSize(TypedValue.COMPLEX_UNIT_PX, getFontSizeFromPreferences(requireContext(), sp));
if (sp.getBoolean(getString(R.string.pref_key_font), false)) {
binding.singleNoteContent.setTypeface(Typeface.MONOSPACE);
}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/SearchableBaseNoteFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/SearchableBaseNoteFragment.java
index f0949432..be0cafd7 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/SearchableBaseNoteFragment.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/SearchableBaseNoteFragment.java
@@ -11,7 +11,6 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.LinearLayout;
-import android.widget.ScrollView;
import androidx.annotation.CallSuper;
import androidx.annotation.ColorInt;
@@ -201,8 +200,6 @@ public abstract class SearchableBaseNoteFragment extends BaseNoteFragment {
protected abstract void colorWithText(@NonNull String newText, @Nullable Integer current, int mainColor, int textColor);
- protected abstract ScrollView getScrollView();
-
protected abstract Layout getLayout();
protected abstract FloatingActionButton getSearchNextButton();
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/formattinghelp/FormattingHelpActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/formattinghelp/FormattingHelpActivity.java
new file mode 100644
index 00000000..04a4a5a3
--- /dev/null
+++ b/app/src/main/java/it/niedermann/owncloud/notes/formattinghelp/FormattingHelpActivity.java
@@ -0,0 +1,242 @@
+package it.niedermann.owncloud.notes.formattinghelp;
+
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.graphics.Typeface;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.text.method.LinkMovementMethod;
+import android.util.TypedValue;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.preference.PreferenceManager;
+
+import com.yydcdut.markdown.MarkdownProcessor;
+import com.yydcdut.markdown.syntax.text.TextFactory;
+
+import it.niedermann.owncloud.notes.R;
+import it.niedermann.owncloud.notes.branding.BrandedActivity;
+import it.niedermann.owncloud.notes.databinding.ActivityFormattingHelpBinding;
+
+import static it.niedermann.owncloud.notes.util.MarkDownUtil.CHECKBOX_CHECKED_MINUS;
+import static it.niedermann.owncloud.notes.util.MarkDownUtil.CHECKBOX_CHECKED_STAR;
+import static it.niedermann.owncloud.notes.util.MarkDownUtil.CHECKBOX_UNCHECKED_MINUS;
+import static it.niedermann.owncloud.notes.util.MarkDownUtil.CHECKBOX_UNCHECKED_STAR;
+import static it.niedermann.owncloud.notes.util.MarkDownUtil.getMarkDownConfiguration;
+import static it.niedermann.owncloud.notes.util.MarkDownUtil.parseCompat;
+import static it.niedermann.owncloud.notes.util.NoteUtil.getFontSizeFromPreferences;
+
+public class FormattingHelpActivity extends BrandedActivity {
+
+ private ActivityFormattingHelpBinding binding;
+ private String content;
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ binding = ActivityFormattingHelpBinding.inflate(getLayoutInflater());
+ setContentView(binding.getRoot());
+
+ setSupportActionBar(binding.toolbar);
+
+ content = buildFormattingHelp();
+
+ final MarkdownProcessor markdownProcessor = new MarkdownProcessor(this);
+ markdownProcessor.factory(TextFactory.create());
+ markdownProcessor.config(getMarkDownConfiguration(binding.content.getContext())
+ .setOnTodoClickCallback((view, line, lineNumber) -> {
+ try {
+ String[] lines = TextUtils.split(content, "\\r?\\n");
+ /*
+ * Workaround for RxMarkdown-bug:
+ * When (un)checking a checkbox in a note which contains code-blocks, the "`"-characters get stripped out in the TextView and therefore the given lineNumber is wrong
+ * Find number of lines starting with ``` before lineNumber
+ */
+ boolean inCodefence = false;
+ for (int i = 0; i < lines.length; i++) {
+ if (lines[i].startsWith("```")) {
+ inCodefence = !inCodefence;
+ lineNumber++;
+ }
+ if (inCodefence && TextUtils.isEmpty(lines[i])) {
+ lineNumber++;
+ }
+ if (i == lineNumber) {
+ break;
+ }
+ }
+
+ /*
+ * Workaround for multiple RxMarkdown-bugs:
+ * When (un)checking a checkbox which is in the last line, every time it gets toggled, the last character of the line gets lost.
+ * When (un)checking a checkbox, every markdown gets stripped in the given line argument
+ */
+ if (lines[lineNumber].startsWith(CHECKBOX_UNCHECKED_MINUS) || lines[lineNumber].startsWith(CHECKBOX_UNCHECKED_STAR)) {
+ lines[lineNumber] = lines[lineNumber].replace(CHECKBOX_UNCHECKED_MINUS, CHECKBOX_CHECKED_MINUS);
+ lines[lineNumber] = lines[lineNumber].replace(CHECKBOX_UNCHECKED_STAR, CHECKBOX_CHECKED_STAR);
+ } else {
+ lines[lineNumber] = lines[lineNumber].replace(CHECKBOX_CHECKED_MINUS, CHECKBOX_UNCHECKED_MINUS);
+ lines[lineNumber] = lines[lineNumber].replace(CHECKBOX_CHECKED_STAR, CHECKBOX_UNCHECKED_STAR);
+ }
+
+ content = TextUtils.join("\n", lines);
+ binding.content.setText(parseCompat(markdownProcessor, content));
+ } catch (IndexOutOfBoundsException e) {
+ Toast.makeText(this, R.string.checkbox_could_not_be_toggled, Toast.LENGTH_SHORT).show();
+ e.printStackTrace();
+ }
+ return line;
+ }
+ )
+ .setOnLinkClickCallback((view, link) -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(link))))
+ .build());
+ binding.content.setMovementMethod(LinkMovementMethod.getInstance());
+ binding.content.setText(parseCompat(markdownProcessor, content));
+
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
+ binding.content.setTextSize(TypedValue.COMPLEX_UNIT_PX, getFontSizeFromPreferences(this, sp));
+ if (sp.getBoolean(getString(R.string.pref_key_font), false)) {
+ binding.content.setTypeface(Typeface.MONOSPACE);
+ }
+ }
+
+ @NonNull
+ private String buildFormattingHelp() {
+ final String lineBreak = "\n";
+ final String indention = " ";
+ final String divider = getString(R.string.formatting_help_divider);
+ final String codefence = getString(R.string.formatting_help_codefence);
+
+ final String lists = getString(R.string.formatting_help_lists_body_1) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_lists_body_2) + lineBreak +
+ getString(R.string.formatting_help_lists_body_3) + lineBreak +
+ getString(R.string.formatting_help_lists_body_4) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_lists_body_5) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_lists_body_6) + lineBreak +
+ getString(R.string.formatting_help_lists_body_7) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_lists_body_8) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_lists_body_9) + lineBreak +
+ getString(R.string.formatting_help_lists_body_10) + lineBreak +
+ indention + getString(R.string.formatting_help_lists_body_11) + lineBreak +
+ indention + getString(R.string.formatting_help_lists_body_12) + lineBreak;
+
+ final String checkboxes = getString(R.string.formatting_help_checkboxes_body_1) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_checkboxes_body_2) + lineBreak +
+ getString(R.string.formatting_help_checkboxes_body_3) + lineBreak;
+
+ final String structuredDocuments = getString(R.string.formatting_help_structured_documents_body_1) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_structured_documents_body_2) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_structured_documents_body_3) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_structured_documents_body_4) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_structured_documents_body_5) + lineBreak +
+ getString(R.string.formatting_help_structured_documents_body_6) + lineBreak;
+
+ final String javascript = getString(R.string.formatting_help_javascript_1) + lineBreak +
+ indention + indention + getString(R.string.formatting_help_javascript_2) + lineBreak +
+ getString(R.string.formatting_help_javascript_3) + lineBreak;
+
+ return getString(R.string.formatting_help_title, getString(R.string.formatting_help_cbf_title)) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_cbf_body_1) + lineBreak +
+ getString(R.string.formatting_help_cbf_body_2) + lineBreak +
+ lineBreak +
+ divider + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_title, getString(R.string.formatting_help_text_title)) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_text_body) + lineBreak +
+ lineBreak +
+ codefence + lineBreak +
+ getString(R.string.formatting_help_text_body) + lineBreak +
+ codefence + lineBreak +
+ lineBreak +
+ divider + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_title, getString(R.string.formatting_help_lists_title)) + lineBreak +
+ lineBreak +
+ lists +
+ lineBreak +
+ codefence + lineBreak +
+ lists +
+ codefence + lineBreak +
+ lineBreak +
+ divider + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_title, getString(R.string.formatting_help_checkboxes_title)) + lineBreak +
+ lineBreak +
+ checkboxes +
+ lineBreak +
+ codefence + lineBreak +
+ checkboxes +
+ codefence + lineBreak +
+ lineBreak +
+ divider + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_title, getString(R.string.formatting_help_structured_documents_title)) + lineBreak +
+ lineBreak +
+ structuredDocuments +
+ lineBreak +
+ codefence + lineBreak +
+ structuredDocuments +
+ codefence + lineBreak +
+ lineBreak +
+ divider + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_title, getString(R.string.formatting_help_code_title)) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_code_body_1) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_code_body_2) + lineBreak +
+ getString(R.string.formatting_help_code_body_3) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_code_body_4) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_codefence_escaped) + lineBreak +
+ javascript +
+ getString(R.string.formatting_help_codefence_escaped) + lineBreak +
+ lineBreak +
+ codefence + lineBreak +
+ javascript +
+ codefence + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_code_body_5) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_codefence_javascript_escaped) + lineBreak +
+ javascript +
+ getString(R.string.formatting_help_codefence_escaped) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_codefence_javascript) + lineBreak +
+ javascript +
+ codefence + lineBreak +
+ lineBreak +
+ divider + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_title, getString(R.string.formatting_help_unsupported_title)) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_unsupported_body_1) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_unsupported_body_2) + lineBreak +
+ getString(R.string.formatting_help_unsupported_body_3) + lineBreak +
+ lineBreak +
+ getString(R.string.formatting_help_unsupported_body_4) + lineBreak;
+ }
+
+ @Override
+ public void applyBrand(int mainColor, int textColor) {
+
+ }
+}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/model/DBNote.java b/app/src/main/java/it/niedermann/owncloud/notes/model/DBNote.java
index aeb67031..d2be6aa2 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/model/DBNote.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/model/DBNote.java
@@ -15,13 +15,15 @@ public class DBNote extends CloudNote implements Item, Serializable {
private final long accountId;
private DBStatus status;
private String excerpt;
+ private int scrollY;
- public DBNote(long id, long remoteId, Calendar modified, String title, String content, boolean favorite, String category, String etag, DBStatus status, long accountId, String excerpt) {
+ public DBNote(long id, long remoteId, Calendar modified, String title, String content, boolean favorite, String category, String etag, DBStatus status, long accountId, String excerpt, int scrollY) {
super(remoteId, modified, title, content, favorite, category, etag);
this.id = id;
this.excerpt = excerpt;
this.status = status;
this.accountId = accountId;
+ this.scrollY = scrollY;
}
public long getId() {
@@ -67,4 +69,12 @@ public class DBNote extends CloudNote implements Item, Serializable {
", excerpt='" + excerpt + '\'' +
'}';
}
+
+ public int getScrollY() {
+ return scrollY;
+ }
+
+ public void setScrollY(int scrollY) {
+ this.scrollY = scrollY;
+ }
}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/AbstractNotesDatabase.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/AbstractNotesDatabase.java
index 13a37b93..057fb598 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/AbstractNotesDatabase.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/AbstractNotesDatabase.java
@@ -1,38 +1,30 @@
package it.niedermann.owncloud.notes.persistence;
-import android.appwidget.AppWidgetManager;
-import android.content.ComponentName;
-import android.content.ContentValues;
import android.content.Context;
-import android.content.SharedPreferences;
-import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
-import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.preference.PreferenceManager;
-import androidx.work.WorkManager;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Hashtable;
-import java.util.Map;
-
-import it.niedermann.owncloud.notes.android.DarkModeSetting;
-import it.niedermann.owncloud.notes.android.appwidget.NoteListWidget;
-import it.niedermann.owncloud.notes.android.appwidget.SingleNoteWidget;
-import it.niedermann.owncloud.notes.model.DBStatus;
+import it.niedermann.owncloud.notes.persistence.migration.Migration_10_11;
+import it.niedermann.owncloud.notes.persistence.migration.Migration_11_12;
+import it.niedermann.owncloud.notes.persistence.migration.Migration_12_13;
+import it.niedermann.owncloud.notes.persistence.migration.Migration_13_14;
+import it.niedermann.owncloud.notes.persistence.migration.Migration_14_15;
+import it.niedermann.owncloud.notes.persistence.migration.Migration_15_16;
+import it.niedermann.owncloud.notes.persistence.migration.Migration_16_17;
+import it.niedermann.owncloud.notes.persistence.migration.Migration_4_5;
+import it.niedermann.owncloud.notes.persistence.migration.Migration_5_6;
+import it.niedermann.owncloud.notes.persistence.migration.Migration_6_7;
+import it.niedermann.owncloud.notes.persistence.migration.Migration_7_8;
+import it.niedermann.owncloud.notes.persistence.migration.Migration_8_9;
+import it.niedermann.owncloud.notes.persistence.migration.Migration_9_10;
import it.niedermann.owncloud.notes.util.DatabaseIndexUtil;
-import it.niedermann.owncloud.notes.util.NoteUtil;
-// Protected APIs
-@SuppressWarnings("WeakerAccess")
abstract class AbstractNotesDatabase extends SQLiteOpenHelper {
- private static final String TAG = AbstractNotesDatabase.class.getSimpleName();
- private static final int database_version = 16;
+ private static final int database_version = 17;
@NonNull
protected final Context context;
@@ -44,7 +36,6 @@ abstract class AbstractNotesDatabase extends SQLiteOpenHelper {
protected static final String table_widget_note_list = "WIDGET_NOTE_LISTS";
protected static final String key_id = "ID";
-
protected static final String key_url = "URL";
protected static final String key_account_name = "ACCOUNT_NAME";
protected static final String key_username = "USERNAME";
@@ -68,6 +59,7 @@ abstract class AbstractNotesDatabase extends SQLiteOpenHelper {
protected static final String key_category_account_id = "CATEGORY_ACCOUNT_ID";
protected static final String key_theme_mode = "THEME_MODE";
protected static final String key_mode = "MODE";
+ protected static final String key_scroll_y = "SCROLL_Y";
protected AbstractNotesDatabase(@NonNull Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory) {
super(context, name, factory, database_version);
@@ -107,6 +99,7 @@ abstract class AbstractNotesDatabase extends SQLiteOpenHelper {
key_category + " INTEGER, " +
key_etag + " TEXT," +
key_excerpt + " TEXT NOT NULL DEFAULT '', " +
+ key_scroll_y + " INTEGER DEFAULT 0, " +
"FOREIGN KEY(" + key_category + ") REFERENCES " + table_category + "(" + key_category_id + "), " +
"FOREIGN KEY(" + key_account_id + ") REFERENCES " + table_accounts + "(" + key_id + "))");
DatabaseIndexUtil.createIndex(db, table_notes, key_remote_id, key_account_id, key_status, key_favorite, key_category, key_modified);
@@ -160,377 +153,39 @@ abstract class AbstractNotesDatabase extends SQLiteOpenHelper {
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- if (oldVersion < 4) {
- recreateDatabase(db);
- return;
- }
- if (oldVersion < 5) {
- db.execSQL("ALTER TABLE NOTES ADD COLUMN REMOTEID INTEGER");
- db.execSQL("UPDATE NOTES SET REMOTEID=ID WHERE (REMOTEID IS NULL OR REMOTEID=0) AND STATUS!=?", new String[]{"LOCAL_CREATED"});
- db.execSQL("UPDATE NOTES SET REMOTEID=0, STATUS=? WHERE STATUS=?", new String[]{DBStatus.LOCAL_EDITED.getTitle(), "LOCAL_CREATED"});
- }
- if (oldVersion < 6) {
- db.execSQL("ALTER TABLE NOTES ADD COLUMN FAVORITE INTEGER DEFAULT 0");
- }
- if (oldVersion < 7) {
- DatabaseIndexUtil.dropIndexes(db);
- db.execSQL("ALTER TABLE NOTES ADD COLUMN CATEGORY TEXT NOT NULL DEFAULT ''");
- db.execSQL("ALTER TABLE NOTES ADD COLUMN ETAG TEXT");
- DatabaseIndexUtil.createIndex(db, "NOTES", "REMOTEID", "STATUS", "FAVORITE", "CATEGORY", "MODIFIED");
- }
- if (oldVersion < 8) {
- final String table_temp = "NOTES_TEMP";
- db.execSQL("CREATE TABLE " + table_temp + " ( " +
- "ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
- "REMOTEID INTEGER, " +
- "STATUS VARCHAR(50), " +
- "TITLE TEXT, " +
- "MODIFIED INTEGER DEFAULT 0, " +
- "CONTENT TEXT, " +
- "FAVORITE INTEGER DEFAULT 0, " +
- "CATEGORY TEXT NOT NULL DEFAULT '', " +
- "ETAG TEXT)");
- DatabaseIndexUtil.createIndex(db, table_temp, "REMOTEID", "STATUS", "FAVORITE", "CATEGORY", "MODIFIED");
- db.execSQL(String.format("INSERT INTO %s(%s,%s,%s,%s,%s,%s,%s,%s,%s) ", table_temp, "ID", "REMOTEID", "STATUS", "TITLE", "MODIFIED", "CONTENT", "FAVORITE", "CATEGORY", "ETAG")
- + String.format("SELECT %s,%s,%s,%s,strftime('%%s',%s),%s,%s,%s,%s FROM %s", "ID", "REMOTEID", "STATUS", "TITLE", "MODIFIED", "CONTENT", "FAVORITE", "CATEGORY", "ETAG", "NOTES"));
- db.execSQL("DROP TABLE NOTES");
- db.execSQL(String.format("ALTER TABLE %s RENAME TO %s", table_temp, "NOTES"));
- }
- if (oldVersion < 9) {
- // Create accounts table
- db.execSQL("CREATE TABLE ACCOUNTS ( " +
- "ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
- "URL TEXT, " +
- "USERNAME TEXT, " +
- "ACCOUNT_NAME TEXT UNIQUE, " +
- "ETAG TEXT, " +
- "MODIFIED INTEGER)");
- DatabaseIndexUtil.createIndex(db, "ACCOUNTS", "URL", "USERNAME", "ACCOUNT_NAME", "ETAG", "MODIFIED");
-
- // Add accountId to notes table
- db.execSQL("ALTER TABLE NOTES ADD COLUMN ACCOUNT_ID INTEGER NOT NULL DEFAULT 0");
- DatabaseIndexUtil.createIndex(db, "NOTES", "ACCOUNT_ID");
-
- // Migrate existing account from SharedPreferences
- SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
- String username = sharedPreferences.getString("settingsUsername", "");
- String url = sharedPreferences.getString("settingsUrl", "");
- if (!url.isEmpty() && url.endsWith("/")) {
- url = url.substring(0, url.length() - 1);
- try {
- String accountName = username + "@" + new URL(url).getHost();
-
- ContentValues migratedAccountValues = new ContentValues();
- migratedAccountValues.put("URL", url);
- migratedAccountValues.put("USERNAME", username);
- migratedAccountValues.put("ACCOUNT_NAME", accountName);
- db.insert("ACCOUNTS", null, migratedAccountValues);
-
- // After successful insertion of migrated account, set accountId to 1 in each note
- ContentValues values = new ContentValues();
- values.put("ACCOUNT_ID", 1);
- db.update("NOTES", values, "ACCOUNT_ID = ?", new String[]{"NULL"});
-
- // Add FOREIGN_KEY constraint
- final String table_temp = "NOTES_TEMP";
- db.execSQL(String.format("ALTER TABLE %s RENAME TO %s", "NOTES", table_temp));
-
- db.execSQL("CREATE TABLE NOTES ( " +
- "ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
- "REMOTEID INTEGER, " +
- "ACCOUNT_ID INTEGER, " +
- "STATUS VARCHAR(50), " +
- "TITLE TEXT, " +
- "MODIFIED INTEGER DEFAULT 0, " +
- "CONTENT TEXT, " +
- "FAVORITE INTEGER DEFAULT 0, " +
- "CATEGORY TEXT NOT NULL DEFAULT '', " +
- "ETAG TEXT," +
- "FOREIGN KEY(ACCOUNT_ID) REFERENCES ACCOUNTS(ID))");
- DatabaseIndexUtil.createIndex(db, "NOTES", "REMOTEID", "ACCOUNT_ID", "STATUS", "FAVORITE", "CATEGORY", "MODIFIED");
-
- db.execSQL(String.format("INSERT INTO %s(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) ", "NOTES", "ID", "ACCOUNT_ID", "REMOTEID", "STATUS", "TITLE", "MODIFIED", "CONTENT", "FAVORITE", "CATEGORY", "ETAG")
- + String.format("SELECT %s,%s,%s,%s,%s,%s,%s,%s,%s,%s FROM %s", "ID", values.get("ACCOUNT_ID"), "REMOTEID", "STATUS", "TITLE", "MODIFIED", "CONTENT", "FAVORITE", "CATEGORY", "ETAG", table_temp));
- db.execSQL(String.format("DROP TABLE %s;", table_temp));
-
- AppWidgetManager awm = AppWidgetManager.getInstance(context);
- SharedPreferences.Editor editor = sharedPreferences.edit();
-
- // Add accountId '1' to any existing (and configured) appwidgets
- int[] appWidgetIdsNLW = awm.getAppWidgetIds(new ComponentName(context, NoteListWidget.class));
- int[] appWidgetIdsSNW = awm.getAppWidgetIds(new ComponentName(context, SingleNoteWidget.class));
-
- final String WIDGET_MODE_KEY = "NLW_mode";
- final String ACCOUNT_ID_KEY = "NLW_account";
-
- for (int appWidgetId : appWidgetIdsNLW) {
- if (sharedPreferences.getInt(WIDGET_MODE_KEY + appWidgetId, -1) >= 0) {
- editor.putLong(ACCOUNT_ID_KEY + appWidgetId, 1);
- }
- }
-
- for (int appWidgetId : appWidgetIdsSNW) {
- if (sharedPreferences.getLong("single_note_widget" + appWidgetId, -1) >= 0) {
- editor.putLong("SNW_accountId" + appWidgetId, 1);
- }
- }
-
- notifyNotesChanged();
-
- // Clean up no longer needed SharedPreferences
- editor.remove("notes_last_etag");
- editor.remove("notes_last_modified");
- editor.remove("settingsUrl");
- editor.remove("settingsUsername");
- editor.remove("settingsPassword");
- editor.apply();
- } catch (MalformedURLException e) {
- Log.e(TAG, "Previous URL could not be parsed. Recreating database...");
- e.printStackTrace();
- recreateDatabase(db);
- return;
- }
- } else {
- Log.e(TAG, "Previous URL is empty or does not end with a '/' character. Recreating database...");
+ switch (oldVersion) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
recreateDatabase(db);
return;
- }
- }
- if (oldVersion < 10) {
- db.execSQL("ALTER TABLE NOTES ADD COLUMN EXCERPT INTEGER NOT NULL DEFAULT ''");
- Cursor cursor = db.query("NOTES", new String[]{"ID", "CONTENT", "TITLE"}, null, null, null, null, null, null);
- while (cursor.moveToNext()) {
- ContentValues values = new ContentValues();
- values.put("EXCERPT", NoteUtil.generateNoteExcerpt(cursor.getString(1), cursor.getString(2)));
- db.update("NOTES", values, "ID" + " = ? ", new String[]{cursor.getString(0)});
- }
- cursor.close();
- }
- if (oldVersion < 11) {
- SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
- SharedPreferences.Editor editor = sharedPreferences.edit();
- Map<String, ?> prefs = sharedPreferences.getAll();
- for (Map.Entry<String, ?> pref : prefs.entrySet()) {
- String key = pref.getKey();
- final String DARK_THEME_KEY = "NLW_darkTheme";
- if ("darkTheme".equals(key) || key.startsWith(DARK_THEME_KEY) || key.startsWith("SNW_darkTheme")) {
- Boolean darkTheme = (Boolean) pref.getValue();
- editor.putString(pref.getKey(), darkTheme ? DarkModeSetting.DARK.name() : DarkModeSetting.LIGHT.name());
- }
- }
- editor.apply();
- }
- if (oldVersion < 12) {
- db.execSQL("ALTER TABLE ACCOUNTS ADD COLUMN API_VERSION TEXT");
- db.execSQL("ALTER TABLE ACCOUNTS ADD COLUMN COLOR VARCHAR(6) NOT NULL DEFAULT '000000'");
- db.execSQL("ALTER TABLE ACCOUNTS ADD COLUMN TEXT_COLOR VARCHAR(6) NOT NULL DEFAULT '0082C9'");
- CapabilitiesWorker.update(context);
- }
- if (oldVersion < 13) {
- db.execSQL("ALTER TABLE ACCOUNTS ADD COLUMN CAPABILITIES_ETAG TEXT");
- WorkManager.getInstance(context.getApplicationContext()).cancelUniqueWork("it.niedermann.owncloud.notes.persistence.SyncWorker");
- WorkManager.getInstance(context.getApplicationContext()).cancelUniqueWork("SyncWorker");
- }
- if (oldVersion < 14) {
- // #754 Move single note widget preferences to database
- db.execSQL("CREATE TABLE WIDGET_SINGLE_NOTES ( " +
- "ID INTEGER PRIMARY KEY, " +
- "ACCOUNT_ID INTEGER, " +
- "NOTE_ID INTEGER, " +
- "THEME_MODE INTEGER NOT NULL, " +
- "FOREIGN KEY(ACCOUNT_ID) REFERENCES ACCOUNTS(ID), " +
- "FOREIGN KEY(NOTE_ID) REFERENCES NOTES(ID))");
-
- final String SP_WIDGET_KEY = "single_note_widget";
- final String SP_ACCOUNT_ID_KEY = "SNW_accountId";
- final String SP_DARK_THEME_KEY = "SNW_darkTheme";
- SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
- SharedPreferences.Editor editor = sharedPreferences.edit();
- Map<String, ?> prefs = sharedPreferences.getAll();
- for (Map.Entry<String, ?> pref : prefs.entrySet()) {
- final String key = pref.getKey();
- Integer widgetId = null;
- Long noteId = null;
- Long accountId = null;
- Integer themeMode = null;
- if (key != null && key.startsWith(SP_WIDGET_KEY)) {
- try {
- widgetId = Integer.parseInt(key.substring(SP_WIDGET_KEY.length()));
- noteId = (Long) pref.getValue();
- accountId = sharedPreferences.getLong(SP_ACCOUNT_ID_KEY + widgetId, -1);
-
- try {
- themeMode = DarkModeSetting.valueOf(sharedPreferences.getString(SP_DARK_THEME_KEY + widgetId, DarkModeSetting.SYSTEM_DEFAULT.name())).getModeId();
- } catch (ClassCastException e) {
- //DARK_THEME was a boolean in older versions of the app. We thereofre have to still support the old setting.
- themeMode = sharedPreferences.getBoolean(SP_DARK_THEME_KEY + widgetId, false) ? DarkModeSetting.DARK.getModeId() : DarkModeSetting.LIGHT.getModeId();
- }
-
- ContentValues migratedWidgetValues = new ContentValues();
- migratedWidgetValues.put("ID", widgetId);
- migratedWidgetValues.put("ACCOUNT_ID", accountId);
- migratedWidgetValues.put("NOTE_ID", noteId);
- migratedWidgetValues.put("THEME_MODE", themeMode);
- db.insert("WIDGET_SINGLE_NOTES", null, migratedWidgetValues);
- } catch (Throwable t) {
- Log.e(TAG, "Could not migrate widget {widgetId: " + widgetId + ", accountId: " + accountId + ", noteId: " + noteId + ", themeMode: " + themeMode + "}");
- t.printStackTrace();
- } finally {
- // Clean up old shared preferences
- editor.remove(SP_WIDGET_KEY + widgetId);
- editor.remove(SP_DARK_THEME_KEY + widgetId);
- editor.remove(SP_ACCOUNT_ID_KEY + widgetId);
- }
- }
- }
- editor.apply();
- notifyNotesChanged();
- }
- if (oldVersion < 15) {
- // #814 normalize database (move category from string field to own table)
- // Rename a tmp_NOTES table.
- String tmpTableNotes = String.format("tmp_%s", "NOTES");
- db.execSQL("ALTER TABLE NOTES RENAME TO " + tmpTableNotes);
- db.execSQL("CREATE TABLE NOTES ( " +
- "ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
- "REMOTEID INTEGER, " +
- "ACCOUNT_ID INTEGER, " +
- "STATUS VARCHAR(50), " +
- "TITLE TEXT, " +
- "MODIFIED INTEGER DEFAULT 0, " +
- "CONTENT TEXT, " +
- "FAVORITE INTEGER DEFAULT 0, " +
- "CATEGORY INTEGER, " +
- "ETAG TEXT," +
- "EXCERPT TEXT NOT NULL DEFAULT '', " +
- "FOREIGN KEY(CATEGORY) REFERENCES CATEGORIES(CATEGORY_ID), " +
- "FOREIGN KEY(ACCOUNT_ID) REFERENCES ACCOUNTS(ID))");
- DatabaseIndexUtil.createIndex(db, "NOTES", "REMOTEID", "ACCOUNT_ID", "STATUS", "FAVORITE", "CATEGORY", "MODIFIED");
- db.execSQL("CREATE TABLE CATEGORIES(" +
- "CATEGORY_ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
- "CATEGORY_ACCOUNT_ID INTEGER NOT NULL, " +
- "CATEGORY_TITLE TEXT NOT NULL, " +
- "UNIQUE( CATEGORY_ACCOUNT_ID , CATEGORY_TITLE), " +
- "FOREIGN KEY(CATEGORY_ACCOUNT_ID) REFERENCES ACCOUNTS(ID))");
- DatabaseIndexUtil.createIndex(db, "CATEGORIES", "CATEGORY_ID", "CATEGORY_ACCOUNT_ID", "CATEGORY_TITLE");
- // A hashtable storing categoryTitle - categoryId Mapping
- // This is used to prevent too many searches in database
- Hashtable<String, Integer> categoryTitleIdMap = new Hashtable<>();
- int id = 1;
- Cursor tmpNotesCursor = db.rawQuery("SELECT * FROM " + tmpTableNotes, null);
- while (tmpNotesCursor.moveToNext()) {
- String categoryTitle = tmpNotesCursor.getString(8);
- int accountId = tmpNotesCursor.getInt(2);
- Log.e("###", accountId + "");
- Integer categoryId;
- if (categoryTitleIdMap.containsKey(categoryTitle) && categoryTitleIdMap.get(categoryTitle) != null) {
- categoryId = categoryTitleIdMap.get(categoryTitle);
- } else {
- // The category does not exists in the database, create it.
- categoryId = id++;
- ContentValues values = new ContentValues();
- values.put("CATEGORY_ID", categoryId);
- values.put("CATEGORY_ACCOUNT_ID", accountId);
- values.put("CATEGORY_TITLE", categoryTitle);
- db.insert("CATEGORIES", null, values);
- categoryTitleIdMap.put(categoryTitle, categoryId);
- }
- // Move the data in tmp_NOTES to NOTES
- ContentValues values = new ContentValues();
- values.put("ID", tmpNotesCursor.getInt(0));
- values.put("REMOTEID", tmpNotesCursor.getInt(1));
- values.put("ACCOUNT_ID", tmpNotesCursor.getInt(2));
- values.put("STATUS", tmpNotesCursor.getString(3));
- values.put("TITLE", tmpNotesCursor.getString(4));
- values.put("MODIFIED", tmpNotesCursor.getLong(5));
- values.put("CONTENT", tmpNotesCursor.getString(6));
- values.put("FAVORITE", tmpNotesCursor.getInt(7));
- values.put("CATEGORY", categoryId);
- values.put("ETAG", tmpNotesCursor.getString(9));
- values.put("EXCERPT", tmpNotesCursor.getString(10));
- db.insert("NOTES", null, values);
- }
- tmpNotesCursor.close();
- db.execSQL("DROP TABLE IF EXISTS " + tmpTableNotes);
- }
- if (oldVersion < 16) {
- // #832 Move note list widget preferences to database
- db.execSQL("CREATE TABLE WIDGET_NOTE_LISTS ( " +
- "ID INTEGER PRIMARY KEY, " +
- "ACCOUNT_ID INTEGER, " +
- "CATEGORY_ID INTEGER, " +
- "MODE INTEGER NOT NULL, " +
- "THEME_MODE INTEGER NOT NULL, " +
- "FOREIGN KEY(ACCOUNT_ID) REFERENCES ACCOUNTS(ID), " +
- "FOREIGN KEY(CATEGORY_ID) REFERENCES CATEGORIES(CATEGORY_ID))");
-
- final String SP_WIDGET_KEY = "NLW_mode";
- final String SP_ACCOUNT_ID_KEY = "NLW_account";
- final String SP_DARK_THEME_KEY = "NLW_darkTheme";
- final String SP_CATEGORY_KEY = "NLW_cat";
-
- SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
- SharedPreferences.Editor editor = sharedPreferences.edit();
- Map<String, ?> prefs = sharedPreferences.getAll();
- for (Map.Entry<String, ?> pref : prefs.entrySet()) {
- final String key = pref.getKey();
- Integer widgetId = null;
- Integer mode = null;
- Long accountId = null;
- Integer themeMode = null;
- Integer categoryId = null;
- if (key != null && key.startsWith(SP_WIDGET_KEY)) {
- try {
- widgetId = Integer.parseInt(key.substring(SP_WIDGET_KEY.length()));
- mode = (Integer) pref.getValue();
- accountId = sharedPreferences.getLong(SP_ACCOUNT_ID_KEY + widgetId, -1);
-
- try {
- themeMode = DarkModeSetting.valueOf(sharedPreferences.getString(SP_DARK_THEME_KEY + widgetId, DarkModeSetting.SYSTEM_DEFAULT.name())).getModeId();
- } catch (ClassCastException e) {
- //DARK_THEME was a boolean in older versions of the app. We thereofre have to still support the old setting.
- themeMode = sharedPreferences.getBoolean(SP_DARK_THEME_KEY + widgetId, false) ? DarkModeSetting.DARK.getModeId() : DarkModeSetting.LIGHT.getModeId();
- }
-
- if (mode == 2) {
- final String categoryTitle = sharedPreferences.getString(SP_CATEGORY_KEY + widgetId, null);
- Cursor cursor = db.query(
- table_category,
- new String[]{key_category_id},
- key_category_title + " = ? AND " + key_category_account_id + " = ? ",
- new String[]{categoryTitle, String.valueOf(accountId)},
- null,
- null,
- null);
- if (cursor.moveToNext()) {
- categoryId = cursor.getInt(0);
- } else {
- throw new IllegalStateException("No category id found for title \"" + categoryTitle + "\"");
- }
- cursor.close();
- }
-
- ContentValues migratedWidgetValues = new ContentValues();
- migratedWidgetValues.put("ID", widgetId);
- migratedWidgetValues.put("ACCOUNT_ID", accountId);
- migratedWidgetValues.put("CATEGORY_ID", categoryId);
- migratedWidgetValues.put("MODE", mode);
- migratedWidgetValues.put("THEME_MODE", themeMode);
- db.insert("WIDGET_NOTE_LISTS", null, migratedWidgetValues);
- } catch (Throwable t) {
- Log.e(TAG, "Could not migrate widget {widgetId: " + widgetId + ", accountId: " + accountId + ", mode: " + mode + ", categoryId: " + categoryId + ", themeMode: " + themeMode + "}");
- t.printStackTrace();
- } finally {
- // Clean up old shared preferences
- editor.remove(SP_WIDGET_KEY + widgetId);
- editor.remove(SP_CATEGORY_KEY + widgetId);
- editor.remove(SP_DARK_THEME_KEY + widgetId);
- editor.remove(SP_ACCOUNT_ID_KEY + widgetId);
- }
- }
- }
- editor.apply();
- notifyNotesChanged();
+ case 4:
+ new Migration_4_5(db);
+ case 5:
+ new Migration_5_6(db);
+ case 6:
+ new Migration_6_7(db);
+ case 7:
+ new Migration_7_8(db);
+ case 8:
+ new Migration_8_9(db, context, this::recreateDatabase, this::notifyWidgets);
+ case 9:
+ new Migration_9_10(db);
+ case 10:
+ new Migration_10_11(context);
+ case 11:
+ new Migration_11_12(db, context);
+ case 12:
+ new Migration_12_13(db, context);
+ case 13:
+ new Migration_13_14(db, context, this::notifyWidgets);
+ case 14:
+ new Migration_14_15(db);
+ case 15:
+ new Migration_15_16(db, context, this::notifyWidgets);
+ case 16:
+ new Migration_16_17(db);
}
}
@@ -547,6 +202,5 @@ abstract class AbstractNotesDatabase extends SQLiteOpenHelper {
onCreate(db);
}
-
- protected abstract void notifyNotesChanged();
+ protected abstract void notifyWidgets();
}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NoteServerSyncHelper.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NoteServerSyncHelper.java
index cb6c2717..7158c9d2 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NoteServerSyncHelper.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NoteServerSyncHelper.java
@@ -513,7 +513,7 @@ public class NoteServerSyncHelper {
callback.onFinish();
}
}
- db.notifyNotesChanged();
+ db.notifyWidgets();
db.updateDynamicShortcuts(localAccount.getId());
// start next sync if scheduled meanwhile
if (syncScheduled.containsKey(ssoAccount.name) && syncScheduled.get(ssoAccount.name) != null && Boolean.TRUE.equals(syncScheduled.get(ssoAccount.name))) {
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java
index 99ee0318..11525a4f 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java
@@ -95,9 +95,9 @@ public class NotesDatabase extends AbstractNotesDatabase {
* @param note Note
*/
public long addNoteAndSync(SingleSignOnAccount ssoAccount, long accountId, CloudNote note) {
- DBNote dbNote = new DBNote(0, 0, note.getModified(), note.getTitle(), note.getContent(), note.isFavorite(), note.getCategory(), note.getEtag(), DBStatus.LOCAL_EDITED, accountId, generateNoteExcerpt(note.getContent(), note.getTitle()));
+ DBNote dbNote = new DBNote(0, 0, note.getModified(), note.getTitle(), note.getContent(), note.isFavorite(), note.getCategory(), note.getEtag(), DBStatus.LOCAL_EDITED, accountId, generateNoteExcerpt(note.getContent(), note.getTitle()), 0);
long id = addNote(accountId, dbNote);
- notifyNotesChanged();
+ notifyWidgets();
getNoteServerSyncHelper().scheduleSync(ssoAccount, true);
return id;
}
@@ -110,7 +110,7 @@ public class NotesDatabase extends AbstractNotesDatabase {
*/
long addNote(long accountId, CloudNote note) {
SQLiteDatabase db = this.getWritableDatabase();
- ContentValues values = new ContentValues();
+ ContentValues values = new ContentValues(11);
if (note instanceof DBNote) {
DBNote dbNote = (DBNote) note;
if (dbNote.getId() > 0) {
@@ -141,7 +141,7 @@ public class NotesDatabase extends AbstractNotesDatabase {
addNoteAndSync(ssoAccount, newAccountId, new CloudNote(0, note.getModified(), note.getTitle(), note.getContent(), note.isFavorite(), note.getCategory(), null));
deleteNoteAndSync(ssoAccount, note.getId());
- notifyNotesChanged();
+ notifyWidgets();
getNoteServerSyncHelper().scheduleSync(ssoAccount, true);
}
@@ -215,8 +215,8 @@ public class NotesDatabase extends AbstractNotesDatabase {
if (selectionArgs.length > 2) {
Log.v(TAG, selection + " ---- " + selectionArgs[0] + " " + selectionArgs[1] + " " + selectionArgs[2]);
}
- String cols = String.format("%s, %s, %s, %s, %s, %s, %s, %s, %s",
- key_id, key_remote_id, key_status, key_title, key_modified, key_favorite, key_category_title, key_etag, key_excerpt);
+ String cols = String.format("%s, %s, %s, %s, %s, %s, %s, %s, %s, %s",
+ key_id, key_remote_id, key_status, key_title, key_modified, key_favorite, key_category_title, key_etag, key_excerpt, key_scroll_y);
if (!pruneContent) {
cols = String.format("%s, %s", cols, key_content);
}
@@ -249,13 +249,14 @@ public class NotesDatabase extends AbstractNotesDatabase {
cursor.getLong(1),
modified,
cursor.getString(3),
- pruneContent ? "" : cursor.getString(9),
+ pruneContent ? "" : cursor.getString(10),
cursor.getInt(5) > 0,
cursor.getString(6),
cursor.getString(7),
DBStatus.parse(cursor.getString(2)),
accountId,
- cursor.getString(8)
+ cursor.getString(8),
+ cursor.getInt(9)
);
}
@@ -450,7 +451,7 @@ public class NotesDatabase extends AbstractNotesDatabase {
note.setFavorite(!note.isFavorite());
note.setStatus(DBStatus.LOCAL_EDITED);
SQLiteDatabase db = this.getWritableDatabase();
- ContentValues values = new ContentValues();
+ ContentValues values = new ContentValues(2);
values.put(key_status, note.getStatus().getTitle());
values.put(key_favorite, note.isFavorite() ? "1" : "0");
db.update(table_notes, values, key_id + " = ?", new String[]{String.valueOf(note.getId())});
@@ -474,7 +475,7 @@ public class NotesDatabase extends AbstractNotesDatabase {
note.setCategory(category);
note.setStatus(DBStatus.LOCAL_EDITED);
SQLiteDatabase db = this.getWritableDatabase();
- ContentValues values = new ContentValues();
+ ContentValues values = new ContentValues(2);
values.put(key_status, note.getStatus().getTitle());
int id = getCategoryIdByTitle(note.getAccountId(), note.getCategory());
values.put(key_category, id);
@@ -489,7 +490,7 @@ public class NotesDatabase extends AbstractNotesDatabase {
private long addCategory(long accountId, @NonNull String title) {
validateAccountId(accountId);
SQLiteDatabase db = getWritableDatabase();
- ContentValues values = new ContentValues();
+ ContentValues values = new ContentValues(2);
values.put(key_category_account_id, accountId);
values.put(key_category_title, title);
return db.insert(table_category, null, values);
@@ -512,7 +513,7 @@ public class NotesDatabase extends AbstractNotesDatabase {
public DBNote updateNoteAndSync(SingleSignOnAccount ssoAccount, @NonNull LocalAccount localAccount, @NonNull DBNote oldNote, @Nullable String newContent, @Nullable String newTitle, @Nullable ISyncCallback callback) {
DBNote newNote;
if (newContent == null) {
- newNote = new DBNote(oldNote.getId(), oldNote.getRemoteId(), oldNote.getModified(), oldNote.getTitle(), oldNote.getContent(), oldNote.isFavorite(), oldNote.getCategory(), oldNote.getEtag(), DBStatus.LOCAL_EDITED, localAccount.getId(), oldNote.getExcerpt());
+ newNote = new DBNote(oldNote.getId(), oldNote.getRemoteId(), oldNote.getModified(), oldNote.getTitle(), oldNote.getContent(), oldNote.isFavorite(), oldNote.getCategory(), oldNote.getEtag(), DBStatus.LOCAL_EDITED, localAccount.getId(), oldNote.getExcerpt(), oldNote.getScrollY());
} else {
final String title;
if (newTitle != null) {
@@ -524,21 +525,22 @@ public class NotesDatabase extends AbstractNotesDatabase {
title = oldNote.getTitle();
}
}
- newNote = new DBNote(oldNote.getId(), oldNote.getRemoteId(), Calendar.getInstance(), title, newContent, oldNote.isFavorite(), oldNote.getCategory(), oldNote.getEtag(), DBStatus.LOCAL_EDITED, localAccount.getId(), generateNoteExcerpt(newContent, title));
+ newNote = new DBNote(oldNote.getId(), oldNote.getRemoteId(), Calendar.getInstance(), title, newContent, oldNote.isFavorite(), oldNote.getCategory(), oldNote.getEtag(), DBStatus.LOCAL_EDITED, localAccount.getId(), generateNoteExcerpt(newContent, title), oldNote.getScrollY());
}
SQLiteDatabase db = this.getWritableDatabase();
- ContentValues values = new ContentValues();
+ ContentValues values = new ContentValues(7);
values.put(key_status, newNote.getStatus().getTitle());
values.put(key_title, newNote.getTitle());
values.put(key_category, getCategoryIdByTitle(newNote.getAccountId(), newNote.getCategory()));
values.put(key_modified, newNote.getModified().getTimeInMillis() / 1000);
values.put(key_content, newNote.getContent());
values.put(key_excerpt, newNote.getExcerpt());
+ values.put(key_scroll_y, newNote.getScrollY());
int rows = db.update(table_notes, values, key_id + " = ? AND (" + key_content + " != ? OR " + key_category + " != ?)", new String[]{String.valueOf(newNote.getId()), newNote.getContent(), newNote.getCategory()});
removeEmptyCategory(localAccount.getId());
// if data was changed, set new status and schedule sync (with callback); otherwise invoke callback directly.
if (rows > 0) {
- notifyNotesChanged();
+ notifyWidgets();
if (callback != null) {
serverSyncHelper.addCallbackPush(ssoAccount, callback);
}
@@ -552,6 +554,14 @@ public class NotesDatabase extends AbstractNotesDatabase {
}
}
+ public void updateScrollY(long noteId, int scrollY) {
+ Log.e(TAG, "Updated scrollY: " + scrollY);
+ SQLiteDatabase db = this.getWritableDatabase();
+ ContentValues values = new ContentValues(1);
+ values.put(key_scroll_y, scrollY);
+ db.update(table_notes, values, key_id + " = ? ", new String[]{String.valueOf(noteId)});
+ }
+
/**
* Updates a single Note with data from the server, (if it was not modified locally).
* Thereby, an optimistic concurrency control is realized in order to prevent conflicts arising due to parallel changes from the UI and synchronization.
@@ -565,7 +575,7 @@ public class NotesDatabase extends AbstractNotesDatabase {
SQLiteDatabase db = this.getWritableDatabase();
// First, update the remote ID, since this field cannot be changed in parallel, but have to be updated always.
- ContentValues values = new ContentValues();
+ ContentValues values = new ContentValues(8);
values.put(key_remote_id, remoteNote.getRemoteId());
db.update(table_notes, values, key_id + " = ?", new String[]{String.valueOf(id)});
@@ -608,24 +618,28 @@ public class NotesDatabase extends AbstractNotesDatabase {
*/
public void deleteNoteAndSync(SingleSignOnAccount ssoAccount, long id) {
SQLiteDatabase db = this.getWritableDatabase();
- ContentValues values = new ContentValues();
+ ContentValues values = new ContentValues(1);
values.put(key_status, DBStatus.LOCAL_DELETED.getTitle());
db.update(table_notes,
values,
key_id + " = ?",
new String[]{String.valueOf(id)});
- notifyNotesChanged();
+ notifyWidgets();
getNoteServerSyncHelper().scheduleSync(ssoAccount, true);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ShortcutManager shortcutManager = getContext().getSystemService(ShortcutManager.class);
- shortcutManager.getPinnedShortcuts().forEach((shortcut) -> {
- String shortcutId = id + "";
- if (shortcut.getId().equals(shortcutId)) {
- Log.v(TAG, "Removing shortcut for " + shortcutId);
- shortcutManager.disableShortcuts(Collections.singletonList(shortcutId), getContext().getResources().getString(R.string.note_has_been_deleted));
- }
- });
+ if(shortcutManager != null) {
+ shortcutManager.getPinnedShortcuts().forEach((shortcut) -> {
+ String shortcutId = id + "";
+ if (shortcut.getId().equals(shortcutId)) {
+ Log.v(TAG, "Removing shortcut for " + shortcutId);
+ shortcutManager.disableShortcuts(Collections.singletonList(shortcutId), getContext().getResources().getString(R.string.note_has_been_deleted));
+ }
+ });
+ } else {
+ Log.e(TAG, ShortcutManager.class.getSimpleName() + "is null.");
+ }
}
}
@@ -647,7 +661,7 @@ public class NotesDatabase extends AbstractNotesDatabase {
/**
* Notify about changed notes.
*/
- protected void notifyNotesChanged() {
+ protected void notifyWidgets() {
updateSingleNoteWidgets(getContext());
updateNoteListWidgets(getContext());
}
@@ -714,7 +728,7 @@ public class NotesDatabase extends AbstractNotesDatabase {
*/
public void addAccount(@NonNull String url, @NonNull String username, @NonNull String accountName, @NonNull Capabilities capabilities) throws SQLiteConstraintException {
SQLiteDatabase db = this.getWritableDatabase();
- ContentValues values = new ContentValues();
+ ContentValues values = new ContentValues(4);
values.put(key_url, url);
values.put(key_username, username);
values.put(key_account_name, accountName);
@@ -824,7 +838,7 @@ public class NotesDatabase extends AbstractNotesDatabase {
}
final SQLiteDatabase db = this.getWritableDatabase();
- final ContentValues values = new ContentValues();
+ final ContentValues values = new ContentValues(2);
values.put(key_color, color);
values.put(key_text_color, textColor);
@@ -852,7 +866,7 @@ public class NotesDatabase extends AbstractNotesDatabase {
}
if (apiVersions.length() > 0) {
final SQLiteDatabase db = this.getWritableDatabase();
- final ContentValues values = new ContentValues();
+ final ContentValues values = new ContentValues(1);
values.put(key_api_version, apiVersion);
final int updatedRows = db.update(table_accounts, values, key_id + " = ?", new String[]{String.valueOf(accountId)});
if (updatedRows == 1) {
@@ -904,7 +918,7 @@ public class NotesDatabase extends AbstractNotesDatabase {
void updateETag(long accountId, String etag) {
validateAccountId(accountId);
SQLiteDatabase db = this.getWritableDatabase();
- ContentValues values = new ContentValues();
+ ContentValues values = new ContentValues(1);
values.put(key_etag, etag);
final int updatedRows = db.update(table_accounts, values, key_id + " = ?", new String[]{String.valueOf(accountId)});
if (updatedRows == 1) {
@@ -917,7 +931,7 @@ public class NotesDatabase extends AbstractNotesDatabase {
public void updateCapabilitiesETag(long accountId, String capabilitiesETag) {
validateAccountId(accountId);
SQLiteDatabase db = this.getWritableDatabase();
- ContentValues values = new ContentValues();
+ ContentValues values = new ContentValues(1);
values.put(key_capabilities_etag, capabilitiesETag);
final int updatedRows = db.update(table_accounts, values, key_id + " = ?", new String[]{String.valueOf(accountId)});
if (updatedRows == 1) {
@@ -933,7 +947,7 @@ public class NotesDatabase extends AbstractNotesDatabase {
throw new IllegalArgumentException("modified must be greater or equal 0");
}
SQLiteDatabase db = this.getWritableDatabase();
- ContentValues values = new ContentValues();
+ ContentValues values = new ContentValues(1);
values.put(key_modified, modified);
final int updatedRows = db.update(table_accounts, values, key_id + " = ?", new String[]{String.valueOf(accountId)});
if (updatedRows == 1) {
@@ -973,7 +987,7 @@ public class NotesDatabase extends AbstractNotesDatabase {
public void createOrUpdateSingleNoteWidgetData(@NonNull SingleNoteWidgetData data) throws SQLException {
validateAccountId(data.getAccountId());
final SQLiteDatabase db = getWritableDatabase();
- final ContentValues values = new ContentValues();
+ final ContentValues values = new ContentValues(4);
values.put(key_id, data.getAppWidgetId());
values.put(key_account_id, data.getAccountId());
values.put(key_note_id, data.getNoteId());
@@ -1007,7 +1021,7 @@ public class NotesDatabase extends AbstractNotesDatabase {
public void createOrUpdateNoteListWidgetData(@NonNull NoteListsWidgetData data) throws SQLException {
validateAccountId(data.getAccountId());
final SQLiteDatabase db = getWritableDatabase();
- final ContentValues values = new ContentValues();
+ final ContentValues values = new ContentValues(5);
if (data.getMode() != MODE_DISPLAY_CATEGORY && data.getCategoryId() != null) {
throw new UnsupportedOperationException("Cannot create a widget with a categoryId when mode is not " + MODE_DISPLAY_CATEGORY);
}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_10_11.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_10_11.java
new file mode 100644
index 00000000..82a627aa
--- /dev/null
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_10_11.java
@@ -0,0 +1,31 @@
+package it.niedermann.owncloud.notes.persistence.migration;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+import androidx.annotation.NonNull;
+import androidx.preference.PreferenceManager;
+
+import java.util.Map;
+
+import it.niedermann.owncloud.notes.android.DarkModeSetting;
+
+public class Migration_10_11 {
+ /**
+ * Changes the boolean for light / dark mode to {@link DarkModeSetting} to also be able to represent system default value
+ */
+ public Migration_10_11(@NonNull Context context) {
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ Map<String, ?> prefs = sharedPreferences.getAll();
+ for (Map.Entry<String, ?> pref : prefs.entrySet()) {
+ String key = pref.getKey();
+ final String DARK_THEME_KEY = "NLW_darkTheme";
+ if ("darkTheme".equals(key) || key.startsWith(DARK_THEME_KEY) || key.startsWith("SNW_darkTheme")) {
+ Boolean darkTheme = (Boolean) pref.getValue();
+ editor.putString(pref.getKey(), darkTheme ? DarkModeSetting.DARK.name() : DarkModeSetting.LIGHT.name());
+ }
+ }
+ editor.apply();
+ }
+}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_11_12.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_11_12.java
new file mode 100644
index 00000000..82a9984e
--- /dev/null
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_11_12.java
@@ -0,0 +1,21 @@
+package it.niedermann.owncloud.notes.persistence.migration;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+
+import androidx.annotation.NonNull;
+
+import it.niedermann.owncloud.notes.model.ApiVersion;
+import it.niedermann.owncloud.notes.persistence.CapabilitiesWorker;
+
+public class Migration_11_12 {
+ /**
+ * Adds columns to store the {@link ApiVersion} and the theme colors
+ */
+ public Migration_11_12(@NonNull SQLiteDatabase db, @NonNull Context context) {
+ db.execSQL("ALTER TABLE ACCOUNTS ADD COLUMN API_VERSION TEXT");
+ db.execSQL("ALTER TABLE ACCOUNTS ADD COLUMN COLOR VARCHAR(6) NOT NULL DEFAULT '000000'");
+ db.execSQL("ALTER TABLE ACCOUNTS ADD COLUMN TEXT_COLOR VARCHAR(6) NOT NULL DEFAULT '0082C9'");
+ CapabilitiesWorker.update(context);
+ }
+}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_12_13.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_12_13.java
new file mode 100644
index 00000000..895a59a1
--- /dev/null
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_12_13.java
@@ -0,0 +1,20 @@
+package it.niedermann.owncloud.notes.persistence.migration;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+
+import androidx.annotation.NonNull;
+import androidx.work.WorkManager;
+
+import it.niedermann.owncloud.notes.model.Capabilities;
+
+public class Migration_12_13 {
+ /**
+ * Adds a column to store the ETag of the server {@link Capabilities}
+ */
+ public Migration_12_13(@NonNull SQLiteDatabase db, @NonNull Context context) {
+ db.execSQL("ALTER TABLE ACCOUNTS ADD COLUMN CAPABILITIES_ETAG TEXT");
+ WorkManager.getInstance(context.getApplicationContext()).cancelUniqueWork("it.niedermann.owncloud.notes.persistence.SyncWorker");
+ WorkManager.getInstance(context.getApplicationContext()).cancelUniqueWork("SyncWorker");
+ }
+}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_13_14.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_13_14.java
new file mode 100644
index 00000000..d69396d3
--- /dev/null
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_13_14.java
@@ -0,0 +1,78 @@
+package it.niedermann.owncloud.notes.persistence.migration;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.database.sqlite.SQLiteDatabase;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.preference.PreferenceManager;
+
+import java.util.Map;
+
+import it.niedermann.owncloud.notes.android.DarkModeSetting;
+
+public class Migration_13_14 {
+
+ private static final String TAG = Migration_13_14.class.getSimpleName();
+
+ /**
+ * Move single note widget preferences to database
+ * https://github.com/stefan-niedermann/nextcloud-notes/issues/754
+ */
+ public Migration_13_14(@NonNull SQLiteDatabase db, @NonNull Context context, @NonNull Runnable notifyWidgets) {
+ db.execSQL("CREATE TABLE WIDGET_SINGLE_NOTES ( " +
+ "ID INTEGER PRIMARY KEY, " +
+ "ACCOUNT_ID INTEGER, " +
+ "NOTE_ID INTEGER, " +
+ "THEME_MODE INTEGER NOT NULL, " +
+ "FOREIGN KEY(ACCOUNT_ID) REFERENCES ACCOUNTS(ID), " +
+ "FOREIGN KEY(NOTE_ID) REFERENCES NOTES(ID))");
+
+ final String SP_WIDGET_KEY = "single_note_widget";
+ final String SP_ACCOUNT_ID_KEY = "SNW_accountId";
+ final String SP_DARK_THEME_KEY = "SNW_darkTheme";
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ Map<String, ?> prefs = sharedPreferences.getAll();
+ for (Map.Entry<String, ?> pref : prefs.entrySet()) {
+ final String key = pref.getKey();
+ Integer widgetId = null;
+ Long noteId = null;
+ Long accountId = null;
+ Integer themeMode = null;
+ if (key != null && key.startsWith(SP_WIDGET_KEY)) {
+ try {
+ widgetId = Integer.parseInt(key.substring(SP_WIDGET_KEY.length()));
+ noteId = (Long) pref.getValue();
+ accountId = sharedPreferences.getLong(SP_ACCOUNT_ID_KEY + widgetId, -1);
+
+ try {
+ themeMode = DarkModeSetting.valueOf(sharedPreferences.getString(SP_DARK_THEME_KEY + widgetId, DarkModeSetting.SYSTEM_DEFAULT.name())).getModeId();
+ } catch (ClassCastException e) {
+ //DARK_THEME was a boolean in older versions of the app. We thereofre have to still support the old setting.
+ themeMode = sharedPreferences.getBoolean(SP_DARK_THEME_KEY + widgetId, false) ? DarkModeSetting.DARK.getModeId() : DarkModeSetting.LIGHT.getModeId();
+ }
+
+ ContentValues migratedWidgetValues = new ContentValues();
+ migratedWidgetValues.put("ID", widgetId);
+ migratedWidgetValues.put("ACCOUNT_ID", accountId);
+ migratedWidgetValues.put("NOTE_ID", noteId);
+ migratedWidgetValues.put("THEME_MODE", themeMode);
+ db.insert("WIDGET_SINGLE_NOTES", null, migratedWidgetValues);
+ } catch (Throwable t) {
+ Log.e(TAG, "Could not migrate widget {widgetId: " + widgetId + ", accountId: " + accountId + ", noteId: " + noteId + ", themeMode: " + themeMode + "}");
+ t.printStackTrace();
+ } finally {
+ // Clean up old shared preferences
+ editor.remove(SP_WIDGET_KEY + widgetId);
+ editor.remove(SP_DARK_THEME_KEY + widgetId);
+ editor.remove(SP_ACCOUNT_ID_KEY + widgetId);
+ }
+ }
+ }
+ editor.apply();
+ notifyWidgets.run();
+ }
+}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_14_15.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_14_15.java
new file mode 100644
index 00000000..b025bbaa
--- /dev/null
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_14_15.java
@@ -0,0 +1,83 @@
+package it.niedermann.owncloud.notes.persistence.migration;
+
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.util.Log;
+
+import java.util.Hashtable;
+
+import it.niedermann.owncloud.notes.util.DatabaseIndexUtil;
+
+public class Migration_14_15 {
+ /**
+ * Normalize database (move category from string field to own table)
+ * https://github.com/stefan-niedermann/nextcloud-notes/issues/814
+ */
+ public Migration_14_15(SQLiteDatabase db) {
+ // Rename a tmp_NOTES table.
+ String tmpTableNotes = String.format("tmp_%s", "NOTES");
+ db.execSQL("ALTER TABLE NOTES RENAME TO " + tmpTableNotes);
+ db.execSQL("CREATE TABLE NOTES ( " +
+ "ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ "REMOTEID INTEGER, " +
+ "ACCOUNT_ID INTEGER, " +
+ "STATUS VARCHAR(50), " +
+ "TITLE TEXT, " +
+ "MODIFIED INTEGER DEFAULT 0, " +
+ "CONTENT TEXT, " +
+ "FAVORITE INTEGER DEFAULT 0, " +
+ "CATEGORY INTEGER, " +
+ "ETAG TEXT," +
+ "EXCERPT TEXT NOT NULL DEFAULT '', " +
+ "FOREIGN KEY(CATEGORY) REFERENCES CATEGORIES(CATEGORY_ID), " +
+ "FOREIGN KEY(ACCOUNT_ID) REFERENCES ACCOUNTS(ID))");
+ DatabaseIndexUtil.createIndex(db, "NOTES", "REMOTEID", "ACCOUNT_ID", "STATUS", "FAVORITE", "CATEGORY", "MODIFIED");
+ db.execSQL("CREATE TABLE CATEGORIES(" +
+ "CATEGORY_ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ "CATEGORY_ACCOUNT_ID INTEGER NOT NULL, " +
+ "CATEGORY_TITLE TEXT NOT NULL, " +
+ "UNIQUE( CATEGORY_ACCOUNT_ID , CATEGORY_TITLE), " +
+ "FOREIGN KEY(CATEGORY_ACCOUNT_ID) REFERENCES ACCOUNTS(ID))");
+ DatabaseIndexUtil.createIndex(db, "CATEGORIES", "CATEGORY_ID", "CATEGORY_ACCOUNT_ID", "CATEGORY_TITLE");
+ // A hashtable storing categoryTitle - categoryId Mapping
+ // This is used to prevent too many searches in database
+ Hashtable<String, Integer> categoryTitleIdMap = new Hashtable<>();
+ int id = 1;
+ Cursor tmpNotesCursor = db.rawQuery("SELECT * FROM " + tmpTableNotes, null);
+ while (tmpNotesCursor.moveToNext()) {
+ String categoryTitle = tmpNotesCursor.getString(8);
+ int accountId = tmpNotesCursor.getInt(2);
+ Log.e("###", accountId + "");
+ Integer categoryId;
+ if (categoryTitleIdMap.containsKey(categoryTitle) && categoryTitleIdMap.get(categoryTitle) != null) {
+ categoryId = categoryTitleIdMap.get(categoryTitle);
+ } else {
+ // The category does not exists in the database, create it.
+ categoryId = id++;
+ ContentValues values = new ContentValues();
+ values.put("CATEGORY_ID", categoryId);
+ values.put("CATEGORY_ACCOUNT_ID", accountId);
+ values.put("CATEGORY_TITLE", categoryTitle);
+ db.insert("CATEGORIES", null, values);
+ categoryTitleIdMap.put(categoryTitle, categoryId);
+ }
+ // Move the data in tmp_NOTES to NOTES
+ ContentValues values = new ContentValues();
+ values.put("ID", tmpNotesCursor.getInt(0));
+ values.put("REMOTEID", tmpNotesCursor.getInt(1));
+ values.put("ACCOUNT_ID", tmpNotesCursor.getInt(2));
+ values.put("STATUS", tmpNotesCursor.getString(3));
+ values.put("TITLE", tmpNotesCursor.getString(4));
+ values.put("MODIFIED", tmpNotesCursor.getLong(5));
+ values.put("CONTENT", tmpNotesCursor.getString(6));
+ values.put("FAVORITE", tmpNotesCursor.getInt(7));
+ values.put("CATEGORY", categoryId);
+ values.put("ETAG", tmpNotesCursor.getString(9));
+ values.put("EXCERPT", tmpNotesCursor.getString(10));
+ db.insert("NOTES", null, values);
+ }
+ tmpNotesCursor.close();
+ db.execSQL("DROP TABLE IF EXISTS " + tmpTableNotes);
+ }
+}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_15_16.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_15_16.java
new file mode 100644
index 00000000..396f29e1
--- /dev/null
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_15_16.java
@@ -0,0 +1,103 @@
+package it.niedermann.owncloud.notes.persistence.migration;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.preference.PreferenceManager;
+
+import java.util.Map;
+
+import it.niedermann.owncloud.notes.android.DarkModeSetting;
+
+public class Migration_15_16 {
+
+ private static final String TAG = Migration_15_16.class.getSimpleName();
+
+ /**
+ * Moves note list widget preferences from {@link SharedPreferences} to database
+ * https://github.com/stefan-niedermann/nextcloud-notes/issues/832
+ */
+ public Migration_15_16(SQLiteDatabase db, @NonNull Context context, @NonNull Runnable notifyWidgets) {
+ db.execSQL("CREATE TABLE WIDGET_NOTE_LISTS ( " +
+ "ID INTEGER PRIMARY KEY, " +
+ "ACCOUNT_ID INTEGER, " +
+ "CATEGORY_ID INTEGER, " +
+ "MODE INTEGER NOT NULL, " +
+ "THEME_MODE INTEGER NOT NULL, " +
+ "FOREIGN KEY(ACCOUNT_ID) REFERENCES ACCOUNTS(ID), " +
+ "FOREIGN KEY(CATEGORY_ID) REFERENCES CATEGORIES(CATEGORY_ID))");
+
+ final String SP_WIDGET_KEY = "NLW_mode";
+ final String SP_ACCOUNT_ID_KEY = "NLW_account";
+ final String SP_DARK_THEME_KEY = "NLW_darkTheme";
+ final String SP_CATEGORY_KEY = "NLW_cat";
+
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+ Map<String, ?> prefs = sharedPreferences.getAll();
+ for (Map.Entry<String, ?> pref : prefs.entrySet()) {
+ final String key = pref.getKey();
+ Integer widgetId = null;
+ Integer mode = null;
+ Long accountId = null;
+ Integer themeMode = null;
+ Integer categoryId = null;
+ if (key != null && key.startsWith(SP_WIDGET_KEY)) {
+ try {
+ widgetId = Integer.parseInt(key.substring(SP_WIDGET_KEY.length()));
+ mode = (Integer) pref.getValue();
+ accountId = sharedPreferences.getLong(SP_ACCOUNT_ID_KEY + widgetId, -1);
+
+ try {
+ themeMode = DarkModeSetting.valueOf(sharedPreferences.getString(SP_DARK_THEME_KEY + widgetId, DarkModeSetting.SYSTEM_DEFAULT.name())).getModeId();
+ } catch (ClassCastException e) {
+ //DARK_THEME was a boolean in older versions of the app. We thereofre have to still support the old setting.
+ themeMode = sharedPreferences.getBoolean(SP_DARK_THEME_KEY + widgetId, false) ? DarkModeSetting.DARK.getModeId() : DarkModeSetting.LIGHT.getModeId();
+ }
+
+ if (mode == 2) {
+ final String categoryTitle = sharedPreferences.getString(SP_CATEGORY_KEY + widgetId, null);
+ Cursor cursor = db.query(
+ "CATEGORIES",
+ new String[]{"CATEGORY_ID"},
+ "CATEGORY_TITLE = ? AND CATEGORY_ACCOUNT_ID = ? ",
+ new String[]{categoryTitle, String.valueOf(accountId)},
+ null,
+ null,
+ null);
+ if (cursor.moveToNext()) {
+ categoryId = cursor.getInt(0);
+ } else {
+ throw new IllegalStateException("No category id found for title \"" + categoryTitle + "\"");
+ }
+ cursor.close();
+ }
+
+ ContentValues migratedWidgetValues = new ContentValues();
+ migratedWidgetValues.put("ID", widgetId);
+ migratedWidgetValues.put("ACCOUNT_ID", accountId);
+ migratedWidgetValues.put("CATEGORY_ID", categoryId);
+ migratedWidgetValues.put("MODE", mode);
+ migratedWidgetValues.put("THEME_MODE", themeMode);
+ db.insert("WIDGET_NOTE_LISTS", null, migratedWidgetValues);
+ } catch (Throwable t) {
+ Log.e(TAG, "Could not migrate widget {widgetId: " + widgetId + ", accountId: " + accountId + ", mode: " + mode + ", categoryId: " + categoryId + ", themeMode: " + themeMode + "}");
+ t.printStackTrace();
+ } finally {
+ // Clean up old shared preferences
+ editor.remove(SP_WIDGET_KEY + widgetId);
+ editor.remove(SP_CATEGORY_KEY + widgetId);
+ editor.remove(SP_DARK_THEME_KEY + widgetId);
+ editor.remove(SP_ACCOUNT_ID_KEY + widgetId);
+ }
+ }
+ }
+ editor.apply();
+ notifyWidgets.run();
+ }
+}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_16_17.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_16_17.java
new file mode 100644
index 00000000..547cb6c7
--- /dev/null
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_16_17.java
@@ -0,0 +1,15 @@
+package it.niedermann.owncloud.notes.persistence.migration;
+
+import android.database.sqlite.SQLiteDatabase;
+
+import androidx.annotation.NonNull;
+
+public class Migration_16_17 {
+ /**
+ * Adds a column to store the current scroll position per note
+ * https://github.com/stefan-niedermann/nextcloud-notes/issues/227
+ */
+ public Migration_16_17(@NonNull SQLiteDatabase db) {
+ db.execSQL("ALTER TABLE NOTES ADD COLUMN SCROLL_Y INTEGER DEFAULT 0");
+ }
+}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_4_5.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_4_5.java
new file mode 100644
index 00000000..612ed1cb
--- /dev/null
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_4_5.java
@@ -0,0 +1,18 @@
+package it.niedermann.owncloud.notes.persistence.migration;
+
+import android.database.sqlite.SQLiteDatabase;
+
+import androidx.annotation.NonNull;
+
+import it.niedermann.owncloud.notes.model.DBStatus;
+
+public class Migration_4_5 {
+ /**
+ * Differentiate between local id and remote id
+ */
+ public Migration_4_5(@NonNull SQLiteDatabase db) {
+ db.execSQL("ALTER TABLE NOTES ADD COLUMN REMOTEID INTEGER");
+ db.execSQL("UPDATE NOTES SET REMOTEID=ID WHERE (REMOTEID IS NULL OR REMOTEID=0) AND STATUS!=?", new String[]{"LOCAL_CREATED"});
+ db.execSQL("UPDATE NOTES SET REMOTEID=0, STATUS=? WHERE STATUS=?", new String[]{DBStatus.LOCAL_EDITED.getTitle(), "LOCAL_CREATED"});
+ }
+}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_5_6.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_5_6.java
new file mode 100644
index 00000000..184a6033
--- /dev/null
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_5_6.java
@@ -0,0 +1,14 @@
+package it.niedermann.owncloud.notes.persistence.migration;
+
+import android.database.sqlite.SQLiteDatabase;
+
+import androidx.annotation.NonNull;
+
+public class Migration_5_6 {
+ /**
+ * Adds a column to support marking notes as favorite
+ */
+ public Migration_5_6(@NonNull SQLiteDatabase db) {
+ db.execSQL("ALTER TABLE NOTES ADD COLUMN FAVORITE INTEGER DEFAULT 0");
+ }
+}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_6_7.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_6_7.java
new file mode 100644
index 00000000..399d6f40
--- /dev/null
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_6_7.java
@@ -0,0 +1,19 @@
+package it.niedermann.owncloud.notes.persistence.migration;
+
+import android.database.sqlite.SQLiteDatabase;
+
+import androidx.annotation.NonNull;
+
+import it.niedermann.owncloud.notes.util.DatabaseIndexUtil;
+
+public class Migration_6_7 {
+ /**
+ * Adds columns for category support and ETags
+ */
+ public Migration_6_7(@NonNull SQLiteDatabase db) {
+ DatabaseIndexUtil.dropIndexes(db);
+ db.execSQL("ALTER TABLE NOTES ADD COLUMN CATEGORY TEXT NOT NULL DEFAULT ''");
+ db.execSQL("ALTER TABLE NOTES ADD COLUMN ETAG TEXT");
+ DatabaseIndexUtil.createIndex(db, "NOTES", "REMOTEID", "STATUS", "FAVORITE", "CATEGORY", "MODIFIED");
+ }
+}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_7_8.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_7_8.java
new file mode 100644
index 00000000..9a968fe1
--- /dev/null
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_7_8.java
@@ -0,0 +1,28 @@
+package it.niedermann.owncloud.notes.persistence.migration;
+
+import android.database.sqlite.SQLiteDatabase;
+
+import androidx.annotation.NonNull;
+
+import it.niedermann.owncloud.notes.util.DatabaseIndexUtil;
+
+public class Migration_7_8 {
+ public Migration_7_8(@NonNull SQLiteDatabase db) {
+ final String table_temp = "NOTES_TEMP";
+ db.execSQL("CREATE TABLE " + table_temp + " ( " +
+ "ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ "REMOTEID INTEGER, " +
+ "STATUS VARCHAR(50), " +
+ "TITLE TEXT, " +
+ "MODIFIED INTEGER DEFAULT 0, " +
+ "CONTENT TEXT, " +
+ "FAVORITE INTEGER DEFAULT 0, " +
+ "CATEGORY TEXT NOT NULL DEFAULT '', " +
+ "ETAG TEXT)");
+ DatabaseIndexUtil.createIndex(db, table_temp, "REMOTEID", "STATUS", "FAVORITE", "CATEGORY", "MODIFIED");
+ db.execSQL(String.format("INSERT INTO %s(%s,%s,%s,%s,%s,%s,%s,%s,%s) ", table_temp, "ID", "REMOTEID", "STATUS", "TITLE", "MODIFIED", "CONTENT", "FAVORITE", "CATEGORY", "ETAG")
+ + String.format("SELECT %s,%s,%s,%s,strftime('%%s',%s),%s,%s,%s,%s FROM %s", "ID", "REMOTEID", "STATUS", "TITLE", "MODIFIED", "CONTENT", "FAVORITE", "CATEGORY", "ETAG", "NOTES"));
+ db.execSQL("DROP TABLE NOTES");
+ db.execSQL(String.format("ALTER TABLE %s RENAME TO %s", table_temp, "NOTES"));
+ }
+}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_8_9.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_8_9.java
new file mode 100644
index 00000000..31957fc0
--- /dev/null
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_8_9.java
@@ -0,0 +1,127 @@
+package it.niedermann.owncloud.notes.persistence.migration;
+
+import android.appwidget.AppWidgetManager;
+import android.content.ComponentName;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.database.sqlite.SQLiteDatabase;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.core.util.Consumer;
+import androidx.preference.PreferenceManager;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import it.niedermann.owncloud.notes.android.appwidget.NoteListWidget;
+import it.niedermann.owncloud.notes.android.appwidget.SingleNoteWidget;
+import it.niedermann.owncloud.notes.util.DatabaseIndexUtil;
+
+public class Migration_8_9 {
+
+ private static final String TAG = Migration_8_9.class.getSimpleName();
+
+ /**
+ * Adds an account table for multi account usage in combination with SingleSignOn
+ */
+ public Migration_8_9(@NonNull SQLiteDatabase db, @NonNull Context context, @NonNull Consumer<SQLiteDatabase> recreateDatabase, @NonNull Runnable notifyWidgets) {
+ // Create accounts table
+ db.execSQL("CREATE TABLE ACCOUNTS ( " +
+ "ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ "URL TEXT, " +
+ "USERNAME TEXT, " +
+ "ACCOUNT_NAME TEXT UNIQUE, " +
+ "ETAG TEXT, " +
+ "MODIFIED INTEGER)");
+ DatabaseIndexUtil.createIndex(db, "ACCOUNTS", "URL", "USERNAME", "ACCOUNT_NAME", "ETAG", "MODIFIED");
+
+ // Add accountId to notes table
+ db.execSQL("ALTER TABLE NOTES ADD COLUMN ACCOUNT_ID INTEGER NOT NULL DEFAULT 0");
+ DatabaseIndexUtil.createIndex(db, "NOTES", "ACCOUNT_ID");
+
+ // Migrate existing account from SharedPreferences
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ String username = sharedPreferences.getString("settingsUsername", "");
+ String url = sharedPreferences.getString("settingsUrl", "");
+ if (!url.isEmpty() && url.endsWith("/")) {
+ url = url.substring(0, url.length() - 1);
+ try {
+ String accountName = username + "@" + new URL(url).getHost();
+
+ ContentValues migratedAccountValues = new ContentValues();
+ migratedAccountValues.put("URL", url);
+ migratedAccountValues.put("USERNAME", username);
+ migratedAccountValues.put("ACCOUNT_NAME", accountName);
+ db.insert("ACCOUNTS", null, migratedAccountValues);
+
+ // After successful insertion of migrated account, set accountId to 1 in each note
+ ContentValues values = new ContentValues();
+ values.put("ACCOUNT_ID", 1);
+ db.update("NOTES", values, "ACCOUNT_ID = ?", new String[]{"NULL"});
+
+ // Add FOREIGN_KEY constraint
+ final String table_temp = "NOTES_TEMP";
+ db.execSQL(String.format("ALTER TABLE %s RENAME TO %s", "NOTES", table_temp));
+
+ db.execSQL("CREATE TABLE NOTES ( " +
+ "ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
+ "REMOTEID INTEGER, " +
+ "ACCOUNT_ID INTEGER, " +
+ "STATUS VARCHAR(50), " +
+ "TITLE TEXT, " +
+ "MODIFIED INTEGER DEFAULT 0, " +
+ "CONTENT TEXT, " +
+ "FAVORITE INTEGER DEFAULT 0, " +
+ "CATEGORY TEXT NOT NULL DEFAULT '', " +
+ "ETAG TEXT," +
+ "FOREIGN KEY(ACCOUNT_ID) REFERENCES ACCOUNTS(ID))");
+ DatabaseIndexUtil.createIndex(db, "NOTES", "REMOTEID", "ACCOUNT_ID", "STATUS", "FAVORITE", "CATEGORY", "MODIFIED");
+
+ db.execSQL(String.format("INSERT INTO %s(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) ", "NOTES", "ID", "ACCOUNT_ID", "REMOTEID", "STATUS", "TITLE", "MODIFIED", "CONTENT", "FAVORITE", "CATEGORY", "ETAG")
+ + String.format("SELECT %s,%s,%s,%s,%s,%s,%s,%s,%s,%s FROM %s", "ID", values.get("ACCOUNT_ID"), "REMOTEID", "STATUS", "TITLE", "MODIFIED", "CONTENT", "FAVORITE", "CATEGORY", "ETAG", table_temp));
+ db.execSQL(String.format("DROP TABLE %s;", table_temp));
+
+ AppWidgetManager awm = AppWidgetManager.getInstance(context);
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+
+ // Add accountId '1' to any existing (and configured) appwidgets
+ int[] appWidgetIdsNLW = awm.getAppWidgetIds(new ComponentName(context, NoteListWidget.class));
+ int[] appWidgetIdsSNW = awm.getAppWidgetIds(new ComponentName(context, SingleNoteWidget.class));
+
+ final String WIDGET_MODE_KEY = "NLW_mode";
+ final String ACCOUNT_ID_KEY = "NLW_account";
+
+ for (int appWidgetId : appWidgetIdsNLW) {
+ if (sharedPreferences.getInt(WIDGET_MODE_KEY + appWidgetId, -1) >= 0) {
+ editor.putLong(ACCOUNT_ID_KEY + appWidgetId, 1);
+ }
+ }
+
+ for (int appWidgetId : appWidgetIdsSNW) {
+ if (sharedPreferences.getLong("single_note_widget" + appWidgetId, -1) >= 0) {
+ editor.putLong("SNW_accountId" + appWidgetId, 1);
+ }
+ }
+
+ notifyWidgets.run();
+
+ // Clean up no longer needed SharedPreferences
+ editor.remove("notes_last_etag");
+ editor.remove("notes_last_modified");
+ editor.remove("settingsUrl");
+ editor.remove("settingsUsername");
+ editor.remove("settingsPassword");
+ editor.apply();
+ } catch (MalformedURLException e) {
+ Log.e(TAG, "Previous URL could not be parsed. Recreating database...");
+ e.printStackTrace();
+ recreateDatabase.accept(db);
+ }
+ } else {
+ Log.e(TAG, "Previous URL is empty or does not end with a '/' character. Recreating database...");
+ recreateDatabase.accept(db);
+ }
+ }
+}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_9_10.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_9_10.java
new file mode 100644
index 00000000..98ddc601
--- /dev/null
+++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_9_10.java
@@ -0,0 +1,26 @@
+package it.niedermann.owncloud.notes.persistence.migration;
+
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+import androidx.annotation.NonNull;
+
+import it.niedermann.owncloud.notes.util.NoteUtil;
+
+public class Migration_9_10 {
+ /**
+ * Adds a column to store excerpt instead of regenerating it each time
+ * https://github.com/stefan-niedermann/nextcloud-notes/issues/528
+ */
+ public Migration_9_10(@NonNull SQLiteDatabase db) {
+ db.execSQL("ALTER TABLE NOTES ADD COLUMN EXCERPT INTEGER NOT NULL DEFAULT ''");
+ Cursor cursor = db.query("NOTES", new String[]{"ID", "CONTENT"}, null, null, null, null, null, null);
+ while (cursor.moveToNext()) {
+ ContentValues values = new ContentValues();
+ values.put("EXCERPT", NoteUtil.generateNoteExcerpt(cursor.getString(1)));
+ db.update("NOTES", values, "ID" + " = ? ", new String[]{cursor.getString(0)});
+ }
+ cursor.close();
+ }
+}
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/util/NoteUtil.java b/app/src/main/java/it/niedermann/owncloud/notes/util/NoteUtil.java
index 5546bdcc..f695f8d9 100644
--- a/app/src/main/java/it/niedermann/owncloud/notes/util/NoteUtil.java
+++ b/app/src/main/java/it/niedermann/owncloud/notes/util/NoteUtil.java
@@ -1,6 +1,7 @@
package it.niedermann.owncloud.notes.util;
import android.content.Context;
+import android.content.SharedPreferences;
import android.text.TextUtils;
import androidx.annotation.NonNull;
@@ -153,4 +154,20 @@ public class NoteUtil {
public static String extendCategory(@NonNull String category) {
return category.replace("/", " / ");
}
+
+ @SuppressWarnings("WeakerAccess") //PMD...
+ public static float getFontSizeFromPreferences(@NonNull Context context, @NonNull SharedPreferences sp) {
+ final String prefValueSmall = context.getString(R.string.pref_value_font_size_small);
+ final String prefValueMedium = context.getString(R.string.pref_value_font_size_medium);
+ // final String prefValueLarge = getString(R.string.pref_value_font_size_large);
+ String fontSize = sp.getString(context.getString(R.string.pref_key_font_size), prefValueMedium);
+
+ if (fontSize.equals(prefValueSmall)) {
+ return context.getResources().getDimension(R.dimen.note_font_size_small);
+ } else if (fontSize.equals(prefValueMedium)) {
+ return context.getResources().getDimension(R.dimen.note_font_size_medium);
+ } else {
+ return context.getResources().getDimension(R.dimen.note_font_size_large);
+ }
+ }
}
diff --git a/app/src/main/res/drawable/ic_baseline_help_outline_24.xml b/app/src/main/res/drawable/ic_baseline_help_outline_24.xml
new file mode 100644
index 00000000..7897850e
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_help_outline_24.xml
@@ -0,0 +1,5 @@
+<vector android:height="24dp" android:tint="#757575"
+ android:viewportHeight="24" android:viewportWidth="24"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="#757575" android:pathData="M11,18h2v-2h-2v2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM12,6c-2.21,0 -4,1.79 -4,4h2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2c0,2 -3,1.75 -3,5h2c0,-2.25 3,-2.5 3,-5 0,-2.21 -1.79,-4 -4,-4z"/>
+</vector>
diff --git a/app/src/main/res/layout/activity_formatting_help.xml b/app/src/main/res/layout/activity_formatting_help.xml
new file mode 100644
index 00000000..69c6838d
--- /dev/null
+++ b/app/src/main/res/layout/activity_formatting_help.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@color/primary"
+ android:orientation="vertical">
+
+ <com.google.android.material.appbar.AppBarLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <androidx.appcompat.widget.Toolbar
+ android:id="@+id/toolbar"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize"
+ android:background="?attr/colorPrimary"
+ app:contentInsetStartWithNavigation="0dp"
+ app:navigationIcon="@drawable/ic_arrow_back_grey600_24dp"
+ app:title="@string/action_formatting_help"
+ app:titleMarginStart="0dp" />
+ </com.google.android.material.appbar.AppBarLayout>
+
+ <ScrollView
+ android:id="@+id/scrollView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ tools:context="it.niedermann.owncloud.notes.android.activity.EditNoteActivity">
+
+ <com.yydcdut.markdown.MarkdownTextView
+ android:id="@+id/content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="@dimen/spacer_2x"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textColor="@color/fg_default"
+ android:textIsSelectable="true"
+ android:theme="@style/textViewStyle"
+ tools:text="@tools:sample/lorem/random" />
+ </ScrollView>
+</LinearLayout> \ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_note_edit.xml b/app/src/main/res/layout/fragment_note_edit.xml
index 64f83e5e..a6ea2fde 100644
--- a/app/src/main/res/layout/fragment_note_edit.xml
+++ b/app/src/main/res/layout/fragment_note_edit.xml
@@ -6,6 +6,15 @@
android:layout_height="match_parent"
tools:background="?attr/colorPrimary">
+ <!-- Dummy item to prevent editContent from receiving focus -->
+ <LinearLayout
+ android:id="@+id/focus_workaround"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ android:orientation="horizontal" />
+
<ScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index 0ea34264..d33644b9 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Edita</string>
<string name="action_edit_save">Desa</string>
<string name="simple_about">Quant a</string>
+ <string name="simple_accounts">Comptes</string>
<string name="simple_bold">Negreta</string>
<string name="simple_link">Enllaç</string>
<string name="simple_italic">Cursiva</string>
@@ -121,6 +122,10 @@
<string name="add_category">Afegeix %1$s</string>
<string name="simple_checkbox">Casella de selecció</string>
<string name="simple_beta">Beta</string>
+ <string name="simple_security">Seguretat</string>
+ <string name="simple_appearance">Aparença</string>
+ <string name="simple_synchronization">Sincronització</string>
+ <string name="manage_accounts">Gestiona els comptes</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Obre en mode d\'edició</item>
diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml
index 5c06044e..23b22204 100644
--- a/app/src/main/res/values-cs-rCZ/strings.xml
+++ b/app/src/main/res/values-cs-rCZ/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Upravit</string>
<string name="action_edit_save">Uložit</string>
<string name="simple_about">O aplikaci</string>
+ <string name="simple_accounts">Účty</string>
<string name="simple_bold">Tučné</string>
<string name="simple_link">Odkaz</string>
<string name="simple_italic">Skloněné</string>
@@ -28,6 +29,9 @@
<string name="menu_preview">Náhled</string>
<string name="menu_share">Sdílet</string>
+ <string name="search_in_category">Hledat v %1$s</string>
+ <string name="search_in_all">Prohledat všechny poznámky</string>
+
<string name="change_category_title">Zvolte kategorii</string>
<string name="listview_updated_today">Dnes</string>
@@ -150,8 +154,13 @@
<string name="added_content">Přidáno „%1$s“</string>
<string name="shared_text_empty">Sdílený text je prázdný</string>
<string name="append_to_note">Připojit k poznámce</string>
+ <string name="settings_branding">Opatření vlastním logem</string>
+ <string name="simple_security">Zabezpečení</string>
+ <string name="simple_appearance">Vzhled</string>
+ <string name="simple_synchronization">Synchronizace</string>
+ <string name="simple_behavior">Chování</string>
<string name="share_multiple">Sdílet obsah %1$d poznámek</string>
-
+ <string name="manage_accounts">Spravovat účty</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Otevřít v režimu úprav</item>
diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml
index 9502a7e5..3e535f3e 100644
--- a/app/src/main/res/values-da/strings.xml
+++ b/app/src/main/res/values-da/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Rediger</string>
<string name="action_edit_save">Gem</string>
<string name="simple_about">Om</string>
+ <string name="simple_accounts">Konti</string>
<string name="simple_bold">Fed</string>
<string name="simple_link">Link</string>
<string name="simple_italic">Kursiv</string>
@@ -145,6 +146,11 @@
<string name="error_dialog_insufficient_storage">Din Nextcloud-instans har ikke mere ledig lagerplads. Slet venligst nogle filer for at synkronisere dine lokale ændringer ind i skyen.</string>
<string name="error_dialog_contact_us">Du er altid velkommen til at kontakte os, hvis problemet varer ved. Du kan finde vores kontaktoplysninger i sektionen Om i sidebjælken.</string>
<string name="error_dialog_we_need_info">Vi har brug for følgende tekniske information for at hjælpe dig:</string>
+ <string name="settings_branding">Branding</string>
+ <string name="simple_security">Sikkerhed</string>
+ <string name="simple_appearance">Udseende</string>
+ <string name="simple_synchronization">Synchronization</string>
+ <string name="manage_accounts">Administrer konti</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Åbn i redigeringstilstand</item>
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 49a31eaf..34f7e1d4 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Bearbeiten</string>
<string name="action_edit_save">Speichern</string>
<string name="simple_about">Über</string>
+ <string name="simple_accounts">Konten</string>
<string name="simple_bold">Fett</string>
<string name="simple_link">Link</string>
<string name="simple_italic">Kursiv</string>
@@ -28,6 +29,9 @@
<string name="menu_preview">Vorschau</string>
<string name="menu_share">Teilen</string>
+ <string name="search_in_category">Suche in %1$s</string>
+ <string name="search_in_all">In allen Notizen suchen</string>
+
<string name="change_category_title">Kategorie auswählen</string>
<string name="listview_updated_today">Heute</string>
@@ -150,8 +154,13 @@
<string name="added_content">„%1$s“ hinzugefügt</string>
<string name="shared_text_empty">Der geteilte Text war ohne Inhalt</string>
<string name="append_to_note">An Notiz anhängen</string>
+ <string name="settings_branding">Branding</string>
+ <string name="simple_security">Sicherheit</string>
+ <string name="simple_appearance">Aussehen</string>
+ <string name="simple_synchronization">Synchronisierung</string>
+ <string name="simple_behavior">Verhalten</string>
<string name="share_multiple">Inhalt von %1$d Notizen teilen</string>
-
+ <string name="manage_accounts">Konten verwalten</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Im Bearbeitungsmodus öffnen</item>
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index df7f3106..9f50951c 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Επεξεργασία</string>
<string name="action_edit_save">Αποθήκευση</string>
<string name="simple_about">Περί</string>
+ <string name="simple_accounts">Λογαριασμοί</string>
<string name="simple_bold">Έντονα</string>
<string name="simple_link">Σύνδεσμος</string>
<string name="simple_italic">Πλάγια</string>
@@ -150,8 +151,12 @@
<string name="added_content">Προστέθηκε \"%1$s\"</string>
<string name="shared_text_empty">Το κοινόχρηστο κείμενο είναι κενό</string>
<string name="append_to_note">Προσάρτηση στη σημείωση</string>
+ <string name="settings_branding">Επωνυμία</string>
+ <string name="simple_security">Ασφάλεια</string>
+ <string name="simple_appearance">Εμφάνιση</string>
+ <string name="simple_synchronization">Συγχρονισμός</string>
<string name="share_multiple">Κοινόχρηστο περιεχόμενο από %1$d σημειώσεις</string>
-
+ <string name="manage_accounts">Διαχείριση λογαριασμών</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Άνοιγμα σε λειτουργία τροποποίησης</item>
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 8ad88e86..f62dbd6d 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Editar</string>
<string name="action_edit_save">Guardar</string>
<string name="simple_about">Acerca de</string>
+ <string name="simple_accounts">Cuentas</string>
<string name="simple_bold">Negrita</string>
<string name="simple_link">Enlace</string>
<string name="simple_italic">Cursiva</string>
@@ -150,8 +151,12 @@
<string name="added_content">Se ha añadido «%1$s»</string>
<string name="shared_text_empty">El texto compartido estaba vacío</string>
<string name="append_to_note">Añadir a la nota</string>
+ <string name="settings_branding">Branding</string>
+ <string name="simple_security">Seguridad</string>
+ <string name="simple_appearance">Apariencia</string>
+ <string name="simple_synchronization">Sincronización</string>
<string name="share_multiple">Compartido contenido de %1$d notas</string>
-
+ <string name="manage_accounts">Gestionar cuentas</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Abrir en modo edición</item>
diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml
index aded23bc..86ee5b6a 100644
--- a/app/src/main/res/values-eu/strings.xml
+++ b/app/src/main/res/values-eu/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Editatu</string>
<string name="action_edit_save">Gorde</string>
<string name="simple_about">Honi buruz</string>
+ <string name="simple_accounts">Kontuak</string>
<string name="simple_bold">Lodia</string>
<string name="simple_link">Esteka</string>
<string name="simple_italic">Etzana</string>
@@ -150,6 +151,11 @@
<string name="added_content">\"%1$s\" gehituta</string>
<string name="shared_text_empty">Partekatutako testua hutsik zegoen</string>
<string name="append_to_note">Gehitu notara</string>
+ <string name="settings_branding">Marka</string>
+ <string name="simple_security">Segurtasuna</string>
+ <string name="simple_appearance">Itxura</string>
+ <string name="simple_synchronization">Sinkronizazioa</string>
+ <string name="manage_accounts">Kudeatu kontuak</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Ireki edizio moduan</item>
diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml
index b55d5790..8b6db628 100644
--- a/app/src/main/res/values-fa/strings.xml
+++ b/app/src/main/res/values-fa/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">ویرایش</string>
<string name="action_edit_save">ذخیره</string>
<string name="simple_about">درباره</string>
+ <string name="simple_accounts">حساب‌ها</string>
<string name="simple_bold">درشت</string>
<string name="simple_link">Link</string>
<string name="simple_italic">Italic</string>
@@ -126,6 +127,10 @@
<string name="add_category">افزودن%1$s</string>
<string name="simple_checkbox">جعبه علامت</string>
<string name="could_not_copy_to_clipboard">به کلیپ بورد کپی نشد</string>
+ <string name="simple_security">امنیت</string>
+ <string name="simple_appearance">ظاهر</string>
+ <string name="simple_synchronization">هم‌گام‌سازی</string>
+ <string name="manage_accounts">مدیریت حساب‌ها</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>در حالت ویرایش باز کنید</item>
diff --git a/app/src/main/res/values-fi-rFI/strings.xml b/app/src/main/res/values-fi-rFI/strings.xml
index 8777be1e..3e89af97 100644
--- a/app/src/main/res/values-fi-rFI/strings.xml
+++ b/app/src/main/res/values-fi-rFI/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Muokkaa</string>
<string name="action_edit_save">Tallenna</string>
<string name="simple_about">Tietoja</string>
+ <string name="simple_accounts">Tilit</string>
<string name="simple_bold">Lihavoitu</string>
<string name="simple_link">Linkki</string>
<string name="simple_italic">Kursivoitu</string>
@@ -118,6 +119,10 @@
<string name="simple_checkbox">Valintaruutu</string>
<string name="simple_beta">Beta</string>
<string name="could_not_copy_to_clipboard">Ei voitu kopioida leikepöydälle</string>
+ <string name="simple_security">Tietoturva</string>
+ <string name="simple_appearance">Ulkoasu</string>
+ <string name="simple_synchronization">Synkronointi</string>
+ <string name="manage_accounts">Tilien hallinta</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Avaa muokkaustilassa</item>
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 24139e52..30540e84 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Modifier</string>
<string name="action_edit_save">Enregistrer</string>
<string name="simple_about">À propos</string>
+ <string name="simple_accounts">Comptes</string>
<string name="simple_bold">Gras</string>
<string name="simple_link">Lien</string>
<string name="simple_italic">Italique</string>
@@ -28,6 +29,9 @@
<string name="menu_preview">Aperçu</string>
<string name="menu_share">Partager</string>
+ <string name="search_in_category">Rechercher dans %1$s</string>
+ <string name="search_in_all">Rechercher dans toutes les notes</string>
+
<string name="change_category_title">Choisir une catégorie</string>
<string name="listview_updated_today">Aujourd\'hui</string>
@@ -150,8 +154,13 @@
<string name="added_content">\"%1$s\" ajouté</string>
<string name="shared_text_empty">Le texte partagé est vide</string>
<string name="append_to_note">Ajouter à la note</string>
+ <string name="settings_branding">marque</string>
+ <string name="simple_security">Sécurité</string>
+ <string name="simple_appearance">Apparence</string>
+ <string name="simple_synchronization">Synchronisation</string>
+ <string name="simple_behavior">Comportement</string>
<string name="share_multiple">Partager le contenu de %1$d notes</string>
-
+ <string name="manage_accounts">Gérer les comptes</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Ouvrir en mode édition</item>
diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml
index e456654c..a55eac01 100644
--- a/app/src/main/res/values-gl/strings.xml
+++ b/app/src/main/res/values-gl/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Editar</string>
<string name="action_edit_save">Gardar</string>
<string name="simple_about">Sobre</string>
+ <string name="simple_accounts">Contas</string>
<string name="simple_bold">Negra</string>
<string name="simple_link">Ligazón</string>
<string name="simple_italic">Itálica</string>
@@ -28,6 +29,9 @@
<string name="menu_preview">Vista previa</string>
<string name="menu_share">Compartir</string>
+ <string name="search_in_category">Buscar en %1$s</string>
+ <string name="search_in_all">Buscar todas as notas</string>
+
<string name="change_category_title">Escolla unha categoría</string>
<string name="listview_updated_today">Hoxe</string>
@@ -150,8 +154,13 @@
<string name="added_content">Engadido «%1$s»</string>
<string name="shared_text_empty">O texto compartido estaba baleiro</string>
<string name="append_to_note">Anexo á nota</string>
+ <string name="settings_branding">Xestión da marca</string>
+ <string name="simple_security">Seguridade</string>
+ <string name="simple_appearance">Aparencia</string>
+ <string name="simple_synchronization">Sincronización</string>
+ <string name="simple_behavior">Comportamento</string>
<string name="share_multiple">Compartir o contido de %1$dnotas</string>
-
+ <string name="manage_accounts">Administrar contas</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Abrir en modo de edición</item>
diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml
index 184f9993..d07fcb17 100644
--- a/app/src/main/res/values-he/strings.xml
+++ b/app/src/main/res/values-he/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">עריכה</string>
<string name="action_edit_save">שמירה</string>
<string name="simple_about">על אודות</string>
+ <string name="simple_accounts">חשבונות</string>
<string name="simple_bold">מודגש</string>
<string name="simple_link">קישור</string>
<string name="simple_italic">נטוי</string>
@@ -135,6 +136,11 @@
<string name="error_dialog_we_need_info">אנו זקוקים לפירוט הטכני הבא כדי לסייע לך:</string>
<string name="shared_text_empty">הטקסט ששותף היה ריק</string>
<string name="append_to_note">הוספה לסוף הפתק</string>
+ <string name="settings_branding">מיתוג</string>
+ <string name="simple_security">אבטחה</string>
+ <string name="simple_appearance">מראה</string>
+ <string name="simple_synchronization">סנכרון</string>
+ <string name="manage_accounts">ניהול חשבונות</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>פתיחה במצב עריכה</item>
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index df30bb74..6cf1fac4 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Uredi</string>
<string name="action_edit_save">Spremi</string>
<string name="simple_about">Informacije</string>
+ <string name="simple_accounts">Računi</string>
<string name="simple_bold">Podebljano</string>
<string name="simple_link">Poveznica</string>
<string name="simple_italic">U kurzivu</string>
@@ -146,6 +147,11 @@
<string name="error_dialog_contact_us">Obratite nam se bez odlaganja ako problemi i dalje postoje. Naše podatke za kontakt možete pronaći u odjeljku s informacijama na bočnoj traci.</string>
<string name="error_dialog_we_need_info">Potrebne su nam sljedeće tehničke informacije kako bismo vam pomogli:</string>
<string name="error_dialog_redirect">Vaš je poslužitelj vratio šifru statusa HTTP 302, što znači da aplikacija Notes nije instalirana na poslužitelju ili postoji pogreška u konfiguraciji. To mogu uzrokovati prilagođena prepisivanja u datoteci .htaccess ili određene aplikacije u Nextcloudu, kao što je OID Client.</string>
+ <string name="settings_branding">Brendiranje</string>
+ <string name="simple_security">Sigurnost</string>
+ <string name="simple_appearance">Izgled</string>
+ <string name="simple_synchronization">Sinkronizacija</string>
+ <string name="manage_accounts">Upravljaj računima</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Otvori u načinu uređivanja</item>
diff --git a/app/src/main/res/values-hu-rHU/strings.xml b/app/src/main/res/values-hu-rHU/strings.xml
index efb1b359..b4847faa 100644
--- a/app/src/main/res/values-hu-rHU/strings.xml
+++ b/app/src/main/res/values-hu-rHU/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Szerkesztés</string>
<string name="action_edit_save">Mentés</string>
<string name="simple_about">Névjegy</string>
+ <string name="simple_accounts">Fiókok</string>
<string name="simple_bold">Vastag</string>
<string name="simple_link">Hivatkozás</string>
<string name="simple_italic">Dőlt</string>
@@ -139,6 +140,11 @@
<string name="error_dialog_insufficient_storage">A Nextcloud példányán elfogyott a szabad hely. Töröljön pár fájlt, hogy szinkronizálhassa a helyi változtatásait a felhővel.</string>
<string name="error_dialog_contact_us">Nyugodtan lépjen velünk kapcsolatba, ha a probléma továbbra is fennáll. A kapcsolati információkat az oldalsáv névjegy részében találja.</string>
<string name="error_dialog_we_need_info">A következő műszaki információkra van szükségünk, hogy segíthessünk:</string>
+ <string name="settings_branding">Márkázas</string>
+ <string name="simple_security">Biztonság</string>
+ <string name="simple_appearance">Megjelenés</string>
+ <string name="simple_synchronization">Szinkronizálás</string>
+ <string name="manage_accounts">Fiókok kezelése</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Megnyitás szerkesztésre</item>
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 05f4f912..485668ee 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Modifica</string>
<string name="action_edit_save">Salva</string>
<string name="simple_about">Informazioni</string>
+ <string name="simple_accounts">Account</string>
<string name="simple_bold">Grassetto</string>
<string name="simple_link">Collegamento</string>
<string name="simple_italic">Corsivo</string>
@@ -28,6 +29,9 @@
<string name="menu_preview">Anteprima</string>
<string name="menu_share">Condividi</string>
+ <string name="search_in_category">Cerca in %1$s</string>
+ <string name="search_in_all">Cerca tutte le note</string>
+
<string name="change_category_title">Scegli una categoria</string>
<string name="listview_updated_today">Oggi</string>
@@ -150,8 +154,13 @@
<string name="added_content">Aggiunto \"%1$s\"</string>
<string name="shared_text_empty">Il testo condiviso era vuoto</string>
<string name="append_to_note">Aggiungi a nota</string>
+ <string name="settings_branding">Marchio</string>
+ <string name="simple_security">Sicurezza</string>
+ <string name="simple_appearance">Aspetto</string>
+ <string name="simple_synchronization">Sincronizzazione</string>
+ <string name="simple_behavior">Comportamento</string>
<string name="share_multiple">Condividi il contenuto di %1$d note</string>
-
+ <string name="manage_accounts">Gestisci account</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Apri in modalità modifica</item>
diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml
index 557b5b10..b992c02a 100644
--- a/app/src/main/res/values-ja-rJP/strings.xml
+++ b/app/src/main/res/values-ja-rJP/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">編集</string>
<string name="action_edit_save">保存</string>
<string name="simple_about">バージョン情報</string>
+ <string name="simple_accounts">アカウント</string>
<string name="simple_bold">太字</string>
<string name="simple_link">リンク</string>
<string name="simple_italic">斜体</string>
@@ -146,6 +147,11 @@
<string name="error_dialog_contact_us">問題が継続する場合はお問い合わせください。我々の連絡先はサイドバーのaboutセクションにかかれています。</string>
<string name="error_dialog_we_need_info">サポートには下記技術情報が必要です:</string>
<string name="error_dialog_redirect">サーバがHTTPステータスコード 302を返しました。これはNotesアプリがインストールされていないか、構成が誤っていることを意味します。.htaccessファイルのカスタムオーバーライドやOIDクライアントのようなNextcloudアプリが原因の可能性があります。</string>
+ <string name="settings_branding">ブランディング</string>
+ <string name="simple_security">セキュリティ</string>
+ <string name="simple_appearance">表示</string>
+ <string name="simple_synchronization">同期</string>
+ <string name="manage_accounts">アカウント管理</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>編集モードで開く</item>
diff --git a/app/src/main/res/values-lt-rLT/strings.xml b/app/src/main/res/values-lt-rLT/strings.xml
index 1b5e55c2..f2759c78 100644
--- a/app/src/main/res/values-lt-rLT/strings.xml
+++ b/app/src/main/res/values-lt-rLT/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Taisyti</string>
<string name="action_edit_save">Įrašyti</string>
<string name="simple_about">Apie</string>
+ <string name="simple_accounts">Paskyros</string>
<string name="simple_bold">Pusjuodis</string>
<string name="simple_link">Nuoroda</string>
<string name="simple_italic">Kursyvas</string>
@@ -130,6 +131,10 @@
<string name="could_not_copy_to_clipboard">Nepavyko nukopijuoti į iškarpinę</string>
<string name="error_dialog_title">O, ne - Kas dabar? 🙁</string>
<string name="error_dialog_we_need_info">Norint jums padėti, mums reikia techninės informacijos:</string>
+ <string name="simple_security">Saugumas</string>
+ <string name="simple_appearance">Išvaizda</string>
+ <string name="simple_synchronization">Sinchronizacija</string>
+ <string name="manage_accounts">Tvarkyti paskyras</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Atverti redagavimo veiksenoje</item>
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 1ba46f37..2c2bb06a 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Bewerken</string>
<string name="action_edit_save">Opslaan</string>
<string name="simple_about">Over</string>
+ <string name="simple_accounts">Accounts</string>
<string name="simple_bold">Vet</string>
<string name="simple_link">Link</string>
<string name="simple_italic">Scheef</string>
@@ -151,8 +152,12 @@
<string name="added_content">\"%1$s\" toegevoegd</string>
<string name="shared_text_empty">Gedeelde tekst was leeg</string>
<string name="append_to_note">Achteraan toevoegen aan notitie</string>
+ <string name="settings_branding">Brandmerken</string>
+ <string name="simple_security">Beveiliging</string>
+ <string name="simple_appearance">Uiterlijk</string>
+ <string name="simple_synchronization">Synchronisatie</string>
<string name="share_multiple">Deel de inhoud van %1$d notities</string>
-
+ <string name="manage_accounts">Accounts beheren </string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Open in wbewerkmodus</item>
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 72a607f1..3eeaf2b0 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Edytuj</string>
<string name="action_edit_save">Zapisz</string>
<string name="simple_about">O aplikacji</string>
+ <string name="simple_accounts">Konta</string>
<string name="simple_bold">Pogrubienie</string>
<string name="simple_link">Odnośnik</string>
<string name="simple_italic">Kursywa</string>
@@ -28,6 +29,9 @@
<string name="menu_preview">Podgląd</string>
<string name="menu_share">Udostępnij</string>
+ <string name="search_in_category">Szukaj w %1$s</string>
+ <string name="search_in_all">Szukaj we wszystkich notatkach</string>
+
<string name="change_category_title">Wybierz kategorię</string>
<string name="listview_updated_today">Dzisiaj</string>
@@ -150,8 +154,13 @@
<string name="added_content">Dodano \"%1$s\"</string>
<string name="shared_text_empty">Udostępniony tekst był pusty</string>
<string name="append_to_note">Dołącz do notatki</string>
+ <string name="settings_branding">Motyw serwera</string>
+ <string name="simple_security">Bezpieczeństwo</string>
+ <string name="simple_appearance">Wygląd</string>
+ <string name="simple_synchronization">Synchronizacja</string>
+ <string name="simple_behavior">Zachowane</string>
<string name="share_multiple">Udostępnij treść notatki %1$d</string>
-
+ <string name="manage_accounts">Zarządzaj kontami</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Otwórz w trybie edycji</item>
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 2e257bd9..de8b8f2b 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Editar</string>
<string name="action_edit_save">Salvar</string>
<string name="simple_about">Sobre</string>
+ <string name="simple_accounts">Contas</string>
<string name="simple_bold">Negrito</string>
<string name="simple_link">Link</string>
<string name="simple_italic">Itálico</string>
@@ -150,8 +151,12 @@
<string name="added_content">\"%1$s\" adicionado</string>
<string name="shared_text_empty">O texto compartilhado estava vazio</string>
<string name="append_to_note">Anexar à nota</string>
+ <string name="settings_branding">Marcação</string>
+ <string name="simple_security">Segurança</string>
+ <string name="simple_appearance">Aparência</string>
+ <string name="simple_synchronization">Sincronização</string>
<string name="share_multiple">Compartilhar o conteúdo de %1$d notas</string>
-
+ <string name="manage_accounts">Gerenciar contas</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Abrir em modo de edição</item>
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index c7d54a3d..1234da29 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Редактировать</string>
<string name="action_edit_save">Сохранить</string>
<string name="simple_about">О программе</string>
+ <string name="simple_accounts">Аккаунты</string>
<string name="simple_bold">Жирный</string>
<string name="simple_link">Ссылка</string>
<string name="simple_italic">Курсив</string>
@@ -150,6 +151,11 @@
<string name="added_content">Добавлена заметка «%1$s»</string>
<string name="shared_text_empty">Публикуемый текст пустой</string>
<string name="append_to_note">Добавить в заметку</string>
+ <string name="settings_branding">Брендирование</string>
+ <string name="simple_security">Безопасность</string>
+ <string name="simple_appearance">Внешний вид</string>
+ <string name="simple_synchronization">Синхронизация</string>
+ <string name="manage_accounts">Управление аккаунтами</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Открывать в режиме редактирования</item>
diff --git a/app/src/main/res/values-sk-rSK/strings.xml b/app/src/main/res/values-sk-rSK/strings.xml
index 0d1c8630..47f1c578 100644
--- a/app/src/main/res/values-sk-rSK/strings.xml
+++ b/app/src/main/res/values-sk-rSK/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Upraviť</string>
<string name="action_edit_save">Uložiť</string>
<string name="simple_about">O aplikácii</string>
+ <string name="simple_accounts">Účty</string>
<string name="simple_bold">Tučné</string>
<string name="simple_link">Odkaz</string>
<string name="simple_italic">Kurzíva</string>
@@ -28,6 +29,9 @@
<string name="menu_preview">Náhľad</string>
<string name="menu_share">Sprístupniť</string>
+ <string name="search_in_category">Hľadať v %1$s</string>
+ <string name="search_in_all">Hľadať všetky poznámky</string>
+
<string name="change_category_title">Vybrať kategóriu</string>
<string name="listview_updated_today">Dnes</string>
@@ -150,8 +154,13 @@
<string name="added_content">Pridané \"%1$s\"</string>
<string name="shared_text_empty">Zdieľaný text bol prázdny</string>
<string name="append_to_note">Pripojiť k poznámke</string>
+ <string name="settings_branding">Použitie vlastného loga</string>
+ <string name="simple_security">Zabezpečenie</string>
+ <string name="simple_appearance">Vzhľad</string>
+ <string name="simple_synchronization">Synchronizácia</string>
+ <string name="simple_behavior">Chod</string>
<string name="share_multiple">Zdieľať obsah %1$d poznámok</string>
-
+ <string name="manage_accounts">Spravovať účty</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Otvoriť v režime úprav</item>
diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml
index 8fed6749..78872be0 100644
--- a/app/src/main/res/values-sl/strings.xml
+++ b/app/src/main/res/values-sl/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Uredi</string>
<string name="action_edit_save">Shrani</string>
<string name="simple_about">O programu</string>
+ <string name="simple_accounts">Računi</string>
<string name="simple_bold">Krepko</string>
<string name="simple_link">Povezava</string>
<string name="simple_italic">Ležeče</string>
@@ -150,6 +151,11 @@
<string name="added_content">Dodano »%1$s«</string>
<string name="shared_text_empty">Besedilo v souporabi je brez vsebine</string>
<string name="append_to_note">Pripni k zabeležki</string>
+ <string name="settings_branding">Prilagajanje oblikovanja</string>
+ <string name="simple_security">Varnost</string>
+ <string name="simple_appearance">Videz</string>
+ <string name="simple_synchronization">Usklajevanje</string>
+ <string name="manage_accounts">Upravljanje z računi</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Zabeležka se odpre v urejevalnem načinu</item>
diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml
index 0c90f1db..b70b2a0e 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Измени</string>
<string name="action_edit_save">Сачувај</string>
<string name="simple_about">О програму</string>
+ <string name="simple_accounts">Налози</string>
<string name="simple_bold">Подебљано</string>
<string name="simple_link">Веза</string>
<string name="simple_italic">Курзив</string>
@@ -138,6 +139,11 @@
<string name="error_dialog_check_maintenance">Проверите да ли Вам инстанца можда тренутно ради у режиму одржавања.</string>
<string name="error_dialog_insufficient_storage">На Некстклауд инстанци више нема простора. Обришите неке фајлове да синхронизујете локалне измене на облак.</string>
<string name="error_dialog_we_need_info">Потребне су нам следеће техничке информација да бисмо Вам помогли:</string>
+ <string name="settings_branding">Брендирање</string>
+ <string name="simple_security">Безбедност</string>
+ <string name="simple_appearance">Изглед</string>
+ <string name="simple_synchronization">Синхронизација</string>
+ <string name="manage_accounts">Управљање налозима</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Отвори у режиму уређивања</item>
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index 692b4a02..7e8a9ff6 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Redigera</string>
<string name="action_edit_save">Spara</string>
<string name="simple_about">Om</string>
+ <string name="simple_accounts">Konton</string>
<string name="simple_bold">Fet</string>
<string name="simple_link">Länk</string>
<string name="simple_italic">Kursiv</string>
@@ -133,6 +134,11 @@
<string name="error_dialog_title">Å nej - Vad händer nu?🙁</string>
<string name="error_dialog_tip_token_mismatch_retry">Försök med att Tvinga appen att stänga och återstarta. En felaktig anslutning till Nextcloud-appen kan ha förekommit.</string>
<string name="error_dialog_tip_token_mismatch_clear_storage">Om problemet kvarstår, prova med att rensa lagringen på både appen Nextcloud och Nextcloud Notes.</string>
+ <string name="settings_branding">Varumärke</string>
+ <string name="simple_security">Säkerhet</string>
+ <string name="simple_appearance">Utseende</string>
+ <string name="simple_synchronization">Synkronisering</string>
+ <string name="manage_accounts">Hantera konton</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Öppna i redigera-läge</item>
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 9c95df31..cc221c44 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">Düzenle</string>
<string name="action_edit_save">Kaydet</string>
<string name="simple_about">Hakkında</string>
+ <string name="simple_accounts">Hesaplar</string>
<string name="simple_bold">Koyu</string>
<string name="simple_link">Bağlantı</string>
<string name="simple_italic">Yatık</string>
@@ -150,8 +151,12 @@
<string name="added_content">\"%1$s\" eklendi</string>
<string name="shared_text_empty">Paylaşılan metin boş</string>
<string name="append_to_note">Nota ekle</string>
+ <string name="settings_branding">Markalama</string>
+ <string name="simple_security">Güvenlik</string>
+ <string name="simple_appearance">Görünüm</string>
+ <string name="simple_synchronization">Eşitleme</string>
<string name="share_multiple">%1$d notun içeriğini paylaş</string>
-
+ <string name="manage_accounts">Hesap yönetimi</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>Düzenleme kipinde aç</item>
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index c4f67bfe..8110d9f9 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">编辑</string>
<string name="action_edit_save">保存</string>
<string name="simple_about">关于</string>
+ <string name="simple_accounts">账号</string>
<string name="simple_bold">粗体</string>
<string name="simple_link">链接</string>
<string name="simple_italic">斜体</string>
@@ -140,6 +141,10 @@
<string name="error_dialog_insufficient_storage">您的 Nextcloud 实例已经没有可用的存储空间了。请删除一些文件来允许本地的变更同步到云。</string>
<string name="error_dialog_contact_us">如果问题持续存在,请不要犹豫来联系我们。您可以在侧边栏的 “关于” 部分找到我们的联系信息。</string>
<string name="error_dialog_we_need_info">我们需要以下技术信息来帮助您:</string>
+ <string name="simple_security">安全</string>
+ <string name="simple_appearance">外观</string>
+ <string name="simple_synchronization">同步</string>
+ <string name="manage_accounts">管理账号</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>以编辑模式打开</item>
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 4661cd19..3acdbb08 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -13,6 +13,7 @@
<string name="simple_edit">修改</string>
<string name="action_edit_save">儲存</string>
<string name="simple_about">關於</string>
+ <string name="simple_accounts">帳戶</string>
<string name="simple_bold">粗體</string>
<string name="simple_link">連結</string>
<string name="simple_italic">斜體</string>
@@ -127,6 +128,9 @@
<string name="simple_checkbox">核取方塊</string>
<string name="unlock_notes">解鎖筆記</string>
<string name="simple_beta">Beta 測試版</string>
+ <string name="simple_security">安全性</string>
+ <string name="simple_synchronization">同步</string>
+ <string name="manage_accounts">帳戶管理</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
<item>以編輯模式開啟</item>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7b316949..76584528 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -199,6 +199,7 @@
<string name="simple_behavior">Behavior</string>
<string name="share_multiple">Share content of %1$d notes</string>
<string name="manage_accounts">Manage accounts</string>
+ <string name="action_formatting_help">Formatting</string>
<!-- Array: note modes -->
<string-array name="noteMode_entries">
@@ -233,4 +234,61 @@
<item quantity="one">%d selected</item>
<item quantity="other">%d selected</item>
</plurals>
+
+ <string name="formatting_help_title" translatable="false"># %1$s</string>
+ <string name="formatting_help_divider" translateable="false">---</string>
+ <string name="formatting_help_codefence" translateable="false">```</string>
+ <string name="formatting_help_codefence_escaped" translatable="false">\\`\\`\\`</string>
+ <string name="formatting_help_javascript_1" translatable="false">if (isAwesome){</string>
+ <string name="formatting_help_javascript_2" translatable="false">return true</string>
+ <string name="formatting_help_javascript_3" translatable="false">}</string>
+ <string name="formatting_help_codefence_javascript_escaped" translatable="false">\\`\\`\\`javascript</string>
+ <string name="formatting_help_codefence_javascript" translateable="false">```javascript</string>
+
+ <string name="formatting_help_cbf_title">Context based formatting</string>
+ <string name="formatting_help_cbf_body_1">A major design goal of the Notes app is to provide a distraction free tool. Though you will be able to format your texts with Markdown. For various of the below mentioned examples, you can use shortcuts so you can format your notes without typing in the codes below.</string>
+ <string name="formatting_help_cbf_body_2">Just select a range of text or tap on your cursor at any position and you will get a popup menu which contains next to the default entries `Cut`, `Copy`, `Select all` entries like `Link` or `Checkbox`.</string>
+
+ <string name="formatting_help_text_title">Text</string>
+ <string name="formatting_help_text_body">It\'s very easy to make some words **bold** and other words *italic* with Markdown. You can ~~strike~~ some words through and even [link to Nextcloud](https://nextcloud.com).</string>
+
+ <string name="formatting_help_lists_title">Lists</string>
+ <string name="formatting_help_lists_body_1">Sometimes you want numbered lists:</string>
+ <string name="formatting_help_lists_body_2">1. One</string>
+ <string name="formatting_help_lists_body_3">2. Two</string>
+ <string name="formatting_help_lists_body_4">3. Three</string>
+ <string name="formatting_help_lists_body_5">Sometimes you want bullet points:</string>
+ <string name="formatting_help_lists_body_6">* Start a line with a star</string>
+ <string name="formatting_help_lists_body_7">* Profit!</string>
+ <string name="formatting_help_lists_body_8">Alternatively,</string>
+ <string name="formatting_help_lists_body_9">- Dashes work just as well</string>
+ <string name="formatting_help_lists_body_10">- And if you have sub points, put two spaces before the dash or star:</string>
+ <string name="formatting_help_lists_body_11">- Like this</string>
+ <string name="formatting_help_lists_body_12">- And this</string>
+
+ <string name="formatting_help_checkboxes_title">Checkboxes</string>
+ <string name="formatting_help_checkboxes_body_1">To create a checkbox, use a list followed by brackets</string>
+ <string name="formatting_help_checkboxes_body_2">- [ ] Item 1</string>
+ <string name="formatting_help_checkboxes_body_3">* [ ] Item 2</string>
+
+ <string name="formatting_help_structured_documents_title">Structured documents</string>
+ <string name="formatting_help_structured_documents_body_1">Sometimes it\'s useful to have different levels of headings to structure your documents. Start lines with a `#` to create headings. Multiple `##` in a row denote smaller heading sizes.</string>
+ <string name="formatting_help_structured_documents_body_2">### This is a third-tier heading</string>
+ <string name="formatting_help_structured_documents_body_3">You can use one `#` all the way up to `######` six for different heading sizes.</string>
+ <string name="formatting_help_structured_documents_body_4">If you\'d like to quote someone, use the > character before the line:</string>
+ <string name="formatting_help_structured_documents_body_5">> Coffee. The finest organic suspension ever devised… I beat the Borg with it.</string>
+ <string name="formatting_help_structured_documents_body_6">> - Captain Janeway</string>
+
+ <string name="formatting_help_code_title">Code</string>
+ <string name="formatting_help_code_body_1">There are many different ways to style code with Markdown. If you have inline code blocks, wrap them in backticks:</string>
+ <string name="formatting_help_code_body_2">\\`var example = true\\`</string>
+ <string name="formatting_help_code_body_3">`var example = true`</string>
+ <string name="formatting_help_code_body_4">Markdown also supports something called code fencing, which allows for multiple lines without indentation:</string>
+ <string name="formatting_help_code_body_5">And if you\'d like to use syntax highlighting, include the language:</string>
+
+ <string name="formatting_help_unsupported_title">Unsupported</string>
+ <string name="formatting_help_unsupported_body_1">While we try to continuously improve the support for Markdown, there are a few features which are not yet supported by Notes:</string>
+ <string name="formatting_help_unsupported_body_2">- Tables</string>
+ <string name="formatting_help_unsupported_body_3">- Images</string>
+ <string name="formatting_help_unsupported_body_4">If you are interested in contributing support for one of those features, get in contact with us via GitHub or E-Mail.</string>
</resources>
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index 3fc5b4f9..191d4819 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
- <it.niedermann.owncloud.notes.branding.BrandedPreferenceCategory
+ <it.niedermann.owncloud.notes.branding.BrandedPreferenceCategory
app:layout="@layout/item_preference_category"
app:title="@string/simple_synchronization">
@@ -25,7 +25,6 @@
</it.niedermann.owncloud.notes.branding.BrandedPreferenceCategory>
<it.niedermann.owncloud.notes.branding.BrandedPreferenceCategory
-
app:layout="@layout/item_preference_category"
app:title="@string/simple_appearance">
@@ -47,21 +46,8 @@
android:title="@string/settings_branding" />
</it.niedermann.owncloud.notes.branding.BrandedPreferenceCategory>
- <it.niedermann.owncloud.notes.branding.BrandedPreferenceCategory
- android:key="@string/pref_category_security"
- app:layout="@layout/item_preference_category"
- app:title="@string/simple_security">
- <it.niedermann.owncloud.notes.branding.BrandedSwitchPreference
- android:defaultValue="@string/pref_value_lock"
- android:icon="@drawable/ic_lock_grey600_24dp"
- android:key="@string/pref_key_lock"
- android:layout="@layout/item_pref"
- android:summary="@string/simple_beta"
- android:title="@string/settings_lock" />
- </it.niedermann.owncloud.notes.branding.BrandedPreferenceCategory>
<it.niedermann.owncloud.notes.branding.BrandedPreferenceCategory
-
app:layout="@layout/item_preference_category"
app:title="@string/simple_behavior">
<it.niedermann.owncloud.notes.branding.BrandedSwitchPreference
@@ -90,4 +76,18 @@
android:summary="%s"
android:title="@string/settings_font_size" />
</it.niedermann.owncloud.notes.branding.BrandedPreferenceCategory>
+
+ <it.niedermann.owncloud.notes.branding.BrandedPreferenceCategory
+ android:key="@string/pref_category_security"
+ app:layout="@layout/item_preference_category"
+ app:title="@string/simple_security">
+ <it.niedermann.owncloud.notes.branding.BrandedSwitchPreference
+ android:defaultValue="@string/pref_value_lock"
+ android:icon="@drawable/ic_lock_grey600_24dp"
+ android:key="@string/pref_key_lock"
+ android:layout="@layout/item_pref"
+ android:summary="@string/simple_beta"
+ android:title="@string/settings_lock" />
+ </it.niedermann.owncloud.notes.branding.BrandedPreferenceCategory>
+
</PreferenceScreen>