Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import android.webkit.WebView;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
Expand Down Expand Up @@ -69,6 +68,7 @@
import net.gsantner.opoc.util.GsContextUtils;
import net.gsantner.opoc.util.GsCoolExperimentalStuff;
import net.gsantner.opoc.web.GsWebViewChromeClient;
import net.gsantner.opoc.wrapper.GsCallback;
import net.gsantner.opoc.wrapper.GsTextWatcherAdapter;

import java.io.File;
Expand Down Expand Up @@ -106,6 +106,7 @@ public static DocumentEditAndViewFragment newInstance(final @NonNull Document do
private DraggableScrollbarScrollView _verticalScrollView;
private HorizontalScrollView _horizontalScrollView;
private LineNumbersView _lineNumbersView;
private TextView _searchResultTextView;
private Document _document;
private FormatRegistry _format;
private MarkorContextUtils _cu;
Expand Down Expand Up @@ -669,16 +670,10 @@ private void showHideActionBar() {
if (activity != null) {
final View bar = activity.findViewById(R.id.document__fragment__edit__text_actions_bar);
final View parent = activity.findViewById(R.id.document__fragment__edit__text_actions_bar__scrolling_parent);
final View viewScroll = activity.findViewById(R.id.document__fragment_view_webview);

if (bar != null && parent != null && _verticalScrollView != null) {
final boolean hide = _textActionsBar.getChildCount() == 0;
parent.setVisibility(hide ? View.GONE : View.VISIBLE);
final int marginBottom = hide ? 0 : (int) getResources().getDimension(R.dimen.textactions_bar_height);
setMarginBottom(_verticalScrollView, marginBottom);
if (viewScroll != null) {
setMarginBottom(viewScroll, marginBottom);
}
syncEditorMinHeightOnce(_verticalScrollView);
}
}
Expand All @@ -693,10 +688,6 @@ private void setupSearchView(SearchView searchView) {
if (searchView == null) {
return;
}
// Only setup SearchView for view-mode, to avoid unnecessary setup for edit-mode
if (!_isPreviewVisible || _webView == null) {
return;
}

searchView.setQueryHint(getString(R.string.search));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
Expand Down Expand Up @@ -730,22 +721,25 @@ public boolean onQueryTextChange(String text) {
return search(text);
}
});
searchView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(@NonNull View v) {
}

@Override
public void onViewDetachedFromWindow(@NonNull View v) {
// Clear search when SearchView is closed abnormally, e.g. switch from QuickNote to To-Do when SearchView is opened
if (searchView.getQuery().length() > 0) {
searchView.setQuery("", false); // This will make onQueryTextChange be called back
if (searchView.getTag(R.id.action_search_view) == null) {
searchView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(@NonNull View v) {
}
if (!searchView.isIconified()) {
searchView.setIconified(true);

@Override
public void onViewDetachedFromWindow(@NonNull View v) {
// Clear search when SearchView is closed abnormally, e.g. switch from QuickNote to To-Do when SearchView is opened
if (searchView.getQuery().length() > 0) {
searchView.setQuery("", false); // This will make onQueryTextChange be called back
}
if (!searchView.isIconified()) {
searchView.setIconified(true);
}
}
}
});
});
searchView.setTag(R.id.action_search_view, Boolean.TRUE);
}

// Because SearchView doesn't provide a public API to add custom buttons
// We must get the searchPlate (the layout containing the text field and close button) from SearchView
Expand All @@ -757,46 +751,68 @@ public void onViewDetachedFromWindow(@NonNull View v) {
return;
}

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.gravity = Gravity.CENTER;
final GsCallback.r0<ViewGroup.LayoutParams> makeLayoutParams = () -> {
final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
params.gravity = Gravity.CENTER;
return params;
};

Context searchViewContext = searchView.getContext();
LinearLayout linearLayout = new LinearLayout(searchViewContext);
linearLayout.setLayoutParams(layoutParams);

// Add search result TextView
TextView resultTextView = new TextView(searchViewContext);
LinearLayout.LayoutParams textViewLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT);
textViewLayoutParams.setMarginEnd(30);
resultTextView.setLayoutParams(textViewLayoutParams);
resultTextView.setGravity(Gravity.CENTER);
resultTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
linearLayout.addView(resultTextView);

// Add previous match Button
ImageView previousButton = new ImageView(searchViewContext);
previousButton.setImageResource(R.drawable.ic_baseline_keyboard_arrow_up_24);
previousButton.setLayoutParams(layoutParams);
previousButton.setPadding(24, 24, 24, 24);
TextViewUtils.setSelectableItemBackgroundBorderless(previousButton, searchViewContext);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
previousButton.setTooltipText(getString(R.string.previous_match));
}
linearLayout.addView(previousButton);

// Add next match Button
ImageButton nextButton = new ImageButton(searchViewContext);
nextButton.setImageResource(R.drawable.ic_baseline_keyboard_arrow_down_24);
nextButton.setLayoutParams(layoutParams);
nextButton.setPadding(24, 24, 24, 24);
TextViewUtils.setSelectableItemBackgroundBorderless(nextButton, searchViewContext);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
nextButton.setTooltipText(getString(R.string.next_match));
}
linearLayout.addView(nextButton);
LinearLayout linearLayout = searchPlate.findViewWithTag("markor_search_nav_controls");
TextView resultTextView;
ImageButton previousButton;
ImageButton nextButton;
if (linearLayout == null) {
linearLayout = new LinearLayout(searchViewContext);
linearLayout.setTag("markor_search_nav_controls");
linearLayout.setLayoutParams(makeLayoutParams.callback());

// Add search result TextView
resultTextView = new TextView(searchViewContext);
resultTextView.setTag("markor_search_nav_result");
LinearLayout.LayoutParams textViewLayoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.MATCH_PARENT
);
textViewLayoutParams.setMarginEnd(30);
resultTextView.setLayoutParams(textViewLayoutParams);
resultTextView.setGravity(Gravity.CENTER);
resultTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
linearLayout.addView(resultTextView);

// Add previous match Button
previousButton = new ImageButton(searchViewContext);
previousButton.setImageResource(R.drawable.ic_baseline_keyboard_arrow_up_24);
previousButton.setLayoutParams(makeLayoutParams.callback());
previousButton.setPadding(24, 24, 24, 24);
TextViewUtils.setSelectableItemBackgroundBorderless(previousButton, searchViewContext);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
previousButton.setTooltipText(getString(R.string.previous_match));
}
linearLayout.addView(previousButton);

// Add next match Button
nextButton = new ImageButton(searchViewContext);
nextButton.setImageResource(R.drawable.ic_baseline_keyboard_arrow_down_24);
nextButton.setLayoutParams(makeLayoutParams.callback());
nextButton.setPadding(24, 24, 24, 24);
TextViewUtils.setSelectableItemBackgroundBorderless(nextButton, searchViewContext);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
nextButton.setTooltipText(getString(R.string.next_match));
}
linearLayout.addView(nextButton);

// Apply to SearchView
searchPlate.addView(linearLayout, 1);
// Apply to SearchView
searchPlate.addView(linearLayout, 1);
} else {
resultTextView = linearLayout.findViewWithTag("markor_search_nav_result");
previousButton = (ImageButton) linearLayout.getChildAt(1);
nextButton = (ImageButton) linearLayout.getChildAt(2);
}
_searchResultTextView = resultTextView;

// Set listeners
previousButton.setOnClickListener(v -> {
Expand All @@ -809,25 +825,24 @@ public void onViewDetachedFromWindow(@NonNull View v) {
_webView.findNext(true);
}
});
bindWebViewSearchListener();
}

private void bindWebViewSearchListener() {
if (_webView == null || _searchResultTextView == null) {
return;
}
_webView.setFindListener((activeMatchOrdinal, numberOfMatches, isDoneCounting) -> {
if (isDoneCounting) {
String searchResult = "";
if (numberOfMatches > 0) {
searchResult = (activeMatchOrdinal + 1) + "/" + numberOfMatches;
}
resultTextView.setText(searchResult);
_searchResultTextView.setText(searchResult);
}
});
}

private void setMarginBottom(final View view, final int marginBottom) {
final ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
if (params != null) {
params.setMargins(params.leftMargin, params.topMargin, params.rightMargin, marginBottom);
view.setLayoutParams(params);
}
}

private void syncEditorMinHeightOnce(final View parent) {
if (parent == null) {
return;
Expand Down Expand Up @@ -1043,6 +1058,10 @@ private void setupWebViewIfNeeded(final Activity activity) {
return false;
});
}
if (_format != null) {
_format.getActions().setUiReferences(activity, _hlEditor, _webView);
}
bindWebViewSearchListener();
}

@SuppressLint({"AddJavascriptInterface", "SetJavaScriptEnabled"})
Expand Down Expand Up @@ -1103,15 +1122,21 @@ protected boolean onToolbarLongClicked(View v) {
}

@Override
public void onDestroy() {
public void onDestroyView() {
if (_webView != null) {
try {
_webView.loadUrl("about:blank");
_webView.destroy();
} catch (Exception ignored) {
}
}
super.onDestroy();
_webView = null;
_webViewClient = null;
_searchResultTextView = null;
if (_format != null) {
_format.getActions().setUiReferences(getActivity(), _hlEditor, null);
}
super.onDestroyView();
}

public Document getDocument() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ private void attachOrCopyAndClose(final File dest, final boolean show) {
_appSettings.addRecentFile(dest);

// Only if not forced link due to attachment
if (attachment == null) {
if (attachment == null && _linkCheckBox != null && _linkCheckBox.getVisibility() == View.VISIBLE) {
_appSettings.setFormatShareAsLink(asLink);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ protected final boolean runCommonAction(final @StringRes int action) {
return true;
}
case R.string.abid_common_web_jump_to_table_of_contents: {
if (_appSettings.isMarkdownTableOfContentsEnabled()) {
if (_appSettings.isMarkdownTableOfContentsEnabled() && _webView != null) {
_webView.loadUrl("javascript:document.getElementsByClassName('toc')[0].scrollIntoView();");
} else {
runTitleClick();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.os.Build;
import android.text.Editable;
Expand All @@ -31,6 +30,7 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.WebView;
import android.widget.Button;
Expand All @@ -42,6 +42,7 @@
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;

import net.gsantner.markor.R;
Expand Down Expand Up @@ -466,12 +467,23 @@ public static DialogOptions makeSttLineSelectionDialog(
return dopt;
}

@Nullable
private static Editable getCurrentSearchText(final AlertDialog dialog) {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@guanglinn instead of neutralButtonCallback2 we fetch the search text from the existing dialog

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I see

final Window window = dialog.getWindow();
if (window == null) {
return null;
}
final View view = window.getDecorView().findViewWithTag("EDIT");
return view instanceof EditText ? ((EditText) view).getText() : null;
}

// Search dialog for todo.txt
public static void showSttSearchDialog(final Activity activity, final EditText text) {
final DialogOptions dopt = makeSttLineSelectionDialog(activity, text, t -> true);
dopt.titleText = R.string.search_documents;
dopt.neutralButtonText = R.string.replace;
dopt.neutralButtonCallback2 = (dialog, searchText) -> {
dopt.neutralButtonCallback = dialog -> {
final Editable searchText = getCurrentSearchText(dialog);
dialog.dismiss();
SearchAndReplaceTextDialog.showSearchReplaceDialog(activity, text.getText(), searchText, TextViewUtils.getSelection(text));
};
Expand Down Expand Up @@ -758,10 +770,11 @@ public static void showSearchDialog(final Activity activity, final EditText edit
dopt.dataFilter = "[^\\s]+"; // Line must have one or more non-whitespace to display
dopt.titleText = R.string.search_documents;
dopt.searchHintText = R.string.search;
dopt.searchText = searchText;
dopt.state.searchText = searchText;
dopt.neutralButtonCallback = null;
dopt.neutralButtonCallback2 = (dialog, searchText2) -> {
dopt.neutralButtonCallback = dialog -> {
dialog.dismiss();
final Editable searchText2 = getCurrentSearchText(dialog);
SearchAndReplaceTextDialog.showSearchReplaceDialog(activity, edit, searchText2, TextViewUtils.getSelection(editText));
};
dopt.neutralButtonText = R.string.replace;
Expand Down Expand Up @@ -1273,6 +1286,6 @@ public static void showPopupWindow(View anchorView, String text, GsCallback.a0 c
popupWindow.dismiss();
});
popupWindow.showAsDropDown(anchorView, 130, -100);
anchorView.getHandler().postDelayed(() -> popupWindow.dismiss(), 3000);
anchorView.getHandler().postDelayed(popupWindow::dismiss, 3000);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ public class SearchAndReplaceTextDialog {

private final List<ReplaceGroup> recentReplaces;

public static void showSearchReplaceDialog(final Activity activity, final Editable edit, Editable searchText, final int[] sel) {
public static void showSearchReplaceDialog(final Activity activity, final Editable edit, @Nullable CharSequence searchText, final int[] sel) {
new SearchAndReplaceTextDialog(activity, edit, searchText, sel);
}

public static void showSearchReplaceDialog(final Activity activity, final Editable edit, final int[] sel) {
showSearchReplaceDialog(activity, edit, null, sel);
}

private SearchAndReplaceTextDialog(final Activity activity, final Editable edit, Editable searchText, final int[] sel) {
private SearchAndReplaceTextDialog(final Activity activity, final Editable edit, @Nullable CharSequence searchText, final int[] sel) {
_activity = activity;
_edit = edit;

Expand Down Expand Up @@ -404,4 +404,4 @@ public JSONObject toJson() {
return obj;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -406,9 +406,9 @@ public static void showSelection(final EditText editText, final int startSelecti
int line = layout.getLineForOffset(startSelection);
int lineHeight = editText.getLineHeight();
if (layout.getLineTop(line) < visible.top - lineHeight) {
showSelection(editText, visible, startSelection, startSelection, -lineHeight);
showSelection(editText, visible, startSelection, startSelection, -lineHeight * 3);
} else if (layout.getLineBottom(line) > visible.bottom - lineHeight) {
showSelection(editText, visible, startSelection, startSelection, lineHeight * 4);
showSelection(editText, visible, startSelection, startSelection, lineHeight * 2);
}
}

Expand Down
Loading
Loading