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

ProgressList.cs

// ProgressList.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 Gtk;
using System.Collections.Generic;
using bareFTP.Protocol;
using bareFTP.Gui;
using Mono.Unix;

namespace bareFTP.Gui.ProgressMonitor
{
      
      public class ProgressList : TreeView
      {
            TreeStore store;
            Dictionary<long, TreeIter> UIdToIter;
            Dictionary<long, XferFile> UIdToFile;           
            
            private TreeIter piter;
            private XferFile parent = null;
            
            private List<long> hidden;
            
            public event EventHandler XferFileReordered;
            public event EventHandler XferFileAbort;
            private ProgressListContextMenu menu;
            
            public virtual void OnXferFileReordered(XferFileReorderedArgs e) {
                  XferFileReordered(this, e);
            }
            
            public ProgressList()
            {
                  hidden = new List<long>();
                  this.ShowExpanders = true;
                  this.Selection.Mode = SelectionMode.Single;
                  
                  Gtk.TreeViewColumn fileColumn = new Gtk.TreeViewColumn ();
                  fileColumn.Title = Catalog.GetString("File");
                  
                  MyCellRendererPixbuf iconCell = new MyCellRendererPixbuf();
                  MyCellRendererText fileCell = new MyCellRendererText(170);
                  fileColumn.PackStart(iconCell, false);
                  fileColumn.PackStart(fileCell, false);
                  fileColumn.SetCellDataFunc (fileCell, new Gtk.TreeCellDataFunc (OnFileNameData));
                  
                  //this.AppendColumn("File",   new MyCellRendererText(170), new TreeCellDataFunc(OnFileNameData));
                  this.AppendColumn(fileColumn);
                  this.AppendColumn("<->",   new MyCellRendererPixbuf(), new TreeCellDataFunc(OnDirectionData));
                  this.AppendColumn(Catalog.GetString("Status"), new MyCellRendererText(100), new TreeCellDataFunc(OnStatusData));
                  this.AppendColumn(Catalog.GetString("Progress"),      new MyCellRendererProgress(120), new TreeCellDataFunc(OnProgressData));
                  this.AppendColumn(Catalog.GetString("Transfered bytes"), new MyCellRendererText(160), new TreeCellDataFunc(OnSizeData));
                  this.AppendColumn(Catalog.GetString("Transfer rate"), new MyCellRendererText(100), new TreeCellDataFunc(OnSpeedData));
                  this.AppendColumn(Catalog.GetString("Time"), new MyCellRendererText(160), new TreeCellDataFunc(OnTimeData));
                  
                  store = new TreeStore(typeof(XferFile));
                  this.Model = store;
                  this.RubberBanding = true;
                  
                  
                  foreach(Gtk.TreeViewColumn col in this.Columns)
                        col.Resizable = true;
                        
                  UIdToIter = new Dictionary<long, TreeIter>();
                  UIdToFile = new Dictionary<long, XferFile>();
                  
                  this.RowCollapsed += new RowCollapsedHandler(OnCollapseHandler);
                  this.RowExpanded += new RowExpandedHandler(OnExpandedHandler);
                  
            }
            
            protected void OnCollapseHandler(object sender, RowCollapsedArgs args)
            {
                  XferFile file = (XferFile)store.GetValue(args.Iter, 0);
                  if(hidden.Contains(file.FileId))
                        hidden.Remove(file.FileId);
            }
            
            protected void OnExpandedHandler(object sender, RowExpandedArgs args)
            {
                  XferFile file = (XferFile)store.GetValue(args.Iter, 0);
                  if(!hidden.Contains(file.FileId))
                        hidden.Add(file.FileId);
            }
            
            public void AppendList(XferFile file)
            {     
                  if(parent == null)
                  {
                        BarePath tpath = new BarePath();
                        tpath.SetFileName(string.Empty, file.RemoteServer);
                        parent = new XferFile(-1, tpath, -1, TransferDirection.Undefined , false, file.RemoteServer); 
                        piter = store.AppendValues(parent);
                        UIdToIter.Add(-1, piter);
                        UIdToFile.Add(-1, parent);
                        parent.TransferInitiated += new EventHandler(OnTransferInitiated);
                        parent.TransferFinished += new EventHandler(OnTransferFinished);
                  }
                  
                  if(parent.Status == DownloadStatus.Finished)
                  {
                        parent.Children.Clear();
                        parent.Status = DownloadStatus.Undefined;
                  }
                  
                  file.Parent = UIdToFile[-1];
                  parent.Children.Add(file);
                  file.TransferInitiated += new EventHandler(OnTransferInitiated);
                  file.TransferFinished += new EventHandler(OnTransferFinished);
                  
                  Gtk.Application.Invoke( delegate {
                                                
                        TreeIter iter = store.AppendValues(piter, file);
                                                   
                        UIdToIter.Add(file.FileId, iter);
                        UIdToFile.Add(file.FileId, file);
                        
                        ExpandAll();
                        
                  });
            }
            
            void OnFileNameData (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
            {
                  
                  XferFile file = (XferFile)store.GetValue(iter, 0);
                  (cell as MyCellRendererText).Text = System.IO.Path.Combine(file.Path.RelativePathLocal, file.Path.FileName);
                  
                  foreach(Gtk.CellRenderer c in tree_column.CellRenderers)
                  {
                        if(c is MyCellRendererPixbuf)
                        {
                              string filename = file.Path.FileName;
                              
                              MyCellRendererPixbuf iconcell = (MyCellRendererPixbuf)c;
                              if(file.FileId == -1)
                              {
                                    if(Gtk.IconTheme.Default.HasIcon(Gtk.Stock.Network))
                                          iconcell.Pixbuf = Gtk.IconTheme.Default.LoadIcon(Gtk.Stock.Network, 16, 0);
                              }
                              else
                                    iconcell.Pixbuf = Gtk.IconTheme.Default.LoadIcon(Gui.IconFinder.FindIconName(filename), 16, 0);
                        }
                  }
                  
                  
            }
            
            void OnDirectionData (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
            {
                  
                  XferFile file = (XferFile)store.GetValue(iter, 0);
                  if(file.FileId > -1)
                  {
                        Gdk.Pixbuf buf = null;
                        if(file.Direction == TransferDirection.Download)
                        {
                              if(Gtk.IconTheme.Default.HasIcon(Gtk.Stock.GoBack))
                                    buf = Gtk.IconTheme.Default.LoadIcon(Gtk.Stock.GoBack, 16, 0);
                              else
                                    buf = Gtk.IconTheme.Default.LoadIcon("stock_left", 16, 0);
                                 
                        }
                        else if(file.Direction == TransferDirection.Upload)
                        {
                              if(Gtk.IconTheme.Default.HasIcon(Gtk.Stock.GoForward))
                                    buf = Gtk.IconTheme.Default.LoadIcon(Gtk.Stock.GoForward, 16, 0);
                              else
                                    buf = Gtk.IconTheme.Default.LoadIcon("stock_right", 16, 0);
                        }
                        ((MyCellRendererPixbuf)cell).Pixbuf = buf;
                  }
                  else
                  {
                        ((MyCellRendererPixbuf)cell).Pixbuf = null;
                  }
            }
            
            void OnStatusData (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
            {
                  
                  XferFile file = (XferFile)store.GetValue(iter, 0);
                  if(!hidden.Contains(file.FileId))
                        ((MyCellRendererText)cell).Text = file.Status.ToString();
                  else
                        ((MyCellRendererText)cell).Text = string.Empty;
                  
            }

            void OnProgressData (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
            {
                  XferFile file = (XferFile)store.GetValue(iter, 0);
                  if(!hidden.Contains(file.FileId))
                  {
                        ((CellRendererProgress)cell).Visible = true;
                        ((CellRendererProgress)cell).Value = (int)(file.Complete*100);
                  }
                  else
                        ((CellRendererProgress)cell).Visible = false;
            }
            
            void OnSizeData (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
            {
                  XferFile file = (XferFile)store.GetValue(iter, 0);
                  if(!hidden.Contains(file.FileId))
                        ((MyCellRendererText)cell).Text = FormatSize( file.TransferedBytes, 2) + " of " + FormatSize( file.TotalBytes, 2);
                  else
                        ((MyCellRendererText)cell).Text = string.Empty;
            }
            
            void OnSpeedData (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
            {
                  XferFile file = (XferFile)store.GetValue(iter, 0);
                  if(!hidden.Contains(file.FileId))
                  {
                        if(file.Status == DownloadStatus.Finished)
                              ((MyCellRendererText)cell).Text = String.Format("{0}/s", FormatSize( Convert.ToInt64(((double)file.Size / file.EndTime.Subtract(file.StartTime).TotalSeconds)), 1 ));
                        else if(file.Status == DownloadStatus.Downloading || file.Status == DownloadStatus.Uploading) 
                              ((MyCellRendererText)cell).Text = FormatSize((int)file.TransferRate, 1) + "/s";
                        else
                              ((MyCellRendererText)cell).Text = string.Empty;
                  }
                  else
                        ((MyCellRendererText)cell).Text = string.Empty;
            
            }
            
            void OnTimeData (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter)
            {
                  XferFile file = (XferFile)store.GetValue(iter, 0);
                  if(!hidden.Contains(file.FileId))
                  {
                        string transfer_time_i18n = Catalog.GetString("Transfer time");
                        string time_elapsed_i18n = Catalog.GetString("Time Elapsed");
                        if(file.Status == DownloadStatus.Finished)
                              ((MyCellRendererText)cell).Text = String.Format("{0}: {1}", transfer_time_i18n, FormatTime(file.EndTime.Subtract(file.StartTime)));
                        else if(file.Status == DownloadStatus.Downloading || file.Status == DownloadStatus.Uploading) 
                              ((MyCellRendererText)cell).Text = String.Format("{0} {1}  ETA: {2}", time_elapsed_i18n, FormatTimeElapsed(file.StartTime), FormatETA(file.ETA));
                        else
                              ((MyCellRendererText)cell).Text = string.Empty;
                  }
                  else
                        ((MyCellRendererText)cell).Text = string.Empty;
            }
            
            public void ClearFinished(bool clear_all)
            {
                  Gtk.Application.Invoke( delegate {
                        
                        List<long> to_be_removed = new List<long>();
                        
                        foreach(XferFile f in UIdToFile.Values)
                        {
                              if(!clear_all)
                              {
                                    if(f.Status == DownloadStatus.Finished || 
                                       f.Status == DownloadStatus.Aborted ||
                                       f.Status == DownloadStatus.Skipped || 
                                       f.Status == DownloadStatus.Failed)
                                          to_be_removed.Add(f.FileId);
                              }
                              else
                                    to_be_removed.Add(f.FileId);
                        }
                        
                        to_be_removed.Sort();
                        to_be_removed.Reverse();
                        
                        foreach(long uid in to_be_removed)
                        {
                              parent.Children.Remove(UIdToFile[uid]);
                              TreeIter i = UIdToIter[uid];
                              store.Remove(ref i);
                              UIdToFile.Remove(uid);
                              UIdToIter.Remove(uid);
                        }
                        
                        if(UIdToFile.Count == 0)
                              parent = null;
                        
                  });
            }
            
            private void OnTransferInitiated(object sender, EventArgs e)
            {
                                    
                  TransferProgressEmittedArgs args = e as TransferProgressEmittedArgs;
                  XferFile file = args.FileTransferInfo as XferFile;
                  
                  file.TransferProgressEmitted += new EventHandler(OnTransferProgress);
            }
            
            private void OnTransferFinished(object sender, EventArgs e)
            {
                  Gtk.Application.Invoke( delegate
                  {
                        TransferProgressEmittedArgs args = e as TransferProgressEmittedArgs;
                        XferFile file = args.FileTransferInfo as XferFile;
                        
                        UpdateProgress(file);
                        
                        file.TransferProgressEmitted -= new EventHandler(OnTransferProgress);
                        if(menu != null)
                        {
                              if(menu.Visible)
                                    menu.Visible = false;
                        }
                                                
                  });
            }
            
            private void OnTransferProgress(object sender, EventArgs e)
            {
                  TransferProgressEmittedArgs args = e as TransferProgressEmittedArgs;
                  UpdateProgress((XferFile)args.FileTransferInfo);
            }
            
            private void UpdateProgress(XferFile file)
            {
                        
                  Gtk.Application.Invoke( delegate
                  {
                        if(UIdToIter.ContainsKey(file.FileId))
                        {
                              TreeIter iter = (TreeIter)UIdToIter[file.FileId];
                              store.SetValue(iter,0,file);
                              try
                              {
                                    store.SetValue(piter,0,file.Parent);
                              }
                              catch(Exception e)
                              {
                                    Console.WriteLine(file.FileId.ToString());
                                    Console.WriteLine(e.ToString());
                              }
                              
                        }
                  });
            }
                  
            public static string FormatSize(long lSizeInBytes, int iDecimals)
            {
                  return Gnome.Vfs.Format.FileSizeForDisplay(lSizeInBytes);
            }
            
            public static string FormatETA(int seconds)
            {
                  TimeSpan span = new TimeSpan(0,0,seconds);
                  return span.ToString();
            }
            
            public static string FormatTimeElapsed(DateTime startTime)
            {
                  
                  TimeSpan span = DateTime.Now.Subtract(startTime);
                  if(span.Milliseconds > 0)
                        return span.ToString().Remove(span.ToString().LastIndexOf('.'));
                  else
                        return span.ToString();
            }
            
            public static string FormatTime(TimeSpan span)
            {
                  string s = span.ToString();
                  return s.Substring(0,8);
                  /*
                  if(span.Milliseconds > 0)
                        return span.ToString().Remove(span.ToString().LastIndexOf('.'));
                  else
                        return span.ToString();
                  */
            }
            
            protected override bool OnButtonPressEvent (Gdk.EventButton evnt)
      {
                  base.OnButtonPressEvent(evnt);
                  
            if(evnt.Button == 3)
                  {
                        
                        List<XferFile> files = new List<XferFile>();
                        TreeIter iter;
                        XferFile next = null;
                        XferFile prev = null;
                        
                if (this.Selection.GetSelected (out iter))
                {
                              
                    files.Add((XferFile) store.GetValue (iter, 0));
                              
                              Gtk.TreePath tmppath = store.GetPath(iter);
                              tmppath.Prev();
                              Gtk.TreeIter previter;
                              if(store.GetIter(out previter, tmppath))
                                    prev = store.GetValue(previter, 0) as XferFile;
                              
                              tmppath.Next();
                              tmppath.Next();
                              
                              if(store.GetIter(out previter, tmppath))
                                    next = store.GetValue(previter, 0) as XferFile;
                              
                        
                  menu = new ProgressListContextMenu(files[0], prev, next);
                  
                        menu.Popup();
                        menu.ShowAll();

                        
                        menu.SkipRequested += delegate {
                              files[0].Status = DownloadStatus.Skipped;
                              UpdateProgress(files[0]);
                        };
                        
                        menu.AbortRequested += delegate {
                              
                              //files[0].Status = DownloadStatus.Aborted;
                              XferFileAbort.Invoke(files[0], null);
                        };
                        
                        menu.MoveUpRequested += delegate {
                              Gtk.TreePath path = store.GetPath(iter);
                              path.Prev();
                              Gtk.TreeIter iter2;
                              store.GetIter(out iter2, path);
                              Gtk.Application.Invoke( delegate {
                                    XferFileReordered(this, new XferFileReorderedArgs((XferFile)store.GetValue(iter,0), 0));
                                    store.Swap(iter, iter2);
                              });
                        };
                        
                        menu.MoveDownRequested += delegate {
                              Gtk.TreePath path = store.GetPath(iter);
                              path.Next();
                              Gtk.TreeIter iter2;
                              store.GetIter(out iter2, path);
                              Gtk.Application.Invoke( delegate {
                                    XferFileReordered(this, new XferFileReorderedArgs((XferFile)store.GetValue(iter,0), 1));
                                    store.Swap(iter, iter2);
                              });
                        };
                        
                        //return true;
                        }
                  }
                  
            return base.OnButtonPressEvent(evnt);
      }
      }
      
      public class XferFileReorderedArgs : EventArgs
      {
            XferFile file;
            int direction; // 0 = up, 1 = down;
            public XferFileReorderedArgs(XferFile file, int direction)
            {
                  this.file = file;
                  this.direction = direction;
            }
            
            public XferFile File
            {
                  get { return file; }
            }
            public int Direction
            {
                  get { return direction; }
            }
      }
      
}

Generated by  Doxygen 1.6.0   Back to index