OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 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 #import "chrome/browser/cocoa/bookmark_tree_controller.h" |
| 6 |
| 7 #include "base/nsimage_cache_mac.h" |
| 8 #include "base/sys_string_conversions.h" |
| 9 #import "chrome/browser/cocoa/bookmark_manager_controller.h" |
| 10 #include "chrome/browser/bookmarks/bookmark_model.h" |
| 11 #include "googleurl/src/gurl.h" |
| 12 #import "third_party/apple/ImageAndTextCell.h" |
| 13 |
| 14 |
| 15 @implementation BookmarkTreeController |
| 16 |
| 17 // Allow the |group| property to be bound (by BookmarkManagerController.) |
| 18 + (void)initialize { |
| 19 [self exposeBinding:@"group"]; |
| 20 } |
| 21 |
| 22 // Initialization after the nib is loaded. |
| 23 - (void)awakeFromNib { |
| 24 [outline_ setTarget:self]; |
| 25 [outline_ setDoubleAction:@selector(itemDoubleClicked:)]; |
| 26 [self registerDragTypes]; |
| 27 } |
| 28 |
| 29 - (id)group { |
| 30 return group_; |
| 31 } |
| 32 |
| 33 - (void)setGroup:(id)group { |
| 34 if (group != group_) { |
| 35 group_ = group; |
| 36 |
| 37 [outline_ deselectAll:self]; |
| 38 [outline_ reloadData]; |
| 39 [outline_ noteNumberOfRowsChanged]; |
| 40 } |
| 41 } |
| 42 |
| 43 - (NSOutlineView*)outline { |
| 44 return outline_; |
| 45 } |
| 46 |
| 47 // Updates the tree after the data model has changed. |
| 48 - (void)itemChanged:(id)nodeItem childrenChanged:(BOOL)childrenChanged { |
| 49 if (nodeItem == group_) |
| 50 nodeItem = nil; |
| 51 [outline_ reloadItem:nodeItem reloadChildren:childrenChanged]; |
| 52 } |
| 53 |
| 54 // Getter for the |selectedItems| property. |
| 55 - (NSArray*)selectedItems { |
| 56 NSMutableArray* items = [NSMutableArray array]; |
| 57 NSIndexSet* selectedRows = [outline_ selectedRowIndexes]; |
| 58 if (selectedRows != nil) { |
| 59 for (NSInteger row = [selectedRows firstIndex]; row != NSNotFound; |
| 60 row = [selectedRows indexGreaterThanIndex:row]) { |
| 61 [items addObject:[outline_ itemAtRow:row]]; |
| 62 } |
| 63 } |
| 64 return items; |
| 65 } |
| 66 |
| 67 // Setter for the |selectedItems| property. |
| 68 - (void)setSelectedItems:(NSArray*)items { |
| 69 NSMutableIndexSet* newSelection = [NSMutableIndexSet indexSet]; |
| 70 |
| 71 for (NSUInteger i = 0; i < [items count]; i++) { |
| 72 NSInteger row = [outline_ rowForItem:[items objectAtIndex:i]]; |
| 73 if (row >= 0) { |
| 74 [newSelection addIndex:row]; |
| 75 } |
| 76 } |
| 77 |
| 78 [outline_ selectRowIndexes:newSelection byExtendingSelection:NO]; |
| 79 } |
| 80 |
| 81 |
| 82 #pragma mark - |
| 83 #pragma mark COMMANDS: |
| 84 |
| 85 |
| 86 // Responds to a double-click by opening the selected URL(s). |
| 87 - (IBAction)itemDoubleClicked:(id)sender { |
| 88 for (id item in [self selectedItems]) { |
| 89 [manager_ openBookmarkItem:item]; |
| 90 } |
| 91 } |
| 92 |
| 93 // The Delete command (also bound to the delete key.) |
| 94 - (IBAction)delete:(id)sender { |
| 95 NSIndexSet* selectedRows = [outline_ selectedRowIndexes]; |
| 96 if (!selectedRows) { |
| 97 NSBeep(); |
| 98 return; |
| 99 } |
| 100 // Iterate backwards so that any selected children are deleted before |
| 101 // selected parents (opposite order would cause double-free!) and so each |
| 102 // deletion doesn't invalidate the remaining row numbers. |
| 103 for (NSInteger row = [selectedRows lastIndex]; row != NSNotFound; |
| 104 row = [selectedRows indexLessThanIndex:row]) { |
| 105 const BookmarkNode* node = [manager_ nodeFromItem: |
| 106 [outline_ itemAtRow:row]]; |
| 107 const BookmarkNode* parent = node->GetParent(); |
| 108 [manager_ bookmarkModel]->Remove(parent, parent->IndexOfChild(node)); |
| 109 } |
| 110 |
| 111 [outline_ reloadData]; |
| 112 [outline_ deselectAll:self]; |
| 113 } |
| 114 |
| 115 |
| 116 #pragma mark - |
| 117 #pragma mark DATA SOURCE: |
| 118 |
| 119 |
| 120 // The NSOutlineView data source methods are called with a nil item to |
| 121 // represent the root of the tree; this compensates for that. |
| 122 - (const BookmarkNode*)nodeFromItem:(id)item { |
| 123 return [manager_ nodeFromItem:(item ? item : group_)]; |
| 124 } |
| 125 |
| 126 - (id)itemFromNode:(const BookmarkNode*)node { |
| 127 id item = [manager_ itemFromNode:node]; |
| 128 return item == group_ ? nil : item; |
| 129 } |
| 130 |
| 131 // Returns the children of an item (NSOutlineView data source) |
| 132 - (NSArray*)childrenOfItem:(id)item { |
| 133 const BookmarkNode* node = [self nodeFromItem:item]; |
| 134 if (!node) { |
| 135 return nil; |
| 136 } |
| 137 int nChildren = node->GetChildCount(); |
| 138 NSMutableArray* children = [NSMutableArray arrayWithCapacity:nChildren]; |
| 139 for (int i = 0; i < nChildren; i++) { |
| 140 [children addObject:[self itemFromNode:node->GetChild(i)]]; |
| 141 } |
| 142 return children; |
| 143 } |
| 144 |
| 145 // Returns the number of children of an item (NSOutlineView data source) |
| 146 - (NSInteger) outlineView:(NSOutlineView*)outlineView |
| 147 numberOfChildrenOfItem:(id)item { |
| 148 const BookmarkNode* node = [self nodeFromItem:item]; |
| 149 return node ? node->GetChildCount() : 0; |
| 150 } |
| 151 |
| 152 // Returns a child of an item (NSOutlineView data source) |
| 153 - (id)outlineView:(NSOutlineView*)outlineView |
| 154 child:(NSInteger)index |
| 155 ofItem:(id)item { |
| 156 const BookmarkNode* node = [self nodeFromItem:item]; |
| 157 return [self itemFromNode:node->GetChild(index)]; |
| 158 } |
| 159 |
| 160 // Returns whether an item is a folder (NSOutlineView data source) |
| 161 - (BOOL)outlineView:(NSOutlineView*)outlineView isItemExpandable:(id)item { |
| 162 return [self nodeFromItem:item]->is_folder(); |
| 163 } |
| 164 |
| 165 // Returns the value to display in a cell (NSOutlineView data source) |
| 166 - (id) outlineView:(NSOutlineView*)outlineView |
| 167 objectValueForTableColumn:(NSTableColumn*)tableColumn |
| 168 byItem:(id)item { |
| 169 const BookmarkNode* node = [self nodeFromItem:item]; |
| 170 NSString* ident = [tableColumn identifier]; |
| 171 if ([ident isEqualToString:@"title"]) { |
| 172 return base::SysWideToNSString(node->GetTitle()); |
| 173 } else if ([ident isEqualToString:@"url"]) { |
| 174 return base::SysUTF8ToNSString(node->GetURL().possibly_invalid_spec()); |
| 175 } else { |
| 176 NOTREACHED(); |
| 177 return nil; |
| 178 } |
| 179 } |
| 180 |
| 181 // Stores the edited value of a cell (NSOutlineView data source) |
| 182 - (void)outlineView:(NSOutlineView*)outlineView |
| 183 setObjectValue:(id)value |
| 184 forTableColumn:(NSTableColumn*)tableColumn |
| 185 byItem:(id)item |
| 186 { |
| 187 const BookmarkNode* node = [self nodeFromItem:item]; |
| 188 NSString* ident = [tableColumn identifier]; |
| 189 if ([ident isEqualToString:@"title"]) { |
| 190 [manager_ bookmarkModel]->SetTitle(node, base::SysNSStringToWide(value)); |
| 191 } else if ([ident isEqualToString:@"url"]) { |
| 192 GURL url(base::SysNSStringToUTF8(value)); |
| 193 if (url != node->GetURL()) { |
| 194 //TODO(snej): Uncomment this once SetURL exists (bug 10603). |
| 195 // ...or work around it by removing node and adding new one. |
| 196 //[manager_ bookmarkModel]->SetURL(node, url); |
| 197 } |
| 198 } |
| 199 } |
| 200 |
| 201 // Returns whether a cell is editable (NSOutlineView data source) |
| 202 - (BOOL) outlineView:(NSOutlineView*)outlineView |
| 203 shouldEditTableColumn:(NSTableColumn*)tableColumn |
| 204 item:(id)item { |
| 205 //TODO(snej): Make URL column editable once setter method exists (bug 10603). |
| 206 NSString* ident = [tableColumn identifier]; |
| 207 return [ident isEqualToString:@"title"]; |
| 208 } |
| 209 |
| 210 // Sets a cell's icon before it's drawn (NSOutlineView data source) |
| 211 - (void)outlineView:(NSOutlineView*)outlineView |
| 212 willDisplayCell:(id)cell |
| 213 forTableColumn:(NSTableColumn*)tableColumn |
| 214 item:(id)item |
| 215 { |
| 216 if ([[tableColumn identifier] isEqualToString:@"title"]) { |
| 217 [(ImageAndTextCell*)cell setImage:[manager_ iconForItem:item]]; |
| 218 } |
| 219 } |
| 220 |
| 221 @end |
| 222 |
| 223 |
| 224 @implementation BookmarksOutlineView |
| 225 |
| 226 - (IBAction)cut:(id)sender { |
| 227 [(BookmarkTreeController*)[self delegate] cut:sender]; |
| 228 } |
| 229 |
| 230 - (IBAction)copy:(id)sender { |
| 231 [(BookmarkTreeController*)[self delegate] copy:sender]; |
| 232 } |
| 233 |
| 234 - (IBAction)paste:(id)sender { |
| 235 [(BookmarkTreeController*)[self delegate] paste:sender]; |
| 236 } |
| 237 |
| 238 - (IBAction)delete:(id)sender { |
| 239 [(BookmarkTreeController*)[self delegate] delete:sender]; |
| 240 } |
| 241 |
| 242 - (BOOL)validateMenuItem:(NSMenuItem*)menuItem { |
| 243 return [[self delegate] validateMenuItem:menuItem]; |
| 244 } |
| 245 |
| 246 - (void)keyDown:(NSEvent*)event { |
| 247 if ([event keyCode] == 51) // Delete key |
| 248 [self delete:self]; |
| 249 else |
| 250 [super keyDown:event]; |
| 251 } |
| 252 |
| 253 @end |
OLD | NEW |