home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / YellowBox / Kits / MiscTableScroll-138.1 / Palettes / MiscTableScroll / Framework / MiscTableScrollData.M < prev    next >
Encoding:
Text File  |  1998-03-31  |  22.6 KB  |  751 lines

  1. //=============================================================================
  2. //
  3. //    Copyright (C) 1995-1997 by Paul S. McCarthy and Eric Sunshine.
  4. //        Written by Paul S. McCarthy and Eric Sunshine.
  5. //                All Rights Reserved.
  6. //
  7. //    This notice may not be removed from this source code.
  8. //
  9. //    This object is included in the MiscKit by permission from the authors
  10. //    and its use is governed by the MiscKit license, found in the file
  11. //    "License.rtf" in the MiscKit distribution.  Please refer to that file
  12. //    for a list of all applicable permissions and restrictions.
  13. //    
  14. //=============================================================================
  15. //-----------------------------------------------------------------------------
  16. // MiscTableScrollData.M
  17. //
  18. //    The (DATA) category of MiscTableScroll.     Implements the management
  19. //    of the cells of the table.
  20. //
  21. // FIXME *SEL*
  22. //    The current selection architecture is imposing undesirable overhead
  23. //    on a *highly* used function, -cellAt::.  We need to come up with a
  24. //    better way to handle this.
  25. //-----------------------------------------------------------------------------
  26. //-----------------------------------------------------------------------------
  27. // $Id: MiscTableScrollData.M,v 1.23 97/06/18 10:08:53 sunshine Exp $
  28. // $Log:    MiscTableScrollData.M,v $
  29. //  Revision 1.23  97/06/18  10:08:53  sunshine
  30. //  v125.9: Renamed methods containing: "buff" --> "buffer"
  31. //  Color-related methods "highlight" --> "selected".
  32. //  
  33. //  Revision 1.22  97/04/15  09:07:40  sunshine
  34. //  v0.125.8: Added "MiscTableScroll/" prefix to #import to facilitate new
  35. //  framework organization.
  36. //  
  37. //  Revision 1.21  97/04/04  05:03:03  sunshine
  38. //  0.125.6: Replaced assert() with NSAssert() variations for portability and
  39. //  because NSAssert() raises an exception which can be caught by the
  40. //  application if need be.
  41. //-----------------------------------------------------------------------------
  42. #import <MiscTableScroll/MiscTableScroll.h>
  43. #import <MiscTableScroll/MiscTableCell.h>
  44. #import "MiscTableBorder.h"
  45. #import "MiscTableScrollPrivate.h"
  46. extern "Objective-C" {
  47. #import <AppKit/NSCell.h>
  48. #import <AppKit/NSImage.h>
  49. }
  50. extern "C" {
  51. #import <limits.h>
  52. #import <stdlib.h>
  53. #import <string.h>
  54. }
  55.  
  56. #define    EAGER_CELL_AT(R,C)    (cells[ (R) * num_cols + (C) ])
  57.  
  58. @implementation MiscTableScroll(DATA)
  59.  
  60. //-----------------------------------------------------------------------------
  61. // - lazyCellAtRow:column:
  62. //-----------------------------------------------------------------------------
  63. - (id)lazyCellAtRow:(int)row column:(int)col
  64.     {
  65.     id del = [self responsibleDelegate:MiscDelegateFlags::DEL_CELL_AT];
  66.     if (del != 0)
  67.     {
  68.     id c = [del tableScroll:self cellAtRow:row column:col];
  69.     if (c != 0 && [c respondsToSelector:@selector(setCellAttribute:to:)])
  70.         [c setCellAttribute:NSCellHighlighted to:([self tracking] &&
  71.         row == [self clickedRow] && col == [self clickedColumn])];
  72.     return c;
  73.     }
  74.     return 0;
  75.     }
  76.  
  77.  
  78. //-----------------------------------------------------------------------------
  79. // - eagerCellAtRow:column:
  80. //-----------------------------------------------------------------------------
  81. - (id)eagerCellAtRow:(int)row column:(int)col
  82.     {
  83.     return EAGER_CELL_AT( row, col );
  84.     }
  85.  
  86.  
  87. //-----------------------------------------------------------------------------
  88. // - cellAtRow:column:
  89. //-----------------------------------------------------------------------------
  90. - (id)cellAtRow:(int)row column:(int)col
  91.     {
  92.     id cell = 0;
  93.     if ((unsigned int) row < (unsigned int) num_rows &&
  94.     (unsigned int) col < (unsigned int) num_cols)
  95.     {
  96.     if (!lazy)
  97.         cell = EAGER_CELL_AT( row, col );
  98.     else
  99.         cell = [self lazyCellAtRow:row column:col];
  100.  
  101.     if ([cell respondsToSelector:@selector(setSelected:)]) // FIXME: *SEL*
  102.         {
  103.         MiscCoord_V vr = rowInfo.border->physicalToVisual(row);
  104.         MiscCoord_V vc = colInfo.border->physicalToVisual(col);
  105.         [cell setSelected:colInfo.border->selectionSet().contains(vc) ||
  106.                   rowInfo.border->selectionSet().contains(vr)];
  107.         }
  108.     }
  109.     return cell;
  110.     }
  111.  
  112.  
  113. //-----------------------------------------------------------------------------
  114. // tagAtRow:column:, intValueAtRow:column:, floatValueAtRow:column:,
  115. // doubleValueAtRow:column:, stringValueAtRow:column:, titleAtRow:column:,
  116. // stateAtRow:column:
  117. //-----------------------------------------------------------------------------
  118. #define MISC_CELL_VAL( DATA_TYPE, NAME, CMD )\
  119. - (DATA_TYPE)NAME##AtRow:(int)r column:(int)c\
  120.     {\
  121.     id del = [self responsibleDelegate:MiscDelegateFlags::DEL_##CMD##_AT];\
  122.     if (del != 0)\
  123.     return [del tableScroll:self NAME##AtRow:r column:c];\
  124.     id cell = (!lazy ?    EAGER_CELL_AT(r,c) : [self lazyCellAtRow:r column:c]);\
  125.     if (cell != 0 && [cell respondsToSelector:@selector(NAME)])\
  126.     return [cell NAME];\
  127.     return 0;\
  128.     }
  129.  
  130. MISC_CELL_VAL( int, tag, TAG )                // tagAtRow:column:
  131. MISC_CELL_VAL( int, intValue, INT_VALUE )        // intValueAtRow:col...
  132. MISC_CELL_VAL( float, floatValue, FLOAT_VALUE )        // floatValueAtRow:c...
  133. MISC_CELL_VAL( double, doubleValue, DOUBLE_VALUE )    // doubleValueAtRow:...
  134. MISC_CELL_VAL( NSString*, stringValue, STRING_VALUE )    // stringValueAtRow:...
  135. MISC_CELL_VAL( int, state, STATE )            // stateAtRow:column:
  136. MISC_CELL_VAL( NSString*, title, TITLE )        // titleAtRow:column:
  137. #undef MISC_CELL_VAL
  138.  
  139.  
  140. //-----------------------------------------------------------------------------
  141. // - bufferCount
  142. //    For lazy-mode tables that perform multiple-buffering.  This can
  143. //    avoid copying when accessing more than one cell at a time (such
  144. //    as during sorting.)
  145. //-----------------------------------------------------------------------------
  146. - (int)bufferCount
  147.     {
  148.     id del = [self responsibleDelegate:MiscDelegateFlags::DEL_BUFFER_COUNT];
  149.     if (del != 0)
  150.     return [del tableScrollBufferCount:self];
  151.     return 1;
  152.     }
  153.  
  154.  
  155. //-----------------------------------------------------------------------------
  156. // - expandIfNeeded
  157. //-----------------------------------------------------------------------------
  158. - (void)expandIfNeeded
  159.     {
  160.     int const num_cells = max_rows * num_cols;
  161.     if (num_cells > max_cells)
  162.     {
  163.     NSZone* const z = [self zone];
  164.     int const nbytes = num_cells * sizeof(*cells);
  165.     if (max_cells == 0)
  166.         cells = (id*) NSZoneMalloc( z, nbytes );
  167.     else
  168.         cells = (id*) NSZoneRealloc( z, cells, nbytes );
  169.     max_cells = num_cells;
  170.     }
  171.     }
  172.  
  173.  
  174. //-----------------------------------------------------------------------------
  175. // - extendMaxRows:
  176. //-----------------------------------------------------------------------------
  177. - (void)extendMaxRows:(int)new_max
  178.     {
  179.     int const old_max = max_rows;
  180.     max_rows = new_max;
  181.  
  182.     [self expandIfNeeded];
  183.     NSZone* const z = [self zone];
  184.     MiscTableBorder* const bp = colInfo.border;
  185.     id* p = cells + old_max * num_cols;
  186.     for (int r = old_max; r < new_max; r++)
  187.     for (int c = 0; c < num_cols; c++)
  188.         *p++ = [bp->getPrototype_P(c) copyWithZone:z];
  189.     }
  190.  
  191.  
  192. //-----------------------------------------------------------------------------
  193. // - lazyInsertColumn:
  194. //-----------------------------------------------------------------------------
  195. - (void)lazyInsertColumn:(int)n
  196.     {
  197.     colInfo.border->insertAt(n,n);    // FIXME: Check this.
  198.     num_cols++;
  199.     }
  200.  
  201.  
  202. //-----------------------------------------------------------------------------
  203. // - eagerInsertColumn:
  204. //-----------------------------------------------------------------------------
  205. - (void)eagerInsertColumn:(int)n
  206.     {
  207.     NSParameterAssert( 0 <= n );  NSParameterAssert( n <= num_cols );
  208.     NSParameterAssert( 0 < num_cols );    // lazyInsert must increment num_cols.
  209.  
  210.     if (max_rows > 0 || num_rows > 0)
  211.     {
  212.     if (max_rows == 0)
  213.         max_rows = num_rows;
  214.     [self expandIfNeeded];
  215.     int const num_new = num_cols;
  216.     int const num_old = num_cols - 1;
  217.     if (num_old > 0)        // Shift old, existing cells.
  218.         {
  219.         int const frag = num_old - n; // #cols right of insert col.
  220.         id* src = cells + (max_rows * num_old) - frag;
  221.         id* dst = cells + (max_rows * num_new) - frag;
  222.         if (frag > 0)        // Last partial row.
  223.         memmove( dst, src, frag * sizeof(*dst) );
  224.  
  225.         int const nbytes = num_old * sizeof(*dst);
  226.         src -= num_old;
  227.         dst -= num_new;
  228.         while (src > cells)        // All full rows.
  229.         {
  230.         memmove( dst, src, nbytes );
  231.         src -= num_old;
  232.         dst -= num_new;
  233.         }
  234.         }
  235.     int row = 0;
  236.     NSZone* const z = [self zone];
  237.     id const proto = colInfo.border->getPrototype_P(n);
  238.     id* const plim = cells + (max_rows * num_new);
  239.     id* p = cells + n;
  240.     while (p < plim)        // Initialize cells in new column.
  241.         {
  242.         *p = [self reviveCell:[proto copyWithZone:z] atRow:row++ column:n];
  243.         p += num_new;
  244.         }
  245.     }
  246.     }
  247.  
  248.  
  249. //-----------------------------------------------------------------------------
  250. // - insertColumn:
  251. //-----------------------------------------------------------------------------
  252. - (void)insertColumn:(int)n
  253.     {
  254.     if (0 <= n && n <= num_cols)
  255.     {
  256.     [self lazyInsertColumn:n];
  257.     if (!lazy)
  258.         [self eagerInsertColumn:n];
  259.     [self constrainSize];
  260.     [self resetSelection];
  261.     [self setNeedsDisplay:YES];
  262.     }
  263.     }
  264.  
  265.  
  266. //-----------------------------------------------------------------------------
  267. // - addColumn
  268. //-----------------------------------------------------------------------------
  269. - (void)addColumn
  270.     {
  271.     [self insertColumn:num_cols];
  272.     }
  273.  
  274.  
  275. //-----------------------------------------------------------------------------
  276. // - lazyRemoveColumn:
  277. //-----------------------------------------------------------------------------
  278. - (void)lazyRemoveColumn:(int)n
  279.     {
  280.     colInfo.border->deleteAt_P(n);
  281.     num_cols--;
  282.     }
  283.  
  284.  
  285. //-----------------------------------------------------------------------------
  286. // - eagerRemoveColumn:
  287. //-----------------------------------------------------------------------------
  288. - (void)eagerRemoveColumn:(int)n
  289.     {
  290.     NSParameterAssert( 0 < num_cols );
  291.     NSParameterAssert( 0 <= n );  NSParameterAssert( n < num_cols );
  292.     if (max_rows > 0)
  293.     {
  294.     int const num_old = num_cols;
  295.     int const num_new = num_cols - 1;
  296.     id* dst = cells + n;
  297.     id* src = dst + 1;
  298.     id* const dst_lim = cells + (num_old * max_rows);
  299.     int row = 0;
  300.     while (dst < dst_lim)        // Destroy deleted cells.
  301.         {
  302.         if (row < num_rows)
  303.         [[self retireCell:*dst atRow:row++ column:n] release];
  304.         else
  305.         [*dst release];
  306.         dst += num_old;
  307.         }
  308.     if (num_new > 0)        // Shift remaining columns.
  309.         {
  310.         dst = cells + n;
  311.         int const nbytes = num_new * sizeof(*dst);
  312.         id* const src_lim = cells + (max_rows - 1) * num_old + n;
  313.         while (src < src_lim)
  314.         {
  315.         memmove( dst, src, nbytes );
  316.         dst += num_new;
  317.         src += num_old;
  318.         }
  319.         if (n < num_new)        // Shift last partial row.
  320.         memmove( dst, src, (num_new - n) * sizeof(*dst) );
  321.         }
  322.     else // (num_new <= 0)
  323.         {
  324.         max_rows = 0;
  325.         }
  326.     }
  327.     }
  328.  
  329.  
  330. //-----------------------------------------------------------------------------
  331. // - removeColumn:
  332. //-----------------------------------------------------------------------------
  333. - (void)removeColumn:(int)n
  334.     {
  335.     if (0 <= n && n < num_cols)
  336.     {
  337.     if (!lazy)
  338.         [self eagerRemoveColumn:n];
  339.     [self lazyRemoveColumn:n];
  340.     [self constrainSize];
  341.     [self resetSelection];
  342.     [self setNeedsDisplay:YES];
  343.     }
  344.     }
  345.  
  346.  
  347. //-----------------------------------------------------------------------------
  348. // - numberOfColumns
  349. //-----------------------------------------------------------------------------
  350. - (int)numberOfColumns
  351.     {
  352.     return num_cols;
  353.     }
  354.  
  355.  
  356. //-----------------------------------------------------------------------------
  357. // - lazyInsertRow:
  358. //-----------------------------------------------------------------------------
  359. - (void)lazyInsertRow:(int)n
  360.     {
  361.     rowInfo.border->insertAt(n,n);    // FIXME.  Check this.
  362.     num_rows++;
  363.     }
  364.  
  365.  
  366. //-----------------------------------------------------------------------------
  367. // - eagerInsertRow:
  368. //-----------------------------------------------------------------------------
  369. - (void)eagerInsertRow:(int)n
  370.     {
  371.     NSParameterAssert( 0 < num_rows );    // lazy-insert must increment num_rows
  372.     NSParameterAssert( 0 <= n );  NSParameterAssert( n < num_rows );
  373.  
  374.     if (num_cols > 0)
  375.     {
  376.     max_rows++;                // Incremental growth.
  377.     NSParameterAssert( num_rows <= max_rows );
  378.     [self expandIfNeeded];
  379.  
  380.     int const old_max = max_rows - 1;
  381.     id* p = cells + n * num_cols;
  382.     if (n < old_max)            // Shift other rows.
  383.         {
  384.         id* src = p;
  385.         id* dst = src + num_cols;
  386.         memmove( dst, src, (old_max - n) * num_cols * sizeof(*dst) );
  387.         }
  388.     NSZone* const z = [self zone];
  389.     MiscTableBorder* const bp = colInfo.border;
  390.     for (int c = 0;     c < num_cols;    c++)    // Initialize new cells.
  391.         *p++ = [self reviveCell:[bp->getPrototype_P(c) copyWithZone:z]
  392.             atRow:n column:c];
  393.     }
  394.     }
  395.  
  396.  
  397. //-----------------------------------------------------------------------------
  398. // - insertRow:
  399. //-----------------------------------------------------------------------------
  400. - (void)insertRow:(int)n
  401.     {
  402.     if (0 <= n && n <= num_rows)
  403.     {
  404.     [self lazyInsertRow:n];
  405.     if (!lazy)
  406.         [self eagerInsertRow:n];
  407.     [self constrainSize];
  408.     [self resetSelection];
  409.     [self setNeedsDisplay:YES];
  410.     }
  411.     }
  412.  
  413.  
  414. //-----------------------------------------------------------------------------
  415. // - eagerAddRow
  416. //-----------------------------------------------------------------------------
  417. - (void)eagerAddRow
  418.     {
  419.     // Lazy insertRow: must increment num_rows.
  420.     NSParameterAssert( 0 < num_rows );
  421.     if (num_cols > 0)
  422.     {
  423.     if (num_rows >= max_rows)
  424.         {
  425.         NSParameterAssert( num_rows < (INT_MAX >> 1) );
  426.         int n = (max_rows != 0 ? max_rows : 16);
  427.         while (n < num_rows)
  428.         n <<= 1;
  429.         [self extendMaxRows:n];
  430.         }
  431.     int const r = num_rows - 1;
  432.     id* p = cells + (num_cols * r);
  433.     for (int c = 0; c < num_cols; c++)
  434.         *p++ = [self reviveCell:*p atRow:r column:c];
  435.     }
  436.     }
  437.  
  438.  
  439. //-----------------------------------------------------------------------------
  440. // - addRow
  441. //
  442. // NOTE: We explicitly do NOT -constrainSize here, because we expect that the
  443. // user will call this routine many times successively.  
  444. //-----------------------------------------------------------------------------
  445. - (void)addRow
  446.     {
  447.     [self lazyInsertRow:num_rows];
  448.     if (!lazy)
  449.     [self eagerAddRow];
  450.     }
  451.  
  452.  
  453. //-----------------------------------------------------------------------------
  454. // - lazyRemoveRow:
  455. //-----------------------------------------------------------------------------
  456. - (void)lazyRemoveRow:(int)n
  457.     {
  458.     rowInfo.border->deleteAt_P(n);
  459.     num_rows--;
  460.     }
  461.  
  462.  
  463. //-----------------------------------------------------------------------------
  464. // - eagerRemoveRow:
  465. //-----------------------------------------------------------------------------
  466. - (void)eagerRemoveRow:(int)n
  467.     {
  468.     NSParameterAssert( 0 < num_rows );
  469.     NSParameterAssert( 0 <= n );  NSParameterAssert( n < num_rows );
  470.     if (num_cols > 0)
  471.     {
  472.     NSParameterAssert( num_rows <= max_rows );
  473.     max_rows--;
  474.     id* const dst = cells + (n * num_cols );
  475.     id* p = dst;
  476.     id* const plim = p + num_cols;
  477.     int col = 0;
  478.     while (p < plim)    // Destroy the cells.
  479.         {
  480.         [[self retireCell:*p atRow:n column:col++] release];
  481.         p++;
  482.         }
  483.     if (n < max_rows)
  484.         memmove( dst, plim, (max_rows - n) * num_cols * sizeof(*dst) );
  485.     }
  486.     }
  487.  
  488.  
  489. //-----------------------------------------------------------------------------
  490. // - removeRow:
  491. //-----------------------------------------------------------------------------
  492. - (void)removeRow:(int)n
  493.     {
  494.     if (0 <= n && n < num_rows)
  495.     {
  496.     if (!lazy)
  497.         [self eagerRemoveRow:n];
  498.     [self lazyRemoveRow:n];
  499.     [self constrainSize];
  500.     [self resetSelection];
  501.     [self setNeedsDisplay:YES];
  502.     }
  503.     }
  504.  
  505.  
  506. //-----------------------------------------------------------------------------
  507. // - numberOfRows
  508. //-----------------------------------------------------------------------------
  509. - (int)numberOfRows
  510.     {
  511.     return num_rows;
  512.     }
  513.  
  514.  
  515. //-----------------------------------------------------------------------------
  516. // - lazyRenewRows:
  517. //-----------------------------------------------------------------------------
  518. - (void)lazyRenewRows:(int)n
  519.     {
  520.     rowInfo.border->setCount(n);
  521.     num_rows = n;
  522.     }
  523.  
  524.  
  525. //-----------------------------------------------------------------------------
  526. // - eagerRenewRows:
  527. //-----------------------------------------------------------------------------
  528. - (void)eagerRenewRows:(int)n
  529.     {
  530.     NSParameterAssert( 0 <= n );
  531.     if (num_cols > 0)
  532.     {
  533.     int const old_num_rows = num_rows;
  534.     int const new_num_rows = n;
  535.     if (n > max_rows)
  536.         [self extendMaxRows:n];
  537.     if (old_num_rows < new_num_rows)        // Growing
  538.         {
  539.         id* p = cells + old_num_rows * num_cols;
  540.         for (int r = old_num_rows; r < new_num_rows; r++)
  541.         for (int c = 0; c < num_cols; c++)
  542.             *p++ = [self reviveCell:*p atRow:r column:c];
  543.         }
  544.     else if (old_num_rows > new_num_rows)        // Shrinking
  545.         {
  546.         id* p = cells + new_num_rows * num_cols;
  547.         for (int r = new_num_rows; r < old_num_rows; r++)
  548.         for (int c = 0; c < num_cols; c++)
  549.             *p++ = [self retireCell:*p atRow:r column:c];
  550.         }
  551.     }
  552.     }
  553.  
  554.  
  555. //-----------------------------------------------------------------------------
  556. // - renewRows:
  557. //-----------------------------------------------------------------------------
  558. - (void)renewRows:(int)n
  559.     {
  560.     [self clearSelection];
  561.     if (0 <= n && n != num_rows)
  562.     {
  563.     if (!lazy)
  564.         [self eagerRenewRows:n];
  565.     [self lazyRenewRows:n];
  566.     }
  567.     [self constrainSize];
  568.     [self setNeedsDisplay:YES];
  569.     }
  570.  
  571.  
  572. //-----------------------------------------------------------------------------
  573. // - empty
  574. //-----------------------------------------------------------------------------
  575. - (void)empty
  576.     {
  577.     [self renewRows:0];
  578.     }
  579.  
  580.  
  581. //-----------------------------------------------------------------------------
  582. // - releaseCells
  583. //-----------------------------------------------------------------------------
  584. - (void)releaseCells
  585.     {
  586.     if (max_rows > 0 && num_cols > 0)
  587.     {
  588.     id* p = cells;
  589.     id* const plim = p + (max_rows * num_cols);
  590.     while (p < plim)
  591.         [*p++ release];
  592.     }
  593.     if (cells != 0)
  594.     NSZoneFree( [self zone], cells );
  595.     cells = 0;
  596.     max_cells = 0;
  597.     max_rows = 0;
  598.     }
  599.  
  600.  
  601. //-----------------------------------------------------------------------------
  602. // - emptyAndReleaseCells
  603. //-----------------------------------------------------------------------------
  604. - (void)emptyAndReleaseCells
  605.     {
  606.     [self empty];
  607.     [self releaseCells]; 
  608.     }
  609.  
  610.  
  611. //-----------------------------------------------------------------------------
  612. // - setLazy:
  613. //-----------------------------------------------------------------------------
  614. - (void)setLazy:(BOOL)flag
  615.     {
  616.     if (lazy != flag)
  617.     {
  618.     lazy = flag;
  619.     if (lazy)
  620.         [self emptyAndReleaseCells];
  621.     else
  622.         [self eagerRenewRows:num_rows];
  623.     }
  624.     }
  625.  
  626.  
  627. //-----------------------------------------------------------------------------
  628. // - isLazy
  629. //-----------------------------------------------------------------------------
  630. - (BOOL)isLazy
  631.     {
  632.     return lazy;
  633.     }
  634.  
  635.  
  636. //-----------------------------------------------------------------------------
  637. // Generic Slot methods
  638. //-----------------------------------------------------------------------------
  639. - (void)addSlot:(MiscBorderType)b
  640.     { if (b == MISC_COL_BORDER) [self addColumn]; else [self addRow]; }
  641.  
  642. - (void)border:(MiscBorderType)b insertSlot:(int)n
  643.     { if (b == MISC_COL_BORDER) 
  644.         [self insertColumn:n]; else [self insertRow:n]; }
  645.  
  646. - (void)border:(MiscBorderType)b removeSlot:(int)n
  647.     { if (b == MISC_COL_BORDER)
  648.         [self removeColumn:n]; else [self removeRow:n]; }
  649.  
  650. - (int)numberOfSlots:(MiscBorderType)b
  651.     { return (b == MISC_COL_BORDER) ?
  652.         [self numberOfColumns] : [self numberOfRows]; }
  653.  
  654.  
  655. //-----------------------------------------------------------------------------
  656. // REVIVE
  657. //-----------------------------------------------------------------------------
  658. - (id)doReviveCell:(id)cell atRow:(int)row column:(int)col
  659.     {
  660.     if (cell != 0)
  661.     {
  662.     if ([cell respondsToSelector:@selector(setOwner:)])
  663.         [cell setOwner:self];
  664.  
  665.     if ([cell respondsToSelector:@selector(setUseOwnerFont:)])
  666.         [cell setUseOwnerFont:YES];
  667.     if ([cell respondsToSelector:@selector(setUseOwnerTextColor:)])
  668.         [cell setUseOwnerTextColor:YES];
  669.     if ([cell respondsToSelector:@selector(setUseOwnerBackgroundColor:)])
  670.         [cell setUseOwnerBackgroundColor:YES];
  671.     if ([cell respondsToSelector:
  672.         @selector(setUseOwnerSelectedTextColor:)])
  673.         [cell setUseOwnerSelectedTextColor:YES];
  674.     if ([cell respondsToSelector:
  675.         @selector(setUseOwnerSelectedBackgroundColor:)])
  676.         [cell setUseOwnerSelectedBackgroundColor:YES];
  677.  
  678.     if ([cell respondsToSelector:@selector(setOwnerFont:)])
  679.         [cell setOwnerFont:[self font]];
  680.     else if ([cell respondsToSelector:@selector(setFont:)])
  681.         [cell setFont:[self font]];
  682.  
  683.     if ([cell respondsToSelector:@selector(setOwnerTextColor:)])
  684.         [cell setOwnerTextColor:[self textColor]];
  685.     else if ([cell respondsToSelector:@selector(setTextColor:)])
  686.         [cell setTextColor:[self textColor]];
  687.  
  688.     if ([cell respondsToSelector:@selector(setOwnerBackgroundColor:)])
  689.         [cell setOwnerBackgroundColor:[self backgroundColor]];
  690.     else if ([cell respondsToSelector:@selector(setBackgroundColor:)])
  691.         [cell setBackgroundColor:[self backgroundColor]];
  692.  
  693.     if ([cell respondsToSelector:@selector(setOwnerSelectedTextColor:)])
  694.         [cell setOwnerSelectedTextColor:[self selectedTextColor]];
  695.     else if ([cell respondsToSelector:@selector(setSelectedTextColor:)])
  696.         [cell setSelectedTextColor:[self selectedTextColor]];
  697.  
  698.     if ([cell respondsToSelector:
  699.         @selector(setOwnerSelectedBackgroundColor:)])
  700.         [cell setOwnerSelectedBackgroundColor:
  701.             [self selectedBackgroundColor]];
  702.     else if ([cell respondsToSelector:
  703.         @selector(setSelectedBackgroundColor:)])
  704.         [cell setSelectedBackgroundColor:[self selectedBackgroundColor]];
  705.     }
  706.     return cell;
  707.     }
  708.  
  709.  
  710. - (id)reviveCell:(id)cell atRow:(int)row column:(int)col
  711.     {
  712.     id del = [self responsibleDelegate:MiscDelegateFlags::DEL_REVIVE_CELL];
  713.     if (del != 0)
  714.     return [del tableScroll:self reviveCell:cell atRow:row column:col];
  715.  
  716.     if (cell != 0 && [cell respondsToSelector:
  717.     @selector(tableScroll:reviveAtRow:column:)])
  718.     return [cell tableScroll:self reviveAtRow:row column:col];
  719.  
  720.     return [self doReviveCell:cell atRow:row column:col];
  721.     }
  722.  
  723.  
  724. //-----------------------------------------------------------------------------
  725. // RETIRE
  726. //-----------------------------------------------------------------------------
  727. - (id)doRetireCell:(id)cell atRow:(int)row column:(int)col
  728.     {
  729.     if ([cell respondsToSelector:@selector(setTitle:)])
  730.     [cell setTitle:@""];
  731.     else if ([cell respondsToSelector:@selector(setStringValue:)])
  732.     [cell setStringValue:@""];
  733.     return cell;
  734.     }
  735.  
  736.  
  737. - (id)retireCell:(id)cell atRow:(int)row column:(int)col
  738.     {
  739.     id del = [self responsibleDelegate:MiscDelegateFlags::DEL_RETIRE_CELL];
  740.     if (del != 0)
  741.     return [del tableScroll:self retireCell:cell atRow:row column:col];
  742.  
  743.     if (cell != 0 && [cell respondsToSelector:
  744.     @selector(tableScroll:retireAtRow:column:)])
  745.     return [cell tableScroll:self retireAtRow:row column:col];
  746.  
  747.     return [self doRetireCell:cell atRow:row column:col];
  748.     }
  749.  
  750. @end
  751.