diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/build.gradle | 7 | ||||
-rw-r--r-- | app/src/androidTest/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragmentTest.java (renamed from app/src/test/java/it/niedermann/owncloud/notes/android/fragment/SearchableBaseNoteFragmentTest.java) | 24 | ||||
-rw-r--r-- | app/src/androidTest/java/it/niedermann/owncloud/notes/persistence/ExampleInstrumentedTest.java | 27 | ||||
-rw-r--r-- | app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java | 41 | ||||
-rw-r--r-- | app/src/main/java/it/niedermann/owncloud/notes/edit/NotesTextWatcher.java | 100 | ||||
-rw-r--r-- | app/src/main/java/it/niedermann/owncloud/notes/edit/format/ContextBasedFormattingCallback.java | 115 | ||||
-rw-r--r-- | app/src/main/java/it/niedermann/owncloud/notes/edit/format/ContextBasedRangeFormattingCallback.java | 147 | ||||
-rw-r--r-- | app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetFactory.java | 17 | ||||
-rw-r--r-- | app/src/main/res/layout/fragment_note_edit.xml | 2 | ||||
-rw-r--r-- | app/src/main/res/layout/widget_single_note.xml | 8 |
10 files changed, 43 insertions, 445 deletions
diff --git a/app/build.gradle b/app/build.gradle index e496bb01..5bb7b7de 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,8 +14,8 @@ android { applicationId "it.niedermann.owncloud.notes" minSdkVersion 19 targetSdkVersion 30 - versionCode 2017001 - versionName "2.17.1" + versionCode 2018001 + versionName "2.18.1" multiDexEnabled true testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" javaCompileOptions { @@ -66,13 +66,14 @@ dependencies { implementation "com.github.nextcloud:Android-SingleSignOn:0.5.4" implementation 'com.github.stefan-niedermann.nextcloud-commons:sso-glide:1.2.2' implementation 'com.github.stefan-niedermann.nextcloud-commons:exception:1.2.2' - implementation 'com.github.stefan-niedermann:android-commons:0.1.1' + implementation 'com.github.stefan-niedermann:android-commons:0.2.0' // Glide implementation 'com.github.bumptech.glide:glide:4.11.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' // Markdown + implementation project(path: ':markdown') implementation 'com.yydcdut:markdown-processor:0.1.3' implementation 'com.yydcdut:rxmarkdown-wrapper:0.1.3' diff --git a/app/src/test/java/it/niedermann/owncloud/notes/android/fragment/SearchableBaseNoteFragmentTest.java b/app/src/androidTest/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragmentTest.java index 1d2bda5c..95a62cc0 100644 --- a/app/src/test/java/it/niedermann/owncloud/notes/android/fragment/SearchableBaseNoteFragmentTest.java +++ b/app/src/androidTest/java/it/niedermann/owncloud/notes/edit/SearchableBaseNoteFragmentTest.java @@ -1,17 +1,14 @@ -package it.niedermann.owncloud.notes.android.fragment; +package it.niedermann.owncloud.notes.edit; +import org.junit.Assert; import org.junit.Test; import java.lang.reflect.Method; import java.util.Arrays; -import it.niedermann.owncloud.notes.edit.SearchableBaseNoteFragment; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - public class SearchableBaseNoteFragmentTest { + @SuppressWarnings("ConstantConditions") @Test public void testCountOccurrencesFixed() { try { @@ -31,16 +28,17 @@ public class SearchableBaseNoteFragmentTest { System.out.println("Total Time: " + (endTime - startTime) + " ms"); System.out.println("Total Times: " + num); System.out.println("String Size: " + (sb.length() / 1024.0) + " K"); - assertEquals((int) Math.pow(2, count), num); + Assert.assertEquals((int) Math.pow(2, count), num); System.out.println(); } } catch (Exception e) { - fail(Arrays.toString(e.getStackTrace())); + Assert.fail(Arrays.toString(e.getStackTrace())); System.out.println("Test Count Occurrences Fixed" + Arrays.toString(e.getStackTrace())); } } + @SuppressWarnings("ConstantConditions") @Test public void testNullOrEmptyInput() { try { @@ -49,16 +47,16 @@ public class SearchableBaseNoteFragmentTest { int num; num = (int) method.invoke(null, null, "Hi"); - assertEquals(0, num); + Assert.assertEquals(0, num); num = (int) method.invoke(null, "Hi my name is Mike Chester Wang", null); - assertEquals(0, num); + Assert.assertEquals(0, num); num = (int) method.invoke(null, "", "Hi"); - assertEquals(0, num); + Assert.assertEquals(0, num); num = (int) method.invoke(null, "Hi my name is Mike Chester Wang", ""); - assertEquals(0, num); + Assert.assertEquals(0, num); } catch (Exception e) { - fail(Arrays.toString(e.getStackTrace())); + Assert.fail(Arrays.toString(e.getStackTrace())); System.out.println("Test Null Or Empty Input" + Arrays.toString(e.getStackTrace())); } } diff --git a/app/src/androidTest/java/it/niedermann/owncloud/notes/persistence/ExampleInstrumentedTest.java b/app/src/androidTest/java/it/niedermann/owncloud/notes/persistence/ExampleInstrumentedTest.java deleted file mode 100644 index 91525356..00000000 --- a/app/src/androidTest/java/it/niedermann/owncloud/notes/persistence/ExampleInstrumentedTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package it.niedermann.owncloud.notes.persistence; - -import android.content.Context; - -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.platform.app.InstrumentationRegistry; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.assertEquals; - -/** - * Instrumented test, which will execute on an Android device. - * - * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); - - assertEquals("it.niedermann.owncloud.notes.dev", appContext.getPackageName()); - } -} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java index 6c37ef60..c2cb62a1 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/NoteEditFragment.java @@ -3,13 +3,11 @@ package it.niedermann.owncloud.notes.edit; import android.content.Context; import android.content.SharedPreferences; import android.graphics.Typeface; -import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.text.Editable; import android.text.Layout; -import android.text.SpannableString; import android.text.TextWatcher; import android.util.Log; import android.util.TypedValue; @@ -20,26 +18,19 @@ import android.view.ViewGroup; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.ScrollView; -import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.preference.PreferenceManager; import com.google.android.material.floatingactionbutton.FloatingActionButton; -import com.yydcdut.markdown.MarkdownProcessor; -import com.yydcdut.markdown.syntax.edit.EditFactory; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.databinding.FragmentNoteEditBinding; -import it.niedermann.owncloud.notes.edit.format.ContextBasedFormattingCallback; -import it.niedermann.owncloud.notes.edit.format.ContextBasedRangeFormattingCallback; import it.niedermann.owncloud.notes.persistence.entity.NoteWithCategory; import it.niedermann.owncloud.notes.shared.model.ISyncCallback; -import it.niedermann.owncloud.notes.shared.util.MarkDownUtil; import static androidx.core.view.ViewCompat.isAttachedToWindow; -import static it.niedermann.owncloud.notes.shared.util.DisplayUtils.searchAndColor; import static it.niedermann.owncloud.notes.shared.util.NoteUtil.getFontSizeFromPreferences; public class NoteEditFragment extends SearchableBaseNoteFragment { @@ -131,10 +122,19 @@ public class NoteEditFragment extends SearchableBaseNoteFragment { public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - textWatcher = new NotesTextWatcher(binding.editContent) { + textWatcher = new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + // Nothing to do here... + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + // Nothing to do here... + } + @Override public void afterTextChanged(final Editable s) { - super.afterTextChanged(s); unsavedEdit = true; if (!saveActive) { handler.removeCallbacks(runAutoSave); @@ -157,21 +157,12 @@ public class NoteEditFragment extends SearchableBaseNoteFragment { } } - // workaround for issue yydcdut/RxMarkdown#41 - note.getNote().setContent(note.getContent().replace("\r\n", "\n")); +// workaround for issue yydcdut/RxMarkdown#41 +// note.getNote().setContent(note.getContent().replace("\r\n", "\n")); - binding.editContent.setText(note.getContent()); + binding.editContent.setMarkdownString(note.getContent()); binding.editContent.setEnabled(true); - final MarkdownProcessor markdownProcessor = new MarkdownProcessor(requireContext()); - markdownProcessor.config(MarkDownUtil.getMarkDownConfiguration(binding.editContent.getContext()).build()); - markdownProcessor.factory(EditFactory.create()); - markdownProcessor.live(binding.editContent); - - binding.editContent.setCustomSelectionActionModeCallback(new ContextBasedRangeFormattingCallback(binding.editContent)); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - binding.editContent.setCustomInsertionActionModeCallback(new ContextBasedFormattingCallback(binding.editContent)); - } 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)) { @@ -246,13 +237,13 @@ public class NoteEditFragment extends SearchableBaseNoteFragment { protected void colorWithText(@NonNull String newText, @Nullable Integer current, int mainColor, int textColor) { if (binding != null && isAttachedToWindow(binding.editContent)) { binding.editContent.clearFocus(); - binding.editContent.setText(searchAndColor(new SpannableString(getContent()), newText, requireContext(), current, mainColor, textColor), TextView.BufferType.SPANNABLE); + binding.editContent.setSearchText(newText, current); } } @Override public void applyBrand(int mainColor, int textColor) { super.applyBrand(mainColor, textColor); - binding.editContent.setHighlightColor(getTextHighlightBackgroundColor(requireContext(), mainColor, colorPrimary, colorAccent)); + binding.editContent.setSearchColor(mainColor); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/NotesTextWatcher.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/NotesTextWatcher.java deleted file mode 100644 index f9ced1ae..00000000 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/NotesTextWatcher.java +++ /dev/null @@ -1,100 +0,0 @@ -package it.niedermann.owncloud.notes.edit; - -import android.text.Editable; -import android.text.TextWatcher; -import android.util.Log; -import android.widget.EditText; - -import androidx.annotation.NonNull; - -import it.niedermann.owncloud.notes.shared.util.MarkDownUtil; - -import static it.niedermann.owncloud.notes.shared.util.MarkDownUtil.CHECKBOX_UNCHECKED_MINUS_TRAILING_SPACE; -import static it.niedermann.owncloud.notes.shared.util.MarkDownUtil.CHECKBOX_UNCHECKED_STAR_TRAILING_SPACE; - -/** - * Implements auto-continuation for checked-lists - */ -public abstract class NotesTextWatcher implements TextWatcher { - - private static final String TAG = NotesTextWatcher.class.getSimpleName(); - - private static final String codeBlock = "```"; - - private static final int lengthCheckbox = 6; - - private boolean resetSelection = false; - private boolean afterTextChangedHandeled = false; - private int resetSelectionTo = -1; - - private final EditText editText; - - protected NotesTextWatcher(EditText editText) { - this.editText = editText; - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - // Nothing to do here... - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - // https://github.com/stefan-niedermann/nextcloud-notes/issues/608 - if (count == 1 && s.charAt(start) == '\n') { // 'Enter' was pressed - autoContinueCheckboxListsOnEnter(s, start, count); - } - // https://github.com/stefan-niedermann/nextcloud-notes/issues/558 - if (s.toString().contains(codeBlock)) { - preventCursorJumpToTopWithinCodeBlock(s, start, count); - } - } - - @Override - public void afterTextChanged(Editable s) { - if (resetSelection && !afterTextChangedHandeled) { - Log.v(TAG, "Resetting selection to " + resetSelectionTo); - afterTextChangedHandeled = true; - setNewText(new StringBuilder(s), resetSelectionTo); - afterTextChangedHandeled = false; - resetSelection = false; - resetSelectionTo = -1; - } - } - - private void autoContinueCheckboxListsOnEnter(@NonNull CharSequence s, int start, int count) { - // Find start of line - int startOfLine = MarkDownUtil.getStartOfLine(s, start); - String line = s.subSequence(startOfLine, start).toString(); - - if (line.equals(CHECKBOX_UNCHECKED_MINUS_TRAILING_SPACE) || line.equals(CHECKBOX_UNCHECKED_STAR_TRAILING_SPACE)) { - editText.setSelection(startOfLine + 1); - setNewText(new StringBuilder(s).replace(startOfLine, startOfLine + lengthCheckbox + 1, "\n"), startOfLine + 1); - } else if (MarkDownUtil.lineStartsWithCheckbox(line, false)) { - setNewText(new StringBuilder(s).insert(start + count, CHECKBOX_UNCHECKED_MINUS_TRAILING_SPACE), start + lengthCheckbox + 1); - } else if (MarkDownUtil.lineStartsWithCheckbox(line, true)) { - setNewText(new StringBuilder(s).insert(start + count, CHECKBOX_UNCHECKED_STAR_TRAILING_SPACE), start + lengthCheckbox + 1); - } - } - - private void preventCursorJumpToTopWithinCodeBlock(@NonNull CharSequence s, int start, int count) { - // Find start of line - int startOfLine = MarkDownUtil.getStartOfLine(s, start); - String line = s.subSequence(startOfLine, start).toString(); - // "start" is the direct sibling of the codeBlock - if (line.startsWith(codeBlock) && start - startOfLine == codeBlock.length() && !resetSelection) { - resetSelectionTo = editText.getSelectionEnd(); - resetSelection = true; - Log.v(TAG, "Entered a character directly behind a codeBlock - prepare selection reset to " + resetSelectionTo); - } else if (s.subSequence(startOfLine, start + count).toString().startsWith(codeBlock) && !resetSelection) { - resetSelectionTo = editText.getSelectionEnd(); - resetSelection = true; - Log.v(TAG, "One completed a ``-codeBlock with the third `-character - prepare selection reset to " + resetSelectionTo); - } - } - - private void setNewText(@NonNull StringBuilder newText, int selection) { - editText.setText(newText); - editText.setSelection(selection); - } -} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/format/ContextBasedFormattingCallback.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/format/ContextBasedFormattingCallback.java deleted file mode 100644 index 32272fba..00000000 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/format/ContextBasedFormattingCallback.java +++ /dev/null @@ -1,115 +0,0 @@ -package it.niedermann.owncloud.notes.edit.format; - -import android.graphics.Typeface; -import android.text.SpannableStringBuilder; -import android.text.TextUtils; -import android.text.style.StyleSpan; -import android.util.Log; -import android.view.ActionMode; -import android.view.Menu; -import android.view.MenuItem; -import android.widget.EditText; - -import it.niedermann.android.util.ClipboardUtil; -import it.niedermann.owncloud.notes.R; -import it.niedermann.owncloud.notes.shared.util.MarkDownUtil; - -import static it.niedermann.owncloud.notes.shared.util.MarkDownUtil.CHECKBOX_UNCHECKED_MINUS_TRAILING_SPACE; -import static it.niedermann.owncloud.notes.shared.util.MarkDownUtil.getEndOfLine; -import static it.niedermann.owncloud.notes.shared.util.MarkDownUtil.getStartOfLine; - -public class ContextBasedFormattingCallback implements ActionMode.Callback { - - private static final String TAG = ContextBasedFormattingCallback.class.getSimpleName(); - - private final EditText editText; - - public ContextBasedFormattingCallback(EditText editText) { - this.editText = editText; - } - - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - mode.getMenuInflater().inflate(R.menu.context_based_formatting, menu); - return true; - } - - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - CharSequence text = editText.getText(); - int originalCursorPosition = editText.getSelectionStart(); - if (originalCursorPosition >= 0 && originalCursorPosition <= text.length()) { - int startOfLine = getStartOfLine(text, originalCursorPosition); - int endOfLine = getEndOfLine(text, startOfLine); - String line = text.subSequence(startOfLine, endOfLine).toString(); - if (MarkDownUtil.lineStartsWithCheckbox(line)) { - menu.findItem(R.id.checkbox).setVisible(false); - Log.i(TAG, "Hide checkbox menu item because line starts already with checkbox"); - } - } else { - Log.e(TAG, "SelectionStart is " + originalCursorPosition + ". Expected to be between 0 and " + text.length()); - } - return false; - } - - @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - switch (item.getItemId()) { - case R.id.checkbox: - insertCheckbox(); - return true; - case R.id.link: - insertLink(); - return true; - default: - return false; - } - } - - private void insertCheckbox() { - CharSequence text = editText.getText(); - int originalCursorPosition = editText.getSelectionStart(); - int startOfLine = getStartOfLine(text, originalCursorPosition); - Log.i(TAG, "Inserting checkbox at position " + startOfLine); - CharSequence part1 = text.subSequence(0, startOfLine); - CharSequence part2 = text.subSequence(startOfLine, text.length()); - editText.setText(TextUtils.concat(part1, CHECKBOX_UNCHECKED_MINUS_TRAILING_SPACE, part2)); - editText.setSelection(originalCursorPosition + CHECKBOX_UNCHECKED_MINUS_TRAILING_SPACE.length()); - } - - private void insertLink() { - SpannableStringBuilder ssb = new SpannableStringBuilder(editText.getText()); - int start = editText.getText().length(); - int end = start; - boolean textToFormatIsLink = TextUtils.indexOf(editText.getText().subSequence(start, end), "http") == 0; - if (textToFormatIsLink) { - Log.i(TAG, "Inserting link description for position " + start + " to " + end); - ssb.insert(end, ")"); - ssb.insert(start, "[]("); - } else { - String clipboardURL = ClipboardUtil.INSTANCE.getClipboardURLorNull(editText.getContext()); - if (clipboardURL != null) { - Log.i(TAG, "Inserting link from clipboard at position " + start + " to " + end + ": " + clipboardURL); - ssb.insert(end, "](" + clipboardURL + ")"); - end += clipboardURL.length(); - } else { - Log.i(TAG, "Inserting empty link for position " + start + " to " + end); - ssb.insert(end, "]()"); - } - ssb.insert(start, "["); - } - end++; - ssb.setSpan(new StyleSpan(Typeface.NORMAL), start, end, 1); - editText.setText(ssb); - if (textToFormatIsLink) { - editText.setSelection(start + 1); - } else { - editText.setSelection(end + 2); // after <end>]( - } - } - - @Override - public void onDestroyActionMode(ActionMode mode) { - // Nothing to do here... - } -} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/format/ContextBasedRangeFormattingCallback.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/format/ContextBasedRangeFormattingCallback.java deleted file mode 100644 index c7b25727..00000000 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/format/ContextBasedRangeFormattingCallback.java +++ /dev/null @@ -1,147 +0,0 @@ -package it.niedermann.owncloud.notes.edit.format; - -import android.graphics.Typeface; -import android.text.SpannableStringBuilder; -import android.text.TextUtils; -import android.text.style.StyleSpan; -import android.util.SparseIntArray; -import android.view.ActionMode; -import android.view.Menu; -import android.view.MenuItem; -import android.widget.EditText; - -import it.niedermann.android.util.ClipboardUtil; -import it.niedermann.owncloud.notes.R; - -public class ContextBasedRangeFormattingCallback implements ActionMode.Callback { - - private static final String TAG = ContextBasedRangeFormattingCallback.class.getSimpleName(); - - private final EditText editText; - - public ContextBasedRangeFormattingCallback(EditText editText) { - this.editText = editText; - } - - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - mode.getMenuInflater().inflate(R.menu.context_based_range_formatting, menu); - - SparseIntArray styleFormatMap = new SparseIntArray(); - styleFormatMap.append(R.id.bold, Typeface.BOLD); - styleFormatMap.append(R.id.italic, Typeface.ITALIC); - - MenuItem item; - CharSequence title; - SpannableStringBuilder ssb; - - for (int i = 0; i < styleFormatMap.size(); i++) { - item = menu.findItem(styleFormatMap.keyAt(i)); - title = item.getTitle(); - ssb = new SpannableStringBuilder(title); - ssb.setSpan(new StyleSpan(styleFormatMap.valueAt(i)), 0, title.length(), 0); - item.setTitle(ssb); - } - - return true; - } - - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - // TODO hide actions if not available? - return false; - } - - @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - int start = editText.getSelectionStart(); - int end = editText.getSelectionEnd(); - SpannableStringBuilder ssb = new SpannableStringBuilder(editText.getText()); - final String markdown; - - - int itemId = item.getItemId(); - if (itemId == R.id.bold) { - markdown = "**"; - if (hasAlreadyMarkdown(start, end, markdown)) { - this.removeMarkdown(ssb, start, end, markdown); - } else { - this.addMarkdown(ssb, start, end, markdown, Typeface.BOLD); - } - editText.setText(ssb); - editText.setSelection(end + markdown.length() * 2); - return true; - } else if (itemId == R.id.italic) { - markdown = "*"; - if (hasAlreadyMarkdown(start, end, markdown)) { - this.removeMarkdown(ssb, start, end, markdown); - } else { - this.addMarkdown(ssb, start, end, markdown, Typeface.ITALIC); - } - editText.setText(ssb); - editText.setSelection(end + markdown.length() * 2); - return true; - } else if (itemId == R.id.link) { - boolean textToFormatIsLink = TextUtils.indexOf(editText.getText().subSequence(start, end), "http") == 0; - if (textToFormatIsLink) { - ssb.insert(end, ")"); - ssb.insert(start, "[]("); - } else { - String clipboardURL = ClipboardUtil.INSTANCE.getClipboardURLorNull(editText.getContext()); - if (clipboardURL != null) { - ssb.insert(end, "](" + clipboardURL + ")"); - end += clipboardURL.length(); - } else { - ssb.insert(end, "]()"); - } - ssb.insert(start, "["); - } - end++; - ssb.setSpan(new StyleSpan(Typeface.NORMAL), start, end, 1); - editText.setText(ssb); - if (textToFormatIsLink) { - editText.setSelection(start + 1); - } else { - editText.setSelection(end + 2); // after <end>]( - } - return true; - } else if (itemId == android.R.id.cut) {// https://github.com/stefan-niedermann/nextcloud-notes/issues/604 - // https://github.com/stefan-niedermann/nextcloud-notes/issues/477 - try { - editText.onTextContextMenuItem(item.getItemId()); - return true; - } catch (IndexOutOfBoundsException e) { - e.printStackTrace(); - editText.setSelection(0, 0); - editText.clearFocus(); - return true; - } - } - return false; - } - - @Override - public void onDestroyActionMode(ActionMode mode) { - // Nothing to do here... - } - - private boolean hasAlreadyMarkdown(int start, int end, String markdown) { - return start > markdown.length() && markdown.contentEquals(editText.getText().subSequence(start - markdown.length(), start)) && - editText.getText().length() > end + markdown.length() && markdown.contentEquals(editText.getText().subSequence(end, end + markdown.length())); - } - - private void removeMarkdown(SpannableStringBuilder ssb, int start, int end, String markdown) { - // FIXME disabled, because it does not work properly and might cause data loss - // ssb.delete(start - markdown.length(), start); - // ssb.delete(end - markdown.length(), end); - // ssb.setSpan(new StyleSpan(Typeface.NORMAL), start, end, 1); - } - - private void addMarkdown(SpannableStringBuilder ssb, int start, int end, String markdown, int typeface) { - ssb.insert(end, markdown); - ssb.insert(start, markdown); - editText.getText().charAt(start); - editText.getText().charAt(start + 1); - ssb.setSpan(new StyleSpan(typeface), start, end + markdown.length() * 2, 1); - } -} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetFactory.java b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetFactory.java index cba7b691..5c09e154 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetFactory.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetFactory.java @@ -8,9 +8,9 @@ import android.util.Log; import android.widget.RemoteViews; import android.widget.RemoteViewsService; -import com.yydcdut.markdown.MarkdownProcessor; -import com.yydcdut.markdown.syntax.text.TextFactory; +import java.util.NoSuchElementException; +import it.niedermann.android.markdown.MarkdownUtil; import it.niedermann.owncloud.notes.NotesApplication; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.edit.EditNoteActivity; @@ -20,11 +20,9 @@ import it.niedermann.owncloud.notes.persistence.entity.SingleNoteWidgetData; import it.niedermann.owncloud.notes.preferences.DarkModeSetting; import it.niedermann.owncloud.notes.shared.util.MarkDownUtil; -import static it.niedermann.owncloud.notes.shared.util.MarkDownUtil.parseCompat; public class SingleNoteWidgetFactory implements RemoteViewsService.RemoteViewsFactory { - private final MarkdownProcessor markdownProcessor; private final Context context; private final int appWidgetId; @@ -36,18 +34,15 @@ public class SingleNoteWidgetFactory implements RemoteViewsService.RemoteViewsFa SingleNoteWidgetFactory(Context context, Intent intent) { this.context = context; - appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, + this.appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); - db = NotesDatabase.getInstance(context); - markdownProcessor = new MarkdownProcessor(this.context); - markdownProcessor.factory(TextFactory.create()); + this.db = NotesDatabase.getInstance(context); final SingleNoteWidgetData data = db.getWidgetSingleNoteDao().getSingleNoteWidgetData(appWidgetId); if (data != null) { darkModeActive = NotesApplication.isDarkThemeActive(context, DarkModeSetting.fromModeID(data.getThemeMode())); } else { Log.w(TAG, "Widget with ID " + appWidgetId + " seems to be not configured yet."); } - markdownProcessor.config(MarkDownUtil.getMarkDownConfiguration(this.context, darkModeActive).build()); } @Override @@ -109,12 +104,12 @@ public class SingleNoteWidgetFactory implements RemoteViewsService.RemoteViewsFa if (darkModeActive) { note_content = new RemoteViews(context.getPackageName(), R.layout.widget_single_note_content_dark); note_content.setOnClickFillInIntent(R.id.single_note_content_tv_dark, fillInIntent); - note_content.setTextViewText(R.id.single_note_content_tv_dark, parseCompat(markdownProcessor, note.getContent())); + note_content.setTextViewText(R.id.single_note_content_tv_dark, MarkdownUtil.renderForWidget(context, note.getContent())); } else { note_content = new RemoteViews(context.getPackageName(), R.layout.widget_single_note_content); note_content.setOnClickFillInIntent(R.id.single_note_content_tv, fillInIntent); - note_content.setTextViewText(R.id.single_note_content_tv, parseCompat(markdownProcessor, note.getContent())); + note_content.setTextViewText(R.id.single_note_content_tv, MarkdownUtil.renderForWidget(context, note.getContent())); } return note_content; diff --git a/app/src/main/res/layout/fragment_note_edit.xml b/app/src/main/res/layout/fragment_note_edit.xml index 289d3128..e4388865 100644 --- a/app/src/main/res/layout/fragment_note_edit.xml +++ b/app/src/main/res/layout/fragment_note_edit.xml @@ -23,7 +23,7 @@ android:orientation="vertical" tools:context="it.niedermann.owncloud.notes.edit.EditNoteActivity"> - <com.yydcdut.markdown.MarkdownEditText + <it.niedermann.android.markdown.MarkdownEditorImpl android:id="@+id/editContent" android:layout_width="match_parent" android:layout_height="wrap_content" diff --git a/app/src/main/res/layout/widget_single_note.xml b/app/src/main/res/layout/widget_single_note.xml index baa23947..5f240c5b 100644 --- a/app/src/main/res/layout/widget_single_note.xml +++ b/app/src/main/res/layout/widget_single_note.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/widget_background"> @@ -8,16 +9,17 @@ android:id="@+id/single_note_widget_lv" android:layout_width="match_parent" android:layout_height="match_parent" - android:padding="@dimen/widget_single_note_padding" /> + android:padding="@dimen/widget_single_note_padding" + tools:listitem="@layout/widget_single_note_content" /> <TextView android:id="@+id/widget_single_note_placeholder_tv" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" + android:padding="@dimen/widget_single_note_padding" android:text="@string/widget_single_note_placeholder_tv" - android:textColor="@color/fg_default_high_dark_theme" android:textAlignment="center" - android:padding="@dimen/widget_single_note_padding" /> + android:textColor="@color/fg_default_high_dark_theme" /> </RelativeLayout> |