fphelp.pas 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998 by Berczi Gabor
  4. Help routines for the IDE
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit FPHelp;
  12. interface
  13. uses
  14. Drivers,
  15. FVConsts,
  16. WHelp,WHlpView,WHTML,
  17. WEditor,WCEdit,
  18. WViews,WHTMLScn,
  19. FPViews;
  20. type
  21. PIDEStatusLine = ^TIDEStatusLine;
  22. TIDEStatusLine = object(TAdvancedStatusLine)
  23. function Hint(AHelpCtx: Word): String; virtual;
  24. procedure HandleEvent(var Event: TEvent); virtual;
  25. end;
  26. PFPHTMLFileLinkScanner = ^TFPHTMLFileLinkScanner;
  27. TFPHTMLFileLinkScanner = object(THTMLFileLinkScanner)
  28. function CheckURL(const URL: string): boolean; virtual;
  29. function CheckText(const Text: string): boolean; virtual;
  30. procedure ProcessDoc(Doc: PHTMLLinkScanFile); virtual;
  31. end;
  32. procedure Help(FileID, Context: THelpCtx; Modal: boolean);
  33. procedure HelpIndex(Keyword: string);
  34. procedure HelpTopicSearch(Editor: PEditor);
  35. procedure HelpTopic(const S: string);
  36. procedure CloseHelpWindows;
  37. procedure InitHelpSystem;
  38. procedure DoneHelpSystem;
  39. procedure InitHelpFiles;
  40. procedure DoneHelpFiles;
  41. procedure CheckHelpSystem;
  42. procedure PushStatus(S: string);
  43. procedure SetStatus(S: string);
  44. procedure ClearStatus;
  45. procedure PopStatus;
  46. const
  47. HelpWindow : PFPHelpWindow = nil;
  48. HelpInited : boolean = false;
  49. implementation
  50. uses Objects,Views,App,MsgBox,
  51. WUtils,WOAHelp,WHTMLHlp,WNGHelp,WOS2Help,WVPHelp,WWinHelp,
  52. FPString,FPConst,FPVars,FPUtils;
  53. const
  54. MaxStatusLevel = {$ifdef FPC}10{$else}1{$endif};
  55. var StatusStack : array[0..MaxStatusLevel] of string[MaxViewWidth];
  56. const
  57. StatusStackPtr : integer = 0;
  58. procedure TIDEStatusLine.HandleEvent(var Event: TEvent);
  59. begin
  60. case Event.What of
  61. evBroadcast :
  62. case Event.Command of
  63. cmUpdate : Update;
  64. end;
  65. end;
  66. inherited HandleEvent(Event);
  67. end;
  68. function TIDEStatusLine.Hint(AHelpCtx: Word): String;
  69. var S: string;
  70. begin
  71. case AHelpCtx of
  72. hcNoContext : S:='';
  73. hcDragging : S:='';
  74. hcSourceWindow : S:='';
  75. hcHelpWindow : S:='';
  76. hcCalcWindow : S:='';
  77. hcInfoWindow : S:='';
  78. hcClipboardWindow:S:='';
  79. hcBrowserWindow : S:='';
  80. hcMessagesWindow: S:='';
  81. hcCompilerMessagesWindow: S:='';
  82. hcASCIITableWindow: S:='';
  83. hcGDBWindow : S:=hint_rawgdbwindow;
  84. hcDisassemblyWindow : S:=hint_disassemblywindow;
  85. hcBreakpointListWindow : S:=hint_allbreakpoints;
  86. hcSystemMenu : S:=hint_systemmenu;
  87. hcUpdate : S:=hint_update;
  88. hcAbout : S:=hint_about;
  89. hcFileMenu : S:=hint_filemenu;
  90. hcNew : S:=hint_filenew;
  91. hcNewFromTemplate:S:=hint_filenewfromtemplate;
  92. hcOpen : S:=hint_fileopen;
  93. hcSave : S:=hint_filesave;
  94. hcSaveAs : S:=hint_filesaveas;
  95. hcSaveAll : S:=hint_filesaveall;
  96. hcPrint : S:=hint_print;
  97. hcPrinterSetup : S:=hint_printersetup;
  98. hcChangeDir : S:=hint_changedir;
  99. hcDOSShell : S:=hint_dosshell;
  100. hcQuit : S:=hint_exit;
  101. hcRecentFileBase..hcRecentFileBase+10
  102. : S:=hint_openrecentfile+RecentFiles[AHelpCtx-hcRecentFileBase].FileName;
  103. hcEditMenu : S:=hint_editmenu;
  104. hcUndo : S:=hint_editundo;
  105. hcRedo : S:=hint_editredo;
  106. hcCut : S:=hint_editcut;
  107. hcCopy : S:=hint_editcopy;
  108. hcPaste : S:=hint_editpaste;
  109. hcSelectAll : S:=hint_editselectall;
  110. hcUnselect : S:=hint_editunselect;
  111. hcCopyWin : S:=hint_editcopywin;
  112. hcPasteWin : S:=hint_editpastewin;
  113. hcClear : S:=hint_editclear;
  114. hcShowClipboard : S:=hint_showclipboard;
  115. hcSearchMenu : S:=hint_searchmenu;
  116. hcFind : S:=hint_searchfind;
  117. hcReplace : S:=hint_searchreplace;
  118. hcSearchAgain : S:=hint_searchagain;
  119. hcGotoLine : S:=hint_gotoline;
  120. hcObjects : S:=hint_objects;
  121. hcModules : S:=hint_modules;
  122. hcGlobals : S:=hint_globals;
  123. hcSymbol : S:=hint_symbol;
  124. hcRunMenu : S:=hint_runmenu;
  125. hcRun : S:=hint_run;
  126. hcRunDir : S:=hint_rundir;
  127. hcParameters : S:=hint_runparameters;
  128. hcResetDebugger : S:=hint_resetprogram;
  129. hcContToCursor : S:=hint_rununtilcursor;
  130. hcUntilReturn : S:=hint_rununtilreturn;
  131. hcUserScreen : S:=hint_userscreen;
  132. hcCompileMenu : S:=hint_compilemenu;
  133. hcCompile : S:=hint_compile;
  134. hcMake : S:=hint_make;
  135. hcBuild : S:=hint_build;
  136. hcTarget : S:=hint_target;
  137. hcPrimaryFile : S:=hint_primaryfile;
  138. hcClearPrimary : S:=hint_clearprimaryfile;
  139. hcCompilerMessages:S:=hint_showmessages;
  140. hcDebugMenu : S:=hint_debugmenu;
  141. hcToggleBreakpoint : S:=hint_togglebreakpoint;
  142. hcNewBreakpoint : S:=hint_createnewbreakpoint;
  143. hcEditBreakpoint : S:=hint_editbreakpoint;
  144. hcDeleteBreakpoint : S:=hint_deletebreakpoint;
  145. hcOpenGDBWindow : S:=hint_opengdbwindow;
  146. hcAddWatch : S:=hint_addwatch;
  147. hcWatchesWindow : S:=hint_watches;
  148. hcStackWindow : S:=hint_callstack;
  149. hcBreakpointList : S:=hint_editbreakpoints;
  150. hcToolsMenu : S:=hint_toolsmenu;
  151. hcCalculator : S:=hint_calculator;
  152. hcGrep : S:=hint_grep;
  153. hcMsgGotoSource : S:=hint_gotosource;
  154. hcRegistersWindow : S:=hint_registers;
  155. hcFPURegisters : S:=hint_FPURegisters;
  156. hcVectorRegisters : S:=hint_VectorRegisters;
  157. hcToolsMessages : S:=hint_messageswindow;
  158. hcToolsMsgNext : S:=hint_gotonextmsg;
  159. hcToolsMsgPrev : S:=hint_gotoprevmsg;
  160. hcToolsBase..
  161. hcToolsBase+MaxToolCount
  162. : S:=hint_usertool;
  163. hcASCIITable : S:=hint_asciitable;
  164. hcOptionsMenu : S:=hint_optionsmenu;
  165. hcSwitchesMode : S:=hint_switchesmode;
  166. hcCompiler,
  167. hcCompilerNoAltX : S:=hint_compiler;
  168. hcMemorySizes : S:=hint_memorysizes;
  169. hcLinker : S:=hint_linkeroptions;
  170. hcDebugger : S:=hint_debugoptions;
  171. hcDirectories : S:=hint_directories;
  172. hcBrowser,
  173. hcBrowserOptions: S:=hint_browser;
  174. hcTools : S:=hint_tools;
  175. hcRemoteDialog : S:=hint_remotedialog;
  176. hcTransferRemote: S:=hint_transferremote;
  177. hcDoReload : S:=hint_reloadmodifiedfile;
  178. hcEnvironmentMenu:S:=hint_environmentmenu;
  179. hcPreferences : S:=hint_preferences;
  180. hcEditor : S:=hint_editoroptions;
  181. hcCodeCompleteOptions:S:=hint_codecomplete;
  182. hcCodeTemplateOptions:S:=hint_codetemplates;
  183. hcMouse : S:=hint_mouseoptions;
  184. hcDesktopOptions: S:=hint_desktopoptions;
  185. hcStartup : S:=hint_startup;
  186. hcColors : S:=hint_colors;
  187. hcOpenINI : S:=hint_openini;
  188. hcSaveINI : S:=hint_saveini;
  189. hcSaveAsINI : S:=hint_saveasini;
  190. hcWindowMenu : S:=hint_windowmenu;
  191. hcTile : S:=hint_tile;
  192. hcCascade : S:=hint_cascade;
  193. hcCloseAll : S:=hint_closeall;
  194. hcResize : S:=hint_resize;
  195. hcZoom : S:=hint_zoom;
  196. hcNext : S:=hint_next;
  197. hcPrev : S:=hint_prev;
  198. hcHide : S:=hint_hide;
  199. hcClose : S:=hint_closewindow;
  200. hcWindowList : S:=hint_windowlist;
  201. hcUserScreenWindow:S:=hint_userscreenwindow;
  202. hcHelpMenu : S:=hint_helpmenu;
  203. hcHelpContents : S:=hint_helpcontents;
  204. hcHelpIndex : S:=hint_helpindex;
  205. hcHelpTopicSearch:S:=hint_helptopicsearch;
  206. hcHelpPrevTopic : S:=hint_helpprevtopic;
  207. hcHelpUsingHelp : S:=hint_helphowtouse;
  208. hcHelpFiles : S:=hint_helpfiles;
  209. hcOpenAtCursor : S:=hint_openatcursor;
  210. hcBrowseAtCursor: S:=hint_browseatcursor;
  211. hcEditorOptions : S:=hint_editoroptionscur;
  212. else S:='???';
  213. end;
  214. Hint:=S;
  215. end;
  216. procedure TFPHTMLFileLinkScanner.ProcessDoc(Doc: PHTMLLinkScanFile);
  217. begin
  218. PushStatus(FormatStrStr(msg_indexingfile,Doc^.GetDocumentURL));
  219. inherited ProcessDoc(Doc);
  220. PopStatus;
  221. end;
  222. function TFPHTMLFileLinkScanner.CheckURL(const URL: string): boolean;
  223. var OK: boolean;
  224. const HTTPPrefix = 'http:';
  225. FTPPrefix = 'ftp:';
  226. begin
  227. OK:=inherited CheckURL(URL);
  228. if OK then OK:=DirAndNameOf(URL)<>'';
  229. if OK then OK:=CompareText(copy(ExtOf(URL),1,4),'.HTM')=0;
  230. if OK then OK:=CompareText(copy(URL,1,length(HTTPPrefix)),HTTPPrefix)<>0;
  231. if OK then OK:=CompareText(copy(URL,1,length(FTPPrefix)),FTPPrefix)<>0;
  232. CheckURL:=OK;
  233. end;
  234. function TFPHTMLFileLinkScanner.CheckText(const Text: string): boolean;
  235. var OK: boolean;
  236. i : sw_integer;
  237. S: string;
  238. begin
  239. S:=Trim(Text);
  240. OK:=(S<>'') and (S[1]<>'[') and (S[1]<>',');
  241. { remove all Indexes }
  242. if s[1] in ['0'..'9'] then
  243. begin
  244. i:=1;
  245. while (i<length(s)) and (s[i] in ['0'..'9']) do
  246. inc(i);
  247. if (i<length(s)) and (s[i] in [' ',#9,'.']) then
  248. OK:=false;
  249. end;
  250. CheckText:=OK;
  251. end;
  252. procedure InitHelpSystem;
  253. procedure AddHelpFile(HelpFile,Param: string);
  254. begin
  255. {$IFDEF DEBUG}SetStatus(msg_LoadingHelpFile+' ('+SmartPath(HelpFile)+')');{$ENDIF}
  256. if HelpFacility^.AddFile(HelpFile,Param)=nil then
  257. ErrorBox(FormatStrStr(msg_failedtoloadhelpfile,HelpFile),nil);
  258. {$IFDEF DEBUG}SetStatus(msg_LoadingHelpFile);{$ENDIF}
  259. end;
  260. var I,P: sw_integer;
  261. S: string;
  262. Param: string;
  263. begin
  264. New(HelpFacility, Init);
  265. WOAHelp.RegisterHelpType;
  266. WNGHelp.RegisterHelpType;
  267. WOS2Help.RegisterHelpType;
  268. WWinHelp.RegisterHelpType;
  269. WVPHelp.RegisterHelpType;
  270. WHTMLHlp.RegisterHelpType;
  271. PushStatus(msg_LoadingHelpFiles);
  272. for I:=0 to HelpFiles^.Count-1 do
  273. begin
  274. S:=HelpFiles^.At(I)^; Param:='';
  275. P:=Pos('|',S);
  276. if P>0 then
  277. begin Param:=copy(S,P+1,High(S)); S:=copy(S,1,P-1); end;
  278. AddHelpFile(S,Param);
  279. end;
  280. PopStatus;
  281. end;
  282. procedure CheckHelpSystem;
  283. begin
  284. if HelpInited then Exit;
  285. InitHelpSystem;
  286. HelpInited:=true;
  287. end;
  288. procedure DoneHelpSystem;
  289. begin
  290. if assigned(HelpFacility) then
  291. begin
  292. Dispose(HelpFacility, Done);
  293. HelpFacility:=nil;
  294. end;
  295. HelpInited:=false;
  296. end;
  297. procedure HelpCreateWindow;
  298. var R: TRect;
  299. begin
  300. CheckHelpSystem;
  301. if HelpWindow=nil then
  302. begin
  303. Desktop^.GetExtent(R); R.Grow(-15,-3); Dec(R.A.Y);
  304. New(HelpWindow, Init(R, dialog_help, 0, 0, SearchFreeWindowNo));
  305. if HelpWindow<>nil then
  306. begin
  307. HelpWindow^.Hide;
  308. Desktop^.Insert(HelpWindow);
  309. end;
  310. end;
  311. end;
  312. procedure Help(FileID, Context: THelpCtx; Modal: boolean);
  313. begin
  314. if Modal then
  315. begin MessageBox(msg_modalhelpnotimplemented,nil,mfInformation+mfInsertInApp+mfOKButton); Exit; end;
  316. HelpCreateWindow;
  317. with HelpWindow^ do
  318. begin
  319. HelpWindow^.ShowTopic(FileID,Context);
  320. if GetState(sfVisible)=false then Show;
  321. MakeFirst;
  322. end;
  323. Message(Application,evCommand,cmUpdate,nil);
  324. end;
  325. procedure HelpTopicSearch(Editor: PEditor);
  326. var S: string;
  327. begin
  328. if Editor=nil then S:='' else
  329. S:=GetEditorCurWord(Editor,[]);
  330. HelpTopic(S);
  331. end;
  332. procedure HelpTopic(const S: string);
  333. var FileID: word;
  334. Ctx : THelpCtx;
  335. var Found: boolean;
  336. begin
  337. CheckHelpSystem;
  338. PushStatus(msg_LocatingTopic);
  339. Found:=HelpFacility^.TopicSearch(S,FileID,Ctx);
  340. PopStatus;
  341. if Found then
  342. Help(FileID,Ctx,false)
  343. else
  344. HelpIndex(S);
  345. end;
  346. procedure HelpIndex(Keyword: string);
  347. begin
  348. HelpCreateWindow;
  349. with HelpWindow^ do
  350. begin
  351. PushStatus(msg_BuildingHelpIndex);
  352. HelpWindow^.ShowIndex;
  353. if Keyword<>'' then
  354. HelpWindow^.HelpView^.Lookup(Keyword);
  355. PopStatus;
  356. if GetState(sfVisible)=false then Show;
  357. MakeFirst;
  358. end;
  359. Message(Application,evCommand,cmUpdate,nil);
  360. end;
  361. procedure PushStatus(S: string);
  362. begin
  363. if StatusLine=nil then
  364. Exit;
  365. If StatusStackPtr<=MaxStatusLevel then
  366. StatusStack[StatusStackPtr]:=PAdvancedStatusLine(StatusLine)^.GetStatusText
  367. else
  368. StatusStack[MaxStatusLevel]:=PAdvancedStatusLine(StatusLine)^.GetStatusText;
  369. SetStatus(S);
  370. Inc(StatusStackPtr);
  371. end;
  372. procedure PopStatus;
  373. begin
  374. if StatusLine=nil then
  375. Exit;
  376. Dec(StatusStackPtr);
  377. If StatusStackPtr<=MaxStatusLevel then
  378. SetStatus(StatusStack[StatusStackPtr])
  379. else
  380. SetStatus(StatusStack[MaxStatusLevel]);
  381. end;
  382. procedure SetStatus(S: string);
  383. begin
  384. if StatusLine=nil then
  385. Exit;
  386. PAdvancedStatusLine(StatusLine)^.SetStatusText(S);
  387. end;
  388. procedure ClearStatus;
  389. begin
  390. PAdvancedStatusLine(StatusLine)^.ClearStatusText;
  391. end;
  392. function FPHTMLGetSectionColor(Section: THTMLSection; var Color: byte): boolean;
  393. var OK: boolean;
  394. S: string;
  395. begin
  396. Color:=0;
  397. OK:=(ord(Section) in [1..length(CHTMLSectionAttrs)]);
  398. if OK then
  399. begin
  400. S:=#0;
  401. S:=copy(CHTMLSectionAttrs,ord(Section),1);
  402. if Assigned(Application)=false then Color:=0 else
  403. Color:=Application^.GetColor(ord(S[1]));
  404. if (Color and $0f) = ((Color and $f0) shr 4) then { same color ? }
  405. OK:=false;
  406. end;
  407. FPHTMLGetSectionColor:=OK;
  408. end;
  409. function FPNGGetAttrColor(Attr: char; var Color: byte): boolean;
  410. var OK: boolean;
  411. begin
  412. OK:=false;
  413. case Attr of
  414. 'A' : OK:=FPHTMLGetSectionColor(hsHeading1,Color);
  415. 'B' : OK:=FPHTMLGetSectionColor(hsHeading2,Color);
  416. 'b' : OK:=FPHTMLGetSectionColor(hsHeading5,Color);
  417. 'U' : OK:=FPHTMLGetSectionColor(hsHeading3,Color);
  418. 'N' : OK:=FPHTMLGetSectionColor(hsHeading4,Color);
  419. {$ifdef DEBUGMSG}
  420. else ErrorBox('Unknown attr encountered : "'+Attr+'"',nil);
  421. {$endif}
  422. end;
  423. FPNGGetAttrColor:=OK;
  424. end;
  425. function FPINFGetAttrColor(TextStyle, TextColor: byte; var Color: byte): boolean;
  426. var OK: boolean;
  427. begin
  428. OK:=false;
  429. case TextColor of
  430. 1 : OK:=FPHTMLGetSectionColor(hsHeading1,Color);
  431. 2 : OK:=FPHTMLGetSectionColor(hsHeading2,Color);
  432. 3 : OK:=FPHTMLGetSectionColor(hsHeading3,Color);
  433. end;
  434. FPINFGetAttrColor:=OK;
  435. end;
  436. procedure InitHelpFiles;
  437. begin
  438. HTMLGetSectionColor:={$ifdef FPC}@{$endif}FPHTMLGetSectionColor;
  439. NGGetAttrColor:={$ifdef FPC}@{$endif}FPNGGetAttrColor;
  440. INFGetAttrColor:={$ifdef FPC}@{$endif}FPINFGetAttrColor;
  441. New(HelpFiles, Init(10,10));
  442. end;
  443. procedure DoneHelpFiles;
  444. begin
  445. if assigned(HelpFiles) then
  446. Dispose(HelpFiles, Done);
  447. end;
  448. procedure CloseHelpWindows;
  449. procedure CloseIfHelpWindow(P: PView); {$ifndef FPC}far;{$endif}
  450. begin
  451. if P^.HelpCtx=hcHelpWindow then
  452. begin
  453. Message(P,evCommand,cmClose,nil);
  454. {Dispose(P, Done); help windows are only hidden on close so we've
  455. to destroy them manually
  456. but this was wrong as it was not correctly
  457. resetting the corresponding pointer in whelp unit PM }
  458. end;
  459. end;
  460. begin
  461. Desktop^.ForEach(@CloseIfHelpWindow);
  462. end;
  463. END.