Skip to content

Commit

Permalink
Navigation and highlighting improvements (PR gsantner#2377 closes gsa…
Browse files Browse the repository at this point in the history
…ntner#2409 closes gsantner#2410)

* Many fixes to navigation and go back
* Cleanups to fragment handling
* Tweaks to showing keyboard
* Final tweaks to activity stacks
* Removed unnecessary 'synchronized' calls for perf
* Tweaks to highlighting
* Reverted some highlighting changes
* Fix template cursor start
* Improvements to display of file browser dialog / fragment
* Initial set of changes for async
* Using canonical paths and and static members
* Defensive logic for indices
* Batching fixup for reduced computation
* Switching back to start end as it made no difference
* Tweaks to launching; file paths -> canonical
* Fixed wikitext link formatting

(cherry picked from commit c5fe529)
  • Loading branch information
harshad1 authored and elyahw committed Sep 26, 2024
1 parent d874d2f commit 00f64e4
Show file tree
Hide file tree
Showing 31 changed files with 944 additions and 780 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ dependencies {
// UI libs
implementation 'com.github.AppIntro:AppIntro:6.2.0'


// Tool libraries
//noinspection AnnotationProcessorOnCompilePath
implementation 'commons-io:commons-io:2.7'
Expand Down
6 changes: 4 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
android:name=".activity.MainActivity"
android:exported="true"
android:label="@string/app_name"
android:launchMode="singleInstance"
android:launchMode="standard"
android:taskAffinity=".activity.MainActivity"
android:windowSoftInputMode="stateUnchanged|adjustResize">
<intent-filter>
Expand Down Expand Up @@ -167,7 +167,9 @@
</activity>
<activity
android:name=".activity.openeditor.OpenFromShortcutOrWidgetActivity"
android:launchMode="singleInstance"

android:launchMode="standard"

android:theme="@android:style/Theme.NoDisplay" />
<activity
android:name=".activity.DocumentActivity"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,24 @@
import net.gsantner.opoc.util.GsFileUtils;

import java.io.File;
import java.util.Stack;

import other.so.AndroidBug5497Workaround;

public class DocumentActivity extends MarkorBaseActivity {
public static final String EXTRA_DO_PREVIEW = "EXTRA_DO_PREVIEW";

private Toolbar _toolbar;

private FragmentManager _fragManager;

private static boolean nextLaunchTransparentBg = false;

public static void launch(final Activity activity, final Intent intent) {
final File file = MarkorContextUtils.getIntentFile(intent, null);
final Integer lineNumber = intent.hasExtra(Document.EXTRA_FILE_LINE_NUMBER) ? intent.getIntExtra(Document.EXTRA_FILE_LINE_NUMBER, -1) : null;
final Boolean doPreview = intent.hasExtra(Document.EXTRA_DO_PREVIEW) ? intent.getBooleanExtra(Document.EXTRA_DO_PREVIEW, false) : null;
launch(activity, file, doPreview, lineNumber);
}

public static void launch(
final Activity activity,
final File file,
Expand Down Expand Up @@ -90,18 +96,16 @@ private static void launch(

intent.putExtra(Document.EXTRA_FILE, file);

if (lineNumber != null && lineNumber >= 0) {
if (lineNumber != null) {
intent.putExtra(Document.EXTRA_FILE_LINE_NUMBER, lineNumber);
}

if (doPreview != null) {
intent.putExtra(DocumentActivity.EXTRA_DO_PREVIEW, doPreview);
intent.putExtra(Document.EXTRA_DO_PREVIEW, doPreview);
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && as.isMultiWindowEnabled()) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
} else {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
}

nextLaunchTransparentBg = (activity instanceof MainActivity);
Expand Down Expand Up @@ -187,7 +191,7 @@ private void handleLaunchingIntent(final Intent intent) {
final Document doc = new Document(file);
Integer startLine = null;
if (intent.hasExtra(Document.EXTRA_FILE_LINE_NUMBER)) {
startLine = intent.getIntExtra(Document.EXTRA_FILE_LINE_NUMBER, -1);
startLine = intent.getIntExtra(Document.EXTRA_FILE_LINE_NUMBER, Document.EXTRA_FILE_LINE_NUMBER_LAST);
} else if (intentData != null) {
final String line = intentData.getQueryParameter("line");
if (line != null) {
Expand All @@ -200,7 +204,7 @@ private void handleLaunchingIntent(final Intent intent) {
if (startLine != null) {
// If a line is requested, open in edit mode so the line is shown
startInPreview = false;
} else if (intent.getBooleanExtra(EXTRA_DO_PREVIEW, false) || file.getName().startsWith("index.")) {
} else if (intent.getBooleanExtra(Document.EXTRA_DO_PREVIEW, false) || file.getName().startsWith("index.")) {
startInPreview = true;
}

Expand Down Expand Up @@ -266,11 +270,11 @@ public void setDocumentTitle(final String title) {
}

public void showTextEditor(final Document document, final Integer lineNumber, final Boolean startPreview) {
final GsFragmentBase currentFragment = getCurrentVisibleFragment();
final GsFragmentBase<?, ?> currentFragment = getCurrentVisibleFragment();

final boolean sameDocumentRequested = (
currentFragment instanceof DocumentEditAndViewFragment &&
document.getPath().equals(((DocumentEditAndViewFragment) currentFragment).getDocument().getPath()));
document.path.equals(((DocumentEditAndViewFragment) currentFragment).getDocument().path));

if (!sameDocumentRequested) {
showFragment(DocumentEditAndViewFragment.newInstance(document, lineNumber, startPreview));
Expand All @@ -286,21 +290,15 @@ protected void onResume() {
@Override
@SuppressWarnings("StatementWithEmptyBody")
public void onBackPressed() {
FragmentManager fragMgr = getSupportFragmentManager();
GsFragmentBase top = getCurrentVisibleFragment();
if (top != null) {
if (!top.onBackPressed()) {
if (fragMgr.getBackStackEntryCount() == 1) {
// Back action was not handled by fragment, handle in activity
} else if (fragMgr.getBackStackEntryCount() > 0) {
// Back action was to go one fragment back
fragMgr.popBackStack();
return;
}
} else {
// Was handled by child fragment
return;
}
final int entryCount = _fragManager.getBackStackEntryCount();
final GsFragmentBase<?, ?> top = getCurrentVisibleFragment();

// We pop the stack to go back to the previous fragment
// if the top fragment does not handle the back press
// Doesn't actually get called as we have 1 fragment in the stack
if (top != null && !top.onBackPressed() && entryCount > 1) {
_fragManager.popBackStack();
return;
}

// Handle in this activity
Expand All @@ -313,10 +311,10 @@ public void onBackPressed() {

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return super.onReceiveKeyPress(getCurrentVisibleFragment(), keyCode, event) ? true : super.onKeyDown(keyCode, event);
return super.onReceiveKeyPress(getCurrentVisibleFragment(), keyCode, event) || super.onKeyDown(keyCode, event);
}

public GsFragmentBase showFragment(GsFragmentBase fragment) {
public GsFragmentBase<?, ?> showFragment(GsFragmentBase<?, ?> fragment) {
if (fragment != getCurrentVisibleFragment()) {
_fragManager.beginTransaction()
.replace(R.id.document__placeholder_fragment, fragment, fragment.getFragmentTag())
Expand All @@ -327,11 +325,11 @@ public GsFragmentBase showFragment(GsFragmentBase fragment) {
return fragment;
}

public synchronized GsFragmentBase getExistingFragment(final String fragmentTag) {
return (GsFragmentBase) getSupportFragmentManager().findFragmentByTag(fragmentTag);
public synchronized GsFragmentBase<?, ?> getExistingFragment(final String fragmentTag) {
return (GsFragmentBase<?, ?>) getSupportFragmentManager().findFragmentByTag(fragmentTag);
}

private GsFragmentBase getCurrentVisibleFragment() {
return (GsFragmentBase) getSupportFragmentManager().findFragmentById(R.id.document__placeholder_fragment);
private GsFragmentBase<?, ?> getCurrentVisibleFragment() {
return (GsFragmentBase<?, ?>) getSupportFragmentManager().findFragmentById(R.id.document__placeholder_fragment);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
_webView.setWebChromeClient(new GsWebViewChromeClient(_webView, activity, view.findViewById(R.id.document__fragment_fullscreen_overlay)));
_webView.setWebViewClient(_webViewClient);
_webView.addJavascriptInterface(this, "Android");
_webView.setBackgroundColor(Color.TRANSPARENT);
WebSettings webSettings = _webView.getSettings();
webSettings.setBuiltInZoomControls(true);
webSettings.setDisplayZoomControls(false);
Expand All @@ -170,17 +171,15 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {

// Upon construction, the document format has been determined from extension etc
// Here we replace it with the last saved format.
_document.setFormat(_appSettings.getDocumentFormat(_document.getPath(), _document.getFormat()));
applyTextFormat(_document.getFormat());
_format.getActions().setDocument(_document);
applyTextFormat(_appSettings.getDocumentFormat(_document.path, _document.getFormat()));

if (activity instanceof DocumentActivity) {
((DocumentActivity) activity).setDocumentTitle(_document.getTitle());
((DocumentActivity) activity).setDocumentTitle(_document.title);
}

// Preview mode set before loadDocument to prevent flicker
final Bundle args = getArguments();
final boolean startInPreview = _appSettings.getDocumentPreviewState(_document.getPath());
final boolean startInPreview = _appSettings.getDocumentPreviewState(_document.path);
if (args != null && savedInstanceState == null) { // Use the launch flag on first launch
setViewModeVisibility(args.getBoolean(START_PREVIEW, startInPreview), false);
} else {
Expand All @@ -199,19 +198,18 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
// Configure the editor. Doing so after load helps prevent some errors
// ---------------------------------------------------------
_hlEditor.setLineSpacing(0, 1);
_hlEditor.setTextSize(TypedValue.COMPLEX_UNIT_SP, _appSettings.getDocumentFontSize(_document.getPath()));
_hlEditor.setTextSize(TypedValue.COMPLEX_UNIT_SP, _appSettings.getDocumentFontSize(_document.path));
_hlEditor.setTypeface(GsFontPreferenceCompat.typeface(getContext(), _appSettings.getFontFamily(), Typeface.NORMAL));
_hlEditor.setBackgroundColor(_appSettings.getEditorBackgroundColor());
_hlEditor.setTextColor(_appSettings.getEditorForegroundColor());
_hlEditor.setGravity(_appSettings.isEditorStartEditingInCenter() ? Gravity.CENTER : Gravity.NO_GRAVITY);
_hlEditor.setHighlightingEnabled(_appSettings.getDocumentHighlightState(_document.getPath(), _hlEditor.getText()));
_hlEditor.setLineNumbersEnabled(_appSettings.getDocumentLineNumbersEnabled(_document.getPath()));
_hlEditor.setAutoFormatEnabled(_appSettings.getDocumentAutoFormatEnabled(_document.getPath()));
_hlEditor.setHighlightingEnabled(_appSettings.getDocumentHighlightState(_document.path, _hlEditor.getText()));
_hlEditor.setLineNumbersEnabled(_appSettings.getDocumentLineNumbersEnabled(_document.path));
_hlEditor.setAutoFormatEnabled(_appSettings.getDocumentAutoFormatEnabled(_document.path));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Do not need to send contents to accessibility
_hlEditor.setImportantForAccessibility(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);
}
_webView.setBackgroundColor(Color.TRANSPARENT);

// Various settings
updateMenuToggleStates(0);
Expand Down Expand Up @@ -247,22 +245,23 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
}

@Override
public void onFragmentFirstTimeVisible() {
_primaryScrollView.invalidate();
int startPos = _appSettings.getLastEditPosition(_document.getPath(), _hlEditor.length());

// First start - overwrite start position if needed
if (_savedInstanceState == null) {
final Bundle args = getArguments();
if (args != null && args.containsKey(Document.EXTRA_FILE_LINE_NUMBER)) {
final int lno = args.getInt(Document.EXTRA_FILE_LINE_NUMBER);
if (lno >= 0) {
startPos = TextViewUtils.getIndexFromLineOffset(_hlEditor.getText(), lno, 0);
} else if (lno == Document.EXTRA_FILE_LINE_NUMBER_LAST) {
startPos = _hlEditor.length();
}
protected void onFragmentFirstTimeVisible() {
final Bundle args = getArguments();

int startPos = _appSettings.getLastEditPosition(_document.path, _hlEditor.length());
if (args != null && args.containsKey(Document.EXTRA_FILE_LINE_NUMBER)) {
final int lno = args.getInt(Document.EXTRA_FILE_LINE_NUMBER);
if (lno >= 0) {
startPos = TextViewUtils.getIndexFromLineOffset(_hlEditor.getText(), lno, 0);
} else if (lno == Document.EXTRA_FILE_LINE_NUMBER_LAST) {
startPos = _hlEditor.length();
}
}

_primaryScrollView.invalidate();
// Can affect layout so run before setting scroll position
_hlEditor.recomputeHighlighting();

TextViewUtils.setSelectionAndShow(_hlEditor, startPos);
}

Expand All @@ -277,9 +276,9 @@ public void onResume() {
public void onPause() {
saveDocument(false);
_webView.onPause();
_appSettings.addRecentFile(_document.getFile());
_appSettings.setDocumentPreviewState(_document.getPath(), _isPreviewVisible);
_appSettings.setLastEditPosition(_document.getPath(), _hlEditor.getSelectionStart());
_appSettings.addRecentFile(_document.file);
_appSettings.setDocumentPreviewState(_document.path, _isPreviewVisible);
_appSettings.setLastEditPosition(_document.path, TextViewUtils.getSelection(_hlEditor)[0]);
super.onPause();
}

Expand Down Expand Up @@ -424,8 +423,7 @@ public boolean loadDocument() {
_editTextUndoRedoHelper.setTextView(_hlEditor);
}

_hlEditor.setSelection(sel[0], sel[1]);
TextViewUtils.showSelection(_hlEditor);
TextViewUtils.setSelectionAndShow(_hlEditor, sel);
}
checkTextChangeState();

Expand Down Expand Up @@ -469,14 +467,15 @@ public boolean onOptionsItemSelected(@NonNull final MenuItem item) {
setViewModeVisibility(!_isPreviewVisible);
return true;
}

case R.string.action_format_wikitext:
case R.string.action_format_keyvalue:
case R.string.action_format_plaintext:
case R.string.action_format_markdown: {
if (itemId != _document.getFormat()) {
_document.setFormat(itemId);
applyTextFormat(itemId);
_appSettings.setDocumentFormat(_document.getPath(), _document.getFormat());
_appSettings.setDocumentFormat(_document.path, _document.getFormat());
}
return true;
}
Expand All @@ -485,26 +484,29 @@ public boolean onOptionsItemSelected(@NonNull final MenuItem item) {
_format.getActions().onSearch();
return true;
}

case R.id.action_line_numbers: {
final boolean newState = !_hlEditor.getLineNumbersEnabled();
_appSettings.setDocumentLineNumbersEnabled(_document.getPath(), newState);
_appSettings.setDocumentLineNumbersEnabled(_document.path, newState);
_hlEditor.setLineNumbersEnabled(newState);
updateMenuToggleStates(0);
return true;
}

case R.id.action_info: {
if (saveDocument(false)) { // In order to have the correct info displayed
FileInfoDialog.show(_document.getFile(), getParentFragmentManager());
FileInfoDialog.show(_document.file, getParentFragmentManager());
}
return true;
}
case R.id.action_set_font_size: {
MarkorDialogFactory.showFontSizeDialog(activity, _appSettings.getDocumentFontSize(_document.getPath()), (newSize) -> {
MarkorDialogFactory.showFontSizeDialog(activity, _appSettings.getDocumentFontSize(_document.path), (newSize) -> {
_hlEditor.setTextSize(TypedValue.COMPLEX_UNIT_SP, (float) newSize);
_appSettings.setDocumentFontSize(_document.getPath(), newSize);
_appSettings.setDocumentFontSize(_document.path, newSize);
});
return true;
}

default: {
return super.onOptionsItemSelected(item);
}
Expand All @@ -520,6 +522,7 @@ public void checkTextChangeState() {
}
}

@Override
public void applyTextFormat(final int textFormatId) {
final Activity activity = getActivity();
if (activity == null) {
Expand All @@ -530,10 +533,11 @@ public void applyTextFormat(final int textFormatId) {
_hlEditor.setHighlighter(_format.getHighlighter());
_hlEditor.setDynamicHighlightingEnabled(_appSettings.isDynamicHighlightingEnabled());
_hlEditor.setAutoFormatters(_format.getAutoFormatInputFilter(), _format.getAutoFormatTextWatcher());
_hlEditor.setAutoFormatEnabled(_appSettings.getDocumentAutoFormatEnabled(_document.getPath()));
_hlEditor.setAutoFormatEnabled(_appSettings.getDocumentAutoFormatEnabled(_document.path));
_format.getActions()
.setDocument(_document) // elyahw line added by merge request
.setUiReferences(activity, _hlEditor, _webView);
// .recreateActionButtons(_textActionsBar, _isPreviewVisible ? ActionButtonBase.ActionItem.DisplayMode.VIEW : ActionButtonBase.ActionItem.DisplayMode.EDIT);

updateMenuToggleStates(_format.getFormatId());

}
Expand Down Expand Up @@ -567,7 +571,7 @@ public void errorClipText() {
}

public boolean isSdStatusBad() {
if (_cu.isUnderStorageAccessFolder(getContext(), _document.getFile(), false) &&
if (_cu.isUnderStorageAccessFolder(getContext(), _document.file, false) &&
_cu.getStorageAccessFrameworkTreeUri(getContext()) == null) {
_cu.showMountSdDialog(getActivity());
return true;
Expand All @@ -580,7 +584,7 @@ public boolean isStateBad() {
return (_document == null ||
_hlEditor == null ||
_appSettings == null ||
!_cu.canWriteFile(getContext(), _document.getFile(), false, true));
!_cu.canWriteFile(getContext(), _document.file, false, true));
}

// Save the file
Expand All @@ -596,7 +600,7 @@ public boolean saveDocument(final boolean forceSaveEmpty) {
if (!_document.isContentSame(text))
{
// Touch parent folder on edit (elyahw) ----------
File ff = _document.getFile();
File ff = _document.file;
String ppath = "";
ppath = ff.getAbsolutePath();
//System.out.println("Touching parent folder\n");
Expand Down
Loading

0 comments on commit 00f64e4

Please sign in to comment.