whlpview.pas 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998 by Berczi Gabor
  5. Help display objects
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit WHlpView;
  13. interface
  14. uses
  15. Objects,Drivers,Commands,Views,
  16. {$ifdef EDITORS}
  17. Editors,
  18. {$else}
  19. WEditor,WCEdit,
  20. {$endif}
  21. WUtils,WHelp;
  22. {$IFNDEF EDITORS}
  23. type
  24. TEditor = TCodeEditor; PEditor = PCodeEditor;
  25. {$ENDIF}
  26. const
  27. cmPrevTopic = 90;
  28. HistorySize = 30;
  29. CHelpViewer = #33#34#35#36;
  30. CHelpFrame = #37#37#38#38#39;
  31. cmHelpFilesChanged = 57340;
  32. type
  33. PHelpLink = ^THelpLink;
  34. THelpLink = record
  35. Bounds : TRect;
  36. FileID : longint;
  37. Context : THelpCtx;
  38. end;
  39. PHelpColorArea = ^THelpColorArea;
  40. THelpColorArea = record
  41. Color : byte;
  42. Bounds : TRect;
  43. AttrMask : byte;
  44. end;
  45. PHelpKeyword = ^THelpKeyword;
  46. THelpKeyword = record
  47. KWord : PString;
  48. Index : sw_integer;
  49. end;
  50. PLinkCollection = ^TLinkCollection;
  51. TLinkCollection = object(TCollection)
  52. procedure FreeItem(Item: Pointer); virtual;
  53. end;
  54. PColorAreaCollection = ^TColorAreaCollection;
  55. TColorAreaCollection = object(TCollection)
  56. procedure FreeItem(Item: Pointer); virtual;
  57. end;
  58. PKeywordCollection = ^TKeywordCollection;
  59. TKeywordCollection = object({TSorted}TCollection)
  60. function At(Index: sw_Integer): PHelpKeyword;
  61. procedure FreeItem(Item: Pointer); virtual;
  62. function Compare(Key1, Key2: Pointer): sw_Integer; virtual;
  63. end;
  64. { TSearchRelation = (srEqual,srGreater,srLess,srGreatEqu,srLessEqu);
  65. PAdvancedStringCollection = ^TAdvancedStringCollection;
  66. TAdvancedStringCollection = object(TStringCollection)
  67. function SearchItem(Key: pointer; Rel: TSearchRelation; var Index: integer): boolean; virtual;
  68. end;}
  69. PNamedMark = ^TNamedMark;
  70. TNamedMark = object(TObject)
  71. constructor Init(const AName: string; AX, AY: integer);
  72. function GetName: string;
  73. destructor Done; virtual;
  74. private
  75. Name: PString;
  76. Pos: TPoint;
  77. end;
  78. PNamedMarkCollection = ^TNamedMarkCollection;
  79. TNamedMarkCollection = object(TSortedCollection)
  80. function At(Index: sw_Integer): PNamedMark;
  81. function Compare(Key1, Key2: Pointer): sw_Integer; virtual;
  82. function SearchMark(const Name: string): PNamedMark;
  83. function GetMarkPos(const Name: string; var P: TPoint): boolean;
  84. procedure Add(const Name: string; P: TPoint);
  85. end;
  86. PHelpTopic = ^THelpTopic;
  87. THelpTopic = object(TObject)
  88. Topic: PTopic;
  89. Lines: PUnsortedStringCollection;
  90. Links: PLinkCollection;
  91. NamedMarks: PNamedMarkCollection;
  92. ColorAreas: PColorAreaCollection;
  93. public
  94. constructor Init(ATopic: PTopic);
  95. procedure SetParams(AMargin, AWidth: sw_integer); virtual;
  96. function GetLineCount: sw_integer; virtual;
  97. function GetLineText(Line: sw_integer): string; virtual;
  98. function GetLinkCount: sw_integer; virtual;
  99. procedure GetLinkBounds(Index: sw_integer; var R: TRect); virtual;
  100. function GetLinkFileID(Index: sw_integer): word; virtual;
  101. function GetLinkContext(Index: sw_integer): THelpCtx; virtual;
  102. function GetColorAreaCount: sw_integer; virtual;
  103. procedure GetColorAreaBounds(Index: sw_integer; var R: TRect); virtual;
  104. function GetColorAreaColor(Index: sw_integer): word; virtual;
  105. function GetColorAreaMask(Index: sw_integer): word; virtual;
  106. destructor Done; virtual;
  107. private
  108. Width,Margin: sw_integer;
  109. { StockItem: boolean;}
  110. procedure ReBuild;
  111. end;
  112. THelpHistoryEntry = record
  113. Context_ : THelpCtx;
  114. Delta_ : TPoint;
  115. CurPos_ : TPoint;
  116. CurLink_ : sw_integer;
  117. FileID_ : word;
  118. end;
  119. PHelpViewer = ^THelpViewer;
  120. THelpViewer = object(TEditor)
  121. Margin: sw_integer;
  122. HelpTopic: PHelpTopic;
  123. CurLink: sw_integer;
  124. constructor Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  125. procedure ChangeBounds(var Bounds: TRect); virtual;
  126. procedure Draw; virtual;
  127. procedure HandleEvent(var Event: TEvent); virtual;
  128. procedure SetCurPtr(X,Y: sw_integer); virtual;
  129. function GetLineCount: sw_integer; virtual;
  130. function GetLine(LineNo: sw_integer): PCustomLine; virtual;
  131. function GetLineText(Line: sw_integer): string; virtual;
  132. function GetDisplayText(I: sw_integer): string; virtual;
  133. function GetLinkCount: sw_integer; virtual;
  134. procedure GetLinkBounds(Index: sw_integer; var R: TRect); virtual;
  135. function GetLinkFileID(Index: sw_integer): word; virtual;
  136. function GetLinkContext(Index: sw_integer): THelpCtx; virtual;
  137. function GetLinkText(Index: sw_integer): string; virtual;
  138. function GetColorAreaCount: sw_integer; virtual;
  139. procedure GetColorAreaBounds(Index: sw_integer; var R: TRect); virtual;
  140. function GetColorAreaColor(Index: sw_integer): word; virtual;
  141. function GetColorAreaMask(Index: sw_integer): word; virtual;
  142. procedure SelectNextLink(ANext: boolean); virtual;
  143. procedure SwitchToIndex; virtual;
  144. procedure SwitchToTopic(SourceFileID: word; Context: THelpCtx); virtual;
  145. procedure SetTopic(Topic: PTopic); virtual;
  146. procedure SetCurLink(Link: sw_integer); virtual;
  147. procedure SelectLink(Index: sw_integer); virtual;
  148. procedure PrevTopic; virtual;
  149. procedure RenderTopic; virtual;
  150. procedure Lookup(S: string); virtual;
  151. function GetPalette: PPalette; virtual;
  152. constructor Load(var S: TStream);
  153. procedure Store(var S: TStream);
  154. destructor Done; virtual;
  155. private
  156. History : array[0..HistorySize] of THelpHistoryEntry;
  157. HistoryPtr : integer;
  158. WordList : PKeywordCollection;
  159. Lookupword : string;
  160. InLookUp : boolean;
  161. IndexTopic : PTopic;
  162. IndexHelpTopic: PHelpTopic;
  163. function LinkContainsPoint(var R: TRect; var P: TPoint): boolean;
  164. procedure ISwitchToTopic(SourceFileID: word; Context: THelpCtx; RecordInHistory: boolean);
  165. procedure ISwitchToTopicPtr(P: PTopic; RecordInHistory: boolean);
  166. procedure BuildTopicWordList;
  167. end;
  168. PHelpFrame = ^THelpFrame;
  169. THelpFrame = object(TFrame)
  170. function GetPalette: PPalette; virtual;
  171. end;
  172. PHelpWindow = ^THelpWindow;
  173. THelpWindow = object(TWindow)
  174. HSB,VSB : PScrollBar;
  175. HelpView: PHelpViewer;
  176. HideOnClose: boolean;
  177. constructor Init(var Bounds: TRect; ATitle: TTitleStr; ASourceFileID: word; AContext: THelpCtx; ANumber: Integer);
  178. procedure InitFrame; virtual;
  179. procedure InitScrollBars; virtual;
  180. procedure InitHelpView; virtual;
  181. procedure ShowIndex; virtual;
  182. procedure ShowTopic(SourceFileID: word; Context: THelpCtx); virtual;
  183. procedure HandleEvent(var Event: TEvent); virtual;
  184. procedure Close; virtual;
  185. function GetPalette: PPalette; virtual; { needs to be overriden }
  186. end;
  187. implementation
  188. uses
  189. Video,
  190. WConsts;
  191. const CommentColor = Blue;
  192. function NewLink(FileID: longint; Topic: THelpCtx; StartP, EndP: TPoint): PHelpLink;
  193. var P: PHelpLink;
  194. begin
  195. New(P); FillChar(P^, SizeOf(P^), 0);
  196. P^.FileID:=FileID;
  197. P^.Context:=Topic; P^.Bounds.A:=StartP; P^.Bounds.B:=EndP;
  198. NewLink:=P;
  199. end;
  200. procedure DisposeLink(P: PHelpLink);
  201. begin
  202. if P<>nil then Dispose(P);
  203. end;
  204. function NewColorArea(Color, AttrMask: byte; StartP, EndP: TPoint): PHelpColorArea;
  205. var P: PHelpColorArea;
  206. begin
  207. New(P); FillChar(P^, SizeOf(P^), 0);
  208. P^.Color:=Color; P^.AttrMask:=AttrMask;
  209. P^.Bounds.A:=StartP; P^.Bounds.B:=EndP;
  210. NewColorArea:=P;
  211. end;
  212. procedure DisposeColorArea(P: PHelpColorArea);
  213. begin
  214. if P<>nil then Dispose(P);
  215. end;
  216. function NewKeyword(Index: sw_integer; KWord: string): PHelpKeyword;
  217. var P: PHelpKeyword;
  218. begin
  219. New(P); FillChar(P^, SizeOf(P^), 0);
  220. P^.Index:=Index; P^.KWord:=NewStr(KWord);
  221. NewKeyword:=P;
  222. end;
  223. procedure DisposeKeyword(P: PHelpKeyword);
  224. begin
  225. if P<>nil then
  226. begin
  227. if P^.KWord<>nil then DisposeStr(P^.KWord);
  228. Dispose(P);
  229. end;
  230. end;
  231. procedure TLinkCollection.FreeItem(Item: Pointer);
  232. begin
  233. if Item<>nil then DisposeLink(Item);
  234. end;
  235. procedure TColorAreaCollection.FreeItem(Item: Pointer);
  236. begin
  237. if Item<>nil then DisposeColorArea(Item);
  238. end;
  239. function TKeywordCollection.At(Index: sw_Integer): PHelpKeyword;
  240. begin
  241. At:=inherited At(Index);
  242. end;
  243. procedure TKeywordCollection.FreeItem(Item: Pointer);
  244. begin
  245. if Item<>nil then DisposeKeyword(Item);
  246. end;
  247. function TKeywordCollection.Compare(Key1, Key2: Pointer): sw_Integer;
  248. var R: sw_integer;
  249. K1: PHelpKeyword absolute Key1;
  250. K2: PHelpKeyword absolute Key2;
  251. S1,S2: string;
  252. begin
  253. S1:=UpcaseStr(K1^.KWord^); S2:=UpcaseStr(K2^.KWord^);
  254. if S1<S2 then R:=-1 else
  255. if S1>S2 then R:=1 else
  256. R:=0;
  257. Compare:=R;
  258. end;
  259. {function TAdvancedStringCollection.SearchItem(Key: pointer; Rel: TSearchRelation; var Index: sw_integer): boolean;
  260. var
  261. L, H, I, C: sw_Integer;
  262. const resSmaller = -1; resEqual = 0; resGreater = 1;
  263. begin
  264. Index:=-1;
  265. case Rel of
  266. srEqual :
  267. while (L <= H) and (Index=-1) do
  268. begin
  269. I := (L + H) shr 1;
  270. C := Compare(KeyOf(Items^[I]), Key);
  271. if C = resSmaller then L := I + 1 else
  272. begin
  273. H := I - 1;
  274. if C = resEqual then
  275. begin
  276. if not Duplicates then L := I;
  277. Index := L;
  278. end;
  279. end;
  280. end;
  281. srGreater :
  282. begin
  283. end;
  284. srLess :
  285. ;
  286. srGreatEqu :
  287. ;
  288. srLessEqu :
  289. ;
  290. else Exit;
  291. end;
  292. Search:=Index<>-1;
  293. end;}
  294. constructor TNamedMark.Init(const AName: string; AX, AY: integer);
  295. begin
  296. inherited Init;
  297. Name:=NewStr(AName);
  298. Pos.X:=AX; Pos.Y:=AY;
  299. end;
  300. function TNamedMark.GetName: string;
  301. begin
  302. GetName:=GetStr(Name);
  303. end;
  304. destructor TNamedMark.Done;
  305. begin
  306. if Assigned(Name) then DisposeStr(Name); Name:=nil;
  307. inherited Done;
  308. end;
  309. function TNamedMarkCollection.At(Index: sw_Integer): PNamedMark;
  310. begin
  311. At:=inherited At(Index);
  312. end;
  313. function TNamedMarkCollection.Compare(Key1, Key2: Pointer): sw_Integer;
  314. var K1: PNamedMark absolute Key1;
  315. K2: PNamedMark absolute Key2;
  316. R: integer;
  317. N1,N2: string;
  318. begin
  319. N1:=UpcaseStr(K1^.GetName); N2:=UpcaseStr(K2^.GetName);
  320. if N1<N2 then R:=-1 else
  321. if N1>N2 then R:= 1 else
  322. R:=0;
  323. Compare:=R;
  324. end;
  325. function TNamedMarkCollection.SearchMark(const Name: string): PNamedMark;
  326. var M,P: PNamedMark;
  327. I: sw_integer;
  328. begin
  329. New(M, Init(Name,0,0));
  330. if Search(M,I)=false then P:=nil else
  331. P:=At(I);
  332. Dispose(M, Done);
  333. SearchMark:=P;
  334. end;
  335. function TNamedMarkCollection.GetMarkPos(const Name: string; var P: TPoint): boolean;
  336. var M: PNamedMark;
  337. begin
  338. M:=SearchMark(Name);
  339. if Assigned(M) then
  340. P:=M^.Pos;
  341. GetMarkPos:=Assigned(M);
  342. end;
  343. procedure TNamedMarkCollection.Add(const Name: string; P: TPoint);
  344. begin
  345. Insert(New(PNamedMark, Init(Name, P.X, P.Y)));
  346. end;
  347. constructor THelpTopic.Init(ATopic: PTopic);
  348. begin
  349. inherited Init;
  350. Topic:=ATopic;
  351. New(Lines, Init(100,100)); New(Links, Init(50,50)); New(ColorAreas, Init(50,50));
  352. New(NamedMarks, Init(10,10));
  353. end;
  354. procedure THelpTopic.SetParams(AMargin, AWidth: sw_integer);
  355. begin
  356. if Width<>AWidth then
  357. begin
  358. Width:=AWidth; Margin:=AMargin;
  359. ReBuild;
  360. end;
  361. end;
  362. procedure THelpTopic.ReBuild;
  363. var TextPos,LinkNo,NamedMarkNo: sw_word;
  364. Line,CurWord: string;
  365. C: char;
  366. InLink,InCodeArea,InColorArea: boolean;
  367. LinkStart,LinkEnd,CodeAreaStart,CodeAreaEnd: TPoint;
  368. ColorAreaStart,ColorAreaEnd: TPoint;
  369. ColorAreaType: (atText,atFull);
  370. CurPos: TPoint;
  371. ZeroLevel: sw_integer;
  372. LineStart,NextLineStart: sw_integer;
  373. LineAlign : (laLeft,laCenter,laRight);
  374. FirstLink,LastLink: sw_integer;
  375. AreaColor: word;
  376. NextByte: (nbNormal,nbAreaColor);
  377. procedure ClearLine;
  378. begin
  379. Line:='';
  380. end;
  381. procedure AddWord(TheWord: string); forward;
  382. procedure NextLine;
  383. var P: sw_integer;
  384. I,Delta: sw_integer;
  385. begin
  386. Line:=CharStr(' ',Margin)+Line;
  387. repeat
  388. P:=Pos(#255,Line);
  389. if P>0 then Line[P]:=#32;
  390. until P=0;
  391. while copy(Line,length(Line),1)=' ' do Delete(Line,length(Line),1);
  392. Delta:=0;
  393. if Line<>'' then
  394. case LineAlign of
  395. laLeft : ;
  396. laCenter : if Margin+length(Line)+Margin<Width then
  397. begin
  398. Delta:=(Width-(Margin+length(Line)+Margin)) div 2;
  399. Line:=CharStr(' ',Delta)+Line;
  400. end;
  401. laRight : if Margin+length(Line)+Margin<Width then
  402. begin
  403. Delta:=Width-(Margin+length(Line)+Margin);
  404. Line:=CharStr(' ',Delta)+Line;
  405. end;
  406. end;
  407. if (Delta>0) and (FirstLink<>LastLink) then
  408. for I:=FirstLink to LastLink-1 do
  409. with PHelpLink(Links^.At(I))^ do
  410. Bounds.Move(Delta,0);
  411. if Line='' then Line:=' ';
  412. Lines^.Insert(NewStr(Line));
  413. ClearLine;
  414. LineStart:=NextLineStart;
  415. CurPos.X:=Margin+LineStart; Line:=CharStr(#255,LineStart); Inc(CurPos.Y);
  416. if InLink then LinkStart:=CurPos;
  417. FirstLink:=LastLink;
  418. end;
  419. procedure FlushLine;
  420. var W: string;
  421. begin
  422. if CurWord<>'' then begin W:=CurWord; CurWord:=''; AddWord(W); end;
  423. NextLine;
  424. end;
  425. procedure AddWord(TheWord: string);
  426. var W: string;
  427. begin
  428. W:=TheWord;
  429. while (length(W)>0) and (W[length(W)] in [' ',#255]) do
  430. Delete(W,length(W),1);
  431. if (copy(Line+TheWord,1,1)<>' ') then
  432. if (Line<>'') and (Margin+length(Line)+length(W)+Margin>Width) then
  433. NextLine;
  434. Line:=Line+TheWord;
  435. CurPos.X:=Margin+length(Line);
  436. end;
  437. procedure CheckZeroLevel;
  438. begin
  439. if ZeroLevel<>0 then
  440. begin
  441. if CurWord<>'' then AddWord(CurWord+' ');
  442. CurWord:='';
  443. ZeroLevel:=0;
  444. end;
  445. end;
  446. procedure EndColorArea;
  447. var Mask: word;
  448. begin
  449. if ColorAreaType=atText then Mask:=$f0 else Mask:=$00;
  450. if CurWord<>'' then AddWord(CurWord); CurWord:='';
  451. ColorAreaEnd:=CurPos; Dec(ColorAreaEnd.X);
  452. ColorAreas^.Insert(NewColorArea(AreaColor,Mask,ColorAreaStart,ColorAreaEnd));
  453. InColorArea:=false; AreaColor:=0;
  454. end;
  455. begin
  456. Lines^.FreeAll; Links^.FreeAll; NamedMarks^.FreeAll; ColorAreas^.FreeAll;
  457. if Topic=nil then Lines^.Insert(NewStr(msg_nohelpavailabelforthistopic)) else
  458. begin
  459. LineStart:=0; NextLineStart:=0;
  460. TextPos:=0; ClearLine; CurWord:=''; Line:='';
  461. CurPos.X:=Margin+LineStart; CurPos.Y:=0; LinkNo:=0;
  462. NamedMarkNo:=0;
  463. InLink:=false; InCodeArea:=false; InColorArea:=false; ZeroLevel:=0;
  464. LineAlign:=laLeft;
  465. FirstLink:=0; LastLink:=0; NextByte:=nbNormal;
  466. while (TextPos<Topic^.TextSize) do
  467. begin
  468. C:=chr(PByteArray(Topic^.Text)^[TextPos]);
  469. case NextByte of
  470. nbAreaColor :
  471. begin
  472. AreaColor:=ord(C);
  473. NextByte:=nbNormal;
  474. end;
  475. nbNormal :
  476. begin
  477. case C of
  478. hscLineBreak :
  479. {if ZeroLevel=0 then ZeroLevel:=1 else
  480. begin FlushLine; FlushLine; ZeroLevel:=0; end;}
  481. if InLink then CurWord:=CurWord+' ' else
  482. begin
  483. NextLineStart:=0;
  484. FlushLine;
  485. LineStart:=0;
  486. LineAlign:=laLeft;
  487. end;
  488. #1 : Break;
  489. hscLink :
  490. begin
  491. CheckZeroLevel;
  492. if InLink=false then
  493. begin LinkStart:=CurPos; InLink:=true; end else
  494. begin
  495. if CurWord<>'' then AddWord(CurWord); CurWord:='';
  496. LinkEnd:=CurPos; Dec(LinkEnd.X);
  497. if Topic^.Links<>nil then
  498. begin
  499. Inc(LastLink);
  500. if LinkNo<Topic^.LinkCount then
  501. Links^.Insert(NewLink(Topic^.Links^[LinkNo].FileID,
  502. Topic^.Links^[LinkNo].Context,LinkStart,LinkEnd));
  503. Inc(LinkNo);
  504. end;
  505. InLink:=false;
  506. end;
  507. end;
  508. hscLineStart :
  509. begin
  510. NextLineStart:=length(Line)+length(CurWord);
  511. { LineStart:=LineStart+(NextLineStart-LineStart);}
  512. end;
  513. hscCode :
  514. begin
  515. if InCodeArea=false then
  516. CodeAreaStart:=CurPos else
  517. begin
  518. if CurWord<>'' then AddWord(CurWord); CurWord:='';
  519. CodeAreaEnd:=CurPos; Dec(CodeAreaEnd.X);
  520. ColorAreas^.Insert(NewColorArea(CommentColor,$f0,CodeAreaStart,CodeAreaEnd));
  521. end;
  522. InCodeArea:=not InCodeArea;
  523. end;
  524. hscCenter :
  525. LineAlign:=laCenter;
  526. hscRight :
  527. LineAlign:=laCenter;
  528. hscNamedMark :
  529. begin
  530. if NamedMarkNo<Topic^.NamedMarks^.Count then
  531. NamedMarks^.Add(GetStr(Topic^.NamedMarks^.At(NamedMarkNo)),CurPos);
  532. Inc(NamedMarkNo);
  533. end;
  534. hscTextAttr,hscTextColor :
  535. begin
  536. if InColorArea then
  537. EndColorArea;
  538. if C=hscTextAttr then
  539. ColorAreaType:=atFull
  540. else
  541. ColorAreaType:=atText;
  542. NextByte:=nbAreaColor;
  543. ColorAreaStart:=CurPos;
  544. InColorArea:=true;
  545. end;
  546. hscNormText :
  547. begin
  548. if InColorArea then
  549. EndColorArea;
  550. end;
  551. #32: if InLink then CurWord:=CurWord+C else
  552. begin CheckZeroLevel; AddWord(CurWord+C); CurWord:=''; end;
  553. else begin CheckZeroLevel; CurWord:=CurWord+C; end;
  554. end;
  555. end;
  556. end;
  557. CurPos.X:=Margin+length(Line)+length(CurWord);
  558. Inc(TextPos);
  559. end;
  560. if (Line<>'') or (CurWord<>'') then FlushLine;
  561. end;
  562. end;
  563. function THelpTopic.GetLineCount: sw_integer;
  564. begin
  565. GetLineCount:=Lines^.Count;
  566. end;
  567. function THelpTopic.GetLineText(Line: sw_integer): string;
  568. var S: string;
  569. begin
  570. if Line<GetLineCount then S:=PString(Lines^.At(Line))^ else S:='';
  571. GetLineText:=S;
  572. end;
  573. function THelpTopic.GetLinkCount: sw_integer;
  574. begin
  575. GetLinkCount:=Links^.Count;
  576. end;
  577. procedure THelpTopic.GetLinkBounds(Index: sw_integer; var R: TRect);
  578. var P: PHelpLink;
  579. begin
  580. P:=Links^.At(Index);
  581. R:=P^.Bounds;
  582. end;
  583. function THelpTopic.GetLinkFileID(Index: sw_integer): word;
  584. var P: PHelpLink;
  585. begin
  586. P:=Links^.At(Index);
  587. GetLinkFileID:=P^.FileID;
  588. end;
  589. function THelpTopic.GetLinkContext(Index: sw_integer): THelpCtx;
  590. var P: PHelpLink;
  591. begin
  592. P:=Links^.At(Index);
  593. GetLinkContext:=P^.Context;
  594. end;
  595. function THelpTopic.GetColorAreaCount: sw_integer;
  596. begin
  597. GetColorAreaCount:=ColorAreas^.Count;
  598. end;
  599. procedure THelpTopic.GetColorAreaBounds(Index: sw_integer; var R: TRect);
  600. var P: PHelpColorArea;
  601. begin
  602. P:=ColorAreas^.At(Index);
  603. R:=P^.Bounds;
  604. end;
  605. function THelpTopic.GetColorAreaColor(Index: sw_integer): word;
  606. var P: PHelpColorArea;
  607. begin
  608. P:=ColorAreas^.At(Index);
  609. GetColorAreaColor:=P^.Color;
  610. end;
  611. function THelpTopic.GetColorAreaMask(Index: sw_integer): word;
  612. var P: PHelpColorArea;
  613. begin
  614. P:=ColorAreas^.At(Index);
  615. GetColorAreaMask:=P^.AttrMask;
  616. end;
  617. destructor THelpTopic.Done;
  618. begin
  619. inherited Done;
  620. Dispose(Lines, Done); Dispose(Links, Done); Dispose(ColorAreas, Done);
  621. Dispose(NamedMarks, Done);
  622. if (Topic<>nil) then DisposeTopic(Topic);
  623. end;
  624. constructor THelpViewer.Init(var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
  625. begin
  626. inherited Init(Bounds, AHScrollBar, AVScrollBar, nil, nil);
  627. Flags:=efInsertMode; ReadOnly:=true;
  628. New(WordList, Init(50,50));
  629. Margin:=1; CurLink:=-1;
  630. end;
  631. procedure THelpViewer.ChangeBounds(var Bounds: TRect);
  632. begin
  633. if Owner<>nil then Owner^.Lock;
  634. inherited ChangeBounds(Bounds);
  635. if (HelpTopic<>nil) and (HelpTopic^.Topic<>nil) and
  636. (HelpTopic^.Topic^.FileID<>0) then RenderTopic;
  637. if Owner<>nil then Owner^.UnLock;
  638. end;
  639. procedure THelpViewer.RenderTopic;
  640. begin
  641. if HelpTopic<>nil then
  642. HelpTopic^.SetParams(Margin,Size.X);
  643. {$ifndef EDITORS}
  644. SetLimit(255,GetLineCount);
  645. {$endif}
  646. DrawView;
  647. end;
  648. function THelpViewer.LinkContainsPoint(var R: TRect; var P: TPoint): boolean;
  649. var OK: boolean;
  650. begin
  651. if (R.A.Y=R.B.Y) then
  652. OK:= (P.Y=R.A.Y) and (R.A.X<=P.X) and (P.X<=R.B.X) else
  653. OK:=
  654. ( (R.A.Y=P.Y) and (R.A.X<=P.X) ) or
  655. ( (R.A.Y<P.Y) and (P.Y<R.B.Y) ) or
  656. ( (R.B.Y=P.Y) and (P.X<=R.B.X) );
  657. LinkContainsPoint:=OK;
  658. end;
  659. procedure THelpViewer.SetCurPtr(X,Y: sw_integer);
  660. var OldCurLink,I: sw_integer;
  661. OldPos,P: TPoint;
  662. R: TRect;
  663. begin
  664. OldPos:=CurPos;
  665. OldCurLink:=CurLink;
  666. inherited SetCurPtr(X,Y);
  667. CurLink:=-1;
  668. P:=CurPos;
  669. for I:=0 to GetLinkCount-1 do
  670. begin
  671. GetLinkBounds(I,R);
  672. if LinkContainsPoint(R,P) then
  673. begin CurLink:=I; Break; end;
  674. end;
  675. if OldCurLink<>CurLink then DrawView;
  676. if ((OldPos.X<>CurPos.X) or (OldPos.Y<>CurPos.Y)) and (InLookup=false) then
  677. Lookup('');
  678. end;
  679. function THelpViewer.GetLineCount: sw_integer;
  680. var Count: sw_integer;
  681. begin
  682. if HelpTopic=nil then Count:=0 else Count:=HelpTopic^.GetLineCount;
  683. GetLineCount:=Count;
  684. end;
  685. function THelpViewer.GetLine(LineNo: sw_integer): PCustomLine;
  686. begin
  687. {Abstract; used in wcedit unit ! }
  688. GetLine:=nil;
  689. end;
  690. function THelpViewer.GetDisplayText(I: sw_integer): string;
  691. begin
  692. GetDisplayText:=ExtractTabs(GetLineText(I),DefaultTabSize);
  693. end;
  694. function THelpViewer.GetLineText(Line: sw_integer): string;
  695. var S: string;
  696. begin
  697. if HelpTopic=nil then S:='' else S:=HelpTopic^.GetLineText(Line);
  698. GetLineText:=S;
  699. end;
  700. function THelpViewer.GetLinkCount: sw_integer;
  701. var Count: sw_integer;
  702. begin
  703. if HelpTopic=nil then Count:=0 else Count:=HelpTopic^.GetLinkCount;
  704. GetLinkCount:=Count;
  705. end;
  706. procedure THelpViewer.GetLinkBounds(Index: sw_integer; var R: TRect);
  707. begin
  708. HelpTopic^.GetLinkBounds(Index,R);
  709. end;
  710. function THelpViewer.GetLinkFileID(Index: sw_integer): word;
  711. begin
  712. GetLinkFileID:=HelpTopic^.GetLinkFileID(Index);
  713. end;
  714. function THelpViewer.GetLinkContext(Index: sw_integer): THelpCtx;
  715. begin
  716. GetLinkContext:=HelpTopic^.GetLinkContext(Index);
  717. end;
  718. function THelpViewer.GetLinkText(Index: sw_integer): string;
  719. var S: string;
  720. R: TRect;
  721. Y,StartX,EndX: sw_integer;
  722. begin
  723. S:=''; GetLinkBounds(Index,R);
  724. Y:=R.A.Y;
  725. while (Y<=R.B.Y) do
  726. begin
  727. if Y=R.A.Y then StartX:=R.A.X else StartX:=Margin;
  728. if Y=R.B.Y then EndX:=R.B.X else EndX:=High(S);
  729. S:=S+copy(GetLineText(Y),StartX+1,EndX-StartX+1);
  730. Inc(Y);
  731. end;
  732. GetLinkText:=S;
  733. end;
  734. function THelpViewer.GetColorAreaCount: sw_integer;
  735. var Count: sw_integer;
  736. begin
  737. if HelpTopic=nil then Count:=0 else Count:=HelpTopic^.GetColorAreaCount;
  738. GetColorAreaCount:=Count;
  739. end;
  740. procedure THelpViewer.GetColorAreaBounds(Index: sw_integer; var R: TRect);
  741. begin
  742. HelpTopic^.GetColorAreaBounds(Index,R);
  743. end;
  744. function THelpViewer.GetColorAreaColor(Index: sw_integer): word;
  745. begin
  746. GetColorAreaColor:=HelpTopic^.GetColorAreaColor(Index);
  747. end;
  748. function THelpViewer.GetColorAreaMask(Index: sw_integer): word;
  749. begin
  750. GetColorAreaMask:=HelpTopic^.GetColorAreaMask(Index);
  751. end;
  752. procedure THelpViewer.SelectNextLink(ANext: boolean);
  753. var I,Link: sw_integer;
  754. R: TRect;
  755. begin
  756. if HelpTopic=nil then Exit;
  757. Link:=CurLink;
  758. if Link<>-1 then
  759. begin
  760. if ANext then
  761. begin Inc(Link); if Link>=GetLinkCount then Link:=0; end else
  762. begin Dec(Link); if Link=-1 then Link:=GetLinkCount-1; end;
  763. end else
  764. for I:=0 to GetLinkCount-1 do
  765. begin
  766. GetLinkBounds(I,R);
  767. if (R.A.Y>CurPos.Y) or
  768. (R.A.Y=CurPos.Y) and (R.A.X>CurPos.X) then
  769. begin Link:=I; Break; end;
  770. end;
  771. if (Link=-1) and (GetLinkCount>0) then
  772. if ANext then Link:=0
  773. else Link:=GetLinkCount-1;
  774. SetCurLink(Link);
  775. end;
  776. procedure THelpViewer.SetCurLink(Link: sw_integer);
  777. var R: TRect;
  778. begin
  779. if Link<>-1 then
  780. begin
  781. GetLinkBounds(Link,R);
  782. SetCurPtr(R.A.X,R.A.Y);
  783. TrackCursor(true);
  784. end;
  785. end;
  786. procedure THelpViewer.SwitchToIndex;
  787. begin
  788. if IndexTopic=nil then
  789. IndexTopic:=HelpFacility^.BuildIndexTopic;
  790. ISwitchToTopicPtr(IndexTopic,true);
  791. end;
  792. procedure THelpViewer.SwitchToTopic(SourceFileID: word; Context: THelpCtx);
  793. begin
  794. ISwitchToTopic(SourceFileID,Context,true);
  795. end;
  796. procedure THelpViewer.ISwitchToTopic(SourceFileID: word; Context: THelpCtx; RecordInHistory: boolean);
  797. var P: PTopic;
  798. begin
  799. if HelpFacility=nil then P:=nil else
  800. if (SourceFileID=0) and (Context=0) and (HelpTopic<>nil) then
  801. P:=IndexTopic else
  802. P:=HelpFacility^.LoadTopic(SourceFileID, Context);
  803. ISwitchToTopicPtr(P,RecordInHistory);
  804. end;
  805. procedure THelpViewer.ISwitchToTopicPtr(P: PTopic; RecordInHistory: boolean);
  806. var HistoryFull: boolean;
  807. begin
  808. if (P<>nil) and RecordInHistory and (HelpTopic<>nil) then
  809. begin
  810. HistoryFull:=HistoryPtr>=HistorySize;
  811. if HistoryFull then
  812. Move(History[1],History[0],SizeOf(History)-SizeOf(History[0]));
  813. with History[HistoryPtr] do
  814. begin
  815. {SourceTopic_:=SourceTopic; }Context_:=HelpTopic^.Topic^.HelpCtx;
  816. FileID_:=HelpTopic^.Topic^.FileID;
  817. Delta_:=Delta; CurPos_:=CurPos; CurLink_:=CurLink;
  818. end;
  819. if HistoryFull=false then Inc(HistoryPtr);
  820. end;
  821. if Owner<>nil then Owner^.Lock;
  822. SetTopic(P);
  823. DrawView;
  824. if Owner<>nil then Owner^.UnLock;
  825. end;
  826. procedure THelpViewer.PrevTopic;
  827. begin
  828. if HistoryPtr>0 then
  829. begin
  830. if Owner<>nil then Owner^.Lock;
  831. Dec(HistoryPtr);
  832. with History[HistoryPtr] do
  833. begin
  834. ISwitchToTopic(FileID_,Context_,false);
  835. ScrollTo(Delta_.X,Delta_.Y);
  836. SetCurPtr(CurPos_.X,CurPos_.Y);
  837. TrackCursor(false);
  838. if CurLink<>CurLink_ then SetCurLink(CurLink_);
  839. end;
  840. DrawView;
  841. if Owner<>nil then Owner^.UnLock;
  842. end;
  843. end;
  844. procedure THelpViewer.SetTopic(Topic: PTopic);
  845. var Bookmark: string;
  846. P: TPoint;
  847. begin
  848. CurLink:=-1;
  849. if (HelpTopic=nil) or (Topic<>HelpTopic^.Topic) then
  850. begin
  851. if (HelpTopic<>nil) and (HelpTopic<>IndexHelpTopic) then
  852. Dispose(HelpTopic, Done);
  853. HelpTopic:=nil;
  854. if Topic<>nil then
  855. begin
  856. if (Topic=IndexTopic) and (IndexHelpTopic<>nil) then
  857. HelpTopic:=IndexHelpTopic else
  858. New(HelpTopic, Init(Topic));
  859. if Topic=IndexTopic then
  860. IndexHelpTopic:=HelpTopic;
  861. end;
  862. end;
  863. if Owner<>nil then Owner^.Lock;
  864. SetCurPtr(0,0); TrackCursor(false);
  865. RenderTopic;
  866. BuildTopicWordList;
  867. Lookup('');
  868. if Assigned(Topic) then
  869. if Topic^.StartNamedMark>0 then
  870. if Topic^.NamedMarks^.Count>=Topic^.StartNamedMark then
  871. begin
  872. Bookmark:=GetStr(Topic^.NamedMarks^.At(Topic^.StartNamedMark-1));
  873. if HelpTopic^.NamedMarks^.GetMarkPos(Bookmark,P) then
  874. begin
  875. SetCurPtr(P.X,P.Y);
  876. ScrollTo(0,Max(0,P.Y-1));
  877. end;
  878. end;
  879. SetSelection(CurPos,CurPos);
  880. DrawView;
  881. if Owner<>nil then Owner^.UnLock;
  882. end;
  883. procedure THelpViewer.BuildTopicWordList;
  884. var I: sw_integer;
  885. begin
  886. WordList^.FreeAll;
  887. for I:=0 to GetLinkCount-1 do
  888. WordList^.Insert(NewKeyword(I,Trim(GetLinkText(I))));
  889. end;
  890. procedure THelpViewer.Lookup(S: string);
  891. var Index, I: Sw_integer;
  892. W: string;
  893. OldLookup: string;
  894. R: TRect;
  895. P: PHelpKeyword;
  896. begin
  897. InLookup:=true;
  898. OldLookup:=LookupWord;
  899. S:=UpcaseStr(S);
  900. Index:=-1;
  901. I:=0; {J:=0;
  902. while (J<GetLinkCount) do
  903. begin
  904. GetLinkBounds(J,R);
  905. if (R.A.Y<CurPos.Y) or ((R.A.Y=CurPos.Y) and (R.B.X<CurPos.X))
  906. then Inc(J) else
  907. begin I:=J; Break; end;
  908. end;}
  909. if S='' then LookupWord:='' else
  910. begin
  911. while (Index=-1) and (I<WordList^.Count) do
  912. begin
  913. P:=WordList^.At(I);
  914. if P^.KWord<>nil then
  915. begin
  916. W:=UpcaseStr(Trim(P^.KWord^));
  917. if copy(W,1,length(S))=S then Index:=I;
  918. end;
  919. { if W>S then Break else}
  920. Inc(I);
  921. end;
  922. if Index<>-1 then
  923. begin
  924. W:=Trim(WordList^.At(Index)^.KWord^);
  925. LookupWord:=copy(W,1,length(S));
  926. end;
  927. end;
  928. if LookupWord<>OldLookup then
  929. begin
  930. if Index=-1 then SetCurLink(CurLink) else
  931. begin
  932. if Owner<>nil then Owner^.Lock;
  933. P:=WordList^.At(Index);
  934. S:=GetLinkText(P^.Index);
  935. I:=Pos(LookupWord,S); if I=0 then I:=1;
  936. GetLinkBounds(P^.Index,R);
  937. SetCurPtr(R.A.X+(I-1)+length(Lookupword),R.A.Y);
  938. CurLink:=P^.Index; DrawView;
  939. TrackCursor(true);
  940. if Owner<>nil then Owner^.UnLock;
  941. end;
  942. end;
  943. InLookup:=false;
  944. end;
  945. procedure THelpViewer.SelectLink(Index: sw_integer);
  946. var ID: word;
  947. Ctx: THelpCtx;
  948. begin
  949. if Index=-1 then Exit;
  950. if HelpTopic=nil then begin ID:=0; Ctx:=0; end else
  951. begin
  952. ID:=GetLinkFileID(Index);
  953. Ctx:=GetLinkContext(Index);
  954. end;
  955. SwitchToTopic(ID,Ctx);
  956. end;
  957. procedure THelpViewer.HandleEvent(var Event: TEvent);
  958. var DontClear: boolean;
  959. procedure GetMousePos(var P: TPoint);
  960. begin
  961. MakeLocal(Event.Where,P);
  962. Inc(P.X,Delta.X); Inc(P.Y,Delta.Y);
  963. end;
  964. begin
  965. case Event.What of
  966. evMouseDown :
  967. if MouseInView(Event.Where) then
  968. if (Event.Buttons=mbLeftButton) and (Event.Double) then
  969. begin
  970. inherited HandleEvent(Event);
  971. if CurLink<>-1 then
  972. SelectLink(CurLink);
  973. end;
  974. evBroadcast :
  975. case Event.Command of
  976. cmHelpFilesChanged :
  977. begin
  978. if HelpTopic=IndexHelpTopic then HelpTopic:=nil;
  979. IndexTopic:=nil;
  980. if IndexHelpTopic<>nil then Dispose(IndexHelpTopic, Done);
  981. IndexHelpTopic:=nil;
  982. end;
  983. end;
  984. evCommand :
  985. begin
  986. DontClear:=false;
  987. case Event.Command of
  988. cmPrevTopic :
  989. PrevTopic;
  990. else DontClear:=true;
  991. end;
  992. if DontClear=false then ClearEvent(Event);
  993. end;
  994. evKeyDown :
  995. begin
  996. DontClear:=false;
  997. case Event.KeyCode of
  998. kbTab :
  999. SelectNextLink(true);
  1000. kbShiftTab :
  1001. begin NoSelect:=true; SelectNextLink(false); NoSelect:=false; end;
  1002. kbEnter :
  1003. if CurLink<>-1 then
  1004. SelectLink(CurLink);
  1005. else
  1006. case Event.CharCode of
  1007. #32..#255 :
  1008. begin NoSelect:=true; Lookup(LookupWord+Event.CharCode); NoSelect:=false; end;
  1009. else DontClear:=true;
  1010. end;
  1011. end;
  1012. TrackCursor(false);
  1013. if DontClear=false then ClearEvent(Event);
  1014. end;
  1015. end;
  1016. inherited HandleEvent(Event);
  1017. end;
  1018. procedure THelpViewer.Draw;
  1019. var NormalColor, LinkColor,
  1020. SelectColor, SelectionColor: word;
  1021. B: TDrawBuffer;
  1022. DX,DY,X,Y,I,MinX,MaxX,ScreenX: sw_integer;
  1023. LastLinkDrawn,LastColorAreaDrawn: sw_integer;
  1024. S: string;
  1025. R: TRect;
  1026. {$ifndef EDITORS}
  1027. SelR : TRect;
  1028. {$endif}
  1029. C,Mask: word;
  1030. CurP: TPoint;
  1031. ANDSB,ORSB: word;
  1032. begin
  1033. if LockFlag>0 then
  1034. begin
  1035. DrawCalled:=true;
  1036. Exit;
  1037. end;
  1038. DrawCalled:=false;
  1039. NormalColor:=GetColor(1); LinkColor:=GetColor(2);
  1040. SelectColor:=GetColor(3); SelectionColor:=GetColor(4);
  1041. {$ifndef EDITORS}
  1042. SelR.A:=SelStart; SelR.B:=SelEnd;
  1043. {$endif}
  1044. LastLinkDrawn:=0; LastColorAreaDrawn:=0;
  1045. for DY:=0 to Size.Y-1 do
  1046. begin
  1047. Y:=Delta.Y+DY;
  1048. MoveChar(B,' ',NormalColor,Size.X);
  1049. if Y<GetLineCount then
  1050. begin
  1051. S:=copy(GetLineText(Y),Delta.X+1,High(S));
  1052. S:=copy(S,1,MaxViewWidth);
  1053. MoveStr(B,S,NormalColor);
  1054. for I:=LastColorAreaDrawn to GetColorAreaCount-1 do
  1055. begin
  1056. GetColorAreaBounds(I,R);
  1057. if R.A.Y>Y then Break;
  1058. LastColorAreaDrawn:=I;
  1059. if Y=R.B.Y then MaxX:=R.B.X else MaxX:=(length(S)-1);
  1060. if Y=R.A.Y then MinX:=R.A.X else MinX:=0;
  1061. if (R.A.Y<=Y) and (Y<=R.B.Y) then
  1062. begin
  1063. C:=GetColorAreaColor(I);
  1064. Mask:=GetColorAreaMask(I);
  1065. for DX:=MinX to MaxX do
  1066. begin
  1067. X:=DX;
  1068. ScreenX:=X-(Delta.X);
  1069. if (ScreenX>0) and (ScreenX<=High(B)) then
  1070. begin
  1071. { CurP.X:=X; CurP.Y:=Y;
  1072. if LinkAreaContainsPoint(R,CurP) then}
  1073. (* B[ScreenX]:=(B[ScreenX] and $f0ff) or (C shl 8);*)
  1074. ANDSB:=(Mask shl 8)+$ff;
  1075. ORSB:=(C shl 8);
  1076. B[ScreenX]:=(B[ScreenX] and ANDSB) or ORSB;
  1077. end;
  1078. end;
  1079. end;
  1080. end;
  1081. for I:=LastLinkDrawn to GetLinkCount-1 do
  1082. begin
  1083. GetLinkBounds(I,R);
  1084. if R.A.Y>Y then Break;
  1085. LastLinkDrawn:=I;
  1086. if Y=R.B.Y then MaxX:=R.B.X else MaxX:=(length(S)-1);
  1087. if Y=R.A.Y then MinX:=R.A.X else MinX:=0;
  1088. if (R.A.Y<=Y) and (Y<=R.B.Y) then
  1089. for DX:=MinX to MaxX do
  1090. begin
  1091. X:=DX;
  1092. ScreenX:=X-(Delta.X);
  1093. if (ScreenX>=0) and (ScreenX<=High(B)) then
  1094. begin
  1095. CurP.X:=X; CurP.Y:=Y;
  1096. if LinkContainsPoint(R,CurP) then
  1097. if I=CurLink then C:=SelectColor else C:=LinkColor;
  1098. B[ScreenX]:=(B[ScreenX] and $ff) or (C shl 8);
  1099. end;
  1100. end;
  1101. end;
  1102. {$ifndef EDITORS}
  1103. if ((SelR.A.X<>SelR.B.X) or (SelR.A.Y<>SelR.B.Y)) and (SelR.A.Y<=Y) and (Y<=SelR.B.Y) then
  1104. begin
  1105. if Y=SelR.A.Y then MinX:=SelR.A.X else MinX:=0;
  1106. if Y=SelR.B.Y then MaxX:=SelR.B.X-1 else MaxX:=High(string);
  1107. for DX:=MinX to MaxX do
  1108. begin
  1109. X:=DX;
  1110. ScreenX:=X-(Delta.X);
  1111. if (ScreenX>=0) and (ScreenX<High(B)) then
  1112. B[ScreenX]:=(B[ScreenX] and $0fff) or ((SelectionColor and $f0) shl 8);
  1113. end;
  1114. end;
  1115. {$endif}
  1116. end;
  1117. WriteLine(0,DY,Size.X,1,B);
  1118. end;
  1119. DrawCursor;
  1120. end;
  1121. function THelpViewer.GetPalette: PPalette;
  1122. const P: string[length(CHelpViewer)] = CHelpViewer;
  1123. begin
  1124. GetPalette:=@P;
  1125. end;
  1126. constructor THelpViewer.Load(var S: TStream);
  1127. begin
  1128. inherited Load(S);
  1129. end;
  1130. procedure THelpViewer.Store(var S: TStream);
  1131. begin
  1132. inherited Store(S);
  1133. end;
  1134. destructor THelpViewer.Done;
  1135. begin
  1136. inherited Done;
  1137. if assigned(WordList) then
  1138. Dispose(WordList, Done);
  1139. end;
  1140. function THelpFrame.GetPalette: PPalette;
  1141. const P: string[length(CHelpFrame)] = CHelpFrame;
  1142. begin
  1143. GetPalette:=@P;
  1144. end;
  1145. constructor THelpWindow.Init(var Bounds: TRect; ATitle: TTitleStr; ASourceFileID: word; AContext: THelpCtx; ANumber: Integer);
  1146. begin
  1147. inherited Init(Bounds, ATitle, ANumber);
  1148. InitScrollBars;
  1149. if Assigned(HSB) then Insert(HSB);
  1150. if Assigned(VSB) then Insert(VSB);
  1151. InitHelpView;
  1152. if Assigned(HelpView) then
  1153. begin
  1154. if (ASourceFileID<>0) or (AContext<>0) then
  1155. ShowTopic(ASourceFileID, AContext);
  1156. Insert(HelpView);
  1157. end;
  1158. end;
  1159. procedure THelpWindow.InitScrollBars;
  1160. var R: TRect;
  1161. begin
  1162. GetExtent(R); R.Grow(0,-1); R.A.X:=R.B.X-1;
  1163. New(VSB, Init(R)); VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;
  1164. GetExtent(R); R.Grow(-1,0); R.A.Y:=R.B.Y-1;
  1165. New(HSB, Init(R)); HSB^.GrowMode:=gfGrowLoY+gfGrowHiX+gfGrowHiY;
  1166. end;
  1167. procedure THelpWindow.InitHelpView;
  1168. var R: TRect;
  1169. begin
  1170. GetExtent(R); R.Grow(-1,-1);
  1171. New(HelpView, Init(R, HSB, VSB));
  1172. HelpView^.GrowMode:=gfGrowHiX+gfGrowHiY;
  1173. end;
  1174. procedure THelpWindow.InitFrame;
  1175. var R: TRect;
  1176. begin
  1177. GetExtent(R);
  1178. Frame:=New(PHelpFrame, Init(R));
  1179. end;
  1180. procedure THelpWindow.ShowIndex;
  1181. begin
  1182. HelpView^.SwitchToIndex;
  1183. end;
  1184. procedure THelpWindow.ShowTopic(SourceFileID: word; Context: THelpCtx);
  1185. begin
  1186. HelpView^.SwitchToTopic(SourceFileID, Context);
  1187. end;
  1188. procedure THelpWindow.HandleEvent(var Event: TEvent);
  1189. begin
  1190. case Event.What of
  1191. evKeyDown :
  1192. case Event.KeyCode of
  1193. kbEsc :
  1194. begin
  1195. Event.What:=evCommand; Event.Command:=cmClose;
  1196. end;
  1197. end;
  1198. end;
  1199. inherited HandleEvent(Event);
  1200. end;
  1201. procedure THelpWindow.Close;
  1202. begin
  1203. if HideOnClose then Hide else inherited Close;
  1204. end;
  1205. function THelpWindow.GetPalette: PPalette;
  1206. begin
  1207. GetPalette:=nil;
  1208. end;
  1209. END.
  1210. {
  1211. $Log$
  1212. Revision 1.2 2000-11-15 00:14:11 pierre
  1213. new merge
  1214. Revision 1.1.2.1 2000/11/14 23:41:33 pierre
  1215. * fix for bug 1234
  1216. Revision 1.1 2000/07/13 09:48:37 michael
  1217. + Initial import
  1218. Revision 1.18 2000/06/22 09:07:14 pierre
  1219. * Gabor changes: see fixes.txt
  1220. Revision 1.17 2000/06/16 08:50:45 pierre
  1221. + new bunch of Gabor's changes
  1222. Revision 1.16 2000/05/30 07:18:33 pierre
  1223. + colors for HTML help by Gabor
  1224. Revision 1.15 2000/05/29 10:45:00 pierre
  1225. + New bunch of Gabor's changes: see fixes.txt
  1226. Revision 1.14 2000/04/25 08:42:35 pierre
  1227. * New Gabor changes : see fixes.txt
  1228. Revision 1.13 2000/04/18 11:42:39 pierre
  1229. lot of Gabor changes : see fixes.txt
  1230. Revision 1.12 2000/03/21 23:21:38 pierre
  1231. adapted to wcedit addition
  1232. Revision 1.11 2000/02/07 08:29:13 michael
  1233. [*] the fake (!) TOKENS.PAS still contained the typo bug
  1234. FSplit(,n,d,e) (correctly FSplit(,d,n,e))
  1235. [*] CodeComplete had a very ugly bug - coordinates were document-relative
  1236. (instead of being screen-relative)
  1237. [*] TResourceStream didn't count the size of the resource names when
  1238. determining the file size and this could lead to the last resources not
  1239. loaded correctly
  1240. [+] Ctrl-Enter in editor now tries to open the file at cursor
  1241. [+] CodeComplete option added to Options|Environment|Editor
  1242. [+] user interface for managing CodeComplete implemented
  1243. [+] user interface for CodeTemplates implemented
  1244. [+] CodeComplete wordlist and CodeTemplates stored in desktop file
  1245. [+] help topic size no longer limited to 64KB when compiled with FPC
  1246. Revision 1.10 1999/08/16 18:25:31 peter
  1247. * Adjusting the selection when the editor didn't contain any line.
  1248. * Reserved word recognition redesigned, but this didn't affect the overall
  1249. syntax highlight speed remarkably (at least not on my Amd-K6/350).
  1250. The syntax scanner loop is a bit slow but the main problem is the
  1251. recognition of special symbols. Switching off symbol processing boosts
  1252. the performance up to ca. 200%...
  1253. * The editor didn't allow copying (for ex to clipboard) of a single character
  1254. * 'File|Save as' caused permanently run-time error 3. Not any more now...
  1255. * Compiler Messages window (actually the whole desktop) did not act on any
  1256. keypress when compilation failed and thus the window remained visible
  1257. + Message windows are now closed upon pressing Esc
  1258. + At 'Run' the IDE checks whether any sources are modified, and recompiles
  1259. only when neccessary
  1260. + BlockRead and BlockWrite (Ctrl+K+R/W) implemented in TCodeEditor
  1261. + LineSelect (Ctrl+K+L) implemented
  1262. * The IDE had problems closing help windows before saving the desktop
  1263. Revision 1.9 1999/06/28 19:32:35 peter
  1264. * fixes from gabor
  1265. Revision 1.8 1999/04/07 21:56:02 peter
  1266. + object support for browser
  1267. * html help fixes
  1268. * more desktop saving things
  1269. * NODEBUG directive to exclude debugger
  1270. Revision 1.7 1999/03/08 14:58:20 peter
  1271. + prompt with dialogs for tools
  1272. Revision 1.6 1999/03/01 15:42:13 peter
  1273. + Added dummy entries for functions not yet implemented
  1274. * MenuBar didn't update itself automatically on command-set changes
  1275. * Fixed Debugging/Profiling options dialog
  1276. * TCodeEditor converts spaces to tabs at save only if efUseTabChars is set
  1277. * efBackSpaceUnindents works correctly
  1278. + 'Messages' window implemented
  1279. + Added '$CAP MSG()' and '$CAP EDIT' to available tool-macros
  1280. + Added TP message-filter support (for ex. you can call GREP thru
  1281. GREP2MSG and view the result in the messages window - just like in TP)
  1282. * A 'var' was missing from the param-list of THelpFacility.TopicSearch,
  1283. so topic search didn't work...
  1284. * In FPHELP.PAS there were still context-variables defined as word instead
  1285. of THelpCtx
  1286. * StdStatusKeys() was missing from the statusdef for help windows
  1287. + Topic-title for index-table can be specified when adding a HTML-files
  1288. Revision 1.5 1999/02/18 13:44:38 peter
  1289. * search fixed
  1290. + backward search
  1291. * help fixes
  1292. * browser updates
  1293. Revision 1.4 1999/02/08 10:37:47 peter
  1294. + html helpviewer
  1295. Revision 1.3 1999/01/21 11:54:32 peter
  1296. + tools menu
  1297. + speedsearch in symbolbrowser
  1298. * working run command
  1299. Revision 1.2 1998/12/28 15:47:57 peter
  1300. + Added user screen support, display & window
  1301. + Implemented Editor,Mouse Options dialog
  1302. + Added location of .INI and .CFG file
  1303. + Option (INI) file managment implemented (see bottom of Options Menu)
  1304. + Switches updated
  1305. + Run program
  1306. Revision 1.31 1998/12/27 12:07:30 gabor
  1307. * changed THelpViewer.Init to reflect changes in WEDITOR
  1308. Revision 1.3 1998/12/22 10:39:56 peter
  1309. + options are now written/read
  1310. + find and replace routines
  1311. }