From 63783b27b5e43aabe0107726f57c2dab27d91511 Mon Sep 17 00:00:00 2001
From: Li Guanglin <2311987902@qq.com>
Date: Fri, 19 Jan 2024 14:40:08 +0800
Subject: [PATCH 01/12] feat: make headline dialog work in view mode
---
.../activity/DocumentEditAndViewFragment.java | 10 +++---
.../markor/format/ActionButtonBase.java | 24 ++++++-------
.../markor/format/TextConverterBase.java | 3 +-
.../markdown/MarkdownActionButtons.java | 2 +-
.../markdown/MarkdownTextConverter.java | 4 +--
.../wikitext/WikitextActionButtons.java | 2 +-
.../markor/frontend/MarkorDialogFactory.java | 21 +++++++++--
.../markor/frontend/NewFileDialog.java | 4 +--
.../frontend/GsSearchOrCustomTextDialog.java | 36 ++++++++++++++-----
app/src/main/res/values-zh-rCN/strings.xml | 3 +-
10 files changed, 69 insertions(+), 40 deletions(-)
diff --git a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java
index 8500a09793..fe65214269 100644
--- a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java
+++ b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java
@@ -660,7 +660,6 @@ private boolean isWrapped() {
}
private void setHorizontalScrollMode(final boolean wrap) {
-
final Context context = getContext();
if (context != null && _hlEditor != null && isWrapped() != wrap) {
@@ -734,7 +733,7 @@ public boolean saveDocument(final boolean forceSaveEmpty) {
return false;
}
- // Document is written iff writeable && content has changed
+ // Document is written if writeable && content has changed
final CharSequence text = _hlEditor.getText();
if (!_document.isContentSame(text)) {
final int minLength = GsContextUtils.TEXTFILE_OVERWRITE_MIN_TEXT_LENGTH;
@@ -832,15 +831,16 @@ public Document getDocument() {
return _document;
}
- public WebView getWebview() {
+ public WebView getWebView() {
return _webView;
}
@Override
protected void onToolbarClicked(View v) {
- if (!_isPreviewVisible && _format != null) {
- _format.getActions().runTitleClick();
+ if (_format == null) {
+ return;
}
+ _format.getActions().runTitleClick();
}
@Override
diff --git a/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java b/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java
index d7d3c6d78b..8343e26828 100644
--- a/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java
+++ b/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java
@@ -142,8 +142,7 @@ public Map getActiveActionMap() {
final List actionList = getActiveActionList();
final List keyList = getActiveActionKeys();
- final Map map = new HashMap();
-
+ final Map map = new HashMap<>();
for (int i = 0; i < actionList.size(); i++) {
map.put(keyList.get(i), actionList.get(i));
}
@@ -210,7 +209,6 @@ private List loadActionPreference(final String suffix) {
* @return List of Action Item keys in order specified by preferences
*/
public List getActionOrder() {
-
final Set order = new LinkedHashSet<>(loadActionPreference(ORDER_SUFFIX));
// Handle the case where order was stored without suffix. i.e. before this release.
@@ -452,7 +450,7 @@ protected void runInlineAction(String _action) {
int selectionStart = _hlEditor.getSelectionStart();
int selectionEnd = _hlEditor.getSelectionEnd();
- //Check if Selection includes the shortcut characters
+ // Check if Selection includes the shortcut characters
if (selectionEnd < text.length() && selectionStart >= 0 && (text.substring(selectionStart, selectionEnd)
.matches("(\\*\\*|~~|_|`)[a-zA-Z0-9\\s]*(\\*\\*|~~|_|`)"))) {
@@ -462,7 +460,7 @@ protected void runInlineAction(String _action) {
.replace(selectionStart, selectionEnd, text);
}
- //Check if Selection is Preceded and succeeded by shortcut characters
+ // Check if Selection is Preceded and succeeded by shortcut characters
else if (((selectionEnd <= (_hlEditor.length() - _action.length())) &&
(selectionStart >= _action.length())) &&
(text.substring(selectionStart - _action.length(),
@@ -475,14 +473,14 @@ else if (((selectionEnd <= (_hlEditor.length() - _action.length())) &&
selectionEnd + _action.length(), text);
}
- //Condition to insert shortcut preceding and succeeding the selection
+ // Condition to insert shortcut preceding and succeeding the selection
else {
_hlEditor.getText().insert(selectionStart, _action);
_hlEditor.getText().insert(_hlEditor.getSelectionEnd(), _action);
}
} else {
- //Condition for Empty Selection
- /*if (false) {
+ // Condition for Empty Selection
+ /* if (false) {
// Condition for things that should only be placed at the start of the line even if no text is selected
} else */
if ("----\n".equals(_action)) {
@@ -496,7 +494,6 @@ else if (((selectionEnd <= (_hlEditor.length() - _action.length())) &&
}
}
-
public ActionButtonBase setUiReferences(@Nullable final Activity activity, @Nullable final HighlightingEditor hlEditor, @Nullable final WebView webview) {
_activity = activity;
_hlEditor = hlEditor;
@@ -638,7 +635,11 @@ protected final boolean runCommonAction(final @StringRes int action) {
return true;
}
case R.string.abid_common_web_jump_to_table_of_contents: {
- _webView.loadUrl("javascript:document.getElementsByClassName('toc')[0].scrollIntoView();");
+ if (_appSettings.isMarkdownTableOfContentsEnabled()) {
+ _webView.loadUrl("javascript:document.getElementsByClassName('toc')[0].scrollIntoView();");
+ } else {
+ runTitleClick();
+ }
return true;
}
case R.string.abid_common_view_file_in_other_app: {
@@ -731,7 +732,6 @@ public ActionItem(@StringRes int key, @DrawableRes int icon, @StringRes int stri
}
public static void moveLineSelectionBy1(final HighlightingEditor hlEditor, final boolean isUp) {
-
final Editable text = hlEditor.getText();
final int[] sel = TextViewUtils.getSelection(hlEditor);
@@ -739,7 +739,6 @@ public static void moveLineSelectionBy1(final HighlightingEditor hlEditor, final
final int linesEnd = TextViewUtils.getLineEnd(text, sel[1]);
if ((isUp && linesStart > 0) || (!isUp && linesEnd < text.length())) {
-
final CharSequence lines = text.subSequence(linesStart, linesEnd);
final int altStart = isUp ? TextViewUtils.getLineStart(text, linesStart - 1) : linesEnd + 1;
@@ -783,7 +782,6 @@ private String rstr(@StringRes int resKey) {
}
public void runSpecialKeyAction() {
-
// Needed to prevent selection from being overwritten on refocus
final int[] sel = TextViewUtils.getSelection(_hlEditor);
_hlEditor.clearFocus();
diff --git a/app/src/main/java/net/gsantner/markor/format/TextConverterBase.java b/app/src/main/java/net/gsantner/markor/format/TextConverterBase.java
index 90ddbcedc3..59e1d84b6d 100644
--- a/app/src/main/java/net/gsantner/markor/format/TextConverterBase.java
+++ b/app/src/main/java/net/gsantner/markor/format/TextConverterBase.java
@@ -104,8 +104,7 @@ public String convertMarkupShowInWebView(
final Activity context,
final WebView webView,
final boolean lightMode,
- final boolean lineNum
- ) {
+ final boolean lineNum) {
String html;
try {
html = convertMarkup(content, context, lightMode, lineNum, document.getFile());
diff --git a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownActionButtons.java b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownActionButtons.java
index 0473ab2bc5..ebccc27533 100644
--- a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownActionButtons.java
+++ b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownActionButtons.java
@@ -244,7 +244,7 @@ private void insertTableRow(int cols, boolean isHeaderEnabled) {
@Override
public boolean runTitleClick() {
final Matcher m = MarkdownReplacePatternGenerator.PREFIX_ATX_HEADING.matcher("");
- MarkorDialogFactory.showHeadlineDialog(getActivity(), _hlEditor, _disabledHeadings, (text, start, end) -> {
+ MarkorDialogFactory.showHeadlineDialog(getActivity(), _hlEditor, _webView, _disabledHeadings, (text, start, end) -> {
if (m.reset(text.subSequence(start, end)).find()) {
return m.end(2) - m.start(2) - 1;
}
diff --git a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java
index ecaff23170..944f983adc 100644
--- a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java
+++ b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java
@@ -163,7 +163,7 @@ public String convertMarkup(String markup, Context context, boolean lightMode, b
options.set(Parser.EXTENSIONS, flexmarkExtensions);
- options.set(Parser.SPACE_IN_LINK_URLS, true); // allow links like [this](some filename with spaces.md)
+ options.set(Parser.SPACE_IN_LINK_URLS, true); // Allow links like [this](some filename with spaces.md)
// options.set(HtmlRenderer.SOFT_BREAK, "
\n"); // Add linefeed to HTML break
@@ -198,7 +198,7 @@ public String convertMarkup(String markup, Context context, boolean lightMode, b
head += CSS_PRESENTATION_BEAMER;
}
- // Frontmatter
+ // Front matter
String fmaText = "";
final List fmaAllowedAttributes = _appSettings.getMarkdownShownYamlFrontMatterKeys();
Map> fma = Collections.EMPTY_MAP;
diff --git a/app/src/main/java/net/gsantner/markor/format/wikitext/WikitextActionButtons.java b/app/src/main/java/net/gsantner/markor/format/wikitext/WikitextActionButtons.java
index 05cba2ff47..fca1d6bcb0 100644
--- a/app/src/main/java/net/gsantner/markor/format/wikitext/WikitextActionButtons.java
+++ b/app/src/main/java/net/gsantner/markor/format/wikitext/WikitextActionButtons.java
@@ -282,7 +282,7 @@ public static String createWikitextHeaderAndTitleContents(String fileNameWithout
@Override
public boolean runTitleClick() {
final Matcher m = WikitextSyntaxHighlighter.HEADING.matcher("");
- MarkorDialogFactory.showHeadlineDialog(getActivity(), _hlEditor, _disabledHeadings, (text, start, end) -> {
+ MarkorDialogFactory.showHeadlineDialog(getActivity(), _hlEditor, _webView, _disabledHeadings, (text, start, end) -> {
if (m.reset(text.subSequence(start, end)).find()) {
return 7 - (m.end(2) - m.start(2));
}
diff --git a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
index c783423ac1..e9d8927631 100644
--- a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
+++ b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
@@ -27,6 +27,7 @@
import android.util.Pair;
import android.view.Gravity;
import android.view.WindowManager;
+import android.webkit.WebView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
@@ -589,9 +590,9 @@ private static class Heading {
public static void showHeadlineDialog(
final Activity activity,
final EditText edit,
+ final WebView webView,
final Set disabled,
- final GsCallback.r3 headingLevel
- ) {
+ final GsCallback.r3 headingLevel) {
// Get all headings and their levels
final CharSequence text = edit.getText();
final List headings = new ArrayList<>();
@@ -616,10 +617,24 @@ public static void showHeadlineDialog(
dopt.titleText = R.string.table_of_contents;
dopt.searchHintText = R.string.search;
dopt.isSearchEnabled = true;
+ dopt.isSoftInputVisible = false;
+ dopt.isDismissOnItemSelected = false;
+ final int width = activity.getResources().getDisplayMetrics().widthPixels;
+ final int height = activity.getResources().getDisplayMetrics().heightPixels;
+ if (width > height) {
+ dopt.dialogWidth = (int) (width * 0.7);
+ dopt.dialogHeight = (int) (height * 0.95);
+ } else {
+ dopt.dialogWidth = (int) (width * 0.95);
+ dopt.dialogHeight = (int) (height * 0.8);
+ }
dopt.neutralButtonText = R.string.filter;
dopt.positionCallback = result -> {
final int index = filtered.get(result.get(0));
TextViewUtils.selectLines(edit, headings.get(index).line);
+ String title = headings.get(index).str;
+ String id = title.substring(title.lastIndexOf('#') + 1).trim().replaceAll("\\s+", "-").replaceAll("&", "").toLowerCase();
+ webView.loadUrl("javascript:document.getElementById('" + id + "').scrollIntoView();");
};
dopt.neutralButtonCallback = (dialog) -> {
@@ -647,7 +662,7 @@ public static void showHeadlineDialog(
};
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt2);
};
- dopt.gravity = Gravity.TOP;
+ dopt.gravity = Gravity.CENTER;
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt);
}
diff --git a/app/src/main/java/net/gsantner/markor/frontend/NewFileDialog.java b/app/src/main/java/net/gsantner/markor/frontend/NewFileDialog.java
index 77c85a2ab6..7abf599fb2 100644
--- a/app/src/main/java/net/gsantner/markor/frontend/NewFileDialog.java
+++ b/app/src/main/java/net/gsantner/markor/frontend/NewFileDialog.java
@@ -146,7 +146,7 @@ private AlertDialog.Builder makeDialog(final File basedir, final boolean allowCr
if (pos == 3) { // Jekyll
prefix = TodoTxtTask.DATEF_YYYY_MM_DD.format(new Date()) + "-";
- } else if (pos == 9) { //ZettelKasten
+ } else if (pos == 9) { // ZettelKasten
prefix = new SimpleDateFormat("yyyyMMddHHmm", Locale.ROOT).format(new Date()) + "-";
}
if (!TextUtils.isEmpty(prefix) && !fileNameEdit.getText().toString().startsWith(prefix)) {
@@ -325,7 +325,7 @@ private String getTemplateByPos(
" line\";2059-12-24\n";
}
case 12: {
- // orgmode
+ // Org-mode
return "OrgMode Reference\n" + "* Headline\n" + "** Nested headline\n" + "*** Deeper\n" + "\n" + "* Basic markup\n" + "This is the general building block for org-mode navigation.\n" + "- _underscores let you underline things_\n" + "- *stars add emphasis*\n" + "- /slashes are italics/\n" + "- +pluses are strikethrough+\n" + "- =equal signs are verbatim text=\n" + "- ~tildes can also be used~\n" + "\n" + "* List\n" + "** Unordered List\n" + "- Item 1\n" + "- Item 2\n" + " - Subitem 2.1\n" + " - Subitem 2.2\n" + "** Ordered List\n" + "1. First Item\n" + "2. Second Item\n" + " 1. Subitem 2.1\n" + " 2. Subitem 2.2\n" + "- [X] Completed Task\n" + "- [ ] Uncompleted Task\n" + "** Nested List\n" + " - Item A\n" + " - Subitem A.1\n" + " - Subitem A.2\n" + " - Item B\n" + "\n" + "* Tables\n" + "\n" + "| First Name | Last Name | Years using Emacs |\n" + "|----------------------------+---------------------+-------------------|\n" + "| Lee | Hinman | 5 |\n" + "| Mike | Hunsinger | 2 |\n" + "| Daniel | Glauser | 4 |\n" + "| Really-long-first-name-guy | long-last-name-pers | 1 |\n" + "\n" + "* Org-mode links\n" + "\n" + "#+BEGIN_SRC fundamental\n" + "[[http://google.com/][Google]]\n" + "#+END_SRC\n" + "\n" + "[[./images/pic1.png]]\n" + "\n" + "\n" + "* TODO List\n" + "** TODO This is a task that needs doing\n" + "** TODO Another todo task\n" + "- [ ] sub task one\n" + "- [X] sub task two\n" + "- [ ] sub task three\n" + "** DONE I've already finished this one\n" + "*** CANCELLED learn todos\n" + " CLOSED: [2023-10-16 Mon 08:39]\n" + "\n" + "* Code\n" + "#+BEGIN_LaTeX\n" + "$a + b$\n" + "#+END_LaTeX\n" + "\n" + "#+BEGIN_SRC emacs-lisp\n" + "(defun my/function ()\n" + " \"docstring\"\n" + " (interactive)\n" + " (progn\n" + " (+ 1 1)\n" + " (message \"Hi\")))\n" + "#+END_SRC\n" + "\n";
}
}
diff --git a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
index 4f3754efe6..526c814e44 100644
--- a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
+++ b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
@@ -88,9 +88,13 @@ public static class DialogOptions {
public CharSequence messageText = "";
public String defaultText = "";
public boolean isSearchEnabled = true;
+ public boolean isSoftInputVisible = true;
+ public boolean isDismissOnItemSelected = true;
public boolean isDarkDialog = false;
public int dialogWidthDp = WindowManager.LayoutParams.MATCH_PARENT;
public int dialogHeightDp = WindowManager.LayoutParams.WRAP_CONTENT;
+ public int dialogWidth;
+ public int dialogHeight;
public int gravity = Gravity.NO_GRAVITY;
public int searchInputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
public GsCallback.a1 highlighter = null;
@@ -311,18 +315,30 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi
});
final Window win = dialog.getWindow();
- if (win != null && dopt.isSearchEnabled) {
- win.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+ if (win != null) {
+ if (dopt.isSearchEnabled) {
+ if (dopt.isSoftInputVisible) {
+ win.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+ } else {
+ win.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
+ }
+ }
}
-
dialog.show();
if (win != null) {
- int ds_w = dopt.dialogWidthDp < 100 ? dopt.dialogWidthDp : ((int) (dopt.dialogWidthDp * activity.getResources().getDisplayMetrics().density));
- int ds_h = dopt.dialogHeightDp < 100 ? dopt.dialogHeightDp : ((int) (dopt.dialogHeightDp * activity.getResources().getDisplayMetrics().density));
- ds_w = (ds_w * 1.1 > activity.getResources().getDisplayMetrics().widthPixels) ? ViewGroup.LayoutParams.MATCH_PARENT : ds_w;
- ds_h = (ds_h * 1.1 > activity.getResources().getDisplayMetrics().heightPixels) ? ViewGroup.LayoutParams.MATCH_PARENT : ds_h;
- win.setLayout(ds_w, ds_h);
+ if (dopt.dialogWidth > 0 && dopt.dialogHeight > 0) {
+ WindowManager.LayoutParams params = win.getAttributes();
+ params.width = dopt.dialogWidth;
+ params.height = dopt.dialogHeight;
+ win.setAttributes(params);
+ } else {
+ int ds_w = dopt.dialogWidthDp < 100 ? dopt.dialogWidthDp : ((int) (dopt.dialogWidthDp * activity.getResources().getDisplayMetrics().density));
+ int ds_h = dopt.dialogHeightDp < 100 ? dopt.dialogHeightDp : ((int) (dopt.dialogHeightDp * activity.getResources().getDisplayMetrics().density));
+ ds_w = (ds_w * 1.1 > activity.getResources().getDisplayMetrics().widthPixels) ? ViewGroup.LayoutParams.MATCH_PARENT : ds_w;
+ ds_h = (ds_h * 1.1 > activity.getResources().getDisplayMetrics().heightPixels) ? ViewGroup.LayoutParams.MATCH_PARENT : ds_h;
+ win.setLayout(ds_w, ds_h);
+ }
}
if (win != null && dopt.gravity != Gravity.NO_GRAVITY) {
@@ -349,7 +365,9 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi
// Helper function to trigger callback with single item
final GsCallback.b1 directActivate = (position) -> {
final int index = listAdapter._filteredItems.get(position);
- dialog.dismiss();
+ if (dopt.isDismissOnItemSelected) {
+ dialog.dismiss();
+ }
if (dopt.callback != null) {
dopt.callback.callback(dopt.data.get(index).toString());
} else if (dopt.positionCallback != null) {
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 3f9d765198..214be49298 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -1,5 +1,4 @@
-
- remove line break)
if (converted.contains("footnote-")) {
@@ -329,14 +340,15 @@ public String convertMarkup(String markup, Context context, boolean lightMode, b
return putContentIntoTemplate(context, converted, lightMode, file, onLoadJs, head);
}
- private static final Pattern linkPattern = Pattern.compile("\\[(.*?)\\]\\((.*?)(\\s+\".*\")?\\)");
+ public static String generateHeaderId(String headerText) {
+ return HeaderIdGenerator.generateId(headerText, toDashChars, false, false);
+ }
private String escapeSpacesInLink(final String markup) {
final Matcher matcher = linkPattern.matcher(markup);
if (!matcher.find()) {
return markup;
}
-
// 1) Walk through the text till finding a link in markdown syntax
// 2) Add all text-before-link to buffer
// 3) Extract [title](link to somehere)
diff --git a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
index e9d8927631..e21ca0e6d2 100644
--- a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
+++ b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
@@ -38,6 +38,7 @@
import net.gsantner.markor.ApplicationObject;
import net.gsantner.markor.R;
import net.gsantner.markor.format.FormatRegistry;
+import net.gsantner.markor.format.markdown.MarkdownTextConverter;
import net.gsantner.markor.format.todotxt.TodoTxtBasicSyntaxHighlighter;
import net.gsantner.markor.format.todotxt.TodoTxtFilter;
import net.gsantner.markor.format.todotxt.TodoTxtTask;
@@ -610,7 +611,6 @@ public static void showHeadlineDialog(
final List filtered = GsCollectionUtils.indices(headings, h -> !disabled.contains(h.level));
final List data = GsCollectionUtils.map(filtered, i -> headings.get(i).str);
-
final DialogOptions dopt = new DialogOptions();
baseConf(activity, dopt);
dopt.data = data;
@@ -619,24 +619,16 @@ public static void showHeadlineDialog(
dopt.isSearchEnabled = true;
dopt.isSoftInputVisible = false;
dopt.isDismissOnItemSelected = false;
- final int width = activity.getResources().getDisplayMetrics().widthPixels;
- final int height = activity.getResources().getDisplayMetrics().heightPixels;
- if (width > height) {
- dopt.dialogWidth = (int) (width * 0.7);
- dopt.dialogHeight = (int) (height * 0.95);
- } else {
- dopt.dialogWidth = (int) (width * 0.95);
- dopt.dialogHeight = (int) (height * 0.8);
- }
- dopt.neutralButtonText = R.string.filter;
+
dopt.positionCallback = result -> {
final int index = filtered.get(result.get(0));
TextViewUtils.selectLines(edit, headings.get(index).line);
- String title = headings.get(index).str;
- String id = title.substring(title.lastIndexOf('#') + 1).trim().replaceAll("\\s+", "-").replaceAll("&", "").toLowerCase();
+ String header = headings.get(index).str;
+ String id = MarkdownTextConverter.generateHeaderId(header.substring(header.lastIndexOf('#') + 1).trim());
webView.loadUrl("javascript:document.getElementById('" + id + "').scrollIntoView();");
};
+ dopt.neutralButtonText = R.string.filter;
dopt.neutralButtonCallback = (dialog) -> {
final DialogOptions dopt2 = new DialogOptions();
dopt2.preSelected = GsCollectionUtils.indices(levels, l -> !disabled.contains(l));
@@ -662,7 +654,18 @@ public static void showHeadlineDialog(
};
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt2);
};
+
+ final int width = activity.getResources().getDisplayMetrics().widthPixels;
+ final int height = activity.getResources().getDisplayMetrics().heightPixels;
+ if (width > height) {
+ dopt.dialogWidth = (int) (width * 0.7);
+ dopt.dialogHeight = (int) (height * 0.95);
+ } else {
+ dopt.dialogWidth = (int) (width * 0.95);
+ dopt.dialogHeight = (int) (height * 0.8);
+ }
dopt.gravity = Gravity.CENTER;
+
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt);
}
From c82ba716b48806903a5ff3310aee69d858596f93 Mon Sep 17 00:00:00 2001
From: Li Guanglin <2311987902@qq.com>
Date: Mon, 22 Jan 2024 18:53:51 +0800
Subject: [PATCH 04/12] refactor: abstract the code about dialog aspect ratio
---
.../activity/DocumentEditAndViewFragment.java | 2 +-
.../markor/frontend/MarkorDialogFactory.java | 11 +----
.../frontend/GsSearchOrCustomTextDialog.java | 45 +++++++++----------
.../gsantner/opoc/util/GsContextUtils.java | 23 ++++++++++
4 files changed, 48 insertions(+), 33 deletions(-)
diff --git a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java
index fb19d26a7a..67c7e51e27 100644
--- a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java
+++ b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java
@@ -733,7 +733,7 @@ public boolean saveDocument(final boolean forceSaveEmpty) {
return false;
}
- // Document is written if writeable && content has changed
+ // Document is written iff writeable && content has changed
final CharSequence text = _hlEditor.getText();
if (!_document.isContentSame(text)) {
final int minLength = GsContextUtils.TEXTFILE_OVERWRITE_MIN_TEXT_LENGTH;
diff --git a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
index e21ca0e6d2..67c5f9aaff 100644
--- a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
+++ b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
@@ -655,15 +655,8 @@ public static void showHeadlineDialog(
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt2);
};
- final int width = activity.getResources().getDisplayMetrics().widthPixels;
- final int height = activity.getResources().getDisplayMetrics().heightPixels;
- if (width > height) {
- dopt.dialogWidth = (int) (width * 0.7);
- dopt.dialogHeight = (int) (height * 0.95);
- } else {
- dopt.dialogWidth = (int) (width * 0.95);
- dopt.dialogHeight = (int) (height * 0.8);
- }
+ dopt.portraitAspectRatio = new float[]{0.95f, 0.8f};
+ dopt.landscapeAspectRatio = new float[]{0.7f, 0.95f};
dopt.gravity = Gravity.CENTER;
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt);
diff --git a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
index 526c814e44..6cf549425f 100644
--- a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
+++ b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
@@ -23,6 +23,7 @@
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
+import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -87,22 +88,22 @@ public static class DialogOptions {
public List iconsForData;
public CharSequence messageText = "";
public String defaultText = "";
+ public boolean isDarkDialog = false;
public boolean isSearchEnabled = true;
public boolean isSoftInputVisible = true;
public boolean isDismissOnItemSelected = true;
- public boolean isDarkDialog = false;
+ public int gravity = Gravity.NO_GRAVITY;
public int dialogWidthDp = WindowManager.LayoutParams.MATCH_PARENT;
public int dialogHeightDp = WindowManager.LayoutParams.WRAP_CONTENT;
- public int dialogWidth;
- public int dialogHeight;
- public int gravity = Gravity.NO_GRAVITY;
public int searchInputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
- public GsCallback.a1 highlighter = null;
+ public float[] portraitAspectRatio = {0.0f, 1.0f};
+ public float[] landscapeAspectRatio = {0.0f, 1.0f};
public String extraFilter = null;
public List preSelected = null;
+ public GsCallback.a1 highlighter = null;
public GsCallback.a1 neutralButtonCallback = null;
- public GsCallback.b2 searchFunction = GsSearchOrCustomTextDialog::standardSearch;
public GsCallback.a1 dismissCallback = null;
+ public GsCallback.b2 searchFunction = GsSearchOrCustomTextDialog::standardSearch;
@ColorInt
public int textColor = 0xFF000000;
@@ -323,28 +324,26 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi
win.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
}
}
- }
- dialog.show();
+ dialog.show();
- if (win != null) {
- if (dopt.dialogWidth > 0 && dopt.dialogHeight > 0) {
- WindowManager.LayoutParams params = win.getAttributes();
- params.width = dopt.dialogWidth;
- params.height = dopt.dialogHeight;
- win.setAttributes(params);
+ DisplayMetrics displayMetrics = activity.getResources().getDisplayMetrics();
+ if (dopt.portraitAspectRatio[0] > 0 && dopt.landscapeAspectRatio[0] > 0) {
+ GsContextUtils.windowAspectRatio(win, dopt.portraitAspectRatio[0], dopt.portraitAspectRatio[1], dopt.landscapeAspectRatio[0], dopt.landscapeAspectRatio[1], displayMetrics);
} else {
- int ds_w = dopt.dialogWidthDp < 100 ? dopt.dialogWidthDp : ((int) (dopt.dialogWidthDp * activity.getResources().getDisplayMetrics().density));
- int ds_h = dopt.dialogHeightDp < 100 ? dopt.dialogHeightDp : ((int) (dopt.dialogHeightDp * activity.getResources().getDisplayMetrics().density));
- ds_w = (ds_w * 1.1 > activity.getResources().getDisplayMetrics().widthPixels) ? ViewGroup.LayoutParams.MATCH_PARENT : ds_w;
- ds_h = (ds_h * 1.1 > activity.getResources().getDisplayMetrics().heightPixels) ? ViewGroup.LayoutParams.MATCH_PARENT : ds_h;
+ int ds_w = dopt.dialogWidthDp < 100 ? dopt.dialogWidthDp : ((int) (dopt.dialogWidthDp * displayMetrics.density));
+ int ds_h = dopt.dialogHeightDp < 100 ? dopt.dialogHeightDp : ((int) (dopt.dialogHeightDp * displayMetrics.density));
+ ds_w = (ds_w * 1.1 > displayMetrics.widthPixels) ? ViewGroup.LayoutParams.MATCH_PARENT : ds_w;
+ ds_h = (ds_h * 1.1 > displayMetrics.heightPixels) ? ViewGroup.LayoutParams.MATCH_PARENT : ds_h;
win.setLayout(ds_w, ds_h);
}
- }
- if (win != null && dopt.gravity != Gravity.NO_GRAVITY) {
- WindowManager.LayoutParams wlp = win.getAttributes();
- wlp.gravity = dopt.gravity;
- win.setAttributes(wlp);
+ if (dopt.gravity != Gravity.NO_GRAVITY) {
+ WindowManager.LayoutParams wlp = win.getAttributes();
+ wlp.gravity = dopt.gravity;
+ win.setAttributes(wlp);
+ }
+ } else {
+ dialog.show();
}
final Button neutralButton = dialog.getButton(AlertDialog.BUTTON_NEUTRAL);
diff --git a/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java b/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java
index c201ee59fb..2c6dbd01f3 100644
--- a/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java
+++ b/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java
@@ -2745,6 +2745,29 @@ public void dialogFullWidth(AlertDialog dialog, boolean fullWidth, boolean showK
}
}
+ public static void windowAspectRatio(final Window window,
+ float portraitWidthRatio,
+ float portraitHeightRatio,
+ float landscapeWidthRatio,
+ float landscapeHeightRatio,
+ final DisplayMetrics displayMetrics) {
+ if (window == null) {
+ return;
+ }
+
+ WindowManager.LayoutParams params = window.getAttributes();
+ final int width = displayMetrics.widthPixels;
+ final int height = displayMetrics.heightPixels;
+ if (width < height) { // Portrait
+ params.width = (int) (width * portraitWidthRatio);
+ params.height = (int) (height * portraitHeightRatio);
+ } else { // Landscape
+ params.width = (int) (width * landscapeWidthRatio);
+ params.height = (int) (height * landscapeHeightRatio);
+ }
+ window.setAttributes(params);
+ }
+
// Make activity/app not show up in the recents history - call before finish / System.exit
public T removeActivityFromHistory(final Context activity) {
try {
From 7120d6968c5feada3f87f4bc87a546d233088d61 Mon Sep 17 00:00:00 2001
From: Li Guanglin <2311987902@qq.com>
Date: Mon, 5 Feb 2024 00:01:32 +0800
Subject: [PATCH 05/12] feat: add support for saving the last position of
heading items
---
.../gsantner/markor/frontend/MarkorDialogFactory.java | 1 +
.../opoc/frontend/GsSearchOrCustomTextDialog.java | 10 ++++++++--
.../java/net/gsantner/opoc/util/GsContextUtils.java | 4 ++--
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
index 67c5f9aaff..a3640c26ed 100644
--- a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
+++ b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
@@ -619,6 +619,7 @@ public static void showHeadlineDialog(
dopt.isSearchEnabled = true;
dopt.isSoftInputVisible = false;
dopt.isDismissOnItemSelected = false;
+ dopt.isSaveItemPositionEnabled = true;
dopt.positionCallback = result -> {
final int index = filtered.get(result.get(0));
diff --git a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
index 6cf549425f..47725f391d 100644
--- a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
+++ b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
@@ -92,6 +92,7 @@ public static class DialogOptions {
public boolean isSearchEnabled = true;
public boolean isSoftInputVisible = true;
public boolean isDismissOnItemSelected = true;
+ public boolean isSaveItemPositionEnabled = false;
public int gravity = Gravity.NO_GRAVITY;
public int dialogWidthDp = WindowManager.LayoutParams.MATCH_PARENT;
public int dialogHeightDp = WindowManager.LayoutParams.WRAP_CONTENT;
@@ -158,7 +159,7 @@ private Adapter(final Context context, final DialogOptions dopt) {
_dopt = dopt;
_extraPattern = (_dopt.extraFilter == null ? null : Pattern.compile(_dopt.extraFilter).matcher(""));
_selectedItems = new HashSet<>(_dopt.preSelected != null ? _dopt.preSelected : Collections.emptyList());
- _layoutHeight = (int) GsContextUtils.instance.convertDpToPx(context, 36);
+ _layoutHeight = GsContextUtils.instance.convertDpToPx(context, 36);
}
@NonNull
@@ -271,6 +272,9 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi
final ListView listView = new ListView(activity);
listView.setId(LIST_VIEW_ID);
listView.setAdapter(listAdapter);
+ if (dopt.isSaveItemPositionEnabled) {
+ listView.setSelection(activity.getIntent().getIntExtra("lastHeadingPosition", 0));
+ }
listView.setVisibility(dopt.data != null && !dopt.data.isEmpty() ? View.VISIBLE : View.GONE);
final LinearLayout.LayoutParams listLayout = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
listLayout.weight = 1;
@@ -278,6 +282,8 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi
if (dopt.dismissCallback != null) {
dialogBuilder.setOnDismissListener(dopt.dismissCallback::callback);
+ } else {
+ dialogBuilder.setOnDismissListener(dialogInterface -> activity.getIntent().putExtra("lastHeadingPosition", listView.getFirstVisiblePosition()));
}
dialogBuilder.setView(mainLayout)
@@ -328,7 +334,7 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi
DisplayMetrics displayMetrics = activity.getResources().getDisplayMetrics();
if (dopt.portraitAspectRatio[0] > 0 && dopt.landscapeAspectRatio[0] > 0) {
- GsContextUtils.windowAspectRatio(win, dopt.portraitAspectRatio[0], dopt.portraitAspectRatio[1], dopt.landscapeAspectRatio[0], dopt.landscapeAspectRatio[1], displayMetrics);
+ GsContextUtils.windowAspectRatio(win, displayMetrics, dopt.portraitAspectRatio[0], dopt.portraitAspectRatio[1], dopt.landscapeAspectRatio[0], dopt.landscapeAspectRatio[1]);
} else {
int ds_w = dopt.dialogWidthDp < 100 ? dopt.dialogWidthDp : ((int) (dopt.dialogWidthDp * displayMetrics.density));
int ds_h = dopt.dialogHeightDp < 100 ? dopt.dialogHeightDp : ((int) (dopt.dialogHeightDp * displayMetrics.density));
diff --git a/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java b/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java
index 2c6dbd01f3..56c49d2e88 100644
--- a/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java
+++ b/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java
@@ -2746,11 +2746,11 @@ public void dialogFullWidth(AlertDialog dialog, boolean fullWidth, boolean showK
}
public static void windowAspectRatio(final Window window,
+ final DisplayMetrics displayMetrics,
float portraitWidthRatio,
float portraitHeightRatio,
float landscapeWidthRatio,
- float landscapeHeightRatio,
- final DisplayMetrics displayMetrics) {
+ float landscapeHeightRatio) {
if (window == null) {
return;
}
From 9ee3d2707d37025176a99f3711916c211d7c4850 Mon Sep 17 00:00:00 2001
From: Li Guanglin <2311987902@qq.com>
Date: Mon, 5 Feb 2024 09:47:36 +0800
Subject: [PATCH 06/12] minor improvements
---
.../markor/format/markdown/MarkdownTextConverter.java | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java
index 29281b2637..5bb1d1a05a 100644
--- a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java
+++ b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java
@@ -155,9 +155,9 @@ public class MarkdownTextConverter extends TextConverterBase {
public static final HtmlRenderer flexmarkRenderer = HtmlRenderer.builder().extensions(flexmarkExtensions).build();
//########################
- //## Extras
+ //## Others
//########################
- private static String toDashChars = null;
+ private static String toDashChars = " -_"; // See HtmlRenderer.HEADER_ID_GENERATOR_TO_DASH_CHARS.getFrom(document)
private static final Pattern linkPattern = Pattern.compile("\\[(.*?)\\]\\((.*?)(\\s+\".*\")?\\)");
@@ -166,7 +166,7 @@ public class MarkdownTextConverter extends TextConverterBase {
//########################
@Override
public String convertMarkup(String markup, Context context, boolean lightMode, boolean enableLineNumbers, File file) {
- String converted = "", onLoadJs = "", head = "";
+ String converted, onLoadJs = "", head = "";
final MutableDataSet options = new MutableDataSet();
options.set(Parser.EXTENSIONS, flexmarkExtensions);
@@ -304,8 +304,6 @@ public String convertMarkup(String markup, Context context, boolean lightMode, b
Document document = flexmarkParser.parse(markup);
converted = fmaText + flexmarkRenderer.withOptions(options).render(document);
- toDashChars = HtmlRenderer.HEADER_ID_GENERATOR_TO_DASH_CHARS.getFrom(document);
-
// After render changes: Fixes for Footnotes (converter creates footnote +
+ ref#(click) --> remove line break)
if (converted.contains("footnote-")) {
converted = converted.replace("
\n↩", "class=\"footnote-backref\"> ↩");
From 36e47aa10a1a45ca7e726d8bb52fed44b2ec504d Mon Sep 17 00:00:00 2001
From: Li Guanglin <2311987902@qq.com>
Date: Fri, 19 Jan 2024 14:40:08 +0800
Subject: [PATCH 07/12] feat: make headline dialog work in view mode
---
.../activity/DocumentEditAndViewFragment.java | 7 ++--
.../markor/format/ActionButtonBase.java | 18 +++++-----
.../markor/format/TextConverterBase.java | 3 +-
.../markdown/MarkdownActionButtons.java | 2 +-
.../markdown/MarkdownTextConverter.java | 4 +--
.../wikitext/WikitextActionButtons.java | 2 +-
.../markor/frontend/MarkorDialogFactory.java | 21 +++++++++--
.../markor/frontend/NewFileDialog.java | 4 +--
.../frontend/GsSearchOrCustomTextDialog.java | 36 ++++++++++++++-----
app/src/main/res/values-zh-rCN/strings.xml | 3 +-
10 files changed, 64 insertions(+), 36 deletions(-)
diff --git a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java
index 8993fe55fa..4381119131 100644
--- a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java
+++ b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java
@@ -700,7 +700,6 @@ private boolean isWrapped() {
}
private void setHorizontalScrollMode(final boolean wrap) {
-
final Context context = getContext();
if (context != null && _hlEditor != null && isWrapped() != wrap) {
@@ -774,7 +773,7 @@ public boolean saveDocument(final boolean forceSaveEmpty) {
return false;
}
- // Document is written iff writeable && content has changed
+ // Document is written if writeable && content has changed
final CharSequence text = _hlEditor.getText();
if (!_document.isContentSame(text)) {
final int minLength = GsContextUtils.TEXTFILE_OVERWRITE_MIN_TEXT_LENGTH;
@@ -861,7 +860,7 @@ public void onAnimationEnd(Animator animation) {
@Override
protected void onToolbarClicked(View v) {
- if (!_isPreviewVisible && _format != null) {
+ if (_format != null) {
_format.getActions().runTitleClick();
}
}
@@ -889,7 +888,7 @@ public Document getDocument() {
return _document;
}
- public WebView getWebview() {
+ public WebView getWebView() {
return _webView;
}
diff --git a/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java b/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java
index 4331ae1d58..953104507d 100644
--- a/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java
+++ b/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java
@@ -149,8 +149,7 @@ public Map getActiveActionMap() {
final List actionList = getActionList();
final List keyList = getActiveActionKeys();
- final Map map = new HashMap();
-
+ final Map map = new HashMap<>();
for (int i = 0; i < actionList.size(); i++) {
map.put(keyList.get(i), actionList.get(i));
}
@@ -251,7 +250,6 @@ private List loadActionPreference(final String suffix) {
* @return List of Action Item keys in order specified by preferences
*/
public List getActionOrder() {
-
final Set order = new LinkedHashSet<>(loadActionPreference(ORDER_SUFFIX));
// Handle the case where order was stored without suffix. i.e. before this release.
@@ -532,7 +530,6 @@ private static void runRegexReplaceAction(final Editable editable, final List 0) || (!isUp && linesEnd < text.length())) {
-
final CharSequence lines = text.subSequence(linesStart, linesEnd);
final int altStart = isUp ? TextViewUtils.getLineStart(text, linesStart - 1) : linesEnd + 1;
@@ -893,7 +892,6 @@ private String rstr(@StringRes int resKey) {
}
public void runSpecialKeyAction() {
-
// Needed to prevent selection from being overwritten on refocus
final int[] sel = TextViewUtils.getSelection(_hlEditor);
_hlEditor.clearFocus();
diff --git a/app/src/main/java/net/gsantner/markor/format/TextConverterBase.java b/app/src/main/java/net/gsantner/markor/format/TextConverterBase.java
index 90ddbcedc3..59e1d84b6d 100644
--- a/app/src/main/java/net/gsantner/markor/format/TextConverterBase.java
+++ b/app/src/main/java/net/gsantner/markor/format/TextConverterBase.java
@@ -104,8 +104,7 @@ public String convertMarkupShowInWebView(
final Activity context,
final WebView webView,
final boolean lightMode,
- final boolean lineNum
- ) {
+ final boolean lineNum) {
String html;
try {
html = convertMarkup(content, context, lightMode, lineNum, document.getFile());
diff --git a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownActionButtons.java b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownActionButtons.java
index ede2fdd247..288772a700 100644
--- a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownActionButtons.java
+++ b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownActionButtons.java
@@ -278,7 +278,7 @@ private void insertTableRow(int cols, boolean isHeaderEnabled) {
@Override
public boolean runTitleClick() {
final Matcher m = MarkdownReplacePatternGenerator.PREFIX_ATX_HEADING.matcher("");
- MarkorDialogFactory.showHeadlineDialog(getActivity(), _hlEditor, _disabledHeadings, (text, start, end) -> {
+ MarkorDialogFactory.showHeadlineDialog(getActivity(), _hlEditor, _webView, _disabledHeadings, (text, start, end) -> {
if (m.reset(text.subSequence(start, end)).find()) {
return m.end(2) - m.start(2) - 1;
}
diff --git a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java
index ecaff23170..944f983adc 100644
--- a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java
+++ b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java
@@ -163,7 +163,7 @@ public String convertMarkup(String markup, Context context, boolean lightMode, b
options.set(Parser.EXTENSIONS, flexmarkExtensions);
- options.set(Parser.SPACE_IN_LINK_URLS, true); // allow links like [this](some filename with spaces.md)
+ options.set(Parser.SPACE_IN_LINK_URLS, true); // Allow links like [this](some filename with spaces.md)
// options.set(HtmlRenderer.SOFT_BREAK, "
\n"); // Add linefeed to HTML break
@@ -198,7 +198,7 @@ public String convertMarkup(String markup, Context context, boolean lightMode, b
head += CSS_PRESENTATION_BEAMER;
}
- // Frontmatter
+ // Front matter
String fmaText = "";
final List fmaAllowedAttributes = _appSettings.getMarkdownShownYamlFrontMatterKeys();
Map> fma = Collections.EMPTY_MAP;
diff --git a/app/src/main/java/net/gsantner/markor/format/wikitext/WikitextActionButtons.java b/app/src/main/java/net/gsantner/markor/format/wikitext/WikitextActionButtons.java
index 3def72f9e3..4a80be9ce4 100644
--- a/app/src/main/java/net/gsantner/markor/format/wikitext/WikitextActionButtons.java
+++ b/app/src/main/java/net/gsantner/markor/format/wikitext/WikitextActionButtons.java
@@ -263,7 +263,7 @@ public static String createWikitextHeaderAndTitleContents(String fileNameWithout
@Override
public boolean runTitleClick() {
final Matcher m = WikitextSyntaxHighlighter.HEADING.matcher("");
- MarkorDialogFactory.showHeadlineDialog(getActivity(), _hlEditor, _disabledHeadings, (text, start, end) -> {
+ MarkorDialogFactory.showHeadlineDialog(getActivity(), _hlEditor, _webView, _disabledHeadings, (text, start, end) -> {
if (m.reset(text.subSequence(start, end)).find()) {
return 7 - (m.end(2) - m.start(2));
}
diff --git a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
index 4abbac0126..695e0b8725 100644
--- a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
+++ b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
@@ -27,6 +27,7 @@
import android.util.Pair;
import android.view.Gravity;
import android.view.WindowManager;
+import android.webkit.WebView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
@@ -666,9 +667,9 @@ private static class Heading {
public static void showHeadlineDialog(
final Activity activity,
final EditText edit,
+ final WebView webView,
final Set disabled,
- final GsCallback.r3 headingLevel
- ) {
+ final GsCallback.r3 headingLevel) {
// Get all headings and their levels
final CharSequence text = edit.getText();
final List headings = new ArrayList<>();
@@ -692,10 +693,24 @@ public static void showHeadlineDialog(
dopt.titleText = R.string.table_of_contents;
dopt.searchHintText = R.string.search;
dopt.isSearchEnabled = true;
+ dopt.isSoftInputVisible = false;
+ dopt.isDismissOnItemSelected = false;
+ final int width = activity.getResources().getDisplayMetrics().widthPixels;
+ final int height = activity.getResources().getDisplayMetrics().heightPixels;
+ if (width > height) {
+ dopt.dialogWidth = (int) (width * 0.7);
+ dopt.dialogHeight = (int) (height * 0.95);
+ } else {
+ dopt.dialogWidth = (int) (width * 0.95);
+ dopt.dialogHeight = (int) (height * 0.8);
+ }
dopt.neutralButtonText = R.string.filter;
dopt.positionCallback = result -> {
final int index = filtered.get(result.get(0));
TextViewUtils.selectLines(edit, headings.get(index).line);
+ String title = headings.get(index).str;
+ String id = title.substring(title.lastIndexOf('#') + 1).trim().replaceAll("\\s+", "-").replaceAll("&", "").toLowerCase();
+ webView.loadUrl("javascript:document.getElementById('" + id + "').scrollIntoView();");
};
dopt.neutralButtonCallback = (dialog) -> {
@@ -723,7 +738,7 @@ public static void showHeadlineDialog(
};
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt2);
};
- dopt.gravity = Gravity.TOP;
+ dopt.gravity = Gravity.CENTER;
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt);
}
diff --git a/app/src/main/java/net/gsantner/markor/frontend/NewFileDialog.java b/app/src/main/java/net/gsantner/markor/frontend/NewFileDialog.java
index 77c85a2ab6..7abf599fb2 100644
--- a/app/src/main/java/net/gsantner/markor/frontend/NewFileDialog.java
+++ b/app/src/main/java/net/gsantner/markor/frontend/NewFileDialog.java
@@ -146,7 +146,7 @@ private AlertDialog.Builder makeDialog(final File basedir, final boolean allowCr
if (pos == 3) { // Jekyll
prefix = TodoTxtTask.DATEF_YYYY_MM_DD.format(new Date()) + "-";
- } else if (pos == 9) { //ZettelKasten
+ } else if (pos == 9) { // ZettelKasten
prefix = new SimpleDateFormat("yyyyMMddHHmm", Locale.ROOT).format(new Date()) + "-";
}
if (!TextUtils.isEmpty(prefix) && !fileNameEdit.getText().toString().startsWith(prefix)) {
@@ -325,7 +325,7 @@ private String getTemplateByPos(
" line\";2059-12-24\n";
}
case 12: {
- // orgmode
+ // Org-mode
return "OrgMode Reference\n" + "* Headline\n" + "** Nested headline\n" + "*** Deeper\n" + "\n" + "* Basic markup\n" + "This is the general building block for org-mode navigation.\n" + "- _underscores let you underline things_\n" + "- *stars add emphasis*\n" + "- /slashes are italics/\n" + "- +pluses are strikethrough+\n" + "- =equal signs are verbatim text=\n" + "- ~tildes can also be used~\n" + "\n" + "* List\n" + "** Unordered List\n" + "- Item 1\n" + "- Item 2\n" + " - Subitem 2.1\n" + " - Subitem 2.2\n" + "** Ordered List\n" + "1. First Item\n" + "2. Second Item\n" + " 1. Subitem 2.1\n" + " 2. Subitem 2.2\n" + "- [X] Completed Task\n" + "- [ ] Uncompleted Task\n" + "** Nested List\n" + " - Item A\n" + " - Subitem A.1\n" + " - Subitem A.2\n" + " - Item B\n" + "\n" + "* Tables\n" + "\n" + "| First Name | Last Name | Years using Emacs |\n" + "|----------------------------+---------------------+-------------------|\n" + "| Lee | Hinman | 5 |\n" + "| Mike | Hunsinger | 2 |\n" + "| Daniel | Glauser | 4 |\n" + "| Really-long-first-name-guy | long-last-name-pers | 1 |\n" + "\n" + "* Org-mode links\n" + "\n" + "#+BEGIN_SRC fundamental\n" + "[[http://google.com/][Google]]\n" + "#+END_SRC\n" + "\n" + "[[./images/pic1.png]]\n" + "\n" + "\n" + "* TODO List\n" + "** TODO This is a task that needs doing\n" + "** TODO Another todo task\n" + "- [ ] sub task one\n" + "- [X] sub task two\n" + "- [ ] sub task three\n" + "** DONE I've already finished this one\n" + "*** CANCELLED learn todos\n" + " CLOSED: [2023-10-16 Mon 08:39]\n" + "\n" + "* Code\n" + "#+BEGIN_LaTeX\n" + "$a + b$\n" + "#+END_LaTeX\n" + "\n" + "#+BEGIN_SRC emacs-lisp\n" + "(defun my/function ()\n" + " \"docstring\"\n" + " (interactive)\n" + " (progn\n" + " (+ 1 1)\n" + " (message \"Hi\")))\n" + "#+END_SRC\n" + "\n";
}
}
diff --git a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
index 3ca26d524c..05257ee393 100644
--- a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
+++ b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
@@ -89,9 +89,13 @@ public static class DialogOptions {
public CharSequence messageText = "";
public String defaultText = "";
public boolean isSearchEnabled = true;
+ public boolean isSoftInputVisible = true;
+ public boolean isDismissOnItemSelected = true;
public boolean isDarkDialog = false;
public int dialogWidthDp = WindowManager.LayoutParams.MATCH_PARENT;
public int dialogHeightDp = WindowManager.LayoutParams.WRAP_CONTENT;
+ public int dialogWidth;
+ public int dialogHeight;
public int gravity = Gravity.NO_GRAVITY;
public int searchInputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
public GsCallback.a1 highlighter = null;
@@ -318,18 +322,30 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi
});
final Window win = dialog.getWindow();
- if (win != null && dopt.isSearchEnabled) {
- win.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+ if (win != null) {
+ if (dopt.isSearchEnabled) {
+ if (dopt.isSoftInputVisible) {
+ win.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+ } else {
+ win.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
+ }
+ }
}
-
dialog.show();
if (win != null) {
- int ds_w = dopt.dialogWidthDp < 100 ? dopt.dialogWidthDp : ((int) (dopt.dialogWidthDp * activity.getResources().getDisplayMetrics().density));
- int ds_h = dopt.dialogHeightDp < 100 ? dopt.dialogHeightDp : ((int) (dopt.dialogHeightDp * activity.getResources().getDisplayMetrics().density));
- ds_w = (ds_w * 1.1 > activity.getResources().getDisplayMetrics().widthPixels) ? ViewGroup.LayoutParams.MATCH_PARENT : ds_w;
- ds_h = (ds_h * 1.1 > activity.getResources().getDisplayMetrics().heightPixels) ? ViewGroup.LayoutParams.MATCH_PARENT : ds_h;
- win.setLayout(ds_w, ds_h);
+ if (dopt.dialogWidth > 0 && dopt.dialogHeight > 0) {
+ WindowManager.LayoutParams params = win.getAttributes();
+ params.width = dopt.dialogWidth;
+ params.height = dopt.dialogHeight;
+ win.setAttributes(params);
+ } else {
+ int ds_w = dopt.dialogWidthDp < 100 ? dopt.dialogWidthDp : ((int) (dopt.dialogWidthDp * activity.getResources().getDisplayMetrics().density));
+ int ds_h = dopt.dialogHeightDp < 100 ? dopt.dialogHeightDp : ((int) (dopt.dialogHeightDp * activity.getResources().getDisplayMetrics().density));
+ ds_w = (ds_w * 1.1 > activity.getResources().getDisplayMetrics().widthPixels) ? ViewGroup.LayoutParams.MATCH_PARENT : ds_w;
+ ds_h = (ds_h * 1.1 > activity.getResources().getDisplayMetrics().heightPixels) ? ViewGroup.LayoutParams.MATCH_PARENT : ds_h;
+ win.setLayout(ds_w, ds_h);
+ }
}
if (win != null && dopt.gravity != Gravity.NO_GRAVITY) {
@@ -356,7 +372,9 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi
// Helper function to trigger callback with single item
final GsCallback.b1 directActivate = (position) -> {
final int index = listAdapter._filteredItems.get(position);
- dialog.dismiss();
+ if (dopt.isDismissOnItemSelected) {
+ dialog.dismiss();
+ }
if (dopt.callback != null) {
dopt.callback.callback(dopt.data.get(index).toString());
} else if (dopt.positionCallback != null) {
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 318da60930..466687702d 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -1,5 +1,4 @@
-
- remove line break)
if (converted.contains("footnote-")) {
@@ -329,14 +340,15 @@ public String convertMarkup(String markup, Context context, boolean lightMode, b
return putContentIntoTemplate(context, converted, lightMode, file, onLoadJs, head);
}
- private static final Pattern linkPattern = Pattern.compile("\\[(.*?)\\]\\((.*?)(\\s+\".*\")?\\)");
+ public static String generateHeaderId(String headerText) {
+ return HeaderIdGenerator.generateId(headerText, toDashChars, false, false);
+ }
private String escapeSpacesInLink(final String markup) {
final Matcher matcher = linkPattern.matcher(markup);
if (!matcher.find()) {
return markup;
}
-
// 1) Walk through the text till finding a link in markdown syntax
// 2) Add all text-before-link to buffer
// 3) Extract [title](link to somehere)
diff --git a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
index 695e0b8725..a601a2f5d7 100644
--- a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
+++ b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
@@ -39,6 +39,7 @@
import net.gsantner.markor.ApplicationObject;
import net.gsantner.markor.R;
import net.gsantner.markor.format.FormatRegistry;
+import net.gsantner.markor.format.markdown.MarkdownTextConverter;
import net.gsantner.markor.format.todotxt.TodoTxtBasicSyntaxHighlighter;
import net.gsantner.markor.format.todotxt.TodoTxtFilter;
import net.gsantner.markor.format.todotxt.TodoTxtTask;
@@ -695,24 +696,16 @@ public static void showHeadlineDialog(
dopt.isSearchEnabled = true;
dopt.isSoftInputVisible = false;
dopt.isDismissOnItemSelected = false;
- final int width = activity.getResources().getDisplayMetrics().widthPixels;
- final int height = activity.getResources().getDisplayMetrics().heightPixels;
- if (width > height) {
- dopt.dialogWidth = (int) (width * 0.7);
- dopt.dialogHeight = (int) (height * 0.95);
- } else {
- dopt.dialogWidth = (int) (width * 0.95);
- dopt.dialogHeight = (int) (height * 0.8);
- }
- dopt.neutralButtonText = R.string.filter;
+
dopt.positionCallback = result -> {
final int index = filtered.get(result.get(0));
TextViewUtils.selectLines(edit, headings.get(index).line);
- String title = headings.get(index).str;
- String id = title.substring(title.lastIndexOf('#') + 1).trim().replaceAll("\\s+", "-").replaceAll("&", "").toLowerCase();
+ String header = headings.get(index).str;
+ String id = MarkdownTextConverter.generateHeaderId(header.substring(header.lastIndexOf('#') + 1).trim());
webView.loadUrl("javascript:document.getElementById('" + id + "').scrollIntoView();");
};
+ dopt.neutralButtonText = R.string.filter;
dopt.neutralButtonCallback = (dialog) -> {
final DialogOptions dopt2 = new DialogOptions();
dopt2.preSelected = GsCollectionUtils.indices(levels, l -> !disabled.contains(l));
@@ -738,7 +731,18 @@ public static void showHeadlineDialog(
};
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt2);
};
+
+ final int width = activity.getResources().getDisplayMetrics().widthPixels;
+ final int height = activity.getResources().getDisplayMetrics().heightPixels;
+ if (width > height) {
+ dopt.dialogWidth = (int) (width * 0.7);
+ dopt.dialogHeight = (int) (height * 0.95);
+ } else {
+ dopt.dialogWidth = (int) (width * 0.95);
+ dopt.dialogHeight = (int) (height * 0.8);
+ }
dopt.gravity = Gravity.CENTER;
+
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt);
}
From 09b54ae8aaa5eaae4959a5239ba0a536b629ff6e Mon Sep 17 00:00:00 2001
From: Li Guanglin <2311987902@qq.com>
Date: Mon, 22 Jan 2024 18:53:51 +0800
Subject: [PATCH 09/12] refactor: abstract the code about dialog aspect ratio
---
.../activity/DocumentEditAndViewFragment.java | 2 +-
.../markor/frontend/MarkorDialogFactory.java | 11 +----
.../frontend/GsSearchOrCustomTextDialog.java | 45 +++++++++----------
.../gsantner/opoc/util/GsContextUtils.java | 23 ++++++++++
4 files changed, 48 insertions(+), 33 deletions(-)
diff --git a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java
index 4381119131..1fb31f7a59 100644
--- a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java
+++ b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java
@@ -773,7 +773,7 @@ public boolean saveDocument(final boolean forceSaveEmpty) {
return false;
}
- // Document is written if writeable && content has changed
+ // Document is written iff writeable && content has changed
final CharSequence text = _hlEditor.getText();
if (!_document.isContentSame(text)) {
final int minLength = GsContextUtils.TEXTFILE_OVERWRITE_MIN_TEXT_LENGTH;
diff --git a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
index a601a2f5d7..97955084aa 100644
--- a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
+++ b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
@@ -732,15 +732,8 @@ public static void showHeadlineDialog(
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt2);
};
- final int width = activity.getResources().getDisplayMetrics().widthPixels;
- final int height = activity.getResources().getDisplayMetrics().heightPixels;
- if (width > height) {
- dopt.dialogWidth = (int) (width * 0.7);
- dopt.dialogHeight = (int) (height * 0.95);
- } else {
- dopt.dialogWidth = (int) (width * 0.95);
- dopt.dialogHeight = (int) (height * 0.8);
- }
+ dopt.portraitAspectRatio = new float[]{0.95f, 0.8f};
+ dopt.landscapeAspectRatio = new float[]{0.7f, 0.95f};
dopt.gravity = Gravity.CENTER;
GsSearchOrCustomTextDialog.showMultiChoiceDialogWithSearchFilterUI(activity, dopt);
diff --git a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
index 05257ee393..e1e76d2e48 100644
--- a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
+++ b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
@@ -23,6 +23,7 @@
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
+import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -88,22 +89,22 @@ public static class DialogOptions {
public List iconsForData;
public CharSequence messageText = "";
public String defaultText = "";
+ public boolean isDarkDialog = false;
public boolean isSearchEnabled = true;
public boolean isSoftInputVisible = true;
public boolean isDismissOnItemSelected = true;
- public boolean isDarkDialog = false;
+ public int gravity = Gravity.NO_GRAVITY;
public int dialogWidthDp = WindowManager.LayoutParams.MATCH_PARENT;
public int dialogHeightDp = WindowManager.LayoutParams.WRAP_CONTENT;
- public int dialogWidth;
- public int dialogHeight;
- public int gravity = Gravity.NO_GRAVITY;
public int searchInputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
- public GsCallback.a1 highlighter = null;
+ public float[] portraitAspectRatio = {0.0f, 1.0f};
+ public float[] landscapeAspectRatio = {0.0f, 1.0f};
public String extraFilter = null;
public Collection preSelected = null;
+ public GsCallback.a1 highlighter = null;
public GsCallback.a1 neutralButtonCallback = null;
- public GsCallback.b2 searchFunction = GsSearchOrCustomTextDialog::standardSearch;
public GsCallback.a1 dismissCallback = null;
+ public GsCallback.b2 searchFunction = GsSearchOrCustomTextDialog::standardSearch;
@ColorInt
public int textColor = 0xFF000000;
@@ -330,28 +331,26 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi
win.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
}
}
- }
- dialog.show();
+ dialog.show();
- if (win != null) {
- if (dopt.dialogWidth > 0 && dopt.dialogHeight > 0) {
- WindowManager.LayoutParams params = win.getAttributes();
- params.width = dopt.dialogWidth;
- params.height = dopt.dialogHeight;
- win.setAttributes(params);
+ DisplayMetrics displayMetrics = activity.getResources().getDisplayMetrics();
+ if (dopt.portraitAspectRatio[0] > 0 && dopt.landscapeAspectRatio[0] > 0) {
+ GsContextUtils.windowAspectRatio(win, dopt.portraitAspectRatio[0], dopt.portraitAspectRatio[1], dopt.landscapeAspectRatio[0], dopt.landscapeAspectRatio[1], displayMetrics);
} else {
- int ds_w = dopt.dialogWidthDp < 100 ? dopt.dialogWidthDp : ((int) (dopt.dialogWidthDp * activity.getResources().getDisplayMetrics().density));
- int ds_h = dopt.dialogHeightDp < 100 ? dopt.dialogHeightDp : ((int) (dopt.dialogHeightDp * activity.getResources().getDisplayMetrics().density));
- ds_w = (ds_w * 1.1 > activity.getResources().getDisplayMetrics().widthPixels) ? ViewGroup.LayoutParams.MATCH_PARENT : ds_w;
- ds_h = (ds_h * 1.1 > activity.getResources().getDisplayMetrics().heightPixels) ? ViewGroup.LayoutParams.MATCH_PARENT : ds_h;
+ int ds_w = dopt.dialogWidthDp < 100 ? dopt.dialogWidthDp : ((int) (dopt.dialogWidthDp * displayMetrics.density));
+ int ds_h = dopt.dialogHeightDp < 100 ? dopt.dialogHeightDp : ((int) (dopt.dialogHeightDp * displayMetrics.density));
+ ds_w = (ds_w * 1.1 > displayMetrics.widthPixels) ? ViewGroup.LayoutParams.MATCH_PARENT : ds_w;
+ ds_h = (ds_h * 1.1 > displayMetrics.heightPixels) ? ViewGroup.LayoutParams.MATCH_PARENT : ds_h;
win.setLayout(ds_w, ds_h);
}
- }
- if (win != null && dopt.gravity != Gravity.NO_GRAVITY) {
- WindowManager.LayoutParams wlp = win.getAttributes();
- wlp.gravity = dopt.gravity;
- win.setAttributes(wlp);
+ if (dopt.gravity != Gravity.NO_GRAVITY) {
+ WindowManager.LayoutParams wlp = win.getAttributes();
+ wlp.gravity = dopt.gravity;
+ win.setAttributes(wlp);
+ }
+ } else {
+ dialog.show();
}
final Button neutralButton = dialog.getButton(AlertDialog.BUTTON_NEUTRAL);
diff --git a/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java b/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java
index a106a953b2..ab18a2cbf5 100644
--- a/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java
+++ b/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java
@@ -2745,6 +2745,29 @@ public void dialogFullWidth(AlertDialog dialog, boolean fullWidth, boolean showK
}
}
+ public static void windowAspectRatio(final Window window,
+ float portraitWidthRatio,
+ float portraitHeightRatio,
+ float landscapeWidthRatio,
+ float landscapeHeightRatio,
+ final DisplayMetrics displayMetrics) {
+ if (window == null) {
+ return;
+ }
+
+ WindowManager.LayoutParams params = window.getAttributes();
+ final int width = displayMetrics.widthPixels;
+ final int height = displayMetrics.heightPixels;
+ if (width < height) { // Portrait
+ params.width = (int) (width * portraitWidthRatio);
+ params.height = (int) (height * portraitHeightRatio);
+ } else { // Landscape
+ params.width = (int) (width * landscapeWidthRatio);
+ params.height = (int) (height * landscapeHeightRatio);
+ }
+ window.setAttributes(params);
+ }
+
// Make activity/app not show up in the recents history - call before finish / System.exit
public T removeActivityFromHistory(final Context activity) {
try {
From b0204e110426b9076d8a0803d73ac32976b2c65c Mon Sep 17 00:00:00 2001
From: Li Guanglin <2311987902@qq.com>
Date: Mon, 5 Feb 2024 00:01:32 +0800
Subject: [PATCH 10/12] feat: add support for saving the last position of
heading items
---
.../gsantner/markor/frontend/MarkorDialogFactory.java | 1 +
.../opoc/frontend/GsSearchOrCustomTextDialog.java | 10 ++++++++--
.../java/net/gsantner/opoc/util/GsContextUtils.java | 4 ++--
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
index 97955084aa..65465f1190 100644
--- a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
+++ b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java
@@ -696,6 +696,7 @@ public static void showHeadlineDialog(
dopt.isSearchEnabled = true;
dopt.isSoftInputVisible = false;
dopt.isDismissOnItemSelected = false;
+ dopt.isSaveItemPositionEnabled = true;
dopt.positionCallback = result -> {
final int index = filtered.get(result.get(0));
diff --git a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
index e1e76d2e48..30c29b56df 100644
--- a/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
+++ b/app/src/main/java/net/gsantner/opoc/frontend/GsSearchOrCustomTextDialog.java
@@ -93,6 +93,7 @@ public static class DialogOptions {
public boolean isSearchEnabled = true;
public boolean isSoftInputVisible = true;
public boolean isDismissOnItemSelected = true;
+ public boolean isSaveItemPositionEnabled = false;
public int gravity = Gravity.NO_GRAVITY;
public int dialogWidthDp = WindowManager.LayoutParams.MATCH_PARENT;
public int dialogHeightDp = WindowManager.LayoutParams.WRAP_CONTENT;
@@ -159,7 +160,7 @@ private Adapter(final Context context, final DialogOptions dopt) {
_dopt = dopt;
_extraPattern = (_dopt.extraFilter == null ? null : Pattern.compile(_dopt.extraFilter).matcher(""));
_selectedItems = new HashSet<>(_dopt.preSelected != null ? _dopt.preSelected : Collections.emptyList());
- _layoutHeight = (int) GsContextUtils.instance.convertDpToPx(context, 36);
+ _layoutHeight = GsContextUtils.instance.convertDpToPx(context, 36);
}
@NonNull
@@ -278,6 +279,9 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi
final ListView listView = new ListView(activity);
listView.setId(LIST_VIEW_ID);
listView.setAdapter(listAdapter);
+ if (dopt.isSaveItemPositionEnabled) {
+ listView.setSelection(activity.getIntent().getIntExtra("lastHeadingPosition", 0));
+ }
listView.setVisibility(dopt.data != null && !dopt.data.isEmpty() ? View.VISIBLE : View.GONE);
final LinearLayout.LayoutParams listLayout = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
listLayout.weight = 1;
@@ -285,6 +289,8 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi
if (dopt.dismissCallback != null) {
dialogBuilder.setOnDismissListener(dopt.dismissCallback::callback);
+ } else {
+ dialogBuilder.setOnDismissListener(dialogInterface -> activity.getIntent().putExtra("lastHeadingPosition", listView.getFirstVisiblePosition()));
}
dialogBuilder.setView(mainLayout)
@@ -335,7 +341,7 @@ public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activi
DisplayMetrics displayMetrics = activity.getResources().getDisplayMetrics();
if (dopt.portraitAspectRatio[0] > 0 && dopt.landscapeAspectRatio[0] > 0) {
- GsContextUtils.windowAspectRatio(win, dopt.portraitAspectRatio[0], dopt.portraitAspectRatio[1], dopt.landscapeAspectRatio[0], dopt.landscapeAspectRatio[1], displayMetrics);
+ GsContextUtils.windowAspectRatio(win, displayMetrics, dopt.portraitAspectRatio[0], dopt.portraitAspectRatio[1], dopt.landscapeAspectRatio[0], dopt.landscapeAspectRatio[1]);
} else {
int ds_w = dopt.dialogWidthDp < 100 ? dopt.dialogWidthDp : ((int) (dopt.dialogWidthDp * displayMetrics.density));
int ds_h = dopt.dialogHeightDp < 100 ? dopt.dialogHeightDp : ((int) (dopt.dialogHeightDp * displayMetrics.density));
diff --git a/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java b/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java
index ab18a2cbf5..ac1ccb974b 100644
--- a/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java
+++ b/app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java
@@ -2746,11 +2746,11 @@ public void dialogFullWidth(AlertDialog dialog, boolean fullWidth, boolean showK
}
public static void windowAspectRatio(final Window window,
+ final DisplayMetrics displayMetrics,
float portraitWidthRatio,
float portraitHeightRatio,
float landscapeWidthRatio,
- float landscapeHeightRatio,
- final DisplayMetrics displayMetrics) {
+ float landscapeHeightRatio) {
if (window == null) {
return;
}
From f5e9ab7294deb96ed5bc643920b02a3192000efe Mon Sep 17 00:00:00 2001
From: Li Guanglin <2311987902@qq.com>
Date: Mon, 5 Feb 2024 09:47:36 +0800
Subject: [PATCH 11/12] minor improvements
---
.../markor/format/markdown/MarkdownTextConverter.java | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java
index 29281b2637..5bb1d1a05a 100644
--- a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java
+++ b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java
@@ -155,9 +155,9 @@ public class MarkdownTextConverter extends TextConverterBase {
public static final HtmlRenderer flexmarkRenderer = HtmlRenderer.builder().extensions(flexmarkExtensions).build();
//########################
- //## Extras
+ //## Others
//########################
- private static String toDashChars = null;
+ private static String toDashChars = " -_"; // See HtmlRenderer.HEADER_ID_GENERATOR_TO_DASH_CHARS.getFrom(document)
private static final Pattern linkPattern = Pattern.compile("\\[(.*?)\\]\\((.*?)(\\s+\".*\")?\\)");
@@ -166,7 +166,7 @@ public class MarkdownTextConverter extends TextConverterBase {
//########################
@Override
public String convertMarkup(String markup, Context context, boolean lightMode, boolean enableLineNumbers, File file) {
- String converted = "", onLoadJs = "", head = "";
+ String converted, onLoadJs = "", head = "";
final MutableDataSet options = new MutableDataSet();
options.set(Parser.EXTENSIONS, flexmarkExtensions);
@@ -304,8 +304,6 @@ public String convertMarkup(String markup, Context context, boolean lightMode, b
Document document = flexmarkParser.parse(markup);
converted = fmaText + flexmarkRenderer.withOptions(options).render(document);
- toDashChars = HtmlRenderer.HEADER_ID_GENERATOR_TO_DASH_CHARS.getFrom(document);
-
// After render changes: Fixes for Footnotes (converter creates footnote +
+ ref#(click) --> remove line break)
if (converted.contains("footnote-")) {
converted = converted.replace("\n↩", "class=\"footnote-backref\"> ↩");
From 70e3eff78ff2a1ad6745223321c83b61b2e3c676 Mon Sep 17 00:00:00 2001
From: Gregor Santner
Date: Wed, 27 Mar 2024 02:39:25 +0100
Subject: [PATCH 12/12] autoreformat
---
app/src/main/res/values-zh-rCN/strings.xml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 466687702d..318da60930 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -1,4 +1,5 @@
-