summaryrefslogtreecommitdiff
path: root/android
diff options
context:
space:
mode:
authorXimeng Zu <uznomis@yahoo.com>2017-03-29 15:43:15 -0500
committerTomaž Vajngerl <quikee@gmail.com>2017-04-18 13:31:38 +0200
commit5333f93a6fd191e424327afe3935f2770a71f620 (patch)
tree27ce4db30bc7b76dedf357435b47ef5aceeed9dc /android
parentbb9ac80998c1e7cd1ff154903b3c60d3e8636a5e (diff)
tdf#96811 Android Viewer doesn't focus on the word you search.
Added the function of focusing on the word you search. Two methods were added. The first one is searchResultSelection, which parses a JSONObject passed from LOK and focuses on the text selection. The second one is moveViewportToMakeSelectionVisible. It handles well both documents and spreadsheets. I also tried to add a search not found toast message. Also corrected a typo. Change-Id: I4453c01afc520bf4deae4c2bd71adea2fe856d7e Reviewed-on: https://gerrit.libreoffice.org/35715 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'android')
-rw-r--r--android/source/res/values/strings.xml1
-rw-r--r--android/source/src/java/org/libreoffice/InvalidationHandler.java81
2 files changed, 81 insertions, 1 deletions
diff --git a/android/source/res/values/strings.xml b/android/source/res/values/strings.xml
index ce3754ee3d15..a554c84b4aef 100644
--- a/android/source/res/values/strings.xml
+++ b/android/source/res/values/strings.xml
@@ -25,6 +25,7 @@
<string name="list_view">List</string>
<string name="grid_view">Grid</string>
<string name="filter">Filter by</string>
+ <string name="search_not_found">Keyword not found</string>
<string name="sort">Sort by</string>
<string name="sort_smallest">Smallest first</string>
<string name="sort_largest">Largest first</string>
diff --git a/android/source/src/java/org/libreoffice/InvalidationHandler.java b/android/source/src/java/org/libreoffice/InvalidationHandler.java
index c4316c50a119..c8d3a5123c11 100644
--- a/android/source/src/java/org/libreoffice/InvalidationHandler.java
+++ b/android/source/src/java/org/libreoffice/InvalidationHandler.java
@@ -6,6 +6,9 @@ import android.graphics.RectF;
import android.net.Uri;
import android.util.Log;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
import org.libreoffice.canvas.SelectionHandle;
import org.libreoffice.kit.Document;
import org.libreoffice.overlay.DocumentOverlay;
@@ -79,9 +82,85 @@ public class InvalidationHandler implements Document.MessageCallback {
case Document.CALLBACK_STATE_CHANGED:
stateChanged(payload);
break;
+ case Document.CALLBACK_SEARCH_RESULT_SELECTION:
+ searchResultSelection(payload);
+ break;
+ case Document.CALLBACK_SEARCH_NOT_FOUND:
+ Log.d(LOGTAG, "LOK_CALLBACK: Search not found.");
+ // this callback is never caught. Hope someone fix this.
+ break;
default:
- Log.d(LOGTAG, "LOK_CALLBACK uncatched: " + messageID + " : " + payload);
+ Log.d(LOGTAG, "LOK_CALLBACK uncaught: " + messageID + " : " + payload);
+ }
+ }
+
+ /**
+ * Handles the search result selection message, which is a JSONObject
+ *
+ * @param payload
+ */
+ private void searchResultSelection(String payload) {
+ RectF selectionRectangle = null;
+ try {
+ JSONObject collectiveResult = new JSONObject(payload);
+ JSONArray searchResult = collectiveResult.getJSONArray("searchResultSelection");
+ if (searchResult.length() == 1) {
+ String rectangle = searchResult.getJSONObject(0).getString("rectangles");
+ selectionRectangle = convertPayloadToRectangle(rectangle);
+ }
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ if (selectionRectangle != null) {
+ moveViewportToMakeSelectionVisible(selectionRectangle);
+ }
+ }
+
+ /**
+ * Move the viewport to show the selection. The selection will appear at the
+ * viewport position depending on where the selection is relative to the
+ * viewport (either selection is above, below, on left or right). The difference
+ * between this method and moveViewportToMakeCursorVisible() is that this method
+ * takes into account the width and height of the selection and zooms out
+ * accordingly.
+ *
+ * @param selectionRectangle - selection position on the document
+ */
+ public void moveViewportToMakeSelectionVisible(RectF selectionRectangle) {
+ RectF moveToRect = mLayerClient.getViewportMetrics().getCssViewport();
+ if (moveToRect.contains(selectionRectangle)) {
+ return;
}
+
+ float newLeft = moveToRect.left;
+ float newTop = moveToRect.top;
+
+ // if selection rectangle is wider or taller than current viewport, we need to zoom out
+ float oldZoom = mLayerClient.getViewportMetrics().getZoomFactor();
+ float widthRatio = 1f;
+ float heightRatio = 1f;
+ if (moveToRect.width() < selectionRectangle.width()) {
+ widthRatio = selectionRectangle.width() / moveToRect.width() / 0.85f; // 0.85f gives some margin (must < 0.9)
+ }
+ if (moveToRect.height() < selectionRectangle.height()) {
+ heightRatio = selectionRectangle.height() / moveToRect.height() / 0.45f; // 0.45f gives some margin (must < 0.5)
+ }
+ float newZoom = widthRatio > heightRatio ? oldZoom/widthRatio : oldZoom/heightRatio;
+
+ // if selection is out of viewport we need to adjust accordingly
+ if (selectionRectangle.right < moveToRect.left || selectionRectangle.left < moveToRect.left) {
+ newLeft = selectionRectangle.left - (moveToRect.width() * 0.1f) * oldZoom / newZoom; // 0.1f gives left margin
+ } else if (selectionRectangle.right > moveToRect.right || selectionRectangle.left > moveToRect.right) {
+ newLeft = selectionRectangle.right - (moveToRect.width() * 0.9f) * oldZoom / newZoom; // 0.9f gives right margin
+ }
+
+ if (selectionRectangle.top < moveToRect.top || selectionRectangle.bottom < moveToRect.top) {
+ newTop = selectionRectangle.top - (moveToRect.height() * 0.1f) * oldZoom / newZoom; // 0.1f gives top margin
+ } else if (selectionRectangle.bottom > moveToRect.bottom || selectionRectangle.top > moveToRect.bottom){
+ newTop = selectionRectangle.bottom - (moveToRect.height() * 0.5f) * oldZoom / newZoom; // 0.5 f gives bottom margin
+ }
+
+ LOKitShell.moveViewportTo(mContext, new PointF(newLeft, newTop), newZoom);
}
private void stateChanged(String payload) {