diff options
Diffstat (limited to 'android')
-rw-r--r-- | android/res/animator/info.xml | 20 | ||||
-rw-r--r-- | android/res/drawable-ldpi/ic_clipboard.png | bin | 0 -> 217 bytes | |||
-rw-r--r-- | android/res/drawable-mdpi/ic_clipboard.png | bin | 0 -> 256 bytes | |||
-rw-r--r-- | android/res/layout/buttons.xml | 43 | ||||
-rw-r--r-- | android/res/values/strings.xml | 2 | ||||
-rw-r--r-- | android/src/com/artifex/mupdf/MuPDFActivity.java | 66 | ||||
-rw-r--r-- | android/src/com/artifex/mupdf/PageView.java | 51 |
7 files changed, 171 insertions, 11 deletions
diff --git a/android/res/animator/info.xml b/android/res/animator/info.xml new file mode 100644 index 00000000..cd7bff28 --- /dev/null +++ b/android/res/animator/info.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:ordering="sequentially" > + + <objectAnimator + android:propertyName="alpha" + android:valueFrom="0.0" + android:valueTo="1.0" + android:duration="200" /> + + <objectAnimator + android:propertyName="alpha" + android:valueTo="1.0" + android:duration="800" /> + + <objectAnimator + android:propertyName="alpha" + android:valueTo="0.0" + android:duration="400" /> +</set>
\ No newline at end of file diff --git a/android/res/drawable-ldpi/ic_clipboard.png b/android/res/drawable-ldpi/ic_clipboard.png Binary files differnew file mode 100644 index 00000000..1fbc90fa --- /dev/null +++ b/android/res/drawable-ldpi/ic_clipboard.png diff --git a/android/res/drawable-mdpi/ic_clipboard.png b/android/res/drawable-mdpi/ic_clipboard.png Binary files differnew file mode 100644 index 00000000..3f22aab5 --- /dev/null +++ b/android/res/drawable-mdpi/ic_clipboard.png diff --git a/android/res/layout/buttons.xml b/android/res/layout/buttons.xml index c8c95153..910076b7 100644 --- a/android/res/layout/buttons.xml +++ b/android/res/layout/buttons.xml @@ -4,7 +4,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" > - <ViewSwitcher + <ViewAnimator android:id="@+id/switcher" android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -97,7 +97,7 @@ android:layout_toRightOf="@+id/cancel" android:layout_toLeftOf="@+id/searchBack" android:inputType="text" - android:hint="Search" + android:hint="@string/search" android:singleLine="true" /> <ImageButton @@ -122,7 +122,34 @@ </RelativeLayout> - </ViewSwitcher> + <RelativeLayout + android:id="@+id/topBar3" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/toolbar" > + + <ImageButton + android:id="@+id/cancelSelectButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerVertical="true" + android:layout_alignParentLeft="true" + android:contentDescription="@string/cancel" + android:background="@drawable/button" + android:src="@drawable/ic_cancel" /> + + <ImageButton + android:id="@+id/copySelectButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerVertical="true" + android:layout_alignParentRight="true" + android:contentDescription="@string/copy" + android:background="@drawable/button" + android:src="@drawable/ic_clipboard" /> + + </RelativeLayout> + </ViewAnimator> <RelativeLayout android:id="@+id/lowerButtons" @@ -160,4 +187,14 @@ </RelativeLayout> + <TextView + android:id="@+id/info" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_above="@+id/pageSlider" + android:layout_centerHorizontal="true" + android:layout_centerVertical="true" + android:background="@drawable/page_num" + android:textAppearance="?android:attr/textAppearanceMedium" + android:textColor="#FFFFFF" /> </RelativeLayout> diff --git a/android/res/values/strings.xml b/android/res/values/strings.xml index 2022e3eb..826ada55 100644 --- a/android/res/values/strings.xml +++ b/android/res/values/strings.xml @@ -17,4 +17,6 @@ <string name="link_control">Link highlighting and enabling</string> <string name="no_further_occurences_found">No further occurences found</string> <string name="select">Select</string> + <string name="search">Search</string> + <string name="copy">Copy</string> </resources> diff --git a/android/src/com/artifex/mupdf/MuPDFActivity.java b/android/src/com/artifex/mupdf/MuPDFActivity.java index d083fc60..0cf14413 100644 --- a/android/src/com/artifex/mupdf/MuPDFActivity.java +++ b/android/src/com/artifex/mupdf/MuPDFActivity.java @@ -2,6 +2,9 @@ package com.artifex.mupdf; import java.util.concurrent.Executor; +import android.animation.Animator; +import android.animation.AnimatorInflater; +import android.animation.AnimatorSet; import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; @@ -11,7 +14,6 @@ import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; import android.graphics.Color; -import android.graphics.PorterDuff; import android.graphics.RectF; import android.net.Uri; import android.os.Bundle; @@ -33,7 +35,7 @@ import android.widget.ImageButton; import android.widget.RelativeLayout; import android.widget.SeekBar; import android.widget.TextView; -import android.widget.ViewSwitcher; +import android.widget.ViewAnimator; class ThreadPerTaskExecutor implements Executor { public void execute(Runnable r) { @@ -95,11 +97,14 @@ public class MuPDFActivity extends Activity private SeekBar mPageSlider; private int mPageSliderRes; private TextView mPageNumberView; + private TextView mInfoView; private ImageButton mSearchButton; private ImageButton mSelectButton; + private ImageButton mCancelSelectButton; + private ImageButton mCopySelectButton; private ImageButton mCancelButton; private ImageButton mOutlineButton; - private ViewSwitcher mTopBarSwitcher; + private ViewAnimator mTopBarSwitcher; private ImageButton mLinkButton; private boolean mTopBarIsSearch; private ImageButton mSearchBack; @@ -511,8 +516,49 @@ public class MuPDFActivity extends Activity // Activate the select button mSelectButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { - mSelecting = !mSelecting; - mSelectButton.setColorFilter(Color.WHITE, mSelecting?PorterDuff.Mode.XOR: PorterDuff.Mode.DST); + mSelecting = true; + mTopBarSwitcher.setDisplayedChild(2); + } + }); + + mCancelSelectButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + PageView pageView = (PageView) mDocView.getDisplayedView(); + if (pageView != null) + pageView.deselectText(); + mSelecting = false; + mTopBarSwitcher.setDisplayedChild(0); + } + }); + + final Context context = this; + mCopySelectButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + PageView pageView = (PageView) mDocView.getDisplayedView(); + boolean copied = false; + if (pageView != null) + copied = pageView.copySelection(); + mSelecting = false; + mTopBarSwitcher.setDisplayedChild(0); + mInfoView.setText(copied?"Copied to clipboard":"No text selected"); + AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(context, R.animator.info); + set.setTarget(mInfoView); + set.addListener(new Animator.AnimatorListener() { + public void onAnimationStart(Animator animation) { + mInfoView.setVisibility(View.VISIBLE); + } + + public void onAnimationRepeat(Animator animation) { + } + + public void onAnimationEnd(Animator animation) { + mInfoView.setVisibility(View.INVISIBLE); + } + + public void onAnimationCancel(Animator animation) { + } + }); + set.start(); } }); @@ -775,7 +821,7 @@ public class MuPDFActivity extends Activity //Focus on EditTextWidget mSearchText.requestFocus(); showKeyboard(); - mTopBarSwitcher.showNext(); + mTopBarSwitcher.setDisplayedChild(1); } } @@ -783,7 +829,7 @@ public class MuPDFActivity extends Activity if (mTopBarIsSearch) { mTopBarIsSearch = false; hideKeyboard(); - mTopBarSwitcher.showPrevious(); + mTopBarSwitcher.setDisplayedChild(0); SearchTaskResult.set(null); // Make the ReaderView act on the change to mSearchTaskResult // via overridden onChildSetup method. @@ -802,17 +848,21 @@ public class MuPDFActivity extends Activity mFilenameView = (TextView)mButtonsView.findViewById(R.id.docNameText); mPageSlider = (SeekBar)mButtonsView.findViewById(R.id.pageSlider); mPageNumberView = (TextView)mButtonsView.findViewById(R.id.pageNumber); + mInfoView = (TextView)mButtonsView.findViewById(R.id.info); mSearchButton = (ImageButton)mButtonsView.findViewById(R.id.searchButton); mSelectButton = (ImageButton)mButtonsView.findViewById(R.id.selectButton); + mCancelSelectButton = (ImageButton)mButtonsView.findViewById(R.id.cancelSelectButton); + mCopySelectButton = (ImageButton)mButtonsView.findViewById(R.id.copySelectButton); mCancelButton = (ImageButton)mButtonsView.findViewById(R.id.cancel); mOutlineButton = (ImageButton)mButtonsView.findViewById(R.id.outlineButton); - mTopBarSwitcher = (ViewSwitcher)mButtonsView.findViewById(R.id.switcher); + mTopBarSwitcher = (ViewAnimator)mButtonsView.findViewById(R.id.switcher); mSearchBack = (ImageButton)mButtonsView.findViewById(R.id.searchBack); mSearchFwd = (ImageButton)mButtonsView.findViewById(R.id.searchForward); mSearchText = (EditText)mButtonsView.findViewById(R.id.searchText); mLinkButton = (ImageButton)mButtonsView.findViewById(R.id.linkButton); mTopBarSwitcher.setVisibility(View.INVISIBLE); mPageNumberView.setVisibility(View.INVISIBLE); + mInfoView.setVisibility(View.INVISIBLE); mPageSlider.setVisibility(View.INVISIBLE); } diff --git a/android/src/com/artifex/mupdf/PageView.java b/android/src/com/artifex/mupdf/PageView.java index f94ee9e0..4a28471c 100644 --- a/android/src/com/artifex/mupdf/PageView.java +++ b/android/src/com/artifex/mupdf/PageView.java @@ -3,6 +3,8 @@ package com.artifex.mupdf; import java.util.ArrayList; import java.util.Iterator; +import android.content.ClipData; +import android.content.ClipboardManager; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; @@ -57,6 +59,9 @@ abstract class TextSelector { protected abstract void onEndLine(); public void select() { + if (mText == null || mSelectBox == null) + return; + ArrayList<TextWord[]> lines = new ArrayList<TextWord[]>(); for (TextWord[] line : mText) if (line[0].bottom > mSelectBox.top && line[0].top < mSelectBox.bottom) @@ -347,6 +352,11 @@ public abstract class PageView extends ViewGroup { mSearchView.invalidate(); } + public void deselectText() { + mSelectBox = null; + mSearchView.invalidate(); + } + public void selectText(float x0, float y0, float x1, float y1) { float scale = mSourceScale*(float)getWidth()/(float)mSize.x; float docRelX0 = (x0 - getLeft())/scale; @@ -378,6 +388,47 @@ public abstract class PageView extends ViewGroup { } } + public boolean copySelection() { + final StringBuilder text = new StringBuilder(); + + TextSelector sel = new TextSelector(mText, mSelectBox) { + StringBuilder line; + + @Override + protected void onStartLine() { + line = new StringBuilder(); + } + + @Override + protected void onWord(TextWord word) { + if (line.length() > 0) + line.append(' '); + line.append(word.w); + } + + @Override + protected void onEndLine() { + if (text.length() > 0) + text.append('\n'); + text.append(line); + } + }; + + sel.select(); + + if (text.length() == 0) + return false; + + ClipboardManager cm = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE); + + cm.setPrimaryClip(ClipData.newPlainText("MuPDF", text)); + + mSelectBox = null; + mSearchView.invalidate(); + + return true; + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int x, y; |