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