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

Side by Side Diff: chrome/browser/cocoa/clear_browsing_data_controller.mm

Issue 3840001: Revert 61848 - [Mac] UI for clearing sync data on the server.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years, 2 months 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 #import "chrome/browser/cocoa/clear_browsing_data_controller.h" 5 #import "chrome/browser/cocoa/clear_browsing_data_controller.h"
6 6
7 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "base/command_line.h"
9 #include "base/mac_util.h" 8 #include "base/mac_util.h"
10 #include "base/scoped_nsobject.h" 9 #include "base/scoped_nsobject.h"
11 #include "base/singleton.h" 10 #include "base/singleton.h"
12 #include "chrome/browser/browser.h" 11 #include "chrome/browser/browser.h"
13 #include "chrome/browser/browser_window.h" 12 #include "chrome/browser/browser_window.h"
14 #include "chrome/browser/browsing_data_remover.h" 13 #include "chrome/browser/browsing_data_remover.h"
15 #include "chrome/browser/platform_util.h"
16 #include "chrome/browser/prefs/pref_service.h" 14 #include "chrome/browser/prefs/pref_service.h"
17 #include "chrome/browser/profile.h" 15 #include "chrome/browser/profile.h"
18 #include "chrome/browser/sync/profile_sync_service.h"
19 #include "chrome/common/chrome_switches.h"
20 #include "chrome/common/pref_names.h" 16 #include "chrome/common/pref_names.h"
21 #include "grit/generated_resources.h"
22 #include "grit/locale_settings.h" 17 #include "grit/locale_settings.h"
23 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" 18 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
24 19
25 NSString* const kClearBrowsingDataControllerDidDelete = 20 NSString* const kClearBrowsingDataControllerDidDelete =
26 @"kClearBrowsingDataControllerDidDelete"; 21 @"kClearBrowsingDataControllerDidDelete";
27 NSString* const kClearBrowsingDataControllerRemoveMask = 22 NSString* const kClearBrowsingDataControllerRemoveMask =
28 @"kClearBrowsingDataControllerRemoveMask"; 23 @"kClearBrowsingDataControllerRemoveMask";
29 24
30 namespace {
31
32 // Compare function for -[NSArray sortedArrayUsingFunction:context:] that
33 // sorts the views in Y order top down.
34 NSInteger CompareFrameY(id view1, id view2, void* context) {
35 CGFloat y1 = NSMinY([view1 frame]);
36 CGFloat y2 = NSMinY([view2 frame]);
37 if (y1 < y2)
38 return NSOrderedDescending;
39 else if (y1 > y2)
40 return NSOrderedAscending;
41 else
42 return NSOrderedSame;
43 }
44
45 typedef std::map<Profile*, ClearBrowsingDataController*> ProfileControllerMap;
46
47 } // namespace
48
49 @interface ClearBrowsingDataController(Private) 25 @interface ClearBrowsingDataController(Private)
50 - (void)initFromPrefs; 26 - (void)initFromPrefs;
51 - (void)persistToPrefs; 27 - (void)persistToPrefs;
52 - (void)dataRemoverDidFinish; 28 - (void)dataRemoverDidFinish;
53 - (void)syncStateChanged;
54 @end 29 @end
55 30
56 class ClearBrowsingObserver : public BrowsingDataRemover::Observer, 31 class ClearBrowsingObserver : public BrowsingDataRemover::Observer {
57 public ProfileSyncServiceObserver {
58 public: 32 public:
59 ClearBrowsingObserver(ClearBrowsingDataController* controller) 33 ClearBrowsingObserver(ClearBrowsingDataController* controller)
60 : controller_(controller) { } 34 : controller_(controller) { }
61 void OnBrowsingDataRemoverDone() { [controller_ dataRemoverDidFinish]; } 35 void OnBrowsingDataRemoverDone() { [controller_ dataRemoverDidFinish]; }
62 void OnStateChanged() { [controller_ syncStateChanged]; }
63 private: 36 private:
64 ClearBrowsingDataController* controller_; 37 ClearBrowsingDataController* controller_;
65 }; 38 };
66 39
40 namespace {
41
42 typedef std::map<Profile*, ClearBrowsingDataController*> ProfileControllerMap;
43
44 } // namespace
45
67 @implementation ClearBrowsingDataController 46 @implementation ClearBrowsingDataController
68 47
69 @synthesize clearBrowsingHistory = clearBrowsingHistory_; 48 @synthesize clearBrowsingHistory = clearBrowsingHistory_;
70 @synthesize clearDownloadHistory = clearDownloadHistory_; 49 @synthesize clearDownloadHistory = clearDownloadHistory_;
71 @synthesize emptyCache = emptyCache_; 50 @synthesize emptyCache = emptyCache_;
72 @synthesize deleteCookies = deleteCookies_; 51 @synthesize deleteCookies = deleteCookies_;
73 @synthesize clearSavedPasswords = clearSavedPasswords_; 52 @synthesize clearSavedPasswords = clearSavedPasswords_;
74 @synthesize clearFormData = clearFormData_; 53 @synthesize clearFormData = clearFormData_;
75 @synthesize timePeriod = timePeriod_; 54 @synthesize timePeriod = timePeriod_;
76 @synthesize isClearing = isClearing_; 55 @synthesize isClearing = isClearing_;
77 @synthesize clearingStatus = clearingStatus_;
78 56
79 + (void)showClearBrowsingDialogForProfile:(Profile*)profile { 57 + (void)showClearBrowsingDialogForProfile:(Profile*)profile {
80 ClearBrowsingDataController* controller = 58 ClearBrowsingDataController* controller =
81 [ClearBrowsingDataController controllerForProfile:profile]; 59 [ClearBrowsingDataController controllerForProfile:profile];
82 if (![controller isWindowLoaded]) { 60 if (![controller isWindowLoaded]) {
83 // This function needs to return instead of blocking, to match the Windows 61 // This function needs to return instead of blocking, to match the windows
84 // version. It caused problems when launching the dialog from the 62 // api call. It caused problems when launching the dialog from the
85 // DomUI history page. See bug and code review for more details. 63 // DomUI history page. See bug and code review for more details.
86 // http://crbug.com/37976 64 // http://crbug.com/37976
87 [controller performSelector:@selector(runModalDialog) 65 [controller performSelector:@selector(runModalDialog)
88 withObject:nil 66 withObject:nil
89 afterDelay:0]; 67 afterDelay:0];
90 } 68 }
91 } 69 }
92 70
93 + (ClearBrowsingDataController *)controllerForProfile:(Profile*)profile { 71 + (ClearBrowsingDataController *)controllerForProfile:(Profile*)profile {
94 // Get the original profile in case we get here from an incognito window 72 // Get the original profile in case we get here from an incognito window
95 // |GetOriginalProfile()| will return the same profile if it is the original 73 // |GetOriginalProfile()| will return the same profile if it is the original
(...skipping 20 matching lines...) Expand all
116 - (id)initWithProfile:(Profile*)profile { 94 - (id)initWithProfile:(Profile*)profile {
117 DCHECK(profile); 95 DCHECK(profile);
118 // Use initWithWindowNibPath:: instead of initWithWindowNibName: so we 96 // Use initWithWindowNibPath:: instead of initWithWindowNibName: so we
119 // can override it in a unit test. 97 // can override it in a unit test.
120 NSString *nibpath = [mac_util::MainAppBundle() 98 NSString *nibpath = [mac_util::MainAppBundle()
121 pathForResource:@"ClearBrowsingData" 99 pathForResource:@"ClearBrowsingData"
122 ofType:@"nib"]; 100 ofType:@"nib"];
123 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { 101 if ((self = [super initWithWindowNibPath:nibpath owner:self])) {
124 profile_ = profile; 102 profile_ = profile;
125 observer_.reset(new ClearBrowsingObserver(self)); 103 observer_.reset(new ClearBrowsingObserver(self));
126 profile_->GetProfileSyncService()->ResetClearServerDataState();
127 profile_->GetProfileSyncService()->AddObserver(observer_.get());
128 [self initFromPrefs]; 104 [self initFromPrefs];
129 } 105 }
130 return self; 106 return self;
131 } 107 }
132 108
133 - (void)dealloc { 109 - (void)dealloc {
134 if (remover_) { 110 if (remover_) {
135 // We were destroyed while clearing history was in progress. This can only 111 // We were destroyed while clearing history was in progress. This can only
136 // occur during automated tests (normally the user can't close the dialog 112 // occur during automated tests (normally the user can't close the dialog
137 // while clearing is in progress as the dialog is modal and not closeable). 113 // while clearing is in progress as the dialog is modal and not closeable).
138 remover_->RemoveObserver(observer_.get()); 114 remover_->RemoveObserver(observer_.get());
139 } 115 }
140 profile_->GetProfileSyncService()->RemoveObserver(observer_.get());
141 [self setClearingStatus:nil];
142 116
143 [super dealloc]; 117 [super dealloc];
144 } 118 }
145 119
146 // Run application modal. 120 // Run application modal.
147 - (void)runModalDialog { 121 - (void)runModalDialog {
148 // Check again to make sure there is only one window. Since we use 122 // Check again to make sure there is only one window. Since we use
149 // |performSelector:afterDelay:| it is possible for this to somehow be 123 // |performSelector:afterDelay:| it is possible for this to somehow be
150 // triggered twice. 124 // triggered twice.
151 DCHECK([NSThread isMainThread]); 125 DCHECK([NSThread isMainThread]);
152 if (![self isWindowLoaded]) { 126 if (![self isWindowLoaded]) {
153 // It takes two passes to adjust the window size. The first pass is to 127 // The Window size in the nib is a min size, loop over the views collecting
154 // determine the width of all the non-wrappable items. The window is then 128 // the max they grew by, that is how much the window needs to be widened by.
155 // resized to that width. Once the width is fixed, the heights of the 129 CGFloat maxWidthGrowth = 0.0;
156 // variable-height items can then be calculated, the items can be spaced,
157 // and the window resized (again) if necessary.
158
159 NSWindow* window = [self window]; 130 NSWindow* window = [self window];
160 131 NSView* contentView = [window contentView];
161 // Adjust the widths of non-wrappable items.
162 CGFloat maxWidthGrowth = 0.0;
163 Class widthBasedTweakerClass = [GTMWidthBasedTweaker class]; 132 Class widthBasedTweakerClass = [GTMWidthBasedTweaker class];
164 for (NSTabViewItem* tabViewItem in [tabView_ tabViewItems]) 133 for (id subView in [contentView subviews]) {
165 for (NSView* subView in [[tabViewItem view] subviews]) 134 if ([subView isKindOfClass:widthBasedTweakerClass]) {
166 if ([subView isKindOfClass:widthBasedTweakerClass]) { 135 GTMWidthBasedTweaker* tweaker = subView;
167 GTMWidthBasedTweaker* tweaker = (GTMWidthBasedTweaker*)subView; 136 CGFloat delta = [tweaker changedWidth];
168 CGFloat delta = [tweaker changedWidth]; 137 maxWidthGrowth = std::max(maxWidthGrowth, delta);
169 maxWidthGrowth = std::max(maxWidthGrowth, delta); 138 }
170 } 139 }
171
172 // Adjust the width of the window.
173 if (maxWidthGrowth > 0.0) { 140 if (maxWidthGrowth > 0.0) {
174 NSSize adjustSize = NSMakeSize(maxWidthGrowth, 0); 141 NSRect rect = [contentView convertRect:[window frame] fromView:nil];
175 adjustSize = [[window contentView] convertSize:adjustSize toView:nil]; 142 rect.size.width += maxWidthGrowth;
176 NSRect windowFrame = [window frame]; 143 rect = [contentView convertRect:rect toView:nil];
177 windowFrame.size.width += adjustSize.width; 144 [window setFrame:rect display:NO];
178 [window setFrame:windowFrame display:NO]; 145 // For some reason the content view is resizing, but some times not
146 // adjusting its origin, so correct it manually.
147 [contentView setFrameOrigin:NSZeroPoint];
179 } 148 }
180
181 // Adjust the heights and locations of the items on the "Other data" tab.
182 CGFloat cumulativeHeightGrowth = 0.0;
183 NSArray* subViews =
184 [[otherDataTab_ subviews] sortedArrayUsingFunction:CompareFrameY
185 context:NULL];
186 for (NSView* view in subViews) {
187 if ([view isHidden])
188 continue;
189
190 if ([objectsToVerticallySize_ containsObject:view]) {
191 DCHECK([view isKindOfClass:[NSTextField class]]);
192 CGFloat viewHeightGrowth = [GTMUILocalizerAndLayoutTweaker
193 sizeToFitFixedWidthTextField:(NSTextField*)view];
194 if (viewHeightGrowth > 0.0)
195 cumulativeHeightGrowth += viewHeightGrowth;
196 }
197
198 NSRect viewFrame = [view frame];
199 viewFrame.origin.y -= cumulativeHeightGrowth;
200 [view setFrame:viewFrame];
201 }
202
203 // Adjust the height of the window.
204 if (cumulativeHeightGrowth > 0.0) {
205 NSSize adjustSize = NSMakeSize(0, cumulativeHeightGrowth);
206 adjustSize = [[window contentView] convertSize:adjustSize toView:nil];
207 NSRect windowFrame = [window frame];
208 windowFrame.size.height += adjustSize.height;
209 [window setFrame:windowFrame display:NO];
210 }
211
212 // Now start the modal loop. 149 // Now start the modal loop.
213 [NSApp runModalForWindow:window]; 150 [NSApp runModalForWindow:window];
214 } 151 }
215 } 152 }
216 153
217 - (int)removeMask { 154 - (int)removeMask {
218 int removeMask = 0L; 155 int removeMask = 0L;
219 if (clearBrowsingHistory_) 156 if (clearBrowsingHistory_)
220 removeMask |= BrowsingDataRemover::REMOVE_HISTORY; 157 removeMask |= BrowsingDataRemover::REMOVE_HISTORY;
221 if (clearDownloadHistory_) 158 if (clearDownloadHistory_)
222 removeMask |= BrowsingDataRemover::REMOVE_DOWNLOADS; 159 removeMask |= BrowsingDataRemover::REMOVE_DOWNLOADS;
223 if (emptyCache_) 160 if (emptyCache_)
224 removeMask |= BrowsingDataRemover::REMOVE_CACHE; 161 removeMask |= BrowsingDataRemover::REMOVE_CACHE;
225 if (deleteCookies_) 162 if (deleteCookies_)
226 removeMask |= BrowsingDataRemover::REMOVE_COOKIES; 163 removeMask |= BrowsingDataRemover::REMOVE_COOKIES;
227 if (clearSavedPasswords_) 164 if (clearSavedPasswords_)
228 removeMask |= BrowsingDataRemover::REMOVE_PASSWORDS; 165 removeMask |= BrowsingDataRemover::REMOVE_PASSWORDS;
229 if (clearFormData_) 166 if (clearFormData_)
230 removeMask |= BrowsingDataRemover::REMOVE_FORM_DATA; 167 removeMask |= BrowsingDataRemover::REMOVE_FORM_DATA;
231 return removeMask; 168 return removeMask;
232 } 169 }
233 170
234 // Called when the user clicks the "clear" button. Do the work and persist 171 // Called when the user clicks the "clear" button. Do the work and persist
235 // the prefs for next time. We don't stop the modal session until we get 172 // the prefs for next time. We don't stop the modal session until we get
236 // the callback from the BrowsingDataRemover so the window stays on the screen. 173 // the callback from the BrowsingDataRemover so the window stays on the screen.
237 // While we're working, dim the buttons so the user can't click them. 174 // While we're working, dim the buttons so the user can't click them.
238 - (IBAction)clearData:(id)sender { 175 - (IBAction)clearData:(id)sender {
239 // Set that we're working so that the buttons disable. 176 // Set that we're working so that the buttons disable.
240 [self setClearingStatus:l10n_util::GetNSString(IDS_CLEAR_DATA_DELETING)];
241 [self setIsClearing:YES]; 177 [self setIsClearing:YES];
242 178
243 [self persistToPrefs]; 179 [self persistToPrefs];
244 180
245 // BrowsingDataRemover deletes itself when done. 181 // BrowsingDataRemover deletes itself when done.
246 remover_ = new BrowsingDataRemover(profile_, 182 remover_ = new BrowsingDataRemover(profile_,
247 static_cast<BrowsingDataRemover::TimePeriod>(timePeriod_), 183 static_cast<BrowsingDataRemover::TimePeriod>(timePeriod_),
248 base::Time()); 184 base::Time());
249 remover_->AddObserver(observer_.get()); 185 remover_->AddObserver(observer_.get());
250 remover_->Remove([self removeMask]); 186 remover_->Remove([self removeMask]);
(...skipping 10 matching lines...) Expand all
261 // The "Clear Data" dialog is app-modal on OS X. Hence, close it before 197 // The "Clear Data" dialog is app-modal on OS X. Hence, close it before
262 // opening a tab with flash settings. 198 // opening a tab with flash settings.
263 [self closeDialog]; 199 [self closeDialog];
264 200
265 Browser* browser = Browser::Create(profile_); 201 Browser* browser = Browser::Create(profile_);
266 browser->OpenURL(GURL(l10n_util::GetStringUTF8(IDS_FLASH_STORAGE_URL)), 202 browser->OpenURL(GURL(l10n_util::GetStringUTF8(IDS_FLASH_STORAGE_URL)),
267 GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); 203 GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK);
268 browser->window()->Show(); 204 browser->window()->Show();
269 } 205 }
270 206
271 - (IBAction)openGoogleDashboard:(id)sender {
272 // The "Clear Data" dialog is app-modal on OS X. Hence, close it before
273 // opening a tab with the dashboard.
274 [self closeDialog];
275
276 Browser* browser = Browser::Create(profile_);
277 browser->OpenURL(GURL(l10n_util::GetStringUTF8(IDS_PRIVACY_DASHBOARD_URL)),
278 GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK);
279 browser->window()->Show();
280 }
281
282 - (void)closeDialog { 207 - (void)closeDialog {
283 ProfileControllerMap* map = Singleton<ProfileControllerMap>::get(); 208 ProfileControllerMap* map = Singleton<ProfileControllerMap>::get();
284 ProfileControllerMap::iterator it = map->find(profile_); 209 ProfileControllerMap::iterator it = map->find(profile_);
285 if (it != map->end()) { 210 if (it != map->end()) {
286 map->erase(it); 211 map->erase(it);
287 } 212 }
288 [self autorelease]; 213 [self autorelease];
289 [[self window] orderOut:self]; 214 [[self window] orderOut:self];
290 [NSApp stopModal]; 215 [NSApp stopModal];
291 } 216 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; 249 NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
325 int removeMask = [self removeMask]; 250 int removeMask = [self removeMask];
326 NSDictionary* userInfo = 251 NSDictionary* userInfo =
327 [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:removeMask] 252 [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:removeMask]
328 forKey:kClearBrowsingDataControllerRemoveMask]; 253 forKey:kClearBrowsingDataControllerRemoveMask];
329 [center postNotificationName:kClearBrowsingDataControllerDidDelete 254 [center postNotificationName:kClearBrowsingDataControllerDidDelete
330 object:self 255 object:self
331 userInfo:userInfo]; 256 userInfo:userInfo];
332 257
333 [self closeDialog]; 258 [self closeDialog];
334 [self setClearingStatus:nil]; 259 [[self window] orderOut:self];
335 [self setIsClearing:NO]; 260 [self setIsClearing:NO];
336 remover_ = NULL; 261 remover_ = NULL;
337 } 262 }
338 263
339 - (IBAction)stopSyncAndDeleteData:(id)sender {
340 // Protect against the unlikely case where the server received a message, and
341 // the syncer syncs and resets itself before the user tries pressing the Clear
342 // button in this dialog again. TODO(raz) Confirm whether we have an issue
343 // here
344 if (profile_->GetProfileSyncService()->HasSyncSetupCompleted()) {
345 bool clear = platform_util::SimpleYesNoBox(
346 nil,
347 l10n_util::GetStringUTF16(IDS_CONFIRM_CLEAR_TITLE),
348 l10n_util::GetStringUTF16(IDS_CONFIRM_CLEAR_DESCRIPTION));
349 if (clear) {
350 profile_->GetProfileSyncService()->ClearServerData();
351 [self syncStateChanged];
352 }
353 }
354 }
355
356 - (void)syncStateChanged {
357 bool deleteInProgress = false;
358
359 ProfileSyncService::ClearServerDataState clearState =
360 profile_->GetProfileSyncService()->GetClearServerDataState();
361 profile_->GetProfileSyncService()->ResetClearServerDataState();
362
363 switch (clearState) {
364 case ProfileSyncService::CLEAR_NOT_STARTED:
365 // This can occur on a first start and after a failed clear (which does
366 // not close the tab). Do nothing.
367 break;
368 case ProfileSyncService::CLEAR_CLEARING:
369 // Clearing buttons on all tabs are disabled at this point, throbber is
370 // going.
371 [self setClearingStatus:l10n_util::GetNSString(IDS_CLEAR_DATA_SENDING)];
372 deleteInProgress = true;
373 break;
374 case ProfileSyncService::CLEAR_FAILED:
375 // Show an error and reallow clearing.
376 [self setClearingStatus:l10n_util::GetNSString(IDS_CLEAR_DATA_ERROR)];
377 deleteInProgress = false;
378 break;
379 case ProfileSyncService::CLEAR_SUCCEEDED:
380 // Close the dialog box, success!
381 [self setClearingStatus:nil];
382 deleteInProgress = false;
383 [self closeDialog];
384 break;
385 }
386
387 [self setIsClearing:deleteInProgress];
388 }
389
390 - (BOOL)isSyncEnabled {
391 BOOL allowClearServerDataUI =
392 CommandLine::ForCurrentProcess()->HasSwitch(
393 switches::kEnableClearServerData);
394
395 return allowClearServerDataUI &&
396 profile_->GetProfileSyncService()->HasSyncSetupCompleted();
397 }
398
399 - (NSFont*)labelFont {
400 return [NSFont boldSystemFontOfSize:13];
401 }
402
403 @end 264 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698