1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/ui/toolbar/wrench_menu_model.h" 6 7 #include <algorithm> 8 #include <cmath> 9 10 #include "base/command_line.h" 11 #include "base/i18n/number_formatting.h" 12 #include "base/string_number_conversions.h" 13 #include "base/string_util.h" 14 #include "base/utf_string_conversions.h" 15 #include "chrome/app/chrome_command_ids.h" 16 #include "chrome/browser/background_page_tracker.h" 17 #include "chrome/browser/browser_process.h" 18 #include "chrome/browser/defaults.h" 19 #include "chrome/browser/prefs/pref_service.h" 20 #include "chrome/browser/profiles/profile.h" 21 #include "chrome/browser/sync/profile_sync_service.h" 22 #include "chrome/browser/sync/sync_ui_util.h" 23 #include "chrome/browser/tabs/tab_strip_model.h" 24 #include "chrome/browser/ui/browser.h" 25 #include "chrome/browser/ui/toolbar/encoding_menu_controller.h" 26 #include "chrome/browser/upgrade_detector.h" 27 #include "chrome/common/chrome_switches.h" 28 #include "chrome/common/pref_names.h" 29 #include "chrome/common/profiling.h" 30 #include "content/browser/tab_contents/tab_contents.h" 31 #include "content/common/notification_service.h" 32 #include "content/common/notification_source.h" 33 #include "content/common/notification_type.h" 34 #include "grit/chromium_strings.h" 35 #include "grit/generated_resources.h" 36 #include "grit/theme_resources.h" 37 #include "ui/base/l10n/l10n_util.h" 38 #include "ui/base/models/button_menu_item_model.h" 39 #include "ui/base/resource/resource_bundle.h" 40 41 #if defined(OS_LINUX) 42 #include <gtk/gtk.h> 43 #include "chrome/browser/ui/gtk/gtk_util.h" 44 #endif 45 46 #if defined(OS_MACOSX) 47 #include "chrome/browser/ui/browser_window.h" 48 #endif 49 50 #if defined(OS_CHROMEOS) 51 #include "chrome/browser/chromeos/cros/cros_library.h" 52 #include "chrome/browser/chromeos/cros/update_library.h" 53 #endif 54 55 #if defined(OS_WIN) 56 #include "chrome/browser/enumerate_modules_model_win.h" 57 #endif 58 59 //////////////////////////////////////////////////////////////////////////////// 60 // EncodingMenuModel 61 62 EncodingMenuModel::EncodingMenuModel(Browser* browser) 63 : ALLOW_THIS_IN_INITIALIZER_LIST(ui::SimpleMenuModel(this)), 64 browser_(browser) { 65 Build(); 66 } 67 68 EncodingMenuModel::~EncodingMenuModel() { 69 } 70 71 void EncodingMenuModel::Build() { 72 EncodingMenuController::EncodingMenuItemList encoding_menu_items; 73 EncodingMenuController encoding_menu_controller; 74 encoding_menu_controller.GetEncodingMenuItems(browser_->profile(), 75 &encoding_menu_items); 76 77 int group_id = 0; 78 EncodingMenuController::EncodingMenuItemList::iterator it = 79 encoding_menu_items.begin(); 80 for (; it != encoding_menu_items.end(); ++it) { 81 int id = it->first; 82 string16& label = it->second; 83 if (id == 0) { 84 AddSeparator(); 85 } else { 86 if (id == IDC_ENCODING_AUTO_DETECT) { 87 AddCheckItem(id, label); 88 } else { 89 // Use the id of the first radio command as the id of the group. 90 if (group_id <= 0) 91 group_id = id; 92 AddRadioItem(id, label, group_id); 93 } 94 } 95 } 96 } 97 98 bool EncodingMenuModel::IsCommandIdChecked(int command_id) const { 99 TabContents* current_tab = browser_->GetSelectedTabContents(); 100 if (!current_tab) 101 return false; 102 EncodingMenuController controller; 103 return controller.IsItemChecked(browser_->profile(), 104 current_tab->encoding(), command_id); 105 } 106 107 bool EncodingMenuModel::IsCommandIdEnabled(int command_id) const { 108 bool enabled = browser_->command_updater()->IsCommandEnabled(command_id); 109 // Special handling for the contents of the Encoding submenu. On Mac OS, 110 // instead of enabling/disabling the top-level menu item, the submenu's 111 // contents get disabled, per Apple's HIG. 112 #if defined(OS_MACOSX) 113 enabled &= browser_->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU); 114 #endif 115 return enabled; 116 } 117 118 bool EncodingMenuModel::GetAcceleratorForCommandId( 119 int command_id, 120 ui::Accelerator* accelerator) { 121 return false; 122 } 123 124 void EncodingMenuModel::ExecuteCommand(int command_id) { 125 browser_->ExecuteCommand(command_id); 126 } 127 128 //////////////////////////////////////////////////////////////////////////////// 129 // ZoomMenuModel 130 131 ZoomMenuModel::ZoomMenuModel(ui::SimpleMenuModel::Delegate* delegate) 132 : SimpleMenuModel(delegate) { 133 Build(); 134 } 135 136 ZoomMenuModel::~ZoomMenuModel() { 137 } 138 139 void ZoomMenuModel::Build() { 140 AddItemWithStringId(IDC_ZOOM_PLUS, IDS_ZOOM_PLUS); 141 AddItemWithStringId(IDC_ZOOM_NORMAL, IDS_ZOOM_NORMAL); 142 AddItemWithStringId(IDC_ZOOM_MINUS, IDS_ZOOM_MINUS); 143 } 144 145 //////////////////////////////////////////////////////////////////////////////// 146 // ToolsMenuModel 147 148 ToolsMenuModel::ToolsMenuModel(ui::SimpleMenuModel::Delegate* delegate, 149 Browser* browser) 150 : SimpleMenuModel(delegate) { 151 Build(browser); 152 } 153 154 ToolsMenuModel::~ToolsMenuModel() {} 155 156 void ToolsMenuModel::Build(Browser* browser) { 157 AddCheckItemWithStringId(IDC_SHOW_BOOKMARK_BAR, IDS_SHOW_BOOKMARK_BAR); 158 159 AddSeparator(); 160 161 #if !defined(OS_CHROMEOS) 162 #if defined(OS_MACOSX) 163 AddItemWithStringId(IDC_CREATE_SHORTCUTS, IDS_CREATE_APPLICATION_MAC); 164 #else 165 AddItemWithStringId(IDC_CREATE_SHORTCUTS, IDS_CREATE_SHORTCUTS); 166 #endif 167 AddSeparator(); 168 #endif 169 170 AddItemWithStringId(IDC_MANAGE_EXTENSIONS, IDS_SHOW_EXTENSIONS); 171 #if defined(OS_CHROMEOS) 172 AddItemWithStringId(IDC_FILE_MANAGER, IDS_FILE_MANAGER); 173 #endif 174 AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER); 175 AddItemWithStringId(IDC_CLEAR_BROWSING_DATA, IDS_CLEAR_BROWSING_DATA); 176 177 AddSeparator(); 178 179 #if !defined(OS_CHROMEOS) 180 // Show IDC_FEEDBACK in "Tools" menu for non-ChromeOS platforms. 181 AddItemWithStringId(IDC_FEEDBACK, IDS_FEEDBACK); 182 AddSeparator(); 183 #endif 184 185 encoding_menu_model_.reset(new EncodingMenuModel(browser)); 186 AddSubMenuWithStringId(IDC_ENCODING_MENU, IDS_ENCODING_MENU, 187 encoding_menu_model_.get()); 188 AddItemWithStringId(IDC_VIEW_SOURCE, IDS_VIEW_SOURCE); 189 AddItemWithStringId(IDC_DEV_TOOLS, IDS_DEV_TOOLS); 190 AddItemWithStringId(IDC_DEV_TOOLS_CONSOLE, IDS_DEV_TOOLS_CONSOLE); 191 192 #if defined(ENABLE_PROFILING) && !defined(NO_TCMALLOC) 193 AddSeparator(); 194 AddCheckItemWithStringId(IDC_PROFILING_ENABLED, IDS_PROFILING_ENABLED); 195 #endif 196 } 197 198 //////////////////////////////////////////////////////////////////////////////// 199 // WrenchMenuModel 200 201 WrenchMenuModel::WrenchMenuModel(ui::AcceleratorProvider* provider, 202 Browser* browser) 203 : ALLOW_THIS_IN_INITIALIZER_LIST(ui::SimpleMenuModel(this)), 204 provider_(provider), 205 browser_(browser), 206 tabstrip_model_(browser_->tabstrip_model()) { 207 Build(); 208 UpdateZoomControls(); 209 210 tabstrip_model_->AddObserver(this); 211 212 registrar_.Add(this, NotificationType::ZOOM_LEVEL_CHANGED, 213 Source<Profile>(browser_->profile())); 214 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, 215 NotificationService::AllSources()); 216 } 217 218 WrenchMenuModel::~WrenchMenuModel() { 219 if (tabstrip_model_) 220 tabstrip_model_->RemoveObserver(this); 221 } 222 223 bool WrenchMenuModel::DoesCommandIdDismissMenu(int command_id) const { 224 return command_id != IDC_ZOOM_MINUS && command_id != IDC_ZOOM_PLUS; 225 } 226 227 bool WrenchMenuModel::IsItemForCommandIdDynamic(int command_id) const { 228 return command_id == IDC_ZOOM_PERCENT_DISPLAY || 229 #if defined(OS_MACOSX) 230 command_id == IDC_FULLSCREEN || 231 #endif 232 command_id == IDC_SYNC_BOOKMARKS || 233 command_id == IDC_VIEW_BACKGROUND_PAGES || 234 command_id == IDC_UPGRADE_DIALOG; 235 } 236 237 string16 WrenchMenuModel::GetLabelForCommandId(int command_id) const { 238 switch (command_id) { 239 case IDC_SYNC_BOOKMARKS: 240 return GetSyncMenuLabel(); 241 case IDC_ZOOM_PERCENT_DISPLAY: 242 return zoom_label_; 243 #if defined(OS_MACOSX) 244 case IDC_FULLSCREEN: { 245 int string_id = IDS_ENTER_FULLSCREEN_MAC; // Default to Enter. 246 // Note: On startup, |window()| may be NULL. 247 if (browser_->window() && browser_->window()->IsFullscreen()) 248 string_id = IDS_EXIT_FULLSCREEN_MAC; 249 return l10n_util::GetStringUTF16(string_id); 250 } 251 #endif 252 case IDC_VIEW_BACKGROUND_PAGES: { 253 string16 num_background_pages = base::FormatNumber( 254 BackgroundPageTracker::GetInstance()->GetBackgroundPageCount()); 255 return l10n_util::GetStringFUTF16(IDS_VIEW_BACKGROUND_PAGES, 256 num_background_pages); 257 } 258 case IDC_UPGRADE_DIALOG: { 259 #if defined(OS_CHROMEOS) 260 const string16 product_name = 261 l10n_util::GetStringUTF16(IDS_PRODUCT_OS_NAME); 262 #else 263 const string16 product_name = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); 264 #endif 265 266 return l10n_util::GetStringFUTF16(IDS_UPDATE_NOW, product_name); 267 } 268 default: 269 NOTREACHED(); 270 return string16(); 271 } 272 } 273 274 bool WrenchMenuModel::GetIconForCommandId(int command_id, 275 SkBitmap* icon) const { 276 switch (command_id) { 277 case IDC_UPGRADE_DIALOG: { 278 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 279 int resource_id; 280 UpgradeDetector::UpgradeNotificationAnnoyanceLevel stage = 281 UpgradeDetector::GetInstance()->upgrade_notification_stage(); 282 switch (stage) { 283 case UpgradeDetector::UPGRADE_ANNOYANCE_SEVERE: 284 resource_id = IDR_UPDATE_MENU4; 285 break; 286 case UpgradeDetector::UPGRADE_ANNOYANCE_HIGH: 287 resource_id = IDR_UPDATE_MENU3; 288 break; 289 case UpgradeDetector::UPGRADE_ANNOYANCE_ELEVATED: 290 resource_id = IDR_UPDATE_MENU2; 291 break; 292 default: 293 resource_id = IDR_UPDATE_MENU; 294 break; 295 } 296 *icon = *rb.GetBitmapNamed(resource_id); 297 break; 298 } 299 default: 300 break; 301 } 302 return false; 303 } 304 305 void WrenchMenuModel::ExecuteCommand(int command_id) { 306 browser_->ExecuteCommand(command_id); 307 } 308 309 bool WrenchMenuModel::IsCommandIdChecked(int command_id) const { 310 if (command_id == IDC_SHOW_BOOKMARK_BAR) { 311 return browser_->profile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); 312 } else if (command_id == IDC_PROFILING_ENABLED) { 313 return Profiling::BeingProfiled(); 314 } 315 316 return false; 317 } 318 319 bool WrenchMenuModel::IsCommandIdEnabled(int command_id) const { 320 if (command_id == IDC_SHOW_BOOKMARK_BAR) { 321 return !browser_->profile()->GetPrefs()->IsManagedPreference( 322 prefs::kEnableBookmarkBar); 323 } 324 return browser_->command_updater()->IsCommandEnabled(command_id); 325 } 326 327 bool WrenchMenuModel::IsCommandIdVisible(int command_id) const { 328 if (command_id == IDC_UPGRADE_DIALOG) { 329 #if defined(OS_CHROMEOS) 330 return (chromeos::CrosLibrary::Get()->GetUpdateLibrary()->status().status 331 == chromeos::UPDATE_STATUS_UPDATED_NEED_REBOOT); 332 #else 333 return UpgradeDetector::GetInstance()->notify_upgrade(); 334 #endif 335 } else if (command_id == IDC_VIEW_INCOMPATIBILITIES) { 336 #if defined(OS_WIN) 337 EnumerateModulesModel* loaded_modules = 338 EnumerateModulesModel::GetInstance(); 339 if (loaded_modules->confirmed_bad_modules_detected() <= 0) 340 return false; 341 loaded_modules->AcknowledgeConflictNotification(); 342 return true; 343 #else 344 return false; 345 #endif 346 } else if (command_id == IDC_VIEW_BACKGROUND_PAGES) { 347 BackgroundPageTracker* tracker = BackgroundPageTracker::GetInstance(); 348 return tracker->GetBackgroundPageCount() > 0; 349 } 350 return true; 351 } 352 353 bool WrenchMenuModel::GetAcceleratorForCommandId( 354 int command_id, 355 ui::Accelerator* accelerator) { 356 return provider_->GetAcceleratorForCommandId(command_id, accelerator); 357 } 358 359 void WrenchMenuModel::TabSelectedAt(TabContentsWrapper* old_contents, 360 TabContentsWrapper* new_contents, 361 int index, 362 bool user_gesture) { 363 // The user has switched between tabs and the new tab may have a different 364 // zoom setting. 365 UpdateZoomControls(); 366 } 367 368 void WrenchMenuModel::TabReplacedAt(TabStripModel* tab_strip_model, 369 TabContentsWrapper* old_contents, 370 TabContentsWrapper* new_contents, 371 int index) { 372 UpdateZoomControls(); 373 } 374 375 void WrenchMenuModel::TabStripModelDeleted() { 376 // During views shutdown, the tabstrip model/browser is deleted first, while 377 // it is the opposite in gtk land. 378 tabstrip_model_->RemoveObserver(this); 379 tabstrip_model_ = NULL; 380 } 381 382 void WrenchMenuModel::Observe(NotificationType type, 383 const NotificationSource& source, 384 const NotificationDetails& details) { 385 switch (type.value) { 386 case NotificationType::ZOOM_LEVEL_CHANGED: 387 case NotificationType::NAV_ENTRY_COMMITTED: 388 UpdateZoomControls(); 389 break; 390 default: 391 NOTREACHED(); 392 } 393 } 394 395 // For testing. 396 WrenchMenuModel::WrenchMenuModel() 397 : ALLOW_THIS_IN_INITIALIZER_LIST(ui::SimpleMenuModel(this)), 398 provider_(NULL), 399 browser_(NULL), 400 tabstrip_model_(NULL) { 401 } 402 403 void WrenchMenuModel::Build() { 404 AddItemWithStringId(IDC_NEW_TAB, IDS_NEW_TAB); 405 AddItemWithStringId(IDC_NEW_WINDOW, IDS_NEW_WINDOW); 406 #if defined(OS_CHROMEOS) 407 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession)) 408 AddItemWithStringId(IDC_NEW_INCOGNITO_WINDOW, IDS_NEW_INCOGNITO_WINDOW); 409 #else 410 AddItemWithStringId(IDC_NEW_INCOGNITO_WINDOW, IDS_NEW_INCOGNITO_WINDOW); 411 #endif 412 413 AddSeparator(); 414 #if defined(OS_MACOSX) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) 415 // WARNING: Mac does not use the ButtonMenuItemModel, but instead defines the 416 // layout for this menu item in Toolbar.xib. It does, however, use the 417 // command_id value from AddButtonItem() to identify this special item. 418 edit_menu_item_model_.reset(new ui::ButtonMenuItemModel(IDS_EDIT, this)); 419 edit_menu_item_model_->AddGroupItemWithStringId(IDC_CUT, IDS_CUT); 420 edit_menu_item_model_->AddGroupItemWithStringId(IDC_COPY, IDS_COPY); 421 edit_menu_item_model_->AddGroupItemWithStringId(IDC_PASTE, IDS_PASTE); 422 AddButtonItem(IDC_EDIT_MENU, edit_menu_item_model_.get()); 423 #else 424 // TODO(port): Move to the above. 425 CreateCutCopyPaste(); 426 #endif 427 428 AddSeparator(); 429 #if defined(OS_MACOSX) || (defined(OS_LINUX) && !defined(TOOLKIT_VIEWS)) 430 // WARNING: See above comment. 431 zoom_menu_item_model_.reset( 432 new ui::ButtonMenuItemModel(IDS_ZOOM_MENU, this)); 433 zoom_menu_item_model_->AddGroupItemWithStringId( 434 IDC_ZOOM_MINUS, IDS_ZOOM_MINUS2); 435 zoom_menu_item_model_->AddButtonLabel(IDC_ZOOM_PERCENT_DISPLAY, 436 IDS_ZOOM_PLUS2); 437 zoom_menu_item_model_->AddGroupItemWithStringId( 438 IDC_ZOOM_PLUS, IDS_ZOOM_PLUS2); 439 zoom_menu_item_model_->AddSpace(); 440 zoom_menu_item_model_->AddItemWithImage( 441 IDC_FULLSCREEN, IDR_FULLSCREEN_MENU_BUTTON); 442 AddButtonItem(IDC_ZOOM_MENU, zoom_menu_item_model_.get()); 443 #else 444 // TODO(port): Move to the above. 445 CreateZoomFullscreen(); 446 #endif 447 448 AddSeparator(); 449 AddItemWithStringId(IDC_SAVE_PAGE, IDS_SAVE_PAGE); 450 AddItemWithStringId(IDC_FIND, IDS_FIND); 451 AddItemWithStringId(IDC_PRINT, IDS_PRINT); 452 453 tools_menu_model_.reset(new ToolsMenuModel(this, browser_)); 454 AddSubMenuWithStringId(IDC_ZOOM_MENU, IDS_TOOLS_MENU, 455 tools_menu_model_.get()); 456 457 AddSeparator(); 458 AddItemWithStringId(IDC_SHOW_BOOKMARK_MANAGER, IDS_BOOKMARK_MANAGER); 459 AddItemWithStringId(IDC_SHOW_HISTORY, IDS_SHOW_HISTORY); 460 AddItemWithStringId(IDC_SHOW_DOWNLOADS, IDS_SHOW_DOWNLOADS); 461 AddSeparator(); 462 463 #if defined(OS_CHROMEOS) 464 AddItemWithStringId(IDC_OPTIONS, IDS_SETTINGS); 465 #elif defined(OS_MACOSX) 466 AddItemWithStringId(IDC_OPTIONS, IDS_PREFERENCES); 467 #elif defined(OS_LINUX) 468 string16 preferences = gtk_util::GetStockPreferencesMenuLabel(); 469 if (!preferences.empty()) 470 AddItem(IDC_OPTIONS, preferences); 471 else 472 AddItemWithStringId(IDC_OPTIONS, IDS_PREFERENCES); 473 #else 474 AddItemWithStringId(IDC_OPTIONS, IDS_OPTIONS); 475 #endif 476 477 #if defined(OS_CHROMEOS) 478 const string16 product_name = l10n_util::GetStringUTF16(IDS_PRODUCT_OS_NAME); 479 #else 480 const string16 product_name = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); 481 #endif 482 AddItem(IDC_ABOUT, l10n_util::GetStringFUTF16(IDS_ABOUT, product_name)); 483 string16 num_background_pages = base::FormatNumber( 484 BackgroundPageTracker::GetInstance()->GetBackgroundPageCount()); 485 AddItem(IDC_VIEW_BACKGROUND_PAGES, l10n_util::GetStringFUTF16( 486 IDS_VIEW_BACKGROUND_PAGES, num_background_pages)); 487 AddItem(IDC_UPGRADE_DIALOG, l10n_util::GetStringFUTF16( 488 IDS_UPDATE_NOW, product_name)); 489 AddItem(IDC_VIEW_INCOMPATIBILITIES, l10n_util::GetStringUTF16( 490 IDS_VIEW_INCOMPATIBILITIES)); 491 492 #if defined(OS_WIN) 493 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 494 SetIcon(GetIndexOfCommandId(IDC_VIEW_INCOMPATIBILITIES), 495 *rb.GetBitmapNamed(IDR_CONFLICT_MENU)); 496 #endif 497 498 AddItemWithStringId(IDC_HELP_PAGE, IDS_HELP_PAGE); 499 #if defined(OS_CHROMEOS) 500 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 501 // Use an icon for IDC_HELP_PAGE menu item. 502 SetIcon(GetIndexOfCommandId(IDC_HELP_PAGE), 503 *rb.GetBitmapNamed(IDR_HELP_MENU)); 504 505 // Show IDC_FEEDBACK in top-tier wrench menu for ChromeOS. 506 AddItemWithStringId(IDC_FEEDBACK, IDS_FEEDBACK); 507 #endif 508 509 if (browser_defaults::kShowExitMenuItem) { 510 AddSeparator(); 511 #if defined(OS_CHROMEOS) 512 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kGuestSession)) { 513 AddItemWithStringId(IDC_EXIT, IDS_EXIT_GUEST_MODE); 514 } else { 515 AddItemWithStringId(IDC_EXIT, IDS_SIGN_OUT); 516 } 517 #else 518 AddItemWithStringId(IDC_EXIT, IDS_EXIT); 519 #endif 520 } 521 } 522 523 void WrenchMenuModel::CreateCutCopyPaste() { 524 // WARNING: views/wrench_menu assumes these items are added in this order. If 525 // you change the order you'll need to update wrench_menu as well. 526 AddItemWithStringId(IDC_CUT, IDS_CUT); 527 AddItemWithStringId(IDC_COPY, IDS_COPY); 528 AddItemWithStringId(IDC_PASTE, IDS_PASTE); 529 } 530 531 void WrenchMenuModel::CreateZoomFullscreen() { 532 // WARNING: views/wrench_menu assumes these items are added in this order. If 533 // you change the order you'll need to update wrench_menu as well. 534 AddItemWithStringId(IDC_ZOOM_MINUS, IDS_ZOOM_MINUS); 535 AddItemWithStringId(IDC_ZOOM_PLUS, IDS_ZOOM_PLUS); 536 AddItemWithStringId(IDC_FULLSCREEN, IDS_FULLSCREEN); 537 } 538 539 void WrenchMenuModel::UpdateZoomControls() { 540 bool enable_increment = false; 541 bool enable_decrement = false; 542 int zoom_percent = 100; 543 if (browser_->GetSelectedTabContents()) { 544 zoom_percent = browser_->GetSelectedTabContents()->GetZoomPercent( 545 &enable_increment, &enable_decrement); 546 } 547 zoom_label_ = l10n_util::GetStringFUTF16( 548 IDS_ZOOM_PERCENT, base::IntToString16(zoom_percent)); 549 } 550 551 string16 WrenchMenuModel::GetSyncMenuLabel() const { 552 return sync_ui_util::GetSyncMenuLabel( 553 browser_->profile()->GetOriginalProfile()->GetProfileSyncService()); 554 } 555