☠☠ backed out by c2b5919558d3 ☠ ☠ | |
author | Shilpan Bhagat <sbhagat@mozilla.com> |
Fri, 26 Jul 2013 09:29:05 -0700 | |
changeset 143460 | 1491af6fc2aeb1e1cca33666cd1871ef38a24d9e |
parent 143459 | ef686945229b4ce2c3560d266bd29a39e975761a |
child 143461 | 8bd773e788ebb4c6fc7be325a3139bdf9c7e05d3 |
push id | 25130 |
push user | lrocha@mozilla.com |
push date | Wed, 21 Aug 2013 09:41:27 +0000 |
treeherder | mozilla-central@b2486721572e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | lucasr |
bugs | 895837 |
milestone | 25.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
|
--- a/mobile/android/base/BrowserApp.java +++ b/mobile/android/base/BrowserApp.java @@ -1312,17 +1312,17 @@ abstract public class BrowserApp extends } } } final PropertyAnimator animator = new PropertyAnimator(300); animator.setUseHardwareLayer(false); mBrowserToolbar.startEditing(url, animator); - showHomePagerWithAnimator(HomePager.Page.VISITED, animator); + showHomePagerWithAnimator(HomePager.Page.HISTORY, animator); animator.start(); } void commitEditingMode() { if (!mBrowserToolbar.isEditing()) { return; } @@ -1391,24 +1391,16 @@ abstract public class BrowserApp extends return; } final Tab tab = Tabs.getInstance().getSelectedTab(); if (tab != null && isAboutHome(tab)) { return; } - // Hide any visible homepager subpages - final FragmentManager fm = getSupportFragmentManager(); - final Fragment subPage = fm.findFragmentByTag(HomePager.SUBPAGE_TAG); - if (subPage != null) { - fm.beginTransaction().remove(subPage).commitAllowingStateLoss(); - fm.popBackStack(); - } - // FIXME: do animation if animate is true mHomePager.hide(); mBrowserToolbar.setShadowVisibility(true); mBrowserToolbar.setNextFocusDownId(R.id.layer_view); // Refresh toolbar height to possibly restore the toolbar padding refreshToolbarHeight();
--- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -224,28 +224,29 @@ FENNEC_JAVA_FILES = \ home/HistoryPage.java \ home/HomeFragment.java \ home/HomeListView.java \ home/HomePager.java \ home/HomePagerTabStrip.java \ home/FadedTextView.java \ home/FaviconsLoader.java \ home/LastTabsPage.java \ + home/MostRecentPage.java \ + home/MostVisitedPage.java \ home/PinBookmarkDialog.java \ home/ReadingListPage.java \ home/SearchEngine.java \ home/SearchEngineRow.java \ home/SearchLoader.java \ home/SimpleCursorLoader.java \ home/SuggestClient.java \ home/TopBookmarkItemView.java \ home/TopBookmarksAdapter.java \ home/TopBookmarksView.java \ home/TwoLinePageRow.java \ - home/VisitedPage.java \ menu/GeckoMenu.java \ menu/GeckoMenuInflater.java \ menu/GeckoMenuItem.java \ menu/GeckoSubMenu.java \ menu/MenuItemActionBar.java \ menu/MenuItemActionView.java \ menu/MenuItemDefault.java \ menu/MenuPanel.java \ @@ -460,21 +461,23 @@ RES_LAYOUT = \ res/layout/doorhanger_button.xml \ res/layout/find_in_page_content.xml \ res/layout/font_size_preference.xml \ res/layout/gecko_app.xml \ res/layout/home_bookmarks_page.xml \ res/layout/home_item_row.xml \ res/layout/home_header_row.xml \ res/layout/home_history_page.xml \ + res/layout/home_history_tabs_indicator.xml \ res/layout/home_last_tabs_page.xml \ res/layout/home_list_with_title.xml \ + res/layout/home_most_recent_page.xml \ + res/layout/home_most_visited_page.xml \ res/layout/home_search_item_row.xml \ res/layout/home_suggestion_prompt.xml \ - res/layout/home_visited_page.xml \ res/layout/web_app.xml \ res/layout/launch_app_list.xml \ res/layout/launch_app_listitem.xml \ res/layout/menu_action_bar.xml \ res/layout/menu_item_action_view.xml \ res/layout/menu_popup.xml \ res/layout/notification_icon_text.xml \ res/layout/notification_progress.xml \ @@ -627,16 +630,19 @@ RES_DRAWABLE_MDPI = \ res/drawable-mdpi/ic_menu_new_tab.png \ res/drawable-mdpi/ic_menu_reload.png \ res/drawable-mdpi/ic_status_logo.png \ res/drawable-mdpi/ic_url_bar_go.png \ res/drawable-mdpi/ic_url_bar_reader.png \ res/drawable-mdpi/ic_url_bar_search.png \ res/drawable-mdpi/ic_url_bar_star.png \ res/drawable-mdpi/ic_url_bar_tab.png \ + res/drawable-mdpi/icon_last_tabs.png \ + res/drawable-mdpi/icon_most_recent.png \ + res/drawable-mdpi/icon_most_visited.png \ res/drawable-mdpi/icon_pageaction.png \ res/drawable-mdpi/progress_spinner_1.png \ res/drawable-mdpi/progress_spinner_2.png \ res/drawable-mdpi/progress_spinner_3.png \ res/drawable-mdpi/progress_spinner_4.png \ res/drawable-mdpi/progress_spinner_5.png \ res/drawable-mdpi/progress_spinner_6.png \ res/drawable-mdpi/progress_spinner_7.png \ @@ -699,16 +705,17 @@ RES_DRAWABLE_MDPI = \ res/drawable-mdpi/bookmarkdefaults_favicon_addons.png \ res/drawable-mdpi/handle_end.png \ res/drawable-mdpi/handle_middle.png \ res/drawable-mdpi/handle_start.png \ res/drawable-mdpi/scrollbar.png \ res/drawable-mdpi/shadow.png \ res/drawable-mdpi/start.png \ res/drawable-mdpi/marketplace.png \ + res/drawable-mdpi/history_tabs_indicator_selected.9.png \ res/drawable-mdpi/warning.png \ res/drawable-mdpi/warning_doorhanger.png \ $(NULL) RES_DRAWABLE_LDPI = \ $(SYNC_RES_DRAWABLE_LDPI) \ $(NULL) @@ -739,16 +746,19 @@ RES_DRAWABLE_HDPI = \ res/drawable-hdpi/ic_menu_new_tab.png \ res/drawable-hdpi/ic_menu_reload.png \ res/drawable-hdpi/ic_status_logo.png \ res/drawable-hdpi/ic_url_bar_go.png \ res/drawable-hdpi/ic_url_bar_reader.png \ res/drawable-hdpi/ic_url_bar_search.png \ res/drawable-hdpi/ic_url_bar_star.png \ res/drawable-hdpi/ic_url_bar_tab.png \ + res/drawable-hdpi/icon_last_tabs.png \ + res/drawable-hdpi/icon_most_recent.png \ + res/drawable-hdpi/icon_most_visited.png \ res/drawable-hdpi/icon_pageaction.png \ res/drawable-hdpi/tab_indicator_divider.9.png \ res/drawable-hdpi/tab_indicator_selected.9.png \ res/drawable-hdpi/tab_indicator_selected_focused.9.png \ res/drawable-hdpi/spinner_default.9.png \ res/drawable-hdpi/spinner_focused.9.png \ res/drawable-hdpi/spinner_pressed.9.png \ res/drawable-hdpi/tab_new.png \ @@ -789,16 +799,17 @@ RES_DRAWABLE_HDPI = \ res/drawable-hdpi/reader_active.png \ res/drawable-hdpi/reading_list.png \ res/drawable-hdpi/validation_arrow.png \ res/drawable-hdpi/validation_arrow_inverted.png \ res/drawable-hdpi/validation_bg.9.png \ res/drawable-hdpi/handle_end.png \ res/drawable-hdpi/handle_middle.png \ res/drawable-hdpi/handle_start.png \ + res/drawable-hdpi/history_tabs_indicator_selected.9.png \ res/drawable-hdpi/warning.png \ res/drawable-hdpi/warning_doorhanger.png \ $(NULL) RES_DRAWABLE_XHDPI = \ res/drawable-xhdpi/blank.png \ res/drawable-xhdpi/favicon.png \ res/drawable-xhdpi/folder.png \ @@ -827,16 +838,19 @@ RES_DRAWABLE_XHDPI = \ res/drawable-xhdpi/ic_menu_new_tab.png \ res/drawable-xhdpi/ic_menu_reload.png \ res/drawable-xhdpi/ic_status_logo.png \ res/drawable-xhdpi/ic_url_bar_go.png \ res/drawable-xhdpi/ic_url_bar_reader.png \ res/drawable-xhdpi/ic_url_bar_search.png \ res/drawable-xhdpi/ic_url_bar_star.png \ res/drawable-xhdpi/ic_url_bar_tab.png \ + res/drawable-xhdpi/icon_last_tabs.png \ + res/drawable-xhdpi/icon_most_recent.png \ + res/drawable-xhdpi/icon_most_visited.png \ res/drawable-xhdpi/icon_pageaction.png \ res/drawable-xhdpi/spinner_default.9.png \ res/drawable-xhdpi/spinner_focused.9.png \ res/drawable-xhdpi/spinner_pressed.9.png \ res/drawable-xhdpi/tab_new.png \ res/drawable-xhdpi/tab_new_pb.png \ res/drawable-xhdpi/tab_close.png \ res/drawable-xhdpi/tab_thumbnail_default.png \ @@ -872,16 +886,17 @@ RES_DRAWABLE_XHDPI = \ res/drawable-xhdpi/tabs_private.png \ res/drawable-xhdpi/tabs_synced.png \ res/drawable-xhdpi/validation_arrow.png \ res/drawable-xhdpi/validation_arrow_inverted.png \ res/drawable-xhdpi/validation_bg.9.png \ res/drawable-xhdpi/handle_end.png \ res/drawable-xhdpi/handle_middle.png \ res/drawable-xhdpi/handle_start.png \ + res/drawable-xhdpi/history_tabs_indicator_selected.9.png \ res/drawable-xhdpi/warning.png \ res/drawable-xhdpi/warning_doorhanger.png \ $(NULL) RES_DRAWABLE_MDPI_V11 = \ res/drawable-mdpi-v11/alert_addon.png \ res/drawable-mdpi-v11/alert_app.png \ res/drawable-mdpi-v11/alert_download.png \ @@ -1046,16 +1061,18 @@ RES_DRAWABLE += \ res/drawable/url_bar_entry.xml \ res/drawable/url_bar_nav_button.xml \ res/drawable/url_bar_right_edge.xml \ res/drawable/bookmark_folder.xml \ res/drawable/divider_vertical.xml \ res/drawable/favicon_bg.xml \ res/drawable/handle_end_level.xml \ res/drawable/handle_start_level.xml \ + res/drawable/home_history_tabs_indicator.xml \ + res/drawable/home_page_title_background.xml \ res/drawable/ic_menu_back.xml \ res/drawable/ic_menu_desktop_mode_off.xml \ res/drawable/ic_menu_desktop_mode_on.xml \ res/drawable/ic_menu_quit.xml \ res/drawable/menu_item_state.xml \ res/drawable/menu_level.xml \ res/drawable/progress_spinner.xml \ res/drawable/remote_tabs_child_divider.xml \
--- a/mobile/android/base/home/HistoryPage.java +++ b/mobile/android/base/home/HistoryPage.java @@ -1,365 +1,99 @@ /* -*- 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 org.mozilla.gecko.R; -import org.mozilla.gecko.db.BrowserDB; -import org.mozilla.gecko.db.BrowserDB.URLColumns; -import org.mozilla.gecko.home.HomePager.OnUrlOpenListener; -import org.mozilla.gecko.home.TwoLinePageRow; - -import android.app.Activity; -import android.content.ContentResolver; +import org.mozilla.gecko.widget.IconTabWidget; +import android.support.v4.app.Fragment; import android.content.Context; import android.content.res.Resources; -import android.database.Cursor; import android.os.Bundle; -import android.support.v4.app.LoaderManager.LoaderCallbacks; -import android.support.v4.content.Loader; -import android.support.v4.widget.SimpleCursorAdapter; -import android.util.SparseArray; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.LayoutInflater; -import android.widget.AdapterView; -import android.widget.ListView; -import android.widget.TextView; + +import android.widget.ImageButton; -import java.util.Date; - -/** - * Fragment that displays recent history in a ListView. - */ -public class HistoryPage extends HomeFragment { +public class HistoryPage extends HomeFragment + implements IconTabWidget.OnTabChangedListener { // Logging tag name private static final String LOGTAG = "GeckoHistoryPage"; - - // Cursor loader ID for history query - private static final int HISTORY_LOADER_ID = 0; - - // For the time sections in history - private static final long MS_PER_DAY = 86400000; - private static final long MS_PER_WEEK = MS_PER_DAY * 7; - - // The time ranges for each section - private static enum HistorySection { - TODAY, - YESTERDAY, - WEEK, - OLDER - }; - - // Maps headers in the list with their respective sections - private SparseArray<HistorySection> mHistorySections; - - // Adapter for the list of search results - private HistoryAdapter mAdapter; - - // The view shown by the fragment. - private ListView mList; - - // Callbacks used for the search and favicon cursor loaders - private CursorLoaderCallbacks mCursorLoaderCallbacks; - - // Inflater used by the adapter - private LayoutInflater mInflater; - - // On URL open listener - private OnUrlOpenListener mUrlOpenListener; - - public static HistoryPage newInstance() { - return new HistoryPage(); - } - - public HistoryPage() { - mUrlOpenListener = null; - } - - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - - try { - mUrlOpenListener = (OnUrlOpenListener) activity; - } catch (ClassCastException e) { - throw new ClassCastException(activity.toString() - + " must implement HomePager.OnUrlOpenListener"); - } - - mInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - } - - @Override - public void onDetach() { - super.onDetach(); - - mHistorySections = null; - mInflater = null; - mUrlOpenListener = null; - } + private IconTabWidget mTabWidget; + private int mSelectedTab; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.home_history_page, container, false); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { - final TextView title = (TextView) view.findViewById(R.id.title); - title.setText(R.string.history_title); - - mList = (ListView) view.findViewById(R.id.list); + super.onViewCreated(view, savedInstanceState); - mList.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView<?> parent, View view, int position, long id) { - position -= getHistorySectionsCountBefore(position); + mTabWidget = (IconTabWidget) view.findViewById(R.id.tab_icon_widget); - final Cursor c = mAdapter.getCursor(); - if (c == null || !c.moveToPosition(position)) { - return; - } + ImageButton button; + final Resources resources = view.getContext().getResources(); - final String url = c.getString(c.getColumnIndexOrThrow(URLColumns.URL)); - mUrlOpenListener.onUrlOpen(url); - } - }); + button = mTabWidget.addTab(R.drawable.icon_most_visited); + button.setContentDescription(resources.getString(R.string.home_most_visited_title)); - registerForContextMenu(mList); - } + button = mTabWidget.addTab(R.drawable.icon_most_recent); + button.setContentDescription(resources.getString(R.string.home_most_recent_title)); - @Override - public void onDestroyView() { - super.onDestroyView(); - mList = null; - } + button = mTabWidget.addTab(R.drawable.icon_last_tabs); + button.setContentDescription(resources.getString(R.string.home_last_tabs_title)); - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - // Initialize map of history sections - mHistorySections = new SparseArray<HistorySection>(); + //Show most visited page as the initial page + showMostVisitedPage(); - // Intialize adapter - mAdapter = new HistoryAdapter(getActivity()); - mList.setAdapter(mAdapter); - - // Create callbacks before the initial loader is started - mCursorLoaderCallbacks = new CursorLoaderCallbacks(); - loadIfVisible(); + mTabWidget.setTabSelectionListener(this); + mTabWidget.setCurrentTab(mSelectedTab); } @Override - protected void load() { - getLoaderManager().initLoader(HISTORY_LOADER_ID, null, mCursorLoaderCallbacks); - } - - private String getHistorySectionTitle(HistorySection section) { - final Resources resources = getActivity().getResources(); - - switch (section) { - case TODAY: - return resources.getString(R.string.history_today_section); - case YESTERDAY: - return resources.getString(R.string.history_yesterday_section); - case WEEK: - return resources.getString(R.string.history_week_section); - case OLDER: - return resources.getString(R.string.history_older_section); - } - - throw new IllegalStateException("Unrecognized history section"); - } - - private int getHistorySectionsCountBefore(int position) { - // Account for the number headers before the given position - int sectionsBefore = 0; + public void load() {} - final int historySectionsCount = mHistorySections.size(); - for (int i = 0; i < historySectionsCount; i++) { - final int sectionPosition = mHistorySections.keyAt(i); - if (sectionPosition > position) { - break; - } - - sectionsBefore++; - } - - return sectionsBefore; - } - - private HistorySection getHistorySectionForTime(long from, long time) { - long delta = from - time; - - if (delta < 0) { - return HistorySection.TODAY; - } - - if (delta < MS_PER_DAY) { - return HistorySection.YESTERDAY; - } - - if (delta < MS_PER_WEEK) { - return HistorySection.WEEK; - } - - return HistorySection.OLDER; - } - - private void loadHistorySections(Cursor c) { - if (c == null || !c.moveToFirst()) { + @Override + public void onTabChanged(int index) { + if (index == mSelectedTab) { return; } - // Clear any history sections that may have been loaded before. - mHistorySections.clear(); - - final Date now = new Date(); - now.setHours(0); - now.setMinutes(0); - now.setSeconds(0); - - final long today = now.getTime(); - HistorySection section = null; - - do { - final int position = c.getPosition(); - final long time = c.getLong(c.getColumnIndexOrThrow(URLColumns.DATE_LAST_VISITED)); - final HistorySection itemSection = getHistorySectionForTime(today, time); - - if (section != itemSection) { - section = itemSection; - mHistorySections.append(position + mHistorySections.size(), section); - } - - // Reached the last section, no need to continue - if (section == HistorySection.OLDER) { - break; - } - } while (c.moveToNext()); - } - - private static class HistoryCursorLoader extends SimpleCursorLoader { - // Max number of history results - private static final int HISTORY_LIMIT = 100; - - public HistoryCursorLoader(Context context) { - super(context); - } - - @Override - public Cursor loadCursor() { - final ContentResolver cr = getContext().getContentResolver(); - return BrowserDB.getRecentHistory(cr, HISTORY_LIMIT); - } - } - - private class HistoryAdapter extends SimpleCursorAdapter { - private static final int ROW_HEADER = 0; - private static final int ROW_STANDARD = 1; - - private static final int ROW_TYPE_COUNT = 2; - - public HistoryAdapter(Context context) { - super(context, -1, null, new String[] {}, new int[] {}); - } - - @Override - public Object getItem(int position) { - final int type = getItemViewType(position); - - // Header items are not in the cursor - if (type == ROW_HEADER) { - return null; - } - - return super.getItem(position - getHistorySectionsCountBefore(position)); - } - - @Override - public int getItemViewType(int position) { - if (mHistorySections.get(position) != null) { - return ROW_HEADER; - } - - return ROW_STANDARD; + if (index == 0) { + showMostVisitedPage(); + } else if (index == 1) { + showMostRecentPage(); + } else if (index == 2) { + showLastTabsPage(); } - @Override - public int getViewTypeCount() { - // view can be either a standard page row, or a header row - return ROW_TYPE_COUNT; - } - - @Override - public boolean isEnabled(int position) { - return (getItemViewType(position) == ROW_STANDARD); - } - - @Override - public int getCount() { - // Add the history section headers to the number of reported results. - return super.getCount() + mHistorySections.size(); - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - final int type = getItemViewType(position); + mTabWidget.setCurrentTab(index); + mSelectedTab = index; + } - if (type == ROW_HEADER) { - final TextView row; - if (convertView == null) { - row = (TextView) mInflater.inflate(R.layout.home_header_row, mList, false); - } else { - row = (TextView) convertView; - } - - final HistorySection section = mHistorySections.get(position); - row.setText(getHistorySectionTitle(section)); - - return row; - } else { - final TwoLinePageRow row; - if (convertView == null) { - row = (TwoLinePageRow) mInflater.inflate(R.layout.home_item_row, mList, false); - } else { - row = (TwoLinePageRow) convertView; - } - - // Account for the search engines - position -= getHistorySectionsCountBefore(position); - - final Cursor c = getCursor(); - if (!c.moveToPosition(position)) { - throw new IllegalStateException("Couldn't move cursor to position " + position); - } - - row.updateFromCursor(c); - - return row; - } - } + private void showSubPage(Fragment subPage) { + getChildFragmentManager().beginTransaction() + .addToBackStack(null).replace(R.id.visited_page_container, subPage) + .commitAllowingStateLoss(); } - private class CursorLoaderCallbacks implements LoaderCallbacks<Cursor> { - @Override - public Loader<Cursor> onCreateLoader(int id, Bundle args) { - return new HistoryCursorLoader(getActivity()); - } + private void showMostVisitedPage() { + final MostVisitedPage mostVisitedPage = MostVisitedPage.newInstance(); + showSubPage(mostVisitedPage); + } - @Override - public void onLoadFinished(Loader<Cursor> loader, Cursor c) { - loadHistorySections(c); - mAdapter.swapCursor(c); - } + private void showMostRecentPage() { + final MostRecentPage mostRecentPage = MostRecentPage.newInstance(); + showSubPage(mostRecentPage); + } - @Override - public void onLoaderReset(Loader<Cursor> loader) { - mAdapter.swapCursor(null); - } + private void showLastTabsPage() { + final LastTabsPage lastTabsPage = LastTabsPage.newInstance(); + showSubPage(lastTabsPage); } }
--- a/mobile/android/base/home/HomeFragment.java +++ b/mobile/android/base/home/HomeFragment.java @@ -41,22 +41,16 @@ abstract class HomeFragment extends Frag private static final String LOGTAG="GeckoHomeFragment"; // Share MIME type. private static final String SHARE_MIME_TYPE = "text/plain"; // URL to Title replacement regex. private static final String REGEX_URL_TO_TITLE = "^([a-z]+://)?(www\\.)?"; - protected void showSubPage(Fragment subPage) { - getActivity().getSupportFragmentManager().beginTransaction() - .addToBackStack(null).replace(R.id.home_pager_container, subPage, HomePager.SUBPAGE_TAG) - .commitAllowingStateLoss(); - } - @Override public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) { if (menuInfo == null || !(menuInfo instanceof HomeContextMenuInfo)) { return; } HomeContextMenuInfo info = (HomeContextMenuInfo) menuInfo;
--- a/mobile/android/base/home/HomePager.java +++ b/mobile/android/base/home/HomePager.java @@ -27,17 +27,17 @@ public class HomePager extends ViewPager // Subpage fragment tag public static final String SUBPAGE_TAG = "home_pager_subpage"; private final Context mContext; private volatile boolean mLoaded; // List of pages in order. public enum Page { - VISITED, + HISTORY, BOOKMARKS, READING_LIST } private EnumMap<Page, Fragment> mPages = new EnumMap<Page, Fragment>(Page.class); public interface OnUrlOpenListener { public void onUrlOpen(String url); @@ -65,17 +65,17 @@ public class HomePager extends ViewPager * * @param fm FragmentManager for the adapter */ public void show(FragmentManager fm, Page page, PropertyAnimator animator) { mLoaded = true; TabsAdapter adapter = new TabsAdapter(fm); // Add the pages to the adapter in order. - adapter.addTab(Page.VISITED, VisitedPage.class, null, getContext().getString(R.string.visited_title)); + adapter.addTab(Page.HISTORY, HistoryPage.class, null, getContext().getString(R.string.home_history_title)); adapter.addTab(Page.BOOKMARKS, BookmarksPage.class, null, getContext().getString(R.string.bookmarks_title)); adapter.addTab(Page.READING_LIST, ReadingListPage.class, null, getContext().getString(R.string.reading_list)); setAdapter(adapter); setCurrentItem(adapter.getItemPosition(page), false); setVisibility(VISIBLE);
copy from mobile/android/base/home/HistoryPage.java copy to mobile/android/base/home/MostRecentPage.java --- a/mobile/android/base/home/HistoryPage.java +++ b/mobile/android/base/home/MostRecentPage.java @@ -28,58 +28,58 @@ import android.widget.AdapterView; import android.widget.ListView; import android.widget.TextView; import java.util.Date; /** * Fragment that displays recent history in a ListView. */ -public class HistoryPage extends HomeFragment { +public class MostRecentPage extends HomeFragment { // Logging tag name - private static final String LOGTAG = "GeckoHistoryPage"; + private static final String LOGTAG = "GeckoMostRecentPage"; // Cursor loader ID for history query private static final int HISTORY_LOADER_ID = 0; // For the time sections in history private static final long MS_PER_DAY = 86400000; private static final long MS_PER_WEEK = MS_PER_DAY * 7; // The time ranges for each section - private static enum HistorySection { + private static enum MostRecentSection { TODAY, YESTERDAY, WEEK, OLDER }; // Maps headers in the list with their respective sections - private SparseArray<HistorySection> mHistorySections; + private SparseArray<MostRecentSection> mMostRecentSections; // Adapter for the list of search results - private HistoryAdapter mAdapter; + private MostRecentAdapter mAdapter; // The view shown by the fragment. private ListView mList; // Callbacks used for the search and favicon cursor loaders private CursorLoaderCallbacks mCursorLoaderCallbacks; // Inflater used by the adapter private LayoutInflater mInflater; // On URL open listener private OnUrlOpenListener mUrlOpenListener; - public static HistoryPage newInstance() { - return new HistoryPage(); + public static MostRecentPage newInstance() { + return new MostRecentPage(); } - public HistoryPage() { + public MostRecentPage() { mUrlOpenListener = null; } @Override public void onAttach(Activity activity) { super.onAttach(activity); try { @@ -91,37 +91,37 @@ public class HistoryPage extends HomeFra mInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public void onDetach() { super.onDetach(); - mHistorySections = null; + mMostRecentSections = null; mInflater = null; mUrlOpenListener = null; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.home_history_page, container, false); + return inflater.inflate(R.layout.home_most_recent_page, container, false); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { final TextView title = (TextView) view.findViewById(R.id.title); - title.setText(R.string.history_title); + title.setText(R.string.home_most_recent_title); mList = (ListView) view.findViewById(R.id.list); mList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { - position -= getHistorySectionsCountBefore(position); + position -= getMostRecentSectionsCountBefore(position); final Cursor c = mAdapter.getCursor(); if (c == null || !c.moveToPosition(position)) { return; } final String url = c.getString(c.getColumnIndexOrThrow(URLColumns.URL)); mUrlOpenListener.onUrlOpen(url); @@ -137,157 +137,157 @@ public class HistoryPage extends HomeFra mList = null; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Initialize map of history sections - mHistorySections = new SparseArray<HistorySection>(); + mMostRecentSections = new SparseArray<MostRecentSection>(); // Intialize adapter - mAdapter = new HistoryAdapter(getActivity()); + mAdapter = new MostRecentAdapter(getActivity()); mList.setAdapter(mAdapter); // Create callbacks before the initial loader is started mCursorLoaderCallbacks = new CursorLoaderCallbacks(); loadIfVisible(); } @Override protected void load() { getLoaderManager().initLoader(HISTORY_LOADER_ID, null, mCursorLoaderCallbacks); } - private String getHistorySectionTitle(HistorySection section) { + private String getMostRecentSectionTitle(MostRecentSection section) { final Resources resources = getActivity().getResources(); switch (section) { case TODAY: return resources.getString(R.string.history_today_section); case YESTERDAY: return resources.getString(R.string.history_yesterday_section); case WEEK: return resources.getString(R.string.history_week_section); case OLDER: return resources.getString(R.string.history_older_section); } throw new IllegalStateException("Unrecognized history section"); } - private int getHistorySectionsCountBefore(int position) { + private int getMostRecentSectionsCountBefore(int position) { // Account for the number headers before the given position int sectionsBefore = 0; - final int historySectionsCount = mHistorySections.size(); + final int historySectionsCount = mMostRecentSections.size(); for (int i = 0; i < historySectionsCount; i++) { - final int sectionPosition = mHistorySections.keyAt(i); + final int sectionPosition = mMostRecentSections.keyAt(i); if (sectionPosition > position) { break; } sectionsBefore++; } return sectionsBefore; } - private HistorySection getHistorySectionForTime(long from, long time) { + private MostRecentSection getMostRecentSectionForTime(long from, long time) { long delta = from - time; if (delta < 0) { - return HistorySection.TODAY; + return MostRecentSection.TODAY; } if (delta < MS_PER_DAY) { - return HistorySection.YESTERDAY; + return MostRecentSection.YESTERDAY; } if (delta < MS_PER_WEEK) { - return HistorySection.WEEK; + return MostRecentSection.WEEK; } - return HistorySection.OLDER; + return MostRecentSection.OLDER; } - private void loadHistorySections(Cursor c) { + private void loadMostRecentSections(Cursor c) { if (c == null || !c.moveToFirst()) { return; } // Clear any history sections that may have been loaded before. - mHistorySections.clear(); + mMostRecentSections.clear(); final Date now = new Date(); now.setHours(0); now.setMinutes(0); now.setSeconds(0); final long today = now.getTime(); - HistorySection section = null; + MostRecentSection section = null; do { final int position = c.getPosition(); final long time = c.getLong(c.getColumnIndexOrThrow(URLColumns.DATE_LAST_VISITED)); - final HistorySection itemSection = getHistorySectionForTime(today, time); + final MostRecentSection itemSection = getMostRecentSectionForTime(today, time); if (section != itemSection) { section = itemSection; - mHistorySections.append(position + mHistorySections.size(), section); + mMostRecentSections.append(position + mMostRecentSections.size(), section); } // Reached the last section, no need to continue - if (section == HistorySection.OLDER) { + if (section == MostRecentSection.OLDER) { break; } } while (c.moveToNext()); } - private static class HistoryCursorLoader extends SimpleCursorLoader { + private static class MostRecentCursorLoader extends SimpleCursorLoader { // Max number of history results private static final int HISTORY_LIMIT = 100; - public HistoryCursorLoader(Context context) { + public MostRecentCursorLoader(Context context) { super(context); } @Override public Cursor loadCursor() { final ContentResolver cr = getContext().getContentResolver(); return BrowserDB.getRecentHistory(cr, HISTORY_LIMIT); } } - private class HistoryAdapter extends SimpleCursorAdapter { + private class MostRecentAdapter extends SimpleCursorAdapter { private static final int ROW_HEADER = 0; private static final int ROW_STANDARD = 1; private static final int ROW_TYPE_COUNT = 2; - public HistoryAdapter(Context context) { + public MostRecentAdapter(Context context) { super(context, -1, null, new String[] {}, new int[] {}); } @Override public Object getItem(int position) { final int type = getItemViewType(position); // Header items are not in the cursor if (type == ROW_HEADER) { return null; } - return super.getItem(position - getHistorySectionsCountBefore(position)); + return super.getItem(position - getMostRecentSectionsCountBefore(position)); } @Override public int getItemViewType(int position) { - if (mHistorySections.get(position) != null) { + if (mMostRecentSections.get(position) != null) { return ROW_HEADER; } return ROW_STANDARD; } @Override public int getViewTypeCount() { @@ -298,67 +298,67 @@ public class HistoryPage extends HomeFra @Override public boolean isEnabled(int position) { return (getItemViewType(position) == ROW_STANDARD); } @Override public int getCount() { // Add the history section headers to the number of reported results. - return super.getCount() + mHistorySections.size(); + return super.getCount() + mMostRecentSections.size(); } @Override public View getView(int position, View convertView, ViewGroup parent) { final int type = getItemViewType(position); if (type == ROW_HEADER) { final TextView row; if (convertView == null) { row = (TextView) mInflater.inflate(R.layout.home_header_row, mList, false); } else { row = (TextView) convertView; } - final HistorySection section = mHistorySections.get(position); - row.setText(getHistorySectionTitle(section)); + final MostRecentSection section = mMostRecentSections.get(position); + row.setText(getMostRecentSectionTitle(section)); return row; } else { final TwoLinePageRow row; if (convertView == null) { row = (TwoLinePageRow) mInflater.inflate(R.layout.home_item_row, mList, false); } else { row = (TwoLinePageRow) convertView; } // Account for the search engines - position -= getHistorySectionsCountBefore(position); + position -= getMostRecentSectionsCountBefore(position); final Cursor c = getCursor(); if (!c.moveToPosition(position)) { throw new IllegalStateException("Couldn't move cursor to position " + position); } row.updateFromCursor(c); return row; } } } private class CursorLoaderCallbacks implements LoaderCallbacks<Cursor> { @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { - return new HistoryCursorLoader(getActivity()); + return new MostRecentCursorLoader(getActivity()); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor c) { - loadHistorySections(c); + loadMostRecentSections(c); mAdapter.swapCursor(c); } @Override public void onLoaderReset(Loader<Cursor> loader) { mAdapter.swapCursor(null); } }
rename from mobile/android/base/home/VisitedPage.java rename to mobile/android/base/home/MostVisitedPage.java --- a/mobile/android/base/home/VisitedPage.java +++ b/mobile/android/base/home/MostVisitedPage.java @@ -18,49 +18,51 @@ import android.os.Bundle; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.Loader; import android.support.v4.widget.CursorAdapter; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ListView; +import android.widget.TextView; /** * Fragment that displays frecency search results in a ListView. */ -public class VisitedPage extends HomeFragment { +public class MostVisitedPage extends HomeFragment { // Logging tag name - private static final String LOGTAG = "GeckoVisitedPage"; + private static final String LOGTAG = "GeckoMostVisitedPage"; // Cursor loader ID for search query private static final int FRECENCY_LOADER_ID = 0; // Cursor loader ID for favicons query private static final int FAVICONS_LOADER_ID = 1; // Adapter for the list of search results private VisitedAdapter mAdapter; // The view shown by the fragment. private ListView mList; // Empty message view private View mEmptyMessage; - // Buttons container - private View mButtonsContainer; - // Callbacks used for the search and favicon cursor loaders private CursorLoaderCallbacks mCursorLoaderCallbacks; // On URL open listener private OnUrlOpenListener mUrlOpenListener; - public VisitedPage() { + public static MostVisitedPage newInstance() { + return new MostVisitedPage(); + } + + public MostVisitedPage() { mUrlOpenListener = null; } @Override public void onAttach(Activity activity) { super.onAttach(activity); try { @@ -75,65 +77,47 @@ public class VisitedPage extends HomeFra public void onDetach() { super.onDetach(); mUrlOpenListener = null; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.home_visited_page, container, false); + return inflater.inflate(R.layout.home_most_visited_page, container, false); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); + final TextView title = (TextView) view.findViewById(R.id.title); + title.setText(R.string.home_most_visited_title); - mList = (HomeListView) view.findViewById(R.id.visited_list); + mEmptyMessage = view.findViewById(R.id.empty_message); + mList = (HomeListView) view.findViewById(R.id.list); 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 String url = c.getString(c.getColumnIndexOrThrow(URLColumns.URL)); mUrlOpenListener.onUrlOpen(url); } }); registerForContextMenu(mList); - - mEmptyMessage = view.findViewById(R.id.empty_message); - mButtonsContainer = view.findViewById(R.id.buttons_container); - - final View historyButton = view.findViewById(R.id.history_button); - historyButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - showHistoryPage(); - } - }); - - final View tabsButton = view.findViewById(R.id.tabs_button); - tabsButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - showTabsPage(); - } - }); } @Override public void onDestroyView() { super.onDestroyView(); mList = null; - mButtonsContainer = null; mEmptyMessage = null; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Intialize the search adapter @@ -145,26 +129,16 @@ public class VisitedPage extends HomeFra loadIfVisible(); } @Override protected void load() { getLoaderManager().initLoader(FRECENCY_LOADER_ID, null, mCursorLoaderCallbacks); } - private void showHistoryPage() { - final HistoryPage historyPage = HistoryPage.newInstance(); - showSubPage(historyPage); - } - - private void showTabsPage() { - final LastTabsPage lastTabsPage = LastTabsPage.newInstance(); - showSubPage(lastTabsPage); - } - private static class FrecencyCursorLoader extends SimpleCursorLoader { // Max number of search results private static final int SEARCH_LIMIT = 50; public FrecencyCursorLoader(Context context) { super(context); } @@ -210,19 +184,16 @@ public class VisitedPage extends HomeFra public void onLoadFinished(Loader<Cursor> loader, Cursor c) { final int loaderId = loader.getId(); switch(loaderId) { case FRECENCY_LOADER_ID: // Only set empty view once cursor is loaded to avoid // flashing the empty message before loading. mList.setEmptyView(mEmptyMessage); - final int buttonsVisibility = (c.getCount() == 0 ? View.GONE : View.VISIBLE); - mButtonsContainer.setVisibility(buttonsVisibility); - mAdapter.swapCursor(c); FaviconsLoader.restartFromCursor(getLoaderManager(), FAVICONS_LOADER_ID, mCursorLoaderCallbacks, c); break; case FAVICONS_LOADER_ID: // Causes the listview to recreate its children and use the @@ -241,9 +212,9 @@ public class VisitedPage extends HomeFra break; case FAVICONS_LOADER_ID: // Do nothing break; } } } -} \ No newline at end of file +}
--- a/mobile/android/base/locales/en-US/android_strings.dtd +++ b/mobile/android/base/locales/en-US/android_strings.dtd @@ -3,19 +3,17 @@ - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> <!ENTITY no_space_to_start_error "There is not enough space available for &brandShortName; to start."> <!ENTITY error_loading_file "An error occurred when trying to load files required to run &brandShortName;"> <!ENTITY all_pages_title "Top Sites"> <!ENTITY bookmarks_title "Bookmarks"> -<!ENTITY history_title "History"> <!ENTITY switch_to_tab "Switch to tab"> -<!ENTITY visited_title "Visited"> <!ENTITY crash_reporter_title "&brandShortName; Crash Reporter"> <!ENTITY crash_message2 "&brandShortName; had a problem and crashed. Your tabs should be listed on the &brandShortName; Start page when you restart."> <!ENTITY crash_send_report_message3 "Tell &vendorShortName; about this crash so they can fix it"> <!ENTITY crash_include_url2 "Include the address of the page I was on"> <!ENTITY crash_sorry "We\'re sorry"> <!ENTITY crash_comment "Add a comment (comments are publicly visible)"> <!ENTITY crash_allow_contact2 "Allow &vendorShortName; to contact me about this report"> @@ -264,18 +262,21 @@ size. --> <!ENTITY button_ok "OK"> <!ENTITY button_cancel "Cancel"> <!ENTITY button_yes "Yes"> <!ENTITY button_no "No"> <!ENTITY button_clear_data "Clear data"> <!ENTITY button_set "Set"> <!ENTITY button_clear "Clear"> -<!ENTITY home_last_tabs_title "Your tabs from last time"> +<!ENTITY home_history_title "History"> +<!ENTITY home_last_tabs_title "Tabs from last time"> <!ENTITY home_last_tabs_open "Open all tabs from last time"> +<!ENTITY home_most_recent_title "Most recent"> +<!ENTITY home_most_visited_title "Most visited"> <!ENTITY home_visited_empty "Websites you visited go here"> <!ENTITY pin_bookmark_dialog_hint "Enter a search keyword"> <!ENTITY filepicker_title "Choose File"> <!ENTITY filepicker_audio_title "Choose or record a sound"> <!ENTITY filepicker_image_title "Choose or take a picture"> <!ENTITY filepicker_video_title "Choose or record a video">
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..03ead6aa8b1c72bd1af9d5a4b1280d2de42254ac GIT binary patch literal 2815 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 R#6182002ovPDHLkV1n2ZH+uj8
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8c2b41f9d2f41d13560da67710f17387c27873c9 GIT binary patch literal 446 zc%17D@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezr3(Ft&QSIEGZ*dV9lAqa{)1_{Z&6 z3^mi0Py2d#t?4n6@bU7L+;DR0l9IrpyVem?rkq`(eY-Mz`mWGNDU&bp@*FQXCSGrU z+uruQ?SJ>{xA*?!pa1dt=bGu?YpZRQyi9m6Fu+hl7<<m!H-Bfe*!*C7eS!O)e)5Fw z8#xZgHk>rM`R0&@1$#=P&OC*)dPcnR(|noPZl+1x)157_EQa}&1Jmj^Mxqa&b>#N7 z&i1~}Af&b7bV%#$;%%HQv$L#OS)>*)a&mAqvTVDVn%6R0>Gm8>^XuyvRTa7g+-{`S zC^SZHn<<?4X&qyxMWc9y@s4K64>Lr5e300<GyOep9<Q8|nW=`uDbodS|D0}6JaK5* zL7NgOKB<PO9cP)o91-21Q6UuTC~lp?BsI;K_tzti3O1pLwDu{jvzxE69r>@Mt!k?P z^qz;q0rd$EeX>Q`cjg=uEMQbIILBuxk~i%U$BTBO8b--0yz*&x19Co1e<=EG;bVTr jU+I3#CJr!k;DPk{tQ`m6OYE@$#tVa|tDnm{r-UW|S=_Z|
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1924bc4a044517474aeeceb03936a4ebb996942e GIT binary patch literal 841 zc$@)A1GfB$P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm0009JNkl<Zc-rmR zZ)i<n0LSrT)@66tUT9`6!d^@*%tV$%q!D{z4b!~YP?i)inMB-oi|_{XXBpC1OUt5` zH%8HF3Co`uEv5X6O=LEEd|&L<uWmc{+;h%N-4~xXclUYD`QEd0?zzvgj4}VUL_i`S z5g;#A9}YV;6`K*pHMF1=O}Kz6tU{{8`8^59LNz*JZ0bh~N{}3{fDD{NKTHhXq5?^N z22|i1jEf#4$LoL;T!)FE3#U<v`IvzW%))Z)#0~s_f%=IuuL9EX07eX<2?el3A@(37 zuLn_%R}to`ayuZ1M=;{K?704$nPDH121_JkFMh#@eQpNagb{T}ffYfcynhL-2y)R4 zJrZl(2-pE5YA{MC7q>?UP?>lpW4<C3OTZNL%A~chgwp^O!h0Fl7)!uKnXCh2Tn<nL z7?80`odismi3X7e%Yy)QLdLc_2?)z1^{{*jNJp=n(Am)jyptWs^*BJ)$oM1C1mwuz zc33_K<jVMm(FAOh!N+_LfLxIVFxGB>o<wWn6rf+AbL<A(l7ZPS1hk_yf;-p_OX!89 z$Zo(r8JOlYAWDTY$8Pz1ncaXk8R+CE;AIB^l_T87Y_%KEA_FHm2v~qV7@OW;qReqX z-m}4OK)noH2+M)-$V0wRc@b_=&d7c&vl~#YhYnU8+?V~xvKz2k23~>XvvK$hGwee& zUu3EH12e1_L7xN4<U_m~?Y&U5Oi=D~fL;mLM;lNq6Liao=B1Ug?av5A8!#HWYH$da z#{zgE+db&?7g;HENpP{p0jFSeMZ;MDptlvDkPXWNl`vvUtg8~!@I@x=!E9JA+Jzz6 zPJ>(PLMxz)xV_lu()GR$Mm)uYSOQcj24O_A!=sUeP3VCUT?l!xxLXuq8SpQfQ3Czc zR5teGH4Ib-GQC`0pC^|&HHar@z*!teE$%`Wt<)t1{dhi*g0P$yvFO6OcsybX;UvDp zIM9i51pI!)q*73f^LU8?7^pt9;VAOGf5_)t05g$~MVO1pF3g*F(47cK1VH@*+q3bN T%mAVp00000NkvXXu0mjf^(A%t
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e7cf2b3b9ce181aaf6efa8a5ff0d54f9d71da054 GIT binary patch literal 421 zc%17D@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezr3(Fy?r=IEGZ*dV6!DH&dca`^W8V zJquRqDlIa5sCH1ds6(ths^@@GMqU92i(^#OB!#F&YgcM!Xx!1-V6WhuvBlLRYLi*_ zi?@<ePZV~1x%d6+EAyHi2cQ1#D1YDRl`Weoq`)ZjA)blrwzcIR$NKE@nAs~9_BcP; z*u>(t(CI?)0ojsvqY?++7{#|n3!X_&ZTz>in&*r60g<@f9UkAj52&o$&9URC-ZaC< zRtfUE+;w9faa5*kY^l^yXqMqpV=`N)`{T%*&W0^Z8<>Ob7q+y13_aq*>LV?8|3J&m z*%EBW_aA8PN;+UX$xLqXyvC2EM{?&fubgmve)5@Tj@!g8eQ;m1%c9ep@tA30v+<Ui z`L+q%%Io4(wd`$d{U#jUk$*%}OCwRNS?_+U&6b598@Y9q*hHtCZm_jk_~QSv#X<o` zHZ(2_d(WuK2=XNoa%3|5z}K71<ErbR*jlO~{v<z)b3%i?#0S>gon8B0^LI7?gP+0E L)z4*}Q$iB}tvaeS
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5def384c1389a80ac0894db64cd8938005afe8e1 GIT binary patch literal 2819 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 VUmb80ZF2ws002ovPDHLkV1g^tIimmo
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f577fd4c46c1382faccd4bab095a29c9c2cdddfc GIT binary patch literal 361 zc$@)g0ha!WP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80003nNkl<Zc-rmO zp-V$i7>4nyGYO6blNJqvL)J8CoJog4!GA!VdCj3g5Ya3MnuW<&RGZOi5SvZwU>4I5 zJwAi?f?V%8CtQXKC;Za)@$tar-Yqi5{HhQT0z$yw3fSF0?5W}sEoq{LoaQ4q&@6U= z3L=@pSz_lLMPI-YjK!9YpIGMan9$CnW#`Eku;U0g*6|z1&a!rljW3{{F`)AA18Oi9 zM>>A(*jdz0*E0X`1x(`&CZUT39pA)f%FZ+L+G$t<TE2juajarp)-b7AtfX0N1qDQs zLpiZi#*i<d?|cEnxIzc7-`rwUM`rMln746?fvf==Fcx*!^OZSYK;K`(5Rf%s+i`qP zN1BeE`K$qX+@*YI?lGn#vv^7QC2U~O6A=Cpg@6zc0)F@c^7DZu@?z*(00000NkvXX Hu0mjf-0Pu_
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e0cfd2ddb781d3c78ac3a449e315b49c9db74034 GIT binary patch literal 599 zc$@)O0;v6oP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80006WNkl<Zc-rmP zPl$|R9KiAC-7Sq(SgmYvP}&oFGUI?0a?q|=7k`#=ASWqO+GG#@9IT?$DCJMdX7|EH z6!suVDQe`xwh<+kH8t&y*yiVZ_#J*t)8lz(p5m~F&tdBKzJ1@n^Sn+({;8P&XMgnd zpZ00O8VukWKHw)xc!weMq7}{~bwGl>7=;8VBagNi0quAUF)Db8AzVZr_fdiv-?6ok zfDXKes2@0v#c-I1qgVxp47T8TRqUa90^0ErqHbdWoN*q4FEuXNK9o$v_A~(r9zoOq zTn)F(jH@AsA_S9I9vZL*qV6K8CqQk&Gz3pV0-EsFoZ9(t^#-U*W^Uu(0ydc8V{j1y z7NKnJC2zn52&T~%BR~y9P(-sY;3)(z;35VbFtaOs0iPkbkuu<+dVpbd(9Etivt7P` zA_Vz>fa?&C3g+r;Cq(V`1&l**B_LoO#xPOCH{3L{S%~WK1-yb_1TLao5S8-<Tr+R3 zOvHf85KLjVFJK2m?SzXUgRc<Wf%65lU;=^ynj-`phN#|<|ALbcbpoydOU;uthFKv2 zEf_VA(l)p{w4z}4)178Lki#SdzsyS|R0m!|)R}r#MBSKzs1alXj{0oXc7sS#2dFGQ zL5w#zhyCb6502m-%4V*Dek6^qiWlN4enSEkus+7B*jk2DD4+tVGLAuPMgkW*z?y?j ltj0<#feSSAZTNo$`~kDX+m3KO65;>=002ovPDHLkV1g{l0;m80
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e7ef4b91e47297b480e19af72cca34b225048f63 GIT binary patch literal 312 zc$@(^0muG{P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800030Nkl<Zc-rmP zu}Z^07{KvNLO>Am08SlUGTA}N<WPzr1=m2JP-jOeWNF_((xKEz+~Nz=O+<VFhb|oo zU0fXOP=|c}hfEm?`EtQPZ}`pk=f1mxb427{*??vT+{L3a^l^<4R|wF;0UU)=0lyF| zAO#s#ctL{GIszm&!5Xr|Tb%(3QpgS&hPZ%NM?efIVTm~&aG!fZqzwom6@9|h26Q16 zeB-3b2+ko&TU=H>0|7)~gN}(q*i+8jH+2hcODz0@F<g_^@UgJ1DQ@7y!wk<D;K=kl zFvS<%5#bPyf;!*>ZOvjPN8s218(;%$z+MIn@QP!D0rqRwtbjikg@vT?+QB;j0000< KMNUMnLSTZXqkZlG
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..86ba13a5f6fde5cf08b16ebf6fd0ad12f8243204 GIT binary patch literal 93 zc%17D@N?(olHy`uVBq!ia0vp^Y(Ol;0U|59*B=E^DxNNmAr-fh6B-)+XGk!W$=Lmt qmprWMu6jXLps|hN%CrMgfeejaJ56tem3slzGkCiCxvX<aXaWEO#2M=V
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c102e8c9e17e8ee045cc8cf1753b9d19f670dc27 GIT binary patch literal 597 zc%17D@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV3P54aSW-r_4bynM`)tV@sGh# z0Rq#Uon0hernoqoEQw%gRQtjdyJFiksjQ5B&QAK#e1{whGd-8z>Ji(nV7_qr*+u0| zD_T~Z*iiFJ@8Dbc=N0pw+dSC$McVFl|Np;5)1Ma!KfhD&%P8W21^o+?-}UXd-W(U* z!<;2bCpSvE2cF(2uWKotU05))SNTQ@%Tnew$3<coy(NxnsT^a~5xG;@lIzivw?|{g zN7k(pj6oLu;%6W3jreq@BEjt1gPG5d@s~{FHINrbI3_dy5bKMK8!tHTteDRGfN75j zqZ)I0m6RD9v-zc|93QlT8t!p0x`{%ZvcRQ*)xy8uw_$bxW0_fw4Bwp{ab^c%E&R=W z8jKb1D}7eWIQ+a}?!HZoWe;>?95-heGe#90PkyY;r)cPxd@(tlB`~g8x{xzj;{1e1 zGS?Ivw@Mv1X!<BKeWR>rTV70TTC&97jd9Js-i#s&aSe=jj#r;auV}BnF}d(W*quYK z=k)f^IQmnI)#BaH<YVS<%-pv;=AF~Na1~1h)AN_xEEmab_$VvAO5lO`oaL6qM_6JS z_8Kyoe2s<$<1B*%mpvH2g(@D9nX_E8_{h|TUe_(*iU%Ss`0Wc1$ZTYtZ&Q9r%eKw$ zVP)fDd9#{|)!dg^>n{Fmu!>S<y&$iGHEu*6$nR%t_A~gbH)q8{U~*ybboFyt=akR{ E0JW&<oB#j-
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7cd12a9abeabbc1ba0f3f791c87cad80266d249e GIT binary patch literal 1128 zc$@)f1eg1XP)<h;3K|Lk000e1NJLTq002M$002M;1^@s6s%dfF000CpNkl<Zc-rmT zO>7ip7{Kv&*Ot~o0tj6~u%^-?25r>Duh6Q&8g=F1#d6RPwN(;hgF%fXMq4ySjRzY< z6ZK*wsThc&6c1`hN{EOW5osU<jHalEf`~|Kh1PxjA3Wjn?5s2I%)E_r_}zA%o&NWu z^YN~+*8Z<$0kQyDfGmLM$=>JUHX99S#B5Z-#3a=K)o4Wz25=Y?u;(aY7@y!J+>Yr} zIl%RJ9VcKz8pmebf&5enP{b}+#}46MRQVd986U&O>|3<@7N8sBA^w<2oC&dA39q0g z?Eo{dwZcDi5WOg(3AN{ZQ8u6*k6{2~umQe8Ls|jmU=M5=Kj2Xmlo|DyUncH-_!_p1 zqgax3fO;H&Rg9nu)i8n_UPTEO@1YJxu^fkB6(`V=RDimGSAHXA1qAF6wtFIAn`u~w zNm#*;xG;$T@4yPqpcAG7&kNi4!&G1yj>8J}q9)D&t6&9VxD}>CFN6*NT!N#pg4f~- zun?olD}M`2VgZ0=98)6P7Ds?>u!2sQ!~+0JmE(xRsBsyf6;|*zOlkpu$6*BzxeV}; z@C3&&%Yy)Ue5o9RRJjPyf|BqAT`;K!0IpT`@opCZ`n0;<1km55JE8{2;U{768W_(4 zv<ox;LLo|kD}|vGD0mnkk74O!5GBAP!oWco?*ahpg}HA=39wNZ*yC}4JB7LXq6GL{ z7+CZ;zyjqkJr^o~a?){eOaTtyMa8pN`;Rqff>E3jX3q~Bpd<{N<|;r0f0Vf{cu;tJ zOPB!Dg+YJ9q#gj+D$Q1o3YUfnFjE+G+EIX~9R%2^%-$_Lwk_;OzzXsX0xZT@!~hQ} zv-b;+y&`OY-=!}U7zeJ#CVcuI4PYgVVno>Ig<%5>3BzuH@zhM^$hA6bfGxtnZjS@p zq+A>^VFUCE1K;;JK##D$Tfzm<&#-<&t)~IL5cc=sC;@74S{S+l#xs|~3YLTq0Bq9! z2YW-maC6Yb6``V1whhJ;^OQ^WYh47$<A`!+Ht$J*x0LgRxzPgvov?z{FezK6oV2ZX zd0D&)L(0j~RWK<j;AdgKPNLv00B|Ep0e5ASREOQLg6_C(j=lja7{WZ5gw$d?tl%@8 z7gvDuu^(1&1WgGoupBJ2P~svNcZb8?l|6~OU}AC&zAv*r;pU{4$Xpk2KED|YU>uo& zK1{$0O1LNKMN)0}HQ>74hKLtYFThjy1y*quE7MvgcR7YDSkt!?t8p1}0W%wMKR&?O zfZ3<8Jne;&bHs0C-6-~AJKjY<KExjJ9i{sQi+ourn!^J)4jZ#^tV6Aji>2qH52LV- zO`;#oQ(?J$J$mpRY(yj2fJIaB2NOB8;u-9!a6$D1_Tgm|rPZeX2hiowh<0?K3#-t9 uA{L_>#<A>2Q(1s4Ko%eikOjyB{M+9KAZZY|I3of80000<MNUMnLSTZb67)0x
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ccdb7fca6217e585540ddf8f2039d89d9a50ad77 GIT binary patch literal 555 zc%17D@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEVEp9i;uunK>+NlOjg~^0;~(#L zuH#7Ez3Idv4WY;-5>wVmY|!XBG*N>sHNo(dm#0^vfO2z+fLXWWCE4y5ZQeiY+vk5z z*zxc};rBoDj(?VoJDofK`{yq<f9F{(-CAbKslcexz%qeB$breDVTrGgZ+e1Y;0yoq ziiTs_N*s>_X3sdv5f#v9qrtsI)j`$d(a{3Vxh>gm66F?WI5i40T~U)L?oNDRA5~n` z@JNKEW8sCBj3RnL0*Pl%GF}T7cpxGA!OHM}MM;;<V+P|F4w6Qbc^+)EYLK_;jVox& zJ(DQ3_=U5zm0?R}PQt-g3`;MVeQZ%$&HUts#(^1M&oe0S<lf-3S;jO+O0J$&e#%OQ zcDCd83)oJjG}Jmjj=#v0YIR^;<Hz?L4vg=1G2b&_NS)4bTx|dA=!I`Y6f!RU5Lor5 zOzgvhqfH;RH8wm>JTd**!}Jfgf12F*a9X`WLh;BxNjZmS^%i{Y8@lACD8KGD_mJ?; zXgRKVpLyE?VU8rWul6xV>q-_fN&5X(nAH7z$9=htJ-hD5IWA{?(RR#|ZDM}HhK&sQ z7EaNB*1lfG@co07T=qXj4Mcb{AO|j(bKpNuz+8m`y|bA#z9@0^3QyUg%@ELEnc{qN h%AaHxs3Hd@d9U^`3;)+&j{_3{gQu&X%Q~loCIHl4<O=`*
new file mode 100644 --- /dev/null +++ b/mobile/android/base/resources/drawable/home_history_tabs_indicator.xml @@ -0,0 +1,48 @@ +<?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/. --> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + + <item android:state_focused="false" + android:state_selected="false" + android:state_pressed="false" + android:drawable="@android:color/transparent"/> + + <item android:state_focused="false" + android:state_selected="true" + android:state_pressed="false" + android:drawable="@drawable/history_tabs_indicator_selected"/> + + <item android:state_focused="true" + android:state_selected="false" + android:state_pressed="false" + android:drawable="@color/highlight_dark_focused"/> + + <item android:state_focused="true" + android:state_selected="true" + android:state_pressed="false" + android:drawable="@drawable/history_tabs_indicator_selected"/> + + <item android:state_focused="false" + android:state_selected="false" + android:state_pressed="true" + android:drawable="@color/highlight_dark"/> + + <item android:state_focused="false" + android:state_selected="true" + android:state_pressed="true" + android:drawable="@color/highlight_dark"/> + + <item android:state_focused="true" + android:state_selected="false" + android:state_pressed="true" + android:drawable="@color/highlight_dark"/> + + <item android:state_focused="true" + android:state_selected="true" + android:state_pressed="true" + android:drawable="@color/highlight_dark"/> + +</selector>
new file mode 100644 --- /dev/null +++ b/mobile/android/base/resources/drawable/home_page_title_background.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > + <item android:left="-1dp" + android:right="-1dp" + android:top="-1dp"> + + <shape android:shape="rectangle" > + <stroke android:width="1px" + android:color="@color/doorhanger_divider_dark" /> + + <solid android:color="#00000000" /> + </shape> + </item> + +</layer-list>
--- a/mobile/android/base/resources/layout/home_history_page.xml +++ b/mobile/android/base/resources/layout/home_history_page.xml @@ -1,14 +1,24 @@ <?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/. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" - android:orientation="vertical" - android:background="@android:color/white"> + android:orientation="vertical"> + + <FrameLayout android:id="@+id/visited_page_container" + android:layout_width="fill_parent" + android:layout_height="0dp" + android:layout_weight="1" /> - <include layout="@layout/home_list_with_title"/> + <org.mozilla.gecko.widget.IconTabWidget android:id="@+id/tab_icon_widget" + android:layout_width="fill_parent" + android:layout_height="@dimen/browser_toolbar_height" + android:tabStripEnabled="false" + android:showDividers="none" + android:background="@color/background_light" + android:layout="@layout/home_history_tabs_indicator"/> -</LinearLayout> \ No newline at end of file +</LinearLayout>
new file mode 100644 --- /dev/null +++ b/mobile/android/base/resources/layout/home_history_tabs_indicator.xml @@ -0,0 +1,9 @@ +<?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/. --> + +<ImageButton xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:background="@drawable/home_history_tabs_indicator"/>
--- a/mobile/android/base/resources/layout/home_last_tabs_page.xml +++ b/mobile/android/base/resources/layout/home_last_tabs_page.xml @@ -8,17 +8,17 @@ android:layout_height="fill_parent" android:orientation="vertical" android:background="@android:color/white"> <include layout="@layout/home_list_with_title"/> <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" - android:background="@color/background_light"> + android:background="@color/home_last_tab_bar_bg"> <Button android:id="@+id/open_all_tabs_button" style="@style/Widget.Home.ActionButton" android:text="@string/home_last_tabs_open" android:gravity="center"/> </LinearLayout>
--- a/mobile/android/base/resources/layout/home_list_with_title.xml +++ b/mobile/android/base/resources/layout/home_list_with_title.xml @@ -1,15 +1,22 @@ <?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/. --> <merge xmlns:android="http://schemas.android.com/apk/res/android"> + <TextView android:id="@+id/empty_message" + style="@style/Widget.Home.EmptyMessage" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:text="@string/home_visited_empty" + android:visibility="gone"/> + <TextView android:id="@+id/title" style="@style/Widget.Home.PageTitle"/> <org.mozilla.gecko.home.HomeListView android:id="@+id/list" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1"/>
new file mode 100644 --- /dev/null +++ b/mobile/android/base/resources/layout/home_most_recent_page.xml @@ -0,0 +1,14 @@ +<?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/. --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical" + android:background="@android:color/white"> + + <include layout="@layout/home_list_with_title"/> + +</LinearLayout> \ No newline at end of file
new file mode 100644 --- /dev/null +++ b/mobile/android/base/resources/layout/home_most_visited_page.xml @@ -0,0 +1,14 @@ +<?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/. --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical" + android:background="@android:color/white"> + + <include layout="@layout/home_list_with_title"/> + +</LinearLayout>
deleted file mode 100644 --- a/mobile/android/base/resources/layout/home_visited_page.xml +++ /dev/null @@ -1,45 +0,0 @@ -<?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/. --> - -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:orientation="vertical"> - - <TextView android:id="@+id/empty_message" - style="@style/Widget.Home.EmptyMessage" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:text="@string/home_visited_empty" - android:visibility="gone"/> - - <org.mozilla.gecko.home.HomeListView - android:id="@+id/visited_list" - android:layout_width="fill_parent" - android:layout_height="fill_parent" - android:layout_weight="1"/> - - <LinearLayout android:id="@+id/buttons_container" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:orientation="vertical" - android:background="@color/background_light" - android:visibility="gone"> - - <Button android:id="@+id/history_button" - style="@style/Widget.Home.PageButton" - android:text="@string/history_title"/> - - <View android:layout_width="fill_parent" - android:layout_height="1dip" - android:background="#FFD1D5DA"/> - - <Button android:id="@+id/tabs_button" - style="@style/Widget.Home.PageButton" - android:text="@string/home_last_tabs_title"/> - - </LinearLayout> - -</LinearLayout>
--- a/mobile/android/base/resources/layout/tabs_panel_header.xml +++ b/mobile/android/base/resources/layout/tabs_panel_header.xml @@ -4,17 +4,18 @@ - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> <merge xmlns:android="http://schemas.android.com/apk/res/android"> <org.mozilla.gecko.widget.IconTabWidget android:id="@+id/tab_widget" android:layout_width="wrap_content" android:layout_height="fill_parent" android:tabStripEnabled="false" - android:divider="@drawable/tab_indicator_divider"/> + android:divider="@drawable/tab_indicator_divider" + android:layout="@layout/tabs_panel_indicator"/> <View android:layout_width="0dip" android:layout_height="fill_parent" android:layout_weight="1.0"/> <ImageButton android:id="@+id/add_tab" style="@style/UrlBar.ImageButton" android:layout_width="@dimen/browser_toolbar_height"
--- a/mobile/android/base/resources/values/arrays.xml +++ b/mobile/android/base/resources/values/arrays.xml @@ -54,17 +54,17 @@ </string-array> <string-array name="pref_donottrack_values"> <item>1</item> <item>2</item> <item>0</item> </string-array> <string-array name="pref_import_android_entries"> <item>@string/bookmarks_title</item> - <item>@string/history_title</item> + <item>@string/home_most_recent_title</item> </string-array> <string-array name="pref_import_android_values"> <item>true</item> <item>true</item> </string-array> <string-array name="pref_import_android_keys"> <item>android_import.data.bookmarks</item> <item>android_import.data.history</item>
--- a/mobile/android/base/resources/values/attrs.xml +++ b/mobile/android/base/resources/values/attrs.xml @@ -188,10 +188,14 @@ <declare-styleable name="BookmarkFolderView"> <attr name="state_open" format="boolean"/> </declare-styleable> <declare-styleable name="GeckoView"> <attr name="url" format="string"/> </declare-styleable> + <declare-styleable name="IconTabWidget"> + <attr name="android:layout"/> + </declare-styleable> + </resources>
--- a/mobile/android/base/resources/values/colors.xml +++ b/mobile/android/base/resources/values/colors.xml @@ -82,10 +82,12 @@ <color name="textbox_background_disabled">#DDD</color> <color name="textbox_stroke">#000</color> <color name="textbox_stroke_disabled">#666</color> <color name="url_bar_urltext">#A6A6A6</color> <color name="url_bar_domaintext">#000</color> <color name="url_bar_domaintext_private">#FFF</color> + <color name="home_last_tab_bar_bg">#FFF5F7F9</color> + </resources>
--- a/mobile/android/base/resources/values/styles.xml +++ b/mobile/android/base/resources/values/styles.xml @@ -187,17 +187,17 @@ <style name="Widget.Home.ActionButton" parent="Widget.Home.PageButton"> <item name="android:textAppearance">@style/TextAppearance.Widget.Home.PageAction</item> </style> <style name="Widget.Home.PageTitle"> <item name="android:layout_width">fill_parent</item> <item name="android:layout_height">32dp</item> <item name="android:textAppearance">@style/TextAppearance.Widget.Home.PageTitle</item> - <item name="android:background">@color/background_light</item> + <item name="android:background">@drawable/home_page_title_background</item> <item name="android:focusable">false</item> <item name="android:gravity">center|left</item> <item name="android:paddingLeft">10dip</item> <item name="android:paddingRight">10dip</item> </style> <!-- TextAppearance
--- a/mobile/android/base/strings.xml.in +++ b/mobile/android/base/strings.xml.in @@ -18,19 +18,17 @@ <resources> <string name="moz_app_displayname">@MOZ_APP_DISPLAYNAME@</string> #include ../services/strings.xml.in <string name="no_space_to_start_error">&no_space_to_start_error;</string> <string name="error_loading_file">&error_loading_file;</string> <string name="all_pages_title">&all_pages_title;</string> <string name="bookmarks_title">&bookmarks_title;</string> - <string name="history_title">&history_title;</string> <string name="switch_to_tab">&switch_to_tab;</string> - <string name="visited_title">&visited_title;</string> <string name="crash_reporter_title">&crash_reporter_title;</string> <string name="crash_message2">&crash_message2;</string> <string name="crash_send_report_message3">&crash_send_report_message3;</string> <string name="crash_include_url2">&crash_include_url2;</string> <string name="crash_sorry">&crash_sorry;</string> <string name="crash_comment">&crash_comment;</string> <string name="crash_allow_contact2">&crash_allow_contact2;</string> @@ -232,18 +230,21 @@ <string name="button_ok">&button_ok;</string> <string name="button_cancel">&button_cancel;</string> <string name="button_clear_data">&button_clear_data;</string> <string name="button_set">&button_set;</string> <string name="button_clear">&button_clear;</string> <string name="button_yes">&button_yes;</string> <string name="button_no">&button_no;</string> + <string name="home_history_title">&home_history_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_most_recent_title">&home_most_recent_title;</string> + <string name="home_most_visited_title">&home_most_visited_title;</string> <string name="home_visited_empty">&home_visited_empty;</string> <string name="pin_bookmark_dialog_hint">&pin_bookmark_dialog_hint;</string> <string name="filepicker_title">&filepicker_title;</string> <string name="filepicker_audio_title">&filepicker_audio_title;</string> <string name="filepicker_image_title">&filepicker_image_title;</string> <string name="filepicker_video_title">&filepicker_video_title;</string>
--- a/mobile/android/base/widget/IconTabWidget.java +++ b/mobile/android/base/widget/IconTabWidget.java @@ -2,35 +2,45 @@ * 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.widget; import org.mozilla.gecko.R; import android.content.Context; +import android.content.res.TypedArray; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageButton; import android.widget.TabWidget; public class IconTabWidget extends TabWidget { private OnTabChangedListener mListener; + private final int mButtonLayoutId; public static interface OnTabChangedListener { public void onTabChanged(int tabIndex); } public IconTabWidget(Context context, AttributeSet attrs) { super(context, attrs); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.IconTabWidget); + mButtonLayoutId = a.getResourceId(R.styleable.IconTabWidget_android_layout, 0); + a.recycle(); + + if (mButtonLayoutId == 0) { + throw new RuntimeException("You must supply layout attribute"); + } } public ImageButton addTab(int resId) { - ImageButton button = (ImageButton) LayoutInflater.from(getContext()).inflate(R.layout.tabs_panel_indicator, null); + ImageButton button = (ImageButton) LayoutInflater.from(getContext()).inflate(mButtonLayoutId, null); button.setImageResource(resId); addView(button); button.setOnClickListener(new TabClickListener(getTabCount() - 1)); button.setOnFocusChangeListener(this); return button; }