Bug 1026715 - Add "Open all" item to recent tabs lists. r=lucasr
authorMargaret Leibovic <margaret.leibovic@gmail.com>
Mon, 23 Jun 2014 14:13:05 -0700
changeset 212388 d825d00cceeef0485feb9720fc8cd193ce3786fb
parent 212387 0701ea0bfaf6309bab3645bf8b0c0aefa2b49468
child 212389 cc4602e0c1d89622c7be5da0555c42f323ae43e4
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslucasr
bugs1026715
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1026715 - Add "Open all" item to recent tabs lists. r=lucasr
mobile/android/base/BrowserApp.java
mobile/android/base/home/HomePager.java
mobile/android/base/home/RecentTabsPanel.java
mobile/android/base/locales/en-US/android_strings.dtd
mobile/android/base/resources/layout/home_open_all_row.xml
mobile/android/base/resources/values/styles.xml
mobile/android/base/strings.xml.in
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko;
 
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.net.URLEncoder;
 import java.util.EnumSet;
+import java.util.List;
 import java.util.Locale;
 import java.util.Vector;
 
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.mozilla.gecko.DynamicToolbar.PinReason;
 import org.mozilla.gecko.DynamicToolbar.VisibilityTransition;
@@ -2741,17 +2742,17 @@ abstract public class BrowserApp extends
                 if (url.length() > 0)
                     GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Feedback:LastUrl", url));
             }
         }).execute();
     }
 
     // HomePager.OnNewTabsListener
     @Override
-    public void onNewTabs(String[] urls) {
+    public void onNewTabs(List<String> urls) {
         final EnumSet<OnUrlOpenListener.Flags> flags = EnumSet.of(OnUrlOpenListener.Flags.ALLOW_SWITCH_TO_TAB);
 
         for (String url : urls) {
             if (!maybeSwitchToTab(url, flags)) {
                 openUrlAndStopEditing(url, true);
             }
         }
     }
--- a/mobile/android/base/home/HomePager.java
+++ b/mobile/android/base/home/HomePager.java
@@ -76,17 +76,17 @@ public class HomePager extends ViewPager
             ALLOW_SWITCH_TO_TAB,
             OPEN_WITH_INTENT
         }
 
         public void onUrlOpen(String url, EnumSet<Flags> flags);
     }
 
     public interface OnNewTabsListener {
-        public void onNewTabs(String[] urls);
+        public void onNewTabs(List<String> urls);
     }
 
     /**
      * Interface for listening into ViewPager panel changes
      */
     public interface OnPanelChangeListener {
         /**
          * Called when a new panel is selected.
--- a/mobile/android/base/home/RecentTabsPanel.java
+++ b/mobile/android/base/home/RecentTabsPanel.java
@@ -1,15 +1,18 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.home;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.mozilla.gecko.AboutPages;
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.GeckoEvent;
 import org.mozilla.gecko.GeckoProfile;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.SessionParser;
 import org.mozilla.gecko.Telemetry;
@@ -81,16 +84,18 @@ public class RecentTabsPanel extends Hom
     }
 
     public static final class RecentTabs implements URLColumns, CommonColumns {
         public static final String TYPE = "type";
 
         public static final int TYPE_HEADER = 0;
         public static final int TYPE_LAST_TIME = 1;
         public static final int TYPE_CLOSED = 2;
+        public static final int TYPE_OPEN_ALL_LAST_TIME = 3;
+        public static final int TYPE_OPEN_ALL_CLOSED = 4;
     }
 
     @Override
     public void onAttach(Activity activity) {
         super.onAttach(activity);
 
         try {
             mNewTabsListener = (OnNewTabsListener) activity;
@@ -120,26 +125,46 @@ public class RecentTabsPanel extends Hom
         mList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
             @Override
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                 final Cursor c = mAdapter.getCursor();
                 if (c == null || !c.moveToPosition(position)) {
                     return;
                 }
 
+                final int itemType = c.getInt(c.getColumnIndexOrThrow(RecentTabs.TYPE));
+
+                if (itemType == RecentTabs.TYPE_OPEN_ALL_LAST_TIME) {
+                    openTabsWithType(RecentTabs.TYPE_LAST_TIME);
+                    return;
+                }
+
+                if (itemType == RecentTabs.TYPE_OPEN_ALL_CLOSED) {
+                    openTabsWithType(RecentTabs.TYPE_CLOSED);
+                    return;
+                }
+
                 Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL);
 
-                final String url = c.getString(c.getColumnIndexOrThrow(RecentTabs.URL));
-                mNewTabsListener.onNewTabs(new String[] { url });
+                final ArrayList<String> urls = new ArrayList<String>();
+                urls.add(c.getString(c.getColumnIndexOrThrow(RecentTabs.URL)));
+
+                mNewTabsListener.onNewTabs(urls);
             }
         });
 
         mList.setContextMenuInfoFactory(new HomeContextMenuInfo.Factory() {
             @Override
             public HomeContextMenuInfo makeInfoForCursor(View view, int position, long id, Cursor cursor) {
+                // Don't show context menus for the "Open all" rows.
+                final int itemType = cursor.getInt(cursor.getColumnIndexOrThrow(RecentTabs.TYPE));
+                if (itemType == RecentTabs.TYPE_OPEN_ALL_LAST_TIME || itemType == RecentTabs.TYPE_OPEN_ALL_CLOSED) {
+                    return null;
+                }
+
                 final HomeContextMenuInfo info = new HomeContextMenuInfo(view, position, id);
                 info.url = cursor.getString(cursor.getColumnIndexOrThrow(RecentTabs.URL));
                 info.title = cursor.getString(cursor.getColumnIndexOrThrow(RecentTabs.TITLE));
                 return info;
             }
         });
 
         registerForContextMenu(mList);
@@ -229,26 +254,27 @@ public class RecentTabsPanel extends Hom
                 // Reload the cursor to show recently closed tabs.
                 if (mClosedTabs.length > 0 && canLoad()) {
                     getLoaderManager().restartLoader(LOADER_ID_RECENT_TABS, null, mCursorLoaderCallbacks);
                 }
             }
         });
     }
 
-    private void openAllTabs() {
+    private void openTabsWithType(int type) {
         final Cursor c = mAdapter.getCursor();
         if (c == null || !c.moveToFirst()) {
             return;
         }
 
-        final String[] urls = new String[c.getCount()];
-
+        final List<String> urls = new ArrayList<String>();
         do {
-            urls[c.getPosition()] = c.getString(c.getColumnIndexOrThrow(RecentTabs.URL));
+            if (c.getInt(c.getColumnIndexOrThrow(RecentTabs.TYPE)) == type) {
+                urls.add(c.getString(c.getColumnIndexOrThrow(RecentTabs.URL)));
+            }
         } while (c.moveToNext());
 
         Telemetry.sendUIEvent(TelemetryContract.Event.LOAD_URL, TelemetryContract.Method.BUTTON);
 
         mNewTabsListener.onNewTabs(urls);
     }
 
     private static class RecentTabsCursorLoader extends SimpleCursorLoader {
@@ -283,16 +309,21 @@ public class RecentTabsPanel extends Hom
                 for (int i = 0; i < length; i++) {
                     final String url = closedTabs[i].url;
 
                     // Don't show recent tabs for about:home
                     if (!AboutPages.isAboutHome(url)) {
                         addRow(c, url, closedTabs[i].title, RecentTabs.TYPE_CLOSED);
                     }
                 }
+
+                // Add an "Open all" button if more than 2 tabs were added to the list.
+                if (length > 1) {
+                    addRow(c, null, null, RecentTabs.TYPE_OPEN_ALL_CLOSED);
+                }
             }
 
             final String jsonString = GeckoProfile.get(context).readSessionFile(true);
             if (jsonString == null) {
                 // No previous session data
                 return c;
             }
 
@@ -312,49 +343,64 @@ public class RecentTabsPanel extends Hom
                     if (c.getCount() == count) {
                         addRow(c, null, context.getString(R.string.home_last_tabs_title), RecentTabs.TYPE_HEADER);
                     }
 
                     addRow(c, url, tab.getTitle(), RecentTabs.TYPE_LAST_TIME);
                 }
             }.parse(jsonString);
 
+            // Add an "Open all" button if more than 2 tabs were added to the list (account for the header)
+            if (c.getCount() - count > 2) {
+                addRow(c, null, null, RecentTabs.TYPE_OPEN_ALL_LAST_TIME);
+            }
+
             return c;
         }
     }
 
     private static class RecentTabsAdapter extends MultiTypeCursorAdapter {
         private static final int ROW_HEADER = 0;
         private static final int ROW_STANDARD = 1;
+        private static final int ROW_OPEN_ALL = 2;
 
-        private static final int[] VIEW_TYPES = new int[] { ROW_STANDARD, ROW_HEADER };
-        private static final int[] LAYOUT_TYPES = new int[] { R.layout.home_item_row, R.layout.home_header_row };
+        private static final int[] VIEW_TYPES = new int[] { ROW_STANDARD, ROW_HEADER, ROW_OPEN_ALL };
+        private static final int[] LAYOUT_TYPES =
+            new int[] { R.layout.home_item_row, R.layout.home_header_row, R.layout.home_open_all_row };
 
         public RecentTabsAdapter(Context context) {
             super(context, null, VIEW_TYPES, LAYOUT_TYPES);
         }
 
         public int getItemViewType(int position) {
             final Cursor c = getCursor(position);
             final int type = c.getInt(c.getColumnIndexOrThrow(RecentTabs.TYPE));
 
             if (type == RecentTabs.TYPE_HEADER) {
                 return ROW_HEADER;
             }
 
+            if (type == RecentTabs.TYPE_OPEN_ALL_LAST_TIME || type == RecentTabs.TYPE_OPEN_ALL_CLOSED) {
+                return ROW_OPEN_ALL;
+            }
+
             return ROW_STANDARD;
          }
 
         public boolean isEnabled(int position) {
             return (getItemViewType(position) != ROW_HEADER);
         }
 
         @Override
         public void bindView(View view, Context context, int position) {
             final int itemType = getItemViewType(position);
+            if (itemType == ROW_OPEN_ALL) {
+                return;
+            }
+
             final Cursor c = getCursor(position);
 
             if (itemType == ROW_HEADER) {
                 final String title = c.getString(c.getColumnIndexOrThrow(RecentTabs.TITLE));
                 final TextView textView = (TextView) view;
                 textView.setText(title);
             } else if (itemType == ROW_STANDARD) {
                 final TwoLinePageRow pageRow = (TwoLinePageRow) view;
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -347,18 +347,18 @@ size. -->
 <!ENTITY home_top_sites_add "Add a site">
 
 <!ENTITY home_history_title "History">
 <!ENTITY home_clear_history_button "Clear browsing history">
 <!ENTITY home_clear_history_confirm "Are you sure you want to clear your history?">
 <!ENTITY home_bookmarks_empty "Bookmarks you save show up here.">
 <!ENTITY home_closed_tabs_title "Recently closed tabs">
 <!ENTITY home_last_tabs_title "Tabs from last time">
-<!ENTITY home_last_tabs_open "Open all tabs from last time">
 <!ENTITY home_last_tabs_empty "Your recent tabs show up here.">
+<!ENTITY home_open_all "Open all">
 <!ENTITY home_most_recent_empty "Websites you visited most recently show up here.">
 <!ENTITY home_reading_list_empty "Articles you save for later show up here.">
 <!-- Localization note (home_reading_list_hint): The "TIP" string is synonymous to "hint", "clue", etc. This string is displayed
      as an advisory message on how to add content to the reading list when the reading list empty.
      The placeholder &formatI; will be replaced by a small image of the icon described, and can be moved to wherever
      it is applicable. -->
 <!ENTITY home_reading_list_hint2 "TIP: Save articles to your reading list by long pressing the &formatI; icon when it appears in the title bar.">
 <!-- Localization note (home_reading_list_hint_accessible): This string is used
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/resources/layout/home_open_all_row.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+          android:text="@string/home_open_all"
+          style="@style/Widget.Home.ActionItem"/>
--- a/mobile/android/base/resources/values/styles.xml
+++ b/mobile/android/base/resources/values/styles.xml
@@ -228,16 +228,23 @@
         <item name="android:paddingLeft">10dip</item>
         <item name="android:paddingRight">10dip</item>
     </style>
 
     <style name="Widget.Home.ActionButton" parent="Widget.Home.PageButton">
         <item name="android:textAppearance">@style/TextAppearance.Widget.Home.PageAction</item>
     </style>
 
+    <style name="Widget.Home.ActionItem">
+        <item name="android:layout_width">fill_parent</item>
+        <item name="android:layout_height">40dip</item>
+        <item name="android:textColor">#000000</item>
+        <item name="android:gravity">center</item>
+    </style>
+
     <style name="Widget.Home.HistoryTabIndicator">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">32dp</item>
         <item name="android:textAppearance">@style/TextAppearance.Widget.Home.PageTitle</item>
         <item name="android:background">@drawable/home_panel_title_background</item>
         <item name="android:focusable">false</item>
         <item name="android:gravity">center|left</item>
         <item name="android:paddingLeft">10dip</item>
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -311,18 +311,18 @@
   <string name="home_top_sites_title">&home_top_sites_title;</string>
   <string name="home_top_sites_add">&home_top_sites_add;</string>
   <string name="home_history_title">&home_history_title;</string>
   <string name="home_clear_history_button">&home_clear_history_button;</string>
   <string name="home_clear_history_confirm">&home_clear_history_confirm;</string>
   <string name="home_bookmarks_empty">&home_bookmarks_empty;</string>
   <string name="home_closed_tabs_title">&home_closed_tabs_title;</string>
   <string name="home_last_tabs_title">&home_last_tabs_title;</string>
-  <string name="home_last_tabs_open">&home_last_tabs_open;</string>
   <string name="home_last_tabs_empty">&home_last_tabs_empty;</string>
+  <string name="home_open_all">&home_open_all;</string>
   <string name="home_most_recent_empty">&home_most_recent_empty;</string>
   <string name="home_reading_list_empty">&home_reading_list_empty;</string>
   <string name="home_reading_list_hint">&home_reading_list_hint2;</string>
   <string name="home_reading_list_hint_accessible">&home_reading_list_hint_accessible;</string>
   <string name="home_default_empty">&home_default_empty;</string>
   <string name="home_move_up_to_filter">&home_move_up_to_filter;</string>
   <string name="private_browsing_title">&private_browsing_title;</string>
   <string name="private_tabs_panel_description">&private_tabs_panel_description;</string>