fphelp.pas 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  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. hcChangeDir : S:=hint_changedir;
  97. hcDOSShell : S:=hint_dosshell;
  98. hcQuit : S:=hint_exit;
  99. hcRecentFileBase..hcRecentFileBase+10
  100. : S:=hint_openrecentfile+RecentFiles[AHelpCtx-hcRecentFileBase].FileName;
  101. hcEditMenu : S:=hint_editmenu;
  102. hcUndo : S:=hint_editundo;
  103. hcRedo : S:=hint_editredo;
  104. hcCut : S:=hint_editcut;
  105. hcCopy : S:=hint_editcopy;
  106. hcPaste : S:=hint_editpaste;
  107. hcSelectAll : S:=hint_editselectall;
  108. hcUnselect : S:=hint_editunselect;
  109. hcCopyWin : S:=hint_editcopywin;
  110. hcPasteWin : S:=hint_editpastewin;
  111. hcClear : S:=hint_editclear;
  112. hcShowClipboard : S:=hint_showclipboard;
  113. hcSearchMenu : S:=hint_searchmenu;
  114. hcFind : S:=hint_searchfind;
  115. hcReplace : S:=hint_searchreplace;
  116. hcSearchAgain : S:=hint_searchagain;
  117. hcGotoLine : S:=hint_gotoline;
  118. hcObjects : S:=hint_objects;
  119. hcModules : S:=hint_modules;
  120. hcGlobals : S:=hint_globals;
  121. hcSymbol : S:=hint_symbol;
  122. hcRunMenu : S:=hint_runmenu;
  123. hcRun : S:=hint_run;
  124. hcRunDir : S:=hint_rundir;
  125. hcParameters : S:=hint_runparameters;
  126. hcResetDebugger : S:=hint_resetprogram;
  127. hcContToCursor : S:=hint_rununtilcursor;
  128. hcUntilReturn : S:=hint_rununtilreturn;
  129. hcUserScreen : S:=hint_userscreen;
  130. hcCompileMenu : S:=hint_compilemenu;
  131. hcCompile : S:=hint_compile;
  132. hcMake : S:=hint_make;
  133. hcBuild : S:=hint_build;
  134. hcTarget : S:=hint_target;
  135. hcPrimaryFile : S:=hint_primaryfile;
  136. hcClearPrimary : S:=hint_clearprimaryfile;
  137. hcCompilerMessages:S:=hint_showmessages;
  138. hcDebugMenu : S:=hint_debugmenu;
  139. hcToggleBreakpoint : S:=hint_togglebreakpoint;
  140. hcNewBreakpoint : S:=hint_createnewbreakpoint;
  141. hcEditBreakpoint : S:=hint_editbreakpoint;
  142. hcDeleteBreakpoint : S:=hint_deletebreakpoint;
  143. hcOpenGDBWindow : S:=hint_opengdbwindow;
  144. hcAddWatch : S:=hint_addwatch;
  145. hcWatchesWindow : S:=hint_watches;
  146. hcStackWindow : S:=hint_callstack;
  147. hcBreakpointList : S:=hint_editbreakpoints;
  148. hcToolsMenu : S:=hint_toolsmenu;
  149. hcCalculator : S:=hint_calculator;
  150. hcGrep : S:=hint_grep;
  151. hcMsgGotoSource : S:=hint_gotosource;
  152. hcRegistersWindow : S:=hint_registers;
  153. hcFPURegisters : S:=hint_FPURegisters;
  154. hcVectorRegisters : S:=hint_VectorRegisters;
  155. hcToolsMessages : S:=hint_messageswindow;
  156. hcToolsMsgNext : S:=hint_gotonextmsg;
  157. hcToolsMsgPrev : S:=hint_gotoprevmsg;
  158. hcToolsBase..
  159. hcToolsBase+MaxToolCount
  160. : S:=hint_usertool;
  161. hcASCIITable : S:=hint_asciitable;
  162. hcOptionsMenu : S:=hint_optionsmenu;
  163. hcSwitchesMode : S:=hint_switchesmode;
  164. hcCompiler,
  165. hcCompilerNoAltX : S:=hint_compiler;
  166. hcMemorySizes : S:=hint_memorysizes;
  167. hcLinker : S:=hint_linkeroptions;
  168. hcDebugger : S:=hint_debugoptions;
  169. hcDirectories : S:=hint_directories;
  170. hcBrowser,
  171. hcBrowserOptions: S:=hint_browser;
  172. hcTools : S:=hint_tools;
  173. hcRemoteDialog : S:=hint_remotedialog;
  174. hcTransferRemote: S:=hint_transferremote;
  175. hcDoReload : S:=hint_reloadmodifiedfile;
  176. hcEnvironmentMenu:S:=hint_environmentmenu;
  177. hcPreferences : S:=hint_preferences;
  178. hcEditor : S:=hint_editoroptions;
  179. hcCodeCompleteOptions:S:=hint_codecomplete;
  180. hcCodeTemplateOptions:S:=hint_codetemplates;
  181. hcMouse : S:=hint_mouseoptions;
  182. hcDesktopOptions: S:=hint_desktopoptions;
  183. hcStartup : S:=hint_startup;
  184. hcColors : S:=hint_colors;
  185. hcOpenINI : S:=hint_openini;
  186. hcSaveINI : S:=hint_saveini;
  187. hcSaveAsINI : S:=hint_saveasini;
  188. hcWindowMenu : S:=hint_windowmenu;
  189. hcTile : S:=hint_tile;
  190. hcCascade : S:=hint_cascade;
  191. hcCloseAll : S:=hint_closeall;
  192. hcResize : S:=hint_resize;
  193. hcZoom : S:=hint_zoom;
  194. hcNext : S:=hint_next;
  195. hcPrev : S:=hint_prev;
  196. hcHide : S:=hint_hide;
  197. hcClose : S:=hint_closewindow;
  198. hcWindowList : S:=hint_windowlist;
  199. hcUserScreenWindow:S:=hint_userscreenwindow;
  200. hcHelpMenu : S:=hint_helpmenu;
  201. hcHelpContents : S:=hint_helpcontents;
  202. hcHelpIndex : S:=hint_helpindex;
  203. hcHelpTopicSearch:S:=hint_helptopicsearch;
  204. hcHelpPrevTopic : S:=hint_helpprevtopic;
  205. hcHelpUsingHelp : S:=hint_helphowtouse;
  206. hcHelpFiles : S:=hint_helpfiles;
  207. hcOpenAtCursor : S:=hint_openatcursor;
  208. hcBrowseAtCursor: S:=hint_browseatcursor;
  209. hcEditorOptions : S:=hint_editoroptionscur;
  210. else S:='???';
  211. end;
  212. Hint:=S;
  213. end;
  214. procedure TFPHTMLFileLinkScanner.ProcessDoc(Doc: PHTMLLinkScanFile);
  215. begin
  216. PushStatus(FormatStrStr(msg_indexingfile,Doc^.GetDocumentURL));
  217. inherited ProcessDoc(Doc);
  218. PopStatus;
  219. end;
  220. function TFPHTMLFileLinkScanner.CheckURL(const URL: string): boolean;
  221. var OK: boolean;
  222. const HTTPPrefix = 'http:';
  223. FTPPrefix = 'ftp:';
  224. begin
  225. OK:=inherited CheckURL(URL);
  226. if OK then OK:=DirAndNameOf(URL)<>'';
  227. if OK then OK:=CompareText(copy(ExtOf(URL),1,4),'.HTM')=0;
  228. if OK then OK:=CompareText(copy(URL,1,length(HTTPPrefix)),HTTPPrefix)<>0;
  229. if OK then OK:=CompareText(copy(URL,1,length(FTPPrefix)),FTPPrefix)<>0;
  230. CheckURL:=OK;
  231. end;
  232. function TFPHTMLFileLinkScanner.CheckText(const Text: string): boolean;
  233. var OK: boolean;
  234. i : sw_integer;
  235. S: string;
  236. begin
  237. S:=Trim(Text);
  238. OK:=(S<>'') and (S[1]<>'[') and (S[1]<>',');
  239. { remove all Indexes }
  240. if s[1] in ['0'..'9'] then
  241. begin
  242. i:=1;
  243. while (i<length(s)) and (s[i] in ['0'..'9']) do
  244. inc(i);
  245. if (i<length(s)) and (s[i] in [' ',#9,'.']) then
  246. OK:=false;
  247. end;
  248. CheckText:=OK;
  249. end;
  250. procedure InitHelpSystem;
  251. procedure AddHelpFile(HelpFile,Param: string);
  252. begin
  253. {$IFDEF DEBUG}SetStatus(msg_LoadingHelpFile+' ('+SmartPath(HelpFile)+')');{$ENDIF}
  254. if HelpFacility^.AddFile(HelpFile,Param)=nil then
  255. ErrorBox(FormatStrStr(msg_failedtoloadhelpfile,HelpFile),nil);
  256. {$IFDEF DEBUG}SetStatus(msg_LoadingHelpFile);{$ENDIF}
  257. end;
  258. var I,P: sw_integer;
  259. S: string;
  260. Param: string;
  261. begin
  262. New(HelpFacility, Init);
  263. WOAHelp.RegisterHelpType;
  264. WNGHelp.RegisterHelpType;
  265. WOS2Help.RegisterHelpType;
  266. WWinHelp.RegisterHelpType;
  267. WVPHelp.RegisterHelpType;
  268. WHTMLHlp.RegisterHelpType;
  269. PushStatus(msg_LoadingHelpFiles);
  270. for I:=0 to HelpFiles^.Count-1 do
  271. begin
  272. S:=HelpFiles^.At(I)^; Param:='';
  273. P:=Pos('|',S);
  274. if P>0 then
  275. begin Param:=copy(S,P+1,High(S)); S:=copy(S,1,P-1); end;
  276. AddHelpFile(S,Param);
  277. end;
  278. PopStatus;
  279. end;
  280. procedure CheckHelpSystem;
  281. begin
  282. if HelpInited then Exit;
  283. InitHelpSystem;
  284. HelpInited:=true;
  285. end;
  286. procedure DoneHelpSystem;
  287. begin
  288. if assigned(HelpFacility) then
  289. begin
  290. Dispose(HelpFacility, Done);
  291. HelpFacility:=nil;
  292. end;
  293. HelpInited:=false;
  294. end;
  295. procedure HelpCreateWindow;
  296. var R: TRect;
  297. begin
  298. CheckHelpSystem;
  299. if HelpWindow=nil then
  300. begin
  301. Desktop^.GetExtent(R); R.Grow(-15,-3); Dec(R.A.Y);
  302. New(HelpWindow, Init(R, dialog_help, 0, 0, SearchFreeWindowNo));
  303. if HelpWindow<>nil then
  304. begin
  305. HelpWindow^.Hide;
  306. Desktop^.Insert(HelpWindow);
  307. end;
  308. end;
  309. end;
  310. procedure Help(FileID, Context: THelpCtx; Modal: boolean);
  311. begin
  312. if Modal then
  313. begin MessageBox(msg_modalhelpnotimplemented,nil,mfInformation+mfInsertInApp+mfOKButton); Exit; end;
  314. HelpCreateWindow;
  315. with HelpWindow^ do
  316. begin
  317. HelpWindow^.ShowTopic(FileID,Context);
  318. if GetState(sfVisible)=false then Show;
  319. MakeFirst;
  320. end;
  321. Message(Application,evCommand,cmUpdate,nil);
  322. end;
  323. procedure HelpTopicSearch(Editor: PEditor);
  324. var S: string;
  325. begin
  326. if Editor=nil then S:='' else
  327. S:=GetEditorCurWord(Editor,[]);
  328. HelpTopic(S);
  329. end;
  330. procedure HelpTopic(const S: string);
  331. var FileID: word;
  332. Ctx : THelpCtx;
  333. var Found: boolean;
  334. begin
  335. CheckHelpSystem;
  336. PushStatus(msg_LocatingTopic);
  337. Found:=HelpFacility^.TopicSearch(S,FileID,Ctx);
  338. PopStatus;
  339. if Found then
  340. Help(FileID,Ctx,false)
  341. else
  342. HelpIndex(S);
  343. end;
  344. procedure HelpIndex(Keyword: string);
  345. begin
  346. HelpCreateWindow;
  347. with HelpWindow^ do
  348. begin
  349. PushStatus(msg_BuildingHelpIndex);
  350. HelpWindow^.ShowIndex;
  351. if Keyword<>'' then
  352. HelpWindow^.HelpView^.Lookup(Keyword);
  353. PopStatus;
  354. if GetState(sfVisible)=false then Show;
  355. MakeFirst;
  356. end;
  357. Message(Application,evCommand,cmUpdate,nil);
  358. end;
  359. procedure PushStatus(S: string);
  360. begin
  361. if StatusLine=nil then
  362. Exit;
  363. If StatusStackPtr<=MaxStatusLevel then
  364. StatusStack[StatusStackPtr]:=PAdvancedStatusLine(StatusLine)^.GetStatusText
  365. else
  366. StatusStack[MaxStatusLevel]:=PAdvancedStatusLine(StatusLine)^.GetStatusText;
  367. SetStatus(S);
  368. Inc(StatusStackPtr);
  369. end;
  370. procedure PopStatus;
  371. begin
  372. if StatusLine=nil then
  373. Exit;
  374. Dec(StatusStackPtr);
  375. If StatusStackPtr<=MaxStatusLevel then
  376. SetStatus(StatusStack[StatusStackPtr])
  377. else
  378. SetStatus(StatusStack[MaxStatusLevel]);
  379. end;
  380. procedure SetStatus(S: string);
  381. begin
  382. if StatusLine=nil then
  383. Exit;
  384. PAdvancedStatusLine(StatusLine)^.SetStatusText(S);
  385. end;
  386. procedure ClearStatus;
  387. begin
  388. PAdvancedStatusLine(StatusLine)^.ClearStatusText;
  389. end;
  390. function FPHTMLGetSectionColor(Section: THTMLSection; var Color: byte): boolean;
  391. var OK: boolean;
  392. S: string;
  393. begin
  394. Color:=0;
  395. OK:=(ord(Section) in [1..length(CHTMLSectionAttrs)]);
  396. if OK then
  397. begin
  398. S:=#0;
  399. S:=copy(CHTMLSectionAttrs,ord(Section),1);
  400. if Assigned(Application)=false then Color:=0 else
  401. Color:=Application^.GetColor(ord(S[1]));
  402. if (Color and $0f) = ((Color and $f0) shr 4) then { same color ? }
  403. OK:=false;
  404. end;
  405. FPHTMLGetSectionColor:=OK;
  406. end;
  407. function FPNGGetAttrColor(Attr: char; var Color: byte): boolean;
  408. var OK: boolean;
  409. begin
  410. OK:=false;
  411. case Attr of
  412. 'A' : OK:=FPHTMLGetSectionColor(hsHeading1,Color);
  413. 'B' : OK:=FPHTMLGetSectionColor(hsHeading2,Color);
  414. 'b' : OK:=FPHTMLGetSectionColor(hsHeading5,Color);
  415. 'U' : OK:=FPHTMLGetSectionColor(hsHeading3,Color);
  416. 'N' : OK:=FPHTMLGetSectionColor(hsHeading4,Color);
  417. {$ifdef DEBUGMSG}
  418. else ErrorBox('Unknown attr encountered : "'+Attr+'"',nil);
  419. {$endif}
  420. end;
  421. FPNGGetAttrColor:=OK;
  422. end;
  423. function FPINFGetAttrColor(TextStyle, TextColor: byte; var Color: byte): boolean;
  424. var OK: boolean;
  425. begin
  426. OK:=false;
  427. case TextColor of
  428. 1 : OK:=FPHTMLGetSectionColor(hsHeading1,Color);
  429. 2 : OK:=FPHTMLGetSectionColor(hsHeading2,Color);
  430. 3 : OK:=FPHTMLGetSectionColor(hsHeading3,Color);
  431. end;
  432. FPINFGetAttrColor:=OK;
  433. end;
  434. procedure InitHelpFiles;
  435. begin
  436. HTMLGetSectionColor:={$ifdef FPC}@{$endif}FPHTMLGetSectionColor;
  437. NGGetAttrColor:={$ifdef FPC}@{$endif}FPNGGetAttrColor;
  438. INFGetAttrColor:={$ifdef FPC}@{$endif}FPINFGetAttrColor;
  439. New(HelpFiles, Init(10,10));
  440. end;
  441. procedure DoneHelpFiles;
  442. begin
  443. if assigned(HelpFiles) then
  444. Dispose(HelpFiles, Done);
  445. end;
  446. procedure CloseHelpWindows;
  447. procedure CloseIfHelpWindow(P: PView); {$ifndef FPC}far;{$endif}
  448. begin
  449. if P^.HelpCtx=hcHelpWindow then
  450. begin
  451. Message(P,evCommand,cmClose,nil);
  452. {Dispose(P, Done); help windows are only hidden on close so we've
  453. to destroy them manually
  454. but this was wrong as it was not correctly
  455. resetting the corresponding pointer in whelp unit PM }
  456. end;
  457. end;
  458. begin
  459. Desktop^.ForEach(@CloseIfHelpWindow);
  460. end;
  461. END.