summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa
diff options
context:
space:
mode:
authorpinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-29 14:30:38 +0000
committerpinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-29 14:30:38 +0000
commit93e18176c674291dc8f6cf6dfdc2d9b7227f561c (patch)
tree366da45470e2fa32cd4a91a6fbf7d955eec29192 /chrome/browser/cocoa
parent2946da155c393685c6cc3f7fe5e28d347bf6642d (diff)
downloadchromium_src-93e18176c674291dc8f6cf6dfdc2d9b7227f561c.zip
chromium_src-93e18176c674291dc8f6cf6dfdc2d9b7227f561c.tar.gz
chromium_src-93e18176c674291dc8f6cf6dfdc2d9b7227f561c.tar.bz2
Implement Clear Browser Data for Mac as an app modal dialog. Uses the profile of the given window or the default profile if run with no windows open. Add a setter to the throbber so it can be used in a nib file.
BUG=none TEST=clear browser functionality (note that clearing passwords doesn't work) and checkbox persistance. Review URL: http://codereview.chromium.org/112065 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17186 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa')
-rw-r--r--chrome/browser/cocoa/browser_window_cocoa.mm8
-rw-r--r--chrome/browser/cocoa/clear_browsing_data_controller.h67
-rw-r--r--chrome/browser/cocoa/clear_browsing_data_controller.mm157
-rw-r--r--chrome/browser/cocoa/throbber_view.h4
-rw-r--r--chrome/browser/cocoa/throbber_view.mm99
5 files changed, 291 insertions, 44 deletions
diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm
index 447d42c..429c0be 100644
--- a/chrome/browser/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/cocoa/browser_window_cocoa.mm
@@ -7,7 +7,8 @@
#include "base/sys_string_conversions.h"
#include "chrome/browser/bookmarks/bookmark_utils.h"
#include "chrome/browser/cocoa/browser_window_cocoa.h"
-#include "chrome/browser/cocoa/browser_window_controller.h"
+#import "chrome/browser/cocoa/browser_window_controller.h"
+#import "chrome/browser/cocoa/clear_browsing_data_controller.h"
#include "chrome/browser/browser.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
@@ -186,7 +187,10 @@ void BrowserWindowCocoa::ShowReportBugDialog() {
}
void BrowserWindowCocoa::ShowClearBrowsingDataDialog() {
- NOTIMPLEMENTED();
+ scoped_nsobject<ClearBrowsingDataController> controller(
+ [[ClearBrowsingDataController alloc]
+ initWithProfile:browser_->profile()]);
+ [controller runModalDialog];
}
void BrowserWindowCocoa::ShowImportDialog() {
diff --git a/chrome/browser/cocoa/clear_browsing_data_controller.h b/chrome/browser/cocoa/clear_browsing_data_controller.h
new file mode 100644
index 0000000..78ef39c
--- /dev/null
+++ b/chrome/browser/cocoa/clear_browsing_data_controller.h
@@ -0,0 +1,67 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_BROWSER_COCOA_CLEAR_BROWSING_DATA_CONTROLLER_
+#define CHROME_BROWSER_COCOA_CLEAR_BROWSING_DATA_CONTROLLER_
+
+#import <Cocoa/Cocoa.h>
+
+#include "base/scoped_ptr.h"
+
+class BrowsingDataRemover;
+class ClearBrowsingObserver;
+class Profile;
+@class ThrobberView;
+
+// A window controller for managing the "Clear Browsing Data" feature. Modally
+// presents a dialog offering the user a set of choices of what browsing data
+// to delete and does so if the user chooses.
+
+@interface ClearBrowsingDataController : NSWindowController {
+ @private
+ Profile* profile_; // Weak, owned by browser.
+ // If non-null means there is a removal in progress. Member used mainly for
+ // automated tests. The remove deletes itself when it's done, so this is a
+ // weak reference.
+ BrowsingDataRemover* remover_;
+ scoped_ptr<ClearBrowsingObserver> observer_;
+ BOOL isClearing_; // YES while clearing data is ongoing.
+ IBOutlet ThrobberView* progress_;
+
+ // Values for checkboxes, kept in sync with bindings. These values get
+ // persisted into prefs if the user accepts the dialog.
+ BOOL clearBrowsingHistory_;
+ BOOL clearDownloadHistory_;
+ BOOL emptyCache_;
+ BOOL deleteCookies_;
+ BOOL clearSavedPasswords_;
+ BOOL clearFormData_;
+ NSInteger timePeriod_;
+}
+
+// Create the controller with the given profile (which must not be NULL).
+- (id)initWithProfile:(Profile*)profile;
+
+// Run the dialog with an application-modal event loop. If the user accepts,
+// performs the deletion of the selected browsing data. The values of the
+// checkboxes will be persisted into prefs for next time.
+- (void)runModalDialog;
+
+// IBActions for the dialog buttons
+- (IBAction)clearData:(id)sender;
+- (IBAction)cancel:(id)sender;
+
+// Properties for bindings
+@property BOOL clearBrowsingHistory;
+@property BOOL clearDownloadHistory;
+@property BOOL emptyCache;
+@property BOOL deleteCookies;
+@property BOOL clearSavedPasswords;
+@property BOOL clearFormData;
+@property NSInteger timePeriod;
+@property BOOL isClearing;
+
+@end
+
+#endif // CHROME_BROWSER_COCOA_CLEAR_BROWSING_DATA_CONTROLLER_
diff --git a/chrome/browser/cocoa/clear_browsing_data_controller.mm b/chrome/browser/cocoa/clear_browsing_data_controller.mm
new file mode 100644
index 0000000..f8ca39a
--- /dev/null
+++ b/chrome/browser/cocoa/clear_browsing_data_controller.mm
@@ -0,0 +1,157 @@
+// Copyright (c) 2009 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.
+
+#import "chrome/browser/cocoa/clear_browsing_data_controller.h"
+
+#include "base/mac_util.h"
+#include "base/scoped_nsobject.h"
+#include "chrome/browser/browsing_data_remover.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/pref_service.h"
+#include "chrome/browser/profile.h"
+
+@interface ClearBrowsingDataController(Private)
+- (void)initFromPrefs;
+- (void)persistToPrefs;
+- (void)dataRemoverDidFinish;
+@end
+
+class ClearBrowsingObserver : public BrowsingDataRemover::Observer {
+ public:
+ ClearBrowsingObserver(ClearBrowsingDataController* controller)
+ : controller_(controller) { }
+ void OnBrowsingDataRemoverDone() { [controller_ dataRemoverDidFinish]; }
+ private:
+ ClearBrowsingDataController* controller_;
+};
+
+@implementation ClearBrowsingDataController
+
+@synthesize clearBrowsingHistory = clearBrowsingHistory_;
+@synthesize clearDownloadHistory = clearDownloadHistory_;
+@synthesize emptyCache = emptyCache_;
+@synthesize deleteCookies = deleteCookies_;
+@synthesize clearSavedPasswords = clearSavedPasswords_;
+@synthesize clearFormData = clearFormData_;
+@synthesize timePeriod = timePeriod_;
+@synthesize isClearing = isClearing_;
+
+
+- (id)initWithProfile:(Profile*)profile {
+ DCHECK(profile);
+ // Use initWithWindowNibPath:: instead of initWithWindowNibName: so we
+ // can override it in a unit test.
+ NSString *nibpath = [mac_util::MainAppBundle()
+ pathForResource:@"ClearBrowsingData"
+ ofType:@"nib"];
+ if ((self = [super initWithWindowNibPath:nibpath owner:self])) {
+ profile_ = profile;
+ observer_.reset(new ClearBrowsingObserver(self));
+ [self initFromPrefs];
+ }
+ return self;
+}
+
+- (void)dealloc {
+ if (remover_) {
+ // We were destroyed while clearing history was in progress. This can only
+ // occur during automated tests (normally the user can't close the dialog
+ // while clearing is in progress as the dialog is modal and not closeable).
+ remover_->RemoveObserver(observer_.get());
+ }
+ [super dealloc];
+}
+
+// Called when outlets are available. Set the throbber icon.
+- (void)awakeFromNib {
+ NSString *imagePath = [mac_util::MainAppBundle()
+ pathForResource:@"throbber"
+ ofType:@"png"];
+ scoped_nsobject<NSImage> throbberImage(
+ [[NSImage alloc] initWithContentsOfFile:imagePath]);
+ [progress_ setImage:throbberImage];
+}
+
+// Run application modal.
+- (void)runModalDialog {
+ [[NSApplication sharedApplication] runModalForWindow:[self window]];
+}
+
+// Called when the user clicks the "clear" button. Do the work and persist
+// the prefs for next time. We don't stop the modal session until we get
+// the callback from the BrowsingDataRemover so the window stays on the screen.
+// While we're working, dim the buttons so the user can't click them.
+- (IBAction)clearData:(id)sender {
+ // Set that we're working so that the buttons disable.
+ [self setIsClearing:YES];
+
+ [self persistToPrefs];
+
+ int removeMask = 0L;
+ if (clearBrowsingHistory_)
+ removeMask |= BrowsingDataRemover::REMOVE_HISTORY;
+ if (clearDownloadHistory_)
+ removeMask |= BrowsingDataRemover::REMOVE_DOWNLOADS;
+ if (emptyCache_)
+ removeMask |= BrowsingDataRemover::REMOVE_CACHE;
+ if (deleteCookies_)
+ removeMask |= BrowsingDataRemover::REMOVE_COOKIES;
+ if (clearSavedPasswords_)
+ removeMask |= BrowsingDataRemover::REMOVE_PASSWORDS;
+ if (clearFormData_)
+ removeMask |= BrowsingDataRemover::REMOVE_PASSWORDS;
+
+ // BrowsingDataRemover deletes itself when done.
+ remover_ = new BrowsingDataRemover(profile_,
+ static_cast<BrowsingDataRemover::TimePeriod>(timePeriod_),
+ base::Time());
+ remover_->AddObserver(observer_.get());
+ remover_->Remove(removeMask);
+}
+
+// Called when the user clicks the cancel button. All we need to do is stop
+// the modal session.
+- (IBAction)cancel:(id)sender {
+ [[NSApplication sharedApplication] stopModal];
+ [[self window] orderOut:self];
+}
+
+// Initialize the bools from prefs using the setters to be KVO-compliant.
+- (void)initFromPrefs {
+ PrefService* prefs = profile_->GetPrefs();
+ [self setClearBrowsingHistory:
+ prefs->GetBoolean(prefs::kDeleteBrowsingHistory)];
+ [self setClearDownloadHistory:
+ prefs->GetBoolean(prefs::kDeleteDownloadHistory)];
+ [self setEmptyCache:prefs->GetBoolean(prefs::kDeleteCache)];
+ [self setDeleteCookies:prefs->GetBoolean(prefs::kDeleteCookies)];
+ [self setClearSavedPasswords:prefs->GetBoolean(prefs::kDeletePasswords)];
+ [self setClearFormData:prefs->GetBoolean(prefs::kDeleteFormData)];
+ [self setTimePeriod:prefs->GetInteger(prefs::kDeleteTimePeriod)];
+}
+
+// Save the checkbox values to the preferences.
+- (void)persistToPrefs {
+ PrefService* prefs = profile_->GetPrefs();
+ prefs->SetBoolean(prefs::kDeleteBrowsingHistory,
+ [self clearBrowsingHistory]);
+ prefs->SetBoolean(prefs::kDeleteDownloadHistory,
+ [self clearDownloadHistory]);
+ prefs->SetBoolean(prefs::kDeleteCache, [self emptyCache]);
+ prefs->SetBoolean(prefs::kDeleteCookies, [self deleteCookies]);
+ prefs->SetBoolean(prefs::kDeletePasswords, [self clearSavedPasswords]);
+ prefs->SetBoolean(prefs::kDeleteFormData, [self clearFormData]);
+ prefs->SetInteger(prefs::kDeleteTimePeriod, [self timePeriod]);
+}
+
+// Called when the data remover object is done with its work. Close the window.
+// The remover will delete itself. End the modal session at this point.
+- (void)dataRemoverDidFinish {
+ [[NSApplication sharedApplication] stopModal];
+ [[self window] orderOut:self];
+ [self setIsClearing:NO];
+ remover_ = NULL;
+}
+
+@end
diff --git a/chrome/browser/cocoa/throbber_view.h b/chrome/browser/cocoa/throbber_view.h
index 00f83ed..e0b06ba 100644
--- a/chrome/browser/cocoa/throbber_view.h
+++ b/chrome/browser/cocoa/throbber_view.h
@@ -32,6 +32,10 @@
// the width. Takes ownership of |image|.
- (id)initWithFrame:(NSRect)frame image:(NSImage*)image;
+// Allows changing the image once the view has been created, such as when the
+// view is loaded from a nib. The same restrictions as above apply.
+- (void)setImage:(NSImage*)image;
+
@end
#endif // CHROME_BROWSER_COCOA_THROBBER_VIEW_H_
diff --git a/chrome/browser/cocoa/throbber_view.mm b/chrome/browser/cocoa/throbber_view.mm
index 26f8ec5..2f9b491 100644
--- a/chrome/browser/cocoa/throbber_view.mm
+++ b/chrome/browser/cocoa/throbber_view.mm
@@ -39,48 +39,7 @@ const float kAnimationIntervalSeconds = 0.03; // 30ms, same as windows
- (id)initWithFrame:(NSRect)frame image:(NSImage*)image {
if ((self = [super initWithFrame:frame])) {
- // Ensure that the height divides evenly into the width. Cache the
- // number of frames in the animation for later.
- NSSize imageSize = [image size];
- DCHECK(imageSize.height && imageSize.width);
- if (!imageSize.height)
- return nil;
- DCHECK((int)imageSize.width % (int)imageSize.height == 0);
- numFrames_ = (int)imageSize.width / (int)imageSize.height;
- DCHECK(numFrames_);
-
- // First check if we have a bitmap image rep and use it, otherwise fall
- // back to creating one.
- NSBitmapImageRep* rep = [[image representations] objectAtIndex:0];
- if (![rep isKindOfClass:[NSBitmapImageRep class]]) {
- [image lockFocus];
- NSRect imageRect = NSMakeRect(0, 0, imageSize.width, imageSize.height);
- rep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect:imageRect]
- autorelease];
- [image unlockFocus];
- }
- image_.reset([[CIImage alloc] initWithBitmapImageRep:rep]);
-
-#if 0
-// TODO(pinkerton): The invalidation of the view to trigger re-draw causes
-// the entire title-bar to redraw (you can see it with QuartzDebug). For some
-// reason, setting isOpaque on this view, or any of its parent views, doesn't
-// help. As a result, enabling this timer causes new tab to take a very long
-// time on a loaded machine, crushing our perf bot when it's under load. For
-// now, I'm disabling the timer so we draw the first frame of the animation,
-// but nothing more. There are a couple of ways we can fix this:
-// 1) Try to figure out why the invalidate is invalidating the entire title bar
-// 2) Find some way to draw only the pixels we want and nothing else, but I
-// don't know how we'd do that.
- // Start a timer for the animation frames.
- target_.reset([[TimerTarget alloc] initWithThrobber:self]);
- timer_ =
- [NSTimer scheduledTimerWithTimeInterval:kAnimationIntervalSeconds
- target:target_.get()
- selector:@selector(animate:)
- userInfo:nil
- repeats:YES];
-#endif
+ [self setImage:image];
}
return self;
}
@@ -116,4 +75,60 @@ const float kAnimationIntervalSeconds = 0.03; // 30ms, same as windows
fraction:1.0];
}
+// Stores the internal representation of the image from |image|. We use
+// CoreImage for speed (though this doesn't seem to help perf issues). We
+// validate that the image is of the appropriate ratio. If the image has more
+// than one frame, restarts the timer.
+- (void)setImage:(NSImage*)image {
+ // Reset the animation counter so there's no chance we are off the end.
+ animationFrame_ = 0;
+ [timer_ invalidate];
+ timer_ = nil;
+
+ // Ensure that the height divides evenly into the width. Cache the
+ // number of frames in the animation for later.
+ NSSize imageSize = [image size];
+ DCHECK(imageSize.height && imageSize.width);
+ if (!imageSize.height)
+ return;
+ DCHECK((int)imageSize.width % (int)imageSize.height == 0);
+ numFrames_ = (int)imageSize.width / (int)imageSize.height;
+ DCHECK(numFrames_);
+
+ // First check if we have a bitmap image rep and use it, otherwise fall
+ // back to creating one.
+ NSBitmapImageRep* rep = [[image representations] objectAtIndex:0];
+ if (![rep isKindOfClass:[NSBitmapImageRep class]]) {
+ [image lockFocus];
+ NSRect imageRect = NSMakeRect(0, 0, imageSize.width, imageSize.height);
+ rep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect:imageRect]
+ autorelease];
+ [image unlockFocus];
+ }
+ image_.reset([[CIImage alloc] initWithBitmapImageRep:rep]);
+
+#if 0
+// TODO(pinkerton): The invalidation of the view to trigger re-draw causes
+// the entire title-bar to redraw (you can see it with QuartzDebug). For some
+// reason, setting isOpaque on this view, or any of its parent views, doesn't
+// help. As a result, enabling this timer causes new tab to take a very long
+// time on a loaded machine, crushing our perf bot when it's under load. For
+// now, I'm disabling the timer so we draw the first frame of the animation,
+// but nothing more. There are a couple of ways we can fix this:
+// 1) Try to figure out why the invalidate is invalidating the entire title bar
+// 2) Find some way to draw only the pixels we want and nothing else, but I
+// don't know how we'd do that.
+ if (numFrames_ > 1) {
+ // Start a timer for the animation frames.
+ target_.reset([[TimerTarget alloc] initWithThrobber:self]);
+ timer_ =
+ [NSTimer scheduledTimerWithTimeInterval:kAnimationIntervalSeconds
+ target:target_.get()
+ selector:@selector(animate:)
+ userInfo:nil
+ repeats:YES];
+ }
+#endif
+}
+
@end