summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/cocoa/first_run_dialog.mm
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/ui/cocoa/first_run_dialog.mm')
-rw-r--r--chrome/browser/ui/cocoa/first_run_dialog.mm195
1 files changed, 195 insertions, 0 deletions
diff --git a/chrome/browser/ui/cocoa/first_run_dialog.mm b/chrome/browser/ui/cocoa/first_run_dialog.mm
new file mode 100644
index 0000000..9590b9b
--- /dev/null
+++ b/chrome/browser/ui/cocoa/first_run_dialog.mm
@@ -0,0 +1,195 @@
+// 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.
+
+#import "chrome/browser/ui/cocoa/first_run_dialog.h"
+
+#include "app/l10n_util_mac.h"
+#include "base/mac_util.h"
+#include "base/message_loop.h"
+#include "base/ref_counted.h"
+#include "grit/locale_settings.h"
+#import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
+
+@interface FirstRunDialogController (PrivateMethods)
+// Show the dialog.
+- (void)show;
+@end
+
+namespace {
+
+// Compare function for -[NSArray sortedArrayUsingFunction:context:] that
+// sorts the views in Y order bottom up.
+NSInteger CompareFrameY(id view1, id view2, void* context) {
+ CGFloat y1 = NSMinY([view1 frame]);
+ CGFloat y2 = NSMinY([view2 frame]);
+ if (y1 < y2)
+ return NSOrderedAscending;
+ else if (y1 > y2)
+ return NSOrderedDescending;
+ else
+ return NSOrderedSame;
+}
+
+class FirstRunShowBridge : public base::RefCounted<FirstRunShowBridge> {
+ public:
+ FirstRunShowBridge(FirstRunDialogController* controller);
+
+ void ShowDialog();
+ private:
+ FirstRunDialogController* controller_;
+};
+
+FirstRunShowBridge::FirstRunShowBridge(
+ FirstRunDialogController* controller) : controller_(controller) {
+}
+
+void FirstRunShowBridge::ShowDialog() {
+ [controller_ show];
+ MessageLoop::current()->QuitNow();
+}
+
+};
+
+@implementation FirstRunDialogController
+
+@synthesize statsEnabled = statsEnabled_;
+@synthesize makeDefaultBrowser = makeDefaultBrowser_;
+
+- (id)init {
+ NSString* nibpath =
+ [mac_util::MainAppBundle() pathForResource:@"FirstRunDialog"
+ ofType:@"nib"];
+ self = [super initWithWindowNibPath:nibpath owner:self];
+ if (self != nil) {
+ // Bound to the dialog checkbox, default to true.
+ makeDefaultBrowser_ = YES;
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [super dealloc];
+}
+
+- (IBAction)showWindow:(id)sender {
+ // The main MessageLoop has not yet run, but has been spun. If we call
+ // -[NSApplication runModalForWindow:] we will hang <http://crbug.com/54248>.
+ // Therefore the main MessageLoop is run so things work.
+
+ scoped_refptr<FirstRunShowBridge> bridge(new FirstRunShowBridge(self));
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(bridge.get(),
+ &FirstRunShowBridge::ShowDialog));
+ MessageLoop::current()->Run();
+}
+
+- (void)show {
+ NSWindow* win = [self window];
+
+ // Only support the sizing the window once.
+ DCHECK(!beenSized_) << "ShowWindow was called twice?";
+ if (!beenSized_) {
+ beenSized_ = YES;
+ DCHECK_GT([objectsToSize_ count], 0U);
+
+ // Size everything to fit, collecting the widest growth needed (XIB provides
+ // the min size, i.e.-never shrink, just grow).
+ CGFloat largestWidthChange = 0.0;
+ for (NSView* view in objectsToSize_) {
+ DCHECK_NE(statsCheckbox_, view) << "Stats checkbox shouldn't be in list";
+ if (![view isHidden]) {
+ NSSize delta = [GTMUILocalizerAndLayoutTweaker sizeToFitView:view];
+ DCHECK_EQ(delta.height, 0.0)
+ << "Didn't expect anything to change heights";
+ if (largestWidthChange < delta.width)
+ largestWidthChange = delta.width;
+ }
+ }
+
+ // Make the window wide enough to fit everything.
+ if (largestWidthChange > 0.0) {
+ NSView* contentView = [win contentView];
+ NSRect windowFrame = [contentView convertRect:[win frame] fromView:nil];
+ windowFrame.size.width += largestWidthChange;
+ windowFrame = [contentView convertRect:windowFrame toView:nil];
+ [win setFrame:windowFrame display:NO];
+ }
+
+ // The stats checkbox gets some really long text, so it gets word wrapped
+ // and then sized.
+ DCHECK(statsCheckbox_);
+ CGFloat statsCheckboxHeightChange = 0.0;
+ [GTMUILocalizerAndLayoutTweaker wrapButtonTitleForWidth:statsCheckbox_];
+ statsCheckboxHeightChange =
+ [GTMUILocalizerAndLayoutTweaker sizeToFitView:statsCheckbox_].height;
+
+ // Walk bottom up shuffling for all the hidden views.
+ NSArray* subViews =
+ [[[win contentView] subviews] sortedArrayUsingFunction:CompareFrameY
+ context:NULL];
+ CGFloat moveDown = 0.0;
+ NSUInteger numSubViews = [subViews count];
+ for (NSUInteger idx = 0 ; idx < numSubViews ; ++idx) {
+ NSView* view = [subViews objectAtIndex:idx];
+
+ // If the view is hidden, collect the amount to move everything above it
+ // down, if it's not hidden, apply any shift down.
+ if ([view isHidden]) {
+ DCHECK_GT((numSubViews - 1), idx)
+ << "Don't support top view being hidden";
+ NSView* nextView = [subViews objectAtIndex:(idx + 1)];
+ CGFloat viewBottom = [view frame].origin.y;
+ CGFloat nextViewBottom = [nextView frame].origin.y;
+ moveDown += nextViewBottom - viewBottom;
+ } else {
+ if (moveDown != 0.0) {
+ NSPoint origin = [view frame].origin;
+ origin.y -= moveDown;
+ [view setFrameOrigin:origin];
+ }
+ }
+ // Special case, if this is the stats checkbox, everything above it needs
+ // to get moved up by the amount it changed height.
+ if (view == statsCheckbox_) {
+ moveDown -= statsCheckboxHeightChange;
+ }
+ }
+
+ // Resize the window for any height change from hidden views, etc.
+ if (moveDown != 0.0) {
+ NSView* contentView = [win contentView];
+ [contentView setAutoresizesSubviews:NO];
+ NSRect windowFrame = [contentView convertRect:[win frame] fromView:nil];
+ windowFrame.size.height -= moveDown;
+ windowFrame = [contentView convertRect:windowFrame toView:nil];
+ [win setFrame:windowFrame display:NO];
+ [contentView setAutoresizesSubviews:YES];
+ }
+
+ }
+
+ // Neat weirdness in the below code - the Application menu stays enabled
+ // while the window is open but selecting items from it (e.g. Quit) has
+ // no effect. I'm guessing that this is an artifact of us being a
+ // background-only application at this stage and displaying a modal
+ // window.
+
+ // Display dialog.
+ [win center];
+ [NSApp runModalForWindow:win];
+}
+
+- (IBAction)ok:(id)sender {
+ [[self window] close];
+ [NSApp stopModal];
+}
+
+- (IBAction)learnMore:(id)sender {
+ NSString* urlStr = l10n_util::GetNSString(IDS_LEARN_MORE_REPORTING_URL);
+ NSURL* learnMoreUrl = [NSURL URLWithString:urlStr];
+ [[NSWorkspace sharedWorkspace] openURL:learnMoreUrl];
+}
+
+@end