source: cprs/branches/GUI-config/backups/8-23-08/MainU.~pas@ 476

Last change on this file since 476 was 476, checked in by Kevin Toppenberg, 16 years ago

New WorldVistA Config Utility

File size: 78.4 KB
Line 
1unit MainU;
2
3 (*
4 WorldVistA Configuration Utility
5 (c) 8/2008 Kevin Toppenberg
6 Programmed by Kevin Toppenberg, Eddie Hagood
7
8 Family Physicians of Greeneville, PC
9 1410 Tusculum Blvd, Suite 2600
10 Greeneville, TN 37745
11 kdtop@yahoo.com
12
13 This library is free software; you can redistribute it and/or
14 modify it under the terms of the GNU Lesser General Public
15 License as published by the Free Software Foundation; either
16 version 2.1 of the License, or (at your option) any later version.
17
18 This library is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 Lesser General Public License for more details.
22
23 You should have received a copy of the GNU Lesser General Public
24 License along with this library; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 *)
27
28interface
29
30uses
31 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
32 Dialogs, StdCtrls, StrUtils,
33 ORNet, ORFn, ComCtrls, ToolWin, Grids, ORCtrls, ExtCtrls, Buttons,
34 AppEvnts, Menus, ImgList,
35 {$IFDEF USE_SKINS}
36 ipSkinManager,
37 {$ENDIF}
38 ValEdit;
39
40type
41 tFileEntry = record
42 Field : string;
43 FileNum : string;
44 FieldName : String;
45 IENS : string;
46 oldValue,newValue : string;
47 end;
48
49 TGridInfo = class; //forward declaration
50 TGridDataLoader = procedure (GridInfo: TGridInfo) of object;
51 TGridInfo = class (TObject)
52 public
53 Grid : TStringGrid; //doesn't own object
54 FileNum : string;
55 IENS : string;
56 BasicMode : Boolean;
57 Data : TStringList; //doesn't own object
58 Message : string; //optional text.
59 DataLoadProc : TGridDataLoader;
60 ApplyBtn : TButton;
61 RevertBtn : TButton;
62 end;
63
64
65 TMainForm = class(TForm)
66 PageControl: TPageControl;
67 tsUsers: TTabSheet;
68 UsersTreeView: TTreeView;
69 UserPageControl: TPageControl;
70 tsBasicPage: TTabSheet;
71 tsAdvancedPage: TTabSheet;
72 RightPanel: TPanel;
73 ButtonPanel: TPanel;
74 btnUsersApply: TBitBtn;
75 btnUsersRevert: TBitBtn;
76 LeftPanel: TPanel;
77 Splitter1: TSplitter;
78 Panel5: TPanel;
79 ApplicationEvents: TApplicationEvents;
80 AdvancedUsersGrid: TStringGrid;
81 BasicUsersGrid: TStringGrid;
82 MainMenu: TMainMenu;
83 File1: TMenuItem;
84 Exit1: TMenuItem;
85 AboutMenu: TMenuItem;
86 CloneBtn: TBitBtn;
87 ImageList1: TImageList;
88 tsSettings: TTabSheet;
89 Panel1: TPanel;
90 Panel2: TPanel;
91 SettingsPageControl: TPageControl;
92 tsBasicSettings: TTabSheet;
93 BasicSettingsGrid: TStringGrid;
94 tsAdvancedSettings: TTabSheet;
95 AdvancedSettingsGrid: TStringGrid;
96 Panel3: TPanel;
97 btnSettingsApply: TBitBtn;
98 btnSettingsRevert: TBitBtn;
99 Panel4: TPanel;
100 SettingsTreeView: TTreeView;
101 Panel6: TPanel;
102 Splitter2: TSplitter;
103 tsPatients: TTabSheet;
104 Panel7: TPanel;
105 Splitter3: TSplitter;
106 Panel8: TPanel;
107 PatientsPageControl: TPageControl;
108 tsBasicPatients: TTabSheet;
109 BasicPatientGrid: TStringGrid;
110 tsAdvancedPatients: TTabSheet;
111 AdvancedPatientGrid: TStringGrid;
112 Panel9: TPanel;
113 btnPatientApply: TBitBtn;
114 btnPatientRevert: TBitBtn;
115 Panel10: TPanel;
116 Panel11: TPanel;
117 AddBtn: TBitBtn;
118 PatientORComboBox: TORComboBox;
119 tsAdvanced: TTabSheet;
120 Panel12: TPanel;
121 Splitter4: TSplitter;
122 RtAdvPanel: TPanel;
123 AnyFilePageControl: TPageControl;
124 TabSheet2: TTabSheet;
125 AnyFileGrid: TStringGrid;
126 Panel14: TPanel;
127 btnAdvancedApply: TBitBtn;
128 btnAdvancedRevert: TBitBtn;
129 LeftAdvPanel: TPanel;
130 BotLeftAdvBtnPanel: TPanel;
131 btnAddAnyRecord: TBitBtn;
132 FileORComboBox: TORComboBox;
133 Label1: TLabel;
134 RecordORComboBox: TORComboBox;
135 Label2: TLabel;
136 TopLeftAdvPanel: TPanel;
137 BotLeftAdvPanel: TPanel;
138 Splitter5: TSplitter;
139 Panel13: TPanel;
140 btnBatchAdd: TBitBtn;
141 procedure GridSetEditText(Sender: TObject; ACol, ARow: Integer; const Value: String);
142 procedure GridSelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);
143 procedure FormDestroy(Sender: TObject);
144 procedure UsersTreeViewChanging(Sender: TObject; Node: TTreeNode; var AllowChange: Boolean);
145 procedure UsersTreeViewChange(Sender: TObject; Node: TTreeNode);
146 procedure Button1Click(Sender: TObject);
147 procedure btnUsersRevertClick(Sender: TObject);
148 procedure btnUsersApplyClick(Sender: TObject);
149 procedure FormClose(Sender: TObject; var Action: TCloseAction);
150 procedure Exit1Click(Sender: TObject);
151 procedure UserPageControlDrawTab(Control: TCustomTabControl; TabIndex: Integer; const Rect: TRect; Active: Boolean);
152 procedure AboutMenuClick(Sender: TObject);
153 procedure CloneBtnClick(Sender: TObject);
154 procedure ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
155 procedure ApplicationEventsShowHint(var HintStr: String; var CanShow: Boolean; var HintInfo: THintInfo);
156 procedure SettingsTreeViewChange(Sender: TObject; Node: TTreeNode);
157 procedure SettingsTreeViewChanging(Sender: TObject; Node: TTreeNode; var AllowChange: Boolean);
158 procedure BasicSettingsGridSetEditText(Sender: TObject; ACol, ARow: Integer; const Value: String);
159 procedure PageControlChanging(Sender: TObject; var AllowChange: Boolean);
160 procedure UserPageControlChanging(Sender: TObject; var AllowChange: Boolean);
161 procedure PatientORComboBoxNeedData(Sender: TObject; const StartFrom: String; Direction, InsertAt: Integer);
162 procedure PageControlChange(Sender: TObject);
163 procedure PatientORComboBoxClick(Sender: TObject);
164 procedure PatientsPageControlChanging(Sender: TObject; var AllowChange: Boolean);
165 procedure SettingsPageControlChanging(Sender: TObject; var AllowChange: Boolean);
166 procedure PatientsPageControlChange(Sender: TObject);
167 procedure SettingsPageControlChange(Sender: TObject);
168 procedure UserPageControlChange(Sender: TObject);
169 procedure FileORComboBoxNeedData(Sender: TObject; const StartFrom: String; Direction, InsertAt: Integer);
170 procedure FileORComboBoxClick(Sender: TObject);
171 procedure RecordORComboBoxNeedData(Sender: TObject; const StartFrom: String; Direction, InsertAt: Integer);
172 procedure RecordORComboBoxClick(Sender: TObject);
173 procedure btnAddAnyRecordClick(Sender: TObject);
174 procedure AddBtnClick(Sender: TObject);
175 procedure btnAdvancedApplyClick(Sender: TObject);
176 procedure btnAdvancedRevertClick(Sender: TObject);
177 procedure AnyFileGridClick(Sender: TObject);
178 procedure btnBatchAddClick(Sender: TObject);
179 procedure ChangeSkinClick(Sender: TObject);
180 procedure btnPatientApplyClick(Sender: TObject);
181 procedure btnPatientRevertClick(Sender: TObject);
182 procedure BasicPatientGridClick(Sender: TObject);
183 procedure ApplicationEventsException(Sender: TObject; E: Exception);
184 procedure btnSettingsRevertClick(Sender: TObject);
185 procedure btnSettingsApplyClick(Sender: TObject);
186 private
187 { Private declarations }
188 CurrentUserData : TStringList;
189 CurrentSettingsData : TStringList;
190 CurrentPatientData : TStringList;
191 CurrentAnyFileData : TStringList;
192 BasicTemplate : TStringList;
193 AllUsers : TTreeNode;
194 AllSettings : TTreeNode;
195 ActiveUsers : TTreeNode;
196 InactiveUsers : TTreeNode;
197 SettingsFiles : TStringList;
198 KernelSysParams : TTreeNode;
199 HospLoc : TTreeNode;
200 RPCBrokerParams : TTreeNode;
201 Devices : TTreeNode;
202 FLastSelectedRow,FLastSelectedCol : integer;
203 FLoadingGrid: boolean;
204 DataForGrid : TStringList; // doesn't own TGridInfo objects
205 CachedHelp : TStringList;
206 CachedHelpIdx : TStringList;
207 CachedWPField : TStringList;
208 FVisibleGridIdx : integer;
209 function GetCurrentUserName : string;
210 procedure SetCursorImage(Cursor : TCursor);
211 function FileNumForSettingsNode (Node : TTreeNode) : string;
212 function GetVisibleGrid: TStringGrid;
213 function GetVisibleGridInfo : TGridInfo;
214 function GetInfoForGrid(Grid : TStringGrid) : TGridInfo;
215 function GetInfoIndexForGrid(Grid : TStringGrid) : integer;
216 procedure SetVisibleGridIdx(Grid : TStringGrid);
217 procedure GetUsersList(UsersList : TStringList; HideInactive: boolean);
218 procedure GetRecordsList(RecordsList : TStringList; FileNum : string);
219 procedure InitializeUsersTreeView;
220 procedure InitializeSettingsFilesTreeView;
221 procedure InitUsersStuff;
222 procedure InitSettingsFilesStuff;
223 Procedure LoadUsersTreeView(UsersList : TStringList);
224 Procedure LoadSettingsTreeView(RecordsList : TStringList;DestNode : TTreeNode);
225 //procedure LoadUserData(IENS : String; Data : TStringList);
226 procedure LoadUserData(GridInfo : TGridInfo);
227 //procedure GetSettingsInfo(FileNum : String; IENS : String; Data : TStringList);
228 procedure GetSettingsInfo(GridInfo : TGridInfo);
229 procedure GetPatientInfo(GridInfo : TGridInfo);
230 //procedure GetPatientInfo(IENS : String; Data : TStringList);
231 procedure GetAnyfileInfo(GridInfo : TGridInfo);
232 //procedure GetAnyfileInfo(FileNum : String; IENS : String; Data : TStringList);
233 function FindInStrings(fieldNum : string; Strings : TStringList; var fileNum : string) : integer;
234 procedure CompileChanges(Grid : TStringGrid; CurrentUserData,Changes : TStringList);
235 function PostChanges(Grid : TStringGrid) : TModalResult;
236 function PostVisibleGrid: TModalResult;
237 procedure LoadAnyGrid(Grid : TStringGrid; BasicMode: boolean; FileNum,IENS : string; CurrentData : TStringList);
238 function DisuserChanged(Changes: TStringList) : boolean;
239 procedure DrawTab(Control: TCustomTabControl; TabIndex: Integer; const Rect: TRect; Active: Boolean);
240 function DoCloneRecord(FileNum, SourceIENS, New01Field : String) : string;
241 function DoCloneUser(SourceIENS, New01Field : String) : string;
242 function GetGridHint(Grid : TStringGrid; FileNum : string; ACol, ARow : integer) : string;
243 function FieldHelp(FileNum, FieldNum, HelpStyle : string) : string;
244 procedure DoRevert(BasicGrid,AdvancedGrid : TStringGrid);
245 public
246 { Public declarations }
247 CurrentUserName: string;
248 LastSelTreeNode : TTreeNode;
249 function GetUserLine(CurrentUserData : TStringList; Grid : TStringGrid; ARow:integer) :integer;
250 function GetLineInfo(Grid : TStringGrid; CurrentUserData : TStringList; ARow: integer) : tFileEntry;
251 function IsSubFile(FieldDef: string ; var SubFileNum : string) : boolean;
252 function IsWPField(FileNum,FieldNum : string) : boolean;
253 function ExtractNum (S : String; StartPos : integer) : string;
254 procedure Initialize;
255 procedure InitORComboBox(ORComboBox: TORComboBox; initValue : string);
256 Procedure GetBlankFileInfo(FileNum : string; BlankList : TStringList);
257 procedure GetOneRecord(FileNum, IENS : string; Data, BlankFileInfo : TStringList);
258 procedure AddGridInfo(Grid: TStringGrid; Data : TStringList; BasicMode : boolean;
259 DataLoader : TGridDataLoader; FileNum : string;
260 ApplyBtn,RevertBtn : TButton);
261 procedure LoadAnyGridFromInfo(GridInfo : TGridInfo);
262 procedure ClearGrid(Grid : TStringGrid);
263 procedure RegisterGridInfo(GridInfo : TGridInfo);
264 procedure UnRegisterGridInfo(GridInfo : TGridInfo);
265 end;
266
267var
268 MainForm: TMainForm;
269
270Const
271 DEF_GRID_ROW_HEIGHT = 17;
272 CLICK_FOR_SUBS = '<CLICK for Sub-Entries>';
273 COMPUTED_FIELD = '<Computed Field --> CAN''T EDIT>';
274 CLICK_TO_EDIT = '<CLICK to Edit Text>';
275 HIDDEN_FIELD = '<Hidden>';
276
277implementation
278
279uses
280 frmSplash, Trpcb , LookupU, SubfilesU, SetSelU, SelDateTimeU, PostU,
281 FMErrorU, AboutU, PleaseWaitU, EditTextU, CreateTemplateU, SkinFormU,
282 BatchAddU;
283
284{$R *.dfm}
285const
286 RPC_CONTEXT = 'TMG RPC CONTEXT GUI_CONFIG';
287
288 procedure TMainForm.Initialize;
289 var tempMenu,tempSubMenu : TMenuItem;
290 begin
291 {$IFDEF USE_SKINS}
292 tempMenu := TMenuItem.Create(MainMenu);
293 tempMenu.Caption := '&Appearance';
294 tempSubMenu := TMenuItem.Create(tempMenu);
295 tempSubMenu.Caption := '&Change Skin';
296 tempSubMenu.OnClick := ChangeSkinClick;
297 tempMenu.Add(tempSubMenu);
298 MainMenu.Items.Add(tempMenu);
299 {$ENDIF}
300
301 SplashForm.show;
302
303 FLoadingGrid := false;
304 SettingsFiles := TStringList.Create;
305 CurrentUserData := TStringList.create;
306 CurrentSettingsData := TStringList.Create;
307 CurrentPatientData := TStringList.Create;
308 CurrentAnyFileData := TStringList.Create;
309
310 DataForGrid := TStringList.Create; //will own GridInfo objects.
311 CachedHelp := TStringList.Create;
312 CachedHelpIdx := TStringList.Create;
313 CachedWPField := TStringList.Create;
314
315 AddGridInfo(BasicUsersGrid,CurrentUserData,true,LoadUserData,'200',btnUsersApply,btnUsersRevert);
316 AddGridInfo(AdvancedUsersGrid,CurrentUserData,false,LoadUserData,'200',btnUsersApply,btnUsersRevert);
317 AddGridInfo(BasicSettingsGrid,CurrentSettingsData,true,GetSettingsInfo,'',btnSettingsApply,btnSettingsRevert);
318 AddGridInfo(AdvancedSettingsGrid,CurrentSettingsData,false,GetSettingsInfo,'',btnSettingsApply,btnSettingsRevert);
319 AddGridInfo(BasicPatientGrid,CurrentPatientData,true,GetPatientInfo,'2',btnPatientApply,btnPatientRevert);
320 AddGridInfo(AdvancedPatientGrid,CurrentPatientData,false,GetPatientInfo,'2',btnPatientApply,btnPatientRevert);
321 AddGridInfo(AnyFileGrid,CurrentAnyFileData,false,GetAnyFileInfo,'',btnAdvancedApply,btnAdvancedRevert);
322
323 MainForm.Visible := false;
324 if not ORNet.ConnectToServer(RPC_CONTEXT) then begin
325 Close;
326 Exit;
327 end;
328 Application.ProcessMessages;
329 LastSelTreeNode := nil;
330 RPCBrokerV.ClearParameters := true;
331 BasicTemplate := TStringList.create;
332 BasicTemplate.Sorted := false;
333
334 InitORCombobox(PatientORComboBox,'A');
335 InitORCombobox(FileORComboBox,'A');
336
337 InitUsersStuff;
338 InitSettingsFilesStuff;
339 CurrentUserName := GetCurrentUserName;
340
341 PageControl.ActivePage := tsUsers;
342 UserPageControl.ActivePage := tsBasicPage;
343 SettingsPageControl.ActivePage := tsBasicSettings;
344
345 PageControlChange(nil); //ensure VisibleGridIdx is initialized.
346
347 {$IFDEF USE_SKINS}
348 if SkinForm.cbSkinAtStartup.Checked then begin
349 SkinForm.ActivateCurrentSkin;
350 end;
351 {$ENDIF}
352
353 self.Visible := true;
354 SplashForm.Hide;
355 end;
356
357 procedure TMainForm.AddGridInfo(Grid: TStringGrid;
358 Data : TStringList;
359 BasicMode : boolean;
360 DataLoader : TGridDataLoader;
361 FileNum : string;
362 ApplyBtn,RevertBtn : TButton );
363 var tempGridInfo : TGridInfo;
364 begin
365 tempGridInfo := TGridInfo.Create;
366 tempGridInfo.Grid := Grid;
367 tempGridInfo.Data := Data;
368 tempGridInfo.BasicMode := BasicMode;
369 tempGridInfo.FileNum := FileNum;
370 tempGridInfo.DataLoadProc := DataLoader;
371 RegisterGridInfo(tempGridInfo);
372 end;
373
374 procedure TMainForm.RegisterGridInfo(GridInfo : TGridInfo);
375 var s : string;
376 begin
377 if GridInfo = nil then exit;
378 s := IntToStr(integer(GridInfo.Grid));
379 DataForGrid.AddObject(s,GridInfo);
380 end;
381
382 procedure TMainForm.UnRegisterGridInfo(GridInfo : TGridInfo);
383 var s : string;
384 i : integer;
385 begin
386 if GridInfo = nil then exit;
387 s := IntToStr(integer(GridInfo.Grid));
388 i := DataForGrid.IndexOf(s);
389 if i > -1 then DataForGrid.Delete(i);
390 end;
391
392 function TMainForm.GetCurrentUserName : string;
393 var RPCResult : string;
394 begin
395 RPCBrokerV.remoteprocedure := 'TMG CHANNEL';
396 RPCBrokerV.param[0].ptype := list;
397 RPCBrokerV.Param[0].Mult['"REQUEST"'] := 'GET CURRENT USER NAME';
398 RPCBrokerV.Call;
399 RPCResult := RPCBrokerV.Results[0]; //returns: error: -1; success=1
400 if piece(RPCResult,'^',1)='-1' then begin
401 CurrentUserName := '';
402 FMErrorForm.Memo.Lines.Assign(RPCBrokerV.Results);
403 FMErrorForm.PrepMessage;
404 FMErrorForm.ShowModal;
405 end else begin
406 result := piece(RPCResult,'^',3);
407 end;
408 end;
409
410 procedure TMainForm.GetUsersList(UsersList : TStringList; HideInactive: boolean);
411 var RPCResult : string;
412 begin
413 UsersList.Clear;
414 RPCBrokerV.remoteprocedure := 'TMG CHANNEL';
415 RPCBrokerV.Param[0].Value := '.X'; // not used
416 RPCBrokerV.param[0].ptype := list;
417 RPCBrokerV.Param[0].Mult['"REQUEST"'] := 'GET USER LIST';
418 RPCBrokerV.Call;
419 RPCResult := RPCBrokerV.Results[0]; //returns: error: -1; success=1
420 if piece(RPCResult,'^',1)='-1' then begin
421 FMErrorForm.Memo.Lines.Assign(RPCBrokerV.Results);
422 FMErrorForm.PrepMessage;
423 FMErrorForm.ShowModal;
424 end else begin
425 UsersList.Assign(RPCBrokerV.Results);
426 end;
427 end;
428
429 procedure TMainForm.GetRecordsList(RecordsList : TStringList; FileNum : string);
430 //Format of Records list:
431 // .01Value^IEN^FileNum
432 // .01Value^IEN^FileNum
433 var RPCResult : string;
434 begin
435 RecordsList.Clear;
436 RPCBrokerV.remoteprocedure := 'TMG CHANNEL';
437 RPCBrokerV.param[0].ptype := list;
438 RPCBrokerV.Param[0].Mult['"REQUEST"'] := 'GET RECORDS LIST^' + FileNum;
439 RPCBrokerV.Call;
440 RPCResult := RPCBrokerV.Results[0]; //returns: error: -1; success=1
441 if piece(RPCResult,'^',1)='-1' then begin
442 FMErrorForm.Memo.Lines.Assign(RPCBrokerV.Results);
443 FMErrorForm.PrepMessage;
444 FMErrorForm.ShowModal;
445 end else begin
446 RecordsList.Assign(RPCBrokerV.Results);
447 end;
448 end;
449
450 Procedure TMainForm.LoadUsersTreeView(UsersList : TStringList);
451 //UsersList Format:
452 // Name^IEN^FileNum^Disuser(1 or 0)
453 // Name^IEN^FileNum^Disuser(1 or 0)
454
455 procedure AddChild(Parent : TTreeNode; Name : string;IEN : longInt);
456 var Node : TTreeNode;
457 begin
458 Node := UsersTreeView.Items.AddChildObject(Parent,Name,pointer(IEN));
459 if Parent=InactiveUsers then begin
460 Node.ImageIndex := 1;
461 Node.SelectedIndex := 4;
462 end else begin
463 Node.ImageIndex := 0;
464 Node.SelectedIndex := 5;
465 end;
466 end;
467
468 var i : integer;
469 oneEntry,Name,IENStr,inactive : string;
470 IEN : longInt;
471 begin
472 for i := 1 to UsersList.Count-1 do begin
473 oneEntry := UsersList.Strings[i];
474 Name := Piece(oneEntry,'^',1);
475 IENStr := Piece(oneEntry,'^',2);
476 inactive := Piece(oneEntry,'^',4);
477 if (Pos('.',IENStr)=0) then begin
478 IEN := StrToInt(IENStr);
479 if (inactive='1') then begin
480 AddChild(InactiveUsers,Name,IEN)
481 end else begin
482 AddChild(ActiveUsers,Name,IEN)
483 end;
484 end;
485 end;
486 End;
487
488
489 Procedure TMainForm.LoadSettingsTreeView(RecordsList : TStringList;DestNode : TTreeNode);
490 //RecordsList Format:
491 // .01Value^IEN^FileNum
492 // .01Value^IEN^FileNum
493 //Note: Will ADD into tree view, leaving prior entries intact
494
495 var i : integer;
496 oneEntry,Name,IENStr : string;
497 IEN : longInt;
498 Node: TTreeNode;
499 begin
500 for i := 1 to RecordsList.Count-1 do begin
501 oneEntry := RecordsList.Strings[i];
502 Name := Piece(oneEntry,'^',1);
503 IENStr := Piece(oneEntry,'^',2);
504 IEN := StrToInt(IENStr);
505 Node := UsersTreeView.Items.AddChildObject(DestNode,Name,pointer(IEN));
506 Node.ImageIndex := 9; //change later for icon
507 Node.SelectedIndex := 10; //change later for icon
508 end;
509 End;
510
511
512 procedure TMainForm.InitUsersStuff;
513 begin
514 BasicTemplate.Add('200^.01'); //Name
515 BasicTemplate.Add('200^1'); //initials
516 BasicTemplate.Add('200^13'); //Nickname
517 BasicTemplate.Add('200^10.6'); //Degree
518 BasicTemplate.Add('200^53.2'); //DEA#
519 BasicTemplate.Add('200^2'); //Access Code
520 BasicTemplate.Add('200^11'); //Verify Code
521 BasicTemplate.Add('200^7'); //DISUSER
522 BasicTemplate.Add('200^20.2'); //Signature block printed name
523 BasicTemplate.Add('200^20.3'); //Signature block title
524 BasicTemplate.Add('200^20.4'); //Electronic signature code
525 BasicTemplate.Add('200^51'); //Keys
526 BasicTemplate.Add('200^8932.1');//Person class
527 BasicTemplate.Add('200^53.5'); //Provider class
528 BasicTemplate.Add('200^53.7'); //Requires cosigner
529 BasicTemplate.Add('200^53.8'); //Usually cosigner
530 BasicTemplate.Add('200^101.13'); //CPRS TAb
531 BasicTemplate.Add('200^200.1');//Timed read #sec
532 BasicTemplate.Add('200^201'); //Primary menu option
533 InitializeUsersTreeView;
534 end;
535
536 procedure TMainForm.InitSettingsFilesStuff;
537 begin
538 // -- KERNEL SYSTEM PARAMETERS
539 BasicTemplate.Add('8989.3^.01'); // DOMAIN NAME
540 BasicTemplate.Add('8989.3^202'); // DEFAULT # OF ATTEMPTS
541 BasicTemplate.Add('8989.3^203'); // DEFAULT LOCK-OUT TIME
542 BasicTemplate.Add('8989.3^204'); // DEFAULT MULTIPLE SIGN-ON
543 BasicTemplate.Add('8989.3^205'); // ASK DEVICE TYPE AT SIGN-ON
544 BasicTemplate.Add('8989.3^206'); // DEFAULT AUTO-MENU
545 BasicTemplate.Add('8989.3^207'); // DEFAULT LANGUAGE
546 BasicTemplate.Add('8989.3^209'); // DEFAULT TYPE-AHEAD
547 BasicTemplate.Add('8989.3^210'); // DEFAULT TIMED-READ (SECONDS)
548 BasicTemplate.Add('8989.3^214'); // LIFETIME OF VERIFY CODE
549 BasicTemplate.Add('8989.3^217'); // DEFAULT INSTITUTION
550 BasicTemplate.Add('8989.3^218'); // DEFAULT AUTO SIGN-ON
551 BasicTemplate.Add('8989.3^219'); // DEFAULT MULTIPLE SIGN-ON LIMIT
552 BasicTemplate.Add('8989.3^230'); // BROKER ACTIVITY TIMEOUT
553 BasicTemplate.Add('8989.3^240'); // INTRO MESSAGE
554 BasicTemplate.Add('8989.3^245'); // POST SIGN-IN MESSAGE
555 BasicTemplate.Add('8989.3^320'); // DEFAULT DIRECTORY FOR HFS
556 BasicTemplate.Add('8989.3^501'); // PRODUCTION account
557
558 // -- HOSPITAL LOCATION
559 BasicTemplate.Add('44^.01'); // NAME
560 BasicTemplate.Add('44^1'); // ABBREVIATION
561 BasicTemplate.Add('44^2'); // TYPE
562 BasicTemplate.Add('44^2.1'); // TYPE EXTENSION
563 BasicTemplate.Add('44^3'); // INSTITUTION
564 BasicTemplate.Add('44^3.5'); // DIVISION
565 BasicTemplate.Add('44^5'); // DEFAULT DEVICE
566 BasicTemplate.Add('44^9'); // SERVICE
567 BasicTemplate.Add('44^9.5'); // TREATING SPECIALTY
568 BasicTemplate.Add('44^10'); // PHYSICAL LOCATION
569 BasicTemplate.Add('44^15'); // CATEGORY OF VISIT
570 BasicTemplate.Add('44^16'); // DEFAULT PROVIDER
571 BasicTemplate.Add('44^23'); // AGENCY
572 BasicTemplate.Add('44^29'); // CLINIC SERVICES RESOURCE
573 BasicTemplate.Add('44^99'); // TELEPHONE
574 BasicTemplate.Add('44^101'); // ASSOCIATED LOCATION TYPES
575 BasicTemplate.Add('44^1916'); // PRINCIPAL CLINIC
576 BasicTemplate.Add('44^2505'); // INACTIVATE DATE
577 BasicTemplate.Add('44^2506'); // REACTIVATE DATE
578 BasicTemplate.Add('44^2507'); // DEFAULT APPOINTMENT TYPE
579 BasicTemplate.Add('44^2508'); // NO SHOW LETTER
580 BasicTemplate.Add('44^2509'); // PRE-APPOINTMENT LETTER
581 BasicTemplate.Add('44^2510'); // CLINIC CANCELLATION LETTER
582 BasicTemplate.Add('44^2511'); // APPT. CANCELLATION LETTER
583 BasicTemplate.Add('44^2600'); // PROVIDER
584 BasicTemplate.Add('44^2700'); // DIAGNOSIS
585 BasicTemplate.Add('44^2801'); // DEFAULT TO PC PRACTITIONER?
586
587 // -- RPC BROKER SITE PARAMETERS
588 BasicTemplate.Add('8994.1^.01'); // DOMAIN NAME
589 BasicTemplate.Add('8994.1^2'); // MAIL GROUP FOR ALERTS
590 BasicTemplate.Add('8994.1^7'); // LISTENER
591
592 // -- DEVICE file
593 BasicTemplate.Add('3.5^.01'); // NAME
594 BasicTemplate.Add('3.5^.02'); // LOCATION OF TERMINAL
595 BasicTemplate.Add('3.5^.03'); // MNEMONIC
596 BasicTemplate.Add('3.5^.04'); // LOCAL SYNONYM
597 BasicTemplate.Add('3.5^1'); // $I
598 BasicTemplate.Add('3.5^1.95'); // SIGN-ON/SYSTEM DEVICE
599 BasicTemplate.Add('3.5^2'); // TYPE
600 BasicTemplate.Add('3.5^3'); // SUBTYPE
601 BasicTemplate.Add('3.5^5.5'); // QUEUING
602 BasicTemplate.Add('3.5^6'); // OUT-OF-SERVICE DATE
603 BasicTemplate.Add('3.5^7'); // NEAREST PHONE
604 BasicTemplate.Add('3.5^8'); // KEY OPERATOR
605 BasicTemplate.Add('3.5^9'); // MARGIN WIDTH
606 BasicTemplate.Add('3.5^11'); // PAGE LENGTH
607 BasicTemplate.Add('3.5^16'); // CLOSEST PRINTER
608 BasicTemplate.Add('3.5^19'); // OPEN PARAMETERS
609 BasicTemplate.Add('3.5^19.3'); // CLOSE PARAMETERS
610 BasicTemplate.Add('3.5^19.5'); // USE PARAMETERS
611 BasicTemplate.Add('3.5^19.7'); // PRE-OPEN EXECUTE
612 BasicTemplate.Add('3.5^19.8'); // POST-CLOSE EXECUTE
613 BasicTemplate.Add('3.5^27'); // PASSWORD
614 BasicTemplate.Add('3.5^51.5'); // ASK DEVICE TYPE AT SIGN-ON
615 BasicTemplate.Add('3.5^51.6'); // AUTO MENU
616 BasicTemplate.Add('3.5^51.9'); // TYPE-AHEAD
617
618 // -- PATIENT file
619 BasicTemplate.Add('2^.01'); // NAME
620 BasicTemplate.Add('2^.02'); // SEX
621 BasicTemplate.Add('2^.03'); // DATE OF BIRTH
622 BasicTemplate.Add('2^.05'); // MARITAL STATUS
623 BasicTemplate.Add('2^.06'); // RACE
624 BasicTemplate.Add('2^.07'); // OCCUPATION
625 BasicTemplate.Add('2^.08'); // RELIGIOUS PREFERENCE
626 BasicTemplate.Add('2^.09'); // SOCIAL SECURITY NUMBER
627 BasicTemplate.Add('2^.091'); // REMARKS
628 BasicTemplate.Add('2^.092'); // PLACE OF BIRTH [CITY]
629 BasicTemplate.Add('2^.093'); // PLACE OF BIRTH [STATE]
630 BasicTemplate.Add('2^.096'); // WHO ENTERED PATIENT
631 BasicTemplate.Add('2^.097'); // DATE ENTERED INTO FILE
632 BasicTemplate.Add('2^.098'); // HOW WAS PATIENT ENTERED?
633 BasicTemplate.Add('2^.103'); // TREATING SPECIALTY
634 BasicTemplate.Add('2^.104'); // PROVIDER
635 BasicTemplate.Add('2^.1041'); // ATTENDING PHYSICIAN
636 BasicTemplate.Add('2^.111'); // STREET ADDRESS [LINE 1]
637 BasicTemplate.Add('2^.1112'); // ZIP+4
638 BasicTemplate.Add('2^.112'); // STREET ADDRESS [LINE 2]
639 BasicTemplate.Add('2^.113'); // STREET ADDRESS [LINE 3]
640 BasicTemplate.Add('2^.114'); // CITY
641 BasicTemplate.Add('2^.115'); // STATE
642 BasicTemplate.Add('2^.116'); // ZIP CODE
643 BasicTemplate.Add('2^.117'); // COUNTY
644 BasicTemplate.Add('2^.131'); // PHONE NUMBER [RESIDENCE]
645 BasicTemplate.Add('2^.132'); // PHONE NUMBER [WORK]
646 BasicTemplate.Add('2^.133'); // PHONE [CELL}
647 BasicTemplate.Add('2^.2401'); // FATHER'S NAME
648 BasicTemplate.Add('2^.2402'); // MOTHER'S NAME
649 BasicTemplate.Add('2^.2403'); // MOTHER'S MAIDEN NAME
650 BasicTemplate.Add('2^994'); // MULTIPLE BIRTH INDICATOR
651 BasicTemplate.Add('2^1901'); // VETERAN (Y/N)?
652
653 InitializeSettingsFilesTreeView;
654 end;
655
656 procedure TMainForm.InitializeUsersTreeView;
657 var
658 UsersList : TStringList;
659
660 begin
661 CurrentUserData.Clear;
662 ClearGrid(AdvancedUsersGrid);
663 ClearGrid(BasicUsersGrid);
664 UsersTreeView.Items.Clear;
665 AllUsers := UsersTreeView.Items.Add(nil, 'All Users'); { Add root node }
666 AllUsers.ImageIndex := 2;
667 AllUsers.SelectedIndex := 2;
668 ActiveUsers := UsersTreeView.Items.AddChild(AllUsers,'Active Users');
669 ActiveUsers.ImageIndex := 0;
670 ActiveUsers.SelectedIndex := 0;
671 InactiveUsers := UsersTreeView.Items.AddChild(AllUsers,'Inactive Users');
672 InactiveUsers.ImageIndex := 1;
673 InactiveUsers.SelectedIndex := 1;
674 AllUsers.Expand(true);
675 UsersList := TStringList.create;
676 UsersList.Sorted := false;
677 GetUsersList(UsersList,false);
678 LoadUsersTreeView(UsersList);
679 UsersList.free;
680 end;
681
682
683 procedure TMainForm.InitializeSettingsFilesTreeView;
684 var
685 RecordsList : TStringList;
686 index : integer;
687 begin
688 RecordsList := TStringList.Create;
689 SettingsFiles.Clear;
690 SettingsFiles.Add('<blank line>'); // to index 0 is not used for file info.
691 ClearGrid(AdvancedSettingsGrid);
692 ClearGrid(BasicSettingsGrid);
693 SettingsTreeView.Items.Clear;
694 AllSettings := SettingsTreeView.Items.Add(nil, 'All Settings Files'); { Add root node }
695 AllSettings.ImageIndex := 8;
696 AllSettings.SelectedIndex := 8;
697 AllSettings.StateIndex := 7;
698
699 index := SettingsFiles.Add('8989.3');
700 KernelSysParams := SettingsTreeView.Items.AddChildObject(AllSettings,'Kernel System Parameters',Pointer(index));
701 KernelSysParams.ImageIndex := 8;
702 KernelSysParams.SelectedIndex := 8;
703 KernelSysParams.StateIndex := 7;
704 GetRecordsList(RecordsList,'8989.3'); // KERNEL SYSTEM PARAMETERS file
705 LoadSettingsTreeView(RecordsList,KernelSysParams);
706 RecordsList.Clear;
707
708 index := SettingsFiles.Add('44');
709 HospLoc := SettingsTreeView.Items.AddChildObject(AllSettings,'Practice Locations',Pointer(index));
710 HospLoc.ImageIndex := 8;
711 HospLoc.SelectedIndex := 8;
712 HospLoc.StateIndex := 7;
713 GetRecordsList(RecordsList,'44'); //HOSPITAL LOCATION file
714 LoadSettingsTreeView(RecordsList,HospLoc);
715 RecordsList.Clear;
716
717 index := SettingsFiles.Add('8994.1');
718 RPCBrokerParams := SettingsTreeView.Items.AddChildObject(AllSettings,'RPC Broker Settings',Pointer(index));
719 RPCBrokerParams.ImageIndex := 8;
720 RPCBrokerParams.SelectedIndex := 8;
721 RPCBrokerParams.StateIndex := 7;
722 GetRecordsList(RecordsList,'8994.1'); // RPC BROKER SITE PARAMETERS
723 LoadSettingsTreeView(RecordsList,RPCBrokerParams);
724 RecordsList.Clear;
725
726 index := SettingsFiles.Add('3.5');
727 Devices := SettingsTreeView.Items.AddChildObject(AllSettings,'Devices',Pointer(index));
728 Devices.ImageIndex := 8;
729 Devices.SelectedIndex := 8;
730 Devices.StateIndex := 7;
731 GetRecordsList(RecordsList,'3.5'); // DEVICE
732 LoadSettingsTreeView(RecordsList,Devices);
733 RecordsList.Clear;
734
735 RecordsList.Free;
736 end;
737
738
739 procedure TMainForm.FormDestroy(Sender: TObject);
740 var i : integer;
741 tempInfo : TGridInfo;
742 begin
743 CurrentUserData.Free;
744 BasicTemplate.Free;
745 SettingsFiles.Free;
746 CurrentSettingsData.Free;
747 CurrentPatientData.Free;
748 CurrentAnyFileData.Free;
749 for i := 0 to DataForGrid.Count-1 do begin
750 tempInfo := TGridInfo(DataForGrid.Objects[i]);
751 //tempInfo.Data.Free; //not owned here....
752 tempInfo.Free;
753 end;
754 DataForGrid.Free;
755
756 CachedHelp.Free;
757 CachedHelpIdx.Free;
758 CachedWPField.Free;
759
760 end;
761
762
763 procedure TMainForm.UsersTreeViewChanging(Sender: TObject; Node: TTreeNode; var AllowChange: Boolean);
764 begin
765 AllowChange := (PostVisibleGrid <> mrNO);
766 if AllowChange then LastSelTreeNode := Node;
767 end;
768
769
770 function TMainForm.PostVisibleGrid: TModalResult;
771 begin
772 result := PostChanges(GetVisibleGrid);
773 end;
774
775
776 procedure TMainForm.SettingsTreeViewChanging(Sender: TObject; Node: TTreeNode; var AllowChange: Boolean);
777 begin
778 AllowChange := (PostVisibleGrid <> mrNO);
779 if AllowChange then LastSelTreeNode := Node;
780 end;
781
782
783 procedure TMainForm.UsersTreeViewChange(Sender: TObject; Node: TTreeNode);
784 var IEN : longInt;
785 GridInfo : TGridInfo;
786 begin
787 //get info from selected node.
788 LastSelTreeNode := Node;
789 IEN := longInt(Node.Data);
790 if IEN = 0 then exit;
791 GridInfo := GetInfoForGrid(BasicUsersGrid);
792 if GridInfo = nil then exit;
793 GridInfo.IENS := IntToStr(IEN) + ',';
794 LoadUserData(GridInfo);
795 end;
796
797 procedure TMainForm.SettingsTreeViewChange(Sender: TObject; Node: TTreeNode);
798 var IEN : longInt;
799 FileNum : string;
800 GridInfo : TGridInfo;
801 begin
802 //get info from selected node.
803 LastSelTreeNode := Node;
804 GridInfo := GetInfoForGrid(BasicSettingsGrid);
805 if GridInfo = nil then exit;
806 IEN := longInt(Node.Data);
807 if IEN = 0 then exit;
808 FileNum := FileNumForSettingsNode (Node);
809 if FileNum = '' then exit;
810 GridInfo.IENS := IntToStr(IEN) + ',';
811 GridInfo.FileNum := FileNum;
812 GetSettingsInfo(GridInfo);
813 end;
814
815 function TMainForm.FileNumForSettingsNode (Node : TTreeNode) : string;
816 var index : integer;
817 Parent : TTreeNode;
818 begin
819 Result := '';
820 Parent := Node.Parent;
821 if Parent <> nil then begin
822 index := integer(Parent.Data);
823 if (index >0) and (index < SettingsFiles.count) then Result := SettingsFiles.Strings[index];
824 end;
825 end;
826
827
828 procedure TMainForm.LoadUserData(GridInfo : TGridInfo);
829 //Purpose: Get all fields from server for one record.
830 //Data is an OUT parameter.
831 var cmd,RPCResult : string;
832 IENS : String;
833 Data : TStringList;
834 begin
835 Data := GridInfo.Data;
836 IENS := GridInfo.IENS;
837 Data.Clear;
838 ClearGrid(AdvancedUsersGrid);
839 ClearGrid(BasicUsersGrid);
840 SetCursorImage(crHourGlass);
841 if IENS <> '0,' then begin
842 RPCBrokerV.remoteprocedure := 'TMG CHANNEL';
843 RPCBrokerV.param[0].ptype := list;
844 cmd := 'GET ONE USER^' + IENS;
845 RPCBrokerV.Param[0].Mult['"REQUEST"'] := cmd;
846 RPCBrokerV.Call;
847 RPCResult := RPCBrokerV.Results[0]; //returns: error: -1; success=1
848 //Results[1]='FileNum^IENS^FieldNum^ExtValue^FieldName^DDInfo...
849 //Results[2]='FileNum^IENS^FieldNum^ExtValue^FieldName^DDInfo...
850 if piece(RPCResult,'^',1)='-1' then begin
851 FMErrorForm.Memo.Lines.Assign(RPCBrokerV.Results);
852 FMErrorForm.PrepMessage;
853 FMErrorForm.ShowModal;
854 end else begin
855 Data.Assign(RPCBrokerV.results);
856 LoadAnyGrid(AdvancedUsersGrid,false,'200',IENS,Data);
857 LoadAnyGrid(BasicUsersGrid,true,'200',IENS,Data);
858 btnUsersRevert.Enabled := false;
859 btnUsersApply.Enabled := false;
860 end;
861 end;
862 SetCursorImage(crDefault);
863
864 end;
865
866 procedure TMainForm.SetCursorImage(Cursor : TCursor);
867 begin
868 BasicUsersGrid.Cursor := Cursor;
869 AdvancedUsersGrid.Cursor := Cursor;
870 UsersTreeView.Cursor := Cursor;
871
872 BasicSettingsGrid.Cursor := Cursor;
873 AdvancedSettingsGrid.Cursor := Cursor;
874 SettingsTreeView.Cursor := Cursor;
875
876 PatientORComboBox.Cursor := Cursor;
877 BasicPatientGrid.Cursor := Cursor;
878 AdvancedPatientGrid.Cursor := Cursor;
879
880 end;
881
882
883 procedure TMainForm.GetSettingsInfo(GridInfo : TGridInfo);
884 //Purpose: Get all fields from server for one record.
885 //Data is an OUT parameter.
886 var cmd,RPCResult : string;
887 FileNum : String;
888 IENS : String;
889 Data : TStringList ;
890 begin
891 FileNum := GridInfo.FileNum;
892 IENS := GridInfo.IENS;
893 Data := GridInfo.Data;
894 Data.Clear;
895 ClearGrid(AdvancedSettingsGrid);
896 ClearGrid(BasicSettingsGrid);
897 if IENS <> '0,' then begin
898 RPCBrokerV.remoteprocedure := 'TMG CHANNEL';
899 RPCBrokerV.param[0].ptype := list;
900 cmd := 'GET ONE RECORD^' + FileNum + '^' + IENS;
901 RPCBrokerV.Param[0].Mult['"REQUEST"'] := cmd;
902 RPCBrokerV.Call;
903 RPCResult := RPCBrokerV.Results[0]; //returns: error: -1; success=1
904 //Results[1]='FileNum^IENS^FieldNum^ExtValue^FieldName^DDInfo...
905 //Results[2]='FileNum^IENS^FieldNum^ExtValue^FieldName^DDInfo...
906 if piece(RPCResult,'^',1)='-1' then begin
907 FMErrorForm.Memo.Lines.Assign(RPCBrokerV.Results);
908 FMErrorForm.PrepMessage;
909 FMErrorForm.ShowModal;
910 end else begin
911 Data.Assign(RPCBrokerV.results);
912 LoadAnyGrid(AdvancedSettingsGrid,false,FileNum,IENS,Data);
913 LoadAnyGrid(BasicSettingsGrid,true,FileNum,IENS,Data);
914 btnSettingsRevert.Enabled := false;
915 btnSettingsApply.Enabled := false;
916 end;
917 end;
918 end;
919
920 procedure TMainForm.GetPatientInfo(GridInfo : TGridInfo);
921 var cmd,RPCResult : string;
922 IENS : String;
923 Data : TStringList;
924 begin
925 IENS := GridInfo.IENS;
926 Data := GridInfo.Data;
927 Data.Clear;
928 ClearGrid(AdvancedPatientGrid);
929 ClearGrid(BasicPatientGrid);
930 SetCursorImage(crHourGlass);
931 if IENS <> '0,' then begin
932 RPCBrokerV.remoteprocedure := 'TMG CHANNEL';
933 RPCBrokerV.param[0].ptype := list;
934 cmd := 'GET ONE RECORD^2^' + IENS;
935 RPCBrokerV.Param[0].Mult['"REQUEST"'] := cmd;
936 RPCBrokerV.Call;
937 RPCResult := RPCBrokerV.Results[0]; //returns: error: -1; success=1
938 //Results[1]='FileNum^IENS^FieldNum^ExtValue^FieldName^DDInfo...
939 //Results[2]='FileNum^IENS^FieldNum^ExtValue^FieldName^DDInfo...
940 if piece(RPCResult,'^',1)='-1' then begin
941 FMErrorForm.Memo.Lines.Assign(RPCBrokerV.Results);
942 FMErrorForm.PrepMessage;
943 FMErrorForm.ShowModal;
944 end else begin
945 Data.Assign(RPCBrokerV.results);
946 LoadAnyGrid(AdvancedPatientGrid,false,'2',IENS,Data);
947 LoadAnyGrid(BasicPatientGrid,true,'2',IENS,Data);
948 btnPatientRevert.Enabled := false;
949 btnPatientApply.Enabled := false;
950 end;
951 end;
952 SetCursorImage(crDefault);
953 end;
954
955
956 procedure TMainForm.GetAnyfileInfo(GridInfo : TGridInfo);
957 //Purpose: Get all fields from server for one record.
958 //Data is an OUT parameter.
959 var cmd,RPCResult : string;
960 FileNum : String;
961 IENS : String;
962 Data : TStringList;
963 begin
964 FileNum := GridInfo.FileNum;
965 IENS := GridInfo.IENS;
966 Data := GridInfo.Data;
967 Data.Clear;
968 ClearGrid(AnyFileGrid);
969 if IENS <> '0,' then begin
970 RPCBrokerV.remoteprocedure := 'TMG CHANNEL';
971 RPCBrokerV.param[0].ptype := list;
972 cmd := 'GET ONE RECORD^' + FileNum + '^' + IENS;
973 RPCBrokerV.Param[0].Mult['"REQUEST"'] := cmd;
974 RPCBrokerV.Call;
975 RPCResult := RPCBrokerV.Results[0]; //returns: error: -1; success=1
976 //Results[1]='FileNum^IENS^FieldNum^ExtValue^FieldName^DDInfo...
977 //Results[2]='FileNum^IENS^FieldNum^ExtValue^FieldName^DDInfo...
978 if piece(RPCResult,'^',1)='-1' then begin
979 FMErrorForm.Memo.Lines.Assign(RPCBrokerV.Results);
980 FMErrorForm.PrepMessage;
981 FMErrorForm.ShowModal;
982 end else begin
983 Data.Assign(RPCBrokerV.results);
984 LoadAnyGrid(AnyFileGrid,false,FileNum,IENS,Data);
985 btnAdvancedRevert.Enabled := false;
986 btnAdvancedApply.Enabled := false;
987 end;
988 end;
989 end;
990
991
992
993 procedure TMainForm.ClearGrid(Grid : TStringGrid);
994 begin
995 Grid.Cells[0,1] := '';
996 Grid.Cells[1,1] := '';
997 Grid.Cells[2,1] := '';
998 Grid.RowCount :=2;
999 end;
1000
1001
1002 procedure TMainForm.LoadAnyGrid(Grid : TStringGrid; //the TStringGrid to load
1003 BasicMode: boolean;
1004 FileNum : string;
1005 IENS : string;
1006 CurrentData : TStringList);
1007 var
1008 GridInfo : TGridInfo;
1009 begin
1010 //This stores load information into GridInfo.
1011 GridInfo := GetInfoForGrid(Grid);
1012 if GridInfo = nil then exit;
1013 GridInfo.Grid := Grid;
1014 GridInfo.BasicMode := BasicMode;
1015 GridInfo.FileNum := FileNum;
1016 GridInfo.IENS := IENS;
1017 GridInfo.Data := CurrentData;
1018 LoadAnyGridFromInfo(GridInfo);
1019 end;
1020
1021
1022 procedure TMainForm.LoadAnyGridFromInfo(GridInfo : TGridInfo);
1023 //Format of CurrentData:
1024 //Data[0]=1^Success
1025 //Data[1]='FileNum^IENS^FieldNum^ExtValue^FieldName^DDInfo...
1026 //Data[2]='FileNum^IENS^FieldNum^ExtValue^FieldName^DDInfo...
1027 //...
1028
1029 //This assumes that GridInfo already has loaded info.
1030 var
1031 Grid : TStringGrid; //the TStringGrid to load
1032 BasicMode: boolean;
1033 FileNum : string;
1034 IENS : string;
1035 CurrentData : TStringList;
1036
1037 procedure LoadOneLine (Grid : TStringGrid; oneEntry : string; GridRow : integer);
1038 var
1039 tempFile,IENS : string;
1040 fieldNum,fieldName,fieldDef : string;
1041 subFileNum : string;
1042 value : string;
1043 begin
1044 tempFile := Piece(oneEntry,'^',1);
1045 if tempFile = FileNum then begin //handle subfiles later...
1046 IENS := Piece(oneEntry,'^',2);
1047 fieldNum := Piece(oneEntry,'^',3);
1048 value := Piece(oneEntry,'^',4);
1049 fieldName := Piece(oneEntry,'^',5);
1050 fieldDef := Piece(oneEntry,'^',6);
1051 Grid.RowCount := GridRow + 1;
1052 Grid.Cells[0,GridRow] := fieldNum;
1053 Grid.Cells[1,GridRow] := fieldName;
1054 if Pos('W',fieldDef)>0 then begin
1055 Grid.Cells[2,GridRow] := CLICK_TO_EDIT;
1056 end else if IsSubFile(fieldDef, subFileNum) then begin
1057 if IsWPField(FileNum,fieldNum) then begin
1058 Grid.Cells[2,GridRow] := CLICK_TO_EDIT;
1059 end else begin
1060 Grid.Cells[2,GridRow] := CLICK_FOR_SUBS;
1061 end;
1062 end else if Pos('C',fieldDef)>0 then begin
1063 Grid.Cells[2,GridRow] := COMPUTED_FIELD;
1064 end else begin
1065 Grid.Cells[2,GridRow] := value;
1066 end;
1067 Grid.RowHeights[GridRow] := DEF_GRID_ROW_HEIGHT;
1068 end;
1069 end;
1070
1071 function getOneLine(CurrentData : TStringList; oneFileNum,oneFieldNum : string) : string;
1072 var i : integer;
1073 FileNum,FieldNum : string;
1074 begin
1075 result := '';
1076 // FileNum^IENS^FieldNum^FieldName^newValue^oldValue
1077 for i := 1 to CurrentData.Count - 1 do begin
1078 FileNum := piece(CurrentData.Strings[i],'^',1);
1079 if FileNum <> oneFileNum then continue;
1080 FieldNum := piece(CurrentData.Strings[i],'^',3);
1081 if FieldNum <> oneFieldNum then continue;
1082 result := CurrentData.Strings[i];
1083 break;
1084 end;
1085 end;
1086
1087 var i : integer;
1088 oneEntry : string;
1089 oneFileNum,oneFieldNum : string;
1090 gridRow : integer;
1091 //GridInfo : TGridInfo;
1092
1093 begin
1094 FLoadingGrid := true;
1095
1096 if GridInfo=nil then exit;
1097
1098 Grid := GridInfo.Grid;
1099 BasicMode := GridInfo.BasicMode;
1100 FileNum := GridInfo.FileNum;
1101 IENS := GridInfo.IENS;
1102 CurrentData := GridInfo.Data;
1103
1104 ClearGrid(Grid);
1105 Grid.ColWidths[0] := 50;
1106 Grid.ColWidths[1] := 200;
1107 Grid.ColWidths[2] := 300;
1108 Grid.Cells[0,0] := '#';
1109 Grid.Cells[1,0] := 'Name';
1110 Grid.Cells[2,0] := 'Value';
1111
1112 if BasicMode=false then begin
1113 for i := 1 to CurrentData.Count-1 do begin //start at 1 because [0] = 1^Success
1114 oneEntry := CurrentData.Strings[i];
1115 LoadOneLine (Grid,oneEntry,i);
1116 end;
1117 end else if BasicMode=true then begin
1118 gridRow := 1;
1119 for i := 0 to BasicTemplate.Count-1 do begin
1120 oneFileNum := Piece(BasicTemplate.Strings[i],'^',1);
1121 if oneFileNum <> fileNum then continue;
1122 oneFieldNum := Piece(BasicTemplate.Strings[i],'^',2);
1123 oneEntry := getOneLine(CurrentData,oneFileNum,oneFieldNum);
1124 LoadOneLine (Grid,oneEntry,gridRow);
1125 Inc(GridRow);
1126 end;
1127 end;
1128 FLoadingGrid := false;
1129 end;
1130
1131
1132 procedure TMainForm.GridSelectCell(Sender: TObject; ACol, ARow: Integer;
1133 var CanSelect: Boolean);
1134 (*
1135 For Field def, here is the legend
1136 character meaning
1137
1138 BC The data is Boolean Computed (true or false).
1139 C The data is Computed.
1140 Cm The data is multiline Computed.
1141 DC The data is Date-valued, Computed.
1142 D The data is Date-valued.
1143 F The data is Free text.
1144 I The data is uneditable.
1145 Pn The data is a Pointer reference to file "n".
1146 S The data is from a discrete Set of codes.
1147
1148 N The data is Numeric-valued.
1149
1150 Jn To specify a print length of n characters.
1151 Jn,d To specify printing n characters with decimals.
1152
1153 V The data is a Variable pointer.
1154 W The data is Word processing.
1155 WL The Word processing data is normally printed in Line mode (i.e., without word wrap).
1156 *)
1157 var oneEntry,FieldDef : string;
1158 date,time: string;
1159 FileNum,FieldNum,SubFileNum : string;
1160 GridFileNum : string;
1161 UserLine : integer;
1162 Grid : TStringGrid;
1163 IEN : int64;
1164 IENS : string;
1165 CurrentData : TStringList;
1166 GridInfo : TGridInfo;
1167 SubFileForm : TSubFileForm;
1168 begin
1169 if FLoadingGrid then exit; //prevent pseudo-clicks during loading...
1170 Grid := (Sender as TStringGrid);
1171 GridInfo := GetInfoForGrid(Grid);
1172 if GridInfo=nil then exit;
1173 GridFileNum := GridInfo.FileNum;
1174 CanSelect := false; //default to NOT selectable.
1175 CurrentData := GridInfo.Data;
1176 if CurrentData=nil then exit;
1177 if CurrentData.Count = 0 then exit;
1178 UserLine := GetUserLine(CurrentData,Grid,ARow);
1179 if UserLine = -1 then exit;
1180 oneEntry := CurrentData.Strings[UserLine];
1181 FieldDef := Piece(oneEntry,'^',6);
1182 if Pos('F',FieldDef)>0 then begin //Free text
1183 CanSelect := true;
1184 end else if IsSubFile(FieldDef,SubFileNum) then begin //Subfiles.
1185 FileNum := Piece(oneEntry,'^',1);
1186 FieldNum := Piece(oneEntry,'^',3);
1187 if IsWPField(FileNum,FieldNum) then begin
1188 IENS := Piece(oneEntry,'^',2);
1189 EditTextForm.PrepForm(FileNum,FieldNum,IENS);
1190 EditTextForm.ShowModal;
1191 end else begin
1192 //handle subfiles here
1193 IENS := '';
1194 if GridInfo.Message = MSG_SUB_FILE then begin //used message from subfile Grid
1195 IENS := GridInfo.IENS;
1196 end else if LastSelTreeNode <> nil then begin //this is one of the selction trees.
1197 IEN := longInt(LastSelTreeNode.Data);
1198 if IEN > 0 then IENS := InttoStr(IEN) + ',';
1199 end else if GridInfo.Data = CurrentAnyFileData then begin
1200 IEN := RecordORComboBox.ItemID; //get info from selected record
1201 if IEN > 0 then IENS := InttoStr(IEN) + ',';
1202 end;
1203 if IENS <> '' then begin
1204 SubFileForm := TSubFileForm.Create(self);
1205 SubFileForm.PrepForm(SubFileNum,IENS);
1206 SubfileForm.ShowModal; // note: may call this function again recursively for sub-sub-files etc.
1207 SubFileForm.Free;
1208 end else begin
1209 MessageDlg('IENS for File="". Can''t process.',mtInformation,[MBOK],0);
1210 end;
1211 end;
1212 end else if Pos('C',FieldDef)>0 then begin //computed fields.
1213 CanSelect := false;
1214 end else if Pos('D',FieldDef)>0 then begin //date field
1215 date := piece(Grid.Cells[ACol,ARow],'@',1);
1216 time := piece(Grid.Cells[ACol,ARow],'@',2);
1217 if date <> '' then begin
1218 SelDateTimeForm.DateTimePicker.Date := StrToDate(date);
1219 end else begin
1220 SelDateTimeForm.DateTimePicker.Date := SysUtils.Date;
1221 end;
1222 if SelDateTimeForm.ShowModal = mrOK then begin
1223 date := DateToStr(SelDateTimeForm.DateTimePicker.Date);
1224 time := TimeToStr(SelDateTimeForm.DateTimePicker.Time);
1225 if time <> '' then date := date; // + '@' + time; elh 8/15/08
1226 Grid.Cells[ACol,ARow] := date;
1227 end;
1228 CanSelect := true;
1229 end else if Pos('S',FieldDef)>0 then begin //Set of Codes
1230 SetSelForm.PrepForm(Piece(oneEntry,'^',7));
1231 if SetSelForm.ShowModal = mrOK then begin
1232 Grid.Cells[ACol,ARow] := SetSelForm.ComboBox.Text;
1233 CanSelect := true;
1234 end;
1235 end else if Pos('I',FieldDef)>0 then begin //uneditable
1236 MessageDlg('Sorry. Flagged as UNEDITABLE.',mtInformation ,[mbOK],0);
1237 end else if Pos('P',FieldDef)>0 then begin //Pointer to file.
1238 FileNum := ExtractNum (FieldDef,Pos('P',FieldDef)+1);
1239 //check for validity here...
1240 FieldLookupForm.PrepForm(FileNum,Grid.Cells[ACol,ARow]);
1241 if FieldLookupForm.ShowModal = mrOK then begin
1242 Grid.Cells[ACol,ARow] := FieldLookupForm.ORComboBox.Text;
1243 CanSelect := true;
1244 end;
1245 end;
1246 if CanSelect then begin
1247 FLastSelectedRow := ARow;
1248 FLastSelectedCol := ACol;
1249 end;
1250 GridInfo.ApplyBtn.Enabled := true;
1251 GridInfo.RevertBtn.Enabled := true;
1252 end;
1253
1254
1255 function TMainForm.GetLineInfo(Grid : TStringGrid; CurrentUserData : TStringList; ARow: integer) : tFileEntry;
1256 var fieldNum : string;
1257 oneEntry : string;
1258 fileNum : string;
1259 gridRow : integer;
1260 begin
1261 fieldNum := Grid.Cells[0,ARow];
1262 gridRow := FindInStrings(fieldNum, CurrentUserData, fileNum);
1263 if gridRow > -1 then begin
1264 oneEntry := CurrentUserData.Strings[gridRow];
1265 Result.Field := fieldNum;
1266 Result.FieldName := Grid.Cells[1,ARow];
1267 Result.FileNum := fileNum;
1268 Result.IENS := Piece(oneEntry,'^',2);
1269 Result.oldValue := Piece(oneEntry,'^',4);
1270 Result.newValue := Grid.Cells[2,ARow];
1271 end else begin
1272 Result.Field := '';
1273 Result.FieldName := '';
1274 Result.FileNum := '';
1275 Result.IENS := '';
1276 Result.oldValue := '';
1277 Result.newValue := '';
1278 end;
1279 end;
1280
1281 function TMainForm.GetUserLine(CurrentUserData : TStringList; Grid : TStringGrid; ARow: integer) : integer;
1282 var fieldNum: string;
1283 tempFileNum : string;
1284 begin
1285 fieldNum := Grid.Cells[0,ARow];
1286 Result := FindInStrings(fieldNum,CurrentUserData,tempFileNum);
1287 end;
1288
1289 function TMainForm.FindInStrings(fieldNum : string; Strings : TStringList; var fileNum : string) : integer;
1290 //Note: if fileNum is passed blank, then first matching file will be placed in it (i.e. OUT parameter)
1291 var tempFieldNum : string;
1292 oneEntry,tempFile : string;
1293 i : integer;
1294 begin
1295 result := -1;
1296 fileNum := '';
1297 for i := 1 to Strings.Count-1 do begin //0 --> 1^success
1298 oneEntry := Strings.Strings[i];
1299 tempFile := Piece(oneEntry,'^',1);
1300 if fileNum='' then fileNum := tempFile;
1301 if tempFile <> fileNum then continue; //ignore subfiles
1302 tempFieldNum := Piece(oneEntry,'^',3);
1303 if tempFieldNum <> fieldNum then continue;
1304 Result := i;
1305 break;
1306 end;
1307 end;
1308
1309
1310 function TMainForm.IsSubFile(FieldDef: string ; var SubFileNum : string) : boolean;
1311 //SubFileNum is OUT parameter
1312 begin
1313 SubFileNum := ExtractNum(FieldDef,1);
1314 result := (SubFileNum <> '');
1315 end;
1316
1317 function TMainForm.IsWPField(FileNum,FieldNum : string) : boolean;
1318 var RPCResult : string;
1319 SrchStr : string;
1320 Idx: integer;
1321 begin
1322 SrchStr := FileNum + '^' + FieldNum + '^';
1323 Idx := CachedWPField.IndexOf(SrchStr + 'YES');
1324 if Idx > -1 then begin Result := true; exit; end;
1325 Idx := CachedWPField.IndexOf(SrchStr + 'NO');
1326 if Idx > -1 then begin Result := false; exit; end;
1327
1328 result := false;
1329 RPCBrokerV.remoteprocedure := 'TMG CHANNEL';
1330 RPCBrokerV.param[0].ptype := list;
1331 RPCBrokerV.Param[0].Mult['"REQUEST"'] := 'IS WP FIELD^' + FileNum + '^' + FieldNum;
1332 RPCBrokerV.Call;
1333 RPCResult := RPCBrokerV.Results[0]; //returns: error: -1; success=1
1334 if piece(RPCResult,'^',1)='-1' then begin
1335 FMErrorForm.Memo.Lines.Assign(RPCBrokerV.Results);
1336 FMErrorForm.PrepMessage;
1337 FMErrorForm.ShowModal;
1338 end else begin
1339 RPCResult := piece(RPCResult,'^',3);
1340 result := (RPCResult = 'YES');
1341 CachedWPField.Add(SrchStr + RPCResult);
1342 end;
1343 end;
1344
1345
1346 function TMainForm.ExtractNum (S : String; StartPos : integer) : string;
1347 var i : integer;
1348 ch : char;
1349 begin
1350 result := '';
1351 if (S = '') or (StartPos < 0) then exit;
1352 i := StartPos;
1353 repeat
1354 ch := S[i];
1355 i := i + 1;
1356 if ch in ['0'..'9','.'] then begin
1357 Result := Result + ch;
1358 end;
1359 until (i > length(S)) or not (ch in ['0'..'9','.'])
1360 end;
1361
1362 procedure TMainForm.Button1Click(Sender: TObject);
1363 begin
1364 FieldLookupForm.Show;
1365 end;
1366
1367 procedure TMainForm.btnUsersRevertClick(Sender: TObject);
1368 begin
1369 DoRevert(BasicUsersGrid,AdvancedUsersGrid);
1370 {
1371 LoadAnyGridFromInfo(GetInfoForGrid(AdvancedUsersGrid));
1372 LoadAnyGridFromInfo(GetInfoForGrid(BasicUsersGrid));
1373 btnUsersRevert.Enabled := false;
1374 btnUsersApply.Enabled := false;
1375 }
1376 end;
1377
1378 function TMainForm.GetVisibleGridInfo : TGridInfo;
1379 begin
1380 result := GetInfoForGrid(GetVisibleGrid);
1381 end;
1382
1383 function TMainForm.GetVisibleGrid: TStringGrid;
1384 begin
1385 if FVisibleGridIdx > -1 then begin
1386 result := TGridInfo(DataForGrid.Objects[FVisibleGridIdx]).Grid;
1387 end else begin
1388 result := nil;
1389 end;
1390 end;
1391
1392 function TMainForm.GetInfoForGrid(Grid : TStringGrid) : TGridInfo;
1393 var i : integer;
1394 begin
1395 i := GetInfoIndexForGrid(Grid);
1396 if i > -1 then begin
1397 result := TGridInfo(DataForGrid.Objects[i]);
1398 end else begin
1399 result := nil;
1400 end;
1401 end;
1402
1403
1404 function TMainForm.GetInfoIndexForGrid(Grid : TStringGrid) : integer;
1405 var s : string;
1406 begin
1407 s := IntToStr(integer(Grid));
1408 result := DataForGrid.IndexOf(s);
1409 end;
1410
1411 procedure TMainForm.SetVisibleGridIdx(Grid : TStringGrid);
1412 begin
1413 FVisibleGridIdx := GetInfoIndexForGrid(Grid);
1414 end;
1415
1416
1417 procedure TMainForm.CompileChanges(Grid : TStringGrid; CurrentUserData,Changes : TStringList);
1418 //Output format:
1419 // FileNum^IENS^FieldNum^FieldName^newValue^oldValue
1420
1421 var row : integer;
1422 Entry : tFileEntry;
1423 oneEntry : string;
1424 begin
1425 for row := 1 to Grid.RowCount-1 do begin
1426 Entry := GetLineInfo(Grid,CurrentUserData, row);
1427 if Entry.oldValue <> Entry.newValue then begin
1428 if (Entry.newValue <> CLICK_FOR_SUBS) and
1429 (Entry.newValue <> COMPUTED_FIELD) and
1430 (Entry.newValue <> CLICK_TO_EDIT) then begin
1431 oneEntry := Entry.FileNum + '^' + Entry.IENS + '^' + Entry.Field + '^' + Entry.FieldName;
1432 oneEntry := oneEntry + '^' + Entry.newValue + '^' + Entry.oldValue;
1433 Changes.Add(oneEntry);
1434 end;
1435 end;
1436 end;
1437 end;
1438
1439
1440 function TMainForm.PostChanges(Grid : TStringGrid) : TModalResult;
1441 //Results: mrNone -- no post done (not needed)
1442 // mrCancel -- user pressed cancel on confirmation screen.
1443 // mrNo -- signals posting error.
1444 var Changes : TStringList;
1445 PostResult : TModalResult;
1446 CurrentData : TStringList;
1447 GridInfo : TGridInfo;
1448 IENS : string;
1449 begin
1450 Result := mrNone; //default to No changes
1451 GridInfo := GetInfoForGrid(Grid);
1452 if GridInfo=nil then exit;
1453 CurrentData := GridInfo.Data;
1454 if CurrentData=nil then exit;
1455 if CurrentData.Count = 0 then exit;
1456 IENS := GridInfo.IENS;
1457 if IENS='' then exit;
1458 Changes := TStringList.Create;
1459 CompileChanges(Grid,CurrentData,Changes);
1460 if Changes.Count>0 then begin
1461 PostForm.PrepForm(Changes);
1462 PostResult := PostForm.ShowModal;
1463 if PostResult = mrOK then begin
1464 if DisuserChanged(Changes) then begin //looks for change in file 200, field 4
1465 InitializeUsersTreeView;
1466 end else begin
1467 if Pos('+',IENS)>0 then begin
1468 GridInfo.IENS := PostForm.GetNewIENS(IENS);
1469 end;
1470 if assigned(GridInfo.DataLoadProc) then begin
1471 GridInfo.DataLoadProc(GridInfo);
1472 end;
1473 {
1474 if CurrentData = CurrentUserData then begin
1475 LoadUserData(IENS,CurrentData); //reload record from server.
1476 end else if CurrentData = CurrentSettingsData then begin
1477 GetSettingsInfo(GridInfo.FileNum, GridInfo.IENS, CurrentData);
1478 end else if CurrentData = CurrentPatientData then begin
1479 GetPatientInfo(GridInfo.IENS, CurrentData);
1480 end else if CurrentData = CurrentAnyFileData then begin
1481 GetAnyFileInfo(GridInfo.FileNum, GridInfo.IENS, CurrentData);
1482 end;
1483 }
1484 end;
1485 end else if PostResult = mrNo then begin //mrNo is signal of post Error
1486 // show error...
1487 end;
1488 Result := PostResult;
1489 end else begin
1490 Result := mrNone;
1491 end;
1492 Changes.Free;
1493 end;
1494
1495 function TMainForm.DisuserChanged(Changes: TStringList) : boolean;
1496 var i : integer;
1497 //Changes format:
1498 // FileNum^IENS^FieldNum^FieldName^newValue^oldValue
1499 begin
1500 result := false;
1501 for i := 0 to Changes.Count-1 do begin
1502 if piece(Changes.Strings[i],'^',1)<> '200' then continue;
1503 if piece(Changes.Strings[i],'^',4)<> 'DISUSER' then continue;
1504 result := true;
1505 break;
1506 end;
1507 end;
1508
1509
1510 procedure TMainForm.btnUsersApplyClick(Sender: TObject);
1511 var result : TModalResult;
1512 begin
1513 result:= PostVisibleGrid;
1514 if result <> mrNone then InitializeUsersTreeView;
1515 end;
1516
1517 procedure TMainForm.GridSetEditText(Sender: TObject; ACol, ARow: Integer; const Value: String);
1518 begin
1519 btnUsersRevert.Enabled := true;
1520 btnUsersApply.Enabled := true;
1521 end;
1522
1523 procedure TMainForm.BasicSettingsGridSetEditText(Sender: TObject; ACol, ARow: Integer; const Value: String);
1524 begin
1525 btnSettingsRevert.Enabled := true;
1526 btnSettingsApply.Enabled := true;
1527 end;
1528
1529
1530 procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
1531 begin
1532 PostVisibleGrid;
1533 RPCBrokerV.Connected := false; //disconnect
1534 end;
1535
1536 procedure TMainForm.Exit1Click(Sender: TObject);
1537 begin
1538 Close;
1539 end;
1540
1541 procedure TMainForm.UserPageControlDrawTab(Control: TCustomTabControl;
1542 TabIndex: Integer;
1543 const Rect: TRect;
1544 Active: Boolean);
1545 begin
1546 DrawTab(Control,TabIndex,Rect,Active);
1547 end;
1548
1549 procedure TMainForm.DrawTab(Control: TCustomTabControl;
1550 TabIndex: Integer;
1551 const Rect: TRect;
1552 Active: Boolean);
1553 var
1554 oRect : TRect;
1555 sCaption,temp : String;
1556 iTop : Integer;
1557 iLeft : Integer;
1558 i : integer;
1559
1560 begin
1561 oRect := Rect;
1562 temp := TPageControl(Control).Pages[TabIndex].Caption;
1563 for i := 1 to length(temp) do begin
1564 if temp[i] <> '&' then sCaption := sCaption + temp[i];
1565 end;
1566
1567 iTop := Rect.Top + ((Rect.Bottom - Rect.Top - Control.Canvas.TextHeight(sCaption)) div 2) + 1;
1568 iLeft := Rect.Left + ((Rect.Right - Rect.Left - Control.Canvas.TextWidth (sCaption)) div 2) + 1;
1569
1570 if Active then begin
1571 Control.Canvas.Brush.Color := TColor($0000FFFF); //Bright yellow
1572 Control.Canvas.FillRect(Rect);
1573// Frame3d(Control.Canvas,oRect,clBtnHighLight,clBtnShadow,3);
1574
1575 end else begin
1576 Control.Canvas.Brush.Color := TColor($000079EFE8); //dull yellow
1577 Control.Canvas.FillRect(Rect);
1578 end;
1579 Control.Canvas.TextOut(iLeft,iTop,sCaption);
1580 end;
1581
1582
1583 procedure TMainForm.AboutMenuClick(Sender: TObject);
1584 begin
1585 AboutForm.show;
1586 end;
1587
1588 procedure TMainForm.CloneBtnClick(Sender: TObject);
1589 var IEN : longInt;
1590 newName : string;
1591 IENS,newIENS : string;
1592
1593 begin
1594 if btnUsersApply.Enabled then btnUsersApplyClick(self); //post any changes first.
1595 if MessageDlg('Clone user: '+LastSelTreeNode.Text+' --> New user?' + #10 + #13 +
1596 'Note: This can not be undone.',
1597 mtConfirmation, mbOKCancel,0) = mrCancel then exit;
1598 IEN := longInt(LastSelTreeNode.Data);
1599 IENS := IntToStr(IEN) + ',';
1600 WaitForm.Show;
1601 newName := 'TEMP,MUST-EDIT';
1602 newIENS := DoCloneUser(IENS,newName);
1603 InitializeUsersTreeView; //refresh UsersTreeView.
1604 WaitForm.Hide;
1605 MessageDlg('A new cloned user has been created,' + #10 + #13 +
1606 'named: ' + newName + #10 + #13 +
1607 #10 + #13 +
1608 'This user can be found in the ''Inactive users'' list,' + #10 + #13 +
1609 'but must must be edited before it may be used.' + #10 + #13 +
1610 'Edit it''s DISUSER field to a value of ''NO''' + #10 + #13 +
1611 'to activate.',mtInformation,[mbOK],0);
1612 end;
1613
1614
1615 function TMainForm.DoCloneRecord(FileNum, SourceIENS, New01Field : String) : string;
1616 //Returns IENS of new record in FileNum, or '' if error
1617 var cmd,RPCResult : string;
1618 begin
1619 Result := '';
1620 RPCBrokerV.remoteprocedure := 'TMG CHANNEL';
1621 RPCBrokerV.param[0].ptype := list;
1622 cmd := 'CLONE RECORD' + '^' + FileNum + '^' + SourceIENS + '^' + New01Field;
1623 RPCBrokerV.Param[0].Mult['"REQUEST"'] := cmd;
1624 RPCBrokerV.Call;
1625 RPCResult := RPCBrokerV.Results[0]; //returns: error: -1^ShortMsg; success=1^Success^NewIENS
1626 if piece(RPCResult,'^',1)='-1' then begin
1627 FMErrorForm.Memo.Lines.Assign(RPCBrokerV.Results);
1628 FMErrorForm.PrepMessage;
1629 FMErrorForm.ShowModal;
1630 end else begin
1631 result := piece(RPCResult,'^',3);
1632 end;
1633 end;
1634
1635 function TMainForm.DoCloneUser(SourceIENS, New01Field : String) : string;
1636 //Returns IENS of new record in FileNum, or '' if error
1637 var cmd,RPCResult : string;
1638 begin
1639 Result := '';
1640 RPCBrokerV.remoteprocedure := 'TMG CHANNEL';
1641 RPCBrokerV.param[0].ptype := list;
1642 cmd := 'CLONE USER' + '^' + SourceIENS + '^' + New01Field;
1643 RPCBrokerV.Param[0].Mult['"REQUEST"'] := cmd;
1644 RPCBrokerV.Call;
1645 RPCResult := RPCBrokerV.Results[0]; //returns: error: -1^ShortMsg; success=1^Success^NewIENS
1646 if piece(RPCResult,'^',1)='-1' then begin
1647 FMErrorForm.Memo.Lines.Assign(RPCBrokerV.Results);
1648 FMErrorForm.PrepMessage;
1649 FMErrorForm.ShowModal;
1650 end else begin
1651 result := piece(RPCResult,'^',3);
1652 end;
1653 end;
1654
1655 function TMainForm.FieldHelp(FileNum, FieldNum, HelpStyle : string) : string;
1656 var
1657 RPCResult: string;
1658 cmd : string;
1659 SrchStr : string;
1660 Idx : integer;
1661 begin
1662 Result := '';
1663 SrchStr := FileNum + '^' + FieldNum + '^' + HelpStyle;
1664 Idx := CachedHelpIdx.IndexOf(SrchStr);
1665 if Idx = -1 then begin
1666 RPCBrokerV.remoteprocedure := 'TMG CHANNEL';
1667 RPCBrokerV.param[0].ptype := list;
1668 cmd := 'GET HELP MSG^' + SrchStr;
1669 RPCBrokerV.Param[0].Mult['"REQUEST"'] := cmd;
1670 RPCBrokerV.Call;
1671 RPCResult := RPCBrokerV.Results[0]; //returns: error: -1; success=1
1672 if piece(RPCResult,'^',1)='-1' then begin
1673 FMErrorForm.Memo.Lines.Assign(RPCBrokerV.Results);
1674 FMErrorForm.PrepMessage;
1675 FMErrorForm.ShowModal;
1676 end else begin
1677 RPCBrokerV.Results.Delete(0);
1678 if RPCBrokerV.Results.Strings[RPCBrokerV.Results.Count-1]='' then begin
1679 RPCBrokerV.Results.Delete(RPCBrokerV.Results.Count-1);
1680 end;
1681 result := RPCBrokerV.Results.Text;
1682 //Maybe later replace text with "Enter F1 for more help."
1683 Result := AnsiReplaceText(Result,'Enter ''??'' for more help.','');
1684 while Result[Length(Result)] in [#10,#13] do begin
1685 Result := AnsiLeftStr(Result,Length(Result)-1);
1686 end;
1687 Idx := CachedHelp.Add(result);
1688 CachedHelpIdx.AddObject(SrchStr,Pointer(Idx)); //Store index here to help stored in CachedHelp
1689 end;
1690 end else begin
1691 Idx := Integer(CachedHelpIdx.Objects[Idx]);
1692 if (Idx >= 0) and (Idx < CachedHelp.Count) then begin
1693 result := CachedHelp.Strings[Idx];
1694 end;
1695 end;
1696 end;
1697
1698 function TMainForm.GetGridHint(Grid : TStringGrid; FileNum : string; ACol, ARow : integer) : string;
1699 var fieldNum : string;
1700 begin
1701 Result := '';
1702 //Result := 'Row=' + IntToStr(ARow) + ', Col='+ IntToStr(ACol);
1703 if ARow > Grid.RowCount-1 then exit;
1704 if (ARow < 0) or (ACol < 0) then exit;
1705 if ACol=0 then begin
1706 Result := 'This is the database field NUMBER';
1707 end else if ACol=1 then begin
1708 Result := 'This is the database field NAME';
1709 end else begin
1710 fieldNum := Grid.Cells[0,ARow];
1711 if Grid.Cells[ACol,ARow]=CLICK_FOR_SUBS then begin
1712 result := 'Clicking will open new window...';
1713 end else if Grid.Cells[ACol,ARow]=COMPUTED_FIELD then begin
1714 result := 'This field can''t be edited';
1715 end else if Grid.Cells[ACol,ARow]=HIDDEN_FIELD then begin
1716 result := 'Original value hidden. Click to edit new value.';
1717 end else if Grid.Cells[ACol,ARow]=CLICK_TO_EDIT then begin
1718 result := 'Clicking will open new window...';
1719 end else begin
1720 Result := FieldHelp(FileNum, fieldNum, '?');
1721 end;
1722 end;
1723 end;
1724
1725
1726 procedure TMainForm.ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
1727 begin
1728 end; (*ApplicationIdle*)
1729
1730
1731 procedure TMainForm.ApplicationEventsShowHint(var HintStr: String;
1732 var CanShow: Boolean;
1733 var HintInfo: THintInfo);
1734 var
1735 Pos : TPoint;
1736 Handle : Hwnd;
1737 ItemBuffer : array[0..256] of Char;
1738 ClassName : AnsiString;
1739 ACol,ARow : integer;
1740 VisibleGridInfo : TGridInfo;
1741 begin
1742 CanShow := true;
1743 //Label2.Caption := HintStr;
1744 Pos := Mouse.CursorPos;
1745 Handle := WindowFromPoint(Pos);
1746 if Handle = 0 then Exit;
1747 GetClassName(Handle, ItemBuffer, SizeOf(ItemBuffer));
1748 ClassName := ItemBuffer;
1749 Windows.ScreenToClient(Handle, Pos);
1750 VisibleGridInfo := GetVisibleGridInfo;
1751 if VisibleGridInfo = nil then exit;
1752 if VisibleGridInfo.Grid = nil then exit;
1753 if (ClassName='TStringGrid') then begin
1754 VisibleGridInfo.Grid.MouseToCell(Pos.X,Pos.Y,ACol,ARow);
1755 HintInfo.HintStr := GetGridHint(VisibleGridInfo.Grid,VisibleGridInfo.FileNum,ACol, ARow);
1756 if HintInfo.HintStr = '' then CanShow := False;
1757 HintInfo.HideTimeout := 1000;
1758 HintInfo.ReshowTimeout := 2000;
1759 HintInfo.HintMaxWidth:= 300; //hint box width.
1760 end;
1761
1762 end;
1763
1764 procedure TMainForm.PageControlChanging(Sender: TObject; var AllowChange: Boolean);
1765 begin
1766 AllowChange := (PostVisibleGrid <> mrNO);
1767 if AllowChange then begin
1768 LastSelTreeNode := nil;
1769 end;
1770 end;
1771
1772 procedure TMainForm.PatientORComboBoxNeedData(Sender: TObject;
1773 const StartFrom: String; Direction, InsertAt: Integer);
1774 var
1775 Result : TStrings;
1776 begin
1777 Result := FieldLookUpForm.SubSetOfFile('2', StartFrom, Direction);
1778 TORComboBox(Sender).ForDataUse(Result);
1779 end;
1780
1781
1782 procedure TMainForm.PageControlChange(Sender: TObject);
1783 begin
1784 if (PageControl.ActivePage = tsUsers) then begin
1785 UserPageControlChange(nil);
1786 end else if (PageControl.ActivePage = tsSettings) then begin
1787 SettingsPageControlChange(nil);
1788 end else if (PageControl.ActivePage = tsPatients) then begin
1789 PatientsPageControlChange(nil);
1790 end else if (PageControl.ActivePage = tsAdvanced) then begin
1791 SetVisibleGridIdx(AnyFileGrid);
1792 end;
1793
1794 end;
1795
1796 procedure TMainForm.PatientORComboBoxClick(Sender: TObject);
1797 var IEN : longInt;
1798 ModalResult : TModalResult;
1799 GridInfo : TGridInfo;
1800 begin
1801 ModalResult := PostVisibleGrid;
1802 if ModalResult = mrNo then exit;
1803 IEN := PatientORComboBox.ItemIEN; //get info from selected patient
1804 if IEN = 0 then exit;
1805 GridInfo := GetInfoForGrid(BasicPatientGrid);
1806 if GridInfo = nil then exit;
1807 GridInfo.IENS := IntToStr(IEN)+',';
1808 GetPatientInfo(GridInfo);
1809 end;
1810
1811 procedure TMainForm.PatientsPageControlChanging(Sender: TObject; var AllowChange: Boolean);
1812 begin
1813 AllowChange := (PostVisibleGrid <> mrNO);
1814 end;
1815
1816 procedure TMainForm.PatientsPageControlChange(Sender: TObject);
1817 begin
1818 if PatientsPageControl.ActivePage = tsBasicPatients then begin
1819 SetVisibleGridIdx(BasicPatientGrid);
1820 end else begin
1821 SetVisibleGridIdx(AdvancedPatientGrid);
1822 end;
1823 end;
1824
1825
1826 procedure TMainForm.UserPageControlChanging(Sender: TObject; var AllowChange: Boolean);
1827 var result : TModalResult;
1828 begin
1829 result := PostVisibleGrid;
1830 AllowChange := (result <> mrNO);
1831 if (result <> mrNone) then begin
1832 InitializeUsersTreeView;
1833 end;
1834 end;
1835
1836 procedure TMainForm.UserPageControlChange(Sender: TObject);
1837 begin
1838 if SettingsPageControl.ActivePage = tsBasicSettings then begin
1839 SetVisibleGridIdx(BasicUsersGrid);
1840 end else begin
1841 SetVisibleGridIdx(AdvancedUsersGrid);
1842 end;
1843 end;
1844
1845
1846 procedure TMainForm.SettingsPageControlChanging(Sender: TObject; var AllowChange: Boolean);
1847 begin
1848 AllowChange := (PostVisibleGrid <> mrNO);
1849 end;
1850
1851 procedure TMainForm.SettingsPageControlChange(Sender: TObject);
1852 begin
1853 if SettingsPageControl.ActivePage = tsBasicSettings then begin
1854 SetVisibleGridIdx(BasicSettingsGrid);
1855 end else begin
1856 SetVisibleGridIdx(AdvancedSettingsGrid);
1857 end;
1858 end;
1859
1860 procedure TMainForm.FileORComboBoxClick(Sender: TObject);
1861 begin
1862 PostVisibleGrid;
1863 InitORCombobox(RecordORComboBox,'');
1864 ClearGrid(GetVisibleGrid);
1865 end;
1866
1867 procedure TMainForm.FileORComboBoxNeedData(Sender: TObject; const StartFrom: String; Direction, InsertAt: Integer);
1868 var Result : TStrings;
1869 begin
1870 Result := FieldLookUpForm.SubSetOfFile('1', StartFrom, Direction);
1871 TORComboBox(Sender).ForDataUse(Result);
1872 end;
1873
1874
1875 procedure TMainForm.RecordORComboBoxNeedData(Sender: TObject; const StartFrom: String; Direction, InsertAt: Integer);
1876 var Result : TStrings;
1877 FileNum : string;
1878 begin
1879 FileNum := FileORComboBox.ItemID;
1880 Result := FieldLookUpForm.SubSetOfFile(FileNum, StartFrom, Direction);
1881 TORComboBox(Sender).ForDataUse(Result);
1882 end;
1883
1884 procedure TMainForm.RecordORComboBoxClick(Sender: TObject);
1885 var ModalResult : TModalResult;
1886 IEN : LongInt;
1887 FileNum : String;
1888 GridInfo : TGridInfo;
1889 begin
1890 ModalResult := PostVisibleGrid;
1891 if ModalResult = mrNo then exit;
1892 FileNum := FileORComboBox.ItemID;
1893 IEN := RecordORComboBox.ItemID; //get info from selected record
1894 if IEN=0 then exit;
1895 GridInfo := GetInfoForGrid(AnyFileGrid);
1896 if GridInfo = nil then exit;
1897 GridInfo.IENS := IntToStr(IEN) + ',';
1898 GridInfo.FileNum := FileNum;
1899 GetAnyfileInfo(GridInfo);
1900 //GetAnyfileInfo(FileNum,IntToStr(IEN)+',',CurrentAnyFileData);
1901 end;
1902
1903 procedure TMainForm.btnAddAnyRecordClick(Sender: TObject);
1904 var IENS, FileNum : string;
1905 BlankFileInfo : TStringList;
1906 begin
1907 BlankFileInfo := Tstringlist.Create;
1908 btnAdvancedRevert.Enabled := True;
1909 btnAdvancedApply.Enabled := True;
1910 FileNum := FileORComboBox.ItemID;
1911 IENS := '+1,';
1912 GetOneRecord(FileNum,IENS,CurrentAnyFileData, BlankFileInfo);
1913
1914 LoadAnyGridFromInfo(GetInfoForGrid(AnyFileGrid));
1915 BlankFileInfo.Free;
1916 end;
1917
1918 procedure TMainForm.AddBtnClick(Sender: TObject);
1919 var IENS : string;
1920 BlankFileInfo : TStringList;
1921 GridInfo : TGridInfo;
1922 begin
1923 BlankFileInfo := Tstringlist.Create;
1924 btnPatientRevert.Enabled := True;
1925 btnPatientApply.Enabled := True;
1926 GridInfo := GetVisibleGridInfo;
1927 IENS := '+1,';
1928 GetOneRecord(GridInfo.FileNum, IENS, GridInfo.Data, BlankFileInfo);
1929 GridInfo.IENS := IENS;
1930 LoadAnyGridFromInfo(GridInfo); //load Basic or Advanced Grid
1931 if GridInfo.Grid = BasicPatientGrid then begin
1932 GridInfo := GetInfoForGrid(AdvancedPatientGrid)
1933 end else begin //Advanced grid is visible.
1934 GridInfo := GetInfoForGrid(BasicPatientGrid)
1935 end;
1936 GridInfo.IENS := IENS;
1937 LoadAnyGridFromInfo(GridInfo); // Load OTHER grid, Advanced or Basic grid.
1938 BlankFileInfo.Free;
1939 end;
1940
1941 procedure TMainForm.btnAdvancedApplyClick(Sender: TObject);
1942 begin
1943 PostVisibleGrid;
1944 end;
1945
1946 procedure TMainForm.btnAdvancedRevertClick(Sender: TObject);
1947 //var tempInfo: TGridInfo;
1948 begin
1949 DoRevert(nil,AnyFileGrid);
1950 {
1951 tempInfo := GetInfoForGrid(AnyFileGrid);
1952 LoadAnyGridFromInfo(tempInfo);
1953 tempInfo.ApplyBtn.Enabled := false;
1954 tempInfo.RevertBtn.Enabled := false;
1955 }
1956 end;
1957
1958 procedure TMainForm.AnyFileGridClick(Sender: TObject);
1959 begin
1960 btnAdvancedApply.Enabled := True;
1961 btnAdvancedRevert.Enabled := True;
1962 end;
1963
1964 procedure TMainForm.btnBatchAddClick(Sender: TObject);
1965 begin
1966 BatchAddForm.ShowModal;
1967 InitORCombobox(PatientORComboBox,'A');
1968 end;
1969
1970 procedure TMainForm.ChangeSkinClick(Sender: TObject);
1971 var result : TModalResult;
1972 begin
1973 try
1974 result := SkinForm.ShowModal;
1975 case result of
1976 mrOK : SkinForm.ActivateCurrentSkin;
1977 mrNo : SkinForm.InactivateSkin;
1978 end; {case}
1979 except
1980 on EInvalidOperation do MessageDlg('Error1',mtInformation,[mbOK],0);
1981 else MessageDlg('Error Applying Skin. Please try another Skin.',mtInformation,[mbOK],0);
1982 end;
1983 end;
1984
1985 procedure TMainForm.InitORComboBox(ORComboBox: TORComboBox; initValue : string);
1986 begin
1987 ORComboBox.Items.Clear;
1988 ORComboBox.Text := initValue;
1989 ORComboBox.InitLongList(initValue);
1990 if ORComboBox.Items.Count > 0 then begin
1991 ORComboBox.Text := Piece(ORComboBox.Items[0],'^',2);
1992 end else begin
1993 ORComboBox.Text := '<Start Typing to Search>';
1994 end;
1995 end;
1996
1997
1998 procedure TMainForm.btnPatientApplyClick(Sender: TObject); //Added elh 8/15/08
1999 begin
2000 PostVisibleGrid;
2001 InitORCombobox(PatientORComboBox,'A');
2002 end;
2003
2004 procedure TMainForm.btnPatientRevertClick(Sender: TObject); //Added elh 8/15/08
2005 //var tempInfo : TGridInfo;
2006 begin
2007 DoRevert(BasicUsersGrid,AdvancedUsersGrid);
2008 {
2009 tempInfo := GetInfoForGrid(AdvancedUsersGrid);
2010 LoadAnyGridFromInfo(tempInfo);
2011
2012 tempInfo := GetInfoForGrid(BasicUsersGrid);
2013 LoadAnyGridFromInfo(tempInfo);
2014
2015 tempInfo.ApplyBtn.Enabled := false;
2016 tempInfo.RevertBtn.Enabled := false;
2017 }
2018 end;
2019
2020 procedure TMainForm.BasicPatientGridClick(Sender: TObject); //Added elh 8/15/08
2021 begin
2022 btnPatientRevert.Enabled := true;
2023 btnPatientApply.Enabled := true;
2024 end;
2025
2026 Procedure TMainForm.GetBlankFileInfo(FileNum : string; BlankList : TStringList);
2027 var RPCResult: string;
2028 //Returned format for BlankList is:
2029 //FileNum^^FieldNum^^FieldName^More DDInfo
2030 //FileNum^^FieldNum^^FieldName^More DDInfo
2031 begin
2032 RPCBrokerV.remoteprocedure := 'TMG CHANNEL';
2033 RPCBrokerV.Param[0].Value := '.X'; // not used
2034 RPCBrokerV.param[0].ptype := list;
2035 RPCBrokerV.Param[0].Mult['"REQUEST"'] := 'GET EMPTY ENTRY^' + FileNum;
2036 RPCBrokerV.Call;
2037 RPCResult := RPCBrokerV.Results[0]; //returns: error: -1; success=1
2038 //Return Format is: FileNum^^FieldNum^^DDInfo...
2039 if piece(RPCResult,'^',1)='-1' then begin
2040 FMErrorForm.Memo.Lines.Assign(RPCBrokerV.Results);
2041 FMErrorForm.PrepMessage;
2042 FMErrorForm.ShowModal;
2043 end else begin
2044 BlankList.Assign(RPCBrokerV.Results);
2045 end;
2046 end;
2047
2048
2049 procedure TMainForm.GetOneRecord(FileNum, IENS : string; Data, BlankFileInfo: TStringList);
2050 var cmd,RPCResult : string;
2051 i : integer;
2052 oneEntry : string;
2053 begin
2054 Data.Clear;
2055 if (IENS='') then exit;
2056 if Pos('+',IENS)=0 then begin //don't ask server to load +1 records.
2057 RPCBrokerV.remoteprocedure := 'TMG CHANNEL';
2058 RPCBrokerV.Param[0].Value := '.X'; // not used
2059 RPCBrokerV.param[0].ptype := list;
2060 cmd := 'GET ONE RECORD^' + FileNum + '^' + IENS;
2061 RPCBrokerV.Param[0].Mult['"REQUEST"'] := cmd;
2062 RPCBrokerV.Call;
2063 RPCResult := RPCBrokerV.Results[0]; //returns: error: -1; success=1
2064 if piece(RPCResult,'^',1)='-1' then begin
2065 FMErrorForm.Memo.Lines.Assign(RPCBrokerV.Results);
2066 FMErrorForm.PrepMessage;
2067 FMErrorForm.ShowModal;
2068 end else begin
2069 Data.Assign(RPCBrokerV.Results);
2070 end;
2071 end else begin
2072 Data.Add('1^Success'); //to keep same as call to server
2073 if BlankFileInfo.Count = 0 then begin
2074 //Format is: FileNum^^FieldNum^^DDInfo...
2075 GetBlankFileInfo(FileNum,BlankFileInfo);
2076 end;
2077 for i := 1 to BlankFileInfo.Count-1 do begin //0 is 1^success
2078 oneEntry := BlankFileInfo.Strings[i];
2079 SetPiece(oneEntry,'^',2,IENS);
2080 Data.Add(oneEntry);
2081 end;
2082 end;
2083 end;
2084
2085
2086 procedure TMainForm.ApplicationEventsException(Sender: TObject; E: Exception);
2087 begin
2088 if E.Message <> 'Cannot focus a disabled or invisible window' then begin
2089 ShowException(E,nil);
2090 end;
2091 end;
2092
2093
2094 procedure TMainForm.btnSettingsRevertClick(Sender: TObject);
2095 //var tempInfo : TGridInfo;
2096 begin
2097 DoRevert(BasicSettingsGrid,AdvancedSettingsGrid);
2098 {
2099 tempInfo := GetInfoForGrid(BasicSettingsGrid);
2100 LoadAnyGridFromInfo(tempInfo);
2101
2102 tempInfo := GetInfoForGrid(AdvancedSettingsGrid);
2103 LoadAnyGridFromInfo(tempInfo);
2104
2105 tempInfo.ApplyBtn.Enabled := false;
2106 tempInfo.RevertBtn.Enabled := false;
2107 }
2108 end;
2109
2110
2111 procedure TMainForm.DoRevert(BasicGrid,AdvancedGrid : TStringGrid);
2112 //BasicGrid doesn't have to be supplied. Can be nil value.
2113 //AdvancedGrid is required.
2114 var tempInfo : TGridInfo;
2115 begin
2116 tempInfo := GetInfoForGrid(AdvancedGrid);
2117 LoadAnyGridFromInfo(tempInfo);
2118 tempInfo.ApplyBtn.Enabled := false;
2119 tempInfo.RevertBtn.Enabled := false;
2120
2121 if BasicGrid <> nil then begin
2122 tempInfo := GetInfoForGrid(BasicGrid);
2123 LoadAnyGridFromInfo(tempInfo);
2124 end;
2125 end;
2126
2127
2128 procedure TMainForm.btnSettingsApplyClick(Sender: TObject);
2129 begin
2130 PostVisibleGrid;
2131 end;
2132
2133end.
2134
Note: See TracBrowser for help on using the repository browser.