TWPXMLPropertyEditor Object
Properties Methods

Unit
WPXMLEditor

Declaration
TWPXMLPropertyEditor = class(TForm)

Hierarchy
TForm <--TWPXMLPropertyEditor

Subclasses
None

Description
The form TWPXMLPropertyEditor is used to edit XML properties of the TWPLanguageControl and TWPXMLTree. It can also be used to edit XML data in your appliocation:
program WPXMLEdit;

uses
  Forms, WPXMLEditor;

{$R *.RES}

begin
  Application.Initialize;
  // This form is loaded from unit "WPXMLEditor"
  Application.CreateForm(TWPXMLPropertyEditor, WPXMLPropertyEditor);
  WPXMLPropertyEditor.Caption := 'wpCubed XML Editor Demo - www.wptools.de';
  WPXMLPropertyEditor.AskSave := TRUE;
  Application.Run;
end.

The editor displays the XML data in a tree. On the left side you can enter text for the properties of an XML tag (NAME="...") and a memo to edit the text inside the XML tag: (<TAG>TEXT</TAG>)



The editor does not allow the creation of new tags or properties but it makes it easy to:


The editor was mainly created to edit the language definition of the TWPLanguageControl and was optimized for this usage.

As an example how to use the powerful class TWPXMLTree here is the interesting part of the XML editor source code:

 TWPXMLPropertyEditor = class(TForm)
  // ... 
  private
    FLastSelected: TTreeNode;
    FModified: Boolean;
    FSaved: Boolean;
    FindList: TList;
    FindNextPos: Integer;
    procedure SetLastSelected(x: TTreeNode);
  public
    Source: TWPCustomXMLInterface;
    AskSave: Boolean;
    property Saved: Boolean read FSaved;
    property LastSelected: TTreeNode read FLastSelected write SetLastSelected;
    procedure UpdateTreeview;
  end;
  
  implementation
  
// Load a File
procedure TWPXMLPropertyEditor.Load1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
  begin
    PageControl1.ActivePage := TabSheet1;
    LastSelected := nil;
    WPXMLTree1.LoadFromFile(OpenDialog1.FileName);
    SaveDialog1.FileName := OpenDialog1.FileName;
    FModified := FALSE;
  end;
end;

// Merge a File
procedure TWPXMLPropertyEditor.Merge1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
  begin
    PageControl1.ActivePage := TabSheet1;
    LastSelected := nil;
    WPXMLTree1.AppendFromFile(OpenDialog1.FileName);
    FModified := TRUE;
  end;
end;

// Save a File
procedure TWPXMLPropertyEditor.Save1Click(Sender: TObject);
begin
  if SaveDialog1.Execute then
  begin
    PageControl1.ActivePage := TabSheet1;
    LastSelected := nil;
    WPXMLTree1.SaveToFile(SaveDialog1.FileName);
    FModified := FALSE;
  end;
end;

// Before Close ...
procedure TWPXMLPropertyEditor.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
  i: Integer;
begin
  PageControl1.ActivePage := TabSheet1;
  if Source <> nil then // Property Editor Mode
  begin
    if MessageDlg('Save XML Data', mtConfirmation, [mbYes, mbNo], 0) = IDYES then
    begin
      LastSelected := nil;
      Source.XMLData.Assign(WPXMLTree1.XMLData);
      FSaved := TRUE;
    end
    else FSaved := FALSE;
  end
  else if FModified and AskSave then // File Editor Mode
  begin
    i := MessageDlg('Save XML Data', mtConfirmation, [mbYes, mbNo, mbCancel], 0);
    if i = IDCANCEL then CanClose := FALSE
    else if i = IDYES then
    begin
      Save1Click(nil);
      CanClose := not FModified;
    end;
  end;
end;

// Select a different branch
procedure TWPXMLPropertyEditor.TreeView1Click(Sender: TObject);
begin
  LastSelected := TreeView1.Selected;
end;


// Event triggered by the TWPXMLTree after a file was loaded
procedure TWPXMLPropertyEditor.WPXMLTree1Loaded(Sender: TObject);
begin
  UpdateTreeview;
  if FindList <> nil then FindList.Clear;
  FindNext1.Enabled := FALSE;
end;


// Create treview nodes from the TWPXMLTree
procedure TWPXMLPropertyEditor.UpdateTreeview;
  procedure AddToTree(Node: TTreeNode; Item: TWPXMLOneLevel);
  var
    NewNode: TTreeNode;
    i: Integer;
  begin
    if Item <> nil then
    begin
      if Item.Name = '' then NewNode := Node
      else NewNode := TreeView1.Items.AddChild(Node, Item.Name);
      if NewNode <> nil then
      begin
        NewNode.Data := Item;
        Item.Obj := NewNode;
      end;
      for i := 0 to Item.Count - 1 do
        AddToTree(NewNode, Item.Elements[i]);
    end;
  end;
begin
  TreeView1.Selected := nil;
  TreeView1.Items.BeginUpdate;
  TreeView1.Items.Clear;
  try
    AddToTree(nil, WPXMLTree1.Tree);
  finally
    TreeView1.Items.EndUpdate;
    if TreeView1.Items.Count > 0 then
    begin
      TreeView1.Selected := TreeView1.Items[0];
      TreeView1Click(nil);
    end;
  end;
end;

// Update the selected Node
procedure TWPXMLPropertyEditor.SetLastSelected(x: TTreeNode);
var
  i: Integer;
  vis: Boolean;
begin
  vis := FALSE;
  if x <> FLastSelected then
  begin
    if (FLastSelected <> nil) and (FLastSelected.Data <> nil) then
    begin
      if StringGrid1.Visible then
        for i := 0 to StringGrid1.RowCount - 1 do
          TWPXMLOneLevel(FLastSelected.Data).ParamValue[StringGrid1.Cells[0, i]] :=
            StringGrid1.Cells[1, i];
      TWPXMLOneLevel(FLastSelected.Data).Content := Memo1.Text;
    end;
    FLastSelected := x;
    if (FLastSelected = nil) or (FLastSelected.Data = nil) then
      StringGrid1.RowCount := 0
    else
    begin
      StringGrid1.RowCount := TWPXMLOneLevel(FLastSelected.Data).ParamCount;
      vis := TWPXMLOneLevel(FLastSelected.Data).ParamCount > 0;
      for i := 0 to TWPXMLOneLevel(FLastSelected.Data).ParamCount - 1 do
      begin
        StringGrid1.Cells[0, i] := TWPXMLOneLevel(FLastSelected.Data).Params.Names[i];
        StringGrid1.Cells[1, i] := TWPXMLOneLevel(FLastSelected.Data).ParamValue[StringGrid1.Cells[0, i]];
      end;
      Memo1.Text := TWPXMLOneLevel(FLastSelected.Data).Content;
      Memo1.Visible := true;
    end;
    StringGrid1.Visible := vis;
  end;
  if FLastSelected = nil then CurrentBranch.Visible := FALSE
  else
  begin
    CurrentBranch.Caption := '&Branch: ' + FLastSelected.Text;
    CurrentBranch.Visible := TRUE;
  end;
end;


// Delete a XML branch
procedure TWPXMLPropertyEditor.DeleteBranch1Click(Sender: TObject);
var
  s: string;
  n: TWPXMLOneLevel;
begin
  if (FLastSelected <> nil) and (FLastSelected.Data <> nil) then
    s := TWPXMLOneLevel(FLastSelected.Data).Path
      + TWPXMLOneLevel(FLastSelected.Data).Name
  else s := '/';
  LastSelected := nil;
  if InputQuery('Delete XML Branch', 'Path', s) then
  begin
    n := WPXMLTree1.Find(s);
    if n <> nil then
    begin
      n.Free;
      UpdateTreeview;
      FModified := TRUE;
    end else ShowMessage('Cannot find path' + s);
  end;
end;

// Move the XML tag
procedure TWPXMLPropertyEditor.MoveBranch1Click(Sender: TObject);
var
  s: string;
begin
  if (FLastSelected <> nil) and (FLastSelected.Data <> nil) then
  begin
    s := TWPXMLOneLevel(FLastSelected.Data).Path + '/' +
      TWPXMLOneLevel(FLastSelected.Data).Name;
    if InputQuery('Move XML Branch "' + s + '"', 'Destination', s) then
    try
      TWPXMLOneLevel(FLastSelected.Data).Path := s;
      FModified := TRUE;
    finally
      UpdateTreeview
    end;
  end;
end;

// Save a tag
procedure TWPXMLPropertyEditor.SaveBranch1Click(Sender: TObject);
var
  p: TWPXMLOneLevel;
  s: string;
begin
  if (FLastSelected <> nil) and (FLastSelected.Data <> nil) then
  begin
    s := TWPXMLOneLevel(FLastSelected.Data).Path +
      TWPXMLOneLevel(FLastSelected.Data).Name;
    if InputQuery('Save XML Branch', 'Path', s) then
    begin
      p := WPXMLTree1.Find(s);
      if (p <> nil) and SaveDialog1.Execute then
      begin
        p.SaveToFile(SaveDialog1.FileName, true);
      end;
    end;
  end;
end;

// Change the name of a branch
procedure TWPXMLPropertyEditor.RenameBranch1Click(Sender: TObject);
var
  s: string;
begin
  if (FLastSelected <> nil) and (FLastSelected.Data <> nil) then
  begin
    s := TWPXMLOneLevel(FLastSelected.Data).Name;
    if InputQuery('Rename XML Branch', 'Name', s) and (s <> '') then
    begin
      TWPXMLOneLevel(FLastSelected.Data).Name := s;
      FLastSelected.Text := s;
      FModified := TRUE;
    end;
  end;
end;

// Finds text
procedure TWPXMLPropertyEditor.FindTextinbranch1Click(Sender: TObject);
var
  s: string;
  f: TWPXMLOneLevel;
begin
  if (FLastSelected <> nil) and (FLastSelected.Data <> nil) then
  begin
    s := '';
    if InputQuery('Find this Text', 'Text', s) and (s <> '') then
    begin
      f := TWPXMLOneLevel(FLastSelected.Data).FindText(s, false, true, FindList);
      if f <> nil then
      begin
        TreeView1.Selected := f.Obj as TTreeNode;
        LastSelected := TreeView1.Selected;
      end;
      FindNextPos := 1;
      FindNext1.Enabled := FindList.Count > FindNextPos;
    end;
  end;
end;

// Repeats "Find"
procedure TWPXMLPropertyEditor.FindNext1Click(Sender: TObject);
begin
  if FindNextPos < FindList.Count then
  begin
    TreeView1.Selected := TWPXMLOneLevel(FindList[FindNextPos]).Obj as TTreeNode;
    LastSelected := TreeView1.Selected;
    inc(FindNextPos);
  end;
  FindNext1.Enabled := FindList.Count > FindNextPos;
end;


// Display the current branch including its start and 
// end tags but without XML header
procedure TWPXMLPropertyEditor.ShowAsString1Click(Sender: TObject);
begin
  if (FLastSelected <> nil) and (FLastSelected.Data <> nil) then
    ShowMessage(TWPXMLOneLevel(FLastSelected.Data).AsString);
end;


// Copy a branch
procedure TWPXMLPropertyEditor.CopyBranch1Click(Sender: TObject);
var
  s, n: string;
  str: TMemoryStream;
begin
  if (FLastSelected <> nil) and (FLastSelected.Data <> nil) then
  begin
    s := TWPXMLOneLevel(FLastSelected.Data).Path + '/' +
      TWPXMLOneLevel(FLastSelected.Data).Name;
    n := TWPXMLOneLevel(FLastSelected.Data).Name;
    if InputQuery('Copy XML Branch "' + s + '"', 'Name on the same level', n) then
    begin
      s := TWPXMLOneLevel(FLastSelected.Data).Name;
      str := TMemoryStream.Create;
      try
        TWPXMLOneLevel(FLastSelected.Data).Name := n;
        TWPXMLOneLevel(FLastSelected.Data).SaveToStream(str, true);
        TWPXMLOneLevel(FLastSelected.Data).Name := s;
        str.Position := 0;
        WPXMLTree1.AppendFromStream(str);
      finally
        str.Free;
      end;
      UpdateTreeview;
      FModified := TRUE;
    end;
  end;
end;


Introduced Properties
LastSelected 
 Saved 

Introduced Methods
CancelClick 
Close1Click 
CopyBranch1Click 
Create1Click 
CreateParaminallelements1Click 
DeleteBranch1Click 
FindNext1Click 
FindTextinbranch1Click 
FormCloseQuery 
FormCreate 
FormDestroy 
FormShow 
Load1Click 
Merge1Click 
MoveBranch1Click 
OKClick 
PageControl1Changing 
RenameBranch1Click 
Save1Click 
SaveBranch1Click 
ShowAsString1Click 
StringGrid1KeyPress 
TabSheet1Resize 
TreeView1Click 
TreeView1Editing 
TreeView1KeyUp 
UpdateTreeview 
WPXMLTree1Loaded 


Copyright (C) by WPCUBED GmbH - Munich
http://www.wpcubed.com