OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/bookmarks/bookmark_bubble_view.h" | 5 #include "chrome/browser/ui/views/bookmarks/bookmark_bubble_view.h" |
6 | 6 |
7 #include <utility> | |
8 | |
9 #include "base/macros.h" | |
10 #include "base/metrics/user_metrics.h" | 7 #include "base/metrics/user_metrics.h" |
11 #include "base/strings/string16.h" | |
12 #include "base/strings/string_util.h" | 8 #include "base/strings/string_util.h" |
13 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
14 #include "chrome/app/chrome_command_ids.h" | |
15 #include "chrome/browser/bookmarks/bookmark_model_factory.h" | 10 #include "chrome/browser/bookmarks/bookmark_model_factory.h" |
16 #include "chrome/browser/platform_util.h" | 11 #include "chrome/browser/platform_util.h" |
17 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
18 #include "chrome/browser/ui/bookmarks/bookmark_bubble_observer.h" | 13 #include "chrome/browser/ui/bookmarks/bookmark_bubble_observer.h" |
19 #include "chrome/browser/ui/bookmarks/bookmark_editor.h" | 14 #include "chrome/browser/ui/bookmarks/bookmark_editor.h" |
20 #include "chrome/browser/ui/browser_dialogs.h" | 15 #include "chrome/browser/ui/browser_dialogs.h" |
21 #include "chrome/browser/ui/sync/sync_promo_ui.h" | 16 #include "chrome/browser/ui/sync/sync_promo_ui.h" |
22 #include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" | 17 #include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" |
23 #include "chrome/browser/ui/views/sync/bubble_sync_promo_view.h" | 18 #include "chrome/browser/ui/views/sync/bubble_sync_promo_view.h" |
24 #include "chrome/grit/chromium_strings.h" | 19 #include "chrome/grit/chromium_strings.h" |
25 #include "chrome/grit/generated_resources.h" | 20 #include "chrome/grit/generated_resources.h" |
26 #include "components/bookmarks/browser/bookmark_model.h" | 21 #include "components/bookmarks/browser/bookmark_model.h" |
27 #include "components/bookmarks/browser/bookmark_utils.h" | 22 #include "components/bookmarks/browser/bookmark_utils.h" |
28 #include "components/strings/grit/components_strings.h" | 23 #include "components/strings/grit/components_strings.h" |
29 #include "ui/accessibility/ax_node_data.h" | 24 #include "ui/accessibility/ax_node_data.h" |
30 #include "ui/base/l10n/l10n_util.h" | 25 #include "ui/base/l10n/l10n_util.h" |
31 #include "ui/events/keycodes/keyboard_codes.h" | 26 #include "ui/events/keycodes/keyboard_codes.h" |
32 #include "ui/views/bubble/bubble_frame_view.h" | |
33 #include "ui/views/controls/button/md_text_button.h" | 27 #include "ui/views/controls/button/md_text_button.h" |
34 #include "ui/views/controls/combobox/combobox.h" | 28 #include "ui/views/controls/combobox/combobox.h" |
35 #include "ui/views/controls/label.h" | 29 #include "ui/views/controls/label.h" |
36 #include "ui/views/controls/link.h" | |
37 #include "ui/views/controls/textfield/textfield.h" | 30 #include "ui/views/controls/textfield/textfield.h" |
38 #include "ui/views/layout/fill_layout.h" | 31 #include "ui/views/layout/fill_layout.h" |
39 #include "ui/views/layout/grid_layout.h" | 32 #include "ui/views/layout/grid_layout.h" |
40 #include "ui/views/widget/widget.h" | 33 #include "ui/views/widget/widget.h" |
41 | 34 |
42 #if defined(OS_WIN) | 35 #if defined(OS_WIN) |
43 #include "chrome/browser/sync/profile_sync_service_factory.h" | 36 #include "chrome/browser/sync/profile_sync_service_factory.h" |
44 #include "chrome/browser/ui/views/desktop_ios_promotion/desktop_ios_promotion_bu
bble_view.h" | 37 #include "chrome/browser/ui/views/desktop_ios_promotion/desktop_ios_promotion_bu
bble_view.h" |
45 #include "chrome/browser/ui/views/desktop_ios_promotion/desktop_ios_promotion_fo
otnote_view.h" | 38 #include "chrome/browser/ui/views/desktop_ios_promotion/desktop_ios_promotion_fo
otnote_view.h" |
46 #include "components/browser_sync/profile_sync_service.h" | 39 #include "components/browser_sync/profile_sync_service.h" |
47 #endif | 40 #endif |
48 | 41 |
49 using base::UserMetricsAction; | 42 using base::UserMetricsAction; |
50 using bookmarks::BookmarkModel; | 43 using bookmarks::BookmarkModel; |
51 using bookmarks::BookmarkNode; | 44 using bookmarks::BookmarkNode; |
52 using views::ColumnSet; | 45 using views::ColumnSet; |
53 using views::GridLayout; | 46 using views::GridLayout; |
54 | 47 |
55 namespace { | 48 namespace { |
56 | 49 |
57 // This combobox prevents any lengthy content from stretching the bubble view. | 50 // This combobox prevents any lengthy content from stretching the bubble view. |
58 class UnsizedCombobox : public views::Combobox { | 51 class UnsizedCombobox : public views::Combobox { |
59 public: | 52 public: |
60 explicit UnsizedCombobox(ui::ComboboxModel* model) : views::Combobox(model) {} | 53 explicit UnsizedCombobox(ui::ComboboxModel* model) : views::Combobox(model) {} |
61 ~UnsizedCombobox() override {} | 54 ~UnsizedCombobox() override {} |
62 | 55 |
| 56 // views::Combobox: |
63 gfx::Size GetPreferredSize() const override { | 57 gfx::Size GetPreferredSize() const override { |
64 return gfx::Size(0, views::Combobox::GetPreferredSize().height()); | 58 return gfx::Size(0, views::Combobox::GetPreferredSize().height()); |
65 } | 59 } |
66 | 60 |
67 private: | 61 private: |
68 DISALLOW_COPY_AND_ASSIGN(UnsizedCombobox); | 62 DISALLOW_COPY_AND_ASSIGN(UnsizedCombobox); |
69 }; | 63 }; |
70 | 64 |
71 } // namespace | 65 } // namespace |
72 | 66 |
73 BookmarkBubbleView* BookmarkBubbleView::bookmark_bubble_ = NULL; | 67 BookmarkBubbleView* BookmarkBubbleView::bookmark_bubble_ = nullptr; |
74 | 68 |
75 // static | 69 // static |
76 views::Widget* BookmarkBubbleView::ShowBubble( | 70 views::Widget* BookmarkBubbleView::ShowBubble( |
77 views::View* anchor_view, | 71 views::View* anchor_view, |
78 const gfx::Rect& anchor_rect, | 72 const gfx::Rect& anchor_rect, |
79 gfx::NativeView parent_window, | 73 gfx::NativeView parent_window, |
80 bookmarks::BookmarkBubbleObserver* observer, | 74 bookmarks::BookmarkBubbleObserver* observer, |
81 std::unique_ptr<BubbleSyncPromoDelegate> delegate, | 75 std::unique_ptr<BubbleSyncPromoDelegate> delegate, |
82 Profile* profile, | 76 Profile* profile, |
83 const GURL& url, | 77 const GURL& url, |
84 bool already_bookmarked) { | 78 bool already_bookmarked) { |
85 if (bookmark_bubble_) | 79 if (bookmark_bubble_) |
86 return nullptr; | 80 return nullptr; |
87 | 81 |
88 bookmark_bubble_ = | 82 bookmark_bubble_ = |
89 new BookmarkBubbleView(anchor_view, observer, std::move(delegate), | 83 new BookmarkBubbleView(anchor_view, observer, std::move(delegate), |
90 profile, url, !already_bookmarked); | 84 profile, url, !already_bookmarked); |
91 // Bookmark bubble should always anchor TOP_RIGHT, but the | 85 // Bookmark bubble should always anchor TOP_RIGHT, but the |
92 // LocationBarBubbleDelegateView does not know that and may use different | 86 // LocationBarBubbleDelegateView does not know that and may use different |
93 // arrow anchoring. | 87 // arrow anchoring. |
94 bookmark_bubble_->set_arrow(views::BubbleBorder::TOP_RIGHT); | 88 bookmark_bubble_->set_arrow(views::BubbleBorder::TOP_RIGHT); |
95 if (!anchor_view) { | 89 if (!anchor_view) { |
96 bookmark_bubble_->SetAnchorRect(anchor_rect); | 90 bookmark_bubble_->SetAnchorRect(anchor_rect); |
97 bookmark_bubble_->set_parent_window(parent_window); | 91 bookmark_bubble_->set_parent_window(parent_window); |
98 } | 92 } |
99 views::Widget* bubble_widget = | 93 views::Widget* bubble_widget = |
100 views::BubbleDialogDelegateView::CreateBubble(bookmark_bubble_); | 94 views::BubbleDialogDelegateView::CreateBubble(bookmark_bubble_); |
101 bubble_widget->Show(); | 95 bubble_widget->Show(); |
102 // Select the entire title textfield contents when the bubble is first shown. | 96 // Select the entire title textfield contents when the bubble is first shown. |
103 bookmark_bubble_->title_tf_->SelectAll(true); | 97 bookmark_bubble_->name_field_->SelectAll(true); |
104 bookmark_bubble_->SetArrowPaintType(views::BubbleBorder::PAINT_TRANSPARENT); | 98 bookmark_bubble_->SetArrowPaintType(views::BubbleBorder::PAINT_TRANSPARENT); |
105 | 99 |
106 if (bookmark_bubble_->observer_) { | 100 if (bookmark_bubble_->observer_) { |
107 BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile); | 101 BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile); |
108 const BookmarkNode* node = model->GetMostRecentlyAddedUserNodeForURL(url); | 102 const BookmarkNode* node = model->GetMostRecentlyAddedUserNodeForURL(url); |
109 bookmark_bubble_->observer_->OnBookmarkBubbleShown(node); | 103 bookmark_bubble_->observer_->OnBookmarkBubbleShown(node); |
110 } | 104 } |
111 return bubble_widget; | 105 return bubble_widget; |
112 } | 106 } |
113 | 107 |
| 108 // static |
114 void BookmarkBubbleView::Hide() { | 109 void BookmarkBubbleView::Hide() { |
115 if (bookmark_bubble_) | 110 if (bookmark_bubble_) |
116 bookmark_bubble_->GetWidget()->Close(); | 111 bookmark_bubble_->GetWidget()->Close(); |
117 } | 112 } |
118 | 113 |
119 BookmarkBubbleView::~BookmarkBubbleView() { | 114 BookmarkBubbleView::~BookmarkBubbleView() { |
120 if (apply_edits_) { | 115 if (apply_edits_) { |
121 ApplyEdits(); | 116 ApplyEdits(); |
122 } else if (remove_bookmark_) { | 117 } else if (remove_bookmark_) { |
123 BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile_); | 118 BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile_); |
124 const BookmarkNode* node = model->GetMostRecentlyAddedUserNodeForURL(url_); | 119 const BookmarkNode* node = model->GetMostRecentlyAddedUserNodeForURL(url_); |
125 if (node) | 120 if (node) |
126 model->Remove(node); | 121 model->Remove(node); |
127 } | 122 } |
128 // |parent_combobox_| needs to be destroyed before |parent_model_| as it | 123 // |parent_combobox_| needs to be destroyed before |parent_model_| as it |
129 // uses |parent_model_| in its destructor. | 124 // uses |parent_model_| in its destructor. |
130 delete parent_combobox_; | 125 delete parent_combobox_; |
131 } | 126 } |
132 | 127 |
133 void BookmarkBubbleView::WindowClosing() { | 128 // Private methods ------------------------------------------------------------- |
134 // We have to reset |bubble_| here, not in our destructor, because we'll be | |
135 // destroyed asynchronously and the shown state will be checked before then. | |
136 DCHECK_EQ(bookmark_bubble_, this); | |
137 bookmark_bubble_ = NULL; | |
138 is_showing_ios_promotion_ = false; | |
139 | |
140 if (observer_) | |
141 observer_->OnBookmarkBubbleHidden(); | |
142 } | |
143 | |
144 bool BookmarkBubbleView::AcceleratorPressed( | |
145 const ui::Accelerator& accelerator) { | |
146 ui::KeyboardCode key_code = accelerator.key_code(); | |
147 if (key_code == ui::VKEY_RETURN) { | |
148 HandleButtonPressed(close_button_); | |
149 return true; | |
150 } | |
151 if (key_code == ui::VKEY_E && accelerator.IsAltDown()) { | |
152 HandleButtonPressed(edit_button_); | |
153 return true; | |
154 } | |
155 if (key_code == ui::VKEY_R && accelerator.IsAltDown()) { | |
156 HandleButtonPressed(remove_button_); | |
157 return true; | |
158 } | |
159 | |
160 return LocationBarBubbleDelegateView::AcceleratorPressed(accelerator); | |
161 } | |
162 | |
163 void BookmarkBubbleView::Init() { | |
164 remove_button_ = views::MdTextButton::CreateSecondaryUiButton( | |
165 this, l10n_util::GetStringUTF16(IDS_BOOKMARK_BUBBLE_REMOVE_BOOKMARK)); | |
166 | |
167 edit_button_ = views::MdTextButton::CreateSecondaryUiButton( | |
168 this, l10n_util::GetStringUTF16(IDS_BOOKMARK_BUBBLE_OPTIONS)); | |
169 | |
170 close_button_ = views::MdTextButton::CreateSecondaryUiButton( | |
171 this, l10n_util::GetStringUTF16(IDS_DONE)); | |
172 close_button_->SetIsDefault(true); | |
173 | |
174 views::Label* combobox_label = new views::Label( | |
175 l10n_util::GetStringUTF16(IDS_BOOKMARK_BUBBLE_FOLDER_TEXT)); | |
176 | |
177 parent_combobox_ = new UnsizedCombobox(&parent_model_); | |
178 parent_combobox_->set_listener(this); | |
179 parent_combobox_->SetAccessibleName( | |
180 l10n_util::GetStringUTF16(IDS_BOOKMARK_AX_BUBBLE_FOLDER_TEXT)); | |
181 | |
182 SetLayoutManager(new views::FillLayout); | |
183 bookmark_details_view_ = base::MakeUnique<View>(); | |
184 GridLayout* layout = new GridLayout(bookmark_details_view_.get()); | |
185 bookmark_details_view_->SetLayoutManager(layout); | |
186 | |
187 // This column set is used for the labels and textfields as well as the | |
188 // buttons at the bottom. | |
189 const int cs_id = 0; | |
190 ColumnSet* cs = layout->AddColumnSet(cs_id); | |
191 ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); | |
192 | |
193 cs->AddColumn(provider->GetControlLabelGridAlignment(), GridLayout::CENTER, 0, | |
194 GridLayout::USE_PREF, 0, 0); | |
195 cs->AddPaddingColumn( | |
196 0, provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_HORIZONTAL)); | |
197 | |
198 cs->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, | |
199 GridLayout::USE_PREF, 0, 0); | |
200 cs->AddPaddingColumn(1, provider->GetDistanceMetric( | |
201 DISTANCE_UNRELATED_CONTROL_HORIZONTAL_LARGE)); | |
202 | |
203 cs->AddColumn(GridLayout::LEADING, GridLayout::TRAILING, 0, | |
204 GridLayout::USE_PREF, 0, 0); | |
205 cs->AddPaddingColumn(0, provider->GetDistanceMetric( | |
206 views::DISTANCE_RELATED_BUTTON_HORIZONTAL)); | |
207 cs->AddColumn(GridLayout::LEADING, GridLayout::TRAILING, 0, | |
208 GridLayout::USE_PREF, 0, 0); | |
209 | |
210 layout->StartRow(0, cs_id); | |
211 views::Label* label = new views::Label( | |
212 l10n_util::GetStringUTF16(IDS_BOOKMARK_BUBBLE_TITLE_TEXT)); | |
213 layout->AddView(label); | |
214 title_tf_ = new views::Textfield(); | |
215 title_tf_->SetText(GetTitle()); | |
216 title_tf_->SetAccessibleName( | |
217 l10n_util::GetStringUTF16(IDS_BOOKMARK_AX_BUBBLE_TITLE_TEXT)); | |
218 | |
219 layout->AddView(title_tf_, 5, 1); | |
220 | |
221 layout->AddPaddingRow( | |
222 0, provider->GetInsetsMetric(views::INSETS_DIALOG_CONTENTS).top()); | |
223 | |
224 layout->StartRow(0, cs_id); | |
225 layout->AddView(combobox_label); | |
226 layout->AddView(parent_combobox_, 5, 1); | |
227 | |
228 layout->AddPaddingRow( | |
229 0, provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL)); | |
230 | |
231 layout->StartRow(0, cs_id); | |
232 layout->SkipColumns(2); | |
233 layout->AddView(remove_button_); | |
234 layout->AddView(edit_button_); | |
235 layout->AddView(close_button_); | |
236 | |
237 AddAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE)); | |
238 AddAccelerator(ui::Accelerator(ui::VKEY_E, ui::EF_ALT_DOWN)); | |
239 AddAccelerator(ui::Accelerator(ui::VKEY_R, ui::EF_ALT_DOWN)); | |
240 | |
241 AddChildView(bookmark_details_view_.get()); | |
242 } | |
243 | |
244 gfx::ImageSkia BookmarkBubbleView::GetWindowIcon() { | |
245 #if defined(OS_WIN) | |
246 if (is_showing_ios_promotion_) { | |
247 return desktop_ios_promotion::GetPromoImage( | |
248 GetNativeTheme()->GetSystemColor( | |
249 ui::NativeTheme::kColorId_TextfieldDefaultColor)); | |
250 } | |
251 #endif | |
252 return gfx::ImageSkia(); | |
253 } | |
254 | |
255 bool BookmarkBubbleView::ShouldShowWindowIcon() const { | |
256 return is_showing_ios_promotion_; | |
257 } | |
258 | |
259 base::string16 BookmarkBubbleView::GetWindowTitle() const { | |
260 #if defined(OS_WIN) | |
261 if (is_showing_ios_promotion_) { | |
262 return desktop_ios_promotion::GetPromoTitle( | |
263 desktop_ios_promotion::PromotionEntryPoint::BOOKMARKS_BUBBLE); | |
264 } | |
265 #endif | |
266 return l10n_util::GetStringUTF16(newly_bookmarked_ | |
267 ? IDS_BOOKMARK_BUBBLE_PAGE_BOOKMARKED | |
268 : IDS_BOOKMARK_BUBBLE_PAGE_BOOKMARK); | |
269 } | |
270 | |
271 const char* BookmarkBubbleView::GetClassName() const { | |
272 return "BookmarkBubbleView"; | |
273 } | |
274 | |
275 views::View* BookmarkBubbleView::GetInitiallyFocusedView() { | |
276 return title_tf_; | |
277 } | |
278 | |
279 views::View* BookmarkBubbleView::CreateFootnoteView() { | |
280 #if defined(OS_WIN) | |
281 if (!is_showing_ios_promotion_ && | |
282 IsIOSPromotionEligible( | |
283 desktop_ios_promotion::PromotionEntryPoint::BOOKMARKS_FOOTNOTE)) { | |
284 footnote_view_ = new DesktopIOSPromotionFootnoteView(profile_, this); | |
285 return footnote_view_; | |
286 } | |
287 #endif | |
288 if (!SyncPromoUI::ShouldShowSyncPromo(profile_)) | |
289 return nullptr; | |
290 | |
291 base::RecordAction( | |
292 base::UserMetricsAction("Signin_Impression_FromBookmarkBubble")); | |
293 | |
294 footnote_view_ = | |
295 new BubbleSyncPromoView(delegate_.get(), IDS_BOOKMARK_SYNC_PROMO_LINK, | |
296 IDS_BOOKMARK_SYNC_PROMO_MESSAGE); | |
297 return footnote_view_; | |
298 } | |
299 | 129 |
300 BookmarkBubbleView::BookmarkBubbleView( | 130 BookmarkBubbleView::BookmarkBubbleView( |
301 views::View* anchor_view, | 131 views::View* anchor_view, |
302 bookmarks::BookmarkBubbleObserver* observer, | 132 bookmarks::BookmarkBubbleObserver* observer, |
303 std::unique_ptr<BubbleSyncPromoDelegate> delegate, | 133 std::unique_ptr<BubbleSyncPromoDelegate> delegate, |
304 Profile* profile, | 134 Profile* profile, |
305 const GURL& url, | 135 const GURL& url, |
306 bool newly_bookmarked) | 136 bool newly_bookmarked) |
307 : LocationBarBubbleDelegateView(anchor_view, nullptr), | 137 : LocationBarBubbleDelegateView(anchor_view, nullptr), |
308 observer_(observer), | 138 observer_(observer), |
309 delegate_(std::move(delegate)), | 139 delegate_(std::move(delegate)), |
310 profile_(profile), | 140 profile_(profile), |
311 url_(url), | 141 url_(url), |
312 newly_bookmarked_(newly_bookmarked), | 142 newly_bookmarked_(newly_bookmarked), |
313 parent_model_(BookmarkModelFactory::GetForBrowserContext(profile_), | 143 parent_model_(BookmarkModelFactory::GetForBrowserContext(profile_), |
314 BookmarkModelFactory::GetForBrowserContext(profile_) | 144 BookmarkModelFactory::GetForBrowserContext(profile_) |
315 ->GetMostRecentlyAddedUserNodeForURL(url)), | 145 ->GetMostRecentlyAddedUserNodeForURL(url)), |
316 remove_button_(nullptr), | 146 remove_button_(nullptr), |
317 edit_button_(nullptr), | 147 edit_button_(nullptr), |
318 close_button_(nullptr), | 148 save_button_(nullptr), |
319 title_tf_(nullptr), | 149 name_field_(nullptr), |
320 parent_combobox_(nullptr), | 150 parent_combobox_(nullptr), |
321 ios_promo_view_(nullptr), | 151 ios_promo_view_(nullptr), |
322 footnote_view_(nullptr), | 152 footnote_view_(nullptr), |
323 remove_bookmark_(false), | 153 remove_bookmark_(false), |
324 apply_edits_(true), | 154 apply_edits_(true), |
325 is_showing_ios_promotion_(false) { | 155 is_showing_ios_promotion_(false) { |
326 chrome::RecordDialogCreation(chrome::DialogIdentifier::BOOKMARK); | 156 chrome::RecordDialogCreation(chrome::DialogIdentifier::BOOKMARK); |
327 } | 157 } |
328 | 158 |
329 base::string16 BookmarkBubbleView::GetTitle() { | 159 base::string16 BookmarkBubbleView::GetBookmarkName() { |
330 BookmarkModel* bookmark_model = | 160 BookmarkModel* bookmark_model = |
331 BookmarkModelFactory::GetForBrowserContext(profile_); | 161 BookmarkModelFactory::GetForBrowserContext(profile_); |
332 const BookmarkNode* node = | 162 const BookmarkNode* node = |
333 bookmark_model->GetMostRecentlyAddedUserNodeForURL(url_); | 163 bookmark_model->GetMostRecentlyAddedUserNodeForURL(url_); |
334 if (node) | 164 if (node) |
335 return node->GetTitle(); | 165 return node->GetTitle(); |
336 else | 166 else |
337 NOTREACHED(); | 167 NOTREACHED(); |
338 return base::string16(); | 168 return base::string16(); |
339 } | 169 } |
340 | 170 |
341 void BookmarkBubbleView::GetAccessibleNodeData(ui::AXNodeData* node_data) { | |
342 LocationBarBubbleDelegateView::GetAccessibleNodeData(node_data); | |
343 node_data->SetName(l10n_util::GetStringUTF8( | |
344 newly_bookmarked_ ? IDS_BOOKMARK_BUBBLE_PAGE_BOOKMARKED | |
345 : IDS_BOOKMARK_AX_BUBBLE_PAGE_BOOKMARK)); | |
346 } | |
347 | |
348 void BookmarkBubbleView::ButtonPressed(views::Button* sender, | |
349 const ui::Event& event) { | |
350 HandleButtonPressed(sender); | |
351 } | |
352 | |
353 void BookmarkBubbleView::OnPerformAction(views::Combobox* combobox) { | |
354 if (combobox->selected_index() + 1 == parent_model_.GetItemCount()) { | |
355 base::RecordAction(UserMetricsAction("BookmarkBubble_EditFromCombobox")); | |
356 ShowEditor(); | |
357 } | |
358 } | |
359 | |
360 void BookmarkBubbleView::HandleButtonPressed(views::Button* sender) { | 171 void BookmarkBubbleView::HandleButtonPressed(views::Button* sender) { |
361 if (sender == remove_button_) { | 172 if (sender == remove_button_) { |
362 base::RecordAction(UserMetricsAction("BookmarkBubble_Unstar")); | 173 base::RecordAction(UserMetricsAction("BookmarkBubble_Unstar")); |
363 // Set this so we remove the bookmark after the window closes. | 174 // Set this so we remove the bookmark after the window closes. |
364 remove_bookmark_ = true; | 175 remove_bookmark_ = true; |
365 apply_edits_ = false; | 176 apply_edits_ = false; |
366 GetWidget()->Close(); | 177 GetWidget()->Close(); |
367 } else if (sender == edit_button_) { | 178 } else if (sender == edit_button_) { |
368 base::RecordAction(UserMetricsAction("BookmarkBubble_Edit")); | 179 base::RecordAction(UserMetricsAction("BookmarkBubble_Edit")); |
369 ShowEditor(); | 180 ShowEditor(); |
370 } else { | 181 } else { |
371 DCHECK_EQ(close_button_, sender); | 182 DCHECK_EQ(save_button_, sender); |
372 #if defined(OS_WIN) | 183 #if defined(OS_WIN) |
373 if (IsIOSPromotionEligible( | 184 if (IsIOSPromotionEligible( |
374 desktop_ios_promotion::PromotionEntryPoint::BOOKMARKS_BUBBLE)) { | 185 desktop_ios_promotion::PromotionEntryPoint::BOOKMARKS_BUBBLE)) { |
375 ShowIOSPromotion( | 186 ShowIOSPromotion( |
376 desktop_ios_promotion::PromotionEntryPoint::BOOKMARKS_BUBBLE); | 187 desktop_ios_promotion::PromotionEntryPoint::BOOKMARKS_BUBBLE); |
377 } else { | 188 } else { |
378 GetWidget()->Close(); | 189 GetWidget()->Close(); |
379 } | 190 } |
380 #else | 191 #else |
381 GetWidget()->Close(); | 192 GetWidget()->Close(); |
(...skipping 20 matching lines...) Expand all Loading... |
402 BookmarkEditor::SHOW_TREE); | 213 BookmarkEditor::SHOW_TREE); |
403 } | 214 } |
404 | 215 |
405 void BookmarkBubbleView::ApplyEdits() { | 216 void BookmarkBubbleView::ApplyEdits() { |
406 // Set this to make sure we don't attempt to apply edits again. | 217 // Set this to make sure we don't attempt to apply edits again. |
407 apply_edits_ = false; | 218 apply_edits_ = false; |
408 | 219 |
409 BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile_); | 220 BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile_); |
410 const BookmarkNode* node = model->GetMostRecentlyAddedUserNodeForURL(url_); | 221 const BookmarkNode* node = model->GetMostRecentlyAddedUserNodeForURL(url_); |
411 if (node) { | 222 if (node) { |
412 const base::string16 new_title = title_tf_->text(); | 223 const base::string16 new_title = name_field_->text(); |
413 if (new_title != node->GetTitle()) { | 224 if (new_title != node->GetTitle()) { |
414 model->SetTitle(node, new_title); | 225 model->SetTitle(node, new_title); |
415 base::RecordAction( | 226 base::RecordAction( |
416 UserMetricsAction("BookmarkBubble_ChangeTitleInBubble")); | 227 UserMetricsAction("BookmarkBubble_ChangeTitleInBubble")); |
417 } | 228 } |
418 parent_model_.MaybeChangeParent(node, parent_combobox_->selected_index()); | 229 parent_model_.MaybeChangeParent(node, parent_combobox_->selected_index()); |
419 } | 230 } |
420 } | 231 } |
421 | 232 |
422 void BookmarkBubbleView::OnIOSPromotionFootnoteLinkClicked() { | |
423 #if defined(OS_WIN) | |
424 ShowIOSPromotion( | |
425 desktop_ios_promotion::PromotionEntryPoint::FOOTNOTE_FOLLOWUP_BUBBLE); | |
426 #endif | |
427 } | |
428 | |
429 #if defined(OS_WIN) | 233 #if defined(OS_WIN) |
430 | 234 |
431 bool BookmarkBubbleView::IsIOSPromotionEligible( | 235 bool BookmarkBubbleView::IsIOSPromotionEligible( |
432 desktop_ios_promotion::PromotionEntryPoint entry_point) { | 236 desktop_ios_promotion::PromotionEntryPoint entry_point) { |
433 PrefService* prefs = profile_->GetPrefs(); | 237 PrefService* prefs = profile_->GetPrefs(); |
434 const browser_sync::ProfileSyncService* sync_service = | 238 const browser_sync::ProfileSyncService* sync_service = |
435 ProfileSyncServiceFactory::GetForProfile(profile_); | 239 ProfileSyncServiceFactory::GetForProfile(profile_); |
436 return desktop_ios_promotion::IsEligibleForIOSPromotion(prefs, sync_service, | 240 return desktop_ios_promotion::IsEligibleForIOSPromotion(prefs, sync_service, |
437 entry_point); | 241 entry_point); |
438 } | 242 } |
439 | 243 |
440 void BookmarkBubbleView::ShowIOSPromotion( | 244 void BookmarkBubbleView::ShowIOSPromotion( |
441 desktop_ios_promotion::PromotionEntryPoint entry_point) { | 245 desktop_ios_promotion::PromotionEntryPoint entry_point) { |
442 DCHECK(!is_showing_ios_promotion_); | 246 DCHECK(!is_showing_ios_promotion_); |
443 RemoveChildView(bookmark_details_view_.get()); | 247 // Hide the contents, but don't delete. It's needed in the destructor. |
| 248 bookmark_contents_view_->SetVisible(false); |
444 delete footnote_view_; | 249 delete footnote_view_; |
445 footnote_view_ = nullptr; | 250 footnote_view_ = nullptr; |
446 is_showing_ios_promotion_ = true; | 251 is_showing_ios_promotion_ = true; |
447 ios_promo_view_ = new DesktopIOSPromotionBubbleView(profile_, entry_point); | 252 ios_promo_view_ = new DesktopIOSPromotionBubbleView(profile_, entry_point); |
448 AddChildView(ios_promo_view_); | 253 AddChildView(ios_promo_view_); |
449 GetWidget()->UpdateWindowIcon(); | 254 GetWidget()->UpdateWindowIcon(); |
450 GetWidget()->UpdateWindowTitle(); | 255 GetWidget()->UpdateWindowTitle(); |
451 // Resize the bubble so it has the same width as the parent bubble. | 256 // Resize the bubble so it has the same width as the parent bubble. |
452 ios_promo_view_->UpdateBubbleHeight(); | 257 ios_promo_view_->UpdateBubbleHeight(); |
453 } | 258 } |
454 #endif | 259 #endif |
| 260 |
| 261 // ui::DialogModel ------------------------------------------------------------- |
| 262 |
| 263 int BookmarkBubbleView::GetDialogButtons() const { |
| 264 // TODO(tapted): DialogClientView should manage the buttons. |
| 265 return ui::DIALOG_BUTTON_NONE; |
| 266 } |
| 267 |
| 268 // views::WidgetDelegate ------------------------------------------------------- |
| 269 |
| 270 views::View* BookmarkBubbleView::GetInitiallyFocusedView() { |
| 271 return name_field_; |
| 272 } |
| 273 |
| 274 base::string16 BookmarkBubbleView::GetWindowTitle() const { |
| 275 #if defined(OS_WIN) |
| 276 if (is_showing_ios_promotion_) { |
| 277 return desktop_ios_promotion::GetPromoTitle( |
| 278 desktop_ios_promotion::PromotionEntryPoint::BOOKMARKS_BUBBLE); |
| 279 } |
| 280 #endif |
| 281 return l10n_util::GetStringUTF16(newly_bookmarked_ |
| 282 ? IDS_BOOKMARK_BUBBLE_PAGE_BOOKMARKED |
| 283 : IDS_BOOKMARK_BUBBLE_PAGE_BOOKMARK); |
| 284 } |
| 285 |
| 286 gfx::ImageSkia BookmarkBubbleView::GetWindowIcon() { |
| 287 #if defined(OS_WIN) |
| 288 if (is_showing_ios_promotion_) { |
| 289 return desktop_ios_promotion::GetPromoImage( |
| 290 GetNativeTheme()->GetSystemColor( |
| 291 ui::NativeTheme::kColorId_TextfieldDefaultColor)); |
| 292 } |
| 293 #endif |
| 294 return gfx::ImageSkia(); |
| 295 } |
| 296 |
| 297 bool BookmarkBubbleView::ShouldShowWindowIcon() const { |
| 298 return is_showing_ios_promotion_; |
| 299 } |
| 300 |
| 301 void BookmarkBubbleView::WindowClosing() { |
| 302 // We have to reset |bubble_| here, not in our destructor, because we'll be |
| 303 // destroyed asynchronously and the shown state will be checked before then. |
| 304 DCHECK_EQ(bookmark_bubble_, this); |
| 305 bookmark_bubble_ = NULL; |
| 306 is_showing_ios_promotion_ = false; |
| 307 |
| 308 if (observer_) |
| 309 observer_->OnBookmarkBubbleHidden(); |
| 310 } |
| 311 |
| 312 // views::DialogDelegate ------------------------------------------------------- |
| 313 |
| 314 views::View* BookmarkBubbleView::CreateFootnoteView() { |
| 315 #if defined(OS_WIN) |
| 316 if (!is_showing_ios_promotion_ && |
| 317 IsIOSPromotionEligible( |
| 318 desktop_ios_promotion::PromotionEntryPoint::BOOKMARKS_FOOTNOTE)) { |
| 319 footnote_view_ = new DesktopIOSPromotionFootnoteView(profile_, this); |
| 320 return footnote_view_; |
| 321 } |
| 322 #endif |
| 323 if (!SyncPromoUI::ShouldShowSyncPromo(profile_)) |
| 324 return nullptr; |
| 325 |
| 326 base::RecordAction(UserMetricsAction("Signin_Impression_FromBookmarkBubble")); |
| 327 |
| 328 footnote_view_ = |
| 329 new BubbleSyncPromoView(delegate_.get(), IDS_BOOKMARK_SYNC_PROMO_LINK, |
| 330 IDS_BOOKMARK_SYNC_PROMO_MESSAGE); |
| 331 return footnote_view_; |
| 332 } |
| 333 |
| 334 // views::View ----------------------------------------------------------------- |
| 335 |
| 336 const char* BookmarkBubbleView::GetClassName() const { |
| 337 return "BookmarkBubbleView"; |
| 338 } |
| 339 |
| 340 bool BookmarkBubbleView::AcceleratorPressed( |
| 341 const ui::Accelerator& accelerator) { |
| 342 ui::KeyboardCode key_code = accelerator.key_code(); |
| 343 if (key_code == ui::VKEY_RETURN) { |
| 344 HandleButtonPressed(save_button_); |
| 345 return true; |
| 346 } |
| 347 if (key_code == ui::VKEY_E && accelerator.IsAltDown()) { |
| 348 HandleButtonPressed(edit_button_); |
| 349 return true; |
| 350 } |
| 351 if (key_code == ui::VKEY_R && accelerator.IsAltDown()) { |
| 352 HandleButtonPressed(remove_button_); |
| 353 return true; |
| 354 } |
| 355 |
| 356 return LocationBarBubbleDelegateView::AcceleratorPressed(accelerator); |
| 357 } |
| 358 |
| 359 void BookmarkBubbleView::GetAccessibleNodeData(ui::AXNodeData* node_data) { |
| 360 LocationBarBubbleDelegateView::GetAccessibleNodeData(node_data); |
| 361 node_data->SetName(l10n_util::GetStringUTF8( |
| 362 newly_bookmarked_ ? IDS_BOOKMARK_BUBBLE_PAGE_BOOKMARKED |
| 363 : IDS_BOOKMARK_AX_BUBBLE_PAGE_BOOKMARK)); |
| 364 } |
| 365 |
| 366 // views::BubbleDialogDelegateView --------------------------------------------- |
| 367 |
| 368 void BookmarkBubbleView::Init() { |
| 369 remove_button_ = views::MdTextButton::CreateSecondaryUiButton( |
| 370 this, l10n_util::GetStringUTF16(IDS_BOOKMARK_BUBBLE_REMOVE_BOOKMARK)); |
| 371 |
| 372 edit_button_ = views::MdTextButton::CreateSecondaryUiButton( |
| 373 this, l10n_util::GetStringUTF16(IDS_BOOKMARK_BUBBLE_OPTIONS)); |
| 374 |
| 375 save_button_ = views::MdTextButton::CreateSecondaryUiButton( |
| 376 this, l10n_util::GetStringUTF16(IDS_DONE)); |
| 377 save_button_->SetIsDefault(true); |
| 378 |
| 379 views::Label* combobox_label = new views::Label( |
| 380 l10n_util::GetStringUTF16(IDS_BOOKMARK_BUBBLE_FOLDER_TEXT)); |
| 381 |
| 382 parent_combobox_ = new UnsizedCombobox(&parent_model_); |
| 383 parent_combobox_->set_listener(this); |
| 384 parent_combobox_->SetAccessibleName( |
| 385 l10n_util::GetStringUTF16(IDS_BOOKMARK_AX_BUBBLE_FOLDER_TEXT)); |
| 386 |
| 387 SetLayoutManager(new views::FillLayout); |
| 388 bookmark_contents_view_ = new views::View(); |
| 389 GridLayout* layout = new GridLayout(bookmark_contents_view_); |
| 390 bookmark_contents_view_->SetLayoutManager(layout); |
| 391 |
| 392 // This column set is used for the labels and textfields as well as the |
| 393 // buttons at the bottom. |
| 394 const int cs_id = 0; |
| 395 ColumnSet* cs = layout->AddColumnSet(cs_id); |
| 396 ChromeLayoutProvider* provider = ChromeLayoutProvider::Get(); |
| 397 |
| 398 cs->AddColumn(provider->GetControlLabelGridAlignment(), GridLayout::CENTER, 0, |
| 399 GridLayout::USE_PREF, 0, 0); |
| 400 cs->AddPaddingColumn( |
| 401 0, provider->GetDistanceMetric(DISTANCE_UNRELATED_CONTROL_HORIZONTAL)); |
| 402 |
| 403 cs->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, GridLayout::USE_PREF, |
| 404 0, 0); |
| 405 cs->AddPaddingColumn(1, provider->GetDistanceMetric( |
| 406 DISTANCE_UNRELATED_CONTROL_HORIZONTAL_LARGE)); |
| 407 |
| 408 cs->AddColumn(GridLayout::LEADING, GridLayout::TRAILING, 0, |
| 409 GridLayout::USE_PREF, 0, 0); |
| 410 cs->AddPaddingColumn(0, provider->GetDistanceMetric( |
| 411 views::DISTANCE_RELATED_BUTTON_HORIZONTAL)); |
| 412 cs->AddColumn(GridLayout::LEADING, GridLayout::TRAILING, 0, |
| 413 GridLayout::USE_PREF, 0, 0); |
| 414 |
| 415 layout->StartRow(0, cs_id); |
| 416 views::Label* label = new views::Label( |
| 417 l10n_util::GetStringUTF16(IDS_BOOKMARK_BUBBLE_TITLE_TEXT)); |
| 418 layout->AddView(label); |
| 419 name_field_ = new views::Textfield(); |
| 420 name_field_->SetText(GetBookmarkName()); |
| 421 name_field_->SetAccessibleName( |
| 422 l10n_util::GetStringUTF16(IDS_BOOKMARK_AX_BUBBLE_TITLE_TEXT)); |
| 423 |
| 424 layout->AddView(name_field_, 5, 1); |
| 425 |
| 426 layout->AddPaddingRow( |
| 427 0, provider->GetInsetsMetric(views::INSETS_DIALOG_CONTENTS).top()); |
| 428 |
| 429 layout->StartRow(0, cs_id); |
| 430 layout->AddView(combobox_label); |
| 431 layout->AddView(parent_combobox_, 5, 1); |
| 432 |
| 433 layout->AddPaddingRow( |
| 434 0, provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL)); |
| 435 |
| 436 layout->StartRow(0, cs_id); |
| 437 layout->SkipColumns(2); |
| 438 layout->AddView(remove_button_); |
| 439 layout->AddView(edit_button_); |
| 440 layout->AddView(save_button_); |
| 441 |
| 442 AddAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE)); |
| 443 AddAccelerator(ui::Accelerator(ui::VKEY_E, ui::EF_ALT_DOWN)); |
| 444 AddAccelerator(ui::Accelerator(ui::VKEY_R, ui::EF_ALT_DOWN)); |
| 445 |
| 446 AddChildView(bookmark_contents_view_); |
| 447 } |
| 448 |
| 449 // views::ButtonListener ------------------------------------------------------- |
| 450 |
| 451 void BookmarkBubbleView::ButtonPressed(views::Button* sender, |
| 452 const ui::Event& event) { |
| 453 HandleButtonPressed(sender); |
| 454 } |
| 455 |
| 456 // views::ComboboxListener ----------------------------------------------------- |
| 457 |
| 458 void BookmarkBubbleView::OnPerformAction(views::Combobox* combobox) { |
| 459 if (combobox->selected_index() + 1 == parent_model_.GetItemCount()) { |
| 460 base::RecordAction(UserMetricsAction("BookmarkBubble_EditFromCombobox")); |
| 461 ShowEditor(); |
| 462 } |
| 463 } |
| 464 |
| 465 // DesktopIOSPromotionFootnoteDelegate ----------------------------------------- |
| 466 |
| 467 void BookmarkBubbleView::OnIOSPromotionFootnoteLinkClicked() { |
| 468 #if defined(OS_WIN) |
| 469 ShowIOSPromotion( |
| 470 desktop_ios_promotion::PromotionEntryPoint::FOOTNOTE_FOLLOWUP_BUBBLE); |
| 471 #endif |
| 472 } |
OLD | NEW |