LibreOffice Module android (master) 1
LOKitTileProvider.java
Go to the documentation of this file.
1/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 */
9package org.libreoffice;
10
11import android.content.Context;
12import android.graphics.Bitmap;
13import android.graphics.PointF;
14import android.os.Build;
15import android.print.PrintAttributes;
16import android.print.PrintDocumentAdapter;
17import android.print.PrintManager;
18import android.util.Log;
19import android.view.KeyEvent;
20import android.widget.Toast;
21
22import org.json.JSONException;
23import org.json.JSONObject;
25import org.libreoffice.kit.Document;
27import org.libreoffice.kit.Office;
31
32import java.io.File;
33import java.nio.ByteBuffer;
34
38class LOKitTileProvider implements TileProvider {
39 private static final String LOGTAG = LOKitTileProvider.class.getSimpleName();
40 private static final int TILE_SIZE = 256;
41 private final float mTileWidth;
42 private final float mTileHeight;
43 private String mInputFile;
44 private Office mOffice;
45 private Document mDocument;
46 private final boolean mIsReady;
47 private final LibreOfficeMainActivity mContext;
48
49 private final float mDPI;
50 private float mWidthTwip;
51 private float mHeightTwip;
52
53 private final Document.MessageCallback mMessageCallback;
54
55 private final long objectCreationTime = System.currentTimeMillis();
56
62 LOKitTileProvider(LibreOfficeMainActivity context, InvalidationHandler messageCallback, String input) {
63 mContext = context;
64 mMessageCallback = messageCallback;
65
66 LibreOfficeKit.putenv("SAL_LOG=+WARN+INFO");
67 LibreOfficeKit.init(mContext);
68
69 mOffice = new Office(LibreOfficeKit.getLibreOfficeKitHandle());
70 mOffice.setMessageCallback(messageCallback);
71 mOffice.setOptionalFeatures(Document.LOK_FEATURE_DOCUMENT_PASSWORD);
72 mContext.setTileProvider(this);
73 mInputFile = input;
74
75 Log.i(LOGTAG, "====> Loading file '" + input + "'");
76
77 File fileToBeEncoded = new File(input);
78 String encodedFileName = android.net.Uri.encode(fileToBeEncoded.getName());
79
80 mDocument = mOffice.documentLoad(
81 (new File(fileToBeEncoded.getParent(),encodedFileName)).getPath()
82 );
83
84 if (mDocument == null && !mContext.isPasswordProtected()) {
85 Log.i(LOGTAG, "====> mOffice.documentLoad() returned null, trying to restart 'Office' and loading again");
86 mOffice.destroy();
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()
97 );
98 }
99
100 Log.i(LOGTAG, "====> mDocument = " + mDocument);
101
102 mDPI = LOKitShell.getDpi(mContext);
103 mTileWidth = pixelToTwip(TILE_SIZE, mDPI);
104 mTileHeight = pixelToTwip(TILE_SIZE, mDPI);
105
106 if (mDocument != null)
107 mDocument.initializeForRendering();
108
109 if (checkDocument()) {
110 postLoad();
111 mIsReady = true;
112 } else {
113 mIsReady = false;
114 }
115 }
116
120 private void postLoad() {
121 mDocument.setMessageCallback(mMessageCallback);
122
123 resetParts();
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);
128 }
129
130 // Enable headers for Calc documents
131 if (mDocument.getDocumentType() == Document.DOCTYPE_SPREADSHEET) {
132 mContext.initializeCalcHeaders();
133 }
134
135 mDocument.setPart(0);
136
137 setupDocumentFonts();
138
139 LOKitShell.getMainHandler().post(new Runnable() {
140 @Override
141 public void run() {
142 mContext.getDocumentPartViewListAdapter().notifyDataSetChanged();
143 }
144 });
145 }
146
147 public void addPart(){
148 int parts = mDocument.getParts();
149 if(mDocument.getDocumentType() == Document.DOCTYPE_SPREADSHEET){
150 try{
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) {
162 e.printStackTrace();
163 }
164 } else if (mDocument.getDocumentType() == Document.DOCTYPE_PRESENTATION){
165 LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND, ".uno:InsertPage"));
166 }
167
168 String partName = mDocument.getPartName(parts);
169 if (partName.isEmpty()) {
170 partName = getGenericPartName(parts);
171 }
172 mDocument.setPart(parts);
173 resetDocumentSize();
174 final DocumentPartView partView = new DocumentPartView(parts, partName);
175 mContext.getDocumentPartView().add(partView);
176 }
177
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);
184
185 if (partName.isEmpty()) {
186 partName = getGenericPartName(i);
187 }
188 Log.i(LOGTAG, "resetParts: " + partName);
189 mDocument.setPart(i);
190 resetDocumentSize();
191 final DocumentPartView partView = new DocumentPartView(i, partName);
192 mContext.getDocumentPartView().add(partView);
193 }
194 }
195 }
196
197 public void renamePart(String partName) {
198 try{
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();
203 return;
204 }
205 }
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));
213 }else {
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));
219 }
220 }catch (JSONException e){
221 e.printStackTrace();
222 }
223 }
224
225 public void removePart() {
226 try{
227 if (!isSpreadsheet() && !isPresentation()) {
228 //document must be spreadsheet or presentation
229 return;
230 }
231
232 if(isPresentation()){
233 LOKitShell.sendEvent(new LOEvent(LOEvent.UNO_COMMAND_NOTIFY, ".uno:DeletePage", true));
234 return;
235 }
236
237 if(getPartsCount() < 2){
238 return;
239 }
240
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){
248 e.printStackTrace();
249 }
250 }
251
252 @Override
253 public boolean saveDocumentAs(final String filePath, String format, boolean takeOwnership) {
254 String options = "";
255 if (takeOwnership) {
256 options = "TakeOwnership";
257 }
258
259 final String newFilePath = "file://" + filePath;
260 Log.d("saveFilePathURL", newFilePath);
261 LOKitShell.showProgressSpinner(mContext);
262 mDocument.saveAs(newFilePath, format, options);
263 final boolean ok;
264 if (!mOffice.getError().isEmpty()){
265 ok = true;
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");
272 } else {
273 LOKitShell.getMainHandler().post(new Runnable() {
274 @Override
275 public void run() {
276 // There was some error
277 mContext.showCustomStatusMessage(mContext.getString(R.string.unable_to_save));
278 }
279 });
280 }
281 } else {
282 ok = false;
283 if (format.equals("svg")) {
284 // successfully created temp slideshow svg file
285 LOKitShell.getMainHandler().post(new Runnable() {
286 @Override
287 public void run() {
288 mContext.startPresentation(newFilePath);
289 }
290 });
291 } else if (takeOwnership) {
292 mInputFile = filePath;
293 }
294 }
295 LOKitShell.hideProgressSpinner(mContext);
296 return ok;
297 }
298
299 @Override
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);
310
311 Log.w(LOGTAG, "Cannot determine file format from document. Not saving.");
312 return false;
313 }
314
315 public void printDocument() {
316 if (Build.VERSION.SDK_INT < 19) {
317 mContext.showCustomStatusMessage(mContext.getString(R.string.printing_not_supported));
318 return;
319 }
320
321 String mInputFileName = (new File(mInputFile)).getName();
322 String file = mInputFileName.substring(0,(mInputFileName.length()-3))+"pdf";
323 String cacheFile = mContext.getExternalCacheDir().getAbsolutePath() + "/" + file;
324 mDocument.saveAs("file://"+cacheFile,"pdf","");
325 try {
326 PrintManager printManager = (PrintManager) mContext.getSystemService(Context.PRINT_SERVICE);
327 PrintDocumentAdapter printAdapter = new PDFDocumentAdapter(mContext, cacheFile);
328 printManager.print("Document", printAdapter, new PrintAttributes.Builder().build());
329
330 } catch (Exception e) {
331 e.printStackTrace();
332 }
333 }
334
335 public void saveDocument(){
336 mContext.saveDocument();
337 }
338
339 private void setupDocumentFonts() {
340 String values = mDocument.getCommandValues(".uno:CharFontName");
341 if (values == null || values.isEmpty())
342 return;
343
344 mContext.getFontController().parseJson(values);
345 mContext.getFontController().setupFontViews();
346 }
347
348 private String getGenericPartName(int i) {
349 if (mDocument == null) {
350 return "";
351 }
352 switch (mDocument.getDocumentType()) {
353 case Document.DOCTYPE_DRAWING:
354 case Document.DOCTYPE_TEXT:
355 return mContext.getString(R.string.page) + " " + (i + 1);
356 case Document.DOCTYPE_SPREADSHEET:
357 return mContext.getString(R.string.sheet) + " " + (i + 1);
358 case Document.DOCTYPE_PRESENTATION:
359 return mContext.getString(R.string.slide) + " " + (i + 1);
360 case Document.DOCTYPE_OTHER:
361 default:
362 return mContext.getString(R.string.part) + " " + (i + 1);
363 }
364 }
365
366 static float twipToPixel(float input, float dpi) {
367 return input / 1440.0f * dpi;
368 }
369
370 private static float pixelToTwip(float input, float dpi) {
371 return (input / dpi) * 1440.0f;
372 }
373
374
378 @Override
379 public int getPartsCount() {
380 return mDocument.getParts();
381 }
382
386 public String getPartPageRectangles() {
387 return mDocument.getPartPageRectangles();
388 }
389
393 public String getCalcHeaders() {
394 long nX = 0;
395 long nY = 0;
396 long nWidth = mDocument.getDocumentWidth();
397 long nHeight = mDocument.getDocumentHeight();
398 return mDocument.getCommandValues(".uno:ViewRowColumnHeaders?x=" + nX + "&y=" + nY
399 + "&width=" + nWidth + "&height=" + nHeight);
400 }
401
405 @Override
406 public void onSwipeLeft() {
407 if (mDocument.getDocumentType() == Document.DOCTYPE_PRESENTATION &&
408 getCurrentPartNumber() < getPartsCount()-1) {
409 LOKitShell.sendChangePartEvent(getCurrentPartNumber()+1);
410 }
411 }
412
416 @Override
417 public void onSwipeRight() {
418 if (mDocument.getDocumentType() == Document.DOCTYPE_PRESENTATION &&
419 getCurrentPartNumber() > 0) {
420 LOKitShell.sendChangePartEvent(getCurrentPartNumber()-1);
421 }
422 }
423
424 private boolean checkDocument() {
425 String error = null;
426 boolean ret;
427
428 if (mDocument == null || !mOffice.getError().isEmpty()) {
429 error = "Cannot open " + mInputFile + ": " + mOffice.getError();
430 ret = false;
431 } else {
432 ret = resetDocumentSize();
433 if (!ret) {
434 error = "Document returned an invalid size or the document is empty.";
435 }
436 }
437
438 if (!ret && !mContext.isPasswordProtected()) {
439 final String message = error;
440 LOKitShell.getMainHandler().post(new Runnable() {
441 @Override
442 public void run() {
443 mContext.showAlertDialog(message);
444 }
445 });
446 } else if (!ret && mContext.isPasswordProtected()) {
447 mContext.finish();
448 }
449
450 return ret;
451 }
452
453 private boolean resetDocumentSize() {
454 mWidthTwip = mDocument.getDocumentWidth();
455 mHeightTwip = mDocument.getDocumentHeight();
456
457 if (mWidthTwip == 0 || mHeightTwip == 0) {
458 Log.e(LOGTAG, "Document size zero - last error: " + mOffice.getError());
459 return false;
460 } else {
461 Log.i(LOGTAG, "Reset document size: " + mDocument.getDocumentWidth() + " x " + mDocument.getDocumentHeight());
462 }
463
464 return true;
465 }
466
467 @Override
468 public void setDocumentSize(int pageWidth, int pageHeight){
469 mWidthTwip = pageWidth;
470 mHeightTwip = pageHeight;
471 }
472
476 @Override
477 public int getPageWidth() {
478 return (int) twipToPixel(mWidthTwip, mDPI);
479 }
480
484 @Override
485 public int getPageHeight() {
486 return (int) twipToPixel(mHeightTwip, mDPI);
487 }
488
492 @Override
493 public boolean isReady() {
494 return mIsReady;
495 }
496
500 @Override
501 public CairoImage createTile(float x, float y, IntSize tileSize, float zoom) {
502 ByteBuffer buffer = DirectBufferAllocator.guardedAllocate(tileSize.width * tileSize.height * 4);
503 if (buffer == null)
504 return null;
505
506 CairoImage image = new BufferedCairoImage(buffer, tileSize.width, tileSize.height, CairoImage.FORMAT_ARGB32);
507 rerenderTile(image, x, y, tileSize, zoom);
508 return image;
509 }
510
514 @Override
515 public void rerenderTile(CairoImage image, float x, float y, IntSize tileSize, float zoom) {
516 if (mDocument != null && image.getBuffer() != null) {
517 float twipX = pixelToTwip(x, mDPI) / zoom;
518 float twipY = pixelToTwip(y, mDPI) / zoom;
519 float twipWidth = mTileWidth / zoom;
520 float twipHeight = mTileHeight / zoom;
521 long start = System.currentTimeMillis() - objectCreationTime;
522
523 //Log.i(LOGTAG, "paintTile >> @" + start + " (" + tileSize.width + " " + tileSize.height + " " + (int) twipX + " " + (int) twipY + " " + (int) twipWidth + " " + (int) twipHeight + ")");
524 mDocument.paintTile(image.getBuffer(), tileSize.width, tileSize.height, (int) twipX, (int) twipY, (int) twipWidth, (int) twipHeight);
525
526 long stop = System.currentTimeMillis() - objectCreationTime;
527 //Log.i(LOGTAG, "paintTile << @" + stop + " elapsed: " + (stop - start));
528 } else {
529 if (mDocument == null) {
530 Log.e(LOGTAG, "Document is null!!");
531 }
532 }
533 }
534
538 @Override
539 public Bitmap thumbnail(int size) {
540 int widthPixel = getPageWidth();
541 int heightPixel = getPageHeight();
542
543 if (widthPixel > heightPixel) {
544 double ratio = heightPixel / (double) widthPixel;
545 widthPixel = size;
546 heightPixel = (int) (widthPixel * ratio);
547 } else {
548 double ratio = widthPixel / (double) heightPixel;
549 heightPixel = size;
550 widthPixel = (int) (heightPixel * ratio);
551 }
552
553 Log.w(LOGTAG, "Thumbnail size: " + getPageWidth() + " " + getPageHeight() + " " + widthPixel + " " + heightPixel);
554
555 ByteBuffer buffer = ByteBuffer.allocateDirect(widthPixel * heightPixel * 4);
556 if (mDocument != null)
557 mDocument.paintTile(buffer, widthPixel, heightPixel, 0, 0, (int) mWidthTwip, (int) mHeightTwip);
558
559 Bitmap bitmap = null;
560 try {
561 bitmap = Bitmap.createBitmap(widthPixel, heightPixel, Bitmap.Config.ARGB_8888);
562 bitmap.copyPixelsFromBuffer(buffer);
563 } catch (IllegalArgumentException e) {
564 Log.e(LOGTAG, "width (" + widthPixel + ") and height (" + heightPixel + ") must not be 0! (ToDo: likely timing issue)");
565 }
566 if (bitmap == null) {
567 Log.w(LOGTAG, "Thumbnail not created!");
568 }
569 return bitmap;
570 }
571
575 @Override
576 public void close() {
577 Log.i(LOGTAG, "Document destroyed: " + mInputFile);
578 if (mDocument != null) {
579 mDocument.destroy();
580 mDocument = null;
581 }
582 }
583
587 @Override
588 public boolean isDrawing() {
589 return mDocument != null && mDocument.getDocumentType() == Document.DOCTYPE_DRAWING;
590 }
591
595 @Override
596 public boolean isTextDocument() {
597 return mDocument != null && mDocument.getDocumentType() == Document.DOCTYPE_TEXT;
598 }
599
603 @Override
604 public boolean isSpreadsheet() {
605 return mDocument != null && mDocument.getDocumentType() == Document.DOCTYPE_SPREADSHEET;
606 }
607
611 @Override
612 public boolean isPresentation(){
613 return mDocument != null && mDocument.getDocumentType() == Document.DOCTYPE_PRESENTATION;
614 }
615
619 private int getCharCode(KeyEvent keyEvent) {
620 switch (keyEvent.getKeyCode())
621 {
622 case KeyEvent.KEYCODE_DEL:
623 case KeyEvent.KEYCODE_ENTER:
624 return 0;
625 }
626 return keyEvent.getUnicodeChar();
627 }
628
633 private int getKeyCode(KeyEvent keyEvent) {
634 switch (keyEvent.getKeyCode()) {
635 case KeyEvent.KEYCODE_DEL:
636 return com.sun.star.awt.Key.BACKSPACE;
637 case KeyEvent.KEYCODE_ENTER:
638 return com.sun.star.awt.Key.RETURN;
639 }
640 return 0;
641 }
642
646 @Override
647 public void sendKeyEvent(KeyEvent keyEvent) {
648 switch (keyEvent.getAction()) {
649 case KeyEvent.ACTION_MULTIPLE:
650 String keyString = keyEvent.getCharacters();
651 for (int i = 0; i < keyString.length(); i++) {
652 int codePoint = keyString.codePointAt(i);
653 mDocument.postKeyEvent(Document.KEY_EVENT_PRESS, codePoint, getKeyCode(keyEvent));
654 }
655 break;
656 case KeyEvent.ACTION_DOWN:
657 mDocument.postKeyEvent(Document.KEY_EVENT_PRESS, getCharCode(keyEvent), getKeyCode(keyEvent));
658 break;
659 case KeyEvent.ACTION_UP:
660 mDocument.postKeyEvent(Document.KEY_EVENT_RELEASE, getCharCode(keyEvent), getKeyCode(keyEvent));
661 break;
662 }
663 }
664
665 private void mouseButton(int type, PointF inDocument, int numberOfClicks, float zoomFactor) {
666 int x = (int) pixelToTwip(inDocument.x, mDPI);
667 int y = (int) pixelToTwip(inDocument.y, mDPI);
668
669 mDocument.setClientZoom(TILE_SIZE, TILE_SIZE, (int) (mTileWidth / zoomFactor), (int) (mTileHeight / zoomFactor));
670 mDocument.postMouseEvent(type, x, y, numberOfClicks, Document.MOUSE_BUTTON_LEFT, Document.KEYBOARD_MODIFIER_NONE);
671 }
672
676 @Override
677 public void mouseButtonDown(PointF documentCoordinate, int numberOfClicks, float zoomFactor) {
678 mouseButton(Document.MOUSE_EVENT_BUTTON_DOWN, documentCoordinate, numberOfClicks, zoomFactor);
679 }
680
684 @Override
685 public void mouseButtonUp(PointF documentCoordinate, int numberOfClicks, float zoomFactor) {
686 mouseButton(Document.MOUSE_EVENT_BUTTON_UP, documentCoordinate, numberOfClicks, zoomFactor);
687 }
688
693 @Override
694 public void postUnoCommand(String command, String arguments) {
695 postUnoCommand(command, arguments, false);
696 }
697
703 @Override
704 public void postUnoCommand(String command, String arguments, boolean notifyWhenFinished) {
705 mDocument.postUnoCommand(command, arguments, notifyWhenFinished);
706 }
707
708 private void setTextSelection(int type, PointF documentCoordinate) {
709 int x = (int) pixelToTwip(documentCoordinate.x, mDPI);
710 int y = (int) pixelToTwip(documentCoordinate.y, mDPI);
711 mDocument.setTextSelection(type, x, y);
712 }
713
717 @Override
718 public void setTextSelectionStart(PointF documentCoordinate) {
719 setTextSelection(Document.SET_TEXT_SELECTION_START, documentCoordinate);
720 }
721
725 @Override
726 public void setTextSelectionEnd(PointF documentCoordinate) {
727 setTextSelection(Document.SET_TEXT_SELECTION_END, documentCoordinate);
728 }
729
733 @Override
734 public void setTextSelectionReset(PointF documentCoordinate) {
735 setTextSelection(Document.SET_TEXT_SELECTION_RESET, documentCoordinate);
736 }
737
742 @Override
743 public String getTextSelection(String mimeType) {
744 return mDocument.getTextSelection(mimeType);
745 }
746
753 @Override
754 public boolean paste(String mimeType, String data) {
755 return mDocument.paste(mimeType, data);
756 }
757
758
762 @Override
763 public void setGraphicSelectionStart(PointF documentCoordinate) {
764 setGraphicSelection(Document.SET_GRAPHIC_SELECTION_START, documentCoordinate);
765 }
766
770 @Override
771 public void setGraphicSelectionEnd(PointF documentCoordinate) {
772 setGraphicSelection(Document.SET_GRAPHIC_SELECTION_END, documentCoordinate);
773 }
774
775 private void setGraphicSelection(int type, PointF documentCoordinate) {
776 int x = (int) pixelToTwip(documentCoordinate.x, mDPI);
777 int y = (int) pixelToTwip(documentCoordinate.y, mDPI);
778 LibreOfficeMainActivity.setDocumentChanged(true);
779 mDocument.setGraphicSelection(type, x, y);
780 }
781
782 @Override
783 protected void finalize() throws Throwable {
784 close();
785 super.finalize();
786 }
787
791 @Override
792 public void changePart(int partIndex) {
793 if (mDocument == null)
794 return;
795
796 mDocument.setPart(partIndex);
797 resetDocumentSize();
798 }
799
803 @Override
804 public int getCurrentPartNumber() {
805 if (mDocument == null)
806 return 0;
807
808 return mDocument.getPart();
809 }
810
811 public void setDocumentPassword(String url, String password) {
812 mOffice.setDocumentPassword(url, password);
813 }
814
815 public Document.MessageCallback getMessageCallback() {
816 return mMessageCallback;
817 }
818}
819
820// vim:set shiftwidth=4 softtabstop=4 expandtab:
#define LOGTAG
A Cairo image that simply saves a buffer of pixel data.
bool close
float y
float x
const char * name
def stop(arg=None)
def run(arg=None, arg2=-1)
OString OOO_DLLPUBLIC_TEST getTextSelection(const css::uno::Reference< css::datatransfer::XTransferable > &xTransferable, OString mimeType)
size
Status finalize()
filePath
int i
index
std::vector< char * > values
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
float pixelToTwip(float fInput, float zoom)
float twipToPixel(float fInput, float zoom)
const sal_uInt8 R