summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXimeng Zu <uznomis@yahoo.com>2017-04-05 23:37:12 -0500
committerTomaž Vajngerl <quikee@gmail.com>2017-04-18 14:10:33 +0200
commit78bc5053a15ef218cce394b0d0e012f1700f760a (patch)
treeba0047750f6f12ae8f6fb425e2b25f3ee5b4320a
parent5333f93a6fd191e424327afe3935f2770a71f620 (diff)
tdf#96764 - Android Viewer does not show page count
Added page number display in text documents. The page nunmber calculation in handled on Java side and the work only involves calls to LOKit when necessary. Majority of the work is done in DocumentOverlayView. java, including calculation and displaying. The page number information is updated whenever a page number change callback is caught (from LOkit). Change-Id: I52014806cd647fa805b329825ac29b0e337c11a1 Reviewed-on: https://gerrit.libreoffice.org/36178 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
-rw-r--r--android/source/src/java/org/libreoffice/InvalidationHandler.java15
-rw-r--r--android/source/src/java/org/libreoffice/LOEvent.java1
-rw-r--r--android/source/src/java/org/libreoffice/LOKitThread.java14
-rw-r--r--android/source/src/java/org/libreoffice/LOKitTileProvider.java7
-rw-r--r--android/source/src/java/org/libreoffice/canvas/PageNumberRect.java64
-rw-r--r--android/source/src/java/org/libreoffice/overlay/DocumentOverlay.java28
-rw-r--r--android/source/src/java/org/libreoffice/overlay/DocumentOverlayView.java61
-rw-r--r--android/source/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java10
8 files changed, 198 insertions, 2 deletions
diff --git a/android/source/src/java/org/libreoffice/InvalidationHandler.java b/android/source/src/java/org/libreoffice/InvalidationHandler.java
index c8d3a5123c11..af42cb131ff7 100644
--- a/android/source/src/java/org/libreoffice/InvalidationHandler.java
+++ b/android/source/src/java/org/libreoffice/InvalidationHandler.java
@@ -29,6 +29,8 @@ public class InvalidationHandler implements Document.MessageCallback {
private boolean mKeyEvent = false;
private LibreOfficeMainActivity mContext;
+ private int currentTotalPageNumber = 0; // total page number of the current document
+
public InvalidationHandler(LibreOfficeMainActivity context) {
mContext = context;
mDocumentOverlay = mContext.getDocumentOverlay();
@@ -196,6 +198,15 @@ public class InvalidationHandler implements Document.MessageCallback {
mContext.getFormattingController().onToggleStateChanged(Document.BULLET_LIST, pressed);
} else if (parts[0].equals(".uno:DefaultNumbering")) {
mContext.getFormattingController().onToggleStateChanged(Document.NUMBERED_LIST, pressed);
+ } else if (parts[0].equals(".uno:StatePageNumber")) {
+ // get the total page number and compare to the current value and update accordingly
+ String[] splitStrings = parts[1].split(" ");
+ int totalPageNumber = Integer.valueOf(splitStrings[splitStrings.length - 1]);
+ if (totalPageNumber != currentTotalPageNumber) {
+ currentTotalPageNumber = totalPageNumber;
+ // update part page rectangles stored in DocumentOverlayView object
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UPDATE_PART_PAGE_RECT));
+ }
} else {
Log.d(LOGTAG, "LOK_CALLBACK_STATE_CHANGED type uncatched: " + payload);
}
@@ -207,7 +218,7 @@ public class InvalidationHandler implements Document.MessageCallback {
* @param payload - invalidation message payload text
* @return rectangle in pixel coordinates
*/
- private RectF convertPayloadToRectangle(String payload) {
+ public RectF convertPayloadToRectangle(String payload) {
String payloadWithoutWhitespace = payload.replaceAll("\\s", ""); // remove all whitespace from the string
if (payloadWithoutWhitespace.isEmpty() || payloadWithoutWhitespace.equals("EMPTY")) {
@@ -241,7 +252,7 @@ public class InvalidationHandler implements Document.MessageCallback {
* @param payload - invalidation message payload text
* @return list of rectangles
*/
- private List<RectF> convertPayloadToRectangles(String payload) {
+ public List<RectF> convertPayloadToRectangles(String payload) {
List<RectF> rectangles = new ArrayList<RectF>();
String[] rectangleArray = payload.split(";");
diff --git a/android/source/src/java/org/libreoffice/LOEvent.java b/android/source/src/java/org/libreoffice/LOEvent.java
index 3e058c8c035e..f5579aea087a 100644
--- a/android/source/src/java/org/libreoffice/LOEvent.java
+++ b/android/source/src/java/org/libreoffice/LOEvent.java
@@ -36,6 +36,7 @@ public class LOEvent implements Comparable<LOEvent> {
public static final int RESUME = 15;
public static final int LOAD_NEW = 16;
public static final int SAVE_AS = 17;
+ public static final int UPDATE_PART_PAGE_RECT= 18;
public final int mType;
public int mPriority = 0;
diff --git a/android/source/src/java/org/libreoffice/LOKitThread.java b/android/source/src/java/org/libreoffice/LOKitThread.java
index 4dd403dd2d0c..52a7c6c2f43a 100644
--- a/android/source/src/java/org/libreoffice/LOKitThread.java
+++ b/android/source/src/java/org/libreoffice/LOKitThread.java
@@ -155,6 +155,17 @@ class LOKitThread extends Thread {
private void refresh() {
mLayerClient.clearAndResetlayers();
redraw();
+ updatePartPageRectangles();
+ }
+
+ /**
+ * Update part page rectangles which hold positions of each document page.
+ * Result is stored in DocumentOverlayView class.
+ */
+ private void updatePartPageRectangles() {
+ String partPageRectString = ((LOKitTileProvider) mTileProvider).getPartPageRectangles();
+ List<RectF> partPageRectangles = mInvalidationHandler.convertPayloadToRectangles(partPageRectString);
+ mContext.getDocumentOverlay().setPartPageRectangles(partPageRectangles);
}
@@ -319,6 +330,9 @@ class LOKitThread extends Thread {
case LOEvent.UNO_COMMAND:
mTileProvider.postUnoCommand(event.mString, event.mValue);
break;
+ case LOEvent.UPDATE_PART_PAGE_RECT:
+ updatePartPageRectangles();
+ break;
}
}
diff --git a/android/source/src/java/org/libreoffice/LOKitTileProvider.java b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
index 6ed73ee32805..1996a1b5bedd 100644
--- a/android/source/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
@@ -200,6 +200,13 @@ class LOKitTileProvider implements TileProvider {
}
/**
+ * Wrapper for getPartPageRectangles() JNI function.
+ */
+ public String getPartPageRectangles() {
+ return mDocument.getPartPageRectangles();
+ }
+
+ /**
* @see TileProvider#onSwipeLeft()
*/
@Override
diff --git a/android/source/src/java/org/libreoffice/canvas/PageNumberRect.java b/android/source/src/java/org/libreoffice/canvas/PageNumberRect.java
new file mode 100644
index 000000000000..62de88ea5441
--- /dev/null
+++ b/android/source/src/java/org/libreoffice/canvas/PageNumberRect.java
@@ -0,0 +1,64 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+package org.libreoffice.canvas;
+
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.text.TextPaint;
+
+/*
+ * A canvas element on DocumentOverlayView. Shows a rectangle with current page
+ * number and total page number inside of it.
+ */
+public class PageNumberRect extends CommonCanvasElement {
+ private String mPageNumberString;
+ private TextPaint mPageNumberRectPaint = new TextPaint();
+ private Paint mBgPaint = new Paint();
+ private Rect mTextBounds = new Rect();
+ private float mBgMargin = 5f;
+
+ public PageNumberRect() {
+ mBgPaint.setColor(Color.BLACK);
+ mBgPaint.setAlpha(100);
+ mPageNumberRectPaint.setColor(Color.WHITE);
+ }
+
+ /**
+ * Implement hit test here
+ *
+ * @param x - x coordinate of the
+ * @param y - y coordinate of the
+ */
+ @Override
+ public boolean onHitTest(float x, float y) {
+ return false;
+ }
+
+ /**
+ * Called inside draw if the element is visible. Override this method to
+ * draw the element on the canvas.
+ *
+ * @param canvas - the canvas
+ */
+ @Override
+ public void onDraw(Canvas canvas) {
+ canvas.drawRect(canvas.getWidth()*0.1f - mBgMargin,
+ canvas.getHeight()*0.1f - mTextBounds.height() - mBgMargin,
+ mTextBounds.width() + canvas.getWidth()*0.1f + mBgMargin,
+ canvas.getHeight()*0.1f + mBgMargin,
+ mBgPaint);
+ canvas.drawText(mPageNumberString, canvas.getWidth()*0.1f, canvas.getHeight()*0.1f, mPageNumberRectPaint);
+ }
+
+ public void setPageNumberString (String pageNumberString) {
+ mPageNumberString = pageNumberString;
+ mPageNumberRectPaint.getTextBounds(mPageNumberString, 0, mPageNumberString.length(), mTextBounds);
+ }
+}
diff --git a/android/source/src/java/org/libreoffice/overlay/DocumentOverlay.java b/android/source/src/java/org/libreoffice/overlay/DocumentOverlay.java
index 8d90ef09fa4a..d9d2b372b714 100644
--- a/android/source/src/java/org/libreoffice/overlay/DocumentOverlay.java
+++ b/android/source/src/java/org/libreoffice/overlay/DocumentOverlay.java
@@ -32,6 +32,8 @@ public class DocumentOverlay {
private final DocumentOverlayView mDocumentOverlayView;
private final DocumentOverlayLayer mDocumentOverlayLayer;
+ private final long hidePageNumberRectDelayInMilliseconds = 500;
+
/**
* DocumentOverlayLayer responsibility is to get the changes to the viewport
* and report them to DocumentOverlayView.
@@ -74,6 +76,10 @@ public class DocumentOverlay {
mDocumentOverlayView.initialize(layerView);
}
+ public void setPartPageRectangles(List<RectF> rectangles) {
+ mDocumentOverlayView.setPartPageRectangles(rectangles);
+ }
+
/**
* Show the cursor at the defined cursor position on the overlay.
*/
@@ -97,6 +103,28 @@ public class DocumentOverlay {
}
/**
+ * Show the page number rectangle on the overlay.
+ */
+ public void showPageNumberRect() {
+ LOKitShell.getMainHandler().post(new Runnable() {
+ public void run() {
+ mDocumentOverlayView.showPageNumberRect();
+ }
+ });
+ }
+
+ /**
+ * Hide the page number rectangle on the overlay.
+ */
+ public void hidePageNumberRect() {
+ LOKitShell.getMainHandler().postDelayed(new Runnable() {
+ public void run() {
+ mDocumentOverlayView.hidePageNumberRect();
+ }
+ }, hidePageNumberRectDelayInMilliseconds);
+ }
+
+ /**
* Position the cursor to the input position on the overlay.
*/
public void positionCursor(final RectF position) {
diff --git a/android/source/src/java/org/libreoffice/overlay/DocumentOverlayView.java b/android/source/src/java/org/libreoffice/overlay/DocumentOverlayView.java
index 48b98b4e7ca5..6afd71309d1d 100644
--- a/android/source/src/java/org/libreoffice/overlay/DocumentOverlayView.java
+++ b/android/source/src/java/org/libreoffice/overlay/DocumentOverlayView.java
@@ -21,6 +21,7 @@ import android.view.View;
import org.libreoffice.LibreOfficeMainActivity;
import org.libreoffice.canvas.Cursor;
import org.libreoffice.canvas.GraphicSelection;
+import org.libreoffice.canvas.PageNumberRect;
import org.libreoffice.canvas.SelectionHandle;
import org.libreoffice.canvas.SelectionHandleEnd;
import org.libreoffice.canvas.SelectionHandleMiddle;
@@ -62,6 +63,11 @@ public class DocumentOverlayView extends View implements View.OnTouchListener {
private SelectionHandle mDragHandle = null;
+ private List<RectF> mPartPageRectangles;
+ private PageNumberRect mPageNumberRect;
+ private boolean mPageNumberAvailable = false;
+ private int previousIndex = 0; // previous page number, used to compare with the current
+
public DocumentOverlayView(Context context) {
super(context);
}
@@ -177,6 +183,16 @@ public class DocumentOverlayView extends View implements View.OnTouchListener {
}
/**
+ * Set part page rectangles and initialize a page number rectangle object
+ * (canvas element).
+ */
+ public void setPartPageRectangles (List<RectF> rectangles) {
+ mPartPageRectangles = rectangles;
+ mPageNumberRect = new PageNumberRect();
+ mPageNumberAvailable = true;
+ }
+
+ /**
* Drawing on canvas.
*/
@Override
@@ -185,6 +201,10 @@ public class DocumentOverlayView extends View implements View.OnTouchListener {
mCursor.draw(canvas);
+ if (mPageNumberAvailable) {
+ mPageNumberRect.draw(canvas);
+ }
+
mHandleMiddle.draw(canvas);
mHandleStart.draw(canvas);
mHandleEnd.draw(canvas);
@@ -233,6 +253,47 @@ public class DocumentOverlayView extends View implements View.OnTouchListener {
}
/**
+ * Calculate and show page number according to current viewport position.
+ * In particular, this function compares the middle point of the
+ * view port with page rectangles and finds out which page the user
+ * is currently on. It does not update the associated canvas element
+ * unless there is a change of page number.
+ */
+ public void showPageNumberRect() {
+ PointF midPoint = mLayerView.getLayerClient().convertViewPointToLayerPoint(new PointF(getWidth()/2f, getHeight()/2f));
+ int index = previousIndex;
+ // search which page the user in currently on. can enhance the search algorithm to binary search if necessary
+ for (RectF page : mPartPageRectangles) {
+ if (page.top < midPoint.y && midPoint.y < page.bottom) {
+ index = mPartPageRectangles.indexOf(page) + 1;
+ break;
+ }
+ }
+ // index == 0 applies to non-text document, i.e. don't show page info on non-text docs
+ if (index == 0) {
+ return;
+ }
+ // if page rectangle canvas element is not visible or the page number is changed, show
+ if (!mPageNumberRect.isVisible() || index != previousIndex) {
+ previousIndex = index;
+ String pageNumberString = "Page " + index + " of " + mPartPageRectangles.size();
+ mPageNumberRect.setPageNumberString(pageNumberString);
+ mPageNumberRect.setVisible(true);
+ invalidate();
+ }
+ }
+
+ /**
+ * Hide page number rectangle canvas element.
+ */
+ public void hidePageNumberRect() {
+ if (mPageNumberRect.isVisible()) {
+ mPageNumberRect.setVisible(false);
+ invalidate();
+ }
+ }
+
+ /**
* Show text selection rectangles.
*/
public void showSelections() {
diff --git a/android/source/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java b/android/source/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java
index 7d7474eae0b4..ce6f4e9b99f7 100644
--- a/android/source/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java
+++ b/android/source/src/java/org/mozilla/gecko/gfx/JavaPanZoomController.java
@@ -498,6 +498,7 @@ class JavaPanZoomController
ImmutableViewportMetrics bounceStartMetrics = getMetrics();
if (bounceStartMetrics.fuzzyEquals(metrics)) {
setState(PanZoomState.NOTHING);
+ finishAnimation();
return;
}
@@ -689,6 +690,7 @@ class JavaPanZoomController
*/
float threshold = (overscrolled && !mSubscroller.scrolling() ? STOPPED_THRESHOLD : FLING_STOPPED_THRESHOLD);
if (getVelocity() >= threshold) {
+ mContext.getDocumentOverlay().showPageNumberRect();
// we're still flinging
return;
}
@@ -712,6 +714,8 @@ class JavaPanZoomController
stopAnimationTimer();
+ mContext.getDocumentOverlay().hidePageNumberRect();
+
// Force a viewport synchronisation
mTarget.forceRedraw();
}
@@ -950,6 +954,12 @@ class JavaPanZoomController
}
@Override
+ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
+ mContext.getDocumentOverlay().showPageNumberRect();
+ return super.onScroll(e1, e2, distanceX, distanceY);
+ }
+
+ @Override
public boolean onSingleTapUp(MotionEvent motionEvent) {
// When double-tapping is allowed, we have to wait to see if this is
// going to be a double-tap.