IDE: improved xml parser to keep TDomText nodes

git-svn-id: trunk@13928 -
This commit is contained in:
mattias 2008-01-30 22:29:50 +00:00
parent 7901ce1c95
commit 1802d34238
6 changed files with 358 additions and 261 deletions

View File

@ -460,11 +460,11 @@ begin
SetWideStringManager(WideStringManager, OldWideStringManager); SetWideStringManager(WideStringManager, OldWideStringManager);
try try
{$ENDIF} {$ENDIF}
// do not call SkipWhitespace. The text is needed by ParseCharData. // do not call SkipWhitespace. They are needed by ParseCharData.
while ParseCharData(AOwner) or ParseCDSect(AOwner) or ParsePI or while ParseCharData(AOwner) or ParseCDSect(AOwner) or ParsePI or
ParseComment(AOwner) or ParseElement(AOwner) or ParseComment(AOwner) or ParseElement(AOwner) or
ParseReference(AOwner) do ParseReference(AOwner)
; do ;
{$IFDEF UsesFPCWidestrings} {$IFDEF UsesFPCWidestrings}
finally finally
SetWideStringManager(OldWideStringManager); SetWideStringManager(OldWideStringManager);

View File

@ -56,6 +56,17 @@ procedure WriteDocumentType(node: TDOMNode); forward;
procedure WriteDocumentFragment(node: TDOMNode); forward; procedure WriteDocumentFragment(node: TDOMNode); forward;
procedure WriteNotation(node: TDOMNode); forward; procedure WriteNotation(node: TDOMNode); forward;
function NodeFrontIsText(Node: TDOMNode): boolean;
begin
Result:=(Node is TDOMText) or (Node.ParentNode is TDOMText)
or (Node.PreviousSibling is TDOMText);
end;
function NodeAfterIsText(Node: TDOMNode): boolean;
begin
Result:=(Node is TDOMText) or (Node.ParentNode is TDOMText)
or (Node.NextSibling is TDOMText);
end;
type type
TWriteNodeProc = procedure(node: TDOMNode); TWriteNodeProc = procedure(node: TDOMNode);
@ -84,7 +95,6 @@ threadvar
f: ^Text; f: ^Text;
stream: TStream; stream: TStream;
wrt, wrtln: TOutputProc; wrt, wrtln: TOutputProc;
InsideTextNode: Boolean;
procedure Text_Write(const Buffer; Count: Longint); procedure Text_Write(const Buffer; Count: Longint);
var s: string; var s: string;
@ -241,10 +251,9 @@ procedure WriteElement(node: TDOMNode);
var var
i: Integer; i: Integer;
attr, child: TDOMNode; attr, child: TDOMNode;
SavedInsideTextNode: Boolean;
s: String; s: String;
begin begin
if not InsideTextNode then if not NodeFrontIsText(Node) then
wrtIndent; wrtIndent;
wrtChr('<'); wrtChr('<');
wrtStr(node.NodeName); wrtStr(node.NodeName);
@ -266,29 +275,30 @@ begin
if Child = nil then begin if Child = nil then begin
wrtChr('/'); wrtChr('/');
wrtChr('>'); wrtChr('>');
if not InsideTextNode then wrtLineEnd; if not NodeAfterIsText(Node) then
wrtLineEnd;
end else end else
begin begin
SavedInsideTextNode := InsideTextNode;
wrtChr('>'); wrtChr('>');
if not (InsideTextNode or Child.InheritsFrom(TDOMText)) then if not ((Node is TDOMText) or (Node.ParentNode is TDOMText) or
(Child is TDOMText))
then
wrtLineEnd; wrtLineEnd;
IncIndent; IncIndent;
repeat repeat
if Child.InheritsFrom(TDOMText) then
InsideTextNode := True;
WriteNode(Child); WriteNode(Child);
Child := Child.NextSibling; Child := Child.NextSibling;
until child = nil; until child = nil;
DecIndent; DecIndent;
if not InsideTextNode then if not ((Node is TDOMText) or (Node.ParentNode is TDOMText) or
(Node.LastChild is TDOMText))
then
wrtIndent; wrtIndent;
InsideTextNode := SavedInsideTextNode;
wrtChr('<'); wrtChr('<');
wrtChr('/'); wrtChr('/');
wrtStr(node.NodeName); wrtStr(node.NodeName);
wrtChr('>'); wrtChr('>');
if not InsideTextNode then if not NodeAfterIsText(Node) then
wrtLineEnd; wrtLineEnd;
end; end;
end; end;
@ -306,7 +316,7 @@ end;
procedure WriteCDATA(node: TDOMNode); procedure WriteCDATA(node: TDOMNode);
begin begin
if not InsideTextNode then if not NodeFrontIsText(Node) then
wrtStr('<![CDATA[' + node.NodeValue + ']]>') wrtStr('<![CDATA[' + node.NodeValue + ']]>')
else begin else begin
wrtIndent; wrtIndent;
@ -328,22 +338,22 @@ end;
procedure WritePI(node: TDOMNode); procedure WritePI(node: TDOMNode);
begin begin
if not InsideTextNode then wrtIndent; if not NodeFrontIsText(Node) then wrtIndent;
wrtChr('<'); wrtChr('!'); wrtChr('<'); wrtChr('!');
wrtStr(TDOMProcessingInstruction(node).Target); wrtStr(TDOMProcessingInstruction(node).Target);
wrtChr(' '); wrtChr(' ');
wrtStr(TDOMProcessingInstruction(node).Data); wrtStr(TDOMProcessingInstruction(node).Data);
wrtChr('>'); wrtChr('>');
if not InsideTextNode then wrtLineEnd; if not NodeAfterIsText(Node) then wrtLineEnd;
end; end;
procedure WriteComment(node: TDOMNode); procedure WriteComment(node: TDOMNode);
begin begin
if not InsideTextNode then wrtIndent; if not NodeFrontIsText(Node) then wrtIndent;
wrtStr('<!--'); wrtStr('<!--');
wrtStr(node.NodeValue); wrtStr(node.NodeValue);
wrtStr('-->'); wrtStr('-->');
if not InsideTextNode then wrtLineEnd; if not NodeAfterIsText(Node) then wrtLineEnd;
end; end;
procedure WriteDocument(node: TDOMNode); procedure WriteDocument(node: TDOMNode);
@ -366,10 +376,8 @@ begin
if node=nil then ; if node=nil then ;
end; end;
procedure InitWriter; procedure InitWriter;
begin begin
InsideTextNode := False;
SetLength(Indent, 0); SetLength(Indent, 0);
end; end;

View File

@ -17,6 +17,12 @@
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* * * *
*************************************************************************** ***************************************************************************
Author: Mattias Gaertner
Abstract:
This unit is part of the IDE's help system. It implements the help for sources via
fpdoc files and pascal comments.
} }
unit CodeHelp; unit CodeHelp;
@ -65,17 +71,18 @@ type
); );
TLazFPDocFileFlags = set of TLazFPDocFileFlag; TLazFPDocFileFlags = set of TLazFPDocFileFlag;
{ TLazFPDocFile } { TLazFPDocFile
An fpdoc xml file. The CodeBuffer is the xml source. The Doc is the parsed dom tree. }
TLazFPDocFile = class TLazFPDocFile = class
private private
fUpdateLock: integer; fUpdateLock: integer;
FFlags: TLazFPDocFileFlags; FFlags: TLazFPDocFileFlags;
public public
Filename: string; Filename: string;// the fpdoc xml filename
Doc: TXMLdocument;// IMPORTANT: if you change this, call DocChanging and DocChanged to notify the references Doc: TXMLdocument;// IMPORTANT: if you change this, call DocChanging and DocChanged to notify the references
DocModified: boolean; DocModified: boolean;
ChangeStep: integer;// the CodeBuffer.ChangeStep value, when Doc was build ChangeStep: integer;// the CodeBuffer.ChangeStep value, when Doc was built
CodeBuffer: TCodeBuffer; CodeBuffer: TCodeBuffer;
destructor Destroy; override; destructor Destroy; override;
function GetModuleNode: TDOMNode; function GetModuleNode: TDOMNode;
@ -102,7 +109,8 @@ type
FilesTimeStamp: integer; FilesTimeStamp: integer;
end; end;
{ TCodeHelpElement } { TCodeHelpElement - mapping between one codetools position and a fpdoc xml node.
This data is only valid for short times, so don't store it. }
TCodeHelpElement = class TCodeHelpElement = class
public public
@ -114,7 +122,9 @@ type
FPDocFile: TLazFPDocFile; FPDocFile: TLazFPDocFile;
end; end;
{ TCodeHelpElementChain } { TCodeHelpElementChain - a list of TCodeHelpElement.
For example the list of one element plus its ancestors.
Only valid for short time. So always check IsValid. }
TCodeHelpElementChain = class TCodeHelpElementChain = class
private private
@ -227,6 +237,7 @@ function CompareAnsistringWithLDSrc2DocSrcFile(Key, Data: Pointer): integer;
function ToUnixLineEnding(const s: String): String; function ToUnixLineEnding(const s: String): String;
function ToOSLineEnding(const s: String): String; function ToOSLineEnding(const s: String): String;
function ReplaceLineEndings(const s, NewLineEnds: string): string;
implementation implementation
@ -286,6 +297,27 @@ begin
end; end;
end; end;
function ReplaceLineEndings(const s, NewLineEnds: string): string;
var
p: Integer;
StartPos: LongInt;
begin
Result:=s;
p:=1;
while (p<=length(Result)) do begin
if Result[p] in [#10,#13] then begin
StartPos:=p;
if (p<length(Result))
and (Result[p+1] in [#10,#13]) and (Result[p]<>Result[p+1]) then
inc(p);
Result:=copy(Result,1,StartPos-1)+NewLineEnds+copy(Result,p+1,length(Result));
inc(p,length(NewLineEnds));
end else begin
inc(p);
end;
end;
end;
function CompareLazFPDocFilenames(Data1, Data2: Pointer): integer; function CompareLazFPDocFilenames(Data1, Data2: Pointer): integer;
begin begin
Result:=CompareFilenames(TLazFPDocFile(Data1).Filename, Result:=CompareFilenames(TLazFPDocFile(Data1).Filename,
@ -384,6 +416,22 @@ begin
end; end;
function TLazFPDocFile.GetChildValuesAsString(Node: TDOMNode): String; function TLazFPDocFile.GetChildValuesAsString(Node: TDOMNode): String;
procedure FindEndOfTag(const Src: string; var EndPos: integer);
begin
while (EndPos<=length(Src)) do begin
if (Src[EndPos]='>') then begin
inc(EndPos);
exit;
end else if Src[EndPos]='"' then begin
repeat
inc(EndPos);
until (EndPos>=length(Src)) or (Src[EndPos]='"');
end;
inc(EndPos);
end;
end;
var var
MemStream: TMemoryStream; MemStream: TMemoryStream;
StartPos: Integer; StartPos: Integer;
@ -398,28 +446,25 @@ begin
SetLength(Result,MemStream.Size); SetLength(Result,MemStream.Size);
if Result<>'' then if Result<>'' then
MemStream.Read(Result[1],length(Result)); MemStream.Read(Result[1],length(Result));
// remove tag(s) for node, because Result should only contain the child values: // remove enclosing tag(s) for Node, because Result should only
// contain the child values:
// <nodename/> or <nodename>...<nodename/> // <nodename/> or <nodename>...<nodename/>
// <nodename something=""/> // <nodename something=""/>
// plus line ends // plus line ends
StartPos:=1; StartPos:=1;
EndPos:=length(Result)+1; EndPos:=length(Result)+1;
// skip start tag // skip start tag and spaces at start
while (StartPos<=length(Result))
and (Result[StartPos] in [' ',#9,#10,#13]) do
inc(StartPos);
if (Result<>'') and (Result[StartPos]='<') then begin if (Result<>'') and (Result[StartPos]='<') then begin
inc(StartPos); inc(StartPos);
while (StartPos<=EndPos) do begin FindEndOfTag(Result,StartPos);
if (Result[StartPos]='>') then begin while (StartPos<=length(Result))
inc(StartPos); and (Result[StartPos] in [' ',#9,#10,#13]) do
break;
end else if Result[StartPos]='"' then begin
repeat
inc(StartPos);
until (StartPos>=EndPos) or (Result[StartPos]='"');
end;
inc(StartPos); inc(StartPos);
end; end;
end; // skip ending line ends and spaces at end
// skip ending line ends
while (EndPos>StartPos) and (Result[EndPos-1] in [' ',#9,#10,#13]) do while (EndPos>StartPos) and (Result[EndPos-1] in [' ',#9,#10,#13]) do
dec(EndPos); dec(EndPos);
// skip end tag // skip end tag
@ -436,31 +481,37 @@ begin
break; break;
end; end;
until false; until false;
while (EndPos>StartPos) and (Result[EndPos-1] in [' ',#9,#10,#13]) do
dec(EndPos);
end; end;
Result:=copy(Result,StartPos,EndPos-StartPos); Result:=copy(Result,StartPos,EndPos-StartPos);
// the xml writer adds/removes spaces/new lines automatically
// add newlines after br and p tags
StartPos:=1;
while StartPos<length(Result) do begin
if Result[StartPos]='<' then begin
// search end of tag
EndPos:=StartPos+1;
FindEndOfTag(Result,EndPos);
if Result[StartPos+1]='/' then
inc(StartPos);
if (CompareIdentifiers(@Result[StartPos+1],'br')=0)
or (CompareIdentifiers(@Result[StartPos+1],'p')=0) then
begin
// add new line
if not (Result[EndPos] in [#10,#13]) then
Result:=copy(Result,1,EndPos-1)+LineEnding+copy(Result,EndPos,length(Result));
end;
StartPos:=EndPos;
end else begin
inc(StartPos);
end;
end;
finally finally
MemStream.Free; MemStream.Free;
end; end;
DebugLn(['TLazFPDocFile.GetChildValuesAsString Node=',Node.NodeName,' Result=',Result]); DebugLn(['TLazFPDocFile.GetChildValuesAsString Node=',Node.NodeName,' Result=',Result]);
{Child:=Node.FirstChild;
//DebugLn(['TLazFPDocFile.GetChildValuesAsString Node=',Node.NodeName]);
while Child<>nil do begin
//DebugLn(['TLazFPDocFile.GetChildValuesAsString ',dbgsName(Child),' ',Child.NodeName]);
if Child is TDOMText then begin
//DebugLn(['TLazFPDocFile.GetChildValuesAsString Data="',TDOMText(Child).Data,'" Length=',TDOMText(Child).Length]);
Result:=Result+TDOMText(Child).Data;
end else if Child is TDOMElement then begin
if Child.FirstChild=nil then begin
Result:=Result+'<'+Child.NodeName+'/>';
end else begin
Result:=Result+'<'+Child.NodeName+'>'
+GetChildValuesAsString(Child)
+'</'+Child.NodeName+'>'
end;
end;
Child:=Child.NextSibling;
end;}
end; end;
function TLazFPDocFile.GetValuesFromNode(Node: TDOMNode): TFPDocElementValues; function TLazFPDocFile.GetValuesFromNode(Node: TDOMNode): TFPDocElementValues;
@ -530,11 +581,14 @@ procedure TLazFPDocFile.SetChildValue(Node: TDOMNode; const ChildName: string;
var var
Child: TDOMNode; Child: TDOMNode;
OldNode: TDOMNode;
FileAttribute: TDOMAttr;
begin begin
Child:=Node.FindNode(ChildName); Child:=Node.FindNode(ChildName);
NewValue:=ToUnixLineEnding(NewValue); NewValue:=ToUnixLineEnding(NewValue);
if Child=nil then begin if ChildName = 'example' then begin
{if ChildName = 'example' then begin OldNode:=nil;
if Child<>nil then
OldNode:=Child.Attributes.GetNamedItem('file'); OldNode:=Child.Attributes.GetNamedItem('file');
NewValue:=FilenameToURLPath(NewValue); NewValue:=FilenameToURLPath(NewValue);
if (NewValue<>'') if (NewValue<>'')
@ -543,14 +597,17 @@ begin
DebugLn(['TLazFPDocFile.SetChildValue Changing Name=',ChildName,' NewValue="',NewValue,'"']); DebugLn(['TLazFPDocFile.SetChildValue Changing Name=',ChildName,' NewValue="',NewValue,'"']);
// add or change example // add or change example
DocChanging; DocChanging;
try
FileAttribute := Doc.CreateAttribute('file'); FileAttribute := Doc.CreateAttribute('file');
FileAttribute.Value := NewValue; FileAttribute.Value := NewValue;
OldNode:=Node.Attributes.SetNamedItem(FileAttribute); OldNode:=Node.Attributes.SetNamedItem(FileAttribute);
OldNode.Free; OldNode.Free;
finally
DocChanged; DocChanged;
end; end;
end end;
else } end else begin
if Child=nil then begin
// add node // add node
if NewValue<>'' then begin if NewValue<>'' then begin
DebugLn(['TLazFPDocFile.SetChildValue Adding Name=',ChildName,' NewValue="',NewValue,'"']); DebugLn(['TLazFPDocFile.SetChildValue Adding Name=',ChildName,' NewValue="',NewValue,'"']);
@ -581,6 +638,7 @@ begin
end; end;
end; end;
end; end;
end;
procedure TLazFPDocFile.DocChanging; procedure TLazFPDocFile.DocChanging;
begin begin

View File

@ -5,7 +5,7 @@ object FPDocEditor: TFPDocEditor
Width = 753 Width = 753
HorzScrollBar.Page = 752 HorzScrollBar.Page = 752
VertScrollBar.Page = 116 VertScrollBar.Page = 116
ActiveControl = LinkIdComboBox ActiveControl = DescrMemo
Caption = 'FPDoc editor' Caption = 'FPDoc editor'
ClientHeight = 117 ClientHeight = 117
ClientWidth = 753 ClientWidth = 753
@ -16,9 +16,9 @@ object FPDocEditor: TFPDocEditor
Left = 17 Left = 17
Height = 117 Height = 117
Width = 736 Width = 736
ActivePage = SeeAlsoTabSheet ActivePage = DescrTabSheet
Align = alClient Align = alClient
TabIndex = 3 TabIndex = 1
TabOrder = 0 TabOrder = 0
TabPosition = tpBottom TabPosition = tpBottom
object ShortTabSheet: TTabSheet object ShortTabSheet: TTabSheet
@ -30,7 +30,8 @@ object FPDocEditor: TFPDocEditor
Width = 730 Width = 730
Align = alTop Align = alTop
BorderSpacing.Right = 2 BorderSpacing.Right = 2
OnEditingDone = DocumentationTagChange OnChange = ShortEditEditingDone
OnEditingDone = ShortEditEditingDone
TabOrder = 0 TabOrder = 0
Text = 'ShortEdit' Text = 'ShortEdit'
end end
@ -75,7 +76,7 @@ object FPDocEditor: TFPDocEditor
Lines.Strings = ( Lines.Strings = (
'DescrMemo' 'DescrMemo'
) )
OnChange = DocumentationTagChange OnChange = DescrMemoChange
TabOrder = 0 TabOrder = 0
end end
end end
@ -92,7 +93,7 @@ object FPDocEditor: TFPDocEditor
Lines.Strings = ( Lines.Strings = (
'ErrorsMemo' 'ErrorsMemo'
) )
OnChange = DocumentationTagChange OnChange = ErrorsMemoChange
TabOrder = 0 TabOrder = 0
end end
end end
@ -177,17 +178,17 @@ object FPDocEditor: TFPDocEditor
Width = 730 Width = 730
Align = alTop Align = alTop
BorderSpacing.Right = 2 BorderSpacing.Right = 2
OnChange = DocumentationTagChange OnChange = ExampleEditChange
TabOrder = 0 TabOrder = 0
Text = 'ExampleEdit' Text = 'ExampleEdit'
end end
object BrowseExampleButton: TButton object BrowseExampleButton: TButton
AnchorSideRight.Control = ExampleTabSheet AnchorSideRight.Control = ExampleTabSheet
AnchorSideRight.Side = asrBottom AnchorSideRight.Side = asrBottom
Left = 592 Left = 574
Height = 25 Height = 29
Top = 28 Top = 28
Width = 134 Width = 156
Anchors = [akTop, akRight] Anchors = [akTop, akRight]
AutoSize = True AutoSize = True
BorderSpacing.Right = 2 BorderSpacing.Right = 2

View File

@ -3,153 +3,153 @@
LazarusResources.Add('TFPDocEditor','FORMDATA',[ LazarusResources.Add('TFPDocEditor','FORMDATA',[
'TPF0'#12'TFPDocEditor'#11'FPDocEditor'#4'Left'#3'/'#1#6'Height'#2'u'#3'Top'#3 'TPF0'#12'TFPDocEditor'#11'FPDocEditor'#4'Left'#3'/'#1#6'Height'#2'u'#3'Top'#3
+'$'#2#5'Width'#3#241#2#18'HorzScrollBar.Page'#3#240#2#18'VertScrollBar.Page' +'$'#2#5'Width'#3#241#2#18'HorzScrollBar.Page'#3#240#2#18'VertScrollBar.Page'
+#2't'#13'ActiveControl'#7#14'LinkIdComboBox'#7'Caption'#6#12'FPDoc editor'#12 +#2't'#13'ActiveControl'#7#9'DescrMemo'#7'Caption'#6#12'FPDoc editor'#12'Clie'
+'ClientHeight'#2'u'#11'ClientWidth'#3#241#2#8'OnCreate'#7#10'FormCreate'#9'O' +'ntHeight'#2'u'#11'ClientWidth'#3#241#2#8'OnCreate'#7#10'FormCreate'#9'OnDes'
+'nDestroy'#7#11'FormDestroy'#8'OnResize'#7#10'FormResize'#0#12'TPageControl' +'troy'#7#11'FormDestroy'#8'OnResize'#7#10'FormResize'#0#12'TPageControl'#11
+#11'PageControl'#4'Left'#2#17#6'Height'#2'u'#5'Width'#3#224#2#10'ActivePage' +'PageControl'#4'Left'#2#17#6'Height'#2'u'#5'Width'#3#224#2#10'ActivePage'#7
+#7#15'SeeAlsoTabSheet'#5'Align'#7#8'alClient'#8'TabIndex'#2#3#8'TabOrder'#2#0 +#13'DescrTabSheet'#5'Align'#7#8'alClient'#8'TabIndex'#2#1#8'TabOrder'#2#0#11
+#11'TabPosition'#7#8'tpBottom'#0#9'TTabSheet'#13'ShortTabSheet'#7'Caption'#6 +'TabPosition'#7#8'tpBottom'#0#9'TTabSheet'#13'ShortTabSheet'#7'Caption'#6#13
+#13'ShortTabSheet'#12'ClientHeight'#2'V'#11'ClientWidth'#3#220#2#0#5'TEdit'#9 +'ShortTabSheet'#12'ClientHeight'#2'V'#11'ClientWidth'#3#220#2#0#5'TEdit'#9'S'
+'ShortEdit'#6'Height'#2#23#5'Width'#3#218#2#5'Align'#7#5'alTop'#19'BorderSpa' +'hortEdit'#6'Height'#2#23#5'Width'#3#218#2#5'Align'#7#5'alTop'#19'BorderSpac'
+'cing.Right'#2#2#13'OnEditingDone'#7#22'DocumentationTagChange'#8'TabOrder'#2 +'ing.Right'#2#2#8'OnChange'#7#20'ShortEditEditingDone'#13'OnEditingDone'#7#20
+#0#4'Text'#6#9'ShortEdit'#0#0#7'TButton'#12'CreateButton'#21'AnchorSideTop.C' +'ShortEditEditingDone'#8'TabOrder'#2#0#4'Text'#6#9'ShortEdit'#0#0#7'TButton'
+'ontrol'#7#9'ShortEdit'#18'AnchorSideTop.Side'#7#9'asrBottom'#4'Left'#2#6#6 +#12'CreateButton'#21'AnchorSideTop.Control'#7#9'ShortEdit'#18'AnchorSideTop.'
+'Height'#2#29#3'Top'#2#29#5'Width'#2'b'#8'AutoSize'#9#20'BorderSpacing.Aroun' +'Side'#7#9'asrBottom'#4'Left'#2#6#6'Height'#2#29#3'Top'#2#29#5'Width'#2'b'#8
+'d'#2#6#7'Caption'#6#12'CreateButton'#7'OnClick'#7#17'CreateButtonClick'#8'T' +'AutoSize'#9#20'BorderSpacing.Around'#2#6#7'Caption'#6#12'CreateButton'#7'On'
+'abOrder'#2#1#0#0#7'TButton'#10'SaveButton'#22'AnchorSideLeft.Control'#7#12 +'Click'#7#17'CreateButtonClick'#8'TabOrder'#2#1#0#0#7'TButton'#10'SaveButton'
+'CreateButton'#19'AnchorSideLeft.Side'#7#9'asrBottom'#21'AnchorSideTop.Contr' +#22'AnchorSideLeft.Control'#7#12'CreateButton'#19'AnchorSideLeft.Side'#7#9'a'
+'ol'#7#12'CreateButton'#4'Left'#2'n'#6'Height'#2#29#3'Top'#2#29#5'Width'#2'W' +'srBottom'#21'AnchorSideTop.Control'#7#12'CreateButton'#4'Left'#2'n'#6'Heigh'
+#8'AutoSize'#9#18'BorderSpacing.Left'#2#6#7'Caption'#6#10'SaveButton'#7'OnCl' +'t'#2#29#3'Top'#2#29#5'Width'#2'W'#8'AutoSize'#9#18'BorderSpacing.Left'#2#6#7
+'ick'#7#15'SaveButtonClick'#8'TabOrder'#2#2#0#0#0#9'TTabSheet'#13'DescrTabSh' +'Caption'#6#10'SaveButton'#7'OnClick'#7#15'SaveButtonClick'#8'TabOrder'#2#2#0
+'eet'#7'Caption'#6#13'DescrTabSheet'#12'ClientHeight'#2'V'#11'ClientWidth'#3 +#0#0#9'TTabSheet'#13'DescrTabSheet'#7'Caption'#6#13'DescrTabSheet'#12'Client'
+#220#2#0#5'TMemo'#9'DescrMemo'#6'Height'#2'R'#5'Width'#3#218#2#5'Align'#7#8 +'Height'#2'V'#11'ClientWidth'#3#220#2#0#5'TMemo'#9'DescrMemo'#6'Height'#2'R'
+'alClient'#19'BorderSpacing.Right'#2#2#20'BorderSpacing.Bottom'#2#4#13'Lines' +#5'Width'#3#218#2#5'Align'#7#8'alClient'#19'BorderSpacing.Right'#2#2#20'Bord'
+'.Strings'#1#6#9'DescrMemo'#0#8'OnChange'#7#22'DocumentationTagChange'#8'Tab' +'erSpacing.Bottom'#2#4#13'Lines.Strings'#1#6#9'DescrMemo'#0#8'OnChange'#7#15
+'Order'#2#0#0#0#0#9'TTabSheet'#14'ErrorsTabSheet'#7'Caption'#6#14'ErrorsTabS' +'DescrMemoChange'#8'TabOrder'#2#0#0#0#0#9'TTabSheet'#14'ErrorsTabSheet'#7'Ca'
+'heet'#12'ClientHeight'#2'V'#11'ClientWidth'#3#220#2#0#5'TMemo'#10'ErrorsMem' +'ption'#6#14'ErrorsTabSheet'#12'ClientHeight'#2'V'#11'ClientWidth'#3#220#2#0
+'o'#6'Height'#2'R'#5'Width'#3#218#2#5'Align'#7#8'alClient'#19'BorderSpacing.' +#5'TMemo'#10'ErrorsMemo'#6'Height'#2'R'#5'Width'#3#218#2#5'Align'#7#8'alClie'
+'Right'#2#2#20'BorderSpacing.Bottom'#2#4#13'Lines.Strings'#1#6#10'ErrorsMemo' +'nt'#19'BorderSpacing.Right'#2#2#20'BorderSpacing.Bottom'#2#4#13'Lines.Strin'
+#0#8'OnChange'#7#22'DocumentationTagChange'#8'TabOrder'#2#0#0#0#0#9'TTabShee' +'gs'#1#6#10'ErrorsMemo'#0#8'OnChange'#7#16'ErrorsMemoChange'#8'TabOrder'#2#0
+'t'#15'SeeAlsoTabSheet'#7'Caption'#6#15'SeeAlsoTabSheet'#12'ClientHeight'#2 +#0#0#0#9'TTabSheet'#15'SeeAlsoTabSheet'#7'Caption'#6#15'SeeAlsoTabSheet'#12
+'V'#11'ClientWidth'#3#220#2#0#8'TListBox'#11'LinkListBox'#21'AnchorSideTop.C' +'ClientHeight'#2'V'#11'ClientWidth'#3#220#2#0#8'TListBox'#11'LinkListBox'#21
+'ontrol'#7#13'AddLinkButton'#18'AnchorSideTop.Side'#7#9'asrBottom'#6'Height' +'AnchorSideTop.Control'#7#13'AddLinkButton'#18'AnchorSideTop.Side'#7#9'asrBo'
+#2'1'#3'Top'#2'!'#5'Width'#3#218#2#5'Align'#7#8'alBottom'#7'Anchors'#11#5'ak' +'ttom'#6'Height'#2'1'#3'Top'#2'!'#5'Width'#3#218#2#5'Align'#7#8'alBottom'#7
+'Top'#6'akLeft'#7'akRight'#8'akBottom'#0#17'BorderSpacing.Top'#2#4#19'Border' +'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#8'akBottom'#0#17'BorderSpacing.To'
+'Spacing.Right'#2#2#20'BorderSpacing.Bottom'#2#4#7'OnClick'#7#16'LinkListBox' +'p'#2#4#19'BorderSpacing.Right'#2#2#20'BorderSpacing.Bottom'#2#4#7'OnClick'#7
+'Click'#8'TabOrder'#2#0#8'TopIndex'#2#255#0#0#7'TButton'#13'AddLinkButton'#23 +#16'LinkListBoxClick'#8'TabOrder'#2#0#8'TopIndex'#2#255#0#0#7'TButton'#13'Ad'
+'AnchorSideRight.Control'#7#16'DeleteLinkButton'#4'Left'#3#241#1#6'Height'#2 +'dLinkButton'#23'AnchorSideRight.Control'#7#16'DeleteLinkButton'#4'Left'#3
+#29#5'Width'#2'i'#7'Anchors'#11#5'akTop'#7'akRight'#0#8'AutoSize'#9#19'Borde' +#241#1#6'Height'#2#29#5'Width'#2'i'#7'Anchors'#11#5'akTop'#7'akRight'#0#8'Au'
+'rSpacing.Right'#2#6#7'Caption'#6#13'AddLinkButton'#7'OnClick'#7#18'AddLinkB' +'toSize'#9#19'BorderSpacing.Right'#2#6#7'Caption'#6#13'AddLinkButton'#7'OnCl'
+'uttonClick'#8'TabOrder'#2#1#0#0#7'TButton'#16'DeleteLinkButton'#23'AnchorSi' +'ick'#7#18'AddLinkButtonClick'#8'TabOrder'#2#1#0#0#7'TButton'#16'DeleteLinkB'
+'deRight.Control'#7#15'SeeAlsoTabSheet'#20'AnchorSideRight.Side'#7#9'asrBott' +'utton'#23'AnchorSideRight.Control'#7#15'SeeAlsoTabSheet'#20'AnchorSideRight'
+'om'#4'Left'#3'`'#2#6'Height'#2#29#5'Width'#2'z'#7'Anchors'#11#5'akTop'#7'ak' +'.Side'#7#9'asrBottom'#4'Left'#3'`'#2#6'Height'#2#29#5'Width'#2'z'#7'Anchors'
+'Right'#0#8'AutoSize'#9#19'BorderSpacing.Right'#2#2#7'Caption'#6#16'DeleteLi' +#11#5'akTop'#7'akRight'#0#8'AutoSize'#9#19'BorderSpacing.Right'#2#2#7'Captio'
+'nkButton'#7'OnClick'#7#21'DeleteLinkButtonClick'#8'TabOrder'#2#2#0#0#5'TEdi' +'n'#6#16'DeleteLinkButton'#7'OnClick'#7#21'DeleteLinkButtonClick'#8'TabOrder'
+'t'#12'LinkTextEdit'#22'AnchorSideLeft.Control'#7#14'LinkIdComboBox'#19'Anch' +#2#2#0#0#5'TEdit'#12'LinkTextEdit'#22'AnchorSideLeft.Control'#7#14'LinkIdCom'
+'orSideLeft.Side'#7#9'asrBottom'#23'AnchorSideRight.Control'#7#13'AddLinkBut' +'boBox'#19'AnchorSideLeft.Side'#7#9'asrBottom'#23'AnchorSideRight.Control'#7
+'ton'#4'Left'#3#229#0#6'Height'#2#27#3'Top'#2#1#5'Width'#3#8#1#7'Anchors'#11 +#13'AddLinkButton'#4'Left'#3#229#0#6'Height'#2#27#3'Top'#2#1#5'Width'#3#8#1#7
+#5'akTop'#6'akLeft'#7'akRight'#0#8'AutoSize'#9#18'BorderSpacing.Left'#2#4#19 +'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#8'AutoSize'#9#18'BorderSpacing.'
+'BorderSpacing.Right'#2#4#8'OnChange'#7#10'LinkChange'#8'TabOrder'#2#3#4'Tex' +'Left'#2#4#19'BorderSpacing.Right'#2#4#8'OnChange'#7#10'LinkChange'#8'TabOrd'
+'t'#6#12'LinkTextEdit'#0#0#9'TComboBox'#14'LinkIdComboBox'#6'Height'#2#27#3 +'er'#2#3#4'Text'#6#12'LinkTextEdit'#0#0#9'TComboBox'#14'LinkIdComboBox'#6'He'
+'Top'#2#1#5'Width'#3#225#0#16'AutoCompleteText'#11#22'cbactEndOfLineComplete' +'ight'#2#27#3'Top'#2#1#5'Width'#3#225#0#16'AutoCompleteText'#11#22'cbactEndO'
+#20'cbactSearchAscending'#0#8'AutoSize'#9#9'MaxLength'#2#0#8'OnChange'#7#10 +'fLineComplete'#20'cbactSearchAscending'#0#8'AutoSize'#9#9'MaxLength'#2#0#8
+'LinkChange'#8'TabOrder'#2#4#4'Text'#6#14'LinkIdComboBox'#0#0#0#9'TTabSheet' +'OnChange'#7#10'LinkChange'#8'TabOrder'#2#4#4'Text'#6#14'LinkIdComboBox'#0#0
+#15'ExampleTabSheet'#7'Caption'#6#15'ExampleTabSheet'#12'ClientHeight'#2'V' +#0#9'TTabSheet'#15'ExampleTabSheet'#7'Caption'#6#15'ExampleTabSheet'#12'Clie'
+#11'ClientWidth'#3#220#2#0#5'TEdit'#11'ExampleEdit'#6'Height'#2#23#5'Width'#3 +'ntHeight'#2'V'#11'ClientWidth'#3#220#2#0#5'TEdit'#11'ExampleEdit'#6'Height'
+#218#2#5'Align'#7#5'alTop'#19'BorderSpacing.Right'#2#2#8'OnChange'#7#22'Docu' +#2#23#5'Width'#3#218#2#5'Align'#7#5'alTop'#19'BorderSpacing.Right'#2#2#8'OnC'
+'mentationTagChange'#8'TabOrder'#2#0#4'Text'#6#11'ExampleEdit'#0#0#7'TButton' +'hange'#7#17'ExampleEditChange'#8'TabOrder'#2#0#4'Text'#6#11'ExampleEdit'#0#0
+#19'BrowseExampleButton'#23'AnchorSideRight.Control'#7#15'ExampleTabSheet'#20 +#7'TButton'#19'BrowseExampleButton'#23'AnchorSideRight.Control'#7#15'Example'
+'AnchorSideRight.Side'#7#9'asrBottom'#4'Left'#3'P'#2#6'Height'#2#25#3'Top'#2 +'TabSheet'#20'AnchorSideRight.Side'#7#9'asrBottom'#4'Left'#3'>'#2#6'Height'#2
+#28#5'Width'#3#134#0#7'Anchors'#11#5'akTop'#7'akRight'#0#8'AutoSize'#9#19'Bo' +#29#3'Top'#2#28#5'Width'#3#156#0#7'Anchors'#11#5'akTop'#7'akRight'#0#8'AutoS'
+'rderSpacing.Right'#2#2#7'Caption'#6#19'BrowseExampleButton'#7'OnClick'#7#24 +'ize'#9#19'BorderSpacing.Right'#2#2#7'Caption'#6#19'BrowseExampleButton'#7'O'
+'BrowseExampleButtonClick'#8'TabOrder'#2#1#0#0#0#9'TTabSheet'#17'InheritedTa' +'nClick'#7#24'BrowseExampleButtonClick'#8'TabOrder'#2#1#0#0#0#9'TTabSheet'#17
+'bSheet'#7'Caption'#6#17'InheritedTabSheet'#12'ClientHeight'#2'V'#11'ClientW' +'InheritedTabSheet'#7'Caption'#6#17'InheritedTabSheet'#12'ClientHeight'#2'V'
+'idth'#3#220#2#0#6'TLabel'#19'InheritedShortLabel'#6'Height'#2#20#3'Top'#2#2 +#11'ClientWidth'#3#220#2#0#6'TLabel'#19'InheritedShortLabel'#6'Height'#2#20#3
,#5'Width'#3#220#2#5'Align'#7#5'alTop'#17'BorderSpacing.Top'#2#2#7'Caption'#6 ,'Top'#2#2#5'Width'#3#220#2#5'Align'#7#5'alTop'#17'BorderSpacing.Top'#2#2#7'C'
+#19'InheritedShortLabel'#11'ParentColor'#8#0#0#5'TEdit'#18'InheritedShortEdi' +'aption'#6#19'InheritedShortLabel'#11'ParentColor'#8#0#0#5'TEdit'#18'Inherit'
+'t'#22'AnchorSideLeft.Control'#7#17'InheritedTabSheet'#21'AnchorSideTop.Cont' +'edShortEdit'#22'AnchorSideLeft.Control'#7#17'InheritedTabSheet'#21'AnchorSi'
+'rol'#7#19'InheritedShortLabel'#18'AnchorSideTop.Side'#7#9'asrBottom'#23'Anc' +'deTop.Control'#7#19'InheritedShortLabel'#18'AnchorSideTop.Side'#7#9'asrBott'
+'horSideRight.Control'#7#17'InheritedTabSheet'#20'AnchorSideRight.Side'#7#9 +'om'#23'AnchorSideRight.Control'#7#17'InheritedTabSheet'#20'AnchorSideRight.'
+'asrBottom'#6'Height'#2#23#3'Top'#2#24#5'Width'#3#220#2#7'Anchors'#11#5'akTo' +'Side'#7#9'asrBottom'#6'Height'#2#23#3'Top'#2#24#5'Width'#3#220#2#7'Anchors'
+'p'#6'akLeft'#7'akRight'#0#17'BorderSpacing.Top'#2#2#8'ReadOnly'#9#8'TabOrde' +#11#5'akTop'#6'akLeft'#7'akRight'#0#17'BorderSpacing.Top'#2#2#8'ReadOnly'#9#8
+'r'#2#0#4'Text'#6#18'InheritedShortEdit'#0#0#7'TButton'#21'MoveToInheritedBu' +'TabOrder'#2#0#4'Text'#6#18'InheritedShortEdit'#0#0#7'TButton'#21'MoveToInhe'
+'tton'#6'Height'#2#29#3'Top'#2'6'#5'Width'#3#158#0#8'AutoSize'#9#7'Caption'#6 +'ritedButton'#6'Height'#2#29#3'Top'#2'6'#5'Width'#3#158#0#8'AutoSize'#9#7'Ca'
+#21'MoveToInheritedButton'#7'OnClick'#7#26'MoveToInheritedButtonClick'#8'Tab' +'ption'#6#21'MoveToInheritedButton'#7'OnClick'#7#26'MoveToInheritedButtonCli'
+'Order'#2#1#0#0#7'TButton'#23'CopyFromInheritedButton'#22'AnchorSideLeft.Con' +'ck'#8'TabOrder'#2#1#0#0#7'TButton'#23'CopyFromInheritedButton'#22'AnchorSid'
+'trol'#7#21'MoveToInheritedButton'#19'AnchorSideLeft.Side'#7#9'asrBottom'#21 +'eLeft.Control'#7#21'MoveToInheritedButton'#19'AnchorSideLeft.Side'#7#9'asrB'
+'AnchorSideTop.Control'#7#21'MoveToInheritedButton'#18'AnchorSideTop.Side'#7 +'ottom'#21'AnchorSideTop.Control'#7#21'MoveToInheritedButton'#18'AnchorSideT'
+#9'asrCenter'#4'Left'#3#168#0#6'Height'#2#29#3'Top'#2'6'#5'Width'#3#175#0#8 +'op.Side'#7#9'asrCenter'#4'Left'#3#168#0#6'Height'#2#29#3'Top'#2'6'#5'Width'
+'AutoSize'#9#18'BorderSpacing.Left'#2#10#7'Caption'#6#23'CopyFromInheritedBu' +#3#175#0#8'AutoSize'#9#18'BorderSpacing.Left'#2#10#7'Caption'#6#23'CopyFromI'
+'tton'#7'OnClick'#7#28'CopyFromInheritedButtonClick'#8'TabOrder'#2#2#0#0#0#0 +'nheritedButton'#7'OnClick'#7#28'CopyFromInheritedButtonClick'#8'TabOrder'#2
+#6'TPanel'#6'Panel1'#6'Height'#2'u'#5'Width'#2#17#5'Align'#7#6'alLeft'#10'Be' +#2#0#0#0#0#6'TPanel'#6'Panel1'#6'Height'#2'u'#5'Width'#2#17#5'Align'#7#6'alL'
+'velOuter'#7#6'bvNone'#12'ClientHeight'#2'u'#11'ClientWidth'#2#17#11'FullRep' +'eft'#10'BevelOuter'#7#6'bvNone'#12'ClientHeight'#2'u'#11'ClientWidth'#2#17
+'aint'#8#14'ParentShowHint'#8#8'ShowHint'#9#8'TabOrder'#2#1#0#12'TSpeedButto' +#11'FullRepaint'#8#14'ParentShowHint'#8#8'ShowHint'#9#8'TabOrder'#2#1#0#12'T'
+'n'#16'BoldFormatButton'#6'Height'#2#17#5'Width'#2#17#5'Align'#7#5'alTop'#5 +'SpeedButton'#16'BoldFormatButton'#6'Height'#2#17#5'Width'#2#17#5'Align'#7#5
+'Color'#7#9'clBtnFace'#10'Glyph.Data'#10#190#4#0#0#186#4#0#0'BM'#186#4#0#0#0 +'alTop'#5'Color'#7#9'clBtnFace'#10'Glyph.Data'#10#190#4#0#0#186#4#0#0'BM'#186
+#0#0#0'6'#0#0#0'('#0#0#0#17#0#0#0#17#0#0#0#1#0' '#0#0#0#0#0#132#4#0#0'd'#0#0 +#4#0#0#0#0#0#0'6'#0#0#0'('#0#0#0#17#0#0#0#17#0#0#0#1#0' '#0#0#0#0#0#132#4#0#0
+#0'd'#0#0#0#0#0#0#0#0#0#0#0#0#255#255#0#219#152' '#0#0#14#165#0#243#165#13#0 +'d'#0#0#0'd'#0#0#0#0#0#0#0#0#0#0#0#0#255#255#0#219#152' '#0#0#14#165#0#243
+#0#0'g'#0#250#226'c'#0#0#255#0#0#0#0#0#0#0#255#255#0#255#255#0#0#0#0#0#0#221 +#165#13#0#0#0'g'#0#250#226'c'#0#0#255#0#0#0#0#0#0#0#255#255#0#255#255#0#0#0#0
+#255#255#0#0#2'|'#0#250#205'R'#0#0#0#0#0#0#0#0#0#136#4#0#0#0#0#0#0#0#0#0#0'h' +#0#0#221#255#255#0#0#2'|'#0#250#205'R'#0#0#0#0#0#0#0#0#0#136#4#0#0#0#0#0#0#0
+#3#0#0#0'|'#167#0#5'9'#178#0#0#0#0#0#0#0#0#0#0#255#255#0#255#255#255#0#0'L' +#0#0#0'h'#3#0#0#0'|'#167#0#5'9'#178#0#0#0#0#0#0#0#0#0#0#255#255#0#255#255#255
+#218#0#221'W'#255#0#0#255#255#0#255#255#255#0#0#255#0#0#0#0#0#0#0#255#0#0#0#0 +#0#0'L'#218#0#221'W'#255#0#0#255#255#0#255#255#255#0#0#255#0#0#0#0#0#0#0#255
+#0#0#0#236'M'#0' '#161#255#0#0#138'v'#0#0#0#0#0#0#255#0#0#0#0#0#0#0#255#0#0#0 +#0#0#0#0#0#0#0#236'M'#0' '#161#255#0#0#138'v'#0#0#0#0#0#0#255#0#0#0#0#0#0#0
+#0#0#0#0#255#0#0'#p'#226#0#0#151#168#0#19#171#150#0#0'n'#204#0#4#29#151#0#0 +#255#0#0#0#0#0#0#0#255#0#0'#p'#226#0#0#151#168#0#19#171#150#0#0'n'#204#0#4#29
+#255#0#0#0#0#0#0#0#0#0#0#0#0'd'#0#0#232#31#0#0'!'#231#0#0#222'-'#0#0#0#0#0#0 +#151#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0'd'#0#0#232#31#0#0'!'#231#0#0#222'-'#0#0
+#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#8#0#0#0#0#224#13#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#8#0#0#0#0#224#13#0#0#0#0#0#0
+#0#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#251#255#0#255#255#254#0#0#0#0#255 +#0#0#0#0#0#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#251#255#0#255#255#254#0#0
+#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#255 +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
+#0#0#0#0#0#0#0#255#0#0#0#0#0#0#0#255#0#0#255#255#255#0#0#0#0#0'~'#0#0#0#0#255 +#255#0#255#0#0#0#0#0#0#0#255#0#0#0#0#0#0#0#255#0#0#255#255#255#0#0#0#0#0'~'#0
+#0#0#0#0#0#0#0#0#0#255#0#0#0#255#0#0#0#255#0#0#23#0#0#252#3#0#0#0#0#255#0#0#0 +#0#0#0#255#0#0#0#0#0#0#0#0#0#255#0#0#0#255#0#0#0#255#0#0#23#0#0#252#3#0#0#0#0
+#255#0#0#0#255#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#231' '#0#0'!'#230#0#0#221 +#255#0#0#0#255#0#0#0#255#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#231' '#0#0'!'
+'-'#0#0#0#0#0#0#255#255#0#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0 +#230#0#0#221'-'#0#0#0#0#0#0#255#255#0#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#0#0
+#255#0#0#0#255#0#0#0#255#0#0#0#0#0#255#0#0#0#0#0#0#0'8'#194#0#0#0#0#0#0'}' +#0#0#0#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#0#0#255#0#0#0#0#0#0#0'8'#194#0#0#0
+#185#0#13#154#152#0#0#0#0#0#0#0#0#0#0#0#0#255#0#0#0#255#0#0#0#255#0#8#246#0#0 +#0#0#0'}'#185#0#13#154#152#0#0#0#0#0#0#0#0#0#0#0#0#255#0#0#0#255#0#0#0#255#0
+#0#0#0#0#0#0#255#0#0#0#255#0#0#0#255#0#255#0#0#4'0'#191#0#0#255#0#0#0#0#4#0#0 +#8#246#0#0#0#0#0#0#0#0#255#0#0#0#255#0#0#0#255#0#255#0#0#4'0'#191#0#0#255#0#0
+#0#0#0#0'z'#133#0#0#255#0#0#0#0#0#0#0#255#0#0#0#0#0#255#0#0#0#255#0#0#0#255#0 +#0#0#4#0#0#0#0#0#0'z'#133#0#0#255#0#0#0#0#0#0#0#255#0#0#0#0#0#255#0#0#0#255#0
+#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#255#0#0#0#0#0#0#0#0#0#0#0
+#0#0#242#161#11#0#0#0'd'#0#249#224'b'#0#0#255#0#0#0#0#0#0#0#0#0#255#0#0#0#255 +#0#0#0#0#0#0#0#242#161#11#0#0#0'd'#0#249#224'b'#0#0#255#0#0#0#0#0#0#0#0#0#255
+#0#0#0#255#0#0#0#0#0#3#133#0#0#0#0#255#0#0#0#255#0#0#0#255#0#255#0#0#0#0#0#0 +#0#0#0#255#0#0#0#255#0#0#0#0#0#3#133#0#0#0#0#255#0#0#0#255#0#0#0#255#0#255#0
+#0#0#163#0#7's'#189#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#0#0#0#0#0#255#0#0 +#0#0#0#0#0#0#0#163#0#7's'#189#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#0#0#0#0
+#0#255#0#0#0#255#0#255#255#0#255#255#255#0#0#0#0#255#0#0#0#255#0#0#0#255#0#0 +#0#255#0#0#0#255#0#0#0#255#0#255#255#0#255#255#255#0#0#0#0#255#0#0#0#255#0#0
+#23#0#0#255#0#0#0#0'd'#0#0#12#163#0#0#0#0#0#0#255#0#0#0#0#0#0#0#255#0#0#5'0' +#0#255#0#0#23#0#0#255#0#0#0#0'd'#0#0#12#163#0#0#0#0#0#0#255#0#0#0#0#0#0#0#255
+#189#0#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#255#0#0#0#255#0#0 +#0#0#5'0'#189#0#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#255#0#0#0
+#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#0#255#255 +#255#0#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#0
+#255#0#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255 +#255#255#255#0#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
+#0#0#0#255#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#0 +#0#0#255#0#0#0#255#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255
+#255#255#255#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#0 +#255#0#255#255#255#0#0#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255
+#255#255#255#0#0#255#255#0#251#222#136#0#0#255#255#0#218#151' '#0#0#0#0#0#0#0 +#255#0#255#255#255#0#0#255#255#0#251#222#136#0#0#255#255#0#218#151' '#0#0#0#0
+#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#184#163#18#0#152#28#241 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#184#163#18#0#152
+#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 +#28#241#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
+#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#9'NumGlyphs'#2#0#7'OnClick'#7 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#9'NumGlyphs'#2#0#7'OnCl'
+#17'FormatButtonClick'#0#0#12'TSpeedButton'#18'ItalicFormatButton'#3'Tag'#2#1 +'ick'#7#17'FormatButtonClick'#0#0#12'TSpeedButton'#18'ItalicFormatButton'#3
+#6'Height'#2#17#3'Top'#2#17#5'Width'#2#17#5'Align'#7#5'alTop'#5'Color'#7#9'c' +'Tag'#2#1#6'Height'#2#17#3'Top'#2#17#5'Width'#2#17#5'Align'#7#5'alTop'#5'Col'
+'lBtnFace'#10'Glyph.Data'#10#190#4#0#0#186#4#0#0'BM'#186#4#0#0#0#0#0#0'6'#0#0 +'or'#7#9'clBtnFace'#10'Glyph.Data'#10#190#4#0#0#186#4#0#0'BM'#186#4#0#0#0#0#0
+#0'('#0#0#0#17#0#0#0#17#0#0#0#1#0' '#0#0#0#0#0#132#4#0#0'd'#0#0#0'd'#0#0#0#0 +#0'6'#0#0#0'('#0#0#0#17#0#0#0#17#0#0#0#1#0' '#0#0#0#0#0#132#4#0#0'd'#0#0#0'd'
+#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#25#0#0#0#0#0#0#0'd'#253'F'#0#0#0#1#0#239#239 +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#25#0#0#0#0#0#0#0'd'#253'F'#0#0#0#1#0
,#136#0#255#255#255#0#0#0#0#0#4#0#0#0#0#4#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0 ,#239#239#136#0#255#255#255#0#0#0#0#0#4#0#0#0#0#4#0#0#1#0#0#0#0#0#0#0#0#0#0#0
+#0#0#0#0#136#4#0#0#197'}N'#0#8#4#0#0#128#0#0#0#1#0#24#0#230#2#224#0#0#0#0#0 +#0#0#0#0#0#0#0#0#136#4#0#0#197'}N'#0#8#4#0#0#128#0#0#0#1#0#24#0#230#2#224#0#0
+#16#0#16#0#152'N$'#0'H'#129'j'#0#0#0#0#0'@'#0#0#0#136#228'D'#0#244#167#18#0#0 +#0#0#0#16#0#16#0#152'N$'#0'H'#129'j'#0#0#0#0#0'@'#0#0#0#136#228'D'#0#244#167
+#0#0#0#0#0#0#0#0#0#0#0#8#168#18#0#251#224#201#0#197'}N'#0' '#0#0#0#0#0#0#0#0 +#18#0#0#0#0#0#0#0#0#0#0#0#0#0#8#168#18#0#251#224#201#0#197'}N'#0' '#0#0#0#0#0
+#0#0#0#0#0#0#0#212'l'#187#0#0#0'h'#0#26#26#198#0#0#0#0#0#0#0#156#0#197'}N'#0 +#0#0#0#0#0#0#0#0#0#0#212'l'#187#0#0#0'h'#0#26#26#198#0#0#0#0#0#0#0#156#0#197
+#197'}N'#0#197'}N'#0#197'}N'#0#197'}N'#0#197'}N'#0#252#226#206#0#251#224#201 +'}N'#0#197'}N'#0#197'}N'#0#197'}N'#0#197'}N'#0#197'}N'#0#252#226#206#0#251
+#0#197'}N'#0#255#0#0#0#0#0#0#0'O'#7'"'#0#174#133'j'#0#181#142'v'#0#188#153 +#224#201#0#197'}N'#0#255#0#0#0#0#0#0#0'O'#7'"'#0#174#133'j'#0#181#142'v'#0
+#129#0#195#162#142#0#211#139'h'#0#225#143'p'#0#195'}C'#0#251#224#201#0#251 +#188#153#129#0#195#162#142#0#211#139'h'#0#225#143'p'#0#195'}C'#0#251#224#201
+#224#201#0#251#224#201#0#251#224#201#0#228#157'X'#0#228#157'X'#0#250#223#199 +#0#251#224#201#0#251#224#201#0#251#224#201#0#228#157'X'#0#228#157'X'#0#250
+#0#197'}N'#0#162#0#0#0#0#0#0#0#164'uV'#0#171'c'#0#177#137'o'#0#198#131'U'#0 +#223#199#0#197'}N'#0#162#0#0#0#0#0#0#0#164'uV'#0#171'c'#0#177#137'o'#0#198
+#239#206#186#0#221#255#255#0#135#238#199#0#228#174'z'#0#228#157'X'#0#229#157 +#131'U'#0#239#206#186#0#221#255#255#0#135#238#199#0#228#174'z'#0#228#157'X'#0
+'\'#0#228#174'z'#0#228#157'X'#0#228#174'z'#0#250#223#199#0#246#218#189#0#0#0 +#229#157'\'#0#228#174'z'#0#228#157'X'#0#228#174'z'#0#250#223#199#0#246#218
+#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#195'Q'#0#239#182 +#189#0#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#195'Q'#0
+#154#0#234#243#232#0#228#157'X'#0#228#157'X'#0#254#232#214#0#253#231#214#0 +#239#182#154#0#234#243#232#0#228#157'X'#0#228#157'X'#0#254#232#214#0#253#231
+#252#227#207#0#252#228#207#0#250#225#202#0#246#217#188#0#247#242#236#0#197'}' +#214#0#252#227#207#0#252#228#207#0#250#225#202#0#246#217#188#0#247#242#236#0
+'N'#0#0#0#0#255#0#0#0#255#175#150#150#255#164'tV'#0#170'~b'#0#177#137'n'#0 +#197'}N'#0#0#0#0#255#0#0#0#255#175#150#150#255#164'tV'#0#170'~b'#0#177#137'n'
+#234#182#151#0#243#243#234#0#237#241#230#0#228#174'z'#0#228#157'X'#0#197'}N' +#0#234#182#151#0#243#243#234#0#237#241#230#0#228#174'z'#0#228#157'X'#0#197'}'
+#0#250#224#199#0#251#226#201#0#249#223#197#0#244#214#184#0#246#216#180#0#175 +'N'#0#250#224#199#0#251#226#201#0#249#223#197#0#244#214#184#0#246#216#180#0
+#150#150#255#0#0#0#255#0#0#0#255#154'eB'#0#160'oO'#0#167'y\'#0#201#139'a'#0 +#175#150#150#255#0#0#0#255#0#0#0#255#154'eB'#0#160'oO'#0#167'y\'#0#201#139'a'
+#230#181#146#0#226#167#129#0#225#167#129#0#197'}N'#0#254#252#251#0#197'}N'#0 +#0#230#181#146#0#226#167#129#0#225#167#129#0#197'}N'#0#254#252#251#0#197'}N'
+#197'}N'#0#197'}N'#0#197'}N'#0#197'}N'#0#197'}N'#0#0#0#0#255#0#0#0#255#175 +#0#197'}N'#0#197'}N'#0#197'}N'#0#197'}N'#0#197'}N'#0#0#0#0#255#0#0#0#255#175
+#150#150#255#150'_<'#0#157'jH'#0#224#187#155#0#202#141'e'#0#234#184#153#0#221 +#150#150#255#150'_<'#0#157'jH'#0#224#187#155#0#202#141'e'#0#234#184#153#0#221
+#165'~'#0#221#166#128#0#208#169#140#0#204#147'n'#0#255#255#255#0#255#255#255 +#165'~'#0#221#166#128#0#208#169#140#0#204#147'n'#0#255#255#255#0#255#255#255
+#0#255#251#247#0#255#248#241#0#228#175#140#0#175#150#150#255#0#0#0#255#0#0#0 +#0#255#251#247#0#255#248#241#0#228#175#140#0#175#150#150#255#0#0#0#255#0#0#0

View File

@ -96,7 +96,9 @@ type
procedure CopyFromInheritedButtonClick(Sender: TObject); procedure CopyFromInheritedButtonClick(Sender: TObject);
procedure CreateButtonClick(Sender: TObject); procedure CreateButtonClick(Sender: TObject);
procedure DeleteLinkButtonClick(Sender: TObject); procedure DeleteLinkButtonClick(Sender: TObject);
procedure DocumentationTagChange(Sender: TObject); procedure DescrMemoChange(Sender: TObject);
procedure ErrorsMemoChange(Sender: TObject);
procedure ExampleEditChange(Sender: TObject);
procedure FormCreate(Sender: TObject); procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject); procedure FormDestroy(Sender: TObject);
procedure FormResize(Sender: TObject); procedure FormResize(Sender: TObject);
@ -106,6 +108,7 @@ type
procedure ApplicationIdle(Sender: TObject; var Done: Boolean); procedure ApplicationIdle(Sender: TObject; var Done: Boolean);
procedure MoveToInheritedButtonClick(Sender: TObject); procedure MoveToInheritedButtonClick(Sender: TObject);
procedure SaveButtonClick(Sender: TObject); procedure SaveButtonClick(Sender: TObject);
procedure ShortEditEditingDone(Sender: TObject);
private private
FCaretXY: TPoint; FCaretXY: TPoint;
FModified: Boolean; FModified: Boolean;
@ -114,6 +117,7 @@ type
fSourceFilename: string; fSourceFilename: string;
fChain: TCodeHelpElementChain; fChain: TCodeHelpElementChain;
FOldValues: TFPDocElementValues; FOldValues: TFPDocElementValues;
FOldVisualValues: TFPDocElementValues;
function GetDoc: TXMLdocument; function GetDoc: TXMLdocument;
function GetDocFile: TLazFPDocFile; function GetDocFile: TLazFPDocFile;
function GetSourceFilename: string; function GetSourceFilename: string;
@ -426,6 +430,12 @@ begin
Save; Save;
end; end;
procedure TFPDocEditor.ShortEditEditingDone(Sender: TObject);
begin
if ShortEdit.Text<>FOldVisualValues[fpdiShort] then
Modified:=true;
end;
function TFPDocEditor.GetContextTitle(Element: TCodeHelpElement): string; function TFPDocEditor.GetContextTitle(Element: TCodeHelpElement): string;
// get codetools path. for example: TButton.Align // get codetools path. for example: TButton.Align
begin begin
@ -619,24 +629,31 @@ begin
if EnabledState then if EnabledState then
begin begin
FOldValues:=Element.FPDocFile.GetValuesFromNode(Element.ElementNode); FOldValues:=Element.FPDocFile.GetValuesFromNode(Element.ElementNode);
ShortEdit.Text := ConvertLineEndings(FOldValues[fpdiShort]); FOldVisualValues[fpdiShort]:=ReplaceLineEndings(FOldValues[fpdiShort],'');
DescrMemo.Lines.Text := ConvertLineEndings(FOldValues[fpdiDescription]); FOldVisualValues[fpdiDescription]:=ConvertLineEndings(FOldValues[fpdiDescription]);
ErrorsMemo.Lines.Text := ConvertLineEndings(FOldValues[fpdiErrors]); FOldVisualValues[fpdiErrors]:=ConvertLineEndings(FOldValues[fpdiErrors]);
LinkListBox.Items.Text := ConvertLineEndings(FOldValues[fpdiSeeAlso]); FOldVisualValues[fpdiSeeAlso]:=ConvertLineEndings(FOldValues[fpdiSeeAlso]);
FOldVisualValues[fpdiExample]:=ConvertLineEndings(FOldValues[fpdiExample]);
DebugLn(['TFPDocEditor.LoadGUIValues Short="',dbgstr(FOldValues[fpdiShort]),'"']);
LinkListBox.Items.Text := FOldVisualValues[fpdiSeeAlso];
LinkIdComboBox.Text := ''; LinkIdComboBox.Text := '';
LinkTextEdit.Clear; LinkTextEdit.Clear;
ExampleEdit.Text := ConvertLineEndings(FOldValues[fpdiExample]);
end end
else else
begin begin
ShortEdit.Text := lisCodeHelpNoDocumentation; FOldVisualValues[fpdiShort]:=lisCodeHelpNoDocumentation;
DescrMemo.Lines.Text := lisCodeHelpNoDocumentation; FOldVisualValues[fpdiDescription]:=lisCodeHelpNoDocumentation;
ErrorsMemo.Lines.Text := lisCodeHelpNoDocumentation; FOldVisualValues[fpdiErrors]:=lisCodeHelpNoDocumentation;
FOldVisualValues[fpdiSeeAlso]:=lisCodeHelpNoDocumentation;
FOldVisualValues[fpdiExample]:=lisCodeHelpNoDocumentation;
LinkIdComboBox.Text := lisCodeHelpNoDocumentation; LinkIdComboBox.Text := lisCodeHelpNoDocumentation;
LinkTextEdit.Text := lisCodeHelpNoDocumentation; LinkTextEdit.Text := lisCodeHelpNoDocumentation;
LinkListBox.Clear; LinkListBox.Clear;
ExampleEdit.Text := lisCodeHelpNoDocumentation;
end; end;
ShortEdit.Text := FOldVisualValues[fpdiShort];
DescrMemo.Lines.Text := FOldVisualValues[fpdiDescription];
ErrorsMemo.Lines.Text := FOldVisualValues[fpdiErrors];
ExampleEdit.Text := FOldVisualValues[fpdiExample];
ShortEdit.Enabled := EnabledState; ShortEdit.Enabled := EnabledState;
DescrMemo.Enabled := EnabledState; DescrMemo.Enabled := EnabledState;
@ -929,9 +946,16 @@ begin
Result:=true; Result:=true;
end; end;
procedure TFPDocEditor.DocumentationTagChange(Sender: TObject); procedure TFPDocEditor.ErrorsMemoChange(Sender: TObject);
begin begin
Modified := True; if ErrorsMemo.Text<>FOldVisualValues[fpdiErrors] then
Modified:=true;
end;
procedure TFPDocEditor.ExampleEditChange(Sender: TObject);
begin
if ExampleEdit.Text<>FOldVisualValues[fpdiExample] then
Modified:=true;
end; end;
function TFPDocEditor.MakeLink: String; function TFPDocEditor.MakeLink: String;
@ -1012,6 +1036,12 @@ begin
end; end;
end; end;
procedure TFPDocEditor.DescrMemoChange(Sender: TObject);
begin
if DescrMemo.Text<>FOldVisualValues[fpdiDescription] then
Modified:=true;
end;
initialization initialization
{$I fpdoceditwindow.lrs} {$I fpdoceditwindow.lrs}