unit UnitListViewMover;

interface
uses ComCtrls, Classes, Contnrs;

procedure MoveSelectedUp(lv : TListView);
procedure MoveSelectedDown(lv : TListView);
procedure MoveSelectedTop(lv : TListView);
procedure MoveSelectedBottom(lv : TListView);

implementation

procedure MoveSelectedUp(lv : TListView);
var i : integer;
    li, liNew : TListItem;
    lst1: TList;
begin
    lv.Items.BeginUpdate;
    if (lv.SelCount > 0) then begin
        lst1 := TList.Create();

        lv.SortType := stNone;
        for i := 0 to (lv.Items.Count - 1) do begin
            if (lv.Items.Item[i].Selected) and
                (lv.Items.Item[i].Index <> 0)then begin
                lst1.Add(lv.Items.Item[i]);
            end;
        end;

        for i := 0 to (lst1.Count - 1) do begin
            li := TListItem( lst1.Items[i] );

            liNew := lv.Items.Insert(li.Index - 1);
            liNew.Caption := li.Caption;
            liNew.SubItems.AddStrings( li.SubItems );
            liNew.Checked := li.Checked;
            liNew.Selected := false;
            liNew.ImageIndex := li.ImageIndex;
            li.Delete;

            liNew.Selected := true;
        end;


        lst1.Free;
    end;
   lv.Items.EndUpdate;
end;

procedure MoveSelectedDown(lv : TListView);
var i : integer;
    li, liNew : TListItem;
    lst1 : TList;
begin
    lv.Items.BeginUpdate;
    if (lv.SelCount > 0) then begin
        lst1 := TList.Create();
        lv.SortType := stNone;

        //
        // get a list of all selected items (that are not the last item)
        //
        for i := (lv.Items.Count - 1) downto 0 do begin
            li := lv.Items.Item[i];
            if (li.Selected) and (li.Index <> lv.Items.count - 1) then begin
                lst1.Add(li);
            end;
        end;

        //
        // insert a copy in the new position, and remove the old item
        //
        for i := 0 to (lst1.Count - 1) do begin
            li := TListItem( lst1.Items[i] );

            if (li.Index <> (lv.items.Count - 1) ) then begin
                liNew := lv.Items.Insert(li.Index + 2);
                liNew.Caption := li.Caption;
                liNew.SubItems.AddStrings( li.SubItems );
                liNew.Checked := li.Checked;
                liNew.Selected := true;
                liNew.ImageIndex := li.ImageIndex;
                li.Delete;
            end;
        end;

        lst1.Free;
    end;
    lv.Items.EndUpdate;
end;

procedure MoveSelectedTop(lv : TListView);
var i : integer;
    li, liNew : TListItem;
    ol : TObjectList;
begin
    lv.Items.BeginUpdate;

    if (lv.SelCount >= 1) then begin
        ol := TObjectList.Create();

        //
        // find all selected items (manipulating the list while
        // enumerating is BAD)
        //
        for i := 0 to (lv.items.count - 1) do begin
            if (lv.Items.Item[i].selected) then begin
                ol.Add(lv.Items.Item[i]);
            end;
        end;

        //
        // Move them all to the top
        //
        lv.SortType := stNone;
        for i := (ol.Count - 1) downto 0 do begin
            li := TListItem(ol.Items[i]);
            liNew := lv.Items.Insert(0);
            liNew.Caption := li.Caption;
            liNew.SubItems.AddStrings( li.SubItems );
            liNew.Checked := li.Checked;
            liNew.Selected := true;
            liNew.ImageIndex := li.ImageIndex;

            ol.Delete(i);
        end;

        ol.Free;
    end;
    lv.Items.EndUpdate;
end;
procedure MoveSelectedBottom(lv : TListView);
var i : integer;
    li, liNew : TListItem;
    ol : TObjectList;
begin
    lv.Items.BeginUpdate;
    if (lv.SelCount >= 1) then begin
        ol := TObjectList.Create();

        //
        // find all selected items (manipulating the list while
        // enumerating is BAD)
        //
        for i := 0 to (lv.items.count - 1) do begin
            if (lv.Items.Item[i].selected) then begin
                ol.Add(lv.Items.Item[i]);
            end;
        end;

        //
        // Move them all to the top
        // delete the old items
        //
        lv.SortType := stNone;
        for i := 0 to (ol.Count - 1) do begin
            li := TListItem(ol.Items[i]);
            liNew := lv.Items.Insert(lv.Items.Count);
            liNew.Caption := li.Caption;
            liNew.SubItems.AddStrings( li.SubItems );
            liNew.Checked := li.Checked;
            liNew.Selected := true;
            liNew.ImageIndex := li.ImageIndex;

            //ol.Delete(i);
        end;

        ol.Free;
    end;
    lv.Items.EndUpdate;
end;


end.
