home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 September / Chip_2001-09_cd1.bin / zkuste / delphi / nastroje / d5 / MFTP.ZIP / src / FtpListView.pas < prev    next >
Pascal/Delphi Source File  |  2001-04-10  |  21KB  |  849 lines

  1. unit FtpListView;
  2.  
  3. interface
  4.  
  5. uses
  6.    Windows, ShellApi, Messages, SysUtils, Classes, Graphics, Forms, Controls,
  7.    ComCtrls, ImgList, Ftp, FtpData, FtpMisc;
  8.  
  9. {$I mftp.inc}
  10.  
  11. type TMFtpSortBase = (stNone, stAttrib, stDateTime, stDescription, stName, stSize,
  12.                       stSymbolLink, stOwner, stGroup, stFileType);
  13.  
  14. type
  15.    TMFtpListView = Class(TCustomListView)
  16.    private
  17.       FFtp:                      TMFtp;
  18.  
  19.       FAccept:                   Boolean;
  20.       FAscending:                Boolean;
  21.       FWebStyle:                 Boolean;
  22.       FSortBase:                 TMFtpSortBase;
  23.  
  24.       Directories, Files:        TMFtpFileInfoList;
  25.  
  26.       FFilter:                   TStrings;
  27.       FFileDropped:              TStrings;
  28.       FFList, FDList:            TStrings;
  29.  
  30.       {$ifdef VIRTUAL_LISTVIEW}
  31.       LookUp:                    TStrings;
  32.       {$ifdef DISPLAY_PARENT_DIRECTORY}
  33.       FRoot:                     Boolean;
  34.       {$endif}
  35.       {$endif}
  36.  
  37.       ShInfo:                    TSHFileInfo;
  38.       SysImageL, SysImageS:      TImageList;
  39.  
  40.       HOnFtpInfo:                Integer;
  41.       HOnListingDone:            Integer;
  42.       HOnIndexFileReceived:      Integer;
  43.  
  44.       FFileDroppedE:             TNotifyEvent;
  45.  
  46.       procedure SetAccept(A: Boolean);
  47.       procedure SetClient(NewFtp: TMFtp);
  48.       procedure SetFilter(NewFilter: TStrings);
  49.       procedure SetWebStyle(W: Boolean);
  50.  
  51.       {$ifdef VIRTUAL_LISTVIEW}
  52.       {$ifdef DISPLAY_PARENT_DIRECTORY}
  53.       procedure NewOnData2(Sender: TObject; Item: TListItem; RealIndex: Integer);
  54.       {$endif}
  55.       procedure NewOnData(Sender: TObject; Item: TListItem);
  56.       procedure NewOnDataFind(Sender: TObject; Find: TItemFind;
  57.                 const FindString: string; const FindPosition: TPoint;
  58.                 FindData: Pointer; StartIndex: Integer;
  59.                 Direction: TSearchDirection; Wrap: Boolean; var Index: Integer);
  60.       {$endif}
  61.       {$ifdef DELPHI5}
  62.       procedure NewOnColumnClick(Sender: TObject; Column: TListColumn);
  63.       {$endif}
  64.  
  65.       procedure NewOnFtpInfo(Sender: TObject; info: FtpInfo; addinfo: String);
  66.       procedure NewOnIndexFileReceived(Sender: TObject);
  67.       procedure NewOnListingDone(Sender: TObject);
  68.  
  69.       function GetSelD: TStrings;
  70.       function GetSelF: TStrings;
  71.    protected
  72.       procedure CreateWnd; override;
  73.       procedure WMDropFiles(var msg : TMessage); message WM_DROPFILES;
  74.    public
  75.       imgCloseIndex:              Integer;
  76.  
  77.       constructor Create(AOwner: TComponent); override;
  78.       destructor Destroy; override;
  79.  
  80.       property FileDropped: TStrings read FFileDropped;
  81.  
  82.       property SelectedDirectories: TStrings read GetSelD;
  83.       property SelectedFiles: TStrings read GetSelF;
  84.  
  85.       property Columns;
  86.       property Items;
  87.  
  88.       procedure SelectAll(Flag: Boolean = True);
  89.       procedure InvertSelection;
  90.       procedure Refresh;
  91.  
  92.       function IsDirectory(LI: TListItem): Boolean;
  93.  
  94.       {$ifdef VIRTUAL_LISTVIEW}
  95.       property OnData;
  96.       property OnDataFind;
  97.       property OnDataHint;
  98.       property OnDataStateChange;
  99.       {$endif}
  100.    published
  101.       property Accept: Boolean read FAccept write SetAccept;
  102.       property Ascending: Boolean read FAscending write FAscending default true;
  103.       property Filter: TStrings read FFilter write SetFilter;
  104.       property Client: TMFtp read FFtp write SetClient;
  105.       property SortType: TMFtpSortBase read FSortBase write FSortBase;
  106.       property WebStyle: Boolean read FWebStyle write SetWebStyle;
  107.  
  108.       property Align;
  109.       property BorderStyle;
  110.       property Color;
  111.       property ColumnClick;
  112.       property HideSelection;
  113.       property IconOptions;
  114.       property MultiSelect;
  115.       property ParentColor default False;
  116.       property ParentFont;
  117.       property ParentShowHint;
  118.       property PopupMenu;
  119.       property ReadOnly;
  120.       property RowSelect;
  121.       property ShowHint;
  122.       property ShowColumnHeaders;
  123.       property TabOrder;
  124.       property TabStop default True;
  125.       property ViewStyle;
  126.  
  127.       property Anchors;
  128.       property BiDiMode;
  129.       property BorderWidth;
  130.       property Constraints;
  131.       property DragCursor;      
  132.       property DragKind;
  133.       property DragMode;
  134.       property FlatScrollBars;
  135.       property FullDrag;
  136.       property GridLines;
  137.       property OwnerDraw;
  138.       property ParentBiDiMode;
  139.  
  140.       {$ifdef DELPHI5}
  141.       property ShowWorkAreas;
  142.       {$endif}
  143.  
  144.       {$ifndef VIRTUAL_LISTVIEW}
  145.       property OwnerData;
  146.       {$endif}
  147.  
  148.       {$ifdef EXPORT_IMAGES}
  149.       property LargeImages;
  150.       property SmallImages;
  151.       property StateImages;
  152.       {$endif}
  153.  
  154.       property OnFileDropped: TNotifyEvent read FFileDroppedE write FFileDroppedE;
  155.  
  156.       property OnChange;
  157.       property OnChanging;
  158.       property OnClick;
  159.       property OnColumnClick;
  160.       property OnCompare;
  161.       property OnDblClick;
  162.       property OnDeletion;
  163.       property OnDragDrop;
  164.       property OnDragOver;
  165.       property OnEdited;
  166.       property OnEditing;
  167.       property OnEndDrag;
  168.       property OnEnter;
  169.       property OnExit;
  170.       property OnInsert;
  171.       property OnKeyDown;
  172.       property OnKeyPress;
  173.       property OnKeyUp;
  174.       property OnMouseDown;
  175.       property OnMouseMove;
  176.       property OnMouseUp;
  177.       property OnStartDrag;
  178.  
  179.       property OnCustomDraw;
  180.       property OnCustomDrawItem;
  181.       property OnCustomDrawSubItem;
  182.       property OnDrawItem;
  183.       property OnEndDock;
  184.       property OnGetImageIndex;
  185.       property OnResize;
  186.       property OnSelectItem;
  187.       property OnStartDock;
  188.  
  189.       {$ifdef DELPHI5}
  190.       property OnAdvancedCustomDraw;
  191.       property OnAdvancedCustomDrawItem;
  192.       property OnAdvancedCustomDrawSubItem;
  193.       property OnColumnRightClick;
  194.       property OnContextPopup;
  195.       property OnGetSubItemImage;
  196.       property OnInfoTip;
  197.       {$endif}
  198.  
  199.       {$ifndef VIRTUAL_LISTVIEW}
  200.       property OnData;
  201.       property OnDataFind;
  202.       property OnDataHint;
  203.       property OnDataStateChange;
  204.       {$endif}
  205.    end;
  206.  
  207. implementation
  208.  
  209. constructor TMFtpListView.Create;
  210. begin
  211.    inherited Create(AOwner);
  212.  
  213.    FFilter := TStringList.Create;
  214.    FFileDropped := TStringList.Create;
  215.  
  216.    Directories := TMFtpFileInfoList.Create;
  217.    Files := TMFtpFileInfoList.Create;
  218.  
  219.    SHGetFileInfo(PChar(GetWindowsDirectory), 0, ShInfo, SizeOf(ShInfo),
  220.                  SHGFI_SYSICONINDEX or SHGFI_LARGEICON);
  221.    imgCloseIndex := ShInfo.iIcon;
  222.  
  223.    SysImageL := TImageList.Create(Self);
  224.    with SysImageL do
  225.    begin
  226.       ShareImages := True;
  227.       Handle := SHGetFileInfo('', 0, ShInfo, SizeOf(ShInfo),
  228.                 SHGFI_SYSICONINDEX or SHGFI_LARGEICON);
  229.    end;
  230.  
  231.    SysImageS := TImageList.Create(Self);
  232.    with SysImageS do
  233.    begin
  234.       ShareImages := True;
  235.       Handle := SHGetFileInfo('', 0, ShInfo, SizeOf(TSHFileInfo),
  236.                 SHGFI_SYSICONINDEX or SHGFI_SMALLICON);
  237.    end;
  238.  
  239.    LargeImages := SysImageL;
  240.    SmallImages := SysImageS;
  241.  
  242.    FAscending := True;
  243.    FSortBase := stName;
  244.  
  245.    FFList := TStringList.Create;
  246.    FDList := TStringList.Create;
  247.  
  248.    {$ifdef VIRTUAL_LISTVIEW}
  249.    LookUp := TStringList.Create;
  250.  
  251.    OnData := NewOnData;
  252.    OnDataFind := NewOnDataFind;
  253.    OwnerData := True;
  254.    {$endif}
  255.  
  256.    {$ifdef DELPHI5}
  257.    if not Assigned(OnColumnClick) then
  258.       if not (csDesigning in ComponentState) then
  259.          OnColumnClick := NewOnColumnClick;
  260.    {$endif}
  261. end;
  262.  
  263. procedure TMFtpListView.CreateWnd;
  264. begin
  265.    inherited CreateWnd;
  266.  
  267.    with Columns.Add do
  268.    begin
  269.       Caption := 'Name';
  270.       {$ifdef DELPHI5}
  271.       Tag := Ord(stName);
  272.       {$endif}
  273.       Width := 128;
  274.    end;
  275.  
  276.    with Columns.Add do
  277.    begin
  278.       Alignment := taRightJustify;
  279.       Caption := 'Size';
  280.       {$ifdef DELPHI5}
  281.       Tag := Ord(stSize);
  282.       {$endif}
  283.       Width := 84;
  284.    end;
  285.  
  286.    with Columns.Add do
  287.    begin
  288.       Caption := 'Type';
  289.       {$ifdef DELPHI5}
  290.       Tag := Ord(stFileType);
  291.       {$endif}
  292.       Width := 108;
  293.    end;
  294.  
  295.    with Columns.Add do
  296.    begin
  297.       Caption := 'Modified';
  298.       {$ifdef DELPHI5}
  299.       Tag := Ord(stDateTime);
  300.       {$endif}
  301.       Width := 108;
  302.    end;
  303.  
  304.    with Columns.Add do
  305.    begin
  306.       Caption := 'Attributes';
  307.       {$ifdef DELPHI5}
  308.       Tag := Ord(stAttrib);
  309.       {$endif}
  310.       Width := 80;
  311.    end;
  312.  
  313.    with Columns.Add do
  314.    begin
  315.       Caption := 'Owner';
  316.       {$ifdef DELPHI5}
  317.       Tag := Ord(stOwner);
  318.       {$endif}
  319.       Width := 80;
  320.    end;
  321.  
  322.    with Columns.Add do
  323.    begin
  324.       Caption := 'Group';
  325.       {$ifdef DELPHI5}
  326.       Tag := Ord(stGroup);
  327.       {$endif}
  328.       Width := 80;
  329.    end;
  330.  
  331.    with Columns.Add do
  332.    begin
  333.       Caption := 'Description';
  334.       {$ifdef DELPHI5}
  335.       Tag := Ord(stDescription);
  336.       {$endif}
  337.       Width := 128;
  338.    end;
  339.  
  340.    SetAccept(FAccept);
  341.    SetWebStyle(FWebStyle);
  342.  
  343.    IconOptions.AutoArrange := True;
  344. end;
  345.  
  346. destructor TMFtpListView.Destroy;
  347. begin
  348.    FreeAndNil(FFilter);
  349.    FreeAndNil(FFileDropped);
  350.  
  351.    Files.MyFree;
  352.    Directories.MyFree;
  353.  
  354.    {$ifdef VIRTUAL_LISTVIEW}
  355.    FreeAndNil(LookUp);
  356.    {$endif}
  357.  
  358.    FreeAndNil(FDList);
  359.    FreeAndNil(FFList);
  360.  
  361.    inherited Destroy;
  362. end;
  363.  
  364. procedure TMFtpListView.WMDropFiles;
  365. var DHandle: HDrop;
  366.     i, nb: Integer;
  367.     fn : array[0..254] of char;
  368. begin
  369.    FFileDropped.Clear;
  370.  
  371.    DHandle := Msg.WParam;
  372.    nb:=DragQueryFile(DHandle, $FFFFFFFF, fn, sizeof(fn));
  373.    for i := 0 to nb - 1 do
  374.    begin
  375.       DragQueryFile(DHandle, i, fn, sizeof(fn));
  376.       FFileDropped.Add(fn);
  377.    end;
  378.    DragFinish(DHandle);
  379.  
  380.    if Assigned(FFileDroppedE) then FFileDroppedE(Self);
  381. end;
  382.  
  383. procedure TMFtpListView.SetAccept;
  384. begin
  385.    FAccept := A;
  386.  
  387.    DragAcceptFiles(Self.Handle, A);
  388. end;
  389.  
  390. procedure TMFtpListView.SetClient;
  391. begin
  392.    if FFtp = NewFtp then Exit;
  393.  
  394.    if Assigned(FFtp) then
  395.    begin
  396.       with FFtp do
  397.       begin
  398.          UnRegisterInfoEvent(HOnFtpInfo);
  399.          UnRegisterNotifyEvent(10, HOnListingDone);
  400.          UnRegisterNotifyEvent(14, HOnIndexFileReceived);
  401.       end;
  402.    end;
  403.  
  404.    FFtp := NewFtp;
  405.  
  406.    if not Assigned(FFtp) then
  407.    begin
  408.       Items.Clear;
  409.       Exit;
  410.    end;
  411.  
  412.    with FFtp do
  413.    begin
  414.       HOnFtpInfo := RegisterInfoEvent(NewOnFtpInfo);
  415.       HOnListingDone := RegisterNotifyEvent(10, NewOnListingDone);
  416.       HOnIndexFileReceived := RegisterNotifyEvent(14, NewOnIndexFileReceived);
  417.    end;
  418.  
  419.    {refresh}
  420.    if FFtp.Directories.Count + FFtp.Files.Count > 0 then NewOnListingDone(Self);
  421. end;
  422.  
  423. procedure TMFtpListView.SetFilter;
  424. begin
  425.    FFilter.Assign(NewFilter);
  426. end;
  427.  
  428. procedure TMFtpListView.SetWebStyle;
  429. begin
  430.    FWebStyle := W;
  431.  
  432.    if W then
  433.    begin
  434.       HotTrack := True;
  435.       HotTrackStyles := [htHandPoint];
  436.    end
  437.    else
  438.    begin
  439.       HotTrack := False;
  440.       HotTrackStyles := [];
  441.    end;
  442. end;
  443.  
  444. {$ifdef DELPHI5}
  445. procedure TMFtpListView.NewOnColumnClick;
  446. begin
  447.    if SortType = TMFtpSortBase(Column.Tag) then
  448.       FAscending := not FAscending
  449.    else
  450.       SortType := TMFtpSortBase(Column.Tag);
  451.    Refresh;
  452. end;
  453. {$endif}
  454.  
  455. {$ifdef VIRTUAL_LISTVIEW}
  456. {$ifndef DISPLAY_PARENT_DIRECTORY}
  457. procedure TMFtpListView.NewOnData;
  458. {$else}
  459. procedure TMFtpListView.NewOnData2;
  460. {$endif}
  461. var i: Integer;
  462.     F: Boolean;
  463. begin
  464.    with Item do
  465.    begin
  466.       {$ifdef DISPLAY_PARENT_DIRECTORY}
  467.       if RealIndex >= Directories.Count then
  468.       begin
  469.          i := RealIndex - Directories.Count;
  470.          F := True;
  471.       end
  472.       else
  473.       begin
  474.          i := RealIndex;
  475.          F := False;
  476.       end;
  477.       {$else}
  478.       if Index >= Directories.Count then
  479.       begin
  480.          i := Index - Directories.Count;
  481.          F := True;
  482.       end
  483.       else
  484.       begin
  485.          i := Index;
  486.          F := False;
  487.       end;
  488.       {$endif}
  489.  
  490.       if F then
  491.       begin         
  492.          if i >= Files.Count then Exit;
  493.  
  494.          Caption := Files[i].Filename;
  495.          SHGetFileInfo(PChar(Caption), 0, ShInfo, SizeOf(TSHFileInfo),
  496.                        SHGFI_TYPENAME or SHGFI_SYSICONINDEX or SHGFI_USEFILEATTRIBUTES);
  497.          ImageIndex := ShInfo.iIcon;
  498.          if ViewStyle <> vsReport then Exit;
  499.  
  500.          {$ifdef DISPLAY_REAL_SIZE}
  501.          if Files[i].Size = '0' then
  502.             SubItems.Add('0')
  503.          else
  504.             SubItems.Add(FormatFloat('#,##', StrToIntDef(Files[i].Size, 0)));
  505.          {$else}
  506.          if Files[i].Size = '0' then
  507.             SubItems.Add('0KB')
  508.          else
  509.             SubItems.Add(FormatFloat('#,##KB', StrToIntDef(Files[i].Size, 0) / 1024));
  510.          if SubItems[SubItems.Count - 1] = 'KB' then SubItems[SubItems.Count - 1] := '1KB';
  511.          {$endif}
  512.  
  513.          SubItems.Add(ShInfo.szTypeName);
  514.          SubItems.Add(Files[i].DateTime);
  515.          SubItems.Add(Files[i].Attrib);
  516.          SubItems.Add(Files[i].Owner);
  517.          SubItems.Add(Files[i].Group);
  518.          SubItems.Add(Files[i].Description);
  519.       end
  520.       else
  521.       begin
  522.          if i >= Directories.Count then Exit;
  523.  
  524.          Caption := Directories[i].Filename;
  525.          ImageIndex := imgCloseIndex;
  526.          if ViewStyle <> vsReport then Exit;
  527.  
  528.          SubItems.Add(''); // It's a waste of CPU time to display a directory's
  529.                            // size, right?
  530.          SubItems.Add('File Folder');
  531.          SubItems.Add(Directories[i].DateTime);
  532.          SubItems.Add(Directories[i].Attrib);
  533.          SubItems.Add(Directories[i].Owner);
  534.          SubItems.Add(Directories[i].Group);
  535.          SubItems.Add(Directories[i].Description);
  536.       end;
  537.    end;
  538. end;
  539.  
  540. {$ifdef DISPLAY_PARENT_DIRECTORY}
  541. procedure TMFtpListView.NewOnData;
  542. begin
  543.    if (FRoot) and (Item.Index = 0) then
  544.    begin
  545.       with Item do
  546.       begin
  547.          Caption := 'Parent Directory';
  548.          ImageIndex := imgCloseIndex;
  549.       end;
  550.       Exit;
  551.    end;
  552.  
  553.    if FRoot then
  554.       NewOnData2(Sender, Item, Item.Index - 1)
  555.    else
  556.       NewOnData2(Sender, Item, Item.Index);
  557. end;
  558. {$endif}
  559.  
  560. procedure TMFtpListView.NewOnDataFind;
  561. var I: Integer;
  562.     Found: Boolean;
  563. begin
  564.    I := StartIndex;
  565.    if (Find = ifExactString) or (Find = ifPartialString) then
  566.    begin
  567.       repeat
  568.          if (I = LookUp.Count - 1) then
  569.             if Wrap then I := 0 else Exit;
  570.          if (I >= LookUp.Count) or (I < 0) then Exit;
  571.          Found := (Pos(UpperCase(FindString), LookUp[i]) = 1);
  572.          Inc(I);
  573.       until Found or (I = StartIndex);
  574.       if Found then Index := I - 1;
  575.    end;
  576. end;
  577. {$endif}
  578.  
  579. procedure TMFtpListView.NewOnFtpInfo;
  580. begin
  581.    if info = ftpStartListing then
  582.    begin
  583. //      Items.BeginUpdate;
  584.    end;
  585. end;
  586.  
  587. procedure TMFtpListView.NewOnIndexFileReceived;
  588. {$ifndef VIRTUAL_LISTVIEW}
  589. var i, n: Integer;
  590. {$endif}
  591. begin
  592.    if OwnerData or OwnerDraw then
  593.    begin
  594.       Repaint;
  595.       Exit;
  596.    end;
  597.  
  598.    {$ifndef VIRTUAL_LISTVIEW}
  599.    if FFtp.CurrentDirectory = '/' then
  600.       n := 0
  601.    else
  602.       n := -1;
  603.  
  604.    for i := 0 to Directories.Count - 1 do
  605.    begin
  606.       Inc(n);
  607.       if n = Items.Count then Break;
  608.       Items[n].SubItems[4] := Directories[i].Description;
  609.    end;
  610.  
  611.    for i := 0 to Files.Count - 1 do
  612.    begin
  613.       Inc(n);
  614.       if n >= Items.Count then Break;
  615.       Items[n].SubItems[4] := Files[i].Description;
  616.    end;
  617.    {$endif}
  618. end;
  619.  
  620. procedure TMFtpListView.NewOnListingDone;
  621. var i, j, b: Integer;
  622. begin
  623.    Selected := nil;
  624.    Directories.Assign(FFtp.Directories);
  625.    Files.Clear;
  626.    if FFilter.Count > 0 then
  627.    begin
  628.       for i := 0 to FFilter.Count - 1 do
  629.       begin
  630.          Application.ProcessMessages;
  631.          for j := 0 to FFtp.Files.Count - 1 do
  632.          begin
  633.             if Files.IndexOf(FFtp.Files[j].Filename) < 0 then
  634.             begin
  635.                if fnmatch(PChar(FFilter[i]), PChar(FFtp.Files[j].Filename)) then
  636.                begin
  637.                   Files.Add(FFtp.Files[j]);
  638.                end;
  639.             end;
  640.          end;
  641.       end
  642.    end
  643.    else
  644.    begin
  645.       Files.Assign(FFtp.Files);
  646.    end;
  647.  
  648.    Items.EndUpdate;
  649.  
  650.    if OwnerDraw then
  651.    begin
  652.       Repaint;
  653.       Exit;
  654.    end;
  655.  
  656.    {$ifndef VIRTUAL_LISTVIEW}
  657.    if OwnerData then
  658.    begin
  659.       Repaint;
  660.       Exit;
  661.    end;
  662.    {$endif}
  663.  
  664.    Screen.Cursor := crAppStart;
  665.    Items.BeginUpdate;
  666.  
  667.    {Sorting}
  668.    b := -2;   {to make compiler happy :-)}
  669.    if FSortBase <> stNone then
  670.    begin
  671.       case FSortBase of
  672.          stAttrib:        b := ItemAttrib;
  673.          stDateTime:      b := ItemDateTime;
  674.          stDescription:   b := ItemDescription;
  675.          stName:          b := ItemFilename;
  676.          stSize:          b := ItemSize;
  677.          stSymbolLink:    b := ItemSymbolLink;
  678.          stFileType:      b := ItemFileType;
  679.          stOwner:         b := ItemOwner;
  680.          stGroup:         b := ItemGroup;
  681.       end;
  682.  
  683.       Directories.Sort(b, FAscending);
  684.       Files.Sort(b, FAscending);
  685.    end;
  686.  
  687.    {$ifdef VIRTUAL_LISTVIEW}
  688.    LookUp.Clear;
  689.  
  690.    Items.Count := Directories.Count + Files.Count;
  691.  
  692.    for i := 0 to Directories.Count - 1 do
  693.       LookUp.Add(UpperCase(Directories[i].Filename));
  694.  
  695.    for i := 0 to Files.Count - 1 do
  696.       LookUp.Add(UpperCase(Files[i].Filename));
  697.  
  698.    {$ifdef DISPLAY_PARENT_DIRECTORY}
  699.    if FFtp.CurrentDirectory <> '/' then
  700.    begin
  701.       FRoot := True;
  702.       Items.Count := Items.Count + 1;
  703.       end
  704.    else
  705.       FRoot := False;
  706.    {$endif}
  707.  
  708.    Repaint;
  709.    {$else}
  710.    with Items do
  711.    begin
  712.       Clear;
  713.  
  714.       {skiping '/'}
  715.       if FFtp.CurrentDirectory <> '/' then
  716.       begin
  717.          with Add do {Add parent directory}
  718.          begin
  719.             Caption := 'Parent Directory';
  720.             ImageIndex := imgCloseIndex;
  721.             {$ifdef OVERLAY_MASK}
  722.             OverlayIndex := 0;
  723.             {$endif}
  724.          end;
  725.       end;
  726.  
  727.       {adding directories}
  728.       for i := 0 to Directories.Count - 1 do
  729.       begin
  730.          with Add do
  731.          begin
  732.              Caption := Directories[i].Filename;
  733.              ImageIndex := imgCloseIndex;
  734.              {$ifdef OVERLAY_MASK}
  735.              if Directories[i].SymbolLink <> '' then OverlayIndex := 1;
  736.              {$endif}
  737.              SubItems.Add('');
  738.              SubItems.Add('File Folder');
  739.              SubItems.Add(Directories[i].DateTime);
  740.              SubItems.Add(Directories[i].Attrib);
  741.              SubItems.Add(Directories[i].Description);
  742.          end;
  743.       end;
  744.  
  745.       {adding files}
  746.       for i := 0 to Files.Count - 1 do
  747.       begin
  748.          with Add do
  749.          begin
  750.             Caption := Files[i].Filename;
  751.             SHGetFileInfo(PChar(Caption), 0, ShInfo, SizeOf(TSHFileInfo),
  752.                           SHGFI_TYPENAME or SHGFI_SYSICONINDEX or SHGFI_USEFILEATTRIBUTES);
  753.             ImageIndex := ShInfo.iIcon;
  754.             {$ifdef OVERLAY_MASK}
  755.             if Files[i].SymbolLink <> '' then OverlayIndex := 1;
  756.             {$endif}
  757.             {$ifdef DISPLAY_REAL_SIZE}
  758.             if Files[i].Size = '0' then
  759.                SubItems.Add('0')
  760.             else
  761.                SubItems.Add(FormatFloat('#,##', StrToIntDef(Files[i].Size, 0)));
  762.             {$else}
  763.             if Files[i].Size = '0' then
  764.                SubItems.Add('0KB')
  765.             else
  766.                SubItems.Add(FormatFloat('#,##KB', StrToIntDef(Files[i].Size, 0) / 1024));
  767.             if SubItems[SubItems.Count - 1] = 'KB' then SubItems[SubItems.Count - 1] := '1KB';
  768.             {$endif}
  769.             SubItems.Add(ShInfo.szTypeName);
  770.             SubItems.Add(Files[i].DateTime);
  771.             SubItems.Add(Files[i].Attrib);
  772.             SubItems.Add(Files[i].Description);
  773.          end;
  774.       end;
  775.    end;
  776.    {$endif}
  777.  
  778.    Screen.Cursor := crDefault;
  779.    Items.EndUpdate;
  780. end;
  781.  
  782. function TMFtpListView.GetSelD;
  783. var LI: TListItem;
  784. begin
  785.    if Assigned(FDList) then
  786.       FDList.Clear
  787.    else
  788.       FDList := TStringList.Create;
  789.  
  790.    LI := Selected;
  791.    while LI <> nil do
  792.    begin
  793.       with LI do if ImageIndex = imgCloseIndex then FDList.Add(Caption);
  794.       LI := GetNextItem(LI, sdAll, [isSelected]);
  795.    end;
  796.  
  797.    Result := FDList;
  798. end;
  799.  
  800. function TMFtpListView.GetSelF;
  801. var LI: TListItem;
  802. begin
  803.    if Assigned(FFList) then
  804.       FFList.Clear
  805.    else
  806.       FFList := TStringList.Create;
  807.  
  808.    LI := Selected;
  809.    while LI <> nil do
  810.    begin
  811.       with LI do if ImageIndex <> imgCloseIndex then FFList.Add(Caption);
  812.       LI := GetNextItem(LI, sdAll, [isSelected]);
  813.    end;
  814.  
  815.    Result := FFList;
  816. end;
  817.  
  818. procedure TMFtpListView.SelectAll;
  819. var C, I: Integer;
  820. begin
  821.    C := Items.Count - 1;
  822.    for I := 0 to C do
  823.       Items[I].Selected := Flag;
  824. end;
  825.  
  826. procedure TMFtpListView.InvertSelection;
  827. var C, I: Integer;
  828. begin
  829.    C := Items.Count - 1;
  830.    for I := 0 to C do
  831.       Items[I].Selected := not Items[I].Selected;
  832. end;
  833.  
  834. procedure TMFtpListView.Refresh;
  835. begin
  836.    if Assigned(FFtp) then
  837.       NewOnListingDone(Self);
  838. end;
  839.  
  840. function TMFtpListView.IsDirectory;
  841. begin
  842.    if Assigned(LI) then
  843.       Result := (LI.ImageIndex = imgCloseIndex)
  844.    else
  845.       Result := False;
  846. end;
  847.  
  848. end.
  849.