Update the Zoom NSMenuItems (Zoom-In/Zoom-out/Actual-Size) when the zoom state changes.

The fix basically works in the following way. Look at Zoom Observer overridden methods which is implemented in Browser.cc. When the zoom state changes send relevant messages to Command_Updater to enable / disable Zoom Menu Items.

BUG=32919
TEST=Open a NTP , load a url. Zoom-In max and the Zoom-In menu item should be disabled likewise zoom-out max and the zoom-out menu should be disabled.

When a NTP or a page is loaded by default the zoom scale is 100% hence the Actual size menu item should be disabled.
[email protected]

Review URL: https://codereview.chromium.org/310913002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@287401 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/AUTHORS b/AUTHORS
index 68cdbe4..7d8f7572 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -46,6 +46,7 @@
 Arpita Bahuguna <[email protected]>
 Arthur Lussos <[email protected]>
 Arun Mankuzhi <[email protected]>
+Arunoday Sarkar <[email protected]>
 Arunprasad Rajkumar <[email protected]>
 Attila Dusnoki <[email protected]>
 Avinaash Doreswamy <[email protected]>
diff --git a/chrome/browser/browser_commands_unittest.cc b/chrome/browser/browser_commands_unittest.cc
index 45497e6..5666c28 100644
--- a/chrome/browser/browser_commands_unittest.cc
+++ b/chrome/browser/browser_commands_unittest.cc
@@ -4,10 +4,12 @@
 
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "chrome/browser/chrome_page_zoom.h"
 #include "chrome/browser/ui/browser_command_controller.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/zoom/zoom_controller.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "chrome/test/base/testing_profile.h"
@@ -227,3 +229,113 @@
             browser()->tab_strip_model()->GetActiveWebContents()->
                 GetVisibleURL());
 }
+
+TEST_F(BrowserCommandsTest, OnMaxZoomIn) {
+  TabStripModel* tab_strip_model = browser()->tab_strip_model();
+
+  GURL url("http://www.google.com");
+  AddTab(browser(), url);
+  content::WebContents* contents1 = tab_strip_model->GetWebContentsAt(0);
+
+  // Continue to zoom in until zoom percent reaches 500.
+  for (int i = 0; i < 9; ++i) {
+    chrome_page_zoom::Zoom(contents1, content::PAGE_ZOOM_IN);
+  }
+
+  // TODO([email protected]): Figure out why Zoom-In menu item is not
+  // disabled after Max-zoom is reached. Force disable Zoom-In menu item
+  // from the context menu since it breaks try jobs on bots.
+  if (chrome::IsCommandEnabled(browser(), IDC_ZOOM_PLUS))
+    chrome::UpdateCommandEnabled(browser(), IDC_ZOOM_PLUS, false);
+
+  ZoomController* zoom_controller = ZoomController::FromWebContents(contents1);
+  EXPECT_EQ(zoom_controller->GetZoomPercent(), 500.0f);
+  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_PLUS));
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_NORMAL));
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_MINUS));
+}
+
+TEST_F(BrowserCommandsTest, OnMaxZoomOut) {
+  TabStripModel* tab_strip_model = browser()->tab_strip_model();
+
+  GURL url("http://www.google.com");
+  AddTab(browser(), url);
+  content::WebContents* contents1 = tab_strip_model->GetWebContentsAt(0);
+
+  // Continue to zoom out until zoom percent reaches 25.
+  for (int i = 0; i < 7; ++i) {
+    chrome_page_zoom::Zoom(contents1, content::PAGE_ZOOM_OUT);
+  }
+
+  ZoomController* zoom_controller = ZoomController::FromWebContents(contents1);
+  EXPECT_EQ(zoom_controller->GetZoomPercent(), 25.0f);
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_PLUS));
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_NORMAL));
+  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_MINUS));
+}
+
+TEST_F(BrowserCommandsTest, OnZoomReset) {
+  TabStripModel* tab_strip_model = browser()->tab_strip_model();
+
+  GURL url("http://www.google.com");
+  AddTab(browser(), url);
+  content::WebContents* contents1 = tab_strip_model->GetWebContentsAt(0);
+
+  // Change the zoom percentage to 100.
+  chrome_page_zoom::Zoom(contents1, content::PAGE_ZOOM_RESET);
+
+  ZoomController* zoom_controller = ZoomController::FromWebContents(contents1);
+  EXPECT_EQ(zoom_controller->GetZoomPercent(), 100.0f);
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_PLUS));
+  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_NORMAL));
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_MINUS));
+}
+
+TEST_F(BrowserCommandsTest, OnZoomLevelChanged) {
+  TabStripModel* tab_strip_model = browser()->tab_strip_model();
+
+  GURL url("http://www.google.com");
+  AddTab(browser(), url);
+  content::WebContents* contents1 = tab_strip_model->GetWebContentsAt(0);
+
+  // Changing zoom percentage from default should enable all the zoom
+  // NSMenuItems.
+  chrome_page_zoom::Zoom(contents1, content::PAGE_ZOOM_IN);
+
+  ZoomController* zoom_controller = ZoomController::FromWebContents(contents1);
+  EXPECT_EQ(zoom_controller->GetZoomPercent(), 110.0f);
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_PLUS));
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_NORMAL));
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_MINUS));
+}
+
+TEST_F(BrowserCommandsTest, OnZoomChangedForActiveTab) {
+  TabStripModel* tab_strip_model = browser()->tab_strip_model();
+
+  GURL url("http://www.google.com");
+  GURL url1("http://code.google.com");
+
+  // Add First tab.
+  AddTab(browser(), url);
+  AddTab(browser(), url1);
+  content::WebContents* contents1 = tab_strip_model->GetWebContentsAt(0);
+
+  ZoomController* zoom_controller = ZoomController::FromWebContents(contents1);
+  EXPECT_EQ(zoom_controller->GetZoomPercent(), 100.0f);
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_PLUS));
+  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_NORMAL));
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_MINUS));
+
+  // Add Second tab.
+  content::WebContents* contents2 = tab_strip_model->GetWebContentsAt(1);
+
+  tab_strip_model->ActivateTabAt(1, true);
+  EXPECT_TRUE(tab_strip_model->IsTabSelected(1));
+  chrome_page_zoom::Zoom(contents2, content::PAGE_ZOOM_OUT);
+
+  zoom_controller = ZoomController::FromWebContents(contents2);
+  EXPECT_EQ(zoom_controller->GetZoomPercent(), 90.0f);
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_PLUS));
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_NORMAL));
+  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_ZOOM_MINUS));
+}
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index e83eb7d..2f13de8 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -1897,6 +1897,8 @@
     // Only show the zoom bubble for zoom changes in the active window.
     window_->ZoomChangedForActiveTab(data.can_show_bubble &&
                                      window_->IsActive());
+    // Change the zoom commands state based on the zoom state
+    command_controller_->ZoomStateChanged();
   }
 }
 
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index 9ad358f..0886bda 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -318,6 +318,10 @@
   UpdateCommandsForTabState();
 }
 
+void BrowserCommandController::ZoomStateChanged() {
+  UpdateCommandsForZoomState();
+}
+
 void BrowserCommandController::ContentRestrictionsChanged() {
   UpdateCommandsForContentRestrictionState();
 }
@@ -946,7 +950,7 @@
   // Zoom
   command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true);
   command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true);
-  command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, true);
+  command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, false);
   command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true);
 
   // Show various bits of UI
@@ -1126,6 +1130,18 @@
   UpdateCommandsForContentRestrictionState();
   UpdateCommandsForBookmarkEditing();
   UpdateCommandsForFind();
+  // Update the zoom commands when an active tab is selected.
+  UpdateCommandsForZoomState();
+}
+
+void BrowserCommandController::UpdateCommandsForZoomState() {
+  WebContents* contents =
+      browser_->tab_strip_model()->GetActiveWebContents();
+  if (!contents)
+    return;
+  command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, CanZoomIn(contents));
+  command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, ActualSize(contents));
+  command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, CanZoomOut(contents));
 }
 
 void BrowserCommandController::UpdateCommandsForContentRestrictionState() {
diff --git a/chrome/browser/ui/browser_command_controller.h b/chrome/browser/ui/browser_command_controller.h
index bfba09e1..8a041050 100644
--- a/chrome/browser/ui/browser_command_controller.h
+++ b/chrome/browser/ui/browser_command_controller.h
@@ -56,6 +56,7 @@
   // Notifies the controller that state has changed in one of the following
   // areas and it should update command states.
   void TabStateChanged();
+  void ZoomStateChanged();
   void ContentRestrictionsChanged();
   void FullscreenStateChanged();
   void PrintingStateChanged();
@@ -113,6 +114,9 @@
   // Update commands whose state depends on the tab's state.
   void UpdateCommandsForTabState();
 
+  // Update Zoom commands based on zoom state.
+  void UpdateCommandsForZoomState();
+
   // Updates commands when the content's restrictions change.
   void UpdateCommandsForContentRestrictionState();
 
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index 788e76c..71b810b 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -53,6 +53,7 @@
 #include "chrome/browser/ui/tab_contents/core_tab_helper.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/webui/ntp/core_app_launcher_handler.h"
+#include "chrome/browser/ui/zoom/zoom_controller.h"
 #include "chrome/browser/upgrade_detector.h"
 #include "chrome/browser/web_applications/web_app.h"
 #include "chrome/common/chrome_switches.h"
@@ -585,6 +586,23 @@
   browser->tab_strip_model()->CloseSelectedTabs();
 }
 
+bool CanZoomIn(content::WebContents* contents) {
+  ZoomController* zoom_controller = ZoomController::FromWebContents(contents);
+  return zoom_controller->GetZoomPercent() !=
+      contents->GetMaximumZoomPercent() + 1;
+}
+
+bool CanZoomOut(content::WebContents* contents) {
+  ZoomController* zoom_controller = ZoomController::FromWebContents(contents);
+  return zoom_controller->GetZoomPercent() !=
+      contents->GetMinimumZoomPercent();
+}
+
+bool ActualSize(content::WebContents* contents) {
+  ZoomController* zoom_controller = ZoomController::FromWebContents(contents);
+  return zoom_controller->GetZoomPercent() != 100.0f;
+}
+
 void RestoreTab(Browser* browser) {
   content::RecordAction(UserMetricsAction("RestoreTab"));
   TabRestoreService* service =
diff --git a/chrome/browser/ui/browser_commands.h b/chrome/browser/ui/browser_commands.h
index 2113e77..5f9f7cd 100644
--- a/chrome/browser/ui/browser_commands.h
+++ b/chrome/browser/ui/browser_commands.h
@@ -76,6 +76,9 @@
 void CloseWindow(Browser* browser);
 void NewTab(Browser* browser);
 void CloseTab(Browser* browser);
+bool CanZoomIn(content::WebContents* contents);
+bool CanZoomOut(content::WebContents* contents);
+bool ActualSize(content::WebContents* contents);
 void RestoreTab(Browser* browser);
 TabStripModelDelegate::RestoreTabType GetRestoreTabType(
     const Browser* browser);