whlpview.pas 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405
  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(true);
  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(false);
  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 Owner^.Lock;
  938. SetCurPtr(0,0); TrackCursor(false);
  939. RenderTopic;
  940. BuildTopicWordList;
  941. Lookup('');
  942. if Assigned(Topic) then
  943. if Topic^.StartNamedMark>0 then
  944. if Topic^.NamedMarks^.Count>=Topic^.StartNamedMark then
  945. begin
  946. Bookmark:=GetStr(Topic^.NamedMarks^.At(Topic^.StartNamedMark-1));
  947. if HelpTopic^.NamedMarks^.GetMarkPos(Bookmark,P) then
  948. begin
  949. SetCurPtr(P.X,P.Y);
  950. ScrollTo(0,Max(0,P.Y-1));
  951. end;
  952. end;
  953. SetSelection(CurPos,CurPos);
  954. DrawView;
  955. if Owner<>nil then Owner^.UnLock;
  956. end;
  957. procedure THelpViewer.BuildTopicWordList;
  958. var I: sw_integer;
  959. begin
  960. WordList^.FreeAll;
  961. for I:=0 to GetLinkCount-1 do
  962. WordList^.Insert(NewKeyword(I,Trim(GetLinkText(I))));
  963. end;
  964. procedure THelpViewer.Lookup(S: string);
  965. var Index, I: Sw_integer;
  966. W: string;
  967. OldLookup: string;
  968. R: TRect;
  969. P: PHelpKeyword;
  970. begin
  971. InLookup:=true;
  972. OldLookup:=LookupWord;
  973. S:=UpcaseStr(S);
  974. Index:=-1;
  975. I:=0; {J:=0;
  976. while (J<GetLinkCount) do
  977. begin
  978. GetLinkBounds(J,R);
  979. if (R.A.Y<CurPos.Y) or ((R.A.Y=CurPos.Y) and (R.B.X<CurPos.X))
  980. then Inc(J) else
  981. begin I:=J; Break; end;
  982. end;}
  983. if S='' then LookupWord:='' else
  984. begin
  985. while (Index=-1) and (I<WordList^.Count) do
  986. begin
  987. P:=WordList^.At(I);
  988. if P^.KWord<>nil then
  989. begin
  990. W:=UpcaseStr(Trim(P^.KWord^));
  991. if copy(W,1,length(S))=S then Index:=I;
  992. end;
  993. { if W>S then Break else}
  994. Inc(I);
  995. end;
  996. if Index<>-1 then
  997. begin
  998. W:=Trim(WordList^.At(Index)^.KWord^);
  999. LookupWord:=copy(W,1,length(S));
  1000. end;
  1001. end;
  1002. if LookupWord<>OldLookup then
  1003. begin
  1004. if Index=-1 then SetCurLink(CurLink) else
  1005. begin
  1006. if Owner<>nil then Owner^.Lock;
  1007. P:=WordList^.At(Index);
  1008. S:=GetLinkText(P^.Index);
  1009. I:=Pos(LookupWord,S); if I=0 then I:=1;
  1010. GetLinkBounds(P^.Index,R);
  1011. SetCurPtr(R.A.X+(I-1)+length(Lookupword),R.A.Y);
  1012. CurLink:=P^.Index; DrawView;
  1013. TrackCursor(true);
  1014. if Owner<>nil then Owner^.UnLock;
  1015. end;
  1016. end;
  1017. InLookup:=false;
  1018. end;
  1019. procedure THelpViewer.SelectLink(Index: sw_integer);
  1020. var ID: word;
  1021. Ctx: THelpCtx;
  1022. begin
  1023. if Index=-1 then Exit;
  1024. if HelpTopic=nil then begin ID:=0; Ctx:=0; end else
  1025. begin
  1026. ID:=GetLinkFileID(Index);
  1027. Ctx:=GetLinkContext(Index);
  1028. end;
  1029. SwitchToTopic(ID,Ctx);
  1030. end;
  1031. procedure THelpViewer.HandleEvent(var Event: TEvent);
  1032. var DontClear: boolean;
  1033. procedure GetMousePos(var P: TPoint);
  1034. begin
  1035. MakeLocal(Event.Where,P);
  1036. Inc(P.X,Delta.X); Inc(P.Y,Delta.Y);
  1037. end;
  1038. begin
  1039. case Event.What of
  1040. evMouseDown :
  1041. if MouseInView(Event.Where) then
  1042. if (Event.Buttons=mbLeftButton) and (Event.Double) then
  1043. begin
  1044. inherited HandleEvent(Event);
  1045. if CurLink<>-1 then
  1046. SelectLink(CurLink);
  1047. end;
  1048. evBroadcast :
  1049. case Event.Command of
  1050. cmHelpFilesChanged :
  1051. begin
  1052. if HelpTopic=IndexHelpTopic then HelpTopic:=nil;
  1053. IndexTopic:=nil;
  1054. if IndexHelpTopic<>nil then Dispose(IndexHelpTopic, Done);
  1055. IndexHelpTopic:=nil;
  1056. end;
  1057. end;
  1058. evCommand :
  1059. begin
  1060. DontClear:=false;
  1061. case Event.Command of
  1062. cmPrevTopic :
  1063. PrevTopic;
  1064. else DontClear:=true;
  1065. end;
  1066. if DontClear=false then ClearEvent(Event);
  1067. end;
  1068. evKeyDown :
  1069. begin
  1070. DontClear:=false;
  1071. case Event.KeyCode of
  1072. kbTab :
  1073. SelectNextLink(true);
  1074. kbShiftTab :
  1075. begin NoSelect:=true; SelectNextLink(false); NoSelect:=false; end;
  1076. kbEnter :
  1077. if CurLink<>-1 then
  1078. SelectLink(CurLink);
  1079. kbBack,kbDel :
  1080. if Length(LookupWord)>0 then
  1081. Lookup(Copy(LookupWord,1,Length(LookupWord)-1));
  1082. else
  1083. case Event.CharCode of
  1084. #32..#255 :
  1085. begin NoSelect:=true; Lookup(LookupWord+Event.CharCode); NoSelect:=false; end;
  1086. else DontClear:=true;
  1087. end;
  1088. end;
  1089. TrackCursor(false);
  1090. if DontClear=false then ClearEvent(Event);
  1091. end;
  1092. end;
  1093. inherited HandleEvent(Event);
  1094. end;
  1095. procedure THelpViewer.Draw;
  1096. var NormalColor, LinkColor,
  1097. SelectColor, SelectionColor: word;
  1098. B: TDrawBuffer;
  1099. DX,DY,X,Y,I,MinX,MaxX,ScreenX: sw_integer;
  1100. LastLinkDrawn,LastColorAreaDrawn: sw_integer;
  1101. S: string;
  1102. R: TRect;
  1103. SelR : TRect;
  1104. C,Mask: word;
  1105. CurP: TPoint;
  1106. ANDSB,ORSB: word;
  1107. begin
  1108. if ELockFlag>0 then
  1109. begin
  1110. DrawCalled:=true;
  1111. Exit;
  1112. end;
  1113. DrawCalled:=false;
  1114. NormalColor:=GetColor(1); LinkColor:=GetColor(2);
  1115. SelectColor:=GetColor(3); SelectionColor:=GetColor(4);
  1116. SelR.A:=SelStart; SelR.B:=SelEnd;
  1117. LastLinkDrawn:=0; LastColorAreaDrawn:=0;
  1118. for DY:=0 to Size.Y-1 do
  1119. begin
  1120. Y:=Delta.Y+DY;
  1121. MoveChar(B,' ',NormalColor,Size.X);
  1122. if Y<GetLineCount then
  1123. begin
  1124. S:=copy(GetLineText(Y),Delta.X+1,High(S));
  1125. S:=copy(S,1,MaxViewWidth);
  1126. MoveStr(B,S,NormalColor);
  1127. for I:=LastColorAreaDrawn to GetColorAreaCount-1 do
  1128. begin
  1129. GetColorAreaBounds(I,R);
  1130. if R.A.Y>Y then Break;
  1131. LastColorAreaDrawn:=I;
  1132. if Y=R.B.Y then MaxX:=R.B.X else MaxX:=(length(S)+Delta.X-1);
  1133. if Y=R.A.Y then MinX:=R.A.X else MinX:=0;
  1134. if (R.A.Y<=Y) and (Y<=R.B.Y) then
  1135. begin
  1136. C:=GetColorAreaColor(I);
  1137. Mask:=GetColorAreaMask(I);
  1138. for DX:=MinX to MaxX do
  1139. begin
  1140. X:=DX;
  1141. ScreenX:=X-(Delta.X);
  1142. if (ScreenX>=0) and (ScreenX<=High(B)) then
  1143. begin
  1144. { CurP.X:=X; CurP.Y:=Y;
  1145. if LinkAreaContainsPoint(R,CurP) then}
  1146. (* B[ScreenX]:=(B[ScreenX] and $f0ff) or (C shl 8);*)
  1147. ANDSB:=(Mask shl 8)+$ff;
  1148. ORSB:=(C shl 8);
  1149. B[ScreenX]:=(B[ScreenX] and ANDSB) or ORSB;
  1150. end;
  1151. end;
  1152. end;
  1153. end;
  1154. for I:=LastLinkDrawn to GetLinkCount-1 do
  1155. begin
  1156. GetLinkBounds(I,R);
  1157. if R.A.Y>Y then Break;
  1158. LastLinkDrawn:=I;
  1159. if Y=R.B.Y then MaxX:=R.B.X else MaxX:=(length(S)-1);
  1160. if Y=R.A.Y then MinX:=R.A.X else MinX:=0;
  1161. if (R.A.Y<=Y) and (Y<=R.B.Y) then
  1162. for DX:=MinX to MaxX do
  1163. begin
  1164. X:=DX;
  1165. ScreenX:=X-(Delta.X);
  1166. if (ScreenX>=0) and (ScreenX<=High(B)) then
  1167. begin
  1168. CurP.X:=X; CurP.Y:=Y;
  1169. if LinkContainsPoint(R,CurP) then
  1170. if I=CurLink then C:=SelectColor else C:=LinkColor;
  1171. B[ScreenX]:=(B[ScreenX] and $ff) or (C shl 8);
  1172. end;
  1173. end;
  1174. end;
  1175. 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
  1176. begin
  1177. if Y=SelR.A.Y then MinX:=SelR.A.X else MinX:=0;
  1178. if Y=SelR.B.Y then MaxX:=SelR.B.X-1 else MaxX:=High(string);
  1179. for DX:=MinX to MaxX do
  1180. begin
  1181. X:=DX;
  1182. ScreenX:=X-(Delta.X);
  1183. if (ScreenX>=0) and (ScreenX<High(B)) then
  1184. B[ScreenX]:=(B[ScreenX] and $0fff) or ((SelectionColor and $f0) shl 8);
  1185. end;
  1186. end;
  1187. end;
  1188. WriteLine(0,DY,Size.X,1,B);
  1189. end;
  1190. DrawCursor;
  1191. end;
  1192. function THelpViewer.GetPalette: PPalette;
  1193. const P: string[length(CHelpViewer)] = CHelpViewer;
  1194. begin
  1195. GetPalette:=@P;
  1196. end;
  1197. constructor THelpViewer.Load(var S: TStream);
  1198. begin
  1199. inherited Load(S);
  1200. end;
  1201. procedure THelpViewer.Store(var S: TStream);
  1202. begin
  1203. inherited Store(S);
  1204. end;
  1205. destructor THelpViewer.Done;
  1206. begin
  1207. if (HelpTopic<>nil) and (HelpTopic<>IndexHelpTopic) then
  1208. Dispose(HelpTopic, Done);
  1209. HelpTopic:=nil;
  1210. if IndexHelpTopic<>nil then
  1211. Dispose(IndexHelpTopic, Done);
  1212. IndexHelpTopic:=nil;
  1213. inherited Done;
  1214. if assigned(WordList) then
  1215. Dispose(WordList, Done);
  1216. end;
  1217. function THelpFrame.GetPalette: PPalette;
  1218. const P: string[length(CHelpFrame)] = CHelpFrame;
  1219. begin
  1220. GetPalette:=@P;
  1221. end;
  1222. constructor THelpWindow.Init(var Bounds: TRect; ATitle: TTitleStr; ASourceFileID: word; AContext: THelpCtx; ANumber: Integer);
  1223. begin
  1224. inherited Init(Bounds, ATitle, ANumber);
  1225. InitScrollBars;
  1226. if Assigned(HSB) then Insert(HSB);
  1227. if Assigned(VSB) then Insert(VSB);
  1228. InitHelpView;
  1229. if Assigned(HelpView) then
  1230. begin
  1231. if (ASourceFileID<>0) or (AContext<>0) then
  1232. ShowTopic(ASourceFileID, AContext);
  1233. Insert(HelpView);
  1234. end;
  1235. end;
  1236. procedure THelpWindow.InitScrollBars;
  1237. var R: TRect;
  1238. begin
  1239. GetExtent(R); R.Grow(0,-1); R.A.X:=R.B.X-1;
  1240. New(VSB, Init(R)); VSB^.GrowMode:=gfGrowLoX+gfGrowHiX+gfGrowHiY;
  1241. GetExtent(R); R.Grow(-1,0); R.A.Y:=R.B.Y-1;
  1242. New(HSB, Init(R)); HSB^.GrowMode:=gfGrowLoY+gfGrowHiX+gfGrowHiY;
  1243. end;
  1244. procedure THelpWindow.InitHelpView;
  1245. var R: TRect;
  1246. begin
  1247. GetExtent(R); R.Grow(-1,-1);
  1248. New(HelpView, Init(R, HSB, VSB));
  1249. HelpView^.GrowMode:=gfGrowHiX+gfGrowHiY;
  1250. end;
  1251. procedure THelpWindow.InitFrame;
  1252. var R: TRect;
  1253. begin
  1254. GetExtent(R);
  1255. Frame:=New(PHelpFrame, Init(R));
  1256. end;
  1257. procedure THelpWindow.ShowIndex;
  1258. begin
  1259. HelpView^.SwitchToIndex;
  1260. end;
  1261. procedure THelpWindow.ShowTopic(SourceFileID: word; Context: THelpCtx);
  1262. begin
  1263. HelpView^.SwitchToTopic(SourceFileID, Context);
  1264. end;
  1265. procedure THelpWindow.HandleEvent(var Event: TEvent);
  1266. begin
  1267. case Event.What of
  1268. evKeyDown :
  1269. case Event.KeyCode of
  1270. kbEsc :
  1271. begin
  1272. Event.What:=evCommand; Event.Command:=cmClose;
  1273. end;
  1274. end;
  1275. end;
  1276. inherited HandleEvent(Event);
  1277. end;
  1278. procedure THelpWindow.Close;
  1279. begin
  1280. if HideOnClose then Hide else inherited Close;
  1281. end;
  1282. function THelpWindow.GetPalette: PPalette;
  1283. begin
  1284. GetPalette:=nil;
  1285. end;
  1286. END.