source: trunk/NewView/GlobalSearchForm.pas@ 98

Last change on this file since 98 was 98, checked in by RBRi, 19 years ago

many small updates/commens/logging changes
fix for #16

  • Property svn:eol-style set to native
File size: 19.6 KB
Line 
1Unit GlobalSearchForm;
2
3// NewView - a new OS/2 Help Viewer
4// Copyright 2003 Aaron Lawrence (aaronl at consultant dot com)
5// This software is released under the Gnu Public License - see readme.txt
6
7Interface
8
9// Global search uses a thread to load helpfiles, search them, and
10// send the results to be displayed.
11
12Uses
13 PmWin,
14 Classes,
15 Forms,
16 Buttons,
17 StdCtrls,
18 ComCtrls,
19 Outline2,
20 GenericThread,
21 ACLLanguageUnit,
22 TextSearchQuery,
23 HelpFile,
24 ExtCtrls,
25 LED;
26
27const
28 // Custom window messages for this form
29 // NOTE! Sibyl uses WM_USER+1 and +2!
30 WM_OPENED = WM_USER + 10;
31
32Type
33 TViewTopicCallback = procedure( Filename: string;
34 TopicIndex: longint ) of object;
35
36 TSearchParameters = class
37 Query: TTextSearchQuery;
38 Directories: TStringList;
39 end;
40
41 // Returned by thread. (Note - helpfiles and topics are destroyed dynamically.)
42 TSearchResult = class
43 Filename: string;
44 FileTitle: string;
45 MatchingTopics: TList;
46 constructor Create;
47 destructor Destroy; override;
48 end;
49
50 TGlobalSearchForm = Class (TForm)
51 SearchTextEdit: TEdit;
52 SearchTextLabel: TLabel;
53 SelectDrivesButton: TButton;
54 SearchTextLabel1: TLabel;
55 ResultsLabel: TLabel;
56 Led: TLed;
57 LEDTimer: TTimer;
58 SearchLocationComboBox: TComboBox;
59 Bevel: TBevel;
60 HelpButton: TButton;
61 ResultsOutline: TOutline2;
62 SearchButton: TButton;
63 ViewTopicButton: TButton;
64 CancelButton: TButton;
65 ProgressBar: TProgressBar;
66 ProgressLabel: TLabel;
67 Procedure SearchLocationComboBoxOnItemSelect (Sender: TObject;
68 Index: LongInt);
69 Procedure LEDTimerOnTimer (Sender: TObject);
70 Procedure SearchInComboBoxOnChange (Sender: TObject);
71 Procedure ResultsOutlineOnEnter (Sender: TObject);
72 Procedure SearchTextEditOnEnter (Sender: TObject);
73 Procedure SelectDrivesButtonOnClick (Sender: TObject);
74 Procedure GlobalSearchFormOnSetupShow (Sender: TObject);
75 Procedure CancelButtonOnClick (Sender: TObject);
76 Procedure GlobalSearchFormOnClose (Sender: TObject;
77 Var Action: TCloseAction);
78 Procedure ResultsOutlineOnItemDblClick (Node: TNode);
79 Procedure ViewTopicButtonOnClick (Sender: TObject);
80 Procedure GlobalSearchFormOnCreate (Sender: TObject);
81 Procedure GlobalSearchFormOnCloseQuery (Sender: TObject;
82 Var CanClose: Boolean);
83 Procedure SearchButtonOnClick (Sender: TObject);
84 Procedure GlobalSearchFormOnShow (Sender: TObject);
85 Protected
86 Procedure OnSearchProgress ( n, outof: integer;
87 S: String );
88 Procedure OnMatchFound( SearchResult: TSearchResult );
89 Procedure OnThreadData( S: string; Data: TObject );
90 Procedure OnSearchFinished( Result: TObject );
91 Procedure SetProgressLabel( const S: String );
92
93 // Handle our own WM_OPENED message
94 Procedure WMOpened( Var Msg: TMessage ); Message WM_OPENED;
95 Procedure ClearResults;
96 Procedure ViewTopic;
97
98 ThreadManager: TGenericThreadManager;
99
100 Procedure UpdateButtons;
101
102
103 Procedure GetSelectedDirectories( List: TStringList );
104
105 // search thread context
106
107 Function Search( Parameters: TObject ): TObject;
108
109 protected
110 Procedure OnLanguageEvent( Language: TLanguageFile;
111 const Apply: boolean );
112
113 SearchCaption: string;
114 StopCaption: string;
115 NoResultsMsg: string;
116 ScanDirectoriesMsg: string;
117 SearchingFileMsg: string;
118 OfMsg: string;
119 DoneMsg: string;
120 SearchErrorTitle: string;
121 SearchError: string;
122
123 StandardHelpPathsLocation: string;
124 FixedDrivesLocation: string;
125 SelectedHelpPathsLocation: string;
126 CustomPathsLocation: string;
127
128 public
129 // set by caller
130 ViewTopicCallback: TViewTopicCallback;
131 Procedure DoSearch;
132 End;
133
134Var
135 GlobalSearchForm: TGlobalSearchForm;
136
137procedure EnsureGlobalSearchFormLoaded;
138
139Implementation
140
141uses
142 SysUtils,
143 DebugUnit,
144 ACLDialogs,
145 ControlsUtility,
146 DriveInfoUnit,
147 ACLStringUtility,
148 IPFFileFormatUnit,
149 HelpTopic,
150 SearchUnit,
151 SearchDirectoriesFormUnit,
152 SettingsUnit,
153 InformationFormUnit,
154 FileUtilsUnit;
155
156type
157 // Used to store filenames in outline
158 THelpFileInfo = class
159 FileName: string;
160 end;
161
162constructor TSearchResult.Create;
163begin
164 inherited Create;
165 MatchingTopics := TList.Create;
166end;
167
168destructor TSearchResult.Destroy;
169begin
170 MatchingTopics.Destroy;
171 inherited Destroy;
172end;
173
174Procedure TGlobalSearchForm.SearchLocationComboBoxOnItemSelect (Sender: TObject; Index: LongInt);
175Begin
176 Settings.GlobalSearchLocation := TGlobalSearchLocation( SearchLocationComboBox.ItemIndex );
177End;
178
179Procedure TGlobalSearchForm.LEDTimerOnTimer (Sender: TObject);
180Begin
181 LED.LedCondition := not LED.LedCondition;
182End;
183
184Procedure TGlobalSearchForm.SearchInComboBoxOnChange (Sender: TObject);
185Begin
186End;
187
188Procedure TGlobalSearchForm.ResultsOutlineOnEnter (Sender: TObject);
189Begin
190 ViewTopicButton.Default := true;
191End;
192
193Procedure TGlobalSearchForm.SearchTextEditOnEnter (Sender: TObject);
194Begin
195 SearchButton.Default := true;
196End;
197
198
199Procedure TGlobalSearchForm.GetSelectedDirectories(List: TStringList);
200Var
201 tmpDirectories : TStringList;
202
203 DriveNumber: longint;
204 DriveType: TDriveType;
205 DriveLetter: char;
206 i: longint;
207 Dir: string;
208 FoundIndex: longint;
209begin
210 List.Clear;
211 case SearchLocationComboBox.ItemIndex of
212 -1:
213 begin
214 // one custom dir...
215 List.Add( SearchLocationComboBox.Text );
216 end;
217
218 Ord( gsHelpPaths ),
219 Ord( gsSelectedHelpPaths ): // standard or selected help paths
220 Begin
221 tmpDirectories := TStringList.Create;
222 List.Sorted := true;
223 List.Duplicates := dupIgnore;
224
225 // GetDirsInPath clears the list tmpDirectories
226 GetDirsInPath(HelpPathEnvironmentVar, tmpDirectories);
227 List.AddStrings(tmpDirectories);
228
229 GetDirsInPath(BookshelfEnvironmentVar, tmpDirectories);
230 List.AddStrings(tmpDirectories);
231
232 tmpDirectories.Destroy;
233
234 // for selected paths we have to adjust the selection
235 if SearchLocationComboBox.ItemIndex = Ord( gsSelectedHelpPaths ) then
236 begin
237 // now mark some as non-selected...
238 for i := 0 to List.Count - 1 do
239 begin
240 Dir := List[i];
241 if not Settings.SearchDirectories.Find( Dir, FoundIndex ) then
242 List.Objects[i] := pointer(1);
243 end;
244 end;
245 end;
246
247
248 Ord( gsFixedDrives ):
249 begin
250 // drives
251 For DriveNumber := MinDriveNumber To MaxDriveNumber Do
252 Begin
253 DriveType := GetDriveType( DriveNumber );
254 DriveLetter := Chr( DriveNumber + Ord( 'A' ) - 1 );
255
256 if DriveType = dtHard then
257 begin
258 List.Add( DriveLetter + ':\...' );
259 end;
260 end;
261 end;
262
263 Ord( gsCustom ):
264 begin
265 // already custom...
266 List.Assign(Settings.SearchDirectories);
267 end;
268 end;
269end;
270
271Procedure TGlobalSearchForm.SelectDrivesButtonOnClick (Sender: TObject);
272begin
273 GetSelectedDirectories(SearchDirectoriesForm.SelectedFolders);
274
275 SearchDirectoriesForm.ShowModal;
276 if SearchDirectoriesForm.ModalResult <> mrOK then
277 exit;
278
279 // there was a selection, so we have to change the dropdown
280 if SearchLocationComboBox.ItemIndex = Ord( gsHelpPaths ) then
281 SearchLocationComboBox.ItemIndex := Ord( gsSelectedHelpPaths );
282
283 if SearchLocationComboBox.ItemIndex = Ord( gsFixedDrives ) then
284 SearchLocationComboBox.ItemIndex := Ord( gsCustom );
285
286 if SearchDirectoriesForm.CustomDirAdded then
287 SearchLocationComboBox.ItemIndex := Ord( gsCustom );
288
289 // update the settings
290 Settings.SearchDirectories.Assign( SearchDirectoriesForm.SelectedFolders );
291 SaveSettings;
292End;
293
294Procedure TGlobalSearchForm.UpdateButtons;
295Begin
296 // HelpPathsRadioButton.Checked := SearchType = stHelpPaths;
297 // EverywhereRadioButton.Checked := SearchType = stDrives;
298// FolderRadioButton.Checked := SearchType = stFolder;
299
300End;
301
302Procedure TGlobalSearchForm.GlobalSearchFormOnSetupShow (Sender: TObject);
303Begin
304 ScaleForm( self, 11, 16 );
305 SearchButton.Align := alFixedRightTop;
306
307 if SearchLocationComboBox.Items.Count = 0 then
308 begin
309 // must match teh global search location enum...
310 SearchLocationComboBox.Items.Add( StandardHelpPathsLocation );
311 SearchLocationComboBox.Items.Add( FixedDrivesLocation );
312 SearchLocationComboBox.Items.Add( SelectedHelpPathsLocation );
313 SearchLocationComboBox.Items.Add( CustomPathsLocation );
314
315 SearchLocationComboBox.ItemIndex := Ord( Settings.GlobalSearchLocation );
316 end;
317
318End;
319
320Procedure TGlobalSearchForm.OnLanguageEvent(Language: TLanguageFile; const Apply: boolean );
321begin
322 LogEvent(LogI18n, 'TGlobalSearchForm.OnLanguageEvent apply: "' + BoolToStr(Apply) + '"');
323
324 Language.LoadComponentLanguage(self, Apply);
325
326 Language.LL(Apply, SearchCaption, 'SearchCaption', '~Search');
327 Language.LL(Apply, StopCaption, 'StopCaption', '~Stop');
328 Language.LL(Apply, NoResultsMsg, 'NoResultsMsg', '(No results found)');
329 Language.LL(Apply, ScanDirectoriesMsg, 'ScanDirectoriesMsg', 'Finding help files...');
330 Language.LL(Apply, SearchingFileMsg, 'SearchingFileMsg', 'Searching ');
331 Language.LL(Apply, OfMsg, 'OfMsg', ' of ');
332 Language.LL(Apply, DoneMsg, 'DoneMsg', 'Done');
333 Language.LL(Apply, SearchErrorTitle, 'SearchErrorTitle', 'Search');
334 Language.LL(Apply, SearchError, 'SearchError', 'Error in search syntax: ');
335
336 Language.LL(Apply, StandardHelpPathsLocation, 'StandardHelpPathsLocation', 'Standard Help Paths');
337 Language.LL(Apply, FixedDrivesLocation, 'FixedDrivesLocation', 'All Hard Drives');
338 Language.LL(Apply, SelectedHelpPathsLocation, 'SelectedHelpPathsLocation', 'Selected Help Paths');
339 Language.LL(Apply, CustomPathsLocation, 'CustomPathsLocation', 'Directory List');
340end;
341
342
343Procedure TGlobalSearchForm.CancelButtonOnClick (Sender: TObject);
344Begin
345 Close;
346End;
347
348Procedure TGlobalSearchForm.GlobalSearchFormOnClose (Sender: TObject;
349 Var Action: TCloseAction);
350Begin
351 ClearResults;
352
353 if SearchLocationComboBox.ItemIndex = -1 then
354 begin
355 Settings.GlobalSearchLocation := gsCustom;
356 Settings.SearchDirectories.Clear;
357 Settings.SearchDirectories.Add( SearchLocationComboBox.Text );
358 end;
359
360 Action := caFreeHandle; // DON'T release the form! (Default action for non-modal forms)
361End;
362
363Procedure TGlobalSearchForm.ResultsOutlineOnItemDblClick (Node: TNode);
364Begin
365 ViewTopic;
366End;
367
368Procedure TGlobalSearchForm.ViewTopicButtonOnClick (Sender: TObject);
369begin
370 ViewTopic;
371end;
372
373Procedure TGlobalSearchForm.ViewTopic;
374var
375 Node: TNode;
376 HelpFileInfo: THelpFileInfo;
377 TopicIndex: longint;
378Begin
379 Node := ResultsOutline.SelectedNode;
380 if Node = nil then
381 exit;
382 case Node.Level of
383 0:
384 begin
385 // file node
386 HelpFileInfo := Node.Data as THelpFileInfo;
387 TopicIndex := -1;
388 end;
389
390 1:
391 begin
392 // topic node
393 HelpFileInfo := Node.Parent.Data as THelpFileInfo;
394 TopicIndex := longint( Node.Data );
395 end;
396
397 else
398 assert( false, 'Invalid node level in ViewTopic!: ' + IntToStr( Node.Level ) );
399 end;
400
401 ViewTopicCallback( HelpFileInfo.FileName, TopicIndex );
402End;
403
404Procedure TGlobalSearchForm.GlobalSearchFormOnCreate (Sender: TObject);
405Begin
406 RegisterForLanguages( OnLanguageEvent );
407
408 UpdateButtons;
409
410 ThreadManager := TGenericThreadManager.Create( self );
411 ThreadManager.OnProgressUpdate := OnSearchProgress;
412 ThreadManager.OnDataFromThread := OnThreadData;
413 ThreadManager.OnJobComplete := OnSearchFinished;
414End;
415
416Procedure TGlobalSearchForm.OnSearchFinished( Result: TObject );
417Begin
418 SearchButton.Caption := SearchCaption;
419 ProgressBar.Hide;
420 LED.LedCondition := false;
421 LEDTimer.Stop;
422
423 if ResultsOutline.ChildCount > 0 then
424 begin
425 ResultsOutline.SelectedNode:= ResultsOutline.Children[ 0 ];
426 ResultsOutline.Focus;
427 SetProgressLabel( '' );
428 end
429 else
430 begin
431 SetProgressLabel( NoResultsMsg );
432 end;
433
434End;
435
436Procedure TGlobalSearchForm.GlobalSearchFormOnCloseQuery (Sender: TObject;
437 Var CanClose: Boolean);
438Begin
439 if ThreadManager.IsRunning then
440 begin
441 ThreadManager.Stop;
442 end;
443End;
444
445Procedure TGlobalSearchForm.SetProgressLabel( const S: String );
446begin
447 ProgressLabel.Text := S;
448 ProgressLabel.Refresh;
449end;
450
451Procedure TGlobalSearchForm.OnSearchProgress ( n, outof: integer;
452 S: String );
453Begin
454 ProgressBar.Position := n * 100 div outof;
455 SetProgressLabel( S );
456End;
457
458Function TGlobalSearchForm.Search( Parameters: TObject ): TObject;
459var
460 Files : TStringList;
461 FileIndex: longint;
462 Filename: string;
463 HelpFile: THelpFile;
464 SearchResult: TSearchResult;
465 MatchingTopics: TList;
466
467 tmpSearchParameters : TSearchParameters;
468 Query: TTextSearchQuery;
469 i: longint;
470 Dir: string;
471
472Begin
473 tmpSearchParameters := Parameters as TSearchParameters;
474
475 Query := tmpSearchParameters.Query;
476 Files := TStringList.Create;
477
478 MatchingTopics := TList.Create;
479 LogEvent(LogParse, 'Creating file list');
480
481 // make sure we ignore duplicate files...
482 Files.Sorted := true;
483 Files.CaseSensitive := false;
484 Files.Duplicates := dupIgnore;
485
486 for i := 0 to tmpSearchParameters.Directories.Count - 1 do
487 begin
488 if ThreadManager.StopRequested then
489 begin
490 break;
491 end;
492
493 ThreadManager.UpdateProgress( i * 10 div tmpSearchParameters.Directories.Count,
494 100,
495 ScanDirectoriesMsg );
496 Dir := tmpSearchParameters.Directories[ i ];
497 if StrEnds( '...', Dir ) then
498 begin
499 Dir := StrLeftWithout( Dir, 3 );
500 ListFilesInDirectoryRecursiveWithTermination(
501 Dir,
502 '*.inf;*.hlp',
503 true,
504 Files,
505 ThreadManager.StopRequested,
506 true ); // check termination
507 end
508 else
509 begin
510 ListFilesInDirectory( Dir, '*.inf;*.hlp', true, Files);
511 end;
512 end;
513
514 for FileIndex := 0 to Files.Count - 1 do
515 begin
516 if ThreadManager.StopRequested then
517 begin
518 break;
519 end;
520
521 Filename := Files[FileIndex];
522
523 ThreadManager.UpdateProgress( 10 + FileIndex * 95 div Files.Count,
524 100,
525 SearchingFileMsg
526 + Filename
527 + ' ('
528 + IntToStr( FileIndex + 1 )
529 + OfMsg
530 + IntToStr( Files.Count )
531 + ')...' );
532
533 try
534 HelpFile := THelpFile.Create( FileName );
535 MatchingTopics.Clear;
536 SearchHelpFile( HelpFile,
537 Query,
538 MatchingTopics,
539 nil // don't care about words matched
540 );
541
542 if MatchingTopics.Count > 0 then
543 begin
544 // Create a searchresult object to send back to main thread.
545 SearchResult := TSearchResult.Create;
546 SearchResult.Filename := HelpFile.Filename;
547 SearchResult.FileTitle := HelpFile.Title;
548
549 SearchResult.MatchingTopics.Assign( MatchingTopics );
550
551 SearchResult.MatchingTopics.Sort( TopicRelevanceCompare );
552 ThreadManager.SendData( '', SearchResult );
553 end;
554
555 HelpFile.Destroy;
556
557 except
558 on E: EHelpFileException do
559 begin
560 ; // ignore exceptions
561 end;
562
563 on E: EWindowsHelpFormatException do
564 begin
565 ; // ignore Windows help files
566 end;
567 end;
568
569 end;
570 ThreadManager.UpdateProgress( 100, 100, DoneMsg );
571 Files.Destroy;
572
573 Query.Destroy;
574
575 tmpSearchParameters.Directories.Destroy;
576 tmpSearchParameters.Destroy;
577
578 Result := nil;
579End;
580
581Procedure TGlobalSearchForm.ClearResults;
582var
583 FileIndex: longint;
584begin
585 for FileIndex := 0 to ResultsOutline.ChildCount - 1 do
586 ResultsOutline.Children[ FileIndex ].Data.Free;
587 ResultsOutline.Clear;
588 ViewTopicButton.Enabled := false;
589end;
590
591Procedure TGlobalSearchForm.SearchButtonOnClick (Sender: TObject);
592begin
593 DoSearch;
594end;
595
596Procedure TGlobalSearchForm.DoSearch;
597var
598 tmpSelectedDirectories : TStringList;
599 i : integer;
600
601 SearchText: string;
602 Query: TTextSearchQuery;
603 SearchParameters: TSearchParameters;
604Begin
605 if ThreadManager.IsRunning then
606 begin
607 ThreadManager.Stop;
608 exit;
609 end;
610
611 SearchText := trim( SearchTextEdit.Text );
612 if SearchText = '' then
613 exit;
614
615 try
616 Query := TTextSearchQuery.Create(SearchText);
617 except
618 on e: ESearchSyntaxError do
619 begin
620 DoErrorDlg( SearchErrorTitle,
621 SearchError
622 + e.Message );
623 exit;
624 end;
625 end;
626
627 ClearResults;
628
629 SearchParameters := TSearchParameters.Create;
630
631 SearchParameters.Query := Query;
632
633 // now the directories to search in
634 SearchParameters.Directories := TStringList.Create;
635
636 tmpSelectedDirectories := TStringList.Create;
637 GetSelectedDirectories(tmpSelectedDirectories);
638
639 // clear the list and add only the selected ones
640 for i := 0 to tmpSelectedDirectories.Count - 1 do
641 begin
642 if tmpSelectedDirectories.Objects[i] = nil then
643 begin
644 SearchParameters.Directories.add(tmpSelectedDirectories[i]);
645 end;
646 end;
647 tmpSelectedDirectories.Destroy;
648
649 ThreadManager.StartJob( Search, SearchParameters );
650 SearchButton.Caption := StopCaption;
651 ProgressBar.Show;
652
653 LED.LedCondition := true;
654 LEDTimer.Start;
655End;
656
657Procedure TGlobalSearchForm.GlobalSearchFormOnShow (Sender: TObject);
658Begin
659 // make search button default
660 SearchButton.Focus;
661 SearchTextEdit.Focus;
662 SetProgressLabel( '' );
663 PostMsg( Handle, WM_OPENED, 0, 0 );
664 SearchButton.Caption := SearchCaption;
665 ProgressBar.Hide;
666 ViewTopicButton.Enabled := false;
667End;
668
669Procedure TGlobalSearchForm.OnThreadData( S: string; Data: TObject );
670var
671 SearchResult: TSearchResult;
672begin
673 SearchResult := Data as TSearchResult;
674 OnMatchFound( SearchResult );
675 SearchResult.Destroy;
676end;
677
678Procedure TGlobalSearchForm.OnMatchFound( SearchResult: TSearchResult );
679var
680 Topic: TTopic;
681 HelpFileInfo: THelpFileInfo;
682 FileNode: TNode;
683 TopicIndex: longint;
684begin
685 ViewTopicButton.Enabled := true;
686
687 HelpFileInfo := THelpFileInfo.Create;
688 HelpFileInfo.FileName := SearchResult.FileName;
689 FileNode := ResultsOutline.AddChild( SearchResult.FileTitle
690 + ' ('
691 + SearchResult.FileName
692 + ')',
693 HelpFileInfo );
694 for TopicIndex := 0 to SearchResult.MatchingTopics.Count - 1 do
695 begin
696 Topic := SearchResult.MatchingTopics[ TopicIndex ];
697 FileNode.AddChild( Topic.Title,
698 TObject( Topic.Index ) );
699 end;
700end;
701
702Procedure TGlobalSearchForm.WMOpened( Var Msg: TMessage );
703begin
704 SearchTextLabel.XAlign := xaLeft;
705 SearchTextLabel.YAlign := yaTop;
706
707 SearchTextEdit.XStretch := xsFrame;
708 SearchTextEdit.YAlign := yaTop;
709 SearchTextEdit.Focus;
710
711 SearchButton.XAlign := xaRight;
712 SearchButton.YAlign := yaTop;
713
714 SearchTextLabel1.XAlign := xaLeft;
715 SearchTextLabel1.YAlign := yaTop;
716
717 SearchLocationComboBox.XStretch := xsFrame;
718 SearchLocationComboBox.YAlign := yaTop;
719
720 SelectDrivesButton.XAlign := xaRight;
721 SelectDrivesButton.YAlign := yaTop;
722
723 Bevel.XStretch := xsFrame;
724 Bevel.YAlign := yaTop;
725
726 LED.XAlign := xaRight;
727 LED.YAlign := yaTop;
728
729 ResultsLabel.XAlign := xaLeft;
730 ResultsLabel.YAlign := yaTop;
731
732 ProgressLabel.XStretch := xsFrame;
733 ProgressLabel.YAlign := yaTop;
734
735 ResultsOutline.XStretch := xsFrame;
736 ResultsOutline.YStretch := ysFrame;
737
738 ProgressBar.XStretch := xsFrame;
739 ProgressBar.YAlign := yaBottom;
740
741end;
742
743procedure EnsureGlobalSearchFormLoaded;
744begin
745 if GlobalSearchForm = nil then
746 GlobalSearchForm := TGlobalSearchForm.Create( nil );
747end;
748
749Initialization
750 RegisterClasses ([TGlobalSearchForm, TEdit, TLabel,
751 TProgressBar, TButton, TOutline2, TComboBox, TBevel, TLed, TTimer]);
752 RegisterUpdateProcForLanguages( EnsureGlobalSearchFormLoaded );
753End.
Note: See TracBrowser for help on using the repository browser.