| 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 "tab_view_picker_table.h" | 5 #import "tab_view_picker_table.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 | 8 |
| 9 @interface TabViewPickerTable (Private) |
| 10 // If a heading is shown, the indices between the tab items and the table rows |
| 11 // are shifted by one. These functions convert between tab indices and table |
| 12 // indices. |
| 13 - (NSInteger)tabIndexFromTableIndex:(NSInteger)tableIndex; |
| 14 - (NSInteger)tableIndexFromTabIndex:(NSInteger)tabIndex; |
| 15 |
| 16 // Returns if |item| is the item shown as heading. If |heading_| is nil, this |
| 17 // always returns |NO|. |
| 18 - (BOOL)isHeadingItem:(id)item; |
| 19 |
| 20 // Reloads the outline view and sets the selection to the row corresponding to |
| 21 // the currently selected tab. |
| 22 - (void)reloadDataWhileKeepingCurrentTabSelected; |
| 23 @end |
| 24 |
| 9 @implementation TabViewPickerTable | 25 @implementation TabViewPickerTable |
| 10 | 26 |
| 11 - (id)initWithFrame:(NSRect)frame { | 27 - (id)initWithFrame:(NSRect)frame { |
| 12 if ((self = [super initWithFrame:frame])) { | 28 if ((self = [super initWithFrame:frame])) { |
| 13 [self setDelegate:self]; | 29 [self setDelegate:self]; |
| 14 [self setDataSource:self]; | 30 [self setDataSource:self]; |
| 15 } | 31 } |
| 16 return self; | 32 return self; |
| 17 } | 33 } |
| 18 | 34 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 30 DCHECK_EQ([self dataSource], self); | 46 DCHECK_EQ([self dataSource], self); |
| 31 DCHECK(![self allowsEmptySelection]); | 47 DCHECK(![self allowsEmptySelection]); |
| 32 DCHECK(![self allowsMultipleSelection]); | 48 DCHECK(![self allowsMultipleSelection]); |
| 33 | 49 |
| 34 // Suppress the "Selection changed" message that's sent while the table is | 50 // Suppress the "Selection changed" message that's sent while the table is |
| 35 // being built for the first time (this causes a selection change to index 0 | 51 // being built for the first time (this causes a selection change to index 0 |
| 36 // and back to the prior index). | 52 // and back to the prior index). |
| 37 id oldTabViewDelegate = [tabView_ delegate]; | 53 id oldTabViewDelegate = [tabView_ delegate]; |
| 38 [tabView_ setDelegate:nil]; | 54 [tabView_ setDelegate:nil]; |
| 39 | 55 |
| 40 NSInteger index = | 56 [self reloadDataWhileKeepingCurrentTabSelected]; |
| 41 [tabView_ indexOfTabViewItem:[tabView_ selectedTabViewItem]]; | |
| 42 [self reloadData]; | |
| 43 [self selectRowIndexes:[NSIndexSet indexSetWithIndex:index] | |
| 44 byExtendingSelection:NO]; | |
| 45 | 57 |
| 46 oldTabViewDelegate_ = oldTabViewDelegate; | 58 oldTabViewDelegate_ = oldTabViewDelegate; |
| 47 [tabView_ setDelegate:self]; | 59 [tabView_ setDelegate:self]; |
| 48 } | 60 } |
| 49 | 61 |
| 50 // Table view delegate method. | 62 - (NSString*)heading { |
| 51 - (void)tableViewSelectionDidChange:(NSNotification*)aNotification { | 63 return heading_.get(); |
| 52 [tabView_ selectTabViewItemAtIndex:[self selectedRow]]; | |
| 53 } | 64 } |
| 54 | 65 |
| 55 // Table view data source methods. | 66 - (void)setHeading:(NSString*)str { |
| 56 - (NSInteger)numberOfRowsInTableView:(NSTableView*)tableView { | 67 heading_.reset([str copy]); |
| 57 return [tabView_ numberOfTabViewItems]; | 68 [self reloadDataWhileKeepingCurrentTabSelected]; |
| 58 } | 69 } |
| 59 | 70 |
| 60 - (id) tableView:(NSTableView*)tableView | 71 - (void)reloadDataWhileKeepingCurrentTabSelected { |
| 61 objectValueForTableColumn:(NSTableColumn*)tableColumn | 72 NSInteger index = |
| 62 row:(NSInteger)rowIndex { | 73 [tabView_ indexOfTabViewItem:[tabView_ selectedTabViewItem]]; |
| 63 return [[tabView_ tabViewItemAtIndex:rowIndex] label]; | 74 [self reloadData]; |
| 75 if (heading_) |
| 76 [self expandItem:[self outlineView:self child:0 ofItem:nil]]; |
| 77 NSIndexSet* indexSet = |
| 78 [NSIndexSet indexSetWithIndex:[self tableIndexFromTabIndex:index]]; |
| 79 [self selectRowIndexes:indexSet byExtendingSelection:NO]; |
| 64 } | 80 } |
| 65 | 81 |
| 66 // NSTabViewDelegate methods. | 82 // NSTabViewDelegate methods. |
| 67 - (void) tabView:(NSTabView*)tabView | 83 - (void) tabView:(NSTabView*)tabView |
| 68 didSelectTabViewItem:(NSTabViewItem*)tabViewItem { | 84 didSelectTabViewItem:(NSTabViewItem*)tabViewItem { |
| 69 DCHECK_EQ(tabView_, tabView); | 85 DCHECK_EQ(tabView_, tabView); |
| 70 NSInteger index = | 86 NSInteger index = |
| 71 [tabView_ indexOfTabViewItem:[tabView_ selectedTabViewItem]]; | 87 [tabView_ indexOfTabViewItem:[tabView_ selectedTabViewItem]]; |
| 72 [self selectRowIndexes:[NSIndexSet indexSetWithIndex:index] | 88 NSIndexSet* indexSet = |
| 73 byExtendingSelection:NO]; | 89 [NSIndexSet indexSetWithIndex:[self tableIndexFromTabIndex:index]]; |
| 90 [self selectRowIndexes:indexSet byExtendingSelection:NO]; |
| 74 if ([oldTabViewDelegate_ | 91 if ([oldTabViewDelegate_ |
| 75 respondsToSelector:@selector(tabView:didSelectTabViewItem:)]) { | 92 respondsToSelector:@selector(tabView:didSelectTabViewItem:)]) { |
| 76 [oldTabViewDelegate_ tabView:tabView didSelectTabViewItem:tabViewItem]; | 93 [oldTabViewDelegate_ tabView:tabView didSelectTabViewItem:tabViewItem]; |
| 77 } | 94 } |
| 78 } | 95 } |
| 79 | 96 |
| 80 - (BOOL) tabView:(NSTabView*)tabView | 97 - (BOOL) tabView:(NSTabView*)tabView |
| 81 shouldSelectTabViewItem:(NSTabViewItem*)tabViewItem { | 98 shouldSelectTabViewItem:(NSTabViewItem*)tabViewItem { |
| 82 if ([oldTabViewDelegate_ | 99 if ([oldTabViewDelegate_ |
| 83 respondsToSelector:@selector(tabView:shouldSelectTabViewItem:)]) { | 100 respondsToSelector:@selector(tabView:shouldSelectTabViewItem:)]) { |
| 84 return [oldTabViewDelegate_ tabView:tabView | 101 return [oldTabViewDelegate_ tabView:tabView |
| 85 shouldSelectTabViewItem:tabViewItem]; | 102 shouldSelectTabViewItem:tabViewItem]; |
| 86 } | 103 } |
| 87 return YES; | 104 return YES; |
| 88 } | 105 } |
| 89 | 106 |
| 90 - (void) tabView:(NSTabView*)tabView | 107 - (void) tabView:(NSTabView*)tabView |
| 91 willSelectTabViewItem:(NSTabViewItem*)tabViewItem { | 108 willSelectTabViewItem:(NSTabViewItem*)tabViewItem { |
| 92 if ([oldTabViewDelegate_ | 109 if ([oldTabViewDelegate_ |
| 93 respondsToSelector:@selector(tabView:willSelectTabViewItem:)]) { | 110 respondsToSelector:@selector(tabView:willSelectTabViewItem:)]) { |
| 94 [oldTabViewDelegate_ tabView:tabView willSelectTabViewItem:tabViewItem]; | 111 [oldTabViewDelegate_ tabView:tabView willSelectTabViewItem:tabViewItem]; |
| 95 } | 112 } |
| 96 } | 113 } |
| 97 | 114 |
| 115 - (NSInteger)tabIndexFromTableIndex:(NSInteger)tableIndex { |
| 116 if (!heading_) |
| 117 return tableIndex; |
| 118 DCHECK(tableIndex > 0); |
| 119 return tableIndex - 1; |
| 120 } |
| 121 |
| 122 - (NSInteger)tableIndexFromTabIndex:(NSInteger)tabIndex { |
| 123 DCHECK_GE(tabIndex, 0); |
| 124 DCHECK_LT(tabIndex, [tabView_ numberOfTabViewItems]); |
| 125 if (!heading_) |
| 126 return tabIndex; |
| 127 return tabIndex + 1; |
| 128 } |
| 129 |
| 130 - (BOOL)isHeadingItem:(id)item { |
| 131 return item && item == heading_.get(); |
| 132 } |
| 133 |
| 134 // NSOutlineViewDataSource methods. |
| 135 - (NSInteger) outlineView:(NSOutlineView*)outlineView |
| 136 numberOfChildrenOfItem:(id)item { |
| 137 if (!item) |
| 138 return heading_ ? 1 : [tabView_ numberOfTabViewItems]; |
| 139 return (item == heading_.get()) ? [tabView_ numberOfTabViewItems] : 0; |
| 140 } |
| 141 |
| 142 - (BOOL)outlineView:(NSOutlineView*)outlineView isItemExpandable:(id)item { |
| 143 return [self isHeadingItem:item]; |
| 144 } |
| 145 |
| 146 - (id)outlineView:(NSOutlineView*)outlineView |
| 147 child:(NSInteger)index |
| 148 ofItem:(id)item { |
| 149 if (!item) { |
| 150 return heading_.get() ? |
| 151 heading_.get() : static_cast<id>([tabView_ tabViewItemAtIndex:index]); |
| 152 } |
| 153 return (item == heading_.get()) ? [tabView_ tabViewItemAtIndex:index] : nil; |
| 154 } |
| 155 |
| 156 - (id) outlineView:(NSOutlineView*)outlineView |
| 157 objectValueForTableColumn:(NSTableColumn*)tableColumn |
| 158 byItem:(id)item { |
| 159 if ([item isKindOfClass:[NSTabViewItem class]]) |
| 160 return [static_cast<NSTabViewItem*>(item) label]; |
| 161 if ([self isHeadingItem:item]) |
| 162 return [item uppercaseString]; |
| 163 return nil; |
| 164 } |
| 165 |
| 166 // NSOutlineViewDelegate methods. |
| 167 - (void)outlineViewSelectionDidChange:(NSNotification*)notification { |
| 168 int row = [self selectedRow]; |
| 169 [tabView_ selectTabViewItemAtIndex:[self tabIndexFromTableIndex:row]]; |
| 170 } |
| 171 |
| 172 - (BOOL)outlineView:(NSOutlineView *)sender isGroupItem:(id)item { |
| 173 return [self isHeadingItem:item]; |
| 174 } |
| 175 |
| 176 - (BOOL)outlineView:(NSOutlineView*)outlineView shouldExpandItem:(id)item { |
| 177 return [self isHeadingItem:item]; |
| 178 } |
| 179 |
| 180 - (BOOL)outlineView:(NSOutlineView*)outlineView shouldCollapseItem:(id)item { |
| 181 return NO; |
| 182 } |
| 183 |
| 184 - (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item { |
| 185 return ![self isHeadingItem:item]; |
| 186 } |
| 187 |
| 188 // -outlineView:shouldShowOutlineCellForItem: is 10.6-only. |
| 189 - (NSRect)frameOfOutlineCellAtRow:(NSInteger)row { |
| 190 return NSZeroRect; |
| 191 } |
| 192 |
| 98 @end | 193 @end |
| OLD | NEW |