diff options
author | raz@chromium.org <raz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-28 21:43:31 +0000 |
---|---|---|
committer | raz@chromium.org <raz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-28 21:43:31 +0000 |
commit | 099eaf0cd8ed17455d3f6a5ee88ed2783b454971 (patch) | |
tree | 6b77231bc4d99ed285a4cf7a9b393a0ce7c6b8a8 /chrome/browser/views/clear_server_data.cc | |
parent | 1424babd5dbbd5200d6e4b4ef71b38f791bce8b1 (diff) | |
download | chromium_src-099eaf0cd8ed17455d3f6a5ee88ed2783b454971.zip chromium_src-099eaf0cd8ed17455d3f6a5ee88ed2783b454971.tar.gz chromium_src-099eaf0cd8ed17455d3f6a5ee88ed2783b454971.tar.bz2 |
Added UI for clearing Chrome Sync data
- Created 2 tabs, one for for clearing local browsing data, one for clearing server data
- Refactored the old local browsing code to use a grid layout rather than less-wieldy math
- Controls on all tabs block while, closing dialog is disabled, new throbber is going while clear is in progress
- Clear server tab will be behind a flag until I deploy the server endpoint
- Retained old clearing behavior: dialog closes on successful lear
- Clear server UI only visible if user is syncing
Outstanding issues:
- Clearing currently causes an account to become unusable. The cause of the issue is a known problem with auth; currently investigating a fix
- Unlike local clearing, clearing server data is more likely to error out. For now I just show a label next to the clear button that says Error, allowing the user to try again
BUG=54349
TEST=Clear from UI, or run sync backend tests checked in for issue 54280
Review URL: http://codereview.chromium.org/3412032
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60845 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views/clear_server_data.cc')
-rw-r--r-- | chrome/browser/views/clear_server_data.cc | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/chrome/browser/views/clear_server_data.cc b/chrome/browser/views/clear_server_data.cc new file mode 100644 index 0000000..dae4387 --- /dev/null +++ b/chrome/browser/views/clear_server_data.cc @@ -0,0 +1,326 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/views/clear_server_data.h" + +#include "app/l10n_util.h" +#include "app/resource_bundle.h" +#include "base/command_line.h" +#include "base/string16.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/browser_window.h" +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/search_engines/template_url_model.h" +#include "chrome/browser/sync/profile_sync_service.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/pref_names.h" +#include "gfx/insets.h" +#include "grit/generated_resources.h" +#include "grit/locale_settings.h" +#include "net/url_request/url_request_context.h" +#include "views/background.h" +#include "views/controls/button/checkbox.h" +#include "views/controls/label.h" +#include "views/controls/separator.h" +#include "views/controls/throbber.h" +#include "views/grid_layout.h" +#include "views/standard_layout.h" +#include "views/widget/widget.h" +#include "views/window/dialog_client_view.h" +#include "views/window/window.h" + +using views::GridLayout; +using views::ColumnSet; + +// The combo box is vertically aligned to the 'time-period' label, which makes +// the combo box look a little too close to the check box above it when we use +// standard layout to separate them. We therefore add a little extra margin to +// the label, giving it a little breathing space. +static const int kExtraMarginForTimePeriodLabel = 3; + +//////////////////////////////////////////////////////////////////////////////// +// ClearServerDataView, public: + +ClearServerDataView::ClearServerDataView(Profile* profile, + ClearDataView* clear_data_view) + : profile_(profile), + clear_data_parent_window_(clear_data_view), + allow_clear_(true) { + DCHECK(profile); + DCHECK(clear_data_view); + + profile_->GetProfileSyncService()->ResetClearServerDataState(); + profile_->GetProfileSyncService()->AddObserver(this); + + Init(); + InitControlLayout(); + InitControlVisibility(); +} + +ClearServerDataView::~ClearServerDataView(void) { + profile_->GetProfileSyncService()->RemoveObserver(this); +} + +void ClearServerDataView::Init() { + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + gfx::Font title_font = + rb.GetFont(ResourceBundle::BaseFont).DeriveFont(0, gfx::Font::BOLD); + + flash_title_label_ = new views::Label( + l10n_util::GetString(IDS_CLEAR_DATA_ADOBE_FLASH_TITLE)); + flash_title_label_->SetFont(title_font); + + flash_description_label_= new views::Label( + l10n_util::GetString(IDS_CLEAR_DATA_ADOBE_FLASH_DESCRIPTION)); + flash_link_ = + new views::Link(l10n_util::GetString(IDS_FLASH_STORAGE_SETTINGS)); + flash_link_->SetController(this); + + chrome_sync_title_label_= new views::Label( + l10n_util::GetString(IDS_CLEAR_DATA_CHROME_SYNC_TITLE)); + chrome_sync_title_label_->SetFont(title_font); + + chrome_sync_description_label_ = new views::Label( + l10n_util::GetString(IDS_CLEAR_DATA_CLEAR_SERVER_DATA_DESCRIPTION)); + + clear_server_data_button_= new views::NativeButton( + this, l10n_util::GetString(IDS_CLEAR_DATA_CLEAR_BUTTON)); + + dashboard_label_ = new views::Label( + l10n_util::GetString(IDS_CLEAR_DASHBOARD_DESCRIPTION)); + + dashboard_link_ = new views::Link(); + dashboard_link_->SetController(this); + dashboard_link_->SetText( + l10n_util::GetString(IDS_SYNC_PRIVACY_DASHBOARD_LINK_LABEL)); + + status_label_ = new views::Label( + l10n_util::GetString(IDS_CLEAR_DATA_DELETING)); + throbber_ = new views::Throbber(50, true); +} + +void ClearServerDataView::InitControlLayout() { + GridLayout* layout = CreatePanelGridLayout(this); + this->SetLayoutManager(layout); + + int centered_column_set_id = 0; + ColumnSet * column_set = layout->AddColumnSet(centered_column_set_id); + column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, + GridLayout::USE_PREF, 0, 0); + + int left_aligned_column_set_id = 1; + column_set = layout->AddColumnSet(left_aligned_column_set_id); + column_set->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1, + GridLayout::USE_PREF, 0, 0); + + const int three_column_set_id = 2; + column_set = layout->AddColumnSet(three_column_set_id); + column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 0, + GridLayout::USE_PREF, 0, 0); + column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); + column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, + GridLayout::USE_PREF, 0, 0); + column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); + column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, + GridLayout::USE_PREF, 0, 0); + + AddWrappingLabelRow(layout, flash_title_label_, + centered_column_set_id, true); + AddWrappingLabelRow(layout, flash_description_label_, + centered_column_set_id, true); + + layout->StartRow(0, left_aligned_column_set_id); + layout->AddView(flash_link_); + layout->AddPaddingRow(0, kPanelVertMargin); + + AddWrappingLabelRow(layout, chrome_sync_title_label_, + centered_column_set_id, true); + AddWrappingLabelRow(layout, chrome_sync_description_label_, + centered_column_set_id, true); + + layout->StartRow(0, three_column_set_id); + layout->AddView(clear_server_data_button_, 1, 1, + GridLayout::LEADING, GridLayout::CENTER); + layout->AddView(status_label_, 1, 1, + GridLayout::LEADING, GridLayout::CENTER); + layout->AddView(throbber_, 1, 1, + GridLayout::TRAILING, GridLayout::CENTER); + layout->AddPaddingRow(0, kPanelVertMargin); + + AddWrappingLabelRow(layout, dashboard_label_, centered_column_set_id, true); + + layout->StartRow(0, left_aligned_column_set_id); + layout->AddView(dashboard_link_); +} + +void ClearServerDataView::InitControlVisibility() { + bool allow_clear_server_data_ui = + CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableClearServerData); + + bool sync_enabled = allow_clear_server_data_ui && + profile_->GetProfileSyncService()->HasSyncSetupCompleted(); + + // Hide progress indicators + throbber_->SetVisible(false); + status_label_->SetVisible(false); + + // Only show the sync portion if sync is enabled + chrome_sync_title_label_->SetVisible(sync_enabled); + chrome_sync_description_label_->SetVisible(sync_enabled); + clear_server_data_button_->SetVisible(sync_enabled); + dashboard_label_->SetVisible(sync_enabled); + dashboard_link_->SetVisible(sync_enabled); +} + +void ClearServerDataView::SetAllowClear(bool allow) { + allow_clear_ = allow; + UpdateControlEnabledState(); +} + +//////////////////////////////////////////////////////////////////////////////// +// ClearServerDataView, views::View implementation: + +void ClearServerDataView::AddWrappingLabelRow(views::GridLayout* layout, + views::Label* label, + int id, + bool related_follows) { + label->SetMultiLine(true); + label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + layout->StartRow(0, id); + layout->AddView(label); + AddSpacing(layout, related_follows); +} + +void ClearServerDataView::AddSpacing(views::GridLayout* layout, + bool related_follows) { + layout->AddPaddingRow(0, related_follows ? kRelatedControlVerticalSpacing + : kUnrelatedControlVerticalSpacing); +} + +gfx::Size ClearServerDataView::GetPreferredSize() { + // If we didn't return a preferred size, the containing view auto-sizes to + // the width of the narrowest button, which is not what we want + return gfx::Size(views::Window::GetLocalizedContentsSize( + IDS_CLEARDATA_DIALOG_WIDTH_CHARS, + IDS_CLEARDATA_DIALOG_HEIGHT_LINES)); +} + +//////////////////////////////////////////////////////////////////////////////// +// ClearServerDataView, views::ButtonListener implementation: + +void ClearServerDataView::ButtonPressed( + views::Button* sender, const views::Event& event) { + + if (sender == clear_server_data_button_) { + // Protect against the unlikely case where the server received a + // message, and the syncer syncs and resets itself before the + // user tries pressing the Clear button in this dialog again. + // TODO(raz) Confirm whether we have an issue here + if (profile_->GetProfileSyncService()->HasSyncSetupCompleted()) { + ConfirmMessageBoxDialog::Run( + GetWindow()->GetNativeWindow(), + this, + l10n_util::GetString(IDS_CONFIRM_CLEAR_DESCRIPTION), + l10n_util::GetString(IDS_CONFIRM_CLEAR_TITLE)); + } + } + + UpdateControlEnabledState(); +} + +void ClearServerDataView::LinkActivated(views::Link* source, + int event_flags) { + Browser* browser = Browser::Create(profile_); + if (source == flash_link_) { + browser->OpenURL(GURL(l10n_util::GetStringUTF8(IDS_FLASH_STORAGE_URL)), + GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); + browser->window()->Show(); + } else { + browser->OpenURL(GURL(l10n_util::GetStringUTF8(IDS_PRIVACY_DASHBOARD_URL)), + GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); + browser->window()->Show(); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// ClearServerDataView, ConfirmMessageBoxObserver implementation: + +void ClearServerDataView::OnConfirmMessageAccept() { + clear_data_parent_window_->StartClearingServerData(); + profile_->GetProfileSyncService()->ClearServerData(); + UpdateControlEnabledState(); +} + +void ClearServerDataView::OnConfirmMessageCancel() { + UpdateControlEnabledState(); +} + +//////////////////////////////////////////////////////////////////////////////// +// ClearServerDataView, ProfileSyncServiceObserver implementation: + +void ClearServerDataView::OnStateChanged() { + // Note that we are listening for all notifications here. Clearing from + // another browser should cause the "clear" button to go gray (if a + // notification nudges the syncer, causing OnStateChanged to be called with + // sync disabled) + UpdateControlEnabledState(); +} + +//////////////////////////////////////////////////////////////////////////////// +// ClearServerDataView, private: + +void ClearServerDataView::UpdateControlEnabledState() { + bool delete_in_progress = false; + + // We only want to call Suceeded/FailedClearingServerData once, not every + // time the view is refreshed. As such, on success/failure we handle that + // state and immediately reset things back to CLEAR_NOT_STARTED. + ProfileSyncService::ClearServerDataState clear_state = + profile_->GetProfileSyncService()->GetClearServerDataState(); + profile_->GetProfileSyncService()->ResetClearServerDataState(); + + switch (clear_state) { + case ProfileSyncService::CLEAR_NOT_STARTED: + // We can get here when we first start and after a failed clear (which + // does not close the tab), do nothing. + break; + case ProfileSyncService::CLEAR_CLEARING: + // Clearing buttons on all tabs are disabled at this + // point, throbber is going + status_label_->SetText(l10n_util::GetString(IDS_CLEAR_DATA_SENDING)); + status_label_->SetVisible(true); + delete_in_progress = true; + break; + case ProfileSyncService::CLEAR_FAILED: + // Show an error and reallow clearing + clear_data_parent_window_->FailedClearingServerData(); + status_label_->SetText(l10n_util::GetString(IDS_CLEAR_DATA_ERROR)); + status_label_->SetVisible(true); + delete_in_progress = false; + break; + case ProfileSyncService::CLEAR_SUCCEEDED: + // Close the dialog box, success! + status_label_->SetVisible(false); + delete_in_progress = false; + clear_data_parent_window_->SucceededClearingServerData(); + break; + } + + // allow_clear can be false when a local browsing data clear is happening + // from the neighboring tab. delete_in_progress means that a clear is + // pending in the current tab. + this->clear_server_data_button_->SetEnabled( + profile_->GetProfileSyncService()->HasSyncSetupCompleted() && + !delete_in_progress && allow_clear_); + + throbber_->SetVisible(delete_in_progress); + if (delete_in_progress) + throbber_->Start(); + else + throbber_->Stop(); +} + |