home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 14 / CDACTUAL.iso / cdactual / demobin / share / program / Pascal / TVDMX.ZIP / TVDMXCOL.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1993-04-01  |  14.0 KB  |  517 lines

  1.  
  2. {■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■}
  3. {                            }
  4. {    tvDMXCOL  --Collection Data Editing Unit    }
  5. {    tvDMX     --data editing project        }
  6. {                            }
  7. {    Copyright (c) 1992,93   Randolph Beck        }
  8. {                P.O. Box  56-0487    }
  9. {                Orlando, FL 32856    }
  10. {                CIS:  72361,753        }
  11. {                            }
  12. {■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■}
  13.  
  14. Unit tvDMXCOL;
  15.  
  16. {$B-,D-,R-,O+,X+,V- }
  17.  
  18. interface
  19.  
  20. uses
  21.     Objects, Drivers, Memory, Views, App, MsgBox,
  22.     RSet, DmxGizma, tvDMX, StdDMX;
  23.  
  24. type
  25.     PDmxCollectView    = ^TDmxCollectView;
  26.     PDmxCollector    = ^TDmxCollector;
  27.     PDmxCollectViewWin    = ^TDmxCollectViewWin;
  28.     PDmxCollectorWin    = ^TDmxCollectorWin;
  29.  
  30.  
  31.     TDmxCollectView    =  OBJECT (TDmxScroller)
  32.       constructor Init (ATemplate : string;  var AData;
  33.             var Bounds : TRect;  ALabels : PView;
  34.             AHScrollBar,AVScrollBar : PScrollBar);
  35.       function  DataAt (RecNum : integer) : pointer;  VIRTUAL;
  36.       procedure InitData (var AData );  VIRTUAL;
  37.       function  RecordLimit : longint;  VIRTUAL;
  38.       procedure SetState (AState : word; Enable : boolean);  VIRTUAL;
  39.     end;
  40.  
  41.  
  42.     TDmxCollector    =  OBJECT (TDmxEditor)
  43.     Expandable    : boolean;
  44.     NewDataRec    : pointer;
  45.     MaxCount    : integer;
  46.     MemWarning    : boolean;
  47.       function  DataAt (RecNum : integer) : pointer;  VIRTUAL;
  48.       procedure DoneData;  VIRTUAL;
  49.       procedure EvaluateRecord;  VIRTUAL;
  50.       procedure HandleEvent (var Event : TEvent);  VIRTUAL;
  51.       procedure InitData (var AData );  VIRTUAL;
  52.       procedure InitNewDataRec;
  53.       procedure LoadStruct (var S : TStream);  VIRTUAL;
  54.       function  RecordLimit : longint;  VIRTUAL;
  55.       procedure SetState (AState : word; Enable : boolean);  VIRTUAL;
  56.       procedure SetupRecord;  VIRTUAL;
  57.       procedure StoreStruct (var S : TStream);  VIRTUAL;
  58.       function  Valid (Command : word) : boolean;  VIRTUAL;
  59.       procedure ZeroizeRecord;  VIRTUAL;
  60.     end;
  61.  
  62.  
  63.     TDmxCollectViewWin    =  OBJECT (TDmxViewer)
  64.       constructor Init (var Bounds : TRect;  ATitle : TTitleStr;
  65.             ANumber : integer;  ATemplate : string;
  66.             ACollection : PCollection;  var ALabels : string);
  67.       procedure InitDMX (ATemplate  : string;  var AData;
  68.              ALabels, ARecInd  : PDmxLink;
  69.              BSize  : longint);  VIRTUAL;
  70.     end;
  71.  
  72.  
  73.     TDmxCollectorWin    =  OBJECT (TDmxWindow)
  74.       constructor Init (var Bounds : TRect;
  75.             ATitle    : TTitleStr;  ANumber  : integer;
  76.             ATemplate : string;  ACollection : PCollection;
  77.             BSize     : integer; var ALabels : string; IndLen : integer);
  78.       procedure InitDMX (ATemplate  : string;  var AData;
  79.              ALabels, ARecInd  : PDmxLink;
  80.              BSize  : longint);  VIRTUAL;
  81.     end;
  82.  
  83.  
  84.   function  fldObjectVMT (Obj : PObject) : string;
  85.     { template prefix to generate a VMT identifier
  86.       for collections of TObject derivatives
  87.      }
  88.  
  89.   procedure ResetCollection (Collection : PCollection);
  90.     { adjust the size of the database }
  91.  
  92.  
  93.   procedure RegisterTVDMXCOL;
  94.  
  95.  
  96. const
  97.     RDmxCollectView    :  TStreamRec = (
  98.     ObjType:   rnDmxCollectView;
  99.     VmtLink:   ofs (TypeOf (TDmxCollectView)^);
  100.     Load:       @TDmxCollectView.Load;
  101.     Store:       @TDmxCollectView.Store
  102.       );
  103.  
  104.     RDmxCollector    :  TStreamRec = (
  105.     ObjType:   rnDmxCollector;
  106.     VmtLink:   ofs (TypeOf (TDmxCollector)^);
  107.     Load:       @TDmxCollector.Load;
  108.     Store:       @TDmxCollector.Store
  109.       );
  110.  
  111.     RDmxCollectViewWin    :  TStreamRec = (
  112.     ObjType:   rnDmxCollectViewWin;
  113.     VmtLink:   ofs (TypeOf (TDmxCollectViewWin)^);
  114.     Load:       @TDmxCollectViewWin.Load;
  115.     Store:       @TDmxCollectViewWin.Store
  116.       );
  117.  
  118.     RDmxCollectorWin    :  TStreamRec = (
  119.     ObjType:   rnDmxCollectorWin;
  120.     VmtLink:   ofs (TypeOf (TDmxCollectorWin)^);
  121.     Load:       @TDmxCollectorWin.Load;
  122.     Store:       @TDmxCollectorWin.Store
  123.       );
  124.  
  125.  
  126. implementation
  127.  
  128.   { ══════════════════════════════════════════════════════════════════════ }
  129.  
  130.  
  131. function  fldObjectVMT (Obj : PObject) : string;
  132. begin
  133.   fldObjectVMT := ^H^F^F'c'^V + pchar(Obj)^ + #0^H^F^F'c'^V + pstring(Obj)^[1] + #0;
  134.   Dispose (Obj, Done);
  135. end;
  136.  
  137.  
  138. procedure ResetCollection (Collection : PCollection);
  139. { adjust the size of the database }
  140. begin
  141.   Repeat
  142.   Until (Message (DeskTop, evBroadcast, cmDMX_Reset, Collection) = nil)
  143.      or (Collection^.Count > 0);
  144.   Message (DeskTop, evCommand, cmDMX_Reset, Collection);
  145. end;
  146.  
  147.  
  148.   { ══ TDmxCollectView ═══════════════════════════════════════════════════ }
  149.  
  150.  
  151. constructor TDmxCollectView.Init (ATemplate    : string;  var AData;
  152.                   var Bounds    : TRect;
  153.                   ALabels    : PView;
  154.                   AHScrollBar,AVScrollBar : PScrollBar);
  155. begin
  156.   TDmxScroller.Init (ATemplate, AData, 0, Bounds, ALabels, AHScrollBar, AVScrollBar);
  157. end;
  158.  
  159.  
  160. function  TDmxCollectView.DataAt (RecNum : integer) : pointer;
  161. begin
  162.   If (PCollection (WorkingData)^.Count <= RecNum) then
  163.     DataAt := nil
  164.    else
  165.     DataAt := PCollection (WorkingData)^.At (RecNum);
  166. end;
  167.  
  168.  
  169. procedure TDmxCollectView.InitData (var AData );
  170. begin
  171.   TDmxScroller.InitData (AData);
  172.   DataBlockSize := (RecordSize * PCollection (WorkingData)^.Count);
  173. end;
  174.  
  175.  
  176. function  TDmxCollectView.RecordLimit : longint;
  177. begin
  178.   RecordLimit := PCollection (WorkingData)^.Count
  179. end;
  180.  
  181.  
  182. procedure TDmxCollectView.SetState (AState : word; Enable : boolean);
  183. begin
  184.   If Enable and (AState = sfFocused) and
  185.     (DataBlockSize <> RecordSize * PCollection (WorkingData)^.Count) then
  186.     DataBlockSize := RecordSize * PCollection (WorkingData)^.Count;
  187.   TDmxScroller.SetState (AState, Enable);
  188. end;
  189.  
  190.  
  191.   { ══ TDmxCollector ═════════════════════════════════════════════════════ }
  192.  
  193.  
  194. function  TDmxCollector.DataAt (RecNum : integer) : pointer;
  195. { this method is called whenever it must retrieve a record,
  196.   whether it is for display purposes or for editing }
  197. begin
  198.   If (PCollection (WorkingData)^.Count <= RecNum) then
  199.     DataAt  := NewDataRec
  200.    else
  201.     DataAt  := PCollection (WorkingData)^.At (RecNum);
  202. end;
  203.  
  204.  
  205. procedure TDmxCollector.DoneData;
  206. { this method is called during termination }
  207. begin
  208.   TDmxEditor.DoneData;
  209.   If (NewDataRec <> nil) then FreeMem (NewDataRec, RecordSize);
  210. end;
  211.  
  212.  
  213. procedure TDmxCollector.EvaluateRecord;
  214. { called after each record is edited }
  215. var  P : pointer;
  216. begin
  217.   TDmxEditor.EvaluateRecord;
  218.   If RecordAltered then
  219.     begin
  220.     { If this is an old record, then we can assume that this is the
  221.       one we were editing.  Otherwise, we need to make a new one. }
  222.     If (PCollection (WorkingData)^.Count <= CurrentRecord) then
  223.       begin
  224.       { place the record into the collection }
  225.       P := NewDataRec;
  226.       PCollection (WorkingData)^.Insert (NewDataRec);
  227.  
  228.       { create a new record for NewDataRec }
  229.       GetMem (NewDataRec, RecordSize);
  230.       RecordData := NewDataRec;
  231.       TDmxEditor.ZeroizeRecord;
  232.       RecordData := P;
  233.       If ((MaxCount = 0) or (PCollection (WorkingData)^.Count < MaxCount))
  234.      and (CurrentRecord < MaxCollectionSize) then
  235.     begin
  236.     If ((MemAvail shr 4) > LowMemSize) then
  237.       begin
  238.       { increase the size of the database }
  239.       DataBlockSize := DataBlockSize + RecordSize;
  240.       SetLimit (Limit.X, DataBlockSize div RecordSize);
  241.       Expandable := TRUE;
  242.       end
  243.      else
  244.       begin
  245.       Expandable := FALSE;
  246.       If not MemWarning then
  247.         begin
  248.         MessageBox ('Too little memory to expand collection.', nil, mfError + mfOKCancel);
  249.         MemWarning := TRUE;
  250.         end;
  251.       end;
  252.     end;
  253.       end;
  254.     end;
  255. end;
  256.  
  257.  
  258. procedure TDmxCollector.HandleEvent (var Event : TEvent);
  259. var  L : longint;
  260. begin
  261.   If (Event.What and evMessage <> 0) and (Event.Command = cmDMX_Reset) and
  262.      (Event.InfoPtr = WorkingData) then
  263.     begin
  264.     DataBlockSize := RecordSize;
  265.     L := PCollection (WorkingData)^.Count;
  266.     DataBlockSize := DataBlockSize * L;
  267.     If (MaxCount = 0) or (PCollection (WorkingData)^.Count < MaxCount) then
  268.       DataBlockSize := DataBlockSize + RecordSize;
  269.     If (DataBlockSize <= 0) and (Owner <> nil) and
  270.        ((State and sfFocused = 0) or (Event.What = evCommand)) then
  271.       begin
  272.       Event.What := evCommand;
  273.       Event.Command := cmClose;
  274.       Event.InfoPtr := Owner;
  275.       end
  276.      else
  277.       begin
  278.       If RecordSelected then
  279.     begin
  280.     FieldAltered  := FALSE;
  281.     RecordAltered := FALSE;
  282.     EvaluateField;
  283.     EvaluateRecord;
  284.     If (CurrentRecord >= (DataBlockSize div RecordSize)) and
  285.        (DataBlockSize > 0) then
  286.       CurrentRecord := pred (DataBlockSize div RecordSize);
  287.     SetupRecord;
  288.     SetupField;
  289.     end;
  290.       SetLimit (Limit.X, DataBlockSize div RecordSize);
  291.       DrawView;
  292.       If (Event.What = evCommand) then ClearEvent (Event);
  293.       end;
  294.     end
  295.    else
  296.     TDmxEditor.HandleEvent (Event);
  297. end;
  298.  
  299.  
  300. procedure TDmxCollector.InitData (var AData );
  301. { this method is called during initialization }
  302. begin
  303.   TDmxEditor.InitData (AData);
  304.  
  305.   { Note that the given database size is used for max record count. }
  306.   Move (DataBlockSize, MaxCount, 2);
  307.  
  308.   DataBlockSize := (RecordSize * PCollection (WorkingData)^.Count);
  309.   If (MaxCount = 0) or (PCollection (WorkingData)^.Count < MaxCount) then
  310.     begin
  311.     DataBlockSize := DataBlockSize + RecordSize;
  312.     Expandable := TRUE;
  313.     end;
  314.  
  315.   InitNewDataRec;
  316. end;
  317.  
  318.  
  319. procedure TDmxCollector.InitNewDataRec;
  320. { initialize a temporary data object for new records }
  321. begin
  322.   If (RecordSize > 0) then
  323.     begin
  324.     GetMem (NewDataRec, RecordSize);
  325.     RecordData        := NewDataRec;
  326.     TDmxEditor.ZeroizeRecord;
  327.     RecordAltered    := FALSE;
  328.     FieldAltered    := FALSE;
  329.     end
  330.    else
  331.     NewDataRec    := nil;
  332. end;
  333.  
  334.  
  335. procedure TDmxCollector.LoadStruct (var S : TStream);
  336. begin
  337.   TDmxEditor.LoadStruct (S);
  338.   S.Read (MaxCount, sizeof (MaxCount));
  339.   InitNewDataRec;
  340. end;
  341.  
  342.  
  343. function  TDmxCollector.RecordLimit : longint;
  344. begin
  345.   RecordLimit := PCollection (WorkingData)^.Count
  346. end;
  347.  
  348.  
  349. procedure TDmxCollector.SetState (AState : word; Enable : boolean);
  350. { resets the DataBlockSize if the collection's limit has changed }
  351. begin
  352.   If Enable and (AState = sfFocused) and
  353.     (DataBlockSize <> RecordSize * succ (PCollection (WorkingData)^.Count)) then
  354.     begin
  355.     DataBlockSize := RecordSize * PCollection (WorkingData)^.Count;
  356.     If (MaxCount = 0) or (PCollection (WorkingData)^.Count < MaxCount) then
  357.       begin
  358.       DataBlockSize := DataBlockSize + RecordSize;
  359.       Expandable := TRUE;
  360.       end
  361.      else
  362.       Expandable := FALSE;
  363.     end;
  364.   TDmxEditor.SetState (AState, Enable);
  365. end;
  366.  
  367.  
  368. procedure TDmxCollector.SetupRecord;
  369. { called before each record is edited }
  370. var  P       : pointer;
  371.      DA,JA : boolean;
  372. begin
  373.   TDmxEditor.SetupRecord;
  374.   If (PCollection (WorkingData)^.Count <= CurrentRecord) then
  375.     begin
  376.     DA := DataAltered;
  377.     JA := JustAltered;
  378.     TDmxEditor.ZeroizeRecord;
  379.     RecordAltered := FALSE;
  380.     FieldAltered := FALSE;
  381.     DataAltered := DA;
  382.     JustAltered := JA;
  383.     Expandable    := TRUE;
  384.     end;
  385. end;
  386.  
  387.  
  388. procedure TDmxCollector.StoreStruct (var S : TStream);
  389. begin
  390.   TDmxEditor.StoreStruct (S);
  391.   S.Write (MaxCount, sizeof (MaxCount));
  392. end;
  393.  
  394.  
  395. function  TDmxCollector.Valid (Command : word) : boolean;
  396. var  V : boolean;
  397. begin
  398.   V := TDmxEditor.Valid (Command);
  399.   If V and (Command = cmValid) and
  400.      ((WorkingData = nil) or (DataBlockSize < RecordSize) or (RecordSize <= 0)) then
  401.     begin
  402.     MessageBox ('No data available.', nil, mfError or mfOKButton);
  403.     Valid := FALSE;
  404.     end
  405.   else
  406.   If V and (Command = cmDMX_ZeroizeRecord) and (not RecordSelected) then
  407.     Valid := FALSE
  408.   else
  409.     Valid := V;
  410. end;
  411.  
  412.  
  413. procedure TDmxCollector.ZeroizeRecord;
  414. var  RS : boolean;
  415.      E  : TEvent;
  416. begin
  417.   If Locked then Exit;
  418.   RS := RecordSelected;
  419.   If RS then
  420.     begin
  421.     EvaluateField;
  422.     EvaluateRecord;
  423.     end;
  424.   If (PCollection (WorkingData)^.Count > CurrentRecord) then
  425.     begin
  426.     PCollection (WorkingData)^.AtFree (CurrentRecord);
  427.     { adjust the size of the database }
  428.     Repeat
  429.     Until (Message (DeskTop, evBroadcast, cmDMX_Reset, WorkingData) = nil)
  430.        or (DataBlockSize > 0);
  431.     If (DataBlockSize = 0) then
  432.       begin
  433.       E.What := evCommand;
  434.       E.Command := cmClose;
  435.       E.InfoPtr := Owner;
  436.       PutEvent (E);
  437.       end;
  438.     end;
  439.   If RS then
  440.     begin
  441.     SetupRecord;
  442.     SetupField;
  443.     end;
  444. end;
  445.  
  446.  
  447.   { ══ TDmxCollectViewWin ════════════════════════════════════════════════ }
  448.  
  449.  
  450. constructor TDmxCollectViewWin.Init (var Bounds  : TRect;
  451.         ATitle    : TTitleStr;  ANumber  : integer;
  452.         ATemplate : string;  ACollection : PCollection;
  453.         var ALabels : string);
  454. begin
  455.   TDmxViewer.Init (Bounds, ATitle, ANumber, ATemplate,
  456.            ACollection^, 0, ALabels);
  457. end;
  458.  
  459.  
  460. procedure TDmxCollectViewWin.InitDMX (ATemplate  : string;  var AData;
  461.                 ALabels, ARecInd : PDmxLink;
  462.                 BSize  : longint);
  463. var  R  : TRect;
  464. begin
  465.   GetExtent (R);
  466.   R.Grow (-1,-1);
  467.   If ALabels <> nil then Inc (R.A.Y, ALabels^.Size.Y);
  468.   Insert (New (PDmxCollectView, Init (ATemplate, AData, R, ALabels,
  469.         StandardScrollBar (sbHorizontal + sbHandleKeyboard),
  470.         StandardScrollBar (sbVertical   + sbHandleKeyboard))));
  471. end;
  472.  
  473.  
  474.   { ══ TDmxCollectorWin ══════════════════════════════════════════════════ }
  475.  
  476.  
  477. constructor TDmxCollectorWin.Init (var Bounds    : TRect;
  478.         ATitle    : TTitleStr;  ANumber  : integer;
  479.         ATemplate : string;  ACollection : PCollection;
  480.         BSize      : integer; var ALabels : string; IndLen : integer);
  481. begin
  482.   TDmxWindow.Init (Bounds, ATitle, ANumber, ATemplate,
  483.            ACollection^, BSize, ALabels, IndLen);
  484. end;
  485.  
  486.  
  487. procedure TDmxCollectorWin.InitDMX (ATemplate  : string;  var AData;
  488.             ALabels, ARecInd : PDmxLink;  BSize  : longint);
  489. var  R  : TRect;
  490. begin
  491.   GetExtent (R);
  492.   R.Grow (-1,-1);
  493.   If ALabels <> nil then Inc (R.A.Y, ALabels^.Size.Y);
  494.   Insert (New (PDmxCollector, Init (ATemplate, AData, BSize, R,
  495.         ALabels, ARecInd,
  496.         StandardScrollBar (sbHorizontal + sbHandleKeyboard),
  497.         StandardScrollBar (sbVertical   + sbHandleKeyboard))));
  498. end;
  499.  
  500.  
  501.   { ══════════════════════════════════════════════════════════════════════ }
  502.  
  503.  
  504. procedure RegisterTVDMXCOL;
  505. begin
  506.   RegisterType (RDmxCollectView);
  507.   RegisterType (RDmxCollector);
  508.   RegisterType (RDmxCollectViewWin);
  509.   RegisterType (RDmxCollectorWin);
  510. end;
  511.  
  512.  
  513.   { ══════════════════════════════════════════════════════════════════════ }
  514.  
  515.  
  516. End.
  517.