merge -r 60439:60440
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / FileDialog.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2004-2006 Novell, Inc. (http://www.novell.com)
21 //
22 // Authors:
23 //
24 //  Alexander Olk       xenomorph2@onlinehome.de
25 //
26
27 // NOT COMPLETE - work in progress
28
29 using System;
30 using System.Drawing;
31 using System.ComponentModel;
32 using System.Resources;
33 using System.IO;
34 using System.Collections;
35 using System.Collections.Specialized;
36 using System.Xml;
37
38 namespace System.Windows.Forms {
39         [DefaultProperty ("FileName")]
40         [DefaultEvent ("FileOk")]
41         public abstract class FileDialog : CommonDialog {
42                 protected static readonly object EventFileOk = new object ();
43                 
44                 internal enum FileDialogType {
45                         OpenFileDialog,
46                         SaveFileDialog
47                 }
48                 
49                 private bool addExtension = true;
50                 private bool checkFileExists = false;
51                 private bool checkPathExists = true;
52                 private string defaultExt = "";
53                 private bool dereferenceLinks = true;
54                 private string fileName = "";
55                 private string[] fileNames;
56                 private string filter;
57                 private int filterIndex = 1;
58                 private string initialDirectory = "";
59                 private bool restoreDirectory = false;
60                 private bool showHelp = false;
61                 private string title = "";
62                 private bool validateNames = true;
63                 
64                 private Button cancelButton;
65                 private ToolBarButton upToolBarButton;
66                 private PopupButtonPanel popupButtonPanel;
67                 private Button openSaveButton;
68                 private Button helpButton;
69                 private Label fileTypeLabel;
70                 private ToolBarButton menueToolBarButton;
71                 private ContextMenu menueToolBarButtonContextMenu;
72                 private ToolBar smallButtonToolBar;
73                 private DirComboBox dirComboBox;
74                 private ComboBox fileNameComboBox;
75                 private Label fileNameLabel;
76                 private MWFFileView mwfFileView;
77                 private Label searchSaveLabel;
78                 private ToolBarButton newdirToolBarButton;
79                 private ToolBarButton backToolBarButton;
80                 private ComboBox fileTypeComboBox;
81                 private ImageList imageListTopToolbar;
82                 private ContextMenu contextMenu;
83                 private CheckBox readonlyCheckBox;
84                 
85                 private string currentDirectoryName;
86                 private string currentFileName = "";
87                 // store current directoryInfo
88                 private DirectoryInfo currentDirectoryInfo;
89                 // store DirectoryInfo for backButton
90                 private Stack directoryStack = new Stack();
91                 private MenuItem previousCheckedMenuItem;
92                 private bool multiSelect = false;
93                 
94                 private string restoreDirectoryString = "";
95                 
96                 private bool show_special_case = false;
97                 
98                 internal static readonly string recently_string = "[recently/recently]";
99                 internal static readonly string network_string = "[network/network]";
100                 internal static readonly string mycomputer_string = "[mycomputer/mycomputer]";
101                 
102                 private string current_special_case;
103                 
104                 internal FileDialogType fileDialogType;
105                 
106                 private bool do_not_call_OnSelectedIndexChangedFileTypeComboBox = false;
107                 
108                 private bool showHiddenFiles = false;
109                 
110                 //protected bool readOnlyChecked = false;
111                 
112                 private bool showReadOnly = false;
113                 private bool readOnlyChecked = false;
114                 internal bool createPrompt = false;
115                 internal bool overwritePrompt = true;
116                 
117                 internal FileFilter fileFilter;
118                 
119                 private static string last_dir_when_opened_or_saved = String.Empty;
120                 private string start_dir;
121                 
122                 internal FileDialog ()
123                 {
124                         fileTypeComboBox = new ComboBox ();
125                         backToolBarButton = new ToolBarButton ();
126                         newdirToolBarButton = new ToolBarButton ();
127                         searchSaveLabel = new Label ();
128                         mwfFileView = new MWFFileView ();
129                         fileNameLabel = new Label ();
130                         fileNameComboBox = new ComboBox ();
131                         dirComboBox = new DirComboBox ();
132                         smallButtonToolBar = new ToolBar ();
133                         menueToolBarButton = new ToolBarButton ();
134                         fileTypeLabel = new Label ();
135                         openSaveButton = new Button ();
136                         form.AcceptButton = openSaveButton;
137                         helpButton = new Button ();
138                         popupButtonPanel = new PopupButtonPanel (this);
139                         upToolBarButton = new ToolBarButton ();
140                         cancelButton = new Button ();
141                         form.CancelButton = cancelButton;
142                         imageListTopToolbar = new ImageList ();
143                         menueToolBarButtonContextMenu = new ContextMenu ();
144                         contextMenu = new ContextMenu ();
145                         readonlyCheckBox = new CheckBox ();
146                         
147                         form.SuspendLayout ();
148                         
149                         //imageListTopToolbar
150                         imageListTopToolbar.ColorDepth = ColorDepth.Depth32Bit;
151                         imageListTopToolbar.ImageSize = new Size (16, 16); // 16, 16
152                         imageListTopToolbar.Images.Add ((Image)Locale.GetResource ("back_arrow"));
153                         imageListTopToolbar.Images.Add ((Image)Locale.GetResource ("folder_arrow_up"));
154                         imageListTopToolbar.Images.Add ((Image)Locale.GetResource ("folder_star"));
155                         imageListTopToolbar.Images.Add ((Image)Locale.GetResource ("window"));
156                         imageListTopToolbar.TransparentColor = Color.Transparent;
157                         
158                         // searchLabel
159                         searchSaveLabel.FlatStyle = FlatStyle.System;
160                         searchSaveLabel.Location = new Point (7, 8);
161                         searchSaveLabel.Size = new Size (72, 21);
162                         searchSaveLabel.TextAlign = ContentAlignment.MiddleRight;
163                         
164                         // dirComboBox
165                         dirComboBox.Anchor = ((AnchorStyles)(((AnchorStyles.Top | AnchorStyles.Left) | AnchorStyles.Right)));
166                         dirComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
167                         dirComboBox.Location = new Point (99, 8);
168                         dirComboBox.Size = new Size (260, 21);
169                         dirComboBox.TabIndex = 0;
170                         
171                         // smallButtonToolBar
172                         smallButtonToolBar.Anchor = ((AnchorStyles)((AnchorStyles.Top | AnchorStyles.Right)));
173                         smallButtonToolBar.Appearance = ToolBarAppearance.Flat;
174                         smallButtonToolBar.AutoSize = false;
175                         smallButtonToolBar.Buttons.AddRange (new ToolBarButton       [] {
176                                                                      backToolBarButton,
177                                                                      upToolBarButton,
178                                                                      newdirToolBarButton,
179                                                                      menueToolBarButton});
180                         smallButtonToolBar.ButtonSize = new Size (24, 24); // 21, 16
181                         smallButtonToolBar.Divider = false;
182                         smallButtonToolBar.Dock = DockStyle.None;
183                         smallButtonToolBar.DropDownArrows = true;
184                         smallButtonToolBar.ImageList = imageListTopToolbar;
185                         smallButtonToolBar.Location = new Point (372, 6);
186                         smallButtonToolBar.ShowToolTips = true;
187                         smallButtonToolBar.Size = new Size (140, 28);
188                         smallButtonToolBar.TabIndex = 1;
189                         smallButtonToolBar.TextAlign = ToolBarTextAlign.Right;
190                         
191                         // buttonPanel
192                         popupButtonPanel.Dock = DockStyle.None;
193                         popupButtonPanel.Location = new Point (7, 37);
194                         popupButtonPanel.TabIndex = 2;
195                         
196                         // mwfFileView
197                         mwfFileView.Anchor = ((AnchorStyles)((((AnchorStyles.Top | AnchorStyles.Bottom) | AnchorStyles.Left) | AnchorStyles.Right)));
198                         mwfFileView.Location = new Point (99, 37);
199                         mwfFileView.Size = new Size (449, 282);
200                         mwfFileView.Columns.Add (" Name", 170, HorizontalAlignment.Left);
201                         mwfFileView.Columns.Add ("Size ", 80, HorizontalAlignment.Right);
202                         mwfFileView.Columns.Add (" Type", 100, HorizontalAlignment.Left);
203                         mwfFileView.Columns.Add (" Last Access", 150, HorizontalAlignment.Left);
204                         mwfFileView.AllowColumnReorder = true;
205                         mwfFileView.MultiSelect = false;
206                         mwfFileView.TabIndex = 3;
207                         mwfFileView.FilterIndex = FilterIndex;
208                         
209                         // fileNameLabel
210                         fileNameLabel.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Left)));
211                         fileNameLabel.FlatStyle = FlatStyle.System;
212                         fileNameLabel.Location = new Point (102, 330);
213                         fileNameLabel.Size = new Size (70, 21);
214                         fileNameLabel.Text = "Filename:";
215                         fileNameLabel.TextAlign = ContentAlignment.MiddleLeft;
216                         
217                         // fileNameComboBox
218                         fileNameComboBox.Anchor = ((AnchorStyles)(((AnchorStyles.Bottom | AnchorStyles.Left) | AnchorStyles.Right)));
219                         fileNameComboBox.Location = new Point (195, 330);
220                         fileNameComboBox.Size = new Size (245, 21);
221                         fileNameComboBox.TabIndex = 4;
222                         fileNameComboBox.Items.Add (" ");
223                         
224                         // fileTypeLabel
225                         fileTypeLabel.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Left)));
226                         fileTypeLabel.FlatStyle = FlatStyle.System;
227                         fileTypeLabel.Location = new Point (102, 356);
228                         fileTypeLabel.Size = new Size (70, 21);
229                         fileTypeLabel.Text = "Filetype:";
230                         fileTypeLabel.TextAlign = ContentAlignment.MiddleLeft;
231                         
232                         // fileTypeComboBox
233                         fileTypeComboBox.Anchor = ((AnchorStyles)(((AnchorStyles.Bottom | AnchorStyles.Left) | AnchorStyles.Right)));
234                         fileTypeComboBox.Location = new Point (195, 356);
235                         fileTypeComboBox.Size = new Size (245, 21);
236                         fileTypeComboBox.TabIndex = 5;
237                         
238                         // backToolBarButton
239                         backToolBarButton.ImageIndex = 0;
240                         backToolBarButton.Enabled = false;
241                         backToolBarButton.Style = ToolBarButtonStyle.PushButton;
242                         
243                         // upToolBarButton
244                         upToolBarButton.ImageIndex = 1;
245                         upToolBarButton.Style = ToolBarButtonStyle.PushButton;
246                         
247                         // newdirToolBarButton
248                         newdirToolBarButton.ImageIndex = 2;
249                         newdirToolBarButton.Style = ToolBarButtonStyle.PushButton;
250                         
251                         // menueToolBarButton
252                         menueToolBarButton.ImageIndex = 3;
253                         menueToolBarButton.DropDownMenu = menueToolBarButtonContextMenu;
254                         menueToolBarButton.Style = ToolBarButtonStyle.DropDownButton;
255                         
256                         // menueToolBarButtonContextMenu
257                         MenuItem mi = new MenuItem ("Small Icon", new EventHandler (OnClickMenuToolBarContextMenu));
258                         mi.RadioCheck = true;
259                         menueToolBarButtonContextMenu.MenuItems.Add (mi);
260                         mi = new MenuItem ("Tiles", new EventHandler (OnClickMenuToolBarContextMenu));
261                         mi.RadioCheck = true;
262                         menueToolBarButtonContextMenu.MenuItems.Add (mi);
263                         mi = new MenuItem ("Large Icon", new EventHandler (OnClickMenuToolBarContextMenu));
264                         mi.RadioCheck = true;
265                         menueToolBarButtonContextMenu.MenuItems.Add (mi);
266                         mi = new MenuItem ("List", new EventHandler (OnClickMenuToolBarContextMenu));
267                         mi.RadioCheck = true;
268                         mi.Checked = true;
269                         previousCheckedMenuItem = mi;
270                         menueToolBarButtonContextMenu.MenuItems.Add (mi);
271                         mi = new MenuItem ("Details", new EventHandler (OnClickMenuToolBarContextMenu));
272                         mi.RadioCheck = true;
273                         menueToolBarButtonContextMenu.MenuItems.Add (mi);
274                         
275                         // contextMenu
276                         mi = new MenuItem ("Show hidden files", new EventHandler (OnClickContextMenu));
277                         mi.Checked = showHiddenFiles;
278                         mwfFileView.ShowHiddenFiles = showHiddenFiles;
279                         contextMenu.MenuItems.Add (mi);
280                         
281                         // openSaveButton
282                         openSaveButton.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Right)));
283                         openSaveButton.FlatStyle = FlatStyle.System;
284                         openSaveButton.Location = new Point (475, 330);
285                         openSaveButton.Size = new Size (72, 21);
286                         openSaveButton.TabIndex = 7;
287                         openSaveButton.FlatStyle = FlatStyle.System;
288                         
289                         // cancelButton
290                         cancelButton.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Right)));
291                         cancelButton.FlatStyle = FlatStyle.System;
292                         cancelButton.Location = new Point (475, 356);
293                         cancelButton.Size = new Size (72, 21);
294                         cancelButton.TabIndex = 8;
295                         cancelButton.Text = "Cancel";
296                         cancelButton.FlatStyle = FlatStyle.System;
297                         
298                         // helpButton
299                         helpButton.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Right)));
300                         helpButton.FlatStyle = FlatStyle.System;
301                         helpButton.Location = new Point (475, 350);
302                         helpButton.Size = new Size (72, 21);
303                         helpButton.TabIndex = 9;
304                         helpButton.Text = "Help";
305                         helpButton.FlatStyle = FlatStyle.System;
306                         
307                         // checkBox
308                         readonlyCheckBox.Anchor = ((AnchorStyles)(((AnchorStyles.Bottom | AnchorStyles.Left) | AnchorStyles.Right)));
309                         readonlyCheckBox.Text = "Open Readonly";
310                         readonlyCheckBox.Location = new Point (195, 350);
311                         readonlyCheckBox.Size = new Size (245, 21);
312                         readonlyCheckBox.TabIndex = 6;
313                         readonlyCheckBox.FlatStyle = FlatStyle.System;
314                         
315                         form.ContextMenu = contextMenu;
316                         
317                         form.SizeGripStyle = SizeGripStyle.Show;
318                         
319                         form.Size =  new Size (554, 405); // 384
320                         form.MaximizeBox = true;
321                         form.FormBorderStyle = FormBorderStyle.Sizable;
322                         form.MinimumSize = new Size (554, 405);
323                         
324                         form.Controls.Add (smallButtonToolBar);
325                         form.Controls.Add (cancelButton);
326                         form.Controls.Add (openSaveButton);
327                         form.Controls.Add (mwfFileView);
328                         form.Controls.Add (fileTypeLabel);
329                         form.Controls.Add (fileNameLabel);
330                         form.Controls.Add (fileTypeComboBox);
331                         form.Controls.Add (fileNameComboBox);
332                         form.Controls.Add (dirComboBox);
333                         form.Controls.Add (searchSaveLabel);
334                         form.Controls.Add (popupButtonPanel);
335                         
336                         form.ResumeLayout (false);
337                         
338                         currentDirectoryName = Environment.CurrentDirectory;
339                         
340                         currentDirectoryInfo = new DirectoryInfo (currentDirectoryName);
341                         
342                         if (RestoreDirectory)
343                                 restoreDirectoryString = currentDirectoryName;
344                         
345                         openSaveButton.Click += new EventHandler (OnClickOpenSaveButton);
346                         cancelButton.Click += new EventHandler (OnClickCancelButton);
347                         helpButton.Click += new EventHandler (OnClickHelpButton);
348                         
349                         smallButtonToolBar.ButtonClick += new ToolBarButtonClickEventHandler (OnClickSmallButtonToolBar);
350                         
351                         fileTypeComboBox.SelectedIndexChanged += new EventHandler (OnSelectedIndexChangedFileTypeComboBox);
352                         
353                         mwfFileView.SelectedFileChanged += new EventHandler (OnSelectedFileChangedFileView);
354                         mwfFileView.DirectoryChanged += new EventHandler (OnDirectoryChangedFileView);
355                         mwfFileView.ForceDialogEnd += new EventHandler (OnForceDialogEndFileView);
356                         mwfFileView.SelectedFilesChanged += new EventHandler (OnSelectedFilesChangedFileView);
357                         mwfFileView.OnDirectoryUp += new EventHandler (OnDirectoryUp);
358                         
359                         dirComboBox.DirectoryChanged += new EventHandler (OnDirectoryChangedDirComboBox);
360                         
361                         readonlyCheckBox.CheckedChanged += new EventHandler (OnCheckCheckChanged);
362                         
363                         start_dir = currentDirectoryName;
364                 }
365                 
366                 [DefaultValue(true)]
367                 public bool AddExtension {
368                         get {
369                                 return addExtension;
370                         }
371                         
372                         set {
373                                 addExtension = value;
374                         }
375                 }
376                 
377                 [DefaultValue(false)]
378                 public virtual bool CheckFileExists {
379                         get {
380                                 return checkFileExists;
381                         }
382                         
383                         set {
384                                 checkFileExists = value;
385                         }
386                 }
387                 
388                 [DefaultValue(true)]
389                 public bool CheckPathExists {
390                         get {
391                                 return checkPathExists;
392                         }
393                         
394                         set {
395                                 checkPathExists = value;
396                         }
397                 }
398                 
399                 [DefaultValue("")]
400                 public string DefaultExt {
401                         get {
402                                 return defaultExt;
403                         }
404                         
405                         set {
406                                 defaultExt = value;
407                                 
408                                 // if there is a dot remove it and everything before it
409                                 if (defaultExt.LastIndexOf ('.') != - 1) {
410                                         string[] split = defaultExt.Split (new char [] { '.' });
411                                         defaultExt = split [split.Length - 1];
412                                 }
413                         }
414                 }
415                 
416                 // in MS.NET it doesn't make a difference if
417                 // DerefenceLinks is true or false
418                 // if the selected file is a link FileDialog
419                 // always returns the link
420                 [DefaultValue(true)]
421                 public bool DereferenceLinks {
422                         get {
423                                 return dereferenceLinks;
424                         }
425                         
426                         set {
427                                 dereferenceLinks = value;
428                         }
429                 }
430                 
431                 [DefaultValue("")]
432                 public string FileName {
433                         get {
434                                 return fileName;
435                         }
436                         
437                         set {
438                                 if (value != null) {
439                                         if (SetFileName (value))
440                                                 fileName = value;
441                                 }
442                         }
443                 }
444                 
445                 [Browsable(false)]
446                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
447                 public string[] FileNames {
448                         get {
449                                 if (fileNames == null || fileNames.Length == 0) {
450                                         string[] null_nada_nothing_filenames = new string [0];
451                                         return null_nada_nothing_filenames;
452                                 }
453                                 
454                                 string[] new_filenames = new string [fileNames.Length];
455                                 fileNames.CopyTo (new_filenames, 0);
456                                 return new_filenames;
457                         }
458                 }
459                 
460                 [DefaultValue("")]
461                 [Localizable(true)]
462                 public string Filter {
463                         get {
464                                 return filter;
465                         }
466                         
467                         set {
468                                 if (value == null)
469                                         throw new NullReferenceException ("Filter");
470                                 
471                                 filter = value;
472                                 
473                                 fileFilter = new FileFilter (filter);
474                                 
475                                 UpdateFilters ();
476                         }
477                 }
478                 
479                 [DefaultValue(1)]
480                 public int FilterIndex {
481                         get {
482                                 return filterIndex;
483                         }
484                         
485                         set {
486                                 if (fileFilter != null && fileFilter.FilterArrayList.Count > value)
487                                         return;  // FIXME: throw an exception ?
488                                 
489                                 filterIndex = value;
490                                 
491                                 SelectFilter ();
492                         }
493                 }
494                 
495                 [DefaultValue("")]
496                 public string InitialDirectory {
497                         get {
498                                 return initialDirectory;
499                         }
500                         
501                         set {
502                                 if (Directory.Exists (value)) {
503                                         initialDirectory = value;
504                                         start_dir = value;
505                                         
506                                         ChangeDirectory (null, initialDirectory);
507                                 }
508                         }
509                 }
510                 
511                 [DefaultValue(false)]
512                 public bool RestoreDirectory {
513                         get {
514                                 return restoreDirectory;
515                         }
516                         
517                         set {
518                                 restoreDirectory = value;
519                         }
520                 }
521                 
522                 [DefaultValue(false)]
523                 public bool ShowHelp {
524                         get {
525                                 return showHelp;
526                         }
527                         
528                         set {
529                                 showHelp = value;
530                                 ResizeAndRelocateForHelpOrReadOnly ();
531                         }
532                 }
533                 
534                 [DefaultValue("")]
535                 [Localizable(true)]
536                 public string Title {
537                         get {
538                                 return title;
539                         }
540                         
541                         set {
542                                 title = value;
543                                 
544                                 form.Text = title;
545                         }
546                 }
547                 
548                 // this one is a hard one ;)
549                 // Win32 filename:
550                 // - up to MAX_PATH characters (windef.h) = 260
551                 // - no trailing dots or spaces
552                 // - case preserving
553                 // - etc...
554                 // NTFS/Posix filename:
555                 // - up to 32,768 Unicode characters
556                 // - trailing periods or spaces
557                 // - case sensitive
558                 // - etc...
559                 [DefaultValue(true)]
560                 public bool ValidateNames {
561                         get {
562                                 return validateNames;
563                         }
564                         
565                         set {
566                                 validateNames = value;
567                         }
568                 }
569                 
570                 public override void Reset ()
571                 {
572                         addExtension = true;
573                         checkFileExists = false;
574                         checkPathExists = true;
575                         defaultExt = "";
576                         dereferenceLinks = true;
577                         fileName = "";
578                         fileNames = null;
579                         Filter = "";
580                         filterIndex = 1;
581                         initialDirectory = "";
582                         restoreDirectory = false;
583                         ShowHelp = false;
584                         Title = "";
585                         validateNames = true;
586                         
587                         UpdateFilters ();
588                 }
589                 
590                 public override string ToString ()
591                 {
592                         return base.ToString ();
593                 }
594                 
595                 public event CancelEventHandler FileOk {
596                         add { Events.AddHandler (EventFileOk, value); }
597                         remove { Events.RemoveHandler (EventFileOk, value); }
598                 }
599                 
600                 protected virtual IntPtr Instance {
601                         get {
602                                 if (form == null)
603                                         return IntPtr.Zero;
604                                 return form.Handle;
605                         }
606                 }
607                 
608                 // This is just for internal use with MSs version, so it doesn't need to be implemented
609                 // as it can't really be accessed anyways
610                 protected int Options {
611                         get { return -1; }
612                 }
613                 
614                 [MonoTODO]
615                 protected  override IntPtr HookProc (IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam)
616                 {
617                         throw new NotImplementedException ();
618                 }
619                 
620                 protected void OnFileOk (CancelEventArgs e)
621                 {
622                         CancelEventHandler fo = (CancelEventHandler) Events [EventFileOk];
623                         if (fo != null)
624                                 fo (this, e);
625                 }
626                 
627                 protected  override bool RunDialog (IntPtr hWndOwner)
628                 {
629                         form.Refresh ();
630                         
631                         if (last_dir_when_opened_or_saved != String.Empty)
632                                 ChangeDirectory (null, last_dir_when_opened_or_saved);
633                         else
634                                 ChangeDirectory (null, start_dir);
635                         
636                         fileNameComboBox.Select ();
637                         
638                         return true;
639                 }
640                 
641                 internal virtual bool ShowReadOnly {
642                         set {
643                                 showReadOnly = value;
644                                 ResizeAndRelocateForHelpOrReadOnly ();
645                         }
646                         
647                         get {
648                                 return showReadOnly;
649                         }
650                 }
651                 
652                 internal virtual bool ReadOnlyChecked {
653                         set {
654                                 readOnlyChecked = value;
655                                 readonlyCheckBox.Checked = value;
656                         }
657                         
658                         get {
659                                 return readOnlyChecked;
660                         }
661                 }
662                 
663                 internal bool BMultiSelect {
664                         set {
665                                 multiSelect = value;
666                                 mwfFileView.MultiSelect = value;
667                         }
668                         
669                         get {
670                                 return multiSelect;
671                         }
672                 }
673                 
674                 internal string OpenSaveButtonText {
675                         set {
676                                 openSaveButton.Text = value;
677                         }
678                 }
679                 
680                 internal string SearchSaveLabel {
681                         set {
682                                 searchSaveLabel.Text = value;
683                         }
684                 }
685                 
686                 private void SelectFilter ()
687                 {
688                         do_not_call_OnSelectedIndexChangedFileTypeComboBox = true;
689                         fileTypeComboBox.BeginUpdate ();
690                         fileTypeComboBox.SelectedIndex = FilterIndex - 1;
691                         fileTypeComboBox.EndUpdate ();
692                         
693                         mwfFileView.FilterIndex = FilterIndex;
694                         
695                         mwfFileView.UpdateFileView (currentDirectoryInfo_or_current_special_case);
696                 }
697                 
698                 private bool SetFileName (string fname)
699                 {
700                         bool rooted = Path.IsPathRooted (fname);
701                         
702                         if (!rooted) {
703                                 if (File.Exists (Path.Combine (currentDirectoryName, fname))) {
704                                         fileNameComboBox.Text = fname;
705                                         mwfFileView.SetSelectedIndexTo (fname);
706                                         
707                                         return true;
708                                 } else
709                                         return false;
710                         } else {
711                                 if (File.Exists (fname)) {
712                                         fileNameComboBox.Text = Path.GetFileName (fname);
713                                         ChangeDirectory (null, Path.GetDirectoryName (fname));
714                                         mwfFileView.SetSelectedIndexTo (fname);
715                                         
716                                         return true;
717                                 }
718                         }
719                         
720                         return false;
721                 }
722                 
723                 void OnClickContextMenu (object sender, EventArgs e)
724                 {
725                         MenuItem senderMenuItem = sender as MenuItem;
726                         
727                         if (senderMenuItem.Index == 0) {
728                                 senderMenuItem.Checked = !senderMenuItem.Checked;
729                                 showHiddenFiles = senderMenuItem.Checked;
730                                 mwfFileView.ShowHiddenFiles = showHiddenFiles;
731                                 mwfFileView.UpdateFileView (currentDirectoryInfo_or_current_special_case);
732                         }
733                 }
734                 
735                 void OnClickOpenSaveButton (object sender, EventArgs e)
736                 {
737                         if (fileDialogType == FileDialogType.OpenFileDialog && mwfFileView.SelectedItems [0] != null) {
738                                 string path = Path.Combine (currentDirectoryName, mwfFileView.SelectedItems [0].Text);
739                                 if (Directory.Exists (path)) {
740                                         ChangeDirectory (null, path);
741                                         openSaveButton.Select ();
742                                         return;
743                                 }
744                         }
745                         
746                         if (!multiSelect) {
747                                 if (!show_special_case) {
748                                         string fileFromComboBox = fileNameComboBox.Text.Trim ();
749                                         
750                                         if (fileFromComboBox.Length > 0) {
751                                                 if (!Path.IsPathRooted (fileFromComboBox))
752                                                         fileFromComboBox = Path.Combine (currentDirectoryName, fileFromComboBox);
753                                                 
754                                                 FileInfo fileInfo = new FileInfo (fileFromComboBox);
755                                                 if (fileInfo.Exists || fileDialogType == FileDialogType.SaveFileDialog)
756                                                         currentFileName = fileFromComboBox;
757                                                 else {
758                                                         DirectoryInfo dirInfo = new DirectoryInfo (fileFromComboBox);
759                                                         if (dirInfo.Exists) {
760                                                                 ChangeDirectory (null, dirInfo.FullName);
761                                                                 
762                                                                 currentFileName = "";
763                                                                 
764                                                                 fileNameComboBox.Text = " ";
765                                                                 return;
766                                                         }                                                               
767                                                 }
768                                         } else
769                                                 return;
770                                 } else {
771                                         if (currentFileName == null || currentFileName == String.Empty) {
772                                                 currentFileName = fileNameComboBox.Text.Trim ();
773                                                 
774                                                 if (currentFileName.Length > 0) {
775                                                         FileInfo fileInfo = new FileInfo (currentFileName);
776                                                         if (!fileInfo.Exists) {
777                                                                 DirectoryInfo dirInfo = new DirectoryInfo (currentFileName);
778                                                                 if (dirInfo.Exists) {
779                                                                         ChangeDirectory (null, dirInfo.FullName);
780                                                                         
781                                                                         currentFileName = "";
782                                                                         
783                                                                         fileNameComboBox.Text = " ";
784                                                                         return;
785                                                                 }                                                               
786                                                         }
787                                                 } else
788                                                         return;
789                                         }
790                                         
791                                         if (currentDirectoryName == String.Empty)
792                                                 currentDirectoryName = Path.GetDirectoryName (currentFileName);
793                                 }
794                                 
795                                 if (fileDialogType == FileDialogType.OpenFileDialog) {
796                                         if (checkFileExists) {
797                                                 if (!File.Exists (currentFileName)) {
798                                                         string message = "\"" + currentFileName + "\" doesn't exist. Please verify that you have entered the correct file name.";
799                                                         MessageBox.Show (message, openSaveButton.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
800                                                         
801                                                         currentFileName = "";
802                                                         
803                                                         return;
804                                                 }
805                                         }
806                                 } else {
807                                         if (overwritePrompt) {
808                                                 if (File.Exists (currentFileName)) {
809                                                         string message = "\"" + currentFileName + "\" exists. Overwrite ?";
810                                                         DialogResult dr = MessageBox.Show (message, openSaveButton.Text, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
811                                                         
812                                                         if (dr == DialogResult.Cancel) {
813                                                                 currentFileName = "";
814                                                                 
815                                                                 return;
816                                                         }
817                                                 }
818                                         }
819                                         
820                                         if (createPrompt) {
821                                                 if (!File.Exists (currentFileName)) {
822                                                         string message = "\"" + currentFileName + "\" doesn't exist. Create ?";
823                                                         DialogResult dr = MessageBox.Show (message, openSaveButton.Text, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
824                                                         
825                                                         if (dr == DialogResult.Cancel) {
826                                                                 currentFileName = "";
827                                                                 
828                                                                 return;
829                                                         }
830                                                 }
831                                         }
832                                 }
833                                 
834                                 if (fileDialogType == FileDialogType.SaveFileDialog) {
835                                         if (addExtension && defaultExt.Length > 0) {
836                                                 if (!currentFileName.EndsWith (defaultExt)) {
837                                                         currentFileName += "." + defaultExt;
838                                                 }
839                                         }
840                                 }
841                                 
842                                 fileNames = new string [1];
843                                 
844                                 fileNames [0] = currentFileName;
845                                 
846                                 fileName = currentFileName;
847                                 
848                                 WriteRecentlyUsed ();
849                         } else // multiSelect = true
850                         if (fileDialogType != FileDialogType.SaveFileDialog) {
851                                 if (mwfFileView.SelectedItems.Count > 0) {
852                                         // first remove all selected directories
853                                         ArrayList al = new ArrayList ();
854                                         
855                                         foreach (ListViewItem lvi in mwfFileView.SelectedItems) {
856                                                 FileStruct fileStruct = (FileStruct)mwfFileView.FileHashtable [lvi.Text];
857                                                 
858                                                 if (fileStruct.attributes != FileAttributes.Directory) {
859                                                         al.Add (fileStruct);
860                                                 }
861                                         }
862                                         
863                                         fileName = ((FileStruct)al [0]).fullname;
864                                         
865                                         fileNames = new string [al.Count];
866                                         
867                                         for (int i = 0; i < al.Count; i++) {
868                                                 fileNames [i] = ((FileStruct)al [i]).fullname;
869                                         }
870                                 }
871                         }
872                         
873                         if (checkPathExists) {
874                                 if (!Directory.Exists (currentDirectoryName)) {
875                                         string message = "\"" + currentDirectoryName + "\" doesn't exist. Please verify that you have entered the correct directory name.";
876                                         MessageBox.Show (message, openSaveButton.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
877                                         
878                                         if (initialDirectory == String.Empty)
879                                                 currentDirectoryName = Environment.CurrentDirectory;
880                                         else
881                                                 currentDirectoryName = initialDirectory;
882                                         
883                                         return;
884                                 }
885                         }
886                         
887                         if (restoreDirectory)
888                                 currentDirectoryName = restoreDirectoryString;
889                         
890                         if (current_special_case != String.Empty)
891                                 last_dir_when_opened_or_saved = current_special_case;
892                         else
893                                 last_dir_when_opened_or_saved = currentDirectoryName;
894                         
895                         CancelEventArgs cancelEventArgs = new CancelEventArgs ();
896                         
897                         cancelEventArgs.Cancel = false;
898                         
899                         OnFileOk (cancelEventArgs);
900                         
901                         form.DialogResult = DialogResult.OK;
902                 }
903                 
904                 void OnClickCancelButton (object sender, EventArgs e)
905                 {
906                         if (restoreDirectory)
907                                 currentDirectoryName = restoreDirectoryString;
908                         
909                         CancelEventArgs cancelEventArgs = new CancelEventArgs ();
910                         
911                         cancelEventArgs.Cancel = true;
912                         
913                         OnFileOk (cancelEventArgs);
914                         
915                         form.DialogResult = DialogResult.Cancel;
916                 }
917                 
918                 void OnClickHelpButton (object sender, EventArgs e)
919                 {
920                         OnHelpRequest (e);
921                 }
922                 
923                 void OnClickSmallButtonToolBar (object sender, ToolBarButtonClickEventArgs e)
924                 {
925                         if (e.Button == upToolBarButton) {
926                                 if (currentDirectoryInfo != null && currentDirectoryInfo.Parent != null)
927                                         ChangeDirectory (null, currentDirectoryInfo.Parent.FullName);
928                         } else
929                         if (e.Button == backToolBarButton) {
930                                 PopDirectory ();
931                         } else
932                         if (e.Button == newdirToolBarButton) {
933                                 
934                         }
935                 }
936                 
937                 void OnClickMenuToolBarContextMenu (object sender, EventArgs e)
938                 {
939                         MenuItem senderMenuItem = (MenuItem)sender;
940                         
941                         previousCheckedMenuItem.Checked = false;
942                         senderMenuItem.Checked = true;
943                         previousCheckedMenuItem = senderMenuItem;
944                         
945                         // FIXME...
946                         
947                         switch (senderMenuItem.Index) {
948                         case 0:
949                                 mwfFileView.View = View.SmallIcon;
950                                 break;
951                         case 1:
952                                 mwfFileView.View = View.LargeIcon;
953                                 break;
954                         case 2:
955                                 mwfFileView.View = View.LargeIcon;
956                                 break;
957                         case 3:
958                                 mwfFileView.View = View.List;
959                                 break;
960                         case 4:
961                                 mwfFileView.View = View.Details;
962                                 break;
963                         default:
964                                 break;
965                         }
966                         
967                         
968                         mwfFileView.UpdateFileView (currentDirectoryInfo_or_current_special_case);
969                 }
970                 
971                 void OnSelectedIndexChangedFileTypeComboBox (object sender, EventArgs e)
972                 {
973                         if (do_not_call_OnSelectedIndexChangedFileTypeComboBox) {
974                                 do_not_call_OnSelectedIndexChangedFileTypeComboBox = false;
975                                 return;
976                         }
977                         
978                         filterIndex = fileTypeComboBox.SelectedIndex + 1;
979                         
980                         mwfFileView.FilterIndex = filterIndex;
981                         
982                         mwfFileView.UpdateFileView (currentDirectoryInfo_or_current_special_case);
983                 }
984                 
985                 void OnSelectedFileChangedFileView (object sender, EventArgs e)
986                 {
987                         fileNameComboBox.Text = mwfFileView.FileName;
988                         currentFileName = mwfFileView.FullFileName;
989                 }
990                 
991                 void OnDirectoryChangedFileView (object sender, EventArgs e)
992                 {
993                         ChangeDirectory (sender, mwfFileView.FullFileName);
994                 }
995                 
996                 void OnForceDialogEndFileView (object sender, EventArgs e)
997                 {
998                         ForceDialogEnd ();
999                 }
1000                 
1001                 void OnSelectedFilesChangedFileView (object sender, EventArgs e)
1002                 {
1003                         fileNameComboBox.Text = mwfFileView.SelectedFilesString;
1004                 }
1005                 
1006                 void OnDirectoryChangedDirComboBox (object sender, EventArgs e)
1007                 {
1008                         ChangeDirectory (sender, dirComboBox.CurrentPath);
1009                 }
1010                 
1011                 void OnCheckCheckChanged (object sender, EventArgs e)
1012                 {
1013                         ReadOnlyChecked = readonlyCheckBox.Checked;
1014                 }
1015                 
1016                 void OnDirectoryUp (Object sender, EventArgs e)
1017                 {
1018                         if (currentDirectoryInfo != null && currentDirectoryInfo.Parent != null) 
1019                                 ChangeDirectory (null, currentDirectoryInfo.Parent.FullName);
1020                         
1021                         // make mwfFileView the active control
1022                         mwfFileView.Select ();
1023                 }
1024                 
1025                 private void UpdateFilters ()
1026                 {
1027                         ArrayList filters = fileFilter.FilterArrayList;
1028                         
1029                         fileTypeComboBox.BeginUpdate ();
1030                         
1031                         fileTypeComboBox.Items.Clear ();
1032                         
1033                         foreach (FilterStruct fs in filters) {
1034                                 fileTypeComboBox.Items.Add (fs.filterName);
1035                         }
1036                         
1037                         fileTypeComboBox.SelectedIndex = FilterIndex - 1;
1038                         
1039                         fileTypeComboBox.EndUpdate ();
1040                         
1041                         mwfFileView.FilterArrayList = filters;
1042                         
1043                         mwfFileView.FilterIndex = FilterIndex;
1044                         
1045                         mwfFileView.UpdateFileView (currentDirectoryInfo_or_current_special_case);
1046                 }
1047                 
1048                 internal void ChangeDirectory (object sender, string path_or_special_case)
1049                 {
1050                         show_special_case = false;
1051                         
1052                         if (sender != dirComboBox)
1053                                 dirComboBox.CurrentPath = path_or_special_case;
1054                         
1055                         if (sender != popupButtonPanel)
1056                                 popupButtonPanel.SetPopupButtonStateByPath (path_or_special_case);
1057                         
1058                         if (currentDirectoryInfo != null)
1059                                 PushDirectory (currentDirectoryInfo);
1060                         else
1061                                 PushDirectory (current_special_case);
1062                         
1063                         if (path_or_special_case == recently_string) {
1064                                 currentDirectoryName = String.Empty;
1065                                 
1066                                 currentDirectoryInfo = null;
1067                                 show_special_case = true;
1068                                 
1069                                 current_special_case = recently_string;
1070                                 
1071                                 mwfFileView.UpdateFileView (recently_string);
1072                                 
1073                         } else if (path_or_special_case == mycomputer_string) {
1074                                 currentDirectoryName = String.Empty;
1075                                 
1076                                 currentDirectoryInfo = null;
1077                                 show_special_case = true;
1078                                 
1079                                 current_special_case = mycomputer_string;
1080                                 
1081                                 mwfFileView.UpdateFileView (mycomputer_string);
1082                                 
1083                         } else if (path_or_special_case == network_string) {
1084                                 currentDirectoryName = String.Empty;
1085                                 
1086                                 currentDirectoryInfo = null;
1087                                 show_special_case = true;
1088                                 
1089                                 current_special_case = network_string;
1090                                 
1091                                 mwfFileView.UpdateFileView (network_string);
1092                                 
1093                         } else {
1094                                 currentDirectoryName = path_or_special_case;
1095                                 
1096                                 current_special_case = "";
1097                                 
1098                                 currentDirectoryInfo = new DirectoryInfo (path_or_special_case);
1099                                 
1100                                 mwfFileView.UpdateFileView (currentDirectoryInfo);
1101                         }
1102                 }
1103                 
1104                 private void ForceDialogEnd ()
1105                 {
1106                         OnClickOpenSaveButton (this, EventArgs.Empty);
1107                 }
1108                 
1109                 private void PushDirectory (object directoryInfo_or_string)
1110                 {
1111                         directoryStack.Push (directoryInfo_or_string);
1112                         backToolBarButton.Enabled = (directoryStack.Count > 1);
1113                 }
1114                 
1115                 private void PopDirectory ()
1116                 {
1117                         if (directoryStack.Count == 0)
1118                                 return;
1119                         
1120                         show_special_case = false;
1121                         
1122                         object directoryInfo_or_string = directoryStack.Pop ();
1123                         
1124                         if (directoryInfo_or_string is DirectoryInfo) {
1125                                 currentDirectoryInfo = directoryInfo_or_string as DirectoryInfo;
1126                                 
1127                                 currentDirectoryName = currentDirectoryInfo.FullName;
1128                                 
1129                                 current_special_case = String.Empty;
1130                         } else
1131                         if (directoryInfo_or_string is string) {
1132                                 currentDirectoryInfo = null;
1133                                 currentDirectoryName = String.Empty;
1134                                 show_special_case = true;
1135                                 current_special_case = directoryInfo_or_string as string;
1136                         }
1137                         
1138                         backToolBarButton.Enabled = (directoryStack.Count > 1);
1139                         
1140                         dirComboBox.CurrentPath = currentDirectoryName_or_special_case;
1141                         
1142                         popupButtonPanel.SetPopupButtonStateByPath (currentDirectoryName_or_special_case);
1143                         
1144                         mwfFileView.UpdateFileView (currentDirectoryInfo_or_current_special_case);
1145                 }
1146                 
1147                 private void ResizeAndRelocateForHelpOrReadOnly ()
1148                 {
1149                         form.SuspendLayout ();
1150                         if (ShowHelp || ShowReadOnly) {
1151                                 mwfFileView.Size = new Size (449, 250); 
1152                                 fileNameLabel.Location = new Point (102, 298);
1153                                 fileNameComboBox.Location = new Point (195, 298);
1154                                 fileTypeLabel.Location = new Point (102, 324);
1155                                 fileTypeComboBox.Location = new Point (195, 324);
1156                                 openSaveButton.Location = new Point (475, 298);
1157                                 cancelButton.Location = new Point (475, 324);
1158                         } else {
1159                                 mwfFileView.Size = new Size (449, 282);
1160                                 fileNameLabel.Location = new Point (102, 330);
1161                                 fileNameComboBox.Location = new Point (195, 330);
1162                                 fileTypeLabel.Location = new Point (102, 356);
1163                                 fileTypeComboBox.Location = new Point (195, 356);
1164                                 openSaveButton.Location = new Point (475, 330);
1165                                 cancelButton.Location = new Point (475, 356);
1166                         }
1167                         
1168                         if (ShowHelp)
1169                                 form.Controls.Add (helpButton);
1170                         else
1171                                 form.Controls.Remove (helpButton);
1172                         
1173                         if (ShowReadOnly)
1174                                 form.Controls.Add (readonlyCheckBox);
1175                         else
1176                                 form.Controls.Remove (readonlyCheckBox);
1177                         form.ResumeLayout ();
1178                 }
1179                 
1180                 private void WriteRecentlyUsed ()
1181                 {
1182                         int platform = (int) Environment.OSVersion.Platform;
1183                         
1184                         // on a *nix platform we use "$HOME/.recently-used" to store our recently used files (GNOME, libegg like)
1185                         if ((platform == 4) || (platform == 128)) {
1186                                 string personal_folder = ThemeEngine.Current.Places (UIIcon.PlacesPersonal);
1187                                 string recently_used_path = Path.Combine (personal_folder, ".recently-used");
1188                                 
1189                                 if (File.Exists (recently_used_path) && new FileInfo (recently_used_path).Length > 0) {
1190                                         XmlDocument xml_doc = new XmlDocument ();
1191                                         xml_doc.Load (recently_used_path);
1192                                         
1193                                         XmlNode grand_parent_node = xml_doc.SelectSingleNode ("RecentFiles");
1194                                         
1195                                         if (grand_parent_node != null) {
1196                                                 // create a new element
1197                                                 XmlElement new_recent_item_node = xml_doc.CreateElement ("RecentItem");
1198                                                 
1199                                                 XmlElement new_child = xml_doc.CreateElement ("URI");
1200                                                 UriBuilder ub = new UriBuilder ();
1201                                                 ub.Path = currentFileName;
1202                                                 ub.Host = null;
1203                                                 ub.Scheme = "file";
1204                                                 XmlText new_text_child = xml_doc.CreateTextNode (ub.ToString ());
1205                                                 new_child.AppendChild (new_text_child);
1206                                                 
1207                                                 new_recent_item_node.AppendChild (new_child);
1208                                                 
1209                                                 new_child = xml_doc.CreateElement ("Mime-Type");
1210                                                 new_text_child = xml_doc.CreateTextNode (Mime.GetMimeTypeForFile (currentFileName));
1211                                                 new_child.AppendChild (new_text_child);
1212                                                 
1213                                                 new_recent_item_node.AppendChild (new_child);
1214                                                 
1215                                                 new_child = xml_doc.CreateElement ("Timestamp");
1216                                                 long seconds = (long)(DateTime.UtcNow - new DateTime (1970, 1, 1)).TotalSeconds;
1217                                                 new_text_child = xml_doc.CreateTextNode (seconds.ToString ());
1218                                                 new_child.AppendChild (new_text_child);
1219                                                 
1220                                                 new_recent_item_node.AppendChild (new_child);
1221                                                 
1222                                                 new_child = xml_doc.CreateElement ("Groups");
1223                                                 
1224                                                 new_recent_item_node.AppendChild (new_child);
1225                                                 
1226                                                 // now search the nodes in grand_parent_node for another instance of the new uri and if found remove it
1227                                                 // so that the new node is the first one
1228                                                 foreach (XmlNode n in grand_parent_node.ChildNodes) {
1229                                                         XmlNode uri_node = n.SelectSingleNode ("URI");
1230                                                         if (uri_node != null) {
1231                                                                 XmlNode uri_node_child = uri_node.FirstChild;
1232                                                                 if (uri_node_child is XmlText)
1233                                                                         if (ub.ToString () == ((XmlText)uri_node_child).Data) {
1234                                                                                 grand_parent_node.RemoveChild (n);
1235                                                                                 break;
1236                                                                         }
1237                                                         }
1238                                                 }
1239                                                 
1240                                                 // prepend the new recent item to the grand parent node list
1241                                                 grand_parent_node.PrependChild (new_recent_item_node);
1242                                                 
1243                                                 // limit the # of RecentItems to 10
1244                                                 if (grand_parent_node.ChildNodes.Count > 10) {
1245                                                         while (grand_parent_node.ChildNodes.Count > 10)
1246                                                                 grand_parent_node.RemoveChild (grand_parent_node.LastChild);
1247                                                 }
1248                                                 
1249                                                 try {
1250                                                         xml_doc.Save (recently_used_path);
1251                                                 } catch (Exception) {
1252                                                 }
1253                                         }
1254                                 } else {
1255                                         XmlDocument xml_doc = new XmlDocument ();
1256                                         xml_doc.AppendChild (xml_doc.CreateXmlDeclaration ("1.0", "", ""));
1257                                         
1258                                         XmlElement recentFiles_element = xml_doc.CreateElement ("RecentFiles");
1259                                         
1260                                         XmlElement new_recent_item_node = xml_doc.CreateElement ("RecentItem");
1261                                         
1262                                         XmlElement new_child = xml_doc.CreateElement ("URI");
1263                                         UriBuilder ub = new UriBuilder ();
1264                                         ub.Path = currentFileName;
1265                                         ub.Host = null;
1266                                         ub.Scheme = "file";
1267                                         XmlText new_text_child = xml_doc.CreateTextNode (ub.ToString ());
1268                                         new_child.AppendChild (new_text_child);
1269                                         
1270                                         new_recent_item_node.AppendChild (new_child);
1271                                         
1272                                         new_child = xml_doc.CreateElement ("Mime-Type");
1273                                         new_text_child = xml_doc.CreateTextNode (Mime.GetMimeTypeForFile (currentFileName));
1274                                         new_child.AppendChild (new_text_child);
1275                                         
1276                                         new_recent_item_node.AppendChild (new_child);
1277                                         
1278                                         new_child = xml_doc.CreateElement ("Timestamp");
1279                                         long seconds = (long)(DateTime.UtcNow - new DateTime (1970, 1, 1)).TotalSeconds;
1280                                         new_text_child = xml_doc.CreateTextNode (seconds.ToString ());
1281                                         new_child.AppendChild (new_text_child);
1282                                         
1283                                         new_recent_item_node.AppendChild (new_child);
1284                                         
1285                                         new_child = xml_doc.CreateElement ("Groups");
1286                                         
1287                                         new_recent_item_node.AppendChild (new_child);
1288                                         
1289                                         recentFiles_element.AppendChild (new_recent_item_node);
1290                                         
1291                                         xml_doc.AppendChild (recentFiles_element);
1292                                         
1293                                         try {
1294                                                 xml_doc.Save (recently_used_path);
1295                                         } catch (Exception) {
1296                                         }
1297                                 }
1298                         }
1299                 }
1300                 
1301                 private object currentDirectoryInfo_or_current_special_case {
1302                         get {
1303                                 if (currentDirectoryInfo != null)
1304                                         return currentDirectoryInfo;
1305                                 else
1306                                         return current_special_case;
1307                         }
1308                 }
1309                 
1310                 private string currentDirectoryName_or_special_case {
1311                         get {
1312                                 if (currentDirectoryName != String.Empty)
1313                                         return currentDirectoryName;
1314                                 else
1315                                         return current_special_case;
1316                         }
1317                 }
1318                 
1319                 internal class PopupButtonPanel : Panel {
1320                         internal class PopupButton : Control {
1321                                 internal enum PopupButtonState { Normal, Down, Up}
1322                                 
1323                                 private Image image = null;
1324                                 private PopupButtonState popupButtonState = PopupButtonState.Normal;
1325                                 private StringFormat text_format = new StringFormat();
1326                                 private Rectangle text_rect = Rectangle.Empty;
1327                                 
1328                                 public PopupButton ()
1329                                 {
1330                                         text_format.Alignment = StringAlignment.Center;
1331                                         text_format.LineAlignment = StringAlignment.Near;
1332                                         
1333                                         SetStyle (ControlStyles.DoubleBuffer, true);
1334                                         SetStyle (ControlStyles.AllPaintingInWmPaint, true);
1335                                         SetStyle (ControlStyles.UserPaint, true);
1336                                 }
1337                                 
1338                                 public Image Image {
1339                                         set {
1340                                                 image = value;
1341                                                 Refresh ();
1342                                         }
1343                                         
1344                                         get {
1345                                                 return image;
1346                                         }
1347                                 }
1348                                 
1349                                 public PopupButtonState ButtonState {
1350                                         set {
1351                                                 popupButtonState = value;
1352                                                 Refresh ();
1353                                         }
1354                                         
1355                                         get {
1356                                                 return popupButtonState;
1357                                         }
1358                                 }
1359                                 
1360                                 protected override void OnPaint (PaintEventArgs pe)
1361                                 {
1362                                         Draw (pe);
1363                                         
1364                                         base.OnPaint (pe);
1365                                 }
1366                                 
1367                                 private void Draw (PaintEventArgs pe)
1368                                 {
1369                                         Graphics gr = pe.Graphics;
1370                                         
1371                                         gr.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (BackColor), ClientRectangle);
1372                                         
1373                                         // draw image
1374                                         if (image != null) {
1375                                                 int i_x = (ClientSize.Width - image.Width) / 2;
1376                                                 int i_y = 4;
1377                                                 gr.DrawImage (image, i_x, i_y);
1378                                         }
1379                                         
1380                                         if (Text != String.Empty) {
1381                                                 if (text_rect == Rectangle.Empty)
1382                                                         text_rect = new Rectangle (0, Height - 30, Width, Height - 30); 
1383                                                 
1384                                                 gr.DrawString (Text, Font, ThemeEngine.Current.ResPool.GetSolidBrush (ForeColor), text_rect, text_format);
1385                                         }
1386                                         
1387                                         switch (popupButtonState) {
1388                                         case PopupButtonState.Up:
1389                                                 gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.White), 0, 0, ClientSize.Width - 1, 0);
1390                                                 gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.White), 0, 0, 0, ClientSize.Height - 1);
1391                                                 gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.Black), ClientSize.Width - 1, 0, ClientSize.Width - 1, ClientSize.Height - 1);
1392                                                 gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.Black), 0, ClientSize.Height - 1, ClientSize.Width - 1, ClientSize.Height - 1);
1393                                                 break;
1394                                                 
1395                                         case PopupButtonState.Down:
1396                                                 gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.Black), 0, 0, ClientSize.Width - 1, 0);
1397                                                 gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.Black), 0, 0, 0, ClientSize.Height - 1);
1398                                                 gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.White), ClientSize.Width - 1, 0, ClientSize.Width - 1, ClientSize.Height - 1);
1399                                                 gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.White), 0, ClientSize.Height - 1, ClientSize.Width - 1, ClientSize.Height - 1);
1400                                                 break;
1401                                         }
1402                                 }
1403                                 
1404                                 protected override void OnMouseEnter (EventArgs e)
1405                                 {
1406                                         if (popupButtonState != PopupButtonState.Down)
1407                                                 popupButtonState = PopupButtonState.Up;
1408                                         Refresh ();
1409                                         base.OnMouseEnter (e);
1410                                 }
1411                                 
1412                                 protected override void OnMouseLeave (EventArgs e)
1413                                 {
1414                                         if (popupButtonState != PopupButtonState.Down)
1415                                                 popupButtonState = PopupButtonState.Normal;
1416                                         Refresh ();
1417                                         base.OnMouseLeave (e);
1418                                 }
1419                                 
1420                                 protected override void OnClick (EventArgs e)
1421                                 {
1422                                         popupButtonState = PopupButtonState.Down;
1423                                         Refresh ();
1424                                         base.OnClick (e);
1425                                 }
1426                         }
1427                         
1428                         private FileDialog fileDialog;
1429                         
1430                         private PopupButton recentlyusedButton;
1431                         private PopupButton desktopButton;
1432                         private PopupButton personalButton;
1433                         private PopupButton mycomputerButton;
1434                         private PopupButton networkButton;
1435                         
1436                         private PopupButton lastPopupButton = null;
1437                         
1438                         private int platform = (int) Environment.OSVersion.Platform;
1439                         
1440                         public PopupButtonPanel (FileDialog fileDialog)
1441                         {
1442                                 this.fileDialog = fileDialog;
1443                                 
1444                                 SuspendLayout ();
1445                                 
1446                                 BorderStyle = BorderStyle.Fixed3D;
1447                                 BackColor = Color.FromArgb (128, 128, 128);
1448                                 Size = new Size (85, 336);
1449                                 
1450                                 recentlyusedButton = new PopupButton ();
1451                                 desktopButton = new PopupButton ();
1452                                 personalButton = new PopupButton ();
1453                                 mycomputerButton = new PopupButton ();
1454                                 networkButton = new PopupButton ();
1455                                 
1456                                 recentlyusedButton.Size = new Size (81, 64);
1457                                 recentlyusedButton.Image = ThemeEngine.Current.Images (UIIcon.PlacesRecentDocuments, 30);
1458                                 recentlyusedButton.BackColor = BackColor;
1459                                 recentlyusedButton.ForeColor = Color.White;
1460                                 recentlyusedButton.Location = new Point (0, 0);
1461                                 recentlyusedButton.Text = "Recently\nused";
1462                                 recentlyusedButton.Click += new EventHandler (OnClickButton);
1463                                 
1464                                 desktopButton.Image = ThemeEngine.Current.Images (UIIcon.PlacesDesktop, 30);
1465                                 desktopButton.BackColor = BackColor;
1466                                 desktopButton.ForeColor = Color.White;
1467                                 desktopButton.Size = new Size (81, 64);
1468                                 desktopButton.Location = new Point (0, 64);
1469                                 desktopButton.Text = "Desktop";
1470                                 desktopButton.Click += new EventHandler (OnClickButton);
1471                                 
1472                                 personalButton.Image = ThemeEngine.Current.Images (UIIcon.PlacesPersonal, 30);
1473                                 personalButton.BackColor = BackColor;
1474                                 personalButton.ForeColor = Color.White;
1475                                 personalButton.Size = new Size (81, 64);
1476                                 personalButton.Location = new Point (0, 128);
1477                                 personalButton.Text = "Personal";
1478                                 personalButton.Click += new EventHandler (OnClickButton);
1479                                 
1480                                 mycomputerButton.Image = ThemeEngine.Current.Images (UIIcon.PlacesMyComputer, 30);
1481                                 mycomputerButton.BackColor = BackColor;
1482                                 mycomputerButton.ForeColor = Color.White;
1483                                 mycomputerButton.Size = new Size (81, 64);
1484                                 mycomputerButton.Location = new Point (0, 192);
1485                                 mycomputerButton.Text = "My Computer";
1486                                 mycomputerButton.Click += new EventHandler (OnClickButton);
1487                                 
1488                                 networkButton.Image = ThemeEngine.Current.Images (UIIcon.PlacesMyNetwork, 30);
1489                                 networkButton.BackColor = BackColor;
1490                                 networkButton.ForeColor = Color.White;
1491                                 networkButton.Size = new Size (81, 64);
1492                                 networkButton.Location = new Point (0, 256);
1493                                 networkButton.Text = "My Network";
1494                                 networkButton.Click += new EventHandler (OnClickButton);
1495                                 
1496                                 Controls.Add (recentlyusedButton);
1497                                 Controls.Add (desktopButton);
1498                                 Controls.Add (personalButton);
1499                                 Controls.Add (mycomputerButton);
1500                                 Controls.Add (networkButton);
1501                                 
1502                                 ResumeLayout (false);
1503                         }
1504                         
1505                         void OnClickButton (object sender, EventArgs e)
1506                         {
1507                                 if (lastPopupButton != null && (PopupButton)sender != lastPopupButton)
1508                                         lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal;
1509                                 lastPopupButton = sender as PopupButton;
1510                                 
1511                                 if (sender == recentlyusedButton) {
1512                                         if ((platform == 4) || (platform == 128))
1513                                         // do NOT change the following line!
1514                                         // FileDialog uses a special handling for recently used files on *nix
1515                                         // recently used files are not stored as links in a directory but
1516                                         // as a xml file called .recently-used in the users home dir
1517                                         // This matches the Freedesktop.org spec which gnome uses
1518                                                 fileDialog.ChangeDirectory (this, FileDialog.recently_string);
1519                                         else
1520                                                 fileDialog.ChangeDirectory (this, ThemeEngine.Current.Places (UIIcon.PlacesRecentDocuments));
1521                                 } else
1522                                 if (sender == desktopButton) {
1523                                         fileDialog.ChangeDirectory (this, ThemeEngine.Current.Places (UIIcon.PlacesDesktop));
1524                                 } else
1525                                 if (sender == personalButton) {
1526                                         fileDialog.ChangeDirectory (this, ThemeEngine.Current.Places (UIIcon.PlacesPersonal));
1527                                 } else
1528                                 if (sender == mycomputerButton) {
1529                                         if ((platform == 4) || (platform == 128))
1530                                         // do NOT change the following line!
1531                                         // on *nix we do not have a special folder MyComputer
1532                                                 fileDialog.ChangeDirectory (this, FileDialog.mycomputer_string);
1533                                         else
1534                                                 fileDialog.ChangeDirectory (this, ThemeEngine.Current.Places (UIIcon.PlacesMyComputer));
1535                                 } else
1536                                 if (sender == networkButton) {
1537                                         if ((platform == 4) || (platform == 128))
1538                                                 fileDialog.ChangeDirectory (this, FileDialog.network_string);
1539                                         else
1540                                                 fileDialog.ChangeDirectory (this, ThemeEngine.Current.Places (UIIcon.PlacesMyNetwork));
1541                                 }
1542                         }
1543                         
1544                         public void SetPopupButtonStateByPath (string path)
1545                         {
1546                                 if (path == FileDialog.recently_string || 
1547                                     path == ThemeEngine.Current.Places (UIIcon.PlacesRecentDocuments)) {
1548                                         if (lastPopupButton != recentlyusedButton) {
1549                                                 if (lastPopupButton != null)
1550                                                         lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal;
1551                                                 recentlyusedButton.ButtonState = PopupButton.PopupButtonState.Down;
1552                                                 lastPopupButton = recentlyusedButton;
1553                                         }
1554                                 } else
1555                                 if (path == ThemeEngine.Current.Places (UIIcon.PlacesDesktop)) {
1556                                         if (lastPopupButton != desktopButton) {
1557                                                 if (lastPopupButton != null)
1558                                                         lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal;
1559                                                 desktopButton.ButtonState = PopupButton.PopupButtonState.Down;
1560                                                 lastPopupButton = desktopButton;
1561                                         }
1562                                 } else
1563                                 if (path == ThemeEngine.Current.Places (UIIcon.PlacesPersonal)) {
1564                                         if (lastPopupButton != personalButton) {
1565                                                 if (lastPopupButton != null)
1566                                                         lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal;
1567                                                 personalButton.ButtonState = PopupButton.PopupButtonState.Down;
1568                                                 lastPopupButton = personalButton;
1569                                         }
1570                                 } else
1571                                 if (path == FileDialog.mycomputer_string || 
1572                                     path == ThemeEngine.Current.Places (UIIcon.PlacesMyComputer)) {
1573                                         if (lastPopupButton != mycomputerButton) {
1574                                                 if (lastPopupButton != null)
1575                                                         lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal;
1576                                                 mycomputerButton.ButtonState = PopupButton.PopupButtonState.Down;
1577                                                 lastPopupButton = mycomputerButton;
1578                                         }
1579                                 } else
1580                                 if (path == FileDialog.network_string || 
1581                                     path == ThemeEngine.Current.Places (UIIcon.PlacesMyNetwork)) {
1582                                         if (lastPopupButton != networkButton) {
1583                                                 if (lastPopupButton != null)
1584                                                         lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal;
1585                                                 networkButton.ButtonState = PopupButton.PopupButtonState.Down;
1586                                                 lastPopupButton = networkButton;
1587                                         }
1588                                 } else {
1589                                         if (lastPopupButton != null) {
1590                                                 lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal;
1591                                                 lastPopupButton = null;
1592                                         }
1593                                 }
1594                         }
1595                 }
1596         }
1597         
1598         internal struct FilterStruct {
1599                 public string filterName;
1600                 public StringCollection filters;
1601                 
1602                 public FilterStruct (string filterName, string filter)
1603                 {
1604                         this.filterName = filterName;
1605                         
1606                         filters =  new StringCollection ();
1607                         
1608                         SplitFilters (filter);
1609                 }
1610                 
1611                 private void SplitFilters (string filter)
1612                 {
1613                         string[] split = filter.Split (new char [] {';'});
1614                         
1615                         filters.AddRange (split);
1616                 }
1617         }
1618         
1619         internal struct FileStruct {
1620                 public enum FileStructType {
1621                         File,
1622                         Directoy,
1623                         Device,
1624                         Network
1625                 }
1626                 
1627                 public string fullname;
1628                 public FileAttributes attributes;
1629                 public long size;
1630                 public FileStructType type;
1631         }
1632         
1633         // MWFFileView
1634         internal class MWFFileView : ListView {
1635                 private ArrayList filterArrayList;
1636                 
1637                 // store the FileStruct of all files in the current directory
1638                 private Hashtable fileHashtable = new Hashtable();
1639                 
1640                 private bool showHiddenFiles = false;
1641                 
1642                 private EventHandler on_selected_file_changed;
1643                 private EventHandler on_selected_files_changed;
1644                 private EventHandler on_directory_changed;
1645                 private EventHandler on_force_dialog_end;
1646                 private EventHandler on_one_directory_up;
1647                 
1648                 private string fileName;
1649                 private string fullFileName;
1650                 private string selectedFilesString;
1651                 
1652                 private int filterIndex;
1653                 
1654                 private ToolTip toolTip;
1655                 private int oldItemIndexForToolTip = -1;
1656                 
1657                 private bool internal_key_up = false;
1658                 
1659                 private MasterMount masterMount = new MasterMount ();
1660                 
1661                 public MWFFileView ()
1662                 {
1663                         SuspendLayout ();
1664                         
1665                         toolTip = new ToolTip ();
1666                         toolTip.InitialDelay = 300;
1667                         toolTip.ReshowDelay = 0; 
1668                         
1669                         LabelWrap = true;
1670                         
1671                         SmallImageList = MimeIconEngine.SmallIcons;
1672                         LargeImageList = MimeIconEngine.LargeIcons;
1673                         
1674                         View = View.List;
1675                         
1676                         ResumeLayout (false);
1677                         
1678                         KeyUp += new KeyEventHandler (MWF_KeyUp);
1679                 }
1680                 
1681                 public ArrayList FilterArrayList {
1682                         set {
1683                                 filterArrayList = value;
1684                         }
1685                         
1686                         get {
1687                                 return filterArrayList;
1688                         }
1689                 }
1690                 
1691                 public Hashtable FileHashtable {
1692                         get {
1693                                 return fileHashtable;
1694                         }
1695                 }
1696                 
1697                 public bool ShowHiddenFiles {
1698                         set {
1699                                 showHiddenFiles = value;
1700                         }
1701                         
1702                         get {
1703                                 return showHiddenFiles;
1704                         }
1705                 }
1706                 
1707                 public string FileName {
1708                         get {
1709                                 return fileName;
1710                         }
1711                 }
1712                 
1713                 public string FullFileName {
1714                         get {
1715                                 return fullFileName;
1716                         }
1717                 }
1718                 
1719                 public int FilterIndex {
1720                         set {
1721                                 filterIndex = value;
1722                         }
1723                         
1724                         get {
1725                                 return filterIndex;
1726                         }
1727                 }
1728                 
1729                 public string SelectedFilesString {
1730                         set {
1731                                 selectedFilesString = value;
1732                         }
1733                         
1734                         get {
1735                                 return selectedFilesString;
1736                         }
1737                 }
1738                 
1739                 public void SetSelectedIndexTo (string fname)
1740                 {
1741                         foreach (ListViewItem item in Items) {
1742                                 if (item.Text == fname) {
1743                                         BeginUpdate ();
1744                                         SelectedItems.Clear ();
1745                                         item.Selected = true;
1746                                         EndUpdate ();
1747                                         break;
1748                                 }
1749                         }
1750                 }
1751                 
1752                 private ArrayList GetFileInfoArrayList (DirectoryInfo directoryInfo)
1753                 {
1754                         ArrayList arrayList = new ArrayList ();
1755                         
1756                         if (filterArrayList != null && filterArrayList.Count != 0) {
1757                                 FilterStruct fs = (FilterStruct)filterArrayList [filterIndex - 1];
1758                                 
1759                                 foreach (string s in fs.filters)
1760                                         arrayList.AddRange (directoryInfo.GetFiles (s));
1761                         } else
1762                                 arrayList.AddRange (directoryInfo.GetFiles ());
1763                         
1764                         return arrayList;
1765                 }
1766                 
1767                 private ArrayList GetFileInfoArrayListByArrayList (ArrayList al)
1768                 {
1769                         ArrayList arrayList = new ArrayList ();
1770                         
1771                         foreach (string path in al) {
1772                                 if (File.Exists (path)) {
1773                                         FileInfo fi = new FileInfo (path);
1774                                         arrayList.Add (fi);
1775                                 }
1776                         }
1777                         
1778                         return arrayList;
1779                 }
1780                 
1781                 public void UpdateFileView (object directoryInfo_or_string)
1782                 {
1783                         if (directoryInfo_or_string is DirectoryInfo)
1784                                 UpdateFileViewByDirectoryInfo (directoryInfo_or_string as DirectoryInfo);
1785                         else
1786                                 UpdateFileViewByString (directoryInfo_or_string as string);
1787                         
1788                         if (Items.Count > 0 && !internal_key_up) {
1789                                 ListViewItem item = Items [0];
1790                                 item.Selected = true;
1791                         } else
1792                                 internal_key_up = false;
1793                 }
1794                 
1795                 private void UpdateFileViewByDirectoryInfo (DirectoryInfo inputDirectoryInfo) 
1796                 {
1797                         DirectoryInfo directoryInfo = inputDirectoryInfo;
1798                         
1799                         DirectoryInfo[] directoryInfoArray = directoryInfo.GetDirectories ();
1800                         
1801                         ArrayList fileInfoArrayList = GetFileInfoArrayList (directoryInfo);
1802                         
1803                         fileHashtable.Clear ();
1804                         
1805                         BeginUpdate ();
1806                         
1807                         Items.Clear ();
1808                         SelectedItems.Clear ();
1809                         
1810                         foreach (DirectoryInfo directoryInfoi in directoryInfoArray) {
1811                                 if (!ShowHiddenFiles)
1812                                         if (directoryInfoi.Name.StartsWith (".") || directoryInfoi.Attributes == FileAttributes.Hidden)
1813                                                 continue;
1814                                 
1815                                 FileStruct fileStruct = new FileStruct ();
1816                                 fileStruct.type = FileStruct.FileStructType.Directoy;
1817                                 
1818                                 fileStruct.fullname = directoryInfoi.FullName;
1819                                 
1820                                 ListViewItem listViewItem = new ListViewItem (directoryInfoi.Name);
1821                                 
1822                                 int index = MimeIconEngine.GetIconIndexForMimeType ("inode/directory");
1823                                 
1824                                 listViewItem.ImageIndex = index;
1825                                 
1826                                 listViewItem.SubItems.Add ("");
1827                                 listViewItem.SubItems.Add ("Directory");
1828                                 listViewItem.SubItems.Add (directoryInfoi.LastAccessTime.ToShortDateString () + " " + directoryInfoi.LastAccessTime.ToShortTimeString ());
1829                                 
1830                                 fileStruct.attributes = FileAttributes.Directory;
1831                                 
1832                                 fileHashtable.Add (directoryInfoi.Name, fileStruct);
1833                                 
1834                                 Items.Add (listViewItem);
1835                         }
1836                         
1837                         foreach (FileInfo fileInfo in fileInfoArrayList) {
1838                                 DoOneFileInfo (fileInfo);
1839                         }
1840                         
1841                         EndUpdate ();
1842                 }
1843                 
1844                 private void UpdateFileViewByString (string kind) 
1845                 {
1846                         if (kind == FileDialog.recently_string) {
1847                                 ArrayList fileInfoArrayList = GetFileInfoArrayListByArrayList (GetFreedesktopSpecRecentlyUsed ());
1848                                 
1849                                 fileHashtable.Clear ();
1850                                 
1851                                 BeginUpdate ();
1852                                 
1853                                 Items.Clear ();
1854                                 SelectedItems.Clear ();
1855                                 
1856                                 foreach (FileInfo fileInfo in fileInfoArrayList) {
1857                                         DoOneFileInfo (fileInfo);
1858                                 }
1859                                 
1860                                 EndUpdate ();
1861                                 
1862                         } else if (kind == FileDialog.mycomputer_string) {
1863                                 
1864                                 if (masterMount.ProcMountAvailable) {
1865                                         masterMount.GetMounts ();
1866                                         
1867                                         fileHashtable.Clear ();
1868                                         
1869                                         BeginUpdate ();
1870                                         
1871                                         Items.Clear ();
1872                                         SelectedItems.Clear ();
1873                                         
1874                                         foreach (MasterMount.Mount mount in masterMount.Block_devices) {
1875                                                 FileStruct fileStruct = new FileStruct ();
1876                                                 fileStruct.type = FileStruct.FileStructType.Device;
1877                                                 
1878                                                 fileStruct.fullname = mount.mount_point;
1879                                                 
1880                                                 string item_name = "HDD (" + mount.fsType + ", " + mount.device_short + ")";
1881                                                 ListViewItem listViewItem = new ListViewItem (item_name);
1882                                                 
1883                                                 int index = MimeIconEngine.GetIconIndexForMimeType ("harddisk/harddisk");
1884                                                 
1885                                                 listViewItem.ImageIndex = index;
1886                                                 
1887                                                 listViewItem.SubItems.Add ("");
1888                                                 listViewItem.SubItems.Add ("Harddisk");
1889 //                                              listViewItem.SubItems.Add (directoryInfoi.LastAccessTime.ToShortDateString () + " " + directoryInfoi.LastAccessTime.ToShortTimeString ());
1890                                                 
1891                                                 fileStruct.attributes = FileAttributes.Directory;
1892                                                 
1893                                                 fileHashtable.Add (item_name, fileStruct);
1894                                                 
1895                                                 Items.Add (listViewItem);
1896                                         }
1897                                         
1898                                         foreach (MasterMount.Mount mount in masterMount.Removable_devices) {
1899                                                 FileStruct fileStruct = new FileStruct ();
1900                                                 fileStruct.type = FileStruct.FileStructType.Device;
1901                                                 
1902                                                 fileStruct.fullname = mount.mount_point;
1903                                                 
1904                                                 bool is_dvd_cdrom = mount.fsType == MasterMount.FsTypes.usbfs ? false : true;
1905                                                 string type_name = is_dvd_cdrom ? "DVD/CD-Rom" : "USB";
1906                                                 string mime_type = is_dvd_cdrom ? "cdrom/cdrom" : "removable/removable";
1907                                                 
1908                                                 string item_name = type_name + " (" + mount.device_short + ")";
1909                                                 
1910                                                 ListViewItem listViewItem = new ListViewItem (item_name);
1911                                                 
1912                                                 int index = MimeIconEngine.GetIconIndexForMimeType (mime_type);
1913                                                 
1914                                                 listViewItem.ImageIndex = index;
1915                                                 
1916                                                 listViewItem.SubItems.Add ("");
1917                                                 listViewItem.SubItems.Add (type_name);
1918 //                                              listViewItem.SubItems.Add (directoryInfoi.LastAccessTime.ToShortDateString () + " " + directoryInfoi.LastAccessTime.ToShortTimeString ());
1919                                                 
1920                                                 fileStruct.attributes = FileAttributes.Directory;
1921                                                 
1922                                                 fileHashtable.Add (item_name, fileStruct);
1923                                                 
1924                                                 Items.Add (listViewItem);
1925                                         }
1926                                         
1927                                         ListViewItem listViewItem2 = new ListViewItem ("Desktop");
1928                                         
1929                                         int index2 = MimeIconEngine.GetIconIndexForMimeType ("desktop/desktop");
1930                                         
1931                                         FileStruct fileStruct2 = new FileStruct ();
1932                                         fileStruct2.type = FileStruct.FileStructType.Directoy;
1933                                         
1934                                         fileStruct2.fullname = ThemeEngine.Current.Places (UIIcon.PlacesDesktop);
1935                                         
1936                                         listViewItem2.ImageIndex = index2;
1937                                         
1938                                         listViewItem2.SubItems.Add ("");
1939                                         listViewItem2.SubItems.Add ("Desktop");
1940 //                                      listViewItem.SubItems.Add (directoryInfoi.LastAccessTime.ToShortDateString () + " " + directoryInfoi.LastAccessTime.ToShortTimeString ());
1941                                         
1942                                         fileStruct2.attributes = FileAttributes.Directory;
1943                                         
1944                                         fileHashtable.Add ("Desktop", fileStruct2);
1945                                         
1946                                         Items.Add (listViewItem2);
1947                                         
1948                                         
1949                                         listViewItem2 = new ListViewItem ("Personal");
1950                                         
1951                                         index2 = MimeIconEngine.GetIconIndexForMimeType ("directory/home");
1952                                         
1953                                         fileStruct2 = new FileStruct ();
1954                                         fileStruct2.type = FileStruct.FileStructType.Directoy;
1955                                         
1956                                         fileStruct2.fullname = ThemeEngine.Current.Places (UIIcon.PlacesPersonal);
1957                                         
1958                                         listViewItem2.ImageIndex = index2;
1959                                         
1960                                         listViewItem2.SubItems.Add ("");
1961                                         listViewItem2.SubItems.Add ("Personal");
1962 //                                      listViewItem.SubItems.Add (directoryInfoi.LastAccessTime.ToShortDateString () + " " + directoryInfoi.LastAccessTime.ToShortTimeString ());
1963                                         
1964                                         fileStruct2.attributes = FileAttributes.Directory;
1965                                         
1966                                         fileHashtable.Add ("Personal", fileStruct2);
1967                                         
1968                                         Items.Add (listViewItem2);
1969                                         
1970                                         AddNetwork ();
1971                                         
1972                                         EndUpdate ();
1973                                 }
1974                                 
1975                         } else if (kind == FileDialog.network_string) {
1976                                 
1977                                 if (masterMount.ProcMountAvailable) {
1978                                         masterMount.GetMounts ();
1979                                         
1980                                         fileHashtable.Clear ();
1981                                         
1982                                         BeginUpdate ();
1983                                         
1984                                         Items.Clear ();
1985                                         SelectedItems.Clear ();
1986                                         
1987                                         AddNetwork ();
1988                                         
1989                                         EndUpdate ();
1990                                 }
1991                         }
1992                 }
1993                 
1994                 private void AddNetwork ()
1995                 {
1996                         foreach (MasterMount.Mount mount in masterMount.Network_devices) {
1997                                 FileStruct fileStruct = new FileStruct ();
1998                                 fileStruct.type = FileStruct.FileStructType.Network;
1999                                 
2000                                 fileStruct.fullname = mount.mount_point;
2001                                 
2002                                 string item_name = "Network (" + mount.fsType + ", " + mount.device_short + ")";
2003                                 
2004                                 ListViewItem listViewItem = new ListViewItem (item_name);
2005                                 
2006                                 int index = 0;
2007                                 
2008                                 switch (mount.fsType) {
2009                                 case MasterMount.FsTypes.nfs:
2010                                         index = MimeIconEngine.GetIconIndexForMimeType ("nfs/nfs");
2011                                         break;
2012                                 case MasterMount.FsTypes.smbfs:
2013                                         index = MimeIconEngine.GetIconIndexForMimeType ("smb/smb");
2014                                         break;
2015                                 case MasterMount.FsTypes.ncpfs:
2016                                         index = MimeIconEngine.GetIconIndexForMimeType ("network/network");
2017                                         break;
2018                                 default:
2019                                         break;
2020                                 }
2021                                 
2022                                 listViewItem.ImageIndex = index;
2023                                 
2024                                 listViewItem.SubItems.Add ("");
2025                                 listViewItem.SubItems.Add ("Network");
2026 //                              listViewItem.SubItems.Add (directoryInfoi.LastAccessTime.ToShortDateString () + " " + directoryInfoi.LastAccessTime.ToShortTimeString ());
2027                                 
2028                                 fileStruct.attributes = FileAttributes.Directory;
2029                                 
2030                                 fileHashtable.Add (item_name, fileStruct);
2031                                 
2032                                 Items.Add (listViewItem);
2033                         }
2034                 }
2035                 
2036                 private void DoOneFileInfo (FileInfo fileInfo) 
2037                 {
2038                         if (!ShowHiddenFiles)
2039                                 if (fileInfo.Name.StartsWith (".")  || fileInfo.Attributes == FileAttributes.Hidden)
2040                                         return;
2041                         
2042                         FileStruct fileStruct = new FileStruct ();
2043                         fileStruct.type = FileStruct.FileStructType.File;
2044                         
2045                         fileStruct.fullname = fileInfo.FullName;
2046                         
2047                         string fileName = fileInfo.Name;
2048                         
2049                         if (fileHashtable.ContainsKey (fileName)) {
2050                                 int i = 1;
2051                                 while (fileHashtable.ContainsKey (fileName + "[" + i + "]")) {
2052                                         i++;
2053                                 }
2054                                 fileName += "[" + i + "]";
2055                         }
2056                         
2057                         ListViewItem listViewItem = new ListViewItem (fileName);
2058                         
2059                         listViewItem.ImageIndex = MimeIconEngine.GetIconIndexForFile (fileStruct.fullname);
2060                         
2061                         long fileLen = 1;
2062                         try {
2063                                 if (fileInfo.Length > 1024)
2064                                         fileLen = fileInfo.Length / 1024;
2065                         } catch (Exception) {
2066                                 fileLen = 1;
2067                         }
2068                         
2069                         fileStruct.size = fileLen;
2070                         
2071                         listViewItem.SubItems.Add (fileLen.ToString () + " KB");
2072                         listViewItem.SubItems.Add ("File");
2073                         listViewItem.SubItems.Add (fileInfo.LastAccessTime.ToShortDateString () + " " + fileInfo.LastAccessTime.ToShortTimeString ());
2074                         
2075                         fileStruct.attributes = FileAttributes.Normal;
2076                         
2077                         fileHashtable.Add (fileName, fileStruct);
2078                         
2079                         Items.Add (listViewItem);
2080                 }
2081                 
2082                 private ArrayList GetFreedesktopSpecRecentlyUsed () 
2083                 {
2084                         // check for GNOME and KDE
2085                         string personal_folder = ThemeEngine.Current.Places (UIIcon.PlacesPersonal);
2086                         string recently_used_path = Path.Combine (personal_folder, ".recently-used");
2087                         
2088                         ArrayList files_al = new ArrayList ();
2089                         
2090                         // GNOME
2091                         if (File.Exists (recently_used_path)) {
2092                                 try {
2093                                         XmlTextReader xtr = new XmlTextReader (recently_used_path);
2094                                         while (xtr.Read ()) {
2095                                                 if (xtr.NodeType == XmlNodeType.Element && xtr.Name.ToUpper () == "URI") {
2096                                                         xtr.Read ();
2097                                                         Uri uri = new Uri (xtr.Value);
2098                                                         if (!files_al.Contains (uri.LocalPath))
2099                                                                 files_al.Add (uri.LocalPath);
2100                                                 }
2101                                         }
2102                                         xtr.Close ();
2103                                 } catch (Exception) {
2104                                         
2105                                 }
2106                         }
2107                         
2108                         // KDE
2109                         string full_kde_recent_document_dir = personal_folder
2110                                 + "/"
2111                                 + ".kde/share/apps/RecentDocuments";
2112                         
2113                         if (Directory.Exists (full_kde_recent_document_dir)) {
2114                                 string[] files = Directory.GetFiles (full_kde_recent_document_dir, "*.desktop");
2115                                 
2116                                 foreach (string file_name in files) {
2117                                         StreamReader sr = new StreamReader (file_name);
2118                                         
2119                                         string line = sr.ReadLine ();
2120                                         
2121                                         while (line != null) {
2122                                                 line = line.Trim ();
2123                                                 
2124                                                 if (line.StartsWith ("URL=")) {
2125                                                         line = line.Replace ("URL=", "");
2126                                                         line = line.Replace ("$HOME", personal_folder);
2127                                                         
2128                                                         Uri uri = new Uri (line);
2129                                                         if (!files_al.Contains (uri.LocalPath))
2130                                                                 files_al.Add (uri.LocalPath);
2131                                                         break;
2132                                                 }
2133                                                 
2134                                                 line = sr.ReadLine ();
2135                                         }
2136                                         
2137                                         sr.Close ();
2138                                 }
2139                         }
2140                         
2141                         
2142                         return files_al;
2143                 }
2144                 
2145                 protected override void OnClick (EventArgs e)
2146                 {
2147                         if (!MultiSelect) {
2148                                 if (SelectedItems.Count > 0) {
2149                                         ListViewItem listViewItem = SelectedItems [0];
2150                                         
2151                                         FileStruct fileStruct = (FileStruct)fileHashtable [listViewItem.Text];
2152                                         
2153                                         if (fileStruct.type == FileStruct.FileStructType.File) {
2154                                                 fileName = listViewItem.Text;
2155                                                 fullFileName = fileStruct.fullname;
2156                                                 
2157                                                 if (on_selected_file_changed != null)
2158                                                         on_selected_file_changed (this, EventArgs.Empty);
2159                                         }
2160                                 }
2161                         }
2162                         
2163                         base.OnClick (e);
2164                 }
2165                 
2166                 protected override void OnDoubleClick (EventArgs e)
2167                 {
2168                         if (SelectedItems.Count > 0) {
2169                                 ListViewItem listViewItem = SelectedItems [0];
2170                                 
2171                                 FileStruct fileStruct = (FileStruct)fileHashtable [listViewItem.Text];
2172                                 
2173                                 if (fileStruct.attributes == FileAttributes.Directory) {
2174                                         fullFileName = fileStruct.fullname;
2175                                         
2176                                         if (on_directory_changed != null)
2177                                                 on_directory_changed (this, EventArgs.Empty);
2178                                 } else {
2179                                         fileName = listViewItem.Text;
2180                                         fullFileName = fileStruct.fullname;
2181                                         
2182                                         if (on_selected_file_changed != null)
2183                                                 on_selected_file_changed (this, EventArgs.Empty);
2184                                         
2185                                         if (on_force_dialog_end != null)
2186                                                 on_force_dialog_end (this, EventArgs.Empty);
2187                                         
2188                                         return;
2189                                 }
2190                         }
2191                         
2192                         base.OnDoubleClick (e);
2193                 }
2194                 
2195                 protected override void OnSelectedIndexChanged (EventArgs e)
2196                 {
2197                         if (MultiSelect) {
2198                                 if (SelectedItems.Count > 0) {
2199                                         selectedFilesString = "";
2200                                         
2201                                         if (SelectedItems.Count == 1) {
2202                                                 FileStruct fileStruct = (FileStruct)fileHashtable [SelectedItems [0].Text];
2203                                                 
2204                                                 if (fileStruct.attributes != FileAttributes.Directory)
2205                                                         selectedFilesString = SelectedItems [0].Text;
2206                                         } else {
2207                                                 foreach (ListViewItem lvi in SelectedItems) {
2208                                                         FileStruct fileStruct = (FileStruct)fileHashtable [lvi.Text];
2209                                                         
2210                                                         if (fileStruct.attributes != FileAttributes.Directory)
2211                                                                 selectedFilesString += "\"" + lvi.Text + "\" ";
2212                                                 }
2213                                         }
2214                                         
2215                                         if (on_selected_files_changed != null)
2216                                                 on_selected_files_changed (this, EventArgs.Empty);
2217                                 }
2218                         }
2219                         
2220                         base.OnSelectedIndexChanged (e);
2221                 }
2222                 
2223                 protected override void OnMouseMove (MouseEventArgs e)
2224                 {
2225                         ListViewItem item = GetItemAt (e.X, e.Y);
2226                         
2227                         if (item != null) {
2228                                 int currentItemIndex = item.Index;
2229                                 
2230                                 if (currentItemIndex != oldItemIndexForToolTip) {
2231                                         oldItemIndexForToolTip = currentItemIndex;
2232                                         
2233                                         if (toolTip != null && toolTip.Active)
2234                                                 toolTip.Active = false;
2235                                         
2236                                         object fileStructObject = fileHashtable [item.Text];
2237                                         
2238                                         if (fileStructObject != null) {
2239                                                 
2240                                                 FileStruct fileStruct = (FileStruct)fileStructObject;
2241                                                 
2242                                                 string output = String.Empty;
2243                                                 
2244                                                 if (fileStruct.type == FileStruct.FileStructType.Directoy)
2245                                                         output = String.Format ("Directory: {0}\n", fileStruct.fullname);
2246                                                 else if (fileStruct.type == FileStruct.FileStructType.Device)
2247                                                         output = String.Format ("Device: {0}", fileStruct.fullname);
2248                                                 else if (fileStruct.type == FileStruct.FileStructType.Network)
2249                                                         output = String.Format ("Network: {0}", fileStruct.fullname);
2250                                                 else
2251                                                         output = String.Format ("File: {0}", fileStruct.fullname);
2252                                                 
2253                                                 toolTip.SetToolTip (this, output);      
2254                                                 
2255                                                 toolTip.Active = true;
2256                                         }
2257                                 }
2258                         }
2259                         
2260                         base.OnMouseMove (e);
2261                 }
2262                 
2263                 private void MWF_KeyUp (object sender, KeyEventArgs e)
2264                 {
2265                         if (SelectedItems.Count > 0 && e.KeyCode == Keys.Back)
2266                                 if (on_one_directory_up != null) {
2267                                         internal_key_up = true;
2268                                         on_one_directory_up (this, EventArgs.Empty);
2269                                 }
2270                 }
2271                 
2272                 public event EventHandler SelectedFileChanged {
2273                         add { on_selected_file_changed += value; }
2274                         remove { on_selected_file_changed -= value; }
2275                 }
2276                 
2277                 public event EventHandler SelectedFilesChanged {
2278                         add { on_selected_files_changed += value; }
2279                         remove { on_selected_files_changed -= value; }
2280                 }
2281                 
2282                 public event EventHandler DirectoryChanged {
2283                         add { on_directory_changed += value; }
2284                         remove { on_directory_changed -= value; }
2285                 }
2286                 
2287                 public event EventHandler ForceDialogEnd {
2288                         add { on_force_dialog_end += value; }
2289                         remove { on_force_dialog_end -= value; }
2290                 }
2291                 
2292                 public event EventHandler OnDirectoryUp {
2293                         add { on_one_directory_up += value; }
2294                         remove { on_one_directory_up -= value; }
2295                 }
2296         }
2297         
2298         internal class FileFilter {
2299                 private ArrayList filterArrayList = new ArrayList();
2300                 
2301                 private string filter;
2302                 
2303                 public FileFilter ()
2304                 {}
2305                 
2306                 public FileFilter (string filter)
2307                 {
2308                         this.filter = filter;
2309                         
2310                         SplitFilter ();
2311                 }
2312                 
2313                 public ArrayList FilterArrayList {
2314                         set {
2315                                 filterArrayList = value;
2316                         }
2317                         
2318                         get {
2319                                 return filterArrayList;
2320                         }
2321                 }
2322                 
2323                 public string Filter {
2324                         set {
2325                                 filter = value;
2326                                 
2327                                 SplitFilter ();
2328                         }
2329                         
2330                         get {
2331                                 return filter;
2332                         }
2333                 }
2334                 
2335                 private void SplitFilter ()
2336                 {
2337                         filterArrayList.Clear ();
2338                         
2339                         if (filter == null)
2340                                 throw new NullReferenceException ("Filter");
2341                         
2342                         if (filter.Length == 0)
2343                                 return;
2344                         
2345                         string[] filters = filter.Split (new char [] {'|'});
2346                         
2347                         if ((filters.Length % 2) != 0)
2348                                 throw new ArgumentException ("Filter");
2349                         
2350                         for (int i = 0; i < filters.Length; i += 2) {
2351                                 FilterStruct filterStruct = new FilterStruct (filters [i], filters [i + 1]);
2352                                 
2353                                 filterArrayList.Add (filterStruct);
2354                         }
2355                 }
2356         }
2357         
2358         internal class DirComboBox : ComboBox {
2359                 internal class DirComboBoxItem {
2360                         private int imageIndex;
2361                         private string name;
2362                         private string path;
2363                         private int xPos;
2364                         
2365                         public DirComboBoxItem (int imageIndex, string name, string path, int xPos)
2366                         {
2367                                 this.imageIndex = imageIndex;
2368                                 this.name = name;
2369                                 this.path = path;
2370                                 this.xPos = xPos;
2371                         }
2372                         
2373                         public int ImageIndex {
2374                                 set {
2375                                         imageIndex = value;
2376                                 }
2377                                 
2378                                 get {
2379                                         return imageIndex;
2380                                 }
2381                         }
2382                         
2383                         public string Name {
2384                                 set {
2385                                         name = value;
2386                                 }
2387                                 
2388                                 get {
2389                                         return name;
2390                                 }
2391                         }
2392                         
2393                         public string Path {
2394                                 set {
2395                                         path = value;
2396                                 }
2397                                 
2398                                 get {
2399                                         return path;
2400                                 }
2401                         }
2402                         
2403                         public int XPos {
2404                                 set {
2405                                         xPos = value;
2406                                 }
2407                                 
2408                                 get {
2409                                         return xPos;
2410                                 }
2411                         }
2412                 }
2413                 
2414                 private ImageList imageList = new ImageList();
2415                 
2416                 private string currentPath;
2417                 
2418                 private EventHandler on_directory_changed;
2419                 
2420                 private bool currentpath_internal_change = false;
2421                 
2422                 private int platform = (int) Environment.OSVersion.Platform;
2423                 private string recently_used_tmp;
2424                 private string my_computer_tmp;
2425                 private string my_network_tmp;
2426                 private string my_root_tmp;
2427                 private Stack dirStack = new Stack();
2428                 
2429                 public DirComboBox ()
2430                 {
2431                         SuspendLayout ();
2432                         
2433                         DrawMode = DrawMode.OwnerDrawFixed;
2434                         
2435                         imageList.ColorDepth = ColorDepth.Depth32Bit;
2436                         imageList.ImageSize = new Size (16, 16);
2437                         imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.PlacesRecentDocuments, 16));
2438                         imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.PlacesDesktop, 16));
2439                         imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.PlacesPersonal, 16));
2440                         imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.PlacesMyComputer, 16));
2441                         imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.PlacesMyNetwork, 16));
2442                         imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.NormalFolder, 16));
2443                         imageList.TransparentColor = Color.Transparent;
2444                         
2445                         if ((platform == 4) || (platform == 128)) {
2446                                 recently_used_tmp = FileDialog.recently_string;
2447                                 my_computer_tmp = FileDialog.mycomputer_string;
2448                                 my_network_tmp = FileDialog.network_string;
2449                                 my_root_tmp = "/";
2450                         } else {
2451                                 recently_used_tmp = ThemeEngine.Current.Places (UIIcon.PlacesRecentDocuments);
2452                                 my_computer_tmp = ThemeEngine.Current.Places (UIIcon.PlacesMyComputer);
2453                                 my_network_tmp = ThemeEngine.Current.Places (UIIcon.PlacesMyNetwork);
2454                         }
2455                         
2456                         Items.AddRange (new object        [] {
2457                                                 new DirComboBoxItem (0, "Recently used", recently_used_tmp, 0),
2458                                                 new DirComboBoxItem (1, "Desktop", ThemeEngine.Current.Places (UIIcon.PlacesDesktop), 0),
2459                                                 new DirComboBoxItem (2, "Personal folder", ThemeEngine.Current.Places (UIIcon.PlacesPersonal), 0),
2460                                                 new DirComboBoxItem (3, "My Computer", my_computer_tmp, 0),
2461                                                 new DirComboBoxItem (4, "My Network", my_network_tmp, 0)
2462                                         }
2463                                         );
2464                         
2465                         if ((platform == 4) || (platform == 128)) {
2466                                 Items.Add(new DirComboBoxItem (5, "/", my_root_tmp, 0));
2467                         }
2468                         
2469                         ResumeLayout (false);
2470                 }
2471                 
2472                 public string CurrentPath {
2473                         set {
2474                                 currentPath = value;
2475                                 
2476                                 currentpath_internal_change = true;
2477                                 
2478                                 CreateComboList ();
2479                         }
2480                         get {
2481                                 return currentPath;
2482                         }
2483                 }
2484                 
2485                 private void CreateComboList ()
2486                 {
2487                         int selection = -1;
2488                         int child_of = - 1;
2489                         
2490                         if (currentPath == recently_used_tmp)
2491                                 selection = 0;
2492                         else
2493                         if (currentPath == ThemeEngine.Current.Places (UIIcon.PlacesDesktop))
2494                                 selection = 1;
2495                         else
2496                         if (currentPath == ThemeEngine.Current.Places (UIIcon.PlacesPersonal))
2497                                 selection = 2;
2498                         else
2499                         if (currentPath == my_computer_tmp)
2500                                 selection = 3;
2501                         else
2502                         if (currentPath == my_network_tmp)
2503                                 selection = 4;
2504                         else
2505                         if (currentPath == my_root_tmp)
2506                                 selection = 5;
2507                         
2508                         child_of = CheckChildOf ();
2509                         
2510                         BeginUpdate ();
2511                         
2512                         Items.Clear ();
2513                         
2514                         Items.Add (new DirComboBoxItem (0, "Recently used", recently_used_tmp, 0));
2515                         
2516                         Items.Add (new DirComboBoxItem (1, "Desktop", ThemeEngine.Current.Places (UIIcon.PlacesDesktop), 0));
2517                         if (child_of == 1)
2518                                 selection = AppendToParent ();
2519                         
2520                         Items.Add (new DirComboBoxItem (2, "Personal folder", ThemeEngine.Current.Places (UIIcon.PlacesPersonal), 0));
2521                         if (child_of == 2)
2522                                 selection = AppendToParent ();
2523                         
2524                         Items.Add (new DirComboBoxItem (3, "My Computer", my_computer_tmp, 0));
2525                         
2526                         Items.Add (new DirComboBoxItem (4, "My Network", my_network_tmp, 0));
2527                         
2528                         if ((platform == 4) || (platform == 128)) {
2529                                 Items.Add (new DirComboBoxItem (5, "/", my_root_tmp, 0));
2530                                 if (child_of == 15)
2531                                         selection = AppendToParent ();
2532                         }
2533                         
2534                         if (selection != -1)
2535                                 SelectedIndex = selection;
2536                         
2537                         EndUpdate ();
2538                 }
2539                 
2540                 private int CheckChildOf ()
2541                 {
2542                         dirStack.Clear ();
2543                         
2544                         if (currentPath == FileDialog.mycomputer_string ||
2545                             currentPath == FileDialog.network_string ||
2546                             currentPath == FileDialog.recently_string)
2547                                 return -1;
2548                         
2549                         DirectoryInfo di = new DirectoryInfo (currentPath);
2550                         
2551                         dirStack.Push (di);
2552                         
2553                         while (di.Parent != null) {
2554                                 di = di.Parent;
2555                                 if (di.FullName == ThemeEngine.Current.Places (UIIcon.PlacesDesktop))
2556                                         return 1;
2557                                 else
2558                                 if (di.FullName == ThemeEngine.Current.Places (UIIcon.PlacesPersonal) || di.FullName == "/home")
2559                                         return 2;
2560                                 else
2561                                 if (di.FullName == "/")
2562                                         return 15;
2563                                 
2564                                 dirStack.Push (di);
2565                         }
2566                         
2567                         return -1;
2568                 }
2569                 
2570                 private int AppendToParent ()
2571                 {
2572                         int xPos = 0;
2573                         int selection = -1;
2574                         
2575                         while (dirStack.Count != 0) {
2576                                 DirectoryInfo dii = dirStack.Pop () as DirectoryInfo;
2577                                 selection = Items.Add (new DirComboBoxItem (5, dii.Name, dii.FullName, xPos + 4));
2578                                 xPos += 4;
2579                         }
2580                         
2581                         return selection;
2582                 }
2583                 
2584                 protected override void OnDrawItem (DrawItemEventArgs e)
2585                 {
2586                         if (e.Index == -1)
2587                                 return;
2588                         
2589                         Bitmap bmp = new Bitmap (e.Bounds.Width, e.Bounds.Height, e.Graphics);
2590                         Graphics gr = Graphics.FromImage (bmp);
2591                         
2592                         DirComboBoxItem dcbi = Items [e.Index] as DirComboBoxItem;
2593                         
2594                         Color backColor = e.BackColor;
2595                         Color foreColor = e.ForeColor;
2596                         
2597                         int xPos = dcbi.XPos;
2598                         
2599                         if ((e.State & DrawItemState.ComboBoxEdit) != 0)
2600                                 xPos = 0;
2601                         else
2602                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
2603                                 backColor = ThemeEngine.Current.ColorHighlight;
2604                                 foreColor = ThemeEngine.Current.ColorHighlightText;
2605                         }
2606                         
2607                         gr.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (backColor), new Rectangle (0, 0, bmp.Width, bmp.Height));
2608                         
2609                         gr.DrawString (dcbi.Name, e.Font , ThemeEngine.Current.ResPool.GetSolidBrush (foreColor), new Point (24 + xPos, (bmp.Height - e.Font.Height) / 2));
2610                         gr.DrawImage (imageList.Images [dcbi.ImageIndex], new Rectangle (new Point (xPos + 2, 0), new Size (16, 16)));
2611                         
2612                         e.Graphics.DrawImage (bmp, e.Bounds.X, e.Bounds.Y);
2613                         gr.Dispose ();
2614                         bmp.Dispose ();
2615                 }
2616                 
2617                 protected override void OnSelectedIndexChanged (EventArgs e)
2618                 {
2619                         if (Items.Count > 0) {
2620                                 DirComboBoxItem dcbi = Items [SelectedIndex] as DirComboBoxItem;
2621                                 
2622                                 currentPath = dcbi.Path;
2623                                 
2624                                 // call DirectoryChange event only if the user changes the index with the ComboBox
2625                                 if (!currentpath_internal_change) {
2626                                         if (on_directory_changed != null)
2627                                                 on_directory_changed (this, EventArgs.Empty);
2628                                 }
2629                         }
2630                         
2631                         currentpath_internal_change = false;
2632                 }
2633                 
2634                 public event EventHandler DirectoryChanged {
2635                         add { on_directory_changed += value; }
2636                         remove { on_directory_changed -= value; }
2637                 }
2638         }
2639         
2640         // Alexsantas little helper
2641         internal class MasterMount {
2642                 // add more...
2643                 internal enum FsTypes {
2644                         ext2,
2645                         ext3,
2646                         hpfs,
2647                         iso9660,
2648                         jfs,
2649                         minix,
2650                         msdos,
2651                         ntfs,
2652                         reiserfs,
2653                         ufs,
2654                         umsdos,
2655                         vfat,
2656                         sysv,
2657                         xfs,
2658                         ncpfs,
2659                         nfs,
2660                         smbfs,
2661                         usbfs
2662                 }
2663                 
2664                 internal struct Mount {
2665                         public string device_or_filesystem;
2666                         public string device_short;
2667                         public string mount_point;
2668                         public FsTypes fsType;
2669                 }
2670                 
2671                 bool proc_mount_available = false;
2672                 
2673                 ArrayList block_devices = new ArrayList ();
2674                 ArrayList network_devices = new ArrayList ();
2675                 ArrayList removable_devices = new ArrayList ();
2676                 
2677                 private int platform = (int) Environment.OSVersion.Platform;
2678                 private MountComparer mountComparer = new MountComparer ();
2679                 
2680                 public MasterMount ()
2681                 {
2682                         // maybe check if the current user can access /proc/mounts
2683                         if ((platform == 4) || (platform == 128))
2684                                 if (File.Exists ("/proc/mounts"))
2685                                         proc_mount_available = true;
2686                 }
2687                 
2688                 public ArrayList Block_devices {
2689                         get {
2690                                 return block_devices;
2691                         }
2692                 }
2693                 
2694                 public ArrayList Network_devices {
2695                         get {
2696                                 return network_devices;
2697                         }
2698                 }
2699                 
2700                 public ArrayList Removable_devices {
2701                         get {
2702                                 return removable_devices;
2703                         }
2704                 }
2705                 
2706                 public bool ProcMountAvailable {
2707                         get {
2708                                 return proc_mount_available;
2709                         }
2710                 }
2711                 
2712                 public void GetMounts ()
2713                 {
2714                         if (!proc_mount_available)
2715                                 return;
2716                         
2717                         block_devices.Clear ();
2718                         network_devices.Clear ();
2719                         removable_devices.Clear ();
2720                         
2721                         try {
2722                                 StreamReader sr = new StreamReader ("/proc/mounts");
2723                                 
2724                                 string line = sr.ReadLine ();
2725                                 
2726                                 while (line != null) {
2727                                         ProcessProcMountLine (line);
2728                                         line = sr.ReadLine ();
2729                                 }
2730                                 
2731                                 sr.Close ();
2732                                 
2733                                 block_devices.Sort (mountComparer);
2734                                 network_devices.Sort (mountComparer);
2735                                 removable_devices.Sort (mountComparer);
2736                         } catch {
2737                                 // bla
2738                         }
2739                 }
2740                 
2741                 private void ProcessProcMountLine (string line)
2742                 {
2743                         string[] split = line.Split (new char [] {' '});
2744                         
2745                         if (split != null && split.Length > 0) {
2746                                 Mount mount = new Mount ();
2747                                 
2748                                 if (split [0].StartsWith ("/dev/"))
2749                                         mount.device_short = split [0].Replace ("/dev/", "");
2750                                 else 
2751                                         mount.device_short = split [0];
2752                                 
2753                                 mount.device_or_filesystem = split [0];
2754                                 mount.mount_point = split [1];
2755                                 
2756                                 // TODO: other removable devices, floppy
2757                                 // ssh
2758                                 
2759                                 // network mount
2760                                 if (split [2] == "nfs") {
2761                                         mount.fsType = FsTypes.nfs;
2762                                         network_devices.Add (mount);
2763                                 } else if (split [2] == "smbfs") {
2764                                         mount.fsType = FsTypes.smbfs;
2765                                         network_devices.Add (mount);
2766                                 } else if (split [2] == "ncpfs") {
2767                                         mount.fsType = FsTypes.ncpfs;
2768                                         network_devices.Add (mount);
2769                                         
2770                                 } else if (split [2] == "iso9660") { //cdrom
2771                                         mount.fsType = FsTypes.iso9660;
2772                                         removable_devices.Add (mount);
2773                                 } else if (split [2] == "usbfs") { //usb ? not tested
2774                                         mount.fsType = FsTypes.usbfs;
2775                                         removable_devices.Add (mount);
2776                                         
2777                                 } else if (split [0].StartsWith ("/")) { //block devices
2778                                         if (split [1].StartsWith ("/dev/"))  // root static, do not add
2779                                                 return;
2780                                         
2781                                         if (split [2] == "ext2")
2782                                                 mount.fsType = FsTypes.ext2;
2783                                         else if (split [2] == "ext3")
2784                                                 mount.fsType = FsTypes.ext3;
2785                                         else if (split [2] == "reiserfs")
2786                                                 mount.fsType = FsTypes.reiserfs;
2787                                         else if (split [2] == "xfs")
2788                                                 mount.fsType = FsTypes.xfs;
2789                                         else if (split [2] == "vfat")
2790                                                 mount.fsType = FsTypes.vfat;
2791                                         else if (split [2] == "ntfs")
2792                                                 mount.fsType = FsTypes.ntfs;
2793                                         else if (split [2] == "msdos")
2794                                                 mount.fsType = FsTypes.msdos;
2795                                         else if (split [2] == "umsdos")
2796                                                 mount.fsType = FsTypes.umsdos;
2797                                         else if (split [2] == "hpfs")
2798                                                 mount.fsType = FsTypes.hpfs;
2799                                         else if (split [2] == "minix")
2800                                                 mount.fsType = FsTypes.minix;
2801                                         else if (split [2] == "jfs")
2802                                                 mount.fsType = FsTypes.jfs;
2803                                         
2804                                         block_devices.Add (mount);
2805                                 }
2806                         }
2807                 }
2808                 
2809                 public class MountComparer : IComparer
2810                 {
2811                         public int Compare(object mount1, object mount2)
2812                         {
2813                                 return String.Compare(((Mount)mount1).device_short, ((Mount)mount2).device_short);
2814                         }
2815                 }
2816         }
2817 }
2818
2819