Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / extensions / media_galleries_dialog_cocoa.mm
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/cocoa/extensions/media_galleries_dialog_cocoa.h"
6
7 #include "base/mac/scoped_nsobject.h"
8 #include "base/strings/sys_string_conversions.h"
9 #include "chrome/browser/ui/chrome_style.h"
10 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_alert.h"
11 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h"
12 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_control_utils.h"
13 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h"
14 #import "chrome/browser/ui/cocoa/key_equivalent_constants.h"
15 #include "content/public/browser/web_contents.h"
16 #include "grit/generated_resources.h"
17 #import "ui/base/cocoa/flipped_view.h"
18 #import "ui/base/cocoa/menu_controller.h"
19 #import "ui/base/models/menu_model.h"
20 #include "ui/base/l10n/l10n_util.h"
21 #include "ui/base/resource/resource_bundle.h"
22
23 // Controller for UI events on items in the media galleries dialog.
24 @interface MediaGalleriesCocoaController : NSObject {
25  @private
26   MediaGalleriesDialogCocoa* dialog_;
27 }
28
29 @property(assign, nonatomic) MediaGalleriesDialogCocoa* dialog;
30
31 - (void)onAcceptButton:(id)sender;
32 - (void)onCancelButton:(id)sender;
33 - (void)onAddFolderClicked:(id)sender;
34
35 @end
36
37 @implementation MediaGalleriesCocoaController
38
39 @synthesize dialog = dialog_;
40
41 - (void)onAcceptButton:(id)sender {
42   dialog_->OnAcceptClicked();
43 }
44
45 - (void)onCancelButton:(id)sender {
46   dialog_->OnCancelClicked();
47 }
48
49 - (void)onAddFolderClicked:(id)sender {
50   DCHECK(dialog_);
51   dialog_->OnAddFolderClicked();
52 }
53
54 @end
55
56 namespace {
57
58 const CGFloat kCheckboxMargin = 10;
59 const CGFloat kCheckboxMaxWidth = 440;
60 const CGFloat kScrollAreaHeight = 220;
61
62 }  // namespace
63
64 MediaGalleriesDialogCocoa::MediaGalleriesDialogCocoa(
65     MediaGalleriesDialogController* controller,
66     MediaGalleriesCocoaController* cocoa_controller)
67     : controller_(controller),
68       accepted_(false),
69       cocoa_controller_([cocoa_controller retain]) {
70   [cocoa_controller_ setDialog:this];
71
72   alert_.reset([[ConstrainedWindowAlert alloc] init]);
73
74   [alert_ setMessageText:base::SysUTF16ToNSString(controller_->GetHeader())];
75   [alert_ setInformativeText:
76       base::SysUTF16ToNSString(controller_->GetSubtext())];
77   [alert_ addButtonWithTitle:
78       l10n_util::GetNSString(IDS_MEDIA_GALLERIES_DIALOG_CONFIRM)
79                keyEquivalent:kKeyEquivalentReturn
80                       target:cocoa_controller_
81                       action:@selector(onAcceptButton:)];
82   [alert_ addButtonWithTitle:
83       l10n_util::GetNSString(IDS_MEDIA_GALLERIES_DIALOG_CANCEL)
84                keyEquivalent:kKeyEquivalentEscape
85                       target:cocoa_controller_
86                       action:@selector(onCancelButton:)];
87   [alert_ addButtonWithTitle:
88       l10n_util::GetNSString(IDS_MEDIA_GALLERIES_DIALOG_ADD_GALLERY)
89                keyEquivalent:kKeyEquivalentNone
90                       target:cocoa_controller_
91                       action:@selector(onAddFolderClicked:)];
92   [[alert_ closeButton] setTarget:cocoa_controller_];
93   [[alert_ closeButton] setAction:@selector(onCancelButton:)];
94
95   InitDialogControls();
96
97   // May be NULL during tests.
98   if (controller->web_contents()) {
99     base::scoped_nsobject<CustomConstrainedWindowSheet> sheet(
100         [[CustomConstrainedWindowSheet alloc]
101             initWithCustomWindow:[alert_ window]]);
102     window_.reset(new ConstrainedWindowMac(
103         this, controller->web_contents(), sheet));
104   }
105 }
106
107 MediaGalleriesDialogCocoa::~MediaGalleriesDialogCocoa() {
108 }
109
110 void MediaGalleriesDialogCocoa::InitDialogControls() {
111   main_container_.reset([[NSBox alloc] init]);
112   [main_container_ setBoxType:NSBoxCustom];
113   [main_container_ setBorderType:NSLineBorder];
114   [main_container_ setBorderWidth:1];
115   [main_container_ setCornerRadius:0];
116   [main_container_ setContentViewMargins:NSZeroSize];
117   [main_container_ setTitlePosition:NSNoTitle];
118   [main_container_ setBorderColor:[NSColor colorWithCalibratedRed:0.625
119                                                             green:0.625
120                                                              blue:0.625
121                                                             alpha:1.0]];
122
123   base::scoped_nsobject<NSScrollView> scroll_view(
124       [[NSScrollView alloc] initWithFrame:
125           NSMakeRect(0, 0, kCheckboxMaxWidth, kScrollAreaHeight)]);
126   [scroll_view setHasVerticalScroller:YES];
127   [scroll_view setHasHorizontalScroller:NO];
128   [scroll_view setBorderType:NSNoBorder];
129   [scroll_view setAutohidesScrollers:YES];
130   [[main_container_ contentView] addSubview:scroll_view];
131
132   // Add gallery permission checkboxes inside the scrolling view.
133   checkbox_container_.reset([[FlippedView alloc] initWithFrame:NSZeroRect]);
134
135   CGFloat y_pos = CreateCheckboxes(0, controller_->AttachedPermissions());
136
137   if (!controller_->UnattachedPermissions().empty()) {
138     y_pos = CreateCheckboxSeparator(y_pos);
139     y_pos = CreateCheckboxes(y_pos, controller_->UnattachedPermissions());
140   }
141
142   // Give the container a reasonable initial size so that the scroll_view can
143   // figure out the content size.
144   [checkbox_container_ setFrameSize:NSMakeSize(kCheckboxMaxWidth, y_pos)];
145   [scroll_view setDocumentView:checkbox_container_];
146   [checkbox_container_ setFrameSize:NSMakeSize([scroll_view contentSize].width,
147                                                y_pos)];
148
149   // Resize to pack the scroll view if possible.
150   NSRect scroll_frame = [scroll_view frame];
151   if (NSHeight(scroll_frame) > NSHeight([checkbox_container_ frame])) {
152     scroll_frame.size.height = NSHeight([checkbox_container_ frame]);
153     [scroll_view setFrameSize:scroll_frame.size];
154   }
155
156   [main_container_ setFrameFromContentFrame:scroll_frame];
157   [main_container_ setFrameOrigin:NSZeroPoint];
158   [alert_ setAccessoryView:main_container_];
159
160   // As a safeguard against the user skipping reading over the dialog and just
161   // confirming, the button will be unavailable for dialogs without any checks
162   // until the user toggles something.
163   [[[alert_ buttons] objectAtIndex:0] setEnabled:
164       controller_->IsAcceptAllowed()];
165
166   [alert_ layout];
167 }
168
169 CGFloat MediaGalleriesDialogCocoa::CreateCheckboxes(
170     CGFloat y_pos,
171     const MediaGalleriesDialogController::GalleryPermissionsVector&
172         permissions) {
173   for (MediaGalleriesDialogController::GalleryPermissionsVector::
174        const_iterator iter = permissions.begin();
175        iter != permissions.end(); iter++) {
176     const MediaGalleriesDialogController::GalleryPermission& permission = *iter;
177     base::scoped_nsobject<MediaGalleryListEntry> checkbox_entry(
178         [[MediaGalleryListEntry alloc]
179             initWithFrame:NSZeroRect
180                controller:this
181                   prefId:permission.gallery_id
182              galleryName:permission.pref_info.GetGalleryDisplayName()
183                subscript:permission.pref_info.GetGalleryAdditionalDetails()
184                  tooltip:permission.pref_info.GetGalleryTooltip()
185         showFolderViewer:false]);
186
187     [checkbox_entry setState:permission.allowed];
188
189     [checkbox_entry setFrameOrigin:NSMakePoint(0, y_pos)];
190     y_pos = NSMaxY([checkbox_entry frame]) + kCheckboxMargin;
191
192     [checkbox_container_ addSubview:checkbox_entry];
193   }
194
195   return y_pos;
196 }
197
198 CGFloat MediaGalleriesDialogCocoa::CreateCheckboxSeparator(CGFloat y_pos) {
199   base::scoped_nsobject<NSBox> separator(
200       [[NSBox alloc] initWithFrame:NSMakeRect(
201           0, y_pos + kCheckboxMargin * 0.5, kCheckboxMaxWidth, 1.0)]);
202   [separator setBoxType:NSBoxSeparator];
203   [separator setBorderType:NSLineBorder];
204   [separator setAlphaValue:0.2];
205   [checkbox_container_ addSubview:separator];
206   y_pos += kCheckboxMargin * 0.5 + 4;
207
208   base::scoped_nsobject<NSTextField> unattached_label(
209       [[NSTextField alloc] initWithFrame:NSZeroRect]);
210   [unattached_label setEditable:NO];
211   [unattached_label setSelectable:NO];
212   [unattached_label setBezeled:NO];
213   [unattached_label setAttributedStringValue:
214       constrained_window::GetAttributedLabelString(
215           base::SysUTF16ToNSString(
216               controller_->GetUnattachedLocationsHeader()),
217           chrome_style::kTextFontStyle,
218           NSNaturalTextAlignment,
219           NSLineBreakByClipping
220       )];
221   [unattached_label sizeToFit];
222   NSSize unattached_label_size = [unattached_label frame].size;
223   [unattached_label setFrame:NSMakeRect(
224       kCheckboxMargin, y_pos + kCheckboxMargin,
225       kCheckboxMaxWidth, unattached_label_size.height)];
226   [checkbox_container_ addSubview:unattached_label];
227   y_pos = NSMaxY([unattached_label frame]) + kCheckboxMargin;
228
229   return y_pos;
230 }
231
232 void MediaGalleriesDialogCocoa::OnAcceptClicked() {
233   accepted_ = true;
234
235   if (window_)
236     window_->CloseWebContentsModalDialog();
237 }
238
239 void MediaGalleriesDialogCocoa::OnCancelClicked() {
240   if (window_)
241     window_->CloseWebContentsModalDialog();
242 }
243
244 void MediaGalleriesDialogCocoa::OnAddFolderClicked() {
245   controller_->OnAddFolderClicked();
246 }
247
248 void MediaGalleriesDialogCocoa::UpdateGalleries() {
249   InitDialogControls();
250 }
251
252 void MediaGalleriesDialogCocoa::OnConstrainedWindowClosed(
253     ConstrainedWindowMac* window) {
254   controller_->DialogFinished(accepted_);
255 }
256
257 void MediaGalleriesDialogCocoa::OnCheckboxToggled(GalleryDialogId gallery_id,
258                                                   bool checked) {
259   controller_->DidToggleGallery(gallery_id, checked);
260
261   [[[alert_ buttons] objectAtIndex:0] setEnabled:
262       controller_->IsAcceptAllowed()];
263 }
264
265 ui::MenuModel* MediaGalleriesDialogCocoa::GetContextMenu(
266     GalleryDialogId gallery_id) {
267   return controller_->GetContextMenu(gallery_id);
268 }
269
270 // static
271 MediaGalleriesDialog* MediaGalleriesDialog::Create(
272     MediaGalleriesDialogController* controller) {
273   base::scoped_nsobject<MediaGalleriesCocoaController> cocoa_controller(
274       [[MediaGalleriesCocoaController alloc] init]);
275   return new MediaGalleriesDialogCocoa(controller, cocoa_controller);
276 }