Skip to content

Commit

Permalink
Improve file I/O, by @harshad1 (PR #1489)
Browse files Browse the repository at this point in the history
* Basic defensive changes
* Removed unnecessary code
* Added manual empty saving
* Use modtime instead of time delta
* set hash on load too
* Better scrolling to position and intent based line number
* Modtime for load within document itself
* Set format etc _before_ load
  • Loading branch information
harshad1 committed Nov 20, 2021
1 parent 7dc3b05 commit 06ad871
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,6 @@ public void showTextEditor(@Nullable Document document, @Nullable File file, boo

if (!sameDocumentRequested) {
if (document != null) {
document.resetModTime();
showFragment(DocumentEditFragment.newInstance(document).setPreviewFlag(preview));
} else {
showFragment(DocumentEditFragment.newInstance(file, fileIsFolder, fileLineNumber).setPreviewFlag(preview));
Expand Down Expand Up @@ -373,16 +372,6 @@ public void setDocument(Document document) {
_toolbarTitleText.setText(_document.getTitle());
}

private boolean saveDocument() {
boolean ret = false;
if (getExistingFragment(DocumentEditFragment.FRAGMENT_TAG) != null) {
DocumentEditFragment def = ((DocumentEditFragment) getExistingFragment(DocumentEditFragment.FRAGMENT_TAG));
ret = def.saveDocument();
setDocument(def.getDocument()); // Apply title again. Document is modified in edit activity
}
return ret;
}

private void onToolbarTitleClicked(View v) {
if (getExistingFragment(DocumentEditFragment.FRAGMENT_TAG) != null) {
DocumentEditFragment def = ((DocumentEditFragment) getExistingFragment(DocumentEditFragment.FRAGMENT_TAG));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import android.annotation.SuppressLint;
import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.arch.lifecycle.Lifecycle;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Color;
Expand All @@ -23,7 +24,6 @@
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.Menu;
Expand Down Expand Up @@ -62,6 +62,7 @@
import net.gsantner.opoc.ui.FilesystemViewerData;
import net.gsantner.opoc.util.ActivityUtils;
import net.gsantner.opoc.util.CoolExperimentalStuff;
import net.gsantner.opoc.util.StringUtils;
import net.gsantner.opoc.util.TextViewUndoRedo;

import java.io.File;
Expand All @@ -71,7 +72,7 @@
import butterknife.OnTextChanged;
import other.writeily.widget.WrMarkorWidgetProvider;

@SuppressWarnings({"UnusedReturnValue", "RedundantCast"})
@SuppressWarnings({"UnusedReturnValue"})
@SuppressLint("NonConstantResourceId")
public class DocumentEditFragment extends GsFragmentBase implements TextFormat.TextFormatApplier {
public static final int HISTORY_DELTA = 5000;
Expand Down Expand Up @@ -110,7 +111,6 @@ public static DocumentEditFragment newInstance(File path, boolean pathIsFolder,
return f;
}


@BindView(R.id.document__fragment__edit__highlighting_editor)
HighlightingEditor _hlEditor;

Expand All @@ -134,6 +134,7 @@ public static DocumentEditFragment newInstance(File path, boolean pathIsFolder,
private boolean _isPreviewVisible;
private MarkorWebViewClient _webViewClient;
private boolean _nextConvertToPrintMode = false;
private long _loadModTime = 0;

public DocumentEditFragment() {
super();
Expand All @@ -157,7 +158,6 @@ protected int getLayoutResId() {
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
//applyTextFormat(TextFormat.FORMAT_PLAIN);
_shareUtil = new ShareUtil(view.getContext());

_webViewClient = new MarkorWebViewClient(getActivity());
Expand All @@ -177,21 +177,29 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
WebView.setWebContentsDebuggingEnabled(true);
}

int intentLineNumber = -1;
if (savedInstanceState != null && savedInstanceState.containsKey(SAVESTATE_DOCUMENT)) {
_document = (Document) savedInstanceState.getSerializable(SAVESTATE_DOCUMENT);
_document.resetModTime(); // Ensure document is loaded on restore state
} else {
_document = Document.fromArguments(getActivity(), getArguments());
intentLineNumber = _document.getIntentLineNumber();
}

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

loadDocument();

if (savedInstanceState != null && savedInstanceState.containsKey(SAVESTATE_CURSOR_POS)) {
int cursor = savedInstanceState.getInt(SAVESTATE_CURSOR_POS);
if (cursor >= 0 && cursor < _hlEditor.length()) {
_hlEditor.setSelection(cursor);
}
Activity activity = getActivity();
if (activity instanceof DocumentActivity) {
DocumentActivity da = ((DocumentActivity) activity);
da.setDocumentTitle(_document.getTitle());
da.setDocument(_document);
}

_editTextUndoRedoHelper = new TextViewUndoRedo(_hlEditor);
new ActivityUtils(getActivity()).hideSoftKeyboard().freeContextRef();
_hlEditor.clearFocus();
Expand All @@ -215,7 +223,32 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
_hlEditor.setImportantForAccessibility(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);
}
restoreDocumentPositions();

// Set the correct position after everything else done
if (!Arrays.asList(_hlEditor, _webView, _document.getFile()).contains(null)) {
if (isDisplayedAtMainActivity()) {

// Scroll to the bottom
_primaryScrollView.post(() -> _primaryScrollView.fullScroll(View.FOCUS_DOWN));

} else {

// Scroll to position
// If Intent contains line number, jump to it
// intentLineNumber only created with document reconstructed from intent
if (intentLineNumber >= 0) {
_hlEditor.smoothMoveCursorToLine(intentLineNumber);
}

// Set cursor if saved cursor state present
final int pos = savedInstanceState != null ? savedInstanceState.getInt(SAVESTATE_CURSOR_POS, -1) : -1;
final CharSequence text = _hlEditor.getText();
if (_hlEditor.indexesValid(pos) && text != null) {
_hlEditor.smoothMoveCursorToLine(StringUtils.getLineOffsetFromIndex(text, pos)[0]);
_hlEditor.setSelection(pos);
}
}
}
}

@Override
Expand All @@ -224,11 +257,6 @@ public void onResume() {

loadDocument();

int cursor = _hlEditor.getSelectionStart();
cursor = Math.max(0, cursor);
cursor = Math.min(_hlEditor.length(), cursor);
_hlEditor.setSelection(cursor);

_hlEditor.setGravity(_appSettings.isEditorStartEditingInCenter() ? Gravity.CENTER : Gravity.NO_GRAVITY);

if (_document != null && _document.getFile() != null) {
Expand Down Expand Up @@ -315,32 +343,23 @@ public boolean onQueryTextChange(String text) {
}

public void loadDocument() {
int editorpos = _hlEditor.getSelectionStart();

// Load document if mod time newer than that recorded on last load
if (_document.hasNewerModTime()) {
_hlEditor.setText(_document.loadContent(getContext()));
}
final long modTime = _document.getFile().lastModified();
//Only trigger the load process if constructing or file updated
if (!getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED) || modTime > _loadModTime) {

editorpos = editorpos > _hlEditor.length() ? _hlEditor.length() - 1 : editorpos;
_hlEditor.setSelection(Math.max(editorpos, 0));
Activity activity = getActivity();

if (activity instanceof DocumentActivity) {
DocumentActivity da = ((DocumentActivity) activity);
da.setDocumentTitle(_document.getTitle());
da.setDocument(_document);
}
final String content = _document.loadContent(getContext());
_loadModTime = modTime;

// Upon construction, the document format has been determined from extension etc
// Here we replace it with the last saved format.
_document.setFormat(_appSettings.getDocumentFormat(getPath(), _document.getFormat()));
applyTextFormat(_document.getFormat());
_textFormat.getTextActions().setDocument(_document);
// Only setText if content changed
final CharSequence text = _hlEditor.getText();
if (text == null || !content.contentEquals(text)) {
_hlEditor.setText(content);
}

if (_isPreviewVisible) {
_webViewClient.setRestoreScrollY(_webView.getScrollY());
setDocumentViewVisibility(_isPreviewVisible);
if (_isPreviewVisible) {
_webViewClient.setRestoreScrollY(_webView.getScrollY());
setDocumentViewVisibility(_isPreviewVisible);
}
}
}

Expand Down Expand Up @@ -371,7 +390,7 @@ public boolean onOptionsItemSelected(final MenuItem item) {
return true;
}
case R.id.action_save: {
saveDocument();
saveDocument(true);
return true;
}
case R.id.action_reload: {
Expand All @@ -395,28 +414,28 @@ public boolean onOptionsItemSelected(final MenuItem item) {
return true;
}
case R.id.action_share_text: {
if (saveDocument()) {
if (saveDocument(false)) {
_shareUtil.shareText(_hlEditor.getText().toString(), "text/plain");
}
return true;
}
case R.id.action_share_file: {
if (saveDocument()) {
if (saveDocument(false)) {
_shareUtil.shareStream(_document.getFile(), "text/plain");
}
return true;
}
case R.id.action_share_html:
case R.id.action_share_html_source: {
if (saveDocument()) {
if (saveDocument(false)) {
TextConverter converter = TextFormat.getFormat(_document.getFormat(), getActivity(), _document, _hlEditor).getConverter();
_shareUtil.shareText(converter.convertMarkup(_hlEditor.getText().toString(), _hlEditor.getContext(), false, _document.getFile()),
"text/" + (item.getItemId() == R.id.action_share_html ? "html" : "plain"));
}
return true;
}
case R.id.action_share_calendar_event: {
if (saveDocument()) {
if (saveDocument(false)) {
if (!_shareUtil.createCalendarAppointment(_document.getTitle(), _hlEditor.getText().toString(), null)) {
Toast.makeText(getActivity(), R.string.no_calendar_app_is_installed, Toast.LENGTH_SHORT).show();
}
Expand All @@ -425,7 +444,7 @@ public boolean onOptionsItemSelected(final MenuItem item) {
}
case android.R.id.home: {
final Activity activity = getActivity();
if (activity != null && saveDocument()) {
if (activity != null && saveDocument(false)) {
activity.onBackPressed();
}
return true;
Expand All @@ -434,7 +453,7 @@ public boolean onOptionsItemSelected(final MenuItem item) {
case R.id.action_share_image:
case R.id.action_share_pdf: {
_appSettings.getSetWebViewFulldrawing(true);
if (saveDocument()) {
if (saveDocument(false)) {
_nextConvertToPrintMode = true;
setDocumentViewVisibility(true);
Toast.makeText(getActivity(), R.string.please_wait, Toast.LENGTH_LONG).show();
Expand Down Expand Up @@ -526,7 +545,7 @@ public void onFsViewerConfig(FilesystemViewerData.Options dopt) {
}
case R.id.action_info: {
if (_document != null && _document.getFile() != null) {
saveDocument(); // In order to have the correct info displayed
saveDocument(false); // In order to have the correct info displayed
FileInfoDialog.show(_document.getFile(), getFragmentManager());
}
return true;
Expand Down Expand Up @@ -662,10 +681,9 @@ public boolean onBackPressed() {
return false;
}


// Save the file
// Only supports java.io.File. TODO: Android Content
public boolean saveDocument() {
public boolean saveDocument(boolean forceSaveEmpty) {
if (isAdded() && _hlEditor != null && _hlEditor.getText() != null) {

if (_document != null && _document.getFile() != null) {
Expand All @@ -674,28 +692,17 @@ public boolean saveDocument() {
}

updateLauncherWidgets();
return _document.saveContent(getContext(), _hlEditor.getText().toString(), _shareUtil);
return _document.saveContent(getContext(), _hlEditor.getText().toString(), _shareUtil, forceSaveEmpty);
}
return false;
}

public void restoreDocumentPositions() {
if (!Arrays.asList(_hlEditor, _webView, _document.getFile()).contains(null) && !isDisplayedAtMainActivity()) {
int v;
if ((v = _document.getInitialLineNumber()) >= 0) { // If Intent contains line number, jump to it
_hlEditor.smoothMoveCursorToLine(v);
}
_document.setInitialLineNumber(-1);
}
}

private boolean isDisplayedAtMainActivity() {
return getActivity() instanceof MainActivity;
}

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
saveDocument();
if (_hlEditor != null) {
outState.putSerializable(SAVESTATE_CURSOR_POS, _hlEditor.getSelectionStart());
}
Expand All @@ -707,7 +714,7 @@ public void onSaveInstanceState(@NonNull Bundle outState) {

@Override
public void onPause() {
saveDocument();
saveDocument(false);
if (_document != null && _document.getFile() != null) {
_appSettings.addRecentDocument(_document.getFile());
}
Expand All @@ -727,7 +734,7 @@ public void setUserVisibleHint(boolean isVisibleToUser) {
if (isVisibleToUser && isDisplayedAtMainActivity()) {
loadDocument();
} else if (!isVisibleToUser && _document != null) {
saveDocument();
saveDocument(false);
}

final Toolbar toolbar = getToolbar();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,6 @@ private void appendToExistingDocument(final File file, final String separator, f
String trimmedContent = document.loadContent(context).trim();
String currentContent = TextUtils.isEmpty(trimmedContent) ? "" : (trimmedContent + "\n");
document.saveContent(context, currentContent + separator + _sharedText);
document.resetModTime();

if (showEditor) {
showInDocumentActivity(document);
Expand Down
Loading

0 comments on commit 06ad871

Please sign in to comment.