summaryrefslogtreecommitdiff
path: root/platform/android
diff options
context:
space:
mode:
authorFred Ross-Perry <fross-perry@conceptuamath.com>2016-08-20 15:08:02 -0700
committerfred ross-perry <fredross-perry@Fred-Ross-Perrys-Computer.local>2016-09-14 08:53:32 -0700
commit7d42acddc4f03e7e99d7012ead554ea7fa93c1d0 (patch)
tree7798450acf172b1689f2e3059aa6dfbc48ec526b /platform/android
parentc315d719236ffe5cbaebfe891400a67ee75ae2b5 (diff)
downloadmupdf-7d42acddc4f03e7e99d7012ead554ea7fa93c1d0.tar.xz
Android example - file toolbar icons, password dialog
add five icons to the File toolbar (not yet functioning) add a dialog to collect the password from the user for protected documents.
Diffstat (limited to 'platform/android')
-rw-r--r--platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocActivityView.java107
-rwxr-xr-xplatform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocViewBase.java21
-rw-r--r--platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/Utilities.java383
-rwxr-xr-xplatform/android/example/mupdf/src/main/res/drawable/icon_open_in.xml22
-rwxr-xr-xplatform/android/example/mupdf/src/main/res/drawable/icon_print.xml39
-rwxr-xr-x[-rw-r--r--]platform/android/example/mupdf/src/main/res/drawable/icon_save.xml0
-rw-r--r--platform/android/example/mupdf/src/main/res/drawable/icon_save_as.xml44
-rwxr-xr-xplatform/android/example/mupdf/src/main/res/drawable/icon_share.xml32
-rw-r--r--platform/android/example/mupdf/src/main/res/layout/file_toolbar.xml111
-rw-r--r--platform/android/example/mupdf/src/main/res/layout/pages_toolbar.xml3
-rw-r--r--platform/android/example/mupdf/src/main/res/layout/password_prompt.xml27
-rw-r--r--platform/android/example/mupdf/src/main/res/values/strings.xml2
12 files changed, 780 insertions, 11 deletions
diff --git a/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocActivityView.java b/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocActivityView.java
index 5d5834be..6a2cca11 100644
--- a/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocActivityView.java
+++ b/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocActivityView.java
@@ -19,7 +19,9 @@ import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TabHost;
import android.widget.TextView;
+import android.widget.Toast;
+import com.artifex.mupdf.fitz.Document;
import com.artifex.mupdf.fitz.Link;
import com.artifex.mupdf.fitz.Outline;
import com.artifex.mupdf.fitz.R;
@@ -48,6 +50,12 @@ public class DocActivityView extends FrameLayout implements TabHost.OnTabChangeL
private ImageButton mSearchPreviousButton;
private ImageButton mBackButton;
+ private ImageButton mSaveButton;
+ private ImageButton mSaveAsButton;
+ private ImageButton mPrintButton;
+ private ImageButton mShareButton;
+ private ImageButton mOpenInButton;
+
public DocActivityView(Context context)
{
super(context);
@@ -308,6 +316,21 @@ public class DocActivityView extends FrameLayout implements TabHost.OnTabChangeL
mSearchText = (EditText) findViewById(R.id.search_text_input);
mSearchText.setOnClickListener(this);
+ mSaveButton = (ImageButton)findViewById(R.id.save_button);
+ mSaveButton.setOnClickListener(this);
+
+ mSaveAsButton = (ImageButton)findViewById(R.id.save_as_button);
+ mSaveAsButton.setOnClickListener(this);
+
+ mPrintButton = (ImageButton)findViewById(R.id.print_button);
+ mPrintButton.setOnClickListener(this);
+
+ mShareButton = (ImageButton)findViewById(R.id.share_button);
+ mShareButton.setOnClickListener(this);
+
+ mOpenInButton = (ImageButton)findViewById(R.id.open_in_button);
+ mOpenInButton.setOnClickListener(this);
+
// this listener will
mSearchText.setOnEditorActionListener(new TextView.OnEditorActionListener()
{
@@ -329,8 +352,54 @@ public class DocActivityView extends FrameLayout implements TabHost.OnTabChangeL
mSearchPreviousButton = (ImageButton)findViewById(R.id.search_previous_button);
mSearchPreviousButton.setOnClickListener(this);
+ mDoc = new Document(path);
+
+ if (mDoc.needsPassword())
+ {
+ askForPassword();
+ }
+ else
+ {
+ afterPassword();
+ }
+ }
+
+ private Document mDoc;
+
+ private void askForPassword()
+ {
+ Utilities.passwordDialog((Activity) getContext(), new Utilities.passwordDialogListener()
+ {
+ @Override
+ public void onOK(String password)
+ {
+ // yes
+ boolean ok = mDoc.authenticatePassword(password);
+ if (ok)
+ {
+ afterPassword();
+ mDocView.requestLayout();
+ }
+ else
+ {
+ askForPassword();
+ }
+ }
+
+ @Override
+ public void onCancel()
+ {
+ mDoc.destroy();
+ if (mDoneListener != null)
+ mDoneListener.done();
+ }
+ });
+ }
+
+ private void afterPassword()
+ {
// start the views
- mDocView.start(path);
+ mDocView.start(mDoc);
if (usePagesView())
{
mDocPagesView.clone(mDocView);
@@ -421,6 +490,17 @@ public class DocActivityView extends FrameLayout implements TabHost.OnTabChangeL
onSearchPreviousButton();
if (v == mBackButton)
onBackButton();
+
+ if (v == mSaveButton)
+ onSaveButton();
+ if (v == mSaveAsButton)
+ onSaveAsButton();
+ if (v == mPrintButton)
+ onPrintButton();
+ if (v == mShareButton)
+ onShareButton();
+ if (v == mOpenInButton)
+ onOpenInButton();
}
public void onSearchNextButton()
@@ -530,6 +610,31 @@ public class DocActivityView extends FrameLayout implements TabHost.OnTabChangeL
mDoneListener.done();
}
+ private void onSaveButton()
+ {
+ Toast.makeText(getContext(),"onSaveButton", Toast.LENGTH_SHORT).show();
+ }
+
+ private void onSaveAsButton()
+ {
+ Toast.makeText(getContext(),"onSaveAsButton", Toast.LENGTH_SHORT).show();
+ }
+
+ private void onPrintButton()
+ {
+ Toast.makeText(getContext(),"onPrintButton", Toast.LENGTH_SHORT).show();
+ }
+
+ private void onShareButton()
+ {
+ Toast.makeText(getContext(),"onShareButton", Toast.LENGTH_SHORT).show();
+ }
+
+ private void onOpenInButton()
+ {
+ Toast.makeText(getContext(),"onOpenInButton", Toast.LENGTH_SHORT).show();
+ }
+
private OnDoneListener mDoneListener = null;
public void setOnDoneListener(OnDoneListener l) {mDoneListener = l;}
public interface OnDoneListener
diff --git a/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocViewBase.java b/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocViewBase.java
index 9c8ab998..6152851c 100755
--- a/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocViewBase.java
+++ b/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/DocViewBase.java
@@ -153,11 +153,11 @@ public class DocViewBase
DocPageView.bitmapMarginY = (h - screenH) / 2;
}
- public void start(final String path)
+ public void start (Document doc)
{
+ mDoc = doc;
mAdapter = new PageAdapter(mContext);
mAdapter.setWidth(getWidth());
- mDoc = new Document(path);
mAdapter.setDocument(mDoc);
mScale = 1.0f;
mStarted = true;
@@ -501,7 +501,10 @@ public class DocViewBase
protected int getPageCount()
{
- return getAdapter().getCount();
+ Adapter adapter = getAdapter();
+ if (null != adapter)
+ return adapter.getCount();
+ return 0;
}
protected void onLayout(boolean changed, int left, int top, int right, int bottom)
@@ -921,10 +924,14 @@ public class DocViewBase
}
// get rid of bitmaps
- bitmaps[0].recycle();
- bitmaps[0] = null;
- bitmaps[1].recycle();
- bitmaps[1] = null;
+ for (int i=0;i<bitmaps.length;i++)
+ {
+ if (null != bitmaps[i])
+ {
+ bitmaps[i].recycle();
+ bitmaps[i] = null;
+ }
+ }
}
public boolean finished()
diff --git a/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/Utilities.java b/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/Utilities.java
new file mode 100644
index 00000000..cecfae0e
--- /dev/null
+++ b/platform/android/example/mupdf/src/main/java/com/artifex/mupdf/android/Utilities.java
@@ -0,0 +1,383 @@
+package com.artifex.mupdf.android;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.webkit.MimeTypeMap;
+import android.widget.EditText;
+
+import com.artifex.mupdf.fitz.R;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class Utilities
+{
+ public static boolean copyFile(String src, String dst, boolean overwrite)
+ {
+ File dstf = new File(dst);
+ File srcf = new File(src);
+
+ // if we can't overwrite, error
+ if (!overwrite && dstf.exists())
+ return false;
+
+ // if we must overwrite but can't delete, error
+ if (overwrite && dstf.exists()) {
+ boolean deleted = deleteFile(dst);
+ if (!deleted)
+ return false;
+ }
+
+ // now copy
+ copyWithStreams(srcf, dstf);
+
+ return true;
+ }
+
+ private static void copyWithStreams(File aSourceFile, File aTargetFile)
+ {
+ InputStream inStream = null;
+ OutputStream outStream = null;
+
+ try
+ {
+ try
+ {
+ byte[] bucket = new byte[32*1024];
+ inStream = new BufferedInputStream(new FileInputStream(aSourceFile));
+ outStream = new BufferedOutputStream(new FileOutputStream(aTargetFile, false));
+ int bytesRead = 0;
+ while(bytesRead != -1)
+ {
+ bytesRead = inStream.read(bucket); //-1, 0, or more
+ if(bytesRead > 0){
+ outStream.write(bucket, 0, bytesRead);
+ }
+ }
+ }
+ finally
+ {
+ if (inStream != null)
+ inStream.close();
+ if (outStream != null)
+ outStream.close();
+ }
+ }
+ catch (FileNotFoundException ex){
+ }
+ catch (IOException ex){
+ }
+ }
+
+ public static boolean deleteFile (String path)
+ {
+ try
+ {
+ File fileToDelete = new File(path);
+ if (fileToDelete.exists()) {
+ fileToDelete.delete();
+ }
+ }
+ catch(Exception e)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public static boolean renameFile (String oldPath, String newPath)
+ {
+ File fOld = new File(oldPath);
+ File fNew = new File(newPath);
+ return fOld.renameTo(fNew);
+ }
+
+ // this function safely replaces a file by first renaming it
+ // and, if the copy fails, renaming it back.
+ public static boolean replaceFile (String srcPath, String dstPath)
+ {
+ // source file must exist
+ File srcFile = new File(srcPath);
+ if (!srcFile.exists())
+ return false;
+
+ // destination file may or may not exist
+ File dstFile = new File(dstPath);
+ boolean dstExists = dstFile.exists();
+ String tmp = dstPath+"xxx";
+
+ // if tmp exists, error
+ File tmpFile = new File(tmp);
+ if (tmpFile.exists())
+ return false;
+
+ // rename the destination temporarily
+ if (dstExists) {
+ if (!renameFile(dstPath,tmp)) {
+ // rename error, do nothing else.
+ return false;
+ }
+ }
+
+ // copy the file
+ if (!copyFile(srcPath,dstPath,true)) {
+ // copy failed, put the destination back
+ if (dstExists) {
+ if (!renameFile(tmp,dstPath)) {
+ // bad mojo here. Can't rename back,
+ // file appears lost.
+ }
+ }
+ return false;
+ }
+
+ // copy succeeded, now delete the tmp file
+ deleteFile(tmp);
+
+ return true;
+ }
+
+ // get the extension part of the filename, not including the "."
+ public static String getExtension(String filename)
+ {
+ String filenameArray[] = filename.split("\\.");
+
+ if (filenameArray.length<=1)
+ {
+ // no extension
+ return "";
+ }
+
+ String extension = filenameArray[filenameArray.length-1];
+ extension = extension.toLowerCase();
+ return extension;
+ }
+
+ public static void showMessage(final Activity activity, final String title, final String body)
+ {
+ showMessage(activity, title, body, activity.getResources().getString(R.string.ok));
+ }
+ public static void showMessage(final Activity activity, final String title, final String body, final String okLabel)
+ {
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ new AlertDialog.Builder(activity)
+ .setTitle(title)
+ .setMessage(body)
+ .setCancelable(false)
+ .setPositiveButton(okLabel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ }
+ }).create().show();
+ }
+ });
+ }
+
+ public static void showMessageAndFinish(final Activity activity, final String title, final String body)
+ {
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ new AlertDialog.Builder(activity)
+ .setTitle(title)
+ .setMessage(body)
+ .setCancelable(false)
+ .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ activity.finish();
+ }
+ }).create().show();
+ }
+ });
+ }
+
+ public static void passwordDialog( final Activity activity, final passwordDialogListener listener)
+ {
+ activity.runOnUiThread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
+ LayoutInflater li = LayoutInflater.from(activity);
+ View promptsView = li.inflate(R.layout.password_prompt, null);
+
+ final EditText et = (EditText)(promptsView.findViewById(R.id.editTextDialogUserInput));
+
+ dialog.setView(promptsView);
+
+ dialog.setTitle("");
+
+ dialog.setPositiveButton(activity.getResources().getString(R.string.ok), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ if (listener!=null)
+ {
+ String password = et.getText().toString();
+ listener.onOK(password);
+ }
+ }
+ });
+
+ dialog.setNegativeButton(activity.getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ if (listener!=null)
+ listener.onCancel();
+ }
+ });
+
+ dialog.create().show();
+ }
+ });
+ }
+
+ public interface passwordDialogListener
+ {
+ void onOK(String password);
+ void onCancel();
+ }
+
+ public static void yesNoMessage(final Activity activity, final String title, final String body,
+ final String yesButtonLabel, final String noButtonLabel,
+ final Runnable yesRunnable, final Runnable noRunnable)
+ {
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+
+ AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
+
+ dialog.setTitle(title);
+ dialog.setMessage(body);
+
+ dialog.setPositiveButton(yesButtonLabel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ if (yesRunnable!=null)
+ yesRunnable.run();
+ }
+ });
+
+ dialog.setNegativeButton(noButtonLabel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ if (noRunnable!=null)
+ noRunnable.run();
+ }
+ });
+
+ dialog.create();
+ dialog.show();
+ }
+ });
+ }
+
+ public static File extractAssetToFile(Context context, String file)
+ {
+ File cacheFile = new File(context.getCacheDir(), file);
+ try
+ {
+ InputStream inputStream = context.getAssets().open(file);
+ try
+ {
+ FileOutputStream outputStream = new FileOutputStream(cacheFile);
+ try
+ {
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = inputStream.read(buf)) > 0)
+ {
+ outputStream.write(buf, 0, len);
+ }
+ } finally
+ {
+ outputStream.close();
+ }
+ } finally
+ {
+ inputStream.close();
+ }
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ return cacheFile;
+ }
+
+ public static String extractAssetToString(Context context, String file)
+ {
+ String json;
+ try {
+ InputStream is = context.getAssets().open(file);
+ int size = is.available();
+ byte[] buffer = new byte[size];
+ is.read(buffer);
+ is.close();
+ json = new String(buffer, "UTF-8");
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ return null;
+ }
+ return json;
+ }
+
+ public static String removeExtention(String filePath)
+ {
+ File f = new File(filePath);
+
+ // if it's a directory, don't remove the extention
+ if (f.isDirectory())
+ return filePath;
+
+ String name = f.getName();
+
+ // Now we know it's a file - don't need to do any special hidden
+ // checking or contains() checking because of:
+ final int lastPeriodPos = name.lastIndexOf('.');
+ if (lastPeriodPos <= 0)
+ {
+ // No period after first character - return name as it was passed in
+ return filePath;
+ }
+ else
+ {
+ // Remove the last period and everything after it
+ File renamed = new File(f.getParent(), name.substring(0, lastPeriodPos));
+ return renamed.getPath();
+ }
+ }
+
+ public static String getMimeType (String path)
+ {
+ String ext = Utilities.getExtension(path);
+ String mime = null;
+ if (ext != null) {
+ mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);
+ }
+ return mime;
+ }
+}
diff --git a/platform/android/example/mupdf/src/main/res/drawable/icon_open_in.xml b/platform/android/example/mupdf/src/main/res/drawable/icon_open_in.xml
new file mode 100755
index 00000000..ba08fa0a
--- /dev/null
+++ b/platform/android/example/mupdf/src/main/res/drawable/icon_open_in.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="50dp"
+ android:height="50dp"
+ android:viewportWidth="50"
+ android:viewportHeight="50">
+
+ <path
+ android:strokeColor="#333333"
+ android:strokeWidth="1.56"
+ android:strokeMiterLimit="10"
+ android:pathData="M36.801,26.869
+v9.601c0,0.6-0.486,1.086-1.085,1.086H12.121c-0.599,0-1.085-0.486-1.085-1.086V12.875c0-0.6,0.486-1.086,1.085-1.086h11.286" />
+ <path
+ android:strokeColor="#333333"
+ android:strokeWidth="1.56"
+ android:pathData="M 33.42 8.107 L 41.235 16.035 L 33.364 23.454 " />
+ <path
+ android:strokeColor="#333333"
+ android:strokeWidth="1.56"
+ android:pathData="M40.443,15.752 c0,0-13.591-1.817-16.473,4.985" />
+</vector> \ No newline at end of file
diff --git a/platform/android/example/mupdf/src/main/res/drawable/icon_print.xml b/platform/android/example/mupdf/src/main/res/drawable/icon_print.xml
new file mode 100755
index 00000000..2ea50da6
--- /dev/null
+++ b/platform/android/example/mupdf/src/main/res/drawable/icon_print.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="50dp"
+ android:height="50dp"
+ android:viewportWidth="50"
+ android:viewportHeight="50">
+
+ <path
+ android:strokeColor="#231F20"
+ android:strokeWidth="1.358"
+ android:pathData="M 16.584 9.143 H 33.395 V 15.468 H 16.584 V 9.143 Z" />
+ <path
+ android:strokeColor="#231F20"
+ android:strokeWidth="1.358"
+ android:pathData="M42.099,19.197H7.73
+c-0.218,0-0.395,0.154-0.395,0.343v15.771c0,0.191,0.177,0.346,0.395,0.346h4.355l1.516-7.161h22.86l1.374,7.161h4.263
+c0.219,0,0.393-0.154,0.393-0.346V19.541C42.491,19.351,42.317,19.197,42.099,19.197z" />
+ <path
+ android:strokeColor="#231F20"
+ android:strokeWidth="1.358"
+ android:pathData="M 32.812 32.95 L 17.162 32.95 L 15.09 42.75 L 34.689 42.75 Z" />
+ <path
+ android:strokeColor="#333333"
+ android:strokeWidth="1.358"
+ android:pathData="M 16.584 9.143 H 33.395 V 15.468 H 16.584 V 9.143 Z" />
+ <path
+ android:strokeColor="#333333"
+ android:strokeWidth="1.358"
+ android:pathData="M42.099,19.197H7.73
+c-0.218,0-0.395,0.154-0.395,0.343v15.771c0,0.191,0.177,0.346,0.395,0.346h4.355l1.516-7.161h22.86l1.374,7.161h4.263
+c0.219,0,0.393-0.154,0.393-0.346V19.541C42.491,19.351,42.317,19.197,42.099,19.197z" />
+ <path
+ android:strokeColor="#333333"
+ android:strokeWidth="1.358"
+ android:pathData="M 32.812 32.95 L 17.162 32.95 L 15.09 42.75 L 34.689 42.75 Z" />
+ <path
+ android:fillColor="#333333"
+ android:pathData="M 38.13 21.442 H 40.422 V 23.734 H 38.13 V 21.442 Z" />
+</vector> \ No newline at end of file
diff --git a/platform/android/example/mupdf/src/main/res/drawable/icon_save.xml b/platform/android/example/mupdf/src/main/res/drawable/icon_save.xml
index 0aa6421c..0aa6421c 100644..100755
--- a/platform/android/example/mupdf/src/main/res/drawable/icon_save.xml
+++ b/platform/android/example/mupdf/src/main/res/drawable/icon_save.xml
diff --git a/platform/android/example/mupdf/src/main/res/drawable/icon_save_as.xml b/platform/android/example/mupdf/src/main/res/drawable/icon_save_as.xml
new file mode 100644
index 00000000..88b0c64d
--- /dev/null
+++ b/platform/android/example/mupdf/src/main/res/drawable/icon_save_as.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="50dp"
+ android:height="50dp"
+ android:viewportWidth="50"
+ android:viewportHeight="50">
+
+ <path
+ android:fillColor="#333333"
+ android:pathData="M40.2505,24.3518 L44.6158,28.7518 L32.9436,40.3319 L28.5784,35.9319
+L40.2505,24.3518 Z" />
+ <path
+ android:fillColor="#333333"
+ android:pathData="M27.881,36.635 L32.235,41.021 L25.537,43.443 Z" />
+ <path
+ android:fillColor="#333333"
+ android:pathData="M45.559,27.822 L48.925,24.484 C49.025,24.384,49.025,24.223,48.926,24.124
+L44.918,20.084 C44.818,19.984,44.657,19.984,44.558,20.083 L41.193,23.421
+L45.559,27.822 Z" />
+ <path
+ android:fillColor="#333333"
+ android:pathData="M36.081,5.721 L36.081,16.26 C36.081,17.112,35.393,17.801,34.54,17.801
+L14.872,17.801 C14.021,17.801,13.33,17.112,13.33,16.26 L13.33,5.721
+L36.081,5.721 M34.709,7.094 L14.703,7.094 L14.703,16.26
+C14.703,16.354,14.777,16.428,14.872,16.428 L34.54,16.428
+C34.635,16.428,34.709,16.354,34.709,16.26 L34.709,7.094 Z" />
+ <path
+ android:strokeColor="#333333"
+ android:strokeWidth="1.372"
+ android:strokeMiterLimit="10"
+ android:pathData="M31.955,8.923 L31.955,14.295" />
+ <path
+ android:fillColor="#333333"
+ android:pathData="M32.52,30.27 L13.331,30.27 L13.331,31.836 L30.939,31.836 Z" />
+ <path
+ android:fillColor="#333333"
+ android:pathData="M36.08,25.535 L13.33,25.535 L13.33,27.104 L34.472,27.104 Z" />
+ <path
+ android:fillColor="#333333"
+ android:pathData="M8.656,5.719 L8.656,37.828 L24.032,37.828 L23.747,37.547 L24.993,36.334
+L10.15,36.334 L10.15,7.212 L39.393,7.212 L39.393,22.31 L40.887,20.853
+L40.887,5.719 L8.656,5.719 Z M40.887,37.828 L40.887,35.807 L38.811,37.828
+L40.887,37.828 Z" />
+</vector> \ No newline at end of file
diff --git a/platform/android/example/mupdf/src/main/res/drawable/icon_share.xml b/platform/android/example/mupdf/src/main/res/drawable/icon_share.xml
new file mode 100755
index 00000000..4dd1cb69
--- /dev/null
+++ b/platform/android/example/mupdf/src/main/res/drawable/icon_share.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="50dp"
+ android:height="50dp"
+ android:viewportWidth="50"
+ android:viewportHeight="50">
+
+ <path
+ android:strokeColor="#333333"
+ android:strokeWidth="1.613"
+ android:pathData="M 34.511 8.669 C 37.3641030176 8.669 39.677 10.9818969824 39.677 13.835 C 39.677 16.6881030176 37.3641030176 19.001 34.511 19.001 C 31.6578969824 19.001 29.345 16.6881030176 29.345 13.835 C 29.345 10.9818969824 31.6578969824 8.669 34.511 8.669 Z" />
+ <path
+ android:strokeColor="#333333"
+ android:strokeWidth="1.613"
+ android:pathData="M 34.511 28.424 C 37.3641030176 28.424 39.677 30.7368969824 39.677 33.59 C 39.677 36.4431030176 37.3641030176 38.756 34.511 38.756 C 31.6578969824 38.756 29.345 36.4431030176 29.345 33.59 C 29.345 30.7368969824 31.6578969824 28.424 34.511 28.424 Z" />
+ <path
+ android:strokeColor="#333333"
+ android:strokeWidth="1.613"
+ android:pathData="M 14.754 18.614 C 17.6071030176 18.614 19.92 20.9268969824 19.92 23.78 C 19.92 26.6331030176 17.6071030176 28.946 14.754 28.946 C 11.9008969824 28.946 9.588 26.6331030176 9.588 23.78 C 9.588 20.9268969824 11.9008969824 18.614 14.754 18.614 Z" />
+ <path
+ android:strokeColor="#333333"
+ android:strokeWidth="1.613"
+ android:pathData="M 19.345 21.077 L 29.962 15.836" />
+ <path
+ android:strokeColor="#333333"
+ android:strokeWidth="1.613"
+ android:pathData="M 19.345 21.077 L 29.962 15.836" />
+ <path
+ android:strokeColor="#333333"
+ android:strokeWidth="1.613"
+ android:pathData="M 29.962 31.829 L 19.345 26.588" />
+</vector> \ No newline at end of file
diff --git a/platform/android/example/mupdf/src/main/res/layout/file_toolbar.xml b/platform/android/example/mupdf/src/main/res/layout/file_toolbar.xml
index e0d8ecb4..6468c9d0 100644
--- a/platform/android/example/mupdf/src/main/res/layout/file_toolbar.xml
+++ b/platform/android/example/mupdf/src/main/res/layout/file_toolbar.xml
@@ -18,7 +18,9 @@
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:paddingLeft="10dp"
+ android:paddingRight="10dp">
<ImageButton
android:layout_width="wrap_content"
@@ -38,6 +40,113 @@
android:text="SAVE"/>
</LinearLayout>
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingLeft="10dp"
+ android:paddingRight="10dp">
+
+ <ImageButton
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:scaleType="fitXY"
+ android:layout_centerVertical="true"
+ android:background="@drawable/toolbar_button"
+ android:id="@+id/save_as_button"
+ android:src="@drawable/icon_save_as" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:textColor="@color/black"
+ android:textSize="11sp"
+ android:text="SAVE AS"/>
+ </LinearLayout>
+
+ <!--a divider-->
+ <View
+ android:layout_width="1dp"
+ android:paddingRight="3dp" android:paddingLeft="3dp"
+ android:layout_height="match_parent"
+ android:background="#FF8E8F90" />
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingLeft="10dp"
+ android:paddingRight="10dp">
+
+ <ImageButton
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:scaleType="fitXY"
+ android:layout_centerVertical="true"
+ android:background="@drawable/toolbar_button"
+ android:id="@+id/print_button"
+ android:src="@drawable/icon_print" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:textColor="@color/black"
+ android:textSize="11sp"
+ android:text="PRINT"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingLeft="10dp"
+ android:paddingRight="10dp">
+
+ <ImageButton
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:scaleType="fitXY"
+ android:layout_centerVertical="true"
+ android:background="@drawable/toolbar_button"
+ android:id="@+id/share_button"
+ android:src="@drawable/icon_share" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:textColor="@color/black"
+ android:textSize="11sp"
+ android:text="SHARE"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingLeft="10dp"
+ android:paddingRight="10dp">
+
+ <ImageButton
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:scaleType="fitXY"
+ android:layout_centerVertical="true"
+ android:background="@drawable/toolbar_button"
+ android:id="@+id/open_in_button"
+ android:src="@drawable/icon_open_in" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:textColor="@color/black"
+ android:textSize="11sp"
+ android:text="OPEN IN"/>
+ </LinearLayout>
+
<!--a divider-->
<View
android:layout_width="1dp"
diff --git a/platform/android/example/mupdf/src/main/res/layout/pages_toolbar.xml b/platform/android/example/mupdf/src/main/res/layout/pages_toolbar.xml
index 39a097c0..06ffa233 100644
--- a/platform/android/example/mupdf/src/main/res/layout/pages_toolbar.xml
+++ b/platform/android/example/mupdf/src/main/res/layout/pages_toolbar.xml
@@ -21,8 +21,7 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="10dp"
- android:paddingRight="10dp"
- >
+ android:paddingRight="10dp">
<ImageButton
android:layout_width="wrap_content"
diff --git a/platform/android/example/mupdf/src/main/res/layout/password_prompt.xml b/platform/android/example/mupdf/src/main/res/layout/password_prompt.xml
new file mode 100644
index 00000000..b8b8d678
--- /dev/null
+++ b/platform/android/example/mupdf/src/main/res/layout/password_prompt.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/layout_root"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical"
+ android:padding="10dp" >
+
+ <TextView
+ android:id="@+id/textView1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Password for document:"
+ android:labelFor="@+id/editTextDialogUserInput"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <EditText
+ android:id="@+id/editTextDialogUserInput"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="textPassword" >
+
+ <requestFocus />
+
+ </EditText>
+
+</LinearLayout>
diff --git a/platform/android/example/mupdf/src/main/res/values/strings.xml b/platform/android/example/mupdf/src/main/res/values/strings.xml
index be1a518a..3709da70 100644
--- a/platform/android/example/mupdf/src/main/res/values/strings.xml
+++ b/platform/android/example/mupdf/src/main/res/values/strings.xml
@@ -10,5 +10,7 @@
<string name="next_upper">NEXT</string>
<string name="previous_upper">PREVIOUS</string>
+ <string name="ok">OK</string>
+ <string name="cancel">Cancel</string>
</resources>