Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2013 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/views/translate/translate_bubble_view.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 #include <string> | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "base/i18n/string_compare.h" | |
| 12 #include "base/memory/singleton.h" | |
| 13 #include "base/metrics/histogram.h" | |
| 14 #include "base/prefs/pref_service.h" | |
| 15 #include "base/strings/utf_string_conversions.h" | |
| 16 #include "chrome/browser/browser_process.h" | |
| 17 #include "chrome/browser/profiles/profile.h" | |
| 18 #include "chrome/browser/translate/translate_manager.h" | |
| 19 #include "chrome/browser/translate/translate_tab_helper.h" | |
| 20 #include "chrome/browser/translate/translate_ui_delegate.h" | |
| 21 #include "chrome/browser/ui/browser.h" | |
| 22 #include "chrome/browser/ui/translate/translate_bubble_model_impl.h" | |
| 23 #include "chrome/common/url_constants.h" | |
| 24 #include "content/public/browser/web_contents.h" | |
| 25 #include "grit/generated_resources.h" | |
| 26 #include "ui/base/l10n/l10n_util.h" | |
| 27 #include "ui/base/models/combobox_model.h" | |
| 28 #include "ui/base/resource/resource_bundle.h" | |
| 29 #include "ui/views/controls/button/checkbox.h" | |
| 30 #include "ui/views/controls/button/label_button.h" | |
| 31 #include "ui/views/controls/combobox/combobox.h" | |
| 32 #include "ui/views/controls/label.h" | |
| 33 #include "ui/views/controls/link.h" | |
| 34 #include "ui/views/layout/box_layout.h" | |
| 35 #include "ui/views/layout/grid_layout.h" | |
| 36 #include "ui/views/layout/layout_constants.h" | |
| 37 #include "ui/views/widget/widget.h" | |
| 38 | |
| 39 namespace { | |
| 40 | |
| 41 views::LabelButton* CreateLabelButton(views::ButtonListener* listener, | |
| 42 const string16& label, int id) { | |
| 43 views::LabelButton* button = new views::LabelButton(listener, label); | |
| 44 button->set_id(id); | |
| 45 button->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); | |
| 46 return button; | |
| 47 } | |
| 48 | |
| 49 views::Link* CreateLink(views::LinkListener* listener, | |
| 50 int resource_id, | |
| 51 int id) { | |
| 52 views::Link* link = new views::Link( | |
| 53 l10n_util::GetStringUTF16(resource_id)); | |
| 54 link->set_listener(listener); | |
| 55 link->set_id(id); | |
| 56 return link; | |
| 57 } | |
| 58 | |
| 59 void GetTranslateLanguages(content::WebContents* web_contents, | |
| 60 std::string* source, | |
| 61 std::string* target) { | |
| 62 DCHECK(source != NULL); | |
| 63 DCHECK(target != NULL); | |
| 64 | |
| 65 TranslateTabHelper* translate_tab_helper = | |
| 66 TranslateTabHelper::FromWebContents(web_contents); | |
| 67 if (!translate_tab_helper) | |
| 68 return; | |
| 69 | |
| 70 *source = translate_tab_helper->language_state().original_language(); | |
| 71 *target = g_browser_process->GetApplicationLocale(); | |
| 72 *target = TranslateManager::GetLanguageCode(*target); | |
| 73 } | |
| 74 | |
| 75 // TODO(hajimehoshi): The interface to offer denial choices should be another | |
| 76 // control instead of Combobox. See crbug/305494. | |
| 77 class TranslateDenialComboboxModel : public ui::ComboboxModel { | |
| 78 public: | |
| 79 enum { | |
| 80 INDEX_NOPE = 0, | |
| 81 INDEX_NEVER_TRANSLATE_LANGUAGE = 2, | |
| 82 INDEX_NEVER_TRANSLATE_SITE = 4, | |
| 83 }; | |
| 84 | |
| 85 explicit TranslateDenialComboboxModel( | |
| 86 const string16& original_language_name) { | |
| 87 items_.push_back(l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_DENY)); | |
| 88 items_.push_back(string16()); | |
| 89 items_.push_back(l10n_util::GetStringFUTF16( | |
| 90 IDS_TRANSLATE_BUBBLE_NEVER_TRANSLATE_LANG, | |
| 91 original_language_name)); | |
| 92 items_.push_back(string16()); | |
| 93 items_.push_back(l10n_util::GetStringUTF16( | |
| 94 IDS_TRANSLATE_BUBBLE_NEVER_TRANSLATE_SITE)); | |
| 95 } | |
| 96 virtual ~TranslateDenialComboboxModel() {} | |
| 97 | |
| 98 private: | |
| 99 // Overridden from ui::ComboboxModel: | |
| 100 virtual int GetItemCount() const OVERRIDE { | |
| 101 return items_.size(); | |
| 102 } | |
| 103 virtual string16 GetItemAt(int index) OVERRIDE { | |
| 104 return items_.at(index); | |
| 105 } | |
| 106 virtual bool IsItemSeparatorAt(int index) OVERRIDE { | |
| 107 return items_.at(index).empty(); | |
| 108 } | |
| 109 virtual int GetDefaultIndex() const OVERRIDE { | |
| 110 return 0; | |
| 111 } | |
| 112 | |
| 113 std::vector<string16> items_; | |
| 114 | |
| 115 DISALLOW_COPY_AND_ASSIGN(TranslateDenialComboboxModel); | |
| 116 }; | |
| 117 | |
| 118 const char* kUMATranslateModifyOriginalLang = "Translate.ModifyOriginalLang"; | |
| 119 const char* kUMATranslateModifyTargetLang = "Translate.ModifyTargetLang"; | |
| 120 | |
| 121 } // namespace | |
| 122 | |
| 123 TranslateBubbleView* TranslateBubbleView::translate_bubble_view_; | |
| 124 | |
| 125 // static | |
| 126 void TranslateBubbleView::ShowBubble(views::View* anchor_view, | |
| 127 content::WebContents* web_contents, | |
| 128 TranslateBubbleModel::ViewType type, | |
| 129 Browser* browser) { | |
| 130 if (IsShowing()) { | |
| 131 translate_bubble_view_->SwitchView(type); | |
| 132 return; | |
| 133 } | |
| 134 | |
| 135 std::string source_language; | |
| 136 std::string target_language; | |
| 137 GetTranslateLanguages(web_contents, &source_language, &target_language); | |
| 138 | |
| 139 scoped_ptr<TranslateUIDelegate> ui_delegate( | |
| 140 new TranslateUIDelegate(web_contents, source_language, target_language)); | |
| 141 scoped_ptr<TranslateBubbleModel> model( | |
| 142 new TranslateBubbleModelImpl(ui_delegate.Pass())); | |
| 143 bool is_in_incognito_window = | |
| 144 web_contents->GetBrowserContext()->IsOffTheRecord(); | |
| 145 TranslateBubbleView* view = new TranslateBubbleView(anchor_view, | |
| 146 model.Pass(), | |
| 147 type, | |
| 148 is_in_incognito_window, | |
| 149 browser); | |
| 150 views::BubbleDelegateView::CreateBubble(view)->Show(); | |
| 151 } | |
| 152 | |
| 153 // static | |
| 154 bool TranslateBubbleView::IsShowing() { | |
| 155 return translate_bubble_view_ != NULL; | |
| 156 } | |
| 157 | |
| 158 TranslateBubbleView::TranslateBubbleView( | |
| 159 views::View* anchor_view, | |
| 160 scoped_ptr<TranslateBubbleModel> model, | |
| 161 TranslateBubbleModel::ViewType type, | |
| 162 bool is_in_incognito_window, | |
| 163 Browser* browser) | |
| 164 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT), | |
| 165 source_language_combobox_(NULL), | |
| 166 target_language_combobox_(NULL), | |
| 167 always_translate_checkbox_(NULL), | |
| 168 model_(model.Pass()), | |
| 169 view_type_(type), | |
| 170 view_type_before_advanced_view_(type), | |
| 171 is_in_incognito_window_(is_in_incognito_window), | |
| 172 browser_(browser), | |
| 173 translate_executed_(false) { | |
| 174 // The initial view type must not be 'Advanced'. | |
| 175 DCHECK(view_type_ != TranslateBubbleModel::ADVANCED); | |
| 176 | |
| 177 if (view_type_ != TranslateBubbleModel::BEFORE_TRANSLATE) | |
| 178 translate_executed_ = true; | |
| 179 | |
| 180 set_margins(gfx::Insets(views::kPanelVertMargin, views::kPanelHorizMargin, | |
| 181 views::kPanelVertMargin, views::kPanelHorizMargin)); | |
| 182 | |
| 183 translate_bubble_view_ = this; | |
| 184 } | |
| 185 | |
| 186 TranslateBubbleView::~TranslateBubbleView() { | |
| 187 // A child view could refer to a model which is owned by this class when | |
| 188 // the child view is destructed. For example, |source_language_combobx_model_| | |
| 189 // is referred by Combobox's destructor. Before destroying the models, | |
| 190 // removing the child views is needed. | |
| 191 RemoveAllChildViews(true); | |
| 192 } | |
| 193 | |
| 194 void TranslateBubbleView::Init() { | |
| 195 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, | |
| 196 0, 0, 0)); | |
| 197 AddChildViewAt(CreateViewBeforeTranslate(), | |
| 198 TranslateBubbleModel::BEFORE_TRANSLATE); | |
| 199 AddChildViewAt(CreateViewTranslating(), | |
| 200 TranslateBubbleModel::TRANSLATING); | |
| 201 AddChildViewAt(CreateViewAfterTranslate(), | |
| 202 TranslateBubbleModel::AFTER_TRANSLATE); | |
| 203 AddChildViewAt(CreateViewError(), | |
| 204 TranslateBubbleModel::ERROR); | |
| 205 AddChildViewAt(CreateViewAdvanced(), | |
| 206 TranslateBubbleModel::ADVANCED); | |
| 207 | |
| 208 AddAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE)); | |
| 209 | |
| 210 UpdateChildVisibilities(); | |
| 211 } | |
| 212 | |
| 213 void TranslateBubbleView::ButtonPressed(views::Button* sender, | |
| 214 const ui::Event& event) { | |
| 215 HandleButtonPressed(sender->id()); | |
| 216 } | |
| 217 | |
| 218 void TranslateBubbleView::WindowClosing() { | |
| 219 if (!translate_executed_) | |
| 220 model_->TranslationDeclined(); | |
| 221 | |
| 222 // We have to reset |translate_bubble_view_| here, not in our destructor, | |
| 223 // because we'll be destroyed asynchronously and the shown state will be | |
| 224 // checked before then. | |
| 225 DCHECK_EQ(translate_bubble_view_, this); | |
| 226 translate_bubble_view_ = NULL; | |
| 227 } | |
| 228 | |
| 229 bool TranslateBubbleView::AcceleratorPressed( | |
| 230 const ui::Accelerator& accelerator) { | |
| 231 switch (view_type_) { | |
| 232 case TranslateBubbleModel::BEFORE_TRANSLATE: { | |
| 233 if (accelerator.key_code() == ui::VKEY_RETURN) { | |
| 234 HandleButtonPressed(BUTTON_ID_TRANSLATE); | |
| 235 return true; | |
| 236 } | |
| 237 break; | |
| 238 } | |
| 239 case TranslateBubbleModel::TRANSLATING: | |
| 240 break; | |
| 241 case TranslateBubbleModel::AFTER_TRANSLATE: { | |
| 242 if (accelerator.key_code() == ui::VKEY_RETURN) { | |
| 243 HandleButtonPressed(BUTTON_ID_SHOW_ORIGINAL); | |
| 244 return true; | |
| 245 } | |
| 246 break; | |
| 247 } | |
| 248 case TranslateBubbleModel::ERROR: | |
| 249 break; | |
| 250 case TranslateBubbleModel::ADVANCED: { | |
| 251 if (accelerator.key_code() == ui::VKEY_RETURN) { | |
| 252 HandleButtonPressed(BUTTON_ID_DONE); | |
| 253 return true; | |
| 254 } | |
| 255 break; | |
| 256 } | |
| 257 default: | |
| 258 NOTREACHED(); | |
| 259 break; | |
| 260 } | |
| 261 return BubbleDelegateView::AcceleratorPressed(accelerator); | |
| 262 } | |
| 263 | |
| 264 gfx::Size TranslateBubbleView::GetPreferredSize() { | |
| 265 int width = 0; | |
| 266 for (int i = 0; i < child_count(); i++) { | |
| 267 views::View* child = child_at(i); | |
| 268 width = std::max(width, child->GetPreferredSize().width()); | |
| 269 } | |
| 270 int height = child_at(view_type_)->GetPreferredSize().height(); | |
| 271 return gfx::Size(width, height); | |
| 272 } | |
| 273 | |
| 274 void TranslateBubbleView::OnSelectedIndexChanged(views::Combobox* combobox) { | |
| 275 switch (combobox->id()) { | |
| 276 case COMBOBOX_ID_DENIAL: { | |
| 277 int index = combobox->selected_index(); | |
| 278 switch (index) { | |
| 279 case TranslateDenialComboboxModel::INDEX_NOPE: | |
| 280 if (!translate_executed_) | |
| 281 model_->TranslationDeclined(); | |
| 282 StartFade(false); | |
| 283 break; | |
| 284 case TranslateDenialComboboxModel::INDEX_NEVER_TRANSLATE_LANGUAGE: | |
| 285 model_->SetLanguageBlocked(true); | |
| 286 StartFade(false); | |
| 287 break; | |
| 288 case TranslateDenialComboboxModel::INDEX_NEVER_TRANSLATE_SITE: | |
| 289 model_->SetSiteBlacklist(true); | |
| 290 StartFade(false); | |
| 291 break; | |
| 292 default: | |
| 293 NOTREACHED(); | |
| 294 break; | |
| 295 } | |
| 296 break; | |
| 297 } | |
| 298 case COMBOBOX_ID_SOURCE_LANGUAGE: { | |
| 299 // TODO(hajimehoshi): This UMA should be counted at a model or a delegate | |
| 300 // not to dependent on platforms. However, this UMA has not been used at | |
| 301 // some platforms. See crbug/306365. | |
| 302 UMA_HISTOGRAM_BOOLEAN(kUMATranslateModifyOriginalLang, true); | |
| 303 UpdateAdvancedView(); | |
| 304 break; | |
| 305 } | |
| 306 case COMBOBOX_ID_TARGET_LANGUAGE: { | |
| 307 // TODO(hajimehoshi): Ditto. | |
| 308 UMA_HISTOGRAM_BOOLEAN(kUMATranslateModifyTargetLang, true); | |
| 309 UpdateAdvancedView(); | |
| 310 break; | |
| 311 } | |
| 312 default: | |
| 313 NOTREACHED(); | |
| 314 break; | |
| 315 } | |
| 316 } | |
| 317 | |
| 318 void TranslateBubbleView::LinkClicked(views::Link* source, int event_flags) { | |
| 319 HandleLinkClicked(source->id()); | |
| 320 } | |
| 321 | |
| 322 void TranslateBubbleView::HandleButtonPressed(int sender_id) { | |
| 323 switch (sender_id) { | |
| 324 case BUTTON_ID_TRANSLATE: { | |
| 325 translate_executed_ = true; | |
| 326 model_->Translate(); | |
| 327 break; | |
| 328 } | |
| 329 case BUTTON_ID_DONE: { | |
| 330 translate_executed_ = true; | |
| 331 DCHECK(source_language_combobox_); | |
| 332 DCHECK(target_language_combobox_); | |
| 333 | |
| 334 model_->SetOriginalLanguageIndex( | |
| 335 source_language_combobox_->selected_index()); | |
| 336 model_->SetTargetLanguageIndex( | |
| 337 target_language_combobox_->selected_index()); | |
| 338 model_->Translate(); | |
| 339 break; | |
| 340 } | |
| 341 case BUTTON_ID_CANCEL: { | |
| 342 SwitchView(view_type_before_advanced_view_); | |
| 343 break; | |
| 344 } | |
| 345 case BUTTON_ID_TRY_AGAIN: { | |
| 346 translate_executed_ = true; | |
| 347 model_->Translate(); | |
| 348 break; | |
| 349 } | |
| 350 case BUTTON_ID_SHOW_ORIGINAL: { | |
| 351 model_->RevertTranslation(); | |
| 352 StartFade(false); | |
| 353 break; | |
| 354 } | |
| 355 case BUTTON_ID_ALWAYS_TRANSLATE: { | |
| 356 DCHECK(always_translate_checkbox_); | |
| 357 model_->SetAlwaysTranslate(always_translate_checkbox_->checked()); | |
| 358 UpdateAdvancedView(); | |
| 359 break; | |
| 360 } | |
| 361 default: | |
| 362 NOTREACHED(); | |
| 363 break; | |
| 364 } | |
| 365 } | |
| 366 | |
| 367 void TranslateBubbleView::HandleLinkClicked(int sender_id) { | |
| 368 switch (sender_id) { | |
| 369 case LINK_ID_ADVANCED: { | |
| 370 SwitchView(TranslateBubbleModel::ADVANCED); | |
| 371 break; | |
| 372 } | |
| 373 case LINK_ID_LEARN_MORE: { | |
| 374 browser_->OpenURL(content::OpenURLParams( | |
| 375 GURL(chrome::kAboutGoogleTranslateURL), | |
| 376 content::Referrer(), | |
| 377 NEW_FOREGROUND_TAB, | |
| 378 content::PAGE_TRANSITION_LINK, | |
| 379 false)); | |
| 380 break; | |
| 381 } | |
| 382 default: | |
| 383 NOTREACHED(); | |
| 384 break; | |
| 385 } | |
| 386 } | |
| 387 | |
| 388 void TranslateBubbleView::SwitchView(TranslateBubbleModel::ViewType view_type) { | |
| 389 if (view_type_ == view_type) | |
| 390 return; | |
| 391 | |
| 392 view_type_ = view_type; | |
| 393 if (view_type != TranslateBubbleModel::ADVANCED) | |
| 394 view_type_before_advanced_view_ = view_type; | |
| 395 | |
| 396 UpdateChildVisibilities(); | |
| 397 SizeToContents(); | |
| 398 } | |
| 399 | |
| 400 void TranslateBubbleView::UpdateChildVisibilities() { | |
| 401 for (int i = 0; i < child_count(); i++) { | |
| 402 views::View* view = child_at(i); | |
| 403 view->SetVisible(i == view_type_); | |
| 404 } | |
| 405 } | |
| 406 | |
| 407 views::View* TranslateBubbleView::CreateViewBeforeTranslate() { | |
| 408 views::Label* message_label = new views::Label( | |
| 409 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_BEFORE_TRANSLATE)); | |
| 410 | |
| 411 string16 original_language_name = | |
| 412 model_->GetLanguageNameAt(model_->GetOriginalLanguageIndex()); | |
| 413 views::Combobox* denial_combobox = new views::Combobox( | |
| 414 new TranslateDenialComboboxModel(original_language_name)); | |
| 415 denial_combobox->set_id(COMBOBOX_ID_DENIAL); | |
| 416 denial_combobox->set_listener(this); | |
| 417 | |
| 418 views::View* view = new views::View(); | |
| 419 views::GridLayout* layout = new views::GridLayout(view); | |
| 420 view->SetLayoutManager(layout); | |
| 421 | |
| 422 using views::GridLayout; | |
| 423 | |
| 424 enum { | |
| 425 COLUMN_SET_ID_MESSAGE, | |
| 426 COLUMN_SET_ID_CONTENT, | |
| 427 }; | |
| 428 | |
| 429 views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE); | |
| 430 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 431 0, GridLayout::USE_PREF, 0, 0); | |
| 432 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing); | |
| 433 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 434 0, GridLayout::USE_PREF, 0, 0); | |
| 435 cs->AddPaddingColumn(1, 0); | |
| 436 | |
| 437 cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT); | |
| 438 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 439 0, GridLayout::USE_PREF, 0, 0); | |
| 440 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing); | |
| 441 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 442 0, GridLayout::USE_PREF, 0, 0); | |
| 443 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing); | |
| 444 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 445 0, GridLayout::USE_PREF, 0, 0); | |
| 446 | |
| 447 layout->StartRow(0, COLUMN_SET_ID_MESSAGE); | |
| 448 layout->AddView(message_label); | |
| 449 layout->AddView(CreateLink(this, | |
| 450 IDS_TRANSLATE_BUBBLE_ADVANCED, | |
| 451 LINK_ID_ADVANCED)); | |
| 452 | |
| 453 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); | |
| 454 | |
| 455 layout->StartRow(0, COLUMN_SET_ID_CONTENT); | |
| 456 layout->AddView(CreateLink(this, | |
| 457 IDS_TRANSLATE_BUBBLE_LEARN_MORE, | |
| 458 LINK_ID_LEARN_MORE)); | |
| 459 layout->AddView(denial_combobox); | |
| 460 layout->AddView(CreateLabelButton( | |
| 461 this, | |
| 462 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_ACCEPT), | |
| 463 BUTTON_ID_TRANSLATE)); | |
| 464 | |
| 465 return view; | |
| 466 } | |
| 467 | |
| 468 views::View* TranslateBubbleView::CreateViewTranslating() { | |
| 469 string16 target_language_name = | |
| 470 model_->GetLanguageNameAt(model_->GetTargetLanguageIndex()); | |
| 471 views::Label* label = new views::Label( | |
| 472 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRANSLATING)); | |
| 473 | |
| 474 views::View* view = new views::View(); | |
| 475 views::GridLayout* layout = new views::GridLayout(view); | |
| 476 view->SetLayoutManager(layout); | |
| 477 | |
| 478 using views::GridLayout; | |
| 479 | |
| 480 enum { | |
| 481 COLUMN_SET_ID_MESSAGE, | |
| 482 COLUMN_SET_ID_CONTENT, | |
| 483 }; | |
| 484 | |
| 485 views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE); | |
| 486 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 487 0, views::GridLayout::USE_PREF, 0, 0); | |
| 488 cs->AddPaddingColumn(1, 0); | |
| 489 | |
| 490 cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT); | |
| 491 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 492 0, GridLayout::USE_PREF, 0, 0); | |
| 493 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing); | |
| 494 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 495 0, GridLayout::USE_PREF, 0, 0); | |
| 496 | |
| 497 layout->StartRow(0, COLUMN_SET_ID_MESSAGE); | |
| 498 layout->AddView(label); | |
| 499 | |
| 500 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); | |
| 501 | |
| 502 layout->StartRow(0, COLUMN_SET_ID_CONTENT); | |
| 503 layout->AddView(CreateLink(this, | |
| 504 IDS_TRANSLATE_BUBBLE_LEARN_MORE, | |
| 505 LINK_ID_LEARN_MORE)); | |
| 506 views::LabelButton* revert_button = CreateLabelButton( | |
| 507 this, | |
| 508 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_REVERT), | |
| 509 BUTTON_ID_SHOW_ORIGINAL); | |
| 510 revert_button->SetEnabled(false); | |
| 511 layout->AddView(revert_button); | |
| 512 | |
| 513 return view; | |
| 514 } | |
| 515 | |
| 516 views::View* TranslateBubbleView::CreateViewAfterTranslate() { | |
|
Takashi Toyoshima
2013/10/14 23:29:34
Don't you show source and target translation langu
hajimehoshi
2013/10/15 04:14:16
No. I think it is intended because the user can se
| |
| 517 views::Label* label = new views::Label( | |
| 518 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRANSLATED)); | |
| 519 | |
| 520 views::View* view = new views::View(); | |
| 521 views::GridLayout* layout = new views::GridLayout(view); | |
| 522 view->SetLayoutManager(layout); | |
| 523 | |
| 524 using views::GridLayout; | |
| 525 | |
| 526 enum { | |
| 527 COLUMN_SET_ID_MESSAGE, | |
| 528 COLUMN_SET_ID_CONTENT, | |
| 529 }; | |
| 530 | |
| 531 views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE); | |
| 532 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 533 0, views::GridLayout::USE_PREF, 0, 0); | |
| 534 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing); | |
| 535 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 536 0, views::GridLayout::USE_PREF, 0, 0); | |
| 537 cs->AddPaddingColumn(1, 0); | |
| 538 | |
| 539 cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT); | |
| 540 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 541 0, GridLayout::USE_PREF, 0, 0); | |
| 542 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing); | |
| 543 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 544 0, GridLayout::USE_PREF, 0, 0); | |
| 545 | |
| 546 layout->StartRow(0, COLUMN_SET_ID_MESSAGE); | |
| 547 layout->AddView(label); | |
| 548 layout->AddView(CreateLink(this, | |
| 549 IDS_TRANSLATE_BUBBLE_ADVANCED, | |
| 550 LINK_ID_ADVANCED)); | |
| 551 | |
| 552 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); | |
| 553 | |
| 554 layout->StartRow(0, COLUMN_SET_ID_CONTENT); | |
| 555 layout->AddView(CreateLink(this, | |
| 556 IDS_TRANSLATE_BUBBLE_LEARN_MORE, | |
| 557 LINK_ID_LEARN_MORE)); | |
| 558 layout->AddView(CreateLabelButton( | |
| 559 this, | |
| 560 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_REVERT), | |
| 561 BUTTON_ID_SHOW_ORIGINAL)); | |
| 562 | |
| 563 return view; | |
| 564 } | |
| 565 | |
| 566 views::View* TranslateBubbleView::CreateViewError() { | |
|
Takashi Toyoshima
2013/10/14 23:29:34
Currently, only one generic message is used for al
hajimehoshi
2013/10/15 04:14:16
Done.
| |
| 567 views::Label* label = new views::Label( | |
| 568 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_COULD_NOT_TRANSLATE)); | |
| 569 | |
| 570 views::View* view = new views::View(); | |
| 571 views::GridLayout* layout = new views::GridLayout(view); | |
| 572 view->SetLayoutManager(layout); | |
| 573 | |
| 574 using views::GridLayout; | |
| 575 | |
| 576 enum { | |
| 577 COLUMN_SET_ID_MESSAGE, | |
| 578 COLUMN_SET_ID_CONTENT, | |
| 579 }; | |
| 580 | |
| 581 views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_MESSAGE); | |
| 582 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 583 0, GridLayout::USE_PREF, 0, 0); | |
| 584 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing); | |
| 585 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 586 0, GridLayout::USE_PREF, 0, 0); | |
| 587 cs->AddPaddingColumn(1, 0); | |
| 588 | |
| 589 cs = layout->AddColumnSet(COLUMN_SET_ID_CONTENT); | |
| 590 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 591 0, GridLayout::USE_PREF, 0, 0); | |
| 592 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing); | |
| 593 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 594 0, GridLayout::USE_PREF, 0, 0); | |
| 595 | |
| 596 layout->StartRow(0, COLUMN_SET_ID_MESSAGE); | |
| 597 layout->AddView(label); | |
| 598 layout->AddView(CreateLink(this, | |
| 599 IDS_TRANSLATE_BUBBLE_ADVANCED, | |
| 600 LINK_ID_ADVANCED)); | |
| 601 | |
| 602 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); | |
| 603 | |
| 604 layout->StartRow(0, COLUMN_SET_ID_CONTENT); | |
| 605 layout->AddView(CreateLink(this, | |
| 606 IDS_TRANSLATE_BUBBLE_LEARN_MORE, | |
| 607 LINK_ID_LEARN_MORE)); | |
| 608 layout->AddView(CreateLabelButton( | |
| 609 this, | |
| 610 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRY_AGAIN), | |
| 611 BUTTON_ID_TRY_AGAIN)); | |
| 612 | |
| 613 return view; | |
| 614 } | |
| 615 | |
| 616 views::View* TranslateBubbleView::CreateViewAdvanced() { | |
| 617 views::Label* source_language_label = new views::Label( | |
| 618 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_PAGE_LANGUAGE)); | |
| 619 | |
| 620 views::Label* target_language_label = new views::Label( | |
| 621 l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_TRANSLATION_LANGUAGE)); | |
| 622 | |
| 623 int source_default_index = model_->GetOriginalLanguageIndex(); | |
| 624 source_language_combobox_model_.reset( | |
| 625 new LanguageComboboxModel(source_default_index, model_.get())); | |
| 626 source_language_combobox_ = | |
| 627 new views::Combobox(source_language_combobox_model_.get()); | |
| 628 | |
| 629 source_language_combobox_->set_id(COMBOBOX_ID_SOURCE_LANGUAGE); | |
| 630 source_language_combobox_->set_listener(this); | |
| 631 | |
| 632 int target_default_index = model_->GetTargetLanguageIndex(); | |
| 633 target_language_combobox_model_.reset( | |
| 634 new LanguageComboboxModel(target_default_index, model_.get())); | |
| 635 target_language_combobox_ = | |
| 636 new views::Combobox(target_language_combobox_model_.get()); | |
| 637 | |
| 638 target_language_combobox_->set_id(COMBOBOX_ID_TARGET_LANGUAGE); | |
| 639 target_language_combobox_->set_listener(this); | |
| 640 | |
| 641 // In an incognito window, "Always translate" checkbox shouldn't be shown. | |
| 642 if (!is_in_incognito_window_) { | |
| 643 always_translate_checkbox_ = new views::Checkbox(string16()); | |
| 644 always_translate_checkbox_->set_id(BUTTON_ID_ALWAYS_TRANSLATE); | |
| 645 always_translate_checkbox_->set_listener(this); | |
| 646 } | |
| 647 | |
| 648 views::View* view = new views::View(); | |
| 649 views::GridLayout* layout = new views::GridLayout(view); | |
| 650 view->SetLayoutManager(layout); | |
| 651 | |
| 652 using views::GridLayout; | |
| 653 | |
| 654 enum { | |
| 655 COLUMN_SET_ID_LANGUAGES, | |
| 656 COLUMN_SET_ID_ALWAYS_TRANSLATE, | |
| 657 COLUMN_SET_ID_BUTTONS, | |
| 658 }; | |
| 659 | |
| 660 views::ColumnSet* cs = layout->AddColumnSet(COLUMN_SET_ID_LANGUAGES); | |
| 661 cs->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, | |
| 662 0, GridLayout::USE_PREF, 0, 0); | |
| 663 cs->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); | |
| 664 cs->AddColumn(GridLayout::FILL, GridLayout::CENTER, | |
| 665 0, GridLayout::USE_PREF, 0, 0); | |
| 666 cs->AddPaddingColumn(1, 0); | |
| 667 | |
| 668 if (!is_in_incognito_window_) { | |
| 669 cs = layout->AddColumnSet(COLUMN_SET_ID_ALWAYS_TRANSLATE); | |
| 670 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 671 0, GridLayout::USE_PREF, 0, 0); | |
| 672 cs->AddPaddingColumn(1, 0); | |
| 673 } | |
| 674 | |
| 675 cs = layout->AddColumnSet(COLUMN_SET_ID_BUTTONS); | |
| 676 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 677 0, GridLayout::USE_PREF, 0, 0); | |
| 678 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing); | |
| 679 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 680 0, GridLayout::USE_PREF, 0, 0); | |
| 681 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing); | |
| 682 cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, | |
| 683 0, GridLayout::USE_PREF, 0, 0); | |
| 684 | |
| 685 layout->StartRow(0, COLUMN_SET_ID_LANGUAGES); | |
| 686 layout->AddView(source_language_label); | |
| 687 layout->AddView(source_language_combobox_); | |
| 688 | |
| 689 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
| 690 | |
| 691 layout->StartRow(0, COLUMN_SET_ID_LANGUAGES); | |
| 692 layout->AddView(target_language_label); | |
| 693 layout->AddView(target_language_combobox_); | |
| 694 | |
| 695 if (!is_in_incognito_window_) { | |
| 696 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); | |
| 697 | |
| 698 layout->StartRow(0, COLUMN_SET_ID_ALWAYS_TRANSLATE); | |
| 699 layout->AddView(always_translate_checkbox_); | |
| 700 } | |
| 701 | |
| 702 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); | |
| 703 | |
| 704 layout->StartRow(0, COLUMN_SET_ID_BUTTONS); | |
| 705 layout->AddView(CreateLink(this, | |
| 706 IDS_TRANSLATE_BUBBLE_LEARN_MORE, | |
| 707 LINK_ID_LEARN_MORE)); | |
| 708 views::LabelButton* cancel_button = CreateLabelButton( | |
| 709 this, l10n_util::GetStringUTF16(IDS_CANCEL), BUTTON_ID_CANCEL); | |
| 710 layout->AddView(cancel_button); | |
| 711 views::LabelButton* done_button = CreateLabelButton( | |
| 712 this, l10n_util::GetStringUTF16(IDS_DONE), BUTTON_ID_DONE); | |
| 713 done_button->SetIsDefault(true); | |
| 714 layout->AddView(done_button); | |
| 715 | |
| 716 UpdateAdvancedView(); | |
| 717 | |
| 718 return view; | |
| 719 } | |
| 720 | |
| 721 void TranslateBubbleView::UpdateAdvancedView() { | |
| 722 DCHECK(source_language_combobox_); | |
| 723 DCHECK(target_language_combobox_); | |
| 724 | |
| 725 model_->SetOriginalLanguageIndex( | |
| 726 source_language_combobox_->selected_index()); | |
| 727 model_->SetTargetLanguageIndex( | |
| 728 target_language_combobox_->selected_index()); | |
| 729 | |
| 730 string16 source_language_name = | |
| 731 model_->GetLanguageNameAt(model_->GetOriginalLanguageIndex()); | |
| 732 string16 target_language_name = | |
| 733 model_->GetLanguageNameAt(model_->GetTargetLanguageIndex()); | |
| 734 | |
| 735 string16 message = | |
| 736 l10n_util::GetStringFUTF16(IDS_TRANSLATE_BUBBLE_ALWAYS, | |
| 737 source_language_name, | |
| 738 target_language_name); | |
| 739 // "Always translate" checkbox doesn't exist in an incognito window. | |
| 740 if (always_translate_checkbox_) { | |
| 741 always_translate_checkbox_->SetText(message); | |
| 742 always_translate_checkbox_->SetChecked( | |
| 743 model_->ShouldAlwaysTranslate()); | |
| 744 } | |
| 745 } | |
| OLD | NEW |