2
***************************************************************************
4
* This source is free software; you can redistribute it and/or modify *
5
* it under the terms of the GNU General Public License as published by *
6
* the Free Software Foundation; either version 2 of the License, or *
7
* (at your option) any later version. *
9
* This code is distributed in the hope that it will be useful, but *
10
* WITHOUT ANY WARRANTY; without even the implied warranty of *
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12
* General Public License for more details. *
14
* A copy of the GNU General Public License is available on the World *
15
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
16
* obtain it by writing to the Free Software Foundation, *
17
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19
***************************************************************************
21
Author: Michael Van Canneyt
22
Changed to Frame by Vladislav V. Sudarikov
30
uses SysUtils, Classes, DOM, xmlread, xmlwrite, Forms, Controls, ExtCtrls,
31
StdCtrls, Dialogs, Menus, fpdeutil, Lazdemsg, Lazdeopts,
32
GraphType, ActnList, LResources, Buttons;
37
TGetElementListEvent = Procedure (List : TStrings) of Object;
38
TGetInitialDirEvent = function: string of object;
42
TElemEditorFrame = Class(TFrame)
50
lblShortDescr: TLabel;
51
lbxExamples: TListBox;
60
spbAddExample: TSpeedButton;
61
spbAddSeeAlso: TSpeedButton;
62
spbEditExample: TSpeedButton;
63
spbEditElementLink: TSpeedButton;
64
spbDeleteExample: TSpeedButton;
65
spbDeleteSeeAlso: TSpeedButton;
66
spbEditSeeAlso: TSpeedButton;
70
Procedure OnEnterControl(Sender : TObject);
71
Procedure OnTextModified(Sender : TObject);
72
Procedure DoEditSeeAlso(Sender: TObject);
73
Procedure DoDeleteSeeAlso(Sender: TObject);
74
Procedure DoAddExample(Sender : TObject);
75
Procedure DoEditExample(Sender : TObject);
76
Procedure DoDeleteExample(Sender : TObject);
77
Procedure DoAddSeeAlso(Sender : TObject);
78
Procedure DoEditElementLink(Sender : TObject);
80
FElementLink : String;
81
Felement : TDomElement;
82
FCurrentEditable : TWinControl;
83
FGetElementList: TGetElementListEvent;
86
FTargetFileName: string;
87
FGetInitialDir: TGetInitialDirEvent;
88
FChangeEvent: TNotifyEvent;
89
FOnChangeCount: Integer;
90
Function EditLink(Var Value,ALinkText : String) : Boolean;
91
procedure SetModified(const AValue: Boolean);
92
procedure ShowElementCaption;
94
Function GetCurrentSelection : String; virtual; abstract;
95
Procedure SetElement (Value : TDomElement); virtual;
96
Function GetInitialDir: String;
97
procedure LockOnChange;
98
procedure UnLockOnChange;
100
Procedure Refresh; virtual; abstract;
101
Function TestSave(S : String) : Boolean; virtual; abstract;
102
Function CurrentXML : String; virtual; abstract;
103
Function Save : Boolean; virtual; abstract;
104
Function CanInsertTag(TagTYpe : TTagType) : Boolean; virtual; abstract;
105
Procedure DeleteElement; virtual; abstract;
106
Procedure InsertTag (tagName : String); virtual; abstract;
107
Procedure InsertTag (TagType : TTagType); virtual; abstract;
108
Procedure InsertLink(LinkTarget,LinkText : String); virtual; abstract;
109
Procedure InsertTable(Cols,Rows : Integer; UseHeader : Boolean); virtual; abstract;
110
procedure InsertPrintShortLink(pLinkTarget: string); virtual; abstract;
111
procedure InsertItemizeList(ItemsCount: Integer); virtual; abstract;
112
procedure InsertEnumerateList(ItemsCount: Integer); virtual; abstract;
114
Property Element : TDomElement Read FElement Write SetElement;
115
Property CurrentSelection : String Read GetCurrentSelection;
116
Property Modified : Boolean Read FModified Write SetModified;
117
Property SavedNode : Boolean Read FSavedNode Write FSavedNode;
118
Property TargetFileName: String read FTargetFileName write FTargetFileName;
119
Property OnGetElementList : TGetElementListEvent Read FGetElementList Write FGetElementList;
120
Property OnGetInitialDir: TGetInitialDirEvent read FGetInitialdir write FGetInitialDir;
121
Property OnChange: TNotifyEvent read FChangeEvent write FChangeEvent;
126
TElementEditor = Class(TElemEditorFrame)
128
FExampleNodes : TList;
132
FSeeAlsoNode : TDomElement;
134
Function CurrentEditable : TWinControl;
136
Constructor Create (AOwner : TComponent); override;
137
Destructor Destroy; override;
138
Procedure Refresh;override;
139
Function GetCurrentSelection : String; override;
140
Procedure SetElement (Value : TDomElement);override;
141
Function TestSave(S : String) : Boolean;override;
142
Function CurrentXML : String; override;
143
Function Save : Boolean; override;
144
Function CanInsertTag(TagTYpe : TTagType) : Boolean; override;
145
Procedure DeleteElement; override;
146
Procedure InsertTag (tagName : String); override;
147
Procedure InsertTag (TagType : TTagType); override;
148
Procedure InsertLink(LinkTarget,LinkText : String); override;
149
Procedure InsertTable(Cols,Rows : Integer; UseHeader : Boolean); override;
150
procedure InsertPrintShortLink(pLinkTarget: string); override;
151
procedure InsertItemizeList(ItemsCount: Integer); override;
152
procedure InsertEnumerateList(ItemsCount: Integer); override;
157
uses frmexample, frmLink, StrUtils, LCLProc, FrmMain;
159
Function JoinLinkText(lblShortDescr,T : String): String;
161
Result:=lblShortDescr;
163
Result:=Result+'|'+T;
166
Procedure SplitLinkText(LT : String; out lblShortDescr,T : String);
181
lblShortDescr:=Copy(LT,1,P-1);
190
procedure TElemEditorFrame.SetModified(const AValue: Boolean);
193
if (FOnChangeCount=0) and FModified and Assigned(FChangeEvent) then
197
procedure TElemEditorFrame.SetElement(Value: TDomElement);
203
function TElemEditorFrame.GetInitialDir: String;
206
if Assigned(FGetInitialDir) then
207
result := FGetInitialdir();
210
procedure TElemEditorFrame.LockOnChange;
215
procedure TElemEditorFrame.UnLockOnChange;
220
{ ---------------------------------------------------------------------
222
---------------------------------------------------------------------}
225
Constructor TElementEditor.Create(AOwner : TComponent);
229
FExampleNodes:=TList.create;
230
lblShortDescr.Caption := SShortDescription;
231
lblDescr.Caption := sDescription;
232
lblErrors.Caption := SErrors;
233
lblSeeAlso.Caption := SSeeAlso;
234
lblExamples.Caption := SCodeExample;
235
spbAddExample.Hint := SHintToolbarAdd;
236
spbAddSeeAlso.Hint := SHintToolbarAdd;
237
spbDeleteExample.Hint := SHintToolbarDelete;
238
spbDeleteSeeAlso.Hint := SHintToolbarDelete;
239
spbEditElementLink.Hint := SHintToolbarEdit;
240
spbEditExample.Hint := SHintToolbarEdit;
241
spbEditSeeAlso.Hint := SHintToolbarEdit;
242
memDescr.PopupMenu:=MainForm.PopupMenu1;
245
destructor TElementEditor.destroy;
247
FreeAndNil(FExampleNodes);
251
Procedure TElementEditor.SetElement (Value : TDomElement);
254
If (Value<>FElement) then
255
If (not Modified) or Save then
262
Procedure TElementEditor.DeleteElement;
267
Procedure TElemEditorFrame.ShowElementCaption;
271
If Assigned(Felement) then
273
ST:=Format(SDataForElement,[FElement['name']]);
274
If (FElementLink<>'') then
275
ST:=ST+SLinksTo+FElementLink;
279
lblNewElem.Caption:=ST;
282
Procedure TElementEditor.Refresh;
284
function RemoveLFAfterTags(S : String) : String;
286
function RemoveLF(S, Tag : string; LenTag : integer) : string;
290
Remove := pos(Tag, S);
291
while Remove <> 0 do begin
293
while (Remove <= length(S)) and (S[Remove] in [#10, #13]) do
294
delete(S, Remove, 1);
295
Remove := PosEx(Tag, S, Remove);
301
Link = '</link>' + LineEnding;
302
LenLink = length(Link) - length(LineEnding);
303
Parag = '<p/>' + LineEnding;
304
LenParag = length(Parag);
305
Bold = '</b>' + LineEnding;
306
LenBold = length(Bold);
308
Result := RemoveLF(S, Link, LenLink);
309
Result := RemoveLF(Result, Parag, LenParag);
310
Result := RemoveLF(Result, Bold, LenBold);
316
Function NodeToString(E : TDomElement) : String;
326
S.Seek(0,soFromBeginning);
334
Result:=RemoveLFAfterTags(S.Datastring);
338
Function RemoveLineFeeds(S : String) : String;
345
For i := Length(Result) downto 1 do
346
If Result[i] in [#10,#13] then
347
Delete(Result, i, 1);
356
S := TStringStream.Create('');
359
edtShortEntry.Text:=RemoveLineFeeds(NodeToString(FShortNode));
360
memDescr.Text:=NodeToString(FDescrNode);
361
memErrors.Text:=NodeToString(FErrorsNode);
362
lbxSeeAlso.Items.Clear;
363
If Assigned(FSeeAlsoNode) then
365
N:=FSeeAlsoNode.FirstChild;
368
If IsLinkNode(N) then
369
lbxSeeAlso.Items.Add(JoinLinkText(TDomElement(N)['id'],NodeToString(TDomElement(N))));
373
lbxExamples.Items.Clear;
374
For I:=0 to FExampleNodes.Count-1 do
375
lbxExamples.Items.Add(TDomElement(FExampleNodes[i])['file']);
383
Function TElementeditor.TestSave(S : String) : Boolean;
386
Head = '<?xml version="1.0" encoding="ISO-8859-1"?><fpdoc-descriptions>';
387
Tail = '</fpdoc-descriptions>';
388
SErrorSaving = 'There is an error in the documentation nodes:'+LineEnding+
390
'Please correct it first and try saving again.';
400
SS:=TStringStream.Create(Head+S+Tail);
408
MessageDlg(Format(SErrorSaving,[E.Message]),mtError,[mbOK],0)
418
Function TElementEditor.CurrentXML : String;
420
Function GetNodeString(NodeName,Value : String) : String;
425
Result:=Format('<%s>%s</%s>',[NodeName,Value,NodeName])
426
else If Not SkipEmptyNodes then
427
result:='<'+NodeName+'/>';
436
If Not Assigned(FElement) then
438
Result:=GetNodeString('short',Trim(edtShortEntry.Text));
439
Result:=Result+GetNodeString('descr',trim(memDescr.Text));
440
Result:=Result+GetNodeString('errors',trim(memErrors.Text));
442
for I:=0 to lbxSeeAlso.Items.Count-1 do
444
LT:=Trim(lbxSeeAlso.Items[i]);
447
SplitLinkText(LT,L,LT);
449
S:=S+'<link id="'+L+'">'+LT+'</link>'
451
S:=S+'<link id="'+L+'"/>';
454
Result:=Result+GetNodeString('seealso',S);
456
for I:=0 to lbxExamples.Items.Count-1 do
457
if Trim(lbxExamples.Items[i])<>'' then
458
S:=S+'<example file="'+Trim(lbxExamples.Items[i])+'"/>';
460
//Result:=Result+GetNodeString('example',S);
463
Function TElementEditor.Save : Boolean;
471
Result:=Not Assigned(FElement);
478
SS:=TStringStream.Create(S);
481
N:=FElement.FirstChild;
485
If not (IsElementNode(N) or IsModuleNode(N) or IsTopicNode(N)) then
486
FElement.RemoveChild(N);
489
// Read them again from stream.
490
SS.Seek(0,soFromBeginning);
491
ReadXMLFragment(FElement,SS);
493
If (FElementLink<>'') then
494
FElement['link']:=FElementLink;
495
// We must get the nodes back, because they were deleted !
506
function TElementEditor.CanInsertTag(TagTYpe: TTagType): Boolean;
508
Result:=(FCurrentEditable is TCustomEdit)
509
and ((TagType<>ttTable) or (FCurrentEditable is TMemo));
512
procedure TElementEditor.InsertTag (tagName : String);
517
If Assigned(CurrentEditable) and (CurrentEditable is TCustomEdit) then
518
with TCustomEdit(CurrentEditable)do
522
S:=Format('<%s>%s</%s>',[TagName,S,TagName]);
525
SelLength:=UTF8Length(S);
530
Procedure TElementEditor.InsertTag(TagType : TTagType);
533
InsertTag(TagNames[TagTYpe]);
536
Procedure TElementEditor.InsertLink(LinkTarget,LinkText : String);
539
If (CurrentEditable<>Nil) and (CurrentEditable is TCustomEdit) then
540
With TCustomEdit(CurrentEditable) do
542
If (LinkText<>'') then
543
SelText:='<link id="'+LinkTarget+'">'+LinkText+'</link>'
545
SelText:='<link id="'+LinkTarget+'"/>';
547
else if (CurrentEditable=lbxSeeAlso) then
548
lbxSeeAlso.Items.add(LinkTarget);
552
Procedure TElementEditor.InsertTable(Cols,Rows : Integer; UseHeader : Boolean);
559
If (CurrentEditable is TMemo) then
564
R:=R+'</tr>'+lineEnding;
572
T:=T+'</th>'+lineEnding;
576
T:=LineEnding+'<table>'+LineEnding+T+'</table>'+LineEnding;
577
With TMemo(CurrentEditable) do
583
procedure TElementEditor.InsertPrintShortLink(pLinkTarget: string);
585
{ Should be Limit insert only to Long Description edit box? }
586
if (CurrentEditable <> nil) and (CurrentEditable is TCustomEdit) then
588
(CurrentEditable as TCustomEdit).SelText :=
589
Format('<%s id="%s"/>', [TagNames[ttPrintShort], pLinkTarget]);
594
procedure TElementEditor.InsertItemizeList(ItemsCount: Integer);
599
If (CurrentEditable is TMemo) then
601
R:='<ul>'+lineEnding;
602
for I:=1 to ItemsCount do
603
R:=R+'<li></li>'+lineEnding;
604
R:=R+'</ul>'+lineEnding;
605
With TMemo(CurrentEditable) do
610
procedure TElementEditor.InsertEnumerateList(ItemsCount: Integer);
615
if (CurrentEditable is TMemo) then
617
R:='<ol>'+lineEnding;
618
for I:=1 to ItemsCount do
619
R:=R+'<li></li>'+lineEnding;
620
R:=R+'</ol>'+lineEnding;
621
with TMemo(CurrentEditable) do
627
Procedure TElementEditor.GetNodes;
639
If Assigned(FElement) then
641
FElementLink:=FElement['link'];
642
Node:=FElement.FirstChild;
643
While Assigned(Node) do
645
If (Node.NodeType=ELEMENT_NODE) then
649
FShortNode:=TDomElement(Node)
650
else if S='descr' then
651
FDescrNode:=TDomElement(Node)
652
else if S='errors' then
653
FErrorsNode:=TDomElement(Node)
654
else if S='seealso' then
655
FSeeAlsoNode:=TDomElement(Node)
656
else if S='example' then
657
FExampleNodes.Add(Node);
659
Node:=Node.NextSibling;
664
Function TElementEditor.CurrentEditable : TWinControl;
667
Result:=FCurrentEditable;
670
procedure TElemEditorFrame.OnEnterControl(Sender: TObject);
673
FCurrentEditable:=Sender as TWinControl;
676
Procedure TElemEditorFrame.OnTextModified(Sender : TObject);
682
procedure TElemEditorFrame.DoAddExample(Sender: TObject);
686
With TExampleForm.Create(Self) do
688
Caption := SInsertExampleCode;
689
EFileName.Text := 'example.pp';
690
LEFileName.Caption := SCodeExample;
691
EFileName.InitialDir := GetInitialDir;
692
If ShowModal=mrOK then
694
if lbxExamples.Items.IndexOf(ExampleName)<0 then
696
lbxExamples.Items.Add(ExampleName);
705
procedure TElemEditorFrame.DoEditExample(Sender: TObject);
711
If ItemIndex<>-1 then
712
With TExampleForm.Create(Self) do
714
Caption := SInsertExampleCode;
715
EFileName.Text := Items[ItemIndex];
716
LEFileName.Caption := SCodeExample;
717
EFileName.InitialDir := GetInitialDir;
718
If ShowModal=mrOK then
720
Items[ItemIndex]:=ExampleName;
729
procedure TElemEditorFrame.DoDeleteExample(Sender: TObject);
735
If ItemIndex<>-1 then
737
Items.Delete(ItemIndex);
743
Function TElemEditorFrame.EditLink(Var Value,ALinkText : String) : Boolean;
745
With TLinkForm.Create(Self) do
747
Caption:=SInsertLink;
748
LLinkTarget.Caption := SLinkTarget;
749
LELinkText.Caption := SLinkText;
750
If Assigned(OnGetElementList) then
754
OnGetElementList(Links);
761
Result:=ShowModal=mrOK;
764
Value:=CBTarget.Text;
772
procedure TElemEditorFrame.DoAddSeeAlso(Sender: TObject);
779
If EditLink(S,T) then
781
S:=JoinLinkText(S,T);
782
if lbxSeeAlso.Items.IndexOf(S)<0 then
784
lbxSeeAlso.Items.Add(S);
790
procedure TElemEditorFrame.DoEditSeeAlso(Sender: TObject);
797
If (ItemIndex>=0) then
799
SplitLinkText(Items[ItemIndex],S,T);
806
If EditLink(S,T) then
808
S:=JoinLinkText(S,T);
809
If (ItemIndex>=0) then
818
procedure TElemEditorFrame.DoDeleteSeeAlso(Sender: TObject);
822
If (ItemIndex<>-1) then
824
Items.Delete(ItemIndex);
829
procedure TElemEditorFrame.DoEditElementLink(Sender: TObject);
831
With TLinkForm.Create(Self) do
833
Caption:=SHintEditElementLink;
834
LLinkTarget.Caption := SLinkTarget;
835
LELinkText.Caption := SLinkText;
836
If Assigned(OnGetElementList) then
840
OnGetElementList(Links);
846
EnableLinkText:=False;
847
If ShowModal=mrOK then
857
Function TElementEditor.GetCurrentSelection : String;
860
If (CurrentEditable=Nil) or not (CurrentEditable is TCustomEdit) then
863
Result:=TCustomEdit(CurrentEditable).SelText;