Skip to content

Commit 828773a

Browse files
authored
Merge branch 'master' into l10n_master
2 parents 48b17c5 + 62e4a09 commit 828773a

File tree

13 files changed

+166
-58
lines changed

13 files changed

+166
-58
lines changed

app/src/main/java/net/gsantner/markor/activity/DocumentActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ private void handleLaunchingIntent(final Intent intent) {
198198
// Start in a specific mode if required. Otherwise let the fragment decide
199199
Boolean startInPreview = null;
200200
if (intent.getBooleanExtra(Document.EXTRA_DO_PREVIEW, false) ||
201-
file.getName().startsWith("index.")
201+
file.getName().startsWith("index.")
202202
) {
203203
startInPreview = true;
204204
}

app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java

Lines changed: 136 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,15 @@
3434
import android.webkit.WebSettings;
3535
import android.webkit.WebView;
3636
import android.widget.HorizontalScrollView;
37+
import android.widget.ImageButton;
3738
import android.widget.LinearLayout;
3839
import android.widget.ScrollView;
39-
import android.widget.SearchView;
40+
import android.widget.TextView;
4041
import android.widget.Toast;
4142

4243
import androidx.annotation.NonNull;
4344
import androidx.appcompat.app.AppCompatActivity;
45+
import androidx.appcompat.widget.SearchView;
4446

4547
import net.gsantner.markor.ApplicationObject;
4648
import net.gsantner.markor.BuildConfig;
@@ -103,7 +105,6 @@ public static DocumentEditAndViewFragment newInstance(final @NonNull Document do
103105
private DraggableScrollbarScrollView _verticalScrollView;
104106
private HorizontalScrollView _horizontalScrollView;
105107
private LineNumbersTextView _lineNumbersView;
106-
private SearchView _menuSearchViewForViewMode;
107108
private Document _document;
108109
private FormatRegistry _format;
109110
private MarkorContextUtils _cu;
@@ -132,7 +133,6 @@ protected int getLayoutResId() {
132133
return R.layout.document__fragment__edit;
133134
}
134135

135-
@SuppressLint({"SetJavaScriptEnabled", "WrongConstant", "AddJavascriptInterface", "JavascriptInterface"})
136136
@Override
137137
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
138138
super.onViewCreated(view, savedInstanceState);
@@ -212,7 +212,7 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
212212
// This works well to preserve keyboard state.
213213
if (activity != null) {
214214
final Window window = activity.getWindow();
215-
// Setting via a windowmanager state is much more robust than using show/hide
215+
// Setting via a window manager state is much more robust than using show/hide
216216
final int adjustResize = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
217217
final int unchanged = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED | adjustResize;
218218
final int hidden = WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN | adjustResize;
@@ -328,35 +328,8 @@ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
328328
menu.findItem(R.id.action_share_image).setVisible(true);
329329
menu.findItem(R.id.action_load_epub).setVisible(isExperimentalFeaturesEnabled);
330330

331-
// SearchView (View Mode)
332-
_menuSearchViewForViewMode = (SearchView) menu.findItem(R.id.action_search_view).getActionView();
333-
if (_menuSearchViewForViewMode != null) {
334-
_menuSearchViewForViewMode.setSubmitButtonEnabled(true);
335-
_menuSearchViewForViewMode.setQueryHint(getString(R.string.search));
336-
_menuSearchViewForViewMode.setOnQueryTextFocusChangeListener((v, searchHasFocus) -> {
337-
if (!searchHasFocus) {
338-
_menuSearchViewForViewMode.setQuery("", false);
339-
_menuSearchViewForViewMode.setIconified(true);
340-
}
341-
});
342-
_menuSearchViewForViewMode.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
343-
@Override
344-
public boolean onQueryTextSubmit(String text) {
345-
if (_webView != null) {
346-
_webView.findNext(true);
347-
}
348-
return true;
349-
}
350-
351-
@Override
352-
public boolean onQueryTextChange(String text) {
353-
if (_webView != null) {
354-
_webView.findAllAsync(text);
355-
}
356-
return true;
357-
}
358-
});
359-
}
331+
// Setup SearchView for view-mode
332+
setupSearchView((SearchView) menu.findItem(R.id.action_search_view).getActionView());
360333

361334
// Set various initial states
362335
updateMenuToggleStates(_document.getFormat());
@@ -653,6 +626,7 @@ public void onFsViewerConfig(GsFileBrowserOptions.Options dopt) {
653626
}
654627
}
655628
}
629+
656630
public void checkTextChangeState() {
657631
final boolean isTextChanged = !_document.isContentSame(_hlEditor.getText());
658632
Drawable d;
@@ -700,6 +674,134 @@ private void showHideActionBar() {
700674
}
701675
}
702676

677+
/**
678+
* Setup SearchView from OptionsMenu for view-mode.
679+
*
680+
* @param searchView the SearchView form OptionsMenu
681+
*/
682+
private void setupSearchView(SearchView searchView) {
683+
if (searchView == null) {
684+
return;
685+
}
686+
// Only setup SearchView for view-mode, to avoid unnecessary setup for edit-mode
687+
if (!_isPreviewVisible || _webView == null) {
688+
return;
689+
}
690+
691+
searchView.setQueryHint(getString(R.string.search));
692+
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
693+
private String searchText = "";
694+
private Runnable searchTask;
695+
696+
private boolean search(String text) {
697+
if (_webView == null) {
698+
return false;
699+
}
700+
if (searchTask == null) {
701+
searchTask = TextViewUtils.makeDebounced(_webView.getHandler(), 500, () -> _webView.findAllAsync(searchText));
702+
}
703+
704+
searchText = text;
705+
searchTask.run();
706+
return true;
707+
}
708+
709+
@Override
710+
public boolean onQueryTextSubmit(String query) {
711+
if (_webView != null) {
712+
_webView.findNext(true);
713+
return true;
714+
}
715+
return false;
716+
}
717+
718+
@Override
719+
public boolean onQueryTextChange(String text) {
720+
return search(text);
721+
}
722+
});
723+
searchView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
724+
@Override
725+
public void onViewAttachedToWindow(@NonNull View v) {
726+
}
727+
728+
@Override
729+
public void onViewDetachedFromWindow(@NonNull View v) {
730+
// Clear search when SearchView is closed abnormally, e.g. switch from QuickNote to To-Do when SearchView is opened
731+
if (searchView.getQuery().length() > 0) {
732+
searchView.setQuery("", false); // This will make onQueryTextChange be called back
733+
}
734+
if (!searchView.isIconified()) {
735+
searchView.setIconified(true);
736+
}
737+
}
738+
});
739+
740+
// Because SearchView doesn't provide a public API to add custom buttons
741+
// We must get the searchPlate (the layout containing the text field and close button) from SearchView
742+
// This approach is more robust than reflection
743+
ViewGroup searchPlate = searchView.findViewById(androidx.appcompat.R.id.search_plate);
744+
if (searchPlate == null) {
745+
// Ensure that SearchView is always available even if getting searchPlate fails
746+
searchView.setSubmitButtonEnabled(true);
747+
return;
748+
}
749+
750+
Context searchViewContext = searchView.getContext();
751+
LinearLayout linearLayout = new LinearLayout(searchViewContext);
752+
753+
// Add search result TextView
754+
TextView resultTextView = new TextView(searchViewContext);
755+
resultTextView.setGravity(Gravity.CENTER);
756+
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
757+
LinearLayout.LayoutParams.WRAP_CONTENT,
758+
LinearLayout.LayoutParams.MATCH_PARENT
759+
);
760+
layoutParams.setMarginEnd(14);
761+
resultTextView.setLayoutParams(layoutParams);
762+
linearLayout.addView(resultTextView);
763+
764+
// Add previous match Button
765+
ImageButton previousButton = new ImageButton(searchViewContext);
766+
previousButton.setImageResource(R.drawable.ic_baseline_keyboard_arrow_up_24);
767+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
768+
previousButton.setTooltipText(getString(R.string.previous_match));
769+
}
770+
linearLayout.addView(previousButton);
771+
772+
// Add next match Button
773+
ImageButton nextButton = new ImageButton(searchViewContext);
774+
nextButton.setImageResource(R.drawable.ic_baseline_keyboard_arrow_down_24);
775+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
776+
nextButton.setTooltipText(getString(R.string.next_match));
777+
}
778+
linearLayout.addView(nextButton);
779+
780+
// Apply to SearchView
781+
searchPlate.addView(linearLayout, 1);
782+
783+
// Set listeners
784+
previousButton.setOnClickListener(v -> {
785+
if (_webView != null) {
786+
_webView.findNext(false);
787+
}
788+
});
789+
nextButton.setOnClickListener(v -> {
790+
if (_webView != null) {
791+
_webView.findNext(true);
792+
}
793+
});
794+
_webView.setFindListener((activeMatchOrdinal, numberOfMatches, isDoneCounting) -> {
795+
if (isDoneCounting) {
796+
String searchResult = "";
797+
if (numberOfMatches > 0) {
798+
searchResult = (activeMatchOrdinal + 1) + "/" + numberOfMatches;
799+
}
800+
resultTextView.setText(searchResult);
801+
}
802+
});
803+
}
804+
703805
private void setMarginBottom(final View view, final int marginBottom) {
704806
final ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
705807
if (params != null) {
@@ -867,6 +969,7 @@ public void setViewModeVisibility(final boolean show) {
867969
setViewModeVisibility(show, true);
868970
}
869971

972+
@SuppressLint({"SetJavaScriptEnabled"})
870973
private void setupWebViewIfNeeded(final Activity activity) {
871974
if (_webView == null) {
872975
_webView = (WebView) _webViewStub.inflate();

app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ private List<ActionItem> getActionList() {
168168
new ActionItem(R.string.abid_common_special_key, R.drawable.ic_keyboard_black_24dp, R.string.special_key),
169169
new ActionItem(R.string.abid_common_time, R.drawable.ic_access_time_black_24dp, R.string.date_and_time),
170170
new ActionItem(R.string.abid_common_open_link_browser, R.drawable.ic_open_in_browser_black_24dp, R.string.open_link),
171-
new ActionItem(R.string.abid_common_change_case, R.drawable.ic_format_text_case_black_24dp, R.string.switch_case),
171+
new ActionItem(R.string.abid_common_change_case, R.drawable.ic_format_text_case_black_24dp, R.string.text_case),
172172

173173
new ActionItem(R.string.abid_common_web_jump_to_very_top_or_bottom, R.drawable.ic_vertical_align_center_black_24dp, R.string.jump_to_bottom).setDisplayMode(ActionItem.DisplayMode.VIEW),
174174
new ActionItem(R.string.abid_common_view_file_in_other_app, R.drawable.ic_baseline_open_in_new_24, R.string.open_with).setDisplayMode(ActionItem.DisplayMode.VIEW),

app/src/main/java/net/gsantner/markor/format/markdown/MarkdownActionButtons.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
import net.gsantner.markor.frontend.textview.AutoTextFormatter;
2323
import net.gsantner.markor.frontend.textview.TextViewUtils;
2424
import net.gsantner.markor.model.Document;
25+
import net.gsantner.opoc.format.GsTextUtils;
2526
import net.gsantner.opoc.util.GsContextUtils;
2627
import net.gsantner.opoc.util.GsFileUtils;
27-
import net.gsantner.opoc.format.GsTextUtils;
2828

2929
import java.io.File;
3030
import java.util.Arrays;

app/src/main/java/net/gsantner/markor/frontend/FileInfoDialog.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,16 @@ private AlertDialog.Builder setUpDialog(final File file, LayoutInflater inflater
8787
tv(root, R.id.ui__fileinfodialog__mimetype_description).setText(GsFileUtils.getMimeType(file));
8888
tv(root, R.id.ui__fileinfodialog__sha_256).setText(GsFileUtils.sha256(file));
8989
tv(root, R.id.ui__fileinfodialog__location).setOnLongClickListener(v -> {
90-
GsContextUtils.instance.setClipboard(v.getContext(), file.getAbsolutePath());
91-
Toast.makeText(v.getContext(), R.string.clipboard, Toast.LENGTH_SHORT).show();
92-
return true;}
90+
GsContextUtils.instance.setClipboard(v.getContext(), file.getAbsolutePath());
91+
Toast.makeText(v.getContext(), R.string.clipboard, Toast.LENGTH_SHORT).show();
92+
return true;
93+
}
9394
);
9495
tv(root, R.id.ui__fileinfodialog__sha_256).setOnLongClickListener(v -> {
95-
GsContextUtils.instance.setClipboard(v.getContext(), GsFileUtils.sha256(file));
96-
Toast.makeText(v.getContext(), R.string.clipboard, Toast.LENGTH_SHORT).show();
97-
return true;}
96+
GsContextUtils.instance.setClipboard(v.getContext(), GsFileUtils.sha256(file));
97+
Toast.makeText(v.getContext(), R.string.clipboard, Toast.LENGTH_SHORT).show();
98+
return true;
99+
}
98100
);
99101

100102

app/src/main/java/net/gsantner/markor/web/DraggableScrollbarWebView.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public boolean isFastScrollEnabled() {
9393
return _fastScrollEnabled;
9494
}
9595

96-
////////
96+
/// /////
9797
// Feature Animated Scrolling
9898
public void scrollAnimatedToXY(final int scrollX, final int scrollY, int... arg0Delay__arg1Duration) {
9999
final int delay = Math.max(1, arg0Delay__arg1Duration != null && arg0Delay__arg1Duration.length > 0 ? arg0Delay__arg1Duration[0] : 500);

app/src/main/java/net/gsantner/opoc/frontend/base/GsPreferenceFragmentBase.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,8 @@ protected boolean appendPreference(Preference pref, @Nullable PreferenceGroup ta
540540

541541
//###############################
542542
//### Divider
543-
////###############################
543+
544+
/// /###############################
544545

545546

546547
public boolean isDividerVisible() {

app/src/main/java/net/gsantner/opoc/frontend/filebrowser/GsFileBrowserFragment.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ public void clearSelection() {
517517
}
518518

519519

520-
///////////////
520+
/// ////////////
521521

522522
private void askForMoveOrCopy(final boolean isMove) {
523523
final List<File> files = new ArrayList<>(_filesystemViewerAdapter.getCurrentSelection());

app/src/main/java/net/gsantner/opoc/util/GsContextUtils.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ protected <T extends GsContextUtils> T thisp() {
201201
protected static String m_chooserTitle = "➥";
202202

203203

204-
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
204+
/// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
205205
//########################
206206
//## Resources
207207
//########################
@@ -289,11 +289,10 @@ public boolean areResourcesAvailable(final Context context, final ResType resTyp
289289
return true;
290290
}
291291

292-
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
292+
/// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
293293
//########################
294294
//## App & Device information
295295
//########################
296-
297296
public static String getAndroidVersion() {
298297
return Build.VERSION.RELEASE + " (" + Build.VERSION.SDK_INT + ")";
299298
}

app/src/main/java/net/gsantner/opoc/util/GsFileUtils.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -672,16 +672,16 @@ public static String sha256(final File file) {
672672
while ((bytesRead = fis.read(buffer)) != -1) {
673673
digest.update(buffer, 0, bytesRead);
674674
}
675-
675+
676676
byte[] hashBytes = digest.digest();
677677
StringBuilder hexString = new StringBuilder();
678-
678+
679679
for (byte b : hashBytes) {
680680
hexString.append(String.format("%02x", b));
681681
}
682-
682+
683683
return hexString.toString();
684-
684+
685685
} catch (IOException | NoSuchAlgorithmException e) {
686686
e.printStackTrace();
687687
return null;
@@ -740,6 +740,7 @@ public static String getFilenameExtension(final File file) {
740740
}
741741

742742
/// Get the file extension of the file, with dot
743+
///
743744
/// @return "" -> "", "index" -> "", "index.html" -> ".html", "my.website.html" -> ".html"
744745
public static String getFilenameExtension(String name) {
745746
name = name.replace(".jenc", "");

0 commit comments

Comments
 (0)