1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
procedure DeleteTreeNode(SourceNode: TTreeNode);
begin
if Assigned(SourceNode.data) Then
FreeMemory(SourceNode.data);
SourceNode.Delete;
end;
procedure MoveTreeNode(tv: TTreeView; SourceNode, DestNode: TTreeNode);
procedure MoveTreeNode_internal(DontMoveSiblings, SourceNode, DestNode: TTreeNode);
var
NewNode: TTreeNode;
begin
if (DestNode = nil) then
Exit;
if (SourceNode = nil) then
Exit;
{Create new child}
NewNode := tv.Items.AddChild(DestNode, SourceNode.Text);
{Use same images}
NewNode.ImageIndex := SourceNode.ImageIndex;
NewNode.SelectedIndex := SourceNode.SelectedIndex;
NewNode.Data := SourceNode.Data;
{If this node has children move them first}
if (SourceNode.HasChildren) then
MoveTreeNode_internal(DontMoveSiblings, SourceNode.GetFirstChild,
NewNode);
{Move all siblings, unless at original level}
if (DontMoveSiblings <> SourceNode) then
MoveTreeNode_internal(DontMoveSiblings, SourceNode.GetNextSibling,
DestNode);
end;
begin
{Copy node + children}
MoveTreeNode_internal(SourceNode, SourceNode, DestNode);
{Delete original}
DeleteTreeNode(SourceNode);
end;
procedure TForm.TreeVIewImgDragDrop(Sender, Source:TObject; X, Y: Integer);
var
TargetNode : TTreeNode;
SourceNode : TTreeNode;
st : String;
begin
with ( Sender as TTreeView ) do // on regade l'appelant
begin
TargetNode := GetNodeAt( X, Y );
SourceNode := Selected;
if( TargetNode = nil ) then
begin
EndDrag( false );
Exit;
end;
if ((TargetNode = Selected) or
(TargetNode = Selected.Parent) ) then // si la destination
//est la meme que la source
begin
EndDrag( false );
Exit;
end;
{No drag-drop of the root allowed}
if( SourceNode.Level = 0 ) then
begin
MessageBeep( MB_ICONEXCLAMATION );
ShowMessage( 'Cant drag/drop the root' );
EndDrag( false );
Exit;
end;
{Can't drop a parent onto a child}
if( IsAParentNode( Selected, TargetNode ) ) then
begin
MessageBeep( MB_ICONEXCLAMATION );
ShowMessage( 'Cant drop parent onto child' );
EndDrag( false );
Exit;
end;
{Does a node with this name exists as a child of TargetNde}
if( IsDuplicateName( TargetNode.GetFirstChild, SourceNode.Text, true ) ) then
begin
MessageBeep( MB_ICONEXCLAMATION );
ShowMessage( 'A node with this name already exists' );
EndDrag( false );
Exit;
end;
//////////////////////////////////////////////////////////////
// Nothing differant up to here. Just the normal drag and
// drop checking. Now the code to make sure that enforce
// "the rules". Eg books may contain no sub-nodes
//////////////////////////////////////////////////////////////
{Use the IsNodeAllowed function to test if the node may be dropped here}
if (not IsNodeAllowed(TargetNode, GetNodeType(SourceNode))) then
begin
MessageBeep($ffffff );
ShowMessage( 'You cant drop this type of node here!' );
EndDrag( false );
Exit;
end;
if GetNodeType(TargetNode) <> OwnNodeType Then
begin
MessageBeep($ffffff );
ShowMessage( 'You cant drop this type of node here!' );
EndDrag( false );
Exit;
end;
{Drag drop was valid so move the nodes}
MoveTreeNode(( Sender as TTreeView ), SourceNode, TargetNode );
enregistrenouvellePos;
{Delete the old node}
SourceNode.Delete;
{Show the nodes that were just moved}
TargetNode.Expand( true );
end;
end;
procedure TForm.TreeVIewImgDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
var
nd : TTreeNode;
begin
Accept := false;
{Only accept drag and drop from a TTreeView}
if( Sender is TTreeView ) then
{Only accept from self}
if( TTreeView(Sender) = TrVImg ) then
begin
Nd := (Sender as TTreeView).Selected;
if assigned(nd.Data) Then
begin
if TObjdata(nd.Data).NodeType = owntypeimg Then
Accept := true;
end;
end;
end;
procedure TForm.TreeVIewImgMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
inherited;
(Sender as TTreeView).BeginDrag(False);
end;
// pour gerer des hint diferent a chaque ligne du treeview
procedure TForm.TreeVIewImgMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
var
tree: TTreeView;
hoverNode : TTreeNode;
hitTest : THitTests;
begin
if (Sender is TTreeView) then
tree := TTreeView(Sender)
else
Exit;
hoverNode := tree.GetNodeAt(X, Y) ;
hitTest := tree.GetHitTestInfoAt(X, Y) ;
if (lastHintNode <> hoverNode) then
begin
Application.CancelHint;
if (hitTest <= [htOnItem, htOnIcon, htOnLabel, htOnStateIcon]) then
begin
lastHintNode := hoverNode;
tree.Hint := NodeHint(hoverNode) ;
end;
end;
end;
function TForm.NodeHint(tn: TTreeNode): string;
begin
result := '';
if assigned(tn.Data) Then
result := TObjdata(tn.Data).Comment;
end; |
Partager