android/lib/src/main/cpp/androidapp.cpp | 21 + android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java | 130 +++++++--- loleaflet/src/control/Control.ContextToolbar.js | 6 3 files changed, 123 insertions(+), 34 deletions(-)
New commits: commit 73f839164a3a2bd0dbec31aaff8c2fcbb7f331b3 Author: kaishu-sahu <kaishusahu...@gmail.com> AuthorDate: Mon Jun 17 06:00:00 2019 +0530 Commit: Jan Holesovsky <ke...@collabora.com> CommitDate: Mon Jul 22 12:03:09 2019 +0200 android: add cut, copy, paste support to document viewer. Change-Id: I85c3a602ab7e98272a193c392bf7bcfd1050dc90 Reviewed-on: https://gerrit.libreoffice.org/74127 Reviewed-by: Jan Holesovsky <ke...@collabora.com> Tested-by: Jan Holesovsky <ke...@collabora.com> diff --git a/android/lib/src/main/cpp/androidapp.cpp b/android/lib/src/main/cpp/androidapp.cpp index f15ebc6a6..5f89ffcc4 100644 --- a/android/lib/src/main/cpp/androidapp.cpp +++ b/android/lib/src/main/cpp/androidapp.cpp @@ -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: */ diff --git a/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java b/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java index 7bd40af27..3d6838a12 100644 --- a/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java +++ b/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java @@ -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; - } - - @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); + 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); + } + }); } - }.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: */ diff --git a/loleaflet/src/control/Control.ContextToolbar.js b/loleaflet/src/control/Control.ContextToolbar.js index 532cbbd62..8d97e29c0 100644 --- a/loleaflet/src/control/Control.ContextToolbar.js +++ b/loleaflet/src/control/Control.ContextToolbar.js @@ -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'); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits