whlpview.pas 39 KB

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