Index: chrome/browser/cocoa/translate_infobar.mm |
diff --git a/chrome/browser/cocoa/translate_infobar.mm b/chrome/browser/cocoa/translate_infobar.mm |
deleted file mode 100644 |
index 949967f79bef8310ce254b0861a1654b1d94e868..0000000000000000000000000000000000000000 |
--- a/chrome/browser/cocoa/translate_infobar.mm |
+++ /dev/null |
@@ -1,941 +0,0 @@ |
-// Copyright (c) 2010 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#import <Cocoa/Cocoa.h> |
-#import "chrome/browser/cocoa/translate_infobar.h" |
- |
-#include "app/l10n_util.h" |
-#include "base/logging.h" // for NOTREACHED() |
-#include "base/mac_util.h" |
-#include "base/sys_string_conversions.h" |
-#include "chrome/app/chrome_dll_resource.h" |
-#import "chrome/browser/cocoa/hover_close_button.h" |
-#include "chrome/browser/cocoa/infobar.h" |
-#import "chrome/browser/cocoa/infobar_controller.h" |
-#import "chrome/browser/cocoa/infobar_gradient_view.h" |
-#include "chrome/browser/tab_contents/tab_contents.h" |
-#include "chrome/browser/translate/page_translated_details.h" |
-#include "chrome/common/notification_service.h" |
-#include "grit/generated_resources.h" |
-#include "grit/locale_settings.h" |
-#include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" |
- |
-// http://crbug.com/46663 disabled since it never worked. |
-#define DISABLE_VERIFY_CONTROL_ORDER 1 |
- |
-// Colors for translate infobar gradient background. |
-const int kGreyTopColor[] = {0xC0, 0xC0, 0xC0}; |
-const int kGreyBottomColor[] = {0xCC, 0xCC, 0xCC}; |
- |
-#pragma mark Anonymous helper functions. |
-namespace { |
- |
-// Move the |toMove| view |spacing| pixels before/after the |anchor| view. |
-// |after| signifies the side of |anchor| on which to place |toMove|. |
-void MoveControl(NSView* anchor, NSView* toMove, int spacing, bool after) { |
- NSRect anchorFrame = [anchor frame]; |
- NSRect toMoveFrame = [toMove frame]; |
- |
- // At the time of this writing, OS X doesn't natively support BiDi UIs, but |
- // it doesn't hurt to be forward looking. |
- bool toRight = after; |
- |
- if (toRight) { |
- toMoveFrame.origin.x = NSMaxX(anchorFrame) + spacing; |
- } else { |
- // Place toMove to theleft of anchor. |
- toMoveFrame.origin.x = NSMinX(anchorFrame) - |
- spacing - NSWidth(toMoveFrame); |
- } |
- [toMove setFrame:toMoveFrame]; |
-} |
- |
-// Vertically center |toMove| in its container. |
-void VerticallyCenterView(NSView *toMove) { |
- NSRect superViewFrame = [[toMove superview] frame]; |
- NSRect viewFrame = [toMove frame]; |
- |
- viewFrame.origin.y = |
- floor((NSHeight(superViewFrame) - NSHeight(viewFrame))/2.0); |
- [toMove setFrame:viewFrame]; |
-} |
- |
-// Check that the control |before| is ordered visually before the |after| |
-// control. |
-// Also, check that there is space between them. |
-// http://crbug.com/46663 the code below seems to be the reverse of this |
-// comment. |
-#if !defined(DISABLE_VERIFY_CONTROL_ORDER) |
-bool VerifyControlOrderAndSpacing(id before, id after) { |
- CGFloat spaceBetweenControls = 0; |
- if (before && after) { |
- // When messaging nil, the rects won't always be zeroed (only sizeof(id) is |
- // going to be zeroed by the Objective-C runtime, rest will be uninitialized |
- // memory). |
- NSRect beforeFrame = [before frame]; |
- NSRect afterFrame = [after frame]; |
- spaceBetweenControls = NSMaxX(beforeFrame) - NSMinX(afterFrame); |
- // RTL case to be used when we have an RTL version of this UI. |
- // spaceBetweenControls = NSMaxX(afterFrame) - NSMinX(beforeFrame); |
- |
- } |
- |
- return (spaceBetweenControls >= 0); |
-} |
-#endif // !defined(DISABLE_VERIFY_CONTROL_ORDER) |
- |
-// Creates a label control in the style we need for the translate infobar's |
-// labels within |bounds|. |
-NSTextField* CreateLabel(NSRect bounds) { |
- NSTextField* ret = [[NSTextField alloc] initWithFrame:bounds]; |
- [ret setEditable:NO]; |
- [ret setDrawsBackground:NO]; |
- [ret setBordered:NO]; |
- return ret; |
-} |
- |
-// Adds an item with the specified properties to |menu|. |
-void AddMenuItem(NSMenu *menu, id target, NSString* title, int tag, |
- bool enabled, bool checked) { |
- NSMenuItem* item = [[[NSMenuItem alloc] |
- initWithTitle:title |
- action:@selector(menuItemSelected:) |
- keyEquivalent:@""] autorelease]; |
- [item setTag:tag]; |
- [menu addItem:item]; |
- [item setTarget:target]; |
- if (checked) |
- [item setState:NSOnState]; |
- if (!enabled) |
- [item setEnabled:NO]; |
-} |
- |
-} // namespace |
- |
-#pragma mark TranslateInfoBarMenuModel class definition |
-// Bridge class to handle interfacing with menu controllers from popup |
-// menus in infobar. |
-class TranslateInfoBarMenuModel : public menus::SimpleMenuModel::Delegate { |
- public: |
- TranslateInfoBarMenuModel(TranslateInfoBarDelegate* delegate, |
- TranslateInfoBarController* controller) : |
- translate_delegate_(delegate), |
- controller_(controller) {} |
- |
- // Overridden from menus::SimpleMenuModel::Delegate: |
- virtual bool IsCommandIdChecked(int command_id) const; |
- virtual bool IsCommandIdEnabled(int command_id) const; |
- virtual bool GetAcceleratorForCommandId(int command_id, |
- menus::Accelerator* accelerator); |
- virtual void ExecuteCommand(int command_id); |
- |
- private: |
- TranslateInfoBarDelegate* translate_delegate_; // weak |
- TranslateInfoBarController* controller_; // weak |
- DISALLOW_COPY_AND_ASSIGN(TranslateInfoBarMenuModel); |
-}; |
- |
-#pragma mark TranslateNotificationObserverBridge class definition |
-// Bridge class to allow obj-c TranslateInfoBarController to observe |
-// notifications. |
-class TranslateNotificationObserverBridge : |
- public NotificationObserver { |
- public: |
- TranslateNotificationObserverBridge( |
- TranslateInfoBarDelegate* delegate, |
- TranslateInfoBarController* controller); |
- |
- // Overridden from NotificationObserver: |
- virtual void Observe(NotificationType type, |
- const NotificationSource& source, |
- const NotificationDetails& details); |
- |
- private: |
- TranslateInfoBarDelegate* translate_delegate_; // weak |
- TranslateInfoBarController* controller_; // weak |
- NotificationRegistrar notification_registrar_; |
- DISALLOW_COPY_AND_ASSIGN(TranslateNotificationObserverBridge); |
-}; |
- |
-@interface TranslateInfoBarController (Private) |
- |
-// Returns the main translate delegate. |
-- (TranslateInfoBarDelegate*)delegate; |
- |
-// Make the infobar grey. |
-- (void)setInfoBarGradientColor; |
- |
-// Reloads text for all labels for the current state. |
-- (void)loadLabelText:(TranslateErrors::Type)error; |
- |
-// Resizes controls and hides/shows them based on state transition. |
-// Called before layout; |
-- (void)resizeAndSetControlVisibility; |
- |
-// Move all the currently visible views into the correct place for the |
-// current mode. |
-- (void)layout; |
- |
-// Create all the various controls we need for the toolbar. |
-- (void)constructViews; |
- |
-// Called when the source or target language selection changes in a menu. |
-// |newLanguageIdx| is the index of the newly selected item in the appropriate |
-// menu. |
-- (void)sourceLanguageModified:(NSInteger)newLanguageIdx; |
-- (void)targetLanguageModified:(NSInteger)newLanguageIdx; |
- |
-// Called when the source or target language have changed to update the |
-// model state and refresh the GUI. |
-- (void)languageModified; |
- |
-// Completely rebuild "from" and "to" language menus from the data model. |
-- (void)populateLanguageMenus; |
- |
-@end |
- |
-#pragma mark TranslateInfoBarController class |
-@implementation TranslateInfoBarController |
- |
-- (id)initWithDelegate:(InfoBarDelegate*)delegate { |
- if ((self = [super initWithDelegate:delegate])) { |
- state_ = TranslateInfoBarDelegate::kTranslateNone; |
- |
- observer_bridge_.reset( |
- new TranslateNotificationObserverBridge([self delegate], self)); |
- |
- original_language_menu_model_.reset( |
- new LanguagesMenuModel(menu_model_.get(), [self delegate], |
- /*original_language=*/true)); |
- |
- target_language_menu_model_.reset( |
- new LanguagesMenuModel(menu_model_.get(), [self delegate], |
- /*original_language=*/false)); |
- |
- menu_model_.reset(new TranslateInfoBarMenuModel([self delegate], self)); |
- } |
- return self; |
-} |
- |
-- (TranslateInfoBarDelegate*)delegate { |
- return reinterpret_cast<TranslateInfoBarDelegate*>(delegate_); |
-} |
- |
-- (void)constructViews { |
- // Using a zero or very large frame causes GTMUILocalizerAndLayoutTweaker |
- // to not resize the view properly so we take the bounds of the first label |
- // which is contained in the nib. |
- NSRect bogusFrame = [label_ frame]; |
- label1_.reset(CreateLabel(bogusFrame)); |
- label2_.reset(CreateLabel(bogusFrame)); |
- label3_.reset(CreateLabel(bogusFrame)); |
- translatingLabel_.reset(CreateLabel(bogusFrame)); |
- |
- optionsPopUp_.reset([[NSPopUpButton alloc] initWithFrame:bogusFrame |
- pullsDown:YES]); |
- fromLanguagePopUp_.reset([[NSPopUpButton alloc] initWithFrame:bogusFrame |
- pullsDown:NO]); |
- toLanguagePopUp_.reset([[NSPopUpButton alloc] initWithFrame:bogusFrame |
- pullsDown:NO]); |
- |
- showOriginalButton_.reset([[NSButton alloc] initWithFrame:bogusFrame]); |
- tryAgainButton_.reset([[NSButton alloc] initWithFrame:bogusFrame]); |
-} |
- |
-- (void)sourceLanguageModified:(NSInteger)newLanguageIdx { |
- DCHECK_GT(newLanguageIdx, 0); |
- |
- if (newLanguageIdx == [self delegate]->original_lang_index()) |
- return; |
- |
- [self delegate]->ModifyOriginalLanguage(newLanguageIdx); |
- |
- int commandId = IDC_TRANSLATE_ORIGINAL_LANGUAGE_BASE + newLanguageIdx; |
- int newMenuIdx = [fromLanguagePopUp_ indexOfItemWithTag:commandId]; |
- [fromLanguagePopUp_ selectItemAtIndex:newMenuIdx]; |
- |
- [self languageModified]; |
-} |
- |
-- (void)targetLanguageModified:(NSInteger)newLanguageIdx { |
- DCHECK_GT(newLanguageIdx, 0); |
- if (newLanguageIdx == [self delegate]->target_lang_index()) |
- return; |
- |
- [self delegate]->ModifyTargetLanguage(newLanguageIdx); |
- |
- int commandId = IDC_TRANSLATE_TARGET_LANGUAGE_BASE + newLanguageIdx; |
- int newMenuIdx = [toLanguagePopUp_ indexOfItemWithTag:commandId]; |
- [toLanguagePopUp_ selectItemAtIndex:newMenuIdx]; |
- |
- [self languageModified]; |
-} |
- |
-- (void)languageModified { |
- // Selecting an item from the "from language" menu in the before translate |
- // phase shouldn't trigger translation - http://crbug.com/36666 |
- TranslateInfoBarDelegate* delegate = [self delegate]; |
- if (delegate->state() == TranslateInfoBarDelegate::kAfterTranslate) { |
- delegate->Translate(); |
- [self updateState:delegate->state() |
- translationPending:delegate->translation_pending() |
- error:delegate->error_type()]; |
- } |
-} |
- |
-- (void)updateState:(TranslateInfoBarDelegate::TranslateState)newState |
- translationPending:(bool)newTranslationPending |
- error:(TranslateErrors::Type)error { |
- if (state_ == newState && translationPending_ == newTranslationPending) |
- return; |
- |
- state_ = newState; |
- translationPending_ = newTranslationPending; |
- |
- [self loadLabelText:error]; |
- |
- [self resizeAndSetControlVisibility]; |
- [self layout]; |
-} |
- |
-- (void)setInfoBarGradientColor { |
- // Use grey gradient for the infobars. |
- NSColor* startingColor = |
- [NSColor colorWithCalibratedRed:kGreyTopColor[0] / 255.0 |
- green:kGreyTopColor[1] / 255.0 |
- blue:kGreyTopColor[2] / 255.0 |
- alpha:1.0]; |
- NSColor* endingColor = |
- [NSColor colorWithCalibratedRed:kGreyBottomColor[0] / 255.0 |
- green:kGreyBottomColor[1] / 255.0 |
- blue:kGreyBottomColor[2] / 255.0 |
- alpha:1.0]; |
- NSGradient* translateInfoBarGradient = |
- [[[NSGradient alloc] initWithStartingColor:startingColor |
- endingColor:endingColor] autorelease]; |
- |
- [infoBarView_ setGradient:translateInfoBarGradient]; |
-} |
- |
-- (void)resizeAndSetControlVisibility { |
- // Step 1: remove all controls from the infobar so we have a clean slate. |
- NSArray *allControls = [NSArray arrayWithObjects:label2_.get(), label3_.get(), |
- translatingLabel_.get(), fromLanguagePopUp_.get(), toLanguagePopUp_.get(), |
- showOriginalButton_.get(), tryAgainButton_.get(), nil]; |
- |
- for (NSControl* control in allControls) { |
- if ([control superview]) |
- [control removeFromSuperview]; |
- } |
- |
- // OK & Cancel buttons are only visible in "before translate" mode when no |
- // translation is in progress. |
- if (state_ != TranslateInfoBarDelegate::kBeforeTranslate || |
- translationPending_) { |
- // Removing okButton_ & cancelButton_ from the view may cause them |
- // to be released and since we can still access them from other areas |
- // in the code later, we need them to be nil when this happens. |
- [okButton_ removeFromSuperview]; |
- okButton_ = nil; |
- [cancelButton_ removeFromSuperview]; |
- cancelButton_ = nil; |
- |
- } |
- |
- // Step 2: Resize all visible controls and add them to the infobar. |
- NSMutableArray *visibleControls = nil; |
- |
- switch (state_) { |
- case TranslateInfoBarDelegate::kBeforeTranslate: |
- visibleControls = [NSMutableArray arrayWithObjects:label1_.get(), |
- label2_.get(), fromLanguagePopUp_.get(), nil]; |
- |
- if (!translationPending_) { |
- [visibleControls addObject:okButton_]; |
- [visibleControls addObject:cancelButton_]; |
- } |
- break; |
- case TranslateInfoBarDelegate::kAfterTranslate: |
- visibleControls = [NSMutableArray arrayWithObjects:label1_.get(), |
- label2_.get(), fromLanguagePopUp_.get(), toLanguagePopUp_.get(), nil]; |
- if (!translationPending_) { |
- [visibleControls addObject:showOriginalButton_.get()]; |
- } |
- break; |
- case TranslateInfoBarDelegate::kTranslateError: |
- visibleControls = [NSMutableArray arrayWithObjects:label1_.get(), nil]; |
- |
- if (!translationPending_) { |
- [visibleControls addObject:tryAgainButton_.get()]; |
- } |
- break; |
- default: |
- NOTREACHED() << "Invalid translate infobar state"; |
- break; |
- } |
- |
- if (translationPending_) { |
- [visibleControls addObject:translatingLabel_]; |
- } |
- |
- if (numLabelsDisplayed_ >= 3) { |
- [visibleControls addObject:label3_.get()]; |
- } |
- |
- // The options popup is only hidden in the translateError view. |
- BOOL optionsPopuUpHidden = |
- (state_ == TranslateInfoBarDelegate::kTranslateError) ? YES : NO; |
- [optionsPopUp_ setHidden:optionsPopuUpHidden]; |
- |
- NSRect optionsFrame = [optionsPopUp_ frame]; |
- for (NSControl* control in visibleControls) { |
- [GTMUILocalizerAndLayoutTweaker sizeToFitView:control]; |
- [control setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin | |
- NSViewMaxYMargin]; |
- |
- // Need to check if a view is already attached since |label1_| is always |
- // parented and we don't want to add it again. |
- if (![control superview]) |
- [infoBarView_ addSubview:control]; |
- |
- if ([control isKindOfClass:[NSButton class]]) |
- VerticallyCenterView(control); |
- |
- // Make "from" and "to" language popup menus the same size as the options |
- // menu. |
- // We don't autosize since some languages names are really long causing |
- // the toolbar to overflow. |
- if ([control isKindOfClass:[NSPopUpButton class]]) |
- [control setFrame:optionsFrame]; |
- } |
-} |
- |
-- (void)layout { |
- if (state_ != TranslateInfoBarDelegate::kAfterTranslate) { |
- // 3rd label is only displayed in some locales, but should never be |
- // visible in this stage. |
- // If it ever is visible then we need to move it into position here. |
- DCHECK(numLabelsDisplayed_ < 3); |
- } |
- |
- switch (state_) { |
- case TranslateInfoBarDelegate::kBeforeTranslate: |
- MoveControl(label1_, fromLanguagePopUp_, 0, true); |
- MoveControl(fromLanguagePopUp_, label2_, 0, true); |
- |
- if (!translationPending_) { |
- MoveControl(label2_, okButton_, spaceBetweenControls_, true); |
- MoveControl(okButton_, cancelButton_, spaceBetweenControls_, true); |
- } else { |
- MoveControl(label2_, translatingLabel_, spaceBetweenControls_, true); |
- } |
- break; |
- |
- case TranslateInfoBarDelegate::kAfterTranslate: { |
- NSView* lastControl = toLanguagePopUp_; |
- MoveControl(label1_, fromLanguagePopUp_, 0, true); |
- MoveControl(fromLanguagePopUp_, label2_, 0, true); |
- MoveControl(label2_, toLanguagePopUp_, 0, true); |
- if (numLabelsDisplayed_ == 3) { |
- MoveControl(toLanguagePopUp_, label3_, 0, true); |
- lastControl = label3_; |
- } |
- |
- if (translationPending_) { |
- MoveControl(lastControl, translatingLabel_, spaceBetweenControls_ * 2, |
- true); |
- } else { |
- MoveControl(lastControl, showOriginalButton_, spaceBetweenControls_ * 2, |
- true); |
- } |
- |
- break; |
- } |
- |
- case TranslateInfoBarDelegate::kTranslateError: |
- if (translationPending_) { |
- MoveControl(label1_, translatingLabel_, 0, true); |
- } else { |
- MoveControl(label1_, tryAgainButton_, spaceBetweenControls_ * 2, true); |
- } |
- break; |
- |
- default: |
- NOTREACHED() << "Invalid translate infobar state"; |
- break; |
- } |
-} |
- |
-- (void) rebuildOptionsMenu { |
- // The options model doesn't know how to handle state transitions, so rebuild |
- // it each time through here. |
- options_menu_model_.reset( |
- new OptionsMenuModel(menu_model_.get(), [self delegate])); |
- |
- [optionsPopUp_ removeAllItems]; |
- // Set title. |
- NSString* optionsLabel = |
- l10n_util::GetNSString(IDS_TRANSLATE_INFOBAR_OPTIONS); |
- [optionsPopUp_ addItemWithTitle:optionsLabel]; |
- |
- // Populate options menu. |
- NSMenu* optionsMenu = [optionsPopUp_ menu]; |
- [optionsMenu setAutoenablesItems:NO]; |
- for (int i = 0; i < options_menu_model_->GetItemCount(); ++i) { |
- NSString* title = base::SysUTF16ToNSString( |
- options_menu_model_->GetLabelAt(i)); |
- int cmd = options_menu_model_->GetCommandIdAt(i); |
- bool checked = options_menu_model_->IsItemCheckedAt(i); |
- bool enabled = options_menu_model_->IsEnabledAt(i); |
- AddMenuItem(optionsMenu, self, title, cmd, enabled, checked); |
- } |
-} |
- |
-- (void)populateLanguageMenus { |
- NSMenu* originalLanguageMenu = [fromLanguagePopUp_ menu]; |
- [originalLanguageMenu setAutoenablesItems:NO]; |
- int selectedMenuIndex = 0; |
- int selectedLangIndex = [self delegate]->original_lang_index(); |
- for (int i = 0; i < original_language_menu_model_->GetItemCount(); ++i) { |
- NSString* title = base::SysUTF16ToNSString( |
- original_language_menu_model_->GetLabelAt(i)); |
- int cmd = original_language_menu_model_->GetCommandIdAt(i); |
- bool checked = |
- (cmd - IDC_TRANSLATE_ORIGINAL_LANGUAGE_BASE) == selectedLangIndex; |
- if (checked) |
- selectedMenuIndex = i; |
- bool enabled = original_language_menu_model_->IsEnabledAt(i); |
- AddMenuItem(originalLanguageMenu, self, title, cmd, enabled, checked); |
- } |
- [fromLanguagePopUp_ selectItemAtIndex:selectedMenuIndex]; |
- |
- NSMenu* targetLanguageMenu = [toLanguagePopUp_ menu]; |
- [targetLanguageMenu setAutoenablesItems:NO]; |
- selectedLangIndex = [self delegate]->target_lang_index(); |
- for (int i = 0; i < target_language_menu_model_->GetItemCount(); ++i) { |
- NSString* title = base::SysUTF16ToNSString( |
- target_language_menu_model_->GetLabelAt(i)); |
- int cmd = target_language_menu_model_->GetCommandIdAt(i); |
- bool checked = |
- (cmd - IDC_TRANSLATE_TARGET_LANGUAGE_BASE) == selectedLangIndex; |
- if (checked) |
- selectedMenuIndex = i; |
- bool enabled = target_language_menu_model_->IsEnabledAt(i); |
- AddMenuItem(targetLanguageMenu, self, title, cmd, enabled, checked); |
- } |
- [toLanguagePopUp_ selectItemAtIndex:selectedMenuIndex]; |
-} |
- |
-- (void)loadLabelText:(TranslateErrors::Type)error { |
- numLabelsDisplayed_ = 2; |
- |
- NSString* label1Text = @""; |
- NSString* label2Text = @""; |
- NSString* label3Text = @""; |
- |
- if (state_ == TranslateInfoBarDelegate::kTranslateError) { |
- // Load an error message, if an error occured and the user clicked |
- // "try again" then blank all labels. |
- if (!translationPending_) { |
- string16 message_text_utf16 = [self delegate]->GetErrorMessage(error); |
- label1Text = base::SysUTF16ToNSString(message_text_utf16); |
- } |
- } else { |
- string16 message_text_utf16; |
- std::vector<size_t> offsets; |
- [self delegate]->GetMessageText(state_, &message_text_utf16, |
- &offsets, &swappedLanguagePlaceholders_); |
- |
- NSString* message_text = base::SysUTF16ToNSString(message_text_utf16); |
- NSRange label1Range = NSMakeRange(0, offsets[0]); |
- label1Text = [message_text substringWithRange:label1Range]; |
- NSRange label2Range = NSMakeRange(offsets[0], |
- offsets[1] - offsets[0]); |
- label2Text = [message_text substringWithRange:label2Range]; |
- |
- // If this locale requires a 3rd label for the status message. |
- if (offsets.size() == 3) { |
- NSRange label3Range = NSMakeRange(offsets[1], |
- offsets[2] - offsets[1]); |
- label3Text = [message_text substringWithRange:label3Range]; |
- numLabelsDisplayed_ = 3; |
- } |
- } |
- |
- [label1_ setStringValue:label1Text]; |
- [label2_ setStringValue:label2Text]; |
- [label3_ setStringValue:label3Text]; |
-} |
- |
-- (void)addAdditionalControls { |
- using l10n_util::GetNSString; |
- using l10n_util::GetNSStringWithFixup; |
- |
- // Get layout information from the NIB. |
- NSRect okButtonFrame = [okButton_ frame]; |
- NSRect cancelButtonFrame = [cancelButton_ frame]; |
- spaceBetweenControls_ = NSMinX(cancelButtonFrame) - NSMaxX(okButtonFrame); |
- |
- // Set infobar background color. |
- [self setInfoBarGradientColor]; |
- |
- // Instantiate additional controls. |
- [self constructViews]; |
- |
- // Set ourselves as the delegate for the options menu so we can populate it |
- // dynamically. |
- [[optionsPopUp_ menu] setDelegate:self]; |
- |
- // Replace label_ with label1_ so we get a consistent look between all the |
- // labels we display in the translate view. |
- [[label_ superview] replaceSubview:label_ with:label1_.get()]; |
- label_.reset(); // Now released. |
- |
- // Populate contextual menus. |
- [self rebuildOptionsMenu]; |
- [self populateLanguageMenus]; |
- |
- // Set OK & Cancel text. |
- [okButton_ setTitle:GetNSStringWithFixup(IDS_TRANSLATE_INFOBAR_ACCEPT)]; |
- [cancelButton_ setTitle:GetNSStringWithFixup(IDS_TRANSLATE_INFOBAR_DENY)]; |
- [translatingLabel_ |
- setStringValue:GetNSString(IDS_TRANSLATE_INFOBAR_TRANSLATING)]; |
- |
- // Set up "Show original" and "Try again" buttons. |
- [showOriginalButton_ setBezelStyle:NSRoundRectBezelStyle]; |
- [showOriginalButton_ setFrame:okButtonFrame]; |
- [tryAgainButton_ setBezelStyle:NSRoundRectBezelStyle]; |
- [tryAgainButton_ setFrame:okButtonFrame]; |
- |
- [showOriginalButton_ setTarget:self]; |
- [showOriginalButton_ setAction:@selector(showOriginal:)]; |
- [tryAgainButton_ setTarget:self]; |
- [tryAgainButton_ setAction:@selector(ok:)]; |
- |
- [showOriginalButton_ |
- setTitle:GetNSStringWithFixup(IDS_TRANSLATE_INFOBAR_REVERT)]; |
- [tryAgainButton_ |
- setTitle:GetNSStringWithFixup(IDS_TRANSLATE_INFOBAR_RETRY)]; |
- |
- // Add and configure controls that are visible in all modes. |
- [optionsPopUp_ setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin | |
- NSViewMaxYMargin]; |
- // Add "options" popup z-ordered below all other controls so when we |
- // resize the toolbar it doesn't hide them. |
- [infoBarView_ addSubview:optionsPopUp_ |
- positioned:NSWindowBelow |
- relativeTo:nil]; |
- [GTMUILocalizerAndLayoutTweaker sizeToFitView:optionsPopUp_]; |
- MoveControl(closeButton_, optionsPopUp_, spaceBetweenControls_, false); |
- VerticallyCenterView(optionsPopUp_); |
- |
- // Show and place GUI elements. |
- TranslateInfoBarDelegate* delegate = [self delegate]; |
- [self updateState:delegate->state() |
- translationPending:delegate->translation_pending() |
- error:delegate->error_type()]; |
-} |
- |
-// Called when "Translate" button is clicked. |
-- (IBAction)ok:(id)sender { |
- TranslateInfoBarDelegate* delegate = [self delegate]; |
- TranslateInfoBarDelegate::TranslateState state = delegate->state(); |
- DCHECK(state == TranslateInfoBarDelegate::kBeforeTranslate || |
- state == TranslateInfoBarDelegate::kTranslateError); |
- delegate->Translate(); |
- [self updateState:state |
- translationPending:delegate->translation_pending() |
- error:delegate->error_type()]; |
- UMA_HISTOGRAM_COUNTS("Translate.Translate", 1); |
-} |
- |
-// Called when someone clicks on the "Nope" button. |
-- (IBAction)cancel:(id)sender { |
- DCHECK( |
- [self delegate]->state() == TranslateInfoBarDelegate::kBeforeTranslate); |
- [self delegate]->TranslationDeclined(); |
- UMA_HISTOGRAM_COUNTS("Translate.DeclineTranslate", 1); |
- [super dismiss:nil]; |
-} |
- |
-- (IBAction)showOriginal:(id)sender { |
- [self delegate]->RevertTranslation(); |
-} |
- |
-- (void)menuItemSelected:(id)item { |
- if ([item respondsToSelector:@selector(tag)]) { |
- int cmd = [item tag]; |
- // Danger Will Robinson! : This call can release the infobar (e.g. invoking |
- // "About Translate" can open a new tab). |
- // Do not access member variables after this line! |
- menu_model_->ExecuteCommand(cmd); |
- } else { |
- NOTREACHED(); |
- } |
-} |
- |
-#pragma mark NSMenuDelegate |
- |
-// Invoked by virtue of us being set as the delegate for the options menu. |
-- (void)menuNeedsUpdate:(NSMenu *)menu { |
- [self rebuildOptionsMenu]; |
-} |
- |
-#pragma mark TestingAPI |
-- (NSMenu*)optionsMenu { |
- return [optionsPopUp_ menu]; |
-} |
- |
-- (NSButton*)tryAgainButton { |
- return tryAgainButton_.get(); |
-} |
- |
-- (TranslateInfoBarDelegate::TranslateState)state { |
- return state_; |
-} |
- |
-- (bool)verifyLayout:(TranslateInfoBarDelegate::TranslateState)state |
- translationPending:(bool)translationPending { |
- NSArray* allControls = [NSArray arrayWithObjects:label1_.get(), label2_.get(), |
- label3_.get(), translatingLabel_.get(), fromLanguagePopUp_.get(), |
- toLanguagePopUp_.get(), optionsPopUp_.get(), closeButton_, |
- showOriginalButton_.get(), tryAgainButton_.get(), nil]; |
- |
- // Sanity check - parameters should match internal state. |
- if (state != state_) { |
- LOG(ERROR) << "State mismatch: " << state << " vs " << state_; |
- return false; |
- } |
- |
- if (translationPending != translationPending_) { |
- LOG(ERROR) << "Pending Translation mismatch: " << |
- translationPending << " vs " << translationPending_; |
- return false; |
- } |
- |
- // Array of all visible controls ordered from start -> end. |
- NSArray* visibleControls = nil; |
- |
- switch (state) { |
- case TranslateInfoBarDelegate::kBeforeTranslate: |
- if (translationPending) { |
- visibleControls = [NSArray arrayWithObjects:label1_.get(), |
- fromLanguagePopUp_.get(), label2_.get(), translatingLabel_.get(), |
- optionsPopUp_.get(), closeButton_, nil]; |
- } else { |
- visibleControls = [NSArray arrayWithObjects:label1_.get(), |
- fromLanguagePopUp_.get(), label2_.get(), optionsPopUp_.get(), |
- closeButton_, nil]; |
- } |
- break; |
- case TranslateInfoBarDelegate::kAfterTranslate: |
- if (translationPending) { |
- visibleControls = [NSArray arrayWithObjects:label1_.get(), |
- fromLanguagePopUp_.get(), label2_.get(), toLanguagePopUp_.get(), |
- translatingLabel_.get(), optionsPopUp_.get(), closeButton_, nil]; |
- } else { |
- visibleControls = [NSArray arrayWithObjects:label1_.get(), |
- fromLanguagePopUp_.get(), label2_.get(), toLanguagePopUp_.get(), |
- showOriginalButton_.get(), optionsPopUp_.get(), closeButton_, nil]; |
- } |
- break; |
- case TranslateInfoBarDelegate::kTranslateError: |
- if (translationPending) { |
- visibleControls = [NSArray arrayWithObjects:label1_.get(), |
- translatingLabel_.get(), closeButton_, nil]; |
- } else { |
- visibleControls = [NSArray arrayWithObjects:label1_.get(), |
- tryAgainButton_.get(), closeButton_, nil]; |
- } |
- break; |
- default: |
- NOTREACHED() << "Unknown state"; |
- return false; |
- } |
- |
- // Step 1: Make sure control visibility is what we expect. |
- for (NSUInteger i = 0; i < [allControls count]; ++i) { |
- id control = [allControls objectAtIndex:i]; |
- bool hasSuperView = [control superview]; |
- bool expectedVisibility = [visibleControls containsObject:control]; |
- |
- |
- // Special case the options popup, which we hide rather than removing |
- // from the superview. |
- if (control == optionsPopUp_.get()) |
- hasSuperView = [control isHidden] == NO; |
- |
- if (expectedVisibility != hasSuperView) { |
- NSString *title = @""; |
- |
- if ([control isKindOfClass:[NSPopUpButton class]]) { |
- title = [[[control menu] itemAtIndex:0] title]; |
- } |
- |
- LOG(ERROR) << |
- "State: " << state << " translationPending " << translationPending << |
- " Control @" << i << (hasSuperView ? " has" : " doesn't have") << |
- " a superview" << [[control description] UTF8String] << |
- " Title=" << [title UTF8String]; |
- return false; |
- } |
- } |
- |
- // Step 2: Check that controls are ordered correctly with no overlap. |
-#if !defined(DISABLE_VERIFY_CONTROL_ORDER) |
- // http://crbug.com/46663 this appears to be invalid. |
- // VerifyControlOrderAndSpacing had an unsigned >= 0 bug, so it used to always |
- // return true. With that bug fixed, this loop now can return a failure. |
- // Scanning the code, it's not clear how this would pass since not all |
- // controls are visible and it needs the array order to always match display |
- // order. |
- id previousControl = nil; |
- for (NSUInteger i = 0; i < [allControls count]; ++i) { |
- id control = [allControls objectAtIndex:i]; |
- if (!VerifyControlOrderAndSpacing(previousControl, control)) { |
- LOG(ERROR) << |
- "State: " << state << " translationPending " << translationPending << |
- " Control @" << i << " not ordered correctly: " << |
- [[control description] UTF8String]; |
- return false; |
- } |
- previousControl = control; |
- } |
-#endif // !defined(DISABLE_VERIFY_CONTROL_ORDER) |
- |
- // Step 3: Check other misc. attributes of layout. |
- if (state == TranslateInfoBarDelegate::kTranslateError && translationPending) |
- { |
- if ([[label1_ stringValue] length] != 0) { |
- LOG(ERROR) << "Expected empty label1_, instead got" << |
- [[label1_ description] UTF8String]; |
- return false; |
- } |
- } |
- |
- return true; |
-} |
- |
-@end |
- |
-#pragma mark CreateInfoBar implementation. |
-InfoBar* TranslateInfoBarDelegate::CreateInfoBar() { |
- TranslateInfoBarController* controller = |
- [[TranslateInfoBarController alloc] initWithDelegate:this]; |
- return new InfoBar(controller); |
-} |
- |
-#pragma mark menus::SimpleMenuModel::Delegates |
- |
-bool TranslateInfoBarMenuModel::IsCommandIdChecked(int command_id) const { |
- switch (command_id) { |
- case IDC_TRANSLATE_OPTIONS_NEVER_TRANSLATE_LANG : |
- return translate_delegate_->IsLanguageBlacklisted(); |
- |
- case IDC_TRANSLATE_OPTIONS_NEVER_TRANSLATE_SITE : |
- return translate_delegate_->IsSiteBlacklisted(); |
- |
- case IDC_TRANSLATE_OPTIONS_ALWAYS : |
- return translate_delegate_->ShouldAlwaysTranslate(); |
- |
- default: |
- NOTREACHED() << "Invalid command_id from menu"; |
- break; |
- } |
- return false; |
-} |
- |
-bool TranslateInfoBarMenuModel::IsCommandIdEnabled(int command_id) const { |
- switch (command_id) { |
- case IDC_TRANSLATE_OPTIONS_NEVER_TRANSLATE_LANG : |
- case IDC_TRANSLATE_OPTIONS_NEVER_TRANSLATE_SITE : |
- return !translate_delegate_->ShouldAlwaysTranslate(); |
- |
- case IDC_TRANSLATE_OPTIONS_ALWAYS : |
- return (!translate_delegate_->IsLanguageBlacklisted() && |
- !translate_delegate_->IsSiteBlacklisted()); |
- |
- default: |
- break; |
- } |
- return true; |
-} |
- |
-bool TranslateInfoBarMenuModel::GetAcceleratorForCommandId(int command_id, |
- menus::Accelerator* accelerator) { |
- return false; |
-} |
- |
-void TranslateInfoBarMenuModel::ExecuteCommand(int command_id) { |
- if (command_id >= IDC_TRANSLATE_TARGET_LANGUAGE_BASE) { |
- int language_command_id = |
- command_id - IDC_TRANSLATE_TARGET_LANGUAGE_BASE; |
- [controller_ |
- targetLanguageModified:language_command_id]; |
- } else if (command_id >= IDC_TRANSLATE_ORIGINAL_LANGUAGE_BASE) { |
- int language_command_id = |
- command_id - IDC_TRANSLATE_ORIGINAL_LANGUAGE_BASE; |
- [controller_ |
- sourceLanguageModified:language_command_id]; |
- } else { |
- switch (command_id) { |
- case IDC_TRANSLATE_OPTIONS_NEVER_TRANSLATE_LANG: |
- translate_delegate_->ToggleLanguageBlacklist(); |
- break; |
- |
- case IDC_TRANSLATE_OPTIONS_NEVER_TRANSLATE_SITE: |
- translate_delegate_->ToggleSiteBlacklist(); |
- break; |
- |
- case IDC_TRANSLATE_OPTIONS_ALWAYS: |
- translate_delegate_->ToggleAlwaysTranslate(); |
- break; |
- |
- case IDC_TRANSLATE_OPTIONS_ABOUT: { |
- TabContents* tab_contents = translate_delegate_->tab_contents(); |
- if (tab_contents) { |
- string16 url = l10n_util::GetStringUTF16( |
- IDS_ABOUT_GOOGLE_TRANSLATE_URL); |
- tab_contents->OpenURL(GURL(url), GURL(), NEW_FOREGROUND_TAB, |
- PageTransition::LINK); |
- } |
- break; |
- } |
- |
- default: |
- NOTREACHED() << "Invalid command id from menu."; |
- break; |
- } |
- } |
-} |
- |
-# pragma mark TranslateInfoBarNotificationObserverBridge |
- |
-TranslateNotificationObserverBridge::TranslateNotificationObserverBridge( |
- TranslateInfoBarDelegate* delegate, |
- TranslateInfoBarController* controller) : |
- translate_delegate_(delegate), |
- controller_(controller) { |
- // Register for PAGE_TRANSLATED notification. |
- notification_registrar_.Add(this, NotificationType::PAGE_TRANSLATED, |
- Source<TabContents>(translate_delegate_->tab_contents())); |
-}; |
- |
-void TranslateNotificationObserverBridge::Observe(NotificationType type, |
- const NotificationSource& source, const NotificationDetails& details) { |
- if (type.value != NotificationType::PAGE_TRANSLATED) |
- return; |
- TabContents* tab = Source<TabContents>(source).ptr(); |
- if (tab != translate_delegate_->tab_contents()) |
- return; |
- PageTranslatedDetails* page_translated_details = |
- Details<PageTranslatedDetails>(details).ptr(); |
- TranslateErrors::Type error = page_translated_details->error_type; |
- TranslateInfoBarDelegate::TranslateState newState = |
- TranslateInfoBarDelegate::kAfterTranslate; |
- if (page_translated_details->error_type != TranslateErrors::NONE) |
- newState = TranslateInfoBarDelegate::kTranslateError; |
- [controller_ updateState:newState translationPending:false error:error]; |
- |
-} |