/*
* Copyright (C) 2006 Eskil Bylund
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections.Generic;
using Gtk;
using Mono.Unix;
using DCSharp.Backend.Managers;
using DCSharp.Backend.Objects;
using DCSharp.Xml;
namespace DCSharp.GUI{
public class DownloadStore : TreeStore
{
private Dictionary<string, TreeIter> directories;
private Dictionary<DownloadFileInfo, TreeIter> downloads;
public enum Column {
Object,
Name,
Path,
Size,
Bytes,
DownloadedBytes,
Downloaded,
Progress,
TimeLeft,
Loaded
};
public DownloadStore() : base(typeof(object), typeof(string),
typeof(string), typeof(string), typeof(double), typeof(double),
typeof(string), typeof(int), typeof(string), typeof(bool))
{
directories = new Dictionary<string, TreeIter>();
downloads = new Dictionary<DownloadFileInfo, TreeIter>();
}
#region Methods
public void Add(DownloadFileInfo download)
{
if (downloads.ContainsKey(download))
{
return;
}
TreeIter parent = CreateDirectoryTree(download.Target);
TreeIter iter = AppendValues(parent, download, download.Name);
downloads.Add(download, iter);
UpdateDownload(download, iter);
UpdateParents(parent);
}
public void Remove(DownloadFileInfo download)
{
if (!downloads.ContainsKey(download))
{
return;
}
TreeIter iter = downloads[download];
downloads.Remove(download);
TreeIter parent;
if (IterParent(out parent, iter))
{
Remove(ref iter);
UpdateParents(parent);
RemoveEmptyDirectories(parent);
}
else
{
Remove(ref iter);
}
}
public bool Contains(DownloadFileInfo download)
{
return downloads.ContainsKey(download);
}
public TreeIter GetIter(DownloadFileInfo download)
{
return downloads[download];
}
private TreeIter CreateDirectoryTree(string path)
{
string root;
string name;
if (path == Runtime.Settings.DownloadDirectory ||
path.StartsWith(Runtime.Settings.DownloadDirectory))
{
root = Runtime.Settings.DownloadDirectory;
name = Catalog.GetString("Download folder");
}
else
{
root = System.IO.Path.GetPathRoot(path);
if (root == "/")
{
name = Catalog.GetString("Filesystem");
}
else
{
name = root;
}
}
if (root != null)
{
if (!directories.ContainsKey(root))
{
TreeIter iter = AppendValues(null, name, root);
directories.Add(root, iter);
}
path = path.Substring(root.Length);
if (path == null)
{
return directories[root];
}
}
string parent = root;
string[] dirs = path.Split(System.IO.Path.DirectorySeparatorChar);
foreach (string dir in dirs)
{
path = System.IO.Path.Combine(parent, dir);
if (!directories.ContainsKey(path))
{
if (parent != null)
{
TreeIter parentIter = directories[parent];
TreeIter iter = AppendValues(parentIter, null, dir, path);
directories.Add(path, iter);
}
else
{
TreeIter iter = AppendValues(null, dir, path);
directories.Add(path, iter);
}
}
parent = path;
}
return directories[path];
}
private void RemoveEmptyDirectories(TreeIter iter)
{
if (!IterHasChild(iter))
{
string path = GetValue(iter, (int)Column.Path) as string;
directories.Remove(path);
TreeIter parent;
if (IterParent(out parent, iter))
{
Remove(ref iter);
RemoveEmptyDirectories(parent);
}
else
{
Remove(ref iter);
}
}
}
public void UpdateDownload(DownloadFileInfo download)
{
if (downloads.ContainsKey(download))
{
UpdateDownload(download, downloads[download]);
}
}
public void UpdateDownload(TreeIter iter)
{
DownloadFileInfo download = GetValue(iter,
(int)Column.Object) as DownloadFileInfo;
if (download != null)
{
UpdateDownload(download, iter);
}
}
private void UpdateDownload(DownloadFileInfo download, TreeIter iter)
{
if (download != null)
{
SetValue(iter, (int)Column.Name, download.Name);
SetValue(iter, (int)Column.Size, Util.FormatFileSize(download.Size));
SetValue(iter, (int)Column.Bytes, (double)download.Size);
SetValue(iter, (int)Column.DownloadedBytes,
(double)download.Position);
// Progress
int progress = (int)(((double)download.Position / download.Size) * 100);
SetValue(iter, (int)Column.Progress, progress);
// Downloaded
string downloaded = String.Format(Catalog.GetString("{0} of {1}"),
Util.FormatFileSize(download.Position),
Util.FormatFileSize(download.Size));
SetValue(iter, (int)Column.Downloaded, " " + downloaded + " ");
// Time left
if (download.Active && download.Bps > 0)
{
TimeSpan remaining = download.GetRemainingTime();
SetValue(iter, (int)Column.TimeLeft, remaining.ToString());
}
else
{
SetValue(iter, (int)Column.TimeLeft, null);
}
}
}
public void UpdateDirectory(TreeIter iter)
{
string path = (string)GetValue(iter, (int)Column.Path);
if (path != null)
{
// It's a directory
double bytes = 0;
double downloadedBytes = 0;
TreeIter childIter;
if (IterChildren(out childIter, iter))
{
do
{
bytes += (double)GetValue(childIter, (int)Column.Bytes);
downloadedBytes += (double)GetValue(childIter,
(int)Column.DownloadedBytes);
}
while (IterNext(ref childIter));
}
int children = IterNChildren(iter);
SetValue(iter, (int)Column.Size, String.Format(
Catalog.GetPluralString("{0} object", "{0} objects", children),
children));
SetValue(iter, (int)Column.Bytes, bytes);
SetValue(iter, (int)Column.DownloadedBytes, downloadedBytes);
SetValue(iter, (int)Column.Progress, (int)((downloadedBytes / bytes) * 100));
// Downloaded
string downloaded = String.Format(Catalog.GetString("{0} of {1}"),
Util.FormatFileSize((long)downloadedBytes),
Util.FormatFileSize((long)bytes));
SetValue(iter, (int)Column.Downloaded, " " + downloaded + " ");
}
}
private void UpdateParents(TreeIter iter)
{
do
{
UpdateDirectory(iter);
}
while (IterParent(out iter, iter));
}
#endregion
}
}
|