1package org.libreoffice;
3import android.content.Intent;
4import android.graphics.PointF;
5import android.graphics.RectF;
7import android.util.Log;
8import android.widget.EditText;
9import android.widget.Toast;
11import org.json.JSONArray;
12import org.json.JSONException;
13import org.json.JSONObject;
20import java.util.ArrayList;
21import java.util.Collections;
54 if (messageID !=
Document.CALLBACK_INVALIDATE_TILES
55 && messageID !=
Document.CALLBACK_DOCUMENT_PASSWORD
56 && messageID !=
Document.CALLBACK_HYPERLINK_CLICKED
57 && messageID !=
Document.CALLBACK_SEARCH_RESULT_SELECTION
58 && messageID !=
Document.CALLBACK_SC_FOLLOW_JUMP
59 && messageID !=
Document.CALLBACK_TEXT_SELECTION
60 && messageID !=
Document.CALLBACK_TEXT_SELECTION_START
61 && messageID !=
Document.CALLBACK_TEXT_SELECTION_END)
65 case Document.CALLBACK_INVALIDATE_TILES:
68 case Document.CALLBACK_UNO_COMMAND_RESULT:
71 case Document.CALLBACK_INVALIDATE_VISIBLE_CURSOR:
74 case Document.CALLBACK_TEXT_SELECTION:
77 case Document.CALLBACK_TEXT_SELECTION_START:
80 case Document.CALLBACK_TEXT_SELECTION_END:
83 case Document.CALLBACK_CURSOR_VISIBLE:
86 case Document.CALLBACK_GRAPHIC_SELECTION:
89 case Document.CALLBACK_HYPERLINK_CLICKED:
90 if (!payload.startsWith(
"http://") && !payload.startsWith(
"https://")) {
91 payload =
"http://" + payload;
93 Intent urlIntent =
new Intent(Intent.ACTION_VIEW);
94 urlIntent.setData(Uri.parse(payload));
97 case Document.CALLBACK_STATE_CHANGED:
100 case Document.CALLBACK_SEARCH_RESULT_SELECTION:
111 case Document.CALLBACK_SEARCH_NOT_FOUND:
112 Log.d(
LOGTAG,
"LOK_CALLBACK: Search not found.");
118 case Document.CALLBACK_SC_FOLLOW_JUMP:
121 case Document.CALLBACK_INVALIDATE_HEADER:
124 case Document.CALLBACK_CELL_ADDRESS:
127 case Document.CALLBACK_CELL_FORMULA:
130 case Document.CALLBACK_DOCUMENT_PASSWORD:
133 case Document.CALLBACK_DOCUMENT_SIZE_CHANGED:
137 Log.d(
LOGTAG,
"LOK_CALLBACK uncaught: " + messageID +
" : " + payload);
143 JSONObject payloadObject =
new JSONObject(payload);
144 if (payloadObject.getString(
"commandName").equals(
".uno:Save")) {
145 if (payloadObject.getString(
"success").equals(
"true")) {
148 }
else if(payloadObject.getString(
"commandName").equals(
".uno:Name") ||
149 payloadObject.getString(
"commandName").equals(
".uno:RenamePage")){
157 Toast.makeText(
mContext,
mContext.getString(
R.string.part_name_changed), Toast.LENGTH_SHORT).show();
160 }
else if(payloadObject.getString(
"commandName").equals(
".uno:Remove") ||
161 payloadObject.getString(
"commandName").equals(
".uno:DeletePage") ) {
168 Toast.makeText(
mContext,
mContext.getString(
R.string.part_deleted), Toast.LENGTH_SHORT).show();
172 }
catch(JSONException e){
181 ((EditText)
mContext.findViewById(
R.id.calc_formula)).setText(payload);
190 ((EditText)
mContext.findViewById(
R.id.calc_address)).setText(payload);
202 synchronized (
this) {
205 }
catch (InterruptedException e) {
215 if (cellCursorRect !=
null) {
224 if (cellCursorRect !=
null) {
235 RectF selectionRectangle =
null;
237 JSONObject collectiveResult =
new JSONObject(payload);
238 JSONArray searchResult = collectiveResult.getJSONArray(
"searchResultSelection");
239 if (searchResult.length() == 1) {
240 String rectangle = searchResult.getJSONObject(0).getString(
"rectangles");
243 }
catch (JSONException e) {
246 if (selectionRectangle !=
null) {
263 if (moveToRect.contains(selectionRectangle)) {
267 float newLeft = moveToRect.left;
268 float newTop = moveToRect.top;
272 float widthRatio = 1f;
273 float heightRatio = 1f;
274 if (moveToRect.width() < selectionRectangle.width()) {
275 widthRatio = selectionRectangle.width() / moveToRect.width() / 0.85f;
277 if (moveToRect.height() < selectionRectangle.height()) {
278 heightRatio = selectionRectangle.height() / moveToRect.height() / 0.45f;
280 float newZoom = widthRatio > heightRatio ? oldZoom/widthRatio : oldZoom/heightRatio;
283 if (selectionRectangle.right < moveToRect.left || selectionRectangle.left < moveToRect.left) {
284 newLeft = selectionRectangle.left - (moveToRect.width() * 0.1f) * oldZoom / newZoom;
285 }
else if (selectionRectangle.right > moveToRect.right || selectionRectangle.left > moveToRect.right) {
286 newLeft = selectionRectangle.right - (moveToRect.width() * 0.9f) * oldZoom / newZoom;
289 if (selectionRectangle.top < moveToRect.top || selectionRectangle.bottom < moveToRect.top) {
290 newTop = selectionRectangle.top - (moveToRect.height() * 0.1f) * oldZoom / newZoom;
291 }
else if (selectionRectangle.bottom > moveToRect.bottom || selectionRectangle.top > moveToRect.bottom){
292 newTop = selectionRectangle.bottom - (moveToRect.height() * 0.5f) * oldZoom / newZoom;
300 String[] bounds = payload.split(
",");
301 int pageWidth =
Integer.parseInt(bounds[0]);
302 int pageHeight =
Integer.parseInt(bounds[1].
trim());
308 String[] parts = payload.split(
"=");
309 if (parts.length < 2) {
310 Log.e(
LOGTAG,
"LOK_CALLBACK_STATE_CHANGED unexpected payload: " + payload);
316 Log.w(
LOGTAG,
"tile provider not ready, ignoring payload "+payload);
319 if (parts[0].equals(
".uno:Bold")) {
321 }
else if (parts[0].equals(
".uno:Italic")) {
323 }
else if (parts[0].equals(
".uno:Underline")) {
325 }
else if (parts[0].equals(
".uno:Strikeout")) {
327 }
else if (parts[0].equals(
".uno:CharFontName")) {
329 }
else if (parts[0].equals(
".uno:FontHeight")) {
331 }
else if (parts[0].equals(
".uno:LeftPara")) {
333 }
else if (parts[0].equals(
".uno:CenterPara")) {
335 }
else if (parts[0].equals(
".uno:RightPara")) {
337 }
else if (parts[0].equals(
".uno:JustifyPara")) {
339 }
else if (parts[0].equals(
".uno:DefaultBullet")) {
341 }
else if (parts[0].equals(
".uno:DefaultNumbering")) {
343 }
else if (parts[0].equals(
".uno:Color")) {
345 }
else if (
mContext.
getTileProvider().isTextDocument() && (parts[0].equals(
".uno:BackColor") || parts[0].equals(
".uno:CharBackColor"))) {
351 }
else if (parts[0].equals(
".uno:StatePageNumber")) {
353 String[] splitStrings = parts[1].split(
" ");
354 int totalPageNumber =
Integer.valueOf(splitStrings[splitStrings.length - 1]);
361 Log.d(
LOGTAG,
"LOK_CALLBACK_STATE_CHANGED type uncatched: " + payload);
372 String payloadWithoutWhitespace = payload.replaceAll(
"\\s",
"");
374 if (payloadWithoutWhitespace.isEmpty() || payloadWithoutWhitespace.equals(
"EMPTY")) {
378 String[] coordinates = payloadWithoutWhitespace.split(
",");
380 if (coordinates.length != 4) {
393 String payloadWithoutWhitespace = payload.replaceAll(
"\\s",
"");
395 if (payloadWithoutWhitespace.isEmpty() || payloadWithoutWhitespace.equals(
"EMPTY")) {
399 String[] coordinates = payloadWithoutWhitespace.split(
",");
401 if (coordinates.length != 6 ) {
414 if (coordinates.length < 4 ) {
418 int x =
Integer.decode(coordinates[0]);
419 int y =
Integer.decode(coordinates[1]);
420 int width =
Integer.decode(coordinates[2]);
421 int height =
Integer.decode(coordinates[3]);
426 LOKitTileProvider.twipToPixel(
x, dpi),
427 LOKitTileProvider.twipToPixel(
y, dpi),
428 LOKitTileProvider.twipToPixel(
x + width, dpi),
429 LOKitTileProvider.twipToPixel(
y + height, dpi)
440 List<RectF> rectangles =
new ArrayList<RectF>();
441 String[] rectangleArray = payload.split(
";");
443 for (
String coordinates : rectangleArray) {
473 if (cursorRectangle !=
null) {
497 if (moveToRect.contains(cursorRectangle)) {
501 float newLeft = moveToRect.left;
502 float newTop = moveToRect.top;
504 if (cursorRectangle.right < moveToRect.left || cursorRectangle.left < moveToRect.left) {
505 newLeft = cursorRectangle.left - (moveToRect.width() * 0.1f);
506 }
else if (cursorRectangle.right > moveToRect.right || cursorRectangle.left > moveToRect.right) {
507 newLeft = cursorRectangle.right - (moveToRect.width() * 0.9f);
510 if (cursorRectangle.top < moveToRect.top || cursorRectangle.bottom < moveToRect.top) {
511 newTop = cursorRectangle.top - (moveToRect.height() * 0.1f);
512 }
else if (cursorRectangle.bottom > moveToRect.bottom || cursorRectangle.top > moveToRect.bottom) {
513 newTop = cursorRectangle.bottom - (moveToRect.height() / 2.0f);
526 if (selectionRect !=
null) {
538 if (selectionRect !=
null) {
549 if (payload.isEmpty() || payload.equals(
"EMPTY")) {
579 if (payload.equals(
"true")) {
584 }
else if (payload.equals(
"false")) {
596 if (payload.isEmpty() || payload.equals(
"EMPTY")) {
635 case GRAPHIC_SELECTION:
711 case GRAPHIC_SELECTION:
void selectFont(final String fontName)
void selectFontSize(final String fontSize)
Parses (interprets) and handles invalidation messages from LibreOffice.
synchronized void changeStateTo(OverlayState next)
Trigger a transition to a new overlay state.
void moveViewportToMakeSelectionVisible(RectF selectionRectangle)
Move the viewport to show the selection.
void handleGraphicSelectionState(OverlayState previous)
Handle a transition to OverlayState.GRAPHIC_SELECTION state.
static final String LOGTAG
void handleCursorState(OverlayState previous)
Handle a transition to OverlayState.CURSOR state.
synchronized void textSelection(String payload)
Handles the text selection message.
final GeckoLayerClient mLayerClient
void searchResultSelection(String payload)
Handles the search result selection message, which is a JSONObject.
OverlayState getCurrentState()
The current state the overlay is in.
void cellAddress(final String payload)
synchronized void invalidateCursor(String payload)
Handles the cursor invalidation message.
void handleNoneState(OverlayState previous)
Handle a transition to OverlayState.NONE state.
void invalidateCellCursor(String payload)
void handleTransitionState(OverlayState previous)
Handle a transition to OverlayState.TRANSITION state.
List< RectF > convertPayloadToRectangles(String payload)
Parses the payload text with more rectangles (separated by ';') and converts to a list of rectangles.
InvalidationHandler(LibreOfficeMainActivity context)
synchronized void changeState(OverlayState previous, OverlayState next)
Executes a transition from old overlay state to a new overlay state.
void graphicSelection(String payload)
Handles the graphic selection change message.
final LibreOfficeMainActivity mContext
final DocumentOverlay mDocumentOverlay
void messageRetrieved(int messageID, String payload)
Processes callback message.
void cellFormula(final String payload)
RectF convertPayloadCellToRectangle(String payload)
Parses the payload text with rectangle coordinates and converts to rectangle in pixel coordinates.
void stateChanged(String payload)
synchronized void cursorVisibility(String payload)
Handles the cursor visibility message.
void keyEvent()
A key event happened (i.e.
void handleSelectionState(OverlayState previous)
Handle a transition to OverlayState.SELECTION state.
void moveViewportToMakeCursorVisible(RectF cursorRectangle)
Move the viewport to show the cursor.
RectF convertPayloadToRectangle(String[] coordinates)
Converts rectangle coordinates to rectangle in pixel coordinates.
void jumpToCell(String payload)
void unoCommandResult(String payload)
synchronized void textSelectionEnd(String payload)
Handles the text selection end message.
void handleGeneralChangeState(OverlayState previous, OverlayState next)
Handle a general transition - executed for all transitions.
RectF convertPayloadToRectangle(String payload)
Parses the payload text with rectangle coordinates and converts to rectangle in pixel coordinates.
synchronized void textSelectionStart(String payload)
Handles the text selection start message.
void invalidateTiles(String payload)
Handles the tile invalidation message.
void pageSizeChanged(String payload)
int currentTotalPageNumber
Events and data that is queued and processed by LOKitThread.
static final int PAGE_SIZE_CHANGED
static final int UPDATE_PART_PAGE_RECT
static final int UPDATE_CALC_HEADERS
Common static LOKit functions, functions to send events.
static boolean isEditingEnabled()
static void sendTileInvalidationRequest(RectF rect)
Send tile invalidation to LOKitThread.
static void sendEvent(LOEvent event)
Make sure LOKitThread is running and send event to it.
static float getDpi(Context context)
static Handler getMainHandler()
static void moveViewportTo(final LibreOfficeMainActivity context, final PointF position, final Float zoom)
Move the viewport to the desired point (top-left), and change the zoom level.
Main activity of the LibreOffice App.
GeckoLayerClient getLayerClient()
FormattingController getFormattingController()
void showSoftKeyboardOrFormattingToolbar()
FontController getFontController()
DocumentOverlay getDocumentOverlay()
void setPasswordProtected(boolean b)
ToolbarController getToolbarController()
static void setDocumentChanged(boolean changed)
DocumentPartViewListAdapter getDocumentPartViewListAdapter()
LOKitTileProvider getTileProvider()
void saveFileToOriginalSource()
void hideSoftKeyboard()
Hides software keyboard on UI thread.
Selection handle is a common class for "start", "middle" and "end" types of selection handles.
The DocumentOverlay is an overlay over the document.
void changeGraphicSelection(final RectF rectangle)
Change the graphic selection rectangle to the input rectangle.
void changeSelections(final List< RectF > selections)
Change the list of selections.
void positionHandle(final SelectionHandle.HandleType type, final RectF rectangle)
Position the handle (of input type) position to the input rectangle.
void hideHandle(final SelectionHandle.HandleType type)
Hide the handle (of input type).
void hideSelections()
Hide selections on the overlay.
void showHeaderSelection(final RectF cellCursorRect)
void showCellSelection(final RectF cellCursorRect)
void showHandle(final SelectionHandle.HandleType type)
Show the handle (of input type) on the overlay.
void showSelections()
Show selections on the overlay.
void showCursor()
Show the cursor at the defined cursor position on the overlay.
void positionCursor(final RectF position)
Position the cursor to the input position on the overlay.
void hideGraphicSelection()
Hide the graphic selection.
void showGraphicSelection()
Show the graphic selection on the overlay.
void hideCursor()
Hide the cursor at the defined cursor position on the overlay.
ImmutableViewportMetrics getViewportMetrics()
Implementation of PanZoomTarget.
GRAPHIC_SELECTION
State where we operate the graphic selection.
SELECTION
State where we operate the text selection.
NONE
State where the overlay is empty.
TRANSITION
In-between state where we need to transition to a new overlay state.
CURSOR
State where we operate with the cursor.
void updateColorPickerPosition(int color)
def run(arg=None, arg2=-1)
std::basic_string_view< charT, traits > trim(std::basic_string_view< charT, traits > str)