summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa/sync_customize_controller.mm
blob: 9bb7cfe2a7477bd16788b5ad40340c4a9561079e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// 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/cocoa/sync_customize_controller.h"
#import "chrome/browser/cocoa/sync_customize_controller_cppsafe.h"

#include <algorithm>

#include "base/basictypes.h"
#include "base/logging.h"
#import "base/mac_util.h"
#import "base/stl_util-inl.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/syncable/model_type.h"
#import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"


@implementation SyncCustomizeController

@synthesize bookmarksRegistered = bookmarksRegistered_;
@synthesize preferencesRegistered = preferencesRegistered_;
@synthesize autofillRegistered = autofillRegistered_;
@synthesize themesRegistered = themesRegistered_;
@synthesize extensionsRegistered = extensionsRegistered_;

// If you add another ***Preferred variable, you must update okEnabled and
// keyPathsForValuesAffectingOkEnabled below.
@synthesize bookmarksPreferred = bookmarksPreferred_;
@synthesize preferencesPreferred = preferencesPreferred_;
@synthesize autofillPreferred = autofillPreferred_;
@synthesize themesPreferred = themesPreferred_;
@synthesize extensionsPreferred = extensionsPreferred_;

// The OK button should be clickable if and only if there's at least one
// datatype chosen to sync.
- (BOOL)okEnabled {
  return bookmarksPreferred_ || preferencesPreferred_ || autofillPreferred_ ||
      themesPreferred_ || extensionsPreferred_;
}

// Naming convention; makes okEnabled get updated whenever any of the below
// "Preferred" variables are updated.
+ (NSSet*)keyPathsForValuesAffectingOkEnabled {
  return [NSSet setWithObjects:@"bookmarksPreferred", @"preferencesPreferred",
                @"autofillPreferred", @"themesPreferred",
                @"extensionsPreferred", nil];
}

- (id)initWithProfileSyncService:(ProfileSyncService*)syncService {
  NSString* nibpath = [mac_util::MainAppBundle()
                        pathForResource:@"SyncCustomize"
                                 ofType:@"nib"];
  if ((self = [super initWithWindowNibPath:nibpath owner:self])) {
    CHECK(syncService);
    syncService_ = syncService;
  }
  return self;
}

// Called when the sheet containing our window is dismissed.
- (void)endSheet:(NSWindow*)sheet
      returnCode:(NSInteger)returnCode
     contextInfo:(void*)context {
  NSWindow* parentWindow = static_cast<NSWindow*>(context);
  [sheet close];
  [sheet orderOut:parentWindow];
}

- (void)runAsModalSheet:(NSWindow*)parentWindow {
  [NSApp beginSheet:[self window]
     modalForWindow:parentWindow
      modalDelegate:self
     didEndSelector:@selector(endSheet:returnCode:contextInfo:)
        contextInfo:parentWindow];
}

- (void)awakeFromNib {
  DCHECK([self window]);
  [[self window] setDelegate:self];

  CGFloat viewHeightChange =
      [GTMUILocalizerAndLayoutTweaker
       sizeToFitFixedWidthTextField:customizeSyncDescriptionTextField_];
  if (viewHeightChange > 0) {
    // Resize the window.  No need to move the controls as they're all
    // bottom-anchored.
    NSSize viewSizeChange = NSMakeSize(0, viewHeightChange);
    NSSize windowSizeChange =
        [customizeSyncDescriptionTextField_ convertSize:viewSizeChange
                                                 toView:nil];
    CGFloat windowHeightChange = windowSizeChange.height;
    NSRect frame = [[self window] frame];
    frame.origin.y -= windowHeightChange;
    frame.size.height += windowHeightChange;
    [[self window] setFrame:frame display:NO];
  }

  syncable::ModelTypeSet registered_types;
  syncService_->GetRegisteredDataTypes(&registered_types);
  const syncable::ModelType expected_types[] = {
    syncable::BOOKMARKS,
    syncable::PREFERENCES,
    syncable::AUTOFILL,
    syncable::THEMES,
    syncable::EXTENSIONS,
  };
  DCHECK(std::includes(expected_types,
                       expected_types + arraysize(expected_types),
                       registered_types.begin(), registered_types.end()));
  DCHECK(ContainsKey(registered_types, syncable::BOOKMARKS));

  [self setBookmarksRegistered:ContainsKey(registered_types,
                                           syncable::BOOKMARKS)];
  [self setPreferencesRegistered:ContainsKey(registered_types,
                                             syncable::PREFERENCES)];
  [self setAutofillRegistered:ContainsKey(registered_types,
                                          syncable::AUTOFILL)];
  [self setThemesRegistered:ContainsKey(registered_types,
                                        syncable::THEMES)];
  [self setExtensionsRegistered:ContainsKey(registered_types,
                                            syncable::EXTENSIONS)];

  syncable::ModelTypeSet preferred_types;
  syncService_->GetPreferredDataTypes(&preferred_types);
  DCHECK(std::includes(registered_types.begin(), registered_types.end(),
                       preferred_types.begin(), preferred_types.end()));

  [self setBookmarksPreferred:ContainsKey(preferred_types,
                                          syncable::BOOKMARKS)];
  [self setPreferencesPreferred:ContainsKey(preferred_types,
                                            syncable::PREFERENCES)];
  [self setAutofillPreferred:ContainsKey(preferred_types,
                                         syncable::AUTOFILL)];
  [self setThemesPreferred:ContainsKey(preferred_types,
                                       syncable::THEMES)];
  [self setExtensionsPreferred:ContainsKey(preferred_types,
                                           syncable::EXTENSIONS)];
}

- (void)windowWillClose:(NSNotification*)notification {
  [self autorelease];
}

// Dismiss the sheet containing our window.
- (void)endSheet {
  [NSApp endSheet:[self window]];
}

- (IBAction)endSheetWithCancel:(id)sender {
  [self endSheet];
}

// Commit the changes made by the user to the ProfileSyncService.
- (void)changePreferredDataTypes {
  syncable::ModelTypeSet preferred_types;
  if ([self bookmarksPreferred]) {
    preferred_types.insert(syncable::BOOKMARKS);
  }
  if ([self preferencesPreferred]) {
    preferred_types.insert(syncable::PREFERENCES);
  }
  if ([self autofillPreferred]) {
    preferred_types.insert(syncable::AUTOFILL);
  }
  if ([self themesPreferred]) {
    preferred_types.insert(syncable::THEMES);
  }
  if ([self extensionsPreferred]) {
    preferred_types.insert(syncable::EXTENSIONS);
  }
  syncService_->ChangePreferredDataTypes(preferred_types);
  [self endSheet];
}

- (IBAction)endSheetWithOK:(id)sender {
  [self changePreferredDataTypes];
  [self endSheet];
}

@end

void ShowSyncCustomizeDialog(gfx::NativeWindow parent_window,
                             ProfileSyncService* sync_service) {
  // syncCustomizeController releases itself on close.
  SyncCustomizeController* syncCustomizeController =
      [[SyncCustomizeController alloc]
        initWithProfileSyncService:sync_service];
  [syncCustomizeController runAsModalSheet:parent_window];
}