2
0

whlpview.pas 39 KB

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