Skip to content

Commit

Permalink
Merge branch 'scroll_sync' of https://github.com/guanglinn/markor int…
Browse files Browse the repository at this point in the history
…o scroll_sync
  • Loading branch information
guanglinn committed Dec 15, 2024
2 parents c53691b + 3f42e2b commit adaab2f
Show file tree
Hide file tree
Showing 18 changed files with 178 additions and 100 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ android {
defaultConfig {
resValue "string", "manifest_package_id", "net.gsantner.markor"
applicationId "net.gsantner.markor"
versionName "2.13.0"
versionCode 155
versionName "2.13.1"
versionCode 156

multiDexEnabled true
minSdkVersion rootProject.ext.version_minSdk
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import android.os.Build;
import android.os.Bundle;
import android.text.Html;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;

Expand Down Expand Up @@ -95,8 +96,8 @@ private static void launch(
intent = new Intent(activity, DocumentActivity.class);

if (!(activity instanceof DocumentActivity) &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
as.isMultiWindowEnabled()
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
as.isMultiWindowEnabled()
) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
}
Expand Down Expand Up @@ -254,7 +255,8 @@ public boolean dispatchTouchEvent(MotionEvent event) {
}
try {
return super.dispatchTouchEvent(event);
} catch (IndexOutOfBoundsException ignored) {
} catch (Exception e) {
Log.e(getClass().getName(), "Error in super.dispatchTouchEvent: " + e);
return false;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,12 @@ private boolean isDisplayedAtMainActivity() {
}

public void updateViewModeText() {
_format.getConverter().convertMarkupShowInWebView(_document, getTextString(), getActivity(), _webView, _nextConvertToPrintMode, _hlEditor.isLineNumbersEnabled());
// Don't let text to view mode crash app
try {
_format.getConverter().convertMarkupShowInWebView(_document, getTextString(), getActivity(), _webView, _nextConvertToPrintMode, _hlEditor.isLineNumbersEnabled());
} catch (OutOfMemoryError e) {
_format.getConverter().convertMarkupShowInWebView(_document, "updateViewModeText getTextString(): OutOfMemory " + e, getActivity(), _webView, _nextConvertToPrintMode, _hlEditor.isLineNumbersEnabled());
}
}

public void setViewModeVisibility(final boolean show) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.util.Patterns;
import android.util.TypedValue;
Expand Down Expand Up @@ -375,7 +376,7 @@ private String formatShare(final String shared) {
}

// Put the shared text in the right place
parts.add(1, shared);
parts.add(parts.isEmpty() ? 0 : 1, shared);

return TextUtils.join("", parts);
}
Expand Down Expand Up @@ -433,7 +434,9 @@ public void onFsViewerConfig(GsFileBrowserOptions.Options dopt) {

@Override
public void onFsViewerSelected(final String request, final File sel, final Integer lineNumber) {
if (sel.isDirectory()) {
if (sel == null) {
Log.e(getClass().getName(), "onFsViewerSelected: selected file is null");
} else if (sel.isDirectory()) {
NewFileDialog.newInstance(sel, false, f -> {
if (f.isFile()) {
appendToExistingDocumentAndClose(f, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,6 @@ private List<String> loadActionPreference(final String suffix) {
public List<String> getActionOrder() {
final Set<String> order = new LinkedHashSet<>(loadActionPreference(ORDER_SUFFIX));

// Handle the case where order was stored without suffix. i.e. before this release.
if (order.isEmpty()) {
order.addAll(loadActionPreference(""));
}

final Set<String> defined = new LinkedHashSet<>(getActiveActionKeys());
final Set<String> disabled = new LinkedHashSet<>(getDisabledActions());

Expand Down Expand Up @@ -302,7 +297,7 @@ public void recreateActionButtons(final ViewGroup barLayout, final ActionItem.Di
@SuppressLint("ClickableViewAccessibility")
private void setupRepeat(final View btn) {
// Velocity and acceleration parameters
final int INITIAL_DELAY = 400, DELTA_DELAY = 50, MIN_DELAY = 100;
final int INITIAL_DELAY = 300, DELTA_DELAY = 100, MIN_DELAY = 100;
final Handler handler = new Handler();

final Runnable repeater = new Runnable() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,12 @@ private AlertDialog makeDialog(final File basedir, final boolean allowCreateDir,
templateAdapter.addAll(GsCollectionUtils.map(templates, p -> p.first));
templateSpinner.setAdapter(templateAdapter);

templateSpinner.setOnItemSelectedListener(new GsAndroidSpinnerOnItemSelectedAdapter(pos -> {
final String template = templateAdapter.getItem(pos);
final String fmt = appSettings.getTemplateTitleFormat(template);
formatEdit.setText(fmt);
}));

// Setup type / format spinner and action
// -----------------------------------------------------------------------------------------
final ArrayAdapter<String> typeAdapter = new ArrayAdapter<>(activity, android.R.layout.simple_spinner_dropdown_item);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,22 @@
import android.text.Layout;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.ActionMode;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.widget.AppCompatEditText;

import net.gsantner.markor.ApplicationObject;
import net.gsantner.markor.R;
import net.gsantner.markor.activity.MainActivity;
import net.gsantner.markor.model.AppSettings;
import net.gsantner.opoc.format.GsTextUtils;
Expand All @@ -37,6 +43,7 @@

import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -111,17 +118,30 @@ public void afterTextChanged(final Editable s) {

// Fix for Android 12 perf issues - https://github.com/gsantner/markor/discussions/1794
setEmojiCompatEnabled(false);

// Custom options
setupCustomOptions();
}

@Override
public boolean onPreDraw() {
_lineNumbersDrawer.setTextSize(getTextSize());
return super.onPreDraw();
try {
return super.onPreDraw();
} catch (OutOfMemoryError ignored) {
return false; // return false to cancel current drawing pass/round
}
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
try {
super.onDraw(canvas);
} catch (Exception e) {
// Hinder drawing from crashing the app
Log.e(getClass().getName(), "HighlightingEdtior onDraw->super.onDraw crash" + e);
Toast.makeText(getContext(), e.toString(), Toast.LENGTH_SHORT).show();
}

if (_numEnabled) {
_lineNumbersDrawer.draw(canvas);
Expand Down Expand Up @@ -181,7 +201,10 @@ public void recomputeHighlighting() {
*/
private void recomputeHighlightingAsync() {
if (runHighlight(true)) {
executor.execute(this::_recomputeHighlightingWorker);
try {
executor.execute(this::_recomputeHighlightingWorker);
} catch (RejectedExecutionException ignored) {
}
}
}

Expand Down Expand Up @@ -289,14 +312,12 @@ public boolean bringPointIntoView(int i) {

private int rowStart(final int y) {
final Layout layout = getLayout();
final int line = layout.getLineForVertical(y);
return layout.getLineStart(line);
return layout == null ? 0 : layout.getLineStart(layout.getLineForVertical(y));
}

private int rowEnd(final int y) {
final Layout layout = getLayout();
final int line = layout.getLineForVertical(y);
return layout.getLineEnd(line);
return layout == null ? 0 : layout.getLineEnd(layout.getLineForVertical(y));
}

public int getFirstVisibleLineNumber() {
Expand Down Expand Up @@ -424,7 +445,12 @@ public boolean onTextContextMenuItem(int id) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && id == android.R.id.paste) {
id = android.R.id.pasteAsPlainText;
}
return super.onTextContextMenuItem(id);
try {
// i.e. DeadSystemRuntimeException can happen here
return super.onTextContextMenuItem(id);
} catch (Exception ignored) {
return true;
}
}

// Accessibility code is blocked during rapid update events
Expand Down Expand Up @@ -529,6 +555,11 @@ public void withAutoFormatDisabled(final GsCallback.a0 callback) {
// Utility functions for interaction
// ---------------------------------------------------------------------------------------------

public void selectLines() {
final int[] sel = TextViewUtils.getLineSelection(this);
setSelection(sel[0], sel[1]);
}

public void simulateKeyPress(int keyEvent_KEYCODE_SOMETHING) {
dispatchKeyEvent(new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, keyEvent_KEYCODE_SOMETHING, 0));
dispatchKeyEvent(new KeyEvent(0, 0, KeyEvent.ACTION_UP, keyEvent_KEYCODE_SOMETHING, 0));
Expand Down Expand Up @@ -749,4 +780,37 @@ public void reset() {
_maxNumberDigits = 0;
}
}

private void setupCustomOptions() {
setCustomSelectionActionModeCallback(new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Add custom items programmatically
menu.add(0, R.string.option_select_lines, 0, "☰");
return true;
}

@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// Modify menu items here if necessary
return true;
}

@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.string.option_select_lines:
HighlightingEditor.this.selectLines();
return true;
default:
return false;
}
}

@Override
public void onDestroyActionMode(ActionMode mode) {
// Cleanup if needed
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@
* Spans are further divided into two categories: dynamic and static.
* - Dynamic spans are updated as one scrolls, as described above
* - Static spans are applied once and never updated. These are typically used for
* spans which affect the text layout.
* - For example, a span which makes text bigger.
* - Updating these dynamically would make the text jump around as one scrolls
* spans which affect the text layout.
* - For example, a span which makes text bigger.
* - Updating these dynamically would make the text jump around as one scrolls
* <p>
* Fixup:
* - As the user types we shift all spans to accomodate the changed text.
Expand All @@ -75,19 +75,19 @@
* - Derived classes should override generateSpans() to generate all spans
* - New spans are added by calling addSpanGroup()
* - The HighlightingEditor will trigger the generation of spans when the text changes.
* - This is debounced so that changes are batched
* - Span generation is done on a background thread
* - This is debounced so that changes are batched
* - Span generation is done on a background thread
* <p>
* Other performance tips:
* - Performance is heavily dependent on the number of spans applied to the text.
* - Combine related spans into a single span if possible
* - HighlightSpan is a helper class which can be used to create a span with multiple attributes
* - For example, a span which makes text bold and italic
* - HighlightSpan is a helper class which can be used to create a span with multiple attributes
* - For example, a span which makes text bold and italic
* - Absolutely minimize the number of spans implementing `UpdateLayout`
* - These spans trigger a text layout update when changed in any way
* - Instead consider using a span implementing `StaticSpan`
* - If StaticSpans are present, the text is reflowed after applying them
* - This happens once, and not for each span, which is much more efficient
* - These spans trigger a text layout update when changed in any way
* - Instead consider using a span implementing `StaticSpan`
* - If StaticSpans are present, the text is reflowed after applying them
* - This happens once, and not for each span, which is much more efficient
*/
public abstract class SyntaxHighlighterBase {

Expand Down Expand Up @@ -230,7 +230,7 @@ public SyntaxHighlighterBase clearStatic() {
boolean hasStatic = false;
for (int i = _groups.size() - 1; i >= 0; i--) {
final SpanGroup group = _groups.get(i);
if (group.isStatic) {
if (group != null && group.isStatic) {
hasStatic = true;
_spannable.removeSpan(group.span);
}
Expand Down Expand Up @@ -348,7 +348,7 @@ public SyntaxHighlighterBase applyDynamic(final int[] range) {
for (int i = 0; i < _groups.size(); i++) {
final SpanGroup group = _groups.get(i);

if (group.isStatic) {
if (group == null || group.isStatic) {
continue;
}

Expand All @@ -368,7 +368,6 @@ public SyntaxHighlighterBase applyDynamic(final int[] range) {
}



public SyntaxHighlighterBase applyStatic() {
if (_spannable != null && !_staticApplied) {
applyFixup();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -869,7 +869,7 @@ public boolean isExperimentalFeaturesEnabled() {
}

public boolean isHighlightBiggerHeadings() {
return getBool(R.string.pref_key__editor_markdown_bigger_headings_2, false);
return getBool(R.string.pref_key__editor_markdown_bigger_headings_3, false);
}

public String getViewModeLinkColor() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ public void onViewCreated(final View root, final @Nullable Bundle savedInstanceS

_filesystemViewerAdapter = new GsFileBrowserListAdapter(_dopt, activity);
_recyclerList.setAdapter(_filesystemViewerAdapter);
_filesystemViewerAdapter.getFilter().filter("");
onFsViewerDoUiUpdate(_filesystemViewerAdapter);

// Setup callbacks
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceStat

_filesystemViewerAdapter = new GsFileBrowserListAdapter(_dopt, context);
_recyclerList.setAdapter(_filesystemViewerAdapter);
_filesystemViewerAdapter.getFilter().filter("");
onFsViewerDoUiUpdate(_filesystemViewerAdapter);

_swipe.setOnRefreshListener(() -> {
Expand Down
Loading

0 comments on commit adaab2f

Please sign in to comment.