{$mode objfpc}
{$h+}
unit pgEditor;
interface
uses SysUtils,Classes,gdk,fpgtk,gtk,fpgtkext,dom,xmlread,xmlwrite;
Type
TTagType = (ttBold,ttItalic,ttUnderline,ttParagraph,ttVariable,ttRemark,
ttNumberedList,ttUnnumberedList,ttListItem,ttTable,ttRow,
ttCell,TTHeader,ttPre,ttCode,ttLink,ttFile);
TNodeTreeItem = Class(TFPGtkTreeItem)
Private
FNode : TDomElement;
Public
Constructor Create (ANode : TDomElement); virtual;
Property Node : TDomElement Read Fnode;
Procedure CheckSubTree;
end;
TModuleTreeItem = Class(TNodeTreeItem);
TTopicTreeItem = Class(TNodeTreeItem);
TPackageTreeItem = Class(TNodeTreeItem);
TNodeSelectEvent = Procedure (Sender : TObject; Node : TDomElement) Of Object;
TPackageEditor = Class(TFPGtkVPaned)
Private
FCurrentPackage,
FCurrentElement,
FCurrentModule,
FCurrentTopic : TDomElement;
FOnSelectElement,
FOnSelectPackage,
FOnSelectTopic,
FOnSelectionChanged,
// FOnDeSelectElement,
FOnSelectModule : TNodeSelectEvent;
FDescriptionNode : TDomNode;
FModuleTree : TFPGtkScrollTree;
FElementTree : TFPGtkScrollTree;
FModuleNode : TNodeTreeItem;
FModified : Boolean;
PTMenu,
PMMenu : TFPgtkMenu;
PMNode : TNodeTreeItem;
FTRenameMenu,
FTDeleteMenu,
FRenameMenu,
FDeleteMenu : TFPgtkMenuItem;
Procedure MenuRenameClick(Sender : TFPGtkObject; Data : Pointer);
Procedure MenuDeleteClick(Sender : TFPGtkObject; Data : Pointer);
Function PopupModuleMenu(Sender:TFPgtkWidget; Event:PGdkEventButton; data:pointer): boolean;
Function PopupTopicMenu(Sender:TFPgtkWidget; Event:PGdkEventButton; data:pointer): boolean;
Procedure SelectTopic(Sender : TFPGtkObject; Data : Pointer);
Procedure SelectModule(Sender : TFPGtkObject; Data : Pointer);
Procedure SelectPackage(Sender : TFPGtkObject; Data : Pointer);
Procedure SelectElement(Sender : TFPGtkObject; Data : Pointer);
// Procedure DeSelectElement(Sender : TFPGtkWidget; Data : Pointer);
// Procedure DoSelectionChanged(Sender : TFPGtkWidget; Data : Pointer);
Procedure ShowModuleElements(Module : TDomElement);
Procedure SetCurrentModule(Value : TDomElement);
Procedure SetCurrentPackage(Value : TDomElement);
Function FindPackageNode(P : TDomElement) : TNodeTreeItem;
Function FindModuleNodeInNode(M : TDomElement; N : TNodeTreeItem) : TNodeTreeItem;
Function FindTopicNodeInNode(M : TDomElement; N : TNodeTreeItem) : TNodeTreeItem;
Function FindElementNode(E : TDomElement; N : TNodeTreeItem) : TNodeTreeItem;
Procedure SetCurrentElement(E : TDomElement);
Procedure SetCurrentTopic(T : TDomElement);
Function CreateElementNode(E : TDomelement) : TNodeTreeItem;
Procedure DeletePackage(N : TNodeTreeItem);
Procedure DeleteModule(N : TNodeTreeItem);
Procedure DeleteTopic(N : TNodeTreeItem);
Procedure DeleteElement(N : TNodeTreeItem);
Procedure RenamePackage(N : TNodeTreeItem);
Procedure RenameModule(N : TNodeTreeItem);
Procedure RenameTopic(N : TNodeTreeItem);
Procedure RenameElement(N : TNodeTreeItem);
Function GetSelectedNode : TNodeTreeItem;
Procedure GetNameData(Sender : TFPGtkWindow;Data : Pointer; Action : Integer;Initiator : TFPGtkObject);
Function NewName(ATitle : String;Var AName : String) : Boolean;
Procedure ClearElements;
Public
Constructor Create;
Procedure SetDescriptionNode (Value : TDomNode);
Procedure Refresh;
Procedure AddElement(E : TDomElement);
Procedure DeletePackage(P : TDomElement);
Procedure DeleteModule(M : TDomElement);
Procedure DeleteElement(E : TDomElement);
Procedure DeleteTopic(T : TDomElement);
Procedure RenamePackage(P : TDomElement);
Procedure RenameModule(M : TDomElement);
Procedure RenameElement(E : TDomElement);
Procedure RenameTopic(T : TDomElement);
Property ModuleTree : TFPGtkScrollTree Read FModuleTree;
Property ElementTree : TFPGtkScrollTree Read FElementTree;
Property DescriptionNode : TDomNode Read FDescriptionNode Write SetDescriptionNode;
Property OnSelectModule : TNodeSelectEvent Read FOnSelectModule Write FOnSelectmodule;
Property OnSelectTopic : TNodeSelectEvent Read FOnSelectTopic Write FOnSelectTopic;
Property OnSelectPackage : TNodeSelectEvent Read FOnSelectPackage Write FOnSelectPackage;
// Property OnDeSelectElement : TNodeSelectEvent Read FOnDeSelectElement Write FOnDeSelectElement;
Property OnSelectElement : TNodeSelectEvent Read FOnSelectElement Write FOnSelectElement;
// Property OnSelectionChanged : TNodeSelectEvent Read FOnSelectionChanged Write FOnSelectionChanged;
Property CurrentPackage : TDomElement Read FCurrentPackage Write SetCurrentPackage;
Property CurrentModule : TDomElement Read FCurrentModule Write SetCurrentModule;
Property CurrentTopic : TDomElement Read FCurrentTopic Write SetCurrentTopic;
Property CurrentElement: TDomElement Read FCurrentElement Write SetCurrentElement;
Property Modified : Boolean Read FModified Write FModified;
end;
TElementEditor = Class(TFPGtkVBox)
Private
FExampleNode,
FShortNode,
FDescrNode,
FErrorsNode,
FSeeAlsoNode,
Felement : TDomElement;
FLabel : TFPGtkLabel;
FShortEntry : TFPGtkEntry;
FDescrMemo,
FErrorsMemo,
FSeeAlsoMemo : TFPGtkScrollText;
FExample : TFPGtkEntry;
FCurrentEditable : TFPGtkEditable;
FModified : Boolean;
Procedure GetNodes;
Procedure SetElement (Value : TDomElement);
Function CurrentEditable : TFPGtkEditable;
Function OnEditableFocusIn(Sender : TFPGtkWidget; Event : PGDKEventFocus;Data : Pointer) : Boolean;
Function GetCurrentSelection : String;
Procedure OnTextModified(Sender : TFPGtkObject; Data : Pointer);
Public
Procedure Refresh;
Constructor Create;
Function TestSave(S : String) : Boolean;
Function CurrentXML : String;
Function Save : Boolean;
Procedure DeleteElement;
Procedure InsertTag (tagName : String);
Procedure InsertTag (TagType : TTagType);
Procedure InsertLink(LinkTarget,LinkText : String);
Procedure InsertTable(Cols,Rows : Integer; UseHeader : Boolean);
Property Element : TDomElement Read FElement Write SetElement;
Property CurrentSelection : String Read GetCurrentSelection;
Property Modified : Boolean Read FModified Write FModified;
end;
TEditorPage = Class(TFPGtkHPaned)
Private
FChangingSelection : Boolean;
FFileNameLabel : TFpGtkLabel;
FDocument : TXMLDocument;
FPackages : TPackageEditor;
FElement : TElementEditor;
FFileNAme : String;
Procedure ElementSelected(Sender : TObject; Node : TDomElement) ;
Procedure TopicSelected(Sender : TObject; Node : TDomElement) ;
Procedure ModuleSelected(Sender : TObject; Node : TDomElement) ;
Procedure PackageSelected(Sender : TObject; Node : TDomElement) ;
// Procedure SelectionChanged(Sender : TFPgtkWidget; Node : TDomElement) ;
// Procedure ElementDeSelected(Sender : TObject; Node : TDomElement) ;
Function GetCurrentSelection : String;
Function GetCurrentPackage : TDomElement;
Function GetCurrentModule : TDomElement;
Function GetCurrentTopic : TDomElement;
Function GetCurrentElement : TDomElement;
Procedure SetCurrentModule(Value : TDomElement);
Procedure SetCurrentTopic(Value : TDomElement);
Procedure SetCurrentPackage(Value : TDomElement);
Procedure SetCurrentElement(Value : TDomElement);
Procedure SetModified(Value : Boolean);
Function GetModified : Boolean;
Function MakeBackup(FN : String) : Boolean;
Public
Constructor Create;
Function FirstPackage : TDomElement;
Function FirstModule(APackage : TDomElement) : TDomElement;
Procedure DisplayDocument;
Procedure ClearDocument;
Procedure LoadFromFile(FN : String);
Procedure LoadFromStream(S : TStream);
Procedure SaveToFile(FN : String);
Procedure SetFileName(FN : String);
Procedure InsertTag(TagType : TTagType);
Procedure InsertLink(LinkTarget,LinkText : String);
Procedure InsertTable(Cols,Rows : Integer; UseHeader : Boolean);
Procedure NewPackage(APackageName : String);
Procedure NewModule(AModuleName : String);
Procedure NewTopic(ATopicName : String);
Procedure NewElement(AElementName : String);
Procedure GetElementList(List : TStrings);
Property FileName : String Read FFileName;
Property CurrentSelection : String Read GetCurrentSelection;
Property CurrentPackage : TDomElement Read GetCurrentPackage Write SetCurrentPackage;
Property CurrentModule : TDomElement Read GetCurrentModule Write SetCurrentModule;
Property CurrentTopic : TDomElement Read GetCurrentTopic Write SetCurrentTopic;
Property CurrentElement : TDomElement Read GetCurrentElement Write SetCurrentElement;
Property FileNameLabel : TFPgtkLabel Read FFileNameLabel Write FFileNameLabel;
Property Modified : Boolean Read GetModified Write SetModified;
end;
Const
TagNames : Array[TTagType] of string = ('b','i','u','p','var','remark',
'ol','ul','li','table','tr',
'td','th','pre','code','link','file'
);
implementation
uses fpdemsg,frmnewnode,fpdeopts;
{ ---------------------------------------------------------------------
TElementEditor
---------------------------------------------------------------------}
Constructor TElementEditor.Create;
Var
F1,F2 : TFPGtkVPaned;
V : TFPgtkVBox;
L : TFpGtkLabel;
begin
Inherited Create;
FLabel:=TFPgtkLabel.Create(SNoElement);
PackStart(FLabel,False,False,0);
L:=TFPGtkLabel.Create(SShortDescription);
// Short
V:=TFPGtkVBox.Create;
FShortEntry:=TFPGtkEntry.Create;
FShortEntry.ConnectFocusInEvent(@OnEditableFocusIn,Nil);
FShortEntry.ConnectChanged(@OnTextModified,Nil);
V.PackStart(L,False,False,0);
V.PackStart(FShortEntry,True,true,0);
PackStart(V,false,false,0);
// Errors
L:=TFPGtkLabel.Create(SErrors);
V:=TFPGtkVBox.Create;
FErrorsMemo:=TFPGtkScrollText.Create;
FErrorsMemo.TheText.ConnectFocusInEvent(@OnEditableFocusIn,Nil);
FErrorsMemo.TheText.ConnectChanged(@OnTextModified,Nil);
FErrorsMemo.setusize(400,50);
V.PackStart(L,False,False,0);
V.PackStart(FErrorsMemo,True,true,0);
F2:=TFPGtkVPaned.Create;
F2.Pack1(V,True,True);
// See Also
V:=TFPGtkVBox.Create;
L:=TFPGtkLabel.Create(SSeeAlso);
FSeeAlsoMemo:=TFPGtkScrollText.Create;
// FSeeAlsoMemo.TheText.ConnectEnterNotify(@OnEnterEditable,Nil);
FSeeAlsoMemo.TheText.ConnectFocusInEvent(@OnEditableFocusIn,Nil);
FSeeAlsoMemo.TheText.ConnectChanged(@OnTextModified,Nil);
FSeeAlsoMemo.setusize(400,50);
V.PackStart(L,False,False,0);
V.PackStart(FSeeAlsoMemo,True,true,0);
F2.Pack2(V,False,True);
// Descr
L:=TFPGtkLabel.Create(SDescription);
V:=TFPGtkVBox.Create;
FDescrMemo:=TFPGtkScrollText.Create;
// FDescrMemo.TheText.ConnectEnterNotify(@OnEnterEditable,Nil);
FDescrMemo.TheText.ConnectFocusInEvent(@OnEditableFocusIn,Nil);
FDescrMemo.TheText.ConnectChanged(@OnTextModified,Nil);
FDescrMemo.setusize(400,150);
V.PackStart(L,False,False,0);
V.PackStart(FDescrMemo,True,true,0);
F1:=TFPGtkVPaned.Create;
F1.Pack1(V,True,True);
F1.Pack2(F2,False,True);
PackStart(F1,true,true,0);
// Example
V:=TFPGtkVBox.Create;
L:=TFPGtkLabel.Create(SCodeExample);
FExample:=TFPGtkEntry.Create;
FExample.ConnectFocusInEvent(@OnEditableFocusIn,Nil);
FExample.ConnectChanged(@OnTextModified,Nil);
V.PackStart(L,False,False,0);
V.PackStart(FExample,True,true,0);
PackStart(V,false,false,0);
end;
Procedure TElementEditor.SetElement (Value : TDomElement);
begin
// Writeln('Setelement');
If (Value<>FElement) then
If not Modified or Save then
begin
{
If (Value=Nil) then
Writeln('Setelement called with Nil')
else
Writeln('Setelement : ',Value['name']);}
FElement:=Value;
// Writeln('Setelement : Refreshing');
Refresh;
// Writeln('SetElement : Refreshed');
end;
end;
Procedure TElementEditor.DeleteElement;
begin
FElement:=Nil;
Refresh;
end;
Procedure TElementEditor.Refresh;
Var
S : TSTringStream;
Function NodeToString(E : TDomElement) : String;
Var
N : TDomNode;
begin
If (E=Nil) then
Result:=''
else
begin
S.Seek(0,soFromBeginning);
S.Size:=0;
N:=E.FirstChild;
While Assigned(N) do
begin
WriteXml(N,S);
N:=N.NextSibling;
end;
Result:=S.Datastring;
end;
end;
Function RemoveLineFeeds(S : String) : String;
Var
I : Integer;
begin
Result:=S;
For I:=1 to Length(Result) do
If Result[i] in [#10,#13] then
Result[i]:=' ';
end;
begin
GetNodes;
If Assigned(Felement) then
FLabel.Text:=Format(SDataForElement,[FElement['name']])
else
FLabel.Text:=SNoElement;
S:=TStringStream.Create('');
Try
FShortEntry.Text:=RemoveLineFeeds(NodeToString(FShortNode));
FDescrMemo.Text:=NodeToString(FDescrNode);
FErrorsMemo.Text:=NodeToString(FErrorsNode);
FSeeAlsoMemo.Text:=NodeToString(FSeeAlsoNode);
If FExampleNode=Nil then
FExample.Text:=''
else
FExample.Text:=FExampleNode['file'];
FModified:=False;
Finally
S.Free;
end;
end;
Function TElementeditor.TestSave(S : String) : Boolean;
Const
Head = '