whlpview.pas 41 KB

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