Q:  How do I move an entire node (with siblings) in an outline?

A:
  This project demonstrates the syntax for getting an outline node's previous sibling, next sibling, a selected node's first and last child, and how to move  an entire node with all it's children vertically in the list.

  Note: Full syntax for the GetPrevChild, (not using "with Items[SelectedItem]",
  would be:

with outline1 do
  IntToStr(Items[SelectedItem].Parent.GetPrevChild(Items[SelectedItem].Index));
 
  This code refers to the previous sibling of the selected item by going through the selected items parent.
 

  Noel Rice
  Borland Technical Support
 
 

unit Oline;

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls, Grids, Outline;

type
  TForm1 = class(TForm)
    Outline1: TOutline;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Button1: TButton;
    Button2: TButton;
    Label7: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure Outline1Click(Sender: TObject);
   procedure MoveSelectedNodeUp(OutLine: TOutLine);
   procedure MoveSelectedNodeDown(OutLine: TOutLine);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

const
  InvalidIndex = -1;
 

procedure TForm1.MoveSelectedNodeUp(OutLine: TOutLine);
begin
  with Outline do
    with Items[SelectedItem] do
      if Parent.GetPrevchild(Index) <> InvalidIndex then
        MoveTo(Parent.GetPrevChild(Index), oaInsert);
end;

procedure TForm1.MoveSelectedNodeDown(OutLine: TOutLine);
var
  ToIndex: Longint;
begin
  with Outline do
    with Items[SelectedItem] do begin
      {   An Insert places a node BEFORE the node specified in the index.
        To insert a node past the next node down on that level, you have
        to go two nodes down, then insert. }
      ToIndex := Parent.GetNextChild(Parent.GetNextChild(Index));
      {   If the next node down is the last node on that level you can't
        insert, because there is no node on that level to insert it ahead
        of.  Rather, you must add the node to the end of that level. }
      if ToIndex = InvalidIndex then begin
      {   Get the index of the last node on the selected level. }
        ToIndex := Parent.GetNextChild(Index);
        {   Allow move only if not at the end of the level. }
          if ToIndex <> InvalidIndex then MoveTo(ToIndex, oaAdd);
      end
      else MoveTo(ToIndex, oaInsert);
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
    OutLine1.FullExpand;
  OutLine1Click(Self);
end;

procedure TForm1.Outline1Click(Sender: TObject);
begin
  with OutLine1 do begin
    Label1.Caption := 'SelectedItem ' + IntToStr(SelectedItem);
    with Items[SelectedItem] do begin
      Label2.Caption := 'GetPrevChild  ' + IntToStr(Parent.GetPrevChild(Index));
      Label3.Caption := 'GetNextChild  ' + IntToStr(Parent.GetNextChild(Index));
      Label4.Caption := 'GetFirstChild ' + IntToStr(GetFirstChild);
      Label5.Caption := 'GetLastChild  ' + IntToStr(GetLastChild);
      Label6.Caption := 'Level ' + IntToStr(Level);
      Label7.Caption := 'Next\NextChild + ' + IntToStr(Parent.GetNextChild(Parent.GetNextChild(Index)));
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MoveSelectedNodeUp(OutLine1);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  MoveSelectedNodeDown(OutLine1);
end;

end.