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