source: trunk/NewView/MainForm.pas@ 51

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

more command line changes

  • Property svn:eol-style set to native
File size: 184.0 KB
Line 
1Unit MainForm;
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
9Uses
10// system is a good unit to be able to open ;)
11// the above line is here so you can use right-mouse open file on "system"
12 OS2Def,
13 SysUtils,
14 Classes,
15 Forms,
16 Graphics,
17 Messages,
18 Buttons,
19 ComCtrls,
20 StdCtrls,
21 ExtCtrls,
22 TabCtrls,
23 Dialogs,
24
25// library
26 ACLString,
27 SharedMemoryUnit,
28 ACLLanguageUnit,
29 GenericThread,
30 CmdLineParameterUnit,
31
32// custom components
33 SplitBar,
34 Outline2,
35 RichTextView,
36 Coolbar2,
37 CustomListBox,
38
39// local
40 HelpFile,
41 HelpTopic,
42 HelpWindowUnit,
43 HelpWindowDimensions,
44 NavigatePointUnit,
45 MiscUnit,
46 HelpManagerUnit,
47 TextSearchQuery,
48 IPFFileFormatUnit,
49 Tabset2Unit;
50
51const
52 // Custom window messages for this form
53 // NOTE! Sibyl uses WM_USER+1 and +2!
54 WM_OPENED = WM_USER + 10;
55 WM_FOLLOWLINK = WM_USER + 11;
56 WM_FOLLOWEXTERNALLINK = WM_USER + 12;
57
58 MAIN_WINDOW_CLASS_NAME = 'NewViewMainForm';
59
60Type
61
62 TMainForm = Class (TForm)
63 VSplitBar: TSplitBar;
64 Notebook: TNoteBook;
65 IndexSearchEdit: TEdit;
66 SearchTextEdit: TEdit;
67 SearchResultsListBox: TListBox;
68 NotesListBox: TListBox;
69 CoolBar: TCoolBar2;
70 MenuItem21: TMenuItem;
71 SaveAsIPFMI: TMenuItem;
72 MenuItem20: TMenuItem;
73 DebugFindBinaryMI: TMenuItem;
74 TopicByNameMI: TMenuItem;
75 DebugTopicByResourceIDMI: TMenuItem;
76 ToolsDebugSep: TMenuItem;
77 DebugSaveLanguageFileMI: TMenuItem;
78 DebugLoadLanguageMI: TMenuItem;
79 TabSet: TTabSet2;
80 NavigateNextMI: TMenuItem;
81 ShowLeftPanelMI: TMenuItem;
82 MenuItem18: TMenuItem;
83 AddNoteButton: TButton;
84 EditNoteButton: TButton;
85 DeleteNoteButton: TButton;
86 GotoNoteButton: TButton;
87 MenuItem23: TMenuItem;
88 MenuItem24: TMenuItem;
89 MenuItem25: TMenuItem;
90 DebugHelpManagerVersionMI: TMenuItem;
91 MenuItem19: TMenuItem;
92 ViewHighlightSearchWordsMI: TMenuItem;
93 MenuItem17: TMenuItem;
94 MenuItem16: TMenuItem;
95 MenuItem15: TMenuItem;
96 FileNewWindowMI: TMenuItem;
97 OpenSpecialMI: TMenuItem;
98 MenuItem14: TMenuItem;
99 SearchPMI: TMenuItem;
100 ViewSourceMI: TMenuItem;
101 FileCloseMI: TMenuItem;
102 MenuItem10: TMenuItem;
103 MenuItem12: TMenuItem;
104 MenuItem13: TMenuItem;
105 StatusPanel: TPanel;
106 ProgressPanel: TPanel;
107 ProgressBar: TProgressBar;
108 DebugShowWordSeparatorsMI: TMenuItem;
109 DebugStressTestMI: TMenuItem;
110 TopicPropertiesPMI: TMenuItem;
111 MenuItem3: TMenuItem;
112 MenuItem2: TMenuItem;
113 MenuItem8: TMenuItem;
114 ToolsOptionsMI: TMenuItem;
115 MenuItem9: TMenuItem;
116 ToolsDebugMenu: TMenuItem;
117 DebugShowParamsMI: TMenuItem;
118 DebugShowCodesMI: TMenuItem;
119 EditGlobalSearchMI: TMenuItem;
120 ViewExpandAllMI: TMenuItem;
121 EditBookmarksMI: TMenuItem;
122 AddBookmarkMI: TMenuItem;
123 ViewPopupMenu: TPopupMenu;
124 SelectAllPMI: TMenuItem;
125 CopyPMI: TMenuItem;
126 ContentsOutline: TOutline2;
127 IndexListBox: TCustomListBox;
128 ViewCollapseAllMI: TMenuItem;
129 MenuItem7: TMenuItem;
130 SystemOpenDialog: TSystemOpenDialog;
131 SearchButton: TButton;
132 MenuItem1: TMenuItem;
133 ViewIndexMI: TMenuItem;
134 ViewContentsMI: TMenuItem;
135 ViewSearchMI: TMenuItem;
136 ViewNotesMI: TMenuItem;
137 ViewRefreshMI: TMenuItem;
138 MenuItem11: TMenuItem;
139 DisplayPanel: TPanel;
140 ButtonImages: TImageList;
141 BookmarksMenu: TMenuItem;
142 MainMenu: TMainMenu;
143 FileMenu: TMenuItem;
144 OpenMI: TMenuItem;
145 FileSaveAsMI: TMenuItem;
146 PrintMI: TMenuItem;
147 FileInformationMI: TMenuItem;
148 MenuItem4: TMenuItem;
149 ExitMI: TMenuItem;
150 EditMenu: TMenuItem;
151 SelectAllMI: TMenuItem;
152 CopyMI: TMenuItem;
153 MenuItem5: TMenuItem;
154 FindMI: TMenuItem;
155 FindNextMI: TMenuItem;
156 NavigateMenu: TMenuItem;
157 NavigateBackMI: TMenuItem;
158 NavigateForwardMI: TMenuItem;
159 MenuItem6: TMenuItem;
160 NavigatePreviousMI: TMenuItem;
161 ToolsMenu: TMenuItem;
162 GlobalSearchMI: TMenuItem;
163 HelpMenu: TMenuItem;
164 HelpMI: TMenuItem;
165 HelpProductInformationMI: TMenuItem;
166 AddNoteMI: TMenuItem;
167
168 Procedure SaveAsIPFMIOnClick (Sender: TObject);
169 Procedure DebugFindBinaryMIOnClick (Sender: TObject);
170 Procedure TopicByNameMIOnClick (Sender: TObject);
171 Procedure CopyLinkLocationPMIOnClick (Sender: TObject);
172 Procedure HelpKeysMIOnClick (Sender: TObject);
173 Procedure MainFormOnCommand (Sender: TObject; Var Command: TCommand);
174 Procedure MainFormOnScan (Sender: TObject; Var KeyCode: TKeyCode);
175 Procedure ShowLeftPanelMIOnClick (Sender: TObject);
176 Procedure CoolBarOnFontChange (Sender: TObject);
177 Procedure NotebookOnFontChange (Sender: TObject);
178 Procedure TabSetOnFontChange (Sender: TObject);
179 Procedure IndexListBoxOnFontChange (Sender: TObject);
180 Procedure NotesListBoxOnFontChange (Sender: TObject);
181 Procedure DisplayPanelOnFontChange (Sender: TObject);
182 Procedure ContentsOutlineOnFontChange (Sender: TObject);
183 Procedure SearchResultsListBoxOnFontChange (Sender: TObject);
184 Procedure DisplayPanelOnDragOver (Sender: TObject; Source: TObject;
185 X: LongInt; Y: LongInt; State: TDragState; Var Accept: Boolean);
186 Procedure NotesListBoxOnDragOver (Sender: TObject; Source: TObject;
187 X: LongInt; Y: LongInt; State: TDragState; Var Accept: Boolean);
188 Procedure DisplayPanelOnDragDrop (Sender: TObject; Source: TObject;
189 X: LongInt; Y: LongInt);
190 Procedure NotesListBoxOnDragDrop (Sender: TObject; Source: TObject;
191 X: LongInt; Y: LongInt);
192 Procedure SearchResultsListBoxOnDragDrop (Sender: TObject; Source: TObject;
193 X: LongInt; Y: LongInt);
194 Procedure SearchResultsListBoxOnDragOver (Sender: TObject; Source: TObject;
195 X: LongInt; Y: LongInt; State: TDragState; Var Accept: Boolean);
196 Procedure IndexListBoxOnDragDrop (Sender: TObject; Source: TObject;
197 X: LongInt; Y: LongInt);
198 Procedure IndexListBoxOnDragOver (Sender: TObject; Source: TObject;
199 X: LongInt; Y: LongInt; State: TDragState; Var Accept: Boolean);
200 Procedure ContentsOutlineOnDragOver (Sender: TObject; Source: TObject;
201 X: LongInt; Y: LongInt; State: TDragState; Var Accept: Boolean);
202 Procedure ContentsOutlineOnDragDrop (Sender: TObject; Source: TObject;
203 X: LongInt; Y: LongInt);
204 Procedure MainFormOnDragOver (Sender: TObject; Source: TObject; X: LongInt;
205 Y: LongInt; State: TDragState; Var Accept: Boolean);
206 Procedure MainFormOnDragDrop (Sender: TObject; Source: TObject; X: LongInt;
207 Y: LongInt);
208 Procedure ContentsOutlineOnItemClick (Node: TNode);
209 Procedure DebugLoadLanguageMIOnClick (Sender: TObject);
210 Procedure DebugSaveLanguageFileMIOnClick (Sender: TObject);
211 Procedure SearchResultsListBoxOnClick (Sender: TObject);
212 Procedure VSplitBarOnDblClick (Sender: TObject);
213 Procedure DebugHelpManagerVersionMIOnClick (Sender: TObject);
214 Procedure DebugTopicByResourceIDMIOnClick (Sender: TObject);
215 Procedure ViewHighlightSearchWordsMIOnClick (Sender: TObject);
216 Procedure FileNewWindowMIOnClick (Sender: TObject);
217 Procedure OpenSpecialMIOnClick (Sender: TObject);
218 Procedure NotesListBoxOnScan (Sender: TObject; Var KeyCode: TKeyCode);
219 Procedure ViewPopupMenuOnPopup (Sender: TObject);
220 Procedure SearchPMIOnClick (Sender: TObject);
221 Procedure ViewSourceMIOnClick (Sender: TObject);
222 Procedure PrintMIOnClick (Sender: TObject);
223 Procedure DebugShowWordSeparatorsMIOnClick (Sender: TObject);
224 Procedure DebugStressTestMIOnClick (Sender: TObject);
225 Procedure TopicPropertiesPMIOnClick (Sender: TObject);
226 Procedure NavigateForwardMIOnClick (Sender: TObject);
227 Procedure IndexListBoxOnScan (Sender: TObject; Var KeyCode: TKeyCode);
228 Procedure SearchResultsListBoxOnScan (Sender: TObject;
229 Var KeyCode: TKeyCode);
230 Procedure ContentsOutlineOnScan (Sender: TObject; Var KeyCode: TKeyCode);
231 Procedure ToolsOptionsMIOnClick (Sender: TObject);
232 Procedure EditGlobalSearchMIOnClick (Sender: TObject);
233 Procedure DebugShowParamsMIOnClick (Sender: TObject);
234 Procedure ViewExpandAllMIOnClick (Sender: TObject);
235 Procedure EditBookmarksMIOnClick (Sender: TObject);
236 Procedure CopyPMIOnClick (Sender: TObject);
237 Procedure SelectAllPMIOnClick (Sender: TObject);
238 Procedure AddNoteButtonOnClick (Sender: TObject);
239 Procedure SearchTextEditOnChange (Sender: TObject);
240 Procedure IndexListBoxOnClick (Sender: TObject);
241 Procedure ViewCollapseAllMIOnClick (Sender: TObject);
242 Procedure NotesListBoxOnDblClick (Sender: TObject);
243 Procedure HelpMIOnClick (Sender: TObject);
244 Procedure NotebookOnPageChanged (Sender: TObject);
245 Procedure ViewRefreshMIOnClick (Sender: TObject);
246 Procedure ViewNotesMIOnClick (Sender: TObject);
247 Procedure ViewSearchMIOnClick (Sender: TObject);
248 Procedure ViewIndexMIOnClick (Sender: TObject);
249 Procedure ViewContentsMIOnClick (Sender: TObject);
250 Procedure MainFormOnCloseQuery (Sender: TObject; Var CanClose: Boolean);
251 Procedure GlobalSearchMIOnClick (Sender: TObject);
252 Procedure GotoNoteButtonOnClick (Sender: TObject);
253 Procedure EditNoteButtonOnClick (Sender: TObject);
254 Procedure NotesListBoxOnItemFocus (Sender: TObject; Index: LongInt);
255 Procedure DeleteNoteButtonOnClick (Sender: TObject);
256 Procedure AddBookmarkMIOnClick (Sender: TObject);
257 Procedure AddNoteMIOnClick (Sender: TObject);
258 Procedure FileCloseMIOnClick (Sender: TObject);
259 Procedure CoolBarOnSectionResize (HeaderControl: THeaderControl;
260 section: THeaderSection);
261 Procedure CoolBarOnSectionClick (HeaderControl: THeaderControl;
262 section: THeaderSection);
263 Procedure MainFormOnDestroy (Sender: TObject);
264 Procedure MainFormOnSetupShow (Sender: TObject);
265 Procedure MainFormOnCreate (Sender: TObject);
266 Procedure MainFormOnShow (Sender: TObject);
267 Procedure FindNextMIOnClick (Sender: TObject);
268 Procedure FindMIOnClick (Sender: TObject);
269 Procedure IndexSearchEditOnScan (Sender: TObject; Var KeyCode: TKeyCode);
270 Procedure IndexSearchEditOnChange (Sender: TObject);
271 Procedure FileInformationMIOnClick (Sender: TObject);
272 Procedure SearchTextEditOnScan (Sender: TObject; Var KeyCode: TKeyCode);
273 Procedure SearchButtonOnClick (Sender: TObject);
274 Procedure FileSaveAsMIOnClick (Sender: TObject);
275 Procedure OptionsMIOnClick (Sender: TObject);
276 Procedure TabSetOnChange (Sender: TObject; NewTab: LongInt;
277 Var AllowChange: Boolean);
278 Procedure NotebookOnSetupShow (Sender: TObject);
279 Procedure NavigateBackMIOnClick (Sender: TObject);
280 Procedure NavigatePreviousMIOnClick (Sender: TObject);
281 Procedure NavigateNextMIOnClick (Sender: TObject);
282 Procedure CopyMIOnClick (Sender: TObject);
283 Procedure SelectAllMIOnClick (Sender: TObject);
284 Procedure DebugShowCodesMIOnClick (Sender: TObject);
285 Procedure HelpProductInformationMIOnClick (Sender: TObject);
286 Procedure OnOverLink ( Sender: TRichTextView; LinkString: String);
287 Procedure OnNotOverLink ( Sender: TRichTextView; LinkString: String);
288 Procedure OnClickLink ( Sender: TRichTextView; LinkString: String);
289 Procedure BackButtonOnClick (Sender: TObject);
290 Procedure RTViewOnSetupShow (Sender: TObject);
291 Procedure OpenMIOnClick (Sender: TObject);
292 Procedure ExitMIOnClick (Sender: TObject);
293
294 Procedure MainFormOnResize (Sender: TObject);
295 Procedure VSplitBarOnChange (NewSplit: LongInt);
296 Protected
297 // Custom window messages ----------------------------------
298
299 // Handle our own WM_OPENED message
300 Procedure WMOpened( Var Msg: TMessage ); Message WM_OPENED;
301 Procedure WMFollowLink( Var Msg: TMessage ); Message WM_FOLLOWLINK;
302 Procedure WMFollowExternalLink( Var Msg: TMessage ); Message WM_FOLLOWEXTERNALLINK;
303
304 // Messages from new help manager OR other instances
305 Procedure NHMDisplayIndex( Var Msg: TMessage ); Message NHM_HELP_INDEX;
306 Procedure NHMDisplayContents( Var Msg: TMessage ); Message NHM_HELP_CONTENTS;
307 Procedure NHMTopicByResourceID( Var Msg: TMessage ); Message NHM_TOPIC_BY_RESOURCE_ID;
308 Procedure NHMTopicByPanelName( Var Msg: TMessage ); Message NHM_TOPIC_BY_PANEL_NAME;
309
310 Procedure NHMTest( Var Msg: TMessage ); Message NHM_TEST;
311
312 Procedure NHMSearch( Var Msg: TMessage ); Message NHM_SEARCH;
313 Procedure NHMGlobalSearch( Var Msg: TMessage ); Message NHM_GLOBAL_SEARCH;
314 Procedure NHMShowUsage( Var Msg: TMessage ); Message NHM_SHOW_USAGE;
315
316 Procedure NHMSetFiles( Var Msg: TMessage ); Message NHM_SET_FILES;
317 Procedure NHMSetTitle( Var Msg: TMessage ); Message NHM_SET_TITLE;
318
319 Protected
320 // GUI events set by code ----------------------------------
321
322 Procedure OnHint( Sender: TObject );
323 Procedure OnWindowClose( Window: THelpWindow );
324 Procedure OnWindowAboutToClose( Window: THelpWindow;
325 var CanClose: boolean );
326 Procedure OnNavigateToMenuItemClick( Sender: TObject );
327 Procedure OnDragOverWindow( Sender: TObject;
328 Source: TObject;
329 X: LongInt;
330 Y: LongInt;
331 State: TDragState;
332 Var Accept: Boolean );
333 Procedure OnDragDropToWindow( Sender: TObject;
334 Source: TObject;
335 X: LongInt;
336 Y: LongInt );
337 Procedure OnWindowFontChange( Sender: TObject );
338 Procedure OnWindowTab( Sender: TObject );
339 Procedure OnWindowBackTab( Sender: TObject );
340
341 Procedure OnException( Sender: TObject;
342 E: Exception );
343 Procedure OnHelp( context: THelpContext;
344 var Result: Boolean );
345
346
347 FShowLeftPanel: boolean;
348
349 Function GetShowLeftPanel: boolean;
350 Procedure SetShowLeftPanel( Value: boolean );
351 Property ShowLeftPanel: boolean read GetShowLeftPanel write SetShowLeftPanel;
352
353 Procedure ShowTab( TabIndex: longint );
354
355 procedure GetClassData(var ClassData: TClassData); override;
356 Public
357
358 // Open the file or list of files in FileNames
359 // Set the window title if given, otherwise get it from first file
360 Function OpenFiles( const FileNames: TStrings;
361 const WindowTitle: string;
362 const DisplayFirstTopic: boolean ): boolean;
363
364 // Open a single file
365 Function OpenFile( const FileName: string;
366 const WindowTitle: string;
367 const DisplayFirstTopic: boolean ): boolean;
368
369 Function OpenAdditionalFiles( const FileNames: TStrings;
370 const DisplayFirstTopic: boolean ): boolean;
371
372 Function OpenAdditionalFile( const FileName: string;
373 const DisplayFirstTopic: boolean ): boolean;
374
375 // open from original helpmgr style file1+file2+file3. ..
376 Function OpenFilesFromTextList( const TextList: string;
377 const DisplayFirstTopic: boolean ): boolean;
378
379 Procedure CloseFile;
380 Function OKToCloseFile: boolean;
381
382 Procedure AddCurrentToMRUFiles;
383
384 Function LoadFiles( const FileNames: TStrings;
385 HelpFiles: TList ): boolean;
386 Procedure DisplayFiles( NewFiles: TList;
387 Var FirstContentsNode: TNode );
388
389 Procedure OpenDroppedFile( Source: TObject );
390
391 Function OpenWindowsHelp( const Filename: string ): boolean;
392
393 function DisplayTopicByResourceID( ID: uint16 ): boolean;
394 function DisplayTopicByName( const TopicName: string ): boolean;
395 function DisplayTopicByGlobalName( const TopicName: string ): boolean;
396
397 Procedure DisplayIndex;
398 Procedure DisplayContents;
399 Procedure DisplaySearch;
400
401 Protected
402 // Startup functions ----------------------------------
403
404 Function pSharedStruct: TPNewHelpMgrSharedStruct;
405 Procedure PositionWindow;
406 Procedure RestoreWindow;
407
408 Procedure CheckEnvironmentVars;
409 Procedure ShowUsage;
410
411 // Loading functions ----------------------------------
412
413 // Most recently used files list
414 Procedure CreateMRUMenuItems;
415 Procedure OnMRUMenuItemClick( Sender: TObject );
416
417 Procedure OnHelpFileLoadProgress( n, outof: integer;
418 message: string );
419
420 // Returns nil if file is not open
421 Function FindOpenHelpFile( FileName: string ): THelpFile;
422
423 // Navigation -------------------------------------------------
424
425 Procedure SaveNavigatePoint;
426 Procedure SaveWindows( SourceList: TList;
427 DestList: TList;
428 Parent: TSavedHelpWindow );
429
430 Procedure UpdateCurrentNavigatePoint;
431 Procedure ClearPageHistory;
432
433 Procedure NavigateToPoint( NavPoint: TNavigatePoint );
434 Procedure NavigateToHistoryIndex( Index: longint );
435
436 Procedure DisplayWindows( WindowList: TList;
437 Parent: THelpWindow );
438 Procedure ShowWindows;
439 Procedure ShowWindowList( WindowList: TList );
440 Procedure CloseWindows;
441
442 Procedure FocusFirstHelpWindow;
443
444 Procedure NavigateBack;
445 Procedure NavigateForward;
446 Procedure NavigatePreviousInContents;
447 Procedure NavigateNextInContents;
448
449 Procedure CreateNavigateToMenuItems;
450
451 // GUI status updates ---------------------------------
452
453 Procedure EnableControls;
454 Procedure EnableSearchButton;
455 Procedure SetStatus( Text: String );
456 Procedure SetProgress( n, outof: integer;
457 message: string );
458 Procedure ResetProgress;
459 Procedure RefreshWindows( WindowList: TList );
460
461 // language stuff
462 // called by callback
463 Procedure OnLanguageEvent( Language: TLanguageFile;
464 const Apply: boolean );
465
466 function ShowCodes: boolean;
467 function ShowWordIndices: boolean;
468
469 // Loading views --------------------------------------
470
471 // Used in loading contents
472 Procedure AddChildNodes( HelpFile: THelpFile;
473 ParentNode: TNode;
474 Level: longint;
475 Var TopicIndex: longint );
476 Procedure LoadContents( Files: TList;
477 Var FirstNode: TNode );
478 Procedure LoadIndex;
479
480 // Note manipulations --------------------------------
481
482 procedure AddNote;
483 Procedure EditNote( NoteIndex: longint );
484 procedure DeleteNote( NoteIndex: longint );
485 Procedure SaveNotes;
486 Procedure SaveNotesForFile( HelpFile: THelpFile );
487 Procedure LoadNotes( HelpFile: THelpFile );
488 Procedure GotoCurrentNote;
489
490 // make sure that note insert positions are not in
491 // the middle of tags due to help file or newview updates.
492 Procedure CorrectNotesPositions( Topic: TTopic;
493 Text: pchar );
494
495 Procedure InsertNotesIntoTopicText( Topic: TTopic;
496 Text: TAString );
497 function FindOriginalNoteCharIndex( NoteCharIndex: longword;
498 Topic: TTopic ): longword;
499 function FindActualNoteCharIndex( NoteCharIndex: longword;
500 MaxNoteIndex: longword;
501 Topic: TTopic ): longword;
502 procedure RefreshNoteInsertInfo( NoteIndex: longword );
503 procedure ClearNotes;
504
505 Procedure EnableNotesControls;
506 Procedure UpdateNotesDisplay;
507
508 Procedure RefreshFontSubstitutions;
509
510 // GUI actions ------------------------------------------
511
512 procedure FileOpen;
513
514 Procedure PrintTopics;
515 function DoPrinting( Parameters: TObject ): TObject;
516 Procedure StopPrinting;
517
518 Procedure DoFind( FindOrigin: TFindOrigin );
519
520 // Bookmarks ------------------------------------------
521
522 Procedure NavigateToBookmark( Bookmark: TBookmark );
523 Procedure BuildBookmarksMenu;
524 Procedure UpdateBookmarksForm;
525 Procedure BookmarksMenuItemClick( Sender: TObject );
526 procedure AddBookmark;
527 procedure ClearBookmarks;
528 procedure SaveBookmarks;
529 procedure SaveBookmarksForFile( HelpFile: THelpFile );
530 procedure LoadBookmarks( HelpFile: THelpFile );
531 procedure OnBookmarksChanged( Sender: TObject );
532
533 // Global search -------------------------------------
534
535 procedure DoGlobalSearch( const SearchText: string );
536 // Called when viewing topics from global search
537 Procedure OnViewGlobalSearchTopic( FileName: string;
538 TopicIndex: longint );
539
540 // Options and appearance -----------------------------
541
542 procedure DoOptions;
543
544 procedure ApplySettings;
545
546 // changes normal or fixed font depending on shift state
547 Procedure SetTopicFont( NewFont: TFont );
548
549 Procedure SetApplicationFont( NewFont: TFont );
550
551 // Retrieve control colours (in case drag'n'drop used to change)
552 Procedure GetColors;
553 // Set the layout of the main form
554 Procedure SetLayout;
555 // Lay out the specified list of help windows
556 Procedure LayoutWindowList( WindowList: TList );
557 // Setup the rich text views in the specified windows (e.g for changing global settings)
558 Procedure SetupViews( WindowList: TList );
559
560 // Topic display -------------------------------------
561
562 // Major display topic function.
563 procedure DisplayTopic( Topic: TTopic );
564
565 Procedure DisplaySelectedIndexTopic;
566 Procedure DisplaySelectedSearchResultTopic;
567 Procedure DisplaySelectedContentsTopic;
568
569 Procedure DisplayTopicInWindow( Window: THelpWindow;
570 FollowAutoLinks: boolean;
571 KeepPosition: boolean );
572
573 function OpenWindow( Topic: TTopic;
574 Group: longint;
575 Parent: THelpWindow;
576 Rect: THelpWindowRect;
577 FollowAutoLinks: boolean ): THelpWindow;
578
579 Procedure RemoveHelpWindowFromParent( Window: THelpWindow );
580
581 Procedure FollowLink( Link: THelpLink;
582 SourceWindow: THelpWindow );
583
584 Function FindTopicByResourceID( ID: uint16 ): TTopic;
585 Function FindTopicByName( const Name: string ): TTopic;
586 Function FindTopicByGlobalName( const Name: string ): TTopic;
587
588 Function FindTopicForLink( Link: THelpLink ): TTopic;
589
590 Function FindWindowFromView( View: TRichTextView; WindowList: TList ): THelpWindow;
591 Function FindWindowFromGroup( Group: longint; WindowList: TList ): THelpWindow;
592 Function FindWindowFromTopic( Topic: TTopic; WindowList: TList ): THelpWindow;
593 Function GetActiveWindow: THelpWindow;
594
595 Procedure DoSearch;
596 Procedure SearchFor( const SearchText: string );
597 Procedure StartupTopicSearch( const SearchText: string );
598
599 // clear search match sequences
600 Procedure ClearAllWordSequences;
601
602 Procedure SetMainCaption;
603
604 // cancel help manager mode
605 Procedure ClearHelpManager;
606 Procedure PostHelpManagerMessage( MessageType: ULONG;
607 Param1: long;
608 Param2: long );
609
610 HelpManagerWindows: TList; // of HWND
611
612 function OwnHelpMode: boolean;
613 CurrentOpenFiles: TList; // current open help files.
614 MRUMenuItems: TList; // most recently used file list
615 NavigateToMenuItems: TList;
616 MainTitle: string;
617
618 // Current topic has the vague meaning that it was the last
619 // topic selected by the user... (?)
620 CurrentTopic: TTopic;
621
622 AllFilesWordSequences: TList; // of lists; one per open file; of possible word sequences
623
624 // use during decode...
625 TopicText: TAString;
626
627 Windows: TList; // top level help windows
628
629 PageHistory: TStringList; // history
630 CurrentHistoryIndex: longint; // where we are in history
631
632 Navigating: boolean; // true while going to a particular history point
633
634 DisplayedIndex: TStringList; // duplicate of index listbox,
635 // for fast case insensitive searching
636 InIndexSearch: boolean; // true while searching index
637 IndexLoaded: boolean;
638
639 ContentsLoaded: boolean;
640
641 StartingUp: boolean; // true while starting
642 SettingFont: boolean;
643 DisplayingTopicWindow: boolean;
644
645 FindText: string; // last text found (Ctrl-F)
646
647 Notes: TList; // Notes in current files.
648
649 Bookmarks: TList;
650 BookmarksMenuItems: TList;
651
652 // while loading... so owe can display progress
653 LoadingFilenameList: TStringList;
654 LoadingFileIndex: integer;
655
656 PrintThread: TGenericThreadManager;
657 procedure OnPrintProgress( n, outof: integer;
658 Message: string );
659 procedure OnPrintComplete( Dummy: TObject );
660 protected
661 // language stuff
662 FileOpenTitle: string;
663 LoadingFileMsg: string;
664 HelpFileError: string;
665 LoadingStatusDisplaying: string;
666 LoadingStatusNotesAndBookmarks: string;
667 LoadingStatusContents: string;
668 LoadingStatusIndex: string;
669 LoadingStatusDone: string;
670
671 AllFilesDesc: string;
672 HelpFilesDesc: string;
673 LanguageFilesDesc: string;
674
675 SaveLanguageTitle: string;
676 OpenLanguageTitle: string;
677 SaveLanguageError: string;
678
679 HelpManagerVersionTitle: string;
680
681 FindResourceIDTitle: string;
682 FindResourceIDPrompt: string;
683 InvalidResourceIDError: string;
684 ResourceIDNotFoundError: string;
685
686 OpenSpecialTitle: string;
687 OpenSpecialPrompt: string;
688
689 PrintTopicTitle: string;
690 NoPrinterError: string;
691 SelectWindowToPrintError: string;
692 PrintingError: string;
693 StoppingPrintMsg: string;
694 PrintStoppedMsg: string;
695 CheckStopPrintTitle: string;
696 CheckStopPrintMsg: string;
697
698 TopicInfoTitle: string;
699 TopicInfoTopicTitle: string;
700 TopicInfoIndex: string;
701 TopicInfoFile: string;
702 TopicInfoResourceIDs: string;
703 TopicInfoNoResourceIDs: string;
704
705 ParameterCountLabel: string;
706
707 NewViewHelpTitle: string;
708 AlreadyNewviewHelp: string;
709 NewViewHelpNotFound: string;
710
711 InvalidLinkErrorTitle: string;
712 InvalidLinkError: string;
713 InvalidResourceIDLinkErrorA: string;
714 InvalidResourceIDLinkErrorB: string;
715
716 OpenedTopicMsg: string;
717
718 AddNoteTitle: string;
719 AddNoteCursorError: string;
720 NoteWithinNoteError: string;
721 LoadNotesTitle: string;
722 LoadNotesError: string;
723 SaveNotesTitle: string;
724 SaveNotesError: string;
725
726 UntitledBookmarkName: string;
727 LoadBookmarksTitle: string;
728 LoadBookmarksError: string;
729 SaveBookmarksTitle: string;
730 SaveBookmarksError: string;
731
732 ApplicationErrorTitle: string;
733 ApplicationErrorA: string;
734 ApplicationErrorB: string;
735 ApplicationErrorC: string;
736
737 EnvironmentVarErrorTitle: string;
738 EnvironmentVarError: string;
739 EnvironmentVarUndefined: string;
740
741 FindTitle: string;
742 FindSelectWindowError: string;
743 FindPrompt: string;
744 TextNotFoundMsg: string;
745
746 FilesInfoTitle: string;
747 FilesInfoOverallTitle: string;
748 FilesInfoFilename: string;
749 FilesInfoFileTitle: string;
750 FilesInfoTopicCount: string;
751 FilesInfoIndexCount: string;
752 FilesInfoDictionaryCount: string;
753 FilesInfoFileSize: string;
754 FilesInfoTotalTopicCount: string;
755 FilesInfoTotalIndexCount: string;
756 FilesInfoTotalFileSize: string;
757
758 SearchTitle: string;
759 SearchSyntaxError: string;
760 SearchingMsg: string;
761 NoSearchMatchesMsg: string;
762 SearchFoundMsgA: string;
763 SearchFoundMsgB: string;
764
765 FileSaveTitle: string;
766 FileSaveSelectWindowError: string;
767 DefaultSaveTopicFilename: string;
768 ReplaceFilePromptA: string;
769 ReplaceFilePromptB: string;
770 UnableToSaveError: string;
771
772 UsageTitle: string;
773 UsageText1: string;
774 UsageText2: string;
775 UsageText3: string;
776 UsageText4: string;
777 UsageText5: string;
778 UsageText6: string;
779 UsageText7: string;
780 UsageText8: string;
781
782 GoBackHint: string;
783
784 SelectAllTitle: string;
785 SelectAllWindowError: string;
786
787 EditNoteMsg: string;
788 ExternalLinkMsg: string;
789 LinkMsg: string;
790 UnknownLinkMsg: string;
791 FootnoteMsg: string;
792
793 ExternalLinkTitle: string;
794 ExternalLinkError: string;
795
796 MRUMultipleFilesHint: string;
797
798 HelpProgramTitle: string;
799 WindowsHelpTitle: string;
800 WindowsHelpPrompt: string;
801
802 ErrorTitle: string;
803
804 FindTopicNameTitle: string;
805 FindTopicNamePrompt: string;
806 TopicNameNotFoundError: string;
807
808 SplitBarDblClickToShow: string;
809 SplitBarDblClickToHide: string;
810
811 End;
812
813Var
814 MainForm: TMainForm;
815
816Implementation
817
818uses
819 BseDos,
820 BseErr,
821 PMWin,
822 PmShl,
823 Dos,
824 Printers,
825
826 // Library
827 ACLStringUtility,
828 AStringUtilityUnit,
829 ACLFileUtility,
830 ACLFileIOUtility,
831 ACLUtility,
832 ACLDialogs,
833 ACLString,
834 RunProgramUnit,
835 StringUtilsUnit,
836 DebugUnit,
837
838 // Components
839 RichTextPrintUnit,
840 RichTextStyleUnit,
841 RichTextDocumentUnit,
842 ControlsUtility,
843
844 // local: forms
845 InformationFormUnit,
846 OptionsForm,
847 ProductInformationFormUnit,
848 NoteForm,
849 GlobalSearchForm,
850 FileDialogForm,
851 BookmarksFormUnit,
852 PrintDialogUnit,
853
854 // local: others
855 SettingsUnit,
856 VersionUnit,
857 SearchUnit,
858 StartupUnit,
859 GlobalFilelistUnit,
860 WebBrowserUnit,
861 HelpBitmap;
862
863{$R Images}
864
865const
866 // Coolbar button indexes
867 ciOpen = 0;
868 ciBack = 1;
869 ciForward = 2;
870 ciPrint = 3;
871 ciAddNote = 4;
872 ciAddBookmark = 5;
873 ciPrevious = 6;
874 ciNext = 7;
875 ciGlobalSearch = 8;
876
877 // Page indexes.
878 piContents = 0;
879 piIndex = 1;
880 piSearch = 2;
881 piNotes = 3;
882
883 CrashLogFileName = 'NewView.log';
884
885 _MAX_PATH = 260;
886
887var
888 hNewViewDLL: HMODULE;
889
890 StartMem: longword;
891 LastMem: longword;
892
893 g_ExternalLinkFilename: string;
894 g_ExternalLinkTopic: string;
895 g_ExternalLinkSourceFilename: string;
896 g_ExternalLinkKeepCurrent: boolean; // whether to keep current files open
897
898//
899// ----------------------------------------------------------------------------------------
900// TMainForm implementation
901// ----------------------------------------------------------------------------------------
902//
903
904Procedure TMainForm.SaveAsIPFMIOnClick (Sender: TObject);
905var
906 FileName: string;
907 F: TextFile;
908 H: THelpFile;
909 i: longint;
910 T: TTopic;
911 ResourceIDs: TList;
912 ImageOffsets: TList;
913 ImageOffset: longint;
914 Image: THelpBitmap;
915Begin
916 H := CurrentOpenFiles[ 0 ];
917
918 FileName := ChangeFileExt( ExtractFileName( H.Filename ), '.ipf' );
919 if not DoSaveFileDialog( FileSaveTitle,
920 'IPF' + '|*.ipf',
921 Filename,
922 Settings.LastSaveDirectory,
923 Filename ) then
924 exit;
925 if FileExists( Filename ) then
926 if not DoConfirmDlg( FileSaveTitle,
927 ReplaceFilePromptA
928 + Filename
929 + ReplaceFilePromptB ) then
930 exit;
931
932 ImageOffsets := TList.Create;
933
934 AssignFile( F, FileName );
935 Rewrite( F );
936 WriteLn( F, ':userdoc.' );
937
938 // We can't tell if some levels of the contents were
939 // merged into the text of topics. So we just assume all are visible
940 WriteLn( F, ':docprof toc=123456.' );
941
942 ResourceIDs := TList.Create;
943
944 WriteLn( F, ':title.' + H.Title );
945
946 for i := 0 to H.TopicCount - 1 do
947 begin
948 T := H.Topics[ i ];
949
950 SetProgress( i div 2, H.TopicCount , 'Saving text...' );
951
952 WriteLn( F, '' );
953
954
955 if T.ContentsLevel = 0 then
956 begin
957 // perhaps it means footnote?
958 // Level := 1;
959 Write( F, ':fn id=fn' + IntToStr( i ) + '.' ); // use index as id
960
961 T.SaveToIPF( F, ImageOffsets );
962
963 WriteLn( F, '' );
964 WriteLn( F, ':efn.' );
965 end
966 else
967 begin
968 Write( F, ':h' + IntToStr( T.ContentsLevel ) );
969 Write( F, ' id=' + IntToStr( i ) ); // use index as id
970
971 H.FindResourceIDsForTopic( T, ResourceIDs );
972 if ResourceIDs.Count > 0 then
973 begin
974 Write( F, ' res=' + IntToStr( longint( ResourceIDs[ 0 ] ) ) );
975 end;
976
977 if not T.ShowInContents then
978 Write( F, ' hide' );
979
980 if T.ContentsGroupIndex > 0 then
981 Write( F, ' group=' + IntToStr( T.ContentsGroupIndex ) );
982
983 Write( F, '.' ); // end of header
984 WriteLn( F, T.Title );
985
986 T.SaveToIPF( F, ImageOffsets );
987 end;
988
989
990
991 end;
992
993 ResourceIDs.Destroy;
994
995 WriteLn( F, ':euserdoc.' );
996 System.Close( F );
997
998 // Now write images
999
1000 for i := 0 to ImageOffsets.Count - 1 do
1001 begin
1002 ImageOffset := longint( ImageOffsets[ i ] );
1003
1004 SetProgress( i div 2 + ImageOffsets.Count div 2,
1005 ImageOffsets.Count ,
1006 'Saving images...' );
1007
1008 Image := H.GetImage( ImageOffset );
1009
1010 if Image <> nil then
1011 begin
1012 Image.SaveToFile( ExtractFilePath( Filename )
1013 + 'img'
1014 + IntToStr( i )
1015 + '.bmp' );
1016 Image.Destroy;
1017 end;
1018
1019 end;
1020
1021 ResetProgress;
1022 SetStatus( 'Save complete' );
1023 ImageOffsets.Destroy;
1024End;
1025
1026Procedure TMainForm.DebugFindBinaryMIOnClick (Sender: TObject);
1027Var
1028 DataStr: string;
1029 data: array[ 0.. 255 ] of byte;
1030 DataLen: longint;
1031 FileIndex: longint;
1032 HelpFile: THelpFile;
1033 i: longint;
1034 Topic: TTopic;
1035
1036Begin
1037 if not DoInputQuery( 'Binary Find',
1038 'Enter data to find (decimal, separate with spaces)',
1039 DataStr ) then
1040 exit;
1041
1042 DataLen := 0;
1043 while Length( DataStr ) > 0 do
1044 begin
1045 Data[ DataLen ] := StrToInt( ExtractNextValue( DataStr, ' ' ) );
1046 inc( DataLen );
1047 end;
1048
1049 ShowTab( piSearch );
1050 SearchResultsListBox.Clear;
1051
1052 for FileIndex := 0 to CurrentOpenFiles.Count - 1 do
1053 begin
1054 HelpFile := CurrentOpenFiles[ FileIndex ];
1055 for i := 0 to HelpFile.TopicCount -1 do
1056 begin
1057 Topic := HelpFile.Topics[ i ];
1058 if Topic.SearchForData( Addr( Data ), DataLen ) then
1059 begin
1060 SearchResultsListBox.Items.AddObject( Topic.Title, Topic );
1061 end;
1062
1063 end;
1064
1065 end;
1066
1067End;
1068
1069Procedure TMainForm.TopicByNameMIOnClick (Sender: TObject);
1070var
1071 TopicNameString: string;
1072Begin
1073 if not DoInputQuery( FindTopicNameTitle,
1074 FindTopicNamePrompt,
1075 TopicNameString ) then
1076 exit;
1077
1078 if not DisplayTopicByName( TopicNameString ) then
1079 if not DisplayTopicByGlobalName( TopicNameString ) then
1080 DoErrorDlg( FindTopicNameTitle,
1081 TopicNameNotFoundError );
1082End;
1083
1084Function TMainForm.pSharedStruct: TPNewHelpMgrSharedStruct;
1085begin
1086 Result := TPNewHelpMgrSharedStruct( SharedMemory.Data );
1087end;
1088
1089Procedure TMainForm.CopyLinkLocationPMIOnClick (Sender: TObject);
1090Begin
1091
1092End;
1093
1094Procedure TMainForm.HelpKeysMIOnClick (Sender: TObject);
1095Begin
1096// Application.Help( 10 );
1097End;
1098
1099Procedure TMainForm.MainFormOnCommand (Sender: TObject; Var Command: TCommand);
1100Begin
1101 case Command of
1102 kbF11:
1103 NavigatePreviousInContents;
1104
1105 kbF12:
1106 NavigateNextInContents;
1107
1108 kbF7,
1109 kbCtrlCLeft:
1110 NavigateBack;
1111
1112 kbF8:
1113 NavigateForward;
1114 end;
1115End;
1116
1117Procedure TMainForm.MainFormOnScan (Sender: TObject; Var KeyCode: TKeyCode);
1118Begin
1119End;
1120
1121Procedure TMainForm.ShowLeftPanelMIOnClick (Sender: TObject);
1122Begin
1123 ShowLeftPanel := not ShowLeftPanel;
1124End;
1125
1126Procedure TMainForm.CoolBarOnFontChange (Sender: TObject);
1127Begin
1128 SetApplicationFont( Coolbar.Font );
1129End;
1130
1131Procedure TMainForm.NotebookOnFontChange (Sender: TObject);
1132Begin
1133 SetApplicationFont( Notebook.Font );
1134End;
1135
1136Procedure TMainForm.TabSetOnFontChange (Sender: TObject);
1137Begin
1138 SetApplicationFont( TabSet.Font );
1139End;
1140
1141Procedure TMainForm.IndexListBoxOnFontChange (Sender: TObject);
1142Begin
1143 SetApplicationFont( IndexListBox.Font );
1144End;
1145
1146Procedure TMainForm.NotesListBoxOnFontChange (Sender: TObject);
1147Begin
1148 SetApplicationFont( NotesListBox.Font );
1149End;
1150
1151Procedure TMainForm.DisplayPanelOnFontChange (Sender: TObject);
1152Begin
1153 SetTopicFont( DisplayPanel.Font );
1154End;
1155
1156Procedure TMainForm.SetTopicFont( NewFont: TFont );
1157var
1158 ShiftPressed: boolean;
1159Begin
1160 if SettingFont or StartingUp then
1161 exit;
1162 LogEvent(LogSettings, 'SetTopicFont');
1163
1164 SettingFont := true;
1165
1166 ShiftPressed := ( WinGetKeyState( HWND_DESKTOP,
1167 VK_SHIFT ) and $8000 ) > 0;
1168 if ShiftPressed then
1169 Settings.FixedFont := NewFont
1170 else
1171 Settings.NormalFont := NewFont;
1172
1173 LogEvent(LogSettings, 'Saving settings');
1174
1175 SaveSettings;
1176 LogEvent(LogSettings, 'Applying settings');
1177 ApplySettings;
1178
1179 SettingFont := false;
1180 LogEvent(LogSettings, 'SetTopicFont done');
1181End;
1182
1183Procedure TMainForm.ContentsOutlineOnFontChange (Sender: TObject);
1184Begin
1185 SetApplicationFont( ContentsOutline.Font );
1186End;
1187
1188Procedure TMainForm.SetApplicationFont( NewFont: TFont );
1189Begin
1190 if ( not SettingFont ) and ( not StartingUp ) then
1191 begin
1192 Settings.Fonts[ ApplicationFontIndex ] := NewFont;
1193 SaveSettings;
1194 ApplySettings;
1195 SetLayout;
1196 end;
1197End;
1198
1199Procedure TMainForm.SearchResultsListBoxOnFontChange (Sender: TObject);
1200Begin
1201 SetApplicationFont( SearchResultsListBox.Font );
1202End;
1203
1204Procedure TMainForm.OnDragOverWindow(Sender: TObject; Source: TObject;
1205 X: LongInt; Y: LongInt; State: TDragState; Var Accept: Boolean);
1206Begin
1207 if Source is TExternalDragDropObject then
1208 Accept := true;
1209
1210End;
1211
1212Procedure TMainForm.OnDragDropToWindow(Sender: TObject; Source: TObject;
1213 X: LongInt; Y: LongInt);
1214Begin
1215 OpenDroppedFile( Source );
1216End;
1217
1218Procedure TMainForm.OnWindowTab( Sender: TObject );
1219Begin
1220 OnWindowBackTab( Sender ); // for now
1221End;
1222
1223Procedure TMainForm.OnWindowBackTab( Sender: TObject );
1224Begin
1225 case NoteBook.PageIndex of
1226 piContents:
1227 ContentsOutline.Focus;
1228 piIndex:
1229 IndexListBox.Focus;
1230 piSearch:
1231 SearchResultsListBox.Focus;
1232 piNotes:
1233 NotesListBox.Focus;
1234 end;
1235End;
1236
1237Procedure TMainForm.OnWindowFontChange( Sender: TObject );
1238begin
1239 if not DisplayingTopicWindow then
1240 SetTopicFont( TControl(Sender).Font );
1241end;
1242
1243Procedure TMainForm.DisplayPanelOnDragOver (Sender: TObject; Source: TObject;
1244 X: LongInt; Y: LongInt; State: TDragState; Var Accept: Boolean);
1245Begin
1246 if Source is TExternalDragDropObject then
1247 Accept := true;
1248End;
1249
1250Procedure TMainForm.NotesListBoxOnDragOver (Sender: TObject; Source: TObject;
1251 X: LongInt; Y: LongInt; State: TDragState; Var Accept: Boolean);
1252Begin
1253 if Source is TExternalDragDropObject then
1254 Accept := true;
1255End;
1256
1257Procedure TMainForm.DisplayPanelOnDragDrop (Sender: TObject; Source: TObject;
1258 X: LongInt; Y: LongInt);
1259Begin
1260 OpenDroppedFile( Source );
1261End;
1262
1263Procedure TMainForm.NotesListBoxOnDragDrop (Sender: TObject; Source: TObject;
1264 X: LongInt; Y: LongInt);
1265Begin
1266 OpenDroppedFile( Source );
1267End;
1268
1269Procedure TMainForm.SearchResultsListBoxOnDragDrop (Sender: TObject;
1270 Source: TObject; X: LongInt; Y: LongInt);
1271Begin
1272 OpenDroppedFile( Source );
1273End;
1274
1275Procedure TMainForm.SearchResultsListBoxOnDragOver (Sender: TObject;
1276 Source: TObject; X: LongInt; Y: LongInt; State: TDragState;
1277 Var Accept: Boolean);
1278Begin
1279 if Source is TExternalDragDropObject then
1280 Accept := true;
1281End;
1282
1283Procedure TMainForm.IndexListBoxOnDragDrop (Sender: TObject; Source: TObject;
1284 X: LongInt; Y: LongInt);
1285Begin
1286 OpenDroppedFile( Source );
1287End;
1288
1289Procedure TMainForm.IndexListBoxOnDragOver (Sender: TObject; Source: TObject;
1290 X: LongInt; Y: LongInt; State: TDragState; Var Accept: Boolean);
1291Begin
1292 if Source is TExternalDragDropObject then
1293 Accept := true;
1294End;
1295
1296Procedure TMainForm.ContentsOutlineOnDragOver (Sender: TObject;
1297 Source: TObject; X: LongInt; Y: LongInt; State: TDragState;
1298 Var Accept: Boolean);
1299Begin
1300 if Source is TExternalDragDropObject then
1301 Accept := true;
1302End;
1303
1304Procedure TMainForm.ContentsOutlineOnDragDrop (Sender: TObject;
1305 Source: TObject; X: LongInt; Y: LongInt);
1306Begin
1307 OpenDroppedFile( Source );
1308End;
1309
1310Procedure TMainForm.OpenDroppedFile( Source: TObject );
1311var
1312 DropObject: TExternalDragDropObject;
1313Begin
1314 if not ( Source is TExternalDragDropObject ) then
1315 // probably not needed, but crashes during drag drop completely
1316 // screw PM, so best to be sure!
1317 exit;
1318
1319 DropObject := Source as TExternalDragDropObject;
1320
1321 g_ExternalLinkFileName := AddSlash( DropObject.ContainerName )
1322 + DropObject.SourceFilename;
1323 g_ExternalLinkTopic := '';
1324 g_ExternalLinkSourceFilename := ''; // don't care
1325
1326 g_ExternalLinkKeepCurrent := ( WinGetKeyState( HWND_DESKTOP,
1327 VK_SHIFT ) and $8000 ) > 0;
1328 PostMsg( Self.Handle,
1329 WM_FOLLOWEXTERNALLINK,
1330 0,
1331 0 );
1332
1333End;
1334
1335Procedure TMainForm.MainFormOnDragOver (Sender: TObject; Source: TObject;
1336 X: LongInt; Y: LongInt; State: TDragState; Var Accept: Boolean);
1337Begin
1338 Accept := true;
1339End;
1340
1341Procedure TMainForm.MainFormOnDragDrop (Sender: TObject; Source: TObject;
1342 X: LongInt; Y: LongInt);
1343Begin
1344End;
1345
1346Procedure TMainForm.ContentsOutlineOnItemClick (Node: TNode);
1347Begin
1348 DisplaySelectedContentsTopic;
1349End;
1350
1351Procedure TMainForm.SetMainCaption;
1352begin
1353 if ( Trim( MainTitle ) = '' )
1354 or ( StringsSame( Trim( MainTitle ), HelpProgramTitle ) ) then
1355 // supress "Help - " or "Help - Help"
1356 Caption := HelpProgramTitle
1357 else
1358 Caption := HelpProgramTitle + ' - ' + MainTitle
1359end;
1360
1361Procedure TMainForm.OnLanguageEvent( Language: TLanguageFile;
1362 const Apply: boolean );
1363Begin
1364 // get rid of mru menu items
1365 DestroyListObjects( MRUMenuItems );
1366 MRUMenuItems.Clear;
1367
1368 Language.LoadComponentLanguage( self, Apply );
1369
1370 if Apply then
1371 begin
1372 // copy menu hints to toolbar hints
1373 Coolbar.Sections[ ciOpen ].Hint := OpenMI.Hint;
1374 Coolbar.Sections[ ciBack ].Hint := NavigateBackMI.Hint;
1375 Coolbar.Sections[ ciForward ].Hint := NavigateForwardMI.Hint;
1376 Coolbar.Sections[ ciPrint ].Hint := PrintMI.Hint;
1377 Coolbar.Sections[ ciAddNote ].Hint := AddNoteMI.Hint;
1378 Coolbar.Sections[ ciAddBookmark ].Hint := AddBookmarkMI.Hint;
1379 Coolbar.Sections[ ciPrevious ].Hint := NavigatePreviousMI.Hint;
1380 Coolbar.Sections[ ciNext ].Hint := NavigateNextMI.Hint;
1381 Coolbar.Sections[ ciGlobalSearch ].Hint := GlobalSearchMI.Hint;
1382 end;
1383
1384 // Load strings referred to by code...
1385 // ----------------------------------------------------------
1386
1387 Language.LL( Apply, FileOpenTitle, 'FileOpenTitle', 'Open Help Files' );
1388 Language.LL( Apply, LoadingFileMsg, 'LoadingFileMsg', 'Loading file ' );
1389 Language.LL( Apply, HelpFileError, 'HelpFileError', 'Could not open ' );
1390 Language.LL( Apply, LoadingStatusDisplaying, 'LoadingStatusDisplaying', 'Displaying...' );
1391 Language.LL( Apply, LoadingStatusNotesAndBookmarks, 'LoadingStatusNotesAndBookmarks', 'Loading notes/bookmarks...' );
1392 Language.LL( Apply, LoadingStatusContents, 'LoadingStatusContents', 'Display contents... ' );
1393 Language.LL( Apply, LoadingStatusIndex, 'LoadingStatusIndex', 'Display index... ' );
1394 Language.LL( Apply, LoadingStatusDone, 'LoadingStatusDone', 'Done' );
1395
1396 Language.LL( Apply, HelpFilesDesc, 'HelpFilesDesc', 'Help Files (*.inf,*.hlp)' );
1397 Language.LL( Apply, AllFilesDesc, 'AllFilesDesc', 'All Files (*)' );
1398 Language.LL( Apply, LanguageFilesDesc, 'LanguageFilesDesc', 'NewView Language Files (*.lng)' );
1399
1400 Language.LL( Apply, SaveLanguageTitle, 'SaveLanguageTitle', 'Save/Update Language File' );
1401 Language.LL( Apply, OpenLanguageTitle, 'OpenLanguageTitle', 'Open Language File' );
1402 Language.LL( Apply, SaveLanguageError, 'SaveLanguageError', 'Error saving language file: ' );
1403
1404 Language.LL( Apply, HelpManagerVersionTitle, 'HelpManagerVersionTitle', 'Help Manager Version' );
1405
1406 Language.LL( Apply, FindResourceIDTitle, 'FindResourceIDTitle', 'Find Resource ID' );
1407 Language.LL( Apply, FindResourceIDPrompt, 'FindResourceIDPrompt', 'Enter the resource ID to find' );
1408 Language.LL( Apply, InvalidResourceIDError, 'InvalidResourceIDError', 'Invalid resource ID entered' );
1409 Language.LL( Apply, ResourceIDNotFoundError, 'ResourceIDNotFoundError', 'Resource ID not found' );
1410
1411 Language.LL( Apply, OpenSpecialTitle, 'OpenSpecialTitle', 'Open Special' );
1412 Language.LL( Apply, OpenSpecialPrompt, 'OpenSpecialPrompt', 'Enter help file name/environment variable name' );
1413
1414 Language.LL( Apply, PrintTopicTitle, 'PrintTopicTitle', 'Print Topic' );
1415 Language.LL( Apply, NoPrinterError, 'NoPrinterError', 'You don''t have a printer configured.' );
1416 Language.LL( Apply, SelectWindowToPrintError, 'SelectWindowToPrintError', 'You must select the window you want to print.' );
1417 Language.LL( Apply, PrintingError, 'PrintingError', 'Error while printing: ' );
1418 Language.LL( Apply, StoppingPrintMsg, 'StoppingPrintMsg', 'Stopping print...' );
1419 Language.LL( Apply, PrintStoppedMsg, 'PrintStoppedMsg', 'Printing stopped' );
1420 Language.LL( Apply, CheckStopPrintTitle, 'CheckStopPrintTitle', 'Stop Print?' );
1421 Language.LL( Apply, CheckStopPrintMsg, 'CheckStopPrintMsg', 'Printing is still in progress. It will be stopped if you close.' );
1422
1423 Language.LL( Apply, TopicInfoTitle, 'TopicInfo.Title', 'Topic Information' );
1424 Language.LL( Apply, TopicInfoTopicTitle, 'TopicInfo.TopicTitle', 'Title: ' );
1425 Language.LL( Apply, TopicInfoIndex, 'TopicInfo.Index', 'Index: ' );
1426 Language.LL( Apply, TopicInfoFile, 'TopicInfo.File', 'File: ' );
1427 Language.LL( Apply, TopicInfoResourceIDs, 'TopicInfo.ResourceIDs', 'Resource IDs:' );
1428 Language.LL( Apply, TopicInfoNoResourceIDs, 'TopicInfo.NoResourceIDs', ' (None)' );
1429
1430 Language.LL( Apply, ParameterCountLabel, 'ParameterCountLabel', 'Parameter Count: ' );
1431
1432 Language.LL( Apply, NewViewHelpTitle, 'NewViewHelpTitle', 'NewView Help' );
1433 Language.LL( Apply, AlreadyNewviewHelp, 'AlreadyNewviewHelp', 'You are already viewing the NewView help file' );
1434 Language.LL( Apply, NewViewHelpNotFound, 'NewViewHelpNotFound', 'Couldn''t find the NewView helpfile: ' );
1435
1436 Language.LL( Apply, InvalidLinkErrorTitle, 'InvalidLinkErrorTitle', 'Invalid Link' );
1437 Language.LL( Apply, InvalidLinkError, 'InvalidLinkError', 'Cannot follow link to nonexistent topic' );
1438 Language.LL( Apply, InvalidResourceIDLinkErrorA, 'InvalidResourceIDLinkErrorA', 'Could not find linked topic (Resource #' );
1439 Language.LL( Apply, InvalidResourceIDLinkErrorB, 'InvalidResourceIDLinkErrorB', '). This may be from another file.' );
1440
1441 Language.LL( Apply, OpenedTopicMsg, 'OpenedTopicMsg', 'Opened topic #' );
1442
1443 Language.LL( Apply, AddNoteTitle, 'AddNoteTitle', 'Add Note' );
1444 Language.LL( Apply, AddNoteCursorError, 'AddNoteCursorError', 'Before adding a note, position the cursor where you want the note to be placed.' );
1445 Language.LL( Apply, NoteWithinNoteError, 'NoteWithinNoteError', 'You can''t add a note within a link or another note' );
1446 Language.LL( Apply, LoadNotesTitle, 'LoadNotesTitle', 'Load Notes' );
1447 Language.LL( Apply, LoadNotesError, 'LoadNotesError', 'Error loading notes from ' );
1448 Language.LL( Apply, SaveNotesTitle, 'SaveNotesTitle', 'Save Notes' );
1449 Language.LL( Apply, SaveNotesError, 'SaveNotesError', 'Error saving notes to ' );
1450
1451 Language.LL( Apply, UntitledBookmarkName, 'UntitledBookmarkName', '(Untitled)' );
1452 Language.LL( Apply, LoadBookmarksTitle, 'LoadBookmarksTitle', 'Load Bookmarks' );
1453 Language.LL( Apply, LoadBookmarksError, 'LoadBookmarksError', 'Could not load bookmarks: ' );
1454 Language.LL( Apply, SaveBookmarksTitle, 'SaveBookmarksTitle', 'Save Bookmarks' );
1455 Language.LL( Apply, SaveBookmarksError, 'SaveBookmarksError', 'Could not save bookmarks: ' );
1456
1457 Language.LL( Apply, ApplicationErrorTitle, 'ApplicationErrorTitle', 'Application Error - Close?' );
1458 Language.LL( Apply, ApplicationErrorA, 'ApplicationErrorA', 'This application has crashed. ' );
1459 Language.LL( Apply, ApplicationErrorB, 'ApplicationErrorB', '(Details logged to ' );
1460 Language.LL( Apply, ApplicationErrorC, 'ApplicationErrorC', 'Close application? ' );
1461
1462 Language.LL( Apply, EnvironmentVarErrorTitle, 'EnvironmentVarErrorTitle', 'Environment Variable Warning' );
1463 Language.LL( Apply, EnvironmentVarError,
1464 'EnvironmentVarError',
1465 'NewView found a problem with environment variables. '
1466 + 'These are used when finding help files. '
1467 + 'You may have problems launching help.' );
1468 Language.LL( Apply, EnvironmentVarUndefined, 'EnvironmentVarUndefined', 'Undefined: ' );
1469
1470 Language.LL( Apply, FindTitle, 'FindTitle', 'Find' );
1471 Language.LL( Apply, FindSelectWindowError, 'FindSelectWindowError', 'Click in a window first' );
1472 Language.LL( Apply, FindPrompt, 'FindPrompt', 'Enter the text to find' );
1473 Language.LL( Apply, TextNotFoundMsg, 'TextNotFoundMsg', 'Text not found' );
1474
1475 Language.LL( Apply, FilesInfoTitle, 'FilesInfoTitle', 'Open Files Information' );
1476 Language.LL( Apply, FilesInfoOverallTitle, 'FilesInfoOverallTitle', 'Title: ' );
1477 Language.LL( Apply, FilesInfoFilename, 'FilesInfoFilename', 'Filename: ' );
1478 Language.LL( Apply, FilesInfoFileTitle, 'FilesInfoFileTitle', ' Title: ' );
1479 Language.LL( Apply, FilesInfoTopicCount, 'FilesInfoTopicCount', ' Topic Count: ' );
1480 Language.LL( Apply, FilesInfoIndexCount, 'FilesInfoIndexCount', ' Index Count: ' );
1481 Language.LL( Apply, FilesInfoDictionaryCount, 'FilesInfoDictionaryCount', ' Dictionary Count: ' );
1482 Language.LL( Apply, FilesInfoFileSize, 'FilesInfoFileSize', ' Size: ' );
1483 Language.LL( Apply, FilesInfoTotalTopicCount, 'FilesInfoTotalTopicCount', 'Total Topic Count: ' );
1484 Language.LL( Apply, FilesInfoTotalIndexCount, 'FilesInfoTotalIndexCount', 'Total Index Count: ' );
1485 Language.LL( Apply, FilesInfoTotalFileSize, 'FilesInfoTotalFileSize', 'Total File Size: ' );
1486
1487 Language.LL( Apply, SearchTitle, 'SearchTitle', 'Search' );
1488 Language.LL( Apply, SearchSyntaxError, 'SearchSyntaxError', 'Error in search syntax: ' );
1489 Language.LL( Apply, SearchingMsg, 'SearchingMsg', 'Searching...' );
1490 Language.LL( Apply, NoSearchMatchesMsg, 'NoSearchMatchesMsg', 'No matches found for ' );
1491 Language.LL( Apply, SearchFoundMsgA, 'SearchFoundMsgA', 'Found ' );
1492 Language.LL( Apply, SearchFoundMsgB, 'SearchFoundMsgB', ' matches for ' );
1493
1494 Language.LL( Apply, FileSaveTitle, 'FileSaveTitle', 'Save Topic' );
1495 Language.LL( Apply, FileSaveSelectWindowError, 'FileSaveSelectWindowError', 'Before saving, click in the window you want to save.' );
1496 Language.LL( Apply, DefaultSaveTopicFilename, 'DefaultSaveTopicFilename', 'topic.txt' );
1497
1498 Language.LL( Apply, ReplaceFilePromptA, 'ReplaceFilePromptA', 'Replace existing file ' );
1499 Language.LL( Apply, ReplaceFilePromptB, 'ReplaceFilePromptB', '?' );
1500 Language.LL( Apply, UnableToSaveError, 'UnableToSaveError', 'Unable to save file: ' );
1501
1502 Language.LL( Apply, UsageTitle, 'UsageTitle', 'NewView Command Line' );
1503 Language.LL( Apply, UsageText1, 'UsageText1', 'Usage: ' );
1504 Language.LL( Apply, UsageText2, 'UsageText2', 'NewView <filename> [<topic>]' );
1505 Language.LL( Apply, UsageText3, 'UsageText3', ' /s:<text> Do search for <text>' );
1506 Language.LL( Apply, UsageText4, 'UsageText4', ' /g:<text> Do global search for <text>' );
1507 Language.LL( Apply, UsageText5, 'UsageText5', ' /pos:l,b,w,h Set window position' );
1508 Language.LL( Apply, UsageText6, 'UsageText6', ' /lang:<lang> Load UI language' );
1509 Language.LL( Apply, UsageText7, 'UsageText7', ' /title:<title> Set window title' );
1510 Language.LL( Apply, UsageText8, 'UsageText8', 'See help for details' );
1511
1512 Language.LL( Apply, GoBackHint, 'GoBackHint', 'Go back to ' );
1513
1514 Language.LL( Apply, SelectAllTitle, 'SelectAllTitle', 'Select All' );
1515 Language.LL( Apply, SelectAllWindowError, 'SelectAllWindowError', 'Click in a text window first' );
1516
1517 Language.LL( Apply, EditNoteMsg, 'EditNoteMsg', 'Click to edit note' );
1518 Language.LL( Apply, ExternalLinkMsg, 'ExternalLinkMsg', 'Link to another file' );
1519 Language.LL( Apply, LinkMsg, 'LinkMsg', 'Link to ' );
1520 Language.LL( Apply, UnknownLinkMsg, 'UnknownLinkMsg', 'Unknown link' );
1521 Language.LL( Apply, FootnoteMsg, 'FootnoteMsg', 'Footnote' );
1522
1523 Language.LL( Apply, ExternalLinkTitle, 'ExternalLinkTitle', 'File Link' );
1524 Language.LL( Apply, ExternalLinkError, 'ExternalLinkError', 'Sorry, this is a link to another file, which is not currently implemented in NewView' );
1525
1526 Language.LL( Apply, MRUMultipleFilesHint, 'MRUMultipleFilesHint', 'files' );
1527 Language.LL( Apply, HelpProgramTitle, 'HelpProgramTitle', 'Help' );
1528
1529 Language.LL( Apply, WindowsHelpTitle, 'WindowsHelpTitle', 'Windows Help' );
1530 Language.LL( Apply,
1531 WindowsHelpPrompt,
1532 'WindowsHelpPrompt',
1533 'This file is a Windows help file. '
1534 + 'Would you like to start Windows Help viewer?' );
1535
1536 Language.LL( Apply, ErrorTitle, 'ErrorTitle', 'Error' );
1537
1538 Language.LL( Apply, FindTopicNameTitle, 'FindTopicNameTitle', 'Find Topic By Name' );
1539 Language.LL( Apply, FindTopicNamePrompt, 'FindTopicNamePrompt', 'Enter the topic name to search for' );
1540 Language.LL( Apply, TopicNameNotFoundError, 'TopicNameNotFoundError', 'Topic name not found' );
1541 Language.LL( Apply, SplitBarDblClickToShow, 'SplitBarDblClickToShow', 'Double-click to show left panel' );
1542 Language.LL( Apply, SplitBarDblClickToHide, 'SplitBarDblClickToHide', 'Double-click to hide left panel' );
1543
1544 SetMainCaption;
1545 CreateMRUMenuItems;
1546
1547 // ----------------------------------------------------------
1548end;
1549
1550Procedure TMainForm.DebugLoadLanguageMIOnClick (Sender: TObject);
1551Var
1552 Dir: string;
1553 Filename: string;
1554Begin
1555 Dir := GetApplicationDir;
1556 if not DoOpenFileDialog( OpenLanguageTitle,
1557 LanguageFilesDesc
1558 + '|*.lng|'
1559 + AllFilesDesc
1560 + '|*',
1561 '*.lng',
1562 Dir,
1563 Filename ) then
1564 exit;
1565
1566 LoadLanguage( Filename );
1567End;
1568
1569Procedure TMainForm.DebugSaveLanguageFileMIOnClick (Sender: TObject);
1570Var
1571 LanguageFile: TLanguageFile;
1572 Dir: string;
1573 Filename: string;
1574Begin
1575 Dir := GetApplicationDir;
1576 if not DoSaveFileDialog( SaveLanguageTitle,
1577 LanguageFilesDesc
1578 + '|*.lng|'
1579 + AllFilesDesc
1580 + '|*',
1581 '*.lng',
1582 Dir,
1583 Filename ) then
1584 exit;
1585
1586 // get rid of mru menu items so they don't clutter the language file
1587 DestroyListObjects( MRUMenuItems );
1588 MRUMenuItems.Clear;
1589
1590 try
1591 LanguageFile := TLanguageFile.Create( Filename );
1592
1593 UpdateLanguage( LanguageFile );
1594 except
1595 on E: Exception do
1596 begin
1597 DoErrorDlg( SaveLanguageTitle,
1598 SaveLanguageError + E.Message );
1599 exit;
1600 end;
1601 end;
1602
1603 LanguageFile.Destroy;
1604
1605 CreateMRUMenuItems;
1606End;
1607
1608Procedure TMainForm.SearchResultsListBoxOnClick (Sender: TObject);
1609Begin
1610 DisplaySelectedSearchResultTopic;
1611End;
1612
1613Procedure TMainForm.VSplitBarOnDblClick (Sender: TObject);
1614Begin
1615 ShowLeftPanel := not ShowLeftPanel;
1616End;
1617
1618Procedure TMainForm.DebugHelpManagerVersionMIOnClick (Sender: TObject);
1619Begin
1620 DoMessageDlg( HelpManagerVersionTitle,
1621 HelpManagerVersion );
1622End;
1623
1624Procedure TMainForm.DebugTopicByResourceIDMIOnClick (Sender: TObject);
1625var
1626 ResourceIDString: string;
1627 ResourceID: USHORT;
1628Begin
1629 if not DoInputQuery( FindResourceIDTitle,
1630 FindResourceIDPrompt,
1631 ResourceIDString ) then
1632 exit;
1633 try
1634 ResourceID := StrToInt( ResourceIDString );
1635 except
1636 DoErrorDlg( FindResourceIDTitle,
1637 InvalidResourceIDError );
1638 exit;
1639 end;
1640
1641 if not DisplayTopicByResourceID( ResourceID ) then
1642 DoErrorDlg( FindResourceIDTitle,
1643 ResourceIDNotFoundError );
1644End;
1645
1646Procedure TMainForm.ViewHighlightSearchWordsMIOnClick (Sender: TObject);
1647Begin
1648 ViewHighlightSearchWordsMI.Checked := not ViewHighlightSearchWordsMI.Checked;
1649 RefreshWindows( Windows );
1650End;
1651
1652Procedure TMainForm.FileNewWindowMIOnClick (Sender: TObject);
1653Begin
1654 Exec( GetApplicationFilename, '' );
1655End;
1656
1657Function TMainForm.OpenFilesFromTextList( const TextList: string;
1658 const DisplayFirstTopic: boolean ): boolean;
1659var
1660 Filenames: TStringList;
1661begin
1662 Filenames := TStringList.Create;
1663 StringToList( TextList, Filenames, '+' );
1664 if Filenames.Count > 0 then
1665 begin
1666 result := OpenFiles( Filenames, '', DisplayFirstTopic );
1667 end
1668 else
1669 begin
1670 CloseFile;
1671 end;
1672 Filenames.Destroy;
1673end;
1674
1675Procedure TMainForm.OpenSpecialMIOnClick (Sender: TObject);
1676var
1677 Parameter: string;
1678Begin
1679 if not OKToCloseFile then
1680 exit;
1681
1682 if DoInputQuery( OpenSpecialTitle,
1683 OpenSpecialPrompt,
1684 Parameter ) then
1685 begin
1686 if OpenFilesFromTextList( Parameter, true ) then
1687 begin
1688 ClearHelpManager;
1689 end;
1690 end;
1691End;
1692
1693Procedure TMainForm.NotesListBoxOnScan (Sender: TObject;
1694 Var KeyCode: TKeyCode);
1695Begin
1696 if KeyCode in [ kbDel, kbBkSp ] then
1697 if NotesListBox.ItemIndex <> -1 then
1698 DeleteNote( NotesListBox.ItemIndex );
1699End;
1700
1701Procedure TMainForm.ViewPopupMenuOnPopup (Sender: TObject);
1702var
1703 Window: THelpWindow;
1704Begin
1705 Window := GetActiveWindow;
1706 if Window = nil then
1707 begin
1708 SearchPMI.Enabled := false;
1709 exit;
1710 end;
1711 SearchPMI.Enabled := Window.View.SelectionLength > 0;
1712End;
1713
1714Procedure TMainForm.SearchPMIOnClick (Sender: TObject);
1715var
1716 Window: THelpWindow;
1717Begin
1718 Window := GetActiveWindow;
1719 if Window = nil then
1720 exit;
1721
1722 SearchFor( Window.View.GetSelectionAsString );
1723end;
1724
1725function TMainForm.DisplayTopicByGlobalName( const TopicName: string ): boolean;
1726var
1727 Topic: TTopic;
1728begin
1729 Topic := FindTopicByGlobalName( TopicName );
1730 if Topic = nil then
1731 begin
1732 Result := false;
1733 exit;
1734 end;
1735
1736 result := true;
1737
1738 DisplayTopic( Topic );
1739end;
1740
1741function TMainForm.DisplayTopicByName( const TopicName: string ): boolean;
1742var
1743 Topic: TTopic;
1744begin
1745 Topic := FindTopicByName( TopicName );
1746 if Topic = nil then
1747 begin
1748 Result := false;
1749 exit;
1750 end;
1751
1752 result := true;
1753
1754 DisplayTopic( Topic );
1755end;
1756
1757function TMainForm.DisplayTopicByResourceID( ID: uint16 ): boolean;
1758var
1759 Topic: TTopic;
1760begin
1761 Topic := FindTopicByResourceID( ID );
1762 if Topic = nil then
1763 begin
1764 Result := false;
1765 exit;
1766 end;
1767
1768 result := true;
1769
1770 DisplayTopic( Topic );
1771end;
1772
1773Procedure TMainForm.ViewSourceMIOnClick (Sender: TObject);
1774var
1775 Window: THelpWindow;
1776Begin
1777 Window := GetActiveWindow;
1778 if Window = nil then
1779 exit;
1780 InformationForm.FText := Window.View.Text;
1781 InformationForm.ShowModal;
1782End;
1783
1784Procedure TMainForm.PrintMIOnClick (Sender: TObject);
1785Begin
1786 PrintTopics;
1787End;
1788
1789type
1790 TPrintSingle = class
1791 Topic: TTopic;
1792 end;
1793
1794 TPrintList = class
1795 Topics: TList;
1796 constructor Create;
1797 destructor Destroy; override;
1798 end;
1799
1800 TPrintAll = class
1801 end;
1802
1803constructor TPrintList.Create;
1804begin
1805 Topics := TList.Create;
1806end;
1807
1808destructor TPrintList.Destroy;
1809begin
1810 Topics.Destroy;
1811end;
1812
1813// Recursive
1814Procedure GetTopicsInWindows( Windows: TList;
1815 Topics: TList );
1816var
1817 Window: THelpWindow;
1818 i: longint;
1819begin
1820 for i := 0 to Windows.Count - 1 do
1821 begin
1822 Window := Windows[ i ];
1823 Topics.Add( Window.Topic );
1824 GetTopicsInWindows( Window.ChildWindows, Topics );
1825 end;
1826end;
1827
1828Procedure TMainForm.PrintTopics;
1829var
1830 Window: THelpWindow;
1831 PrintParameters: TObject;
1832Begin
1833 if Printer.Printers.Count = 0 then
1834 begin
1835 DoErrorDlg( PrintTopicTitle,
1836 NoPrinterError );
1837 exit;
1838 end;
1839
1840 if NewViewPrintDialog.ShowModal <> mrOK then
1841 exit;
1842
1843 if PrintThread = nil then
1844 begin
1845 PrintThread := TGenericThreadManager.Create( self );
1846 PrintThread.OnProgressUpdate := OnPrintProgress;
1847 PrintThread.OnJobComplete := OnPrintComplete;
1848
1849 end;
1850
1851 case NewViewPrintDialog.WhatToPrintRadioGroup.ItemIndex of
1852 0:
1853 begin
1854 PrintParameters := TPrintSingle.Create;
1855 Window := GetActiveWindow;
1856 TPrintSingle( PrintParameters ).Topic := Window.Topic;
1857 end;
1858
1859 1:
1860 begin
1861 PrintParameters := TPrintList.Create;
1862 GetTopicsInWindows( Windows,
1863 TPrintList( PrintParameters ).Topics );
1864 end;
1865
1866 2:
1867 begin
1868 PrintParameters := TPrintAll.Create;
1869 end;
1870 end;
1871
1872 PrintThread.StartJob( DoPrinting, PrintParameters );
1873
1874 SetStatus( 'Printing...' );
1875end;
1876
1877procedure PrintTopic( Topic: TTopic;
1878 RichTextSettings: TRichTextSettings;
1879 Var PageY: longint );
1880var
1881 TopicText: TAstring;
1882 TitleText: TAString;
1883 ImageOffsets: TList;
1884 Images: TImageList;
1885begin
1886 TopicText := TAstring.Create;
1887 Images := TImageList.Create( nil );
1888 TitleText := TAString.Create;
1889 ImageOffsets := TList.Create;
1890
1891 TitleText.AddString( '<leftmargin 1><h1>'
1892 + Topic.Title
1893 + '</h>'
1894 + #10
1895 + #10 );
1896 PrintRichText( TitleText.AsPChar,
1897 Images,
1898 RichTextSettings,
1899 PageY );
1900
1901 Topic.GetText( nil, // no highlights
1902 false, // no codes
1903 false, // no word separators
1904 TopicText, // text to print
1905 ImageOffsets, // image offsets
1906 nil ); // no highlight matches required
1907
1908 THelpFile( Topic.HelpFile ).GetImages( ImageOffsets,
1909 Images );
1910
1911 PrintRichText( TopicText.AsPChar,
1912 Images,
1913 RichTextSettings,
1914 PageY );
1915
1916 TitleText.Clear;
1917 TitleText.AddString( #10
1918 + '<leftmargin 1><align center>'
1919 + '--------------------------------------------'
1920 + #10
1921 + #10 );
1922 PrintRichText( TitleText.AsPChar,
1923 Images,
1924 RichTextSettings,
1925 PageY );
1926
1927 ImageOffsets.Destroy;
1928 TitleText.Destroy;
1929 Images.Destroy;
1930 TopicText.Destroy;
1931end;
1932
1933function TMainForm.DoPrinting( Parameters: TObject ): TObject;
1934var
1935 PrintSingle: TPrintSingle;
1936 PrintList: TPrintList;
1937 PageY: longint;
1938 RichTextSettings: TRichTextSettings;
1939 PrinterResolution: longint;
1940 MarginSize: longint;
1941
1942 HelpFile: THelpFile;
1943
1944 FileIndex: longint;
1945 TopicIndex: longint;
1946
1947 TotalTopics: longint;
1948 TotalTopicIndex: longint;
1949begin
1950 PrintSingle := nil;
1951 PrintList := nil;
1952
1953 if Parameters is TPrintSingle then
1954 PrintSingle := Parameters as TPrintSingle
1955 else if Parameters is TPrintList then
1956 PrintList := Parameters as TPrintList;
1957
1958 if Parameters is TPrintSingle then
1959 Printer.Title := PrintSingle.Topic.Title
1960 else
1961 Printer.Title := MainTitle;
1962
1963 Printer.BeginDoc;
1964
1965 PageY := Printer.PageHeight - 1;
1966
1967 RichTextSettings := TRichTextSettings.Create( nil );
1968 RichTextSettings.NormalFont := Settings.NormalFont;
1969 RichTextSettings.FixedFont := Settings.FixedFont;
1970
1971 // set half inch margins
1972 PrinterResolution := Printer.Canvas.HorizontalResolution; // pixels per meter!
1973 MarginSize := Round( PrinterResolution * 0.0125 ); // 12.5 mm = 0.5 inch
1974 RichTextSettings.Margins := Rect( MarginSize,
1975 MarginSize,
1976 MarginSize,
1977 MarginSize );
1978
1979 try
1980 if Parameters is TPrintSingle then
1981 begin
1982 PrintTopic( PrintSingle.Topic, RichTextSettings, PageY );
1983 end
1984
1985 else if Parameters is TPrintList then
1986 begin
1987 for TopicIndex := 0 to PrintList.Topics.Count -1 do
1988 begin
1989 PrintThread.UpdateProgress( TopicIndex, PrintList.Topics.Count, 'Printing' );
1990
1991 PrintTopic( PrintList.Topics[ TopicIndex ] , RichTextSettings, PageY );
1992
1993 if PrintThread.StopRequested then
1994 break;
1995 end
1996 end
1997
1998 else if Parameters is TPrintAll then
1999 begin
2000 // first count up total number of topics.
2001 TotalTopics := 0;
2002 for FileIndex := 0 to CurrentOpenFiles.Count - 1 do
2003 begin
2004 HelpFile := CurrentOpenFiles[ FileIndex ];
2005 inc( TotalTopics, HelpFile.TopicCount );
2006 end;
2007
2008 TotalTopicIndex := 0;
2009 for FileIndex := 0 to CurrentOpenFiles.Count - 1 do
2010 begin
2011 HelpFile := CurrentOpenFiles[ FileIndex ];
2012 for TopicIndex := 0 to HelpFile.TopicCount - 1 do
2013 begin
2014 PrintThread.UpdateProgress( TotalTopicIndex, TotalTopics, 'Printing' );
2015 PrintTopic( HelpFile.Topics[ TopicIndex ], RichTextSettings, PageY );
2016 if PrintThread.StopRequested then
2017 break;
2018 inc( TotalTopicIndex );
2019 end;
2020 end;
2021 end;
2022 except
2023 on E: EPrinter do
2024 begin
2025 DoErrorDlg( PrintTopicTitle,
2026 PrintingError + E.Message );
2027 end;
2028 end;
2029
2030 Printer.EndDoc;
2031 result := nil;
2032End;
2033
2034procedure TMainForm.OnPrintProgress( n, outof: integer;
2035 Message: string );
2036begin
2037 SetProgress( n, outof, message );
2038end;
2039
2040procedure TMainForm.OnPrintComplete( Dummy: TObject );
2041begin
2042 SetStatus( 'Printing complete' );
2043 ResetProgress;
2044end;
2045
2046// --------------------------------------------------
2047
2048Procedure TMainForm.DebugShowWordSeparatorsMIOnClick (Sender: TObject);
2049Begin
2050 DebugShowWordSeparatorsMI.Checked := not DebugShowWordSeparatorsMI.Checked;
2051 RefreshWindows( Windows );
2052End;
2053
2054Procedure TMainForm.DebugStressTestMIOnClick (Sender: TObject);
2055var
2056 i: longint;
2057 NString: string;
2058 N: longint;
2059Begin
2060 if not DoInputQuery( 'Stress Test',
2061 'Repititions?',
2062 NString ) then
2063 exit;
2064 N := StrToIntDef( NString, 1 );
2065 for i := 0 to N - 1 do
2066 begin
2067 ContentsOutline.GotoFirstNode;
2068 repeat
2069 DisplaySelectedContentsTopic;
2070 Application.ProcessMessages;
2071 until not ContentsOutline.GotoNextNodeDown;
2072 end;
2073End;
2074
2075// Find topic specified by global name, in all open files
2076Function TMainForm.FindTopicByGlobalName( const Name: string ): TTopic;
2077var
2078 FileIndex: longint;
2079 HelpFile: THelpFile;
2080begin
2081 Result := nil;
2082
2083 for FileIndex := 0 to CurrentOpenFiles.Count - 1 do
2084 begin
2085 HelpFile := CurrentOpenFiles[ FileIndex ];
2086 Result := HelpFile.FindTopicByGlobalName( Name );
2087 if Result <> nil then
2088 // found
2089 exit;
2090 end;
2091
2092 // not found.
2093 Result := nil;
2094end;
2095
2096// Find topic specified by numeric resource ID, in all open files
2097Function TMainForm.FindTopicByResourceID( ID: uint16 ): TTopic;
2098var
2099 FileIndex: longint;
2100 HelpFile: THelpFile;
2101begin
2102 for FileIndex := 0 to CurrentOpenFiles.Count - 1 do
2103 begin
2104 HelpFile := CurrentOpenFiles[ FileIndex ];
2105
2106 Result := HelpFile.FindTopicByResourceID( ID );
2107 if Result <> nil then
2108 // found
2109 exit;
2110 end;
2111
2112 // not found.
2113 Result := nil;
2114end;
2115
2116// Find topic specified by text name, in all open files
2117Function TMainForm.FindTopicByName( const Name: string ): TTopic;
2118var
2119 FileIndex: longint;
2120 HelpFile: THelpFile;
2121begin
2122 Result := nil;
2123
2124 for FileIndex := 0 to CurrentOpenFiles.Count - 1 do
2125 begin
2126 HelpFile := CurrentOpenFiles[ FileIndex ];
2127 Result := HelpFile.FindTopicByLocalName( Name );
2128 if Result <> nil then
2129 // found
2130 exit;
2131 end;
2132
2133 // not found.
2134 Result := nil;
2135end;
2136
2137// Find the target topic for the given link
2138Function TMainForm.FindTopicForLink( Link: THelpLink ): TTopic;
2139var
2140 HelpFile: THelpFile;
2141begin
2142 HelpFile := Link.HelpFile as THelpFile;
2143 if Link is TFootnoteHelpLink then
2144 begin
2145 Result := HelpFile.Topics[ TFootnoteHelpLink( Link ).TopicIndex ];
2146 end
2147 else if Link is TInternalHelpLink then
2148 begin
2149 Result := HelpFile.Topics[ TInternalHelpLink( Link ).TopicIndex ];
2150 end
2151 else if Link is THelpLinkByResourceID then
2152 begin
2153 Result := FindTopicByResourceID( THelpLinkByResourceID( Link ).ResourceID );
2154 end
2155end;
2156
2157Procedure TMainForm.TopicPropertiesPMIOnClick (Sender: TObject);
2158var
2159 Window: THelpWindow;
2160 Topic: TTopic;
2161 HelpFile: THelpFile;
2162 ResourceIDs: TList;
2163 i: longint;
2164Begin
2165 Window := GetActiveWindow;
2166 if Window = nil then
2167 exit;
2168 Topic := Window.Topic;
2169 HelpFile := Topic.HelpFile as THelpFile;
2170
2171 ResourceIDs := TList.Create;
2172 HelpFile.FindResourceIDsForTopic( Topic,
2173 ResourceIDs );
2174
2175 with InformationForm.InformationMemo do
2176 begin
2177 Lines.Clear;
2178 Lines.Add( TopicInfoTitle );
2179 Lines.Add( TopicInfoTopicTitle + Topic.Title );
2180 Lines.Add( TopicInfoIndex + IntToStr( Topic.Index ) );
2181 Lines.Add( TopicInfoFile + HelpFile.Filename );
2182 Lines.Add( TopicInfoResourceIDs );
2183 for i := 0 to ResourceIDs.Count - 1 do
2184 Lines.Add( ' ' + IntToStr( longint( ResourceIDs[ i ] ) ) );
2185 if ResourceIDs.Count = 0 then
2186 Lines.Add( TopicInfoNoResourceIDs );
2187 end;
2188 ResourceIDs.Destroy;
2189
2190 InformationForm.ShowModal;
2191End;
2192Procedure TMainForm.NavigateForwardMIOnClick (Sender: TObject);
2193Begin
2194 NavigateForward;
2195End;
2196
2197Procedure TMainForm.FocusFirstHelpWindow;
2198begin
2199 if Windows.Count > 0 then
2200 THelpWindow( Windows[ 0 ] ).View.Focus;
2201end;
2202
2203Procedure TMainForm.IndexListBoxOnScan (Sender: TObject;
2204 Var KeyCode: TKeyCode);
2205Begin
2206 case KeyCode of
2207 kbTab:
2208 begin
2209 FocusFirstHelpWindow;
2210 KeyCode := kbNull;
2211 end;
2212 kb_VK + VK_NEWLINE:
2213 DisplaySelectedIndexTopic;
2214 end;
2215End;
2216
2217Procedure TMainForm.SearchResultsListBoxOnScan (Sender: TObject;
2218 Var KeyCode: TKeyCode);
2219Begin
2220 case KeyCode of
2221 kbTab:
2222 begin
2223 FocusFirstHelpWindow;
2224 KeyCode := kbNull;
2225 end;
2226
2227 kb_VK + VK_NEWLINE:
2228 DisplaySelectedSearchResultTopic;
2229 end;
2230End;
2231
2232Procedure TMainForm.ContentsOutlineOnScan (Sender: TObject;
2233 Var KeyCode: TKeyCode);
2234Begin
2235 case KeyCode of
2236 kbTab:
2237 begin
2238 FocusFirstHelpWindow;
2239 KeyCode := kbNull;
2240 end;
2241 kb_VK + VK_NEWLINE:
2242 DisplaySelectedContentsTopic;
2243 end;
2244End;
2245
2246Procedure TMainForm.ToolsOptionsMIOnClick (Sender: TObject);
2247Begin
2248 DoOptions;
2249End;
2250
2251Procedure TMainForm.EditGlobalSearchMIOnClick (Sender: TObject);
2252Begin
2253 DoGlobalSearch( '' );
2254End;
2255
2256Procedure TMainForm.ViewExpandAllMIOnClick (Sender: TObject);
2257Begin
2258 DisplayContents;
2259 ContentsOutline.ExpandAll;
2260End;
2261
2262Procedure TMainForm.DebugShowParamsMIOnClick (Sender: TObject);
2263var
2264 tmpWindowPosition : TWindowPosition;
2265Begin
2266 with InformationForm.InformationMemo do
2267 begin
2268
2269 Lines.Clear;
2270 Lines.Add('');
2271 Lines.Add('parsed infos:');
2272 Lines.Add('getShowUsageFlag: ' + boolToStr(CmdLineParameters.getShowUsageFlag));
2273 Lines.Add('getSearchFlag: ' + boolToStr(CmdLineParameters.getSearchFlag));
2274 Lines.Add('getSearchText: ' + CmdLineParameters.getSearchText);
2275 Lines.Add('getGlobalSearchFlag: ' + boolToStr(CmdLineParameters.getGlobalSearchFlag));
2276 Lines.Add('getLanguage: ' + CmdLineParameters.getLanguage);
2277 Lines.Add('getHelpManagerFlag: ' + boolToStr(CmdLineParameters.getHelpManagerFlag));
2278 Lines.Add('getHelpManagerFlag: ' + boolToStr(CmdLineParameters.getHelpManagerFlag));
2279 Lines.Add('getHelpManagerWindow: ' + intToStr(CmdLineParameters.getHelpManagerWindow));
2280 Lines.Add('getWindowPositionFlag: ' + boolToStr(CmdLineParameters.getWindowPositionFlag));
2281
2282 tmpWindowPosition := CmdLineParameters.getWindowPosition;
2283 Lines.Add('getWindowPosition: ');
2284 Lines.Add(' left: ' + intToStr(tmpWindowPosition.left));
2285 Lines.Add(' bottom: ' + intToStr(tmpWindowPosition.bottom));
2286 Lines.Add(' width: ' + intToStr(tmpWindowPosition.width));
2287 Lines.Add(' height: ' + intToStr(tmpWindowPosition.height));
2288 Lines.Add('getOwnerWindow: ' + intToStr(CmdLineParameters.getOwnerWindow));
2289 Lines.Add('getWindowTitle: ' + CmdLineParameters.getWindowTitle);
2290 Lines.Add('getFileNames: ' + CmdLineParameters.getFileNames);
2291 end;
2292
2293 InformationForm.ShowModal;
2294End;
2295
2296Procedure TMainForm.EditBookmarksMIOnClick (Sender: TObject);
2297Begin
2298 BookmarksForm.BookmarkList := Bookmarks;
2299 BookmarksForm.OpenBookmarkCallback := NavigateToBookmark;
2300 BookmarksForm.BookmarksChangedCallback := OnBookmarksChanged;
2301 BookmarksForm.Show;
2302
2303 // Since we are showing a nonmodal dialog, set the PM owner window
2304 // so that the bookmarks form remains on top.
2305 WinSetOwner( BookmarksForm.Frame.Handle,
2306 Frame.Handle );
2307End;
2308
2309Procedure TMainForm.CopyPMIOnClick (Sender: TObject);
2310var
2311 Window: THelpWindow;
2312Begin
2313 Window := GetActiveWindow;
2314 if Window = nil then
2315 exit;
2316 Window.View.CopySelectionToClipboard;
2317End;
2318
2319Procedure TMainForm.SelectAllPMIOnClick (Sender: TObject);
2320var
2321 Window: THelpWindow;
2322Begin
2323 Window := GetActiveWindow;
2324 if Window = nil then
2325 exit;
2326 Window.View.SelectAll;
2327End;
2328
2329Procedure TMainForm.AddNoteButtonOnClick (Sender: TObject);
2330Begin
2331 AddNote;
2332End;
2333
2334Procedure TMainForm.EnableSearchButton;
2335var
2336 CanSearch: boolean;
2337begin
2338 CanSearch := false;
2339 if CurrentOpenFiles.Count > 0 then
2340 if trim( SearchTextEdit.Text ) > '' then
2341 CanSearch := true;
2342 SearchButton.Enabled := CanSearch;
2343end;
2344
2345Procedure TMainForm.SearchTextEditOnChange (Sender: TObject);
2346Begin
2347 EnableSearchButton;
2348End;
2349
2350Procedure TMainForm.OnHint( Sender: TObject );
2351begin
2352 SetStatus( Application.Hint );
2353end;
2354
2355Procedure TMainForm.DisplaySelectedIndexTopic;
2356var
2357 Topic: TTopic;
2358Begin
2359 if IndexListBox.ItemIndex = -1 then
2360 exit;
2361 Topic := DisplayedIndex.Objects[ IndexListBox.ItemIndex ] as TTopic;
2362 DisplayTopic( Topic );
2363End;
2364
2365Procedure TMainForm.IndexListBoxOnClick (Sender: TObject);
2366Begin
2367 DisplaySelectedIndexTopic;
2368End;
2369
2370Procedure TMainForm.ViewCollapseAllMIOnClick (Sender: TObject);
2371Begin
2372 DisplayContents;
2373 ContentsOutline.CollapseAll;
2374 DisplaySelectedContentsTopic;
2375End;
2376
2377Procedure TMainForm.NotesListBoxOnDblClick (Sender: TObject);
2378Begin
2379 GotoCurrentNote;
2380End;
2381
2382function TMainForm.OwnHelpMode: boolean;
2383var
2384 Filename: string;
2385 NamePart: string;
2386begin
2387 result := false;
2388 if CurrentOpenFiles.Count <> 1 then
2389 exit;
2390
2391 Filename := THelpFile( CurrentOpenFiles[ 0 ] ).Filename;
2392 NamePart := ExtractFileName( Filename );
2393 Result := StrStarts( 'newview', NamePart );
2394end;
2395
2396Procedure TMainForm.HelpMIOnClick (Sender: TObject);
2397Begin
2398 if OwnHelpMode then
2399 begin
2400 DoErrorDlg( NewViewHelpTitle,
2401 AlreadyNewviewHelp );
2402 exit;
2403 end;
2404 Application.HelpContents;
2405End;
2406
2407Procedure TMainForm.NotebookOnPageChanged (Sender: TObject);
2408var
2409 FileIndex: longint;
2410 HelpFile: THelpFile;
2411Begin
2412 EnableControls;
2413 case Notebook.PageIndex of
2414 piContents:
2415 begin
2416 // not really feasible to load contents here, as we rely
2417 // on it for many things
2418 ContentsOutline.Focus;
2419 end;
2420
2421 piIndex:
2422 begin
2423 if not IndexLoaded then
2424 begin
2425 LoadIndex;
2426 end;
2427 IndexSearchEdit.Focus;
2428 end;
2429
2430 piSearch:
2431 begin
2432 SearchButton.Focus;
2433 SearchTextEdit.Focus;
2434 end;
2435
2436 piNotes:
2437 begin
2438 for FileIndex := 0 to CurrentOpenFiles.Count - 1 do
2439 begin
2440 HelpFile := CurrentOpenFiles[ FileIndex ];
2441 if not HelpFile.NotesLoaded then
2442 LoadNotes( HelpFile );
2443 end;
2444 NotesListBox.Focus;
2445 UpdateNotesDisplay;
2446 end;
2447 end;
2448
2449End;
2450
2451Procedure TMainForm.ViewRefreshMIOnClick (Sender: TObject);
2452Begin
2453 RefreshWindows( Windows );
2454End;
2455
2456Procedure TMainForm.ViewNotesMIOnClick (Sender: TObject);
2457Begin
2458 ShowLeftPanel := true;
2459 TabSet.TabIndex := piNotes;
2460End;
2461
2462Procedure TMainForm.ViewSearchMIOnClick (Sender: TObject);
2463Begin
2464 DisplaySearch;
2465End;
2466
2467Procedure TMainForm.ShowTab( TabIndex: longint );
2468Begin
2469 ShowLeftPanel := true;
2470 TabSet.TabIndex := TabIndex;
2471 NotebookOnPageChanged( self );// focus control etc
2472End;
2473
2474Procedure TMainForm.DisplaySearch;
2475Begin
2476 ShowTab( piSearch );
2477End;
2478
2479Procedure TMainForm.ViewIndexMIOnClick (Sender: TObject);
2480Begin
2481 DisplayIndex;
2482End;
2483
2484Procedure TMainForm.DisplayIndex;
2485Begin
2486 ShowTab( piIndex );
2487End;
2488
2489Procedure TMainForm.ViewContentsMIOnClick (Sender: TObject);
2490Begin
2491 DisplayContents;
2492End;
2493
2494Procedure TMainForm.DisplayContents;
2495Begin
2496 ShowTab( piContents );
2497End;
2498
2499function TMainForm.OpenWindow( Topic: TTopic;
2500 Group: longint;
2501 Parent: THelpWindow;
2502 Rect: THelpWindowRect;
2503 FollowAutoLinks: boolean ): THelpWindow;
2504var
2505 Window: THelpWindow;
2506 DisplayTopicRequired: boolean;
2507begin
2508 Window := nil;
2509
2510 if ( Group <> DefaultGroupIndex ) and ( Parent = nil ) then
2511 begin
2512 // Normal window (not a split window) and a specific group is desired.
2513 // So see if we can find one with that group number
2514 Window := FindWindowFromGroup( Group, Windows );
2515
2516 end
2517 else
2518 begin
2519 // only reuse window if it has the same topic.
2520 Window := FindWindowFromTopic( Topic, Windows );
2521 end;
2522
2523 if Window = nil then
2524 begin
2525 DisplayingTopicWindow := true;
2526
2527 // not found, or want a new one
2528 Window := THelpWindow.Create( Parent = nil );
2529
2530 // add to parent
2531 if Parent = nil then
2532 begin
2533 Window.Parent := DisplayPanel;
2534 Windows.Add( Window );
2535 end
2536 else
2537 begin
2538 Window.Parent := Parent.View;
2539 Parent.ChildWindows.Add( Window );
2540 end;
2541
2542 Window.ParentHelpWindow := Parent;
2543
2544 DisplayingTopicWindow := false;
2545
2546 end
2547 else
2548 begin
2549 // reusing an existing window. Don't change parent
2550 end;
2551
2552 Window.Group := Group;
2553
2554 Window.View.PopupMenu := ViewPopupMenu;
2555
2556 Window.View.Images := Window.Images;
2557
2558 Window.View.OnClickLink := OnClickLink;
2559 Window.View.OnOverLink := OnOverLink;
2560 Window.View.OnNotOverLink := OnNotOverLink;
2561
2562 Window.OnClose := OnWindowClose;
2563 Window.OnCloseQuery := OnWindowAboutToClose;
2564 Window.OnDragOver := OnDragOverWindow;
2565 Window.OnDragDrop := OnDragDropToWindow;
2566 Window.OnFontChange := OnWindowFontChange;
2567 Window.OnTab := OnWindowTab;
2568 Window.OnBackTab := OnWindowBackTab;
2569
2570 // Use the contents rect by default...
2571 Topic.GetContentsWindowRect( Window.Rect );
2572 if Rect <> nil then
2573 begin
2574 // the rect is being overridden, so use it instead
2575 if Rect.Left <> -1 then
2576 Window.Rect.Left := Rect.Left;
2577 if Rect.Bottom <> -1 then
2578 Window.Rect.Bottom := Rect.Bottom;
2579 if Rect.Width <> -1 then
2580 Window.Rect.Width := Rect.Width;
2581 if Rect.Height <> -1 then
2582 Window.Rect.Height := Rect.Height;
2583 end;
2584
2585 if Window.ChildWindows.Count > 0 then
2586 begin
2587 // close existing child windows
2588 DestroyListObjects( Window.ChildWindows );
2589 Window.ChildWindows.Clear;
2590 Window.View.Show; // show the view again
2591 end;
2592
2593 DisplayTopicRequired := Window.Topic <> Topic;
2594 Window.Topic := Topic; // set this now so that SetLayout can log meaninful stuff
2595
2596 // Adjust the window size to it's specified Rect
2597 // Must do this before displaying child windows (DisplayTopicInWindow,
2598 // split window autolinks),
2599 // otherwise they will not size themselves correctly
2600 Window.SetLayout;
2601
2602 if DisplayTopicRequired then
2603 begin
2604 DisplayTopicInWindow( Window, FollowAutoLinks, false );
2605 end;
2606
2607 // Bring this window to the front
2608 Window.BringToFront;
2609
2610 Result := Window;
2611end;
2612
2613// Find an existing help window containing the given richtext view control
2614Function TMainForm.FindWindowFromView( View: TRichTextView;
2615 WindowList: TList ): THelpWindow;
2616var
2617 WindowIndex: longint;
2618begin
2619 for WindowIndex:= 0 to WindowList.Count - 1 do
2620 begin
2621 Result:= WindowList[ WindowIndex ];
2622 if Result.View = View then
2623 exit;
2624 Result:= FindWindowFromView( View, Result.ChildWindows );
2625 if Result <> nil then
2626 exit;
2627 end;
2628 Result:= nil;
2629end;
2630
2631// Find an existing help window with the given group number (if any)
2632Function TMainForm.FindWindowFromGroup( Group: longint; WindowList: TList ): THelpWindow;
2633var
2634 WindowIndex: longint;
2635begin
2636 for WindowIndex:= 0 to WindowList.Count - 1 do
2637 begin
2638 Result:= WindowList[ WindowIndex ];
2639 if Result.Group = Group then
2640 exit;
2641 Result:= FindWindowFromGroup( Group, Result.ChildWindows );
2642 if Result <> nil then
2643 exit;
2644 end;
2645 Result:= nil;
2646end;
2647
2648// Find an existing help window alreadying displaying the given topic
2649Function TMainForm.FindWindowFromTopic( Topic: TTopic; WindowList: TList ): THelpWindow;
2650var
2651 WindowIndex: longint;
2652begin
2653 for WindowIndex:= 0 to WindowList.Count - 1 do
2654 begin
2655 Result:= WindowList[ WindowIndex ];
2656 if Result.Topic = Topic then
2657 exit;
2658 Result:= FindWindowFromTopic( Topic, Result.ChildWindows );
2659 if Result <> nil then
2660 exit;
2661 end;
2662 Result:= nil;
2663end;
2664
2665Procedure TMainForm.RefreshFontSubstitutions;
2666var
2667 FileIndex: longint;
2668 HelpFile: THelpFile;
2669begin
2670 for FileIndex := 0 to CurrentOpenFiles.Count - 1 do
2671 begin
2672 HelpFile := CurrentOpenFiles[ FileIndex ];
2673
2674 if Settings.FixedFontSubstitution then
2675 HelpFile.SetupFontSubstitutes( Settings.FixedFontSubstitutes )
2676 else
2677 HelpFile.SetupFontSubstitutes( '' );
2678 end;
2679end;
2680
2681// Redisplay topics in all windows
2682Procedure TMainForm.RefreshWindows( WindowList: TList );
2683var
2684 WindowIndex: longint;
2685 Window: THelpWindow;
2686begin
2687 for WindowIndex:= 0 to WindowList.Count - 1 do
2688 begin
2689 Window:= WindowList[ WindowIndex ];
2690 DisplayTopicInWindow( Window,
2691 false, // don't follow links!
2692 true ); // keep position
2693 RefreshWindows( Window.ChildWindows );
2694 end;
2695end;
2696
2697Procedure TMainForm.WMFollowExternalLink( Var Msg: TMessage );
2698var
2699 FilePath: string;
2700 Topic: TTopic;
2701begin
2702 // try in same dir as source file
2703 FilePath := AddSlash( ExtractFilePath( g_ExternalLinkSourceFilename ) )
2704 + g_ExternalLinkFilename;
2705
2706 if not StringsSame( FilePath, g_ExternalLinkSourceFilename ) then
2707 begin
2708 // different file - try and open it
2709 if not FileExists( FilePath ) then
2710 // not in same directory, find in help paths
2711 FilePath := FindHelpFile( g_ExternalLinkFilename );
2712
2713 if not FileExists( FilePath ) then
2714 begin
2715 DoErrorDlg( 'Link Error',
2716 'Cannot find linked file '
2717 + g_ExternalLinkFilename );
2718 exit;
2719 end;
2720
2721 if g_ExternalLinkKeepCurrent then
2722 begin
2723 if not OpenAdditionalFile( FilePath, false ) then
2724 exit;
2725 end
2726 else
2727 begin
2728 if not OpenFile( FilePath, '', false ) then
2729 exit;
2730 end;
2731
2732 end;
2733
2734 if g_ExternalLinkTopic = '' then
2735 begin
2736 // specific topic not required.
2737 DisplaySelectedContentsTopic;
2738 exit;
2739 end;
2740
2741 Topic := FindTopicByGlobalName( g_ExternalLinkTopic );
2742 if Topic = nil then
2743 begin
2744 DoErrorDlg( 'Link Error',
2745 'Unable to find topic with global name '
2746 + g_ExternalLinkTopic );
2747 exit;
2748 end;
2749
2750 DisplayTopic( Topic );
2751end;
2752
2753// We are following a link, specified as param1 in msg
2754Procedure TMainForm.WMFollowLink( Var Msg: TMessage );
2755var
2756 NewTopic: TTopic;
2757 Link: THelpLink;
2758 SourceWindow: THelpWindow;
2759begin
2760 Link:= THelpLink( Msg.Param1 );
2761 SourceWindow:= THelpWindow( Msg.Param2 );
2762 NewTopic:= FindTopicForLink( Link );
2763
2764 // remove the link target info from status
2765 SetStatus( '' );
2766
2767 if NewTopic = nil then
2768 begin
2769 // Linked topic not found, this is an error... which kind?
2770
2771 if Link is THelpLinkByResourceID then
2772 begin
2773 // may happen if e.g. PM4.INF is loaded by itself,
2774 // and a link references a resource ID from e.g PM2.INF
2775 DoErrorDlg( InvalidLinkErrorTitle,
2776 InvalidResourceIDLinkErrorA
2777 + IntToStr( THelpLinkByResourceID( Link ).ResourceID )
2778 + InvalidResourceIDLinkErrorB );
2779 end
2780 else
2781 begin
2782 // should never happen, given valid help files
2783 DoErrorDlg( InvalidLinkErrorTitle,
2784 InvalidLinkError );
2785 end;
2786
2787 exit;
2788 end;
2789
2790 UpdateCurrentNavigatePoint;
2791
2792 FollowLink( Link, SourceWindow );
2793
2794 if NewTopic.ShowInContents then
2795 begin
2796 Navigating:= true;
2797 if ContentsOutline.SelectedNode = nil then
2798 ContentsOutline.SetSelectedObject( NewTopic )
2799 else if ContentsOutline.SelectedNode.Data <> NewTopic then
2800 ContentsOutline.SetSelectedObject( NewTopic );
2801 Navigating:= false;
2802 end;
2803 SaveNavigatePoint;
2804 EnableControls;
2805 ShowWindows;
2806
2807end;
2808
2809// Follow the given link from the given window.
2810// ie. open the topic or footnote it points to
2811Procedure TMainForm.FollowLink( Link: THelpLink;
2812 SourceWindow: THelpWindow );
2813var
2814 LinkedTopic: TTopic;
2815 ParentWindow: THelpWindow;
2816 WindowedLink: TWindowedHelpLink;
2817 NewWindow: THelpWIndow;
2818begin
2819 LinkedTopic := FindTopicForLink( Link );
2820
2821 if LinkedTopic = nil then
2822 begin
2823 exit;
2824 end;
2825
2826 if Link is TFootnoteHelpLink then
2827 begin
2828 NewWindow := OpenWindow( LinkedTopic,
2829 DefaultGroupIndex,
2830 nil, // no parent
2831 FootnoteRect,
2832 true );
2833 NewWindow.Caption := TFootnoteHelpLink( Link ).Title;
2834 exit;
2835 end;
2836
2837 WindowedLink := Link as TWindowedHelpLink;
2838
2839 ParentWindow:= nil;
2840 if WindowedLink.Split then
2841 ParentWindow:= SourceWindow;
2842
2843 if WindowedLink.ViewPort then
2844 // link always wants a new window
2845 OpenWindow( LinkedTopic,
2846 DefaultGroupIndex,
2847 ParentWindow,
2848 WindowedLink.Rect,
2849 true )
2850
2851 else if WindowedLink.GroupIndex <> DefaultGroupIndex then
2852 // link overrides group index
2853 OpenWindow( LinkedTopic,
2854 WindowedLink.GroupIndex,
2855 ParentWindow,
2856 WindowedLink.Rect,
2857 true )
2858 else
2859 // no special case
2860 OpenWindow( LinkedTopic,
2861 LinkedTopic.ContentsGroupIndex,
2862 ParentWindow,
2863 WindowedLink.Rect,
2864 true );
2865end;
2866
2867function TMainForm.ShowCodes: boolean;
2868begin
2869 if DebugShowCodesMI = nil then
2870 result := false
2871 else
2872 result := DebugShowCodesMI.Checked;
2873end;
2874
2875function TMainForm.ShowWordIndices: boolean;
2876begin
2877 if DebugShowWordSeparatorsMI = nil then
2878 result := false
2879 else
2880 result := DebugShowWordSeparatorsMI.Checked;
2881end;
2882
2883// Decode and display the topic for the given window.
2884Procedure TMainForm.DisplayTopicInWindow( Window: THelpWindow;
2885 FollowAutoLinks: boolean;
2886 KeepPosition: boolean );
2887var
2888 ImageIndices: TList;
2889 LinkIndex: longint;
2890 Link: THelpLink;
2891 WindowedHelpLink: TWindowedHelpLink;
2892 InternalHelpLink: TInternalHelpLink;
2893 HelpFile: THelpFile;
2894 LinkedTopic: TTopic;
2895 SourceTopic: TTopic;
2896 TopCharIndex: longint;
2897 i: longint;
2898 HighlightWordSequences: TList;
2899 FileIndex: longint;
2900Begin
2901 LogEvent(LogDisplay, 'DisplayTopicInWindow');
2902
2903 SetWaitCursor;
2904
2905 TopCharIndex := Window.View.TopCharIndex;
2906
2907 Window.View.Hide;
2908 Window.View.Clear;
2909 ImageIndices := TList.Create;
2910
2911 HelpFile := TopicFile( Window.Topic );
2912
2913 if ( AllFilesWordSequences.Count > 0 ) // ie we have done a search...
2914 and ViewHighlightSearchWordsMI.Checked then
2915 begin
2916 FileIndex := CurrentOpenFiles.IndexOf( HelpFile );
2917 HighlightWordSequences := AllFilesWordSequences[ FileIndex ];
2918 end
2919 else
2920 begin
2921 HighlightWordSequences := nil;
2922 end;
2923 TopicText.Clear;
2924 Window.Topic.GetText( HighlightWordSequences,
2925 ShowCodes,
2926 ShowWordIndices,
2927 TopicText,
2928 ImageIndices,
2929 Window.Highlights );
2930
2931 HelpFile.GetImages( ImageIndices, Window.Images );
2932
2933 if not HelpFile.NotesLoaded then
2934 LoadNotes( HelpFile );
2935 InsertNotesIntoTopicText( Window.Topic, TopicText );
2936
2937 Window.View.AddText( TopicText.AsPChar );
2938
2939 if KeepPosition then
2940 Window.View.TopCharIndex := TopCharIndex;
2941
2942 Window.View.Show;
2943
2944 if not KeepPosition then
2945 if Window.Highlights.Count > 0 then
2946 // ensure first search match is visible
2947 Window.View.MakeCharVisible( longint( Window.Highlights[ 0 ] ) );
2948
2949 Window.Caption := Window.Topic.Title;
2950 Window.BringToFront;
2951 Window.View.Focus;
2952
2953 // Take a copy of the topic, because the window in question could be changing
2954 // due to recursion!
2955 SourceTopic := Window.Topic;
2956
2957 if FollowAutoLinks then
2958 begin
2959 i := 0;
2960 for LinkIndex:= 0 to SourceTopic.Links.Count - 1 do
2961 begin
2962 Link:= SourceTopic.Links[ LinkIndex ];
2963 if Link is TWindowedHelpLink then
2964 begin
2965 WindowedHelpLink := Link as TWindowedHelpLink;
2966 if WindowedHelpLink.Automatic then
2967 begin
2968 if Link is TInternalHelpLink then
2969 begin
2970 InternalHelpLink := TInternalHelpLink( Link );
2971 LinkedTopic :=
2972 THelpFile( InternalHelpLink.HelpFile ).
2973 Topics[ InternalHelpLink.TopicIndex ];
2974 if LinkedTopic.Index = SourceTopic.Index then
2975 // what the - ? The link wants to open the same topic again
2976 continue;
2977 end;
2978
2979 FollowLink( Link, Window );
2980 Window := Window;
2981
2982 inc( i );
2983 // Note 1: it is possible to crash here if
2984 // e.g. window1 auto-opens window2 which auto-opens window1 with a different topic..
2985 // I can't think of a nice, easy way to detect this
2986 //
2987 // Note 2: If there is no group number specified
2988 // (ie. group = default = 0 ) then behaves as if viewport is set:
2989 // always opens another window.
2990 end;
2991 end;
2992 end;
2993 end;
2994
2995 ClearWaitCursor;
2996
2997 ImageIndices.Destroy;
2998End;
2999
3000Procedure TMainForm.MainFormOnCloseQuery (Sender: TObject;
3001 Var CanClose: Boolean);
3002Begin
3003 LogEvent(LogShutdown, '-------- Shutdown ----------');
3004
3005
3006 if OKToCloseFile then
3007 CloseFile
3008 else
3009 CanClose := false;
3010End;
3011
3012procedure TMainForm.DisplayTopic( Topic: TTopic );
3013begin
3014 if Navigating then
3015 exit;
3016
3017 UpdateCurrentNavigatePoint;
3018
3019 CloseWindows;
3020
3021 CurrentTopic:= Topic;
3022
3023 OpenWindow( CurrentTopic,
3024 CurrentTopic.ContentsGroupIndex,
3025 nil,
3026 nil,
3027 true );
3028 SetStatus( OpenedTopicMsg
3029 + IntToStr( Topic.Index ) );
3030
3031 Navigating:= true;
3032
3033 if ContentsOutline.SelectedNode = nil then
3034 ContentsOutline.SetSelectedObject( Topic )
3035 else if ContentsOutline.SelectedNode.Data <> Topic then
3036 ContentsOutline.SetSelectedObject( Topic );
3037
3038 SaveNavigatePoint;
3039
3040 Navigating:= false;
3041 // find in index...
3042 // find in search results...
3043
3044 EnableControls;
3045
3046 ShowWindows;
3047
3048// if Windows.Count > 0 then
3049// THelpWindow( Windows[ 0 ] ).View.Focus;
3050
3051end;
3052
3053// Make the all current help windows visible
3054Procedure TMainForm.ShowWindows;
3055begin
3056 ShowWindowList( Windows );
3057end;
3058
3059// Make the specified windows visible
3060Procedure TMainForm.ShowWindowList( WindowList: TList );
3061var
3062 i: integer;
3063 Window: THelpWindow;
3064begin
3065 for i := 0 to WindowList.Count - 1 do
3066 begin
3067 Window:= WindowList[ i ];
3068 Window.Show;
3069 ShowWindowList( Window.ChildWindows );
3070 end;
3071end;
3072
3073// Global search -----------------------------------------------------------
3074
3075Procedure TMainForm.GlobalSearchMIOnClick (Sender: TObject);
3076begin
3077 DoGlobalSearch( '' );
3078end;
3079
3080Procedure TMainForm.DoGlobalSearch( const SearchText: string );
3081Begin
3082 EnsureGlobalSearchFormLoaded;
3083
3084 GlobalSearchForm.ViewTopicCallback:= OnViewGlobalSearchTopic;
3085 GlobalSearchForm.Show;
3086 WinSetOwner( GlobalSearchForm.Frame.Handle, Frame.Handle );
3087
3088 if SearchText <> '' then
3089 begin
3090 GlobalSearchForm.SearchTextEdit.Text := SearchText;
3091 GlobalSearchForm.DoSearch;
3092 end;
3093End;
3094
3095Procedure TMainForm.OnViewGlobalSearchTopic( FileName: string;
3096 TopicIndex: longint );
3097var
3098 HelpFile: THelpFile;
3099begin
3100 HelpFile:= FindOpenHelpFile( FileName );
3101
3102 if HelpFile = nil then
3103 begin
3104 if OpenFile( Filename, '', false ) then
3105 begin
3106 HelpFile := CurrentOpenFiles[ 0 ];
3107 ClearHelpManager;
3108 end;
3109 end;
3110
3111 if HelpFile <> nil then
3112 if TopicIndex <> -1 then
3113 DisplayTopic( HelpFile.Topics[ TopicIndex ] );
3114
3115end;
3116
3117// Notes -----------------------------------------------------------
3118
3119Procedure TMainForm.GotoNoteButtonOnClick (Sender: TObject);
3120begin
3121 GotoCurrentNote;
3122end;
3123
3124Procedure TMainForm.EditNoteButtonOnClick (Sender: TObject);
3125Begin
3126 if NotesListBox.ItemIndex = -1 then
3127 exit;
3128 EditNote( NotesListBox.ItemIndex );
3129End;
3130
3131Procedure TMainForm.NotesListBoxOnItemFocus (Sender: TObject; Index: LongInt);
3132var
3133 Note: THelpNote;
3134Begin
3135 Note:= NotesListBox.Items.Objects[ NotesListBox.ItemIndex ] as THelpNote;
3136 EnableNotesControls;
3137End;
3138
3139Procedure TMainForm.DeleteNoteButtonOnClick (Sender: TObject);
3140Begin
3141 if NotesListBox.ItemIndex = -1 then
3142 exit;
3143 DeleteNote( NotesListBox.ItemIndex );
3144End;
3145
3146Procedure TMainForm.AddBookmarkMIOnClick (Sender: TObject);
3147Begin
3148 AddBookmark;
3149End;
3150
3151Procedure TMainForm.AddNoteMIOnClick (Sender: TObject);
3152Begin
3153 AddNote;
3154End;
3155
3156// -----------------------------------------------------------
3157
3158Procedure TMainForm.FileCloseMIOnClick (Sender: TObject);
3159Begin
3160 if not OKToCloseFile then
3161 exit;
3162
3163 CloseFile;
3164End;
3165
3166Procedure TMainForm.SetStatus( Text: String );
3167begin
3168 StatusPanel.Caption:= Text;
3169 StatusPanel.Refresh;
3170end;
3171
3172Procedure TMainForm.ResetProgress;
3173begin
3174 ProgressBar.Position:= 0;
3175 ProgressBar.Hide;
3176end;
3177
3178Procedure TMainForm.CoolBarOnSectionResize (HeaderControl: THeaderControl;
3179 section: THeaderSection);
3180Begin
3181
3182End;
3183
3184Procedure TMainForm.CoolBarOnSectionClick (HeaderControl: THeaderControl;
3185 section: THeaderSection);
3186Begin
3187 case Section.Index of
3188 ciOpen:
3189 FileOpen;
3190 ciBack:
3191 NavigateBack;
3192 ciForward:
3193 NavigateForward;
3194 ciPrint:
3195 PrintTopics;
3196 ciAddNote:
3197 AddNote;
3198 ciAddBookmark:
3199 AddBookmark;
3200 ciPrevious:
3201 NavigatePreviousInContents;
3202 ciNext:
3203 NavigateNextInContents;
3204 ciGlobalSearch:
3205 DoGlobalSearch( '' );
3206 end;
3207
3208End;
3209
3210// ---------------- Notes ----------------------
3211
3212function TMainForm.FindOriginalNoteCharIndex( NoteCharIndex: longword;
3213 Topic: TTopic ): longword;
3214var
3215 NoteIndex: longint;
3216 Note: THelpNote;
3217begin
3218 Result := NoteCharIndex;
3219 for NoteIndex := 0 to Notes.Count - 1 do
3220 begin
3221 Note := Notes[ NoteIndex ];
3222 if Note.Topic = Topic then
3223 if Note.InsertPoint < NoteCharIndex then
3224 dec( Result, Note.InsertText.Length );
3225 end;
3226end;
3227
3228function TMainForm.FindActualNoteCharIndex( NoteCharIndex: longword;
3229 MaxNoteIndex: longword;
3230 Topic: TTopic ): longword;
3231var
3232 NoteIndex: longint;
3233 Note: THelpNote;
3234begin
3235 NoteIndex:= 0;
3236 Result:= NoteCharIndex;
3237 for NoteIndex:= 0 to MaxNoteIndex - 1 do
3238 begin
3239 Note:= Notes[ NoteIndex ];
3240 if Note.Topic = Topic then
3241 if Note.InsertPoint < NoteCharIndex then
3242 inc( Result, Note.InsertText.Length );
3243 end;
3244end;
3245
3246procedure TMainForm.RefreshNoteInsertInfo( NoteIndex: longword );
3247var
3248 Note: THelpNote;
3249begin
3250 Note:= Notes[ NoteIndex ];
3251
3252 if Note.Topic = nil then
3253 exit;
3254 with Note do
3255 begin
3256 InsertText.AssignString( '<color #'
3257 + IntToHex( Settings.Colors[ NotesTextColorIndex ], 6 )
3258 + '><link note'
3259 + IntToStr( NoteIndex )
3260 + '>' );
3261 InsertText.Add( Text );
3262 InsertText.AddString( '</color></link>' );
3263 end;
3264end;
3265
3266procedure TMainForm.ClearNotes;
3267begin
3268 DestroyListObjects( Notes );
3269 Notes.Clear;
3270end;
3271
3272procedure TMainForm.AddNote;
3273var
3274 Note: THelpNote;
3275 Window: THelpWindow;
3276begin
3277 Window := GetActiveWindow;
3278 if Window = nil then
3279 begin
3280 DoErrorDlg( AddNoteTitle,
3281 AddNoteCursorError );
3282 exit;
3283 end;
3284
3285 if Window.View.CursorIndex = -1 then
3286 begin
3287 DoErrorDlg( AddNoteTitle,
3288 AddNoteCursorError );
3289 exit;
3290 end;
3291
3292 // check that the note position isn't
3293 // within a note already
3294 if Window.View.LinkFromIndex( Window.View.CursorIndex ) <> '' then
3295 begin
3296 DoErrorDlg( AddNoteTitle,
3297 NoteWithinNoteError );
3298 exit;
3299 end;
3300
3301 // ask for note text
3302 NoteForm.DeleteNoteButton.Enabled := false; // can't delete it while creating!
3303 NoteForm.Text.Clear;
3304 if NoteForm.ShowModal <> mrOK then
3305 exit;
3306
3307 // store note data
3308 Note := THelpNote.Create;
3309 Note.Text.Assign( NoteForm.Text );
3310
3311 // compensate for existing notes
3312 if Window.View.CursorIndex <> -1 then
3313 Note.InsertPoint := FindOriginalNoteCharIndex( Window.View.CursorIndex, Window.Topic )
3314 else
3315 Note.InsertPoint := 0;
3316
3317 Note.Topic := Window.Topic;
3318
3319 Notes.Add( Note );
3320
3321 // redisplay topic
3322 DisplayTopicInWindow( Window,
3323 false, // don't follow links!
3324 true ); // keep position
3325 Window.View.SelectionStart := FindActualNoteCharIndex( Note.InsertPoint,
3326 Notes.Count - 1,
3327 Window.Topic );
3328 UpdateNotesDisplay;
3329
3330 SaveNotes;
3331
3332end;
3333
3334procedure TMainForm.DeleteNote( NoteIndex: longint );
3335var
3336 Note: THelpNote;
3337begin
3338 Note := Notes[ NoteIndex ];
3339 Notes.Delete( NoteIndex );
3340
3341 RefreshWindows( Windows );
3342
3343 Note.Destroy;
3344
3345 UpdateNotesDisplay;
3346
3347 SaveNotes;
3348end;
3349
3350Procedure TMainForm.EditNote( NoteIndex: longint );
3351var
3352 Note: THelpNote;
3353begin
3354 Note:= Notes[ NoteIndex ];
3355
3356 NoteForm.Text.Assign( Note.Text );
3357
3358 NoteForm.DeleteNoteButton.Enabled:= true;
3359
3360 if NoteForm.ShowModal = mrCancel then
3361 exit;
3362
3363 if NoteForm.ModalResult = cmDiscard then
3364 begin
3365 DeleteNote( NoteIndex );
3366 exit;
3367 end;
3368
3369 Note.Text.Assign( NoteForm.Text );
3370
3371 RefreshWindows( Windows );
3372
3373 UpdateNotesDisplay;
3374
3375 SaveNotes;
3376end;
3377
3378Procedure TMainForm.GotoCurrentNote;
3379var
3380 Note: THelpNote;
3381Begin
3382 if NotesListBox.ItemIndex = -1 then
3383 exit;
3384 Note:= NotesListBox.Items.Objects[ NotesListBox.ItemIndex ] as THelpNote;
3385 DisplayTopic( Note.Topic );
3386End;
3387
3388// ---------------- Bookmarks ----------------------
3389
3390procedure TMainForm.OnBookmarksChanged( Sender: TObject );
3391begin
3392 BuildBookmarksMenu;
3393 UpdateBookmarksForm;
3394 SaveBookmarks;
3395end;
3396
3397procedure TMainForm.AddBookmark;
3398var
3399 Bookmark: TBookmark;
3400begin
3401 if Windows.Count = 0 then
3402 exit;
3403
3404 Bookmark := TBookmark.Create;
3405 SaveWindows( Windows, Bookmark.Windows, nil );
3406
3407 if ContentsOutline.SelectedNode <> nil then
3408 begin
3409 Bookmark.ContentsTopic:=
3410 ContentsOutline.SelectedNode.Data as TTopic;
3411 Bookmark.Name := Bookmark.ContentsTopic.Title;
3412 end
3413 else
3414 begin
3415 Bookmark.ContentsTopic:= nil;
3416 // Bookmark.Name := THelpWindow( Windows[ 0 ] ).Title;
3417 end;
3418
3419 Bookmarks.Add( Bookmark );
3420 OnBookmarksChanged( self );
3421end;
3422
3423Procedure TMainForm.BookmarksMenuItemClick( Sender: TObject );
3424var
3425 Tag: longint;
3426 MenuItem: TMenuItem;
3427 Bookmark: TBookmark;
3428begin
3429 MenuItem:= Sender as TMenuItem;
3430 Tag:= MenuItem.Tag;
3431 Bookmark := Bookmarks[ Tag ];
3432
3433 NavigateToBookmark( Bookmark );
3434end;
3435
3436Procedure TMainForm.NavigateToBookmark( Bookmark: TBookmark );
3437Begin
3438 UpdateCurrentNavigatePoint;
3439 NavigateToPoint( Bookmark );
3440 SaveNavigatePoint;
3441End;
3442
3443Procedure TMainForm.BuildBookmarksMenu;
3444var
3445 i: integer;
3446 Bookmark: TBookmark;
3447 MenuItem: TMenuItem;
3448begin
3449 DestroyListObjects( BookmarksMenuItems );
3450 BookmarksMenuItems.Clear;
3451
3452 if Bookmarks.Count > 0 then
3453 begin
3454 MenuItem:= TMenuItem.Create( self );
3455 MenuItem.Caption:= '-';
3456 BookmarksMenu.Add( MenuItem );
3457 BookmarksMenuItems.Add( MenuItem );
3458 end;
3459
3460 for i:= 0 to Bookmarks.Count -1 do
3461 begin
3462 Bookmark := Bookmarks[ i ];
3463 MenuItem:= TMenuItem.Create( self );
3464
3465 MenuItem.Caption:= Bookmark.Name;
3466 MenuItem.OnClick:= BookmarksMenuItemClick;
3467 MenuItem.Tag:= i;
3468 BookmarksMenu.Add( MenuItem );
3469 BookmarksMenuItems.Add( MenuItem );
3470 end;
3471end;
3472
3473Procedure TMainForm.UpdateBookmarksForm;
3474begin
3475 if Assigned( BookmarksForm ) then
3476 BookmarksForm.RefreshList;
3477end;
3478
3479Procedure TMainForm.ClearBookmarks;
3480begin
3481 ClearListAndObjects( Bookmarks );
3482 BuildBookmarksMenu;
3483 if Assigned( BookmarksForm ) then
3484 begin
3485 UpdateBookmarksForm; // clear bookmarks for next show
3486 BookmarksForm.Hide;
3487 end;
3488
3489end;
3490
3491procedure TMainForm.LoadBookmarks( HelpFile: THelpFile );
3492var
3493 Bookmark: TBookmark;
3494 BookmarksFile: TextFile;
3495 BookmarksFileName: string;
3496 S: string;
3497begin
3498 LogEvent(LogSettings, 'Load bookmarks for ' + HelpFile.Filename);
3499
3500 BookmarksFileName:= ChangeFileExt( HelpFile.FileName, '.bmk' );
3501
3502 if not FileExists( BookmarksFileName ) then
3503 exit;
3504
3505 FileMode := fmInput;
3506 AssignFile( BookmarksFile, BookmarksFileName );
3507 try
3508 Reset( BookmarksFile );
3509 try
3510 while not Eof( BookmarksFile ) do
3511 begin
3512 ReadLn( BookmarksFile, s );
3513 if trim( Uppercase( s ) ) = '[BOOKMARK]' then
3514 begin
3515 Bookmark:= TBookmark.Load( BookmarksFile, HelpFile );
3516 Bookmarks.Add( Bookmark );
3517 end;
3518 end;
3519 finally
3520 System.Close( BookmarksFile );
3521 end;
3522 except
3523 on e: exception do
3524 DoErrorDlg( LoadBookmarksTitle,
3525 LoadBookmarksError
3526 + e.message );
3527 end;
3528end;
3529
3530procedure TMainForm.SaveBookmarks;
3531var
3532 FileIndex: integer;
3533 HelpFile: THelpFile;
3534begin
3535 for FileIndex := 0 to CurrentOpenFiles.Count - 1 do
3536 begin
3537 HelpFile := CurrentOpenFiles[ FileIndex ];
3538 SaveBookmarksForFile( HelpFile );
3539 end;
3540end;
3541
3542procedure TMainForm.SaveNotes;
3543var
3544 FileIndex: integer;
3545 HelpFile: THelpFile;
3546begin
3547 LogEvent(LogSettings, 'Save notes');
3548
3549 for FileIndex := 0 to CurrentOpenFiles.Count - 1 do
3550 begin
3551 HelpFile := CurrentOpenFiles[ FileIndex ];
3552 SaveNotesForFile( HelpFile );
3553 end;
3554end;
3555
3556procedure TMainForm.SaveBookmarksForFile( HelpFile: THelpFile );
3557var
3558 i: integer;
3559 Bookmark: TBookmark;
3560 BookmarksFile: TextFile;
3561 BookmarksFileName: string;
3562 BookmarkCount: integer;
3563begin
3564 LogEvent(LogSettings, 'Save bookmarks for ' + HelpFile.Filename);
3565
3566 BookmarksFileName:= ChangeFileExt( HelpFile.FileName, '.bmk' );
3567
3568 BookmarkCount:= 0;
3569 for i:= 0 to Bookmarks.Count - 1 do
3570 begin
3571 Bookmark := Bookmarks[ i ];
3572
3573 if Bookmark.ContentsTopic.HelpFile = HelpFile then
3574 inc( BookmarkCount );
3575 end;
3576
3577 if BookmarkCount = 0 then
3578 begin
3579 if FileExists( BookmarksFileName ) then
3580 DeleteFile( BookmarksFileName );
3581 exit;
3582 end;
3583
3584 AssignFile( BookmarksFile, BookmarksFileName );
3585 try
3586 Rewrite( BookmarksFile );
3587 try
3588 for i := 0 to Bookmarks.Count - 1 do
3589 begin
3590 Bookmark:= Bookmarks[ i ];
3591 if Bookmark.ContentsTopic.HelpFile = HelpFile then
3592 begin
3593 WriteLn( BookmarksFile, '[Bookmark]' );
3594 Bookmark.Save( BookmarksFile );
3595 end;
3596 end;
3597 finally
3598 System.Close( BookmarksFile );
3599 end;
3600 except
3601 on e: exception do
3602 DoErrorDlg( SaveBookmarksTitle,
3603 SaveBookmarksError
3604 + e.message );
3605 end;
3606end;
3607
3608// Reads colors back from controls, in case they have changed by
3609// drag and drop
3610Procedure TMainForm.GetColors;
3611begin
3612 with Settings do
3613 begin
3614 Colors[ ContentsBackgroundColorIndex ] := ContentsOutline.Color;
3615 Colors[ ContentsTextColorIndex ] := ContentsOutline.PenColor;
3616 Colors[ IndexBackgroundColorIndex ] := IndexListBox.Color;
3617 Colors[ IndexTextColorIndex ] := IndexListBox.PenColor;
3618 Colors[ SearchBackgroundColorIndex ] := SearchResultsListBox.Color;
3619 Colors[ SearchTextColorIndex ] := SearchResultsListBox.PenColor;
3620 Colors[ NotesListBackgroundColorIndex ] := NotesListBox.Color;
3621 Colors[ NotesListTextColorIndex ] := NotesListBox.PenColor;
3622 end;
3623end;
3624
3625Procedure TMainForm.MainFormOnDestroy (Sender: TObject);
3626Begin
3627 LogEvent(LogShutdown, 'MainFormOnDestroy');
3628
3629 LogEvent(LogSettings, 'Write window position');
3630 WriteWindowPos( self );
3631
3632 LogEvent(LogSettings, 'Update colors');
3633 GetColors;
3634
3635 LogEvent(LogSettings, 'Save settings');
3636 SaveSettings;
3637 LogEvent(LogSettings, 'Save settings done');
3638
3639 // else- don't save position/size if doing own help
3640
3641 TopicText.Destroy;
3642
3643 LogEvent(LogShutdown, 'Destroy MRU menu items');
3644 MRUMenuItems.Destroy;
3645
3646 LogEvent(LogShutdown, 'Destroy navigate to menu items');
3647 NavigateToMenuItems.Destroy;
3648
3649 LogEvent(LogShutdown, 'Destroy pagehistory');
3650 PageHistory.Destroy;
3651
3652 LogEvent(LogShutdown, 'Clear/destroy notes');
3653 ClearNotes;
3654 Notes.Destroy;
3655
3656 LogEvent(LogShutdown, 'Clear/destroy bookmarks');
3657 ClearBookmarks;
3658 Bookmarks.Destroy;
3659
3660 LogEvent(LogShutdown, 'Destroy bookmark menu items');
3661 BookmarksMenuItems.Destroy;
3662
3663 LogEvent(LogShutdown, 'Destroy files/index/windows');
3664 CurrentOpenFiles.Destroy;
3665 DisplayedIndex.Destroy;
3666 Windows.Destroy;
3667
3668 // tell help manager(s) we are stopping.
3669 PostHelpManagerMessage( NHM_FORGET_VIEWER, 0, 0 );
3670
3671 HelpManagerWindows.Destroy;
3672
3673 DestroyListObjects( Settings.MRUList );
3674 Settings.MRUList.Destroy;
3675
3676 // TODO rbri maybe we have to do this
3677 // Parameters.FilenamesParam.Destroy;
3678
3679 if g_CurrentLanguageFile <> nil then
3680 g_CurrentLanguageFile.Destroy;
3681
3682 LogEvent(LogShutdown, 'Close global filelist');
3683 GlobalFilelist.Destroy;
3684
3685 LogEvent(LogShutdown, 'Close shared memory');
3686 SharedMemory.Destroy;
3687
3688 AllFilesWordSequences.Destroy;
3689
3690 LogEvent(LogShutdown, 'MainFormOnDestroy done');
3691End;
3692
3693Procedure TMainForm.MainFormOnSetupShow (Sender: TObject);
3694Begin
3695 LogEvent(LogSettings, 'OnSetupShow');
3696 TabSet.TabIndex := 0;
3697 Notebook.PageIndex := 0;
3698End;
3699
3700Procedure TMainForm.OnException( Sender: TObject;
3701 E: Exception );
3702var
3703 TheText : string;
3704 F: TextFile;
3705 i: integer;
3706 HelpFile: THelpFile;
3707 LogFilename: string;
3708
3709begin
3710 LogFilename := GetLogFilesDir + CrashLogFileName;
3711
3712 LogException( E,
3713 LogFileName,
3714 'NewView',
3715 GetAppVersion,
3716 F );
3717
3718 if CurrentOpenFiles <> nil then
3719 begin
3720 WriteLn( F, 'Loaded files ('
3721 + IntToStr( CurrentOpenFiles.Count )
3722 + '):' );
3723 try
3724 for i := 0 to CurrentOpenFiles.Count - 1 do
3725 begin
3726 HelpFile := CurrentOpenFiles[ i ];
3727 WriteLn( F, HelpFile.Filename );
3728 end;
3729 except
3730 end;
3731 end;
3732 try
3733 if CurrentTopic <> nil then
3734 WriteLn( F, 'Last major topic index: '
3735 + IntToStr( CurrentTopic.Index ) );
3736 except
3737 // ignore exceptions if there isn't a valid current topic
3738 end;
3739 if Windows <> nil then
3740 begin
3741 WriteLn( F, 'Top-level open windows: '
3742 + IntToStr( Windows.Count ) );
3743 end;
3744
3745 System.Close( F );
3746
3747 TheText := ApplicationErrorA + EndLine
3748 + EndLine
3749 + E.Message + EndLine
3750 + ApplicationErrorB
3751 + LogFilename
3752 + ')' + EndLine
3753 + EndLine
3754 + ApplicationErrorC
3755 + EndLine;
3756
3757 if DoYesNoDlg( ApplicationErrorTitle,
3758 TheText ) then
3759 begin
3760 // exit a bit more nicely - remove ourselves from the global filelist.
3761 GlobalFilelist.RemoveWindowFiles( Frame.Handle );
3762 Application.Terminate;
3763 end;
3764end;
3765
3766// give our main window a unique class name we can find
3767procedure TMainForm.GetClassData(var ClassData: TClassData);
3768Begin
3769 inherited GetClassData( ClassData );
3770 ClassData.ClassName := MAIN_WINDOW_CLASS_NAME;
3771End;
3772
3773// Position the window offset from existing top help window (if any)
3774Procedure TMainForm.PositionWindow;
3775var
3776 hTopWindow: HWND;
3777 TopHelpWindowPos: SWP;
3778 Offset: longint;
3779Begin
3780 hTopWindow := FindTopFormWindow( MAIN_WINDOW_CLASS_NAME );
3781
3782 if hTopWindow <> NULLHANDLE then
3783 begin
3784 // found an existing help window, find it's location
3785 if WinQueryWindowPos(
3786 hTopWindow,
3787 TopHelpWindowPos ) then
3788 begin
3789 if ( TopHelpWindowPos.FL and ( SWP_MINIMIZE or SWP_MINIMIZE ) ) > 0 then
3790 Begin
3791 // window is maximized or minimised, so get the restore position from window USHORTs
3792 TopHelpWindowPos.x := WinQueryWindowUShort( hTopWindow, QWS_XRESTORE );
3793 TopHelpWindowPos.Y := WinQueryWindowUShort( hTopWindow, QWS_YRESTORE );
3794 end;
3795
3796 // offset new window by height of title bar + border
3797 Offset := Screen.SystemMetrics( smCyTitleBar )
3798 + Screen.SystemMetrics( smCySizeBorder );
3799 Left := TopHelpWindowPos.x + Offset;
3800 Bottom := TopHelpWindowPos.y - Offset;
3801
3802 // I guess I am leaving width/height out for compatibility...?
3803 end;
3804 end;
3805end;
3806
3807Procedure TMainForm.OnHelp( context: THelpContext;
3808 var Result: Boolean );
3809begin
3810 if OwnHelpMode then
3811 begin
3812 // we are viewing the help file now - display our own help!
3813 PostMsg( Handle, NHM_TOPIC_BY_RESOURCE_ID, context, 0 );
3814 exit;
3815 end;
3816
3817 Application.HelpContext( context );
3818end;
3819
3820Procedure TMainForm.MainFormOnCreate (Sender: TObject);
3821var
3822 tmpCmdLine: String;
3823Begin
3824 LogEvent(LogStartup, 'MainFormOnCreate');
3825
3826 StartingUp := true;
3827
3828 Application.HelpFile := GetOwnHelpFilename; // OWN_HELP_MARKER;
3829 Application.OnHelp := OnHelp;
3830
3831 SharedMemory := AccessSharedMemory;
3832 GlobalFilelist := TGlobalFilelist.Create;
3833
3834 // parse parameters into Parameters object
3835 tmpCmdLine := nativeOS2GetCmdLineParameter;
3836 CmdLineParameters := TCmdLineParameters.Create;
3837 CmdLineParameters.parseCmdLine(tmpCmdLine);
3838
3839 RegisterForLanguages( OnLanguageEvent );
3840
3841 // if debug is not enabled, get rid of the debug menu and separator.
3842 if GetEnv( 'NEWVIEW_DEBUG' ) = '' then
3843 begin
3844 ToolsDebugSep.Destroy;
3845 ToolsDebugMenu.Destroy;
3846 DebugShowCodesMI := nil;
3847 DebugShowWordSeparatorsMI := nil;
3848 end;
3849
3850 // set up globals for Exec
3851 ExecViaSession := true;
3852 AsynchExec := true;
3853
3854 // set up form icons
3855 Forms.FormIconResourceID := 1;
3856
3857 Application.OnException := OnException;
3858
3859 ContentsOutline.SmoothScroll := false;
3860
3861 LogEvent(LogStartup, 'Choosing default font: Trying WarpSans');
3862
3863 Font := GetNiceDefaultFont;
3864
3865 // Set the menu fonts, because they remember their own specific one
3866 MainMenu.Font := Screen.MenuFont;
3867 ViewPopupMenu.Font := Screen.MenuFont;
3868
3869 // NOTE: SPCC will copy this font to TApplication
3870 // in TApplication.Run
3871
3872 LogEvent(LogStartup, 'Starting NewView: MainFormOnCreate');
3873
3874 Application.OnHint := OnHint;
3875
3876 StartMem := MemAvailBytes;
3877
3878 DisplayedIndex := TStringList.Create;
3879
3880 HelpManagerWindows := TList.Create;
3881
3882 AllFilesWordSequences := TList.Create;
3883
3884 CurrentOpenFiles := TList.Create;
3885 Notes := TList.Create;
3886 Bookmarks := TList.Create;
3887 BookmarksMenuItems := TList.Create;
3888 Windows := TList.Create;
3889
3890 TopicText := TAString.Create;
3891
3892 Navigating := false;
3893 InIndexSearch := false;
3894 SettingFont := false;
3895
3896 PageHistory := TStringList.Create;
3897 CurrentHistoryIndex := -1;
3898
3899 Settings.MRUList := TList.Create;
3900
3901 MRUMenuItems := TList.Create;
3902 NavigateToMenuItems := TList.Create;
3903
3904 LogEvent(LogSettings, 'Loading settings');
3905
3906 LoadSettings;
3907 SetShowLeftPanel( ShowLeftPanel ); // update menu
3908
3909 // load default strings
3910 LogEvent(LogSettings, 'Loading language');
3911
3912 if CmdLineParameters.getLanguage <> '' then
3913 LoadAutoLanguage( 'newview', CmdLineParameters.getLanguage )
3914 else
3915 LoadDefaultLanguage( 'newview' );
3916
3917 LogEvent(LogSettings, 'Applying settings');
3918 ApplySettings;
3919
3920 // default position is centered..
3921 LogEvent(LogSettings, 'Set default position');
3922 if Width > Screen.Width then
3923 Width := Screen.Width;
3924 if Height > Screen.Height then
3925 Height := Screen.Height;
3926 Left := ( Screen.Width - Width ) div 2;
3927 Bottom := ( Screen.Height - Height ) div 2;
3928
3929 LogEvent(LogSettings, 'ReadWindowPos');
3930 ReadWindowPos( Self );
3931
3932 PositionWindow;
3933
3934 LogEvent(LogSettings, 'Creating MRU list');
3935
3936 CreateMRUMenuItems;
3937
3938 CloseFile;
3939
3940 LogEvent(LogStartup, 'OnCreate done');
3941
3942 if CmdLineParameters.getWindowPositionFlag then
3943 begin
3944 SmartSetWindowPos( self,
3945 CmdLineParameters.getWindowPosition.Left,
3946 CmdLineParameters.getWindowPosition.Bottom,
3947 CmdLineParameters.getWindowPosition.Width,
3948 CmdLineParameters.getWindowPosition.Height,
3949 false );
3950 end;
3951
3952 LogEvent(LogStartup, 'MainFormOnCreate Done');
3953End;
3954
3955Procedure TMainForm.ApplySettings;
3956var
3957 ToolbarBitmap: TBitmap;
3958begin
3959 ContentsOutline.Color:= Settings.Colors[ ContentsBackgroundColorIndex ];
3960 ContentsOutline.PenColor:= Settings.Colors[ ContentsTextColorIndex ];
3961 ContentsOutline.TreeLineColor:= Settings.Colors[ ContentsLinesColorIndex ];
3962 IndexListBox.Color:= Settings.Colors[ IndexBackgroundColorIndex ];
3963 IndexListBox.PenColor:= Settings.Colors[ IndexTextColorIndex ];
3964 SearchResultsListBox.Color:= Settings.Colors[ SearchBackgroundColorIndex ];
3965 SearchResultsListBox.PenColor:= Settings.Colors[ SearchTextColorIndex ];
3966 NotesListBox.Color:= Settings.Colors[ NotesListBackgroundColorIndex ];
3967 NotesListBox.PenColor:= Settings.Colors[ NotesListTextColorIndex ];
3968
3969 SettingFont := true;
3970 Notebook.ParentFont := true;
3971 ContentsOutline.ParentFont := true;
3972 IndexListBox.ParentFont := true;
3973 SearchResultsListBox.ParentFont := true;
3974 NotesListBox.ParentFont := true;
3975 TabSet.ParentFont := true;
3976 Coolbar.ParentFont := true;
3977 if Settings.Fonts[ ApplicationFontIndex ] <> nil then
3978 Font := Settings.Fonts[ ApplicationFontIndex ]
3979 else
3980 Font := GetNiceDefaultFont;
3981 SettingFont := false;
3982
3983 Coolbar.BackgroundBitmap := nil;
3984 if FileExists( Settings.ToolbarBackgroundImageFilename ) then
3985 begin
3986 ToolbarBitmap:= TBitmap.Create;
3987 try
3988 ToolbarBitmap.LoadFromFIle( Settings.ToolbarBackgroundImageFilename );
3989 Coolbar.BackgroundBitmap := ToolbarBitmap;
3990 except
3991 end;
3992 ToolbarBitmap.Destroy;
3993 end;
3994
3995 CoolBar.ShowImages := Settings.ToolbarStyle in [ tsImages, tsImagesAndText ];
3996 CoolBar.ShowText := Settings.ToolbarStyle in [ tsText, tsImagesAndText ];
3997
3998 CoolBar.SetMinConstButtonWidth;
3999
4000 DisplayPanel.Color := Settings.Colors[ TopicBackgroundColorIndex ];
4001
4002 SetupViews( Windows );
4003end;
4004
4005// Setup the rich text views in the specified windows (e.g for changing global settings)
4006Procedure TMainForm.SetupViews( WindowList: TList );
4007var
4008 WindowIndex: longint;
4009 Window: THelpWindow;
4010begin
4011 for WindowIndex := 0 to WindowList.Count - 1 do
4012 begin
4013 Window := WindowList[ WindowIndex ];
4014 Window.SetupRTView;
4015 SetupViews( Window.ChildWindows );
4016 end;
4017end;
4018
4019Procedure TMainForm.PostHelpManagerMessage( MessageType: ULONG;
4020 Param1: long;
4021 Param2: long );
4022var
4023 i: longint;
4024begin
4025 for i := 0 to HelpManagerWindows.Count - 1 do
4026 PostMsg( HWND( HelpManagerWindows[ i ] ),
4027 MessageType,
4028 Param1,
4029 Param2 );
4030end;
4031
4032Procedure TMainForm.ClearHelpManager;
4033Begin
4034 if not CmdLineParameters.getHelpManagerFlag then
4035 exit;
4036
4037 // tell the help manager(s) we are no longer playing with them
4038 PostHelpManagerMessage( NHM_FORGET_VIEWER, 0, 0 );
4039
4040 CmdLineParameters.setHelpManagerFlag(false);
4041
4042 HelpManagerWindows.Clear;
4043End;
4044
4045Procedure TMainForm.MainFormOnShow (Sender: TObject);
4046Begin
4047 EnableCallstackLogging( true );
4048
4049 LogEvent(LogStartup, 'MainFormOnShow');
4050
4051 if CmdLineParameters.getOwnerWindow <> NULLHANDLE then
4052 begin
4053 LogEvent(LogStartup, 'Setting owner: '
4054 + IntToStr( CmdLineParameters.getOwnerWindow));
4055 WinSetOwner( Frame.Handle,
4056 CmdLineParameters.getOwnerWindow );
4057
4058 end;
4059
4060 if CmdLineParameters.getHelpManagerFlag then
4061 begin
4062 LogEvent(LogStartup, ' Help Manager Title: '
4063 + StrNPas( pSharedStruct ^. Title,
4064 SHARED_STRUCT_TITLE_SIZE ) );
4065 HelpManagerVersion := StrNPas( pSharedStruct ^. Version,
4066 SHARED_STRUCT_VERSION_SIZE );
4067 LogEvent(LogStartup, ' Help Manager Version: ' + HelpManagerVersion );
4068
4069 end;
4070
4071 CoolBar.SetMinConstButtonWidth;
4072
4073 LogEvent(LogStartup, 'Post WM_OPENED');
4074
4075 ResetProgress;
4076
4077 AddShortcut( kbF11, kbF11 ); // prev in contents
4078 AddShortcut( kbF12, kbF12 ); // next in contents
4079 AddShortcut( kbF7, kbF7 ); // back
4080 AddShortcut( kbF8, kbF8 ); // forward
4081 AddShortcut( kbCtrlCLeft, kbCtrlCLeft ); // back
4082
4083 PostMsg( Handle, WM_OPENED, 0, 0 );
4084End;
4085
4086Procedure TMainForm.DisplaySelectedContentsTopic;
4087var
4088 Topic: TTopic;
4089Begin
4090 if ContentsOutline.SelectedNode = nil then
4091 exit;
4092 Topic := ContentsOutline.SelectedNode.Data as TTopic;
4093 DisplayTopic( Topic );
4094End;
4095
4096// Check that the HELP and BOOKSHELF environment variables
4097// are defined (as they should be on any working OS/2 system).
4098// Show a warning message if not.
4099Procedure TMainForm.CheckEnvironmentVars;
4100var
4101 HelpOK: boolean;
4102 BookshelfOK: boolean;
4103 ErrorText: string;
4104begin
4105 HelpOK := GetEnv( HelpPathEnvironmentVar ) <> '';
4106 BookshelfOK := GetEnv( BookshelfEnvironmentVar ) <> '';
4107 if HelpOK and BookshelfOK then
4108 // all ok.
4109 exit;
4110
4111 // One or both missing
4112
4113 ErrorText := '';
4114 if not BookshelfOK then
4115 ErrorText := ErrorText
4116 + EnvironmentVarUndefined
4117 + BookshelfEnvironmentVar
4118 + EndLine;
4119
4120 if not HelpOK then
4121 ErrorText := ErrorText
4122 + EnvironmentVarUndefined
4123 + HelpPathEnvironmentVar
4124 + EndLine;
4125
4126 DoWarningDlg( EnvironmentVarErrorTitle,
4127 EnvironmentVarError
4128 + EndLine
4129 + EndLine
4130 + ErrorText );
4131
4132end;
4133
4134Procedure LoadSupportDLL;
4135begin
4136 try
4137 LoadDLLFunction( 'newview.dll',
4138 'LZWDECOMPRESSBLOCK',
4139 hNewViewDLL,
4140 pointer( LZWDecompressBlock ) );
4141 except
4142 on E: Exception do
4143 begin
4144 DoErrorDlg( 'DLL Error',
4145 E.Message );
4146 LZWDecompressBlock := nil;
4147 end;
4148 end;
4149end;
4150
4151Procedure TMainForm.WMOpened( Var Msg: TMessage );
4152var
4153 Filenames: TStringList;
4154 M1: longword;
4155 OpenFirstTopic: boolean;
4156begin
4157 if Application.HelpFile = '' then
4158 DoErrorDlg( 'NewView Help', 'NewView help file not found' );
4159
4160 LoadSupportDLL;
4161
4162 LogEvent(LogStartup, 'WMOpened: SetLayout');
4163
4164 if CmdLineParameters.getHelpManagerFlag then
4165 FShowLeftPanel := Settings.ShowLeftPanel_Help
4166 else
4167 FShowLeftPanel := Settings.ShowLeftPanel_Standalone;
4168
4169 SetLayout;
4170
4171// ProfileEvent( 'Apply settings' );
4172// ApplySettings;
4173
4174 LogEvent(LogStartup, 'Enable controls');
4175 EnableControls;
4176
4177// ProfileEvent( 'ReadWindowPos' );
4178// ReadWindowPos( Self );
4179
4180 LogEvent(LogStartup, 'Finish paint');
4181 Update;
4182
4183 if not CmdLineParameters.getHelpManagerFlag then
4184 begin
4185 LogEvent(LogStartup, 'Check environment vars');
4186 CheckEnvironmentVars;
4187
4188 if CmdLineParameters.getShowUsageFlag then
4189 begin
4190 LogEvent(LogStartup, 'Showing usage');
4191 ShowUsage;
4192
4193 if FileExists( GetOwnHelpFileName ) then
4194 OpenFile( GetOwnHelpFileName, '', true );
4195
4196 exit;
4197 end;
4198 end;
4199
4200 HelpManagerWindows.Add( pointer( CmdLineParameters.getHelpManagerWindow ) );
4201
4202 if CmdLineParameters.getFileNames <> '' then
4203 begin
4204 // open specified files
4205 Filenames := TStringList.Create;
4206
4207 // TODO use StrExtractStrings
4208 StringToList(cmdLineParameters.getFileNames, Filenames, '+' );
4209
4210 LogEvent(LogStartup, 'Call OpenFiles');
4211
4212 OpenFirstTopic := true;
4213
4214 if ( CmdLineParameters.getSearchText <> '' )
4215 or CmdLineParameters.getSearchFlag then
4216 // if we're going to search, don't open first topic
4217 OpenFirstTopic := false;
4218
4219 if CmdLineParameters.getHelpManagerFlag then
4220 begin
4221 // don't open first topic if we're online help
4222 // in case we are wanting to show a specific topic
4223 // - saves time/flicker
4224 OpenFirstTopic := false;
4225 end;
4226
4227 if NOT ( CmdLineParameters.getGlobalSearchFlag
4228 AND (CmdLineParameters.getSearchText = '')
4229 )
4230 then
4231 begin
4232 OpenFiles( Filenames,
4233 CmdLineParameters.getWindowTitle,
4234 OpenFirstTopic );
4235 end;
4236
4237 Filenames.Destroy;
4238
4239 if not CmdLineParameters.getSearchFlag
4240 and not CmdLineParameters.getGlobalSearchFlag
4241 and (CmdLineParameters.getSearchText <> '') then
4242 begin
4243 // search in contents only!
4244 LogEvent(LogStartup, 'Do startup topic search');
4245
4246 StartupTopicSearch( CmdLineParameters.getSearchText );
4247 end
4248 else if CmdLineParameters.getSearchFlag then
4249 begin
4250 // search in specified files
4251 LogEvent(LogStartup, 'Do search for topic');
4252 DisplaySearch;
4253
4254 SearchFor( CmdLineParameters.getSearchText );
4255 end;
4256 end;
4257
4258 if CmdLineParameters.getGlobalSearchFlag then
4259 begin
4260 // Global search
4261 if (CmdLineParameters.getSearchText = '')
4262 AND (CmdLineParameters.getFileNamesRaw <> '')
4263 then
4264 begin
4265 LogEvent(LogStartup, 'Do global search: ' + CmdLineParameters.getFileNamesRaw );
4266 DoGlobalSearch( CmdLineParameters.getFileNamesRaw );
4267 end
4268 else
4269 begin
4270 LogEvent(LogStartup, 'Do global search: ' + CmdLineParameters.getSearchText );
4271 DoGlobalSearch( CmdLineParameters.getSearchText );
4272 end;
4273 end;
4274
4275 if ( length(CmdLineParameters.getFileNames) = 0 )
4276 and ( not CmdLineParameters.getSearchFlag ) then
4277 begin
4278 // user hasn't requested any particular file
4279 // at startup, so if the option is still set,
4280 // load the NewView help file
4281 if Settings.StartupHelp then
4282 if FileExists( GetOwnHelpFileName ) then
4283 OpenFile( GetOwnHelpFileName, '', true );
4284 end;
4285
4286 LogEvent(LogStartup, 'Open finished');
4287
4288 if CmdLineParameters.getHelpManagerFlag then
4289 begin
4290 // Tell helpmanager(s) our window handle
4291 PostHelpManagerMessage( NHM_VIEWER_READY,
4292 Handle,
4293 0 );
4294 end;
4295
4296 M1:= MemAvail;
4297
4298 StartingUp := false;
4299
4300 LogEvent(LogStartup, 'RUN PROGRAM');
4301end;
4302
4303Procedure TMainForm.MainFormOnResize (Sender: TObject);
4304Begin
4305 if not Visible then
4306 exit;
4307 if Handle = 0 then
4308 exit;
4309
4310 SetLayout;
4311
4312End;
4313
4314Function TMainForm.GetShowLeftPanel: boolean;
4315begin
4316 Result := FShowLeftPanel;
4317end;
4318
4319Procedure TMainForm.SetShowLeftPanel( Value: boolean );
4320begin
4321 ShowLeftPanelMI.Checked := Value;
4322 if Value = FShowLeftPanel then
4323 exit;
4324 FShowLeftPanel := Value;
4325 if FShowLeftPanel then
4326 NotebookOnPageChanged( self ) // make sure page is updated
4327 else
4328 FocusFirstHelpWindow;
4329 EnableControls;
4330 SetLayout;
4331end;
4332
4333Procedure TMainForm.VSplitBarOnChange (NewSplit: LongInt);
4334Begin
4335 if VSplitBar.Left < 30 then
4336 begin
4337 ShowLeftPanel := false
4338 end
4339 else
4340 begin
4341 Settings.LeftPanelWidth := VSplitBar.Left;
4342 ShowLeftPanel := true;
4343 end;
4344 SetLayout;
4345End;
4346
4347// Set the layout of the main form
4348Procedure TMainForm.SetLayout;
4349var
4350 RealClientHeight : longint;
4351 CoolbarSpace: longint;
4352 TextHeight: longint;
4353Begin
4354 TextHeight := Canvas.TextHeight( 'S' );
4355 Tabset.Height := TextHeight + 5;
4356
4357 Coolbar.Visible := Settings.ToolbarStyle <> tsNone;
4358
4359 case Settings.ToolbarStyle of
4360 tsImages:
4361 Coolbar.Height := Coolbar.Sections[ 0 ].Width;
4362 tsText:
4363 Coolbar.Height := TextHeight + 5;
4364 tsImagesAndText:
4365 CoolBar.Height := ButtonImages.GetBitmapReference(0).Width + TextHeight + 10;
4366 end;
4367
4368 CoolbarSpace := Coolbar.Height;
4369 if not Coolbar.Visible then
4370 CoolbarSpace := 0;
4371
4372 StatusPanel.Left:= 0;
4373 StatusPanel.Width:= ClientWidth div 2 - 2;
4374 StatusPanel.Height := TextHeight + 2;
4375
4376 ProgressPanel.Left:= ClientWidth div 2 + 2;
4377 ProgressPanel.Width:= ClientWidth - ProgressPanel.Left;
4378 ProgressPanel.Height := TextHeight + 2;
4379
4380 Notebook.Bottom := StatusPanel.Height + 3;
4381 VSplitBar.Bottom := Notebook.Bottom;
4382 DisplayPanel.Bottom := Notebook.Bottom;
4383
4384 RealClientHeight := ClientHeight
4385 - CoolbarSpace
4386 - Notebook.Bottom;
4387
4388 LogEvent(LogStartup, 'TMainForm.SetLayout');
4389 LogEvent(LogStartup, ' RealClientHeight: ' + IntToStr( RealClientHeight ));
4390
4391 LogEvent(LogStartup, ' Form Width: ' + IntToStr( Width ));
4392 LogEvent(LogStartup, ' Form Height: ' + IntToStr( Height ) );
4393 LogEvent(LogStartup, ' Form ClientWidth: ' + IntToStr( ClientWidth ) );
4394 LogEvent(LogStartup, ' Form ClientHeight: ' + IntToStr( ClientHeight ) );
4395 LogEvent(LogStartup, ' CoolBar.Height: ' + IntToStr( CoolBar.Height ) );
4396 LogEvent(LogStartup, ' CoolBar.Bottom: ' + IntToStr( CoolBar.Bottom ) );
4397
4398 if CurrentOpenFiles.Count > 0 then
4399 VSplitBar.Width := Max( 5, Canvas.TextWidth( ' ' ) )
4400 else
4401 VSplitBar.Width := 0;
4402
4403 VSplitBar.Height := RealClientHeight;
4404
4405 if Settings.LeftPanelWidth > ClientWidth - 50 then
4406 Settings.LeftPanelWidth := ClientWidth - 50;
4407 if Settings.LeftPanelWidth < 50 then
4408 Settings.LeftPanelWidth := 50;
4409
4410 if ShowLeftPanel then
4411 begin
4412 VSplitBar.Left := Settings.LeftPanelWidth;
4413 VSplitBar.Hint := SplitBarDblClickToHide;
4414 end
4415 else
4416 begin
4417 VSplitBar.Left := 0;
4418 VSplitBar.Hint := SplitBarDblClickToShow;
4419 end;
4420
4421 Tabset.Left := 0;
4422 Tabset.Width := VSplitBar.Left;
4423 Tabset.Bottom := ClientHeight
4424 - CoolbarSpace
4425 - Tabset.Height;
4426
4427 Notebook.Left := 0;
4428 Notebook.Width := VSplitBar.Left;
4429 Notebook.Height := RealClientHeight
4430 - Tabset.Height
4431 - 3;
4432
4433 DisplayPanel.Left:= VSplitBar.Left + VSplitBar.Width;
4434 DisplayPanel.Width:= ClientWidth - DisplayPanel.Left;
4435 DisplayPanel.Height := RealClientHeight;
4436 LogEvent(LogStartup, ' DisplayPanel.Width: ' + IntToStr( DisplayPanel.Width ) );
4437 LogEvent(LogStartup, ' DisplayPanel.Height: ' + IntToStr( DisplayPanel.Height ) );
4438 LogEvent(LogStartup, ' DisplayPanel.Bottom: ' + IntToStr( DisplayPanel.Bottom ) );
4439
4440 ProgressBar.Left:= 1;
4441 ProgressBar.Bottom:= 1;
4442 ProgressBar.Width:= ProgressPanel.Width - 2;
4443 ProgressBar.Height:= ProgressPanel.Height - 2;
4444
4445 // Layout the visible help windows also
4446 LayoutWindowList( Windows );
4447End;
4448
4449// Lay out the specified list of help windows
4450Procedure TMainForm.LayoutWindowList( WindowList: TList );
4451var
4452 Window: THelpWindow;
4453 WindowIndex: longint;
4454begin
4455 for WindowIndex:= 0 to WindowList.Count - 1 do
4456 begin
4457 Window:= WindowList[ WindowIndex ];
4458 Window.SetLayout;
4459 end;
4460end;
4461
4462Procedure TMainForm.FindNextMIOnClick (Sender: TObject);
4463begin
4464 if FindText = '' then
4465 begin
4466 FindMIOnClick( sender );
4467 exit;
4468 end;
4469
4470 if GetActiveWindow = nil then
4471 begin
4472 DoErrorDlg( FindTitle,
4473 FindSelectWindowError );
4474 exit;
4475 end;
4476
4477 DoFind( foFromCurrent );
4478end;
4479
4480Procedure TMainForm.DoFind( FindOrigin: TFindOrigin );
4481var
4482 Window: THelpWindow;
4483begin
4484 SetWaitCursor;
4485 Window := GetActiveWindow;
4486 if not Window.View.Find( FindOrigin, FindText ) then
4487 begin
4488 SetStatus( TextNotFoundMsg );
4489 Beep( 1000, 100 );
4490 end;
4491 ClearWaitCursor;
4492End;
4493
4494Procedure TMainForm.FindMIOnClick (Sender: TObject);
4495begin
4496 if GetActiveWindow = nil then
4497 begin
4498 DoErrorDlg( FindTitle,
4499 FindSelectWindowError );
4500 exit;
4501 end;
4502 if not DoInputQuery( FindTitle,
4503 FindPrompt,
4504 FindText ) then
4505 exit;
4506
4507 DoFind( foFromStart );
4508End;
4509
4510Procedure TMainForm.IndexSearchEditOnScan (Sender: TObject;
4511 Var KeyCode: TKeyCode);
4512Begin
4513 case KeyCode of
4514 kbCUp:
4515 begin
4516 if IndexListBox.ItemIndex > 0 then
4517 IndexListBox.ItemIndex:= IndexListBox.ItemIndex - 1;
4518 KeyCode:= kbNull;
4519 end;
4520
4521 kbCDown:
4522 begin
4523 if IndexListBox.ItemIndex < IndexListBox.Items.Count - 1 then
4524 IndexListBox.ItemIndex:= IndexListBox.ItemIndex + 1;
4525 KeyCode:= kbNull;
4526 end;
4527
4528 kb_VK + VK_NEWLINE:
4529 begin
4530 DisplaySelectedIndexTopic;
4531 end;
4532 end;
4533
4534End;
4535
4536Procedure TMainForm.IndexSearchEditOnChange (Sender: TObject);
4537var
4538 MatchIndex: longint;
4539 IndexINdex: longint;
4540 SearchText: string;
4541Begin
4542 if InIndexSearch then
4543 exit;
4544
4545 MatchIndex:= -1;
4546 SearchText:= trim( IndexSearchEdit.Text );
4547 for IndexIndex:= 0 to DisplayedIndex.Count - 1 do
4548 begin
4549 if StrStarts( SearchText, DisplayedIndex[ IndexIndex ] ) then //IndexEntry ) then
4550 begin
4551 MatchIndex:= IndexIndex;
4552 break;
4553 end;
4554 end;
4555
4556 if MatchIndex = -1 then
4557 exit;
4558
4559 InIndexSearch:= true;
4560
4561 if IndexListBox.ItemIndex <> MatchIndex then
4562 IndexListBox.ItemIndex:= MatchIndex;
4563
4564 InIndexSearch:= false;
4565End;
4566
4567Procedure TMainForm.FileInformationMIOnClick (Sender: TObject);
4568var
4569 FileIndex: longint;
4570 HelpFile: THelpFile;
4571
4572 TotalTopicCount: longint;
4573 TotalIndexCount: longint;
4574 TotalFileSize: longint;
4575
4576Begin
4577 TotalTopicCount := 0;
4578 TotalIndexCount := 0;
4579 TotalFileSize := 0;
4580
4581 with InformationForm.InformationMemo do
4582 begin
4583 BeginUpdate;
4584 Lines.Clear;
4585 Lines.Add( FilesInfoTitle );
4586 for FileIndex := 0 to CurrentOpenFiles.Count - 1 do
4587 begin
4588 HelpFile := CurrentOpenFiles[ FileIndex ];
4589
4590 Lines.Add( FilesInfoFilename + HelpFile.FileName );
4591 Lines.Add( FilesInfoFileTitle
4592 + HelpFile.Title );
4593 Lines.Add( FilesInfoTopicCount
4594 + IntToStr( HelpFile.TopicCount ) );
4595 Lines.Add( FilesInfoIndexCount
4596 + IntToStr( HelpFile.Index.Count ) );
4597 Lines.Add( FilesInfoDictionaryCount
4598 + IntToStr( HelpFile.DictionaryCount ) );
4599 Lines.Add( FilesInfoFileSize
4600 + IntToStr( HelpFile.FileSize ) );
4601
4602 inc( TotalTopicCount, HelpFile.TopicCount );
4603 inc( TotalIndexCount, HelpFile.Index.Count );
4604 inc( TotalFileSize, HelpFile.FileSize );
4605
4606 end;
4607
4608 Lines.Add( '' );
4609 Lines.Add( FilesInfoTotalTopicCount
4610 + IntToStr( TotalTopicCount ) );
4611 Lines.Add( FilesInfoTotalIndexCount
4612 + IntToStr( TotalIndexCount ) );
4613 Lines.Add( FilesInfoTotalFileSize
4614 + IntToStr( TotalFileSize ) );
4615 Lines.Add( '' );
4616
4617 EndUpdate;
4618 end;
4619 InformationForm.ShowModal;
4620End;
4621
4622Procedure TMainForm.DisplaySelectedSearchResultTopic;
4623var
4624 Topic: TTopic;
4625Begin
4626 if SearchResultsListBox.ItemIndex = -1 then
4627 exit;
4628 if SelectedObject( SearchResultsListBox ) = nil then
4629 // the "no results" place holder
4630 exit;
4631 Topic := SelectedObject( SearchResultsListBox ) as TTopic;
4632 DisplayTopic( Topic );
4633End;
4634
4635Procedure TMainForm.SearchTextEditOnScan (Sender: TObject;
4636 Var KeyCode: TKeyCode);
4637Begin
4638 case KeyCode of
4639 kbCUp:
4640 begin
4641 if SearchResultsListBox.ItemIndex > 0 then
4642 SearchResultsListBox.ItemIndex := SearchResultsListBox.ItemIndex - 1;
4643 KeyCode := kbNull;
4644 SearchResultsListBox.Focus;
4645 end;
4646
4647 kbCDown:
4648 begin
4649 if SearchResultsListBox.ItemIndex < SearchResultsListBox.Items.Count - 1 then
4650 SearchResultsListBox.ItemIndex := SearchResultsListBox.ItemIndex + 1;
4651 KeyCode := kbNull;
4652 SearchResultsListBox.Focus;
4653 end;
4654 end;
4655End;
4656
4657Procedure TMainForm.SearchButtonOnClick (Sender: TObject);
4658Begin
4659 DoSearch;
4660End;
4661
4662// Matches old stupid View algorithm
4663Procedure TMainForm.StartupTopicSearch( const SearchText: string );
4664var
4665 i: longint;
4666 HelpFile: THelpFile;
4667 Topic: TTopic;
4668 // s: string;
4669begin
4670 // search files in order they are open
4671 for i := 0 to CurrentOpenFiles.Count - 1 do
4672 begin
4673 HelpFile := THelpFile( CurrentOpenFiles[ i ] );
4674
4675 // look for a topic whose title starts with the searchtext
4676 Topic := HelpFile.FindTopicByTitleStartsWith( SearchText );
4677
4678 if Topic = nil then
4679 // look for an index entry that starts with the searchtext
4680 Topic := HelpFile.FindTopicByIndexStartsWith( SearchText );
4681
4682 if Topic = nil then
4683 // look for a topic whose title contains the searchtext
4684 Topic := HelpFile.FindTopicByTitleContains( SearchText );
4685
4686 if Topic = nil then
4687 // look for an index entry that contains the searchtext
4688 Topic := HelpFile.FindTopicByIndexContains( SearchText );
4689
4690 if Topic <> nil then
4691 begin
4692 // found something, display it (don't keep searching files)
4693 DisplayTopic( Topic );
4694 exit;
4695 end;
4696 end;
4697 DoErrorDlg( SearchTitle, TextNotFoundMsg );
4698end;
4699
4700Procedure TMainForm.SearchFor( const SearchText: string );
4701begin
4702 SearchTextEdit.Text := SearchText;
4703 DisplaySearch;
4704 SearchResultsListBox.Focus;
4705
4706 // force repaint of everything before we start searching.
4707 Update;
4708
4709 DoSearch;
4710end;
4711
4712Procedure TMainForm.ClearAllWordSequences;
4713var
4714 i: longint;
4715 FileWordSequences: TList;
4716 HelpFile: THelpFile;
4717begin
4718 if AllFilesWordSequences = nil then
4719 exit;
4720
4721 for i := 0 to AllFilesWordSequences.Count - 1 do
4722 begin
4723 FileWordSequences := AllFilesWordSequences[ i ];
4724 HelpFile := CurrentOpenFiles[ i ];
4725 ClearWordSequences( FileWordSequences, HelpFile.DictionaryCount );
4726 FileWordSequences.Destroy;
4727 end;
4728 AllFilesWordSequences.Clear;
4729end;
4730
4731// Perform search for text in searchedit.
4732Procedure TMainForm.DoSearch;
4733var
4734 SearchResults: TList;
4735 SearchText: string;
4736 FileIndex: longint;
4737 HelpFile: THelpFile;
4738 TopicIndex: longint;
4739 Topic: TTopic;
4740 FileWordSequences: TList;
4741 Query: TTextSearchQuery;
4742begin
4743 SearchText := Trim( SearchTextEdit.Text );
4744
4745 SearchResultsListBox.Clear;
4746
4747 if SearchText = '' then
4748 exit;
4749
4750 SearchResultsListBox.Items.Add( SearchingMsg );
4751 SetStatus( SearchingMsg );
4752
4753 try
4754 Query := TTextSearchQuery.Create( SearchText );
4755 except
4756 on e: ESearchSyntaxError do
4757 begin
4758 DoErrorDlg( SearchTitle,
4759 SearchSyntaxError
4760 + e.Message );
4761 exit;
4762 end;
4763 end;
4764
4765 ClearAllWordSequences;
4766
4767 SetWaitCursor;
4768
4769 SearchResults := TList.Create;
4770
4771 // Search open help file
4772 for FileIndex := 0 to CurrentOpenFiles.Count - 1 do
4773 begin
4774 HelpFile := CurrentOpenFiles[ FileIndex ];
4775
4776 FileWordSequences := TList.Create;
4777
4778 try
4779 SearchHelpFile( HelpFile,
4780 Query,
4781 SearchResults,
4782 FileWordSequences );
4783 except
4784 on E: EHelpFileException do
4785 begin
4786 DoErrorDlg( ErrorTitle, E.Message );
4787 Query.Destroy;
4788 ClearWaitCursor;
4789 exit;
4790 end;
4791 end;
4792
4793 AllFilesWordSequences.Add( FileWordSequences );
4794
4795 end;
4796
4797 // Sort results across all files by relevance
4798 SearchResults.Sort( TopicRelevanceCompare );
4799
4800 // Load topics into search results list.
4801 SearchResultsListBox.BeginUpdate;
4802 SearchResultsListBox.Clear;
4803
4804 for TopicIndex := 0 to SearchResults.Count - 1 do
4805 begin
4806 Topic := SearchResults[ TopicIndex ];
4807 SearchResultsListBox.Items.AddObject( Topic.Title
4808 + ' ['
4809 + IntToStr( Topic.SearchRelevance )
4810 + ']',
4811 Topic );
4812 end;
4813
4814 EnableControls;
4815 if SearchResultsListBox.Items.Count > 0 then
4816 // there are some search matches, so highlight words
4817 ViewHighlightSearchWordsMI.Checked := true;
4818
4819 SearchResultsListBox.ItemIndex := -1;
4820 SearchResultsListBox.EndUpdate;
4821
4822 Query.Destroy;
4823 SearchResults.Destroy;
4824
4825 if SearchResultsListBox.Items.Count > 0 then
4826 begin
4827 SearchResultsListBox.ItemIndex := 0;
4828 end
4829 else
4830 begin
4831 SearchResultsListBox.Items.Add( NoSearchMatchesMsg
4832 + ': '
4833 + SearchText );
4834 RefreshWindows( Windows ); // update to remove old highlights
4835 end;
4836 SetStatus( SearchFoundMsgA
4837 + IntToStr( SearchResultsListBox.Items.Count )
4838 + SearchFoundMsgB
4839 + StrDoubleQuote( SearchText ) );
4840
4841 ClearWaitCursor;
4842
4843 DisplaySelectedSearchResultTopic;
4844
4845End;
4846
4847Procedure TMainForm.FileSaveAsMIOnClick (Sender: TObject);
4848var
4849 F: File;
4850 EntryText: PChar;
4851 TextLength: longint;
4852 Window: THelpWindow;
4853 Filename: string;
4854Begin
4855 Window := GetActiveWindow;
4856 if Window = nil then
4857 begin
4858 DoErrorDlg( FileSaveTitle,
4859 FileSaveSelectWindowError );
4860 exit;
4861 end;
4862
4863 if DoSaveFileDialog( FileSaveTitle,
4864 AllFilesDesc + '|*',
4865 DefaultSaveTopicFilename,
4866 Settings.LastSaveDirectory,
4867 Filename ) then
4868 begin
4869 if FileExists( Filename ) then
4870 if not DoConfirmDlg( FileSaveTitle,
4871 ReplaceFilePromptA
4872 + Filename
4873 + ReplaceFilePromptB ) then
4874 exit;
4875 System.Assign( F, Filename );
4876
4877 try
4878 Rewrite( F );
4879 except
4880 on E: Exception do
4881 begin
4882 DoErrorDlg( FileSaveTitle,
4883 UnableToSaveError
4884 + Filename
4885 + ': '
4886 + E.Message );
4887 exit;
4888 end;
4889 end;
4890
4891 // find out length of (plain) text
4892 TextLength := Window.View.CopyTextToBuffer( nil, -1 );
4893
4894 // allocate space
4895 EntryText:= StrAlloc( TextLength );
4896
4897 // get the plain text
4898 Window.View.CopyTextToBuffer( EntryText, TextLength );
4899
4900 // save to file
4901 System.BlockWrite( F, EntryText^, TextLength );
4902
4903 // free space
4904 StrDispose( EntryText );
4905
4906 System.Close( F );
4907 end;
4908End;
4909
4910Procedure TMainForm.OptionsMIOnClick (Sender: TObject);
4911begin
4912 DoOptions;
4913end;
4914
4915Procedure TMainForm.DoOptions;
4916Begin
4917 EnsureOptionsFormLoaded;
4918
4919 GetColors; // in case changed by drag drop
4920
4921 if OptionsForm.ShowModal = mrOK then
4922 begin
4923 ApplySettings;
4924 SetLayout;
4925 RefreshFontSubstitutions;
4926 RefreshWindows( Windows );
4927 end;
4928End;
4929
4930Procedure TMainForm.ShowUsage;
4931begin
4932 DoMessageDlg( UsageTitle,
4933 UsageText1 + EndLine
4934 + UsageText2 + EndLine
4935 + UsageText3 + EndLine
4936 + UsageText4 + EndLine
4937 + UsageText5 + EndLine
4938 + UsageText6 + EndLine
4939 + UsageText7 + EndLine
4940 + UsageText8 );
4941end;
4942
4943Procedure TMainForm.TabSetOnChange (Sender: TObject; NewTab: LongInt;
4944 Var AllowChange: Boolean);
4945Begin
4946 NoteBook.PageIndex := NewTab;
4947End;
4948
4949Procedure TMainForm.NotebookOnSetupShow (Sender: TObject);
4950Begin
4951 ContentsOutline.xStretch := xsFrame;
4952 ContentsOutline.yStretch := ysFrame;
4953
4954 IndexSearchEdit.yAlign := yaTop;
4955 IndexSearchEdit.xStretch := xsFrame;
4956 IndexListBox.yStretch := ysFrame;
4957 IndexListBox.xStretch := xsFrame;
4958
4959 SearchTextEdit.yAlign := yaTop;
4960 SearchTextEdit.xStretch := xsFrame;
4961 SearchButton.yAlign := yaTop;
4962 SearchButton.xAlign := xaRight;
4963 SearchResultsListBox.xStretch := xsFrame;
4964 SearchResultsListBox.yStretch := ysFrame;
4965
4966 NotesListBox.xStretch := xsFrame;
4967 NotesListBox.yStretch := ysFrame;
4968End;
4969
4970Procedure TMainForm.EnableControls;
4971var
4972 BackEnabled: boolean;
4973 ForwardEnabled: boolean;
4974 FileOpen: boolean;
4975 WindowOpen: boolean;
4976 AtTop: boolean;
4977 AtBottom: boolean;
4978begin
4979 ViewContentsMI.Checked := ShowLeftPanel and ( Notebook.PageIndex = piContents );
4980 ViewIndexMI.Checked := ShowLeftPanel and ( Notebook.PageIndex = piIndex );
4981 ViewSearchMI.Checked := ShowLeftPanel and ( Notebook.PageIndex = piSearch );
4982 ViewNotesMI.Checked := ShowLeftPanel and ( Notebook.PageIndex = piNotes );
4983
4984 BackEnabled := CurrentHistoryIndex > 0;
4985 ForwardEnabled := CurrentHistoryIndex < PageHistory.Count - 1;
4986
4987 FileOpen := CurrentOpenFiles.Count > 0;
4988 WindowOpen := Windows.Count > 0;
4989
4990 ViewContentsMI.Enabled := FileOpen;
4991 ViewIndexMI.Enabled := FileOpen;
4992 ViewSearchMI.Enabled := FileOpen;
4993 ViewNotesMI.Enabled := FileOpen;
4994
4995 ShowLeftPanelMI.Enabled := FileOpen;
4996
4997 Coolbar.Sections[ ciBack ].Disabled := not BackEnabled;
4998 NavigateBackMI.Enabled := BackEnabled;
4999 Coolbar.Sections[ ciForward ].Disabled := not ForwardEnabled;
5000 NavigateForwardMI.Enabled := ForwardEnabled;
5001
5002 FileSaveAsMI.Enabled := FileOpen;
5003
5004 Coolbar.Sections[ ciPrint ].Disabled := not FileOpen;
5005 PrintMI.Enabled := FileOpen;
5006 FileInformationMI.Enabled := FileOpen;
5007
5008 Coolbar.Sections[ ciAddBookmark ].Disabled := not FileOpen;
5009 AddBookmarkMI.Enabled := FileOpen;
5010 EditBookmarksMI.Enabled := FileOpen;
5011 Coolbar.Sections[ ciAddNote ].Disabled := not FileOpen;
5012 AddNoteMI.Enabled := FileOpen;
5013
5014 if ContentsOutline.SelectedNode <> nil then
5015 begin
5016 AtTop := ContentsOutline.NextNodeUp( ContentsOutline.SelectedNode, false ) = nil;
5017 AtBottom := ContentsOutline.NextNodeDown( ContentsOutline.SelectedNode, false ) = nil;
5018 end;
5019
5020 NavigateNextMI.Enabled := FileOpen
5021 and ( ContentsOutline.SelectedNode <> nil )
5022 and ( not AtBottom );
5023 Coolbar.Sections[ ciNext ].Disabled := not NavigateNextMI.Enabled;
5024 NavigatePreviousMI.Enabled := FileOpen
5025 and ( ContentsOutline.SelectedNode <> nil )
5026 and ( not AtTop );
5027 Coolbar.Sections[ ciPrevious ].Disabled := not NavigatePreviousMI.Enabled;
5028
5029 FileCloseMI.Enabled := FileOpen;
5030
5031 FindMI.Enabled := WindowOpen;
5032 FindNextMI.Enabled := WindowOpen;
5033 CopyMI.Enabled := WindowOpen;
5034 SelectAllMI.Enabled := WindowOpen;
5035
5036 ViewExpandAllMI.Enabled := ContentsOutline.ChildCount > 0;
5037 ViewCollapseAllMI.Enabled := ContentsOutline.ChildCount > 0;
5038
5039 DebugTopicByResourceIDMI.Enabled := FileOpen;
5040 TopicByNameMI.Enabled := FileOpen;
5041
5042 ViewHighlightSearchWordsMI.Enabled := SearchResultsListBox.Items.Count > 0;
5043 if not ViewHighlightSearchWordsMI.Enabled then
5044 ViewHighlightSearchWordsMI.Checked := false;
5045
5046 ViewRefreshMI.Enabled := WindowOpen;
5047
5048 EnableSearchButton;
5049 EnableNotesControls;
5050
5051 VSplitBar.Visible := FileOpen;
5052 if not FileOpen then
5053 begin
5054 SetShowLeftPanel( false );
5055 end;
5056
5057
5058end;
5059
5060Procedure TMainForm.NavigateBackMIOnClick (Sender: TObject);
5061begin
5062 NavigateBack;
5063end;
5064
5065Procedure TMainForm.SaveNavigatePoint;
5066var
5067 NavPoint: TNavigatePoint;
5068begin
5069 // delete rest of history.
5070 while CurrentHistoryIndex < PageHistory.Count - 1 do
5071 begin
5072 NavPoint:= PageHistory.Objects[ CurrentHistoryIndex + 1 ] as TNavigatePoint;
5073 NavPoint.Destroy;
5074 PageHistory.Delete( CurrentHistoryIndex + 1 );
5075 end;
5076
5077 NavPoint:= TNavigatePoint.Create;
5078 SaveWindows( Windows, NavPoint.Windows, nil );
5079
5080 if ContentsOutline.SelectedNode <> nil then
5081 NavPoint.ContentsTopic:= ContentsOutline.SelectedNode.Data as TTopic
5082 else
5083 NavPoint.ContentsTopic:= nil;
5084
5085 if CurrentTopic <> nil then
5086 PageHistory.AddObject( CurrentTopic.Title, NavPoint )
5087 else
5088 PageHistory.AddObject( '', NavPoint );
5089
5090 inc( CurrentHistoryIndex );
5091
5092 CreateNavigateToMenuItems;
5093end;
5094
5095Procedure TMainForm.UpdateCurrentNavigatePoint;
5096var
5097 NavPoint: TNavigatePoint;
5098begin
5099 if CurrentHistoryIndex = -1 then
5100 exit;
5101
5102 NavPoint:= PageHistory.Objects[ CurrentHistoryIndex ] as TNavigatePoint;
5103
5104 DestroyListObjects( NavPoint.Windows );
5105 NavPoint.Windows.Clear;
5106
5107 SaveWindows( Windows, NavPoint.Windows, nil );
5108end;
5109
5110Procedure TMainForm.ClearPageHistory;
5111var
5112 i: longint;
5113 NavPoint: TNavigatePoint;
5114begin
5115 for i := 0 to PageHistory.Count - 1 do
5116 begin
5117 NavPoint := PageHistory.Objects[ i ] as TNavigatePoint;
5118 NavPoint.Destroy;
5119 end;
5120 PageHistory.Clear;
5121 CurrentHistoryIndex := -1;
5122 CreateNavigateToMenuItems;
5123 EnableControls;
5124end;
5125
5126Procedure TMainForm.SaveWindows( SourceList: TList;
5127 DestList: TList;
5128 Parent: TSavedHelpWindow );
5129
5130var
5131 WindowIndex: longint;
5132 Window: THelpWindow;
5133 WindowCopy: TSavedHelpWindow;
5134begin
5135 // limit storage to only what's need since list will be static.
5136 DestList.Capacity := SourceList.Count;
5137 for WindowIndex := 0 to SourceList.Count - 1 do
5138 begin
5139 Window := SourceList[ WindowIndex ];
5140 WindowCopy := TSavedHelpWindow.Create;
5141 WindowCopy.Parent := Parent;
5142 WindowCopy.Rect.Assign( Window.Rect );
5143 WindowCopy.Topic := Window.Topic;
5144 WindowCopy.Group := Window.Group;
5145 WindowCopy.TopCharIndex := Window.View.TopCharIndex;
5146 SaveWindows( Window.ChildWindows, WindowCopy.ChildWindows, WindowCopy );
5147 DestList.Add( WindowCopy );
5148 end;
5149end;
5150
5151Procedure TMainForm.DisplayWindows( WindowList: TList;
5152 Parent: THelpWindow );
5153var
5154 WindowIndex: longint;
5155 WindowCopy: TSavedHelpWindow;
5156 NewWindow: THelpWindow;
5157begin
5158 for WindowIndex := 0 to WindowList.Count - 1 do
5159 begin
5160 WindowCopy := WindowList[ WindowIndex ];
5161 NewWindow := OpenWindow( WindowCopy.Topic,
5162 WindowCopy.Group,
5163 Parent,
5164 WindowCopy.Rect,
5165 false ); // don't follow links
5166 NewWindow.View.TopCharIndex := WindowCopy.TopCharIndex;
5167 DisplayWindows( WindowCopy.ChildWindows, NewWindow );
5168 end;
5169end;
5170
5171Procedure TMainForm.CreateNavigateToMenuItems;
5172var
5173 MenuItem: TMenuItem;
5174 i: integer;
5175begin
5176 // clear existing items
5177 DestroyListObjects( NavigateToMenuItems );
5178 NavigateToMenuItems.Clear;
5179
5180 if CurrentHistoryIndex > 0 then
5181 begin
5182 // We are going to add some items, so
5183 // add a seperator from the rest of the menu first
5184 MenuItem := TMenuItem.Create( self );
5185 MenuItem.Caption:= '-';
5186 NavigateMenu.Add( MenuItem );
5187 NavigateToMenuItems.Add( MenuItem );
5188 end;
5189
5190 i := CurrentHistoryIndex - 1; // don't include the current history item
5191 while ( ( i >= 0 )
5192 and ( i > CurrentHistoryIndex - 10 ) ) do
5193 begin
5194 MenuItem := TMenuItem.Create( self );
5195 MenuItem.Caption := PageHistory[ i ];
5196 MenuItem.Hint := GoBackHint
5197 + StrDoubleQuote( PageHistory[ i ] );
5198 MenuItem.OnClick := OnNavigateToMenuItemClick;
5199 MenuItem.Tag := i;
5200
5201 NavigateMenu.Add( MenuItem );
5202 NavigateToMenuItems.Add( MenuItem );
5203 dec( i );
5204 end;
5205end;
5206
5207Procedure TMainForm.NavigateToPoint( NavPoint: TNavigatePoint );
5208begin
5209 Navigating := true;
5210
5211 // close current windows
5212 CloseWindows;
5213
5214 // Display windows for the navigate point
5215 DisplayWindows( NavPoint.Windows, nil );
5216
5217 // Select the contents topic
5218 ContentsOutline.SetSelectedObject( NavPoint.ContentsTopic );
5219
5220 // Update the navigate menu (since a different set of
5221 // back-points are now available)
5222 CreateNavigateToMenuItems;
5223
5224 // Make the topic windows visible
5225 ShowWindows;
5226
5227 // Update back buttons etc...
5228 EnableControls;
5229
5230 Navigating := false;
5231end;
5232
5233Procedure TMainForm.NavigateToHistoryIndex( Index: longint );
5234var
5235 NavPoint: TNavigatePoint;
5236begin
5237 UpdateCurrentNavigatePoint;
5238 CurrentHistoryIndex := Index;
5239 NavPoint := PageHistory.Objects[ CurrentHistoryIndex ] as TNavigatePoint;
5240 NavigateToPoint( NavPoint );
5241end;
5242
5243Procedure TMainForm.NavigateForward;
5244Begin
5245 if CurrentHistoryIndex < PageHistory.Count - 1 then
5246 begin
5247 NavigateToHistoryIndex( CurrentHistoryIndex + 1 );
5248 end;
5249End;
5250
5251Procedure TMainForm.NavigateBack;
5252Begin
5253 if CurrentHistoryIndex > 0 then
5254 begin
5255 NavigateToHistoryIndex( CurrentHistoryIndex - 1 );
5256 end;
5257End;
5258
5259Procedure TMainForm.NavigatePreviousInContents;
5260begin
5261 ContentsOutline.GotoNextNodeUp;
5262 DisplaySelectedContentsTopic;
5263end;
5264
5265Procedure TMainForm.NavigateNextInContents;
5266begin
5267 ContentsOutline.GotoNextNodeDown;
5268 DisplaySelectedContentsTopic;
5269end;
5270
5271Procedure TMainForm.CorrectNotesPositions( Topic: TTopic;
5272 Text: pchar );
5273var
5274 NoteIndex: longint;
5275 Note: THelpNote;
5276 p: pchar;
5277 NextP: pchar;
5278 Element: TTextElement;
5279 TextIndex: longint;
5280begin
5281 NoteIndex := 0;
5282 for NoteIndex := 0 to Notes.Count - 1 do
5283 begin
5284 Note := Notes[ NoteIndex ];
5285 if Note.Topic = Topic then
5286 begin
5287 // this note belongs the the specified topic.
5288 p := Text;
5289
5290 while true do
5291 begin
5292 Element := ExtractNextTextElement( p, NextP );
5293 if Element.ElementType = teTextEnd then
5294 break;
5295 TextIndex := PCharDiff( p, Text );
5296 if TextIndex >= Note.InsertPoint then
5297 begin
5298 // found a safe point to insert
5299 if TextIndex <> Note.InsertPoint then
5300 begin
5301 // correct it.
5302 Note.InsertPoint := TextIndex;
5303 end;
5304 break;
5305 end;
5306
5307 p := NextP;
5308 end;
5309 end;
5310 end;
5311end;
5312
5313Procedure TMainForm.InsertNotesIntoTopicText( Topic: TTopic;
5314 Text: TAString );
5315var
5316 NoteIndex: longint;
5317 Note: THelpNote;
5318 ActualInsertPoint: longword;
5319begin
5320 CorrectNotesPositions( Topic, Text.AsPChar );
5321
5322 for NoteIndex := 0 to Notes.Count - 1 do
5323 begin
5324 Note := Notes[ NoteIndex ];
5325 if Note.Topic = Topic then
5326 begin
5327 // Adjust insert point for any notes we have already inserted.
5328 ActualInsertPoint := FindActualNoteCharIndex( Note.InsertPoint,
5329 NoteIndex,
5330 Topic );
5331 RefreshNoteInsertInfo( NoteIndex );
5332 Text.Insert( ActualInsertPoint, Note.InsertText );
5333 end;
5334 end;
5335end;
5336
5337Procedure TMainForm.NavigatePreviousMIOnClick (Sender: TObject);
5338Begin
5339 NavigatePreviousInContents;
5340End;
5341
5342Procedure TMainForm.NavigateNextMIOnClick (Sender: TObject);
5343Begin
5344 NavigateNextInContents;
5345End;
5346
5347Function TMainForm.GetActiveWindow: THelpWindow;
5348var
5349 View: TRichTextView;
5350 FirstWindow: THelpWindow;
5351begin
5352 Result := nil;
5353 if Screen.ActiveControl is TRichTextView then
5354 begin
5355 View := Screen.ActiveControl as TRichTextView;
5356 Result := FindWindowFromView( View, Windows );
5357 end
5358 else if Windows.Count = 1 then
5359 begin
5360 FirstWindow := Windows[ 0 ];
5361 if FirstWindow.ChildWindows.Count = 0 then
5362 Result := FirstWindow;
5363 end;
5364end;
5365
5366Procedure TMainForm.CopyMIOnClick (Sender: TObject);
5367var
5368 Window: THelpWindow;
5369begin
5370 if ActiveControl = nil then
5371 exit;
5372
5373 if ActiveControl is TEdit then
5374 begin
5375 // this is for the edit controls in the left panel
5376 TEdit( ActiveControl ).CopyToClipboard;
5377 exit;
5378 end;
5379
5380 // else copy from rtv in active help window
5381
5382 Window := GetActiveWindow;
5383 if Window = nil then
5384 exit;
5385
5386 Window.View.CopySelectionToClipboard;
5387End;
5388
5389Procedure TMainForm.SelectAllMIOnClick (Sender: TObject);
5390var
5391 Window: THelpWindow;
5392begin
5393 Window:= GetActiveWindow;
5394 if Window = nil then
5395 begin
5396 DoErrorDlg( SelectAllTitle,
5397 SelectAllWindowError );
5398 exit;
5399 end;
5400 Window.View.SelectAll;
5401End;
5402
5403Procedure TMainForm.DebugShowCodesMIOnClick (Sender: TObject);
5404Begin
5405 DebugShowCodesMI.Checked:= not DebugShowCodesMI.Checked;
5406 RefreshWindows( Windows );
5407End;
5408
5409Procedure TMainForm.HelpProductInformationMIOnClick (Sender: TObject);
5410Begin
5411 EnsureProductInformationFormLoaded;
5412 ProductInformationForm.ShowModal;
5413End;
5414
5415Procedure TMainForm.OnOverLink ( Sender: TRichTextView; LinkString: String);
5416var
5417 Link: THelpLink;
5418 LinkIndex: longint;
5419 Window: THelpWindow;
5420 LinkedTopic: TTopic;
5421 Filename: string;
5422 SourceFile: THelpFile;
5423 LinkedProgram: string;
5424 URL: string;
5425 LinkDetails: string;
5426Begin
5427 if StrLeft( LinkString, 4 ) = 'note' then
5428 begin
5429 SetStatus( EditNoteMsg )
5430 end
5431 else if StrLeft( LinkString, 7 ) = 'program' then
5432 begin
5433 LinkedProgram := StrRightFrom( LinkString, 9 );
5434 SetStatus( LinkMsg
5435 + LinkedProgram );
5436 end
5437 else if StrLeft( LinkString, 3 ) = 'url' then
5438 begin
5439 URL := StrRightFrom( LinkString, 5 );
5440 SetStatus( LinkMsg
5441 + URL );
5442 end
5443 else if StrLeft( LinkString, 8 ) = 'external' then
5444 begin
5445 LinkDetails := StrRightFrom( LinkString, 10 );
5446 LinkIndex := StrToInt( ExtractNextValue( LinkDetails, ' ' ) );
5447 Window := FindWindowFromView( Sender, Windows );
5448 SourceFile := Window.Topic.HelpFile as THelpFile;
5449 Filename := SourceFile.ReferencedFiles[ LinkIndex ];
5450 SetStatus( LinkMsg
5451 + StrDoubleQuote( Filename ) );
5452 end
5453 else
5454 begin
5455 Window := FindWindowFromView( Sender, Windows );
5456 LinkIndex := StrToInt( LinkString );
5457 Link := Window.Topic.Links[ LinkIndex ];
5458
5459 if Link is TFootnoteHelpLink then
5460 begin
5461 SetStatus( FootnoteMsg );
5462 end
5463 else
5464 begin
5465 LinkedTopic := FindTopicForLink( Link );
5466
5467 if LinkedTopic <> nil then
5468 begin
5469 SetStatus( LinkMsg
5470 + StrDoubleQuote( Trim( LinkedTopic.Title ) ) );
5471 end
5472 else
5473 begin
5474 SetStatus( UnknownLinkMsg );
5475 end;
5476 end;
5477 end;
5478End;
5479
5480Procedure TMainForm.OnNotOverLink ( Sender: TRichTextView; LinkString: String);
5481Begin
5482 SetStatus( '' );
5483end;
5484
5485Procedure TMainForm.OnClickLink ( Sender: TRichTextView; LinkString: String);
5486var
5487 Link: THelpLink;
5488 LinkIndex: longint;
5489 SourceWindow: THelpWindow;
5490 NoteIndex: longint;
5491 Window: THelpWindow;
5492 SourceFile: THelpFile;
5493 ProgramLink: string;
5494 ProgramPath: string;
5495 URL: string;
5496 LinkDetails: string;
5497 ProgramInfo : TSerializableStringList;
5498Begin
5499 if StrLeft( LinkString, 4 ) = 'note' then
5500 begin
5501 NoteIndex := StrToInt( StrRightFrom( LinkString, 5 ) );
5502 NotesListBox.ItemIndex := NoteIndex;
5503 EditNote( NoteIndex );
5504 end
5505 else if StrLeft( LinkString, 7 ) = 'program' then
5506 begin
5507 ProgramInfo := TSerializableStringList.create;
5508 ProgramInfo.readValuesFromSerializedString(StrRightFrom( LinkString, 9 ));
5509 ProgramPath := ProgramInfo.get(0);
5510 ProgramLink := ProgramInfo.get(1);
5511 TSerializableStringList.destroy;
5512 // call LaunchProgram here to inherit the environment
5513 LaunchProgram(ProgramPath, ProgramLink, '');
5514 SetStatus( 'Launched ' + ProgramPath );
5515 end
5516 else if StrLeft( LinkString, 3 ) = 'url' then
5517 begin
5518 URL := StrRightFrom( LinkString, 5 );
5519 LaunchURL( URL );
5520 SetStatus( 'Opened '
5521 + URL );
5522 end
5523 else if StrLeft( LinkString, 8 ) = 'external' then
5524 begin
5525 LinkDetails := StrRightFrom( LinkString, 10 );
5526 LinkIndex := StrToInt( ExtractNextValue( LinkDetails, ' ' ) );
5527 Window := FindWindowFromView( Sender, Windows );
5528 SourceFile := Window.Topic.HelpFile as THelpFile;
5529
5530 g_ExternalLinkFileName := SourceFile.ReferencedFiles[ LinkIndex ];
5531 g_ExternalLinkTopic := LinkDetails;
5532 g_ExternalLinkSourceFilename := SourceFile.Filename;
5533 g_ExternalLinkKeepCurrent := true; // hm... what would be nice?
5534
5535 PostMsg( Self.Handle,
5536 WM_FOLLOWEXTERNALLINK,
5537 0,
5538 0 );
5539 end
5540 else
5541 begin
5542 SourceWindow := FindWindowFromView( Sender, Windows );
5543 LinkIndex := StrToInt( LinkString );
5544 Link := SourceWindow.Topic.Links[ LinkIndex ];
5545
5546 PostMsg( Self.Handle,
5547 WM_FOLLOWLINK,
5548 longint( Link ),
5549 longint( SourceWindow ) );
5550
5551 end;
5552End;
5553
5554Procedure TMainForm.OnWindowAboutToClose( Window: THelpWindow;
5555 var CanClose: boolean );
5556begin
5557 if Navigating then
5558 exit;
5559
5560 UpdateCurrentNavigatePoint; // Save it before close...
5561
5562 CanClose := true;
5563end;
5564
5565Procedure TMainForm.RemoveHelpWindowFromParent( Window: THelpWindow );
5566var
5567 ParentWindow: THelpWindow;
5568 WindowIndex: longint;
5569Begin
5570 if Navigating then
5571 exit;
5572
5573 if Window.ParentHelpWindow = nil then
5574 begin
5575 WindowIndex := Windows.IndexOf( Window );
5576 Windows.Delete( WindowIndex );
5577 end
5578 else
5579 begin
5580 ParentWindow := Window.ParentHelpWindow;
5581 WindowIndex := ParentWindow.ChildWindows.IndexOf( Window );
5582 ParentWindow.ChildWindows.Delete( WindowIndex );
5583 end;
5584end;
5585
5586Procedure TMainForm.OnWindowClose( Window: THelpWindow );
5587Begin
5588 if Navigating then
5589 exit;
5590
5591 RemoveHelpWindowFromParent( Window );
5592
5593 SaveNavigatePoint;
5594 EnableControls;
5595End;
5596
5597Procedure TMainForm.BackButtonOnClick (Sender: TObject);
5598Begin
5599 NavigateBack;
5600End;
5601
5602Procedure TMainForm.RTViewOnSetupShow (Sender: TObject);
5603Begin
5604End;
5605
5606Procedure TMainForm.ExitMIOnClick (Sender: TObject);
5607Begin
5608 Close;
5609End;
5610
5611Procedure TMainForm.CreateMRUMenuItems;
5612var
5613 MenuItem: TMenuItem;
5614 i: integer;
5615 FileName: string;
5616 FileNameIndex: longint;
5617 MRUText: string;
5618 MRUItem: TMRUItem;
5619begin
5620 DestroyListObjects( MRUMenuItems );
5621 MRUMenuItems.Clear;
5622
5623 // if there are Most Recently Used files
5624 if Settings.MRUList.Count > 0 then
5625 begin
5626 // create a seperator after Exit
5627 MenuItem:= TMenuItem.Create( self );
5628 MenuItem.Name := 'MRUSeparatorMI';
5629 MenuItem.Caption:= '-';
5630 FileMenu.Add( MenuItem );
5631 MRUMenuItems.Add( MenuItem );
5632 end;
5633
5634 // Add items for the MRU files
5635 for i:= 0 to Settings.MRUList.Count -1 do
5636 begin
5637 MRUItem := Settings.MRUList[ i ];
5638
5639 MenuItem := TMenuItem.Create( self );
5640
5641 MenuItem.Name := 'MRUItem' + IntToStr( i ) + 'MI';
5642 MRUText := MRUItem.Title;
5643 if Trim( MRUText ) = '' then
5644 begin
5645 // Take the filenames, less path, as caption...
5646 MRUText := '';
5647 for FileNameIndex := 0 to MRUItem.Filenames.Count - 1 do
5648 begin
5649 FileName := MRUItem.Filenames[ FileNameIndex ];
5650 FileName := ExtractFileName( FileName );
5651 FileName := ChangeFileExt( FileName, '' );// remove extension
5652 AddToListString( MRUText,
5653 FileName,
5654 '+' );
5655
5656 // stop after 50 chars
5657 if Length( MRUText ) > 50 then
5658 begin
5659 MRUText := MRUText + '+ ...';
5660 break;
5661 end;
5662 end;
5663 end;
5664
5665 MenuItem.Caption:= '~'
5666 + IntToStr( i + 1 )
5667 + '. '
5668 + MRUText;
5669 if MRUItem.Filenames.Count = 1 then
5670 MenuItem.Hint := MRUItem.Filenames[ 0 ]
5671 else
5672 MenuItem.Hint := MRUItem.Title
5673 + ' ('
5674 + IntToStr( MRUItem.Filenames.Count )
5675 + ' '
5676 + MRUMultipleFilesHint
5677 + ')';
5678
5679 MenuItem.OnClick:= OnMRUMenuItemClick;
5680 MenuItem.Tag:= i;
5681 FileMenu.Add( MenuItem );
5682 MRUMenuItems.Add( MenuItem );
5683 end;
5684end;
5685
5686procedure TMainForm.OnMRUMenuItemClick( Sender: TObject );
5687var
5688 Tag: longint;
5689 MenuItem: TMenuItem;
5690 MRUItem: TMRUItem;
5691begin
5692 MenuItem:= Sender as TMenuItem;
5693 Tag:= MenuItem.Tag;
5694 MRUItem := Settings.MRUList[ Tag ];
5695 if OpenFiles( MRUItem.FileNames, '', true ) then
5696 begin
5697 ClearHelpManager;
5698 end;
5699end;
5700
5701Procedure TMainForm.OnNavigateToMenuItemClick( Sender: TObject );
5702var
5703 MenuItem: TMenuItem;
5704 Tag: longint;
5705begin
5706 MenuItem:= Sender as TMenuItem;
5707 Tag:= MenuItem.Tag;
5708 NavigateToHistoryIndex( Tag );
5709end;
5710
5711Procedure TMainForm.AddChildNodes( HelpFile: THelpFile;
5712 ParentNode: TNode;
5713 Level: longint;
5714 Var TopicIndex: longint );
5715var
5716 Topic: TTopic;
5717 Node: TNode;
5718begin
5719 assert( ParentNode <> nil );
5720 Node := nil;
5721 while TopicIndex < HelpFile.TopicCount do
5722 begin
5723 Topic:= HelpFile.Topics[ TopicIndex ];
5724
5725 if Topic.ShowInContents then
5726 begin
5727 if Topic.ContentsLevel < Level then
5728 break;
5729
5730 if Topic.ContentsLevel = Level then
5731 begin
5732 Node:= ParentNode.AddChild( Topic.Title,
5733 Topic );
5734 inc( TopicIndex );
5735 end
5736 else
5737 begin
5738 assert( Node <> nil );
5739 AddChildNodes( HelpFile,
5740 Node,
5741 Topic.ContentsLevel,
5742 TopicIndex );
5743 Node := nil;
5744 end
5745 end
5746 else
5747 begin
5748 inc( TopicIndex );
5749 end;
5750 end;
5751
5752end;
5753
5754Procedure TMainForm.LoadContents( Files: TList;
5755 Var FirstNode: TNode );
5756var
5757 TopicIndex: longint;
5758 Topic: TTopic;
5759 Node: TNode;
5760 FileIndex: longint;
5761 HelpFile: THelpFile;
5762begin
5763 ContentsOutline.BeginUpdate;
5764 LogEvent(LogStartup, 'Load contents outline');
5765
5766 // we don't clear it first, to allow adding additional files
5767 // into the contents tree
5768
5769 LogEvent(LogStartup, 'Loop files');
5770
5771 FirstNode := nil;
5772
5773 Node := nil;
5774
5775 for FileIndex:= 0 to Files.Count - 1 do
5776 begin
5777 HelpFile := Files[ FileIndex ];
5778 LogEvent(LogStartup, 'File ' + IntToStr( FileIndex ) );
5779 TopicIndex := 0;
5780 while TopicIndex < HelpFile.TopicCount do
5781 begin
5782 Topic := HelpFile.Topics[ TopicIndex ];
5783 assert( Topic.ContentsLevel >= 0,
5784 'Topic contents level is ' + IntToStr( Topic.ContentsLevel ) );
5785 if Topic.ShowInContents then
5786 begin
5787 if Topic.ContentsLevel = 1 then
5788 begin
5789 Node := ContentsOutline.AddChild( Topic.Title,
5790 Topic );
5791 if FirstNode = nil then
5792 FirstNode := node;
5793
5794 inc( TopicIndex );
5795 end
5796 else
5797 begin
5798 // subnodes
5799 assert( Node <> nil, 'No level 1 topic for subnodes!' );
5800 AddChildNodes( HelpFile,
5801 Node,
5802 Topic.ContentsLevel,
5803 TopicIndex );
5804 Node := nil;
5805 end;
5806 end
5807 else
5808 begin
5809 inc( TopicIndex );
5810 end;
5811 end;
5812 end;
5813 LogEvent(LogStartup, ' EndUpdate' );
5814 ContentsOutline.EndUpdate;
5815
5816 if Settings.OpenWithExpandedContents then
5817 begin
5818 LogEvent(LogStartup, ' Expand all contents' );
5819 ContentsOutline.ExpandAll
5820 end
5821 else if ContentsOutline.ChildCount = 1 then
5822 begin
5823 LogEvent(LogStartup, ' Expand first node' );
5824 // Contents has only one top level node... expand it
5825 FirstNode.Expand;
5826 end;
5827
5828 ContentsLoaded := true;
5829 LogEvent(LogStartup, ' Contents loaded' );
5830
5831end;
5832
5833Procedure TMainForm.SaveNotesForFile( HelpFile: THelpFile );
5834var
5835 NotesFileName: string;
5836 TopicIndex: longword;
5837 Note: THelpNote;
5838 NoteIndex: longint;
5839
5840 NotesFile: HFile;
5841 OpenAction: ULong;
5842 rc: APIRET;
5843 CName: Cstring;
5844 FileNoteCount: integer;
5845
5846begin
5847 LogEvent(LogStartup, 'Save notes for ' + HelpFile.Filename );
5848
5849 if not HelpFile.NotesLoaded then
5850 // we never loaded the notes/displayed a topic from this file
5851 // so don't do anything.
5852 exit;
5853
5854 LogEvent(LogStartup, 'Really saving' );
5855
5856 NotesFileName := ChangeFileExt( HelpFile.FileName, '.nte' );
5857
5858 FileNoteCount := 0;
5859 for NoteIndex := 0 to Notes.Count - 1 do
5860 begin
5861 Note := Notes[ NoteIndex ];
5862
5863 if Note.Topic.HelpFile = HelpFile then
5864 inc( FileNoteCount );
5865 end;
5866
5867 if FileNoteCount = 0 then
5868 begin
5869 // no notes. delete notes file if it already exists.
5870 if FileExists( NotesFileName ) then
5871 DeleteFile( NotesFileName );
5872 exit;
5873 end;
5874
5875 CName:= NotesFileName;
5876 rc:= DosOpen( CName,
5877 NotesFile,
5878 OpenAction,
5879 0, // file size
5880 0, // attrs
5881 OPEN_ACTION_CREATE_IF_NEW + OPEN_ACTION_REPLACE_IF_EXISTS,
5882 OPEN_SHARE_DENYREADWRITE + OPEN_ACCESS_WRITEONLY,
5883 nil ); // no eas
5884 if rc <> 0 then
5885 begin
5886 DoErrorDlg( SaveNotesTitle,
5887 SaveNotesError
5888 + EndLine
5889 + NotesFileName
5890 + EndLine
5891 + SysErrorMessage( rc ) );
5892 exit;
5893 end;
5894
5895 for NoteIndex:= 0 to Notes.Count - 1 do
5896 begin
5897 Note:= Notes[ NoteIndex ];
5898
5899 if Note.Topic.HelpFile <> HelpFile then
5900 continue;
5901
5902 TopicIndex:= HelpFile.IndexOfTopic( Note.Topic );
5903
5904 MyWriteLn( NotesFile,
5905 IntToStr( TopicIndex ));
5906 MyWriteLn( NotesFile,
5907 IntToStr( Note.InsertPoint ) );
5908
5909 MyWrite( NotesFile,
5910 Note.Text.AsPChar,
5911 Note.Text.Length );
5912
5913 MyWriteLn( NotesFile,
5914 '' );
5915 MyWriteLn( NotesFile,
5916 '#ENDNOTE#' );
5917
5918 end;
5919
5920 DosClose( NotesFile );
5921end;
5922
5923Procedure TMainForm.LoadNotes( HelpFile: THelpFile );
5924var
5925 NotesFileName: string;
5926 TopicIndex: longint;
5927 InsertPoint: longint;
5928 Note: THelpNote;
5929
5930 NotesFile: HFile;
5931 OpenAction: ULong;
5932 rc: APIRET;
5933 CName: Cstring;
5934
5935 Paragraph: TAString;
5936 NotEOF: boolean;
5937 NoteText: TAString;
5938
5939begin
5940 LogEvent(LogStartup, 'Load notes for ' + HelpFile.Filename );
5941
5942 if HelpFile.NotesLoaded then
5943 exit;
5944
5945 HelpFile.NotesLoaded := true;
5946 NotesFileName := ChangeFileExt( HelpFile.FileName, '.nte' );
5947
5948 if not FileExists( NotesFileName ) then
5949 // no notes
5950 exit;
5951
5952 CName := NotesFileName;
5953 rc := DosOpen( CName,
5954 NotesFile,
5955 OpenAction,
5956 0, // file size - irrelevant, not creating,
5957 0, // attrs - ''
5958 OPEN_ACTION_OPEN_IF_EXISTS,
5959 OPEN_SHARE_DENYREADWRITE + OPEN_ACCESS_READONLY,
5960 nil ); // no eas
5961 if rc <> 0 then
5962 begin
5963 DoErrorDlg( LoadNotesTitle,
5964 LoadNotesError
5965 + EndLine
5966 + NotesFileName
5967 + EndLine
5968 + SysErrorMessage( rc ) );
5969 exit;
5970 end;
5971
5972 Paragraph := TAString.Create;
5973 NoteText := TAString.Create;
5974
5975 NotEOF := true;
5976
5977 while NotEOF do
5978 begin
5979 // Read contents index
5980 NotEOF := Paragraph.ReadParagraph( NotesFile );
5981 if not NotEOF then
5982 continue;
5983 try
5984 TopicIndex := StrToInt( Paragraph.AsString );
5985 except
5986 TopicIndex := -1;
5987 end;
5988
5989 // Read insert point
5990 NotEOF := Paragraph.ReadParagraph( NotesFile );
5991 if not NotEOF then
5992 continue;
5993 try
5994 InsertPoint := StrToInt( Paragraph.AsString );
5995 except
5996 InsertPoint := -1;
5997 end;
5998
5999 NoteText.Clear;
6000
6001 while NotEOF do
6002 begin
6003 NotEOF := Paragraph.ReadParagraph( NotesFile );
6004 if Paragraph.SameAs( '#ENDNOTE#' ) then
6005 begin
6006 // found end of note
6007 if ( TopicIndex >= 0 )
6008 and ( InsertPoint >= 0 ) then
6009 begin
6010 Note := THelpNote.Create;
6011 Note.Topic := HelpFile.Topics[ TopicIndex ];
6012 Note.InsertPoint := InsertPoint;
6013
6014 // Remove the last end line
6015 Note.Text.Assign( NoteText );
6016 if Note.Text.Length > 2 then
6017 Note.Text.Delete( Note.Text.Length - 2, 2 );
6018
6019 Notes.Add( Note );
6020 end;
6021 break;
6022 end;
6023 NoteText.Add( Paragraph );
6024 NoteText.AddString( #13 + #10 );
6025 end;
6026
6027 end;
6028 DosClose( NotesFile );
6029
6030 Paragraph.Destroy;
6031 NoteText.Destroy;
6032
6033end;
6034
6035Procedure TMainForm.UpdateNotesDisplay;
6036var
6037 NoteIndex: longint;
6038 Note: THelpNote;
6039 NoteTitle: string;
6040begin
6041 NotesListBox.Clear;
6042 for NoteIndex := 0 to Notes.Count - 1 do
6043 begin
6044 Note := Notes[ NoteIndex ];
6045
6046 if Note.Topic > nil then
6047 NoteTitle := Note.Topic.Title
6048 else
6049 NoteTitle := StrLeft( Note.Text.AsString, 100 );
6050 NotesListBox.Items.AddObject( NoteTitle,
6051 Note );
6052 end;
6053 EnableNotesControls;
6054end;
6055
6056Procedure TMainForm.EnableNotesControls;
6057var
6058 NoteSelected: boolean;
6059begin
6060 NoteSelected:= NotesListBox.ItemIndex <> -1;
6061 EditNoteButton.Enabled:= NoteSelected;
6062 GotoNoteButton.Enabled:= NoteSelected;
6063 DeleteNoteButton.Enabled:= NoteSelected;
6064 AddNoteButton.Enabled := CurrentOpenFiles.Count > 0;
6065end;
6066
6067Function TMainForm.OKToCloseFile: boolean;
6068begin
6069 Result := true;
6070
6071 if PrintThread = nil then
6072 // haven't used print thread yet
6073 exit;
6074
6075 if not PrintThread.IsRunning then
6076 // not currently running
6077 exit;
6078
6079 Result := DoConfirmDlg( CheckStopPrintTitle,
6080 CheckStopPrintMsg );
6081
6082end;
6083
6084Procedure TMainForm.StopPrinting;
6085begin
6086 if PrintThread <> nil then
6087 begin
6088 if PrintThread.IsRunning then
6089 begin
6090 SetStatus( StoppingPrintMsg );
6091 PrintThread.ForceStop( 5 ); // wait up to 5 seconds then terminate
6092 SetStatus( PrintStoppedMsg );
6093 ResetProgress;
6094 end;
6095 end;
6096end;
6097
6098Procedure TMainForm.CloseFile;
6099var
6100 FileIndex: longint;
6101 HelpFile: THelpFile;
6102 M1: longint;
6103begin
6104 StopPrinting;
6105
6106 LogEvent(LogShutdown, 'Set Caption' );
6107 MainTitle := '';
6108 SetMainCaption;
6109
6110 LogEvent(LogShutdown, 'Close Windows' );
6111 CloseWindows;
6112
6113 LogEvent(LogShutdown, 'Set selected node to nil' );
6114 ContentsOutline.SelectedNode:= Nil;
6115
6116 M1:= MemAvail;
6117
6118 LogEvent(LogShutdown, 'Clear contents outline' );
6119 ContentsOutline.Clear;
6120
6121 LogEvent(LogShutdown, 'Free contents: ' + IntToStr( MemAvail - M1 ) );
6122 M1:= MemAvail;
6123
6124 DisplayedIndex.Clear;
6125 IndexListBox.Clear;
6126 LogEvent(LogShutdown, 'Clear index ' + IntToStr( MemAvail - M1 ) );
6127 M1:= MemAvail;
6128
6129 NotesListBox.Clear;
6130 SearchResultsListBox.Clear;
6131
6132 LogEvent(LogShutdown, 'Notes, search etc ' + IntToStr( MemAvail - M1 ) );
6133 M1:= MemAvail;
6134
6135 // First save notes and bookmarks.
6136 // It's important we do this first
6137 // since we scan all notes each time to find the ones
6138 // belonging to this file.
6139 SaveBookmarks;
6140
6141 SaveNotes;
6142
6143 ClearAllWordSequences;
6144
6145 LogEvent(LogShutdown, 'Destroy helpfile objects' );
6146
6147 // Now destroy help files
6148 for FileIndex := 0 to CurrentOpenFiles.Count - 1 do
6149 begin
6150 HelpFile := CurrentOpenFiles[ FileIndex ];
6151 GlobalFilelist.RemoveFile( Frame.Handle,
6152 HelpFile.Filename );
6153 HelpFile.Free;
6154 end;
6155
6156 CurrentOpenFiles.Clear;
6157
6158 LogEvent(LogShutdown, 'Destroy helpfiles ' + IntToStr( MemAvail - M1 ) );
6159 M1 := MemAvail;
6160
6161 LogEvent(LogShutdown, 'Clear notes' );
6162 ClearNotes;
6163
6164 LogEvent(LogShutdown, 'Clear bookmarks' );
6165 ClearBookmarks;
6166
6167 ClearPageHistory;
6168
6169 LogEvent(LogShutdown, 'Enable controls' );
6170 EnableControls;
6171
6172 LogEvent(LogShutdown, 'CloseFile done' );
6173
6174end;
6175
6176Function TMainForm.FindOpenHelpFile( FileName: string ): THelpFile;
6177var
6178 FileIndex: longint;
6179begin
6180 for FileIndex:= 0 to CurrentOpenFiles.Count - 1 do
6181 begin
6182 Result:= CurrentOpenFiles[ FileIndex ];
6183 if StringsSame( Result.Filename, FileName ) then
6184 // found
6185 exit;
6186 end;
6187 Result:= nil;
6188end;
6189
6190// This rather horrendous looking bit of code simply:
6191
6192// Gets the contents from each file
6193// Sorts it alphabetically.
6194// Merges all the sorted contents and indexes together,
6195// alphabetically.
6196type
6197 TListType = ( ltContents, ltIndex );
6198
6199procedure TMainForm.LoadIndex;
6200var
6201 HelpFile: THelpFile;
6202 TextCompareResult: integer;
6203
6204 FileIndex: longint;
6205
6206 Contents: TList;
6207 ContentsLists: TList; // of tlist
6208 IndexLists: TList; // of tstringlist
6209 ContentsNextIndex: array[ 0..255 ] of longint;
6210 IndexNextIndex: array[ 0..255 ] of longint;
6211 Topic: TTopic;
6212
6213 ListIndex: longint;
6214
6215 pListEntry: pstring;
6216 pLowestEntry: pstring;
6217 pLastEntry: pstring;
6218
6219 LowestEntryListIndex: longint;
6220 LowestEntryListType: TListType;
6221 LowestEntryTopic: TTopic;
6222
6223 Index: TStringList;
6224
6225 i : longint;
6226begin
6227 LogEvent(LogStartup, 'Create index' );
6228
6229 SetWaitCursor;
6230
6231 LogEvent(LogStartup, ' Get/sort lists' );
6232
6233 ProgressBar.Position := 70;
6234 SetStatus( 'Building index... ' );
6235
6236 ContentsLists := TList.Create;
6237 IndexLists := TList.Create;
6238
6239 // collect the contents and index lists from the files
6240 for FileIndex := 0 to CurrentOpenFiles.Count - 1 do
6241 begin
6242 HelpFile := CurrentOpenFiles[ FileIndex ];
6243 ProgressBar.Position := 70 + 10 * FileIndex div CurrentOpenFiles.Count;
6244
6245 if Settings.IndexStyle in [ isAlphabetical, isFull ] then
6246 begin
6247 Contents := TList.Create;
6248 Contents.Capacity := HelpFile.TopicCount;
6249
6250 // copy [contents] topic list
6251 for i := 0 to HelpFile.TopicCount - 1 do
6252 begin
6253 Topic := HelpFile.Topics[ i ];
6254 if Topic.ShowInContents then
6255 Contents.Add( Topic );
6256 end;
6257
6258 // sort by title
6259 Contents.Sort( TopicTitleCompare );
6260
6261 ContentsLists.Add( Contents );
6262
6263 // initialise list index
6264 ContentsNextIndex[ ContentsLists.Count - 1 ] := 0;
6265 end;
6266
6267 if Settings.IndexStyle in [ isFileOnly, isFull ] then
6268 begin
6269 IndexLists.Add( HelpFile.Index );
6270 IndexNextIndex[ IndexLists.Count - 1 ] := 0;
6271 end;
6272 end;
6273
6274 // Unlike contents, we do clear the index
6275 // (even if we are adding more files) because we need
6276 // to re-merge the whole thing
6277 DisplayedIndex.Clear;
6278 ProgressBar.Position := 80;
6279
6280 LogEvent(LogStartup, ' Merge lists' );
6281
6282 pLastEntry := NullStr;
6283 while true do
6284 begin
6285 pLowestEntry := NullStr;
6286 LowestEntryListIndex := -1;
6287
6288 // Find alphabetically lowest (remaining) topic
6289
6290 // first, look in contents lists
6291 for ListIndex := 0 to ContentsLists.Count - 1 do
6292 begin
6293 Contents := ContentsLists[ ListIndex ];
6294 if ContentsNextIndex[ ListIndex ] < Contents.Count then
6295 begin
6296 // list is not yet finished, get next entry
6297 Topic := Contents[ ContentsNextIndex[ ListIndex ] ];
6298 pListEntry := Topic.TitlePtr;
6299
6300 if pLowestEntry^ <> '' then
6301 TextCompareResult := CompareText( pListEntry^, pLowestEntry^ )
6302 else
6303 TextCompareResult := -1;
6304
6305 if TextCompareResult < 0 then
6306 begin
6307 // this index entry comes before the lowest one so far
6308 pLowestEntry := pListEntry;
6309 LowestEntryListIndex := ListIndex;
6310 LowestEntryListType := ltContents;
6311 LowestEntryTopic := Topic;
6312 end;
6313 end;
6314 end;
6315
6316 // look in indices
6317 for ListIndex := 0 to IndexLists.Count - 1 do
6318 begin
6319 Index := IndexLists[ ListIndex ];
6320 if IndexNextIndex[ ListIndex ] < Index.Count then
6321 begin
6322 // list is not yet finished, get next entry
6323 pListEntry := Index.ValuePtrs[ IndexNextIndex[ ListIndex ] ];
6324
6325 if pLowestEntry^ <> '' then
6326 TextCompareResult := CompareText( pListEntry^, pLowestEntry^ )
6327 else
6328 TextCompareResult := -1;
6329
6330 if TextCompareResult < 0 then
6331 begin
6332 // this index entry comes before the lowest one so far
6333 pLowestEntry := pListEntry;
6334 LowestEntryListIndex := ListIndex;
6335 LowestEntryListType := ltIndex;
6336 LowestEntryTopic := TTopic( Index.Objects[ IndexNextIndex[ ListIndex ] ] );
6337 end;
6338 end;
6339 end;
6340
6341 if LowestEntryListIndex = -1 then
6342 // we're out
6343 break;
6344
6345 if ( pLowestEntry^ ) <> ( pLastEntry^ ) then
6346 // add, if different from last
6347 DisplayedIndex.AddObject( pLowestEntry^,
6348 LowestEntryTopic );
6349 pLastEntry := pLowestEntry;
6350
6351 if LowestEntryListType = ltContents then
6352 begin
6353 inc( ContentsNextIndex[ LowestEntryListIndex ] );
6354 end
6355 else
6356 begin
6357 // found in one of indices.
6358 // Check for subsequent indented strings
6359 Index := IndexLists[ LowestEntryListIndex ];
6360
6361 i := IndexNextIndex[ LowestEntryListIndex ] + 1;
6362 while i < Index.Count do
6363 begin
6364 pListEntry := Index.ValuePtrs[ i ];
6365 if pListEntry^ = '' then
6366 break;
6367
6368 if pListEntry^[ 1 ] <> ' ' then
6369 // not indented, stop looking
6370 break;
6371
6372 // found one,
6373 Topic := Index.Objects[ i ] as TTopic;
6374 DisplayedIndex.AddObject( pListEntry^,
6375 Topic );
6376 inc( i );
6377 end;
6378 IndexNextIndex[ LowestEntryListIndex ] := i;
6379 end;
6380 end;
6381
6382 ProgressBar.Position := 95;
6383 LogEvent(LogStartup, ' Display index (count = '
6384 + IntToStr( DisplayedIndex.Count )
6385 + ')' );
6386
6387 // Now display the final index list
6388 IndexListBox.Items.Assign( DisplayedIndex );
6389
6390 LogEvent(LogStartup, ' Tidy up' );
6391
6392 IndexLists.Destroy;
6393
6394 DestroyListAndObjects( ContentsLists );
6395
6396 IndexLoaded := true;
6397
6398 ClearWaitCursor;
6399
6400 SetStatus( 'Index loaded' );
6401 LogEvent(LogStartup, ' Done' );
6402end;
6403
6404Procedure TMainForm.OnHelpFileLoadProgress( n, outof: integer;
6405 message: string );
6406var
6407 ProgressOnFiles: longint;
6408 Filename: string;
6409 ProgressOnThisFile: longint;
6410
6411begin
6412 Filename := LoadingFilenameList[ LoadingFileIndex ];
6413
6414 ProgressOnFiles := round( 100 * LoadingFileIndex / LoadingFilenameList.Count );
6415 ProgressOnThisFile := round( 100 * n / outof / LoadingFilenameList.Count );
6416
6417 SetProgress( ( ProgressOnFiles + ProgressOnThisFile ) div 2,
6418 100,
6419 LoadingFileMsg
6420 + ExtractFileName( Filename )
6421 + ': '
6422 + message );
6423end;
6424
6425Procedure TMainForm.SetProgress( n, outof: integer;
6426 message: string );
6427begin
6428 ProgressBar.Position := n * 100 div outof;
6429 SetStatus( message );
6430 ProgressBar.Show;
6431end;
6432
6433// Load a single file.
6434Function TMainForm.OpenFile( const FileName: string;
6435 const WindowTitle: string;
6436 const SelectFirstContentsNode: boolean ): boolean;
6437var
6438 FileNames: TStringList;
6439begin
6440 FileNames := TStringList.Create;
6441 FileNames.Add( FileName );
6442 Result := OpenFiles( FileNames,
6443 WindowTitle,
6444 DisplayFirstTopic );
6445 FileNames.Destroy;
6446end;
6447
6448Function TMainForm.OpenAdditionalFile( const FileName: string;
6449 const DisplayFirstTopic: boolean ): boolean;
6450var
6451 FileNames: TStringList;
6452begin
6453 FileNames := TStringList.Create;
6454 FileNames.Add( FileName );
6455 Result := OpenAdditionalFiles( FileNames,
6456 DisplayFirstTopic );
6457 FileNames.Destroy;
6458end;
6459
6460Function TMainForm.OpenWindowsHelp( const Filename: string ): boolean;
6461var
6462 WinHelpDetails: PROGDETAILS;
6463 szFilename: cstring;
6464begin
6465
6466 result := true;
6467 if Settings.ConfirmWinHelp then
6468 result := DoYesNoDlg( WindowsHelpTitle,
6469 WindowsHelpPrompt
6470 + EndLine
6471 + FileName );
6472 if not result then
6473 exit;
6474
6475 szFilename := FileName;
6476 with WinHelpDetails do
6477 begin
6478 Length := sizeof( WinHelpDetails );
6479 progt.progc := PROG_31_ENHSEAMLESSCOMMON ;
6480 progt.fbVisible := SHE_VISIBLE;
6481 pszTitle := ''; // not used?
6482 pszExecutable := 'winhelp.exe';
6483 pszParameters := Addr( szFilename );
6484 pszStartupDir := nil;
6485 pszIcon := nil;
6486 pszEnvironment := nil;
6487 swpInitial.fl := SWP_ACTIVATE or SWP_SHOW;
6488 end;
6489
6490 result := WinStartApp( NULLHANDLE,
6491 WinHelpDetails,
6492 '',
6493 nil,
6494 SAF_INSTALLEDCMDLINE ) <> 0;
6495
6496 // Doesn't work for Dos/Win programs
6497 // RunProgram( 'winhelp.exe', FileName );
6498end;
6499
6500// Load the specified set of help files
6501Function TMainForm.LoadFiles( const FileNames: TStrings;
6502 HelpFiles: TList ): boolean;
6503var
6504 HelpFile: THelpFile;
6505 FileIndex: longint;
6506 FileName: string;
6507 FullFilePath: string;
6508
6509 FileHandlesAdjustNum: LONG;
6510 CurrentMaxFileHandles: ULONG;
6511 RequiredFileHandles: LONG;
6512begin
6513 LogEvent(LogStartup, 'LoadFiles' );
6514
6515 LoadingFilenameList := TStringList.Create;
6516
6517 TranslateIPFEnvironmentVars( FileNames, LoadingFilenameList );
6518
6519 LogEvent(LogStartup, 'Finding files' );
6520
6521 ProgressBar.Show;
6522
6523 // now find full file paths,
6524 // and also the total file size for progress display
6525 for FileIndex := 0 to LoadingFilenameList.Count - 1 do
6526 begin
6527 FileName := LoadingFilenameList[ FileIndex ];
6528 LogEvent(LogStartup, ' File: ' + FileName );
6529
6530 // Find the help file, if possible
6531 FullFilePath := FindHelpFile( Filename );
6532 if FullFilePath <> '' then
6533 begin
6534 LogEvent(LogStartup, ' Full path: ' + FullFilePath );
6535 end
6536 else
6537 begin
6538 LogEvent(LogStartup, ' File not found' );
6539 FullFilePath := FileName; // we'll complain later.
6540 end;
6541 LoadingFilenameList[ FileIndex ] := FullFilePath;
6542 end;
6543
6544 // Make sure we have enough file handles
6545
6546 FileHandlesAdjustNum := 0;
6547 DosSetRelMaxFH( FileHandlesAdjustNum, // 0 queries current
6548 CurrentMaxFileHandles );
6549
6550 RequiredFileHandles := CurrentOpenFiles.Count // already opened
6551 + LoadingFilenameList.Count // new ones
6552 + 40; // some spares.
6553 if CurrentMaxFileHandles < RequiredFileHandles then
6554 begin
6555 // need some more
6556 FileHandlesAdjustNum := RequiredFileHandles - CurrentMaxFileHandles;
6557 DosSetRelMaxFH( FileHandlesAdjustNum,
6558 CurrentMaxFileHandles );
6559 end;
6560
6561 // Now actually load the files
6562 for FileIndex := 0 to LoadingFilenameList.Count - 1 do
6563 begin
6564 Filename := LoadingFilenameList[ FileIndex ];
6565 LogEvent(LogStartup, ' Loading: ' + Filename );
6566 try
6567 LoadingFileIndex := FileIndex;
6568
6569 // load the file
6570 HelpFile := THelpFile.Create( FileName );
6571 if Settings.FixedFontSubstitution then
6572 HelpFile.SetupFontSubstitutes( Settings.FixedFontSubstitutes );
6573
6574 HelpFiles.Add( HelpFile );
6575
6576 except
6577 on E: Exception do
6578 begin
6579
6580 if E is EWindowsHelpFormatException then
6581 begin
6582 OpenWindowsHelp( Filename );
6583 end
6584 else
6585 begin
6586 DoErrorDlg( FileOpenTitle,
6587 HelpFileError
6588 + FileName
6589 + ': '
6590 + E.Message );
6591 end;
6592
6593 // back out of the load process
6594 Result := false;
6595
6596 DestroyListObjects( HelpFiles );
6597
6598 LoadingFilenameList.Destroy;
6599 ResetProgress;
6600 exit;
6601 end
6602 end;
6603 end;
6604
6605 LoadingFilenameList.Destroy;
6606
6607 Result := true;
6608
6609end;
6610
6611// Add the current list of open files as
6612// a Most Recently Used entry
6613Procedure TMainForm.AddCurrentToMRUFiles;
6614var
6615 Filenames: TStringList;
6616 i: longint;
6617 HelpFile: THelpFile;
6618begin
6619 Filenames := TStringList.Create;
6620
6621 for i := 0 to CurrentOpenFiles.Count - 1 do
6622 begin
6623 HelpFile := CurrentOpenFiles[ i ];
6624 Filenames.Add( HelpFile.Filename );
6625 end;
6626
6627 // update most-recently-used file list
6628 HelpFile := CurrentOpenFiles[ 0 ];
6629 AddToMRUList( HelpFile.Title,
6630 Filenames );
6631
6632 // recreate menu
6633 CreateMRUMenuItems;
6634
6635 Filenames.Destroy;
6636end;
6637
6638// Display the specified set of files
6639Procedure TMainForm.DisplayFiles( NewFiles: TList;
6640 Var FirstContentsNode: TNode );
6641var
6642 HelpFile: THelpFile;
6643 FileIndex: longint;
6644begin
6645 LogEvent(LogStartup, 'DisplayFiles' );
6646 // Now load the various parts of the file(s)
6647 // into the user interface
6648 ProgressBar.Position := 50;
6649 SetStatus( LoadingStatusDisplaying );
6650
6651 // Add our open files in the global filelist
6652 for FileIndex := 0 to NewFiles.Count - 1 do
6653 begin
6654 HelpFile := NewFiles[ FileIndex ];
6655 GlobalFilelist.AddFile( HelpFile.Filename, Frame.Handle );
6656 // LoadNotes( HelpFile );
6657 LoadBookmarks( HelpFile );
6658 end;
6659
6660 UpdateNotesDisplay;
6661
6662 BuildBookmarksMenu;
6663 UpdateBookmarksForm;
6664
6665 ProgressBar.Position := 55;
6666
6667 ContentsLoaded := false;
6668 IndexLoaded := false;
6669
6670 LoadContents( NewFiles, FirstContentsNode );
6671
6672 ProgressBar.Position := 75;
6673
6674 // LoadIndex;
6675
6676 ProgressBar.Position := 100;
6677 SetStatus( LoadingStatusDone );
6678
6679 LogEvent(LogStartup, 'DisplayFiles Done' );
6680
6681end;
6682
6683Function TMainForm.OpenFiles( const FileNames: TStrings;
6684 const WindowTitle: string;
6685 const DisplayFirstTopic: boolean ): boolean;
6686var
6687 HelpFiles: TList;
6688 FirstContentsNode: TNode;
6689begin
6690 LogEvent(LogStartup, 'OpenFiles' );
6691
6692 if not OKToCloseFile then
6693 exit;
6694
6695 SetWaitCursor;
6696
6697 HelpFiles := TList.Create;
6698
6699 if not LoadFiles( FileNames,
6700 HelpFiles ) then
6701 begin
6702 ClearWaitCursor;
6703 HelpFiles.Destroy;
6704 exit;
6705 end;
6706
6707 Result := true;
6708
6709 SearchResultsListBox.Clear;
6710 PageHistory.Clear;
6711 CurrentHistoryIndex := -1;
6712
6713 // Now that we have successfully loaded the new help file(s)
6714 // close the existing one.
6715 CloseFile;
6716
6717 AssignList( HelpFiles, CurrentOpenFiles );
6718
6719 ProgressBar.Position := 50;
6720 SetStatus( LoadingStatusDisplaying );
6721
6722 AddCurrentToMRUFiles;
6723
6724 if WindowTitle = '' then
6725 MainTitle := THelpFile( CurrentOpenFiles[ 0 ] ).Title
6726 else
6727 MainTitle := WindowTitle;
6728
6729 SetMainCaption;
6730
6731 // Now load the various parts of the file(s)
6732 // into the user interface
6733
6734 ContentsOutline.Clear;
6735
6736 DisplayFiles( HelpFiles,
6737 FirstContentsNode );
6738
6739 if CmdLineParameters.getHelpManagerFlag then
6740 ShowLeftPanel := Settings.ShowLeftPanel_Help
6741 else
6742 ShowLeftPanel := Settings.ShowLeftPanel_Standalone;
6743
6744 // Select first contents node if there is one
6745 if FirstContentsNode <> nil then
6746 begin
6747 LogEvent(LogStartup, ' Select first node' );
6748 ContentsOutline.SelectedNode := FirstContentsNode;
6749 end;
6750
6751 ClearWaitCursor;
6752
6753 ResetProgress;
6754
6755 NotebookOnPageChanged( self ); // ensure e.g. index loaded
6756
6757 EnableControls;
6758
6759 if DisplayFirstTopic then
6760 begin
6761 LogEvent(LogStartup, 'Display first topic' );
6762 DisplaySelectedContentsTopic;
6763 end;
6764
6765 LogEvent(LogStartup, 'OpenFiles complete' );
6766end;
6767
6768Function TMainForm.OpenAdditionalFiles( const FileNames: TStrings;
6769 const DisplayFirstTopic: boolean ): boolean;
6770var
6771 HelpFiles: TList;
6772 FirstNewContentsNode: TNode;
6773begin
6774 LogEvent(LogStartup, 'OpenAdditionalFiles' );
6775
6776 if not OKToCloseFile then
6777 exit;
6778
6779 SetWaitCursor;
6780
6781 HelpFiles := TList.Create;
6782
6783 if not LoadFiles( FileNames,
6784 HelpFiles ) then
6785 begin
6786 ClearWaitCursor;
6787 HelpFiles.Destroy;
6788 exit;
6789 end;
6790
6791 Result := true;
6792
6793 AddList( HelpFiles, CurrentOpenFiles );
6794
6795 AddCurrentToMRUFiles;
6796
6797 DisplayFiles( HelpFiles,
6798 FirstNewContentsNode );
6799
6800 // Select first contents node of new file
6801 if FirstNewContentsNode <> nil then
6802 ContentsOutline.SelectedNode := FirstNewContentsNode;
6803
6804 HelpFiles.Destroy;
6805
6806 ClearWaitCursor;
6807
6808 ResetProgress;
6809
6810 EnableControls;
6811
6812 if DisplayFirstTopic then
6813 DisplaySelectedContentsTopic;
6814
6815 LogEvent(LogStartup, 'OpenAdditionalFiles complete' );
6816end;
6817
6818Procedure TMainForm.OpenMIOnClick (Sender: TObject);
6819Begin
6820 FileOpen;
6821end;
6822
6823procedure TMainForm.FileOpen;
6824var
6825 Filenames: TStringList;
6826 KeepCurrentFiles: boolean;
6827 OpenedOK: boolean;
6828begin
6829 if not OKToCloseFile then
6830 exit;
6831
6832 if Settings.UseOriginalDialogs then
6833 begin
6834 SystemOpenDialog.Filename := AddSlash( Settings.LastOpenDirectory ) + '*.hlp;*.inf';
6835 if not SystemOpenDialog.Execute then
6836 exit;
6837
6838 Settings.LastOpenDirectory := ExtractFilePath( SystemOpenDialog.Filename );
6839 // note - sibyl's encapsulation doesn't allow multi-select
6840 OpenedOK := OpenFile( SystemOpenDialog.FileName, '', true );
6841 end
6842 else
6843 begin
6844 Filenames := TStringList.Create;
6845 KeepCurrentFiles := false;
6846 if not DoOpenMultiFileDialog( FileOpenTitle,
6847 HelpFilesDesc
6848 + '|*.inf;*.hlp|'
6849 + AllFilesDesc
6850 + '|*.*',
6851 '*.hlp;*.inf',
6852 Settings.LastOpenDirectory,
6853 KeepCurrentFiles,
6854 Filenames ) then
6855 exit;
6856
6857 if KeepCurrentFiles then
6858 OpenedOK := OpenAdditionalFiles( FileNames, true )
6859 else
6860 OpenedOK := OpenFiles( FileNames, '', true );
6861 Filenames.Destroy;
6862 end;
6863
6864 if OpenedOK then
6865 ClearHelpManager;
6866End;
6867
6868Procedure TMainForm.CloseWindows;
6869Begin
6870 DestroyListObjects( Windows );
6871 Windows.Clear;
6872end;
6873
6874// Help manager mode
6875
6876// if window is minimised then restore it
6877// (ideally should go back to maximized - don't know how)
6878Procedure TMainForm.RestoreWindow;
6879Begin
6880 If WindowState = wsMinimized then
6881 WindowState := wsNormal;
6882end;
6883
6884Procedure TMainForm.NHMDisplayIndex( Var Msg: TMessage );
6885begin
6886 RestoreWindow;
6887 DisplayIndex;
6888 // if nothing is being display already...
6889 if Windows.Count = 0 then
6890 // display first topic
6891 DisplaySelectedContentsTopic;
6892end;
6893
6894Procedure TMainForm.NHMDisplayContents( Var Msg: TMessage );
6895begin
6896 RestoreWindow;
6897 DisplayContents;
6898 // if nothing is being display already...
6899 if Windows.Count = 0 then
6900 // display first topic
6901 DisplaySelectedContentsTopic;
6902end;
6903
6904Procedure TMainForm.NHMTopicByResourceID( Var Msg: TMessage );
6905begin
6906 RestoreWindow;
6907 DisplayTopicByResourceID( Msg.Param1 );
6908end;
6909
6910Procedure TMainForm.NHMTopicByPanelName( Var Msg: TMessage );
6911var
6912 pMessageMem: pchar;
6913 PanelName: string;
6914 Topic: TTopic;
6915begin
6916 RestoreWindow;
6917
6918 pMessageMem := pchar( Msg.Param1 );
6919 PanelName := StrPas( pMessageMem );
6920 SharedMemory.Free( pMessageMem );
6921
6922 Topic := FindTopicByName( PanelName );
6923 if Topic = nil then
6924 Topic := FindTopicByGlobalName( PanelName );
6925
6926 if Topic <> nil then
6927 DisplayTopic( Topic )
6928 else
6929 SearchFor( PanelName );
6930end;
6931
6932// Sent from other instances starting up (and exiting immediately)
6933
6934Procedure TMainForm.NHMSearch( Var Msg: TMessage );
6935var
6936 pSearchText: pchar;
6937begin
6938 RestoreWindow;
6939
6940 pSearchText := pstring( Msg.Param1 );
6941 SearchFor( StrPas( pSearchText ) );
6942 SharedMemory.Free( pSearchText );
6943end;
6944
6945Procedure TMainForm.NHMGlobalSearch( Var Msg: TMessage );
6946var
6947 pSearchText: pchar;
6948begin
6949 RestoreWindow;
6950
6951 pSearchText := pstring( Msg.Param1 );
6952 DoGlobalSearch( StrPas( pSearchText ) );
6953 SharedMemory.Free( pSearchText );
6954end;
6955
6956Procedure TMainForm.NHMShowUsage( Var Msg: TMessage );
6957begin
6958 RestoreWindow;
6959 ShowUsage;
6960end;
6961
6962Procedure TMainForm.NHMSetFiles( Var Msg: TMessage );
6963var
6964 pFileNames: pchar;
6965begin
6966 // NOT restoring window here because this is not something the user should see...
6967 pFileNames := pstring( Msg.Param1 );
6968 OpenFilesFromTextList( StrPas( pFileNames ), false );
6969 SharedMemory.Free( pFileNames );
6970end;
6971
6972Procedure TMainForm.NHMSetTitle( Var Msg: TMessage );
6973var
6974 pTitle: pchar;
6975begin
6976 pTitle := pstring( Msg.Param1 );
6977 MainTitle := StrPas( pTitle );
6978 SharedMemory.Free( pTitle );
6979
6980 SetMainCaption;
6981end;
6982
6983Procedure TMainForm.NHMTest( Var Msg: TMessage );
6984var
6985 ps: pstring;
6986begin
6987 ps := PString( Msg.Param1 );
6988 ShowMessage( 'Got test message: ' + ps^ );
6989 SharedMemory.Free( ps );
6990end;
6991
6992Initialization
6993 RegisterClasses ([TMainForm, TSplitBar,
6994 TNoteBook,
6995 TEdit, TListBox,
6996 TRichTextView, TCoolBar2, TMainMenu, TMenuItem,
6997 TImageList, TPanel, TButton,
6998 TSystemOpenDialog, TOutline2, TCustomListBox, TPopupMenu, TSpeedButton
6999 , TProgressBar, TTabSet2]);
7000End.
Note: See TracBrowser for help on using the repository browser.