jenkins-bot has submitted this change and it was merged.

Change subject: Get selected text from the WebView.
......................................................................


Get selected text from the WebView.

Sort-of hacky method that works by programmatically copying the selected
text to the clipboard, then peeking at the clipboard contents. (The actual
WebView provides no way of getting selected text)

Only works with API >10, which is fine since API 10 doesn't provide
long-press context functionality for the WebView anyway.

Also moved Bus-related methods into an inner class, because of this issue:
https://github.com/square/otto/issues/37

When the Bus registers a class for event notifications, it uses reflection
on all of the class's methods and fields. If a field does not exist in the
current API, it crashes.  Therefore, it's suggested to use an inner class
that only contains methods specific to the Bus.

Change-Id: I6c29eff4d9930bd218a9f686493cbcbc67d78691
---
M wikipedia/src/main/java/org/wikipedia/page/PageActivity.java
1 file changed, 147 insertions(+), 71 deletions(-)

Approvals:
  BearND: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/wikipedia/src/main/java/org/wikipedia/page/PageActivity.java 
b/wikipedia/src/main/java/org/wikipedia/page/PageActivity.java
index f3d824f..2a9083f 100644
--- a/wikipedia/src/main/java/org/wikipedia/page/PageActivity.java
+++ b/wikipedia/src/main/java/org/wikipedia/page/PageActivity.java
@@ -27,8 +27,11 @@
 import com.squareup.otto.Subscribe;
 import de.keyboardsurfer.android.widget.crouton.Crouton;
 import de.keyboardsurfer.android.widget.crouton.Style;
+import android.annotation.TargetApi;
 import android.app.AlertDialog;
 import android.app.SearchManager;
+import android.content.ClipboardManager;
+import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -70,6 +73,7 @@
     public static final int ACTIVITY_REQUEST_GALLERY = 2;
 
     private Bus bus;
+    private EventBusMethods busMethods;
     private WikipediaApp app;
 
     private View fragmentContainerView;
@@ -77,7 +81,10 @@
     private NavDrawerFragment fragmentNavdrawer;
     private SearchArticlesFragment searchFragment;
     private TextView searchHintText;
+
     private ActionMode webViewActionMode;
+    private ClipboardManager.OnPrimaryClipChangedListener clipListener;
+    private MenuItem copyMenuItem;
 
     public static final int PROGRESS_BAR_MAX_VALUE = 10000;
     private ProgressBar progressBar;
@@ -138,7 +145,8 @@
         toolbarContainer = findViewById(R.id.main_toolbar_container);
 
         bus = app.getBus();
-        bus.register(this);
+        busMethods = new EventBusMethods();
+        bus.register(busMethods);
 
         drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
         fragmentNavdrawer = (NavDrawerFragment) 
getSupportFragmentManager().findFragmentById(R.id.navdrawer);
@@ -522,46 +530,6 @@
         themeChooser.show();
     }
 
-    @Subscribe
-    public void onChangeTextSize(ChangeTextSizeEvent event) {
-        if (getCurPageFragment() != null && getCurPageFragment().getWebView() 
!= null) {
-            getCurPageFragment().updateFontSize();
-        }
-    }
-
-    @Subscribe
-    public void onChangeTheme(ThemeChangeEvent event) {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
-
-            // this is all that's necessary!
-            // ALL of the other code relating to changing themes is only for 
API 10 support!
-            this.recreate();
-
-        } else {
-            // TODO: remove this when we drop support for API 10
-            // sigh.
-            Bundle state = new Bundle();
-            Intent intent = new Intent(this, PageActivity.class);
-            // In order to change our theme, we need to relaunch the activity.
-            // There doesn't seem to be a way to relaunch an activity in a way 
that forces it to save its
-            // instance state (and all of its fragments' instance state)... so 
we need to explicitly save
-            // the state that we need, and pass it into the Intent.
-            // We'll simply save the last Fragment that was on top of the 
backstack, as well as its arguments.
-            Fragment curFragment = 
getSupportFragmentManager().findFragmentById(R.id.content_fragment_container);
-            state.putString(KEY_LAST_FRAGMENT, 
curFragment.getClass().getName());
-            // if the fragment had arguments, save them too:
-            if (curFragment.getArguments() != null) {
-                state.putBundle(KEY_LAST_FRAGMENT_ARGS, 
curFragment.getArguments());
-            }
-
-            saveState(state);
-            state.putBoolean("changeTheme", true);
-            finish();
-            intent.putExtras(state);
-            startActivity(intent);
-        }
-    }
-
     @Override
     public void onBackPressed() {
         if (drawerLayout.isDrawerOpen(Gravity.START)) {
@@ -583,31 +551,79 @@
         }
     }
 
-    @Subscribe
-    public void onWikipediaZeroStateChangeEvent(WikipediaZeroStateChangeEvent 
event) {
-        boolean latestWikipediaZeroDisposition = 
app.getWikipediaZeroHandler().isZeroEnabled();
-        ZeroMessage latestCarrierMessage = 
app.getWikipediaZeroHandler().getCarrierMessage();
-
-        if (pausedStateOfZero && !latestWikipediaZeroDisposition) {
-            String title = getString(R.string.zero_charged_verbiage);
-            String verbiage = 
getString(R.string.zero_charged_verbiage_extended);
-            
makeWikipediaZeroCrouton(getResources().getColor(R.color.holo_red_dark),
-                    getResources().getColor(android.R.color.white),
-                    title);
-            fragmentNavdrawer.setupDynamicItems();
-            showDialogAboutZero(null, title, verbiage);
-        } else if ((!pausedStateOfZero || 
!pausedMessageOfZero.equals(latestCarrierMessage)) && 
latestWikipediaZeroDisposition) {
-            String title = latestCarrierMessage.getMsg();
-            int fg = latestCarrierMessage.getFg();
-            int bg = latestCarrierMessage.getBg();
-            String verbiage = getString(R.string.zero_learn_more);
-            makeWikipediaZeroCrouton(bg, fg, title);
-            fragmentNavdrawer.setupDynamicItems();
-            showDialogAboutZero(ZERO_ON_NOTICE_PRESENTED, title, verbiage);
+    private class EventBusMethods {
+        @Subscribe
+        public void onChangeTextSize(ChangeTextSizeEvent event) {
+            if (getCurPageFragment() != null && 
getCurPageFragment().getWebView() != null) {
+                getCurPageFragment().updateFontSize();
+            }
         }
-        pausedStateOfZero = latestWikipediaZeroDisposition;
-        pausedMessageOfZero = latestCarrierMessage;
-        searchHintText.setText(getString(latestWikipediaZeroDisposition ? 
R.string.zero_search_hint : R.string.search_hint));
+
+        @Subscribe
+        public void onChangeTheme(ThemeChangeEvent event) {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+
+                // this is all that's necessary!
+                // ALL of the other code relating to changing themes is only 
for API 10 support!
+                PageActivity.this.recreate();
+            } else {
+                // TODO: remove this when we drop support for API 10
+                // sigh.
+                Bundle state = new Bundle();
+                Intent intent = new Intent(PageActivity.this, 
PageActivity.class);
+                // In order to change our theme, we need to relaunch the 
activity.
+                // There doesn't seem to be a way to relaunch an activity in a 
way that forces it to save its
+
+                // instance state (and all of its fragments' instance 
state)... so we need to
+                // explicitly save
+                // the state that we need, and pass it into the Intent.
+                // We'll simply save the last Fragment that was on top of the 
backstack, as well as its arguments.
+                Fragment curFragment = getSupportFragmentManager()
+                        .findFragmentById(R.id.content_fragment_container);
+                state.putString(KEY_LAST_FRAGMENT, 
curFragment.getClass().getName());
+                // if the fragment had arguments, save them too:
+                if (curFragment.getArguments() != null) {
+                    state.putBundle(KEY_LAST_FRAGMENT_ARGS, 
curFragment.getArguments());
+                }
+
+                saveState(state);
+                state.putBoolean("changeTheme", true);
+                finish();
+                intent.putExtras(state);
+                startActivity(intent);
+            }
+        }
+
+        @Subscribe
+        public void 
onWikipediaZeroStateChangeEvent(WikipediaZeroStateChangeEvent event) {
+            boolean latestWikipediaZeroDisposition = 
app.getWikipediaZeroHandler().isZeroEnabled();
+            ZeroMessage latestCarrierMessage = 
app.getWikipediaZeroHandler().getCarrierMessage();
+
+            if (pausedStateOfZero && !latestWikipediaZeroDisposition) {
+                String title = getString(R.string.zero_charged_verbiage);
+                String verbiage = 
getString(R.string.zero_charged_verbiage_extended);
+                
makeWikipediaZeroCrouton(getResources().getColor(R.color.holo_red_dark),
+                                         
getResources().getColor(android.R.color.white),
+                                         title);
+                fragmentNavdrawer.setupDynamicItems();
+                showDialogAboutZero(null, title, verbiage);
+            } else if ((!pausedStateOfZero || 
!pausedMessageOfZero.equals(latestCarrierMessage))
+                       && latestWikipediaZeroDisposition) {
+                String title = latestCarrierMessage.getMsg();
+                int fg = latestCarrierMessage.getFg();
+                int bg = latestCarrierMessage.getBg();
+                String verbiage = getString(R.string.zero_learn_more);
+                makeWikipediaZeroCrouton(bg, fg, title);
+                fragmentNavdrawer.setupDynamicItems();
+                showDialogAboutZero(ZERO_ON_NOTICE_PRESENTED, title, verbiage);
+            }
+            pausedStateOfZero = latestWikipediaZeroDisposition;
+            pausedMessageOfZero = latestCarrierMessage;
+            searchHintText.setText(getString(
+                    latestWikipediaZeroDisposition
+                            ? R.string.zero_search_hint
+                            : R.string.search_hint));
+        }
     }
 
     private void makeWikipediaZeroCrouton(int bgcolor, int fgcolor, String 
verbiage) {
@@ -658,7 +674,7 @@
         super.onStart();
         if (bus == null) {
             bus = app.getBus();
-            bus.register(this);
+            bus.register(busMethods);
             Log.d("Wikipedia", "Registering bus");
         }
     }
@@ -698,7 +714,7 @@
     public void onActivityResult(int requestCode, int resultCode, final Intent 
data) {
         if (bus == null) {
             bus = app.getBus();
-            bus.register(this);
+            bus.register(busMethods);
             Log.d("Wikipedia", "Registering bus");
         }
         if ((requestCode == ACTIVITY_REQUEST_LANGLINKS && resultCode == 
LangLinksActivity.ACTIVITY_RESULT_LANGLINK_SELECT)) {
@@ -729,27 +745,87 @@
         app.getSessionFunnel().persistSession();
 
         super.onStop();
-        bus.unregister(this);
+        bus.unregister(busMethods);
         bus = null;
         Log.d("Wikipedia", "Deregistering bus");
     }
 
+    /**
+     * ActionMode that is invoked when the user long-presses inside the 
WebView.
+     * Since API <11 doesn't provide a long-press context for the WebView 
anyway, and we're
+     * using clipboard features that are only supported in API 11+, we'll mark 
this whole
+     * method as TargetApi(11), so that the IDE doesn't get upset.
+     * @param mode ActionMode under which this context is starting.
+     */
+    @TargetApi(11)
     @Override
     public void onSupportActionModeStarted(ActionMode mode) {
         if (webViewActionMode == null) {
             webViewActionMode = mode;
             Menu menu = mode.getMenu();
+
+            // Find the context menu item for copying text to the clipboard...
+            // The most practical way to do this seems to be to get the 
resource name of the
+            // menu item, and see if it resembles "action_menu_copy", which 
appears to remain
+            // consistent throughout the various APIs.
+            for (int i = 0; i < menu.size(); i++) {
+                String resourceName = 
getResources().getResourceName(menu.getItem(i).getItemId());
+                if (resourceName.contains("action_menu_copy")) {
+                    copyMenuItem = menu.getItem(i);
+                    break;
+                }
+            }
+
+            // add our clipboard listener, so that we'll get an event when the 
text
+            // is copied onto it...
+            ClipboardManager clipboard = (ClipboardManager) getSystemService(
+                    Context.CLIPBOARD_SERVICE);
+            if (clipListener == null) {
+                clipListener = new 
ClipboardManager.OnPrimaryClipChangedListener() {
+                    @Override
+                    public void onPrimaryClipChanged() {
+                        // get the text from the clipboard!
+                        ClipboardManager clipboard = (ClipboardManager) 
getSystemService(
+                                Context.CLIPBOARD_SERVICE);
+                        if (clipboard.hasPrimaryClip()
+                            && clipboard.getPrimaryClip().getItemCount() > 0) {
+
+
+                            // TODO: Pass the clipboard text to the Share 
handler!
+
+
+                            Log.d("Share", ">>> Clipboard text: " + 
clipboard.getPrimaryClip()
+                                            
.getItemAt(0).coerceToText(PageActivity.this));
+
+                        }
+                        
clipboard.removePrimaryClipChangedListener(clipListener);
+                    }
+                };
+            }
+            // remove it first, just in case it was added from the last 
context, and
+            // ended up not being used.
+            clipboard.removePrimaryClipChangedListener(clipListener);
+            // and add it again.
+            clipboard.addPrimaryClipChangedListener(clipListener);
+
+            // inject our Share item into the menu...
             MenuItem shareItem = menu.add(R.string.share_via);
             shareItem.setIcon(app.getCurrentTheme() == WikipediaApp.THEME_DARK
                                       ? R.drawable.ic_share_dark
                                       : R.drawable.ic_share);
             MenuItemCompat.setShowAsAction(shareItem, 
MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
+
             shareItem.setOnMenuItemClickListener(new 
MenuItem.OnMenuItemClickListener() {
                 @Override
                 public boolean onMenuItemClick(MenuItem item) {
-
-                    // TODO: implement sharing of image with quote!
-
+                    if (copyMenuItem != null) {
+                        // programmatically invoke the copy-to-clipboard 
action...
+                        webViewActionMode.getMenu()
+                                         
.performIdentifierAction(copyMenuItem.getItemId(), 0);
+                        // this will trigger a state-change event in the 
Clipboard, which we'll
+                        // catch with our listener above.
+                    }
+                    // leave context mode...
                     if (webViewActionMode != null) {
                         webViewActionMode.finish();
                     }

-- 
To view, visit https://gerrit.wikimedia.org/r/181261
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I6c29eff4d9930bd218a9f686493cbcbc67d78691
Gerrit-PatchSet: 10
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Dbrant <[email protected]>
Gerrit-Reviewer: BearND <[email protected]>
Gerrit-Reviewer: Brion VIBBER <[email protected]>
Gerrit-Reviewer: Dbrant <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to