home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-10 | 82.6 KB | 2,360 lines | [TEXT/PJMM] |
- unit vListMngr;
-
- {version 3}
- { handles copying and pasting from scrap}
- {version 4}
- { fixed problems with multi-cell selection}
- {version 7}
- { attempt to activate/deactivate scroll bar as number of lines needed varies}
- {version 8.6}
- { changed vLNew to create a list with:}
- { No heading}
- { list font = window font}
- { added routines:}
- { SetHeading to add/change heading}
- { SetListFont to change list font}
- { SetHeadingFont to change list font}
- {version 8.9}
- { got resizing of list to work by adding/modifying routines:}
- { AdjustScrollBars}
- { vLInsetList}
- { vLSize}
- { 8.9.4}
- { Altered SetMaxScrollBar to avoid cutting off right side of rightmost cell}
- {9.01}
- { vLNew uses same call as LNew - can be used interchangeably}
- {9.02}
- { changed vLInset}
- {**PROBLEM - if last column shows only partially, we move over a whold column in order to display it, and then move the Scroll bars}
- {**SOLUTION - don't move scroll bars around every time we scroll - only when:}
- { rView or lView changes}
- { rows are added or deleted}
- { cols are added or deleted}
- {9.05 }
- { vLDrawCell changed to fix problem with unerased cell areas and port Clip}
- { removed HLock/HUnLock/With from all internally called routines}
- {9.06}
- { vLCalcCellWidths changed to avoid trashing existing cell widths}
- { vLScrollHorz changed to keep headings straight}
- {9.1.0}
- { removed format record}
- { removed vListHeading record}
- {9.1.1}
- { added fields:}
- { listTE}
- { lActiveTE}
- { lEditMode}
- {9.2.0}
- { ScrapToCells}
- { CellsToScrap}
- { maxOffsets}
- { maxChars}
- {9.21}
- { vLAddCol}
- {9.2.2}
- { Fix vLInsetList}
- { Add CalcVisBottom}
- {PROBLEM}
- { shrink window with headings on}
- { List is drawn outside scroll bars}
- { Can't replicate problem!!}
- {PROBLEM}
- { Top border is not drawn around list when there are no headings}
- { Top border is drawn when headings are present, but border is not erased on resizing }
- { border is outside clip rectangle}
- {9.2.3}
- { Changed frame drawing in vLDrawCell}
- { frame top & left in Cell rectangle}
- { frame bottom & right outside Cell rectangle}
- { clip to CalcVisRect to avoid trashing scroll bars}
- { Changed AdjustScrollBars to coincide}
- { Changed vLDrawHeading similarly}
- { Changed StartEdit similarly}
- { vLTEDispose}
- {9.2.4}
- { vLCalcCellWidths}
- { vLInsetList}
- { vLSizeList}
- {9.2.5}
- { vLNew - changed cellSize to pcellSize for passed value, was getting confused with vList field cellSize}
- { - check for allocation of vList and cells}
-
-
- {PROBLEM}
- {TE has weird outline}
-
- interface
- const
- { Masks for selection flags (selFlags) }
- LOnlyOne = -128; { 0 = multiple selections, 1 = one }
- LExtendDrag = 64; { 1 = drag select without shift key }
- LNoDisjoint = 32; { 1 = turn off selections on click }
- LNoExtend = 16; { 1 = don't extend shift selections }
- LNoRect = 8; { 1 = don't grow (shift,drag) selection as rect }
- LUseSense = 4; { 1 = shift should use sense of start cell }
- LNoNilHilite = 2; { 1 = don't hilite empty cells }
-
- { Masks for other flags (listFlags) }
- LDoVAutoscroll = 2; { 1 = allow vertical autoscrolling }
- LDoHAutoscroll = 1; { 1 = allow horizontal autoscrolling }
-
- {Size of list}
- maxCols = 31;
- maxChars = 16000;
- maxOffsets = 4095;
-
- type
- Cell = Point;
-
- EditModeType = (editCell, editTE);
-
- DataArray = packed array[0..maxChars] of Char;
- DataPtr = ^DataArray;
- DataHandle = ^DataPtr;
-
- OffsetArray = array[0..maxOffsets] of INTEGER;
-
- vLScrapHandle = ^vLScrapPtr;
- vLScrapPtr = ^vListScrapRec;
- vListScrapRec = record
- scrapBounds: RECT; {}
- scrapData: dataArray;
- scrapOffsets: offsetArray;
- end;
-
- lHeadArray = array[1..4] of STR255;
-
- WidthArray = array[0..maxCols] of Integer;
-
- modifierType = (none, command, option, control, shift);
-
- vListHandle = ^vListPtr;
- vListPtr = ^vListRec;
- vListRec = record
- rView: RECT; {rectangle in which list heading and are viewed}
- port: GrafPtr; {Grafport that owns us}
- indent: Point; {Indent pixels in cell}
- cellSize: Point; {Cell width and height (width is ignored)}
- visible: Rect; {visible row/column bounds, i.e. indices of top left and bottom right cells}
- vScroll: ControlHandle; {vertical scroll bar (or NIL)}
- hScroll: ControlHandle; {horizontal scroll bar (or NIL)}
- selFlags: SignedByte; { defines selection characteristics}
- LActive: Boolean; { active or not}
- LReserved: SignedByte; { internally used flags}
- listFlags: SignedByte; { other flags}
- clikTime: Longint; { save time of last click}
- clikLoc: Point; { save position of last click}
- mouseLoc: Point; { current mouse position}
- lClikLoop: Ptr; { routine called repeatedly during ListClick}
- lastClick: Cell; { the last cell clicked in}
- refCon: Longint; { reference value}
- listDefProc: Handle; { Handle to the defProc}
- userHandle: Handle; { General purpose handle for user}
- dataBounds: Rect; { Total number of rows/columns}
- cells: DataHandle; { Handle to data}
- maxIndex: Integer; { index past the last element = length of cellArray}
- cellArray: OffsetArray; { offsets to elements up to maxCols and maxOffsets/(maxCols+1) rows}
- cellWidth: WidthArray; {array of cell widths}
- lView: Rect; {Rect in which list alone is viewed}
- frameWidth: INTEGER; {width of frame around cells}
- just: INTEGER; {text justification mode}
- lFont, lSize: INTEGER; {list font info}
- lFace: Style; {list font info}
- nhRows: Integer; {# rows in heading}
- lHead: lHeadArray; {heading text}
- hFont, hSize: INTEGER; {list font info}
- hFace: Style; {list font info}
- hCellHeight: INTEGER; {height of heading cell}
- listTE: TEHandle; {edit TE (or NIL)}
- lActiveTE: BOOLEAN; {is the TE active?}
- lEditMode: BOOLEAN; {are we editing a TE?}
- end;
-
-
- procedure vLActivate (act: Boolean; vlHandle: vListHandle);
- {hilight selected cells and scroll bars}
-
- function vLAddColumn (count, colNum: Integer; vlHandle: vListHandle): Integer;
-
- function vLAddRow (count, rowNum: Integer; vlHandle: vListHandle): Integer;
-
- procedure vLAddToCell (dataPtr: Ptr; dataLen: Integer; theCell: Cell; vlHandle: vListHandle);
-
- procedure vLAutoScroll (vlHandle: vListHandle);
-
- procedure vLCalcCellWidths (var newWidth: WidthArray; var nCol: INTEGER; vlHandle: vListHandle);
-
- procedure vLCellSize (cSize: Point; vlHandle: vListHandle);
-
- function vLClick (pt: Point; modifiers: Integer; vlHandle: vListHandle): Boolean;
-
- procedure vLClrCell (theCell: Cell; vlHandle: vListHandle);
-
- procedure vLDelColumn (count, colNum: Integer; vlHandle: vListHandle);
-
- procedure vLDelRow (count, rowNum: Integer; vlHandle: vListHandle);
-
- procedure vLDispose (vlHandle: vListHandle);
-
- procedure vLDoDraw (drawIt: Boolean; vlHandle: vListHandle);
-
- procedure vLDraw (theCell: Cell; vlHandle: vListHandle);
-
- procedure vLFind (var offset, len: Integer; theCell: Cell; vlHandle: vListHandle);
-
- procedure vLFont (myFont, mySize: INTEGER; myFace: Style; vlHandle: vListHandle);
-
- procedure vLGetCell (dataPtr: Ptr; var dataLen: Integer; theCell: Cell; vlHandle: vListHandle);
-
- function vLGetSelect (next: Boolean; var theCell: Cell; vlHandle: vListHandle): Boolean;
-
- function vLLastClick (vlHandle: vListHandle): Cell;
-
- procedure vLSetHeadings (nhRows: INTEGER; headings: lHeadArray; vlHandle: vListHandle);
-
- procedure vLSetWidths (widths: WidthArray; vlHandle: vListHandle);
-
- function vLNew (plView, pdatabounds: RECT; pcellSize: POINT; procID: INTEGER; theWindow: WindowPtr; drawIt, hasGrow, scrollHoriz, scrollVert: Boolean): vListHandle;
-
- function vLNewScrap: vLScrapHandle;
-
- function vLNextCell (hNext, vNext: Boolean; var theCell: Cell; vlHandle: vListHandle): Boolean;
-
- procedure vLRect (var cellRect: Rect; theCell: Cell; vlHandle: vListHandle);
-
- procedure vLScroll (dRows, dCols: Integer; vlHandle: vListHandle);
-
- function vLSearch (dataPtr: Ptr; dataLen: Integer; SearchProc: Ptr; var theCell: Cell; vlHandle: vListHandle): Boolean;
-
- procedure vLSetCell (dataPtr: Ptr; dataLen: Integer; theCell: Cell; vlHandle: vListHandle);
-
- procedure vLSetSelect (setIt: Boolean; theCell: Cell; vlHandle: vListHandle);
-
- procedure vLInsetList (dH, dV: Integer; vlHandle: vListHandle);
-
- procedure vLSize (newWidth, newHeight: INTEGER; vlHandle: vListHandle);
-
- procedure vLUpdate (theRgn: RgnHandle; vlHandle: vListHandle);
-
- procedure vLUpdateSelRect (selRect: Rect; vlHandle: vListHandle);
-
- procedure vLCellsToScrap (whatCells: RECT; vlHandle: vListHandle; hScrap: vLScrapHandle); {copy cells to scrap}
-
- procedure vLDrawHeading (vlHandle: vListHandle);
-
- function vLEncloseSel (vlHandle: vListHandle): Rect;
-
- procedure vLFrame (frameWidth: INTEGER; var vlHandle: vListHandle);
-
- procedure vLIndent (indent: POINT; var vlHandle: vListHandle);
-
- procedure vLJust (just: INTEGER; var vlHandle: vListHandle);
-
- procedure vLScrapToCells (whatCells: RECT; vlHandle: vListHandle; hScrap: vLScrapHandle);
-
- procedure vLTENew (active: BOOLEAN; whatCell: Cell; vlHandle: vListHandle);
-
- procedure vLTEDispose (vlHandle: vListHandle);
-
- procedure vLActivateTE (active: BOOLEAN; vlHandle: vListHandle);
-
- procedure vLKey (ch: CHAR; modifiers: Integer; vlHandle: vListHandle; vScrap: vLScrapHandle);
-
- implementation
- var
- oldFont, oldSize: INTEGER; {current font stuff}
- oldFace: Style; {current font stuff}
- oldPen: PenState; {current font stuff}
- oldPort: GrafPtr; {the current GrafPort}
- oldClip: RgnHandle;
- oldSelectRect, SelectRect: RECT; {selection range}
-
- procedure AdjustList (vlHandle: vListHandle);
- forward;
-
- function vLCellRect (theCell: Cell; vlHandle: vListHandle): RECT;
- forward;
-
- procedure vLUnSelectAll (vlHandle: vListHandle);
- forward;
-
- procedure SaveFont;
- begin
- oldFont := oldPort^.txFont;
- oldSize := oldPort^.txSize;
- oldFace := oldPort^.txFace;
- end; {}
-
- procedure RestoreFont;
- begin
- TextFont(oldFont); {set font info}
- TextSize(oldSize);
- TextFace(oldFace);
- end; {}
-
- procedure StartEdit (theCell: Cell; vlHandle: vListHandle);
- {begin editing a cell using}
- {need to make sure cell is visible before editing}
- var
- cRect: RECT;
- offset, len: INTEGER;
- begin
- vLFind(offset, len, theCell, vlHandle); {get offset of data in vlHandle^^.cells and length of data}
- vLRect(cRect, theCell, vlHandle); {cell rectangle of the cell}
- {don't edit cell which is not visible}
- if vlHandle^^.listTE <> nil then
- if (cRect.right - cRect.left) * (cRect.bottom - cRect.top) > 1 then
- begin
- InsetRect(cRect, 3, 3); {}
- { cRect.top := cRect.top + 1; {don't trash borders}
- cRect.left := cRect.left + vlHandle^^.indent.h;
- if (cRect.right - cRect.left) < 30 then {make it at least 30 pixels wide}
- cRect.right := cRect.left + 30;
- vlHandle^^.listTE^^.destRect := cRect; {position TE record over new cell}
- vlHandle^^.listTE^^.viewRect := cRect;
- vLFind(offset, len, theCell, vlHandle);
- HLock(Handle(vlHandle^^.cells));
- TESetText(Ptr(ORD4(vlHandle^^.cells^) + offset), len, vlHandle^^.listTE); {move cell contents to TERec}
- HUnLock(Handle(vlHandle^^.cells));
- vlHandle^^.lastClick := theCell;
- vlHandle^^.leditMode := TRUE;
- vlHandle^^.lActiveTE := TRUE;
- TEActivate(vlHandle^^.listTE);
- TESetSelect(0, 0, vlHandle^^.listTE); {select all text}
- TEUpdate(cRect, vlHandle^^.listTE); {show the text}
- end;
- end; {procedure StartEdit}
-
- procedure StopEdit (save: BOOLEAN; theCell: Cell; vlHandle: vListHandle);
- {if save is true,transfer text to cell}
- {change editMode to editCell}
- var
- hChars: CharsHandle;
- begin
- if save then
- begin
- {transfer text to cell}
- hChars := TEGetText(vlHandle^^.listTE);
- HLock(Handle(hChars));
- vLSetCell(Ptr(hChars^), vlHandle^^.listTE^^.teLength, theCell, vlHandle);
- HUnLock(Handle(hChars));
- end; {if save..}
- EraseRect(vlHandle^^.listTE^^.viewRect); {}
- InvalRect(vlHandle^^.listTE^^.viewRect); {force redraw}
- { vLDraw(theCell, vlHandle); {}
- vlHandle^^.leditMode := FALSE;
- vlHandle^^.lActiveTE := FALSE;
- TEDeActivate(vlHandle^^.listTE);
- TESetSelect(0, 0, vlHandle^^.listTE); {no text selected}
- end; {procedure StopEdit}
-
- function CalcVisibleBottom (firstRow: INTEGER; var dangle: INTEGER; vlHandle: vListHandle): INTEGER;
- var
- i, j, nVrow: INTEGER;
- begin
- nVrow := 0;
- i := firstRow;
- j := vlHandle^^.lView.bottom - vlHandle^^.lView.top;
- {calculate how many rows fit in lView}
- nVrow := j div vlHandle^^.cellSize.v;
- CalcVisibleBottom := firstRow + nVrow;
- dangle := j - nVrow * vlHandle^^.cellSize.v;
- end; {function CalcVisibleBottom}
-
- function CalcVisibleRight (firstCol: INTEGER; var dangle: INTEGER; vlHandle: vListHandle): INTEGER;
- var
- i, j, nVcol: INTEGER;
- begin
- nVcol := 0;
- i := firstCol;
- j := vlHandle^^.lView.right - vlHandle^^.lView.left;
- {calculate how many columns fit in lView}
- while (j > 0) and (i < vlHandle^^.databounds.right) do
- begin
- nVcol := nVcol + 1;
- if vlHandle^^.cellWidth[i] > 1 then
- j := j - vlHandle^^.cellWidth[i]
- else
- j := j - 1;
- i := i + 1;
- end; {while j>0}
- CalcVisibleRight := firstCol + nVcol;
- if j < 0 then
- dangle := -j
- else
- dangle := 0;
- end; {function CalcVisible}
-
- procedure SetScrollMax (vlHandle: vListhandle);
- {set ControlMax such that if column # ControllMax is leftmost column}
- {the rightmost column will be fully visible}
- const
- active = 0;
- inactive = 255;
- var
- i, j, dangle: INTEGER;
- begin
- {visible.bottom-visible.top = # lines which can be seen}
- {set control max to # of columns which lie outside the visible rectangle}
- with vlHandle^^ do
- begin
- if vScroll <> nil then
- begin
- i := databounds.bottom - visible.bottom + visible.top;
- if i > 0 then
- begin
- SetCtlMax(vScroll, i);
- HiliteControl(vScroll, active);
- end
- else
- begin
- SetCtlMax(vScroll, 0);
- HiliteControl(vScroll, inactive);
- end;
- end; {if vScroll <> nil}
- if hScroll <> nil then
- begin
- {check for partially showing columns}
- {++++++++}
- i := databounds.right - 1;
- j := 0;
- repeat
- begin
- j := j + cellWidth[i];
- i := i - 1;
- end;
- until (j >= lView.right - lView.left) or (i < 0);
- if j > (lView.right - lView.left) then
- i := i + 2
- else
- i := i + 1;
-
- if i > 0 then
- begin
- SetCtlMax(hScroll, i);
- HiliteControl(hScroll, active);
- end
- else
- begin
- SetCtlMax(hScroll, 0);
- HiliteControl(hScroll, inactive);
- end;
- end; {if hScroll <> nil}
- end; {with vlHandle..}
- end; {procedure SetScrollMax}
-
- function CalcVisRect (vlHandle: vListHandle): RECT;
- {return rectangle enclosing visible cells of list}
- {clip rectangle to lView in case some cells are only partially visible}
- var
- tBool: BOOLEAN;
- tCell: Cell;
- tRect1, tRect2, visRect: RECT;
- begin
- SetPt(tCell, vlHandle^^.visible.left, vlHandle^^.visible.top); {first visible cell}
- tRect1 := vLCellRect(tCell, vlHandle); {rect of first visible cell}
- SetPt(tCell, vlHandle^^.visible.right - 1, vlHandle^^.visible.bottom - 1); {last visible cell}
- tRect2 := vLCellRect(tCell, vlHandle); {rect of last visible cell}
- UnionRect(tRect1, tRect2, visRect); {rect enclosing visible cells}
- tBool := SectRect(vlHandle^^.lView, visRect, visRect); {make visRect smaller of lView, visible}
- CalcVisRect := visRect;
- end; {CalcVisRect}
-
- procedure AdjustScrollBars (vlHandle: vListHandle);
- {adjust size and postion of scroll bars}
- {put scroll bars along edge of CalcVisRect}
- {call if rView or lView is changed, or after scrolling}
- var
- tBool: BOOLEAN;
- tCell: Cell;
- tRect1, tRect2, visRect: RECT;
- begin
- visRect := CalcVisRect(vlHandle);
- if vlHandle^^.hScroll <> nil then
- begin
- MoveControl(vlHandle^^.hScroll, visRect.left, visRect.bottom);
- SizeControl(vlHandle^^.hScroll, visRect.right - visRect.left + 1, 16);
- vLDrawHeading(vlHandle);
- end;
- if vlHandle^^.vScroll <> nil then
- begin
- MoveControl(vlHandle^^.vScroll, visRect.right, visRect.top);
- SizeControl(vlHandle^^.vScroll, 16, visRect.bottom - visRect.top + 1);
- end;
- end; {procedure AdjustScrollBars}
-
- procedure AdjustList (vlHandle: vListHandle);
- {adjust list display to match scroll bar and redraw cells}
- {control values show columns and rows which should be visible}
- {control range max should not leave one row (or column) of cells at top (left) of screen}
- var
- i, j, dangle: INTEGER;
- tPt: Point;
- tBool: BOOLEAN;
- visRect: RECT; {contains visible cells}
- tCell1, tCell2: Cell;
- begin
- {erase old cells}
- visRect := CalcVisRect(vlHandle);
- EraseRect(visRect);
- {determine visible cells}
- vlHandle^^.visible.top := 0;
- vlHandle^^.visible.left := 0;
- if vlHandle^^.vScroll <> nil then
- vlHandle^^.visible.top := GetCtlValue(vlHandle^^.vScroll);
- if vlHandle^^.hScroll <> nil then
- vlHandle^^.visible.left := GetCtlValue(vlHandle^^.hScroll);
- vlHandle^^.visible.bottom := vlHandle^^.visible.top + (vlHandle^^.lView.bottom - vlHandle^^.lView.top) div vlHandle^^.cellSize.v;
- {determine # of columns at least partially visible in lView}
- vlHandle^^.visible.right := CalcVisibleRight(vlHandle^^.visible.left, dangle, vlHandle);
- tBool := SectRect(vlHandle^^.databounds, vlHandle^^.visible, vlHandle^^.visible); {make visible smaller of databounds, visible}
- {redraw cells}
- for i := vlHandle^^.visible.top to vlHandle^^.visible.bottom do
- for j := vlHandle^^.visible.left to vlHandle^^.visible.right do
- begin
- SetPt(tPt, j, i);
- vLDraw(tPt, vlHandle);
- end;
- end; {procedure AdjustList}
-
- function CalcDelta (vRect: RECT; code: INTEGER): INTEGER; {0=pageUp, 1=pageDwn, 2=pageLeft, 3=pageRight}
- {calculate change in control setting for control hits}
- var
- tDelta: INTEGER;
- begin
- with vRect do
- case code of
- 0: {pageUp}
- tDelta := -(bottom - top - 1);
- 1: {pageDwn}
- tDelta := bottom - top - 1;
- 2: {pageLeft}
- tDelta := -(right - left - 1);
- 3: {pageRight}
- tDelta := right - left - 1;
- otherwise
- {do nothing}
- end; {case}
- CalcDelta := tDelta;
- end; {procedure CalcDelta}
-
- function LoBits (bigNum: INTEGER): INTEGER;
- {returns lower 15 bits of INTEGER}
- begin
- LoBits := BitAnd(bigNum, $7FFF);
- end; {function LoBits}
-
- function PtToCell (pt: Point; vlHandle: vListHandle): Cell; {return cell located at this point}
- {does not check to see if cell is valid}
- var
- tCell: Cell;
- tWidth: WidthArray;
- tVis: Rect;
- i, j, k, tHeight: INTEGER;
- begin
- pt.h := pt.h - vlHandle^^.lView.left; {convert to list coordinates}
- pt.v := pt.v - vlHandle^^.lView.top;
- tWidth := vlHandle^^.cellWidth;
- tVis := vlHandle^^.visible;
- tHeight := vlHandle^^.cellSize.v;
- SetPt(tCell, tVis.left, tVis.top); {start at left of window}
- tCell.v := pt.v div tHeight + tVis.top; {adjust vertical}
- i := 0;
- j := tVis.left; {start at left}
- repeat
- i := i + tWidth[j]; {add width of this column}
- if pt.h <= i then
- tCell.h := j;
- j := j + 1; {increment column}
- until (i > pt.h) or (j > tVis.right);
- PtToCell := tCell;
- end; {function PtToCell}
-
- procedure vLActivate (act: Boolean; vlHandle: vListHandle);
- {activates list if act = TRUE}
- {deactivates list if act=FALSE}
- const
- active = 0;
- inactive = 255;
- begin
- if act <> vlHandle^^.LActive then
- begin
- vlHandle^^.LActive := act; { active or not}
- if act = TRUE then
- begin {activate}
- if vlHandle^^.vScroll <> nil then
- HiliteControl(vlHandle^^.vScroll, active);
- if vlHandle^^.hScroll <> nil then
- HiliteControl(vlHandle^^.hScroll, active);
- InvalRect(vlHandle^^.rView);
- if vlHandle^^.listTE <> nil then
- TEActivate(vlHandle^^.listTE);
- end
- else
- begin {deactivate}
- if vlHandle^^.vScroll <> nil then
- HiliteControl(vlHandle^^.vScroll, inactive);
- if vlHandle^^.hScroll <> nil then
- HiliteControl(vlHandle^^.hScroll, inactive);
- InvalRect(vlHandle^^.rView);
- end;
- end;
- end; {procedure vLActivate}
-
- procedure vLActivateTE (active: BOOLEAN; vlHandle: vListHandle);
- begin
- if (vlHandle^^.listTE <> nil) and (active <> vlHandle^^.lActiveTE) then
- begin
- vlHandle^^.lActiveTE := active;
- if active then
- begin
- TEActivate(vlHandle^^.listTE);
- vlHandle^^.lEditMode := TRUE;
- StartEdit(vlHandle^^.lastClick, vlHandle); {}
- end
- else
- begin
- TEDeactivate(vlHandle^^.listTE);
- vlHandle^^.lEditMode := FALSE;
- StopEdit(False, vlHandle^^.lastClick, vlHandle);
- end;
- end; {active <> vlHandle^^.lActiveTE}
- end; {procedure vLActivateTE}
-
- function vLAddColumn (count, colNum: Integer; vlHandle: vListHandle): Integer;
- {inserts count columns into list starting at colNum, using the default column width}
- {the number of the first added column is returned}
- {if drawing is on and the columns are visible, the list and its scroll bars is updated}
- {does NOT fix headings}
- begin
- {NOT IMPLEMENTED}
- end; {function vLAddCol}
-
- function vLAddRow (count, rowNum: Integer; vlHandle: vListHandle): Integer;
- {adds/inserts count rows into list starting at rowNum}
- {the number of the first added row is returned}
- {if drawing is on and the rows are visible, the list and its scroll bars is updated}
- var
- nCol, nRow, index: Integer;
- newcells, lastcell: Integer;
- i, j, k: Integer;
- startOffset, endOffset: INTEGER;
- tPtr: Ptr;
- nVcol, nVrow: INTEGER;
- begin
- HLock(Handle(vlHandle));
- with vlHandle^^ do
- begin
- vLUnSelectAll(vlHandle); {eliminate confusion over LoBits, etc.}
- nCol := databounds.right; {# columns}
- nRow := databounds.bottom; {# rows}
- if rowNum > nRow then { rowNum > nRow, add rows to end}
- begin
- index := nRow * nCol; {get index to end of offset array}
- newcells := count * nCol; {# new cells to add}
- for i := index to index + newcells do
- cellArray[i] := cellArray[index]; {set offsets of new cells to last offset}
- databounds.bottom := databounds.bottom + count; {set databounds}
- end { rowNum > nRow}
- else
- begin { rowNum <= nRow, insert rows}
- index := rowNum * nCol; {get index into offset array}
- newcells := count * nCol; {# new cells to add}
- lastcell := nRow * nCol;
- for i := lastcell downto index do {move offsets down in array}
- cellArray[i + newcells] := cellArray[i];
- for i := index to index + newcells - 1 do
- cellArray[i] := cellArray[index + newcells];
- {fix databounds}
- databounds.bottom := databounds.bottom + count; {set databounds}
- end; { rowNum <= nRow, insert rows}
- maxIndex := databounds.right * databounds.bottom;
- SetScrollMax(vlHandle); {fix control max}
- if rowNum + count > visible.bottom then {if new rows are not on screen then..}
- SetCtlValue(vScroll, rowNum); {position new row at top of screen if necessary}
- AdjustList(vlHandle); {scroll and adjust visible rectangle}
- SetScrollMax(vlHandle);
- AdjustScrollBars(vlHandle);
- vLUpdate(port^.visRgn, vlHandle)
- end; {with vlHandle...}
- HUnLock(Handle(vlHandle));
- if rowNum > nRow then
- vLAddRow := nRow
- else
- vLAddRow := rowNum;
- end; {function vLAddRow}
-
- procedure vLAddToCell (dataPtr: Ptr; dataLen: Integer; theCell: Cell; vlHandle: vListHandle);
- begin
- {NOT IMPLEMENTED}
- end;
-
- procedure vLAutoScroll (vlHandle: vListHandle);
- begin
- {NOT IMPLEMENTED}
- end;
-
- procedure vLCalcCellWidths (var newWidth: WidthArray; var nCol: INTEGER; vlHandle: vListHandle);
- {calculate number of columns and column widths based on heading string, using | to delineate columns}
- {minumum column width is 1}
- {default to current column width if there is no header string}
- var
- tStr1, tStr2, tStr3: STR255;
- i, rowNum, charIndex, k: INTEGER;
- teRect: RECT;
- begin
- HLock(Handle(vlHandle));
- with vlHandle^^ do
- begin
- GetPort(oldPort);
- SetPort(port);
- SaveFont;
- if nhRows > 0 then
- begin
- TextFont(hfont); {set font info}
- TextSize(hSize);
- TextFace(hFace);
- for i := 0 to maxCols do
- newWidth[i] := cellWidth[i];
- {calculate column widths}
- for rowNum := 1 to nhRows do
- begin
- tStr1 := lHead[rowNum];
- tStr2 := '';
- k := 0; {column counter}
- charIndex := Pos('|', tStr1);
- while charIndex <> 0 do
- begin
- tStr3 := Copy(tStr1, 1, charIndex - 1); {copy substring}
- if tStr3 <> '' then
- newWidth[k] := 1; {don't change existing widths if header is blank}
- if StringWidth(tStr3) + 1 > newWidth[k] then
- newWidth[k] := StringWidth(tStr3) + 1; {get width of string + 1 pixel for vertical line}
- nCol := k;
- k := k + 1;
- Delete(tStr1, 1, charIndex); {remove substring}
- charIndex := Pos('|', tStr1);
- end;
- end; {for rowNum ..}
- nCol := k;
- end; {with myHeading}
- end; {with vlHandle}
- RestoreFont;
- SetPort(oldPort);
- HLock(Handle(vlHandle));
- end; {procedure vLCalcCellWidths}
-
- function vLCellRect (theCell: Cell; vlHandle: vListHandle): RECT;
- {give a cell and a list, return rectangle to draw cell in}
- var
- cRect: Rect;
- i, vRoffset, hRoffset: Integer; {offsets for cell rectangle}
- begin
- {create cell rectangle}
- SetRect(cRect, 0, 0, 0, 0);
- if (theCell.h >= 0) and (theCell.v >= 0) then
- begin
- SetRect(cRect, 0, 0, vlHandle^^.cellWidth[theCell.h], vlHandle^^.cellSize.v); {left,top,right,bottom}
- vRoffset := (theCell.v - vlHandle^^.visible.top) * vlHandle^^.cellSize.v;
- hRoffset := 0;
- for i := vlHandle^^.visible.left to theCell.h - 1 do
- hRoffset := hRoffset + vlHandle^^.cellWidth[i];
- OffsetRect(cRect, hRoffset, vRoffset); {}
- OffsetRect(cRect, vlHandle^^.lView.left, vlHandle^^.lView.top);
- end; {if ...}
- vLCellRect := cRect;
- end; {function vLCellRect}
-
- procedure vLCellSize (cSize: Point; vlHandle: vListHandle);
- begin
- {NOT IMPLEMENTED}
- end; {procedure vLCellSize}
-
- procedure vLCellsToScrap (whatCells: RECT; vlHandle: vListHandle; hScrap: vLScrapHandle);
- {transfer cells in whatCells to the scrap, replacing scrap contents}
- {selected points are within whatCells, i.e. whatCells.right is 1 greater than rightmost cell index}
- {cells are not neccesarily contiguous}
- var
- i, j, k, cLen: INTEGER;
- theCell: Cell;
- tPtr: Ptr;
- tRect: RECT;
- tBool: BOOLEAN;
- begin
- tBool := SectRect(whatCells, vlHandle^^.databounds, whatCells); {Clip whatCells to databounds}
- if tBool then {if some of whatCells is in databounds}
- begin
- HLock(Handle(hScrap));
- with hScrap^^ do
- begin
- scrapBounds := whatCells;
- OffsetRect(scrapBounds, -whatCells.left, -whatCells.top); {make first cell in scrap 0,0}
- k := 0;
- hScrap^^.scrapOffsets[k] := 0;
- for i := whatCells.top to whatCells.bottom - 1 do
- for j := whatCells.left to whatCells.right - 1 do
- begin
- SetPt(theCell, j, i); {h,v}
- tPtr := PTR(ORD4(@scrapData) + scrapOffsets[k]); {destination pointer to data array location for copied data}
- SetPtrSize(tPtr, maxChars - scrapOffsets[k]); {make sure tPtr big enough}
- vLGetCell(tPtr, cLen, theCell, vlHandle); {copy cell data inot scrap}
- k := k + 1;
- scrapOffsets[k] := scrapOffsets[k - 1] + cLen;
- end; {for j..}
- end; {with hScrap}
- HUnLock(Handle(hScrap));
- end; {if tBool}
- end; {vLCellsToScrap}
-
- function vLClick (pt: Point; modifiers: Integer; vlHandle: vListHandle): Boolean;
- {called when mouse is down in the list window}
- {tracks mouse and selects cells and scrolls display if neccesary}
- {result is true if a double click occured in a single cell}
- var
- myPart: INTEGER; {part code}
- myControl: ControlHandle;
- myTime, clickInt: LONGINT;
- newPt: Point;
- mySelect: BOOLEAN;
- optionKey, cmdKey, shiftKey, noKey: BOOLEAN;
- selAnchor: Point;
- selRect: Rect;
- oldCell, newCell, midCell, tCell: Cell;
- i: INTEGER;
-
- function GetMods: modifierType;
- var
- myKeyMap: KeyMap;
- begin
- GetKeys(myKeyMap);
- GetMods := none;
- if myKeyMap[56] then
- GetMods := shift;
- if myKeyMap[56] then
- GetMods := shift;
- if myKeyMap[58] then
- GetMods := option;
- if myKeyMap[55] then
- GetMods := command;
- end; {function GetMods}
-
- procedure AdjustSelRect1 (var mySel: Rect; var myAnchor: Point; myCell: Cell);
- {add cell(s) to existing selection}
- {may change myAnchor}
- { Regions: put myCell at center, and determine region by relative position of anchor}
- { 4 | 3}
- { _____}
- { 2 | 1}
- {may need to swap topleft and botRight of SelRect}
- begin
- if EmptyRect(mySel) then
- begin
- mySel.topLeft := myCell;
- myAnchor := myCell;
- mySel.right := myCell.h + 1;
- mySel.bottom := myCell.v + 1;
- end
- else
- begin
- midCell.h := mySel.left + (mySel.right - 1 - mySel.left) div 2;
- midCell.v := mySel.top + (mySel.bottom - 1 - mySel.top) div 2;
- if (myCell.v <= midCell.v) and (myCell.h <= midCell.h) then
- begin {region 1}
- myAnchor.v := mySel.bottom - 1;
- myAnchor.h := mySel.right - 1;
- mySel.topLeft := myCell;
- end;
- if (myCell.v <= midCell.v) and (myCell.h > midCell.h) then
- begin {region 2}
- myAnchor.v := mySel.bottom - 1;
- myAnchor.h := mySel.left;
- mySel.top := myCell.v;
- mySel.right := myCell.h + 1;
- end;
- if (myCell.v > midCell.v) and (myCell.h <= midCell.h) then
- begin {region 3}
- myAnchor.v := mySel.top;
- myAnchor.h := mySel.right - 1;
- mySel.bottom := myCell.v + 1;
- mySel.left := myCell.h;
- end;
- if (myCell.v > midCell.v) and (myCell.h > midCell.h) then
- begin {region 4}
- myAnchor.v := mySel.top;
- myAnchor.h := mySel.left;
- mySel.bottom := myCell.v + 1;
- mySel.right := myCell.h + 1;
- end
- end;
- end; {procedure AdjustSelRect1}
-
- procedure AdjustSelRect2 (var mySel: Rect; myAnchor: Point; myCell: Cell);
- {adjust selection to accomodate myCell}
- {do not change anchor}
- {mySel can extend to databounds, i.e. 1 cell below and right of actual data}
- begin
- if (myCell.v <= myAnchor.v) and (myCell.h <= myAnchor.h) then {region 1}
- SetRect(mySel, myCell.h, myCell.v, myAnchor.h + 1, myAnchor.v + 1); {left, top, right, bottom}
- if (myCell.v <= myAnchor.v) and (myCell.h > myAnchor.h) then {region 2}
- SetRect(mySel, myAnchor.h, myCell.v, myCell.h + 1, myAnchor.v + 1); {left, top, right, bottom}
- if (myCell.v > myAnchor.v) and (myCell.h <= myAnchor.h) then {region 3}
- SetRect(mySel, myCell.h, myAnchor.v, myAnchor.h + 1, myCell.v + 1); {left, top, right, bottom}
- if (myCell.v > myAnchor.v) and (myCell.h > myAnchor.h) then {region 4}
- SetRect(mySel, myAnchor.h, myAnchor.v, myCell.h + 1, myCell.v + 1); {left, top, right, bottom}
- end; {procedure AdjustSelRect2}
-
-
- procedure DoVertScroll (myPt: Point; myPart: INTEGER);
- {handle mousedown in scroll bar}
- var
- newPt: Point;
- delta, oldvalue: INTEGER;
- begin
- if myPart = InThumb then
- begin
- myPart := TrackControl(vlHandle^^.vScroll, myPt, nil);
- AdjustList(vlHandle); {adjust list display to match scroll bar}
- end
- else
- repeat
- GetMouse(newpt); {get new mouse location}
- if TestControl(vlHandle^^.vScroll, newPt) = myPart then {are we in same part where mouse was pressed?}
- case myPart of
- inUpButton:
- begin
- delta := -1;
- HiliteControl(vlHandle^^.vScroll, inUpButton); {hilite it}
- end;
- inDownButton:
- begin
- delta := 1;
- HiliteControl(vlHandle^^.vScroll, inDownButton); {hilite it}
- end;
- inPageUp:
- delta := CalcDelta(vlHandle^^.visible, 0);
- inPageDown:
- delta := CalcDelta(vlHandle^^.visible, 1); {0=pageUp, 1=pageDwn, 2=pageLeft, 3=pageRight}
- otherwise
- {do nothing}
- end; {case myPart of}
- if myPart <> 0 then
- begin
- oldValue := GetCtlValue(myControl);
- SetCtlValue(myControl, oldValue + delta); {let SetCtl handle out of range values}
- if GetCtlValue(myControl) <> oldValue then
- AdjustList(vlHandle); {adjust list display if necessary}
- case myPart of
- inUpButton:
- begin
- HiliteControl(vlHandle^^.vScroll, 0); {unhilite it}
- end;
- inDownButton:
- begin
- HiliteControl(vlHandle^^.vScroll, 0); {unhilite it}
- end;
- otherwise
- {do nothing}
- end; {case myPart..}
- end; {if myPart <> 0}
- until not StillDown;
- end; {procedure DoVertScroll}
-
- procedure DoHorzScroll (myPt: Point; myPart: INTEGER);
- {handle mousedown in scroll bar}
- var
- newPt: Point;
- delta, oldvalue: INTEGER;
- begin
- delta := 0;
- if myPart = InThumb then
- begin
- myPart := TrackControl(vlHandle^^.hScroll, myPt, nil);
- AdjustList(vlHandle); {adjust list display to match scroll bar}
- end
- else
- repeat
- GetMouse(newpt); {get new mouse location}
- if TestControl(vlHandle^^.hScroll, newPt) = myPart then {are we in same part where mouse was pressed?}
- case myPart of
- inUpButton:
- begin
- delta := -1;
- HiliteControl(vlHandle^^.hScroll, inUpButton); {hilite it}
- end;
- inDownButton:
- begin
- delta := 1;
- HiliteControl(vlHandle^^.hScroll, inDownButton); {hilite it}
- end;
- inPageUp:
- delta := CalcDelta(vlHandle^^.visible, 2);
- inPageDown:
- delta := CalcDelta(vlHandle^^.visible, 3); {0=pageUp, 1=pageDwn, 2=pageLeft, 3=pageRight}
- otherwise
- {do nothing}
- end; {case myPart of}
- if myPart <> 0 then
- begin
- oldValue := GetCtlValue(myControl);
- SetCtlValue(myControl, oldValue + delta); {let SetCtl handle out of range values}
- if GetCtlValue(myControl) <> oldValue then
- AdjustList(vlHandle); {adjust list display if necessary}
- vLDrawHeading(vlHandle); {redraw the heading}
- end; {if myPart..}
- until not StillDown;
- end; {procedure DoHorzScroll}
-
- function TrackList (var oldCell: Cell; vlHandle: vListHandle): BOOLEAN;
- {track list - return if mouse button up or mouse location moves from oldCell}
- var
- newCell: Cell;
- validRect: Rect;
- begin
- validRect := vlHandle^^.visible;
- repeat
- GetMouse(newpt); {get new mouse location}
- newCell := PtToCell(newPt, vlHandle);
- if not PtInRect(newCell, validRect) then
- newCell := oldCell; {don't accept invalid cells}
- until (not EqualPt(oldCell, newCell)) or (not StillDown);
- oldCell := newCell;
- TrackList := StillDown;
- end; {function TrackList}
-
- procedure DoScrollClick;
- begin
- if (myControl = vlHandle^^.vScroll) and (myControl <> nil) then
- DoVertScroll(pt, myPart); {handle v scroll bar}
- if (myControl = vlHandle^^.hScroll) and (myControl <> nil) then
- DoHorzScroll(pt, myPart); {handle h scroll bar}
- end;
-
- procedure DoCellClick;
- {handle mouseclick in cell editing mode}
- var
- i: INTEGER;
- begin
- {determine modifier status}
- case GetMods of
- none:
- begin
- selAnchor := newCell;
- SetRect(selRect, 0, 0, 0, 0); {deselect all cells}
- vLUpdateSelRect(selRect, vlHandle); {redraw cells}
- vLSetSelect(TRUE, newCell, vlHandle); {select the new cell}
- end;
- option:
- begin
- selAnchor := newCell;
- SetRect(selRect, 0, 0, 0, 0); {deselect all cells}
- vLUpdateSelRect(selRect, vlHandle); {redraw cells}
- for i := 0 to vlHandle^^.databounds.right - 1 do
- begin
- SetPt(tCell, i, newCell.v); {select whole row}
- vLSetSelect(TRUE, tCell, vlHandle);
- end; {for i..}
- end; {if optionKey}
- shift:
- begin
- selRect := vLEncloseSel(vlHandle); {get rect of current selections}
- AdjustSelRect1(selRect, selAnchor, newCell); {extend/alter selection to enclose new cell}
- vLUpdateSelRect(selRect, vlHandle); {select all cells in the selRect and update display}
- end; {if shiftKey.}
- otherwise
- selAnchor := newCell;
- end; {case...}
- {track mouse until mouse released}
- oldCell := vlHandle^^.lastClick;
- newCell := oldCell;
- while TrackList(newCell, vlHandle) do {}
- begin
- case GetMods of
- none:
- begin
- selAnchor := newCell;
- vLSetSelect(FALSE, oldCell, vlHandle);
- vLSetSelect(TRUE, newCell, vlHandle);
- SetRect(selRect, newCell.h, newCell.v, newCell.h + 1, newCell.v + 1);
- vLUpdateSelRect(selRect, vlHandle); {select all cells in the selRect and update display}
- oldCell := newCell;
- end;
- shift:
- begin
- selRect := vLEncloseSel(vlHandle); {get rect of current selections}
- AdjustSelRect2(selRect, selAnchor, newCell); {}
- vLUpdateSelRect(selRect, vlHandle); {select all cells in the selRect and update display}
- end; {if shiftKey.}
- otherwise
- ; {nothing}
- end; {case...}
- end; {while TrackList}
- end; {procedure DoCellClick}
-
-
- {START procedure vLClick}
- begin
- HLock(Handle(vlHandle));
- with vlHandle^^ do
- begin
- myPart := FindControl(pt, WindowPtr(port), myControl); {are we in a control?}
- if myPart <> 0 then
- {handle mouse in scroll bars}
- begin
- DoScrollClick;
- end;
- if myPart = 0 then
- begin
- {handle mouse in list}
- newCell := PtToCell(pt, vlHandle);
- if (PtInRect(pt, lView)) and (PtInRect(newCell, databounds)) then
- begin
- myTime := TickCount;
- {check for double click}
- clickInt := myTime - clikTime;
- if EqualPt(pt, clikLoc) and ((myTime - clikTime) < GetDblTime) then
- begin
- vLClick := TRUE;
- if (listTE <> nil) then
- begin
- if (lActiveTE) then
- StopEdit(FALSE, lastClick, vlHandle); {quit editing previous cell}
- StartEdit(newCell, vlHandle); {start editing new cell}
- end; {listTE <>nil}
- end {if double click}
- else
- vLClick := FALSE;
- clikTime := myTime;
- {check if click in active TE}
- if (listTE <> nil) and (lActiveTE) and (leditMode) then
- begin
- if PtInRect(pt, listTE^^.viewRect) then
- begin
- if GetMods = shift then
- TEClick(pt, TRUE, listTE)
- else
- TEClick(pt, FALSE, listTE);
- end {if PtInRect}
- else
- StopEdit(FALSE, lastClick, vlHandle) {stop editing if click outside TE}
- end; {(listActive)}
- if not leditMode then
- begin {handle click in list}
- oldSelectRect := SelectRect; {keep previous selection rect}
- DoCellClick;
- SetPt(tCell, 0, 0); {edit first selected cell}
- SelectRect := vLEncloseSel(vlHandle); {save selection rect}
- end; {if leditMode}
- end; {not leditMode}
- {update stored values}
- clikLoc := pt;
- lastClick := newCell;
- clikTime := myTime;
- end; {myPart = 0}
- end; {with vlHandle}
- HUnLock(Handle(vlHandle));
- end; {procedure vLClick}
-
-
- procedure vLClrCell (theCell: Cell; vlHandle: vListHandle);
- begin
- vLSetCell(nil, 0, theCell, vlHandle); {set cell to 0 length data}
- end;
-
- procedure vLDelColumn (count, colNum: Integer; vlHandle: vListHandle);
- {deletes count columns into list starting at colNum}
- {if colNum is greater than databounds nothing is done}
- {if drawing is on and the columns are visible, the list and its scroll bars is updated}
- {if count = 0 all columns are deleted}
- begin
- {NOT IMPLEMENTED}
- end;
-
- procedure vLDelRow (count, rowNum: Integer; vlHandle: vListHandle);
- {deletes count rows in list starting at colNum}
- {if rowNum is greater than databounds nothing is done}
- {if drawing is on and the rows are visible, the list and its scroll bars are updated}
- {if count = 0 all rows are deleted}
- var
- nCol, nRow, index1, index2: Integer;
- ncells, lastcell, dlen: Integer;
- i, j, k: Integer;
- startOffset, endOffset: INTEGER;
- tPtr: Ptr;
- nVcol, nVrow: INTEGER;
- tBool: BOOLEAN;
- begin
- HLock(Handle(vlHandle));
- with vlHandle^^ do
- begin
- {theCell.h = column number}
- {theCell.v = row number}
- nCol := databounds.right; {# columns}
- nRow := databounds.bottom; {# rows}
- if rowNum < nRow then {only process valid row #}
- begin
- vLUnSelectAll(vlHandle); {eliminate confusion over LoBits, etc.}
- index1 := rowNum * nCol; {index to first cell to be deleted}
- index2 := (rowNum + count) * nCol; {index to last cell to be deleted}
- if index2 > maxindex then
- index2 := maxIndex;
- ncells := count * nCol; {# cells to delete}
- dlen := cellArray[index2] - cellArray[index1]; {# data bytes to delete}
- {fix data}
- HLock(Handle(cells));
- for i := cellArray[index1] to cellArray[maxIndex] do
- cells^^[i] := cells^^[i + dlen];
- HUnLock(Handle(cells));
- {fix offsets}
- for i := index1 + 1 to maxindex - ncells do
- cellArray[i] := cellArray[i + ncells] - dlen; {set new cell offsets}
- {set visible rectangle}
- databounds.bottom := databounds.bottom - count; {set databounds}
- maxIndex := databounds.right * databounds.bottom;
- nVrow := (lView.bottom - lView.top) div cellSize.v;
- nVcol := 0;
- i := 0;
- j := lView.right - lView.left;
- while (j > 0) and (i < databounds.right) do
- begin
- nVcol := nVcol + 1;
- j := j - cellWidth[i];
- i := i + 1;
- end; {while j>0}
- SetRect(visible, 0, 0, nVcol, nVrow);
- tBool := SectRect(databounds, visible, visible); {make visible smaller of databounds, visible}
- end; {if rowNum < nRow}
- SetScrollMax(vlHandle); {fix control max}
- if rowNum + count > visible.bottom then {if new rows are not on screen then..}
- SetCtlValue(vScroll, rowNum); {position new row at top of screen if necessary}
- {redraw everything}
- AdjustList(vlHandle);
- AdjustScrollBars(vlHandle);
- vLUpdate(port^.visRgn, vlHandle);
- end; {with vlHandle...}
- HUnLock(Handle(vlHandle));
- end; {procedure vLDelRow}
-
- procedure vLDispose (vlHandle: vListHandle);
- begin
- if vlHandle^^.hScroll <> nil then
- DisposeControl(vlHandle^^.hScroll);
- if vlHandle^^.vScroll <> nil then
- DisposeControl(vlHandle^^.vScroll);
- if (vlHandle^^.listTE <> nil) then
- TEDispose(vlHandle^^.listTE);
- DisposHandle(Handle(vlHandle^^.cells));
- DisposHandle(Handle(vlHandle));
- end;
-
- procedure vLDoDraw (drawIt: Boolean; vlHandle: vListHandle);
- {set drawing mode (stored in lActive) as appropriate}
- begin
- vlHandle^^.lActive := drawIt;
- end;
-
- procedure vLDrawCell (theCell: Cell; lSelect: Boolean; cRect: Rect; lDataOffset, lDataLen: INTEGER; vlHandle: vListHandle);
- {draw a cell with a given rectangle with given select mode}
- {save old port and clipping region}
- {set clip to VisRect}
- {draw cell}
- {restore port and clipping region}
- var
- tPtr: Ptr;
- tRect: RECT;
- tBool: BOOLEAN;
- begin
- if vlHandle^^.lActive then
- begin
- {set port}
- GetPort(oldPort);
- SetPort(vlHandle^^.port);
- SaveFont; {get data}
- oldClip := NewRgn;{}
- GetClip(oldClip); {save Clip Rect}
- ClipRect(CalcVisRect(vlHandle)); {don't draw outside VisRect so scroll bars don't get trashed}
- TextFont(vlHandle^^.lFont); {set font info}
- TextSize(vlHandle^^.lSize);
- TextFace(vlHandle^^.lFace);
- EraseRect(cRect);
- InsetRect(cRect, vlHandle^^.indent.h, vlHandle^^.indent.v);
- HLock(Handle(vlHandle^^.cells));
- tPtr := Ptr(ORD4(vlHandle^^.cells^) + lDataOffset);
- TextBox(tPtr, lDataLen, cRect, vlHandle^^.just);
- HUnLock(Handle(vlHandle^^.cells));
- InsetRect(cRect, -vlHandle^^.indent.h, -vlHandle^^.indent.v);
- {frame left and top are within rectangle}
- {frame bottom and right are outside of rectangle}
- {FrameRect draws INSIDE the Rectangle boundaries}
- if vlHandle^^.frameWidth > 0 then
- begin
- tRect := cRect;
- tRect.bottom := tRect.bottom + 1;
- tRect.right := tRect.right + 1;
- GetPenState(oldPen);
- PenSize(vlHandle^^.frameWidth, vlHandle^^.frameWidth);
- FrameRect(tRect);
- SetPenState(oldPen);
- if lSelect then
- InvertRect(tRect);
- end {if frameWidth > 0}
- else if lSelect then
- InvertRect(cRect);
- SetClip(oldClip);
- DisposeRgn(oldClip);
- RestoreFont;
- SetPort(oldPort);
- end; {if lActive}
- end; {vLDrawCell}
-
- procedure vLDraw (theCell: Cell; vlHandle: vListHandle);
- {draw the selected cell}
- {figure out where to draw the cell}
- {call listdefcon to draw cell}
- var
- cRect: Rect;
- i: Integer;
- index, dataOffset, dataLen: Integer;
- lSelect: BOOLEAN;
- begin
- {is cell visible?}
- {is drawing enabled?}
- if PtInRect(theCell, vlHandle^^.visible) and vlHandle^^.lActive then
- begin
- {create cell rectangle}
- cRect := vLCellRect(theCell, vlHandle);
- index := theCell.v * vlHandle^^.databounds.right + theCell.h; {get index into offset array}
- dataOffset := LoBits(vlHandle^^.cellArray[index]);
- dataLen := LoBits(vlHandle^^.cellArray[index + 1]) - LoBits(vlHandle^^.cellArray[index]);
- if vlHandle^^.cellArray[index] < 0 then
- lSelect := TRUE
- else
- lSelect := FALSE;
- vLDrawCell(theCell, lSelect, cRect, dataOffset, dataLen, vlHandle);
- end; {if PtInRect}
- end; { procedure vLDraw}
-
- procedure vLDrawHeading (vlHandle: vListHandle);
- {draw heading strings}
- {surround strings with a frame which is one pixel above and one pixel to the right of the text area}
- {draw a two pixel line between heading and list}
- var
- tStr1, tStr2: str255;
- i, j, k, colIndex, endIndex, index, nCol, hoffset, loffset, roffset, voffset: INTEGER;
- oldFont, oldSize: INTEGER;
- oldFace: Style;
- colWidth: WidthArray;
- tByte: Byte;
- headRect, tRect: RECT;
- begin
- if (vlHandle^^.lActive) and (vlHandle^^.nhRows > 0) then
- begin
- GetPort(oldPort);
- SetPort(vlHandle^^.port);
- GetPenState(oldPen);
- SaveFont;
- oldClip := NewRgn;
- GetClip(oldClip);
- PenSize(vlHandle^^.frameWidth, vlHandle^^.frameWidth);
- TextFont(vlHandle^^.hfont); {set font info}
- TextSize(vlHandle^^.hSize);
- TextFace(vlHandle^^.hFace);
- {erase old heading}
- headRect := vlHandle^^.rView;
- headRect.bottom := vlHandle^^.lView.top;
- headRect.right := headRect.right + 1;
- EraseRect(headRect);
- {set clip}
- headRect := CalcVisRect(vlHandle);
- headRect.bottom := headRect.top + 1; {so border lines up with scroll bar}
- headRect.top := vlHandle^^.rView.top - 1;
- headRect.right := headRect.right + 1; {so border lines up with scroll bar}
- ClipRect(headRect); {don't draw outside headRect}
- {Offset left by width of non-visible columns}
- hOffset := 0;
- for i := 1 to vlHandle^^.visible.left do
- hOffset := hOffset + vlHandle^^.cellWidth[i - 1];
- voffset := vlHandle^^.rView.top;
- {loop through rows}
- for index := 1 to vlHandle^^.nhRows do
- begin
- colIndex := 0;
- loffset := vlHandle^^.rView.left;
- tStr1 := vlHandle^^.lHead[index];
- {process heading string}
- while Length(tStr1) > 1 do
- begin
- roffset := loffset;
- tStr2 := Copy(tStr1, 1, Pos('|', tStr1) - 1); {get substring}
- tStr1 := Omit(tStr1, 1, Pos('|', tStr1)); {remove first substring}
- {strip spaces from tStr2}
- while (tStr2[1] = ' ') and (Length(tStr2) > 1) do
- tStr2 := Omit(tStr2, 1, 1); {strip leading spaces}
- endIndex := Length(tStr2);
- while (tStr2[endIndex] = ' ') and (Length(tStr2) > 1) do
- begin
- tStr2 := Omit(tStr2, endIndex, endIndex); {strip trailing spaces}
- endIndex := Length(tStr2);
- end;
- colWidth := vlHandle^^.cellWidth;
- {Print Heading[index] centered over next nCol cols}
- tByte := Byte(tStr2[1]);
- if (tByte > 48) and (tByte < 58) then {is there a number at the beginning of the string?}
- begin
- nCol := tByte - 48; {remember how many columns to center this heading over}
- tStr2 := Omit(tStr2, 1, 1); {omit the number}
- end
- else
- nCol := 1;
- for j := 1 to nCol do
- roffset := roffset + colWidth[colIndex + j - 1];
- colIndex := colIndex + nCol;
- SetRect(tRect, loffset, voffset, roffset, voffset + vlHandle^^.hCellHeight);
- OffsetRect(tRect, -hOffset, 0); {account for scrolled position}
- InsetRect(tRect, 1, 1);
- TextBox(Ptr(Ord4(@tStr2) + 1), Length(tStr2), tRect, teJustCenter); {print substring}
- if vlHandle^^.frameWidth > 0 then
- begin
- SetRect(tRect, loffset, voffset, roffset + 1, voffset + vlHandle^^.hCellHeight + 1); {add 1 to bottom and add one to right for frame}
- OffsetRect(tRect, -hOffset, 0); {account for scrolled position}
- FrameRect(tRect);
- end;
- loffset := roffset; {}
- end; {while Length ( tStr1 ) > 1}
- voffset := voffset + vlHandle^^.hCellHeight;
- end; {for index}
- {Draw line under last heading row}
- MoveTo(vlHandle^^.rView.left, vlHandle^^.lView.top - 1);
- PenSize(1, 1); {}
- LineTo(headRect.right, vlHandle^^.lView.top - 1); {}
- RestoreFont;
- SetPenState(oldPen);
- SetClip(oldClip);
- DisposeRgn(oldClip);
- SetPort(oldPort);
- end; {if active}
- end; {procedure DrawHeading}
-
- function vLEncloseSel (vlHandle: vListHandle): Rect;
- {return smallest rectangle which encloses all selected cells}
- var
- i, nCol, nRow, imax: INTEGER;
- tRect: Rect;
- begin
- nCol := vlHandle^^.databounds.right; {# columns}
- nRow := vlHandle^^.databounds.bottom; {# rows}
- imax := vlHandle^^.maxindex;
- SetRect(tRect, 0, 0, 0, 0);
- {find first selected cell}
- i := -1;
- repeat
- i := i + 1;
- until (vlHandle^^.cellArray[i] < 0) or (i > imax);
- if i <= imax then
- begin
- tRect.top := i div nCol;
- tRect.left := i - tRect.top * nCol;
- end;
- {find last selected cell}
- i := vlHandle^^.maxindex + 1;
- repeat
- i := i - 1;
- until (vlHandle^^.cellArray[i] < 0) or (i <= 0);
- if i >= 0 then
- begin
- tRect.bottom := i div nCol + 1;
- tRect.right := i - (tRect.bottom - 1) * nCol + 1;
- end;
- vLEncloseSel := tRect;
- end; { function vLEncloseSel}
-
- procedure vLFind (var offset, len: Integer; theCell: Cell; vlHandle: vListHandle);
- {returns the offset and length of theCell's data}
- {if theCell is invalid, offset and len are set to -1}
- var
- nCol, nRow, index: Integer;
- begin
- nCol := vlHandle^^.databounds.right; {# columns}
- nRow := vlHandle^^.databounds.bottom; {# rows}
- index := theCell.v * nCol + theCell.h; {get index into offset array}
- if index <= vlHandle^^.maxIndex then
- begin
- offset := LoBits(vlHandle^^.cellArray[index]);
- len := LoBits(vlHandle^^.cellArray[index + 1]) - LoBits(vlHandle^^.cellArray[index]);
- end
- else
- begin
- offset := -1;
- len := -1;
- end;
- end; {procedure vLFind}
-
- procedure vLFrame (frameWidth: INTEGER; var vlHandle: vListHandle);
- {set frame width (default = 0)}
- begin
- vlHandle^^.frameWidth := frameWidth;
- end; {}
-
- procedure vLFont (myFont, mySize: INTEGER; myFace: Style; vlHandle: vListHandle);
- {set list font info}
- begin
- vlHandle^^.lFont := myFont;
- vlHandle^^.lSize := mySize;
- vlHandle^^.lFace := myFace;
- end; {procedure vLFont}
-
- procedure vLGetCell (dataPtr: Ptr; var dataLen: Integer; theCell: Cell; vlHandle: vListHandle);
- {copy contents of cell to dataPtr}
- {if theCell is not valid return 0 for length}
- var
- nCol, nRow, cLen, offset, index: Integer;
- begin
- nCol := vlHandle^^.databounds.right; {# columns}
- nRow := vlHandle^^.databounds.bottom; {# rows}
- index := theCell.v * nCol + theCell.h; {get index into offset array}
- if index < vlHandle^^.maxIndex then {make sure we have valid cell}
- begin
- offset := LoBits(vlHandle^^.cellArray[index]);
- cLen := LoBits(vlHandle^^.cellArray[index + 1]) - LoBits(vlHandle^^.cellArray[index]);
- {make sure we don't copy too many bytes to dataPtr}
- if cLen > GetPtrSize(dataPtr) then
- dataLen := GetPtrSize(dataPtr)
- else
- dataLen := cLen;
- {rely on caller to make sure we don't copy too many bytes to dataPtr}
- dataLen := cLen;
- HLock(Handle(vlHandle^^.cells));
- BlockMove(Ptr(ORD4(vlHandle^^.cells^) + offset), dataPtr, dataLen);
- HUnLock(Handle(vlHandle^^.cells));
- end
- else
- dataLen := 0;
- end;
-
- function vLGetSelect (next: Boolean; var theCell: Cell; vlHandle: vListHandle): Boolean;
- {return select status of theCell}
- {if next is FALSE, returns True if theCell is selected}
- {if next is TRUE, returns in theCell the next selected cell (start at theCell)}
- var
- nCol, nRow, cLen, offset, index: Integer;
- treply: BOOLEAN;
- begin
- tReply := FALSE;
- vLGetSelect := FALSE;
- HLock(Handle(vlHandle));
- with vlHandle^^ do
- begin
- if next then
- begin
- nCol := databounds.right; {# columns}
- index := theCell.v * nCol + theCell.h - 1; {get index to next cell in offset array}
- while (index <= maxIndex) and (tReply = FALSE) do
- begin
- index := index + 1;
- if cellArray[index] < 0 then
- begin
- tReply := TRUE;
- theCell.v := index div nCol;
- theCell.h := index - theCell.v * nCol;
- end; {if cellArray...}
- end
- end {if next...}
- else
- begin
- nCol := databounds.right; {# columns}
- index := theCell.v * nCol + theCell.h; {get index into offset array}
- if cellArray[index] < 0 then
- tReply := TRUE
- end;
- end; {with...}
- HUnLock(Handle(vlHandle));
- vLGetSelect := tReply;
- end; {procedure vLGetSelect}
-
-
- procedure vLIndent (indent: POINT; var vlHandle: vListHandle);
- {set indentation mode (default = 0,0)}
- begin
- vlHandle^^.indent := indent;
- end; { procedure vLIndent}
-
- procedure vLInsetList (dH, dV: Integer; vlHandle: vListHandle);
- {handle change to our view rectangle}
- {keep top left of visible same}
- {calculate new visible rectangle}
- {redraw list and scrollbars}
- var
- i, j, myCtlValue, dangle: INTEGER;
- tBool: BOOLEAN;
- begin
- HLock(Handle(vlHandle));
- with vlHandle^^ do
- begin
- GetPort(oldPort);
- SetPort(port);
- EraseRect(rView);
- rView.right := rView.right - dH;
- rView.bottom := rView.bottom - dV;
- lView.right := lView.right - dH;
- lView.bottom := lView.bottom - dV;
- tBool := vlHandle^^.lActive; {save status}
- vlHandle^^.lActive := FALSE; {don't draw yet}
- {avoid problem of scroll bar staying narrow when window expanded}
- {reduce ctlvalue while keeping visible.right rightmost in lView}
- j := vlHandle^^.visible.right - 1;
- myCtlValue := GetCtlValue(vlHandle^^.hScroll);
- if vlHandle^^.hScroll <> nil then
- if (myCtlValue > 0) then
- begin
- i := CalcVisibleRight(myCtlValue, dangle, vlHandle);
- while (myCtlValue > -1) and (i >= j) do
- begin
- i := CalcVisibleRight(myCtlValue, dangle, vlHandle);
- myCtlValue := myCtlValue - 1;
- end;
- myCtlValue := myCtlValue + 1;
- end;
- SetCtlValue(vlHandle^^.hScroll, myCtlValue);
- {avoid problem of scroll bar staying short when window expanded}
- {reduce ctlvalue while keeping visible.bottom lowest in lView}
- j := vlHandle^^.visible.bottom - 1;
- myCtlValue := GetCtlValue(vlHandle^^.vScroll);
- if vlHandle^^.vScroll <> nil then
- if (myCtlValue > 0) then
- begin
- i := CalcVisibleBottom(myCtlValue, dangle, vlHandle);
- while (myCtlValue > -1) and (i >= j) do
- begin
- i := CalcVisibleBottom(myCtlValue, dangle, vlHandle);
- myCtlValue := myCtlValue - 1;
- end;
- myCtlValue := myCtlValue + 1;
- end;
- SetCtlValue(vlHandle^^.vScroll, myCtlValue);
- AdjustList(vlHandle); {calculate visible rectangle}
- vlHandle^^.lActive := tBool; {restore status}
- SetScrollMax(vlHandle);
- AdjustScrollBars(vlHandle);
- AdjustList(vlHandle); {draw cells}
- end; {with}
- SetPort(oldPort);
- HUnLock(Handle(vlHandle));
- end; {vLInsetList}
-
- procedure vLJust (just: INTEGER; var vlHandle: vListHandle);
- {set justification mode (default = teJustLeft)}
- begin
- vlHandle^^.just := just;
- end; {procedure vLJust}
-
- procedure vLKey (ch: CHAR; modifiers: Integer; vlHandle: vListHandle; vScrap: vLScrapHandle);
- {Handle a key press when our window is frontmost and list is active}
- {Determine whether key press applies to a TE or to a Cell/Cells}
- const
- tab = chr(9);
- larrow = chr(28);
- rarrow = chr(29);
- uarrow = chr(30);
- darrow = chr(31);
- del = chr(8);
- enter = chr(3);
- return = chr(13);
- var
- myPt: Point; {Point where event happened}
- theControl: ControlHandle;{Handle for a control}
- MyErr: OSErr; {OS error returned}
- dblClick: BOOLEAN;
- chCode: INTEGER;
- hNext, vNext: BOOLEAN;
- hChars: CharsHandle;
- nextCell, theCell: Cell;
- dummy: BOOLEAN;
-
- function TestMods (modifiers: INTEGER): modifierType;
- begin
- if BitAND(modifiers, cmdKey) <> 0 then
- TestMods := command;
- if BitAND(modifiers, shiftKey) <> 0 then
- TestMods := shift;
- if BitAND(modifiers, optionKey) <> 0 then
- TestMods := option;
- if BitAND(modifiers, controlKey) <> 0 then
- TestMods := control;
- end; {function TestMods}
-
- function RectSize (theRect: Rect): INTEGER;
- {return size of selection in cells}
- begin
- RectSize := (theRect.right - theRect.left) * (theRect.bottom - theRect.top);
- end; {function RectSize}
-
- function CellAction (ch: CHAR; mode: BOOLEAN): BOOLEAN;
- {determine whether to perform TE or Cell editing}
- begin
- CellAction := FALSE;
- if mode = FALSE then {if not in edit mode then must be cell editing}
- CellAction := TRUE;
- if RectSize(SelectRect) > 1 then
- CellAction := TRUE; {if more than one cell then must be cell editing}
- if (RectSize(oldSelectRect) > 1) and (RectSize(SelectRect) = 1) then
- CellAction := TRUE; {if more than one cell previously selected and one cell now selected then cell editing}
- if (vlHandle^^.listTE^^.selStart = 0) and (vlHandle^^.listTE^^.selEnd = vlHandle^^.listTE^^.teLength) then
- ch := ch;
- if (ch >= ' ') then
- CellAction := FALSE; {only do cell edit on non-printable chars}
- end; {function CellAction}
-
- procedure CopyCells (whatCells: Rect; whatList: vListHandle; whatScrap: vLScrapHandle);
- begin
- vLCellsToScrap(whatCells, whatList, whatScrap);
- end; {procedure CopyCells}
-
- procedure CutCells (whatCells: Rect; whatList: vListHandle; whatScrap: vLScrapHandle);
- var
- i, j: INTEGER;
- tCell: Cell;
- begin
- {copy selected cells}
- vLCellsToScrap(whatCells, whatList, whatScrap);
- {clear selected cells}
- for i := whatCells.top to whatCells.bottom - 1 do
- for j := whatCells.left to whatCells.right - 1 do
- begin
- SetPt(tCell, j, i);
- vLClrCell(tCell, vlHandle);
- end; {for j..}
- end; {procedure CutCells}
-
- procedure PasteCells (whatCells: Rect; whatList: vListHandle; whatScrap: vLScrapHandle);
- {copy data in the scrap to cells contained in whatCells}
- {handle selections which are not identical in size}
- var
- tRect: Rect;
- i, j, k, sourceSize, destSize: INTEGER;
- begin
- sourceSize := RectSize(whatScrap^^.scrapBounds);
- destSize := RectSize(whatCells);
- if sourceSize = destSize then
- begin
- vLScrapToCells(whatCells, whatList, whatScrap);
- end; {if sourceSize = destSize}
- if sourceSize > destSize then
- begin
- if destSize = 1 then
- {paste whole scrap starting at this cell if only one cell selected}
- {have to trick ScrapToCells by setting tRect = scrapBounds but offset to location of whatCells}
- begin
- tRect := whatScrap^^.scrapBounds;
- OffsetRect(tRect, whatCells.left - tRect.left, whatCells.top - tRect.top);
- vLScrapToCells(tRect, whatList, whatScrap);
- end
- else
- vLScrapToCells(whatCells, whatList, whatScrap);
- end; { if sourceSize > destSize}
- if sourceSize < destSize then
- begin
- if sourceSize = 1 then
- begin
- for i := whatCells.top to whatCells.bottom - 1 do
- for j := whatCells.left to whatCells.right - 1 do
- begin
- SetRect(tRect, j, i, j + 1, i + 1); {repeatedly paste source to destination cells}
- vLScrapToCells(tRect, whatList, whatScrap);
- end; {for j..}
- end {if sourceSize=1}
- else
- {'trick' ScrapToCells by setting tRect = scrapBounds but offset to location of whatCells}
- begin
- tRect := whatScrap^^.scrapBounds;
- OffsetRect(tRect, whatCells.left - tRect.left, whatCells.top - tRect.top); {align tRect to whatCells topleft}
- i := 0;
- j := whatScrap^^.scrapBounds.bottom - whatScrap^^.scrapBounds.top; {height of source}
- k := whatCells.bottom - whatCells.top;
- if j > 0 then
- while i < k do
- begin
- vLScrapToCells(tRect, whatList, whatScrap);
- OffsetRect(tRect, 0, j);
- i := i + j;
- end; {while i<k..}
- end; {sourceSize<>1}
- end; {if sourceSize < destSize}
- {adjust rectangles so that paste works}
- SelectRect := oldSelectRect;
- end; {procedure PasteCells}
-
- procedure FindNextCell (ch: CHAR);
- begin
- with vlHandle^^ do
- begin
- theCell := lastClick;
- {set up search}
- case ch of
- return:
- begin
- hNext := FALSE;
- vNext := TRUE;
- end;
- enter:
- begin
- hNext := FALSE;
- vNext := TRUE;
- end;
- darrow:
- begin
- hNext := FALSE;
- vNext := TRUE;
- end;
- rarrow:
- begin
- hNext := TRUE;
- vNext := FALSE;
- end;
- tab:
- begin
- hNext := TRUE;
- vNext := FALSE;
- end;
- uarrow:
- begin
- hNext := FALSE;
- vNext := TRUE;
- theCell.v := theCell.v - 2;
- end;
- larrow:
- begin
- hNext := TRUE;
- vNext := FALSE;
- theCell.h := theCell.h - 2;
- end;
- otherwise
- begin
- hNext := FALSE;
- vNext := FALSE;
- end;
- end; {case}
- {search}
- nextCell := theCell;
- if vLNextCell(hNext, vNext, theCell, vlHandle) = FALSE then
- begin
- {must be out of databounds}
- if nextCell.h >= databounds.right - 1 then
- begin {went off right edge}
- theCell.h := databounds.left;
- theCell.v := theCell.v + 1; {move to start of next row}
- if theCell.v > databounds.bottom - 1 then
- theCell.v := databounds.top; {if last row, go to first row}
- end
- else if nextCell.v >= databounds.bottom - 1 then
- begin {went off bottom edge}
- theCell.v := databounds.top;
- theCell.h := theCell.h + 1; {move to start of next col}
- if theCell.h > databounds.right - 1 then
- theCell.h := databounds.left; {if last col, go to first col}
- end
- else if nextCell.h < databounds.left then
- begin {went off left edge}
- theCell.h := databounds.right - 1;
- theCell.v := theCell.v - 1; {move to start of next row}
- if theCell.v < databounds.top then
- theCell.v := databounds.bottom - 1; {if last row, go to first row}
- end
- else if nextCell.v < databounds.top then
- begin {went off top edge}
- theCell.v := databounds.bottom - 1;
- theCell.h := theCell.h - 1; {move to start of next col}
- if theCell.h < databounds.left then
- theCell.h := databounds.right - 1; {if last col, go to first col}
- end;
- end; {if vLNextCell}
- oldSelectRect := SelectRect;
- SetRect(SelectRect, 0, 0, 0, 0);
- vLUpdateSelRect(SelectRect, vlHandle); {unselect all cells}
- vLSetSelect(TRUE, theCell, vlHandle); {select found cell}
- SelectRect := vLEncloseSel(vlHandle); {save selection rect}
- lastClick := theCell;
- end; {with..}
- end; {FindNextCell}
-
- procedure DoEditTE;
- {Handle keypress in editTE mode}
- begin
- with vlHandle^^ do
- begin
- if TestMods(modifiers) = command then
- begin
- {handle command keys}
- if (ch = 'x') or (ch = 'X') then
- TECut(listTE);
- if (ch = 'c') or (ch = 'C') then
- TECopy(listTE);
- if (ch = 'v') or (ch = 'V') then
- TEPaste(listTE);
- end
- else
- begin
- {handle non-command keys}
- if (ch = return) or (ch = enter) or (ch = tab) then
- begin
- StopEdit(TRUE, vLLastClick(vlHandle), vlHandle); {stop editing and save results on TAB, RETURN or ENTER}
- FindNextCell(ch);
- end {if(ch = return) or (ch = enter)..}
- else
- TEKey(ch, listTE) {pass other keys to TEDit}
- end; {non-command keys}
- end; {with}
- end; {procedure DoEditTE}
-
-
- procedure DoEditCells;
- begin
- if (TestMods(modifiers) = command) and (vScrap <> nil) then
- begin
- {handle command keys}
- SelectRect := vLEncloseSel(vlHandle); {get selection rect}
- if (ch = 'x') or (ch = 'X') then
- CutCells(SelectRect, vlHandle, vScrap);
- if (ch = 'c') or (ch = 'C') then
- CopyCells(SelectRect, vlHandle, vScrap);
- if (ch = 'v') or (ch = 'V') then
- PasteCells(SelectRect, vlHandle, vScrap);
- end {if command}
- else
- begin
- {handle non-command keys}
- if ch = del then
- vLClrCell(vlHandle^^.lastClick, vlHandle)
- else
- FindNextCell(ch);
- end; {non-command keys}
- end; {procedure DoEditCells}
-
- {START procedure vLKey}
- {need to double click in a cell to edit text}
- begin
- HLock(Handle(vlHandle));
- with vlHandle^^ do
- begin
- SelectRect := vLEncloseSel(vlHandle);
- if (listTE <> nil) and (lActiveTE) then
- if CellAction(ch, leditMode) then
- {handle editing cells}
- DoEditCells
- else
- {handle editing TE}
- DoEditTE
- else
- DoEditCells;
- end; {with vlHandle...}
- oldSelectRect := SelectRect;
- HUnLock(Handle(vlHandle));
- end; {function vLKey}
- function vLLastClick (vlHandle: vListHandle): Cell;
- {return last cell clicked in}
- begin
- vLLastClick := vlHandle^^.lastClick;
- end; { function vLLastClick}
-
- function vLNew (plView, pdatabounds: RECT; pcellSize: POINT; procID: INTEGER; theWindow: WindowPtr; drawIt, hasGrow, scrollHoriz, scrollVert: Boolean): vListHandle;
- {return a new vListHandle}
- {return nil if memory can't be allocated for the list}
- var
- MyvListh: vListHandle;
- hcntrlRect, vcntrlRect, prView, cRect: Rect;
- i, j, nVcol, nVrow: Integer;
- tBool: BOOLEAN;
- myCell: Cell;
- myFontInfo: FontInfo;
- begin
- MyvListh := vListHandle(NewHandle(SIZEOF(vListRec)));
- if MyvListh <> nil then {in case out of memory!}
- begin
- MyvListh^^.cells := DataHandle(NewHandle(SIZEOF(DataArray)));
- if MyvListh^^.cells <> nil then
- begin
- HLock(Handle(MyvListh));
-