2009-05-26 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / FileDialog.cs
index e95e4c6aa9b4c41aa6626a48cea3919435bffbcf..ad36c708ca85d2c3302cf07e2c06a4f4e80b57c7 100644 (file)
@@ -23,6 +23,7 @@
 //
 //  Alexander Olk      alex.olk@googlemail.com
 //  Gert Driesen (drieseng@users.sourceforge.net)
+//  Eric Petit (surfzoid2002@yahoo.fr)
 //
 // TODO:
 // Keyboard shortcuts (DEL, F5, F2)
@@ -69,6 +70,8 @@ namespace System.Windows.Forms
                private string title;
                private bool validateNames = true;
 #if NET_2_0
+               private bool auto_upgrade_enable = true;
+               private FileDialogCustomPlacesCollection custom_places;
                private bool supportMultiDottedExtensions;
                private bool checkForIllegalChars = true;
 #endif
@@ -86,6 +89,7 @@ namespace System.Windows.Forms
                private ComboBox fileNameComboBox;
                private Label fileNameLabel;
                private MWFFileView mwfFileView;
+               private MwfFileViewItemComparer file_view_comparer;
                private Label searchSaveLabel;
                private ToolBarButton newdirToolBarButton;
                private ToolBarButton backToolBarButton;
@@ -107,7 +111,7 @@ namespace System.Windows.Forms
                internal bool overwritePrompt = true;
                
                private FileFilter fileFilter;
-               
+               private string[] configFileNames = null;                
                private string lastFolder = String.Empty;
                
                private MWFVFS vfs;
@@ -120,15 +124,17 @@ namespace System.Windows.Forms
                private const string x_string = "X";
                private const string y_string = "Y";
                
+               private readonly char [] wildcard_chars = new char [] { '*', '?' };
+
                private bool disable_form_closed_event;
                
                internal FileDialog ()
                {
+                       form = new DialogForm (this);
                        vfs = new MWFVFS ();
                        
                        Size formConfigSize = Size.Empty;
                        Point formConfigLocation = Point.Empty;
-                       string[] configFileNames = null;
                        
                        object formWidth = MWFConfig.GetValue (filedialog_string, width_string);
                        
@@ -157,7 +163,6 @@ namespace System.Windows.Forms
                        menueToolBarButton = new ToolBarButton ();
                        fileTypeLabel = new Label ();
                        openSaveButton = new Button ();
-                       form.AcceptButton = openSaveButton;
                        helpButton = new Button ();
                        popupButtonPanel = new PopupButtonPanel ();
                        upToolBarButton = new ToolBarButton ();
@@ -180,15 +185,15 @@ namespace System.Windows.Forms
                        
                        // searchLabel
                        searchSaveLabel.FlatStyle = FlatStyle.System;
-                       searchSaveLabel.Location = new Point (7, 8);
-                       searchSaveLabel.Size = new Size (72, 21);
+                       searchSaveLabel.Location = new Point (6, 6);
+                       searchSaveLabel.Size = new Size (86, 22);
                        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.Location = new Point (99, 6);
+                       dirComboBox.Size = new Size (261, 22);
                        dirComboBox.TabIndex = 7;
                        
                        // smallButtonToolBar
@@ -213,18 +218,15 @@ namespace System.Windows.Forms
                        
                        // buttonPanel
                        popupButtonPanel.Dock = DockStyle.None;
-                       popupButtonPanel.Location = new Point (7, 37);
+                       popupButtonPanel.Anchor = ((AnchorStyles)((((AnchorStyles.Top | AnchorStyles.Bottom) | AnchorStyles.Left))));
+                       popupButtonPanel.Location = new Point (6, 35);
+                       popupButtonPanel.Size = new Size (87, 338);
                        popupButtonPanel.TabIndex = 9;
                        
                        // 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.Location = new Point (99, 35);
+                       mwfFileView.Size = new Size (450, 283);
                        mwfFileView.MultiSelect = false;
                        mwfFileView.TabIndex = 10;
                        mwfFileView.RegisterSender (dirComboBox);
@@ -233,33 +235,24 @@ namespace System.Windows.Forms
                        // fileNameLabel
                        fileNameLabel.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Left)));
                        fileNameLabel.FlatStyle = FlatStyle.System;
-                       fileNameLabel.Location = new Point (102, 330);
+                       fileNameLabel.Location = new Point (101, 326);
                        fileNameLabel.Size = new Size (70, 21);
                        fileNameLabel.Text = "File name:";
                        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.Location = new Point (195, 326);
+                       fileNameComboBox.Size = new Size (246, 22);
                        fileNameComboBox.TabIndex = 1;
                        fileNameComboBox.MaxDropDownItems = MaxFileNameItems;
-                       
-                       if (configFileNames != null) {
-                               foreach (string configFileName in configFileNames) {
-                                       if (configFileName == null || configFileName.Trim ().Length == 0)
-                                               continue;
-                                       // add no more than 10 items
-                                       if (fileNameComboBox.Items.Count >= MaxFileNameItems)
-                                               break;
-                                       fileNameComboBox.Items.Add (configFileName);
-                               }
-                       }
+                       fileNameComboBox.RestoreContextMenu ();
+                       UpdateRecentFiles ();
                        
                        // fileTypeLabel
                        fileTypeLabel.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Left)));
                        fileTypeLabel.FlatStyle = FlatStyle.System;
-                       fileTypeLabel.Location = new Point (102, 356);
+                       fileTypeLabel.Location = new Point (101, 355);
                        fileTypeLabel.Size = new Size (90, 21);
                        fileTypeLabel.Text = "Files of type:";
                        fileTypeLabel.TextAlign = ContentAlignment.MiddleLeft;
@@ -267,8 +260,8 @@ namespace System.Windows.Forms
                        // fileTypeComboBox
                        fileTypeComboBox.Anchor = ((AnchorStyles)(((AnchorStyles.Bottom | AnchorStyles.Left) | AnchorStyles.Right)));
                        fileTypeComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
-                       fileTypeComboBox.Location = new Point (195, 356);
-                       fileTypeComboBox.Size = new Size (245, 21);
+                       fileTypeComboBox.Location = new Point (195, 355);
+                       fileTypeComboBox.Size = new Size (246, 22);
                        fileTypeComboBox.TabIndex = 2;
                        
                        // backToolBarButton
@@ -297,16 +290,16 @@ namespace System.Windows.Forms
                        // 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.Location = new Point (474, 326);
+                       openSaveButton.Size = new Size (75, 23);
                        openSaveButton.TabIndex = 4;
                        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.Location = new Point (474, 353);
+                       cancelButton.Size = new Size (75, 23);
                        cancelButton.TabIndex = 5;
                        cancelButton.Text = "Cancel";
                        cancelButton.FlatStyle = FlatStyle.System;
@@ -314,11 +307,12 @@ namespace System.Windows.Forms
                        // 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.Location = new Point (474, 353);
+                       helpButton.Size = new Size (75, 23);
                        helpButton.TabIndex = 6;
                        helpButton.Text = "Help";
                        helpButton.FlatStyle = FlatStyle.System;
+                       helpButton.Visible = false;
                        
                        // checkBox
                        readonlyCheckBox.Anchor = ((AnchorStyles)(((AnchorStyles.Bottom | AnchorStyles.Left) | AnchorStyles.Right)));
@@ -327,16 +321,16 @@ namespace System.Windows.Forms
                        readonlyCheckBox.Size = new Size (245, 21);
                        readonlyCheckBox.TabIndex = 3;
                        readonlyCheckBox.FlatStyle = FlatStyle.System;
+                       readonlyCheckBox.Visible = false;
                        
                        form.SizeGripStyle = SizeGripStyle.Show;
-                       
+                       form.AcceptButton = openSaveButton;
                        form.MaximizeBox = true;
                        form.MinimizeBox = true;
                        form.FormBorderStyle = FormBorderStyle.Sizable;
-                       form.MinimumSize = new Size (554, 405);
-                       
-                       form.ClientSize =  new Size (554, 405); // 384
-                       
+                       form.ClientSize =  new Size (555, 385);
+                       form.MinimumSize = form.Size;
+
                        form.Controls.Add (smallButtonToolBar);
                        form.Controls.Add (cancelButton);
                        form.Controls.Add (openSaveButton);
@@ -348,11 +342,13 @@ namespace System.Windows.Forms
                        form.Controls.Add (dirComboBox);
                        form.Controls.Add (searchSaveLabel);
                        form.Controls.Add (popupButtonPanel);
+                       form.Controls.Add (helpButton);
+                       form.Controls.Add (readonlyCheckBox);
                        
-                       form.ResumeLayout (false);
-                       
+                       form.ResumeLayout (true);
+
                        if (formConfigSize != Size.Empty) {
-                               form.Size = formConfigSize;
+                               form.ClientSize = formConfigSize;
                        }
                        
                        if (formConfigLocation != Point.Empty) {
@@ -370,13 +366,15 @@ namespace System.Windows.Forms
                        mwfFileView.SelectedFileChanged += new EventHandler (OnSelectedFileChangedFileView);
                        mwfFileView.ForceDialogEnd += new EventHandler (OnForceDialogEndFileView);
                        mwfFileView.SelectedFilesChanged += new EventHandler (OnSelectedFilesChangedFileView);
+                       mwfFileView.ColumnClick += new ColumnClickEventHandler(OnColumnClickFileView);
                        
                        dirComboBox.DirectoryChanged += new EventHandler (OnDirectoryChangedDirComboBox);
                        popupButtonPanel.DirectoryChanged += new EventHandler (OnDirectoryChangedPopupButtonPanel);
-                       
+
                        readonlyCheckBox.CheckedChanged += new EventHandler (OnCheckCheckChanged);
 #if NET_2_0
                        form.FormClosed += new FormClosedEventHandler (OnFileDialogFormClosed);
+                       custom_places = new FileDialogCustomPlacesCollection ();
 #else
                        form.Closed += new EventHandler (OnFileDialogFormClosed);
 #endif
@@ -393,6 +391,15 @@ namespace System.Windows.Forms
                        }
                }
                
+#if NET_2_0
+               [MonoTODO ("Stub, value not respected")]
+               [DefaultValue (true)]
+               public bool AutoUpgradeEnabled {
+                       get { return auto_upgrade_enable; }
+                       set { auto_upgrade_enable = value; }
+               }
+#endif
+
                [DefaultValue(false)]
                public virtual bool CheckFileExists {
                        get {
@@ -415,6 +422,15 @@ namespace System.Windows.Forms
                        }
                }
                
+#if NET_2_0
+               [MonoTODO ("Stub, collection not used")]
+               [Browsable (false)]
+               [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+               public FileDialogCustomPlacesCollection CustomPlaces {
+                       get { return custom_places; }
+               }
+#endif
+
                [DefaultValue("")]
                public string DefaultExt {
                        get {
@@ -686,20 +702,23 @@ namespace System.Windows.Forms
                                return Title;
                        }
                }
-               
-               [MonoTODO]
-               protected  override IntPtr HookProc (IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam)
+
+               [MonoTODO ("Not implemented, will throw NotImplementedException")]
+               protected override IntPtr HookProc (IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam)
                {
                        throw new NotImplementedException ();
                }
                
                protected void OnFileOk (CancelEventArgs e)
-               {
-                       WriteConfigValues (e);
-                       
+               {       
                        CancelEventHandler fo = (CancelEventHandler) Events [EventFileOk];
                        if (fo != null)
                                fo (this, e);
+               }
+               
+               private void CleanupOnClose ()
+               {
+                       WriteConfigValues ();
                        
                        Mime.CleanFileCache ();
                        
@@ -780,6 +799,16 @@ namespace System.Windows.Forms
                        }
                }
 
+               internal string CustomFilter {
+                       get {
+                               string fname = fileNameComboBox.Text;
+                               if (fname.IndexOfAny (wildcard_chars) == -1)
+                                       return null;
+
+                               return fname;
+                       }
+               }
+
                private void SelectFilter ()
                {
                        int filter_to_select = (filterIndex - 1);
@@ -836,16 +865,16 @@ namespace System.Windows.Forms
                                        if (sl.Count == 1) {
                                                FileViewListViewItem item = sl [0] as FileViewListViewItem;
                                                FSEntry fsEntry = item.FSEntry;
-                                               
-                                               if (fsEntry.Attributes == FileAttributes.Directory) {
-                                                       mwfFileView.ChangeDirectory (null, fsEntry.FullName);
+
+                                               if ((fsEntry.Attributes & FileAttributes.Directory) == FileAttributes.Directory) {
+                                                       mwfFileView.ChangeDirectory (null, fsEntry.FullName, CustomFilter);
                                                        return;
                                                }
                                        } else {
                                                foreach (FileViewListViewItem item in sl) {
                                                        FSEntry fsEntry = item.FSEntry;
-                                                       if (fsEntry.Attributes == FileAttributes.Directory) {
-                                                               mwfFileView.ChangeDirectory (null, fsEntry.FullName);
+                                                       if ((fsEntry.Attributes & FileAttributes.Directory) == FileAttributes.Directory) {
+                                                               mwfFileView.ChangeDirectory (null, fsEntry.FullName, CustomFilter);
                                                                return;
                                                        }
                                                }
@@ -853,6 +882,12 @@ namespace System.Windows.Forms
                                }
                        }
 
+                       // Custom filter, typed by the user, ignoring the stored filters
+                       if (fileNameComboBox.Text.IndexOfAny (wildcard_chars) != -1) {
+                               mwfFileView.UpdateFileView (fileNameComboBox.Text);
+                               return;
+                       }
+
                        ArrayList files = new ArrayList ();
                        FileNamesTokenizer tokenizer = new FileNamesTokenizer (
                                fileNameComboBox.Text, multiSelect);
@@ -880,7 +915,7 @@ namespace System.Windows.Forms
                                } else {
                                        DirectoryInfo dirInfo = new DirectoryInfo (fileName);
                                        if (dirInfo.Exists) {
-                                               mwfFileView.ChangeDirectory (null, dirInfo.FullName);
+                                               mwfFileView.ChangeDirectory (null, dirInfo.FullName, CustomFilter);
                                                fileNameComboBox.Text = null;
                                                return;
                                        } else {
@@ -912,7 +947,7 @@ namespace System.Windows.Forms
 
                                if (checkFileExists) {
                                        if (!File.Exists (internalfullfilename)) {
-                                               string message = "\"" + internalfullfilename + "\" doesn't exist. Please verify that you have entered the correct file name.";
+                                               string message = "\"" + internalfullfilename + "\" does not exist. Please verify that you have entered the correct file name.";
                                                MessageBox.Show (message, openSaveButton.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                                                return;
                                        }
@@ -921,7 +956,7 @@ namespace System.Windows.Forms
                                if (fileDialogType == FileDialogType.SaveFileDialog) {
                                        if (overwritePrompt) {
                                                if (File.Exists (internalfullfilename)) {
-                                                       string message = "\"" + internalfullfilename + "\" exists. Overwrite ?";
+                                                       string message = "\"" + internalfullfilename + "\" already exists. Do you want to overwrite it?";
                                                        DialogResult dr = MessageBox.Show (message, openSaveButton.Text, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
                                                        if (dr == DialogResult.Cancel)
                                                                return;
@@ -930,7 +965,7 @@ namespace System.Windows.Forms
 
                                        if (createPrompt) {
                                                if (!File.Exists (internalfullfilename)) {
-                                                       string message = "\"" + internalfullfilename + "\" doesn't exist. Create ?";
+                                                       string message = "\"" + internalfullfilename + "\" does not exist. Do you want to create it?";
                                                        DialogResult dr = MessageBox.Show (message, openSaveButton.Text, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
                                                        if (dr == DialogResult.Cancel)
                                                                return;
@@ -960,17 +995,29 @@ namespace System.Windows.Forms
                                // remove items above the maximum items that we want to display
                                while (fileNameComboBox.Items.Count > MaxFileNameItems)
                                        fileNameComboBox.Items.RemoveAt (MaxFileNameItems);
+                       } else {
+                               // If a directory is selected, navigate into it
+                               foreach (FileViewListViewItem item in mwfFileView.SelectedItems) {
+                                       FSEntry fsEntry = item.FSEntry;
+                                       
+                                       if ((fsEntry.Attributes & FileAttributes.Directory) == FileAttributes.Directory) {
+                                               mwfFileView.ChangeDirectory (null, fsEntry.FullName, CustomFilter);
+                                               return;
+                                       }
+                               }
+
+                               return;
                        }
 
                        if (checkPathExists && mwfFileView.CurrentRealFolder != null) {
                                if (!Directory.Exists (mwfFileView.CurrentRealFolder)) {
-                                       string message = "\"" + mwfFileView.CurrentRealFolder + "\" doesn't exist. Please verify that you have entered the correct directory name.";
+                                       string message = "\"" + mwfFileView.CurrentRealFolder + "\" does not exist. Please verify that you have entered the correct directory name.";
                                        MessageBox.Show (message, openSaveButton.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
 
                                        if (InitialDirectory.Length == 0 || !Directory.Exists (InitialDirectory))
-                                               mwfFileView.ChangeDirectory (null, lastFolder);
+                                               mwfFileView.ChangeDirectory (null, lastFolder, CustomFilter);
                                        else
-                                               mwfFileView.ChangeDirectory (null, InitialDirectory);
+                                               mwfFileView.ChangeDirectory (null, InitialDirectory, CustomFilter);
                                        return;
                                }
                        }
@@ -986,10 +1033,12 @@ namespace System.Windows.Forms
 
                        CancelEventArgs cancelEventArgs = new CancelEventArgs ();
 
-                       cancelEventArgs.Cancel = false;
-
                        OnFileOk (cancelEventArgs);
 
+                       if (cancelEventArgs.Cancel)
+                               return;
+                               
+                       CleanupOnClose ();
                        form.DialogResult = DialogResult.OK;
                }
 
@@ -1086,12 +1135,8 @@ namespace System.Windows.Forms
                {
                        if (restoreDirectory)
                                mwfFileView.CurrentFolder = restoreDirectoryString;
-                       
-                       CancelEventArgs cancelEventArgs = new CancelEventArgs ();
-                       
-                       cancelEventArgs.Cancel = true;
-                       
-                       OnFileOk (cancelEventArgs);
+
+                       CleanupOnClose ();
                        
                        form.DialogResult = DialogResult.Cancel;
                }
@@ -1104,10 +1149,10 @@ namespace System.Windows.Forms
                void OnClickSmallButtonToolBar (object sender, ToolBarButtonClickEventArgs e)
                {
                        if (e.Button == upToolBarButton) {
-                               mwfFileView.OneDirUp ();
+                               mwfFileView.OneDirUp (CustomFilter);
                        } else
                        if (e.Button == backToolBarButton) {
-                               mwfFileView.PopDir ();
+                               mwfFileView.PopDir (CustomFilter);
                        } else
                        if (e.Button == newdirToolBarButton) {
                                mwfFileView.CreateNewFolder ();
@@ -1120,7 +1165,9 @@ namespace System.Windows.Forms
                                do_not_call_OnSelectedIndexChangedFileTypeComboBox = false;
                                return;
                        }
-                       
+
+                       UpdateRecentFiles ();
+
                        mwfFileView.FilterIndex = fileTypeComboBox.SelectedIndex + 1;
                }
                
@@ -1143,12 +1190,12 @@ namespace System.Windows.Forms
                
                void OnDirectoryChangedDirComboBox (object sender, EventArgs e)
                {
-                       mwfFileView.ChangeDirectory (sender, dirComboBox.CurrentFolder);
+                       mwfFileView.ChangeDirectory (sender, dirComboBox.CurrentFolder, CustomFilter);
                }
                
                void OnDirectoryChangedPopupButtonPanel (object sender, EventArgs e)
                {
-                       mwfFileView.ChangeDirectory (sender, popupButtonPanel.CurrentFolder);
+                       mwfFileView.ChangeDirectory (sender, popupButtonPanel.CurrentFolder, CustomFilter);
                }
                
                void OnCheckCheckChanged (object sender, EventArgs e)
@@ -1167,7 +1214,21 @@ namespace System.Windows.Forms
                        HandleFormClosedEvent (sender);
                }
 #endif
-               
+
+               private void OnColumnClickFileView (object sender, ColumnClickEventArgs e)
+               {
+                       if (file_view_comparer == null)
+                               file_view_comparer = new MwfFileViewItemComparer (true);
+
+                       file_view_comparer.ColumnIndex = e.Column;
+                       file_view_comparer.Ascendent = !file_view_comparer.Ascendent;
+
+                       if (mwfFileView.ListViewItemSorter == null)
+                               mwfFileView.ListViewItemSorter = file_view_comparer;
+                       else
+                               mwfFileView.Sort ();
+               }
+
                void HandleFormClosedEvent (object sender)
                {
                        if (!disable_form_closed_event)
@@ -1195,56 +1256,62 @@ namespace System.Windows.Forms
                        
                        mwfFileView.FilterArrayList = filters;
                }
+
+               private void UpdateRecentFiles ()
+               {
+                       fileNameComboBox.Items.Clear ();
+                       if (configFileNames != null) {
+                               foreach (string configFileName in configFileNames) {
+                                       if (configFileName == null || configFileName.Trim ().Length == 0)
+                                               continue;
+                                       // add no more than 10 items
+                                       if (fileNameComboBox.Items.Count >= MaxFileNameItems)
+                                               break;
+                                       fileNameComboBox.Items.Add (configFileName);
+                               }
+                       }
+               }
                
                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);
+
+                       int fx = form.Size.Width - form.MinimumSize.Width;
+                       int fy = form.Size.Height - form.MinimumSize.Height;
+
+                       if (!ShowHelp && !ShowReadOnly)
+                               fy += 29;
+
+                       mwfFileView.Size = new Size (450 + fx, 254 + fy);
+                       fileNameLabel.Location = new Point (101, 298 + fy);
+                       fileNameComboBox.Location = new Point (195, 298 + fy);
+                       fileTypeLabel.Location = new Point (101, 326 + fy);
+                       fileTypeComboBox.Location = new Point (195, 326 + fy);
+                       openSaveButton.Location = new Point (474 + fx, 298 + fy);
+                       cancelButton.Location = new Point (474 + fx, 324 + fy);
+                       helpButton.Location = new Point (474 + fx, 353 + fy);
+                       readonlyCheckBox.Location = new Point (195, 350 + fy);
+
+                       helpButton.Visible = ShowHelp;
+                       readonlyCheckBox.Visible = ShowReadOnly;
                        
-                       if (ShowReadOnly)
-                               form.Controls.Add (readonlyCheckBox);
-                       else
-                               form.Controls.Remove (readonlyCheckBox);
                        form.ResumeLayout ();
                }
                
-               private void WriteConfigValues (CancelEventArgs ce)
+               private void WriteConfigValues ()
                {
-                       MWFConfig.SetValue (filedialog_string, width_string, form.Width);
-                       MWFConfig.SetValue (filedialog_string, height_string, form.Height);
+                       MWFConfig.SetValue (filedialog_string, width_string, form.ClientSize.Width);
+                       MWFConfig.SetValue (filedialog_string, height_string, form.ClientSize.Height);
                        MWFConfig.SetValue (filedialog_string, x_string, form.Location.X);
                        MWFConfig.SetValue (filedialog_string, y_string, form.Location.Y);
                        
-                       if (!ce.Cancel) {
-                               MWFConfig.SetValue (filedialog_string, lastfolder_string, lastFolder);
+                       MWFConfig.SetValue (filedialog_string, lastfolder_string, lastFolder);
                                
-                               string[] fileNameCBItems = new string [fileNameComboBox.Items.Count];
+                       string[] fileNameCBItems = new string [fileNameComboBox.Items.Count];
                                
-                               fileNameComboBox.Items.CopyTo (fileNameCBItems, 0);
+                       fileNameComboBox.Items.CopyTo (fileNameCBItems, 0);
                                
-                               MWFConfig.SetValue (filedialog_string, filenames_string, fileNameCBItems);
-                       }
+                       MWFConfig.SetValue (filedialog_string, filenames_string, fileNameCBItems);
                }
                
                private void ReadConfigValues ()
@@ -1418,7 +1485,14 @@ namespace System.Windows.Forms
                                        return popupButtonState;
                                }
                        }
-                       
+#if NET_2_0
+                       #region UIA Framework Members
+                       internal void PerformClick ()
+                       {
+                               OnClick (EventArgs.Empty);
+                       }
+                       #endregion
+#endif
                        protected override void OnPaint (PaintEventArgs pe)
                        {
                                Draw (pe);
@@ -1472,7 +1546,7 @@ namespace System.Windows.Forms
                                
                                if (panel.focusButton != null && panel.focusButton.ButtonState == PopupButtonState.Up) {
                                        panel.focusButton.ButtonState = PopupButtonState.Normal;
-                                       panel.focusButton = null;
+                                       panel.SetFocusButton (null);
                                }
                                Invalidate ();
                                base.OnMouseEnter (e);
@@ -1514,6 +1588,7 @@ namespace System.Windows.Forms
                        
                        BackColor = Color.FromArgb (128, 128, 128);
                        Size = new Size (85, 336);
+                       InternalBorderStyle = BorderStyle.Fixed3D;
                        
                        recentlyusedButton = new PopupButton ();
                        desktopButton = new PopupButton ();
@@ -1573,7 +1648,7 @@ namespace System.Windows.Forms
                        
                        SetStyle (ControlStyles.StandardClick, false);
                }
-               
+
                void OnClickButton (object sender, EventArgs e)
                {
                        if (lastPopupButton != null && lastPopupButton != sender as PopupButton)
@@ -1601,6 +1676,28 @@ namespace System.Windows.Forms
                                eh (this, EventArgs.Empty);
                }
                
+#if NET_2_0
+               static object UIAFocusedItemChangedEvent = new object ();
+
+               internal event EventHandler UIAFocusedItemChanged {
+                       add { Events.AddHandler (UIAFocusedItemChangedEvent, value); }
+                       remove { Events.RemoveHandler (UIAFocusedItemChangedEvent, value); }
+               }
+
+               internal void OnUIAFocusedItemChanged ()
+               {
+                       EventHandler eh = (EventHandler) Events [UIAFocusedItemChangedEvent];
+                       if (eh != null)
+                               eh (this, EventArgs.Empty);
+               }
+
+               internal PopupButton UIAFocusButton {
+                       get {
+                               return focusButton;
+                       }
+               }
+#endif
+
                public string CurrentFolder {
                        set {
                                string currentPath = value;
@@ -1655,17 +1752,11 @@ namespace System.Windows.Forms
                        }
                }
                
-               protected override void OnPaint (PaintEventArgs e)
-               {
-                       ControlPaint.DrawBorder3D (e.Graphics, ClientRectangle, Border3DStyle.Sunken);
-                       base.OnPaint (e);
-               }
-               
                protected override void OnGotFocus (EventArgs e)
                {
                        if (lastPopupButton != recentlyusedButton) {
                                recentlyusedButton.ButtonState = PopupButton.PopupButtonState.Up;
-                               focusButton = recentlyusedButton;
+                               SetFocusButton (recentlyusedButton);
                        }
                        currentFocusIndex = 0;
                        
@@ -1723,7 +1814,7 @@ namespace System.Windows.Forms
                                        focusButton.ButtonState = PopupButton.PopupButtonState.Normal;
                                if (newfocusButton.ButtonState != PopupButton.PopupButtonState.Down)
                                        newfocusButton.ButtonState = PopupButton.PopupButtonState.Up;
-                               focusButton = newfocusButton;
+                               SetFocusButton (newfocusButton);
                        }
                        
                        e.Handled = true;
@@ -1735,6 +1826,17 @@ namespace System.Windows.Forms
                        add { Events.AddHandler (PDirectoryChangedEvent, value); }
                        remove { Events.RemoveHandler (PDirectoryChangedEvent, value); }
                }
+
+               internal void SetFocusButton (PopupButton button)
+               {
+                       if (button == focusButton)
+                       return;
+
+                       focusButton = button;
+#if NET_2_0
+                               OnUIAFocusedItemChanged ();
+#endif
+               }
        }
        #endregion
        
@@ -1792,6 +1894,14 @@ namespace System.Windows.Forms
                                        return imageList;
                                }
                        }
+#if NET_2_0
+                       #region UIA Framework Members
+                       public override string ToString ()
+                       {
+                               return name;
+                       }
+                       #endregion
+#endif
                }
                #endregion
                
@@ -2202,6 +2312,8 @@ namespace System.Windows.Forms
                
                private int old_menuitem_index;
                private bool do_update_view = false;
+
+               private ColumnHeader [] columns;
                
                public MWFFileView (MWFVFS vfs)
                {
@@ -2271,12 +2383,31 @@ namespace System.Windows.Forms
                        LabelEdit = true;
                        
                        ContextMenu = contextMenu;
+
+                       // Create columns, but only add them when view changes to Details
+                       columns = new ColumnHeader [4];
+                       columns [0] = CreateColumnHeader (" Name", 170, HorizontalAlignment.Left);
+                       columns [1] = CreateColumnHeader ("Size ", 80, HorizontalAlignment.Right);
+                       columns [2] = CreateColumnHeader (" Type", 100, HorizontalAlignment.Left);
+                       columns [3] = CreateColumnHeader (" Last Access", 150, HorizontalAlignment.Left);
+
+                       AllowColumnReorder = true;
                        
                        ResumeLayout (false);
                        
                        KeyDown += new KeyEventHandler (MWF_KeyDown);
                }
-               
+
+               ColumnHeader CreateColumnHeader (string text, int width, HorizontalAlignment alignment)
+               {
+                       ColumnHeader col = new ColumnHeader ();
+                       col.Text = text;
+                       col.Width = width;
+                       col.TextAlign = alignment;
+
+                       return col;
+               }
+
                public string CurrentFolder {
                        get {
                                return currentFolder;
@@ -2363,8 +2494,13 @@ namespace System.Windows.Forms
                        
                        EnableOrDisableDirstackObjects ();
                }
-               
+
                public void PopDir ()
+               {
+                       PopDir (null);
+               }
+               
+               public void PopDir (string filter)
                {
                        if (directoryStack.Count == 0)
                                return;
@@ -2375,7 +2511,7 @@ namespace System.Windows.Forms
                        
                        should_push = false;
                        
-                       ChangeDirectory (null, new_folder);
+                       ChangeDirectory (null, new_folder, filter);
                }
                
                public void RegisterSender (IUpdateFolder iud)
@@ -2461,15 +2597,25 @@ namespace System.Windows.Forms
                                }
                        }
                }
-               
+
                public void OneDirUp ()
+               {
+                       OneDirUp (null);
+               }
+               
+               public void OneDirUp (string filter)
                {
                        string parent_folder = vfs.GetParent ();
                        if (parent_folder != null)
-                               ChangeDirectory (null, parent_folder);
+                               ChangeDirectory (null, parent_folder, filter);
                }
-               
+
                public void ChangeDirectory (object sender, string folder)
+               {
+                       ChangeDirectory (sender, folder, null);
+               }
+               
+               public void ChangeDirectory (object sender, string folder, string filter)
                {
                        if (folder == MWFVFS.DesktopPrefix || folder == MWFVFS.RecentlyUsedPrefix)
                                folderUpToolBarButton.Enabled = false;
@@ -2514,17 +2660,27 @@ namespace System.Windows.Forms
                        EndUpdate ();
 
                        try {
-                               UpdateFileView ();
+                               UpdateFileView (filter);
                        } catch (Exception e) {
                                if (should_push)
                                        PopDir ();
                                MessageBox.Show (e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                }
-               
+
                public void UpdateFileView ()
                {
-                       if (filterArrayList != null && filterArrayList.Count != 0) {
+                       UpdateFileView (null);
+               }
+               
+               public void UpdateFileView (string custom_filter)
+               {
+                       if (custom_filter != null) {
+                               StringCollection custom_filters = new StringCollection ();
+                               custom_filters.Add (custom_filter);
+
+                               vfs.GetFolderContent (custom_filters);
+                       } else if (filterArrayList != null && filterArrayList.Count != 0) {
                                FilterStruct fs = (FilterStruct)filterArrayList [filterIndex - 1];
                                
                                vfs.GetFolderContent (fs.filters);
@@ -2541,7 +2697,7 @@ namespace System.Windows.Forms
                        
                        foreach (FSEntry directoryFSEntry in directoriesArrayList) {
                                if (!ShowHiddenFiles)
-                                       if (directoryFSEntry.Name.StartsWith (".") || directoryFSEntry.Attributes == FileAttributes.Hidden)
+                                       if (directoryFSEntry.Name.StartsWith (".") || (directoryFSEntry.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
                                                continue;
                                
                                FileViewListViewItem listViewItem = new FileViewListViewItem (directoryFSEntry);
@@ -2617,7 +2773,7 @@ namespace System.Windows.Forms
                private void DoOneFSEntry (FSEntry fsEntry) 
                {
                        if (!ShowHiddenFiles)
-                               if (fsEntry.Name.StartsWith (".")  || fsEntry.Attributes == FileAttributes.Hidden)
+                               if (fsEntry.Name.StartsWith (".") || (fsEntry.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
                                        return;
                        
                        FileViewListViewItem listViewItem = new FileViewListViewItem (fsEntry);
@@ -2629,9 +2785,25 @@ namespace System.Windows.Forms
                {
                        if (e.KeyCode == Keys.Back) {
                                OneDirUp ();
+                       } else if (e.Control && e.KeyCode == Keys.A && MultiSelect) {
+                               foreach (ListViewItem lvi in Items)
+                                       lvi.Selected = true;
                        }
                }
                
+#if NET_2_0
+               #region UIA Framework Members
+               internal void PerformClick ()
+               {
+                       OnClick (EventArgs.Empty);
+               }
+
+               internal void PerformDoubleClick ()
+               {
+                       OnDoubleClick (EventArgs.Empty);
+               }
+               #endregion
+#endif
                protected override void OnClick (EventArgs e)
                {
                        if (!MultiSelect) {
@@ -2659,8 +2831,8 @@ namespace System.Windows.Forms
                                FileViewListViewItem listViewItem = SelectedItems [0] as FileViewListViewItem;
                                
                                FSEntry fsEntry = listViewItem.FSEntry;
-                               
-                               if (fsEntry.Attributes == FileAttributes.Directory) {
+
+                               if ((fsEntry.Attributes & FileAttributes.Directory) == FileAttributes.Directory) {
                                        
                                        ChangeDirectory (null, fsEntry.FullName);
                                        
@@ -2695,13 +2867,13 @@ namespace System.Windows.Forms
                                        
                                        FSEntry fsEntry = listViewItem.FSEntry;
 
-                                       if (fsEntry.Attributes != FileAttributes.Directory)
+                                       if ((fsEntry.Attributes & FileAttributes.Directory) != FileAttributes.Directory)
                                                selectedFilesString = SelectedItems [0].Text;
                                } else {
                                        foreach (FileViewListViewItem lvi in SelectedItems) {
                                                FSEntry fsEntry = lvi.FSEntry;
 
-                                               if (fsEntry.Attributes != FileAttributes.Directory)
+                                               if ((fsEntry.Attributes & FileAttributes.Directory) != FileAttributes.Directory)
                                                        selectedFilesString = selectedFilesString + "\"" + lvi.Text + "\" ";
                                        }
                                }
@@ -2767,14 +2939,19 @@ namespace System.Windows.Forms
                        
                        UpdateMenuItems (senderMenuItem);
                        
-                       // update me
+                       // update me - call BeginUpdate/EndUpdate to avoid flicker when columns change
                        
+                       BeginUpdate ();
                        switch (senderMenuItem.Index) {
                                case 0:
                                        View = View.SmallIcon;
                                        break;
                                case 1:
+#if NET_2_0
+                                       View = View.Tile;
+#else
                                        View = View.LargeIcon;
+#endif
                                        break;
                                case 2:
                                        View = View.LargeIcon;
@@ -2788,6 +2965,15 @@ namespace System.Windows.Forms
                                default:
                                        break;
                        }
+
+                       if (View == View.Details)
+                               Columns.AddRange (columns);
+                       else {
+                               ListViewItemSorter = null;
+                               Columns.Clear ();
+                       }
+
+                       EndUpdate ();
                }
 
                protected override void OnBeforeLabelEdit (LabelEditEventArgs e)
@@ -2947,8 +3133,56 @@ namespace System.Windows.Forms
                        }
                }
        }
+
        #endregion
        
+       #region MwfFileViewItemComparer
+       class MwfFileViewItemComparer : IComparer
+       {
+               int column_index;
+               bool asc;
+
+               public MwfFileViewItemComparer (bool asc)
+               {
+                       this.asc = asc;
+               }
+
+               public int ColumnIndex {
+                       get {
+                               return column_index;
+                       }
+                       set {
+                               column_index = value;
+                       }
+               }
+
+               public bool Ascendent {
+                       get {
+                               return asc;
+                       }
+                       set {
+                               asc = value;
+                       }
+               }
+
+               public int Compare (object a, object b)
+               {
+                       ListViewItem item_a = (ListViewItem)a;
+                       ListViewItem item_b = (ListViewItem)b;
+
+                       int retval;
+                       if (asc)
+                               retval = String.Compare (item_a.SubItems [column_index].Text, 
+                                               item_b.SubItems [column_index].Text);
+                       else
+                               retval = String.Compare (item_b.SubItems [column_index].Text,
+                                               item_a.SubItems [column_index].Text);
+
+                       return retval;
+               }
+       }
+       #endregion
+
        #region IUpdateFolder
        internal interface IUpdateFolder
        {
@@ -3239,7 +3473,7 @@ namespace System.Windows.Forms
                                } else
                                        File.Move (sourceFileName, destFileName);
                        } catch (Exception e) {
-                               MessageBox.Show (e.Message, "Error Renaming Folder",
+                               MessageBox.Show (e.Message, "Error Renaming File",
                                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                                return false;
                        }
@@ -3267,6 +3501,7 @@ namespace System.Windows.Forms
                protected FSEntry currentFolderFSEntry = null;
                protected FSEntry currentTopFolderFSEntry = null;
                private FileInfoComparer fileInfoComparer = new FileInfoComparer ();
+               private FSEntryComparer fsEntryComparer = new FSEntryComparer ();
                
                public FSEntry ChangeDirectory (string folder)
                {
@@ -3411,20 +3646,22 @@ namespace System.Windows.Forms
                        directories_out = new ArrayList ();
                        
                        DirectoryInfo[] dirs = null;
-                       
+
                        try {
                                dirs = dirinfo.GetDirectories ();
                        } catch (Exception) {}
-                       
+
                        if (dirs != null)
                                for (int i = 0; i < dirs.Length; i++) {
                                        directories_out.Add (GetDirectoryFSEntry (dirs [i], currentTopFolderFSEntry));
                                }
+
+                       directories_out.Sort (fsEntryComparer);
                        
                        files_out = new ArrayList ();
                        
                        ArrayList files = new ArrayList ();
-                       
+
                        try {
                                if (filters == null) {
                                        files.AddRange (dirinfo.GetFiles ());
@@ -3435,14 +3672,14 @@ namespace System.Windows.Forms
                                        files.Sort (fileInfoComparer);
                                }
                        } catch (Exception) {}
-                       
+
                        for (int i = 0; i < files.Count; i++) {
                                FSEntry fs = GetFileFSEntry (files [i] as FileInfo);
                                if (fs != null)
                                        files_out.Add (fs);
                        }
                }
-               
+
                protected ArrayList GetNormalFolders (string from_folder)
                {
                        DirectoryInfo dirinfo = new DirectoryInfo (from_folder);
@@ -3505,7 +3742,15 @@ namespace System.Windows.Forms
                                return String.Compare (((FileInfo)fileInfo1).Name, ((FileInfo)fileInfo2).Name);
                        }
                }
-               
+
+               internal class FSEntryComparer : IComparer
+               {
+                       public int Compare (object fileInfo1, object fileInfo2)
+                       {
+                               return String.Compare (((FSEntry)fileInfo1).Name, ((FSEntry)fileInfo2).Name);
+                       }
+               }
+       
                protected abstract FSEntry GetDesktopFSEntry ();
                
                protected abstract FSEntry GetRecentlyUsedFSEntry ();