source: cprs/branches/ScanSourceForConstants/SrcScannerU.pas@ 1536

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

Initial upload of Multi-language support appt: ScanSourceForConstants

File size: 20.6 KB
Line 
1unit SrcScannerU;
2
3interface
4
5uses
6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
7 Dialogs, StdCtrls, Buttons, ExtCtrls, ComCtrls, Menus;
8
9const
10 SIGNIF_LEN = 3;
11 MODIFIED_STRING = '//kt -- Modified with SourceScanner on ';
12
13type
14 TMainForm = class(TForm)
15 Panel1: TPanel;
16 Splitter1: TSplitter;
17 Panel2: TPanel;
18 Panel4: TPanel;
19 Panel5: TPanel;
20 Panel3: TPanel;
21 Panel6: TPanel;
22 SaveButton: TBitBtn;
23 OpenButton: TBitBtn;
24 NextButton: TBitBtn;
25 PrevButton: TBitBtn;
26 OpenDialog1: TOpenDialog;
27 Label1: TLabel;
28 Label2: TLabel;
29 SaveAsButton: TBitBtn;
30 SaveDialog1: TSaveDialog;
31 FileNameLabel: TLabel;
32 ChangesLabel: TLabel;
33 ConstantsButton: TBitBtn;
34 DoneBtn: TBitBtn;
35 OrigEdit: TMemo;
36 NewEdit: TMemo;
37 BitBtn1: TBitBtn;
38 MainMenu1: TMainMenu;
39 File1: TMenuItem;
40 Done1: TMenuItem;
41 Report1: TMenuItem;
42 ReportSourceChanges1: TMenuItem;
43 procedure OpenButtonClick(Sender: TObject);
44 procedure SpeedButton1Click(Sender: TObject);
45 procedure SaveButtonClick(Sender: TObject);
46 procedure FormCreate(Sender: TObject);
47 procedure NextButtonClick(Sender: TObject);
48 procedure PrevButtonClick(Sender: TObject);
49 procedure DoneBtnClick(Sender: TObject);
50 procedure FormClose(Sender: TObject; var Action: TCloseAction);
51 procedure BitBtn1Click(Sender: TObject);
52 procedure ReportSourceChanges1Click(Sender: TObject);
53 private
54 { Private declarations }
55 FileModuleName : string;
56 FName : string;
57 dateStr : string;
58 FileList: TStringList;
59 FileListIndex :integer;
60 NewEditText : AnsiString;
61 ChangeNum : integer;
62 function OpenInputFile(FName : string) : integer;
63 function CloseCurFiles : integer;
64 procedure ProcessFile;
65 function HasSignifStr(s: string) : boolean;
66 procedure ConvertCodeLine(var s:string;var constSName,constStr : string);
67 function MakeConstName(Module,s : string) : string;
68 function DoSave : integer;
69 procedure SetChangesNum(Num: integer);
70 function AlreadyEdited : Boolean;
71 procedure HandleConstSection;
72 procedure ShutDown;
73 public
74 { Public declarations }
75 end;
76
77var
78 MainForm: TMainForm;
79
80function Piece(const S: string; Delim: char; PieceNum: Integer): string;
81
82implementation
83
84{$R *.dfm}
85
86uses StrUtils,ShowConstsU, WorkingSplashU,ReviewChangesU, SearchMissingU;
87
88
89function Piece(const S: string; Delim: char; PieceNum: Integer): string;
90{ returns the Nth piece (PieceNum) of a string delimited by Delim }
91var
92 i: Integer;
93 Strt, Next: PChar;
94begin
95 i := 1;
96 Strt := PChar(S);
97 Next := StrScan(Strt, Delim);
98 while (i < PieceNum) and (Next <> nil) do
99 begin
100 Inc(i);
101 Strt := Next + 1;
102 Next := StrScan(Strt, Delim);
103 end;
104 if Next = nil then Next := StrEnd(Strt);
105 if i < PieceNum then Result := '' else SetString(Result, Strt, Next - Strt);
106end;
107
108
109
110
111procedure TMainForm.OpenButtonClick(Sender: TObject);
112begin
113 dateStr := DateToStr(Date);
114 if OpenDialog1.Execute then begin
115 FileList.Assign(OpenDialog1.Files);
116 FileListIndex:=-1;
117 NextButtonClick(nil);
118 end;
119end;
120
121procedure TMainForm.NextButtonClick(Sender: TObject);
122var Result : integer;
123begin
124 CloseCurFiles;
125 repeat
126 FileListIndex:=FileListIndex+1;
127 if FileListIndex<FileList.Count then begin
128 FName := FileList.Strings[FileListIndex];
129 Result := OpenInputFile(FName);
130 if Result = mrCancel then FileListIndex:=FileListIndex-1;
131 end else begin
132 FileListIndex:=FileListIndex-1;
133 //Result := MessageDlg('No "Next" file to select.', mtError, [mbOK], 0);
134 Result := 0;
135 end;
136 until Result <> -1;
137end;
138
139
140procedure TMainForm.PrevButtonClick(Sender: TObject);
141var Result : integer;
142begin
143 FileListIndex:=FileListIndex-1;
144 if FileListIndex>-1 then begin
145 FName := FileList.Strings[FileListIndex];
146 Result := OpenInputFile(FName);
147 if Result = mrCancel then FileListIndex:=FileListIndex+1;
148 end else begin
149 FileListIndex:=FileListIndex+1;
150 MessageDlg('No "Previous" file to select.', mtError, [mbOK], 0);
151 end;
152end;
153
154function TMainForm.OpenInputFile(FName : string) : integer;
155var BakFName : string;
156 UserChoice : integer;
157begin
158 Result := CloseCurFiles;
159 if result <> mrCancel then begin
160 FileNameLabel.Caption:= ExtractFileName(FName);
161 FileModuleName := AnsiReplaceStr(FileNameLabel.Caption, '.pas', '');
162 FileModuleName := AnsiReplaceStr(FileModuleName, ' ', '_');
163
164 OrigEdit.Lines.LoadFromFile(FName); //does a clear first
165 UserChoice := mrYes;
166 if AlreadyEdited then Begin
167 UserChoice := MessageDlg(FName + #10+#10+#13 + 'File already processed. Process AGAIN?',mtConfirmation, mbYesNoCancel,0);
168 end;
169 if UserChoice=mrYes then begin
170 BakFName:=FName + '.bak';
171 OrigEdit.Lines.SaveToFile(BakFName); //make an immediate copy
172 ProcessFile;
173 end else if (UserChoice=mrNo) or (UserChoice=mrCancel) then begin
174 if userChoice=mrCancel then Result := -2
175 else Result := -1;
176 CloseCurFiles;
177 //OrigEdit.Lines.Clear;
178 Application.ProcessMessages;
179 end;
180 end;
181end;
182
183function TMainForm.AlreadyEdited : Boolean;
184begin
185 Result := false;
186 if OrigEdit.Lines.Count>0 then begin
187 Result := (Pos(MODIFIED_STRING,OrigEdit.Lines.Strings[0])>0);
188 end;
189end;
190
191function TMainForm.CloseCurFiles : integer;
192begin
193 //check if should be saved.
194 Result := DoSave;
195 if Result <> mrCancel then begin
196 NewEdit.Lines.Clear;
197 end;
198 SetChangesNum(0);
199 OrigEdit.Lines.Clear;
200 FileNameLabel.Caption := '';
201end;
202
203procedure TMainForm.ProcessFile;
204var i,j,tempI : integer;
205 tempS,s : string;
206 UserChoice: integer;
207 constSName,constStr : string;
208 FromList,ToList : TStringList;
209 Abort : boolean;
210
211begin
212 WorkingForm.visible := true;
213 Application.ProcessMessages;
214
215 FromList := TStringList.Create;
216 ToList := TStringList.Create;
217
218 NewEdit.Visible := False;
219 NewEdit.Lines.Add(MODIFIED_STRING+DateStr);
220
221 //collect possible changes. -- finish later
222 for i:=0 to OrigEdit.Lines.Count-1 do begin
223 s := OrigEdit.Lines.Strings[i];
224 if HasSignifStr(s) then begin
225 tempS := s;
226 ConvertCodeLine(s,constSName,constStr); //s can be modified
227 if tempS<>s then begin
228 FromList.Add(tempS);
229 ToList.Add(s);
230 end
231 end;
232 end;
233
234 ReviewChangesForm.CheckListBox1.Items.Clear;
235 for i := 0 to FromList.Count-1 do begin
236 ReviewChangesForm.CheckListBox1.Items.Add(FromList.Strings[i]);
237 ReviewChangesForm.CheckListBox1.Checked[i]:= true;
238 end;
239
240 Abort := false;
241 if FromList.Count > 0 then begin
242 Abort := (ReviewChangesForm.ShowModal = mrCancel); //let user deselect some lines
243 end;
244 if Abort then exit;
245
246 for i:=0 to OrigEdit.Lines.Count-1 do begin
247 s := OrigEdit.Lines.Strings[i];
248 if HasSignifStr(s) then begin
249 tempS := s;
250 ConvertCodeLine(s,constSName,constStr); //s can be modified
251 if tempS<>s then begin
252 tempI := FromList.IndexOf(tempS);
253 if (tempI > -1) then begin
254 if ReviewChangesForm.CheckListBox1.Checked[tempI] = true then begin
255 for j:=1 to 2 do if MidStr(tempS,1,1)=' ' then tempS:=MidStr(tempS,2,999);
256 tempS := '//'+tempS+ ' <-- original line. //kt '+ dateStr;
257 NewEdit.Lines.Add(tempS);
258 ConstantsOutputForm.AddConst(constSName,constStr);
259 SetChangesNum(ChangeNum+1);
260 end else begin
261 s := tempS;
262 end;
263 end else begin
264 s := tempS;
265 end;
266 (*
267 UserChoice := MessageDlg('Convert original line:'+#10+#13#13+
268 tempS+#10+#13#13+'To:'+#10+#13#13+s,mtConfirmation,mbYesNoCancel,0);
269 if UserChoice=mrYes then begin
270 for j:=1 to 2 do if MidStr(tempS,1,1)=' ' then tempS:=MidStr(tempS,2,999);
271 tempS := '//'+tempS+ ' <-- original line. //kt '+ dateStr;
272 NewEdit.Lines.Add(tempS);
273 ConstantsOutputForm.AddConst(constSName,constStr);
274 SetChangesNum(ChangeNum+1);
275 end else if UserChoice=mrNo then begin
276 s := tempS;
277 end;
278 *)
279 end
280 end;
281 NewEdit.Lines.Add(s);
282 end;
283 HandleConstSection;
284 WorkingForm.visible := false;
285 NewEdit.Visible := True;
286 FromList.Free;
287 ToList.Free;
288end;
289
290procedure TMainForm.SetChangesNum(Num: integer);
291begin
292 ChangeNum := Num;
293 ChangesLabel.Caption := IntToStr(ChangeNum) + ' Changes.';
294end;
295
296function TMainForm.HasSignifStr(s: string) : boolean;
297var p1,p2 : integer;
298 tempS : string;
299
300begin
301 Result := false;
302 s := AnsiReplaceStr(s, '''''', ''); // convert '' --> null
303 //screen for "//" style comments
304 if Pos('//',s)>0 then begin //ignore text after comments
305 p1 := Pos('//',s);
306 s := MidStr(s,1,p1-1);
307 end;
308 p1 := 0;
309 repeat
310 p1 := PosEx('''',s,p1+1);
311 if (p1>0) and ((midstr(s,p1,2)<>'\"')) then begin
312 p2 := PosEx('''',s,p1+1);
313 if (p2-p1-1)>=SIGNIF_LEN then begin
314 tempS:=midstr(s,p1,p2-p1);
315 if (Pos('mmm',tempS)=0) and (Pos('yyy',tempS)=0) //skip date formatting strings
316 and (Pos('ddd',tempS)=0)
317 and (tempS<>UpperCase(tempS)) then begin //skip all string that are COMPLETELY UPPER CASE
318 Result:= true;
319 end;
320 end;
321 p1:=p2;
322 end;
323 until (p1=0) or (Result=true);
324end;
325
326
327procedure TMainForm.ConvertCodeLine(var s:string;var constSName,constStr : string);
328var
329 origS, tempS : string;
330 //constStr,constSName: string;
331 p1,p2:integer;
332begin
333 origS:=s;
334 while Pos('''''',s)>0 do begin
335 s := AnsiReplaceStr(s, '''''', '\"'); // convert '' --> \"
336 end;
337 p1 := 0;
338 repeat
339 p1 := PosEx('''',s,p1+1);
340 if (p1>0) and ((midstr(s,p1,2)<>'\"')) then begin
341 p2 := PosEx('''',s,p1+1);
342 if (p2-p1-1)>=SIGNIF_LEN then begin
343 //create dkLang constant name & value
344 constStr := AnsiMidStr(s, p1+1, (p2-p1-1));
345 constStr := AnsiReplaceStr(constStr, '\"', ''''''); // convert '\"' --> ''
346 constSName := MakeConstName(FileModuleName,constStr);
347 //ConstantsOutputForm.AddConst(constSName,constStr);
348 tempS := AnsiMidStr(s, 1, p1-1)+ 'DKLangConstW(''' + constSName + ''')';
349 s := tempS + AnsiMidStr(s, p2+1, 999);
350 p1 := length(tempS)+1;
351 end else p1:=p2+1
352 end;
353 until (p1=0);
354
355 s := AnsiReplaceStr(s, '\"', ''''''); // convert '\"' --> ''
356 s := s+ ' //kt added ' +dateStr;
357end;
358
359function TMainForm.MakeConstName(Module,s : string) : string;
360var i : integer;
361begin
362 s := Trim(s);
363 s := AnsiReplaceStr(s, ' ', '_');
364 i:=1;
365 while not (i>Length(s)) do begin
366 if not (s[i] in [' ','0'..'9','A'..'Z','a'..'z','_']) then begin
367 //Delete(s, i,1); //remove illegal characters.
368 s[i]:='x' //convert illegal chars to x. If just delete, leads to name conflicts
369 end;
370 //end else i:=i+1;
371 i:=i+1;
372 end;
373 Result := FileModuleName + '_' + s;
374end;
375
376procedure TMainForm.SpeedButton1Click(Sender: TObject);
377begin
378 ConstantsOutputForm.Show;
379end;
380
381procedure TMainForm.SaveButtonClick(Sender: TObject);
382begin
383 DoSave;
384end;
385
386function TMainForm.DoSave : integer;
387begin
388 ConstantsOutputForm.SaveButtonClick(nil);
389 Result := mrYes;
390 if (NewEdit.Lines.Count>0) and (NewEdit.Lines.Text<>NewEditText) then begin
391 Result := MessageDlg('Save Modified Source Code?' + #10+#13 +
392 '(Original saved as .bak file)',mtConfirmation, [mbYes, mbNo, mbCancel],0);
393 if Result = mrYes then begin
394 NewEdit.Lines.SaveToFile(FName);
395 NewEditText:=NewEdit.Lines.Text;
396 end;
397 end else begin
398 //MessageDlg('Nothing to save!', mtInformation, [mbOK], 0);
399 end;
400end;
401
402
403procedure TMainForm.FormCreate(Sender: TObject);
404begin
405 FileList := TStringList.Create;
406 ChangeNum := 0;
407
408end;
409
410procedure TMainForm.DoneBtnClick(Sender: TObject);
411var Result : word;
412begin
413 ShutDown;
414 Application.Terminate;
415end;
416
417
418Procedure TMainForm.HandleConstSection;
419(* Note this is targeted for CPRS code, and the constants
420 section comes after the implementation keyword
421*)
422
423var
424 i,j,p1,p2 : integer;
425 found : boolean;
426 tempS : string;
427 constStart,constEnd : integer;
428 classStartLine,privateStartLine : integer;
429 ConstList : TStringList;
430 newProcList : TStringList;
431 varList : TStringList;
432 className :string;
433 maxLen : integer;
434 startI,endI : integer;
435 implementationStartI : integer;
436
437 function IsProcFn(s : string) : boolean;
438 //return if line contains a procedure or function declaration
439 begin
440 Result := false;
441 s := UpperCase(s);
442 if pos ('//',s)>0 then begin
443 s := MidStr(s,1,pos('//',s)-1);
444 end;
445 if (pos('PROCEDURE',s)>0) or (pos('FUNCTION',s)>0) then result := true;
446 end;
447
448 procedure FindProcFn(searchStartI : integer; var startI,endI: integer);
449 //start as searchStartI and look for 'procedure' or 'function'
450 //If found, then look for next iteration or end of file.
451 //results returned in startI and endI (OUT parameters)
452 var i : integer;
453 startFound: boolean;
454 tempS : string;
455 begin
456 endI := NewEdit.Lines.Count-1;
457 startI := endI;
458 startFound := false;
459 for i:= searchStartI to NewEdit.Lines.Count-1 do begin
460 tempS := NewEdit.Lines.Strings[i];
461 if IsProcFn(tempS) then begin
462 if startFound = false then begin
463 startFound := true;
464 startI := i;
465 end else begin
466 endI := i-1;
467 break;
468 end;
469 end;
470 end;
471 end;
472
473 function ContainsConst(startI,endI : integer) : boolean;
474 //scan code and see if any reference is made to new vars (substituted for consts)
475 var i,j : integer;
476 tempS : string;
477 begin
478 Result := false;
479 for i := startI to endI do begin
480 tempS := UpperCase(NewEdit.Lines.Strings[i]);
481 for j := 0 to ConstList.Count-1 do begin
482 if pos(ConstList.Strings[j],tempS)>0 then begin
483 Result := true;
484 break;
485 end;
486 end;
487 if Result = true then break;
488 end;
489 end;
490
491 procedure InsertSetupVars(startI : integer);
492 //insert 'SetupVars' into line directly after first 'begin'
493 //Note: this will fail if code has imbedded procedures (which I
494 // don't think CPRS programmers used.)
495 // Also will fail if begin is not on a line by itself.
496 var i : integer;
497 tempS : string;
498 found : boolean;
499 begin
500 found := false;
501 for i := startI to NewEdit.Lines.Count-1 do begin
502 tempS := UpperCase(NewEdit.Lines.Strings[i]);
503 if tempS='BEGIN' then begin
504 found := true;
505 break;
506 end;
507 end;
508 if found then begin
509 temps := ' SetupVars; //kt added '+DateStr+' to replace constants with vars.';
510 NewEdit.Lines.Insert(i+1,tempS);
511 end;
512 end;
513
514 procedure CheckFixProcFn(startI,endI : integer);
515 //Scan procedure or function and add 'SetupVars;' if needed.
516 var i : integer;
517 tempS : string;
518 begin
519 tempS := UpperCase(NewEdit.Lines.Strings[startI]);
520 if pos('.SETUPVARS',tempS)=0 then begin
521 if ContainsConst(startI,endI) then begin
522 InsertSetupVars(startI);
523 end;
524 end;
525 end;
526
527 function implementationStart : integer;
528 var i : integer;
529 begin
530 Result := 0;
531 //find implementation line
532 for i := 0 to NewEdit.Lines.Count-1 do begin
533 tempS := NewEdit.Lines.Strings[i];
534 tempS := UpperCase(tempS);
535 if pos('IMPLEMENTATION',tempS)>0 then begin
536 Result := i;
537 break;
538 end;
539 end;
540 end;
541
542
543begin
544 ConstList := TStringList.Create;
545 newProcList := TStringList.Create;
546 varList := TStringList.Create;
547
548 found := false;
549 //Find class name
550 for i := 0 to NewEdit.Lines.Count-1 do begin
551 tempS := NewEdit.Lines.Strings[i];
552 tempS := UpperCase(tempS);
553 if (pos('CLASS',tempS)>0) and (pos('=',tempS)>0) then begin
554 classStartLine := i;
555 className := piece(NewEdit.Lines.Strings[i],'=',1);
556 className := trim(className);
557 found := true;
558 newProcList.Add(' ');
559 newProcList.Add(' ');
560 newProcList.Add('procedure '+className+'.SetupVars;');
561 newProcList.Add('//kt Added entire function to replace constant declarations '+DateStr);
562 newProcList.Add('begin');
563 break;
564 end;
565 end;
566 //next implementation line
567 if found = true then begin
568 implementationStartI := implementationStart();
569 if implementationStartI=0 then found := false;
570 end;
571
572 //Next find 'const' starting line
573 if found then begin
574 found := false;
575 for i := i to NewEdit.Lines.Count-1 do begin
576 tempS := NewEdit.Lines.Strings[i];
577 tempS := Trim(UpperCase(tempS));
578 if tempS='CONST' then begin
579 found := true;
580 constStart:=i+1;
581 break;
582 end;
583 end;
584 end;
585 //next find end of const section
586 if found then begin
587 found := false;
588 for i := constStart to NewEdit.Lines.Count-1 do begin
589 tempS := NewEdit.Lines.Strings[i];
590 tempS := MidStr(UpperCase(tempS),1,3);
591 if (tempS='VAR') or (tempS='PRO') or (tempS='FUN')
592 or (tempS='IMP') then begin
593 constEnd := i-1;
594 found := true;
595 break;
596 end;
597 end;
598 end;
599 //Insert function for SetupVars into code
600 if found = true then begin
601 for i:=constStart to constEnd do begin
602 tempS := NewEdit.Lines.Strings[i];
603 if (MidStr(tempS,1,2)<>'//') and (Pos('DKLangConstW',tempS)>0) then begin
604 p1:=pos('//kt',tempS);
605 if p1>0 then begin
606 tempS := MidStr(tempS,1,p1-1);
607 end; //chnage here...
608 newProcList.Add(tempS);
609 if pos('=',tempS)>0 then begin
610 tempS := piece(tempS,'=',1);
611 tempS := Trim(tempS);
612 constList.Add(tempS);
613 end;
614 end;
615 end;
616 newProcList.Add('end;');
617 newProcList.Add(' ');
618 for i := 0 to newProcList.Count-1 do begin
619 tempS := newProcList.Strings[i];
620 NewEdit.Lines.Insert(constEnd+1+i,tempS);
621 end;
622 //now remove changes from old const section
623 for i := constEnd downto constStart do begin
624 tempS := newEdit.Lines.Strings[i];
625 if pos('DKLangConstW',tempS)>0 then begin
626 newEdit.Lines.Delete(i);
627 end;
628 end;
629 //now add constants names into class def as string vars
630 found := false;
631 for i := classStartLine to NewEdit.Lines.Count-1 do begin
632 tempS := UpperCase(newEdit.Lines.Strings[i]);
633 if pos('PRIVATE',tempS)>0 then begin
634 privateStartLine := i+1;
635 found := true;
636 break;
637 end;
638 end;
639 if (found = true) and (ConstList.Count>0) then begin
640 //first find length of longest entry to allow better text formatting
641 maxLen := 0;
642 for i := 0 to ConstList.Count-1 do begin
643 if length(ConstList.Strings[i])>maxLen then maxLen := length(ConstList.Strings[i]);
644 end;
645 newEdit.Lines.Insert(privateStartLine,' //kt Begin Mod (change Consts to Vars) '+DateStr);
646 for i := ConstList.Count-1 downto 0 do begin
647 tempS := ' '+ConstList.Strings[i];
648 for j := 1 to maxLen-length(ConstList.Strings[i]) do tempS := tempS + ' ';
649 tempS := tempS +' : string; //kt';
650 newEdit.Lines.Insert(privateStartLine+1,tempS);
651 end;
652 newEdit.Lines.Insert(privateStartLine+ConstList.Count+1,' //kt End Mod -------------------');
653 end;
654
655 //add declaration of procedure SetupVars to END of private section in type def
656
657 // complete...
658
659 //Last step: ensure any proc/function that references one of the entries in ConstList
660 //includes a call to SetupVars at the beginning of the code
661 i := implementationStart();
662 while (i<NewEdit.Lines.Count) do begin
663 FindProcFn(i,startI,endI);
664 if startI<>endI then begin
665 CheckFixProcFn(startI,endI);
666 i := endI;
667 end else begin
668 i := i+1;
669 end;
670 end;
671
672 end;
673 ConstList.Free;
674 newProcList.Free;
675end;
676
677procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
678begin
679 ShutDown;
680end;
681
682procedure TMainForm.ShutDown;
683begin
684 CloseCurFiles;
685 ConstantsOutputForm.SaveButtonClick(nil);
686 FileList.Free;
687end;
688
689procedure TMainForm.BitBtn1Click(Sender: TObject);
690begin
691 SearchConstsForm.Show;
692 SearchConstsForm.SearchBtnClick(self);
693end;
694
695procedure TMainForm.ReportSourceChanges1Click(Sender: TObject);
696begin
697 SearchConstsForm.Show;
698 SearchConstsForm.cbReportChanges.Checked := true;
699 SearchConstsForm.SearchBtnClick(self);
700 SearchConstsForm.cbReportChanges.Checked := false;
701end;
702
703end.
Note: See TracBrowser for help on using the repository browser.