| 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];
|
| -
|
| -}
|
|
|