diff options
Diffstat (limited to 'mcs/class/Managed.Windows.Forms/System.Windows.Forms/FileDialog.cs')
-rw-r--r-- | mcs/class/Managed.Windows.Forms/System.Windows.Forms/FileDialog.cs | 2773 |
1 files changed, 2773 insertions, 0 deletions
diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/FileDialog.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/FileDialog.cs new file mode 100644 index 00000000000..8a5f07f6bdd --- /dev/null +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/FileDialog.cs @@ -0,0 +1,2773 @@ +// 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) 2004-2006 Novell, Inc. (http://www.novell.com) +// +// Authors: +// +// Alexander Olk xenomorph2@onlinehome.de +// + +// NOT COMPLETE - work in progress + +using System; +using System.Drawing; +using System.ComponentModel; +using System.Resources; +using System.IO; +using System.Collections; +using System.Collections.Specialized; +using System.Xml; + +namespace System.Windows.Forms { + [DefaultProperty ("FileName")] + [DefaultEvent ("FileOk")] + public abstract class FileDialog : CommonDialog { + protected static readonly object EventFileOk = new object (); + + internal enum FileDialogType { + OpenFileDialog, + SaveFileDialog + } + + private bool addExtension = true; + private bool checkFileExists = false; + private bool checkPathExists = true; + private string defaultExt = ""; + private bool dereferenceLinks = true; + private string fileName = ""; + private string[] fileNames; + private string filter; + private int filterIndex = 1; + private string initialDirectory = ""; + private bool restoreDirectory = false; + private bool showHelp = false; + private string title = ""; + private bool validateNames = true; + + private Button cancelButton; + private ToolBarButton upToolBarButton; + private PopupButtonPanel popupButtonPanel; + private Button openSaveButton; + private Button helpButton; + private Label fileTypeLabel; + private ToolBarButton menueToolBarButton; + private ContextMenu menueToolBarButtonContextMenu; + private ToolBar smallButtonToolBar; + private DirComboBox dirComboBox; + private ComboBox fileNameComboBox; + private Label fileNameLabel; + private MWFFileView mwfFileView; + private Label searchSaveLabel; + private ToolBarButton newdirToolBarButton; + private ToolBarButton backToolBarButton; + private ComboBox fileTypeComboBox; + private ImageList imageListTopToolbar; + private ContextMenu contextMenu; + private CheckBox readonlyCheckBox; + + private string currentDirectoryName; + private string currentFileName = ""; + // store current directoryInfo + private DirectoryInfo currentDirectoryInfo; + // store DirectoryInfo for backButton + private Stack directoryStack = new Stack(); + private MenuItem previousCheckedMenuItem; + private bool multiSelect = false; + + private string restoreDirectoryString = ""; + + private bool show_special_case = false; + + internal static readonly string recently_string = "[recently/recently]"; + internal static readonly string network_string = "[network/network]"; + internal static readonly string mycomputer_string = "[mycomputer/mycomputer]"; + + private string current_special_case; + + internal FileDialogType fileDialogType; + + private bool do_not_call_OnSelectedIndexChangedFileTypeComboBox = false; + + private bool showHiddenFiles = false; + + //protected bool readOnlyChecked = false; + + private bool showReadOnly = false; + private bool readOnlyChecked = false; + internal bool createPrompt = false; + internal bool overwritePrompt = true; + + internal FileFilter fileFilter; + + internal FileDialog () + { + fileTypeComboBox = new ComboBox (); + backToolBarButton = new ToolBarButton (); + newdirToolBarButton = new ToolBarButton (); + searchSaveLabel = new Label (); + mwfFileView = new MWFFileView (); + fileNameLabel = new Label (); + fileNameComboBox = new ComboBox (); + dirComboBox = new DirComboBox (); + smallButtonToolBar = new ToolBar (); + menueToolBarButton = new ToolBarButton (); + fileTypeLabel = new Label (); + openSaveButton = new Button (); + form.AcceptButton = openSaveButton; + helpButton = new Button (); + popupButtonPanel = new PopupButtonPanel (this); + upToolBarButton = new ToolBarButton (); + cancelButton = new Button (); + form.CancelButton = cancelButton; + imageListTopToolbar = new ImageList (); + menueToolBarButtonContextMenu = new ContextMenu (); + contextMenu = new ContextMenu (); + readonlyCheckBox = new CheckBox (); + + form.SuspendLayout (); + + //imageListTopToolbar + imageListTopToolbar.ColorDepth = ColorDepth.Depth32Bit; + imageListTopToolbar.ImageSize = new Size (16, 16); // 16, 16 + imageListTopToolbar.Images.Add ((Image)Locale.GetResource ("back_arrow")); + imageListTopToolbar.Images.Add ((Image)Locale.GetResource ("folder_arrow_up")); + imageListTopToolbar.Images.Add ((Image)Locale.GetResource ("folder_star")); + imageListTopToolbar.Images.Add ((Image)Locale.GetResource ("window")); + imageListTopToolbar.TransparentColor = Color.Transparent; + + // searchLabel + searchSaveLabel.FlatStyle = FlatStyle.System; + searchSaveLabel.Location = new Point (7, 8); + searchSaveLabel.Size = new Size (72, 21); + searchSaveLabel.TabIndex = 0; + searchSaveLabel.TextAlign = ContentAlignment.MiddleRight; + + // dirComboBox + dirComboBox.Anchor = ((AnchorStyles)(((AnchorStyles.Top | AnchorStyles.Left) | AnchorStyles.Right))); + dirComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + dirComboBox.Location = new Point (99, 8); + dirComboBox.Size = new Size (260, 21); + dirComboBox.TabIndex = 1; + + // smallButtonToolBar + smallButtonToolBar.Anchor = ((AnchorStyles)((AnchorStyles.Top | AnchorStyles.Right))); + smallButtonToolBar.Appearance = ToolBarAppearance.Flat; + smallButtonToolBar.AutoSize = false; + smallButtonToolBar.Buttons.AddRange (new ToolBarButton [] { + backToolBarButton, + upToolBarButton, + newdirToolBarButton, + menueToolBarButton}); + smallButtonToolBar.ButtonSize = new Size (21, 16); // 21, 16 + smallButtonToolBar.Divider = false; + smallButtonToolBar.Dock = DockStyle.None; + smallButtonToolBar.DropDownArrows = true; + smallButtonToolBar.ImageList = imageListTopToolbar; + smallButtonToolBar.Location = new Point (372, 8); + smallButtonToolBar.ShowToolTips = true; + smallButtonToolBar.Size = new Size (110, 20); + smallButtonToolBar.TabIndex = 2; + smallButtonToolBar.TextAlign = ToolBarTextAlign.Right; + + // buttonPanel + popupButtonPanel.Dock = DockStyle.None; + popupButtonPanel.Location = new Point (7, 37); + popupButtonPanel.TabIndex = 3; + + // mwfFileView + mwfFileView.Anchor = ((AnchorStyles)((((AnchorStyles.Top | AnchorStyles.Bottom) | AnchorStyles.Left) | AnchorStyles.Right))); + mwfFileView.Location = new Point (99, 37); + mwfFileView.Size = new Size (449, 282); + mwfFileView.Columns.Add (" Name", 170, HorizontalAlignment.Left); + mwfFileView.Columns.Add ("Size ", 80, HorizontalAlignment.Right); + mwfFileView.Columns.Add (" Type", 100, HorizontalAlignment.Left); + mwfFileView.Columns.Add (" Last Access", 150, HorizontalAlignment.Left); + mwfFileView.AllowColumnReorder = true; + mwfFileView.MultiSelect = false; + mwfFileView.TabIndex = 4; + mwfFileView.FilterIndex = FilterIndex; + + // fileNameLabel + fileNameLabel.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Left))); + fileNameLabel.FlatStyle = FlatStyle.System; + fileNameLabel.Location = new Point (102, 330); + fileNameLabel.Size = new Size (70, 21); + fileNameLabel.TabIndex = 5; + fileNameLabel.Text = "Filename:"; + fileNameLabel.TextAlign = ContentAlignment.MiddleLeft; + + // fileNameComboBox + fileNameComboBox.Anchor = ((AnchorStyles)(((AnchorStyles.Bottom | AnchorStyles.Left) | AnchorStyles.Right))); + fileNameComboBox.Location = new Point (195, 330); + fileNameComboBox.Size = new Size (245, 21); + fileNameComboBox.TabIndex = 6; + fileNameComboBox.Items.Add (" "); + + // fileTypeLabel + fileTypeLabel.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Left))); + fileTypeLabel.FlatStyle = FlatStyle.System; + fileTypeLabel.Location = new Point (102, 356); + fileTypeLabel.Size = new Size (70, 21); + fileTypeLabel.TabIndex = 7; + fileTypeLabel.Text = "Filetype:"; + fileTypeLabel.TextAlign = ContentAlignment.MiddleLeft; + + // fileTypeComboBox + fileTypeComboBox.Anchor = ((AnchorStyles)(((AnchorStyles.Bottom | AnchorStyles.Left) | AnchorStyles.Right))); + fileTypeComboBox.Location = new Point (195, 356); + fileTypeComboBox.Size = new Size (245, 21); + fileTypeComboBox.TabIndex = 8; + + // backToolBarButton + backToolBarButton.ImageIndex = 0; + backToolBarButton.Enabled = false; + backToolBarButton.Style = ToolBarButtonStyle.ToggleButton; + + // upToolBarButton + upToolBarButton.ImageIndex = 1; + upToolBarButton.Style = ToolBarButtonStyle.ToggleButton; + + // newdirToolBarButton + newdirToolBarButton.ImageIndex = 2; + newdirToolBarButton.Style = ToolBarButtonStyle.ToggleButton; + + // menueToolBarButton + menueToolBarButton.ImageIndex = 3; + menueToolBarButton.DropDownMenu = menueToolBarButtonContextMenu; + menueToolBarButton.Style = ToolBarButtonStyle.DropDownButton; + + // menueToolBarButtonContextMenu + MenuItem mi = new MenuItem ("Small Icon", new EventHandler (OnClickMenuToolBarContextMenu)); + menueToolBarButtonContextMenu.MenuItems.Add (mi); + mi = new MenuItem ("Tiles", new EventHandler (OnClickMenuToolBarContextMenu)); + menueToolBarButtonContextMenu.MenuItems.Add (mi); + mi = new MenuItem ("Large Icon", new EventHandler (OnClickMenuToolBarContextMenu)); + menueToolBarButtonContextMenu.MenuItems.Add (mi); + mi = new MenuItem ("List", new EventHandler (OnClickMenuToolBarContextMenu)); + mi.Checked = true; + previousCheckedMenuItem = mi; + menueToolBarButtonContextMenu.MenuItems.Add (mi); + mi = new MenuItem ("Details", new EventHandler (OnClickMenuToolBarContextMenu)); + menueToolBarButtonContextMenu.MenuItems.Add (mi); + + // contextMenu + mi = new MenuItem ("Show hidden files", new EventHandler (OnClickContextMenu)); + mi.Checked = showHiddenFiles; + mwfFileView.ShowHiddenFiles = showHiddenFiles; + contextMenu.MenuItems.Add (mi); + + // openSaveButton + openSaveButton.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Right))); + openSaveButton.FlatStyle = FlatStyle.System; + openSaveButton.Location = new Point (475, 330); + openSaveButton.Size = new Size (72, 21); + openSaveButton.TabIndex = 9; + openSaveButton.FlatStyle = FlatStyle.System; + + // cancelButton + cancelButton.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Right))); + cancelButton.FlatStyle = FlatStyle.System; + cancelButton.Location = new Point (475, 356); + cancelButton.Size = new Size (72, 21); + cancelButton.TabIndex = 10; + cancelButton.Text = "Cancel"; + cancelButton.FlatStyle = FlatStyle.System; + + // helpButton + helpButton.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Right))); + helpButton.FlatStyle = FlatStyle.System; + helpButton.Location = new Point (475, 350); + helpButton.Size = new Size (72, 21); + helpButton.TabIndex = 11; + helpButton.Text = "Help"; + helpButton.FlatStyle = FlatStyle.System; + + // checkBox + readonlyCheckBox.Anchor = ((AnchorStyles)(((AnchorStyles.Bottom | AnchorStyles.Left) | AnchorStyles.Right))); + readonlyCheckBox.Text = "Open Readonly"; + readonlyCheckBox.Location = new Point (195, 350); + readonlyCheckBox.Size = new Size (245, 21); + readonlyCheckBox.FlatStyle = FlatStyle.System; + readonlyCheckBox.TabIndex = 12; + + form.ContextMenu = contextMenu; + + form.Size = new Size (554, 405); // 384 + form.MaximizeBox = true; + form.FormBorderStyle = FormBorderStyle.Sizable; + form.MinimumSize = new Size (554, 405); + + form.Controls.Add (smallButtonToolBar); + form.Controls.Add (cancelButton); + form.Controls.Add (openSaveButton); + form.Controls.Add (mwfFileView); + form.Controls.Add (fileTypeLabel); + form.Controls.Add (fileNameLabel); + form.Controls.Add (fileTypeComboBox); + form.Controls.Add (fileNameComboBox); + form.Controls.Add (dirComboBox); + form.Controls.Add (searchSaveLabel); + form.Controls.Add (popupButtonPanel); + + form.ResumeLayout (false); + + currentDirectoryName = Environment.CurrentDirectory; + + currentDirectoryInfo = new DirectoryInfo (currentDirectoryName); + + if (RestoreDirectory) + restoreDirectoryString = currentDirectoryName; + + openSaveButton.Click += new EventHandler (OnClickOpenSaveButton); + cancelButton.Click += new EventHandler (OnClickCancelButton); + helpButton.Click += new EventHandler (OnClickHelpButton); + + smallButtonToolBar.ButtonClick += new ToolBarButtonClickEventHandler (OnClickSmallButtonToolBar); + + fileTypeComboBox.SelectedIndexChanged += new EventHandler (OnSelectedIndexChangedFileTypeComboBox); + + mwfFileView.SelectedFileChanged += new EventHandler (OnSelectedFileChangedFileView); + mwfFileView.DirectoryChanged += new EventHandler (OnDirectoryChangedFileView); + mwfFileView.ForceDialogEnd += new EventHandler (OnForceDialogEndFileView); + mwfFileView.SelectedFilesChanged += new EventHandler (OnSelectedFilesChangedFileView); + mwfFileView.OnDirectoryUp += new EventHandler (OnDirectoryUp); + + dirComboBox.DirectoryChanged += new EventHandler (OnDirectoryChangedDirComboBox); + + readonlyCheckBox.CheckedChanged += new EventHandler (OnCheckCheckChanged); + + ChangeDirectory (null, currentDirectoryName); + } + + [DefaultValue(true)] + public bool AddExtension { + get { + return addExtension; + } + + set { + addExtension = value; + } + } + + [DefaultValue(false)] + public virtual bool CheckFileExists { + get { + return checkFileExists; + } + + set { + checkFileExists = value; + } + } + + [DefaultValue(true)] + public bool CheckPathExists { + get { + return checkPathExists; + } + + set { + checkPathExists = value; + } + } + + [DefaultValue("")] + public string DefaultExt { + get { + return defaultExt; + } + + set { + defaultExt = value; + + // if there is a dot remove it and everything before it + if (defaultExt.LastIndexOf ('.') != - 1) { + string[] split = defaultExt.Split (new char [] { '.' }); + defaultExt = split [split.Length - 1]; + } + } + } + + // in MS.NET it doesn't make a difference if + // DerefenceLinks is true or false + // if the selected file is a link FileDialog + // always returns the link + [DefaultValue(true)] + public bool DereferenceLinks { + get { + return dereferenceLinks; + } + + set { + dereferenceLinks = value; + } + } + + [DefaultValue("")] + public string FileName { + get { + return fileName; + } + + set { + if (value != null) { + if (SetFileName (value)) + fileName = value; + } + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public string[] FileNames { + get { + if (fileNames == null || fileNames.Length == 0) { + string[] null_nada_nothing_filenames = new string [0]; + return null_nada_nothing_filenames; + } + + string[] new_filenames = new string [fileNames.Length]; + fileNames.CopyTo (new_filenames, 0); + return new_filenames; + } + } + + [DefaultValue("")] + [Localizable(true)] + public string Filter { + get { + return filter; + } + + set { + if (value == null) + throw new NullReferenceException ("Filter"); + + filter = value; + + fileFilter = new FileFilter (filter); + + UpdateFilters (); + } + } + + [DefaultValue(1)] + public int FilterIndex { + get { + return filterIndex; + } + + set { + if (fileFilter != null && fileFilter.FilterArrayList.Count > value) + return; // FIXME: throw an exception ? + + filterIndex = value; + + SelectFilter (); + } + } + + [DefaultValue("")] + public string InitialDirectory { + get { + return initialDirectory; + } + + set { + if (Directory.Exists (value)) { + initialDirectory = value; + + ChangeDirectory (null, initialDirectory); + } + } + } + + [DefaultValue(false)] + public bool RestoreDirectory { + get { + return restoreDirectory; + } + + set { + restoreDirectory = value; + } + } + + [DefaultValue(false)] + public bool ShowHelp { + get { + return showHelp; + } + + set { + showHelp = value; + ResizeAndRelocateForHelpOrReadOnly (); + } + } + + [DefaultValue("")] + [Localizable(true)] + public string Title { + get { + return title; + } + + set { + title = value; + + form.Text = title; + } + } + + // this one is a hard one ;) + // Win32 filename: + // - up to MAX_PATH characters (windef.h) = 260 + // - no trailing dots or spaces + // - case preserving + // - etc... + // NTFS/Posix filename: + // - up to 32,768 Unicode characters + // - trailing periods or spaces + // - case sensitive + // - etc... + [DefaultValue(true)] + public bool ValidateNames { + get { + return validateNames; + } + + set { + validateNames = value; + } + } + + public override void Reset () + { + addExtension = true; + checkFileExists = false; + checkPathExists = true; + defaultExt = ""; + dereferenceLinks = true; + fileName = ""; + fileNames = null; + Filter = ""; + filterIndex = 1; + initialDirectory = ""; + restoreDirectory = false; + ShowHelp = false; + Title = ""; + validateNames = true; + + UpdateFilters (); + } + + public override string ToString () + { + return base.ToString (); + } + + public event CancelEventHandler FileOk { + add { Events.AddHandler (EventFileOk, value); } + remove { Events.RemoveHandler (EventFileOk, value); } + } + + protected virtual IntPtr Instance { + get { + if (form == null) + return IntPtr.Zero; + return form.Handle; + } + } + + // This is just for internal use with MSs version, so it doesn't need to be implemented + // as it can't really be accessed anyways + protected int Options { + get { return -1; } + } + + [MonoTODO] + protected override IntPtr HookProc (IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam) + { + throw new NotImplementedException (); + } + + protected void OnFileOk (CancelEventArgs e) + { + CancelEventHandler fo = (CancelEventHandler) Events [EventFileOk]; + if (fo != null) + fo (this, e); + } + + [MonoTODO] + protected override bool RunDialog (IntPtr hWndOwner) + { + form.Refresh (); + return true; + } + + internal virtual bool ShowReadOnly { + set { + showReadOnly = value; + ResizeAndRelocateForHelpOrReadOnly (); + } + + get { + return showReadOnly; + } + } + + internal virtual bool ReadOnlyChecked { + set { + readOnlyChecked = value; + readonlyCheckBox.Checked = value; + } + + get { + return readOnlyChecked; + } + } + + internal bool BMultiSelect { + set { + multiSelect = value; + mwfFileView.MultiSelect = value; + } + + get { + return multiSelect; + } + } + + internal string OpenSaveButtonText { + set { + openSaveButton.Text = value; + } + } + + internal string SearchSaveLabel { + set { + searchSaveLabel.Text = value; + } + } + + private void SelectFilter () + { + do_not_call_OnSelectedIndexChangedFileTypeComboBox = true; + fileTypeComboBox.BeginUpdate (); + fileTypeComboBox.SelectedIndex = FilterIndex - 1; + fileTypeComboBox.EndUpdate (); + + mwfFileView.FilterIndex = FilterIndex; + + mwfFileView.UpdateFileView (currentDirectoryInfo_or_current_special_case); + } + + private bool SetFileName (string fname) + { + bool rooted = Path.IsPathRooted (fname); + + if (!rooted) { + if (File.Exists (Path.Combine (currentDirectoryName, fname))) { + fileNameComboBox.Text = fname; + mwfFileView.SetSelectedIndexTo (fname); + + return true; + } else + return false; + } else { + if (File.Exists (fname)) { + fileNameComboBox.Text = Path.GetFileName (fname); + ChangeDirectory (null, Path.GetDirectoryName (fname)); + mwfFileView.SetSelectedIndexTo (fname); + + return true; + } + } + + return false; + } + + void OnClickContextMenu (object sender, EventArgs e) + { + MenuItem senderMenuItem = sender as MenuItem; + + if (senderMenuItem.Index == 0) { + senderMenuItem.Checked = !senderMenuItem.Checked; + showHiddenFiles = senderMenuItem.Checked; + mwfFileView.ShowHiddenFiles = showHiddenFiles; + mwfFileView.UpdateFileView (currentDirectoryInfo_or_current_special_case); + } + } + + void OnClickOpenSaveButton (object sender, EventArgs e) + { + if (mwfFileView.SelectedItems [0] != null) { + string path = Path.Combine (currentDirectoryName, mwfFileView.SelectedItems [0].Text); + if (Directory.Exists (path)) { + ChangeDirectory (null, path); + openSaveButton.Select (); + return; + } + } + + if (!multiSelect) { + if (!show_special_case) { + string fileFromComboBox = fileNameComboBox.Text.Trim (); + + if (fileFromComboBox.Length > 0) { + if (!Path.IsPathRooted (fileFromComboBox)) + fileFromComboBox = Path.Combine (currentDirectoryName, fileFromComboBox); + + FileInfo fileInfo = new FileInfo (fileFromComboBox); + if (fileInfo.Exists) + currentFileName = fileFromComboBox; + else { + DirectoryInfo dirInfo = new DirectoryInfo (fileFromComboBox); + if (dirInfo.Exists) { + ChangeDirectory (null, dirInfo.FullName); + + currentFileName = ""; + + fileNameComboBox.Text = " "; + return; + } + } + } else + return; + } else { + if (currentFileName == null || currentFileName == String.Empty) { + currentFileName = fileNameComboBox.Text.Trim (); + + if (currentFileName.Length > 0) { + FileInfo fileInfo = new FileInfo (currentFileName); + if (!fileInfo.Exists) { + DirectoryInfo dirInfo = new DirectoryInfo (currentFileName); + if (dirInfo.Exists) { + ChangeDirectory (null, dirInfo.FullName); + + currentFileName = ""; + + fileNameComboBox.Text = " "; + return; + } + } + } else + return; + } + + if (currentDirectoryName == String.Empty) + currentDirectoryName = Path.GetDirectoryName (currentFileName); + } + + if (fileDialogType == FileDialogType.OpenFileDialog) { + if (checkFileExists) { + if (!File.Exists (currentFileName)) { + string message = "\"" + currentFileName + "\" doesn't exist. Please verify that you have entered the correct file name."; + MessageBox.Show (message, openSaveButton.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning); + + currentFileName = ""; + + return; + } + } + } else { + if (overwritePrompt) { + if (File.Exists (currentFileName)) { + string message = "\"" + currentFileName + "\" exists. Overwrite ?"; + DialogResult dr = MessageBox.Show (message, openSaveButton.Text, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning); + + if (dr == DialogResult.Cancel) { + currentFileName = ""; + + return; + } + } + } + + if (createPrompt) { + if (!File.Exists (currentFileName)) { + string message = "\"" + currentFileName + "\" doesn't exist. Create ?"; + DialogResult dr = MessageBox.Show (message, openSaveButton.Text, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning); + + if (dr == DialogResult.Cancel) { + currentFileName = ""; + + return; + } + } + } + } + + if (fileDialogType == FileDialogType.SaveFileDialog) { + if (addExtension && defaultExt.Length > 0) { + if (!currentFileName.EndsWith (defaultExt)) { + currentFileName += "." + defaultExt; + } + } + } + + fileNames = new string [1]; + + fileNames [0] = currentFileName; + + fileName = currentFileName; + + WriteRecentlyUsed (); + } else // multiSelect = true + if (fileDialogType != FileDialogType.SaveFileDialog) { + if (mwfFileView.SelectedItems.Count > 0) { + // first remove all selected directories + ArrayList al = new ArrayList (); + + foreach (ListViewItem lvi in mwfFileView.SelectedItems) { + FileStruct fileStruct = (FileStruct)mwfFileView.FileHashtable [lvi.Text]; + + if (fileStruct.attributes != FileAttributes.Directory) { + al.Add (fileStruct); + } + } + + fileName = ((FileStruct)al [0]).fullname; + + fileNames = new string [al.Count]; + + for (int i = 0; i < al.Count; i++) { + fileNames [i] = ((FileStruct)al [i]).fullname; + } + } + } + + if (checkPathExists) { + if (!Directory.Exists (currentDirectoryName)) { + string message = "\"" + currentDirectoryName + "\" doesn't exist. Please verify that you have entered the correct directory name."; + MessageBox.Show (message, openSaveButton.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning); + + if (initialDirectory == String.Empty) + currentDirectoryName = Environment.CurrentDirectory; + else + currentDirectoryName = initialDirectory; + + return; + } + } + + if (restoreDirectory) + currentDirectoryName = restoreDirectoryString; + + CancelEventArgs cancelEventArgs = new CancelEventArgs (); + + cancelEventArgs.Cancel = false; + + OnFileOk (cancelEventArgs); + + form.DialogResult = DialogResult.OK; + } + + void OnClickCancelButton (object sender, EventArgs e) + { + if (restoreDirectory) + currentDirectoryName = restoreDirectoryString; + + CancelEventArgs cancelEventArgs = new CancelEventArgs (); + + cancelEventArgs.Cancel = true; + + OnFileOk (cancelEventArgs); + + form.DialogResult = DialogResult.Cancel; + } + + void OnClickHelpButton (object sender, EventArgs e) + { + OnHelpRequest (e); + } + + void OnClickSmallButtonToolBar (object sender, ToolBarButtonClickEventArgs e) + { + if (e.Button == upToolBarButton) { + if (currentDirectoryInfo != null && currentDirectoryInfo.Parent != null) + ChangeDirectory (null, currentDirectoryInfo.Parent.FullName); + } else + if (e.Button == backToolBarButton) { + PopDirectory (); + } else + if (e.Button == newdirToolBarButton) { + + } + } + + void OnClickMenuToolBarContextMenu (object sender, EventArgs e) + { + MenuItem senderMenuItem = (MenuItem)sender; + + previousCheckedMenuItem.Checked = false; + senderMenuItem.Checked = true; + previousCheckedMenuItem = senderMenuItem; + + // FIXME... + + switch (senderMenuItem.Index) { + case 0: + mwfFileView.View = View.SmallIcon; + break; + case 1: + mwfFileView.View = View.LargeIcon; + break; + case 2: + mwfFileView.View = View.LargeIcon; + break; + case 3: + mwfFileView.View = View.List; + break; + case 4: + mwfFileView.View = View.Details; + break; + default: + break; + } + + + mwfFileView.UpdateFileView (currentDirectoryInfo_or_current_special_case); + } + + void OnSelectedIndexChangedFileTypeComboBox (object sender, EventArgs e) + { + if (do_not_call_OnSelectedIndexChangedFileTypeComboBox) { + do_not_call_OnSelectedIndexChangedFileTypeComboBox = false; + return; + } + + filterIndex = fileTypeComboBox.SelectedIndex + 1; + + mwfFileView.FilterIndex = filterIndex; + + mwfFileView.UpdateFileView (currentDirectoryInfo_or_current_special_case); + } + + void OnSelectedFileChangedFileView (object sender, EventArgs e) + { + fileNameComboBox.Text = mwfFileView.FileName; + currentFileName = mwfFileView.FullFileName; + } + + void OnDirectoryChangedFileView (object sender, EventArgs e) + { + ChangeDirectory (sender, mwfFileView.FullFileName); + } + + void OnForceDialogEndFileView (object sender, EventArgs e) + { + ForceDialogEnd (); + } + + void OnSelectedFilesChangedFileView (object sender, EventArgs e) + { + fileNameComboBox.Text = mwfFileView.SelectedFilesString; + } + + void OnDirectoryChangedDirComboBox (object sender, EventArgs e) + { + ChangeDirectory (sender, dirComboBox.CurrentPath); + } + + void OnCheckCheckChanged (object sender, EventArgs e) + { + ReadOnlyChecked = readonlyCheckBox.Checked; + } + + void OnDirectoryUp (Object sender, EventArgs e) + { + if (currentDirectoryInfo != null && currentDirectoryInfo.Parent != null) + ChangeDirectory (null, currentDirectoryInfo.Parent.FullName); + + // make mwfFileView the active control + mwfFileView.Select (); + } + + private void UpdateFilters () + { + ArrayList filters = fileFilter.FilterArrayList; + + fileTypeComboBox.BeginUpdate (); + + fileTypeComboBox.Items.Clear (); + + foreach (FilterStruct fs in filters) { + fileTypeComboBox.Items.Add (fs.filterName); + } + + fileTypeComboBox.SelectedIndex = FilterIndex - 1; + + fileTypeComboBox.EndUpdate (); + + mwfFileView.FilterArrayList = filters; + + mwfFileView.FilterIndex = FilterIndex; + + mwfFileView.UpdateFileView (currentDirectoryInfo_or_current_special_case); + } + + internal void ChangeDirectory (object sender, string path_or_special_case) + { + show_special_case = false; + + if (sender != dirComboBox) + dirComboBox.CurrentPath = path_or_special_case; + + if (sender != popupButtonPanel) + popupButtonPanel.SetPopupButtonStateByPath (path_or_special_case); + + if (currentDirectoryInfo != null) + PushDirectory (currentDirectoryInfo); + else + PushDirectory (current_special_case); + + if (path_or_special_case == recently_string) { + currentDirectoryName = String.Empty; + + currentDirectoryInfo = null; + show_special_case = true; + + current_special_case = recently_string; + + mwfFileView.UpdateFileView (recently_string); + + } else if (path_or_special_case == mycomputer_string) { + currentDirectoryName = String.Empty; + + currentDirectoryInfo = null; + show_special_case = true; + + current_special_case = mycomputer_string; + + mwfFileView.UpdateFileView (mycomputer_string); + + } else if (path_or_special_case == network_string) { + currentDirectoryName = String.Empty; + + currentDirectoryInfo = null; + show_special_case = true; + + current_special_case = network_string; + + mwfFileView.UpdateFileView (network_string); + + } else { + currentDirectoryName = path_or_special_case; + + currentDirectoryInfo = new DirectoryInfo (path_or_special_case); + + mwfFileView.UpdateFileView (currentDirectoryInfo); + } + } + + private void ForceDialogEnd () + { + OnClickOpenSaveButton (this, EventArgs.Empty); + } + + private void PushDirectory (object directoryInfo_or_string) + { + directoryStack.Push (directoryInfo_or_string); + backToolBarButton.Enabled = true; + } + + private void PopDirectory () + { + if (directoryStack.Count == 0) + return; + + show_special_case = false; + + object directoryInfo_or_string = directoryStack.Pop (); + + if (directoryInfo_or_string is DirectoryInfo) { + currentDirectoryInfo = directoryInfo_or_string as DirectoryInfo; + + currentDirectoryName = currentDirectoryInfo.FullName; + + current_special_case = String.Empty; + } else + if (directoryInfo_or_string is string) { + currentDirectoryInfo = null; + currentDirectoryName = String.Empty; + show_special_case = true; + current_special_case = directoryInfo_or_string as string; + } + + if (directoryStack.Count == 0) + backToolBarButton.Enabled = false; + + dirComboBox.CurrentPath = currentDirectoryName_or_special_case; + + popupButtonPanel.SetPopupButtonStateByPath (currentDirectoryName_or_special_case); + + mwfFileView.UpdateFileView (currentDirectoryInfo_or_current_special_case); + } + + private void ResizeAndRelocateForHelpOrReadOnly () + { + form.SuspendLayout (); + if (ShowHelp || ShowReadOnly) { + mwfFileView.Size = new Size (449, 250); + fileNameLabel.Location = new Point (102, 298); + fileNameComboBox.Location = new Point (195, 298); + fileTypeLabel.Location = new Point (102, 324); + fileTypeComboBox.Location = new Point (195, 324); + openSaveButton.Location = new Point (475, 298); + cancelButton.Location = new Point (475, 324); + } else { + mwfFileView.Size = new Size (449, 282); + fileNameLabel.Location = new Point (102, 330); + fileNameComboBox.Location = new Point (195, 330); + fileTypeLabel.Location = new Point (102, 356); + fileTypeComboBox.Location = new Point (195, 356); + openSaveButton.Location = new Point (475, 330); + cancelButton.Location = new Point (475, 356); + } + + if (ShowHelp) + form.Controls.Add (helpButton); + else + form.Controls.Remove (helpButton); + + if (ShowReadOnly) + form.Controls.Add (readonlyCheckBox); + else + form.Controls.Remove (readonlyCheckBox); + form.ResumeLayout (); + } + + private void WriteRecentlyUsed () + { + int platform = (int) Environment.OSVersion.Platform; + + // on a *nix platform we use "$HOME/.recently-used" to store our recently used files (GNOME, libegg like) + if ((platform == 4) || (platform == 128)) { + string personal_folder = ThemeEngine.Current.Places (UIIcon.PlacesPersonal); + string recently_used_path = Path.Combine (personal_folder, ".recently-used"); + + if (File.Exists (recently_used_path) && new FileInfo (recently_used_path).Length > 0) { + XmlDocument xml_doc = new XmlDocument (); + xml_doc.Load (recently_used_path); + + XmlNode grand_parent_node = xml_doc.SelectSingleNode ("RecentFiles"); + + if (grand_parent_node != null) { + // create a new element + XmlElement new_recent_item_node = xml_doc.CreateElement ("RecentItem"); + + XmlElement new_child = xml_doc.CreateElement ("URI"); + UriBuilder ub = new UriBuilder (); + ub.Path = currentFileName; + ub.Host = null; + ub.Scheme = "file"; + XmlText new_text_child = xml_doc.CreateTextNode (ub.ToString ()); + new_child.AppendChild (new_text_child); + + new_recent_item_node.AppendChild (new_child); + + new_child = xml_doc.CreateElement ("Mime-Type"); + new_text_child = xml_doc.CreateTextNode (Mime.GetMimeTypeForFile (currentFileName)); + new_child.AppendChild (new_text_child); + + new_recent_item_node.AppendChild (new_child); + + new_child = xml_doc.CreateElement ("Timestamp"); + long seconds = (long)(DateTime.UtcNow - new DateTime (1970, 1, 1)).TotalSeconds; + new_text_child = xml_doc.CreateTextNode (seconds.ToString ()); + new_child.AppendChild (new_text_child); + + new_recent_item_node.AppendChild (new_child); + + new_child = xml_doc.CreateElement ("Groups"); + + new_recent_item_node.AppendChild (new_child); + + // now search the nodes in grand_parent_node for another instance of the new uri and if found remove it + // so that the new node is the first one + foreach (XmlNode n in grand_parent_node.ChildNodes) { + XmlNode uri_node = n.SelectSingleNode ("URI"); + if (uri_node != null) { + XmlNode uri_node_child = uri_node.FirstChild; + if (uri_node_child is XmlText) + if (ub.ToString () == ((XmlText)uri_node_child).Data) { + grand_parent_node.RemoveChild (n); + break; + } + } + } + + // prepend the new recent item to the grand parent node list + grand_parent_node.PrependChild (new_recent_item_node); + + // limit the # of RecentItems to 10 + if (grand_parent_node.ChildNodes.Count > 10) { + while (grand_parent_node.ChildNodes.Count > 10) + grand_parent_node.RemoveChild (grand_parent_node.LastChild); + } + + try { + xml_doc.Save (recently_used_path); + } catch ( Exception e ) { + } + } + } else { + XmlDocument xml_doc = new XmlDocument (); + xml_doc.AppendChild (xml_doc.CreateXmlDeclaration ("1.0", "", "")); + + XmlElement recentFiles_element = xml_doc.CreateElement ("RecentFiles"); + + XmlElement new_recent_item_node = xml_doc.CreateElement ("RecentItem"); + + XmlElement new_child = xml_doc.CreateElement ("URI"); + UriBuilder ub = new UriBuilder (); + ub.Path = currentFileName; + ub.Host = null; + ub.Scheme = "file"; + XmlText new_text_child = xml_doc.CreateTextNode (ub.ToString ()); + new_child.AppendChild (new_text_child); + + new_recent_item_node.AppendChild (new_child); + + new_child = xml_doc.CreateElement ("Mime-Type"); + new_text_child = xml_doc.CreateTextNode (Mime.GetMimeTypeForFile (currentFileName)); + new_child.AppendChild (new_text_child); + + new_recent_item_node.AppendChild (new_child); + + new_child = xml_doc.CreateElement ("Timestamp"); + long seconds = (long)(DateTime.UtcNow - new DateTime (1970, 1, 1)).TotalSeconds; + new_text_child = xml_doc.CreateTextNode (seconds.ToString ()); + new_child.AppendChild (new_text_child); + + new_recent_item_node.AppendChild (new_child); + + new_child = xml_doc.CreateElement ("Groups"); + + new_recent_item_node.AppendChild (new_child); + + recentFiles_element.AppendChild (new_recent_item_node); + + xml_doc.AppendChild (recentFiles_element); + + try { + xml_doc.Save (recently_used_path); + } catch ( Exception e ) { + } + } + } + } + + private object currentDirectoryInfo_or_current_special_case { + get { + if (currentDirectoryInfo != null) + return currentDirectoryInfo; + else + return current_special_case; + } + } + + private string currentDirectoryName_or_special_case { + get { + if (currentDirectoryName != String.Empty) + return currentDirectoryName; + else + return current_special_case; + } + } + + internal class PopupButtonPanel : Panel { + internal class PopupButton : Control { + internal enum PopupButtonState { Normal, Down, Up} + + private Image image = null; + private PopupButtonState popupButtonState = PopupButtonState.Normal; + private StringFormat text_format = new StringFormat(); + + public PopupButton () + { + text_format.Alignment = StringAlignment.Center; + text_format.LineAlignment = StringAlignment.Far; + + SetStyle (ControlStyles.DoubleBuffer, true); + SetStyle (ControlStyles.AllPaintingInWmPaint, true); + SetStyle (ControlStyles.UserPaint, true); + } + + public Image Image { + set { + image = value; + Refresh (); + } + + get { + return image; + } + } + + public PopupButtonState ButtonState { + set { + popupButtonState = value; + Refresh (); + } + + get { + return popupButtonState; + } + } + + protected override void OnPaint (PaintEventArgs pe) + { + Draw (pe); + + base.OnPaint (pe); + } + + private void Draw (PaintEventArgs pe) + { + Graphics gr = pe.Graphics; + + gr.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (BackColor), ClientRectangle); + + // draw image + if (image != null) { + int i_x = (ClientSize.Width - image.Width) / 2; + int i_y = 4; + gr.DrawImage (image, i_x, i_y); + } + + if (Text != String.Empty) { + Rectangle text_rect = Rectangle.Inflate (ClientRectangle, -4, 0); + + gr.DrawString (Text, Font, ThemeEngine.Current.ResPool.GetSolidBrush (ForeColor), text_rect, text_format); + } + + switch (popupButtonState) { + case PopupButtonState.Up: + gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.White), 0, 0, ClientSize.Width - 1, 0); + gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.White), 0, 0, 0, ClientSize.Height - 1); + gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.Black), ClientSize.Width - 1, 0, ClientSize.Width - 1, ClientSize.Height - 1); + gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.Black), 0, ClientSize.Height - 1, ClientSize.Width - 1, ClientSize.Height - 1); + break; + + case PopupButtonState.Down: + gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.Black), 0, 0, ClientSize.Width - 1, 0); + gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.Black), 0, 0, 0, ClientSize.Height - 1); + gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.White), ClientSize.Width - 1, 0, ClientSize.Width - 1, ClientSize.Height - 1); + gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.White), 0, ClientSize.Height - 1, ClientSize.Width - 1, ClientSize.Height - 1); + break; + } + } + + protected override void OnMouseEnter (EventArgs e) + { + if (popupButtonState != PopupButtonState.Down) + popupButtonState = PopupButtonState.Up; + Refresh (); + base.OnMouseEnter (e); + } + + protected override void OnMouseLeave (EventArgs e) + { + if (popupButtonState != PopupButtonState.Down) + popupButtonState = PopupButtonState.Normal; + Refresh (); + base.OnMouseLeave (e); + } + + protected override void OnClick (EventArgs e) + { + popupButtonState = PopupButtonState.Down; + Refresh (); + base.OnClick (e); + } + } + + private FileDialog fileDialog; + + private PopupButton recentlyusedButton; + private PopupButton desktopButton; + private PopupButton personalButton; + private PopupButton mycomputerButton; + private PopupButton networkButton; + + private PopupButton lastPopupButton = null; + + private int platform = (int) Environment.OSVersion.Platform; + + public PopupButtonPanel (FileDialog fileDialog) + { + this.fileDialog = fileDialog; + + SuspendLayout (); + + BorderStyle = BorderStyle.Fixed3D; + BackColor = Color.FromArgb (128, 128, 128); + Size = new Size (85, 336); + + recentlyusedButton = new PopupButton (); + desktopButton = new PopupButton (); + personalButton = new PopupButton (); + mycomputerButton = new PopupButton (); + networkButton = new PopupButton (); + + recentlyusedButton.Size = new Size (82, 64); + recentlyusedButton.Image = ThemeEngine.Current.Images (UIIcon.PlacesRecentDocuments, 38); + recentlyusedButton.BackColor = BackColor; + recentlyusedButton.ForeColor = Color.White; + recentlyusedButton.Location = new Point (2, 2); + recentlyusedButton.Text = "Recently\nused"; + recentlyusedButton.Click += new EventHandler (OnClickButton); + + desktopButton.Image = ThemeEngine.Current.Images (UIIcon.PlacesDesktop, 38); + desktopButton.BackColor = BackColor; + desktopButton.ForeColor = Color.White; + desktopButton.Size = new Size (82, 64); + desktopButton.Location = new Point (2, 66); + desktopButton.Text = "Desktop"; + desktopButton.Click += new EventHandler (OnClickButton); + + personalButton.Image = ThemeEngine.Current.Images (UIIcon.PlacesPersonal, 38); + personalButton.BackColor = BackColor; + personalButton.ForeColor = Color.White; + personalButton.Size = new Size (82, 64); + personalButton.Location = new Point (2, 130); + personalButton.Text = "Personal"; + personalButton.Click += new EventHandler (OnClickButton); + + mycomputerButton.Image = ThemeEngine.Current.Images (UIIcon.PlacesMyComputer, 38); + mycomputerButton.BackColor = BackColor; + mycomputerButton.ForeColor = Color.White; + mycomputerButton.Size = new Size (82, 64); + mycomputerButton.Location = new Point (2, 194); + mycomputerButton.Text = "My Computer"; + mycomputerButton.Click += new EventHandler (OnClickButton); + + networkButton.Image = ThemeEngine.Current.Images (UIIcon.PlacesMyNetwork, 38); + networkButton.BackColor = BackColor; + networkButton.ForeColor = Color.White; + networkButton.Size = new Size (82, 64); + networkButton.Location = new Point (2, 258); + networkButton.Text = "My Network"; + networkButton.Click += new EventHandler (OnClickButton); + + Controls.Add (recentlyusedButton); + Controls.Add (desktopButton); + Controls.Add (personalButton); + Controls.Add (mycomputerButton); + Controls.Add (networkButton); + + ResumeLayout (false); + } + + void OnClickButton (object sender, EventArgs e) + { + if (lastPopupButton != null && (PopupButton)sender != lastPopupButton) + lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal; + lastPopupButton = sender as PopupButton; + + if (sender == recentlyusedButton) { + if ((platform == 4) || (platform == 128)) + // do NOT change the following line! + // FileDialog uses a special handling for recently used files on *nix + // recently used files are not stored as links in a directory but + // as a xml file called .recently-used in the users home dir + // This matches the Freedesktop.org spec which gnome uses + fileDialog.ChangeDirectory (this, FileDialog.recently_string); + else + fileDialog.ChangeDirectory (this, ThemeEngine.Current.Places (UIIcon.PlacesRecentDocuments)); + } else + if (sender == desktopButton) { + fileDialog.ChangeDirectory (this, ThemeEngine.Current.Places (UIIcon.PlacesDesktop)); + } else + if (sender == personalButton) { + fileDialog.ChangeDirectory (this, ThemeEngine.Current.Places (UIIcon.PlacesPersonal)); + } else + if (sender == mycomputerButton) { + if ((platform == 4) || (platform == 128)) + // do NOT change the following line! + // on *nix we do not have a special folder MyComputer + fileDialog.ChangeDirectory (this, FileDialog.mycomputer_string); + else + fileDialog.ChangeDirectory (this, ThemeEngine.Current.Places (UIIcon.PlacesMyComputer)); + } else + if (sender == networkButton) { + if ((platform == 4) || (platform == 128)) + fileDialog.ChangeDirectory (this, FileDialog.network_string); + else + fileDialog.ChangeDirectory (this, ThemeEngine.Current.Places (UIIcon.PlacesMyNetwork)); + } + } + + public void SetPopupButtonStateByPath (string path) + { + if (path == FileDialog.recently_string || + path == ThemeEngine.Current.Places (UIIcon.PlacesRecentDocuments)) { + if (lastPopupButton != recentlyusedButton) { + if (lastPopupButton != null) + lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal; + recentlyusedButton.ButtonState = PopupButton.PopupButtonState.Down; + lastPopupButton = recentlyusedButton; + } + } else + if (path == ThemeEngine.Current.Places (UIIcon.PlacesDesktop)) { + if (lastPopupButton != desktopButton) { + if (lastPopupButton != null) + lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal; + desktopButton.ButtonState = PopupButton.PopupButtonState.Down; + lastPopupButton = desktopButton; + } + } else + if (path == ThemeEngine.Current.Places (UIIcon.PlacesPersonal)) { + if (lastPopupButton != personalButton) { + if (lastPopupButton != null) + lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal; + personalButton.ButtonState = PopupButton.PopupButtonState.Down; + lastPopupButton = personalButton; + } + } else + if (path == FileDialog.mycomputer_string || + path == ThemeEngine.Current.Places (UIIcon.PlacesMyComputer)) { + if (lastPopupButton != mycomputerButton) { + if (lastPopupButton != null) + lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal; + mycomputerButton.ButtonState = PopupButton.PopupButtonState.Down; + lastPopupButton = mycomputerButton; + } + } else + if (path == FileDialog.network_string || + path == ThemeEngine.Current.Places (UIIcon.PlacesMyNetwork)) { + if (lastPopupButton != networkButton) { + if (lastPopupButton != null) + lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal; + networkButton.ButtonState = PopupButton.PopupButtonState.Down; + lastPopupButton = networkButton; + } + } else { + if (lastPopupButton != null) { + lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal; + lastPopupButton = null; + } + } + } + } + } + + internal struct FilterStruct { + public string filterName; + public StringCollection filters; + + public FilterStruct (string filterName, string filter) + { + this.filterName = filterName; + + filters = new StringCollection (); + + SplitFilters (filter); + } + + private void SplitFilters (string filter) + { + string[] split = filter.Split (new char [] {';'}); + + filters.AddRange (split); + } + } + + internal struct FileStruct { + public enum FileStructType { + File, + Directoy, + Device, + Network + } + + public string fullname; + public FileAttributes attributes; + public long size; + public FileStructType type; + } + + // MWFFileView + internal class MWFFileView : ListView { + private ArrayList filterArrayList; + + // store the FileStruct of all files in the current directory + private Hashtable fileHashtable = new Hashtable(); + + private bool showHiddenFiles = false; + + private EventHandler on_selected_file_changed; + private EventHandler on_selected_files_changed; + private EventHandler on_directory_changed; + private EventHandler on_force_dialog_end; + private EventHandler on_one_directory_up; + + private string fileName; + private string fullFileName; + private string selectedFilesString; + + private int filterIndex; + + private ToolTip toolTip; + private int oldItemIndexForToolTip = -1; + + private MasterMount masterMount = new MasterMount (); + + public MWFFileView () + { + SuspendLayout (); + + toolTip = new ToolTip (); + toolTip.InitialDelay = 300; + toolTip.ReshowDelay = 0; + + LabelWrap = true; + + SmallImageList = MimeIconEngine.SmallIcons; + LargeImageList = MimeIconEngine.LargeIcons; + + View = View.List; + + ResumeLayout (false); + + KeyUp += new KeyEventHandler (MWF_KeyUp); + } + + public ArrayList FilterArrayList { + set { + filterArrayList = value; + } + + get { + return filterArrayList; + } + } + + public Hashtable FileHashtable { + get { + return fileHashtable; + } + } + + public bool ShowHiddenFiles { + set { + showHiddenFiles = value; + } + + get { + return showHiddenFiles; + } + } + + public string FileName { + get { + return fileName; + } + } + + public string FullFileName { + get { + return fullFileName; + } + } + + public int FilterIndex { + set { + filterIndex = value; + } + + get { + return filterIndex; + } + } + + public string SelectedFilesString { + set { + selectedFilesString = value; + } + + get { + return selectedFilesString; + } + } + + public void SetSelectedIndexTo (string fname) + { + foreach (ListViewItem item in Items) { + if (item.Text == fname) { + BeginUpdate (); + SelectedItems.Clear (); + item.Selected = true; + EndUpdate (); + break; + } + } + } + + private ArrayList GetFileInfoArrayList (DirectoryInfo directoryInfo) + { + ArrayList arrayList = new ArrayList (); + + if (filterArrayList != null && filterArrayList.Count != 0) { + FilterStruct fs = (FilterStruct)filterArrayList [filterIndex - 1]; + + foreach (string s in fs.filters) + arrayList.AddRange (directoryInfo.GetFiles (s)); + } else + arrayList.AddRange (directoryInfo.GetFiles ()); + + return arrayList; + } + + private ArrayList GetFileInfoArrayListByArrayList (ArrayList al) + { + ArrayList arrayList = new ArrayList (); + + foreach (string path in al) { + if (File.Exists (path)) { + FileInfo fi = new FileInfo (path); + arrayList.Add (fi); + } + } + + return arrayList; + } + + public void UpdateFileView (object directoryInfo_or_string) + { + if (directoryInfo_or_string is DirectoryInfo) + UpdateFileViewByDirectoryInfo (directoryInfo_or_string as DirectoryInfo); + else + UpdateFileViewByString (directoryInfo_or_string as string); + + if (Items.Count > 0) { + ListViewItem item = Items [0]; + item.Selected = true; + } + } + + private void UpdateFileViewByDirectoryInfo (DirectoryInfo inputDirectoryInfo) + { + DirectoryInfo directoryInfo = inputDirectoryInfo; + + DirectoryInfo[] directoryInfoArray = directoryInfo.GetDirectories (); + + ArrayList fileInfoArrayList = GetFileInfoArrayList (directoryInfo); + + fileHashtable.Clear (); + + BeginUpdate (); + + Items.Clear (); + SelectedItems.Clear (); + + foreach (DirectoryInfo directoryInfoi in directoryInfoArray) { + if (!ShowHiddenFiles) + if (directoryInfoi.Name.StartsWith (".") || directoryInfoi.Attributes == FileAttributes.Hidden) + continue; + + FileStruct fileStruct = new FileStruct (); + fileStruct.type = FileStruct.FileStructType.Directoy; + + fileStruct.fullname = directoryInfoi.FullName; + + ListViewItem listViewItem = new ListViewItem (directoryInfoi.Name); + + int index = MimeIconEngine.GetIconIndexForMimeType ("inode/directory"); + + listViewItem.ImageIndex = index; + + listViewItem.SubItems.Add (""); + listViewItem.SubItems.Add ("Directory"); + listViewItem.SubItems.Add (directoryInfoi.LastAccessTime.ToShortDateString () + " " + directoryInfoi.LastAccessTime.ToShortTimeString ()); + + fileStruct.attributes = FileAttributes.Directory; + + fileHashtable.Add (directoryInfoi.Name, fileStruct); + + Items.Add (listViewItem); + } + + foreach (FileInfo fileInfo in fileInfoArrayList) { + DoOneFileInfo (fileInfo); + } + + EndUpdate (); + } + + private void UpdateFileViewByString (string kind) + { + if (kind == FileDialog.recently_string) { + ArrayList fileInfoArrayList = GetFileInfoArrayListByArrayList (GetFreedesktopSpecRecentlyUsed ()); + + fileHashtable.Clear (); + + BeginUpdate (); + + Items.Clear (); + SelectedItems.Clear (); + + foreach (FileInfo fileInfo in fileInfoArrayList) { + DoOneFileInfo (fileInfo); + } + + EndUpdate (); + + } else if (kind == FileDialog.mycomputer_string) { + + if (masterMount.ProcMountAvailable) { + masterMount.GetMounts (); + + fileHashtable.Clear (); + + BeginUpdate (); + + Items.Clear (); + SelectedItems.Clear (); + + foreach (MasterMount.Mount mount in masterMount.Block_devices) { + FileStruct fileStruct = new FileStruct (); + fileStruct.type = FileStruct.FileStructType.Device; + + fileStruct.fullname = mount.mount_point; + + string item_name = "HDD (" + mount.fsType + ", " + mount.device_short + ")"; + ListViewItem listViewItem = new ListViewItem (item_name); + + int index = MimeIconEngine.GetIconIndexForMimeType ("harddisk/harddisk"); + + listViewItem.ImageIndex = index; + + listViewItem.SubItems.Add (""); + listViewItem.SubItems.Add ("Harddisk"); +// listViewItem.SubItems.Add (directoryInfoi.LastAccessTime.ToShortDateString () + " " + directoryInfoi.LastAccessTime.ToShortTimeString ()); + + fileStruct.attributes = FileAttributes.Directory; + + fileHashtable.Add (item_name, fileStruct); + + Items.Add (listViewItem); + } + + foreach (MasterMount.Mount mount in masterMount.Removable_devices) { + FileStruct fileStruct = new FileStruct (); + fileStruct.type = FileStruct.FileStructType.Device; + + fileStruct.fullname = mount.mount_point; + + bool is_dvd_cdrom = mount.fsType == MasterMount.FsTypes.usbfs ? false : true; + string type_name = is_dvd_cdrom ? "DVD/CD-Rom" : "USB"; + string mime_type = is_dvd_cdrom ? "cdrom/cdrom" : "removable/removable"; + + string item_name = type_name + " (" + mount.device_short + ")"; + + ListViewItem listViewItem = new ListViewItem (item_name); + + int index = MimeIconEngine.GetIconIndexForMimeType (mime_type); + + listViewItem.ImageIndex = index; + + listViewItem.SubItems.Add (""); + listViewItem.SubItems.Add (type_name); +// listViewItem.SubItems.Add (directoryInfoi.LastAccessTime.ToShortDateString () + " " + directoryInfoi.LastAccessTime.ToShortTimeString ()); + + fileStruct.attributes = FileAttributes.Directory; + + fileHashtable.Add (item_name, fileStruct); + + Items.Add (listViewItem); + } + + ListViewItem listViewItem2 = new ListViewItem ("Desktop"); + + int index2 = MimeIconEngine.GetIconIndexForMimeType ("desktop/desktop"); + + FileStruct fileStruct2 = new FileStruct (); + fileStruct2.type = FileStruct.FileStructType.Directoy; + + fileStruct2.fullname = ThemeEngine.Current.Places (UIIcon.PlacesDesktop); + + listViewItem2.ImageIndex = index2; + + listViewItem2.SubItems.Add (""); + listViewItem2.SubItems.Add ("Desktop"); +// listViewItem.SubItems.Add (directoryInfoi.LastAccessTime.ToShortDateString () + " " + directoryInfoi.LastAccessTime.ToShortTimeString ()); + + fileStruct2.attributes = FileAttributes.Directory; + + fileHashtable.Add ("Desktop", fileStruct2); + + Items.Add (listViewItem2); + + + listViewItem2 = new ListViewItem ("Personal"); + + index2 = MimeIconEngine.GetIconIndexForMimeType ("directory/home"); + + fileStruct2 = new FileStruct (); + fileStruct2.type = FileStruct.FileStructType.Directoy; + + fileStruct2.fullname = ThemeEngine.Current.Places (UIIcon.PlacesPersonal); + + listViewItem2.ImageIndex = index2; + + listViewItem2.SubItems.Add (""); + listViewItem2.SubItems.Add ("Personal"); +// listViewItem.SubItems.Add (directoryInfoi.LastAccessTime.ToShortDateString () + " " + directoryInfoi.LastAccessTime.ToShortTimeString ()); + + fileStruct2.attributes = FileAttributes.Directory; + + fileHashtable.Add ("Personal", fileStruct2); + + Items.Add (listViewItem2); + + AddNetwork (); + + EndUpdate (); + } + + } else if (kind == FileDialog.network_string) { + + if (masterMount.ProcMountAvailable) { + masterMount.GetMounts (); + + fileHashtable.Clear (); + + BeginUpdate (); + + Items.Clear (); + SelectedItems.Clear (); + + AddNetwork (); + + EndUpdate (); + } + } + } + + private void AddNetwork () + { + foreach (MasterMount.Mount mount in masterMount.Network_devices) { + FileStruct fileStruct = new FileStruct (); + fileStruct.type = FileStruct.FileStructType.Network; + + fileStruct.fullname = mount.mount_point; + + string item_name = "Network (" + mount.fsType + ", " + mount.device_short + ")"; + + ListViewItem listViewItem = new ListViewItem (item_name); + + int index = 0; + + switch (mount.fsType) { + case MasterMount.FsTypes.nfs: + index = MimeIconEngine.GetIconIndexForMimeType ("nfs/nfs"); + break; + case MasterMount.FsTypes.smbfs: + index = MimeIconEngine.GetIconIndexForMimeType ("smb/smb"); + break; + case MasterMount.FsTypes.ncpfs: + index = MimeIconEngine.GetIconIndexForMimeType ("network/network"); + break; + default: + break; + } + + listViewItem.ImageIndex = index; + + listViewItem.SubItems.Add (""); + listViewItem.SubItems.Add ("Network"); +// listViewItem.SubItems.Add (directoryInfoi.LastAccessTime.ToShortDateString () + " " + directoryInfoi.LastAccessTime.ToShortTimeString ()); + + fileStruct.attributes = FileAttributes.Directory; + + fileHashtable.Add (item_name, fileStruct); + + Items.Add (listViewItem); + } + } + + private void DoOneFileInfo (FileInfo fileInfo) + { + if (!ShowHiddenFiles) + if (fileInfo.Name.StartsWith (".") || fileInfo.Attributes == FileAttributes.Hidden) + return; + + FileStruct fileStruct = new FileStruct (); + fileStruct.type = FileStruct.FileStructType.File; + + fileStruct.fullname = fileInfo.FullName; + + string fileName = fileInfo.Name; + + if (fileHashtable.ContainsKey (fileName)) { + int i = 1; + while (fileHashtable.ContainsKey (fileName + "[" + i + "]")) { + i++; + } + fileName += "[" + i + "]"; + } + + ListViewItem listViewItem = new ListViewItem (fileName); + + listViewItem.ImageIndex = MimeIconEngine.GetIconIndexForFile (fileStruct.fullname); + + long fileLen = 1; + try { + if (fileInfo.Length > 1024) + fileLen = fileInfo.Length / 1024; + } catch ( Exception e ) { + fileLen = 1; + } + + fileStruct.size = fileLen; + + listViewItem.SubItems.Add (fileLen.ToString () + " KB"); + listViewItem.SubItems.Add ("File"); + listViewItem.SubItems.Add (fileInfo.LastAccessTime.ToShortDateString () + " " + fileInfo.LastAccessTime.ToShortTimeString ()); + + fileStruct.attributes = FileAttributes.Normal; + + fileHashtable.Add (fileName, fileStruct); + + Items.Add (listViewItem); + } + + private ArrayList GetFreedesktopSpecRecentlyUsed () + { + // check for GNOME and KDE + string personal_folder = ThemeEngine.Current.Places (UIIcon.PlacesPersonal); + string recently_used_path = Path.Combine (personal_folder, ".recently-used"); + + ArrayList files_al = new ArrayList (); + + // GNOME + if (File.Exists (recently_used_path)) { + try { + XmlTextReader xtr = new XmlTextReader (recently_used_path); + while (xtr.Read ()) { + if (xtr.NodeType == XmlNodeType.Element && xtr.Name.ToUpper () == "URI") { + xtr.Read (); + Uri uri = new Uri (xtr.Value); + if (!files_al.Contains (uri.LocalPath)) + files_al.Add (uri.LocalPath); + } + } + xtr.Close (); + } catch ( Exception e ) { + + } + } + + // KDE + string full_kde_recent_document_dir = personal_folder + + "/" + + ".kde/share/apps/RecentDocuments"; + + if (Directory.Exists (full_kde_recent_document_dir)) { + string[] files = Directory.GetFiles (full_kde_recent_document_dir, "*.desktop"); + + foreach (string file_name in files) { + StreamReader sr = new StreamReader (file_name); + + string line = sr.ReadLine (); + + while (line != null) { + line = line.Trim (); + + if (line.StartsWith ("URL=")) { + line = line.Replace ("URL=", ""); + line = line.Replace ("$HOME", personal_folder); + + Uri uri = new Uri (line); + if (!files_al.Contains (uri.LocalPath)) + files_al.Add (uri.LocalPath); + break; + } + + line = sr.ReadLine (); + } + + sr.Close (); + } + } + + + return files_al; + } + + protected override void OnClick (EventArgs e) + { + if (!MultiSelect) { + if (SelectedItems.Count > 0) { + ListViewItem listViewItem = SelectedItems [0]; + + FileStruct fileStruct = (FileStruct)fileHashtable [listViewItem.Text]; + + if (fileStruct.type == FileStruct.FileStructType.File) { + fileName = listViewItem.Text; + fullFileName = fileStruct.fullname; + + if (on_selected_file_changed != null) + on_selected_file_changed (this, EventArgs.Empty); + } + } + } + + base.OnClick (e); + } + + protected override void OnDoubleClick (EventArgs e) + { + if (SelectedItems.Count > 0) { + ListViewItem listViewItem = SelectedItems [0]; + + FileStruct fileStruct = (FileStruct)fileHashtable [listViewItem.Text]; + + if (fileStruct.attributes == FileAttributes.Directory) { + fullFileName = fileStruct.fullname; + + if (on_directory_changed != null) + on_directory_changed (this, EventArgs.Empty); + } else { + fileName = listViewItem.Text; + fullFileName = fileStruct.fullname; + + if (on_selected_file_changed != null) + on_selected_file_changed (this, EventArgs.Empty); + + if (on_force_dialog_end != null) + on_force_dialog_end (this, EventArgs.Empty); + + return; + } + } + + base.OnDoubleClick (e); + } + + protected override void OnSelectedIndexChanged (EventArgs e) + { + if (MultiSelect) { + if (SelectedItems.Count > 0) { + selectedFilesString = ""; + + if (SelectedItems.Count == 1) { + FileStruct fileStruct = (FileStruct)fileHashtable [SelectedItems [0].Text]; + + if (fileStruct.attributes != FileAttributes.Directory) + selectedFilesString = SelectedItems [0].Text; + } else { + foreach (ListViewItem lvi in SelectedItems) { + FileStruct fileStruct = (FileStruct)fileHashtable [lvi.Text]; + + if (fileStruct.attributes != FileAttributes.Directory) + selectedFilesString += "\"" + lvi.Text + "\" "; + } + } + + if (on_selected_files_changed != null) + on_selected_files_changed (this, EventArgs.Empty); + } + } + + base.OnSelectedIndexChanged (e); + } + + protected override void OnMouseMove (MouseEventArgs e) + { + ListViewItem item = GetItemAt (e.X, e.Y); + + if (item != null) { + int currentItemIndex = item.Index; + + if (currentItemIndex != oldItemIndexForToolTip) { + oldItemIndexForToolTip = currentItemIndex; + + if (toolTip != null && toolTip.Active) + toolTip.Active = false; + + object fileStructObject = fileHashtable [item.Text]; + + if (fileStructObject != null) { + + FileStruct fileStruct = (FileStruct)fileStructObject; + + string output = String.Empty; + + if (fileStruct.type == FileStruct.FileStructType.Directoy) + output = String.Format ("Directory: {0}\n", fileStruct.fullname); + else if (fileStruct.type == FileStruct.FileStructType.Device) + output = String.Format ("Device: {0}", fileStruct.fullname); + else if (fileStruct.type == FileStruct.FileStructType.Network) + output = String.Format ("Network: {0}", fileStruct.fullname); + else + output = String.Format ("File: {0}", fileStruct.fullname); + + toolTip.SetToolTip (this, output); + + toolTip.Active = true; + } + } + } + + base.OnMouseMove (e); + } + + private void MWF_KeyUp (object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Back) + if (on_one_directory_up != null) + on_one_directory_up (this, EventArgs.Empty); + } + + public event EventHandler SelectedFileChanged { + add { on_selected_file_changed += value; } + remove { on_selected_file_changed -= value; } + } + + public event EventHandler SelectedFilesChanged { + add { on_selected_files_changed += value; } + remove { on_selected_files_changed -= value; } + } + + public event EventHandler DirectoryChanged { + add { on_directory_changed += value; } + remove { on_directory_changed -= value; } + } + + public event EventHandler ForceDialogEnd { + add { on_force_dialog_end += value; } + remove { on_force_dialog_end -= value; } + } + + public event EventHandler OnDirectoryUp { + add { on_one_directory_up += value; } + remove { on_one_directory_up -= value; } + } + } + + internal class FileFilter { + private ArrayList filterArrayList = new ArrayList(); + + private string filter; + + public FileFilter () + {} + + public FileFilter (string filter) + { + this.filter = filter; + + SplitFilter (); + } + + public ArrayList FilterArrayList { + set { + filterArrayList = value; + } + + get { + return filterArrayList; + } + } + + public string Filter { + set { + filter = value; + + SplitFilter (); + } + + get { + return filter; + } + } + + private void SplitFilter () + { + filterArrayList.Clear (); + + if (filter == null) + throw new NullReferenceException ("Filter"); + + if (filter.Length == 0) + return; + + string[] filters = filter.Split (new char [] {'|'}); + + if ((filters.Length % 2) != 0) + throw new ArgumentException ("Filter"); + + for (int i = 0; i < filters.Length; i += 2) { + FilterStruct filterStruct = new FilterStruct (filters [i], filters [i + 1]); + + filterArrayList.Add (filterStruct); + } + } + } + + internal class DirComboBox : ComboBox { + internal class DirComboBoxItem { + private int imageIndex; + private string name; + private string path; + private int xPos; + + public DirComboBoxItem (int imageIndex, string name, string path, int xPos) + { + this.imageIndex = imageIndex; + this.name = name; + this.path = path; + this.xPos = xPos; + } + + public int ImageIndex { + set { + imageIndex = value; + } + + get { + return imageIndex; + } + } + + public string Name { + set { + name = value; + } + + get { + return name; + } + } + + public string Path { + set { + path = value; + } + + get { + return path; + } + } + + public int XPos { + set { + xPos = value; + } + + get { + return xPos; + } + } + } + + private ImageList imageList = new ImageList(); + + private string currentPath; + + private EventHandler on_directory_changed; + + private bool currentpath_internal_change = false; + + private int platform = (int) Environment.OSVersion.Platform; + private string recently_used_tmp; + private string my_computer_tmp; + private string my_network_tmp; + private Stack dirStack = new Stack(); + + public DirComboBox () + { + SuspendLayout (); + + DrawMode = DrawMode.OwnerDrawFixed; + + 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; + + if ((platform == 4) || (platform == 128)) { + recently_used_tmp = FileDialog.recently_string; + my_computer_tmp = FileDialog.mycomputer_string; + my_network_tmp = FileDialog.network_string; + } else { + recently_used_tmp = ThemeEngine.Current.Places (UIIcon.PlacesRecentDocuments); + my_computer_tmp = ThemeEngine.Current.Places (UIIcon.PlacesMyComputer); + my_network_tmp = ThemeEngine.Current.Places (UIIcon.PlacesMyNetwork); + } + + Items.AddRange (new object [] { + new DirComboBoxItem (0, "Recently used", recently_used_tmp, 0), + new DirComboBoxItem (1, "Desktop", ThemeEngine.Current.Places (UIIcon.PlacesDesktop), 0), + new DirComboBoxItem (2, "Personal folder", ThemeEngine.Current.Places (UIIcon.PlacesPersonal), 0), + new DirComboBoxItem (3, "My Computer", my_computer_tmp, 0), + new DirComboBoxItem (4, "My Network", my_network_tmp, 0) + } + ); + + ResumeLayout (false); + } + + public string CurrentPath { + set { + currentPath = value; + + currentpath_internal_change = true; + + CreateComboList (); + } + get { + return currentPath; + } + } + + private void CreateComboList () + { + int selection = -1; + int child_of = - 1; + + if (currentPath == recently_used_tmp) + selection = 0; + else + if (currentPath == ThemeEngine.Current.Places (UIIcon.PlacesDesktop)) + selection = 1; + else + if (currentPath == ThemeEngine.Current.Places (UIIcon.PlacesPersonal)) + selection = 2; + else + if (currentPath == my_computer_tmp) + selection = 3; + else + if (currentPath == my_network_tmp) + selection = 4; + + child_of = CheckChildOf (); + + BeginUpdate (); + + Items.Clear (); + + Items.Add (new DirComboBoxItem (0, "Recently used", recently_used_tmp, 0)); + + Items.Add (new DirComboBoxItem (1, "Desktop", ThemeEngine.Current.Places (UIIcon.PlacesDesktop), 0)); + if (child_of == 1) + selection = AppendToParent (); + + Items.Add (new DirComboBoxItem (2, "Personal folder", ThemeEngine.Current.Places (UIIcon.PlacesPersonal), 0)); + if (child_of == 2) + selection = AppendToParent (); + + Items.Add (new DirComboBoxItem (3, "My Computer", my_computer_tmp, 0)); + + Items.Add (new DirComboBoxItem (4, "My Network", my_network_tmp, 0)); + + if (selection != -1) + SelectedIndex = selection; + + EndUpdate (); + } + + private int CheckChildOf () + { + dirStack.Clear (); + + if (currentPath == FileDialog.mycomputer_string || + currentPath == FileDialog.network_string || + currentPath == FileDialog.recently_string) + return -1; + + DirectoryInfo di = new DirectoryInfo (currentPath); + + dirStack.Push (di); + + while (di.Parent != null) { + di = di.Parent; + if (di.FullName == ThemeEngine.Current.Places (UIIcon.PlacesDesktop)) + return 1; + else + if (di.FullName == ThemeEngine.Current.Places (UIIcon.PlacesPersonal)) + return 2; + + dirStack.Push (di); + } + + return -1; + } + + private int AppendToParent () + { + int xPos = 0; + int selection = -1; + + while (dirStack.Count != 0) { + DirectoryInfo dii = dirStack.Pop () as DirectoryInfo; + selection = Items.Add (new DirComboBoxItem (5, dii.Name, dii.FullName, xPos + 4)); + xPos += 4; + } + + return selection; + } + + protected override void OnDrawItem (DrawItemEventArgs e) + { + if (e.Index == -1) + return; + + Bitmap bmp = new Bitmap (e.Bounds.Width, e.Bounds.Height, e.Graphics); + Graphics gr = Graphics.FromImage (bmp); + + DirComboBoxItem dcbi = Items [e.Index] as DirComboBoxItem; + + Color backColor = e.BackColor; + Color foreColor = e.ForeColor; + + int xPos = dcbi.XPos; + + if ((e.State & DrawItemState.ComboBoxEdit) != 0) + xPos = 0; + else + if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) { + backColor = ThemeEngine.Current.ColorHighlight; + foreColor = ThemeEngine.Current.ColorHighlightText; + } + + gr.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (backColor), new Rectangle (0, 0, bmp.Width, bmp.Height)); + + gr.DrawString (dcbi.Name, e.Font , ThemeEngine.Current.ResPool.GetSolidBrush (foreColor), new Point (24 + xPos, (bmp.Height - e.Font.Height) / 2)); + gr.DrawImage (imageList.Images [dcbi.ImageIndex], new Rectangle (new Point (xPos + 2, 0), new Size (16, 16))); + + e.Graphics.DrawImage (bmp, e.Bounds.X, e.Bounds.Y); + gr.Dispose (); + bmp.Dispose (); + } + + protected override void OnSelectedIndexChanged (EventArgs e) + { + if (Items.Count > 0) { + DirComboBoxItem dcbi = Items [SelectedIndex] as DirComboBoxItem; + + currentPath = dcbi.Path; + + // call DirectoryChange event only if the user changes the index with the ComboBox + if (!currentpath_internal_change) { + if (on_directory_changed != null) + on_directory_changed (this, EventArgs.Empty); + } + } + + currentpath_internal_change = false; + } + + public event EventHandler DirectoryChanged { + add { on_directory_changed += value; } + remove { on_directory_changed -= value; } + } + } + + // Alexsantas little helper + internal class MasterMount { + // add more... + internal enum FsTypes { + ext2, + ext3, + hpfs, + iso9660, + jfs, + minix, + msdos, + ntfs, + reiserfs, + ufs, + umsdos, + vfat, + sysv, + xfs, + ncpfs, + nfs, + smbfs, + usbfs + } + + internal struct Mount { + public string device_or_filesystem; + public string device_short; + public string mount_point; + public FsTypes fsType; + } + + bool proc_mount_available = false; + + ArrayList block_devices = new ArrayList (); + ArrayList network_devices = new ArrayList (); + ArrayList removable_devices = new ArrayList (); + + private int platform = (int) Environment.OSVersion.Platform; + private MountComparer mountComparer = new MountComparer (); + + public MasterMount () + { + // maybe check if the current user can access /proc/mounts + if ((platform == 4) || (platform == 128)) + if (File.Exists ("/proc/mounts")) + proc_mount_available = true; + } + + public ArrayList Block_devices { + get { + return block_devices; + } + } + + public ArrayList Network_devices { + get { + return network_devices; + } + } + + public ArrayList Removable_devices { + get { + return removable_devices; + } + } + + public bool ProcMountAvailable { + get { + return proc_mount_available; + } + } + + public void GetMounts () + { + if (!proc_mount_available) + return; + + block_devices.Clear (); + network_devices.Clear (); + removable_devices.Clear (); + + try { + StreamReader sr = new StreamReader ("/proc/mounts"); + + string line = sr.ReadLine (); + + while (line != null) { + ProcessProcMountLine (line); + line = sr.ReadLine (); + } + + sr.Close (); + + block_devices.Sort (mountComparer); + network_devices.Sort (mountComparer); + removable_devices.Sort (mountComparer); + } catch { + // bla + } + } + + private void ProcessProcMountLine (string line) + { + string[] split = line.Split (new char [] {' '}); + + if (split != null && split.Length > 0) { + Mount mount = new Mount (); + + if (split [0].StartsWith ("/dev/")) + mount.device_short = split [0].Replace ("/dev/", ""); + else + mount.device_short = split [0]; + + mount.device_or_filesystem = split [0]; + mount.mount_point = split [1]; + + // TODO: other removable devices, floppy + // ssh + + // network mount + if (split [2] == "nfs") { + mount.fsType = FsTypes.nfs; + network_devices.Add (mount); + } else if (split [2] == "smbfs") { + mount.fsType = FsTypes.smbfs; + network_devices.Add (mount); + } else if (split [2] == "ncpfs") { + mount.fsType = FsTypes.ncpfs; + network_devices.Add (mount); + + } else if (split [2] == "iso9660") { //cdrom + mount.fsType = FsTypes.iso9660; + removable_devices.Add (mount); + } else if (split [2] == "usbfs") { //usb ? not tested + mount.fsType = FsTypes.usbfs; + removable_devices.Add (mount); + + } else if (split [0].StartsWith ("/")) { //block devices + if (split [1].StartsWith ("/dev/")) // root static, do not add + return; + + if (split [2] == "ext2") + mount.fsType = FsTypes.ext2; + else if (split [2] == "ext3") + mount.fsType = FsTypes.ext3; + else if (split [2] == "reiserfs") + mount.fsType = FsTypes.reiserfs; + else if (split [2] == "xfs") + mount.fsType = FsTypes.xfs; + else if (split [2] == "vfat") + mount.fsType = FsTypes.vfat; + else if (split [2] == "ntfs") + mount.fsType = FsTypes.ntfs; + else if (split [2] == "msdos") + mount.fsType = FsTypes.msdos; + else if (split [2] == "umsdos") + mount.fsType = FsTypes.umsdos; + else if (split [2] == "hpfs") + mount.fsType = FsTypes.hpfs; + else if (split [2] == "minix") + mount.fsType = FsTypes.minix; + else if (split [2] == "jfs") + mount.fsType = FsTypes.jfs; + + block_devices.Add (mount); + } + } + } + + public class MountComparer : IComparer + { + public int Compare(object mount1, object mount2) + { + return String.Compare(((Mount)mount1).device_short, ((Mount)mount2).device_short); + } + } + } +} + + |