Logo Search packages:      
Sourcecode: bareftp version File versions  Download package

FileListRemote.cs

// FileTreeRemote.cs
//
//  Copyright (C) 2008-2009 Christian Eide
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//

using System;
using System.Collections.Generic;
using System.Threading;
using Gtk;
using bareFTP.Protocol;
using bareFTP.Connection;
using bareFTP.Common.Utils;
using Mono.Unix;

namespace bareFTP.Gui.FileManager
{
      public delegate void ExternalUploadRequestHandler(List<string> localFiles, FileTreeNode rnode);
      
      public class FileManagerRemote : Gtk.VBox
      {
            FileList filelist;
            Gtk.Entry pathEntry;
            bool isConnected;
            Connection.Connection conn;
            
            private FileListCache cache;
            private bareFTP.Protocol.BarePath cwd;
            private List<RemoteFile> currentDirFileList;
            
            public event System.EventHandler UploadRequest;
            public event System.EventHandler DownloadRequest;
            public event System.EventHandler UserAction;
            public event System.EventHandler StatusBarMessage;
            public event ExternalUploadRequestHandler ExternalUploadRequest;
            
            private Gui.ActivityProgressBar progress;
            private Button btnup;
            private Button btnnewfolder;
            private string showhiddenstr;
            
            public FileManagerRemote(bareFTP.Preferences.Config config, Gui.ActivityProgressBar progressBar) : base(false, 1)
            {
                  
                  progress = progressBar;
                  cache = new FileListCache(3600);
                  cwd = new BarePath();
                  isConnected = false;
                  conn = null;
                  Gtk.HBox hbox = new Gtk.HBox(false, 1);
                  
                  pathEntry = new Gtk.Entry();
                  pathEntry.Activated += new EventHandler(OnPathEntryActivated);
                  hbox.PackStart(pathEntry);
                  
                  btnup = new Gtk.Button();
                  btnup.CanFocus = true;
                  Gtk.Image w44 = new Gtk.Image();
            w44.Pixbuf = Gtk.IconTheme.Default.LoadIcon(Gtk.Stock.GoUp, 16, 0);
                  w44.TooltipText = Catalog.GetString("Parent Directory");
            btnup.Add(w44);
            btnup.Label = null;
                  btnup.Relief = ReliefStyle.None;
            btnup.Clicked += new EventHandler(DirUpClicked); 
            hbox.PackStart(btnup, false, false, 0);
            
            btnnewfolder = new Gtk.Button();
                  btnnewfolder.CanFocus = true;
                  Gtk.Image w45 = new Gtk.Image();
            if(Gtk.IconTheme.Default.HasIcon("stock_new-dir"))
                        w45.Pixbuf = Gtk.IconTheme.Default.LoadIcon("stock_new-dir", 16, 0);
                  else
                        w45.Pixbuf = Gtk.IconTheme.Default.LoadIcon(Gtk.Stock.Directory, 16, 0);
                  w45.TooltipText = Catalog.GetString("Create New Diretory");
            btnnewfolder.Add(w45);
            btnnewfolder.Label = null;
                  btnnewfolder.Relief = ReliefStyle.None;
            btnnewfolder.Clicked += new System.EventHandler(OnNewDirClicked);
                  hbox.PackStart(btnnewfolder, false, false, 0);
                  
                  this.PackStart(hbox, false, false, 0);
                  
                  Gtk.ScrolledWindow scrollw = new Gtk.ScrolledWindow();
                  filelist = new FileList(new Gtk.ListStore (typeof (FileTreeNode)),true, config);
                  
                  Gtk.TargetEntry[] te1 = new TargetEntry[] { 
                        new TargetEntry("treeViewLocal", Gtk.TargetFlags.App, 0),
                        new TargetEntry("text/uri-list", Gtk.TargetFlags.OtherApp, 1)};
                  
                  Gtk.TargetEntry[] te2 = new TargetEntry[] { 
                        new TargetEntry("text/uri-list", Gtk.TargetFlags.OtherApp, 1),
                        new TargetEntry("treeViewRemote", Gtk.TargetFlags.App, 0)};
                  
                  filelist.EnableModelDragSource(Gdk.ModifierType.Button1Mask, te2, Gdk.DragAction.Move | Gdk.DragAction.Move);
                  filelist.EnableModelDragDest(te1, Gdk.DragAction.Copy);
                  filelist.DragDataGet += OnDragDataGet;
                  filelist.DragDataReceived += OnDragDataReceived;
                  filelist.DirectoryChanged += new DirectoryChangedHandler(OnDirChanged);
                  filelist.NewDirectoryNamed += DirectoryNamed;
                  filelist.FileRenameRequest += new FileRenameRequestHandler(OnFileRenameRequest);
                  filelist.DeleteRequest += new DeleteRequestHandler(OnDeleteRequest);
                  filelist.TransferRequest += new TransferRequestHandler(OnTransferRequested);
                  filelist.ChmodRequested += new ChmodRequestHandler(OnChmodRequested);
                  filelist.LinkActivated += new LinkActivatedHandler(OnLinkActivated);
                  filelist.NewDirRequested += OnNewDirClicked;
                  filelist.CdUp += CdUp;;
                  
                  scrollw.Add(filelist);
                  scrollw.ShadowType = Gtk.ShadowType.EtchedIn;
                  
                  pathEntry.Sensitive = false;
                  
                  this.PackStart(scrollw);
                  
            }
            
            protected override void OnFocusGrabbed ()
            {
                  this.filelist.GrabFocus();
            }
            
            public void CdUp()
            {
                  ChangeDir(cwd.RemoveElementRemote(), true);
            }
            
            protected void OnFileRenameRequest(FileRenamedArgs args)
            {
                  UserAction(null,null);
                  try
                  {
                        this.conn.RenameFile(args.OldName, args.NewName);
                  }
                  catch(FtpException) {}
            ChangeDir(cwd.RemotePath, false);
            }
            
            protected void OnChmodRequested(FileListActionArgs args)
            {
                  UserAction(null,null);
                  
                  bareFTP.Gui.Dialog.ChmodDialog dlg = new bareFTP.Gui.Dialog.ChmodDialog();
                  
                  if(filelist.SelectedFiles.Count == 1)
                  {
                        FileTreeNode n = filelist.SelectedFileNodes[0];
                        dlg.Permissions = n.Rights;
                  }
                        
                  dlg.Modal = true;
                  if(dlg.Run() == (int)ResponseType.Ok)
                  {
                        try
                        {
                              Console.WriteLine(dlg.Permissions);
                              foreach(string filename in filelist.SelectedFiles)
                                    conn.Chmod(dlg.Permissions, filename);
                        }
                        catch(FtpException) {}
                        ChangeDir(cwd.RemotePath, false);
                  }
                  
                  dlg.Destroy();
            }
            
            protected void OnDeleteRequest(FileListActionArgs args)
            {
                  if(!bareFTP.Gui.Dialog.Dialogs.QuestionDialog(Catalog.GetString("Are you sure you want to delete the selected files or directories?")))
                        return;

                  System.Threading.Thread t = new System.Threading.Thread(DoDelete);
                  t.Start();
                              
            }
            
            protected void OnTransferRequested(FileListActionArgs args)
            {
                  UserAction(null,null);
                  // From context menu...
                  DownloadRequest(null,null);
            }
            
            protected void DirectoryNamed(Gtk.EditedArgs args)
      {
                  UserAction(null,null);
                  
                  try
                  {
                        this.conn.MakeDir(args.NewText);
                  }
                  catch(FtpException) {}
            ChangeDir(cwd.RemotePath, false);
      }
      
      public void ChangeDir(string nPath, bool usecache)
            {
                  ChangeDir(nPath, usecache, false);
            }
            
            public void ChangeDir(string nPath, bool usecache, bool internalCall)
            {
                  if(!internalCall)
                        UserAction(null,null);
                  try
                  {
                        Gtk.ListStore store;
                        
                        if(nPath == null)
                        {
                              store = MakeNodeStore(new List<RemoteFile>());
                              Gtk.Application.Invoke( delegate {
                                    filelist.Model = store;
                              });
                              return;
                        }

                        if(string.IsNullOrEmpty(nPath))
                        {
                              store = MakeNodeStore(conn.XDir());
                        }
                        else
                  {
                              if(!isConnected)
                              {
                                    bareFTP.Gui.Dialog.Dialogs.ErrorDialog(Catalog.GetString("Can't change directory when not connected"));
                                    pathEntry.Text = String.Empty;
                                    return;
                              }
                              
                              try
                              {
                              conn.SetCurrentDirectory(nPath);
                              }
                              catch
                              {
                                    // Probably a non-existing dir. Revert.
                                    nPath = cwd.RemotePath; 
                              }
                        
                        if(!usecache)
                              store = null;
                        else
                              store = cache.GetCachedStore(System.IO.Path.Combine(cwd.RemotePath, nPath));
                        
                        if(store == null)
                        {
                                    store = MakeNodeStore(conn.XDir());
                              //cache.AddEntry(System.IO.Path.Combine(cwd, nPath), store);
                        }
                        
                  }
                        
                        Gtk.Application.Invoke( delegate {
                                    
                              filelist.SetModel(store);
                              });

                        cwd.SetBaseRemote(conn.GetCurrentDirectory());
                        
                        Gtk.Application.Invoke( delegate {
                              pathEntry.Text = cwd.ToString(true);
                              filelist.ScrollToPoint(0,0);
                        });
                  }
                  catch(FtpException) 
                  {
                  }
                  catch(Exception)
                  {
                        //ChangeDir("..", false);
                  }
            }
            
            public void SetConnection(Connection.Connection conn, string startDir)
            {
                  pathEntry.Sensitive = true;
                  this.conn = conn;
                  IsConnected = true;
                  ChangeDir(startDir, false);
            }
            
            public void RemoveConnection()
            {
                  pathEntry.Text = string.Empty;
                  pathEntry.Sensitive = false;
                  IsConnected = false;
                  ChangeDir(null, false, true);
            }
            
            protected void OnDirChanged(DirectoryChangedArgs args)
            {
                  ChangeDir(args.NewPath, false);
            }
            
            protected void OnLinkActivated(DirectoryChangedArgs args)
            {
                  if(conn.IsDir(args.NewPath))
                        ChangeDir(args.NewPath, false);
                  else
                        DownloadRequest(null, null);
            }

            protected void OnPathEntryActivated(object o, EventArgs args)
            {
                  ChangeDir(pathEntry.Text, false);
            }
            
            protected void OnNewDirClicked(object o, EventArgs args)
            {
                  UserAction(null,null);
                  
                  if(conn == null || !conn.Connected)
                        return;
                  
                  this.filelist.MakeDir(Catalog.GetString("New Directory"), true);
            }
            
            protected void DirUpClicked(object o, EventArgs args)
            {
                  
                  if(conn == null || !conn.Connected)
                        return;

                  ChangeDir(cwd.RemoveElementRemote(), true);

            }
            
            public bool IsConnected
            {
                  get { return this.isConnected; }
                  set { this.isConnected = value; }
            }
            
            public List<RemoteFile> CurrentDirRemoteFiles
            {
                  get { return this.currentDirFileList; }
            }
            
            private Gtk.ListStore MakeNodeStore(List<RemoteFile> filelist)
            {
                  
                  Gtk.ListStore store = new Gtk.ListStore (typeof (FileTreeNode));
                  bool showHidden;
                  if(!string.IsNullOrEmpty(showhiddenstr))
                        showHidden = bool.Parse(showhiddenstr);
                  else
                        showHidden = this.filelist.ShowHiddenFiles;
                  
                  foreach(RemoteFile rfile in filelist)
                  {
                        
                        if(rfile.Filename != ".")
                        {
                              if(showHidden || rfile.Filename == ".." || (!showHidden && !rfile.Filename.StartsWith(".")))
                                          store.AppendValues (new FileTreeNode(rfile));
                        }
                        
                  }
                  
                  currentDirFileList = filelist;
            return store;
            }
            
            public List<RemoteFile> SelectedFileTree
            {
                  get 
                  {
                        List<RemoteFile> paths = new List<RemoteFile>();
                                    
                        foreach(FileTreeNode fnode in filelist.SelectedFileNodes)
                        {
                              RemoteFile rfile = new RemoteFile();
                              rfile.Path.SetBaseRemote(cwd.ToString(true));
                              
                              rfile.Size = Convert.ToInt64(fnode.Size);
                              rfile.IsDir =  fnode.IsDir;
                              rfile.IsLink = fnode.IsLink;
                              rfile.Linkdest = fnode.LinkName;
                              if(!string.IsNullOrEmpty(fnode.Rights))
                                    rfile.Permissions = PermissionParser.RWXToMode(fnode.Rights);
                              
                              if(!rfile.IsDir)
                                    rfile.Path.SetFileName(string.Empty, fnode.FileName);
                              else
                                    rfile.Path.SetFileName(fnode.FileName, string.Empty);
                              
                              if(fnode.FileName == "..")
                                    continue;
                              
                              paths.Add(rfile);
                              if(rfile.IsDir)
                                    Traverser(rfile.Path, paths);
                        }
                        
                        conn.SetCurrentDirectory(cwd.RemotePath);
                        return paths;
                  }
            }

            private void Traverser(bareFTP.Protocol.BarePath path, List<RemoteFile> _paths)
            {
                  conn.SetCurrentDirectory(path.RemotePathAbs);
                  
                  foreach(RemoteFile file in conn.XDir())
                  {
                        if(file.Filename != "." && file.Filename != "..")
                        {
                              file.Path.SetBaseRemote(cwd.ToString(true));
                              if(!file.IsDir)
                                    file.Path.SetFileName(path.RelativePathRemote, file.Filename);
                              else
                              {
                                    file.Path.SetFileName(path.RelativePathRemote, string.Empty);
                                    file.Path.AddRelativeElement(file.Filename);
                              }
                              _paths.Add(file);
                              if(file.IsDir)
                              {
                                    bareFTP.Protocol.BarePath tpath = new bareFTP.Protocol.BarePath();
                                    tpath.SetBaseRemote(cwd.ToString(true));
                                    tpath.SetFileName(path.RelativePathRemote, string.Empty);
                                    tpath.AddRelativeElement(file.Filename);
                                    Traverser(tpath,  _paths);
                              }
                              
                        }
                  }
            }
            
            private void OnDragDataGet(object o, DragDataGetArgs args)
            {
                  string str = string.Empty;
                  if(filelist != null && filelist.SelectedFileNodes.Count > 0)
                  {
                        Gnome.Vfs.Vfs.Initialize();
                        
                        foreach(FileTreeNode node in filelist.SelectedFileNodes)
                        {
                              
                              Gnome.Vfs.Uri uri = new Gnome.Vfs.Uri(conn.Protocol.ToString().ToLower() + "://" + cwd.ToString(true) + "/" +node.FileName);
                              uri.HostName = conn.ConnProperties.Hostname;
                              uri.UserName = conn.ConnProperties.User;
                              str += uri.ToString() +  "\n";
                        }
                  }
                  Gnome.Vfs.Vfs.Shutdown();
                  args.SelectionData.Set(args.SelectionData.Target, 8,
                                      System.Text.Encoding.UTF8.GetBytes(str));
            }
            
            private void OnDragDataReceived(object o, DragDataReceivedArgs args)
            {
                  FileTreeNode node = null;
                  Gtk.TreePath path;
                  Gtk.TreeIter iter;
                  Gtk.TreeViewDropPosition pos;
                  filelist.GetDestRowAtPos(args.X, args.Y, out path, out pos);
                  if(path != null)
                  {
                        filelist.Model.GetIter(out iter, path);
                        node = (FileTreeNode)filelist.Model.GetValue(iter,0);
                  }
                  
                  string files = System.Text.Encoding.Default.GetString(args.SelectionData.Data);
                  if(args.Info == 0 && this.IsConnected && !string.IsNullOrEmpty(files.Trim()))
                  {
                        UploadRequest(node,null);
                  }
                  
                  if(args.Info == 1)
                  {
                        
                        List<string> lfiles = new List<string>();
                        foreach(string s in files.Split(Environment.NewLine.ToCharArray()))
                        {
                              if(!string.IsNullOrEmpty(s.Trim()) && s.StartsWith("file://"))
                                    lfiles.Add(s.Substring(7).Trim());
                        }
                        
                        ExternalUploadRequest(lfiles, node);
                  }
            }
            
            public BarePath CurrentDir
            {
                  get { return this.cwd; }
            }
            
            public string ShowHidden
            {
                  set { showhiddenstr = value;} 
            }
            
            
            ///////////THREADED REMOTE ACTIONS//////////////

            private void DoDelete()
            {
                  UserAction(null,null);
                  
                  Disable();

                  try
                  {
                        progress.Start();
                        if(StatusBarMessage != null)
                              StatusBarMessage(null, new StatusBarMessageArgs("Getting file and directory list..", false));
                        List<RemoteFile> rfiles = SelectedFileTree;
                        
                        if(rfiles != null)
                        {
                              // Reversing list to start deleting in the "deepest" end of the tree..
                              rfiles.Reverse();

                              if(StatusBarMessage != null)
                                    StatusBarMessage(null, new StatusBarMessageArgs("Deleting..", false));
                              
                              foreach(RemoteFile file in rfiles)
                              {
                                    if(file.IsDir)
                                    {
                                          try
                                          {
                                                conn.RemoveDir(file.Path.FileNameRemoteAbs);
                                          } 
                                          catch(FtpException) {}
                                    }
                                    
                                    else
                                    {
                                          try
                                          {
                                                conn.DeleteFile(file.Path.FileNameRemoteAbs);
                                          }
                                          catch(FtpException) {}
                                    }
                              }

                              if(StatusBarMessage != null)
                                    StatusBarMessage(null, new StatusBarMessageArgs("", false));
                              
                        }
                  }
                  catch(Exception ex)
                  {
                        if(StatusBarMessage != null)
                              StatusBarMessage(null, new StatusBarMessageArgs(ex.Message, true));
                  }
                  finally
                  {
                        progress.Stop();
                        Enable();
                        ChangeDir(cwd.ToString(true), false, true);
                  }
            }

            public void Disable()
            {
                  
                  Gtk.Application.Invoke(delegate {
                              filelist.Sensitive = false;
                              pathEntry.Sensitive = false;
                              btnnewfolder.Sensitive = false;
                              btnup.Sensitive = false;
                        });
            }

            public void Enable()
            {
                  Gtk.Application.Invoke(delegate {
                              filelist.Sensitive = true;
                              pathEntry.Sensitive = true;
                              btnnewfolder.Sensitive = true;
                              btnup.Sensitive = true;
                        });
            }
      }
      
}

Generated by  Doxygen 1.6.0   Back to index