/*
* 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.Managers;
using DCSharp.Backend.Objects;
using DCSharp.Settings;
using DCSharp.Xml.FileList;
namespace DCSharp.GUI{
public class PreferencesWindow : GladeWindow
{
private IRuntimeSettings settings;
private IConnectionSettings connectionSettings;
private ShareManager shareManager;
private uint timeout;
[Widget]
private Button closeButton;
// General
[Widget]
private Entry nicknameEntry;
[Widget]
private Entry emailEntry;
[Widget]
private Entry descriptionEntry;
[Widget]
private ComboBox connectionTypeComboBox;
[Widget]
private RadioButton activeConnectionButton;
[Widget]
private Table activeConnectionTable;
[Widget]
private Entry ipEntry;
[Widget]
private SpinButton portSpinButton;
[Widget]
private Button applyButton;
// Downloads
[Widget]
private FileChooserButton downloadDirectoryButton;
// Sharing
private ListStore shareStore;
[Widget]
private SpinButton uploadSlotsSpinButton;
[Widget]
private TreeView shareTreeView;
[Widget]
private Button addShareButton;
[Widget]
private Button removeShareButton;
[Widget]
private Button refreshShareButton;
[Widget]
private Box shareSizeBox;
[Widget]
private Label shareSizeLabel;
[Widget]
private Box loadingBox;
[Widget]
private ProgressBar shareProgressBar;
#region Constructors
public PreferencesWindow(IRuntimeSettings settings, IConnectionSettings connectionSettings,
ShareManager shareManager, Window parent) :
base("PreferencesWindow.glade", parent)
{
if (settings == null)
{
throw new ArgumentNullException("settings");
}
if (connectionSettings == null)
{
throw new ArgumentNullException("connectionSettings");
}
if (shareManager == null)
{
throw new ArgumentNullException("shareManager");
}
this.settings = settings;
this.connectionSettings = connectionSettings;
this.shareManager = shareManager;
Window.Title = String.Format(Catalog.GetString("{0} Preferences"),
DCSharp.Extras.Util.AppName);
Initialize();
ConnectSignals();
}
#endregion
#region Methods
public override void Destroy()
{
if (timeout != 0)
{
GLib.Source.Remove(timeout);
timeout = 0;
}
base.Destroy();
}
private void Initialize()
{
// General
LocalIdentity localUser = settings.LocalIdentity;
Util.SetText(nicknameEntry, localUser.Nick);
Util.SetText(emailEntry, localUser.Email);
Util.SetText(descriptionEntry, localUser.Description);
connectionTypeComboBox.Active = 0;
TreeIter iter;
TreeModel model = connectionTypeComboBox.Model;
if (model.GetIterFirst(out iter))
{
do
{
string connection = (string)model.GetValue(iter, 0);
if (connection == localUser.Connection)
{
connectionTypeComboBox.SetActiveIter(iter);
break;
}
}
while (model.IterNext(ref iter));
}
activeConnectionButton.Active = connectionSettings.SupportsIncoming;
Util.SetText(ipEntry, connectionSettings.Address);
portSpinButton.Value = connectionSettings.Port;
activeConnectionTable.Sensitive = activeConnectionButton.Active;
// Downloads
downloadDirectoryButton.SetCurrentFolder(settings.DownloadDirectory);
// Sharing
shareStore = new ListStore(typeof(string), typeof(string));
shareTreeView.Model = shareStore;
TreeViewColumn column;
CellRendererText renderer;
renderer = new CellRendererText();
renderer.Editable = true;
renderer.Edited += OnVirtualNameEdited;
column = shareTreeView.AppendColumn(Catalog.GetString("Name"),
renderer, "text", 0);
column.SortColumnId = 0;
renderer = new CellRendererText();
renderer.Ellipsize = Pango.EllipsizeMode.End;
column = shareTreeView.AppendColumn(Catalog.GetString("Directory"),
renderer, "text", 1);
column.SortColumnId = 1;
removeShareButton.Sensitive = false;
uploadSlotsSpinButton.Value = settings.Slots;
lock (shareManager.SyncRoot)
{
foreach (ShareInfo shared in shareManager)
{
shareStore.AppendValues(shared.VirtualName, shared.Path);
}
shareManager.DirectoryAdded += OnDirectoryAdded;
shareManager.DirectoryRemoved += OnDirectoryRemoved;
shareManager.DirectoryRenamed += OnDirectoryRenamed;
}
RefreshShare();
}
private void ConnectSignals()
{
LocalIdentity localUser = settings.LocalIdentity;
// General
nicknameEntry.FocusOutEvent += delegate
{
if (nicknameEntry.Text.Length > 0)
{
localUser.Nick = nicknameEntry.Text;
}
else
{
nicknameEntry.Text = localUser.Nick;
}
};
emailEntry.FocusOutEvent += delegate
{
localUser.Email = emailEntry.Text;
};
descriptionEntry.FocusOutEvent += delegate
{
localUser.Description = descriptionEntry.Text;
};
connectionTypeComboBox.Changed += delegate
{
localUser.Connection = connectionTypeComboBox.ActiveText;
};
activeConnectionButton.Toggled += delegate
{
activeConnectionTable.Sensitive = activeConnectionButton.Active;
UpdateSensitivity();
};
ipEntry.Changed += delegate
{
UpdateSensitivity();
};
portSpinButton.ValueChanged += delegate
{
UpdateSensitivity();
};
applyButton.Clicked += OnApplyButtonClicked;
// Downloads
downloadDirectoryButton.CurrentFolderChanged += delegate
{
settings.DownloadDirectory = downloadDirectoryButton.Filename;
settings.TempDownloadDirectory = downloadDirectoryButton.Filename;
};
// Sharing
shareTreeView.Selection.Changed += OnSelectionChanged;
addShareButton.Clicked += OnAddShareButtonClicked;
removeShareButton.Clicked += OnRemoveShareButtonClicked;
refreshShareButton.Clicked += OnRefreshShareButtonClicked;
uploadSlotsSpinButton.ValueChanged += delegate
{
settings.Slots = uploadSlotsSpinButton.ValueAsInt;
};
closeButton.Clicked += OnCloseButtonClicked;
}
private void RefreshShare()
{
shareSizeBox.Visible = true;
loadingBox.Visible = false;
refreshShareButton.Sensitive = shareStore.IterNChildren() > 0;
long total = shareManager.Total;
long remaining = shareManager.BytesRemaining;
long hashed = total - remaining;
if (remaining > 0)
{
if (hashed < total && total > 0 && hashed > 0)
{
shareSizeBox.Visible = false;
loadingBox.Visible = true;
shareProgressBar.Fraction = (double)hashed / total;
shareProgressBar.Text = String.Format(Catalog.GetString("{0} of {1}"),
Util.FormatFileSize(hashed), Util.FormatFileSize(total));
}
else
{
shareSizeLabel.Text = Util.FormatFileSize(total);
}
if (timeout == 0)
{
timeout = GLib.Timeout.Add(500, OnRefreshTimeout);
}
}
else
{
shareSizeLabel.Text = Util.FormatFileSize(total);
if (timeout != 0)
{
GLib.Source.Remove(timeout);
timeout = 0;
}
}
}
private void UpdateSensitivity()
{
bool active = connectionSettings.SupportsIncoming;
if (active != activeConnectionButton.Active ||
(active &&
(connectionSettings.Address != ipEntry.Text ||
connectionSettings.Port != portSpinButton.ValueAsInt)))
{
applyButton.Sensitive = true;
return;
}
applyButton.Sensitive = false;
}
private void OnApplyButtonClicked(object obj, EventArgs args)
{
bool active = connectionSettings.SupportsIncoming;
string ip = connectionSettings.Address;
int port = connectionSettings.Port;
connectionSettings.SupportsIncoming = activeConnectionButton.Active;
connectionSettings.Address = ipEntry.Text;
connectionSettings.Port = portSpinButton.ValueAsInt;
if (!Runtime.StartServers())
{
// Restore settings
connectionSettings.SupportsIncoming = active;
connectionSettings.Address = ip;
connectionSettings.Port = port;
}
UpdateSensitivity();
}
private void OnCloseButtonClicked(object obj, EventArgs args)
{
Destroy();
}
private void OnAddShareButtonClicked(object obj, EventArgs args)
{
FileChooserDialog chooser = new FileChooserDialog(
Catalog.GetString("Select Folder"),
Window, FileChooserAction.SelectFolder,
Stock.Cancel, ResponseType.Cancel,
Stock.Open, ResponseType.Accept);
if (chooser.Run() == (int)ResponseType.Accept)
{
string filename = chooser.Filename;
char[] chars = {System.IO.Path.DirectorySeparatorChar,
System.IO.Path.AltDirectorySeparatorChar};
string[] dirs = filename.Split(chars);
string dirname = dirs[dirs.Length - 1];
string virtualName = dirname;
int i = 2;
while(true)
{
if(!shareManager.ContainsVirtualName(virtualName))
{
break;
}
virtualName = dirname + " " + i;
i++;
}
try
{
shareManager.AddDirectory(filename, virtualName);
}
catch
{
// TODO: Display error message.
}
}
chooser.Destroy();
}
private void OnRemoveShareButtonClicked(object obj, EventArgs args)
{
TreeIter iter;
if (shareTreeView.Selection.GetSelected(out iter))
{
string path = (string)shareStore.GetValue(iter, 1);
shareManager.RemoveDirectory(path);
}
}
private void OnRefreshShareButtonClicked(object obj, EventArgs args)
{
shareManager.Refresh();
RefreshShare();
}
private void OnVirtualNameEdited(object obj, EditedArgs args)
{
TreeIter iter;
if (shareStore.GetIter(out iter, new TreePath(args.Path)))
{
string name = (string)shareStore.GetValue(iter, 0);
string newName = args.NewText;
if (newName.Length > 0)
{
shareManager.RenameDirectory(name, newName);
}
}
}
private void OnSelectionChanged(object obj, EventArgs args)
{
TreeIter iter;
if (shareTreeView.Selection.GetSelected(out iter))
{
removeShareButton.Sensitive = true;
}
else
{
removeShareButton.Sensitive = false;
}
}
private bool OnRefreshTimeout()
{
RefreshShare();
return true;
}
private void OnDirectoryAdded(object obj, DirectoryEventArgs args)
{
Application.Invoke(delegate
{
shareStore.AppendValues(args.VirtualName, args.Path);
RefreshShare();
});
}
private void OnDirectoryRemoved(object obj, DirectoryEventArgs args)
{
Application.Invoke(delegate
{
TreeIter iter;
if (GetShareIter(args.Path, out iter))
{
shareStore.Remove(ref iter);
shareTreeView.ColumnsAutosize();
RefreshShare();
}
});
}
private void OnDirectoryRenamed(object obj, DirectoryRenamedEventArgs args)
{
Application.Invoke(delegate
{
TreeIter iter;
if (GetShareIter(args.Path, out iter))
{
shareStore.SetValue(iter, 0, args.VirtualName);
shareTreeView.ColumnsAutosize();
}
});
}
private bool GetShareIter(string path, out TreeIter retIter)
{
TreeIter iter;
if (shareStore.GetIterFirst(out iter))
{
do
{
string p = (string)shareStore.GetValue(iter, 1);
if (p == path)
{
retIter = iter;
return true;
}
}
while (shareStore.IterNext(ref iter));
}
retIter = TreeIter.Zero;
return false;
}
#endregion
}
}
|