| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/views/extensions/extension_message_bubble_view.h" | 5 #include "chrome/browser/ui/views/extensions/extension_message_bubble_view.h" |
| 6 | 6 |
| 7 #include "base/strings/string_number_conversions.h" | 7 #include "base/strings/string_number_conversions.h" |
| 8 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
| 9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "chrome/browser/extensions/dev_mode_bubble_controller.h" | 10 #include "chrome/browser/extensions/dev_mode_bubble_controller.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 | 47 |
| 48 } // namespace | 48 } // namespace |
| 49 | 49 |
| 50 //////////////////////////////////////////////////////////////////////////////// | 50 //////////////////////////////////////////////////////////////////////////////// |
| 51 // ExtensionMessageBubbleView | 51 // ExtensionMessageBubbleView |
| 52 | 52 |
| 53 namespace extensions { | 53 namespace extensions { |
| 54 | 54 |
| 55 ExtensionMessageBubbleView::ExtensionMessageBubbleView( | 55 ExtensionMessageBubbleView::ExtensionMessageBubbleView( |
| 56 views::View* anchor_view, | 56 views::View* anchor_view, |
| 57 ExtensionMessageBubbleController::Delegate* delegate) | 57 scoped_ptr<ExtensionMessageBubbleController> controller) |
| 58 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT), | 58 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT), |
| 59 weak_factory_(this), | 59 weak_factory_(this), |
| 60 delegate_(delegate), | 60 controller_(controller.Pass()), |
| 61 headline_(NULL), | 61 headline_(NULL), |
| 62 learn_more_(NULL), | 62 learn_more_(NULL), |
| 63 dismiss_button_(NULL), | 63 dismiss_button_(NULL), |
| 64 link_clicked_(false), | 64 link_clicked_(false), |
| 65 action_taken_(false) { | 65 action_taken_(false) { |
| 66 DCHECK(anchor_view->GetWidget()); | 66 DCHECK(anchor_view->GetWidget()); |
| 67 set_close_on_deactivate(false); | 67 set_close_on_deactivate(false); |
| 68 set_move_with_anchor(true); | 68 set_move_with_anchor(true); |
| 69 set_close_on_esc(true); | 69 set_close_on_esc(true); |
| 70 | 70 |
| 71 // Compensate for built-in vertical padding in the anchor view's image. | 71 // Compensate for built-in vertical padding in the anchor view's image. |
| 72 set_anchor_view_insets(gfx::Insets(5, 0, 5, 0)); | 72 set_anchor_view_insets(gfx::Insets(5, 0, 5, 0)); |
| 73 } | 73 } |
| 74 | 74 |
| 75 // static | 75 // static |
| 76 void ExtensionMessageBubbleView::MaybeShow( | 76 void ExtensionMessageBubbleView::MaybeShow( |
| 77 Browser* browser, | 77 Browser* browser, |
| 78 ToolbarView* toolbar_view, | 78 ToolbarView* toolbar_view, |
| 79 views::View* anchor_view) { | 79 views::View* anchor_view) { |
| 80 #if defined(OS_WIN) | 80 #if defined(OS_WIN) |
| 81 // The list of suspicious extensions takes priority over the dev mode bubble, | 81 // The list of suspicious extensions takes priority over the dev mode bubble, |
| 82 // since that needs to be shown as soon as we disable something. The dev mode | 82 // since that needs to be shown as soon as we disable something. The dev mode |
| 83 // bubble is not as time sensitive so we'll catch the dev mode extensions on | 83 // bubble is not as time sensitive so we'll catch the dev mode extensions on |
| 84 // the next startup/next window that opens. That way, we're not too spammy | 84 // the next startup/next window that opens. That way, we're not too spammy |
| 85 // with the bubbles. | 85 // with the bubbles. |
| 86 SuspiciousExtensionBubbleController* suspicious_extensions = | 86 scoped_ptr<SuspiciousExtensionBubbleController> suspicious_extensions( |
| 87 extensions::SuspiciousExtensionBubbleController::Get( | 87 new SuspiciousExtensionBubbleController(browser->profile())); |
| 88 browser->profile()); | |
| 89 if (suspicious_extensions->ShouldShow()) { | 88 if (suspicious_extensions->ShouldShow()) { |
| 89 SuspiciousExtensionBubbleController* controller = |
| 90 suspicious_extensions.get(); |
| 90 ExtensionMessageBubbleView* bubble_delegate = | 91 ExtensionMessageBubbleView* bubble_delegate = |
| 91 new ExtensionMessageBubbleView(anchor_view, suspicious_extensions); | 92 new ExtensionMessageBubbleView(anchor_view, |
| 93 suspicious_extensions.Pass()); |
| 92 views::BubbleDelegateView::CreateBubble(bubble_delegate); | 94 views::BubbleDelegateView::CreateBubble(bubble_delegate); |
| 93 suspicious_extensions->Show(bubble_delegate); | 95 controller->Show(bubble_delegate); |
| 94 return; | 96 return; |
| 95 } | 97 } |
| 96 | 98 |
| 97 DevModeBubbleController* dev_mode_extensions = | 99 scoped_ptr<DevModeBubbleController> dev_mode_extensions( |
| 98 extensions::DevModeBubbleController::Get( | 100 new DevModeBubbleController(browser->profile())); |
| 99 browser->profile()); | |
| 100 if (dev_mode_extensions->ShouldShow()) { | 101 if (dev_mode_extensions->ShouldShow()) { |
| 101 views::View* reference_view = NULL; | 102 views::View* reference_view = NULL; |
| 102 BrowserActionsContainer* container = toolbar_view->browser_actions(); | 103 BrowserActionsContainer* container = toolbar_view->browser_actions(); |
| 103 if (container->animating()) | 104 if (container->animating()) |
| 104 return; | 105 return; |
| 105 | 106 |
| 106 ExtensionService* service = extensions::ExtensionSystem::Get( | 107 ExtensionService* service = extensions::ExtensionSystem::Get( |
| 107 browser->profile())->extension_service(); | 108 browser->profile())->extension_service(); |
| 108 extensions::ExtensionActionManager* extension_action_manager = | 109 extensions::ExtensionActionManager* extension_action_manager = |
| 109 extensions::ExtensionActionManager::Get(browser->profile()); | 110 extensions::ExtensionActionManager::Get(browser->profile()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 124 } | 125 } |
| 125 if (reference_view) { | 126 if (reference_view) { |
| 126 // If we have a view, it means we found a browser action and we want to | 127 // If we have a view, it means we found a browser action and we want to |
| 127 // point to the chevron, not the hotdog menu. | 128 // point to the chevron, not the hotdog menu. |
| 128 if (!reference_view->visible()) | 129 if (!reference_view->visible()) |
| 129 reference_view = container->chevron(); // It's hidden, use the chevron. | 130 reference_view = container->chevron(); // It's hidden, use the chevron. |
| 130 } | 131 } |
| 131 if (reference_view && reference_view->visible()) | 132 if (reference_view && reference_view->visible()) |
| 132 anchor_view = reference_view; // Catch-all is the hotdog menu. | 133 anchor_view = reference_view; // Catch-all is the hotdog menu. |
| 133 | 134 |
| 134 // Show the bubble. | 135 DevModeBubbleController* controller = dev_mode_extensions.get(); |
| 135 ExtensionMessageBubbleView* bubble_delegate = | 136 ExtensionMessageBubbleView* bubble_delegate = |
| 136 new ExtensionMessageBubbleView(anchor_view, dev_mode_extensions); | 137 new ExtensionMessageBubbleView(anchor_view, dev_mode_extensions.Pass()); |
| 137 views::BubbleDelegateView::CreateBubble(bubble_delegate); | 138 views::BubbleDelegateView::CreateBubble(bubble_delegate); |
| 138 dev_mode_extensions->Show(bubble_delegate); | 139 controller->Show(bubble_delegate); |
| 139 } | 140 } |
| 140 #endif | 141 #endif |
| 141 } | 142 } |
| 142 | 143 |
| 143 void ExtensionMessageBubbleView::OnActionButtonClicked( | 144 void ExtensionMessageBubbleView::OnActionButtonClicked( |
| 144 const base::Closure& callback) { | 145 const base::Closure& callback) { |
| 145 action_callback_ = callback; | 146 action_callback_ = callback; |
| 146 } | 147 } |
| 147 | 148 |
| 148 void ExtensionMessageBubbleView::OnDismissButtonClicked( | 149 void ExtensionMessageBubbleView::OnDismissButtonClicked( |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 } | 190 } |
| 190 | 191 |
| 191 void ExtensionMessageBubbleView::Init() { | 192 void ExtensionMessageBubbleView::Init() { |
| 192 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 193 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 193 | 194 |
| 194 views::GridLayout* layout = views::GridLayout::CreatePanel(this); | 195 views::GridLayout* layout = views::GridLayout::CreatePanel(this); |
| 195 layout->SetInsets(kInsetTop, kInsetLeft, | 196 layout->SetInsets(kInsetTop, kInsetLeft, |
| 196 kInsetBottomRight, kInsetBottomRight); | 197 kInsetBottomRight, kInsetBottomRight); |
| 197 SetLayoutManager(layout); | 198 SetLayoutManager(layout); |
| 198 | 199 |
| 200 ExtensionMessageBubbleController::Delegate* delegate = |
| 201 controller_->delegate(); |
| 202 |
| 199 const int headline_column_set_id = 0; | 203 const int headline_column_set_id = 0; |
| 200 views::ColumnSet* top_columns = layout->AddColumnSet(headline_column_set_id); | 204 views::ColumnSet* top_columns = layout->AddColumnSet(headline_column_set_id); |
| 201 top_columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, | 205 top_columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, |
| 202 0, views::GridLayout::USE_PREF, 0, 0); | 206 0, views::GridLayout::USE_PREF, 0, 0); |
| 203 top_columns->AddPaddingColumn(1, 0); | 207 top_columns->AddPaddingColumn(1, 0); |
| 204 layout->StartRow(0, headline_column_set_id); | 208 layout->StartRow(0, headline_column_set_id); |
| 205 | 209 |
| 206 headline_ = new views::Label(delegate_->GetTitle(), | 210 headline_ = new views::Label(delegate->GetTitle(), |
| 207 rb.GetFontList(ui::ResourceBundle::MediumFont)); | 211 rb.GetFontList(ui::ResourceBundle::MediumFont)); |
| 208 layout->AddView(headline_); | 212 layout->AddView(headline_); |
| 209 | 213 |
| 210 layout->AddPaddingRow(0, kHeadlineRowPadding); | 214 layout->AddPaddingRow(0, kHeadlineRowPadding); |
| 211 | 215 |
| 212 const int text_column_set_id = 1; | 216 const int text_column_set_id = 1; |
| 213 views::ColumnSet* upper_columns = layout->AddColumnSet(text_column_set_id); | 217 views::ColumnSet* upper_columns = layout->AddColumnSet(text_column_set_id); |
| 214 upper_columns->AddColumn( | 218 upper_columns->AddColumn( |
| 215 views::GridLayout::LEADING, views::GridLayout::LEADING, | 219 views::GridLayout::LEADING, views::GridLayout::LEADING, |
| 216 0, views::GridLayout::USE_PREF, 0, 0); | 220 0, views::GridLayout::USE_PREF, 0, 0); |
| 217 layout->StartRow(0, text_column_set_id); | 221 layout->StartRow(0, text_column_set_id); |
| 218 | 222 |
| 219 views::Label* message = new views::Label(); | 223 views::Label* message = new views::Label(); |
| 220 message->SetMultiLine(true); | 224 message->SetMultiLine(true); |
| 221 message->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 225 message->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 222 message->SetText(delegate_->GetMessageBody()); | 226 message->SetText(delegate->GetMessageBody()); |
| 223 message->SizeToFit(views::Widget::GetLocalizedContentsWidth( | 227 message->SizeToFit(views::Widget::GetLocalizedContentsWidth( |
| 224 IDS_EXTENSION_WIPEOUT_BUBBLE_WIDTH_CHARS)); | 228 IDS_EXTENSION_WIPEOUT_BUBBLE_WIDTH_CHARS)); |
| 225 layout->AddView(message); | 229 layout->AddView(message); |
| 226 | 230 |
| 227 if (delegate_->ShouldShowExtensionList()) { | 231 if (delegate->ShouldShowExtensionList()) { |
| 228 const int extension_list_column_set_id = 2; | 232 const int extension_list_column_set_id = 2; |
| 229 views::ColumnSet* middle_columns = | 233 views::ColumnSet* middle_columns = |
| 230 layout->AddColumnSet(extension_list_column_set_id); | 234 layout->AddColumnSet(extension_list_column_set_id); |
| 231 middle_columns->AddPaddingColumn(0, kExtensionListPadding); | 235 middle_columns->AddPaddingColumn(0, kExtensionListPadding); |
| 232 middle_columns->AddColumn( | 236 middle_columns->AddColumn( |
| 233 views::GridLayout::LEADING, views::GridLayout::CENTER, | 237 views::GridLayout::LEADING, views::GridLayout::CENTER, |
| 234 0, views::GridLayout::USE_PREF, 0, 0); | 238 0, views::GridLayout::USE_PREF, 0, 0); |
| 235 | 239 |
| 236 layout->StartRowWithPadding(0, extension_list_column_set_id, | 240 layout->StartRowWithPadding(0, extension_list_column_set_id, |
| 237 0, kHeadlineMessagePadding); | 241 0, kHeadlineMessagePadding); |
| 238 views::Label* extensions = new views::Label(); | 242 views::Label* extensions = new views::Label(); |
| 239 extensions->SetMultiLine(true); | 243 extensions->SetMultiLine(true); |
| 240 extensions->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 244 extensions->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 241 | 245 |
| 242 std::vector<base::string16> extension_list; | 246 std::vector<base::string16> extension_list; |
| 243 base::char16 bullet_point = 0x2022; | 247 base::char16 bullet_point = 0x2022; |
| 244 | 248 |
| 245 std::vector<base::string16> suspicious = delegate_->GetExtensions(); | 249 std::vector<base::string16> suspicious = controller_->GetExtensionList(); |
| 246 size_t i = 0; | 250 size_t i = 0; |
| 247 for (; i < suspicious.size() && i < kMaxExtensionsToShow; ++i) { | 251 for (; i < suspicious.size() && i < kMaxExtensionsToShow; ++i) { |
| 248 // Add each extension with bullet point. | 252 // Add each extension with bullet point. |
| 249 extension_list.push_back( | 253 extension_list.push_back( |
| 250 bullet_point + base::ASCIIToUTF16(" ") + suspicious[i]); | 254 bullet_point + base::ASCIIToUTF16(" ") + suspicious[i]); |
| 251 } | 255 } |
| 252 | 256 |
| 253 if (i > kMaxExtensionsToShow) { | 257 if (i > kMaxExtensionsToShow) { |
| 254 base::string16 difference = base::IntToString16(i - kMaxExtensionsToShow); | 258 base::string16 difference = base::IntToString16(i - kMaxExtensionsToShow); |
| 255 extension_list.push_back(bullet_point + base::ASCIIToUTF16(" ") + | 259 extension_list.push_back(bullet_point + base::ASCIIToUTF16(" ") + |
| 256 delegate_->GetOverflowText(difference)); | 260 delegate->GetOverflowText(difference)); |
| 257 } | 261 } |
| 258 | 262 |
| 259 extensions->SetText(JoinString(extension_list, base::ASCIIToUTF16("\n"))); | 263 extensions->SetText(JoinString(extension_list, base::ASCIIToUTF16("\n"))); |
| 260 extensions->SizeToFit(views::Widget::GetLocalizedContentsWidth( | 264 extensions->SizeToFit(views::Widget::GetLocalizedContentsWidth( |
| 261 IDS_EXTENSION_WIPEOUT_BUBBLE_WIDTH_CHARS)); | 265 IDS_EXTENSION_WIPEOUT_BUBBLE_WIDTH_CHARS)); |
| 262 layout->AddView(extensions); | 266 layout->AddView(extensions); |
| 263 } | 267 } |
| 264 | 268 |
| 265 base::string16 action_button = delegate_->GetActionButtonLabel(); | 269 base::string16 action_button = delegate->GetActionButtonLabel(); |
| 266 | 270 |
| 267 const int action_row_column_set_id = 3; | 271 const int action_row_column_set_id = 3; |
| 268 views::ColumnSet* bottom_columns = | 272 views::ColumnSet* bottom_columns = |
| 269 layout->AddColumnSet(action_row_column_set_id); | 273 layout->AddColumnSet(action_row_column_set_id); |
| 270 bottom_columns->AddColumn(views::GridLayout::LEADING, | 274 bottom_columns->AddColumn(views::GridLayout::LEADING, |
| 271 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); | 275 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); |
| 272 bottom_columns->AddPaddingColumn(1, 0); | 276 bottom_columns->AddPaddingColumn(1, 0); |
| 273 bottom_columns->AddColumn(views::GridLayout::TRAILING, | 277 bottom_columns->AddColumn(views::GridLayout::TRAILING, |
| 274 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); | 278 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); |
| 275 if (!action_button.empty()) { | 279 if (!action_button.empty()) { |
| 276 bottom_columns->AddColumn(views::GridLayout::TRAILING, | 280 bottom_columns->AddColumn(views::GridLayout::TRAILING, |
| 277 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); | 281 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); |
| 278 } | 282 } |
| 279 layout->StartRowWithPadding(0, action_row_column_set_id, | 283 layout->StartRowWithPadding(0, action_row_column_set_id, |
| 280 0, kMessageBubblePadding); | 284 0, kMessageBubblePadding); |
| 281 | 285 |
| 282 learn_more_ = new views::Link(delegate_->GetLearnMoreLabel()); | 286 learn_more_ = new views::Link(delegate->GetLearnMoreLabel()); |
| 283 learn_more_->set_listener(this); | 287 learn_more_->set_listener(this); |
| 284 layout->AddView(learn_more_); | 288 layout->AddView(learn_more_); |
| 285 | 289 |
| 286 if (!action_button.empty()) { | 290 if (!action_button.empty()) { |
| 287 action_button_ = new views::LabelButton(this, action_button.c_str()); | 291 action_button_ = new views::LabelButton(this, action_button.c_str()); |
| 288 action_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); | 292 action_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); |
| 289 layout->AddView(action_button_); | 293 layout->AddView(action_button_); |
| 290 } | 294 } |
| 291 | 295 |
| 292 dismiss_button_ = new views::LabelButton(this, | 296 dismiss_button_ = new views::LabelButton(this, |
| 293 delegate_->GetDismissButtonLabel()); | 297 delegate->GetDismissButtonLabel()); |
| 294 dismiss_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); | 298 dismiss_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); |
| 295 layout->AddView(dismiss_button_); | 299 layout->AddView(dismiss_button_); |
| 296 } | 300 } |
| 297 | 301 |
| 298 void ExtensionMessageBubbleView::ButtonPressed(views::Button* sender, | 302 void ExtensionMessageBubbleView::ButtonPressed(views::Button* sender, |
| 299 const ui::Event& event) { | 303 const ui::Event& event) { |
| 300 if (sender == action_button_) { | 304 if (sender == action_button_) { |
| 301 action_taken_ = true; | 305 action_taken_ = true; |
| 302 action_callback_.Run(); | 306 action_callback_.Run(); |
| 303 } else { | 307 } else { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 319 state->role = ui::AccessibilityTypes::ROLE_ALERT; | 323 state->role = ui::AccessibilityTypes::ROLE_ALERT; |
| 320 } | 324 } |
| 321 | 325 |
| 322 void ExtensionMessageBubbleView::ViewHierarchyChanged( | 326 void ExtensionMessageBubbleView::ViewHierarchyChanged( |
| 323 const ViewHierarchyChangedDetails& details) { | 327 const ViewHierarchyChangedDetails& details) { |
| 324 if (details.is_add && details.child == this) | 328 if (details.is_add && details.child == this) |
| 325 NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, true); | 329 NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, true); |
| 326 } | 330 } |
| 327 | 331 |
| 328 } // namespace extensions | 332 } // namespace extensions |
| OLD | NEW |