android: add cut, copy, paste support to document viewer.
Change-Id: I85c3a602ab7e98272a193c392bf7bcfd1050dc90 Reviewed-on: https://gerrit.libreoffice.org/74127 Reviewed-by: Jan Holesovsky <kendy@collabora.com> Tested-by: Jan Holesovsky <kendy@collabora.com>
This commit is contained in:
parent
f5a67c696d
commit
73f839164a
3 changed files with 123 additions and 34 deletions
|
@ -332,4 +332,25 @@ Java_org_libreoffice_androidlib_LOActivity_saveAs(JNIEnv *env, jobject instance,
|
|||
env->ReleaseStringUTFChars(fileUri_, fileUri);
|
||||
env->ReleaseStringUTFChars(format_, format);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_org_libreoffice_androidlib_LOActivity_getTextSelection(JNIEnv *env, jobject instance) {
|
||||
|
||||
return env->NewStringUTF(getLOKDocument()->getTextSelection("text/plain;charset=utf-8"));
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_libreoffice_androidlib_LOActivity_paste(JNIEnv *env, jobject instance, jstring mimeType_,
|
||||
jstring data_) {
|
||||
const char *mimeType = env->GetStringUTFChars(mimeType_, 0);
|
||||
const char *data = env->GetStringUTFChars(data_, 0);
|
||||
const size_t nSize = env->GetStringLength(data_);
|
||||
|
||||
getLOKDocument()->paste(mimeType, data, nSize);
|
||||
|
||||
env->ReleaseStringUTFChars(mimeType_, mimeType);
|
||||
env->ReleaseStringUTFChars(data_, data);
|
||||
}
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
package org.libreoffice.androidlib;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipDescription;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Intent;
|
||||
|
@ -23,6 +26,7 @@ import android.os.AsyncTask;
|
|||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.print.PrintAttributes;
|
||||
import android.print.PrintDocumentAdapter;
|
||||
|
@ -83,6 +87,12 @@ public class LOActivity extends AppCompatActivity {
|
|||
private boolean isDocEditable = false;
|
||||
private boolean isDocDebuggable = BuildConfig.DEBUG;
|
||||
|
||||
private ClipboardManager clipboardManager;
|
||||
private ClipData clipData;
|
||||
private Thread nativeMsgThread;
|
||||
private Handler nativeHandler;
|
||||
private Looper nativeLooper;
|
||||
|
||||
private ValueCallback<Uri[]> valueCallback;
|
||||
public static final int REQUEST_SELECT_FILE = 555;
|
||||
|
||||
|
@ -282,6 +292,18 @@ public class LOActivity extends AppCompatActivity {
|
|||
|
||||
mainHandler = new Handler(getMainLooper());
|
||||
|
||||
clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
|
||||
nativeMsgThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Looper.prepare();
|
||||
nativeLooper = Looper.myLooper();
|
||||
nativeHandler = new Handler(nativeLooper);
|
||||
Looper.loop();
|
||||
}
|
||||
});
|
||||
nativeMsgThread.start();
|
||||
|
||||
mWebView.setWebChromeClient(new WebChromeClient() {
|
||||
@Override
|
||||
public boolean onShowFileChooser(WebView mWebView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
|
||||
|
@ -406,6 +428,7 @@ public class LOActivity extends AppCompatActivity {
|
|||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
Log.i(TAG, "onDestroy() - we know we are leaving the document");
|
||||
nativeLooper.quit();
|
||||
postMobileMessageNative("BYE");
|
||||
}
|
||||
|
||||
|
@ -497,20 +520,62 @@ public class LOActivity extends AppCompatActivity {
|
|||
}
|
||||
|
||||
/**
|
||||
* return true to pass the message to the native part and false to block the message
|
||||
* return true to pass the message to the native part or false to block the message
|
||||
*/
|
||||
boolean interceptMsgFromWebView(String message) {
|
||||
if (message.equals("PRINT")) {
|
||||
mainHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
initiatePrint();
|
||||
switch (message) {
|
||||
case "PRINT":
|
||||
mainHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
LOActivity.this.initiatePrint();
|
||||
}
|
||||
});
|
||||
return false;
|
||||
case "SLIDESHOW":
|
||||
initiateSlideShow();
|
||||
return false;
|
||||
case "uno .uno:Paste":
|
||||
clipData = clipboardManager.getPrimaryClip();
|
||||
if (clipData != null) {
|
||||
if (clipData.getDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
|
||||
final ClipData.Item clipItem = clipData.getItemAt(0);
|
||||
nativeHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
LOActivity.this.paste("text/plain;charset=utf-16", clipItem.getText().toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return false;
|
||||
} else if (message.equals("SLIDESHOW")) {
|
||||
initiateSlideShow();
|
||||
return false;
|
||||
break;
|
||||
case "uno .uno:Copy": {
|
||||
nativeHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String tempSelectedText = LOActivity.this.getTextSelection();
|
||||
if (!tempSelectedText.equals("")) {
|
||||
clipData = ClipData.newPlainText(ClipDescription.MIMETYPE_TEXT_PLAIN, tempSelectedText);
|
||||
clipboardManager.setPrimaryClip(clipData);
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "uno .uno:Cut": {
|
||||
nativeHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String tempSelectedText = LOActivity.this.getTextSelection();
|
||||
if (!tempSelectedText.equals("")) {
|
||||
clipData = ClipData.newPlainText(ClipDescription.MIMETYPE_TEXT_PLAIN, tempSelectedText);
|
||||
clipboardManager.setPrimaryClip(clipData);
|
||||
}
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -526,34 +591,37 @@ public class LOActivity extends AppCompatActivity {
|
|||
.setCancelable(false)
|
||||
.setView(R.layout.lolib_dialog_loading)
|
||||
.create();
|
||||
new AsyncTask<Void, Void, String>() {
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
slideShowProgress.show();
|
||||
}
|
||||
|
||||
nativeHandler.post(new Runnable() {
|
||||
@Override
|
||||
protected String doInBackground(Void... voids) {
|
||||
public void run() {
|
||||
LOActivity.this.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
slideShowProgress.show();
|
||||
}
|
||||
});
|
||||
Log.v(TAG, "saving svg for slideshow by " + Thread.currentThread().getName());
|
||||
String slideShowFileUri = new File(getCacheDir(), "slideShow.svg").toURI().toString();
|
||||
saveAs(slideShowFileUri, "svg");
|
||||
return slideShowFileUri;
|
||||
final String slideShowFileUri = new File(LOActivity.this.getCacheDir(), "slideShow.svg").toURI().toString();
|
||||
LOActivity.this.saveAs(slideShowFileUri, "svg");
|
||||
LOActivity.this.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
slideShowProgress.dismiss();
|
||||
Intent slideShowActIntent = new Intent(LOActivity.this, SlideShowActivity.class);
|
||||
slideShowActIntent.putExtra(SlideShowActivity.SVG_URI_KEY, slideShowFileUri);
|
||||
LOActivity.this.startActivity(slideShowActIntent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String slideShowFileUri) {
|
||||
super.onPostExecute(slideShowFileUri);
|
||||
slideShowProgress.dismiss();
|
||||
Intent slideShowActIntent = new Intent(LOActivity.this, SlideShowActivity.class);
|
||||
slideShowActIntent.putExtra(SlideShowActivity.SVG_URI_KEY, slideShowFileUri);
|
||||
startActivity(slideShowActIntent);
|
||||
}
|
||||
}.execute();
|
||||
});
|
||||
}
|
||||
|
||||
public native void saveAs(String fileUri, String format);
|
||||
|
||||
public native String getTextSelection();
|
||||
|
||||
public native void paste(String mimeType, String data);
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
||||
|
|
|
@ -36,7 +36,7 @@ L.Control.ContextToolbar = L.Control.extend({
|
|||
},
|
||||
|
||||
_initLayout: function () {
|
||||
if (window.ThisIsTheiOSApp)
|
||||
if (window.ThisIsTheiOSApp || window.ThisIsTheAndroidApp)
|
||||
this._container = L.DomUtil.create('div', 'loleaflet-ios-context-toolbar');
|
||||
else
|
||||
this._container = L.DomUtil.create('div', 'loleaflet-context-toolbar');
|
||||
|
@ -47,7 +47,7 @@ L.Control.ContextToolbar = L.Control.extend({
|
|||
stopEvents = 'touchstart touchmove touchend mousedown mousemove mouseout mouseover mouseup mousewheel click scroll',
|
||||
container;
|
||||
|
||||
if (window.ThisIsTheiOSApp)
|
||||
if (window.ThisIsTheiOSApp || window.ThisIsTheAndroidApp)
|
||||
container = L.DomUtil.create('table', 'loleaflet-ios-context-table', this._container);
|
||||
else
|
||||
container = L.DomUtil.create('table', 'loleaflet-context-table', this._container);
|
||||
|
@ -55,7 +55,7 @@ L.Control.ContextToolbar = L.Control.extend({
|
|||
var tbody = L.DomUtil.create('tbody', '', container),
|
||||
tr = L.DomUtil.create('tr', '', tbody);
|
||||
|
||||
if (window.ThisIsTheiOSApp) {
|
||||
if (window.ThisIsTheiOSApp || window.ThisIsTheAndroidApp) {
|
||||
this._leftroundedend = L.DomUtil.create(tagTd, 'loleaflet-ios-context-button loleaflet-ios-context-left', tr);
|
||||
this._cut = L.DomUtil.create(tagTd, 'loleaflet-ios-context-button loleaflet-ios-context-first-and-middle-entry loleaflet-ios-context-cut', tr);
|
||||
this._cut.innerHTML = _UNO('.uno:Cut');
|
||||
|
|
Loading…
Reference in a new issue