New test.
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / FileDialog.cs
index 73ecbe21bafbbcf03379a820e9b0742b6e8e3962..b5078c50c0398f28815fb28a59a43550254b12ac 100644 (file)
@@ -53,16 +53,17 @@ namespace System.Windows.Forms {
                private bool addExtension = true;
                private bool checkFileExists = false;
                private bool checkPathExists = true;
-               private string defaultExt = "";
+               private string defaultExt = String.Empty;
                private bool dereferenceLinks = true;
-               private string fileName = "";
+               private string fileName = String.Empty;
                private string[] fileNames;
-               private string filter;
+               private string filter = "";
                private int filterIndex = 1;
-               private string initialDirectory = "";
+               private int setFilterIndex = 1;
+               private string initialDirectory = String.Empty;
                private bool restoreDirectory = false;
                private bool showHelp = false;
-               private string title = "";
+               private string title = String.Empty;
                private bool validateNames = true;
                
                private Button cancelButton;
@@ -87,7 +88,7 @@ namespace System.Windows.Forms {
                
                private bool multiSelect = false;
                
-               private string restoreDirectoryString = "";
+               private string restoreDirectoryString = String.Empty;
                
                internal FileDialogType fileDialogType;
                
@@ -100,7 +101,7 @@ namespace System.Windows.Forms {
                
                internal FileFilter fileFilter;
                
-               private string lastFolder = "";
+               private string lastFolder = String.Empty;
                
                private MWFVFS vfs;
                
@@ -441,8 +442,19 @@ namespace System.Windows.Forms {
                        
                        set {
                                if (value != null) {
-                                       if (SetFileName (value))
+                                       if (SetFileName (value)) {
                                                fileName = value;
+                                               if (fileNames == null) {
+                                                       fileNames = new string [1];
+                                                       fileNames [0] = value;
+                                               }
+                                       }
+                               } else {
+                                       fileName = String.Empty;
+                                       fileNames = new string [0];
+                                       // this does not match ms exactly,
+                                       // but there is no other way to clear that %#&?ยง combobox
+                                       fileNameComboBox.Text = " ";
                                }
                        }
                }
@@ -470,12 +482,18 @@ namespace System.Windows.Forms {
                        }
                        
                        set {
-                               if (value == null)
-                                       throw new NullReferenceException ("Filter");
-                               
-                               filter = value;
-                               
-                               fileFilter = new FileFilter (filter);
+                               if (value == null) {
+                                       filter = "";
+                                       if (fileFilter != null)
+                                               fileFilter.FilterArrayList.Clear ();
+                               } else {
+                                       if (FileFilter.CheckFilter (value)) {
+                                               filter = value;
+                                               
+                                               fileFilter = new FileFilter (filter);
+                                       } else
+                                               throw new ArgumentException ();
+                               }
                                
                                UpdateFilters ();
                        }
@@ -484,14 +502,16 @@ namespace System.Windows.Forms {
                [DefaultValue(1)]
                public int FilterIndex {
                        get {
-                               return filterIndex;
+                               return setFilterIndex;
                        }
                        
                        set {
-                               if (fileFilter != null && fileFilter.FilterArrayList.Count > value)
-                                       return;  // FIXME: throw an exception ?
+                               setFilterIndex = value;
                                
-                               filterIndex = value;
+                               if (value < 1)
+                                       filterIndex = 1;
+                               else
+                                       filterIndex = value;
                                
                                SelectFilter ();
                        }
@@ -576,16 +596,15 @@ namespace System.Windows.Forms {
                        addExtension = true;
                        checkFileExists = false;
                        checkPathExists = true;
-                       defaultExt = "";
+                       defaultExt = String.Empty;
                        dereferenceLinks = true;
-                       fileName = "";
-                       fileNames = null;
-                       Filter = "";
-                       filterIndex = 1;
-                       initialDirectory = "";
+                       FileName = String.Empty;
+                       Filter = String.Empty;
+                       FilterIndex = 1;
+                       initialDirectory = String.Empty;
                        restoreDirectory = false;
                        ShowHelp = false;
-                       Title = "";
+                       Title = String.Empty;
                        validateNames = true;
                        
                        UpdateFilters ();
@@ -593,7 +612,7 @@ namespace System.Windows.Forms {
                
                public override string ToString ()
                {
-                       return base.ToString ();
+                       return String.Format("{0}: Title: {1}, FileName: {2}", base.ToString (), Title, fileName);
                }
                
                public event CancelEventHandler FileOk {
@@ -690,15 +709,15 @@ namespace System.Windows.Forms {
                
                private void SelectFilter ()
                {
-                       if (FilterIndex > mwfFileView.FilterArrayList.Count)
+                       if (mwfFileView.FilterArrayList == null || filterIndex > mwfFileView.FilterArrayList.Count)
                                return;
                        
                        do_not_call_OnSelectedIndexChangedFileTypeComboBox = true;
                        fileTypeComboBox.BeginUpdate ();
-                       fileTypeComboBox.SelectedIndex = FilterIndex - 1;
+                       fileTypeComboBox.SelectedIndex = filterIndex - 1;
                        fileTypeComboBox.EndUpdate ();
                        
-                       mwfFileView.FilterIndex = FilterIndex;
+                       mwfFileView.FilterIndex = filterIndex;
                }
                
                private bool SetFileName (string fname)
@@ -754,7 +773,7 @@ namespace System.Windows.Forms {
                                }
                        }
                        
-                       string internalfullfilename = "";
+                       string internalfullfilename = String.Empty;
                        
                        if (!multiSelect) {
                                string fileFromComboBox = fileNameComboBox.Text.Trim ();
@@ -823,8 +842,8 @@ namespace System.Windows.Forms {
                                
                                if (fileDialogType == FileDialogType.SaveFileDialog) {
                                        if (addExtension) {
-                                               string extension_to_use = "";
-                                               string filter_exentsion = "";
+                                               string extension_to_use = String.Empty;
+                                               string filter_exentsion = String.Empty;
                                                
                                                if (fileFilter != null) {
                                                        FilterStruct filterstruct = (FilterStruct)fileFilter.FilterArrayList [filterIndex - 1];
@@ -843,13 +862,14 @@ namespace System.Windows.Forms {
                                                        }
                                                }
                                                
-                                               if (filter_exentsion != "")
+                                               if (filter_exentsion != String.Empty)
                                                        extension_to_use = filter_exentsion;
                                                else
-                                               if (defaultExt != "")
+                                               if (defaultExt != String.Empty)
                                                        extension_to_use = "." + defaultExt;
                                                
-                                               internalfullfilename += extension_to_use;
+                                               if (!internalfullfilename.EndsWith (extension_to_use))
+                                                       internalfullfilename += extension_to_use;
                                        }
                                }
                                
@@ -999,6 +1019,9 @@ namespace System.Windows.Forms {
                
                private void UpdateFilters ()
                {
+                       if (fileFilter == null)
+                               fileFilter = new FileFilter ();
+                       
                        ArrayList filters = fileFilter.FilterArrayList;
                        
                        fileTypeComboBox.BeginUpdate ();
@@ -1009,13 +1032,14 @@ namespace System.Windows.Forms {
                                fileTypeComboBox.Items.Add (fs.filterName);
                        }
                        
-                       fileTypeComboBox.SelectedIndex = FilterIndex - 1;
+                       if (filters.Count > 0 && FilterIndex <= filters.Count)
+                               fileTypeComboBox.SelectedIndex = filterIndex - 1;
                        
                        fileTypeComboBox.EndUpdate ();
                        
                        mwfFileView.FilterArrayList = filters;
                        
-                       mwfFileView.FilterIndex = FilterIndex;
+                       mwfFileView.FilterIndex = filterIndex;
                }
                
                private void ResizeAndRelocateForHelpOrReadOnly ()
@@ -1079,10 +1103,10 @@ namespace System.Windows.Forms {
                                }
                        }
                        
-                       if (initialDirectory != "")
+                       if (initialDirectory != String.Empty)
                                lastFolder = initialDirectory;
                        else
-                       if (lastFolder == null || lastFolder == "")
+                       if (lastFolder == null || lastFolder == String.Empty)
                                lastFolder = Environment.CurrentDirectory;
                        
                        if (RestoreDirectory)
@@ -1519,8 +1543,6 @@ namespace System.Windows.Forms {
                
                private EventHandler on_directory_changed;
                
-               private bool currentpath_internal_change = false;
-               
                private Stack folderStack = new Stack();
                
                private static readonly int indent = 6;
@@ -1575,8 +1597,6 @@ namespace System.Windows.Forms {
                        set {
                                currentPath = value;
                                
-                               currentpath_internal_change = true;
-                               
                                CreateComboList ();
                        }
                        get {
@@ -1754,15 +1774,13 @@ namespace System.Windows.Forms {
                                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;
+               }
+               
+               protected override void OnSelectionChangeCommitted (EventArgs e)
+               {
+                       if (on_directory_changed != null)
+                               on_directory_changed (this, EventArgs.Empty);
                }
                
                public event EventHandler DirectoryChanged {
@@ -1790,8 +1808,9 @@ namespace System.Windows.Forms {
                private void SplitFilters (string filter)
                {
                        string[] split = filter.Split (new char [] {';'});
-                       
-                       filters.AddRange (split);
+                       foreach (string s in split) {
+                               filters.Add (s.Trim ());
+                       }
                }
        }
        #endregion
@@ -1806,13 +1825,26 @@ namespace System.Windows.Forms {
                public FileFilter ()
                {}
                
-               public FileFilter (string filter)
+               public FileFilter (string filter) : base ()
                {
                        this.filter = filter;
                        
                        SplitFilter ();
                }
                
+               public static bool CheckFilter (string val)
+               {
+                       if (val.Length == 0)
+                               return true;
+                       
+                       string[] filters = val.Split (new char [] {'|'});
+                       
+                       if ((filters.Length % 2) != 0)
+                               return false;
+                       
+                       return true;
+               }
+               
                public ArrayList FilterArrayList {
                        set {
                                filterArrayList = value;
@@ -1839,17 +1871,11 @@ namespace System.Windows.Forms {
                {
                        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]);
                                
@@ -2122,7 +2148,7 @@ namespace System.Windows.Forms {
                        TextEntryDialog ted = new TextEntryDialog ();
                        ted.IconPictureBoxImage = MimeIconEngine.LargeIcons.Images.GetImage (fsEntry.IconIndex);
                        
-                       string folder = "";
+                       string folder = String.Empty;
                        
                        if (currentFolderFSEntry.RealName != null)
                                folder = currentFolderFSEntry.RealName;
@@ -2399,7 +2425,7 @@ namespace System.Windows.Forms {
                protected override void OnSelectedIndexChanged (EventArgs e)
                {
                        if (SelectedItems.Count > 0) {
-                               selectedFilesString = "";
+                               selectedFilesString = String.Empty;
                                
                                if (SelectedItems.Count == 1) {
                                        FileViewListViewItem listViewItem = SelectedItems [0] as FileViewListViewItem;
@@ -2454,7 +2480,8 @@ namespace System.Windows.Forms {
                                        
                                        toolTip.Active = true;
                                }
-                       }
+                       } else
+                               toolTip.Active = false;
                        
                        base.OnMouseMove (e);
                }
@@ -2554,7 +2581,7 @@ namespace System.Windows.Forms {
                        
                        switch (fsEntry.FileType) {
                                case FSEntry.FSEntryType.Directory:
-                                       SubItems.Add ("");
+                                       SubItems.Add (String.Empty);
                                        SubItems.Add ("Directory");
                                        SubItems.Add (fsEntry.LastAccessTime.ToShortDateString () + " " + fsEntry.LastAccessTime.ToShortTimeString ()); 
                                        break;
@@ -2572,12 +2599,12 @@ namespace System.Windows.Forms {
                                        SubItems.Add (fsEntry.LastAccessTime.ToShortDateString () + " " + fsEntry.LastAccessTime.ToShortTimeString ()); 
                                        break;
                                case FSEntry.FSEntryType.Device:
-                                       SubItems.Add ("");
+                                       SubItems.Add (String.Empty);
                                        SubItems.Add ("Device");
                                        SubItems.Add (fsEntry.LastAccessTime.ToShortDateString () + " " + fsEntry.LastAccessTime.ToShortTimeString ()); 
                                        break;
                                case FSEntry.FSEntryType.RemovableDevice:
-                                       SubItems.Add ("");
+                                       SubItems.Add (String.Empty);
                                        SubItems.Add ("RemovableDevice");
                                        SubItems.Add (fsEntry.LastAccessTime.ToShortDateString () + " " + fsEntry.LastAccessTime.ToShortTimeString ()); 
                                        break;
@@ -2655,7 +2682,7 @@ namespace System.Windows.Forms {
                        newNameTextBox.Location = new Point (16, 128);
                        newNameTextBox.Size = new Size (200, 20);
                        newNameTextBox.TabIndex = 5;
-                       newNameTextBox.Text = "";
+                       newNameTextBox.Text = String.Empty;
                        
                        // okButton
                        okButton.DialogResult = DialogResult.OK;
@@ -2871,9 +2898,10 @@ namespace System.Windows.Forms {
        #region FileSystem
        internal abstract class FileSystem
        {
-               protected string currentTopFolder = "";
+               protected string currentTopFolder = String.Empty;
                protected FSEntry currentFolderFSEntry = null;
                protected FSEntry currentTopFolderFSEntry = null;
+               private FileInfoComparer fileInfoComparer = new FileInfoComparer ();
                
                public FSEntry ChangeDirectory (string folder)
                {
@@ -3017,25 +3045,36 @@ namespace System.Windows.Forms {
                        
                        directories_out = new ArrayList ();
                        
-                       DirectoryInfo[] dirs = dirinfo.GetDirectories ();
+                       DirectoryInfo[] dirs = null;
                        
-                       for (int i = 0; i < dirs.Length; i++) {
-                               directories_out.Add (GetDirectoryFSEntry (dirs [i], currentTopFolderFSEntry));
-                       }
+                       try {
+                               dirs = dirinfo.GetDirectories ();
+                       } catch (Exception) {}
+                       
+                       if (dirs != null)
+                               for (int i = 0; i < dirs.Length; i++) {
+                                       directories_out.Add (GetDirectoryFSEntry (dirs [i], currentTopFolderFSEntry));
+                               }
                        
                        files_out = new ArrayList ();
                        
                        ArrayList files = new ArrayList ();
                        
-                       if (filters == null) {
-                               files.AddRange (dirinfo.GetFiles ());
-                       } else {
-                               foreach (string s in filters)
-                                       files.AddRange (dirinfo.GetFiles (s));
-                       }
+                       try {
+                               if (filters == null) {
+                                       files.AddRange (dirinfo.GetFiles ());
+                               } else {
+                                       foreach (string s in filters)
+                                               files.AddRange (dirinfo.GetFiles (s));
+                                       
+                                       files.Sort (fileInfoComparer);
+                               }
+                       } catch (Exception) {}
                        
                        for (int i = 0; i < files.Count; i++) {
-                               files_out.Add (GetFileFSEntry (files [i] as FileInfo));
+                               FSEntry fs = GetFileFSEntry (files [i] as FileInfo);
+                               if (fs != null)
+                                       files_out.Add (fs);
                        }
                }
                
@@ -3045,11 +3084,16 @@ namespace System.Windows.Forms {
                        
                        ArrayList directories_out = new ArrayList ();
                        
-                       DirectoryInfo[] dirs = dirinfo.GetDirectories ();
+                       DirectoryInfo[] dirs = null;
                        
-                       for (int i = 0; i < dirs.Length; i++) {
-                               directories_out.Add (GetDirectoryFSEntry (dirs [i], currentTopFolderFSEntry));
-                       }
+                       try {
+                               dirs = dirinfo.GetDirectories ();
+                       } catch (Exception) {}
+                       
+                       if (dirs != null)
+                               for (int i = 0; i < dirs.Length; i++) {
+                                       directories_out.Add (GetDirectoryFSEntry (dirs [i], currentTopFolderFSEntry));
+                               }
                        
                        return directories_out;
                }
@@ -3071,6 +3115,11 @@ namespace System.Windows.Forms {
                
                protected virtual FSEntry GetFileFSEntry (FileInfo fileinfo)
                {
+                       // *sigh* FileInfo gives us no usable information for links to directories
+                       // so, return null
+                       if ((fileinfo.Attributes & FileAttributes.Directory) == FileAttributes.Directory)
+                               return null;
+                       
                        FSEntry fs = new FSEntry ();
                        
                        fs.Attributes = fileinfo.Attributes;
@@ -3078,14 +3127,19 @@ namespace System.Windows.Forms {
                        fs.Name = fileinfo.Name;
                        fs.FileType = FSEntry.FSEntryType.File;
                        fs.IconIndex = MimeIconEngine.GetIconIndexForFile (fileinfo.FullName);
+                       fs.FileSize = fileinfo.Length;
                        fs.LastAccessTime = fileinfo.LastAccessTime;
-                       // the following catches broken symbolic links
-                       if ((int)fs.Attributes != 0)
-                               fs.FileSize = fileinfo.Length;
                        
                        return fs;
                }
                
+               internal class FileInfoComparer : IComparer
+               {
+                       public int Compare (object fileInfo1, object fileInfo2)
+                       {
+                               return String.Compare (((FileInfo)fileInfo1).Name, ((FileInfo)fileInfo2).Name);
+                       }
+               }
                
                protected abstract FSEntry GetDesktopFSEntry ();
                
@@ -3262,7 +3316,7 @@ namespace System.Windows.Forms {
                                }
                        } else {
                                XmlDocument xml_doc = new XmlDocument ();
-                               xml_doc.AppendChild (xml_doc.CreateXmlDeclaration ("1.0", "", ""));
+                               xml_doc.AppendChild (xml_doc.CreateXmlDeclaration ("1.0", String.Empty, String.Empty));
                                
                                XmlElement recentFiles_element = xml_doc.CreateElement ("RecentFiles");
                                
@@ -3322,8 +3376,11 @@ namespace System.Windows.Forms {
                                                        xtr.Read ();
                                                        Uri uri = new Uri (xtr.Value);
                                                        if (!files_al.Contains (uri.LocalPath))
-                                                               if (File.Exists (uri.LocalPath))
-                                                                       files_al.Add (GetFileFSEntry (new FileInfo (uri.LocalPath)));
+                                                               if (File.Exists (uri.LocalPath)) {
+                                                                       FSEntry fs = GetFileFSEntry (new FileInfo (uri.LocalPath));
+                                                                       if (fs != null)
+                                                                               files_al.Add (fs);
+                                                               }
                                                }
                                        }
                                        xtr.Close ();
@@ -3345,13 +3402,16 @@ namespace System.Windows.Forms {
                                                line = line.Trim ();
                                                
                                                if (line.StartsWith ("URL=")) {
-                                                       line = line.Replace ("URL=", "");
+                                                       line = line.Replace ("URL=", String.Empty);
                                                        line = line.Replace ("$HOME", personal_folder);
                                                        
                                                        Uri uri = new Uri (line);
                                                        if (!files_al.Contains (uri.LocalPath))
-                                                               if (File.Exists (uri.LocalPath))
-                                                                       files_al.Add (GetFileFSEntry (new FileInfo (uri.LocalPath)));
+                                                               if (File.Exists (uri.LocalPath)) {
+                                                                       FSEntry fs = GetFileFSEntry (new FileInfo (uri.LocalPath));
+                                                                       if (fs != null)
+                                                                               files_al.Add (fs);
+                                                               }
                                                        break;
                                                }
                                                
@@ -3594,7 +3654,9 @@ namespace System.Windows.Forms {
                        FileInfo[] fileinfos = di.GetFiles ();
                        
                        foreach (FileInfo fi in fileinfos) {
-                               al.Add (GetFileFSEntry (fi));
+                               FSEntry fs = GetFileFSEntry (fi);
+                               if (fs != null)
+                                       al.Add (fs);
                        }
                        
                        return al;
@@ -4002,7 +4064,7 @@ namespace System.Windows.Forms {
                                Mount mount = new Mount ();
                                
                                if (split [0].StartsWith ("/dev/"))
-                                       mount.device_short = split [0].Replace ("/dev/", "");
+                                       mount.device_short = split [0].Replace ("/dev/", String.Empty);
                                else 
                                        mount.device_short = split [0];
                                
@@ -4520,7 +4582,7 @@ namespace System.Windows.Forms {
                                
                                private void WriteSingleContent (XmlTextWriter xtw)
                                {
-                                       string type_string = "";
+                                       string type_string = String.Empty;
                                        
                                        if (value is string)
                                                type_string = "string";
@@ -4544,8 +4606,8 @@ namespace System.Windows.Forms {
                                
                                private void WriteArrayContent (XmlTextWriter xtw)
                                {
-                                       string type_string = "";
-                                       string type_name = "";
+                                       string type_string = String.Empty;
+                                       string type_name = String.Empty;
                                        
                                        if (value is string[]) {
                                                type_string = "string-array";