/*
* Copyright (C) 2006-2007 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 Glade;
using Mono.Unix;
using DCSharp.Backend.Connections;
using DCSharp.Backend.Objects;
using DCSharp.Backend.Managers;
namespace DCSharp.GUI{
public class UploadPage : Page
{
private ConnectionManager connectionManager;
private UploadStore uploadStore;
private UploadView uploadView;
private VisibleColumnsWindow columnsWindow;
private List<UploadFileInfo> activeUploads;
private uint timeout;
[Widget]
private ScrolledWindow scrolledWindow;
[Widget]
private Button cancelButton;
[Widget]
private Button clearButton;
#region Constructors
public UploadPage(ConnectionManager connectionManager) : base("UploadPage.glade")
{
if (connectionManager == null)
{
throw new ArgumentNullException("connectionManager");
}
this.connectionManager = connectionManager;
uploadStore = new UploadStore();
uploadStore.SetSortColumnId((int)UploadStore.Column.Started,
SortType.Descending);
activeUploads = new List<UploadFileInfo>();
// User interface
ActionEntry[] entries = new ActionEntry[] {
new ActionEntry("VisibleColumns", null, Catalog.GetString("_Visible Columns..."), null,
Catalog.GetString("Edit visible columns"),
OnVisibleColumns),
};
actionGroup = new ActionGroup("UploadPageActions");
actionGroup.Add(entries);
// Upload view
uploadView = new UploadView(uploadStore);
uploadView.KeyPressEvent += OnViewKeyPressEvent;
uploadView.Selection.Changed += OnViewSelectionChanged;
uploadView.Show();
uploadView.GetColumn("Directory").Visible = false;
uploadView.GetColumn("Size").Visible = false;
scrolledWindow.Add(uploadView);
// Widgets
cancelButton.Clicked += OnCancelButtonClicked;
clearButton.Clicked += OnClearButtonClicked;
// Initialize
lock (connectionManager.SyncRoot)
{
foreach (UserConnection connection in connectionManager)
{
Monitor(connection);
}
connectionManager.ConnectionAdded += OnConnectionAdded;
connectionManager.ConnectionRemoved += OnConnectionRemoved;
}
}
#endregion
#region Properties
public override string Title
{
get { return Catalog.GetString("Uploads"); }
}
public override Gdk.Pixbuf Icon
{
get { return RenderIcon(Stock.GoUp, IconSize.Menu, null); }
}
public override string Tooltip
{
get { return Title; }
}
public override string Status
{
get { return null; }
}
public override ActionGroup Actions
{
get { return actionGroup; }
}
private ActionGroup actionGroup;
public int VisibleColumns
{
get { return Util.GetVisibleColumns(uploadView.Columns); }
set { Util.SetVisibleColumns(uploadView.Columns, value | 3); }
}
#endregion
#region Methods
public override void Dispose()
{
connectionManager.ConnectionAdded -= OnConnectionAdded;
connectionManager.ConnectionRemoved -= OnConnectionRemoved;
if (columnsWindow != null)
{
columnsWindow.Destroy();
columnsWindow = null;
}
base.Dispose();
}
private void Add(UploadFileInfo upload)
{
uploadStore.Add(upload);
upload.ActiveChanged += OnActiveChanged;
UpdateActive(upload);
UpdateSensitivity();
OnPageChanged();
}
private TreeIter Remove(UploadFileInfo upload)
{
upload.ActiveChanged -= OnActiveChanged;
activeUploads.Remove(upload);
return uploadStore.Remove(upload);
}
private void UpdateActive(UploadFileInfo upload)
{
if (upload.Active && !activeUploads.Contains(upload))
{
activeUploads.Add(upload);
if (timeout == 0)
{
timeout = GLib.Timeout.Add(1000, OnRefreshTimeout);
}
}
else if (!upload.Active)
{
activeUploads.Remove(upload);
}
}
private void Monitor(UserConnection connection)
{
connection.TransferStarted += OnTransferStarted;
connection.TransferCompleted += OnTransferCompleted;
UploadFileInfo upload = connection.Upload;
if (upload != null)
{
Add(upload);
}
}
private void StopMonitor(UserConnection connection)
{
connection.TransferStarted -= OnTransferStarted;
connection.TransferCompleted -= OnTransferCompleted;
}
private void UpdateSensitivity()
{
UpdateCancelButtonSensitivity();
UpdateClearButtonSensitivity();
}
private void UpdateCancelButtonSensitivity()
{
UploadFileInfo[] selectedUploads = uploadView.GetSelectedUploads(false);
foreach (UploadFileInfo upload in selectedUploads)
{
if (upload.Active)
{
cancelButton.Sensitive = true;
return;
}
}
cancelButton.Sensitive = false;
}
private void UpdateClearButtonSensitivity()
{
TreeIter iter;
if (uploadStore.GetIterFirst(out iter))
{
do
{
UploadFileInfo upload = (UploadFileInfo)uploadStore.GetValue(
iter, (int)UploadStore.Column.Object);
if (!upload.Active)
{
clearButton.Sensitive = true;
return;
}
}
while (uploadStore.IterNext(ref iter));
}
clearButton.Sensitive = false;
}
#region Event handlers
private void OnVisibleColumns(object obj, EventArgs args)
{
if (columnsWindow == null)
{
columnsWindow = new VisibleColumnsWindow(uploadView.Columns,
Toplevel as Window, uploadView.Columns[0],
uploadView.Columns[1]);
columnsWindow.Window.Destroyed += delegate
{
columnsWindow = null;
};
}
columnsWindow.Show();
}
private void OnViewKeyPressEvent(object obj, KeyPressEventArgs args)
{
if (args.Event.Key == Gdk.Key.Delete)
{
OnCancelButtonClicked(this, null);
UploadFileInfo[] selectedUploads = uploadView.GetSelectedUploads(false);
foreach (UploadFileInfo upload in selectedUploads)
{
Remove(upload);
}
UpdateSensitivity();
}
}
private void OnViewSelectionChanged(object obj, EventArgs args)
{
UpdateCancelButtonSensitivity();
}
private void OnCancelButtonClicked(object obj, EventArgs args)
{
UploadFileInfo[] selectedUploads = uploadView.GetSelectedUploads(false);
foreach (UploadFileInfo upload in selectedUploads)
{
UserConnection connection = upload.UserConnection;
if (connection != null)
{
connection.Disconnect();
}
}
}
private void OnClearButtonClicked(object obj, EventArgs args)
{
TreeIter iter;
if (uploadStore.GetIterFirst(out iter))
{
do
{
UploadFileInfo upload = (UploadFileInfo)uploadStore.GetValue(
iter, (int)UploadStore.Column.Object);
if (!upload.Active)
{
iter = Remove(upload);
continue;
}
uploadStore.IterNext(ref iter);
}
while (uploadStore.IterIsValid(iter));
}
UpdateSensitivity();
}
private bool OnRefreshTimeout()
{
if (activeUploads.Count > 0)
{
foreach (UploadFileInfo upload in activeUploads)
{
uploadStore.Update(upload);
}
return true;
}
timeout = 0;
return false;
}
#region External
private void OnConnectionAdded(object obj, ConnectionEventArgs args)
{
Application.Invoke(delegate
{
Monitor((UserConnection)args.Connection);
});
}
private void OnConnectionRemoved(object obj, ConnectionEventArgs args)
{
Application.Invoke(delegate
{
StopMonitor((UserConnection)args.Connection);
});
}
private void OnTransferStarted(object obj, TransferEventArgs args)
{
UploadFileInfo upload = args.Transfer as UploadFileInfo;
if (upload != null)
{
Application.Invoke(delegate
{
Add(upload);
});
}
}
private void OnTransferCompleted(object obj, TransferEventArgs args)
{
UploadFileInfo upload = args.Transfer as UploadFileInfo;
if (upload != null)
{
// Upload completed
OnActiveChanged(upload, args);
}
}
private void OnActiveChanged(object obj, EventArgs args)
{
UploadFileInfo upload = (UploadFileInfo)obj;
Application.Invoke(delegate
{
// Upload completed or an error occured
// Check Contains since the upload might have been removed after
// this timeout handler was added
if (uploadStore.Contains(upload))
{
uploadStore.Update(upload);
UpdateActive(upload);
UpdateSensitivity();
QueueDraw();
OnPageChanged();
}
});
}
#endregion
#endregion
#endregion
}
}
|