| 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 |