diff --git a/ChangeLog b/ChangeLog
index ae6603ce0..943cab4e0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2024-07-25 Gregory John Casamento Returns the NSBrowserCell class (regardless of whether a
+/** Returns the NSBrowserCell class (regardless of whether a
-setCellClass: message has been sent to a particular instance). This
method is not meant to be used by applications. See Also: -setCellClass: Sets the NSCell instance copied to display items in the columns of
- NSBrowser. See Also: -cellPrototype
See Also: -cellPrototype
*/ - (void) setCellPrototype: (NSCell *)aCell { @@ -295,7 +303,7 @@ static BOOL browserUseBezels; } /**Returns the class of NSMatrix used in the NSBrowser's columns.
-See Also: -setMatrixClass:
+See Also: -setMatrixClass:
*/ - (Class) matrixClass { @@ -303,7 +311,7 @@ static BOOL browserUseBezels; } /**Sets the matrix class (NSMatrix or an NSMatrix subclass) used in the - NSBrowser's columns.
See Also: -matrixClass
+ NSBrowser's columns.See Also: -matrixClass
*/ - (void) setMatrixClass: (Class)classId { @@ -328,7 +336,7 @@ static BOOL browserUseBezels; { return nil; } - + if (!(matrix = [self matrixInColumn: i])) { return nil; @@ -337,9 +345,9 @@ static BOOL browserUseBezels; return [matrix selectedCell]; } -/**Returns the last (lowest) NSCell that's selected in column. +/**
Returns the last (lowest) NSCell that's selected in column. Returns nil if no cell is selected
-See Also: -selectedCell -selectedCells
+See Also: -selectedCell -selectedCells
*/ - (id) selectedCellInColumn: (NSInteger)column { @@ -354,7 +362,7 @@ static BOOL browserUseBezels; } /**Returns a NSArray of selected cells in the rightmost column. Returns - nil if no cell is selected.
See Also: -selectedCell + nil if no cell is selected.
See Also: -selectedCell -selectedCellInColumn: [NSMatrix selectedCells]
*/ - (NSArray *) selectedCells @@ -367,7 +375,7 @@ static BOOL browserUseBezels; { return nil; } - + if (!(matrix = [self matrixInColumn: i])) { return nil; @@ -407,15 +415,15 @@ static BOOL browserUseBezels; return [matrix selectedRow]; } -/**Selects the cell at index row in the column identified by - index column. If the delegate method +/**
Selects the cell at index row in the column identified by + index column. If the delegate method -browser:selectRow:inColumn: is implemented, this is its responsability to select the cell. This method adds a NSBrowser column if needed - and deselects other selections if the browser does not allows multiple - selection.
See Also: -loadedCellAtRow:column: + and deselects other selections if the browser does not allows multiple + selection.
See Also: -loadedCellAtRow:column: -browser:selectRow:inColumn: [NSMatrix-selectCellAtRow:column:]
*/ -- (void) selectRow: (NSInteger)row inColumn: (NSInteger)column +- (void) selectRow: (NSInteger)row inColumn: (NSInteger)column { NSMatrix *matrix; id cell; @@ -432,18 +440,18 @@ static BOOL browserUseBezels; } [self setLastColumn: column]; - + if (_allowsMultipleSelection == NO) { [matrix deselectAllCells]; } if ([_browserDelegate respondsToSelector: - @selector(browser:selectRow:inColumn:)]) + @selector(browser:selectRow:inColumn:)]) { didSelect = [_browserDelegate browser: self - selectRow: row - inColumn: column]; + selectRow: row + inColumn: column]; } else { @@ -451,8 +459,8 @@ static BOOL browserUseBezels; didSelect = YES; } - if (didSelect && (![cell respondsToSelector: @selector(isLeaf)] - || ([(NSBrowserCell*)cell isLeaf] == NO))) + if (didSelect && (![cell respondsToSelector: @selector(isLeaf)] + || ([(NSBrowserCell*)cell isLeaf] == NO))) { [self addColumn]; } @@ -469,14 +477,14 @@ static BOOL browserUseBezels; if (selectedColumn > -1) { NSUInteger rowIndexes[selectedColumn + 1]; - - for (columnNumber = 0; columnNumber <= selectedColumn; columnNumber++) - { - rowIndexes[columnNumber] = [self selectedRowInColumn: columnNumber]; - } - return [[NSIndexPath alloc] initWithIndexes: rowIndexes - length: selectedColumn + 1]; + for (columnNumber = 0; columnNumber <= selectedColumn; columnNumber++) + { + rowIndexes[columnNumber] = [self selectedRowInColumn: columnNumber]; + } + + return [[NSIndexPath alloc] initWithIndexes: rowIndexes + length: selectedColumn + 1]; } return nil; @@ -499,15 +507,15 @@ static BOOL browserUseBezels; // FIXME: There should be a more efficent way to the the selected row numbers if (!(matrix = [self matrixInColumn: selectedColumn])) - { - return nil; - } + { + return nil; + } selectedCells = [matrix selectedCells]; if (selectedCells == nil) - { - return nil; - } + { + return nil; + } count = [selectedCells count]; NSInteger seletedRows[count]; @@ -516,46 +524,46 @@ static BOOL browserUseBezels; int i = 0; while ((cell = [enumerator nextObject]) != nil) - { - NSInteger row; - NSInteger column; + { + NSInteger row; + NSInteger column; - [matrix getRow: &row - column: &column - ofCell: cell]; - seletedRows[i++] = row; - } + [matrix getRow: &row + column: &column + ofCell: cell]; + seletedRows[i++] = row; + } if (selectedColumn > 0) - { - NSIndexPath *indexPath; - NSUInteger rowIndexes[selectedColumn]; - NSInteger columnNumber = 0; - - for (columnNumber = 0; columnNumber < selectedColumn; columnNumber++) - { - rowIndexes[columnNumber] = [self selectedRowInColumn: columnNumber]; - } - - indexPath = [[NSIndexPath alloc] initWithIndexes: rowIndexes - length: selectedColumn]; - - for (i = 0; i < count; i++) - { - [paths addObject: [indexPath indexPathByAddingIndex: seletedRows[i]]]; - } - } - if (selectedColumn == 0) - { - NSIndexPath *indexPath; + { + NSIndexPath *indexPath; + NSUInteger rowIndexes[selectedColumn]; + NSInteger columnNumber = 0; - for (i = 0; i < count; i++) - { - indexPath = [[NSIndexPath alloc] initWithIndex: seletedRows[i]]; - [paths addObject: indexPath]; - RELEASE(indexPath); - } - } + for (columnNumber = 0; columnNumber < selectedColumn; columnNumber++) + { + rowIndexes[columnNumber] = [self selectedRowInColumn: columnNumber]; + } + + indexPath = [[NSIndexPath alloc] initWithIndexes: rowIndexes + length: selectedColumn]; + + for (i = 0; i < count; i++) + { + [paths addObject: [indexPath indexPathByAddingIndex: seletedRows[i]]]; + } + } + if (selectedColumn == 0) + { + NSIndexPath *indexPath; + + for (i = 0; i < count; i++) + { + indexPath = [[NSIndexPath alloc] initWithIndex: seletedRows[i]]; + [paths addObject: indexPath]; + RELEASE(indexPath); + } + } return paths; } @@ -588,12 +596,12 @@ static BOOL browserUseBezels; } } -/** Loads if necessary and returns the NSCell at row in column. +/** Loads if necessary and returns the NSCell at row in column. if you change this code, you may want to look at the __performLoadOfColumn: - method in which the following code is integrated (for speed) + method in which the following code is integrated (for speed) */ - (id) loadedCellAtRow: (NSInteger)row - column: (NSInteger)column + column: (NSInteger)column { NSMatrix *matrix; NSCell *cell; @@ -610,27 +618,27 @@ static BOOL browserUseBezels; } // Load if not already loaded - if (![cell respondsToSelector: @selector(isLoaded)] + if (![cell respondsToSelector: @selector(isLoaded)] || [(NSBrowserCell*)cell isLoaded]) { return cell; } else { - if (_passiveDelegate || [_browserDelegate respondsToSelector: - @selector(browser:willDisplayCell:atRow:column:)]) - { - [_browserDelegate browser: self willDisplayCell: cell - atRow: row column: column]; - } + if (_passiveDelegate || [_browserDelegate respondsToSelector: + @selector(browser:willDisplayCell:atRow:column:)]) + { + [_browserDelegate browser: self willDisplayCell: cell + atRow: row column: column]; + } [(NSBrowserCell*)cell setLoaded: YES]; } return cell; } -/**Returns the matrix located in the column identified by index - column. Returns nil if the matrix does not exists
+/**Returns the matrix located in the column identified by index + column. Returns nil if the matrix does not exists
*/ - (NSMatrix *) matrixInColumn: (NSInteger)column { @@ -642,7 +650,7 @@ static BOOL browserUseBezels; } browserColumn = [_browserColumns objectAtIndex: column]; - + if ((browserColumn == nil) || !(browserColumn->_isLoaded)) { return nil; @@ -723,7 +731,7 @@ static BOOL browserUseBezels; subStrings = [[path componentsSeparatedByString: _pathSeparator] mutableCopy]; [subStrings removeObject: @""]; numberOfSubStrings = [subStrings count]; - + if ([path hasPrefix: _pathSeparator]) { NSUInteger i; @@ -739,20 +747,20 @@ static BOOL browserUseBezels; * case, we can avoid redrawing those columns. */ for (i = 0; i <= _lastColumnLoaded; i++) - { - if ((i < numberOfSubStrings) && - [[[self selectedCellInColumn: i] stringValue] - isEqualToString: [subStrings objectAtIndex: i]]) - { - column = i; - } - else - { - // Actually it's always called at 0 column, when string is "/" - [[self matrixInColumn: i] deselectAllCells]; - break; - } - } + { + if ((i < numberOfSubStrings) && + [[[self selectedCellInColumn: i] stringValue] + isEqualToString: [subStrings objectAtIndex: i]]) + { + column = i; + } + else + { + // Actually it's always called at 0 column, when string is "/" + [[self matrixInColumn: i] deselectAllCells]; + break; + } + } [self setLastColumn: column]; indexOfSubStrings = column; @@ -773,53 +781,53 @@ static BOOL browserUseBezels; BOOL found = NO; if (useDelegate == YES) - { - if ([_browserDelegate browser: self - selectCellWithString: aStr - inColumn: column]) - { - found = YES; - selectedCell = [matrix selectedCell]; - } - } + { + if ([_browserDelegate browser: self + selectCellWithString: aStr + inColumn: column]) + { + found = YES; + selectedCell = [matrix selectedCell]; + } + } else - { - NSInteger numOfRows = [matrix numberOfRows]; - NSInteger row; + { + NSInteger numOfRows = [matrix numberOfRows]; + NSInteger row; - // find the cell in the browser matrix which is equal to aStr - for (row = 0; row < numOfRows; row++) - { - selectedCell = [matrix cellAtRow: row column: 0]; + // find the cell in the browser matrix which is equal to aStr + for (row = 0; row < numOfRows; row++) + { + selectedCell = [matrix cellAtRow: row column: 0]; - if ([[selectedCell stringValue] isEqualToString: aStr]) - { - [matrix selectCellAtRow: row column: 0]; - found = YES; - break; - } - } - } + if ([[selectedCell stringValue] isEqualToString: aStr]) + { + [matrix selectCellAtRow: row column: 0]; + found = YES; + break; + } + } + } if (found) - { - indexOfSubStrings++; - } + { + indexOfSubStrings++; + } else - { - // if unable to find a cell whose title matches aStr return NO - NSDebugLLog (@"NSBrowser", - @"unable to find cell '%@' in column %d\n", - aStr, (int)column); - break; - } + { + // if unable to find a cell whose title matches aStr return NO + NSDebugLLog (@"NSBrowser", + @"unable to find cell '%@' in column %d\n", + aStr, (int)column); + break; + } // if the cell is a leaf, we are finished setting the path if ([selectedCell isLeaf]) - { - break; - } - + { + break; + } + // else, it is not a leaf: get a column in the browser for it [self addColumn]; column++; @@ -846,7 +854,7 @@ static BOOL browserUseBezels; NSMutableString *separator = [_pathSeparator mutableCopy]; NSString *string; NSInteger i; - + /* * Cannot go past the number of loaded columns */ @@ -860,22 +868,22 @@ static BOOL browserUseBezels; id cell = [self selectedCellInColumn: i]; if (i != 0) - { - [separator appendString: _pathSeparator]; - } + { + [separator appendString: _pathSeparator]; + } string = [cell stringValue]; - + if (string == nil) - { - /* This should happen only when c == nil, in which case it - doesn't make sense to go with the path */ - break; - } + { + /* This should happen only when c == nil, in which case it + doesn't make sense to go with the path */ + break; + } else - { - [separator appendString: string]; - } + { + [separator appendString: string]; + } } /* * We actually return a mutable string, but that's ok since a mutable @@ -904,7 +912,7 @@ static BOOL browserUseBezels; /* - * Manipulating columns + * Manipulating columns */ - (NSBrowserColumn *) _createColumn { @@ -919,7 +927,7 @@ static BOOL browserUseBezels; [sc setHasHorizontalScroller: NO]; [sc setHasVerticalScroller: YES]; [sc setBorderType: [self _resolvedBorderType]]; - + [bc setColumnScrollView: sc]; [self addSubview: sc]; RELEASE(sc); @@ -1028,7 +1036,7 @@ static BOOL browserUseBezels; [sc setNeedsDisplay: YES]; } -/**Returns the column number in which matrix is located. +/**
Returns the column number in which matrix is located. Returns -1 if matrix is not found.
*/ - (NSInteger) columnOfMatrix: (NSMatrix *)matrix @@ -1040,7 +1048,7 @@ static BOOL browserUseBezels; for (i = 0; i < count; ++i) { if (matrix == [self matrixInColumn: i]) - return i; + return i; } // Not found @@ -1056,11 +1064,11 @@ static BOOL browserUseBezels; for (i = _lastColumnLoaded; i >= 0; i--) { if (!(matrix = [self matrixInColumn: i])) - continue; + continue; if ([matrix selectedCell]) - return i; + return i; } - + return -1; } @@ -1085,7 +1093,7 @@ static BOOL browserUseBezels; { return; } - + if (column < 0) { column = -1; @@ -1103,25 +1111,25 @@ static BOOL browserUseBezels; sc = [bc columnScrollView]; if ([bc isLoaded]) - { - // Make the column appear empty by removing the matrix - if (sc) - { - [sc setDocumentView: nil]; - } - [bc setIsLoaded: NO]; - [self setTitle: nil ofColumn: i]; - } + { + // Make the column appear empty by removing the matrix + if (sc) + { + [sc setDocumentView: nil]; + } + [bc setIsLoaded: NO]; + [self setTitle: nil ofColumn: i]; + } if (!_reusesColumns && i > _lastVisibleColumn) - { - [sc removeFromSuperview]; - [_browserColumns removeObject: bc]; - count--; - i--; - } + { + [sc removeFromSuperview]; + [_browserColumns removeObject: bc]; + count--; + i--; + } } - + [self scrollColumnToVisible:column]; } @@ -1149,15 +1157,15 @@ static BOOL browserUseBezels; return _lastVisibleColumn; } -/** Invokes delegate method -browser:isColumnValid: for visible columns. +/** Invokes delegate method -browser:isColumnValid: for visible columns. */ - (void) validateVisibleColumns { NSInteger i; // If delegate doesn't care, just return - if (![_browserDelegate respondsToSelector: - @selector(browser:isColumnValid:)]) + if (![_browserDelegate respondsToSelector: + @selector(browser:isColumnValid:)]) { return; } @@ -1168,9 +1176,9 @@ static BOOL browserUseBezels; // Ask delegate if the column is valid and if not // then reload the column if (![_browserDelegate browser: self isColumnValid: i]) - { - [self reloadColumn: i]; - } + { + [self reloadColumn: i]; + } } } @@ -1212,12 +1220,13 @@ static BOOL browserUseBezels; { return; } - + // Get the previously selected cells selectedCells = [[matrix selectedCells] copy]; - + // Perform the data load [self _performLoadOfColumn: column]; + // set last column loaded [self setLastColumn: column]; @@ -1229,9 +1238,9 @@ static BOOL browserUseBezels; NSInteger sRow, sColumn; if ([matrix getRow: &sRow column: &sColumn ofCell: cell]) - { - [matrix selectCellAtRow: sRow column: sColumn]; - } + { + [matrix selectCellAtRow: sRow column: sColumn]; + } } RELEASE(selectedCells); } @@ -1243,7 +1252,7 @@ static BOOL browserUseBezels; /**Returns whether the user can select branch items when multiple selection is enabled. By default YES.
-See Also: -setAllowsBranchSelection:
+See Also: -setAllowsBranchSelection:
*/ - (BOOL) allowsBranchSelection { @@ -1251,7 +1260,7 @@ static BOOL browserUseBezels; } /**Sets whether the user can select branch items when multiple selection - is enabled. By default YES.
See Also: -allowsBranchSelection
+ is enabled. By default YES.See Also: -allowsBranchSelection
*/ - (void) setAllowsBranchSelection: (BOOL)flag { @@ -1259,7 +1268,7 @@ static BOOL browserUseBezels; } /**Returns whether there can be nothing selected. By default YES.
-See Also: -setAllowsEmptySelection:
+See Also: -setAllowsEmptySelection:
*/ - (BOOL) allowsEmptySelection { @@ -1277,14 +1286,14 @@ static BOOL browserUseBezels; _allowsEmptySelection = flag; for (i = 0; i <= _lastColumnLoaded; i++) - { - [[self matrixInColumn: i] setAllowsEmptySelection: flag]; - } + { + [[self matrixInColumn: i] setAllowsEmptySelection: flag]; + } } } /**Returns whether the user can select multiple items. By default YES.
-See Also: -allowsMultipleSelection
+See Also: -allowsMultipleSelection
*/ - (BOOL) allowsMultipleSelection { @@ -1292,7 +1301,7 @@ static BOOL browserUseBezels; } /**Sets whether the user can select multiple items. By default YES.
-See Also: -allowsMultipleSelection
+See Also: -allowsMultipleSelection
*/ - (void) setAllowsMultipleSelection: (BOOL)flag { @@ -1303,17 +1312,17 @@ static BOOL browserUseBezels; _allowsMultipleSelection = flag; if (flag) - { - mode = NSListModeMatrix; - } + { + mode = NSListModeMatrix; + } else - { - mode = NSRadioModeMatrix; - } + { + mode = NSRadioModeMatrix; + } for (i = 0; i <= _lastColumnLoaded; i++) - { - [[self matrixInColumn: i] setMode: mode]; - } + { + [[self matrixInColumn: i] setMode: mode]; + } } } @@ -1324,7 +1333,7 @@ static BOOL browserUseBezels; /**Returns YES if NSMatrix objects aren't freed when their columns are unloaded. By default a NSBrowser does not reuses their columns.
-See Also: -setReusesColumns: [NSMatrix-renewRows:columns:]
+See Also: -setReusesColumns: [NSMatrix-renewRows:columns:]
*/ - (BOOL) reusesColumns { @@ -1332,8 +1341,8 @@ static BOOL browserUseBezels; } /**If flag is YES, prevents NSMatrix objects from being freed when - their columns are unloaded, so they can be reused. By default a NSBrowser - does not reuses their columns.
See Also: -reusesColumns + their columns are unloaded, so they can be reused. By default a NSBrowser + does not reuses their columns.
See Also: -reusesColumns [NSMatrix-renewRows:columns:]
*/ - (void) setReusesColumns: (BOOL)flag @@ -1342,16 +1351,16 @@ static BOOL browserUseBezels; } /**Returns the maximum number of visible columns. By default a NSBrowser - has 3 visible columns.
See Also: -setMaxVisibleColumns:
+ has 3 visible columns.See Also: -setMaxVisibleColumns:
*/ - (NSInteger) maxVisibleColumns { return _maxVisibleColumns; } -/**Sets the maximum number of columns displayed and adjusts the various +/**
Sets the maximum number of columns displayed and adjusts the various subviews. By default a NSBrowser has 3 visible columns.
-See Also: -maxVisibleColumns
+See Also: -maxVisibleColumns
*/ - (void) setMaxVisibleColumns: (NSInteger)columnCount { @@ -1364,7 +1373,7 @@ static BOOL browserUseBezels; [self tile]; } -/**Returns the minimum column width in pixels.
+/**Returns the minimum column width in pixels.
See Also: -setMinColumnWidth:
*/ - (CGFloat) minColumnWidth @@ -1392,7 +1401,7 @@ static BOOL browserUseBezels; [self tile]; } -/**Returns whether columns are separated by bezeled borders. By default a +/**
Returns whether columns are separated by bezeled borders. By default a NSBrowser has separate columns.
See Also: -setSeparatesColumns:
*/ - (BOOL) separatesColumns @@ -1400,7 +1409,7 @@ static BOOL browserUseBezels; return _separatesColumns; } -/**Sets whether to separate columns with bezeled borders and marks self for +/**
Sets whether to separate columns with bezeled borders and marks self for display. Does nothing if the NSBrowser is titled. By default a NSBrowser has separate columns.
See Also: -separatesColumns -isTitled
*/ @@ -1481,7 +1490,7 @@ static BOOL browserUseBezels; } -/**Returns YES if the title of a column is set to the string value of +/**
Returns YES if the title of a column is set to the string value of the selected NSCell in the previous column. By default YES
See Also: -setTakesTitleFromPreviousColumn: -selectedCellInColumn:
*/ @@ -1491,7 +1500,7 @@ static BOOL browserUseBezels; } /**Sets whether the title of a column is set to the string value of the - selected NSCell in the previous column and marks self for display. By + selected NSCell in the previous column and marks self for display. By default YES
See Also: -takesTitleFromPreviousColumn -selectedCellInColumn:
*/ @@ -1527,16 +1536,16 @@ static BOOL browserUseBezels; } - (BOOL) canDragRowsWithIndexes: (NSIndexSet *)rowIndexes - inColumn: (NSInteger)columnIndex - withEvent: (NSEvent *)dragEvent + inColumn: (NSInteger)columnIndex + withEvent: (NSEvent *)dragEvent { - if ([_browserDelegate respondsToSelector: - @selector(browser:canDragRowsWithIndexes:inColumn:withEvent:)]) + if ([_browserDelegate respondsToSelector: + @selector(browser:canDragRowsWithIndexes:inColumn:withEvent:)]) { return [_browserDelegate browser: self - canDragRowsWithIndexes: rowIndexes - inColumn: columnIndex - withEvent: dragEvent]; + canDragRowsWithIndexes: rowIndexes + inColumn: columnIndex + withEvent: dragEvent]; } else { @@ -1560,24 +1569,24 @@ static BOOL browserUseBezels; return browserColumn->_columnTitle; } -/**Sets the title of the column at index column to +/**
Sets the title of the column at index column to aString and marks the title for dispaly if the NSBrowser can diplay titles or if the column column is visible.
See Also: -isTitled -titleFrameOfColumn: -titleHeight
*/ - (void) setTitle: (NSString *)aString - ofColumn: (NSInteger)column + ofColumn: (NSInteger)column { NSBrowserColumn *bc; bc = [_browserColumns objectAtIndex: column]; [bc setColumnTitle: aString]; - + // If column is not visible then nothing to redisplay if (!_isTitled || !NSBR_COLUMN_IS_VISIBLE(column)) return; - + [self setNeedsDisplayInRect: [self titleFrameOfColumn: column]]; } @@ -1592,13 +1601,13 @@ static BOOL browserUseBezels; /**Sets whether columns display titles and marks self for display. Does nothing if the NSBrowser hasn't separates columns. By default a NSBrowser displays titles.
-See Also: -isTitled -separatesColumns
+See Also: -isTitled -separatesColumns
*/ - (void) setTitled: (BOOL)flag { if (_isTitled == flag || !_separatesColumns) return; - + _isTitled = flag; [self tile]; [self setNeedsDisplay: YES]; @@ -1606,27 +1615,40 @@ static BOOL browserUseBezels; /** */ -- (void) drawTitleOfColumn: (NSInteger)column - inRect: (NSRect)aRect +- (void) drawTitleOfColumn: (NSInteger)column + inRect: (NSRect)aRect { - [self drawTitle: [self titleOfColumn: column] - inRect: aRect - ofColumn: column]; + [self drawTitle: [self titleOfColumn: column] + inRect: aRect + ofColumn: column]; } /** Draws the title for the column at index column within the rectangle defined by aRect. */ - (void) drawTitle: (NSString *)title - inRect: (NSRect)aRect - ofColumn: (NSInteger)column + inRect: (NSRect)aRect + ofColumn: (NSInteger)column { + NSView *cv = nil; + if (!_isTitled || !NSBR_COLUMN_IS_VISIBLE(column)) return; -// [titleCell setControlView: self]; + if (_itemBasedDelegate == YES) + { + SEL sel = @selector(browser:headerViewControllerForItem:); + if ([_browserDelegate respondsToSelector: sel]) + { + id item = [self _itemForColumn: column]; + NSViewController *vc = nil; + vc = [_browserDelegate browser: self headerViewControllerForItem: item]; + cv = [vc view]; + } + } + [titleCell setStringValue: title]; [titleCell drawWithFrame: aRect inView: self]; - [titleCell setControlView: nil]; + [titleCell setControlView: cv]; } /**Returns the height of column titles. The Nextish look returns 21.
@@ -1657,25 +1679,25 @@ static BOOL browserUseBezels; // Calculate origin if (_separatesColumns) - { - rect.origin.x = nbColumn * (_columnSize.width + browserColumnSeparation); - } + { + rect.origin.x = nbColumn * (_columnSize.width + browserColumnSeparation); + } else - { - rect.origin.x = nbColumn * _columnSize.width; - } + { + rect.origin.x = nbColumn * _columnSize.width; + } rect.origin.y = _frame.size.height - titleHeight; - + // Calculate size if (column == _lastVisibleColumn) - { - rect.size.width = _frame.size.width - rect.origin.x; - } + { + rect.size.width = _frame.size.width - rect.origin.x; + } else - { - rect.size.width = _columnSize.width; - } + { + rect.size.width = _columnSize.width; + } rect.size.height = titleHeight; @@ -1697,14 +1719,14 @@ static BOOL browserUseBezels; if (_lastVisibleColumn < column) { [self scrollColumnsRightBy: (column - _lastVisibleColumn)]; - } + } else if (_firstVisibleColumn > column) { [self scrollColumnsLeftBy: (_firstVisibleColumn - column)]; - } + } } -/**Scrolls columns left by shiftAmount columns.
+/**Scrolls columns left by shiftAmount columns.
See Also: -scrollColumnsRightBy: -scrollColumnToVisible:
*/ - (void) scrollColumnsLeftBy: (NSInteger)shiftAmount @@ -1735,7 +1757,7 @@ static BOOL browserUseBezels; // Notify the delegate if ([_browserDelegate respondsToSelector: @selector(browserDidScroll:)]) - [_browserDelegate browserDidScroll: self]; + [_browserDelegate browserDidScroll: self]; } /**Scrolls columns right by shiftAmount columns.
@@ -1796,7 +1818,7 @@ static BOOL browserUseBezels; [_horizontalScroller setFloatValue: fv knobProportion: prop]; } -/** Scrolls columns left or right based on an NSScroller. +/** Scrolls columns left or right based on an NSScroller. */ - (void) scrollViaScroller: (NSScroller *)sender { @@ -1804,36 +1826,36 @@ static BOOL browserUseBezels; if ([sender class] != [NSScroller class]) return; - + hit = [sender hitPart]; - + switch (hit) { // Scroll to the left case NSScrollerDecrementLine: case NSScrollerDecrementPage: - [self scrollColumnsLeftBy: 1]; - break; - + [self scrollColumnsLeftBy: 1]; + break; + // Scroll to the right case NSScrollerIncrementLine: case NSScrollerIncrementPage: - [self scrollColumnsRightBy: 1]; - break; - + [self scrollColumnsRightBy: 1]; + break; + // The knob or knob slot case NSScrollerKnob: case NSScrollerKnobSlot: - { - float f = [sender floatValue]; + { + float f = [sender floatValue]; + + [self scrollColumnToVisible: GSRoundTowardsInfinity(f * _lastColumnLoaded)]; + } + break; - [self scrollColumnToVisible: GSRoundTowardsInfinity(f * _lastColumnLoaded)]; - } - break; - // NSScrollerNoPart ??? default: - break; + break; } } @@ -1842,7 +1864,7 @@ static BOOL browserUseBezels; NSMatrix *matrix = [self matrixInColumn: column]; [matrix scrollCellToVisibleAtRow: row - column: 1]; + column: 1]; } /* @@ -1851,7 +1873,7 @@ static BOOL browserUseBezels; /**Returns whether an NSScroller is used to scroll horizontally. By default a NSBrowser has a horizontal scroller.
See Also: - -setHasHorizontalScroller:
+ -setHasHorizontalScroller: */ - (BOOL) hasHorizontalScroller { @@ -1870,9 +1892,9 @@ static BOOL browserUseBezels; { _hasHorizontalScroller = flag; if (!flag) - [_horizontalScroller removeFromSuperview]; + [_horizontalScroller removeFromSuperview]; else - [self addSubview: _horizontalScroller]; + [self addSubview: _horizontalScroller]; [self tile]; [self setNeedsDisplay: YES]; } @@ -1911,7 +1933,7 @@ static BOOL browserUseBezels; /**Sets whether pressing an arrow key will cause the action message to be sent (in addition to causing scrolling). By default YES.
-See Also: -sendsActionOnArrowKeys -setAcceptsArrowKeys: +
See Also: -sendsActionOnArrowKeys -setAcceptsArrowKeys: [NSControl-setAction:] [NSControl-action]
*/ - (void) setSendsActionOnArrowKeys: (BOOL)flag @@ -1959,9 +1981,9 @@ static BOOL browserUseBezels; else if (!_separatesColumns && browserUseBezels) { if (column == _firstVisibleColumn) - rect.origin.x += 2; + rect.origin.x += 2; else - rect.origin.x += (n + 2); + rect.origin.x += (n + 2); } // Adjust for horizontal scroller @@ -1970,15 +1992,15 @@ static BOOL browserUseBezels; if (_hasHorizontalScroller) { if (_separatesColumns) - rect.origin.y = (scrollerWidth - 1) + (2 * bezelBorderSize.height) + + rect.origin.y = (scrollerWidth - 1) + (2 * bezelBorderSize.height) + browserVerticalPadding; else rect.origin.y = scrollerWidth + bezelBorderSize.width; } else if (!_separatesColumns) - { - rect.origin.y += bezelBorderSize.width; - } + { + rect.origin.y += bezelBorderSize.width; + } } else { @@ -1990,10 +2012,10 @@ static BOOL browserUseBezels; if (column == _lastVisibleColumn) { if (_separatesColumns) - rect.size.width = _frame.size.width - rect.origin.x; - else - rect.size.width = _frame.size.width - - (rect.origin.x + bezelBorderSize.width); + rect.size.width = _frame.size.width - rect.origin.x; + else + rect.size.width = _frame.size.width - + (rect.origin.x + bezelBorderSize.width); // FIXME: Assumes left-side scrollers if ([[GSTheme theme] scrollViewScrollersOverlapBorders]) @@ -2059,7 +2081,7 @@ static BOOL browserUseBezels; bezelBorderSize = [[GSTheme theme] sizeForBorderType: NSBezelBorder]; _columnSize.height = _frame.size.height; - + // Titles (there is no real frames to resize) if (_isTitled) { @@ -2073,16 +2095,16 @@ static BOOL browserUseBezels; _scrollerRect.origin.x = bezelBorderSize.width; _scrollerRect.origin.y = bezelBorderSize.height - scrollerHightReduction; - _scrollerRect.size.width = (_frame.size.width - - (2 * bezelBorderSize.width)); + _scrollerRect.size.width = (_frame.size.width - + (2 * bezelBorderSize.width)); _scrollerRect.size.height = scrollerWidth; - + if (_separatesColumns) - _columnSize.height -= (scrollerWidth - scrollerHightReduction) + - (2 * bezelBorderSize.height) + browserVerticalPadding; + _columnSize.height -= (scrollerWidth - scrollerHightReduction) + + (2 * bezelBorderSize.height) + browserVerticalPadding; else - _columnSize.height -= scrollerWidth + (2 * bezelBorderSize.height); - + _columnSize.height -= scrollerWidth + (2 * bezelBorderSize.height); + // "Bottom corner" box if (!browserUseBezels && !useBottomCorner) { @@ -2099,20 +2121,20 @@ static BOOL browserUseBezels; } if (!NSEqualRects(_scrollerRect, [_horizontalScroller frame])) - { - [_horizontalScroller setFrame: _scrollerRect]; - } + { + [_horizontalScroller setFrame: _scrollerRect]; + } } else { _scrollerRect = NSZeroRect; if (!_separatesColumns) - _columnSize.height -= 2 * bezelBorderSize.width; + _columnSize.height -= 2 * bezelBorderSize.width; } if (_columnSize.height < 0) _columnSize.height = 0; - + num = _lastVisibleColumn - _firstVisibleColumn + 1; // Column count @@ -2121,14 +2143,14 @@ static BOOL browserUseBezels; CGFloat colWidth = _minColumnWidth + scrollerWidth; if (_separatesColumns) - colWidth += browserColumnSeparation; + colWidth += browserColumnSeparation; if (_frame.size.width > colWidth) - { - columnCount = (int)(_frame.size.width / colWidth); - } + { + columnCount = (int)(_frame.size.width / colWidth); + } else - columnCount = 1; + columnCount = 1; } else columnCount = num; @@ -2140,18 +2162,18 @@ static BOOL browserUseBezels; if (columnCount != num) { if (num > 0) - delta = columnCount - num; + delta = columnCount - num; else - delta = columnCount - 1; + delta = columnCount - 1; if ((delta > 0) && (_lastVisibleColumn <= _lastColumnLoaded)) - { - _firstVisibleColumn = (_firstVisibleColumn - delta > 0) ? - _firstVisibleColumn - delta : 0; - } + { + _firstVisibleColumn = (_firstVisibleColumn - delta > 0) ? + _firstVisibleColumn - delta : 0; + } for (i = [_browserColumns count]; i < columnCount; i++) - [self _createColumn]; + [self _createColumn]; _lastVisibleColumn = _firstVisibleColumn + columnCount - 1; } @@ -2160,8 +2182,8 @@ static BOOL browserUseBezels; if (_separatesColumns) frameWidth = _frame.size.width - ((columnCount - 1) * browserColumnSeparation); else - frameWidth = _frame.size.width - ((columnCount - 1) + - (2 * bezelBorderSize.width)); + frameWidth = _frame.size.width - ((columnCount - 1) + + (2 * bezelBorderSize.width)); _columnSize.width = (int)(frameWidth / (CGFloat)columnCount); @@ -2177,38 +2199,38 @@ static BOOL browserUseBezels; bc = [_browserColumns objectAtIndex: i]; if (!(sc = [bc columnScrollView])) - { - NSLog(@"NSBrowser error, sc != [bc columnScrollView]"); - return; - } + { + NSLog(@"NSBrowser error, sc != [bc columnScrollView]"); + return; + } [sc setBorderType: [self _resolvedBorderType]]; [sc setFrame: [self frameOfColumn: i]]; matrix = [bc columnMatrix]; - + // Adjust matrix to fit in scrollview if column has been loaded if (matrix && [bc isLoaded]) - { - NSSize cs, ms; - - cs = [sc contentSize]; - ms = [matrix cellSize]; - ms.width = cs.width; - [matrix setCellSize: ms]; - [sc setDocumentView: matrix]; - } + { + NSSize cs, ms; + + cs = [sc contentSize]; + ms = [matrix cellSize]; + ms.width = cs.width; + [matrix setCellSize: ms]; + [sc setDocumentView: matrix]; + } } if (columnCount != num) { [self updateScroller]; [self _remapColumnSubviews: YES]; - // [self _setColumnTitlesNeedDisplay]; + // [self _setColumnTitlesNeedDisplay]; [self setNeedsDisplay: YES]; } } -/** Override from NSControl. Don't do anything to change the size of the +/** Override from NSControl. Don't do anything to change the size of the browser. */ - (void) sizeToFit { @@ -2229,9 +2251,9 @@ static BOOL browserUseBezels; *Sets the delegate of the receiver. * If not nil, the delegate must either be passive and respond to * [NSObject-browser:numberOfRowsInColumn:] or be active and respond to - * [NSObject-browser:createRowsForColumn:inMatrix:] but not both. + * [NSObject-browser:createRowsForColumn:inMatrix:] but not both. * If the delegate is active it must also respond to - * [NSObject-browser:willDisplayCell:atRow:column:]. + * [NSObject-browser:willDisplayCell:atRow:column:]. * If the delegate is not nil but does not meet these conditions, * an NSBrowserIllegalDelegateException will be raised.
*See Also: -delegate
@@ -2242,46 +2264,60 @@ static BOOL browserUseBezels; /* Default to YES for nil delegate. */ _passiveDelegate = YES; + _itemBasedDelegate = NO; - if ([anObject respondsToSelector: - @selector(browser:numberOfRowsInColumn:)]) - { - flag = YES; - if (![anObject respondsToSelector: - @selector(browser:willDisplayCell:atRow:column:)]) - [NSException raise: NSBrowserIllegalDelegateException - format: @"(Passive) Delegate does not respond to %s\n", - GSNameFromSelector - (@selector(browser:willDisplayCell:atRow:column:))]; - } - - if ([anObject respondsToSelector: - @selector(browser:createRowsForColumn:inMatrix:)]) + if ([anObject respondsToSelector: + @selector(browser:numberOfChildrenOfItem:)] + && [anObject respondsToSelector: + @selector(browser:child:ofItem:)] + && [anObject respondsToSelector: + @selector(browser:isLeafItem:)]) { _passiveDelegate = NO; - - /* If flag is already set - then the delegate must respond to both methods. */ - if (flag) - { - [NSException raise: NSBrowserIllegalDelegateException - format: @"Delegate responds to both %s and %s\n", - GSNameFromSelector - (@selector(browser:numberOfRowsInColumn:)), - GSNameFromSelector - (@selector(browser:createRowsForColumn:inMatrix:))]; - } - - flag = YES; + _itemBasedDelegate = YES; } + else + { + if ([anObject respondsToSelector: + @selector(browser:numberOfRowsInColumn:)]) + { + flag = YES; + if (![anObject respondsToSelector: + @selector(browser:willDisplayCell:atRow:column:)]) + [NSException raise: NSBrowserIllegalDelegateException + format: @"(Passive) Delegate does not respond to %s\n", + GSNameFromSelector + (@selector(browser:willDisplayCell:atRow:column:))]; + } - if (!flag && anObject) - [NSException raise: NSBrowserIllegalDelegateException - format: @"Delegate does not respond to %s or %s\n", - GSNameFromSelector - (@selector(browser:numberOfRowsInColumn:)), - GSNameFromSelector - (@selector(browser:createRowsForColumn:inMatrix:))]; + if ([anObject respondsToSelector: + @selector(browser:createRowsForColumn:inMatrix:)]) + { + _passiveDelegate = NO; + + /* If flag is already set + then the delegate must respond to both methods. */ + if (flag) + { + [NSException raise: NSBrowserIllegalDelegateException + format: @"Delegate responds to both %s and %s\n", + GSNameFromSelector + (@selector(browser:numberOfRowsInColumn:)), + GSNameFromSelector + (@selector(browser:createRowsForColumn:inMatrix:))]; + } + + flag = YES; + } + + if (!flag && anObject) + [NSException raise: NSBrowserIllegalDelegateException + format: @"Delegate does not respond to %s or %s\n", + GSNameFromSelector + (@selector(browser:numberOfRowsInColumn:)), + GSNameFromSelector + (@selector(browser:createRowsForColumn:inMatrix:))]; + } _browserDelegate = anObject; } @@ -2292,7 +2328,7 @@ static BOOL browserUseBezels; */ /**Returns the NSBrowser's double-click action method.
-See Also: -setDoubleAction:
+See Also: -setDoubleAction:
*/ - (SEL) doubleAction { @@ -2300,14 +2336,14 @@ static BOOL browserUseBezels; } /**Sets the NSBrowser's double-click action to aSelector.
-See Also: -doubleAction
+See Also: -doubleAction
*/ - (void) setDoubleAction: (SEL)aSelector { _doubleAction = aSelector; } -/** Sends the action message to the target. Returns YES upon success, +/** Sends the action message to the target. Returns YES upon success, NO if no target for the message could be found. */ - (BOOL) sendAction { @@ -2337,7 +2373,7 @@ static BOOL browserUseBezels; // If the matrix isn't ours then just return if (column < 0 || column > _lastColumnLoaded) return; - + array = [sender selectedCells]; aCount = [array count]; if (aCount == 0) @@ -2349,9 +2385,9 @@ static BOOL browserUseBezels; while ((cell = [enumerator nextObject])) { if (_allowsBranchSelection == NO && [cell isLeaf] == NO) - { - [selectedCells removeObject: cell]; - } + { + [selectedCells removeObject: cell]; + } } if ([selectedCells count] == 0 && [sender selectedCell] != nil) @@ -2371,7 +2407,7 @@ static BOOL browserUseBezels; [sender deselectAllCells]; enumerator = [selectedCells objectEnumerator]; while ((cell = [enumerator nextObject])) - [sender selectCell: cell]; + [sender selectCell: cell]; [sender setAutoscroll: autoscroll]; } @@ -2383,9 +2419,9 @@ static BOOL browserUseBezels; // If the cell is not a leaf we need to load a column if (![cell isLeaf]) - { - [self addColumn]; - } + { + [self addColumn]; + } [sender scrollCellToVisibleAtRow: [sender selectedRow] column: 0]; } @@ -2441,13 +2477,13 @@ static BOOL browserUseBezels; // Initial version [self setVersion: 1]; - + /* Create the shared titleCell if it hasn't been created already. */ if (!titleCell) - { - titleCell = [GSBrowserTitleCell new]; - } - + { + titleCell = [GSBrowserTitleCell new]; + } + [self _themeDidActivate: nil]; } } @@ -2469,7 +2505,7 @@ static BOOL browserUseBezels; // Class setting _browserCellPrototype = [[[NSBrowser cellClass] alloc] init]; _browserMatrixClass = [NSMatrix class]; - + // Default values _pathSeparator = @"/"; _allowsBranchSelection = YES; @@ -2489,7 +2525,7 @@ static BOOL browserUseBezels; _sendsActionOnAlphaNumericalKeys = YES; _browserDelegate = nil; _passiveDelegate = YES; - _doubleAction = NULL; + _doubleAction = NULL; // FIXME: Seems a bit wrong to look at the current theme here bs = NSZeroSize; if (browserUseBezels) @@ -2519,6 +2555,9 @@ static BOOL browserUseBezels; _maxVisibleColumns = 3; [self _createColumn]; + // Item based delegate, 10.6+ + _itemBasedDelegate = NO; + [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_themeDidActivate:) @@ -2579,7 +2618,7 @@ static BOOL browserUseBezels; /* - * Events handling + * Events handling */ - (void) drawRect: (NSRect)rect @@ -2613,26 +2652,26 @@ static BOOL browserUseBezels; matrix = (NSMatrix *)[_window firstResponder]; selectedColumn = [self columnOfMatrix:matrix]; if (selectedColumn == -1) - { - selectedColumn = [self selectedColumn]; - matrix = [self matrixInColumn: selectedColumn]; - } + { + selectedColumn = [self selectedColumn]; + matrix = [self matrixInColumn: selectedColumn]; + } if (selectedColumn > 0) - { - [matrix deselectAllCells]; - [matrix scrollCellToVisibleAtRow:0 column:0]; - [self setLastColumn: selectedColumn]; + { + [matrix deselectAllCells]; + [matrix scrollCellToVisibleAtRow:0 column:0]; + [self setLastColumn: selectedColumn]; - selectedColumn--; - [self scrollColumnToVisible: selectedColumn]; - matrix = [self matrixInColumn: selectedColumn]; - [_window makeFirstResponder: matrix]; + selectedColumn--; + [self scrollColumnToVisible: selectedColumn]; + matrix = [self matrixInColumn: selectedColumn]; + [_window makeFirstResponder: matrix]; - if (_sendsActionOnArrowKeys == YES) - { - [super sendAction: _action to: _target]; - } - } + if (_sendsActionOnArrowKeys == YES) + { + [super sendAction: _action to: _target]; + } + } } } @@ -2646,47 +2685,47 @@ static BOOL browserUseBezels; matrix = (NSMatrix *)[_window firstResponder]; selectedColumn = [self columnOfMatrix:matrix]; if (selectedColumn == -1) - { - selectedColumn = [self selectedColumn]; - matrix = [self matrixInColumn: selectedColumn]; - } + { + selectedColumn = [self selectedColumn]; + matrix = [self matrixInColumn: selectedColumn]; + } if (selectedColumn == -1) - { - matrix = [self matrixInColumn: 0]; + { + matrix = [self matrixInColumn: 0]; - if ([[matrix cells] count]) - { - [matrix selectCellAtRow: 0 column: 0]; - } - } + if ([[matrix cells] count]) + { + [matrix selectCellAtRow: 0 column: 0]; + } + } else - { - // if there is one selected cell and it is a leaf, move right - // (column is already loaded) - if (![[matrix selectedCell] isLeaf] - && [[matrix selectedCells] count] == 1) - { - selectedColumn++; - matrix = [self matrixInColumn: selectedColumn]; - if ([[matrix cells] count] && [matrix selectedCell] == nil) - { - [matrix selectCellAtRow: 0 column: 0]; - } - // if selected cell is a leaf, we need to add a column - if (![[matrix selectedCell] isLeaf] - && [[matrix selectedCells] count] == 1) - { - [self addColumn]; - } - } - } + { + // if there is one selected cell and it is a leaf, move right + // (column is already loaded) + if (![[matrix selectedCell] isLeaf] + && [[matrix selectedCells] count] == 1) + { + selectedColumn++; + matrix = [self matrixInColumn: selectedColumn]; + if ([[matrix cells] count] && [matrix selectedCell] == nil) + { + [matrix selectCellAtRow: 0 column: 0]; + } + // if selected cell is a leaf, we need to add a column + if (![[matrix selectedCell] isLeaf] + && [[matrix selectedCells] count] == 1) + { + [self addColumn]; + } + } + } [_window makeFirstResponder: matrix]; if (_sendsActionOnArrowKeys == YES) - { - [super sendAction: _action to: _target]; - } + { + [super sendAction: _action to: _target]; + } } } @@ -2703,32 +2742,32 @@ static BOOL browserUseBezels; if (_acceptsArrowKeys) { switch (character) - { - case NSUpArrowFunctionKey: - case NSDownArrowFunctionKey: - return; - case NSLeftArrowFunctionKey: - [self moveLeft:self]; - return; - case NSRightArrowFunctionKey: - [self moveRight:self]; - return; - case NSBackTabCharacter: - [_window selectKeyViewPrecedingView: self]; - return; - case NSTabCharacter: - { - if ([theEvent modifierFlags] & NSShiftKeyMask) - { - [_window selectKeyViewPrecedingView: self]; - } - else - { - [_window selectKeyViewFollowingView: self]; - } - } - return; - } + { + case NSUpArrowFunctionKey: + case NSDownArrowFunctionKey: + return; + case NSLeftArrowFunctionKey: + [self moveLeft:self]; + return; + case NSRightArrowFunctionKey: + [self moveRight:self]; + return; + case NSBackTabCharacter: + [_window selectKeyViewPrecedingView: self]; + return; + case NSTabCharacter: + { + if ([theEvent modifierFlags] & NSShiftKeyMask) + { + [_window selectKeyViewPrecedingView: self]; + } + else + { + [_window selectKeyViewFollowingView: self]; + } + } + return; + } } if (_acceptsAlphaNumericalKeys && (character < 0xF700) @@ -2744,83 +2783,83 @@ static BOOL browserUseBezels; selectedColumn = [self selectedColumn]; if (selectedColumn != -1) - { - matrix = [self matrixInColumn: selectedColumn]; - n = [matrix numberOfRows]; - s = [matrix selectedRow]; - - if (!_charBuffer) - { - _charBuffer = [characters substringToIndex: 1]; - RETAIN(_charBuffer); - } - else - { - if (([theEvent timestamp] - _lastKeyPressed < 2000.0) - && (_alphaNumericalLastColumn == selectedColumn)) - { - NSString *transition; - transition = [_charBuffer - stringByAppendingString: - [characters substringToIndex: 1]]; - RELEASE(_charBuffer); - _charBuffer = transition; - RETAIN(_charBuffer); - } - else - { - RELEASE(_charBuffer); - _charBuffer = [characters substringToIndex: 1]; - RETAIN(_charBuffer); - } - } + { + matrix = [self matrixInColumn: selectedColumn]; + n = [matrix numberOfRows]; + s = [matrix selectedRow]; - _alphaNumericalLastColumn = selectedColumn; - _lastKeyPressed = [theEvent timestamp]; - - sv = [((*lcarc)(self, lcarcSel, s, selectedColumn)) - stringValue]; + if (!_charBuffer) + { + _charBuffer = [characters substringToIndex: 1]; + RETAIN(_charBuffer); + } + else + { + if (([theEvent timestamp] - _lastKeyPressed < 2000.0) + && (_alphaNumericalLastColumn == selectedColumn)) + { + NSString *transition; + transition = [_charBuffer + stringByAppendingString: + [characters substringToIndex: 1]]; + RELEASE(_charBuffer); + _charBuffer = transition; + RETAIN(_charBuffer); + } + else + { + RELEASE(_charBuffer); + _charBuffer = [characters substringToIndex: 1]; + RETAIN(_charBuffer); + } + } - if (([sv length] > 0) - && ([sv hasPrefix: _charBuffer])) - return; + _alphaNumericalLastColumn = selectedColumn; + _lastKeyPressed = [theEvent timestamp]; - match = -1; - for (i = s + 1; i < n; i++) - { - sv = [((*lcarc)(self, lcarcSel, i, selectedColumn)) - stringValue]; - if (([sv length] > 0) - && ([sv hasPrefix: _charBuffer])) - { - match = i; - break; - } - } - if (i == n) - { - for (i = 0; i < s; i++) - { - sv = [((*lcarc)(self, lcarcSel, i, selectedColumn)) - stringValue]; - if (([sv length] > 0) - && ([sv hasPrefix: _charBuffer])) - { - match = i; - break; - } - } - } - if (match != -1) - { - [matrix deselectAllCells]; - [self selectRow: match - inColumn: selectedColumn]; - [matrix scrollCellToVisibleAtRow: match column: 0]; - [matrix performClick: self]; - return; - } - } + sv = [((*lcarc)(self, lcarcSel, s, selectedColumn)) + stringValue]; + + if (([sv length] > 0) + && ([sv hasPrefix: _charBuffer])) + return; + + match = -1; + for (i = s + 1; i < n; i++) + { + sv = [((*lcarc)(self, lcarcSel, i, selectedColumn)) + stringValue]; + if (([sv length] > 0) + && ([sv hasPrefix: _charBuffer])) + { + match = i; + break; + } + } + if (i == n) + { + for (i = 0; i < s; i++) + { + sv = [((*lcarc)(self, lcarcSel, i, selectedColumn)) + stringValue]; + if (([sv length] > 0) + && ([sv hasPrefix: _charBuffer])) + { + match = i; + break; + } + } + } + if (match != -1) + { + [matrix deselectAllCells]; + [self selectRow: match + inColumn: selectedColumn]; + [matrix scrollCellToVisibleAtRow: match column: 0]; + [matrix performClick: self]; + return; + } + } _lastKeyPressed = 0.; } @@ -2870,9 +2909,9 @@ static BOOL browserUseBezels; [aCoder encodeInt: _columnResizing forKey: @"NSColumnResizingType"]; //[aCoder encodeInt: prefWidth forKey: @"NSPreferedColumnWidth"]; if (nil != [self columnsAutosaveName]) - { - [aCoder encodeObject: [self columnsAutosaveName] forKey: @"NSColumnsAutosaveName"]; - } + { + [aCoder encodeObject: [self columnsAutosaveName] forKey: @"NSColumnsAutosaveName"]; + } } else { @@ -2880,7 +2919,7 @@ static BOOL browserUseBezels; [aCoder encodeObject: nil]; [aCoder encodeObject:_browserCellPrototype]; [aCoder encodeObject: NSStringFromClass (_browserMatrixClass)]; - + [aCoder encodeObject:_pathSeparator]; [aCoder encodeValueOfObjCType: @encode(BOOL) at: &_isLoaded]; [aCoder encodeValueOfObjCType: @encode(BOOL) at: &_allowsBranchSelection]; @@ -2892,32 +2931,32 @@ static BOOL browserUseBezels; [aCoder encodeValueOfObjCType: @encode(BOOL) at: &_separatesColumns]; [aCoder encodeValueOfObjCType: @encode(BOOL) at: &_takesTitleFromPreviousColumn]; [aCoder encodeValueOfObjCType: @encode(BOOL) at: &_isTitled]; - - + + [aCoder encodeObject:_horizontalScroller]; [aCoder encodeValueOfObjCType: @encode(BOOL) at: &_hasHorizontalScroller]; [aCoder encodeRect: _scrollerRect]; [aCoder encodeSize: _columnSize]; - + [aCoder encodeValueOfObjCType: @encode(BOOL) at: &_acceptsArrowKeys]; [aCoder encodeValueOfObjCType: @encode(BOOL) at: &_sendsActionOnArrowKeys]; [aCoder encodeValueOfObjCType: @encode(BOOL) at: &_acceptsAlphaNumericalKeys]; [aCoder encodeValueOfObjCType: @encode(BOOL) at: &_sendsActionOnAlphaNumericalKeys]; - + [aCoder encodeConditionalObject:_browserDelegate]; - + [aCoder encodeValueOfObjCType: @encode(SEL) at: &_doubleAction]; [aCoder encodeConditionalObject: _target]; [aCoder encodeValueOfObjCType: @encode(SEL) at: &_action]; - + [aCoder encodeObject: _browserColumns]; - + // Just encode the number of columns and the first visible // and rebuild the browser columns on the decoding side { - int colCount = [_browserColumns count]; - [aCoder encodeValueOfObjCType: @encode(int) at: &colCount]; - [aCoder encodeValueOfObjCType: @encode(int) at: &_firstVisibleColumn]; + int colCount = [_browserColumns count]; + [aCoder encodeValueOfObjCType: @encode(int) at: &colCount]; + [aCoder encodeValueOfObjCType: @encode(int) at: &_firstVisibleColumn]; } } } @@ -2932,11 +2971,11 @@ static BOOL browserUseBezels; NSString *sep = [aDecoder decodeObjectForKey: @"NSPathSeparator"]; long flags; NSSize bs; - + // Class setting _browserCellPrototype = [[[NSBrowser cellClass] alloc] init]; _browserMatrixClass = [NSMatrix class]; - + // Default values _pathSeparator = @"/"; _allowsBranchSelection = YES; @@ -2956,15 +2995,18 @@ static BOOL browserUseBezels; _sendsActionOnAlphaNumericalKeys = YES; _browserDelegate = nil; _passiveDelegate = YES; - _doubleAction = NULL; + _doubleAction = NULL; // FIXME: Seems a bit wrong to look at the current theme here bs = NSZeroSize; if (browserUseBezels) bs = [[GSTheme theme] sizeForBorderType: NSBezelBorder]; _minColumnWidth = scrollerWidth + (2 * bs.width); if (_minColumnWidth < 100.0) - _minColumnWidth = 100.0; - + _minColumnWidth = 100.0; + + // Item based delegate, 10.6+ + _itemBasedDelegate = NO; + // Horizontal scroller _scrollerRect.origin.x = bs.width; _scrollerRect.origin.y = bs.height; @@ -2975,76 +3017,76 @@ static BOOL browserUseBezels; [_horizontalScroller setAction: @selector(scrollViaScroller:)]; [self addSubview: _horizontalScroller]; _skipUpdateScroller = NO; - + // Columns _browserColumns = [[NSMutableArray alloc] init]; - + // Create a single column _lastColumnLoaded = -1; _firstVisibleColumn = 0; _lastVisibleColumn = 0; _maxVisibleColumns = 3; [self _createColumn]; - // end // - + // end // + [self setCellPrototype: proto]; [self setPathSeparator: sep]; [self setTitle: title ofColumn: 0]; if ([aDecoder containsValueForKey: @"NSBrFlags"]) - { - flags = [aDecoder decodeIntForKey: @"NSBrFlags"]; + { + flags = [aDecoder decodeIntForKey: @"NSBrFlags"]; - [self setHasHorizontalScroller: ((flags & 0x10000) == 0x10000)]; - [self setAllowsEmptySelection: !((flags & 0x20000) == 0x20000)]; - [self setSendsActionOnArrowKeys: ((flags & 0x40000) == 0x40000)]; - [self setAcceptsArrowKeys: ((flags & 0x100000) == 0x100000)]; - [self setSeparatesColumns: ((flags & 0x4000000) == 0x4000000)]; - [self setTakesTitleFromPreviousColumn: ((flags & 0x8000000) == 0x8000000)]; - [self setTitled: ((flags & 0x10000000) == 0x10000000)]; - [self setReusesColumns: ((flags & 0x20000000) == 0x20000000)]; - [self setAllowsBranchSelection: ((flags & 0x40000000) == 0x40000000)]; - [self setAllowsMultipleSelection: ((flags & 0x80000000) == 0x80000000)]; - } + [self setHasHorizontalScroller: ((flags & 0x10000) == 0x10000)]; + [self setAllowsEmptySelection: !((flags & 0x20000) == 0x20000)]; + [self setSendsActionOnArrowKeys: ((flags & 0x40000) == 0x40000)]; + [self setAcceptsArrowKeys: ((flags & 0x100000) == 0x100000)]; + [self setSeparatesColumns: ((flags & 0x4000000) == 0x4000000)]; + [self setTakesTitleFromPreviousColumn: ((flags & 0x8000000) == 0x8000000)]; + [self setTitled: ((flags & 0x10000000) == 0x10000000)]; + [self setReusesColumns: ((flags & 0x20000000) == 0x20000000)]; + [self setAllowsBranchSelection: ((flags & 0x40000000) == 0x40000000)]; + [self setAllowsMultipleSelection: ((flags & 0x80000000) == 0x80000000)]; + } if ([aDecoder containsValueForKey: @"NSNumberOfVisibleColumns"]) - { - [self setMaxVisibleColumns: [aDecoder decodeIntForKey: - @"NSNumberOfVisibleColumns"]]; - } + { + [self setMaxVisibleColumns: [aDecoder decodeIntForKey: + @"NSNumberOfVisibleColumns"]]; + } if ([aDecoder containsValueForKey: @"NSMinColumnWidth"]) - { - [self setMinColumnWidth: [aDecoder decodeIntForKey: @"NSMinColumnWidth"]]; - } + { + [self setMinColumnWidth: [aDecoder decodeIntForKey: @"NSMinColumnWidth"]]; + } if ([aDecoder containsValueForKey: @"NSColumnResizingType"]) - { - [self setColumnResizingType: [aDecoder decodeIntForKey: @"NSColumnResizingType"]]; - } + { + [self setColumnResizingType: [aDecoder decodeIntForKey: @"NSColumnResizingType"]]; + } if ([aDecoder containsValueForKey: @"NSPreferedColumnWidth"]) - { - //int prefWidth = [aDecoder decodeIntForKey: @"NSPreferedColumnWidth"]; - } + { + //int prefWidth = [aDecoder decodeIntForKey: @"NSPreferedColumnWidth"]; + } if ([aDecoder containsValueForKey: @"NSColumnsAutosaveName"]) - { - [self setColumnsAutosaveName: [aDecoder decodeObjectForKey: - @"NSColumnsAutosaveName"]]; - } + { + [self setColumnsAutosaveName: [aDecoder decodeObjectForKey: + @"NSColumnsAutosaveName"]]; + } } else { int colCount; - + // Here to keep compatibility with old version [aDecoder decodeObject]; _browserCellPrototype = RETAIN([aDecoder decodeObject]); _browserMatrixClass = NSClassFromString ((NSString *)[aDecoder decodeObject]); - + [self setPathSeparator: [aDecoder decodeObject]]; - + [aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_isLoaded]; [aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_allowsBranchSelection]; [aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_allowsEmptySelection]; @@ -3055,7 +3097,7 @@ static BOOL browserUseBezels; [aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_separatesColumns]; [aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_takesTitleFromPreviousColumn]; [aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_isTitled]; - + //NSBox *_horizontalScrollerBox; _horizontalScroller = RETAIN([aDecoder decodeObject]); [aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_hasHorizontalScroller]; @@ -3064,9 +3106,9 @@ static BOOL browserUseBezels; _skipUpdateScroller = NO; /* - _horizontalScroller = [[NSScroller alloc] initWithFrame: _scrollerRect]; - [_horizontalScroller setTarget: self]; - [_horizontalScroller setAction: @selector(scrollViaScroller:)]; + _horizontalScroller = [[NSScroller alloc] initWithFrame: _scrollerRect]; + [_horizontalScroller setTarget: self]; + [_horizontalScroller setAction: @selector(scrollViaScroller:)]; */ [self setHasHorizontalScroller: _hasHorizontalScroller]; @@ -3080,27 +3122,27 @@ static BOOL browserUseBezels; _browserDelegate = [aDecoder decodeObject]; if (_browserDelegate != nil) - [self setDelegate:_browserDelegate]; + [self setDelegate:_browserDelegate]; else - _passiveDelegate = YES; - + _passiveDelegate = YES; + [aDecoder decodeValueOfObjCType: @encode(SEL) at: &_doubleAction]; _target = [aDecoder decodeObject]; [aDecoder decodeValueOfObjCType: @encode(SEL) at: &_action]; - + // Do the minimal thing to initiate the browser... /* - _lastColumnLoaded = -1; - _firstVisibleColumn = 0; - _lastVisibleColumn = 0; - [self _createColumn]; + _lastColumnLoaded = -1; + _firstVisibleColumn = 0; + _lastVisibleColumn = 0; + [self _createColumn]; */ _browserColumns = RETAIN([aDecoder decodeObject]); // ..and rebuild any existing browser columns [aDecoder decodeValueOfObjCType: @encode(int) at: &colCount]; [aDecoder decodeValueOfObjCType: @encode(int) at: &_firstVisibleColumn]; } - + // Display even if there isn't any column _isLoaded = NO; [self tile]; @@ -3147,14 +3189,14 @@ static BOOL browserUseBezels; _acceptsAlphaNumericalKeys = flag; } -/** Returns NO if pressing an arrow key only scrolls the browser, YES if +/** Returns NO if pressing an arrow key only scrolls the browser, YES if it also sends the action message specified by setAction:. */ - (BOOL) sendsActionOnAlphaNumericalKeys { return _sendsActionOnAlphaNumericalKeys; } -/** Sets whether pressing an arrow key will cause the action message +/** Sets whether pressing an arrow key will cause the action message to be sent (in addition to causing scrolling). */ - (void) setSendsActionOnAlphaNumericalKeys: (BOOL)flag { @@ -3187,13 +3229,13 @@ static BOOL browserUseBezels; sc = [bc columnScrollView]; if (!firstResponder && [bc columnMatrix] == [_window firstResponder]) - { - firstResponder = [bc columnMatrix]; - } + { + firstResponder = [bc columnMatrix]; + } if (sc) - { - [sc removeFromSuperviewWithoutNeedingDisplay]; - } + { + [sc removeFromSuperviewWithoutNeedingDisplay]; + } } if (_firstVisibleColumn > _lastVisibleColumn) @@ -3205,49 +3247,84 @@ static BOOL browserUseBezels; if (fromFirst) { for (i = _firstVisibleColumn; i <= _lastVisibleColumn; i++) - { - bc = [_browserColumns objectAtIndex: i]; - sc = [bc columnScrollView]; - [self addSubview: sc]; + { + bc = [_browserColumns objectAtIndex: i]; + sc = [bc columnScrollView]; + [self addSubview: sc]; - if ([bc isLoaded] && [bc columnMatrix] == firstResponder) - { - [_window makeFirstResponder: firstResponder]; - setFirstResponder = YES; - } - } + if ([bc isLoaded] && [bc columnMatrix] == firstResponder) + { + [_window makeFirstResponder: firstResponder]; + setFirstResponder = YES; + } + } if (firstResponder && setFirstResponder == NO) - { - [_window makeFirstResponder: - [[_browserColumns objectAtIndex: _firstVisibleColumn] - columnMatrix]]; - } + { + [_window makeFirstResponder: + [[_browserColumns objectAtIndex: _firstVisibleColumn] + columnMatrix]]; + } } else { for (i = _lastVisibleColumn; i >= _firstVisibleColumn; i--) - { - bc = [_browserColumns objectAtIndex: i]; - sc = [bc columnScrollView]; - [self addSubview: sc]; + { + bc = [_browserColumns objectAtIndex: i]; + sc = [bc columnScrollView]; + [self addSubview: sc]; - if ([bc isLoaded] && [bc columnMatrix] == firstResponder) - { - [_window makeFirstResponder: firstResponder]; - setFirstResponder = YES; - } - } + if ([bc isLoaded] && [bc columnMatrix] == firstResponder) + { + [_window makeFirstResponder: firstResponder]; + setFirstResponder = YES; + } + } if (firstResponder && setFirstResponder == NO) - { - [_window makeFirstResponder: - [[_browserColumns objectAtIndex: _lastVisibleColumn] - columnMatrix]]; - } + { + [_window makeFirstResponder: + [[_browserColumns objectAtIndex: _lastVisibleColumn] + columnMatrix]]; + } } } +- (id) _itemForColumn: (NSInteger)column +{ + id item = nil; + + if (column == 0) + { + item = [_browserDelegate rootItemForBrowser: self]; + } + else + { + NSInteger col = column - 1; + NSBrowserColumn *bc; + + bc = [_browserColumns objectAtIndex: col]; + if (bc != nil) + { + NSMatrix *matrix; + + matrix = [bc columnMatrix]; + if (matrix != nil) + { + NSArray *selectedCells = [matrix selectedCells]; + if (selectedCells != nil && [selectedCells count] > 0) + { + id cell = [selectedCells objectAtIndex: 0]; + + item = [cell objectValue]; + } + } + } + } + + return item; +} + /* Loads column 'column' (asking the delegate). */ - (void) _performLoadOfColumn: (NSInteger)column { @@ -3255,8 +3332,18 @@ static BOOL browserUseBezels; NSScrollView *sc; NSMatrix *matrix; NSInteger i, rows, cols; + id child = nil; + id item = nil; - if (_passiveDelegate) + if (_itemBasedDelegate) + { + item = [self _itemForColumn: column]; + + // Ask the delegate for the number of rows for a given item... + rows = [_browserDelegate browser: self numberOfChildrenOfItem: item]; + cols = 1; + } + else if (_passiveDelegate) { // Ask the delegate for the number of rows rows = [_browserDelegate browser: self numberOfRowsInColumn: column]; @@ -3281,9 +3368,9 @@ static BOOL browserUseBezels; // Mark all the cells as unloaded for (i = 0; i < rows; i++) - { - [[matrix cellAtRow: i column: 0] setLoaded: NO]; - } + { + [[matrix cellAtRow: i column: 0] setLoaded: NO]; + } } else { @@ -3292,11 +3379,11 @@ static BOOL browserUseBezels; // create a new col matrix matrix = [[_browserMatrixClass alloc] - initWithFrame: matrixRect - mode: NSListModeMatrix - prototype: _browserCellPrototype - numberOfRows: rows - numberOfColumns: cols]; + initWithFrame: matrixRect + mode: NSListModeMatrix + prototype: _browserCellPrototype + numberOfRows: rows + numberOfColumns: cols]; [matrix setIntercellSpacing: matrixIntercellSpace]; [matrix setAllowsEmptySelection: _allowsEmptySelection]; [matrix setAutoscroll: YES]; @@ -3306,21 +3393,41 @@ static BOOL browserUseBezels; [matrix setDrawsBackground: YES]; if (!_allowsMultipleSelection) - { - [matrix setMode: NSRadioModeMatrix]; - } + { + [matrix setMode: NSRadioModeMatrix]; + } [matrix setTarget: self]; [matrix setAction: @selector(doClick:)]; [matrix setDoubleAction: @selector(doDoubleClick:)]; - + // set new col matrix and release old [bc setColumnMatrix: matrix]; RELEASE (matrix); } [sc setDocumentView: matrix]; - // Loading is different based upon passive/active delegate - if (_passiveDelegate) + // Loading is different based upon item/passive/active delegate + if (_itemBasedDelegate) + { + // Iterate over the children for the item.... + for (i = 0; i < rows; i++) + { + id aCell = [matrix cellAtRow: i column: 0]; + if (![aCell isLoaded]) + { + BOOL leaf = YES; + id val = nil; + + child = [_browserDelegate browser: self child: i ofItem: item]; + leaf = [_browserDelegate browser: self isLeafItem: child]; + val = [_browserDelegate browser: self objectValueForItem: child]; + [aCell setLeaf: leaf]; + [aCell setObjectValue: val]; + [aCell setLoaded: YES]; + } + } + } + else if (_passiveDelegate) { // Now loop through the cells and load each one id aCell; @@ -3328,46 +3435,46 @@ static BOOL browserUseBezels; IMP imp1 = [_browserDelegate methodForSelector: sel1]; SEL sel2 = @selector(cellAtRow:column:); IMP imp2 = [matrix methodForSelector: sel2]; - + for (i = 0; i < rows; i++) - { - aCell = (*imp2)(matrix, sel2, i, 0); - if (![aCell isLoaded]) - { - (*imp1)(_browserDelegate, sel1, self, aCell, i, - column); - [aCell setLoaded: YES]; - } - } + { + aCell = (*imp2)(matrix, sel2, i, 0); + if (![aCell isLoaded]) + { + (*imp1)(_browserDelegate, sel1, self, aCell, i, + column); + [aCell setLoaded: YES]; + } + } } else { // Tell the delegate to create the rows [_browserDelegate browser: self - createRowsForColumn: column - inMatrix: matrix]; + createRowsForColumn: column + inMatrix: matrix]; } [bc setIsLoaded: YES]; - + if (column > _lastColumnLoaded) { _lastColumnLoaded = column; } - /* Determine the height of a cell in the matrix, and set that as the + /* Determine the height of a cell in the matrix, and set that as the cellSize of the matrix. */ { NSSize cs, ms; - NSBrowserCell *b = [matrix cellAtRow: 0 column: 0]; + NSBrowserCell *b = [matrix cellAtRow: 0 column: 0]; if (b != nil) { - ms = [b cellSize]; + ms = [b cellSize]; } else { - ms = [matrix cellSize]; + ms = [matrix cellSize]; } cs = [sc contentSize]; ms.width = cs.width; @@ -3384,68 +3491,68 @@ static BOOL browserUseBezels; - (NSString *) _getTitleOfColumn: (NSInteger)column { // Ask the delegate for the column title - if ([_browserDelegate respondsToSelector: - @selector(browser:titleOfColumn:)]) + if ([_browserDelegate respondsToSelector: + @selector(browser:titleOfColumn:)]) { return [_browserDelegate browser: self titleOfColumn: column]; } - + // Check if we take title from previous column if (_takesTitleFromPreviousColumn) { id c; - + // If first column then use the path separator if (column == 0) - { - return _pathSeparator; - } - + { + return _pathSeparator; + } + // Get the selected cell // Use its string value as the title // Only if it is not a leaf if (_allowsMultipleSelection == NO) - { - c = [self selectedCellInColumn: column - 1]; - } + { + c = [self selectedCellInColumn: column - 1]; + } else - { - NSMatrix *matrix; - NSArray *selectedCells; + { + NSMatrix *matrix; + NSArray *selectedCells; - if (!(matrix = [self matrixInColumn: column - 1])) - return @""; + if (!(matrix = [self matrixInColumn: column - 1])) + return @""; - selectedCells = [matrix selectedCells]; + selectedCells = [matrix selectedCells]; - if ([selectedCells count] == 1) - { - c = [selectedCells objectAtIndex:0]; - } - else - { - return @""; - } - } + if ([selectedCells count] == 1) + { + c = [selectedCells objectAtIndex:0]; + } + else + { + return @""; + } + } if ([c isLeaf]) - { - return @""; - } + { + return @""; + } else - { - NSString *value = [c stringValue]; + { + NSString *value = [c stringValue]; - if (value != nil) - { - return value; - } - else - { - return @""; - } - } + if (value != nil) + { + return value; + } + else + { + return @""; + } + } } return @""; }