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

FileList.cs

// FileList.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 Gtk;
using Mono.Unix;

namespace bareFTP.Gui.FileManager
{
      
      // TODO: Do we need all these?..
      public delegate void DirectoryChangedHandler (DirectoryChangedArgs args);
      public delegate void LinkActivatedHandler (DirectoryChangedArgs args);
      public delegate void NewDirectoryNamedChangedHandler (Gtk.EditedArgs args);
      public delegate void FileRenameRequestHandler (FileRenamedArgs args);
      public delegate void DeleteRequestHandler (FileListActionArgs args);
      public delegate void ChmodRequestHandler (FileListActionArgs args);
      public delegate void TransferRequestHandler (FileListActionArgs args);
      public delegate void FileListChangedHandler();
      public delegate void CdUpHandler();
      
      public partial class FileList : Gtk.TreeView
      {
            public event DirectoryChangedHandler DirectoryChanged;
            public event CdUpHandler CdUp;
            public event LinkActivatedHandler LinkActivated;
            public event NewDirectoryNamedChangedHandler NewDirectoryNamed;
            public event DeleteRequestHandler DeleteRequest;
            public event FileRenameRequestHandler FileRenameRequest;
            public event TransferRequestHandler TransferRequest;
            public event ChmodRequestHandler ChmodRequested;
            public event EventHandler NewDirRequested;
            
            private bool IsRemote;
            private bareFTP.Preferences.Config conf;
            
            public FileList(TreeModel model, bool isremote, bareFTP.Preferences.Config config) : base(model)
            {
                  IsRemote = isremote;
                  this.conf = config;
                  
                  this.RowActivated += new Gtk.RowActivatedHandler (OnRowActivated);
                  this.KeyPressEvent += new Gtk.KeyPressEventHandler(OnKeyPressEvent);
                  this.Selection.Mode = Gtk.SelectionMode.Multiple;
                  
                  //this.EnableGridLines = Gtk.TreeViewGridLines.Vertical;
                  //this.RubberBanding = true;
                  //RulesHint = true;
                  
                  Gtk.TreeViewColumn fileColumn = new Gtk.TreeViewColumn ();
                  fileColumn.Title = Catalog.GetString("Filename");
                  fileColumn.SortColumnId = 0;
                  fileColumn.SortIndicator = true;
                  fileColumn.SortOrder = SortType.Ascending;
                  
                  Gtk.TreeViewColumn sizeColumn = new Gtk.TreeViewColumn ();
                  sizeColumn.Title = Catalog.GetString("Size");
                  sizeColumn.SortColumnId = 1;
                  sizeColumn.SortIndicator = true;
                  
                  Gtk.TreeViewColumn dateColumn = new Gtk.TreeViewColumn ();
                  dateColumn.Title = Catalog.GetString("Date");
                  dateColumn.SortColumnId = 2;
                  dateColumn.SortIndicator = true;
                  
                  Gtk.TreeViewColumn userColumn = new Gtk.TreeViewColumn ();
                  userColumn.Title = Catalog.GetString("User");
                  userColumn.SortColumnId = 3;
                  
                  Gtk.TreeViewColumn groupColumn = new Gtk.TreeViewColumn ();
                  groupColumn.Title = Catalog.GetString("Group");
                  groupColumn.SortColumnId = 4;
                  
                  Gtk.TreeViewColumn privsColumn = new Gtk.TreeViewColumn ();
                  privsColumn.Title = Catalog.GetString("Permissions");
                  privsColumn.SortColumnId = 5;
                  
                  MyCellRendererPixbuf iconCell = new MyCellRendererPixbuf();
                  MyCellRendererText fileCell = new MyCellRendererText(180);
                  fileColumn.PackStart(iconCell, false);
                  fileColumn.PackStart(fileCell, false);
                  fileColumn.SetCellDataFunc (fileCell, new Gtk.TreeCellDataFunc (RenderFileName));
                  
                  MyCellRendererText sizeCell = new MyCellRendererText(80);
                  sizeColumn.PackStart(sizeCell, false);
                  sizeColumn.SetCellDataFunc (sizeCell, new Gtk.TreeCellDataFunc (RenderSize));
                  
                  MyCellRendererText dateCell = new MyCellRendererText(160);
                  dateColumn.PackStart(dateCell, false);
                  dateColumn.SetCellDataFunc (dateCell, new Gtk.TreeCellDataFunc (RenderDate));
                  
                  MyCellRendererText userCell = new MyCellRendererText(60);
                  userColumn.PackStart(userCell, false);
                  userColumn.SetCellDataFunc (userCell, new Gtk.TreeCellDataFunc (RenderUser));
                  
                  MyCellRendererText groupCell = new MyCellRendererText(60);
                  groupColumn.PackStart(groupCell, false);
                  groupColumn.SetCellDataFunc (groupCell, new Gtk.TreeCellDataFunc (RenderGroup));
                  
                  MyCellRendererText privsCell = new MyCellRendererText(100);
                  privsColumn.PackStart(privsCell, false);
                  privsColumn.SetCellDataFunc (privsCell, new Gtk.TreeCellDataFunc (RenderFilePrivs));
                  
                  this.AppendColumn(fileColumn);
                  this.AppendColumn(sizeColumn);
                  this.AppendColumn(dateColumn);
                  this.AppendColumn(userColumn);
                  this.AppendColumn(groupColumn);
                  this.AppendColumn(privsColumn);
                  
                  foreach(Gtk.TreeViewColumn col in this.Columns)
                        col.Resizable = true;

            }

            public void SetModel(TreeModel model)
            {
                  ListStore ls = Model as ListStore;
                  
                  TreeSortable sortable = model as TreeSortable;
                  sortable.SetSortFunc(0, SortName);
                  sortable.SetSortFunc(1, SortSize);
                  sortable.SetSortFunc(2, SortDate);
                  sortable.SetSortFunc(3, SortUser);
                  sortable.SetSortFunc(4, SortGroup);
                  sortable.SetSortFunc(5, SortPermissions);
                  
                  int sortcol;
                  Gtk.SortType st;
                  if(ls.GetSortColumnId(out sortcol, out st))
                        sortable.SetSortColumnId(sortcol, st);
                  else
                        sortable.SetSortColumnId(0, Gtk.SortType.Ascending);
                  Model = model;
            }
            
            protected override void OnDragBegin (Gdk.DragContext context)
            {
                  Gtk.Drag.SetIconDefault(context);
            }

            private void RenderFileName (Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
            {
                      
                  FileTreeNode node = (FileTreeNode)model.GetValue(iter, 0);
                  (cell as MyCellRendererText).Text = node.FileName;
                  
                  foreach(Gtk.CellRenderer c in column.CellRenderers)
                  {
                        if(c is MyCellRendererPixbuf)
                        {
                              MyCellRendererPixbuf iconcell = (MyCellRendererPixbuf)c;
                              iconcell.Pixbuf = node.Type;
                        }
                  }
            }
            
            private void RenderSize (Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
            {
                  FileTreeNode node = (FileTreeNode)model.GetValue(iter, 0);
                  string size = string.Empty;
                  if(!node.IsDir)
                  {
                        if(node.Size >= 0)
                              size = Gnome.Vfs.Format.FileSizeForDisplay(node.Size);
                  }
                  (cell as MyCellRendererText).Text = size;
            }
            
            private void RenderDate (Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
            {
                  FileTreeNode node = (FileTreeNode)model.GetValue(iter, 0);
                  if(node.Date < DateTime.MaxValue)
                        (cell as MyCellRendererText).Text = node.Date.ToString();
                  else
                        (cell as MyCellRendererText).Text = string.Empty;
            }
            
            private void RenderUser (Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
            {
                  FileTreeNode node = (FileTreeNode)model.GetValue(iter, 0);
                  (cell as MyCellRendererText).Text = node.User;
            }
            
            private void RenderGroup (Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
            {
                  FileTreeNode node = (FileTreeNode)model.GetValue(iter, 0);
                  (cell as MyCellRendererText).Text = node.Group;
            }
            
            private void RenderFilePrivs (Gtk.TreeViewColumn column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
            {
                  FileTreeNode node = (FileTreeNode)model.GetValue(iter, 0);
                  (cell as MyCellRendererText).Text = node.Rights;
            }

            #region Properties
            
            public bool ShowHiddenFiles
            {
                  get { return conf.General_ShowHiddenFiles; }
            }
            
            public List<string> SelectedFiles
      {
            get 
            {
                        List<string> selectedFiles = new List<string>();
                        
                        foreach(FileTreeNode node in SelectedFileNodes)
                        {
                              selectedFiles.Add(node.FileName);
                        }
                        
                        return selectedFiles;
            }
      }
            
            public List<FileTreeNode> SelectedFileNodes
            {
                  get
                  {
                        List<FileTreeNode> files = new List<FileTreeNode>();
                        
                        Gtk.TreeIter iter;
                        Gtk.TreePath[] paths = this.Selection.GetSelectedRows();
                        foreach(Gtk.TreePath path in paths)
                        {
                              this.Model.GetIter(out iter, path);
                              FileTreeNode node = (FileTreeNode)this.Model.GetValue(iter,0);
                              files.Add(node);
                        }
                        
                        return files;
                  }
            }
                        
            #endregion
                        
            public void MakeDir(string proposedName, bool newEntry)
            {
                  Gtk.TreePath path = new Gtk.TreePath("1");
                  Gtk.ListStore store = this.Model as Gtk.ListStore;
                  Gtk.TreeIter iter;
                  store.GetIterFirst(out iter);
                  
                  //bool fp = true;
                  //FileTreeNode node;
                  
                  /*
                  while(fp)
                  {
                        node = (FileTreeNode)store.GetValue(iter,0);
                        if(!node.IsDir)
                              fp = false;
                        else
                              fp = store.IterNext(ref iter);
                  }
                  */
                  Gtk.TreeIter newiter;
                  //if(store.IterIsValid(iter))
                  //    newiter = store.InsertBefore(iter);
                  //else
                        newiter = store.Insert(1);
                  
                  store.SetValue(newiter,0, new FileTreeNode(proposedName));
                  path = store.GetPath(newiter);
                  
                  if(!newEntry)
                  {
                        Gtk.TreeIter iter2;
                        store.GetIter(out iter2, path);
                        store.Remove(ref iter2);
                  }
                  
                  Gtk.CellRendererText cr = FileNameCell;
                  cr.Editable = true;
                  cr.Edited += FileName_Edited;
                  
                  SetCursorOnCell(path, GetColumn(0), cr, true);
            }
            
            private void FileName_Edited (object o, Gtk.EditedArgs args)
            {     
                  Gtk.CellRendererText cr = FileNameCell;
                  cr.Editable = false;
                  cr.Edited -= FileName_Edited;
                  
                  NewDirectoryNamed(args);
            }
            
            private void File_Renamed (object o, Gtk.EditedArgs args)
            {     
                  Gtk.CellRendererText cr = FileNameCell;
                  cr.Editable = false;
                  cr.Edited -= File_Renamed;
                  
                  FileTreeNode node = SelectedFileNodes[0]; 
                  FileRenameRequest(new FileRenamedArgs(node.FileName, args.NewText));
                  
            }
            
            [GLib.ConnectBefore]
            void OnKeyPressEvent(object o, Gtk.KeyPressEventArgs args)
            {
                  FileListActionArgs _args = new FileListActionArgs(SelectedFileNodes);
                  if(args.Event.State == Gdk.ModifierType.Mod1Mask)
                  {
                        if(args.Event.Key == Gdk.Key.Up)
                        {
                              CdUp();
                        }
                  }
                  else if(args.Event.State == Gdk.ModifierType.ControlMask)
                  {
                        if(args.Event.Key == Gdk.Key.r || args.Event.Key == Gdk.Key.R)
                              DirectoryChanged(new DirectoryChangedArgs(string.Empty));
                  }
                  else if(args.Event.Key == Gdk.Key.Delete)
                  {
                        this.DeleteRequest(_args);
                  }
                  else if(args.Event.Key == Gdk.Key.F2)
                  {
                        InitRename();
                  }
                  
            }
            
            void OnRowActivated (object o, Gtk.RowActivatedArgs args)
            {
                  
                  if(SelectedFileNodes.Count == 1)
                  {
                        FileTreeNode node = SelectedFileNodes[0];
                        
                  if(node.IsDir)
                        DirectoryChanged(new DirectoryChangedArgs(node.FileName));
                  else if(node.IsLink)
                  {
                              LinkActivated(new DirectoryChangedArgs(node.FileName));
                  }
                  else
                  {
                        FileListActionArgs _args = new FileListActionArgs(node);
                        TransferRequest(_args);
                  }
            }
      }
            
            private MyCellRendererText FileNameCell
            {
                  get
                  {
                        foreach(Gtk.CellRenderer cr in GetColumn(0).CellRenderers)
                        {
                              if(cr is MyCellRendererText)
                              {
                                    return cr as MyCellRendererText;
                              }
                        }
                        return null;
                  }
            }

            protected override bool OnButtonPressEvent (Gdk.EventButton evnt)
            {
                  if(evnt.Button == 3)
                  {
                  ShowPopup();
                        return false;
                  }
                  return base.OnButtonPressEvent(evnt);
            }
            
      private void ShowPopup ()
      {
                  List<FileTreeNode> files = new List<FileTreeNode>();
                  Gtk.TreeIter iter;
                  Gtk.TreePath[] paths = this.Selection.GetSelectedRows();
                  foreach(Gtk.TreePath path in paths)
                  {
                        this.Model.GetIter(out iter, path);
                        files.Add((FileTreeNode)this.Model.GetValue(iter,0));
                  }

                  using(ContextMenu menu = new ContextMenu(IsRemote, files.Count))
                  {
                  FileListActionArgs _args = new FileListActionArgs(files);
                        
                        if(files.Count == 1)
                  {
                        _args.FileTreePath = paths[0];
                              
                        if(!files[0].IsDir)
                                    menu.DisableDirectoryMethods();
                  }
                        
                        menu.RenameRequested += delegate { 
                              InitRename();
                        };
                        
                        menu.DeleteRequested += delegate {
                              DeleteRequest(_args);
                        };
                        
                        menu.TransferRequested += delegate {
                              if(_args != null)
                                    TransferRequest(_args);
                        };
                        menu.DirOpenRequested += delegate {
                              DirectoryChanged(new DirectoryChangedArgs(_args.FileTreeNodes[0].FileName));
                        };
                        menu.ChmodRequested += delegate {
                              ChmodRequested(_args);
                        };
                        menu.NewDirRequested += delegate {
                              NewDirRequested(null,null);
                        };
                        menu.Popup();
                        menu.ShowAll();
                  }
            }

            #region Sorting
            protected int SortName(TreeModel model, TreeIter t1, TreeIter t2)
            {
                  FileTreeNode node = model.GetValue(t1,0) as FileTreeNode;
                  FileTreeNode node2 = model.GetValue(t2,0) as FileTreeNode;
                  if(node.FileName == "..")
                        return 0;
                  else if(node.IsDir && !node2.IsDir)
                        return 0;
                  else if(!node.IsDir && node2.IsDir)
                        return 1;
                  else
                        return node.FileName.CompareTo(node2.FileName);
            }

            protected int SortDate(TreeModel model, TreeIter t1, TreeIter t2)
            {
                  FileTreeNode node = model.GetValue(t1,0) as FileTreeNode;
                  FileTreeNode node2 = model.GetValue(t2,0) as FileTreeNode;
                  if(node.FileName == "..")
                        return 0;
                  else if(node.IsDir && !node2.IsDir)
                        return 0;
                  else if(!node.IsDir && node2.IsDir)
                        return 1;
                  else
                        return node.Date.CompareTo(node2.Date);
            }

            protected int SortSize(TreeModel model, TreeIter t1, TreeIter t2)
            {
                  FileTreeNode node = model.GetValue(t1,0) as FileTreeNode;
                  FileTreeNode node2 = model.GetValue(t2,0) as FileTreeNode;
                  if(node.FileName == "..")
                        return 0;
                  else if(node.IsDir && !node2.IsDir)
                        return 0;
                  else if(!node.IsDir && node2.IsDir)
                        return 1;
                  else
                        return node.Size.CompareTo(node2.Size);
                  
            }

            protected int SortUser(TreeModel model, TreeIter t1, TreeIter t2)
            {
                  FileTreeNode node = model.GetValue(t1,0) as FileTreeNode;
                  FileTreeNode node2 = model.GetValue(t2,0) as FileTreeNode;
                  if(node.FileName == "..")
                        return 0;
                  else if(node.IsDir && !node2.IsDir)
                        return 0;
                  else if(!node.IsDir && node2.IsDir)
                        return 1;
                  else
                        return node.User.CompareTo(node2.User);
            }

            protected int SortGroup(TreeModel model, TreeIter t1, TreeIter t2)
            {
                  FileTreeNode node = model.GetValue(t1,0) as FileTreeNode;
                  FileTreeNode node2 = model.GetValue(t2,0) as FileTreeNode;
                  if(node.FileName == "..")
                        return 0;
                  else if(node.IsDir && !node2.IsDir)
                        return 0;
                  else if(!node.IsDir && node2.IsDir)
                        return 1;
                  else
                        return node.Group.CompareTo(node2.Group);
            }

            protected int SortPermissions(TreeModel model, TreeIter t1, TreeIter t2)
            {
                  FileTreeNode node = model.GetValue(t1,0) as FileTreeNode;
                  FileTreeNode node2 = model.GetValue(t2,0) as FileTreeNode;
                  if(node.FileName == "..")
                        return 0;
                  else if(node.IsDir && !node2.IsDir)
                        return 0;
                  else if(!node.IsDir && node2.IsDir)
                        return 1;
                  else
                        return node.Rights.CompareTo(node2.Rights);     
            }
            
            void InitRename()
            {
                  if(SelectedFileNodes.Count == 1)
                        {
                              MyCellRendererText c = FileNameCell;
                              c.Editable = true;
                              c.Edited += File_Renamed;
                              SetCursorOnCell(Selection.GetSelectedRows()[0], GetColumn(0), c, true);
                        }     
            }
#endregion
            
      }
      
      public class DirectoryChangedArgs : EventArgs
      {
      
            private string newPath;
            public string NewPath
            {
                  get { return newPath; }
            }

            public DirectoryChangedArgs(string newPath)
            {
                  this.newPath = newPath;
            }
      }
      
      public class FileRenamedArgs : EventArgs
      {
            private string oldName;
            private string newName;
            
            public string NewName
            {
                  get { return newName; }
            }
            public string OldName
            {
                  get { return oldName; }
            }
            
            public FileRenamedArgs()
            {}
            
            public FileRenamedArgs(string oldname, string newname)
            {
                  this.oldName = oldname;
                  this.newName = newname;
            }
      }
      
      public class FileListActionArgs : EventArgs
      {
      
            private List<FileTreeNode> files;
            private Gtk.TreePath tpath;
            
            public List<FileTreeNode> FileTreeNodes
            {
                  get { return files; }
            }
            
            public Gtk.TreePath FileTreePath
            {
                  get { return tpath; }
                  set { tpath = value; }
            }

            public FileListActionArgs(List<FileTreeNode> files)
            {
                  this.files = files;
                  tpath = null;
            }
            
            public FileListActionArgs(FileTreeNode file)
            {
                  this.files = new List<FileTreeNode>();
                  files.Add(file);
                  tpath = null;
            }
            
            
      }

      public class StatusBarMessageArgs : EventArgs
      {
            public StatusBarMessageArgs(string msg, bool error)
            {
                  this.msg = msg;
                  this.error = error;
            }
            private string msg;
            private bool error;
            
            public bool Error {
                  get {
                        return error;
                  }
                  set {
                        error = value;
                  }
            }

            public string Msg {
                  get {
                        return msg;
                  }
                  set {
                        msg = value;
                  }
            }
            
      }
      
}

Generated by  Doxygen 1.6.0   Back to index