772 lines
22 KiB
C#
772 lines
22 KiB
C#
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||
|
// a copy of this software and associated documentation files (the
|
||
|
// "Software"), to deal in the Software without restriction, including
|
||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
||
|
// permit persons to whom the Software is furnished to do so, subject to
|
||
|
// the following conditions:
|
||
|
//
|
||
|
// The above copyright notice and this permission notice shall be
|
||
|
// included in all copies or substantial portions of the Software.
|
||
|
//
|
||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
//
|
||
|
// Copyright (c) 2006 Alexander Olk
|
||
|
//
|
||
|
// Authors:
|
||
|
// Alexander Olk (alex.olk@googlemail.com)
|
||
|
// Gert Driesen (drieseng@users.sourceforge.net)
|
||
|
//
|
||
|
//
|
||
|
|
||
|
using System;
|
||
|
using System.Drawing;
|
||
|
using System.ComponentModel;
|
||
|
using System.Resources;
|
||
|
using System.IO;
|
||
|
using System.Collections;
|
||
|
|
||
|
namespace System.Windows.Forms {
|
||
|
[DefaultEvent ("HelpRequest")]
|
||
|
[DefaultProperty ("SelectedPath")]
|
||
|
[Designer ("System.Windows.Forms.Design.FolderBrowserDialogDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
|
||
|
public sealed class FolderBrowserDialog : CommonDialog
|
||
|
{
|
||
|
#region Local Variables
|
||
|
private Environment.SpecialFolder rootFolder = Environment.SpecialFolder.Desktop;
|
||
|
private string selectedPath = string.Empty;
|
||
|
private bool showNewFolderButton = true;
|
||
|
|
||
|
private Label descriptionLabel;
|
||
|
private Button cancelButton;
|
||
|
private Button okButton;
|
||
|
private FolderBrowserTreeView folderBrowserTreeView;
|
||
|
private Button newFolderButton;
|
||
|
private ContextMenu folderBrowserTreeViewContextMenu;
|
||
|
private MenuItem newFolderMenuItem;
|
||
|
|
||
|
private string old_selectedPath = string.Empty;
|
||
|
|
||
|
private readonly string folderbrowserdialog_string = "FolderBrowserDialog";
|
||
|
private readonly string width_string = "Width";
|
||
|
private readonly string height_string = "Height";
|
||
|
private readonly string x_string = "X";
|
||
|
private readonly string y_string = "Y";
|
||
|
#endregion // Local Variables
|
||
|
|
||
|
#region Public Constructors
|
||
|
public FolderBrowserDialog ()
|
||
|
{
|
||
|
form = new DialogForm (this);
|
||
|
Size formConfigSize = Size.Empty;
|
||
|
Point formConfigLocation = Point.Empty;
|
||
|
|
||
|
object formWidth = MWFConfig.GetValue (folderbrowserdialog_string, width_string);
|
||
|
|
||
|
object formHeight = MWFConfig.GetValue (folderbrowserdialog_string, height_string);
|
||
|
|
||
|
if (formHeight != null && formWidth != null)
|
||
|
formConfigSize = new Size ((int)formWidth, (int)formHeight);
|
||
|
|
||
|
object formLocationX = MWFConfig.GetValue (folderbrowserdialog_string, x_string);
|
||
|
object formLocationY = MWFConfig.GetValue (folderbrowserdialog_string, y_string);
|
||
|
|
||
|
if (formLocationX != null && formLocationY != null)
|
||
|
formConfigLocation = new Point ((int)formLocationX, (int)formLocationY);
|
||
|
|
||
|
newFolderButton = new Button ();
|
||
|
folderBrowserTreeView = new FolderBrowserTreeView (this);
|
||
|
okButton = new Button ();
|
||
|
cancelButton = new Button ();
|
||
|
descriptionLabel = new Label ();
|
||
|
folderBrowserTreeViewContextMenu = new ContextMenu ();
|
||
|
|
||
|
form.AcceptButton = okButton;
|
||
|
form.CancelButton = cancelButton;
|
||
|
|
||
|
form.SuspendLayout ();
|
||
|
form.ClientSize = new Size (322, 324);
|
||
|
form.MinimumSize = new Size (310, 254);
|
||
|
form.Text = "Browse For Folder";
|
||
|
form.SizeGripStyle = SizeGripStyle.Show;
|
||
|
|
||
|
newFolderMenuItem = new MenuItem("New Folder", new EventHandler (OnClickNewFolderButton));
|
||
|
folderBrowserTreeViewContextMenu.MenuItems.Add(newFolderMenuItem);
|
||
|
|
||
|
// descriptionLabel
|
||
|
descriptionLabel.Anchor = ((AnchorStyles)(((AnchorStyles.Top | AnchorStyles.Left)
|
||
|
| AnchorStyles.Right)));
|
||
|
descriptionLabel.Location = new Point (15, 14);
|
||
|
descriptionLabel.Size = new Size (292, 40);
|
||
|
descriptionLabel.TabIndex = 0;
|
||
|
descriptionLabel.Text = string.Empty;
|
||
|
|
||
|
// folderBrowserTreeView
|
||
|
folderBrowserTreeView.Anchor = ((AnchorStyles)((((AnchorStyles.Top | AnchorStyles.Bottom)
|
||
|
| AnchorStyles.Left)
|
||
|
| AnchorStyles.Right)));
|
||
|
folderBrowserTreeView.ImageIndex = -1;
|
||
|
folderBrowserTreeView.Location = new Point (15, 60);
|
||
|
folderBrowserTreeView.SelectedImageIndex = -1;
|
||
|
folderBrowserTreeView.Size = new Size (292, 212);
|
||
|
folderBrowserTreeView.TabIndex = 3;
|
||
|
folderBrowserTreeView.ShowLines = false;
|
||
|
folderBrowserTreeView.ShowPlusMinus = true;
|
||
|
folderBrowserTreeView.HotTracking = true;
|
||
|
folderBrowserTreeView.BorderStyle = BorderStyle.Fixed3D;
|
||
|
folderBrowserTreeView.ContextMenu = folderBrowserTreeViewContextMenu;
|
||
|
//folderBrowserTreeView.Indent = 2;
|
||
|
|
||
|
// newFolderButton
|
||
|
newFolderButton.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Left)));
|
||
|
newFolderButton.FlatStyle = FlatStyle.System;
|
||
|
newFolderButton.Location = new Point (15, 285);
|
||
|
newFolderButton.Size = new Size (105, 23);
|
||
|
newFolderButton.TabIndex = 4;
|
||
|
newFolderButton.Text = "Make New Folder";
|
||
|
newFolderButton.Enabled = true;
|
||
|
|
||
|
// okButton
|
||
|
okButton.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Right)));
|
||
|
okButton.FlatStyle = FlatStyle.System;
|
||
|
okButton.Location = new Point (135, 285);
|
||
|
okButton.Size = new Size (80, 23);
|
||
|
okButton.TabIndex = 1;
|
||
|
okButton.Text = "OK";
|
||
|
|
||
|
// cancelButton
|
||
|
cancelButton.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Right)));
|
||
|
cancelButton.DialogResult = DialogResult.Cancel;
|
||
|
cancelButton.FlatStyle = FlatStyle.System;
|
||
|
cancelButton.Location = new Point (227, 285);
|
||
|
cancelButton.Size = new Size (80, 23);
|
||
|
cancelButton.TabIndex = 2;
|
||
|
cancelButton.Text = "Cancel";
|
||
|
|
||
|
form.Controls.Add (cancelButton);
|
||
|
form.Controls.Add (okButton);
|
||
|
form.Controls.Add (newFolderButton);
|
||
|
form.Controls.Add (folderBrowserTreeView);
|
||
|
form.Controls.Add (descriptionLabel);
|
||
|
|
||
|
form.ResumeLayout (false);
|
||
|
|
||
|
if (formConfigSize != Size.Empty) {
|
||
|
form.Size = formConfigSize;
|
||
|
}
|
||
|
|
||
|
if (formConfigLocation != Point.Empty) {
|
||
|
form.Location = formConfigLocation;
|
||
|
}
|
||
|
|
||
|
okButton.Click += new EventHandler (OnClickOKButton);
|
||
|
cancelButton.Click += new EventHandler (OnClickCancelButton);
|
||
|
newFolderButton.Click += new EventHandler (OnClickNewFolderButton);
|
||
|
|
||
|
form.VisibleChanged += new EventHandler (OnFormVisibleChanged);
|
||
|
|
||
|
RootFolder = rootFolder;
|
||
|
}
|
||
|
|
||
|
#endregion // Public Constructors
|
||
|
|
||
|
#region Public Instance Properties
|
||
|
[Browsable(true)]
|
||
|
[DefaultValue("")]
|
||
|
[Localizable(true)]
|
||
|
public string Description {
|
||
|
set {
|
||
|
descriptionLabel.Text = value;
|
||
|
}
|
||
|
|
||
|
get {
|
||
|
return descriptionLabel.Text;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Browsable(true)]
|
||
|
[DefaultValue(Environment.SpecialFolder.Desktop)]
|
||
|
[Localizable(false)]
|
||
|
[TypeConverter (typeof (SpecialFolderEnumConverter))]
|
||
|
public Environment.SpecialFolder RootFolder {
|
||
|
set {
|
||
|
int v = (int)value;
|
||
|
|
||
|
Type enumType = typeof (Environment.SpecialFolder);
|
||
|
if (!Enum.IsDefined (enumType, v))
|
||
|
throw new InvalidEnumArgumentException (
|
||
|
"value", v, enumType);
|
||
|
|
||
|
rootFolder = value;
|
||
|
}
|
||
|
get {
|
||
|
return rootFolder;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Browsable(true)]
|
||
|
[DefaultValue("")]
|
||
|
[Editor("System.Windows.Forms.Design.SelectedPathEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
|
||
|
[Localizable(true)]
|
||
|
public string SelectedPath {
|
||
|
set {
|
||
|
if (value == null)
|
||
|
value = string.Empty;
|
||
|
selectedPath = value;
|
||
|
old_selectedPath = value;
|
||
|
}
|
||
|
get {
|
||
|
return selectedPath;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Browsable(true)]
|
||
|
[DefaultValue(true)]
|
||
|
[Localizable(false)]
|
||
|
public bool ShowNewFolderButton {
|
||
|
set {
|
||
|
if (value != showNewFolderButton) {
|
||
|
newFolderButton.Visible = value;
|
||
|
showNewFolderButton = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
get {
|
||
|
return showNewFolderButton;
|
||
|
}
|
||
|
}
|
||
|
#endregion // Public Instance Properties
|
||
|
|
||
|
#region Public Instance Methods
|
||
|
public override void Reset ()
|
||
|
{
|
||
|
Description = string.Empty;
|
||
|
RootFolder = Environment.SpecialFolder.Desktop;
|
||
|
selectedPath = string.Empty;
|
||
|
ShowNewFolderButton = true;
|
||
|
}
|
||
|
|
||
|
protected override bool RunDialog (IntPtr hWndOwner)
|
||
|
{
|
||
|
folderBrowserTreeView.RootFolder = RootFolder;
|
||
|
folderBrowserTreeView.SelectedPath = SelectedPath;
|
||
|
|
||
|
form.Refresh ();
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
#endregion // Public Instance Methods
|
||
|
|
||
|
#region Internal Methods
|
||
|
void OnClickOKButton (object sender, EventArgs e)
|
||
|
{
|
||
|
WriteConfigValues ();
|
||
|
|
||
|
form.DialogResult = DialogResult.OK;
|
||
|
}
|
||
|
|
||
|
void OnClickCancelButton (object sender, EventArgs e)
|
||
|
{
|
||
|
WriteConfigValues ();
|
||
|
|
||
|
selectedPath = old_selectedPath;
|
||
|
form.DialogResult = DialogResult.Cancel;
|
||
|
}
|
||
|
|
||
|
void OnClickNewFolderButton (object sender, EventArgs e)
|
||
|
{
|
||
|
folderBrowserTreeView.CreateNewFolder ();
|
||
|
}
|
||
|
|
||
|
void OnFormVisibleChanged (object sender, EventArgs e)
|
||
|
{
|
||
|
if (form.Visible && okButton.Enabled)
|
||
|
okButton.Select ();
|
||
|
}
|
||
|
|
||
|
private void WriteConfigValues ()
|
||
|
{
|
||
|
MWFConfig.SetValue (folderbrowserdialog_string, width_string, form.Width);
|
||
|
MWFConfig.SetValue (folderbrowserdialog_string, height_string, form.Height);
|
||
|
MWFConfig.SetValue (folderbrowserdialog_string, x_string, form.Location.X);
|
||
|
MWFConfig.SetValue (folderbrowserdialog_string, y_string, form.Location.Y);
|
||
|
}
|
||
|
#endregion // Internal Methods
|
||
|
|
||
|
#region Events
|
||
|
[Browsable(false)]
|
||
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||
|
public new event EventHandler HelpRequest {
|
||
|
add { base.HelpRequest += value; }
|
||
|
remove { base.HelpRequest -= value; }
|
||
|
}
|
||
|
#endregion
|
||
|
|
||
|
internal class FolderBrowserTreeView : TreeView
|
||
|
{
|
||
|
private MWFVFS vfs = new MWFVFS ();
|
||
|
new private FBTreeNode root_node;
|
||
|
private FolderBrowserDialog parentDialog;
|
||
|
private ImageList imageList = new ImageList ();
|
||
|
private Environment.SpecialFolder rootFolder;
|
||
|
private bool dont_enable = false;
|
||
|
private TreeNode node_under_mouse;
|
||
|
|
||
|
public FolderBrowserTreeView (FolderBrowserDialog parent_dialog)
|
||
|
{
|
||
|
parentDialog = parent_dialog;
|
||
|
HideSelection = false;
|
||
|
ImageList = imageList;
|
||
|
SetupImageList ();
|
||
|
}
|
||
|
|
||
|
public Environment.SpecialFolder RootFolder {
|
||
|
set {
|
||
|
rootFolder = value;
|
||
|
|
||
|
string root_path = string.Empty;
|
||
|
|
||
|
switch (rootFolder) {
|
||
|
case Environment.SpecialFolder.Desktop:
|
||
|
root_node = new FBTreeNode ("Desktop");
|
||
|
root_node.RealPath = ThemeEngine.Current.Places (UIIcon.PlacesDesktop);
|
||
|
root_path = MWFVFS.DesktopPrefix;
|
||
|
break;
|
||
|
case Environment.SpecialFolder.Recent:
|
||
|
root_node = new FBTreeNode ("My Recent Documents");
|
||
|
root_node.RealPath = ThemeEngine.Current.Places (UIIcon.PlacesRecentDocuments);
|
||
|
root_path = MWFVFS.RecentlyUsedPrefix;
|
||
|
break;
|
||
|
case Environment.SpecialFolder.MyComputer:
|
||
|
root_node = new FBTreeNode ("My Computer");
|
||
|
root_path = MWFVFS.MyComputerPrefix;
|
||
|
break;
|
||
|
case Environment.SpecialFolder.Personal:
|
||
|
root_node = new FBTreeNode ("Personal");
|
||
|
root_path = MWFVFS.PersonalPrefix;
|
||
|
root_node.RealPath = ThemeEngine.Current.Places (UIIcon.PlacesPersonal);
|
||
|
break;
|
||
|
default:
|
||
|
root_node = new FBTreeNode (rootFolder.ToString ());
|
||
|
root_node.RealPath = Environment.GetFolderPath (rootFolder);
|
||
|
root_path = root_node.RealPath;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
root_node.Tag = root_path;
|
||
|
root_node.ImageIndex = NodeImageIndex (root_path);
|
||
|
|
||
|
BeginUpdate ();
|
||
|
Nodes.Clear ();
|
||
|
EndUpdate ();
|
||
|
|
||
|
FillNode (root_node);
|
||
|
|
||
|
root_node.Expand ();
|
||
|
|
||
|
Nodes.Add (root_node);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public string SelectedPath {
|
||
|
set {
|
||
|
if (value.Length == 0)
|
||
|
return;
|
||
|
|
||
|
if (!Path.IsPathRooted (value))
|
||
|
return;
|
||
|
|
||
|
try {
|
||
|
if (Check_if_path_is_child_of_RootFolder (value))
|
||
|
SetSelectedPath (Path.GetFullPath (value));
|
||
|
} catch (Exception) {
|
||
|
// If we can't set the user's requested path, the
|
||
|
// best we can do is not crash and reset to the default
|
||
|
EndUpdate ();
|
||
|
RootFolder = rootFolder;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private string parent_real_path;
|
||
|
private bool dont_do_onbeforeexpand;
|
||
|
|
||
|
public void CreateNewFolder ()
|
||
|
{
|
||
|
FBTreeNode fbnode = node_under_mouse == null ? SelectedNode as FBTreeNode : node_under_mouse as FBTreeNode;
|
||
|
|
||
|
if (fbnode == null || fbnode.RealPath == null)
|
||
|
return;
|
||
|
|
||
|
string tmp_filename = "New Folder";
|
||
|
|
||
|
if (Directory.Exists (Path.Combine (fbnode.RealPath, tmp_filename))) {
|
||
|
int i = 1;
|
||
|
|
||
|
if (XplatUI.RunningOnUnix) {
|
||
|
tmp_filename = tmp_filename + "-" + i;
|
||
|
} else {
|
||
|
tmp_filename = tmp_filename + " (" + i + ")";
|
||
|
}
|
||
|
|
||
|
while (Directory.Exists (Path.Combine (fbnode.RealPath, tmp_filename))) {
|
||
|
i++;
|
||
|
if (XplatUI.RunningOnUnix) {
|
||
|
tmp_filename = "New Folder" + "-" + i;
|
||
|
} else {
|
||
|
tmp_filename = "New Folder" + " (" + i + ")";
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
parent_real_path = fbnode.RealPath;
|
||
|
|
||
|
FillNode (fbnode);
|
||
|
dont_do_onbeforeexpand = true;
|
||
|
fbnode.Expand ();
|
||
|
dont_do_onbeforeexpand = false;
|
||
|
|
||
|
// to match MS, immediately create the new folder
|
||
|
// and rename it once the label edit completes
|
||
|
string fullPath = Path.Combine (fbnode.RealPath, tmp_filename);
|
||
|
if (!vfs.CreateFolder (fullPath))
|
||
|
return;
|
||
|
|
||
|
FBTreeNode new_node = new FBTreeNode (tmp_filename);
|
||
|
new_node.ImageIndex = NodeImageIndex (tmp_filename);
|
||
|
new_node.Tag = new_node.RealPath = fullPath;
|
||
|
fbnode.Nodes.Add (new_node);
|
||
|
|
||
|
LabelEdit = true;
|
||
|
new_node.BeginEdit();
|
||
|
}
|
||
|
|
||
|
protected override void OnAfterLabelEdit (NodeLabelEditEventArgs e)
|
||
|
{
|
||
|
if (e.Label != null) {
|
||
|
if (e.Label.Length > 0) {
|
||
|
FBTreeNode fbnode = e.Node as FBTreeNode;
|
||
|
|
||
|
string originalPath = fbnode.RealPath;
|
||
|
string newPath = Path.Combine (parent_real_path, e.Label);
|
||
|
|
||
|
if (vfs.MoveFolder (originalPath, newPath)) {
|
||
|
fbnode.Tag = fbnode.RealPath = newPath;
|
||
|
} else {
|
||
|
e.CancelEdit = true;
|
||
|
e.Node.BeginEdit ();
|
||
|
return;
|
||
|
}
|
||
|
} else {
|
||
|
e.CancelEdit = true;
|
||
|
e.Node.BeginEdit ();
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// select new folder only if both the curren node under
|
||
|
// mouse pointer and SelectedNode are the same (match .Net)
|
||
|
if (node_under_mouse == SelectedNode)
|
||
|
SelectedNode = e.Node;
|
||
|
|
||
|
// disable LabelEdit when either edit has finished
|
||
|
// or has been cancelled, to prevent the user from
|
||
|
// editing label of existing folders
|
||
|
LabelEdit = false;
|
||
|
}
|
||
|
|
||
|
private void SetSelectedPath (string path)
|
||
|
{
|
||
|
BeginUpdate ();
|
||
|
|
||
|
FBTreeNode node = FindPathInNodes (path, Nodes);
|
||
|
|
||
|
if (node == null) {
|
||
|
Stack stack = new Stack ();
|
||
|
|
||
|
string path_cut = path.Substring (0, path.LastIndexOf (Path.DirectorySeparatorChar));
|
||
|
if (!XplatUI.RunningOnUnix && path_cut.Length == 2)
|
||
|
path_cut += Path.DirectorySeparatorChar;
|
||
|
|
||
|
while (node == null && path_cut.Length > 0) {
|
||
|
node = FindPathInNodes (path_cut, Nodes);
|
||
|
|
||
|
if (node == null) {
|
||
|
string path_cut_new = path_cut.Substring (0, path_cut.LastIndexOf (Path.DirectorySeparatorChar));
|
||
|
string leftover = path_cut.Replace (path_cut_new, string.Empty);
|
||
|
|
||
|
stack.Push (leftover);
|
||
|
|
||
|
path_cut = path_cut_new;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// If we didn't find anything, just display the full, unselected tree
|
||
|
if (node == null) {
|
||
|
EndUpdate ();
|
||
|
RootFolder = rootFolder;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
FillNode (node);
|
||
|
node.Expand ();
|
||
|
|
||
|
// walk through the subdirs and fill the nodes
|
||
|
while (stack.Count > 0) {
|
||
|
string part_name = stack.Pop () as string;
|
||
|
|
||
|
foreach (TreeNode treeNode in node.Nodes) {
|
||
|
FBTreeNode fbnode = treeNode as FBTreeNode;
|
||
|
|
||
|
if (path_cut + part_name == fbnode.RealPath) {
|
||
|
node = fbnode;
|
||
|
path_cut += part_name;
|
||
|
|
||
|
FillNode (node);
|
||
|
node.Expand ();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// finally find the node for the complete path
|
||
|
foreach (TreeNode treeNode in node.Nodes) {
|
||
|
FBTreeNode fbnode = treeNode as FBTreeNode;
|
||
|
|
||
|
if (path == fbnode.RealPath) {
|
||
|
node = fbnode;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (node != null) {
|
||
|
SelectedNode = node;
|
||
|
node.EnsureVisible ();
|
||
|
}
|
||
|
|
||
|
EndUpdate ();
|
||
|
}
|
||
|
|
||
|
private FBTreeNode FindPathInNodes (string path, TreeNodeCollection nodes)
|
||
|
{
|
||
|
// On Windows the devices can be passed as C: yet match
|
||
|
// the C:\ form
|
||
|
//
|
||
|
// Hackish, but works
|
||
|
if (!XplatUI.RunningOnUnix && path.Length == 2)
|
||
|
path += Path.DirectorySeparatorChar;
|
||
|
|
||
|
foreach (TreeNode node in nodes) {
|
||
|
FBTreeNode fbnode = node as FBTreeNode;
|
||
|
|
||
|
if (fbnode != null && fbnode.RealPath != null) {
|
||
|
if (fbnode.RealPath == path)
|
||
|
return fbnode;
|
||
|
}
|
||
|
|
||
|
FBTreeNode n = FindPathInNodes (path, node.Nodes);
|
||
|
if (n != null)
|
||
|
return n;
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
private bool Check_if_path_is_child_of_RootFolder (string path)
|
||
|
{
|
||
|
string root_path = (string) root_node.RealPath;
|
||
|
|
||
|
if (root_path != null || rootFolder == Environment.SpecialFolder.MyComputer) {
|
||
|
try {
|
||
|
if (!Directory.Exists (path))
|
||
|
return false;
|
||
|
|
||
|
switch (rootFolder) {
|
||
|
case Environment.SpecialFolder.Desktop:
|
||
|
case Environment.SpecialFolder.MyComputer:
|
||
|
return true;
|
||
|
case Environment.SpecialFolder.Personal:
|
||
|
if (!path.StartsWith (root_path))
|
||
|
return false;
|
||
|
else
|
||
|
return true;
|
||
|
default:
|
||
|
return false;
|
||
|
}
|
||
|
} catch {}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
private void FillNode (TreeNode node)
|
||
|
{
|
||
|
BeginUpdate ();
|
||
|
|
||
|
node.Nodes.Clear ();
|
||
|
vfs.ChangeDirectory ((string)node.Tag);
|
||
|
ArrayList folders = vfs.GetFoldersOnly ();
|
||
|
|
||
|
foreach (FSEntry fsentry in folders) {
|
||
|
if (fsentry.Name.StartsWith ("."))
|
||
|
continue;
|
||
|
|
||
|
FBTreeNode child = new FBTreeNode (fsentry.Name);
|
||
|
child.Tag = fsentry.FullName;
|
||
|
child.RealPath = fsentry.RealName == null ? fsentry.FullName : fsentry.RealName;
|
||
|
child.ImageIndex = NodeImageIndex (fsentry.FullName);
|
||
|
|
||
|
vfs.ChangeDirectory (fsentry.FullName);
|
||
|
ArrayList sub_folders = vfs.GetFoldersOnly ();
|
||
|
|
||
|
foreach (FSEntry fsentry_sub in sub_folders) {
|
||
|
if (!fsentry_sub.Name.StartsWith (".")) {
|
||
|
child.Nodes.Add (new TreeNode (String.Empty));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
node.Nodes.Add (child);
|
||
|
}
|
||
|
|
||
|
EndUpdate ();
|
||
|
}
|
||
|
|
||
|
private void SetupImageList ()
|
||
|
{
|
||
|
imageList.ColorDepth = ColorDepth.Depth32Bit;
|
||
|
imageList.ImageSize = new Size (16, 16);
|
||
|
imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.PlacesRecentDocuments, 16));
|
||
|
imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.PlacesDesktop, 16));
|
||
|
imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.PlacesPersonal, 16));
|
||
|
imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.PlacesMyComputer, 16));
|
||
|
imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.PlacesMyNetwork, 16));
|
||
|
imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.NormalFolder, 16));
|
||
|
imageList.TransparentColor = Color.Transparent;
|
||
|
}
|
||
|
|
||
|
private int NodeImageIndex (string path)
|
||
|
{
|
||
|
int index = 5;
|
||
|
|
||
|
if (path == MWFVFS.DesktopPrefix)
|
||
|
index = 1;
|
||
|
else if (path == MWFVFS.RecentlyUsedPrefix)
|
||
|
index = 0;
|
||
|
else if (path == MWFVFS.PersonalPrefix)
|
||
|
index = 2;
|
||
|
else if (path == MWFVFS.MyComputerPrefix)
|
||
|
index = 3;
|
||
|
else if (path == MWFVFS.MyNetworkPrefix)
|
||
|
index = 4;
|
||
|
|
||
|
return index;
|
||
|
}
|
||
|
|
||
|
protected override void OnAfterSelect (TreeViewEventArgs e)
|
||
|
{
|
||
|
if (e.Node == null)
|
||
|
return;
|
||
|
|
||
|
FBTreeNode fbnode = e.Node as FBTreeNode;
|
||
|
|
||
|
if (fbnode.RealPath == null || fbnode.RealPath.IndexOf ("://") != -1) {
|
||
|
parentDialog.okButton.Enabled = false;
|
||
|
parentDialog.newFolderButton.Enabled = false;
|
||
|
parentDialog.newFolderMenuItem.Enabled = false;
|
||
|
dont_enable = true;
|
||
|
} else {
|
||
|
parentDialog.okButton.Enabled = true;
|
||
|
parentDialog.newFolderButton.Enabled = true;
|
||
|
parentDialog.newFolderMenuItem.Enabled = true;
|
||
|
parentDialog.selectedPath = fbnode.RealPath;
|
||
|
dont_enable = false;
|
||
|
}
|
||
|
|
||
|
base.OnAfterSelect (e);
|
||
|
}
|
||
|
|
||
|
protected internal override void OnBeforeExpand (TreeViewCancelEventArgs e)
|
||
|
{
|
||
|
if (!dont_do_onbeforeexpand) {
|
||
|
if (e.Node == root_node)
|
||
|
return;
|
||
|
FillNode (e.Node);
|
||
|
}
|
||
|
|
||
|
base.OnBeforeExpand (e);
|
||
|
}
|
||
|
|
||
|
protected override void OnMouseDown (MouseEventArgs e)
|
||
|
{
|
||
|
node_under_mouse = GetNodeAt (e.X, e.Y);
|
||
|
base.OnMouseDown (e);
|
||
|
}
|
||
|
|
||
|
protected override void OnMouseUp (MouseEventArgs e)
|
||
|
{
|
||
|
if (SelectedNode == null) {
|
||
|
parentDialog.okButton.Enabled = false;
|
||
|
parentDialog.newFolderButton.Enabled = false;
|
||
|
parentDialog.newFolderMenuItem.Enabled = false;
|
||
|
} else
|
||
|
if (!dont_enable) {
|
||
|
parentDialog.okButton.Enabled = true;
|
||
|
parentDialog.newFolderButton.Enabled = true;
|
||
|
parentDialog.newFolderMenuItem.Enabled = true;
|
||
|
}
|
||
|
|
||
|
node_under_mouse = null;
|
||
|
|
||
|
base.OnMouseUp (e);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal class FBTreeNode : TreeNode
|
||
|
{
|
||
|
private string realPath = null;
|
||
|
|
||
|
public FBTreeNode (string text)
|
||
|
{
|
||
|
Text = text;
|
||
|
}
|
||
|
|
||
|
public string RealPath {
|
||
|
set {
|
||
|
realPath = value;
|
||
|
}
|
||
|
|
||
|
get {
|
||
|
return realPath;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal class SpecialFolderEnumConverter : TypeConverter
|
||
|
{
|
||
|
public override object ConvertFrom (ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
|
||
|
{
|
||
|
if ((value == null) || !(value is String))
|
||
|
return base.ConvertFrom (context, culture, value);
|
||
|
|
||
|
return Enum.Parse (typeof (Environment.SpecialFolder), (string)value, true);
|
||
|
}
|
||
|
|
||
|
public override object ConvertTo (ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
|
||
|
{
|
||
|
if ((value == null) || !(value is Environment.SpecialFolder) || (destinationType != typeof (string)))
|
||
|
return base.ConvertTo (context, culture, value, destinationType);
|
||
|
|
||
|
return ((Environment.SpecialFolder)value).ToString ();
|
||
|
}
|
||
|
}
|
||
|
}
|