author | Margaret Leibovic <margaret.leibovic@gmail.com> |
Mon, 29 Jul 2013 08:40:40 -0700 | |
changeset 143469 | c2b5919558d3f7b1b8f39eaada2ccb8aa164ad16 |
parent 143468 | 1ae4d0688fb1a6dfb501c333e7686f8e040d9e4c |
child 143470 | 73eef60094a0b688037a55b91f3b3ea48a08dac1 |
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) |
milestone | 25.0a1 |
backs out | 1491af6fc2aeb1e1cca33666cd1871ef38a24d9e |
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 @@ -1318,17 +1318,17 @@ abstract public class BrowserApp extends } } } final PropertyAnimator animator = new PropertyAnimator(300); animator.setUseHardwareLayer(false); mBrowserToolbar.startEditing(url, animator); - showHomePagerWithAnimator(HomePager.Page.HISTORY, animator); + showHomePagerWithAnimator(HomePager.Page.VISITED, animator); animator.start(); } void commitEditingMode() { if (!mBrowserToolbar.isEditing()) { return; } @@ -1397,16 +1397,24 @@ 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,29 +224,28 @@ 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 \ @@ -461,23 +460,21 @@ 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 \ @@ -630,19 +627,16 @@ 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 \ @@ -705,17 +699,16 @@ 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) @@ -746,19 +739,16 @@ 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 \ @@ -799,17 +789,16 @@ 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 \ @@ -838,19 +827,16 @@ 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 \ @@ -886,17 +872,16 @@ 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 \ @@ -1061,18 +1046,16 @@ 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,99 +1,365 @@ /* -*- 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.widget.IconTabWidget; -import android.support.v4.app.Fragment; +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 android.content.Context; import android.content.res.Resources; +import android.database.Cursor; import android.os.Bundle; -import android.view.LayoutInflater; +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.View; import android.view.ViewGroup; import android.view.LayoutInflater; - -import android.widget.ImageButton; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.TextView; -public class HistoryPage extends HomeFragment - implements IconTabWidget.OnTabChangedListener { +import java.util.Date; + +/** + * Fragment that displays recent history in a ListView. + */ +public class HistoryPage extends HomeFragment { // Logging tag name private static final String LOGTAG = "GeckoHistoryPage"; - private IconTabWidget mTabWidget; - private int mSelectedTab; + + // 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; + } @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) { - super.onViewCreated(view, savedInstanceState); + final TextView title = (TextView) view.findViewById(R.id.title); + title.setText(R.string.history_title); + + mList = (ListView) view.findViewById(R.id.list); - mTabWidget = (IconTabWidget) view.findViewById(R.id.tab_icon_widget); + mList.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView<?> parent, View view, int position, long id) { + position -= getHistorySectionsCountBefore(position); - ImageButton button; - final Resources resources = view.getContext().getResources(); + final Cursor c = mAdapter.getCursor(); + if (c == null || !c.moveToPosition(position)) { + return; + } - button = mTabWidget.addTab(R.drawable.icon_most_visited); - button.setContentDescription(resources.getString(R.string.home_most_visited_title)); + final String url = c.getString(c.getColumnIndexOrThrow(URLColumns.URL)); + mUrlOpenListener.onUrlOpen(url); + } + }); - button = mTabWidget.addTab(R.drawable.icon_most_recent); - button.setContentDescription(resources.getString(R.string.home_most_recent_title)); + registerForContextMenu(mList); + } - button = mTabWidget.addTab(R.drawable.icon_last_tabs); - button.setContentDescription(resources.getString(R.string.home_last_tabs_title)); + @Override + public void onDestroyView() { + super.onDestroyView(); + mList = null; + } - //Show most visited page as the initial page - showMostVisitedPage(); + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + // Initialize map of history sections + mHistorySections = new SparseArray<HistorySection>(); - mTabWidget.setTabSelectionListener(this); - mTabWidget.setCurrentTab(mSelectedTab); + // Intialize adapter + mAdapter = new HistoryAdapter(getActivity()); + mList.setAdapter(mAdapter); + + // Create callbacks before the initial loader is started + mCursorLoaderCallbacks = new CursorLoaderCallbacks(); + loadIfVisible(); } @Override - public void load() {} + 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; - @Override - public void onTabChanged(int index) { - if (index == mSelectedTab) { + 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()) { return; } - if (index == 0) { - showMostVisitedPage(); - } else if (index == 1) { - showMostRecentPage(); - } else if (index == 2) { - showLastTabsPage(); + // 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); } - mTabWidget.setCurrentTab(index); - mSelectedTab = index; + @Override + public Cursor loadCursor() { + final ContentResolver cr = getContext().getContentResolver(); + return BrowserDB.getRecentHistory(cr, HISTORY_LIMIT); + } } - private void showSubPage(Fragment subPage) { - getChildFragmentManager().beginTransaction() - .addToBackStack(null).replace(R.id.visited_page_container, subPage) - .commitAllowingStateLoss(); - } + 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; + } + + @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); + } - private void showMostVisitedPage() { - final MostVisitedPage mostVisitedPage = MostVisitedPage.newInstance(); - showSubPage(mostVisitedPage); + @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); + + 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 showMostRecentPage() { - final MostRecentPage mostRecentPage = MostRecentPage.newInstance(); - showSubPage(mostRecentPage); - } + private class CursorLoaderCallbacks implements LoaderCallbacks<Cursor> { + @Override + public Loader<Cursor> onCreateLoader(int id, Bundle args) { + return new HistoryCursorLoader(getActivity()); + } - private void showLastTabsPage() { - final LastTabsPage lastTabsPage = LastTabsPage.newInstance(); - showSubPage(lastTabsPage); + @Override + public void onLoadFinished(Loader<Cursor> loader, Cursor c) { + loadHistorySections(c); + mAdapter.swapCursor(c); + } + + @Override + public void onLoaderReset(Loader<Cursor> loader) { + mAdapter.swapCursor(null); + } } }
--- a/mobile/android/base/home/HomeFragment.java +++ b/mobile/android/base/home/HomeFragment.java @@ -41,16 +41,22 @@ 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 { - HISTORY, + VISITED, 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.HISTORY, HistoryPage.class, null, getContext().getString(R.string.home_history_title)); + adapter.addTab(Page.VISITED, VisitedPage.class, null, getContext().getString(R.string.visited_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);
deleted file mode 100644 --- a/mobile/android/base/home/MostRecentPage.java +++ /dev/null @@ -1,398 +0,0 @@ -/* -*- 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 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.View; -import android.view.ViewGroup; -import android.view.LayoutInflater; -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 MostRecentPage extends HomeFragment { - // Logging tag name - private static final String LOGTAG = "GeckoMostRecentPage"; - - // Cursor loader ID for history query - private static final int HISTORY_LOADER_ID = 0; - - // Cursor loader ID for favicons query - private static final int FAVICONS_LOADER_ID = 1; - - // 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 MostRecentSection { - TODAY, - YESTERDAY, - WEEK, - OLDER - }; - - // Maps headers in the list with their respective sections - private SparseArray<MostRecentSection> mMostRecentSections; - - // Adapter for the list of search results - 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 MostRecentPage newInstance() { - return new MostRecentPage(); - } - - public MostRecentPage() { - 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(); - - mMostRecentSections = null; - mInflater = null; - mUrlOpenListener = null; - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - 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.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 -= 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); - } - }); - - registerForContextMenu(mList); - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - mList = null; - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - // Initialize map of history sections - mMostRecentSections = new SparseArray<MostRecentSection>(); - - // Intialize adapter - 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 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 getMostRecentSectionsCountBefore(int position) { - // Account for the number headers before the given position - int sectionsBefore = 0; - - final int historySectionsCount = mMostRecentSections.size(); - for (int i = 0; i < historySectionsCount; i++) { - final int sectionPosition = mMostRecentSections.keyAt(i); - if (sectionPosition > position) { - break; - } - - sectionsBefore++; - } - - return sectionsBefore; - } - - private MostRecentSection getMostRecentSectionForTime(long from, long time) { - long delta = from - time; - - if (delta < 0) { - return MostRecentSection.TODAY; - } - - if (delta < MS_PER_DAY) { - return MostRecentSection.YESTERDAY; - } - - if (delta < MS_PER_WEEK) { - return MostRecentSection.WEEK; - } - - return MostRecentSection.OLDER; - } - - private void loadMostRecentSections(Cursor c) { - if (c == null || !c.moveToFirst()) { - return; - } - - // Clear any history sections that may have been loaded before. - mMostRecentSections.clear(); - - final Date now = new Date(); - now.setHours(0); - now.setMinutes(0); - now.setSeconds(0); - - final long today = now.getTime(); - MostRecentSection section = null; - - do { - final int position = c.getPosition(); - final long time = c.getLong(c.getColumnIndexOrThrow(URLColumns.DATE_LAST_VISITED)); - final MostRecentSection itemSection = getMostRecentSectionForTime(today, time); - - if (section != itemSection) { - section = itemSection; - mMostRecentSections.append(position + mMostRecentSections.size(), section); - } - - // Reached the last section, no need to continue - if (section == MostRecentSection.OLDER) { - break; - } - } while (c.moveToNext()); - } - - private static class MostRecentCursorLoader extends SimpleCursorLoader { - // Max number of history results - private static final int HISTORY_LIMIT = 100; - - public MostRecentCursorLoader(Context context) { - super(context); - } - - @Override - public Cursor loadCursor() { - final ContentResolver cr = getContext().getContentResolver(); - return BrowserDB.getRecentHistory(cr, HISTORY_LIMIT); - } - } - - 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 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 - getMostRecentSectionsCountBefore(position)); - } - - @Override - public int getItemViewType(int position) { - if (mMostRecentSections.get(position) != null) { - return ROW_HEADER; - } - - return ROW_STANDARD; - } - - @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() + 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 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 -= 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) { - switch(id) { - case HISTORY_LOADER_ID: - return new MostRecentCursorLoader(getActivity()); - - case FAVICONS_LOADER_ID: - return FaviconsLoader.createInstance(getActivity(), args); - } - - return null; - } - - @Override - public void onLoadFinished(Loader<Cursor> loader, Cursor c) { - final int loaderId = loader.getId(); - switch(loaderId) { - case HISTORY_LOADER_ID: - loadMostRecentSections(c); - 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 - // now in-memory favicons. - mAdapter.notifyDataSetChanged(); - break; - } - } - - @Override - public void onLoaderReset(Loader<Cursor> loader) { - final int loaderId = loader.getId(); - switch(loaderId) { - case HISTORY_LOADER_ID: - mAdapter.swapCursor(null); - break; - - case FAVICONS_LOADER_ID: - // Do nothing - break; - } - } - } -}
deleted file mode 100644 --- a/mobile/android/base/home/MostVisitedPage.java +++ /dev/null @@ -1,220 +0,0 @@ -/* -*- 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 android.app.Activity; -import android.content.ContentResolver; -import android.content.Context; -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.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 MostVisitedPage extends HomeFragment { - // Logging tag name - 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; - - // Callbacks used for the search and favicon cursor loaders - private CursorLoaderCallbacks mCursorLoaderCallbacks; - - // On URL open listener - private OnUrlOpenListener mUrlOpenListener; - - public static MostVisitedPage newInstance() { - return new MostVisitedPage(); - } - - public MostVisitedPage() { - 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"); - } - } - - @Override - public void onDetach() { - super.onDetach(); - - mUrlOpenListener = null; - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.home_most_visited_page, container, false); - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - final TextView title = (TextView) view.findViewById(R.id.title); - title.setText(R.string.home_most_visited_title); - - 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); - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - mList = null; - mEmptyMessage = null; - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - // Intialize the search adapter - mAdapter = new VisitedAdapter(getActivity(), null); - mList.setAdapter(mAdapter); - - // Create callbacks before the initial loader is started - mCursorLoaderCallbacks = new CursorLoaderCallbacks(); - loadIfVisible(); - } - - @Override - protected void load() { - getLoaderManager().initLoader(FRECENCY_LOADER_ID, null, mCursorLoaderCallbacks); - } - - private static class FrecencyCursorLoader extends SimpleCursorLoader { - // Max number of search results - private static final int SEARCH_LIMIT = 50; - - public FrecencyCursorLoader(Context context) { - super(context); - } - - @Override - public Cursor loadCursor() { - final ContentResolver cr = getContext().getContentResolver(); - return BrowserDB.filter(cr, "", SEARCH_LIMIT); - } - } - - private class VisitedAdapter extends CursorAdapter { - public VisitedAdapter(Context context, Cursor cursor) { - super(context, cursor); - } - - @Override - public void bindView(View view, Context context, Cursor cursor) { - final TwoLinePageRow row = (TwoLinePageRow) view; - row.updateFromCursor(cursor); - } - - @Override - public View newView(Context context, Cursor cursor, ViewGroup parent) { - return LayoutInflater.from(parent.getContext()).inflate(R.layout.home_item_row, parent, false); - } - } - - private class CursorLoaderCallbacks implements LoaderCallbacks<Cursor> { - @Override - public Loader<Cursor> onCreateLoader(int id, Bundle args) { - switch(id) { - case FRECENCY_LOADER_ID: - return new FrecencyCursorLoader(getActivity()); - - case FAVICONS_LOADER_ID: - return FaviconsLoader.createInstance(getActivity(), args); - } - - return null; - } - - @Override - 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); - - 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 - // now in-memory favicons. - mAdapter.notifyDataSetChanged(); - break; - } - } - - @Override - public void onLoaderReset(Loader<Cursor> loader) { - final int loaderId = loader.getId(); - switch(loaderId) { - case FRECENCY_LOADER_ID: - mAdapter.swapCursor(null); - break; - - case FAVICONS_LOADER_ID: - // Do nothing - break; - } - } - } -}
new file mode 100644 --- /dev/null +++ b/mobile/android/base/home/VisitedPage.java @@ -0,0 +1,249 @@ +/* -*- 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 android.app.Activity; +import android.content.ContentResolver; +import android.content.Context; +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.CursorAdapter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ListView; + +/** + * Fragment that displays frecency search results in a ListView. + */ +public class VisitedPage extends HomeFragment { + // Logging tag name + private static final String LOGTAG = "GeckoVisitedPage"; + + // 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() { + 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"); + } + } + + @Override + 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); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + mList = (HomeListView) view.findViewById(R.id.visited_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 + mAdapter = new VisitedAdapter(getActivity(), null); + mList.setAdapter(mAdapter); + + // Create callbacks before the initial loader is started + mCursorLoaderCallbacks = new CursorLoaderCallbacks(); + 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); + } + + @Override + public Cursor loadCursor() { + final ContentResolver cr = getContext().getContentResolver(); + return BrowserDB.filter(cr, "", SEARCH_LIMIT); + } + } + + private class VisitedAdapter extends CursorAdapter { + public VisitedAdapter(Context context, Cursor cursor) { + super(context, cursor); + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + final TwoLinePageRow row = (TwoLinePageRow) view; + row.updateFromCursor(cursor); + } + + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + return LayoutInflater.from(parent.getContext()).inflate(R.layout.home_item_row, parent, false); + } + } + + private class CursorLoaderCallbacks implements LoaderCallbacks<Cursor> { + @Override + public Loader<Cursor> onCreateLoader(int id, Bundle args) { + switch(id) { + case FRECENCY_LOADER_ID: + return new FrecencyCursorLoader(getActivity()); + + case FAVICONS_LOADER_ID: + return FaviconsLoader.createInstance(getActivity(), args); + } + + return null; + } + + @Override + 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 + // now in-memory favicons. + mAdapter.notifyDataSetChanged(); + break; + } + } + + @Override + public void onLoaderReset(Loader<Cursor> loader) { + final int loaderId = loader.getId(); + switch(loaderId) { + case FRECENCY_LOADER_ID: + mAdapter.swapCursor(null); + 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,17 +3,19 @@ - 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"> @@ -262,21 +264,18 @@ 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_history_title "History"> -<!ENTITY home_last_tabs_title "Tabs from last time"> +<!ENTITY home_last_tabs_title "Your 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">
deleted file mode 100644 index 03ead6aa8b1c72bd1af9d5a4b1280d2de42254ac..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 index 8c2b41f9d2f41d13560da67710f17387c27873c9..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 index 1924bc4a044517474aeeceb03936a4ebb996942e..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 index e7cf2b3b9ce181aaf6efa8a5ff0d54f9d71da054..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 index 5def384c1389a80ac0894db64cd8938005afe8e1..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 index f577fd4c46c1382faccd4bab095a29c9c2cdddfc..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 index e0cfd2ddb781d3c78ac3a449e315b49c9db74034..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 index e7ef4b91e47297b480e19af72cca34b225048f63..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 index 86ba13a5f6fde5cf08b16ebf6fd0ad12f8243204..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 index c102e8c9e17e8ee045cc8cf1753b9d19f670dc27..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 index 7cd12a9abeabbc1ba0f3f791c87cad80266d249e..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 index ccdb7fca6217e585540ddf8f2039d89d9a50ad77..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 --- a/mobile/android/base/resources/drawable/home_history_tabs_indicator.xml +++ /dev/null @@ -1,48 +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/. --> - -<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>
deleted file mode 100644 --- a/mobile/android/base/resources/drawable/home_page_title_background.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?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,24 +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"> - - <FrameLayout android:id="@+id/visited_page_container" - android:layout_width="fill_parent" - android:layout_height="0dp" - android:layout_weight="1" /> + android:orientation="vertical" + android:background="@android:color/white"> - <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"/> + <include layout="@layout/home_list_with_title"/> -</LinearLayout> +</LinearLayout> \ No newline at end of file
deleted file mode 100644 --- a/mobile/android/base/resources/layout/home_history_tabs_indicator.xml +++ /dev/null @@ -1,9 +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/. --> - -<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/home_last_tab_bar_bg"> + android:background="@color/background_light"> <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,22 +1,15 @@ <?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"/>
deleted file mode 100644 --- a/mobile/android/base/resources/layout/home_most_recent_page.xml +++ /dev/null @@ -1,14 +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" - android:background="@android:color/white"> - - <include layout="@layout/home_list_with_title"/> - -</LinearLayout> \ No newline at end of file
deleted file mode 100644 --- a/mobile/android/base/resources/layout/home_most_visited_page.xml +++ /dev/null @@ -1,14 +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" - android:background="@android:color/white"> - - <include layout="@layout/home_list_with_title"/> - -</LinearLayout>
new file mode 100644 --- /dev/null +++ b/mobile/android/base/resources/layout/home_visited_page.xml @@ -0,0 +1,45 @@ +<?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,18 +4,17 @@ - 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:layout="@layout/tabs_panel_indicator"/> + android:divider="@drawable/tab_indicator_divider"/> <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/home_most_recent_title</item> + <item>@string/history_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,14 +188,10 @@ <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,12 +82,10 @@ <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">@drawable/home_page_title_background</item> + <item name="android:background">@color/background_light</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,17 +18,19 @@ <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> @@ -230,21 +232,18 @@ <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,45 +2,35 @@ * 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(mButtonLayoutId, null); + ImageButton button = (ImageButton) LayoutInflater.from(getContext()).inflate(R.layout.tabs_panel_indicator, null); button.setImageResource(resId); addView(button); button.setOnClickListener(new TabClickListener(getTabCount() - 1)); button.setOnFocusChangeListener(this); return button; }