OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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/options/cookies_view.h" | |
6 | |
7 #include <algorithm> | |
8 | |
9 #include "base/message_loop.h" | |
10 #include "base/string_util.h" | |
11 #include "chrome/browser/profiles/profile.h" | |
12 #include "chrome/browser/ui/views/appcache_info_view.h" | |
13 #include "chrome/browser/ui/views/cookie_info_view.h" | |
14 #include "chrome/browser/ui/views/database_info_view.h" | |
15 #include "chrome/browser/ui/views/indexed_db_info_view.h" | |
16 #include "chrome/browser/ui/views/local_storage_info_view.h" | |
17 #include "grit/generated_resources.h" | |
18 #include "grit/locale_settings.h" | |
19 #include "net/base/cookie_monster.h" | |
20 #include "ui/base/l10n/l10n_util.h" | |
21 #include "ui/gfx/canvas.h" | |
22 #include "ui/gfx/color_utils.h" | |
23 #include "views/border.h" | |
24 #include "views/controls/button/native_button.h" | |
25 #include "views/controls/label.h" | |
26 #include "views/controls/textfield/textfield.h" | |
27 #include "views/controls/tree/tree_view.h" | |
28 #include "views/layout/grid_layout.h" | |
29 #include "views/layout/layout_constants.h" | |
30 | |
31 // static | |
32 views::Window* CookiesView::instance_ = NULL; | |
33 static const int kSearchFilterDelayMs = 500; | |
34 | |
35 /////////////////////////////////////////////////////////////////////////////// | |
36 // CookiesTreeView | |
37 // Overridden to handle Delete key presses | |
38 | |
39 class CookiesTreeView : public views::TreeView { | |
40 public: | |
41 explicit CookiesTreeView(CookiesTreeModel* cookies_model); | |
42 virtual ~CookiesTreeView() {} | |
43 | |
44 // Removes the items associated with the selected node in the TreeView | |
45 void RemoveSelectedItems(); | |
46 | |
47 private: | |
48 DISALLOW_COPY_AND_ASSIGN(CookiesTreeView); | |
49 }; | |
50 | |
51 CookiesTreeView::CookiesTreeView(CookiesTreeModel* cookies_model) { | |
52 SetModel(cookies_model); | |
53 SetRootShown(false); | |
54 SetEditable(false); | |
55 } | |
56 | |
57 void CookiesTreeView::RemoveSelectedItems() { | |
58 ui::TreeModelNode* selected_node = GetSelectedNode(); | |
59 if (selected_node) { | |
60 static_cast<CookiesTreeModel*>(model())->DeleteCookieNode( | |
61 static_cast<CookieTreeNode*>(GetSelectedNode())); | |
62 } | |
63 } | |
64 | |
65 /////////////////////////////////////////////////////////////////////////////// | |
66 // CookiesView::InfoPanelView | |
67 // Overridden to handle layout of the various info views. | |
68 // | |
69 // This view is a child of the CookiesView and participates | |
70 // in its GridLayout. The various info views are all children | |
71 // of this view. Only one child is expected to be visible at a time. | |
72 | |
73 class CookiesView::InfoPanelView : public views::View { | |
74 public: | |
75 virtual void Layout() { | |
76 for (int i = 0; i < child_count(); ++i) | |
77 GetChildViewAt(i)->SetBounds(0, 0, width(), height()); | |
78 } | |
79 | |
80 virtual gfx::Size GetPreferredSize() { | |
81 DCHECK(has_children()); | |
82 return GetChildViewAt(0)->GetPreferredSize(); | |
83 } | |
84 }; | |
85 | |
86 /////////////////////////////////////////////////////////////////////////////// | |
87 // CookiesView, public: | |
88 | |
89 // static | |
90 void CookiesView::ShowCookiesWindow(Profile* profile) { | |
91 if (!instance_) { | |
92 CookiesView* cookies_view = new CookiesView(profile); | |
93 instance_ = views::Window::CreateChromeWindow( | |
94 NULL, gfx::Rect(), cookies_view); | |
95 } | |
96 if (!instance_->IsVisible()) { | |
97 instance_->Show(); | |
98 } else { | |
99 instance_->Activate(); | |
100 } | |
101 } | |
102 | |
103 CookiesView::~CookiesView() { | |
104 cookies_tree_->SetModel(NULL); | |
105 } | |
106 | |
107 /////////////////////////////////////////////////////////////////////////////// | |
108 // CookiesView, TreeModelObserver overrides: | |
109 | |
110 void CookiesView::TreeNodesAdded(ui::TreeModel* model, | |
111 ui::TreeModelNode* parent, | |
112 int start, | |
113 int count) { | |
114 UpdateRemoveButtonsState(); | |
115 } | |
116 | |
117 /////////////////////////////////////////////////////////////////////////////// | |
118 // CookiesView, views::Buttonlistener implementation: | |
119 | |
120 void CookiesView::ButtonPressed( | |
121 views::Button* sender, const views::Event& event) { | |
122 if (sender == remove_button_) { | |
123 cookies_tree_->RemoveSelectedItems(); | |
124 if (cookies_tree_model_->GetRoot()->child_count() == 0) | |
125 UpdateForEmptyState(); | |
126 } else if (sender == remove_all_button_) { | |
127 cookies_tree_model_->DeleteAllStoredObjects(); | |
128 UpdateForEmptyState(); | |
129 } else if (sender == clear_search_button_) { | |
130 ResetSearchQuery(); | |
131 } | |
132 } | |
133 | |
134 /////////////////////////////////////////////////////////////////////////////// | |
135 // CookiesView, views::TextfieldController implementation: | |
136 | |
137 void CookiesView::ContentsChanged(views::Textfield* sender, | |
138 const std::wstring& new_contents) { | |
139 clear_search_button_->SetEnabled(!search_field_->text().empty()); | |
140 search_update_factory_.RevokeAll(); | |
141 MessageLoop::current()->PostDelayedTask(FROM_HERE, | |
142 search_update_factory_.NewRunnableMethod( | |
143 &CookiesView::UpdateSearchResults), kSearchFilterDelayMs); | |
144 } | |
145 | |
146 bool CookiesView::HandleKeyEvent(views::Textfield* sender, | |
147 const views::KeyEvent& key_event) { | |
148 if (key_event.key_code() == ui::VKEY_ESCAPE) { | |
149 ResetSearchQuery(); | |
150 } else if (key_event.key_code() == ui::VKEY_RETURN) { | |
151 search_update_factory_.RevokeAll(); | |
152 UpdateSearchResults(); | |
153 } | |
154 return false; | |
155 } | |
156 | |
157 /////////////////////////////////////////////////////////////////////////////// | |
158 // CookiesView, views::DialogDelegate implementation: | |
159 | |
160 int CookiesView::GetDialogButtons() const { | |
161 return MessageBoxFlags::DIALOGBUTTON_CANCEL; | |
162 } | |
163 | |
164 views::View* CookiesView::GetInitiallyFocusedView() { | |
165 return search_field_; | |
166 } | |
167 | |
168 bool CookiesView::CanResize() const { | |
169 return true; | |
170 } | |
171 | |
172 std::wstring CookiesView::GetWindowTitle() const { | |
173 return UTF16ToWide( | |
174 l10n_util::GetStringUTF16(IDS_COOKIES_WEBSITE_PERMISSIONS_WINDOW_TITLE)); | |
175 } | |
176 | |
177 void CookiesView::WindowClosing() { | |
178 instance_ = NULL; | |
179 } | |
180 | |
181 views::View* CookiesView::GetContentsView() { | |
182 return this; | |
183 } | |
184 | |
185 /////////////////////////////////////////////////////////////////////////////// | |
186 // CookiesView, views::View overrides: | |
187 | |
188 void CookiesView::Layout() { | |
189 // Lay out the Remove/Remove All buttons in the parent view. | |
190 gfx::Size ps = remove_button_->GetPreferredSize(); | |
191 gfx::Rect parent_bounds = parent()->GetContentsBounds(); | |
192 int y_buttons = | |
193 parent_bounds.bottom() - ps.height() - views::kButtonVEdgeMargin; | |
194 | |
195 remove_button_->SetBounds(views::kPanelHorizMargin, y_buttons, ps.width(), | |
196 ps.height()); | |
197 | |
198 ps = remove_all_button_->GetPreferredSize(); | |
199 int remove_all_x = remove_button_->x() + remove_button_->width() + | |
200 views::kRelatedControlHorizontalSpacing; | |
201 remove_all_button_->SetBounds(remove_all_x, y_buttons, ps.width(), | |
202 ps.height()); | |
203 | |
204 // Lay out this View | |
205 View::Layout(); | |
206 } | |
207 | |
208 gfx::Size CookiesView::GetPreferredSize() { | |
209 return gfx::Size(views::Window::GetLocalizedContentsSize( | |
210 IDS_COOKIES_DIALOG_WIDTH_CHARS, | |
211 IDS_COOKIES_DIALOG_HEIGHT_LINES)); | |
212 } | |
213 | |
214 void CookiesView::ViewHierarchyChanged(bool is_add, | |
215 views::View* parent, | |
216 views::View* child) { | |
217 if (is_add && child == this) | |
218 Init(); | |
219 } | |
220 | |
221 /////////////////////////////////////////////////////////////////////////////// | |
222 // CookiesView, views::TreeViewController overrides: | |
223 | |
224 void CookiesView::OnTreeViewSelectionChanged(views::TreeView* tree_view) { | |
225 UpdateRemoveButtonsState(); | |
226 CookieTreeNode::DetailedInfo detailed_info = | |
227 static_cast<CookieTreeNode*>(tree_view->GetSelectedNode())-> | |
228 GetDetailedInfo(); | |
229 if (detailed_info.node_type == CookieTreeNode::DetailedInfo::TYPE_COOKIE) { | |
230 UpdateVisibleDetailedInfo(cookie_info_view_); | |
231 cookie_info_view_->SetCookie(detailed_info.cookie->Domain(), | |
232 *detailed_info.cookie); | |
233 } else if (detailed_info.node_type == | |
234 CookieTreeNode::DetailedInfo::TYPE_DATABASE) { | |
235 UpdateVisibleDetailedInfo(database_info_view_); | |
236 database_info_view_->SetDatabaseInfo(*detailed_info.database_info); | |
237 } else if (detailed_info.node_type == | |
238 CookieTreeNode::DetailedInfo::TYPE_LOCAL_STORAGE) { | |
239 UpdateVisibleDetailedInfo(local_storage_info_view_); | |
240 local_storage_info_view_->SetLocalStorageInfo( | |
241 *detailed_info.local_storage_info); | |
242 } else if (detailed_info.node_type == | |
243 CookieTreeNode::DetailedInfo::TYPE_APPCACHE) { | |
244 UpdateVisibleDetailedInfo(appcache_info_view_); | |
245 appcache_info_view_->SetAppCacheInfo(detailed_info.appcache_info); | |
246 } else if (detailed_info.node_type == | |
247 CookieTreeNode::DetailedInfo::TYPE_INDEXED_DB) { | |
248 UpdateVisibleDetailedInfo(indexed_db_info_view_); | |
249 indexed_db_info_view_->SetIndexedDBInfo(*detailed_info.indexed_db_info); | |
250 } else { | |
251 UpdateVisibleDetailedInfo(cookie_info_view_); | |
252 cookie_info_view_->ClearCookieDisplay(); | |
253 } | |
254 } | |
255 | |
256 void CookiesView::OnTreeViewKeyDown(ui::KeyboardCode keycode) { | |
257 if (keycode == ui::VKEY_DELETE) | |
258 cookies_tree_->RemoveSelectedItems(); | |
259 } | |
260 | |
261 /////////////////////////////////////////////////////////////////////////////// | |
262 // CookiesView, public: | |
263 | |
264 void CookiesView::UpdateSearchResults() { | |
265 cookies_tree_model_->UpdateSearchResults(search_field_->text()); | |
266 UpdateRemoveButtonsState(); | |
267 } | |
268 | |
269 /////////////////////////////////////////////////////////////////////////////// | |
270 // CookiesView, private: | |
271 | |
272 CookiesView::CookiesView(Profile* profile) | |
273 : | |
274 search_label_(NULL), | |
275 search_field_(NULL), | |
276 clear_search_button_(NULL), | |
277 description_label_(NULL), | |
278 cookies_tree_(NULL), | |
279 info_panel_(NULL), | |
280 cookie_info_view_(NULL), | |
281 database_info_view_(NULL), | |
282 local_storage_info_view_(NULL), | |
283 appcache_info_view_(NULL), | |
284 indexed_db_info_view_(NULL), | |
285 remove_button_(NULL), | |
286 remove_all_button_(NULL), | |
287 profile_(profile), | |
288 ALLOW_THIS_IN_INITIALIZER_LIST(search_update_factory_(this)) { | |
289 } | |
290 | |
291 void CookiesView::Init() { | |
292 search_label_ = new views::Label( | |
293 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_SEARCH_LABEL))); | |
294 search_field_ = new views::Textfield; | |
295 search_field_->SetController(this); | |
296 clear_search_button_ = new views::NativeButton( | |
297 this, | |
298 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_CLEAR_SEARCH_LABEL))); | |
299 clear_search_button_->SetEnabled(false); | |
300 description_label_ = new views::Label( | |
301 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_INFO_LABEL))); | |
302 description_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); | |
303 cookies_tree_model_.reset(new CookiesTreeModel( | |
304 profile_->GetRequestContext()->GetCookieStore()->GetCookieMonster(), | |
305 new BrowsingDataDatabaseHelper(profile_), | |
306 new BrowsingDataLocalStorageHelper(profile_), | |
307 NULL, | |
308 new BrowsingDataAppCacheHelper(profile_), | |
309 BrowsingDataIndexedDBHelper::Create(profile_))); | |
310 cookies_tree_model_->AddCookiesTreeObserver(this); | |
311 | |
312 info_panel_ = new InfoPanelView; | |
313 cookie_info_view_ = new CookieInfoView(false); | |
314 database_info_view_ = new DatabaseInfoView; | |
315 local_storage_info_view_ = new LocalStorageInfoView; | |
316 appcache_info_view_ = new AppCacheInfoView; | |
317 indexed_db_info_view_ = new IndexedDBInfoView; | |
318 info_panel_->AddChildView(cookie_info_view_); | |
319 info_panel_->AddChildView(database_info_view_); | |
320 info_panel_->AddChildView(local_storage_info_view_); | |
321 info_panel_->AddChildView(appcache_info_view_); | |
322 info_panel_->AddChildView(indexed_db_info_view_); | |
323 | |
324 cookies_tree_ = new CookiesTreeView(cookies_tree_model_.get()); | |
325 remove_button_ = new views::NativeButton( | |
326 this, | |
327 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_REMOVE_LABEL))); | |
328 remove_all_button_ = new views::NativeButton( | |
329 this, | |
330 UTF16ToWide(l10n_util::GetStringUTF16(IDS_COOKIES_REMOVE_ALL_LABEL))); | |
331 | |
332 using views::GridLayout; | |
333 using views::ColumnSet; | |
334 | |
335 GridLayout* layout = GridLayout::CreatePanel(this); | |
336 SetLayoutManager(layout); | |
337 | |
338 const int five_column_layout_id = 0; | |
339 ColumnSet* column_set = layout->AddColumnSet(five_column_layout_id); | |
340 column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, | |
341 GridLayout::USE_PREF, 0, 0); | |
342 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); | |
343 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, | |
344 GridLayout::USE_PREF, 0, 0); | |
345 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); | |
346 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, | |
347 GridLayout::USE_PREF, 0, 0); | |
348 | |
349 const int single_column_layout_id = 1; | |
350 column_set = layout->AddColumnSet(single_column_layout_id); | |
351 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, | |
352 GridLayout::USE_PREF, 0, 0); | |
353 | |
354 layout->StartRow(0, five_column_layout_id); | |
355 layout->AddView(search_label_); | |
356 layout->AddView(search_field_); | |
357 layout->AddView(clear_search_button_); | |
358 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); | |
359 | |
360 layout->StartRow(0, single_column_layout_id); | |
361 layout->AddView(description_label_); | |
362 | |
363 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
364 layout->StartRow(1, single_column_layout_id); | |
365 cookies_tree_->set_lines_at_root(true); | |
366 cookies_tree_->set_auto_expand_children(true); | |
367 layout->AddView(cookies_tree_); | |
368 | |
369 cookies_tree_->SetController(this); | |
370 | |
371 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); | |
372 layout->StartRow(0, single_column_layout_id); | |
373 layout->AddView(info_panel_); | |
374 | |
375 // Add the Remove/Remove All buttons to the ClientView | |
376 parent()->AddChildView(remove_button_); | |
377 parent()->AddChildView(remove_all_button_); | |
378 if (!cookies_tree_model_.get()->GetRoot()->child_count()) { | |
379 UpdateForEmptyState(); | |
380 } else { | |
381 UpdateVisibleDetailedInfo(cookie_info_view_); | |
382 UpdateRemoveButtonsState(); | |
383 } | |
384 } | |
385 | |
386 void CookiesView::ResetSearchQuery() { | |
387 search_field_->SetText(std::wstring()); | |
388 clear_search_button_->SetEnabled(false); | |
389 UpdateSearchResults(); | |
390 } | |
391 | |
392 void CookiesView::UpdateForEmptyState() { | |
393 cookie_info_view_->ClearCookieDisplay(); | |
394 remove_button_->SetEnabled(false); | |
395 remove_all_button_->SetEnabled(false); | |
396 UpdateVisibleDetailedInfo(cookie_info_view_); | |
397 } | |
398 | |
399 void CookiesView::UpdateRemoveButtonsState() { | |
400 remove_button_->SetEnabled(cookies_tree_model_->GetRoot()-> | |
401 GetTotalNodeCount() > 1 && cookies_tree_->GetSelectedNode()); | |
402 remove_all_button_->SetEnabled(cookies_tree_model_->GetRoot()-> | |
403 GetTotalNodeCount() > 1); | |
404 } | |
405 | |
406 void CookiesView::UpdateVisibleDetailedInfo(views::View* view) { | |
407 cookie_info_view_->SetVisible(view == cookie_info_view_); | |
408 database_info_view_->SetVisible(view == database_info_view_); | |
409 local_storage_info_view_->SetVisible(view == local_storage_info_view_); | |
410 appcache_info_view_->SetVisible(view == appcache_info_view_); | |
411 indexed_db_info_view_->SetVisible(view == indexed_db_info_view_); | |
412 } | |
OLD | NEW |