1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 package org
.libreoffice
;
11 import android
.content
.Context
;
12 import android
.graphics
.Bitmap
;
13 import android
.graphics
.PointF
;
14 import android
.print
.PrintAttributes
;
15 import android
.print
.PrintDocumentAdapter
;
16 import android
.print
.PrintManager
;
17 import android
.util
.Log
;
18 import android
.view
.KeyEvent
;
19 import android
.widget
.Toast
;
21 import org
.json
.JSONException
;
22 import org
.json
.JSONObject
;
23 import org
.libreoffice
.kit
.DirectBufferAllocator
;
24 import org
.libreoffice
.kit
.Document
;
25 import org
.libreoffice
.kit
.LibreOfficeKit
;
26 import org
.libreoffice
.kit
.Office
;
27 import org
.mozilla
.gecko
.gfx
.BufferedCairoImage
;
28 import org
.mozilla
.gecko
.gfx
.CairoImage
;
29 import org
.mozilla
.gecko
.gfx
.IntSize
;
32 import java
.nio
.ByteBuffer
;
35 * LOKit implementation of TileProvider.
37 class LOKitTileProvider
implements TileProvider
{
38 private static final String LOGTAG
= LOKitTileProvider
.class.getSimpleName();
39 private static final int TILE_SIZE
= 256;
40 private final float mTileWidth
;
41 private final float mTileHeight
;
42 private String mInputFile
;
43 private Office mOffice
;
44 private Document mDocument
;
45 private final boolean mIsReady
;
46 private final LibreOfficeMainActivity mContext
;
48 private final float mDPI
;
49 private float mWidthTwip
;
50 private float mHeightTwip
;
52 private final Document
.MessageCallback mMessageCallback
;
54 private final long objectCreationTime
= System
.currentTimeMillis();
57 * Initialize LOKit and load the document.
58 * @param messageCallback - callback for messages retrieved from LOKit
59 * @param input - input path of the document
61 LOKitTileProvider(LibreOfficeMainActivity context
, InvalidationHandler messageCallback
, String input
) {
63 mMessageCallback
= messageCallback
;
65 LibreOfficeKit
.putenv("SAL_LOG=+WARN+INFO");
66 LibreOfficeKit
.putenv("SAL_LOK_OPTIONS=compact_fonts");
67 LibreOfficeKit
.init(mContext
);
69 mOffice
= new Office(LibreOfficeKit
.getLibreOfficeKitHandle());
70 mOffice
.setMessageCallback(messageCallback
);
71 mOffice
.setOptionalFeatures(Document
.LOK_FEATURE_DOCUMENT_PASSWORD
);
72 mContext
.setTileProvider(this);
75 Log
.i(LOGTAG
, "====> Loading file '" + input
+ "'");
77 File fileToBeEncoded
= new File(input
);
78 String encodedFileName
= android
.net
.Uri
.encode(fileToBeEncoded
.getName());
80 mDocument
= mOffice
.documentLoad(
81 (new File(fileToBeEncoded
.getParent(),encodedFileName
)).getPath()
84 if (mDocument
== null && !mContext
.isPasswordProtected()) {
85 Log
.i(LOGTAG
, "====> mOffice.documentLoad() returned null, trying to restart 'Office' and loading again");
87 Log
.i(LOGTAG
, "====> mOffice.destroy() done");
88 ByteBuffer handle
= LibreOfficeKit
.getLibreOfficeKitHandle();
89 Log
.i(LOGTAG
, "====> getLibreOfficeKitHandle() = " + handle
);
90 mOffice
= new Office(handle
);
91 Log
.i(LOGTAG
, "====> new Office created");
92 mOffice
.setMessageCallback(messageCallback
);
93 mOffice
.setOptionalFeatures(Document
.LOK_FEATURE_DOCUMENT_PASSWORD
);
94 Log
.i(LOGTAG
, "====> setup Lokit callback and optional features (password support)");
95 mDocument
= mOffice
.documentLoad(
96 (new File(fileToBeEncoded
.getParent(),encodedFileName
)).getPath()
100 Log
.i(LOGTAG
, "====> mDocument = " + mDocument
);
102 mDPI
= LOKitShell
.getDpi(mContext
);
103 mTileWidth
= pixelToTwip(TILE_SIZE
, mDPI
);
104 mTileHeight
= pixelToTwip(TILE_SIZE
, mDPI
);
106 if (mDocument
!= null)
107 mDocument
.initializeForRendering();
109 if (checkDocument()) {
118 * Triggered after the document is loaded.
120 private void postLoad() {
121 mDocument
.setMessageCallback(mMessageCallback
);
124 // Writer documents always have one part, so hide the navigation drawer.
125 if (mDocument
.getDocumentType() == Document
.DOCTYPE_TEXT
) {
126 mContext
.disableNavigationDrawer();
127 mContext
.getToolbarController().hideItem(R
.id
.action_parts
);
130 // Enable headers for Calc documents
131 if (mDocument
.getDocumentType() == Document
.DOCTYPE_SPREADSHEET
) {
132 mContext
.initializeCalcHeaders();
135 mDocument
.setPart(0);
137 setupDocumentFonts();
139 LOKitShell
.getMainHandler().post(new Runnable() {
142 mContext
.getDocumentPartViewListAdapter().notifyDataSetChanged();
147 public void addPart(){
148 int parts
= mDocument
.getParts();
149 if(mDocument
.getDocumentType() == Document
.DOCTYPE_SPREADSHEET
){
151 JSONObject jsonObject
= new JSONObject();
152 JSONObject values
= new JSONObject();
153 JSONObject values2
= new JSONObject();
154 values
.put("type", "long");
155 values
.put("value", 0); //add to the last
156 values2
.put("type", "string");
157 values2
.put("value", "");
158 jsonObject
.put("Name", values2
);
159 jsonObject
.put("Index", values
);
160 LOKitShell
.sendEvent(new LOEvent(LOEvent
.UNO_COMMAND
, ".uno:Insert", jsonObject
.toString()));
161 }catch (JSONException e
) {
164 } else if (mDocument
.getDocumentType() == Document
.DOCTYPE_PRESENTATION
){
165 LOKitShell
.sendEvent(new LOEvent(LOEvent
.UNO_COMMAND
, ".uno:InsertPage"));
168 String partName
= mDocument
.getPartName(parts
);
169 if (partName
.isEmpty()) {
170 partName
= getGenericPartName(parts
);
172 mDocument
.setPart(parts
);
174 final DocumentPartView partView
= new DocumentPartView(parts
, partName
);
175 mContext
.getDocumentPartView().add(partView
);
178 public void resetParts(){
179 mContext
.getDocumentPartView().clear();
180 if (mDocument
.getDocumentType() != Document
.DOCTYPE_TEXT
) {
181 int parts
= mDocument
.getParts();
182 for (int i
= 0; i
< parts
; i
++) {
183 String partName
= mDocument
.getPartName(i
);
185 if (partName
.isEmpty()) {
186 partName
= getGenericPartName(i
);
188 Log
.i(LOGTAG
, "resetParts: " + partName
);
189 mDocument
.setPart(i
);
191 final DocumentPartView partView
= new DocumentPartView(i
, partName
);
192 mContext
.getDocumentPartView().add(partView
);
197 public void renamePart(String partName
) {
199 for(int i
=0; i
<mDocument
.getParts(); i
++){
200 if(mContext
.getDocumentPartView().get(i
).partName
.equals(partName
)){
201 //part name must be unique
202 Toast
.makeText(mContext
, mContext
.getString(R
.string
.name_already_used
), Toast
.LENGTH_SHORT
).show();
206 JSONObject parameter
= new JSONObject();
207 JSONObject name
= new JSONObject();
208 name
.put("type", "string");
209 name
.put("value", partName
);
210 parameter
.put("Name", name
);
211 if(isPresentation()){
212 LOKitShell
.sendEvent(new LOEvent(LOEvent
.UNO_COMMAND_NOTIFY
, ".uno:RenamePage", parameter
.toString(),true));
214 JSONObject index
= new JSONObject();
215 index
.put("type","long");
216 index
.put("value", getCurrentPartNumber()+1);
217 parameter
.put("Index", index
);
218 LOKitShell
.sendEvent(new LOEvent(LOEvent
.UNO_COMMAND_NOTIFY
, ".uno:Name", parameter
.toString(),true));
220 }catch (JSONException e
){
225 public void removePart() {
227 if (!isSpreadsheet() && !isPresentation()) {
228 //document must be spreadsheet or presentation
232 if(isPresentation()){
233 LOKitShell
.sendEvent(new LOEvent(LOEvent
.UNO_COMMAND_NOTIFY
, ".uno:DeletePage", true));
237 if(getPartsCount() < 2){
241 JSONObject parameter
= new JSONObject();
242 JSONObject index
= new JSONObject();
243 index
.put("type","long");
244 index
.put("value", getCurrentPartNumber()+1);
245 parameter
.put("Index", index
);
246 LOKitShell
.sendEvent(new LOEvent(LOEvent
.UNO_COMMAND_NOTIFY
, ".uno:Remove", parameter
.toString(),true));
247 }catch (JSONException e
){
253 public boolean saveDocumentAs(final String filePath
, String format
, boolean takeOwnership
) {
256 options
= "TakeOwnership";
259 final String newFilePath
= "file://" + filePath
;
260 Log
.d("saveFilePathURL", newFilePath
);
261 LOKitShell
.showProgressSpinner(mContext
);
262 mDocument
.saveAs(newFilePath
, format
, options
);
264 if (!mOffice
.getError().isEmpty()){
266 Log
.e("Save Error", mOffice
.getError());
267 if (format
.equals("svg")) {
268 // error in creating temp slideshow svg file
269 Log
.d(LOGTAG
, "Error in creating temp slideshow svg file");
270 } else if(format
.equals("pdf")){
271 Log
.d(LOGTAG
, "Error in creating pdf file");
273 LOKitShell
.getMainHandler().post(new Runnable() {
276 // There was some error
277 mContext
.showCustomStatusMessage(mContext
.getString(R
.string
.unable_to_save
));
283 if (format
.equals("svg")) {
284 // successfully created temp slideshow svg file
285 LOKitShell
.getMainHandler().post(new Runnable() {
288 mContext
.startPresentation(newFilePath
);
291 } else if (takeOwnership
) {
292 mInputFile
= filePath
;
295 LOKitShell
.hideProgressSpinner(mContext
);
300 public boolean saveDocumentAs(final String filePath
, boolean takeOwnership
) {
301 final int docType
= mDocument
.getDocumentType();
302 if (docType
== Document
.DOCTYPE_TEXT
)
303 return saveDocumentAs(filePath
, "odt", takeOwnership
);
304 else if (docType
== Document
.DOCTYPE_SPREADSHEET
)
305 return saveDocumentAs(filePath
, "ods", takeOwnership
);
306 else if (docType
== Document
.DOCTYPE_PRESENTATION
)
307 return saveDocumentAs(filePath
, "odp", takeOwnership
);
308 else if (docType
== Document
.DOCTYPE_DRAWING
)
309 return saveDocumentAs(filePath
, "odg", takeOwnership
);
311 Log
.w(LOGTAG
, "Cannot determine file format from document. Not saving.");
315 public void printDocument() {
316 String mInputFileName
= (new File(mInputFile
)).getName();
317 String file
= mInputFileName
.substring(0,(mInputFileName
.length()-3))+"pdf";
318 String cacheFile
= mContext
.getExternalCacheDir().getAbsolutePath() + "/" + file
;
319 mDocument
.saveAs("file://"+cacheFile
,"pdf","");
321 PrintManager printManager
= (PrintManager
) mContext
.getSystemService(Context
.PRINT_SERVICE
);
322 PrintDocumentAdapter printAdapter
= new PDFDocumentAdapter(mContext
, cacheFile
);
323 printManager
.print("Document", printAdapter
, new PrintAttributes
.Builder().build());
325 } catch (Exception e
) {
330 public void saveDocument(){
331 mContext
.saveDocument();
334 private void setupDocumentFonts() {
335 String values
= mDocument
.getCommandValues(".uno:CharFontName");
336 if (values
== null || values
.isEmpty())
339 mContext
.getFontController().parseJson(values
);
340 mContext
.getFontController().setupFontViews();
343 private String
getGenericPartName(int i
) {
344 if (mDocument
== null) {
347 switch (mDocument
.getDocumentType()) {
348 case Document
.DOCTYPE_DRAWING
:
349 case Document
.DOCTYPE_TEXT
:
350 return mContext
.getString(R
.string
.page
) + " " + (i
+ 1);
351 case Document
.DOCTYPE_SPREADSHEET
:
352 return mContext
.getString(R
.string
.sheet
) + " " + (i
+ 1);
353 case Document
.DOCTYPE_PRESENTATION
:
354 return mContext
.getString(R
.string
.slide
) + " " + (i
+ 1);
355 case Document
.DOCTYPE_OTHER
:
357 return mContext
.getString(R
.string
.part
) + " " + (i
+ 1);
361 static float twipToPixel(float input
, float dpi
) {
362 return input
/ 1440.0f
* dpi
;
365 private static float pixelToTwip(float input
, float dpi
) {
366 return (input
/ dpi
) * 1440.0f
;
371 * @see TileProvider#getPartsCount()
374 public int getPartsCount() {
375 return mDocument
.getParts();
379 * Wrapper for getPartPageRectangles() JNI function.
381 public String
getPartPageRectangles() {
382 return mDocument
.getPartPageRectangles();
386 * Fetch Calc header information.
388 public String
getCalcHeaders() {
391 long nWidth
= mDocument
.getDocumentWidth();
392 long nHeight
= mDocument
.getDocumentHeight();
393 return mDocument
.getCommandValues(".uno:ViewRowColumnHeaders?x=" + nX
+ "&y=" + nY
394 + "&width=" + nWidth
+ "&height=" + nHeight
);
398 * @see TileProvider#onSwipeLeft()
401 public void onSwipeLeft() {
402 if (mDocument
.getDocumentType() == Document
.DOCTYPE_PRESENTATION
&&
403 getCurrentPartNumber() < getPartsCount()-1) {
404 LOKitShell
.sendChangePartEvent(getCurrentPartNumber()+1);
409 * @see TileProvider#onSwipeRight()
412 public void onSwipeRight() {
413 if (mDocument
.getDocumentType() == Document
.DOCTYPE_PRESENTATION
&&
414 getCurrentPartNumber() > 0) {
415 LOKitShell
.sendChangePartEvent(getCurrentPartNumber()-1);
419 private boolean checkDocument() {
423 if (mDocument
== null || !mOffice
.getError().isEmpty()) {
424 error
= "Cannot open " + mInputFile
+ ": " + mOffice
.getError();
427 ret
= resetDocumentSize();
429 error
= "Document returned an invalid size or the document is empty.";
433 if (!ret
&& !mContext
.isPasswordProtected()) {
434 final String message
= error
;
435 LOKitShell
.getMainHandler().post(new Runnable() {
438 mContext
.showAlertDialog(message
);
441 } else if (!ret
&& mContext
.isPasswordProtected()) {
448 private boolean resetDocumentSize() {
449 mWidthTwip
= mDocument
.getDocumentWidth();
450 mHeightTwip
= mDocument
.getDocumentHeight();
452 if (mWidthTwip
== 0 || mHeightTwip
== 0) {
453 Log
.e(LOGTAG
, "Document size zero - last error: " + mOffice
.getError());
456 Log
.i(LOGTAG
, "Reset document size: " + mDocument
.getDocumentWidth() + " x " + mDocument
.getDocumentHeight());
463 public void setDocumentSize(int pageWidth
, int pageHeight
){
464 mWidthTwip
= pageWidth
;
465 mHeightTwip
= pageHeight
;
469 * @see TileProvider#getPageWidth()
472 public int getPageWidth() {
473 return (int) twipToPixel(mWidthTwip
, mDPI
);
477 * @see TileProvider#getPageHeight()
480 public int getPageHeight() {
481 return (int) twipToPixel(mHeightTwip
, mDPI
);
485 * @see TileProvider#isReady()
488 public boolean isReady() {
493 * @see TileProvider#createTile(float, float, org.mozilla.gecko.gfx.IntSize, float)
496 public CairoImage
createTile(float x
, float y
, IntSize tileSize
, float zoom
) {
497 ByteBuffer buffer
= DirectBufferAllocator
.guardedAllocate(tileSize
.width
* tileSize
.height
* 4);
501 CairoImage image
= new BufferedCairoImage(buffer
, tileSize
.width
, tileSize
.height
, CairoImage
.FORMAT_ARGB32
);
502 rerenderTile(image
, x
, y
, tileSize
, zoom
);
507 * @see TileProvider#rerenderTile(org.mozilla.gecko.gfx.CairoImage, float, float, org.mozilla.gecko.gfx.IntSize, float)
510 public void rerenderTile(CairoImage image
, float x
, float y
, IntSize tileSize
, float zoom
) {
511 if (mDocument
!= null && image
.getBuffer() != null) {
512 float twipX
= pixelToTwip(x
, mDPI
) / zoom
;
513 float twipY
= pixelToTwip(y
, mDPI
) / zoom
;
514 float twipWidth
= mTileWidth
/ zoom
;
515 float twipHeight
= mTileHeight
/ zoom
;
516 long start
= System
.currentTimeMillis() - objectCreationTime
;
518 //Log.i(LOGTAG, "paintTile >> @" + start + " (" + tileSize.width + " " + tileSize.height + " " + (int) twipX + " " + (int) twipY + " " + (int) twipWidth + " " + (int) twipHeight + ")");
519 mDocument
.paintTile(image
.getBuffer(), tileSize
.width
, tileSize
.height
, (int) twipX
, (int) twipY
, (int) twipWidth
, (int) twipHeight
);
521 long stop
= System
.currentTimeMillis() - objectCreationTime
;
522 //Log.i(LOGTAG, "paintTile << @" + stop + " elapsed: " + (stop - start));
524 if (mDocument
== null) {
525 Log
.e(LOGTAG
, "Document is null!!");
531 * @see TileProvider#thumbnail(int)
534 public Bitmap
thumbnail(int size
) {
535 int widthPixel
= getPageWidth();
536 int heightPixel
= getPageHeight();
538 if (widthPixel
> heightPixel
) {
539 double ratio
= heightPixel
/ (double) widthPixel
;
541 heightPixel
= (int) (widthPixel
* ratio
);
543 double ratio
= widthPixel
/ (double) heightPixel
;
545 widthPixel
= (int) (heightPixel
* ratio
);
548 Log
.w(LOGTAG
, "Thumbnail size: " + getPageWidth() + " " + getPageHeight() + " " + widthPixel
+ " " + heightPixel
);
550 ByteBuffer buffer
= ByteBuffer
.allocateDirect(widthPixel
* heightPixel
* 4);
551 if (mDocument
!= null)
552 mDocument
.paintTile(buffer
, widthPixel
, heightPixel
, 0, 0, (int) mWidthTwip
, (int) mHeightTwip
);
554 Bitmap bitmap
= null;
556 bitmap
= Bitmap
.createBitmap(widthPixel
, heightPixel
, Bitmap
.Config
.ARGB_8888
);
557 bitmap
.copyPixelsFromBuffer(buffer
);
558 } catch (IllegalArgumentException e
) {
559 Log
.e(LOGTAG
, "width (" + widthPixel
+ ") and height (" + heightPixel
+ ") must not be 0! (ToDo: likely timing issue)");
561 if (bitmap
== null) {
562 Log
.w(LOGTAG
, "Thumbnail not created!");
568 * @see TileProvider#close()
571 public void close() {
572 Log
.i(LOGTAG
, "Document destroyed: " + mInputFile
);
573 if (mDocument
!= null) {
580 * @see TileProvider#isDrawing()
583 public boolean isDrawing() {
584 return mDocument
!= null && mDocument
.getDocumentType() == Document
.DOCTYPE_DRAWING
;
588 * @see TileProvider#isTextDocument()
591 public boolean isTextDocument() {
592 return mDocument
!= null && mDocument
.getDocumentType() == Document
.DOCTYPE_TEXT
;
596 * @see TileProvider#isSpreadsheet()
599 public boolean isSpreadsheet() {
600 return mDocument
!= null && mDocument
.getDocumentType() == Document
.DOCTYPE_SPREADSHEET
;
604 * @see TileProvider#isPresentation()
607 public boolean isPresentation(){
608 return mDocument
!= null && mDocument
.getDocumentType() == Document
.DOCTYPE_PRESENTATION
;
612 * Returns the Unicode character generated by this event or 0.
614 private int getCharCode(KeyEvent keyEvent
) {
615 switch (keyEvent
.getKeyCode())
617 case KeyEvent
.KEYCODE_DEL
:
618 case KeyEvent
.KEYCODE_ENTER
:
621 return keyEvent
.getUnicodeChar();
625 * Returns the integer code representing the key of the event (non-zero for
628 private int getKeyCode(KeyEvent keyEvent
) {
629 switch (keyEvent
.getKeyCode()) {
630 case KeyEvent
.KEYCODE_DEL
:
631 return com
.sun
.star
.awt
.Key
.BACKSPACE
;
632 case KeyEvent
.KEYCODE_DPAD_DOWN
:
633 return com
.sun
.star
.awt
.Key
.DOWN
;
634 case KeyEvent
.KEYCODE_DPAD_LEFT
:
635 return com
.sun
.star
.awt
.Key
.LEFT
;
636 case KeyEvent
.KEYCODE_DPAD_RIGHT
:
637 return com
.sun
.star
.awt
.Key
.RIGHT
;
638 case KeyEvent
.KEYCODE_DPAD_UP
:
639 return com
.sun
.star
.awt
.Key
.UP
;
640 case KeyEvent
.KEYCODE_ENTER
:
641 return com
.sun
.star
.awt
.Key
.RETURN
;
647 * @see TileProvider#sendKeyEvent(android.view.KeyEvent)
650 public void sendKeyEvent(KeyEvent keyEvent
) {
651 switch (keyEvent
.getAction()) {
652 case KeyEvent
.ACTION_MULTIPLE
:
653 String keyString
= keyEvent
.getCharacters();
654 for (int i
= 0; i
< keyString
.length(); i
++) {
655 int codePoint
= keyString
.codePointAt(i
);
656 mDocument
.postKeyEvent(Document
.KEY_EVENT_PRESS
, codePoint
, getKeyCode(keyEvent
));
659 case KeyEvent
.ACTION_DOWN
:
660 mDocument
.postKeyEvent(Document
.KEY_EVENT_PRESS
, getCharCode(keyEvent
), getKeyCode(keyEvent
));
662 case KeyEvent
.ACTION_UP
:
663 mDocument
.postKeyEvent(Document
.KEY_EVENT_RELEASE
, getCharCode(keyEvent
), getKeyCode(keyEvent
));
668 private void mouseButton(int type
, PointF inDocument
, int numberOfClicks
, float zoomFactor
) {
669 int x
= (int) pixelToTwip(inDocument
.x
, mDPI
);
670 int y
= (int) pixelToTwip(inDocument
.y
, mDPI
);
672 mDocument
.setClientZoom(TILE_SIZE
, TILE_SIZE
, (int) (mTileWidth
/ zoomFactor
), (int) (mTileHeight
/ zoomFactor
));
673 mDocument
.postMouseEvent(type
, x
, y
, numberOfClicks
, Document
.MOUSE_BUTTON_LEFT
, Document
.KEYBOARD_MODIFIER_NONE
);
677 * @see TileProvider#mouseButtonDown(android.graphics.PointF, int, float)
680 public void mouseButtonDown(PointF documentCoordinate
, int numberOfClicks
, float zoomFactor
) {
681 mouseButton(Document
.MOUSE_EVENT_BUTTON_DOWN
, documentCoordinate
, numberOfClicks
, zoomFactor
);
685 * @see TileProvider#mouseButtonUp(android.graphics.PointF, int, float)
688 public void mouseButtonUp(PointF documentCoordinate
, int numberOfClicks
, float zoomFactor
) {
689 mouseButton(Document
.MOUSE_EVENT_BUTTON_UP
, documentCoordinate
, numberOfClicks
, zoomFactor
);
693 * @param command UNO command string
694 * @param arguments Arguments to UNO command
697 public void postUnoCommand(String command
, String arguments
) {
698 postUnoCommand(command
, arguments
, false);
704 * @param notifyWhenFinished
707 public void postUnoCommand(String command
, String arguments
, boolean notifyWhenFinished
) {
708 mDocument
.postUnoCommand(command
, arguments
, notifyWhenFinished
);
711 private void setTextSelection(int type
, PointF documentCoordinate
) {
712 int x
= (int) pixelToTwip(documentCoordinate
.x
, mDPI
);
713 int y
= (int) pixelToTwip(documentCoordinate
.y
, mDPI
);
714 mDocument
.setTextSelection(type
, x
, y
);
718 * @see TileProvider#setTextSelectionStart(android.graphics.PointF)
721 public void setTextSelectionStart(PointF documentCoordinate
) {
722 setTextSelection(Document
.SET_TEXT_SELECTION_START
, documentCoordinate
);
726 * @see TileProvider#setTextSelectionEnd(android.graphics.PointF)
729 public void setTextSelectionEnd(PointF documentCoordinate
) {
730 setTextSelection(Document
.SET_TEXT_SELECTION_END
, documentCoordinate
);
734 * @see TileProvider#setTextSelectionReset(android.graphics.PointF)
737 public void setTextSelectionReset(PointF documentCoordinate
) {
738 setTextSelection(Document
.SET_TEXT_SELECTION_RESET
, documentCoordinate
);
746 public String
getTextSelection(String mimeType
) {
747 return mDocument
.getTextSelection(mimeType
);
757 public boolean paste(String mimeType
, String data
) {
758 return mDocument
.paste(mimeType
, data
);
763 * @see org.libreoffice.TileProvider#setGraphicSelectionStart(android.graphics.PointF)
766 public void setGraphicSelectionStart(PointF documentCoordinate
) {
767 setGraphicSelection(Document
.SET_GRAPHIC_SELECTION_START
, documentCoordinate
);
771 * @see org.libreoffice.TileProvider#setGraphicSelectionEnd(android.graphics.PointF)
774 public void setGraphicSelectionEnd(PointF documentCoordinate
) {
775 setGraphicSelection(Document
.SET_GRAPHIC_SELECTION_END
, documentCoordinate
);
778 private void setGraphicSelection(int type
, PointF documentCoordinate
) {
779 int x
= (int) pixelToTwip(documentCoordinate
.x
, mDPI
);
780 int y
= (int) pixelToTwip(documentCoordinate
.y
, mDPI
);
781 LibreOfficeMainActivity
.setDocumentChanged(true);
782 mDocument
.setGraphicSelection(type
, x
, y
);
786 protected void finalize() throws Throwable
{
792 * @see TileProvider#changePart(int)
795 public void changePart(int partIndex
) {
796 if (mDocument
== null)
799 mDocument
.setPart(partIndex
);
804 * @see TileProvider#getCurrentPartNumber()
807 public int getCurrentPartNumber() {
808 if (mDocument
== null)
811 return mDocument
.getPart();
814 public void setDocumentPassword(String url
, String password
) {
815 mOffice
.setDocumentPassword(url
, password
);
818 public Document
.MessageCallback
getMessageCallback() {
819 return mMessageCallback
;
823 // vim:set shiftwidth=4 softtabstop=4 expandtab: