Chromium Code Reviews| 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 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), |
| 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( |
|
not at google - send to devlin
2014/01/10 21:28:43
i still think it's odd to have this on extension_m
Finnur
2014/01/13 15:36:32
Yup. I believe we are in agreement. Someone wants
| |
| 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 // Show the ExtensionMessageBubbleView and pass ownership of |controller| to | |
| 90 // the view. | |
|
not at google - send to devlin
2014/01/10 21:28:43
i think this comment, particularly after the scope
Finnur
2014/01/13 15:36:32
Done.
| |
| 91 SuspiciousExtensionBubbleController* controller = | |
| 92 suspicious_extensions.release(); | |
|
not at google - send to devlin
2014/01/10 21:28:43
when the View takes a scoped_ptr<controller> this
Finnur
2014/01/13 15:36:32
Done.
| |
| 90 ExtensionMessageBubbleView* bubble_delegate = | 93 ExtensionMessageBubbleView* bubble_delegate = |
| 91 new ExtensionMessageBubbleView(anchor_view, suspicious_extensions); | 94 new ExtensionMessageBubbleView(anchor_view, controller); |
| 92 views::BubbleDelegateView::CreateBubble(bubble_delegate); | 95 views::BubbleDelegateView::CreateBubble(bubble_delegate); |
| 93 suspicious_extensions->Show(bubble_delegate); | 96 controller->Show(bubble_delegate); |
| 94 return; | 97 return; |
| 95 } | 98 } |
| 96 | 99 |
| 97 DevModeBubbleController* dev_mode_extensions = | 100 scoped_ptr<DevModeBubbleController> dev_mode_extensions( |
| 98 extensions::DevModeBubbleController::Get( | 101 new DevModeBubbleController(browser->profile())); |
| 99 browser->profile()); | |
| 100 if (dev_mode_extensions->ShouldShow()) { | 102 if (dev_mode_extensions->ShouldShow()) { |
| 101 views::View* reference_view = NULL; | 103 views::View* reference_view = NULL; |
| 102 BrowserActionsContainer* container = toolbar_view->browser_actions(); | 104 BrowserActionsContainer* container = toolbar_view->browser_actions(); |
| 103 if (container->animating()) | 105 if (container->animating()) |
| 104 return; | 106 return; |
| 105 | 107 |
| 106 ExtensionService* service = extensions::ExtensionSystem::Get( | 108 ExtensionService* service = extensions::ExtensionSystem::Get( |
| 107 browser->profile())->extension_service(); | 109 browser->profile())->extension_service(); |
| 108 extensions::ExtensionActionManager* extension_action_manager = | 110 extensions::ExtensionActionManager* extension_action_manager = |
| 109 extensions::ExtensionActionManager::Get(browser->profile()); | 111 extensions::ExtensionActionManager::Get(browser->profile()); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 124 } | 126 } |
| 125 if (reference_view) { | 127 if (reference_view) { |
| 126 // If we have a view, it means we found a browser action and we want to | 128 // 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. | 129 // point to the chevron, not the hotdog menu. |
| 128 if (!reference_view->visible()) | 130 if (!reference_view->visible()) |
| 129 reference_view = container->chevron(); // It's hidden, use the chevron. | 131 reference_view = container->chevron(); // It's hidden, use the chevron. |
| 130 } | 132 } |
| 131 if (reference_view && reference_view->visible()) | 133 if (reference_view && reference_view->visible()) |
| 132 anchor_view = reference_view; // Catch-all is the hotdog menu. | 134 anchor_view = reference_view; // Catch-all is the hotdog menu. |
| 133 | 135 |
| 134 // Show the bubble. | 136 // Show the ExtensionMessageBubbleView and pass ownership of |controller| to |
| 137 // the view. | |
|
not at google - send to devlin
2014/01/10 21:28:43
likewise x2
Finnur
2014/01/13 15:36:32
Done.
| |
| 138 DevModeBubbleController* controller = dev_mode_extensions.release(); | |
| 135 ExtensionMessageBubbleView* bubble_delegate = | 139 ExtensionMessageBubbleView* bubble_delegate = |
| 136 new ExtensionMessageBubbleView(anchor_view, dev_mode_extensions); | 140 new ExtensionMessageBubbleView(anchor_view, controller); |
| 137 views::BubbleDelegateView::CreateBubble(bubble_delegate); | 141 views::BubbleDelegateView::CreateBubble(bubble_delegate); |
| 138 dev_mode_extensions->Show(bubble_delegate); | 142 controller->Show(bubble_delegate); |
| 139 } | 143 } |
| 140 #endif | 144 #endif |
| 141 } | 145 } |
| 142 | 146 |
| 143 void ExtensionMessageBubbleView::OnActionButtonClicked( | 147 void ExtensionMessageBubbleView::OnActionButtonClicked( |
| 144 const base::Closure& callback) { | 148 const base::Closure& callback) { |
| 145 action_callback_ = callback; | 149 action_callback_ = callback; |
| 146 } | 150 } |
| 147 | 151 |
| 148 void ExtensionMessageBubbleView::OnDismissButtonClicked( | 152 void ExtensionMessageBubbleView::OnDismissButtonClicked( |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 189 } | 193 } |
| 190 | 194 |
| 191 void ExtensionMessageBubbleView::Init() { | 195 void ExtensionMessageBubbleView::Init() { |
| 192 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 196 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 193 | 197 |
| 194 views::GridLayout* layout = views::GridLayout::CreatePanel(this); | 198 views::GridLayout* layout = views::GridLayout::CreatePanel(this); |
| 195 layout->SetInsets(kInsetTop, kInsetLeft, | 199 layout->SetInsets(kInsetTop, kInsetLeft, |
| 196 kInsetBottomRight, kInsetBottomRight); | 200 kInsetBottomRight, kInsetBottomRight); |
| 197 SetLayoutManager(layout); | 201 SetLayoutManager(layout); |
| 198 | 202 |
| 203 ExtensionMessageBubbleController::Delegate* delegate = | |
| 204 controller_->delegate(); | |
| 205 | |
| 199 const int headline_column_set_id = 0; | 206 const int headline_column_set_id = 0; |
| 200 views::ColumnSet* top_columns = layout->AddColumnSet(headline_column_set_id); | 207 views::ColumnSet* top_columns = layout->AddColumnSet(headline_column_set_id); |
| 201 top_columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, | 208 top_columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER, |
| 202 0, views::GridLayout::USE_PREF, 0, 0); | 209 0, views::GridLayout::USE_PREF, 0, 0); |
| 203 top_columns->AddPaddingColumn(1, 0); | 210 top_columns->AddPaddingColumn(1, 0); |
| 204 layout->StartRow(0, headline_column_set_id); | 211 layout->StartRow(0, headline_column_set_id); |
| 205 | 212 |
| 206 headline_ = new views::Label(delegate_->GetTitle(), | 213 headline_ = new views::Label(delegate->GetTitle(), |
| 207 rb.GetFontList(ui::ResourceBundle::MediumFont)); | 214 rb.GetFontList(ui::ResourceBundle::MediumFont)); |
| 208 layout->AddView(headline_); | 215 layout->AddView(headline_); |
| 209 | 216 |
| 210 layout->AddPaddingRow(0, kHeadlineRowPadding); | 217 layout->AddPaddingRow(0, kHeadlineRowPadding); |
| 211 | 218 |
| 212 const int text_column_set_id = 1; | 219 const int text_column_set_id = 1; |
| 213 views::ColumnSet* upper_columns = layout->AddColumnSet(text_column_set_id); | 220 views::ColumnSet* upper_columns = layout->AddColumnSet(text_column_set_id); |
| 214 upper_columns->AddColumn( | 221 upper_columns->AddColumn( |
| 215 views::GridLayout::LEADING, views::GridLayout::LEADING, | 222 views::GridLayout::LEADING, views::GridLayout::LEADING, |
| 216 0, views::GridLayout::USE_PREF, 0, 0); | 223 0, views::GridLayout::USE_PREF, 0, 0); |
| 217 layout->StartRow(0, text_column_set_id); | 224 layout->StartRow(0, text_column_set_id); |
| 218 | 225 |
| 219 views::Label* message = new views::Label(); | 226 views::Label* message = new views::Label(); |
| 220 message->SetMultiLine(true); | 227 message->SetMultiLine(true); |
| 221 message->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 228 message->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 222 message->SetText(delegate_->GetMessageBody()); | 229 message->SetText(delegate->GetMessageBody()); |
| 223 message->SizeToFit(views::Widget::GetLocalizedContentsWidth( | 230 message->SizeToFit(views::Widget::GetLocalizedContentsWidth( |
| 224 IDS_EXTENSION_WIPEOUT_BUBBLE_WIDTH_CHARS)); | 231 IDS_EXTENSION_WIPEOUT_BUBBLE_WIDTH_CHARS)); |
| 225 layout->AddView(message); | 232 layout->AddView(message); |
| 226 | 233 |
| 227 if (delegate_->ShouldShowExtensionList()) { | 234 if (delegate->ShouldShowExtensionList()) { |
| 228 const int extension_list_column_set_id = 2; | 235 const int extension_list_column_set_id = 2; |
| 229 views::ColumnSet* middle_columns = | 236 views::ColumnSet* middle_columns = |
| 230 layout->AddColumnSet(extension_list_column_set_id); | 237 layout->AddColumnSet(extension_list_column_set_id); |
| 231 middle_columns->AddPaddingColumn(0, kExtensionListPadding); | 238 middle_columns->AddPaddingColumn(0, kExtensionListPadding); |
| 232 middle_columns->AddColumn( | 239 middle_columns->AddColumn( |
| 233 views::GridLayout::LEADING, views::GridLayout::CENTER, | 240 views::GridLayout::LEADING, views::GridLayout::CENTER, |
| 234 0, views::GridLayout::USE_PREF, 0, 0); | 241 0, views::GridLayout::USE_PREF, 0, 0); |
| 235 | 242 |
| 236 layout->StartRowWithPadding(0, extension_list_column_set_id, | 243 layout->StartRowWithPadding(0, extension_list_column_set_id, |
| 237 0, kHeadlineMessagePadding); | 244 0, kHeadlineMessagePadding); |
| 238 views::Label* extensions = new views::Label(); | 245 views::Label* extensions = new views::Label(); |
| 239 extensions->SetMultiLine(true); | 246 extensions->SetMultiLine(true); |
| 240 extensions->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 247 extensions->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 241 | 248 |
| 242 std::vector<base::string16> extension_list; | 249 std::vector<base::string16> extension_list; |
| 243 base::char16 bullet_point = 0x2022; | 250 base::char16 bullet_point = 0x2022; |
| 244 | 251 |
| 245 std::vector<base::string16> suspicious = delegate_->GetExtensions(); | 252 std::vector<base::string16> suspicious = controller_->GetExtensionList(); |
| 246 size_t i = 0; | 253 size_t i = 0; |
| 247 for (; i < suspicious.size() && i < kMaxExtensionsToShow; ++i) { | 254 for (; i < suspicious.size() && i < kMaxExtensionsToShow; ++i) { |
| 248 // Add each extension with bullet point. | 255 // Add each extension with bullet point. |
| 249 extension_list.push_back( | 256 extension_list.push_back( |
| 250 bullet_point + base::ASCIIToUTF16(" ") + suspicious[i]); | 257 bullet_point + base::ASCIIToUTF16(" ") + suspicious[i]); |
| 251 } | 258 } |
| 252 | 259 |
| 253 if (i > kMaxExtensionsToShow) { | 260 if (i > kMaxExtensionsToShow) { |
| 254 base::string16 difference = base::IntToString16(i - kMaxExtensionsToShow); | 261 base::string16 difference = base::IntToString16(i - kMaxExtensionsToShow); |
| 255 extension_list.push_back(bullet_point + base::ASCIIToUTF16(" ") + | 262 extension_list.push_back(bullet_point + base::ASCIIToUTF16(" ") + |
| 256 delegate_->GetOverflowText(difference)); | 263 delegate->GetOverflowText(difference)); |
| 257 } | 264 } |
| 258 | 265 |
| 259 extensions->SetText(JoinString(extension_list, base::ASCIIToUTF16("\n"))); | 266 extensions->SetText(JoinString(extension_list, base::ASCIIToUTF16("\n"))); |
| 260 extensions->SizeToFit(views::Widget::GetLocalizedContentsWidth( | 267 extensions->SizeToFit(views::Widget::GetLocalizedContentsWidth( |
| 261 IDS_EXTENSION_WIPEOUT_BUBBLE_WIDTH_CHARS)); | 268 IDS_EXTENSION_WIPEOUT_BUBBLE_WIDTH_CHARS)); |
| 262 layout->AddView(extensions); | 269 layout->AddView(extensions); |
| 263 } | 270 } |
| 264 | 271 |
| 265 base::string16 action_button = delegate_->GetActionButtonLabel(); | 272 base::string16 action_button = delegate->GetActionButtonLabel(); |
| 266 | 273 |
| 267 const int action_row_column_set_id = 3; | 274 const int action_row_column_set_id = 3; |
| 268 views::ColumnSet* bottom_columns = | 275 views::ColumnSet* bottom_columns = |
| 269 layout->AddColumnSet(action_row_column_set_id); | 276 layout->AddColumnSet(action_row_column_set_id); |
| 270 bottom_columns->AddColumn(views::GridLayout::LEADING, | 277 bottom_columns->AddColumn(views::GridLayout::LEADING, |
| 271 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); | 278 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); |
| 272 bottom_columns->AddPaddingColumn(1, 0); | 279 bottom_columns->AddPaddingColumn(1, 0); |
| 273 bottom_columns->AddColumn(views::GridLayout::TRAILING, | 280 bottom_columns->AddColumn(views::GridLayout::TRAILING, |
| 274 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); | 281 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); |
| 275 if (!action_button.empty()) { | 282 if (!action_button.empty()) { |
| 276 bottom_columns->AddColumn(views::GridLayout::TRAILING, | 283 bottom_columns->AddColumn(views::GridLayout::TRAILING, |
| 277 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); | 284 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0); |
| 278 } | 285 } |
| 279 layout->StartRowWithPadding(0, action_row_column_set_id, | 286 layout->StartRowWithPadding(0, action_row_column_set_id, |
| 280 0, kMessageBubblePadding); | 287 0, kMessageBubblePadding); |
| 281 | 288 |
| 282 learn_more_ = new views::Link(delegate_->GetLearnMoreLabel()); | 289 learn_more_ = new views::Link(delegate->GetLearnMoreLabel()); |
| 283 learn_more_->set_listener(this); | 290 learn_more_->set_listener(this); |
| 284 layout->AddView(learn_more_); | 291 layout->AddView(learn_more_); |
| 285 | 292 |
| 286 if (!action_button.empty()) { | 293 if (!action_button.empty()) { |
| 287 action_button_ = new views::LabelButton(this, action_button.c_str()); | 294 action_button_ = new views::LabelButton(this, action_button.c_str()); |
| 288 action_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); | 295 action_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); |
| 289 layout->AddView(action_button_); | 296 layout->AddView(action_button_); |
| 290 } | 297 } |
| 291 | 298 |
| 292 dismiss_button_ = new views::LabelButton(this, | 299 dismiss_button_ = new views::LabelButton(this, |
| 293 delegate_->GetDismissButtonLabel()); | 300 delegate->GetDismissButtonLabel()); |
| 294 dismiss_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); | 301 dismiss_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); |
| 295 layout->AddView(dismiss_button_); | 302 layout->AddView(dismiss_button_); |
| 296 } | 303 } |
| 297 | 304 |
| 298 void ExtensionMessageBubbleView::ButtonPressed(views::Button* sender, | 305 void ExtensionMessageBubbleView::ButtonPressed(views::Button* sender, |
| 299 const ui::Event& event) { | 306 const ui::Event& event) { |
| 300 if (sender == action_button_) { | 307 if (sender == action_button_) { |
| 301 action_taken_ = true; | 308 action_taken_ = true; |
| 302 action_callback_.Run(); | 309 action_callback_.Run(); |
| 303 } else { | 310 } else { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 319 state->role = ui::AccessibilityTypes::ROLE_ALERT; | 326 state->role = ui::AccessibilityTypes::ROLE_ALERT; |
| 320 } | 327 } |
| 321 | 328 |
| 322 void ExtensionMessageBubbleView::ViewHierarchyChanged( | 329 void ExtensionMessageBubbleView::ViewHierarchyChanged( |
| 323 const ViewHierarchyChangedDetails& details) { | 330 const ViewHierarchyChangedDetails& details) { |
| 324 if (details.is_add && details.child == this) | 331 if (details.is_add && details.child == this) |
| 325 NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, true); | 332 NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_ALERT, true); |
| 326 } | 333 } |
| 327 | 334 |
| 328 } // namespace extensions | 335 } // namespace extensions |
| OLD | NEW |