summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXimeng Zu <uznomis@yahoo.com>2017-06-18 16:37:13 -0500
committerTomaž Vajngerl <quikee@gmail.com>2017-07-31 23:15:48 +0200
commitb9471511523d5c80b80a5e99d149af65e9915840 (patch)
tree4c8fb05425bd6dba1b278e04e10efd5c91db3e76
parent90ac4671c13ed4f548bb4188355b02217b9e24ba (diff)
[Android Viewer] Add cell selection by row/column/all
Added cell selection to Calc docs in Android Viewer with a similar behavior to LOOL wrt. row/column selection. The user can tap on any header to select whole row/column or select all by tapping the top left corner of the header. Change-Id: I34bdbb1aacc5fc0ed9175908936a8a5e6eec4ff4 Reviewed-on: https://gerrit.libreoffice.org/39694 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
-rw-r--r--android/source/src/java/org/libreoffice/InvalidationHandler.java14
-rw-r--r--android/source/src/java/org/libreoffice/LOKitShell.java1
-rw-r--r--android/source/src/java/org/libreoffice/LOKitThread.java2
-rw-r--r--android/source/src/java/org/libreoffice/LOKitTileProvider.java6
-rwxr-xr-xandroid/source/src/java/org/libreoffice/LibreOfficeMainActivity.java9
-rw-r--r--android/source/src/java/org/libreoffice/canvas/CalcHeaderCell.java10
-rw-r--r--android/source/src/java/org/libreoffice/canvas/CalcSelectionBox.java111
-rw-r--r--android/source/src/java/org/libreoffice/overlay/CalcHeadersController.java30
-rw-r--r--android/source/src/java/org/libreoffice/overlay/CalcHeadersView.java101
-rw-r--r--android/source/src/java/org/libreoffice/overlay/DocumentOverlay.java16
-rw-r--r--android/source/src/java/org/libreoffice/overlay/DocumentOverlayView.java51
11 files changed, 337 insertions, 14 deletions
diff --git a/android/source/src/java/org/libreoffice/InvalidationHandler.java b/android/source/src/java/org/libreoffice/InvalidationHandler.java
index 5edc6c7dcb19..e5fdf05b120f 100644
--- a/android/source/src/java/org/libreoffice/InvalidationHandler.java
+++ b/android/source/src/java/org/libreoffice/InvalidationHandler.java
@@ -91,11 +91,22 @@ public class InvalidationHandler implements Document.MessageCallback {
Log.d(LOGTAG, "LOK_CALLBACK: Search not found.");
// this callback is never caught. Hope someone fix this.
break;
+ case Document.CALLBACK_CELL_CURSOR:
+ invalidateCellCursor(payload);
+ break;
default:
Log.d(LOGTAG, "LOK_CALLBACK uncaught: " + messageID + " : " + payload);
}
}
+ private void invalidateCellCursor(String payload) {
+ RectF cellCursorRect = convertPayloadToRectangle(payload);
+
+ if (cellCursorRect != null) {
+ mDocumentOverlay.showCellSelection(cellCursorRect);
+ }
+ }
+
/**
* Handles the search result selection message, which is a JSONObject
*
@@ -374,6 +385,9 @@ public class InvalidationHandler implements Document.MessageCallback {
}
changeStateTo(OverlayState.SELECTION);
mDocumentOverlay.changeSelections(rectangles);
+ if (mContext.isSpreadsheet()) {
+ mDocumentOverlay.showHeaderSelection(rectangles.get(0));
+ }
}
}
diff --git a/android/source/src/java/org/libreoffice/LOKitShell.java b/android/source/src/java/org/libreoffice/LOKitShell.java
index 7b7525722250..c69e02669619 100644
--- a/android/source/src/java/org/libreoffice/LOKitShell.java
+++ b/android/source/src/java/org/libreoffice/LOKitShell.java
@@ -27,6 +27,7 @@ public class LOKitShell {
private static final String LOGTAG = LOKitShell.class.getSimpleName();
public static float getDpi(Context context) {
+ if (((LibreOfficeMainActivity)context).isSpreadsheet()) return 96f;
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return metrics.density * 160;
}
diff --git a/android/source/src/java/org/libreoffice/LOKitThread.java b/android/source/src/java/org/libreoffice/LOKitThread.java
index 9ab54c20a1f8..50836ce5b65a 100644
--- a/android/source/src/java/org/libreoffice/LOKitThread.java
+++ b/android/source/src/java/org/libreoffice/LOKitThread.java
@@ -211,7 +211,7 @@ class LOKitThread extends Thread {
LOKitShell.showProgressSpinner(mContext);
mTileProvider.changePart(partIndex);
mViewportMetrics = mLayerClient.getViewportMetrics();
- mLayerClient.setViewportMetrics(mViewportMetrics.scaleTo(0.9f, new PointF()));
+ // mLayerClient.setViewportMetrics(mViewportMetrics.scaleTo(0.9f, new PointF()));
refresh();
LOKitShell.hideProgressSpinner(mContext);
}
diff --git a/android/source/src/java/org/libreoffice/LOKitTileProvider.java b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
index 3278265dfa3f..ba49cfaf26ee 100644
--- a/android/source/src/java/org/libreoffice/LOKitTileProvider.java
+++ b/android/source/src/java/org/libreoffice/LOKitTileProvider.java
@@ -28,7 +28,6 @@ import java.nio.ByteBuffer;
*/
class LOKitTileProvider implements TileProvider {
private static final String LOGTAG = LOKitTileProvider.class.getSimpleName();
- private static final float DPI_1X_ZOOM = 96f; // for use in Calc at fixed zoom 1x
private static int TILE_SIZE = 256;
private final float mTileWidth;
private final float mTileHeight;
@@ -79,11 +78,10 @@ class LOKitTileProvider implements TileProvider {
Log.i(LOGTAG, "====> mDocument = " + mDocument);
if(isSpreadsheet()) {
- mDPI = DPI_1X_ZOOM; // Calc has a fixed zoom at 1x
- } else {
- mDPI = LOKitShell.getDpi(mContext);
+ mContext.setIsSpreadsheet(true); // Calc is treated differently e.g. DPI = 96f
}
+ mDPI = LOKitShell.getDpi(mContext);
mTileWidth = pixelToTwip(TILE_SIZE, mDPI);
mTileHeight = pixelToTwip(TILE_SIZE, mDPI);
diff --git a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
index 8354dca63aa3..b16812f0bc97 100755
--- a/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
+++ b/android/source/src/java/org/libreoffice/LibreOfficeMainActivity.java
@@ -93,6 +93,7 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
private FontController mFontController;
private SearchController mSearchController;
private CalcHeadersController mCalcHeadersController;
+ private boolean mIsSpreadsheet;
public GeckoLayerClient getLayerClient() {
return mLayerClient;
@@ -703,6 +704,14 @@ public class LibreOfficeMainActivity extends AppCompatActivity implements Settin
});
}
+ public void setIsSpreadsheet(boolean b) {
+ mIsSpreadsheet = b;
+ }
+
+ public boolean isSpreadsheet() {
+ return mIsSpreadsheet;
+ }
+
private class DocumentPartClickListener implements android.widget.AdapterView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
diff --git a/android/source/src/java/org/libreoffice/canvas/CalcHeaderCell.java b/android/source/src/java/org/libreoffice/canvas/CalcHeaderCell.java
index dc46f047c10c..c1f8e74e7ba2 100644
--- a/android/source/src/java/org/libreoffice/canvas/CalcHeaderCell.java
+++ b/android/source/src/java/org/libreoffice/canvas/CalcHeaderCell.java
@@ -13,9 +13,15 @@ public class CalcHeaderCell extends CommonCanvasElement {
private RectF mBounds;
private String mText;
- public CalcHeaderCell(float left, float top, float width, float height, String text) {
+ public CalcHeaderCell(float left, float top, float width, float height, String text, boolean selected) {
mBounds = new RectF(left, top, left + width, top + height);
- mBgPaint.setStyle(Style.STROKE);
+ if (selected) {
+ // if the cell is selected, display filled
+ mBgPaint.setStyle(Style.FILL_AND_STROKE);
+ } else {
+ // if not, display only the frame
+ mBgPaint.setStyle(Style.STROKE);
+ }
mBgPaint.setColor(Color.GRAY);
mBgPaint.setAlpha(100); // hard coded for now
mTextPaint.setColor(Color.GRAY);
diff --git a/android/source/src/java/org/libreoffice/canvas/CalcSelectionBox.java b/android/source/src/java/org/libreoffice/canvas/CalcSelectionBox.java
new file mode 100644
index 000000000000..af31d708d44e
--- /dev/null
+++ b/android/source/src/java/org/libreoffice/canvas/CalcSelectionBox.java
@@ -0,0 +1,111 @@
+package org.libreoffice.canvas;
+
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PointF;
+import android.graphics.RectF;
+
+import org.libreoffice.LOKitShell;
+import org.libreoffice.LibreOfficeMainActivity;
+import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
+
+/**
+ * CalcSelectionBox is the selection frame for the current highlighted area/cells
+ * in Calc.
+ */
+
+public class CalcSelectionBox extends CommonCanvasElement {
+ private static final long MINIMUM_HANDLE_UPDATE_TIME = 50 * 1000000;
+ private static final float CIRCLE_HANDLE_RADIUS = 8f;
+
+ public RectF mDocumentPosition;
+
+ private LibreOfficeMainActivity mContext;
+ private RectF mScreenPosition;
+ private long mLastTime = 0;
+ private Paint mPaint;
+ private Paint mCirclePaint;
+
+ public CalcSelectionBox(LibreOfficeMainActivity context) {
+ mContext = context;
+ mScreenPosition = new RectF();
+ mDocumentPosition = new RectF();
+ mPaint = new Paint();
+ mPaint.setStyle(Paint.Style.STROKE);
+ mPaint.setColor(Color.BLACK);
+ mPaint.setStrokeWidth(2f);
+ mCirclePaint = new Paint();
+ mCirclePaint.setColor(Color.BLACK);
+ mCirclePaint.setStyle(Paint.Style.FILL);
+ }
+
+ /**
+ * Start of a touch and drag action on the box.
+ */
+ public void dragStart(PointF point) {}
+
+ /**
+ * End of a touch and drag action on the box.
+ */
+ public void dragEnd(PointF point) {}
+
+ /**
+ * Box has been dragged.
+ */
+ public void dragging(PointF point) {
+ long currentTime = System.nanoTime();
+ if (currentTime - mLastTime > MINIMUM_HANDLE_UPDATE_TIME) {
+ mLastTime = currentTime;
+ signalHandleMove(point.x, point.y);
+ }
+ }
+
+ /**
+ * Signal to move the handle to a new position to LO.
+ */
+ private void signalHandleMove(float newX, float newY) {
+ ImmutableViewportMetrics viewportMetrics = mContext.getLayerClient().getViewportMetrics();
+ float zoom = viewportMetrics.zoomFactor;
+ PointF origin = viewportMetrics.getOrigin();
+
+ PointF documentPoint = new PointF((newX+origin.x)/zoom , (newY+origin.y)/zoom);
+
+ if (documentPoint.x < mDocumentPosition.left || documentPoint.y < mDocumentPosition.top) {
+ LOKitShell.sendChangeHandlePositionEvent(SelectionHandle.HandleType.START, documentPoint);
+ } else if (documentPoint.x > mDocumentPosition.right || documentPoint.y > mDocumentPosition.bottom){
+ LOKitShell.sendChangeHandlePositionEvent(SelectionHandle.HandleType.END, documentPoint);
+ }
+ }
+
+ @Override
+ public boolean onHitTest(float x, float y) {
+ return mScreenPosition.contains(x, y);
+ }
+
+ @Override
+ public void onDraw(Canvas canvas) {
+ canvas.drawRect(mScreenPosition, mPaint);
+ canvas.drawCircle(mScreenPosition.left, mScreenPosition.top, CIRCLE_HANDLE_RADIUS, mCirclePaint);
+ canvas.drawCircle(mScreenPosition.right, mScreenPosition.bottom, CIRCLE_HANDLE_RADIUS, mCirclePaint);
+ }
+
+ public void reposition(RectF rect) {
+ mScreenPosition = rect;
+ }
+
+ @Override
+ public boolean contains(float x, float y) {
+ // test if in range of the box or the circular handles
+ boolean inRange = new RectF(mScreenPosition.left - CIRCLE_HANDLE_RADIUS,
+ mScreenPosition.top - CIRCLE_HANDLE_RADIUS,
+ mScreenPosition.left + CIRCLE_HANDLE_RADIUS,
+ mScreenPosition.top + CIRCLE_HANDLE_RADIUS).contains(x, y)
+ || new RectF(mScreenPosition.right - CIRCLE_HANDLE_RADIUS,
+ mScreenPosition.bottom - CIRCLE_HANDLE_RADIUS,
+ mScreenPosition.right + CIRCLE_HANDLE_RADIUS,
+ mScreenPosition.bottom + CIRCLE_HANDLE_RADIUS).contains(x, y)
+ || onHitTest(x, y);
+ return inRange && isVisible();
+ }
+}
diff --git a/android/source/src/java/org/libreoffice/overlay/CalcHeadersController.java b/android/source/src/java/org/libreoffice/overlay/CalcHeadersController.java
index 80cb0e5791d8..ced93381f0ce 100644
--- a/android/source/src/java/org/libreoffice/overlay/CalcHeadersController.java
+++ b/android/source/src/java/org/libreoffice/overlay/CalcHeadersController.java
@@ -1,6 +1,8 @@
package org.libreoffice.overlay;
+import android.graphics.RectF;
import android.util.Log;
+import android.view.View;
import org.json.JSONArray;
import org.json.JSONException;
@@ -15,7 +17,6 @@ import java.util.ArrayList;
public class CalcHeadersController {
private static final String LOGTAG = CalcHeadersController.class.getSimpleName();
- private static final float DPI_1X_ZOOM = 96f; // Calc uses a fixed zoom a 1x which is 96 dpi
private final CalcHeadersView mCalcRowHeadersView;
private final CalcHeadersView mCalcColumnHeadersView;
@@ -34,6 +35,12 @@ public class CalcHeadersController {
mCalcColumnHeadersView.initialize(layerView, false);
}
LOKitShell.sendEvent(new LOEvent(LOEvent.UPDATE_CALC_HEADERS));
+ context.findViewById(R.id.calc_header_top_left).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:SelectAll"));
+ }
+ });
}
public void setHeaders(String headers) {
@@ -64,12 +71,12 @@ public class CalcHeadersController {
JSONArray rowResult = collectiveResult.getJSONArray("rows");
for (int i = 0; i < rowResult.length(); i++) {
headerInfo.rowLabels.add(rowResult.getJSONObject(i).getString("text"));
- headerInfo.rowDimens.add(twipToPixel(rowResult.getJSONObject(i).getLong("size"), DPI_1X_ZOOM));
+ headerInfo.rowDimens.add(twipToPixel(rowResult.getJSONObject(i).getLong("size"), LOKitShell.getDpi(mContext)));
}
JSONArray columnResult = collectiveResult.getJSONArray("columns");
for (int i = 0; i < columnResult.length(); i++) {
headerInfo.columnLabels.add(columnResult.getJSONObject(i).getString("text"));
- headerInfo.columnDimens.add(twipToPixel(columnResult.getJSONObject(i).getLong("size"), DPI_1X_ZOOM));
+ headerInfo.columnDimens.add(twipToPixel(columnResult.getJSONObject(i).getLong("size"), LOKitShell.getDpi(mContext)));
}
return headerInfo;
} catch (JSONException e) {
@@ -82,12 +89,27 @@ public class CalcHeadersController {
return input / 1440.0f * dpi;
}
+ public void showHeaderSelection(RectF cellCursorRect) {
+ mCalcRowHeadersView.setHeaderSelection(cellCursorRect);
+ mCalcColumnHeadersView.setHeaderSelection(cellCursorRect);
+ showHeaders();
+ }
+
+ public void setPendingRowOrColumnSelectionToShowUp(boolean b) {
+ mCalcRowHeadersView.setPendingRowOrColumnSelectionToShowUp(b);
+ mCalcColumnHeadersView.setPendingRowOrColumnSelectionToShowUp(b);
+ }
+
+ public boolean pendingRowOrColumnSelectionToShowUp() {
+ return mCalcColumnHeadersView.pendingRowOrColumnSelectionToShowUp()
+ || mCalcRowHeadersView.pendingRowOrColumnSelectionToShowUp();
+ }
+
private class HeaderInfo {
ArrayList<String> rowLabels;
ArrayList<Float> rowDimens;
ArrayList<String> columnLabels;
ArrayList<Float> columnDimens;
-
private HeaderInfo() {
rowLabels = new ArrayList<String>();
rowDimens = new ArrayList<Float>();
diff --git a/android/source/src/java/org/libreoffice/overlay/CalcHeadersView.java b/android/source/src/java/org/libreoffice/overlay/CalcHeadersView.java
index d15941470bd7..7485b6c0cb6d 100644
--- a/android/source/src/java/org/libreoffice/overlay/CalcHeadersView.java
+++ b/android/source/src/java/org/libreoffice/overlay/CalcHeadersView.java
@@ -3,23 +3,33 @@ package org.libreoffice.overlay;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.PointF;
+import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.libreoffice.LOEvent;
+import org.libreoffice.LOKitShell;
import org.libreoffice.canvas.CalcHeaderCell;
import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
import org.mozilla.gecko.gfx.LayerView;
import java.util.ArrayList;
+import java.util.Collections;
public class CalcHeadersView extends View implements View.OnTouchListener {
+ private static final String LOGTAG = CalcHeadersView.class.getSimpleName();
private boolean mInitialized;
private LayerView mLayerView;
private boolean mIsRow; // true if this is for row headers, false for column
private ArrayList<String> mLabels;
private ArrayList<Float> mDimens;
+ private RectF mCellCursorRect;
+ private PointF pointOfTouch;
+ private boolean mPendingRowOrColumnSelectionToShowUp;
public CalcHeadersView(Context context) {
super(context);
@@ -55,6 +65,8 @@ public class CalcHeadersView extends View implements View.OnTouchListener {
ImmutableViewportMetrics metrics = mLayerView.getViewportMetrics();
float zoom = metrics.getZoomFactor();
PointF origin = metrics.getOrigin();
+
+ // Draw headers
boolean inRangeOfVisibleHeaders = false; // a helper variable for skipping unnecessary onDraw()'s
float top,bottom,left,right;
for (int i = 1; i < mLabels.size(); i++) {
@@ -63,7 +75,12 @@ public class CalcHeadersView extends View implements View.OnTouchListener {
bottom = -origin.y + zoom*mDimens.get(i);
if (top <= getHeight() && bottom >= 0) {
inRangeOfVisibleHeaders = true;
- new CalcHeaderCell(0f, top, getWidth(), bottom - top, mLabels.get(i)).onDraw(canvas);
+ if (mCellCursorRect != null && bottom > mCellCursorRect.top - origin.y && top < mCellCursorRect.bottom - origin.y) {
+ // if cell is within current selected portion
+ new CalcHeaderCell(0f, top, getWidth(), bottom - top, mLabels.get(i), true).onDraw(canvas);
+ } else {
+ new CalcHeaderCell(0f, top, getWidth(), bottom - top, mLabels.get(i), false).onDraw(canvas);
+ }
} else {
if (inRangeOfVisibleHeaders) {
break;
@@ -73,7 +90,12 @@ public class CalcHeadersView extends View implements View.OnTouchListener {
left = -origin.x + zoom*mDimens.get(i-1);
right = -origin.x + zoom*mDimens.get(i);
if (left <= getWidth() && right >= 0) {
- new CalcHeaderCell(left, 0f, right - left, getHeight(), mLabels.get(i)).onDraw(canvas);
+ if (mCellCursorRect != null && right > mCellCursorRect.left - origin.x && left < mCellCursorRect.right - origin.x) {
+ // if cell is within current selected portion
+ new CalcHeaderCell(left, 0f, right - left, getHeight(), mLabels.get(i), true).onDraw(canvas);
+ } else {
+ new CalcHeaderCell(left, 0f, right - left, getHeight(), mLabels.get(i), false).onDraw(canvas);
+ }
} else {
if (inRangeOfVisibleHeaders) {
break;
@@ -83,13 +105,86 @@ public class CalcHeadersView extends View implements View.OnTouchListener {
}
}
+ /**
+ * Handle the triggered touch event.
+ */
@Override
- public boolean onTouch(View v, MotionEvent event) {
+ public boolean onTouch(View view, MotionEvent event) {
+ PointF point = new PointF(event.getX(), event.getY());
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ pointOfTouch = point;
+ return true;
+ case MotionEvent.ACTION_UP:
+ if (pointOfTouch != null) {
+ highlightRowOrColumn();
+ }
+ }
return false;
}
+ /**
+ * Handle a single tap event on a header cell.
+ * Selects whole row/column.
+ */
+ private void highlightRowOrColumn() {
+ int searchedIndex, index;
+ ImmutableViewportMetrics metrics = mLayerView.getViewportMetrics();
+ float zoom = metrics.getZoomFactor();
+ PointF origin = metrics.getOrigin();
+ if (mIsRow) {
+ searchedIndex = Collections.binarySearch(mDimens, (pointOfTouch.y+origin.y)/zoom);
+ } else {
+ searchedIndex = Collections.binarySearch(mDimens, (pointOfTouch.x+origin.x)/zoom);
+ }
+ // converting searched index to real index on headers
+ if (searchedIndex < 0) {
+ index = - searchedIndex - 2;
+ } else {
+ index = searchedIndex;
+ }
+ try {
+ JSONObject rootJson = new JSONObject();
+ addProperty(rootJson, "Modifier", "unsigned short", "0");
+ if (mIsRow) {
+ addProperty(rootJson, "Row", "unsigned short", String.valueOf(index));
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:SelectRow", rootJson.toString()));
+ } else {
+ addProperty(rootJson, "Col", "unsigned short", String.valueOf(index));
+ LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:SelectColumn", rootJson.toString()));
+ }
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ // At this point, InvalidationHandler.java will have received two callbacks.
+ // One is for text selection (first) and the other for cell selection (second).
+ // The second will override the first on headers which is not wanted.
+ // setPendingRowOrColumnSelectionToShowUp(true) will skip the second call.
+ setPendingRowOrColumnSelectionToShowUp(true);
+ pointOfTouch = null;
+ }
+
+ public void setPendingRowOrColumnSelectionToShowUp(boolean b) {
+ mPendingRowOrColumnSelectionToShowUp = b;
+ }
+
+ public boolean pendingRowOrColumnSelectionToShowUp() {
+ return mPendingRowOrColumnSelectionToShowUp;
+ }
+
+ private void addProperty(JSONObject json, String parentValue, String type, String value) throws JSONException {
+ JSONObject child = new JSONObject();
+ child.put("type", type);
+ child.put("value", value);
+ json.put(parentValue, child);
+ }
+
public void setHeaders(ArrayList<String> labels, ArrayList<Float> dimens) {
mLabels = labels;
mDimens = dimens;
}
+
+ public void setHeaderSelection(RectF cellCursorRect) {
+ mCellCursorRect = cellCursorRect;
+ }
}
diff --git a/android/source/src/java/org/libreoffice/overlay/DocumentOverlay.java b/android/source/src/java/org/libreoffice/overlay/DocumentOverlay.java
index 4809921012bc..47669797fb1c 100644
--- a/android/source/src/java/org/libreoffice/overlay/DocumentOverlay.java
+++ b/android/source/src/java/org/libreoffice/overlay/DocumentOverlay.java
@@ -242,6 +242,22 @@ public class DocumentOverlay {
mDocumentOverlayView.setCalcHeadersController(calcHeadersController);
}
+ public void showCellSelection(final RectF cellCursorRect) {
+ LOKitShell.getMainHandler().post(new Runnable() {
+ public void run() {
+ mDocumentOverlayView.showCellSelection(cellCursorRect);
+ }
+ });
+ }
+
+ public void showHeaderSelection(final RectF cellCursorRect) {
+ LOKitShell.getMainHandler().post(new Runnable() {
+ public void run() {
+ mDocumentOverlayView.showHeaderSelection(cellCursorRect);
+ }
+ });
+ }
+
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/android/source/src/java/org/libreoffice/overlay/DocumentOverlayView.java b/android/source/src/java/org/libreoffice/overlay/DocumentOverlayView.java
index 7d5ab1972d39..d5cfcaa3edc3 100644
--- a/android/source/src/java/org/libreoffice/overlay/DocumentOverlayView.java
+++ b/android/source/src/java/org/libreoffice/overlay/DocumentOverlayView.java
@@ -19,6 +19,7 @@ import android.view.MotionEvent;
import android.view.View;
import org.libreoffice.LibreOfficeMainActivity;
+import org.libreoffice.canvas.CalcSelectionBox;
import org.libreoffice.canvas.Cursor;
import org.libreoffice.canvas.GraphicSelection;
import org.libreoffice.canvas.PageNumberRect;
@@ -69,6 +70,9 @@ public class DocumentOverlayView extends View implements View.OnTouchListener {
private int previousIndex = 0; // previous page number, used to compare with the current
private CalcHeadersController mCalcHeadersController;
+ private CalcSelectionBox mCalcSelectionBox;
+ private boolean mCalcSelectionBoxDragging;
+
public DocumentOverlayView(Context context) {
super(context);
}
@@ -168,6 +172,11 @@ public class DocumentOverlayView extends View implements View.OnTouchListener {
mScaledSelections.add(scaledSelection);
}
+ if (mCalcSelectionBox != null) {
+ rect = convertToScreen(mCalcSelectionBox.mDocumentPosition, x, y, zoom);
+ mCalcSelectionBox.reposition(rect);
+ }
+
RectF scaledGraphicSelection = convertToScreen(mGraphicSelection.mRectangle, x, y, zoom);
mGraphicSelection.reposition(scaledGraphicSelection);
invalidate();
@@ -216,6 +225,10 @@ public class DocumentOverlayView extends View implements View.OnTouchListener {
}
}
+ if (mCalcSelectionBox != null) {
+ mCalcSelectionBox.draw(canvas);
+ }
+
mGraphicSelection.draw(canvas);
if (mCalcHeadersController != null) {
@@ -368,6 +381,12 @@ public class DocumentOverlayView extends View implements View.OnTouchListener {
mHandleMiddle.dragStart(point);
mDragHandle = mHandleMiddle;
return true;
+ } else if (mCalcSelectionBox != null &&
+ mCalcSelectionBox.contains(point.x, point.y) &&
+ !mHandleStart.isVisible()) {
+ mCalcSelectionBox.dragStart(point);
+ mCalcSelectionBoxDragging = true;
+ return true;
}
}
}
@@ -380,6 +399,9 @@ public class DocumentOverlayView extends View implements View.OnTouchListener {
} else if (mDragHandle != null) {
mDragHandle.dragEnd(point);
mDragHandle = null;
+ } else if (mCalcSelectionBoxDragging) {
+ mCalcSelectionBox.dragEnd(point);
+ mCalcSelectionBoxDragging = false;
}
}
case MotionEvent.ACTION_MOVE: {
@@ -389,6 +411,8 @@ public class DocumentOverlayView extends View implements View.OnTouchListener {
return true;
} else if (mDragHandle != null) {
mDragHandle.dragging(point);
+ } else if (mCalcSelectionBoxDragging) {
+ mCalcSelectionBox.dragging(point);
}
}
}
@@ -457,6 +481,33 @@ public class DocumentOverlayView extends View implements View.OnTouchListener {
public void setCalcHeadersController(CalcHeadersController calcHeadersController) {
mCalcHeadersController = calcHeadersController;
+ mCalcSelectionBox = new CalcSelectionBox((LibreOfficeMainActivity) getContext());
+ }
+
+ public void showCellSelection(RectF cellCursorRect) {
+ if (mCalcHeadersController == null || mCalcSelectionBox == null) return;
+ if (RectUtils.fuzzyEquals(mCalcSelectionBox.mDocumentPosition, cellCursorRect)) {
+ return;
+ }
+
+ // show selection on main GL view (i.e. in the document)
+ RectUtils.assign(mCalcSelectionBox.mDocumentPosition, cellCursorRect);
+ mCalcSelectionBox.setVisible(true);
+
+ ImmutableViewportMetrics metrics = mLayerView.getViewportMetrics();
+ repositionWithViewport(metrics.viewportRectLeft, metrics.viewportRectTop, metrics.zoomFactor);
+
+ // show selection on headers
+ if (!mCalcHeadersController.pendingRowOrColumnSelectionToShowUp()) {
+ showHeaderSelection(cellCursorRect);
+ } else {
+ mCalcHeadersController.setPendingRowOrColumnSelectionToShowUp(false);
+ }
+ }
+
+ public void showHeaderSelection(RectF rect) {
+ if (mCalcHeadersController == null) return;
+ mCalcHeadersController.showHeaderSelection(rect);
}
}