whlpview.pas 39 KB

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