whlpview.pas 39 KB

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