From e4059efaeae3b11c298d5def879e08c819dbf581 Mon Sep 17 00:00:00 2001 From: stefan-niedermann Date: Thu, 23 Jan 2020 11:10:26 +0100 Subject: [PATCH] #550 In-note-search doesn't jump to occurrence of searchstring - Jump to last occurrence when previously selected occurrence was the first one - Hide search fabs, if only one occurrecen --- .../android/fragment/BaseNoteFragment.java | 92 +++++++++++++------ 1 file changed, 66 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/BaseNoteFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/BaseNoteFragment.java index e67675fa..bfcab052 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/BaseNoteFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/android/fragment/BaseNoteFragment.java @@ -190,7 +190,8 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo } } - private int occurrence = 1; + private int currentOccurrence = 1; + private int occurrenceCount = 0; @Override public void onPrepareOptionsMenu(@NonNull Menu menu) { @@ -215,9 +216,6 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo final LinearLayout searchEditFrame = searchView.findViewById(R.id .search_edit_frame); - FloatingActionButton next = getSearchNextButton(); - FloatingActionButton prev = getSearchPrevButton(); - searchEditFrame.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { int oldVisibility = -1; @@ -229,19 +227,9 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo if (currentVisibility != View.VISIBLE) { colorWithText(""); searchQuery = ""; - if (prev != null) { - prev.hide(); - } - if (next != null) { - next.hide(); - } + hideSearchFabs(); } else { - if (prev != null) { - prev.show(); - } - if (next != null) { - next.show(); - } + showSearchFabs(); } oldVisibility = currentVisibility; @@ -249,16 +237,20 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo } }); + + FloatingActionButton next = getSearchNextButton(); + FloatingActionButton prev = getSearchPrevButton(); + if (next != null) { next.setOnClickListener(v -> { - occurrence++; + currentOccurrence++; jumpToOccurrence(); }); } if (prev != null) { prev.setOnClickListener(v -> { - occurrence--; + currentOccurrence--; jumpToOccurrence(); }); } @@ -266,7 +258,7 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { - occurrence++; + currentOccurrence++; jumpToOccurrence(); return true; } @@ -275,30 +267,59 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo public boolean onQueryTextChange(String newText) { searchQuery = newText; colorWithText(newText); - occurrence = 1; + occurrenceCount = countOccurrences(getContent(), searchQuery); + if(occurrenceCount > 1) { + showSearchFabs(); + } else { + hideSearchFabs(); + } + currentOccurrence = 1; jumpToOccurrence(); return true; } }); } + private void hideSearchFabs() { + FloatingActionButton next = getSearchNextButton(); + FloatingActionButton prev = getSearchPrevButton(); + if (prev != null) { + prev.hide(); + } + if (next != null) { + next.hide(); + } + } + + private void showSearchFabs() { + FloatingActionButton next = getSearchNextButton(); + FloatingActionButton prev = getSearchPrevButton(); + if (prev != null) { + prev.show(); + } + if (next != null) { + next.show(); + } + } + private void jumpToOccurrence() { if (searchQuery == null || searchQuery.isEmpty()) { // No search term return; } - if (occurrence < 1) { - // TODO find last occurrence - occurrence = 1; + if (currentOccurrence < 1) { + // if currentOccurrence is lower than 1, jump to last occurrence + currentOccurrence = occurrenceCount; + jumpToOccurrence(); return; } String currentContent = getContent().toLowerCase(); - int indexOfNewText = indexOfNth(currentContent, searchQuery.toLowerCase(), 0, occurrence); + int indexOfNewText = indexOfNth(currentContent, searchQuery.toLowerCase(), 0, currentOccurrence); if (indexOfNewText <= 0) { // Search term is not n times in text // Go back to first search result - if (occurrence != 1) { - occurrence = 1; + if (currentOccurrence != 1) { + currentOccurrence = 1; jumpToOccurrence(); } return; @@ -322,6 +343,25 @@ public abstract class BaseNoteFragment extends Fragment implements CategoryDialo return indexOfNth(input, value, idx + 1, --nth); } + private static int countOccurrences(String haystack, String needle) { + if(haystack == null || haystack.isEmpty() || needle == null || needle.isEmpty()) { + return 0; + } + haystack = haystack.toLowerCase(); + needle = needle.toLowerCase(); + int lastIndex = 0; + int count = 0; + + while (lastIndex != -1) { + lastIndex = haystack.indexOf(needle, lastIndex); + if (lastIndex != -1) { + count++; + lastIndex += needle.length(); + } + } + return count; + } + protected abstract ScrollView getScrollView(); protected abstract Layout getLayout();