Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(395)

Side by Side Diff: chrome/browser/ui/views/collected_cookies_views.cc

Issue 2511163002: harmony: convert collected cookies dialog (Closed)
Patch Set: remove ?: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/collected_cookies_views.h" 5 #include "chrome/browser/ui/views/collected_cookies_views.h"
6 6
7 #include "base/macros.h" 7 #include "base/macros.h"
8 #include "chrome/browser/browsing_data/browsing_data_appcache_helper.h" 8 #include "chrome/browser/browsing_data/browsing_data_appcache_helper.h"
9 #include "chrome/browser/browsing_data/browsing_data_channel_id_helper.h" 9 #include "chrome/browser/browsing_data/browsing_data_channel_id_helper.h"
10 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h" 10 #include "chrome/browser/browsing_data/browsing_data_cookie_helper.h"
11 #include "chrome/browser/browsing_data/browsing_data_database_helper.h" 11 #include "chrome/browser/browsing_data/browsing_data_database_helper.h"
12 #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h" 12 #include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
13 #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h" 13 #include "chrome/browser/browsing_data/browsing_data_indexed_db_helper.h"
14 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" 14 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
15 #include "chrome/browser/browsing_data/cookies_tree_model.h" 15 #include "chrome/browser/browsing_data/cookies_tree_model.h"
16 #include "chrome/browser/chrome_notification_types.h" 16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/content_settings/cookie_settings_factory.h" 17 #include "chrome/browser/content_settings/cookie_settings_factory.h"
18 #include "chrome/browser/content_settings/local_shared_objects_container.h" 18 #include "chrome/browser/content_settings/local_shared_objects_container.h"
19 #include "chrome/browser/content_settings/tab_specific_content_settings.h" 19 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
20 #include "chrome/browser/infobars/infobar_service.h" 20 #include "chrome/browser/infobars/infobar_service.h"
21 #include "chrome/browser/profiles/profile.h" 21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/ui/collected_cookies_infobar_delegate.h" 22 #include "chrome/browser/ui/collected_cookies_infobar_delegate.h"
23 #include "chrome/browser/ui/views/cookie_info_view.h" 23 #include "chrome/browser/ui/views/cookie_info_view.h"
24 #include "chrome/browser/ui/views/harmony/layout_delegate.h"
25 #include "chrome/browser/ui/views/layout_utils.h"
24 #include "chrome/common/pref_names.h" 26 #include "chrome/common/pref_names.h"
25 #include "chrome/grit/generated_resources.h" 27 #include "chrome/grit/generated_resources.h"
26 #include "chrome/grit/locale_settings.h" 28 #include "chrome/grit/locale_settings.h"
27 #include "chrome/grit/theme_resources.h" 29 #include "chrome/grit/theme_resources.h"
28 #include "components/constrained_window/constrained_window_views.h" 30 #include "components/constrained_window/constrained_window_views.h"
29 #include "components/content_settings/core/browser/cookie_settings.h" 31 #include "components/content_settings/core/browser/cookie_settings.h"
30 #include "components/content_settings/core/common/pref_names.h" 32 #include "components/content_settings/core/common/pref_names.h"
31 #include "components/prefs/pref_service.h" 33 #include "components/prefs/pref_service.h"
32 #include "components/strings/grit/components_strings.h" 34 #include "components/strings/grit/components_strings.h"
33 #include "content/public/browser/notification_details.h" 35 #include "content/public/browser/notification_details.h"
(...skipping 24 matching lines...) Expand all
58 // Width of the infobar frame. 60 // Width of the infobar frame.
59 const int kInfobarBorderSize = 1; 61 const int kInfobarBorderSize = 1;
60 62
61 // Dimensions of the tree views. 63 // Dimensions of the tree views.
62 const int kTreeViewWidth = 400; 64 const int kTreeViewWidth = 400;
63 const int kTreeViewHeight = 125; 65 const int kTreeViewHeight = 125;
64 66
65 // The color of the border around the cookies tree view. 67 // The color of the border around the cookies tree view.
66 const SkColor kCookiesBorderColor = SkColorSetRGB(0xC8, 0xC8, 0xC8); 68 const SkColor kCookiesBorderColor = SkColorSetRGB(0xC8, 0xC8, 0xC8);
67 69
68 // Spacing constants used with the new dialog style. 70 // Spacing constants used with non-Harmony dialogs.
69 const int kTabbedPaneTopPadding = 14; 71 const int kTabbedPaneTopPadding = 14;
70 const int kLabelBottomPadding = 17;
71 const int kCookieInfoBottomPadding = 4; 72 const int kCookieInfoBottomPadding = 4;
72 const int kVPanelPadding = 15; 73
74 LayoutDelegate::LayoutDistanceType GetTreeviewToButtonsDistanceType() {
75 // Hack: in the Harmony specs, the buttons under the treeview are "unrelated"
76 // to it (which looks better), but in the existing dialog they were related.
77 return LayoutDelegate::Get()->IsHarmonyMode()
78 ? LayoutDelegate::LayoutDistanceType::
79 UNRELATED_CONTROL_VERTICAL_SPACING
80 : LayoutDelegate::LayoutDistanceType::
81 RELATED_CONTROL_VERTICAL_SPACING;
82 }
73 83
74 } // namespace 84 } // namespace
75 85
76 // A custom view that conditionally displays an infobar. 86 // A custom view that conditionally displays an infobar.
77 class InfobarView : public views::View { 87 class InfobarView : public views::View {
78 public: 88 public:
79 InfobarView() { 89 InfobarView() {
80 content_ = new views::View; 90 content_ = new views::View;
81 SkColor border_color = SK_ColorGRAY; 91 SkColor border_color = SK_ColorGRAY;
82 content_->SetBorder( 92 content_->SetBorder(
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 } 273 }
264 274
265 /////////////////////////////////////////////////////////////////////////////// 275 ///////////////////////////////////////////////////////////////////////////////
266 // CollectedCookiesViews, views::View overrides: 276 // CollectedCookiesViews, views::View overrides:
267 277
268 gfx::Size CollectedCookiesViews::GetMinimumSize() const { 278 gfx::Size CollectedCookiesViews::GetMinimumSize() const {
269 // Allow UpdateWebContentsModalDialogPosition to clamp the dialog width. 279 // Allow UpdateWebContentsModalDialogPosition to clamp the dialog width.
270 return gfx::Size(0, View::GetMinimumSize().height()); 280 return gfx::Size(0, View::GetMinimumSize().height());
271 } 281 }
272 282
283 gfx::Size CollectedCookiesViews::GetPreferredSize() const {
284 int preferred = LayoutDelegate::Get()->GetDialogPreferredWidth(
285 LayoutDelegate::DialogWidthType::MEDIUM);
286 return gfx::Size(preferred ? preferred : View::GetPreferredSize().width(),
287 View::GetPreferredSize().height());
288 }
289
273 void CollectedCookiesViews::ViewHierarchyChanged( 290 void CollectedCookiesViews::ViewHierarchyChanged(
274 const ViewHierarchyChangedDetails& details) { 291 const ViewHierarchyChangedDetails& details) {
275 views::DialogDelegateView::ViewHierarchyChanged(details); 292 views::DialogDelegateView::ViewHierarchyChanged(details);
276 if (details.is_add && details.child == this) 293 if (details.is_add && details.child == this)
277 Init(); 294 Init();
278 } 295 }
279 296
280 //////////////////////////////////////////////////////////////////////////////// 297 ////////////////////////////////////////////////////////////////////////////////
281 // CollectedCookiesViews, private: 298 // CollectedCookiesViews, private:
282 299
283 CollectedCookiesViews::~CollectedCookiesViews() { 300 CollectedCookiesViews::~CollectedCookiesViews() {
284 allowed_cookies_tree_->SetModel(NULL); 301 allowed_cookies_tree_->SetModel(NULL);
285 blocked_cookies_tree_->SetModel(NULL); 302 blocked_cookies_tree_->SetModel(NULL);
286 } 303 }
287 304
288 void CollectedCookiesViews::Init() { 305 void CollectedCookiesViews::Init() {
289 using views::GridLayout; 306 using views::GridLayout;
290 307
291 GridLayout* layout = GridLayout::CreatePanel(this); 308 GridLayout* layout = new GridLayout(this);
309 if (LayoutDelegate::Get()->UseExtraDialogPadding())
310 layout->SetInsets(gfx::Insets(kTabbedPaneTopPadding, 0, 0, 0));
292 SetLayoutManager(layout); 311 SetLayoutManager(layout);
293 312
294 const int single_column_layout_id = 0; 313 const int single_column_layout_id = 0;
295 views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id); 314 views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
296 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, 315 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
297 GridLayout::USE_PREF, 0, 0); 316 GridLayout::USE_PREF, 0, 0);
298 317
299 layout->StartRow(0, single_column_layout_id); 318 layout->StartRow(0, single_column_layout_id);
300 views::TabbedPane* tabbed_pane = new views::TabbedPane(); 319 views::TabbedPane* tabbed_pane = new views::TabbedPane();
301 layout->SetInsets(gfx::Insets(kTabbedPaneTopPadding, 0, 0, 0));
302 320
303 layout->AddView(tabbed_pane); 321 layout->AddView(tabbed_pane);
304 // NOTE: Panes must be added after |tabbed_pane| has been added to its parent. 322 // NOTE: Panes must be added after |tabbed_pane| has been added to its parent.
305 base::string16 label_allowed = l10n_util::GetStringUTF16( 323 base::string16 label_allowed = l10n_util::GetStringUTF16(
306 IDS_COLLECTED_COOKIES_ALLOWED_COOKIES_TAB_LABEL); 324 IDS_COLLECTED_COOKIES_ALLOWED_COOKIES_TAB_LABEL);
307 base::string16 label_blocked = l10n_util::GetStringUTF16( 325 base::string16 label_blocked = l10n_util::GetStringUTF16(
308 IDS_COLLECTED_COOKIES_BLOCKED_COOKIES_TAB_LABEL); 326 IDS_COLLECTED_COOKIES_BLOCKED_COOKIES_TAB_LABEL);
309 tabbed_pane->AddTab(label_allowed, CreateAllowedPane()); 327 tabbed_pane->AddTab(label_allowed, CreateAllowedPane());
310 tabbed_pane->AddTab(label_blocked, CreateBlockedPane()); 328 tabbed_pane->AddTab(label_blocked, CreateBlockedPane());
311 tabbed_pane->SelectTabAt(0); 329 tabbed_pane->SelectTabAt(0);
312 tabbed_pane->set_listener(this); 330 tabbed_pane->set_listener(this);
313 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 331 if (LayoutDelegate::Get()->UseExtraDialogPadding()) {
332 layout->AddPaddingRow(0, LayoutDelegate::Get()->GetLayoutDistance(
333 LayoutDelegate::LayoutDistanceType::
334 RELATED_CONTROL_VERTICAL_SPACING));
335 }
314 336
315 layout->StartRow(0, single_column_layout_id); 337 layout->StartRow(0, single_column_layout_id);
316 cookie_info_view_ = new CookieInfoView(); 338 cookie_info_view_ = new CookieInfoView();
317 layout->AddView(cookie_info_view_); 339 layout->AddView(cookie_info_view_);
318 layout->AddPaddingRow(0, kCookieInfoBottomPadding); 340 if (LayoutDelegate::Get()->UseExtraDialogPadding())
341 layout->AddPaddingRow(0, kCookieInfoBottomPadding);
319 342
320 layout->StartRow(0, single_column_layout_id); 343 layout->StartRow(0, single_column_layout_id);
321 infobar_ = new InfobarView(); 344 infobar_ = new InfobarView();
322 layout->AddView(infobar_); 345 layout->AddView(infobar_);
323 346
324 EnableControls(); 347 EnableControls();
325 ShowCookieInfo(); 348 ShowCookieInfo();
326 } 349 }
327 350
328 views::View* CollectedCookiesViews::CreateAllowedPane() { 351 views::View* CollectedCookiesViews::CreateAllowedPane() {
(...skipping 18 matching lines...) Expand all
347 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_BLOCK_BUTTON)); 370 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_BLOCK_BUTTON));
348 371
349 delete_allowed_button_ = views::MdTextButton::CreateSecondaryUiButton(this, 372 delete_allowed_button_ = views::MdTextButton::CreateSecondaryUiButton(this,
350 l10n_util::GetStringUTF16(IDS_COOKIES_REMOVE_LABEL)); 373 l10n_util::GetStringUTF16(IDS_COOKIES_REMOVE_LABEL));
351 374
352 // Create the view that holds all the controls together. This will be the 375 // Create the view that holds all the controls together. This will be the
353 // pane added to the tabbed pane. 376 // pane added to the tabbed pane.
354 using views::GridLayout; 377 using views::GridLayout;
355 378
356 views::View* pane = new views::View(); 379 views::View* pane = new views::View();
357 GridLayout* layout = GridLayout::CreatePanel(pane); 380 GridLayout* layout = layout_utils::CreatePanelLayout(pane);
358 layout->SetInsets(kVPanelPadding, views::kButtonHEdgeMarginNew,
359 kVPanelPadding, views::kButtonHEdgeMarginNew);
360 pane->SetLayoutManager(layout);
361 381
362 const int single_column_layout_id = 0; 382 const int single_column_layout_id = 0;
363 views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id); 383 views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
364 column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1, 384 column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1,
365 GridLayout::USE_PREF, 0, 0); 385 GridLayout::USE_PREF, 0, 0);
366 386
367 const int three_columns_layout_id = 1; 387 const int three_columns_layout_id = 1;
368 column_set = layout->AddColumnSet(three_columns_layout_id); 388 column_set = layout->AddColumnSet(three_columns_layout_id);
369 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, 389 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
370 GridLayout::USE_PREF, 0, 0); 390 GridLayout::USE_PREF, 0, 0);
371 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); 391 column_set->AddPaddingColumn(0, LayoutDelegate::Get()->GetLayoutDistance(
392 LayoutDelegate::LayoutDistanceType::
393 RELATED_CONTROL_HORIZONTAL_SPACING));
372 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, 394 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
373 GridLayout::USE_PREF, 0, 0); 395 GridLayout::USE_PREF, 0, 0);
374 396
375 layout->StartRow(0, single_column_layout_id); 397 layout->StartRow(0, single_column_layout_id);
376 layout->AddView(allowed_label_); 398 layout->AddView(allowed_label_);
377 layout->AddPaddingRow(0, kLabelBottomPadding); 399 layout->AddPaddingRow(0, LayoutDelegate::Get()->GetLayoutDistance(
400 LayoutDelegate::LayoutDistanceType::
401 UNRELATED_CONTROL_VERTICAL_SPACING));
378 402
379 layout->StartRow(1, single_column_layout_id); 403 layout->StartRow(1, single_column_layout_id);
380 layout->AddView(CreateScrollView(allowed_cookies_tree_), 1, 1, 404 layout->AddView(CreateScrollView(allowed_cookies_tree_), 1, 1,
381 GridLayout::FILL, GridLayout::FILL, kTreeViewWidth, 405 GridLayout::FILL, GridLayout::FILL, kTreeViewWidth,
382 kTreeViewHeight); 406 kTreeViewHeight);
383 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 407 layout->AddPaddingRow(0, LayoutDelegate::Get()->GetLayoutDistance(
408 GetTreeviewToButtonsDistanceType()));
384 409
385 layout->StartRow(0, three_columns_layout_id); 410 layout->StartRow(0, three_columns_layout_id);
386 layout->AddView(block_allowed_button_); 411 layout->AddView(block_allowed_button_);
387 layout->AddView(delete_allowed_button_); 412 layout->AddView(delete_allowed_button_);
388 413
389 return pane; 414 return pane;
390 } 415 }
391 416
392 views::View* CollectedCookiesViews::CreateBlockedPane() { 417 views::View* CollectedCookiesViews::CreateBlockedPane() {
393 TabSpecificContentSettings* content_settings = 418 TabSpecificContentSettings* content_settings =
(...skipping 25 matching lines...) Expand all
419 this, l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_ALLOW_BUTTON)); 444 this, l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_ALLOW_BUTTON));
420 for_session_blocked_button_ = views::MdTextButton::CreateSecondaryUiButton( 445 for_session_blocked_button_ = views::MdTextButton::CreateSecondaryUiButton(
421 this, 446 this,
422 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_SESSION_ONLY_BUTTON)); 447 l10n_util::GetStringUTF16(IDS_COLLECTED_COOKIES_SESSION_ONLY_BUTTON));
423 448
424 // Create the view that holds all the controls together. This will be the 449 // Create the view that holds all the controls together. This will be the
425 // pane added to the tabbed pane. 450 // pane added to the tabbed pane.
426 using views::GridLayout; 451 using views::GridLayout;
427 452
428 views::View* pane = new views::View(); 453 views::View* pane = new views::View();
429 GridLayout* layout = GridLayout::CreatePanel(pane); 454 GridLayout* layout = layout_utils::CreatePanelLayout(pane);
430 layout->SetInsets(kVPanelPadding, views::kButtonHEdgeMarginNew,
431 kVPanelPadding, views::kButtonHEdgeMarginNew);
432 pane->SetLayoutManager(layout);
433 455
434 const int single_column_layout_id = 0; 456 const int single_column_layout_id = 0;
435 views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id); 457 views::ColumnSet* column_set = layout->AddColumnSet(single_column_layout_id);
436 column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1, 458 column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1,
437 GridLayout::USE_PREF, 0, 0); 459 GridLayout::USE_PREF, 0, 0);
438 460
439 const int three_columns_layout_id = 1; 461 const int three_columns_layout_id = 1;
440 column_set = layout->AddColumnSet(three_columns_layout_id); 462 column_set = layout->AddColumnSet(three_columns_layout_id);
441 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, 463 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
442 GridLayout::USE_PREF, 0, 0); 464 GridLayout::USE_PREF, 0, 0);
443 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); 465 column_set->AddPaddingColumn(0, LayoutDelegate::Get()->GetLayoutDistance(
466 LayoutDelegate::LayoutDistanceType::
467 RELATED_CONTROL_HORIZONTAL_SPACING));
444 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, 468 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
445 GridLayout::USE_PREF, 0, 0); 469 GridLayout::USE_PREF, 0, 0);
446 470
447 layout->StartRow(0, single_column_layout_id); 471 layout->StartRow(0, single_column_layout_id);
448 layout->AddView(blocked_label_, 1, 1, GridLayout::FILL, GridLayout::FILL); 472 layout->AddView(blocked_label_, 1, 1, GridLayout::FILL, GridLayout::FILL);
449 layout->AddPaddingRow(0, kLabelBottomPadding); 473 layout->AddPaddingRow(0, LayoutDelegate::Get()->GetLayoutDistance(
474 LayoutDelegate::LayoutDistanceType::
475 UNRELATED_CONTROL_VERTICAL_SPACING));
450 476
451 layout->StartRow(1, single_column_layout_id); 477 layout->StartRow(1, single_column_layout_id);
452 layout->AddView( 478 layout->AddView(
453 CreateScrollView(blocked_cookies_tree_), 1, 1, 479 CreateScrollView(blocked_cookies_tree_), 1, 1,
454 GridLayout::FILL, GridLayout::FILL, kTreeViewWidth, kTreeViewHeight); 480 GridLayout::FILL, GridLayout::FILL, kTreeViewWidth, kTreeViewHeight);
455 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 481 layout->AddPaddingRow(0, LayoutDelegate::Get()->GetLayoutDistance(
482 GetTreeviewToButtonsDistanceType()));
456 483
457 layout->StartRow(0, three_columns_layout_id); 484 layout->StartRow(0, three_columns_layout_id);
458 layout->AddView(allow_blocked_button_); 485 layout->AddView(allow_blocked_button_);
459 layout->AddView(for_session_blocked_button_); 486 layout->AddView(for_session_blocked_button_);
460 487
461 return pane; 488 return pane;
462 } 489 }
463 490
464 views::View* CollectedCookiesViews::CreateScrollView(views::TreeView* pane) { 491 views::View* CollectedCookiesViews::CreateScrollView(views::TreeView* pane) {
465 views::ScrollView* scroll_view = new views::ScrollView(); 492 views::ScrollView* scroll_view = new views::ScrollView();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 /////////////////////////////////////////////////////////////////////////////// 561 ///////////////////////////////////////////////////////////////////////////////
535 // CollectedCookiesViews, content::NotificationObserver implementation: 562 // CollectedCookiesViews, content::NotificationObserver implementation:
536 563
537 void CollectedCookiesViews::Observe( 564 void CollectedCookiesViews::Observe(
538 int type, 565 int type,
539 const content::NotificationSource& source, 566 const content::NotificationSource& source,
540 const content::NotificationDetails& details) { 567 const content::NotificationDetails& details) {
541 DCHECK_EQ(chrome::NOTIFICATION_COLLECTED_COOKIES_SHOWN, type); 568 DCHECK_EQ(chrome::NOTIFICATION_COLLECTED_COOKIES_SHOWN, type);
542 GetWidget()->Close(); 569 GetWidget()->Close();
543 } 570 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/collected_cookies_views.h ('k') | chrome/browser/ui/views/harmony/harmony_layout_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698