Bug 936756 - Part 3: rebuild menus and action items on locale change. r=sriram

This commit is contained in:
Richard Newman 2013-12-01 21:53:17 -08:00
parent 9a54791062
commit 952a8e00d0
3 changed files with 84 additions and 38 deletions

View File

@ -124,7 +124,7 @@ abstract public class BrowserApp extends GeckoApp
private static final int GECKO_TOOLS_MENU = -1;
private static final int ADDON_MENU_OFFSET = 1000;
private class MenuItemInfo {
private static class MenuItemInfo {
public int id;
public String label;
public String icon;
@ -133,6 +133,7 @@ abstract public class BrowserApp extends GeckoApp
public boolean enabled = true;
public boolean visible = true;
public int parent;
public boolean added = false; // So we can re-add after a locale change.
}
// The types of guest mdoe dialogs we show
@ -1646,6 +1647,11 @@ abstract public class BrowserApp extends GeckoApp
// Blow it away and rebuild it with the right strings.
mHomePager.redisplay(getSupportFragmentManager());
}
if (mMenu != null) {
mMenu.clear();
onCreateOptionsMenu(mMenu);
}
}
private void showHomePagerWithAnimator(HomePager.Page page, PropertyAnimator animator) {
@ -1820,7 +1826,7 @@ abstract public class BrowserApp extends GeckoApp
}
}
private Menu findParentMenu(Menu menu, MenuItem item) {
private static Menu findParentMenu(Menu menu, MenuItem item) {
final int itemId = item.getItemId();
final int count = (menu != null) ? menu.size() : 0;
@ -1840,54 +1846,58 @@ abstract public class BrowserApp extends GeckoApp
return null;
}
private void addAddonMenuItem(final MenuItemInfo info) {
if (mMenu == null) {
if (mAddonMenuItemsCache == null)
mAddonMenuItemsCache = new Vector<MenuItemInfo>();
mAddonMenuItemsCache.add(info);
return;
}
Menu menu;
/**
* Add the provided item to the provided menu, which should be
* the root (mMenu).
*/
private void addAddonMenuItemToMenu(final Menu menu, final MenuItemInfo info) {
info.added = true;
final Menu destination;
if (info.parent == 0) {
menu = mMenu;
destination = menu;
} else if (info.parent == GECKO_TOOLS_MENU) {
MenuItem tools = mMenu.findItem(R.id.tools);
menu = tools != null ? tools.getSubMenu() : mMenu;
MenuItem tools = menu.findItem(R.id.tools);
destination = tools != null ? tools.getSubMenu() : menu;
} else {
MenuItem parent = mMenu.findItem(info.parent);
if (parent == null)
MenuItem parent = menu.findItem(info.parent);
if (parent == null) {
return;
}
Menu parentMenu = findParentMenu(mMenu, parent);
Menu parentMenu = findParentMenu(menu, parent);
if (!parent.hasSubMenu()) {
parentMenu.removeItem(parent.getItemId());
menu = parentMenu.addSubMenu(Menu.NONE, parent.getItemId(), Menu.NONE, parent.getTitle());
if (parent.getIcon() != null)
((SubMenu) menu).getItem().setIcon(parent.getIcon());
destination = parentMenu.addSubMenu(Menu.NONE, parent.getItemId(), Menu.NONE, parent.getTitle());
if (parent.getIcon() != null) {
((SubMenu) destination).getItem().setIcon(parent.getIcon());
}
} else {
menu = parent.getSubMenu();
destination = parent.getSubMenu();
}
}
MenuItem item = menu.add(Menu.NONE, info.id, Menu.NONE, info.label);
MenuItem item = destination.add(Menu.NONE, info.id, Menu.NONE, info.label);
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
Log.i(LOGTAG, "menu item clicked");
Log.i(LOGTAG, "Menu item clicked");
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Menu:Clicked", Integer.toString(info.id - ADDON_MENU_OFFSET)));
return true;
}
});
if (info.icon != null) {
if (info.icon == null) {
item.setIcon(R.drawable.ic_menu_addons_filler);
} else {
final int id = info.id;
BitmapUtils.getDrawable(this, info.icon, new BitmapUtils.BitmapLoader() {
@Override
public void onBitmapFound(Drawable d) {
MenuItem item = mMenu.findItem(id);
// TODO: why do we re-find the item?
MenuItem item = destination.findItem(id);
if (item == null) {
return;
}
@ -1898,8 +1908,6 @@ abstract public class BrowserApp extends GeckoApp
item.setIcon(d);
}
});
} else {
item.setIcon(R.drawable.ic_menu_addons_filler);
}
item.setCheckable(info.checkable);
@ -1908,6 +1916,24 @@ abstract public class BrowserApp extends GeckoApp
item.setVisible(info.visible);
}
private void addAddonMenuItem(final MenuItemInfo info) {
if (mAddonMenuItemsCache == null) {
mAddonMenuItemsCache = new Vector<MenuItemInfo>();
}
// Mark it as added if the menu was ready.
info.added = (mMenu != null);
// Always cache so we can rebuild after a locale switch.
mAddonMenuItemsCache.add(info);
if (mMenu == null) {
return;
}
addAddonMenuItemToMenu(mMenu, info);
}
private void removeAddonMenuItem(int id) {
// Remove add-on menu item from cache, if available.
if (mAddonMenuItemsCache != null && !mAddonMenuItemsCache.isEmpty()) {
@ -1937,13 +1963,15 @@ abstract public class BrowserApp extends GeckoApp
item.checked = options.optBoolean("checked", item.checked);
item.enabled = options.optBoolean("enabled", item.enabled);
item.visible = options.optBoolean("visible", item.visible);
item.added = (mMenu != null);
break;
}
}
}
if (mMenu == null)
if (mMenu == null) {
return;
}
MenuItem menuItem = mMenu.findItem(id);
if (menuItem != null) {
@ -1957,22 +1985,23 @@ abstract public class BrowserApp extends GeckoApp
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Sets mMenu = menu.
super.onCreateOptionsMenu(menu);
// Inform the menu about the action-items bar.
if (menu instanceof GeckoMenu && HardwareUtils.isTablet())
if (menu instanceof GeckoMenu &&
HardwareUtils.isTablet()) {
((GeckoMenu) menu).setActionItemBarPresenter(mBrowserToolbar);
}
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.browser_app_menu, mMenu);
// Add add-on menu items if any.
// Add add-on menu items, if any exist.
if (mAddonMenuItemsCache != null && !mAddonMenuItemsCache.isEmpty()) {
for (MenuItemInfo item : mAddonMenuItemsCache) {
addAddonMenuItem(item);
addAddonMenuItemToMenu(mMenu, item);
}
mAddonMenuItemsCache.clear();
}
// Action providers are available only ICS+.

View File

@ -10,6 +10,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ActionProvider;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@ -114,7 +115,7 @@ public class GeckoMenu extends ListView
mItems = new ArrayList<GeckoMenuItem>();
mActionItems = new HashMap<GeckoMenuItem, View>();
mActionItemBarPresenter = (DefaultActionItemBar) LayoutInflater.from(context).inflate(R.layout.menu_action_bar, null);
mActionItemBarPresenter = (DefaultActionItemBar) LayoutInflater.from(context).inflate(R.layout.menu_action_bar, null);
}
@Override
@ -219,14 +220,26 @@ public class GeckoMenu extends ListView
public void clear() {
for (GeckoMenuItem menuItem : mItems) {
if (menuItem.hasSubMenu()) {
menuItem.getSubMenu().clear();
SubMenu sub = menuItem.getSubMenu();
if (sub == null) {
continue;
}
try {
sub.clear();
} catch (Exception ex) {
Log.e(LOGTAG, "Couldn't clear submenu.", ex);
}
}
}
mAdapter.clear();
mItems.clear();
/*
* Reinflating the menu will re-add any action items to the toolbar, so
* remove the old ones. This also ensures that any text associated with
* these is switched to the correct locale.
*/
if (mActionItemBarPresenter != null) {
for (View item : mActionItems.values()) {
mActionItemBarPresenter.removeActionItem(item);

View File

@ -142,7 +142,11 @@ public class GeckoMenuItem implements MenuItem {
@Override
public SubMenu getSubMenu() {
return mSubMenu;
// For consistency with hasSubMenu.
if (mActionProvider == null) {
return mSubMenu;
}
return null;
}
@Override