OLD | NEW |
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/simple_content_exceptions_window_controller.h" | 5 #import "chrome/browser/cocoa/simple_content_exceptions_window_controller.h" |
6 | 6 |
7 #include <set> | |
8 | |
9 #include "app/l10n_util_mac.h" | 7 #include "app/l10n_util_mac.h" |
10 #include "app/table_model_observer.h" | 8 #include "app/table_model_observer.h" |
11 #import "base/mac_util.h" | 9 #import "base/mac_util.h" |
12 #import "base/scoped_nsobject.h" | 10 #import "base/scoped_nsobject.h" |
13 #include "base/sys_string_conversions.h" | 11 #include "base/sys_string_conversions.h" |
14 #include "grit/generated_resources.h" | 12 #include "grit/generated_resources.h" |
15 #include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" | 13 #include "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" |
16 | 14 |
17 @interface SimpleContentExceptionsWindowController (Private) | 15 @interface SimpleContentExceptionsWindowController (Private) |
18 - (id)initWithTableModel:(RemoveRowsTableModel*)model; | 16 - (id)initWithTableModel:(RemoveRowsTableModel*)model; |
19 - (void)selectedRows:(RemoveRowsTableModel::Rows*)rows; | |
20 - (void)adjustEditingButtons; | |
21 - (void)modelDidChange; | |
22 @end | 17 @end |
23 | 18 |
24 // Observer for a RemoveRowsTableModel. | |
25 class RemoveRowsObserverBridge : public TableModelObserver { | |
26 public: | |
27 RemoveRowsObserverBridge(SimpleContentExceptionsWindowController* controller) | |
28 : controller_(controller) {} | |
29 virtual ~RemoveRowsObserverBridge() {} | |
30 | |
31 virtual void OnModelChanged() { | |
32 [controller_ modelDidChange]; | |
33 } | |
34 virtual void OnItemsChanged(int start, int length) { | |
35 [controller_ modelDidChange]; | |
36 } | |
37 virtual void OnItemsAdded(int start, int length) { | |
38 [controller_ modelDidChange]; | |
39 } | |
40 virtual void OnItemsRemoved(int start, int length) { | |
41 [controller_ modelDidChange]; | |
42 } | |
43 | |
44 private: | |
45 SimpleContentExceptionsWindowController* controller_; // weak | |
46 }; | |
47 | |
48 namespace { | 19 namespace { |
49 | 20 |
50 const CGFloat kButtonBarHeight = 35.0; | 21 const CGFloat kButtonBarHeight = 35.0; |
51 | 22 |
52 SimpleContentExceptionsWindowController* g_exceptionWindow = nil; | 23 SimpleContentExceptionsWindowController* g_exceptionWindow = nil; |
53 | 24 |
54 } // namespace | 25 } // namespace |
55 | 26 |
56 @implementation SimpleContentExceptionsWindowController | 27 @implementation SimpleContentExceptionsWindowController |
57 | 28 |
58 + (id)controllerWithTableModel:(RemoveRowsTableModel*)model { | 29 + (id)controllerWithTableModel:(RemoveRowsTableModel*)model { |
59 if (!g_exceptionWindow) { | 30 if (!g_exceptionWindow) { |
60 g_exceptionWindow = [[SimpleContentExceptionsWindowController alloc] | 31 g_exceptionWindow = [[SimpleContentExceptionsWindowController alloc] |
61 initWithTableModel:model]; | 32 initWithTableModel:model]; |
62 } | 33 } |
63 return g_exceptionWindow; | 34 return g_exceptionWindow; |
64 } | 35 } |
65 | 36 |
66 - (id)initWithTableModel:(RemoveRowsTableModel*)model { | 37 - (id)initWithTableModel:(RemoveRowsTableModel*)model { |
67 NSString* nibpath = [mac_util::MainAppBundle() | 38 NSString* nibpath = [mac_util::MainAppBundle() |
68 pathForResource:@"SimpleContentExceptionsWindow" | 39 pathForResource:@"SimpleContentExceptionsWindow" |
69 ofType:@"nib"]; | 40 ofType:@"nib"]; |
70 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { | 41 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { |
71 model_.reset(model); | 42 model_.reset(model); |
72 tableObserver_.reset(new RemoveRowsObserverBridge(self)); | |
73 model_->SetObserver(tableObserver_.get()); | |
74 | 43 |
75 // TODO(thakis): autoremember window rect. | 44 // TODO(thakis): autoremember window rect. |
76 // TODO(thakis): sorting support. | 45 // TODO(thakis): sorting support. |
77 } | 46 } |
78 return self; | 47 return self; |
79 } | 48 } |
80 | 49 |
81 - (void)awakeFromNib { | 50 - (void)awakeFromNib { |
82 DCHECK([self window]); | 51 DCHECK([self window]); |
83 DCHECK_EQ(self, [[self window] delegate]); | 52 DCHECK_EQ(self, [[self window] delegate]); |
84 DCHECK(tableView_); | 53 DCHECK(tableView_); |
85 DCHECK_EQ(self, [tableView_ dataSource]); | 54 DCHECK(arrayController_); |
86 DCHECK_EQ(self, [tableView_ delegate]); | |
87 | 55 |
88 CGFloat minWidth = [[removeButton_ superview] bounds].size.width + | 56 CGFloat minWidth = [[removeButton_ superview] bounds].size.width + |
89 [[doneButton_ superview] bounds].size.width; | 57 [[doneButton_ superview] bounds].size.width; |
90 [[self window] setMinSize:NSMakeSize(minWidth, | 58 [[self window] setMinSize:NSMakeSize(minWidth, |
91 [[self window] minSize].height)]; | 59 [[self window] minSize].height)]; |
92 | 60 NSDictionary* columns = [NSDictionary dictionaryWithObjectsAndKeys: |
93 [self adjustEditingButtons]; | 61 [NSNumber numberWithInt:IDS_EXCEPTIONS_HOSTNAME_HEADER], @"hostname", |
| 62 [NSNumber numberWithInt:IDS_EXCEPTIONS_ACTION_HEADER], @"action", |
| 63 nil]; |
| 64 [arrayController_ bindToTableModel:model_.get() |
| 65 withColumns:columns |
| 66 groupTitleColumn:@"hostname"]; |
94 } | 67 } |
95 | 68 |
96 - (void)setMinWidth:(CGFloat)minWidth { | 69 - (void)setMinWidth:(CGFloat)minWidth { |
97 NSWindow* window = [self window]; | 70 NSWindow* window = [self window]; |
98 [window setMinSize:NSMakeSize(minWidth, [window minSize].height)]; | 71 [window setMinSize:NSMakeSize(minWidth, [window minSize].height)]; |
99 if ([window frame].size.width < minWidth) { | 72 if ([window frame].size.width < minWidth) { |
100 NSRect frame = [window frame]; | 73 NSRect frame = [window frame]; |
101 frame.size.width = minWidth; | 74 frame.size.width = minWidth; |
102 [window setFrame:frame display:NO]; | 75 [window setFrame:frame display:NO]; |
103 } | 76 } |
104 } | 77 } |
105 | 78 |
106 - (void)windowWillClose:(NSNotification*)notification { | 79 - (void)windowWillClose:(NSNotification*)notification { |
107 // Without this, some of the unit tests fail on 10.6: | |
108 [tableView_ setDataSource:nil]; | |
109 | |
110 g_exceptionWindow = nil; | 80 g_exceptionWindow = nil; |
111 [self autorelease]; | 81 [self autorelease]; |
112 } | 82 } |
113 | 83 |
114 // Let esc close the window. | 84 // Let esc close the window. |
115 - (void)cancel:(id)sender { | 85 - (void)cancel:(id)sender { |
116 [self closeSheet:self]; | 86 [self closeSheet:self]; |
117 } | 87 } |
118 | 88 |
119 - (void)keyDown:(NSEvent*)event { | 89 - (void)keyDown:(NSEvent*)event { |
120 NSString* chars = [event charactersIgnoringModifiers]; | 90 NSString* chars = [event charactersIgnoringModifiers]; |
121 if ([chars length] == 1) { | 91 if ([chars length] == 1) { |
122 switch ([chars characterAtIndex:0]) { | 92 switch ([chars characterAtIndex:0]) { |
123 case NSDeleteCharacter: | 93 case NSDeleteCharacter: |
124 case NSDeleteFunctionKey: | 94 case NSDeleteFunctionKey: |
125 // Delete deletes. | 95 // Delete deletes. |
126 if ([[tableView_ selectedRowIndexes] count] > 0) | 96 if ([[tableView_ selectedRowIndexes] count] > 0) |
127 [self removeRow:self]; | 97 [arrayController_ remove:event]; |
128 return; | 98 return; |
129 } | 99 } |
130 } | 100 } |
131 [super keyDown:event]; | 101 [super keyDown:event]; |
132 } | 102 } |
133 | 103 |
134 - (void)attachSheetTo:(NSWindow*)window { | 104 - (void)attachSheetTo:(NSWindow*)window { |
135 [NSApp beginSheet:[self window] | 105 [NSApp beginSheet:[self window] |
136 modalForWindow:window | 106 modalForWindow:window |
137 modalDelegate:self | 107 modalDelegate:self |
138 didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) | 108 didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) |
139 contextInfo:nil]; | 109 contextInfo:nil]; |
140 } | 110 } |
141 | 111 |
142 - (void)sheetDidEnd:(NSWindow*)sheet | 112 - (void)sheetDidEnd:(NSWindow*)sheet |
143 returnCode:(NSInteger)returnCode | 113 returnCode:(NSInteger)returnCode |
144 contextInfo:(void*)context { | 114 contextInfo:(void*)context { |
145 [sheet close]; | 115 [sheet close]; |
146 [sheet orderOut:self]; | 116 [sheet orderOut:self]; |
147 } | 117 } |
148 | 118 |
149 - (IBAction)closeSheet:(id)sender { | 119 - (IBAction)closeSheet:(id)sender { |
150 [NSApp endSheet:[self window]]; | 120 [NSApp endSheet:[self window]]; |
151 } | 121 } |
152 | 122 |
153 - (IBAction)removeRow:(id)sender { | |
154 RemoveRowsTableModel::Rows rows; | |
155 [self selectedRows:&rows]; | |
156 model_->RemoveRows(rows); | |
157 } | |
158 | |
159 - (IBAction)removeAll:(id)sender { | |
160 model_->RemoveAll(); | |
161 } | |
162 | |
163 // Table View Data Source ----------------------------------------------------- | |
164 | |
165 - (NSInteger)numberOfRowsInTableView:(NSTableView*)table { | |
166 return model_->RowCount(); | |
167 } | |
168 | |
169 - (id)tableView:(NSTableView*)tv | |
170 objectValueForTableColumn:(NSTableColumn*)tableColumn | |
171 row:(NSInteger)row { | |
172 NSObject* result = nil; | |
173 NSString* identifier = [tableColumn identifier]; | |
174 if ([identifier isEqualToString:@"hostname"]) { | |
175 std::wstring host = model_->GetText(row, IDS_EXCEPTIONS_HOSTNAME_HEADER); | |
176 result = base::SysWideToNSString(host); | |
177 } else if ([identifier isEqualToString:@"action"]) { | |
178 std::wstring action = model_->GetText(row, IDS_EXCEPTIONS_ACTION_HEADER); | |
179 result = base::SysWideToNSString(action); | |
180 } else { | |
181 NOTREACHED(); | |
182 } | |
183 return result; | |
184 } | |
185 | |
186 // Table View Delegate -------------------------------------------------------- | |
187 | |
188 // When the selection in the table view changes, we need to adjust buttons. | |
189 - (void)tableViewSelectionDidChange:(NSNotification*)notification { | |
190 [self adjustEditingButtons]; | |
191 } | |
192 | |
193 // Private -------------------------------------------------------------------- | |
194 | |
195 // Returns the selected rows. | |
196 - (void)selectedRows:(RemoveRowsTableModel::Rows*)rows { | |
197 NSIndexSet* selection = [tableView_ selectedRowIndexes]; | |
198 for (NSUInteger index = [selection lastIndex]; index != NSNotFound; | |
199 index = [selection indexLessThanIndex:index]) | |
200 rows->insert(index); | |
201 } | |
202 | |
203 // This method appropriately sets the enabled states on the table's editing | |
204 // buttons. | |
205 - (void)adjustEditingButtons { | |
206 RemoveRowsTableModel::Rows rows; | |
207 [self selectedRows:&rows]; | |
208 [removeButton_ setEnabled:model_->CanRemoveRows(rows)]; | |
209 [removeAllButton_ setEnabled:([tableView_ numberOfRows] > 0)]; | |
210 } | |
211 | |
212 - (void)modelDidChange { | |
213 [tableView_ reloadData]; | |
214 [self adjustEditingButtons]; | |
215 } | |
216 | 123 |
217 @end | 124 @end |
OLD | NEW |