2006-07-14 Alexander Olk <alex.olk@googlemail.com>
[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 using System.Threading;
38
39 namespace System.Windows.Forms {
40         #region FileDialog
41         [DefaultProperty ("FileName")]
42         [DefaultEvent ("FileOk")]
43         public abstract class FileDialog : CommonDialog
44         {
45                 protected static readonly object EventFileOk = new object ();
46                 
47                 internal enum FileDialogType
48                 {
49                         OpenFileDialog,
50                         SaveFileDialog
51                 }
52                 
53                 private bool addExtension = true;
54                 private bool checkFileExists = false;
55                 private bool checkPathExists = true;
56                 private string defaultExt = "";
57                 private bool dereferenceLinks = true;
58                 private string fileName = "";
59                 private string[] fileNames;
60                 private string filter;
61                 private int filterIndex = 1;
62                 private string initialDirectory = "";
63                 private bool restoreDirectory = false;
64                 private bool showHelp = false;
65                 private string title = "";
66                 private bool validateNames = true;
67                 
68                 private Button cancelButton;
69                 private ToolBarButton upToolBarButton;
70                 private PopupButtonPanel popupButtonPanel;
71                 private Button openSaveButton;
72                 private Button helpButton;
73                 private Label fileTypeLabel;
74                 private ToolBarButton menueToolBarButton;
75                 private ContextMenu menueToolBarButtonContextMenu;
76                 private ToolBar smallButtonToolBar;
77                 private DirComboBox dirComboBox;
78                 private ComboBox fileNameComboBox;
79                 private Label fileNameLabel;
80                 private MWFFileView mwfFileView;
81                 private Label searchSaveLabel;
82                 private ToolBarButton newdirToolBarButton;
83                 private ToolBarButton backToolBarButton;
84                 private ComboBox fileTypeComboBox;
85                 private ImageList imageListTopToolbar;
86                 private CheckBox readonlyCheckBox;
87                 
88                 private bool multiSelect = false;
89                 
90                 private string restoreDirectoryString = "";
91                 
92                 internal FileDialogType fileDialogType;
93                 
94                 private bool do_not_call_OnSelectedIndexChangedFileTypeComboBox = false;
95                 
96                 private bool showReadOnly = false;
97                 private bool readOnlyChecked = false;
98                 internal bool createPrompt = false;
99                 internal bool overwritePrompt = true;
100                 
101                 internal FileFilter fileFilter;
102                 
103                 private string lastFolder = "";
104                 
105                 private MWFVFS vfs;
106                 
107                 private readonly string filedialog_string = "FileDialog";
108                 private readonly string lastfolder_string = "LastFolder";
109                 private readonly string width_string = "Width";
110                 private readonly string height_string = "Height";
111                 private readonly string filenames_string = "FileNames";
112                 private readonly string x_string = "X";
113                 private readonly string y_string = "Y";
114                 
115                 internal FileDialog ()
116                 {
117                         vfs = new MWFVFS ();
118                         
119                         Size formConfigSize = Size.Empty;
120                         Point formConfigLocation = Point.Empty;
121                         string[] configFileNames = null;
122                         
123                         object formWidth = MWFConfig.GetValue (filedialog_string, width_string);
124                         
125                         object formHeight = MWFConfig.GetValue (filedialog_string, height_string);
126                         
127                         if (formHeight != null && formWidth != null)
128                                 formConfigSize = new Size ((int)formWidth, (int)formHeight);
129                         
130                         object formLocationX = MWFConfig.GetValue (filedialog_string, x_string);
131                         object formLocationY = MWFConfig.GetValue (filedialog_string, y_string);
132                         
133                         if (formLocationX != null && formLocationY != null)
134                                 formConfigLocation = new Point ((int)formLocationX, (int)formLocationY);
135                         
136                         configFileNames = (string[])MWFConfig.GetValue (filedialog_string, filenames_string);
137                         
138                         fileTypeComboBox = new ComboBox ();
139                         backToolBarButton = new ToolBarButton ();
140                         newdirToolBarButton = new ToolBarButton ();
141                         searchSaveLabel = new Label ();
142                         mwfFileView = new MWFFileView (vfs);
143                         fileNameLabel = new Label ();
144                         fileNameComboBox = new ComboBox ();
145                         dirComboBox = new DirComboBox (vfs);
146                         smallButtonToolBar = new ToolBar ();
147                         menueToolBarButton = new ToolBarButton ();
148                         fileTypeLabel = new Label ();
149                         openSaveButton = new Button ();
150                         form.AcceptButton = openSaveButton;
151                         helpButton = new Button ();
152                         popupButtonPanel = new PopupButtonPanel ();
153                         upToolBarButton = new ToolBarButton ();
154                         cancelButton = new Button ();
155                         form.CancelButton = cancelButton;
156                         imageListTopToolbar = new ImageList ();
157                         menueToolBarButtonContextMenu = new ContextMenu ();
158                         readonlyCheckBox = new CheckBox ();
159                         
160                         form.SuspendLayout ();
161                         
162                         //imageListTopToolbar
163                         imageListTopToolbar.ColorDepth = ColorDepth.Depth32Bit;
164                         imageListTopToolbar.ImageSize = new Size (16, 16); // 16, 16
165                         imageListTopToolbar.Images.Add (ResourceImageLoader.Get ("go-previous.png"));
166                         imageListTopToolbar.Images.Add (ResourceImageLoader.Get ("go-top.png"));
167                         imageListTopToolbar.Images.Add (ResourceImageLoader.Get ("folder-new.png"));
168                         imageListTopToolbar.Images.Add (ResourceImageLoader.Get ("preferences-system-windows.png"));
169                         imageListTopToolbar.TransparentColor = Color.Transparent;
170                         
171                         // searchLabel
172                         searchSaveLabel.FlatStyle = FlatStyle.System;
173                         searchSaveLabel.Location = new Point (7, 8);
174                         searchSaveLabel.Size = new Size (72, 21);
175                         searchSaveLabel.TextAlign = ContentAlignment.MiddleRight;
176                         
177                         // dirComboBox
178                         dirComboBox.Anchor = ((AnchorStyles)(((AnchorStyles.Top | AnchorStyles.Left) | AnchorStyles.Right)));
179                         dirComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
180                         dirComboBox.Location = new Point (99, 8);
181                         dirComboBox.Size = new Size (260, 21);
182                         dirComboBox.TabIndex = 7;
183                         
184                         // smallButtonToolBar
185                         smallButtonToolBar.Anchor = ((AnchorStyles)((AnchorStyles.Top | AnchorStyles.Right)));
186                         smallButtonToolBar.Appearance = ToolBarAppearance.Flat;
187                         smallButtonToolBar.AutoSize = false;
188                         smallButtonToolBar.Buttons.AddRange (new ToolBarButton [] {
189                                                                      backToolBarButton,
190                                                                      upToolBarButton,
191                                                                      newdirToolBarButton,
192                                                                      menueToolBarButton});
193                         smallButtonToolBar.ButtonSize = new Size (24, 24); // 21, 16
194                         smallButtonToolBar.Divider = false;
195                         smallButtonToolBar.Dock = DockStyle.None;
196                         smallButtonToolBar.DropDownArrows = true;
197                         smallButtonToolBar.ImageList = imageListTopToolbar;
198                         smallButtonToolBar.Location = new Point (372, 6);
199                         smallButtonToolBar.ShowToolTips = true;
200                         smallButtonToolBar.Size = new Size (140, 28);
201                         smallButtonToolBar.TabIndex = 8;
202                         smallButtonToolBar.TextAlign = ToolBarTextAlign.Right;
203                         
204                         // buttonPanel
205                         popupButtonPanel.Dock = DockStyle.None;
206                         popupButtonPanel.Location = new Point (7, 37);
207                         popupButtonPanel.TabIndex = 9;
208                         
209                         // mwfFileView
210                         mwfFileView.Anchor = ((AnchorStyles)((((AnchorStyles.Top | AnchorStyles.Bottom) | AnchorStyles.Left) | AnchorStyles.Right)));
211                         mwfFileView.Location = new Point (99, 37);
212                         mwfFileView.Size = new Size (449, 282);
213                         mwfFileView.Columns.Add (" Name", 170, HorizontalAlignment.Left);
214                         mwfFileView.Columns.Add ("Size ", 80, HorizontalAlignment.Right);
215                         mwfFileView.Columns.Add (" Type", 100, HorizontalAlignment.Left);
216                         mwfFileView.Columns.Add (" Last Access", 150, HorizontalAlignment.Left);
217                         mwfFileView.AllowColumnReorder = true;
218                         mwfFileView.MultiSelect = false;
219                         mwfFileView.TabIndex = 10;
220                         mwfFileView.RegisterSender (dirComboBox);
221                         mwfFileView.RegisterSender (popupButtonPanel);
222                         
223                         // fileNameLabel
224                         fileNameLabel.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Left)));
225                         fileNameLabel.FlatStyle = FlatStyle.System;
226                         fileNameLabel.Location = new Point (102, 330);
227                         fileNameLabel.Size = new Size (70, 21);
228                         fileNameLabel.Text = "Filename:";
229                         fileNameLabel.TextAlign = ContentAlignment.MiddleLeft;
230                         
231                         // fileNameComboBox
232                         fileNameComboBox.Anchor = ((AnchorStyles)(((AnchorStyles.Bottom | AnchorStyles.Left) | AnchorStyles.Right)));
233                         fileNameComboBox.Location = new Point (195, 330);
234                         fileNameComboBox.Size = new Size (245, 21);
235                         fileNameComboBox.TabIndex = 1;
236                         fileNameComboBox.MaxDropDownItems = 10;
237                         fileNameComboBox.Items.Add (" ");
238                         
239                         if (configFileNames != null) {
240                                 fileNameComboBox.Items.Clear ();
241                                 
242                                 foreach (string configFileName in configFileNames) {
243                                         if (configFileName != null)
244                                                 if (configFileName.Trim ().Length > 0)
245                                                         fileNameComboBox.Items.Add (configFileName);
246                                 }
247                         }
248                         
249                         
250                         // fileTypeLabel
251                         fileTypeLabel.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Left)));
252                         fileTypeLabel.FlatStyle = FlatStyle.System;
253                         fileTypeLabel.Location = new Point (102, 356);
254                         fileTypeLabel.Size = new Size (70, 21);
255                         fileTypeLabel.Text = "Filetype:";
256                         fileTypeLabel.TextAlign = ContentAlignment.MiddleLeft;
257                         
258                         // fileTypeComboBox
259                         fileTypeComboBox.Anchor = ((AnchorStyles)(((AnchorStyles.Bottom | AnchorStyles.Left) | AnchorStyles.Right)));
260                         fileTypeComboBox.DropDownStyle = ComboBoxStyle.DropDownList;
261                         fileTypeComboBox.Location = new Point (195, 356);
262                         fileTypeComboBox.Size = new Size (245, 21);
263                         fileTypeComboBox.TabIndex = 2;
264                         
265                         // backToolBarButton
266                         backToolBarButton.ImageIndex = 0;
267                         backToolBarButton.Enabled = false;
268                         backToolBarButton.Style = ToolBarButtonStyle.PushButton;
269                         mwfFileView.AddControlToEnableDisableByDirStack (backToolBarButton);
270                         
271                         // upToolBarButton
272                         upToolBarButton.ImageIndex = 1;
273                         upToolBarButton.Style = ToolBarButtonStyle.PushButton;
274                         mwfFileView.SetFolderUpToolBarButton (upToolBarButton);
275                         
276                         // newdirToolBarButton
277                         newdirToolBarButton.ImageIndex = 2;
278                         newdirToolBarButton.Style = ToolBarButtonStyle.PushButton;
279                         
280                         // menueToolBarButton
281                         menueToolBarButton.ImageIndex = 3;
282                         menueToolBarButton.DropDownMenu = menueToolBarButtonContextMenu;
283                         menueToolBarButton.Style = ToolBarButtonStyle.DropDownButton;
284                         
285                         // menueToolBarButtonContextMenu
286                         menueToolBarButtonContextMenu.MenuItems.AddRange (mwfFileView.ViewMenuItems);
287                         
288                         // openSaveButton
289                         openSaveButton.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Right)));
290                         openSaveButton.FlatStyle = FlatStyle.System;
291                         openSaveButton.Location = new Point (475, 330);
292                         openSaveButton.Size = new Size (72, 21);
293                         openSaveButton.TabIndex = 4;
294                         openSaveButton.FlatStyle = FlatStyle.System;
295                         
296                         // cancelButton
297                         cancelButton.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Right)));
298                         cancelButton.FlatStyle = FlatStyle.System;
299                         cancelButton.Location = new Point (475, 356);
300                         cancelButton.Size = new Size (72, 21);
301                         cancelButton.TabIndex = 5;
302                         cancelButton.Text = "Cancel";
303                         cancelButton.FlatStyle = FlatStyle.System;
304                         
305                         // helpButton
306                         helpButton.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Right)));
307                         helpButton.FlatStyle = FlatStyle.System;
308                         helpButton.Location = new Point (475, 350);
309                         helpButton.Size = new Size (72, 21);
310                         helpButton.TabIndex = 6;
311                         helpButton.Text = "Help";
312                         helpButton.FlatStyle = FlatStyle.System;
313                         
314                         // checkBox
315                         readonlyCheckBox.Anchor = ((AnchorStyles)(((AnchorStyles.Bottom | AnchorStyles.Left) | AnchorStyles.Right)));
316                         readonlyCheckBox.Text = "Open Readonly";
317                         readonlyCheckBox.Location = new Point (195, 350);
318                         readonlyCheckBox.Size = new Size (245, 21);
319                         readonlyCheckBox.TabIndex = 3;
320                         readonlyCheckBox.FlatStyle = FlatStyle.System;
321                         
322                         form.SizeGripStyle = SizeGripStyle.Show;
323                         
324                         form.MaximizeBox = true;
325                         form.FormBorderStyle = FormBorderStyle.Sizable;
326                         form.MinimumSize = new Size (554, 405);
327                         
328                         form.Size =  new Size (554, 405); // 384
329                         
330                         form.Controls.Add (smallButtonToolBar);
331                         form.Controls.Add (cancelButton);
332                         form.Controls.Add (openSaveButton);
333                         form.Controls.Add (mwfFileView);
334                         form.Controls.Add (fileTypeLabel);
335                         form.Controls.Add (fileNameLabel);
336                         form.Controls.Add (fileTypeComboBox);
337                         form.Controls.Add (fileNameComboBox);
338                         form.Controls.Add (dirComboBox);
339                         form.Controls.Add (searchSaveLabel);
340                         form.Controls.Add (popupButtonPanel);
341                         
342                         form.ResumeLayout (false);
343                         
344                         if (formConfigSize != Size.Empty) {
345                                 form.Size = formConfigSize;
346                         }
347                         
348                         if (formConfigLocation != Point.Empty) {
349                                 form.Location = formConfigLocation;
350                         }
351                         
352                         openSaveButton.Click += new EventHandler (OnClickOpenSaveButton);
353                         cancelButton.Click += new EventHandler (OnClickCancelButton);
354                         helpButton.Click += new EventHandler (OnClickHelpButton);
355                         
356                         smallButtonToolBar.ButtonClick += new ToolBarButtonClickEventHandler (OnClickSmallButtonToolBar);
357                         
358                         fileTypeComboBox.SelectedIndexChanged += new EventHandler (OnSelectedIndexChangedFileTypeComboBox);
359                         
360                         mwfFileView.SelectedFileChanged += new EventHandler (OnSelectedFileChangedFileView);
361                         mwfFileView.ForceDialogEnd += new EventHandler (OnForceDialogEndFileView);
362                         mwfFileView.SelectedFilesChanged += new EventHandler (OnSelectedFilesChangedFileView);
363                         
364                         dirComboBox.DirectoryChanged += new EventHandler (OnDirectoryChangedDirComboBox);
365                         popupButtonPanel.DirectoryChanged += new EventHandler (OnDirectoryChangedPopupButtonPanel);
366                         
367                         readonlyCheckBox.CheckedChanged += new EventHandler (OnCheckCheckChanged);
368                 }
369                 
370                 [DefaultValue(true)]
371                 public bool AddExtension {
372                         get {
373                                 return addExtension;
374                         }
375                         
376                         set {
377                                 addExtension = value;
378                         }
379                 }
380                 
381                 [DefaultValue(false)]
382                 public virtual bool CheckFileExists {
383                         get {
384                                 return checkFileExists;
385                         }
386                         
387                         set {
388                                 checkFileExists = value;
389                         }
390                 }
391                 
392                 [DefaultValue(true)]
393                 public bool CheckPathExists {
394                         get {
395                                 return checkPathExists;
396                         }
397                         
398                         set {
399                                 checkPathExists = value;
400                         }
401                 }
402                 
403                 [DefaultValue("")]
404                 public string DefaultExt {
405                         get {
406                                 return defaultExt;
407                         }
408                         
409                         set {
410                                 defaultExt = value;
411                                 
412                                 // if there is a dot remove it and everything before it
413                                 if (defaultExt.LastIndexOf ('.') != - 1) {
414                                         string[] split = defaultExt.Split (new char [] { '.' });
415                                         defaultExt = split [split.Length - 1];
416                                 }
417                         }
418                 }
419                 
420                 // in MS.NET it doesn't make a difference if
421                 // DerefenceLinks is true or false
422                 // if the selected file is a link FileDialog
423                 // always returns the link
424                 [DefaultValue(true)]
425                 public bool DereferenceLinks {
426                         get {
427                                 return dereferenceLinks;
428                         }
429                         
430                         set {
431                                 dereferenceLinks = value;
432                         }
433                 }
434                 
435                 [DefaultValue("")]
436                 public string FileName {
437                         get {
438                                 return fileName;
439                         }
440                         
441                         set {
442                                 if (value != null) {
443                                         if (SetFileName (value))
444                                                 fileName = value;
445                                 }
446                         }
447                 }
448                 
449                 [Browsable(false)]
450                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
451                 public string[] FileNames {
452                         get {
453                                 if (fileNames == null || fileNames.Length == 0) {
454                                         string[] null_nada_nothing_filenames = new string [0];
455                                         return null_nada_nothing_filenames;
456                                 }
457                                 
458                                 string[] new_filenames = new string [fileNames.Length];
459                                 fileNames.CopyTo (new_filenames, 0);
460                                 return new_filenames;
461                         }
462                 }
463                 
464                 [DefaultValue("")]
465                 [Localizable(true)]
466                 public string Filter {
467                         get {
468                                 return filter;
469                         }
470                         
471                         set {
472                                 if (value == null)
473                                         throw new NullReferenceException ("Filter");
474                                 
475                                 filter = value;
476                                 
477                                 fileFilter = new FileFilter (filter);
478                                 
479                                 UpdateFilters ();
480                         }
481                 }
482                 
483                 [DefaultValue(1)]
484                 public int FilterIndex {
485                         get {
486                                 return filterIndex;
487                         }
488                         
489                         set {
490                                 if (fileFilter != null && fileFilter.FilterArrayList.Count > value)
491                                         return;  // FIXME: throw an exception ?
492                                 
493                                 filterIndex = value;
494                                 
495                                 SelectFilter ();
496                         }
497                 }
498                 
499                 [DefaultValue("")]
500                 public string InitialDirectory {
501                         get {
502                                 return initialDirectory;
503                         }
504                         
505                         set {
506                                 if (Directory.Exists (value)) {
507                                         initialDirectory = value;
508                                         
509                                         mwfFileView.ChangeDirectory (null, initialDirectory);
510                                 }
511                         }
512                 }
513                 
514                 [DefaultValue(false)]
515                 public bool RestoreDirectory {
516                         get {
517                                 return restoreDirectory;
518                         }
519                         
520                         set {
521                                 restoreDirectory = value;
522                         }
523                 }
524                 
525                 [DefaultValue(false)]
526                 public bool ShowHelp {
527                         get {
528                                 return showHelp;
529                         }
530                         
531                         set {
532                                 showHelp = value;
533                                 ResizeAndRelocateForHelpOrReadOnly ();
534                         }
535                 }
536                 
537                 [DefaultValue("")]
538                 [Localizable(true)]
539                 public string Title {
540                         get {
541                                 return title;
542                         }
543                         
544                         set {
545                                 title = value;
546                                 
547                                 form.Text = title;
548                         }
549                 }
550                 
551                 // this one is a hard one ;)
552                 // Win32 filename:
553                 // - up to MAX_PATH characters (windef.h) = 260
554                 // - no trailing dots or spaces
555                 // - case preserving
556                 // - etc...
557                 // NTFS/Posix filename:
558                 // - up to 32,768 Unicode characters
559                 // - trailing periods or spaces
560                 // - case sensitive
561                 // - etc...
562                 [DefaultValue(true)]
563                 public bool ValidateNames {
564                         get {
565                                 return validateNames;
566                         }
567                         
568                         set {
569                                 validateNames = value;
570                         }
571                 }
572                 
573                 public override void Reset ()
574                 {
575                         addExtension = true;
576                         checkFileExists = false;
577                         checkPathExists = true;
578                         defaultExt = "";
579                         dereferenceLinks = true;
580                         fileName = "";
581                         fileNames = null;
582                         Filter = "";
583                         filterIndex = 1;
584                         initialDirectory = "";
585                         restoreDirectory = false;
586                         ShowHelp = false;
587                         Title = "";
588                         validateNames = true;
589                         
590                         UpdateFilters ();
591                 }
592                 
593                 public override string ToString ()
594                 {
595                         return base.ToString ();
596                 }
597                 
598                 public event CancelEventHandler FileOk {
599                         add { Events.AddHandler (EventFileOk, value); }
600                         remove { Events.RemoveHandler (EventFileOk, value); }
601                 }
602                 
603                 protected virtual IntPtr Instance {
604                         get {
605                                 if (form == null)
606                                         return IntPtr.Zero;
607                                 return form.Handle;
608                         }
609                 }
610                 
611                 // This is just for internal use with MSs version, so it doesn't need to be implemented
612                 // as it can't really be accessed anyways
613                 protected int Options {
614                         get { return -1; }
615                 }
616                 
617                 [MonoTODO]
618                 protected  override IntPtr HookProc (IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam)
619                 {
620                         throw new NotImplementedException ();
621                 }
622                 
623                 protected void OnFileOk (CancelEventArgs e)
624                 {
625                         WriteConfigValues (e);
626                         
627                         CancelEventHandler fo = (CancelEventHandler) Events [EventFileOk];
628                         if (fo != null)
629                                 fo (this, e);
630                 }
631                 
632                 protected  override bool RunDialog (IntPtr hWndOwner)
633                 {
634                         ReadConfigValues ();
635                         
636                         form.Refresh ();
637                         
638                         mwfFileView.ChangeDirectory (null, lastFolder);
639                         
640                         fileNameComboBox.Select ();
641                         
642                         return true;
643                 }
644                 
645                 internal virtual bool ShowReadOnly {
646                         set {
647                                 showReadOnly = value;
648                                 ResizeAndRelocateForHelpOrReadOnly ();
649                         }
650                         
651                         get {
652                                 return showReadOnly;
653                         }
654                 }
655                 
656                 internal virtual bool ReadOnlyChecked {
657                         set {
658                                 readOnlyChecked = value;
659                                 readonlyCheckBox.Checked = value;
660                         }
661                         
662                         get {
663                                 return readOnlyChecked;
664                         }
665                 }
666                 
667                 internal bool BMultiSelect {
668                         set {
669                                 multiSelect = value;
670                                 mwfFileView.MultiSelect = value;
671                         }
672                         
673                         get {
674                                 return multiSelect;
675                         }
676                 }
677                 
678                 internal string OpenSaveButtonText {
679                         set {
680                                 openSaveButton.Text = value;
681                         }
682                 }
683                 
684                 internal string SearchSaveLabel {
685                         set {
686                                 searchSaveLabel.Text = value;
687                         }
688                 }
689                 
690                 private void SelectFilter ()
691                 {
692                         if (FilterIndex > mwfFileView.FilterArrayList.Count)
693                                 return;
694                         
695                         do_not_call_OnSelectedIndexChangedFileTypeComboBox = true;
696                         fileTypeComboBox.BeginUpdate ();
697                         fileTypeComboBox.SelectedIndex = FilterIndex - 1;
698                         fileTypeComboBox.EndUpdate ();
699                         
700                         mwfFileView.FilterIndex = FilterIndex;
701                 }
702                 
703                 private bool SetFileName (string fname)
704                 {
705                         bool rooted = Path.IsPathRooted (fname);
706                         
707                         if (!rooted) {
708                                 string dir = mwfFileView.CurrentRealFolder ;
709                                 if (dir == null) {
710                                         dir = Environment.CurrentDirectory;
711                                 }
712                                 if (File.Exists (Path.Combine (dir, fname))) {
713                                         fileNameComboBox.Text = fname;
714                                         mwfFileView.SetSelectedIndexTo (fname);
715                                         
716                                         return true;
717                                 }
718                         } else {
719                                 if (File.Exists (fname)) {
720                                         fileNameComboBox.Text = Path.GetFileName (fname);
721                                         mwfFileView.ChangeDirectory (null, Path.GetDirectoryName (fname));
722                                         mwfFileView.SetSelectedIndexTo (fname);
723                                         
724                                         return true;
725                                 }
726                         }
727                         
728                         return false;
729                 }
730                 
731                 void OnClickOpenSaveButton (object sender, EventArgs e)
732                 {
733                         if (fileDialogType == FileDialogType.OpenFileDialog) {
734                                 ListView.SelectedListViewItemCollection sl = mwfFileView.SelectedItems;
735                                 if (sl.Count > 0 && sl [0] != null) {
736                                         if (sl.Count == 1) {
737                                                 FileViewListViewItem item = sl [0] as FileViewListViewItem;
738                                                 FSEntry fsEntry = item.FSEntry;
739                                                 
740                                                 if (fsEntry.Attributes == FileAttributes.Directory) {
741                                                         mwfFileView.ChangeDirectory (null, fsEntry.FullName);
742                                                         return;
743                                                 }
744                                         } else {
745                                                 foreach (FileViewListViewItem item in sl) {
746                                                         FSEntry fsEntry = item.FSEntry;
747                                                         if (fsEntry.Attributes == FileAttributes.Directory) {
748                                                                 mwfFileView.ChangeDirectory (null, fsEntry.FullName);
749                                                                 return;
750                                                         }
751                                                 }
752                                         }
753                                 }
754                         }
755                         
756                         string internalfullfilename = "";
757                         
758                         if (!multiSelect) {
759                                 string fileFromComboBox = fileNameComboBox.Text.Trim ();
760                                 
761                                 if (fileFromComboBox.Length > 0) {
762                                         if (!Path.IsPathRooted (fileFromComboBox)) {
763                                                 // on unix currentRealFolder for "Recently used files" is null,
764                                                 // because recently used files don't get saved as links in a directory
765                                                 // recently used files get saved in a xml file
766                                                 if (mwfFileView.CurrentRealFolder != null)
767                                                         fileFromComboBox = Path.Combine (mwfFileView.CurrentRealFolder, fileFromComboBox);
768                                                 else
769                                                 if (mwfFileView.CurrentFSEntry != null) {
770                                                         fileFromComboBox = mwfFileView.CurrentFSEntry.FullName;
771                                                 }
772                                         }
773                                         
774                                         FileInfo fileInfo = new FileInfo (fileFromComboBox);
775                                         
776                                         if (fileInfo.Exists || fileDialogType == FileDialogType.SaveFileDialog) {
777                                                 internalfullfilename = fileFromComboBox;
778                                         } else {
779                                                 DirectoryInfo dirInfo = new DirectoryInfo (fileFromComboBox);
780                                                 if (dirInfo.Exists) {
781                                                         mwfFileView.ChangeDirectory (null, dirInfo.FullName);
782                                                         
783                                                         fileNameComboBox.Text = " ";
784                                                         return;
785                                                 } else {
786                                                         internalfullfilename = fileFromComboBox;
787                                                 }                                                       
788                                         }
789                                 } else
790                                         return;
791                                 
792                                 if (fileDialogType == FileDialogType.OpenFileDialog) {
793                                         if (checkFileExists) {
794                                                 if (!File.Exists (internalfullfilename)) {
795                                                         string message = "\"" + internalfullfilename + "\" doesn't exist. Please verify that you have entered the correct file name.";
796                                                         MessageBox.Show (message, openSaveButton.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
797                                                         
798                                                         return;
799                                                 }
800                                         }
801                                 } else {
802                                         if (overwritePrompt) {
803                                                 if (File.Exists (internalfullfilename)) {
804                                                         string message = "\"" + internalfullfilename + "\" exists. Overwrite ?";
805                                                         DialogResult dr = MessageBox.Show (message, openSaveButton.Text, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
806                                                         
807                                                         if (dr == DialogResult.Cancel)
808                                                                 return;
809                                                 }
810                                         }
811                                         
812                                         if (createPrompt) {
813                                                 if (!File.Exists (internalfullfilename)) {
814                                                         string message = "\"" + internalfullfilename + "\" doesn't exist. Create ?";
815                                                         DialogResult dr = MessageBox.Show (message, openSaveButton.Text, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
816                                                         
817                                                         if (dr == DialogResult.Cancel)
818                                                                 return;
819                                                 }
820                                         }
821                                 }
822                                 
823                                 if (fileDialogType == FileDialogType.SaveFileDialog) {
824                                         if (addExtension) {
825                                                 string extension_to_use = "";
826                                                 string filter_exentsion = "";
827                                                 
828                                                 if (fileFilter != null) {
829                                                         FilterStruct filterstruct = (FilterStruct)fileFilter.FilterArrayList [filterIndex - 1];
830                                                         
831                                                         for (int i = 0; i < filterstruct.filters.Count; i++) {
832                                                                 string extension = filterstruct.filters [i];
833                                                                 
834                                                                 if (extension.StartsWith ("*"))
835                                                                         extension = extension.Remove (0, 1);
836                                                                 
837                                                                 if (extension.IndexOf ('*') != -1)
838                                                                         continue;
839                                                                 
840                                                                 filter_exentsion = extension;
841                                                                 break;
842                                                         }
843                                                 }
844                                                 
845                                                 if (filter_exentsion != "")
846                                                         extension_to_use = filter_exentsion;
847                                                 else
848                                                 if (defaultExt != "")
849                                                         extension_to_use = "." + defaultExt;
850                                                 
851                                                 internalfullfilename += extension_to_use;
852                                         }
853                                 }
854                                 
855                                 fileNames = new string [1];
856                                 
857                                 fileNames [0] = internalfullfilename;
858                                 
859                                 fileName = internalfullfilename;
860                                 
861                                 mwfFileView.WriteRecentlyUsed (internalfullfilename);
862                         } else // multiSelect = true
863                         if (fileDialogType != FileDialogType.SaveFileDialog) {
864                                 if (mwfFileView.SelectedItems.Count > 0) {
865                                         // first remove all selected directories
866                                         ArrayList al = new ArrayList ();
867                                         
868                                         foreach (FileViewListViewItem lvi in mwfFileView.SelectedItems) {
869                                                 FSEntry fsEntry = lvi.FSEntry;
870                                                 
871                                                 if (fsEntry.Attributes != FileAttributes.Directory) {
872                                                         al.Add (fsEntry);
873                                                 }
874                                         }
875                                         
876                                         fileName = ((FSEntry)al [0]).FullName;
877                                         
878                                         fileNames = new string [al.Count];
879                                         
880                                         for (int i = 0; i < al.Count; i++) {
881                                                 fileNames [i] = ((FSEntry)al [i]).FullName;
882                                         }
883                                 }
884                         }
885                         
886                         if (checkPathExists && mwfFileView.CurrentRealFolder != null) {
887                                 if (!Directory.Exists (mwfFileView.CurrentRealFolder)) {
888                                         string message = "\"" + mwfFileView.CurrentRealFolder + "\" doesn't exist. Please verify that you have entered the correct directory name.";
889                                         MessageBox.Show (message, openSaveButton.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
890                                         
891                                         if (initialDirectory == String.Empty)
892                                                 mwfFileView.ChangeDirectory (null, lastFolder);
893                                         else
894                                                 mwfFileView.ChangeDirectory (null, initialDirectory);
895                                         
896                                         return;
897                                 }
898                         }
899                         
900                         if (restoreDirectory) {
901                                 lastFolder  = restoreDirectoryString;
902                         } else {
903                                 lastFolder = mwfFileView.CurrentFolder;
904                         }
905                         
906                         if (fileNameComboBox.Items.Count > 0) {
907                                 if (fileNameComboBox.Items.IndexOf (fileName) == -1) {
908                                         fileNameComboBox.Items.Insert (0, fileName);
909                                 }
910                         } else
911                                 fileNameComboBox.Items.Add (fileName);
912                         
913                         if (fileNameComboBox.Items.Count == 11)
914                                 fileNameComboBox.Items.RemoveAt (10);
915                         
916                         CancelEventArgs cancelEventArgs = new CancelEventArgs ();
917                         
918                         cancelEventArgs.Cancel = false;
919                         
920                         OnFileOk (cancelEventArgs);
921                         
922                         form.DialogResult = DialogResult.OK;
923                 }
924                 
925                 void OnClickCancelButton (object sender, EventArgs e)
926                 {
927                         if (restoreDirectory)
928                                 mwfFileView.CurrentFolder = restoreDirectoryString;
929                         
930                         CancelEventArgs cancelEventArgs = new CancelEventArgs ();
931                         
932                         cancelEventArgs.Cancel = true;
933                         
934                         OnFileOk (cancelEventArgs);
935                         
936                         form.DialogResult = DialogResult.Cancel;
937                 }
938                 
939                 void OnClickHelpButton (object sender, EventArgs e)
940                 {
941                         OnHelpRequest (e);
942                 }
943                 
944                 void OnClickSmallButtonToolBar (object sender, ToolBarButtonClickEventArgs e)
945                 {
946                         if (e.Button == upToolBarButton) {
947                                 mwfFileView.OneDirUp ();
948                         } else
949                         if (e.Button == backToolBarButton) {
950                                 mwfFileView.PopDir ();
951                         } else
952                         if (e.Button == newdirToolBarButton) {
953                                 mwfFileView.CreateNewFolder ();
954                         }
955                 }
956                 
957                 void OnSelectedIndexChangedFileTypeComboBox (object sender, EventArgs e)
958                 {
959                         if (do_not_call_OnSelectedIndexChangedFileTypeComboBox) {
960                                 do_not_call_OnSelectedIndexChangedFileTypeComboBox = false;
961                                 return;
962                         }
963                         
964                         filterIndex = fileTypeComboBox.SelectedIndex + 1;
965                         
966                         mwfFileView.FilterIndex = filterIndex;
967                 }
968                 
969                 void OnSelectedFileChangedFileView (object sender, EventArgs e)
970                 {
971                         fileNameComboBox.Text = mwfFileView.CurrentFSEntry.Name;
972                 }
973                 
974                 void OnSelectedFilesChangedFileView (object sender, EventArgs e)
975                 {
976                         fileNameComboBox.Text = mwfFileView.SelectedFilesString;
977                 }
978                 
979                 void OnForceDialogEndFileView (object sender, EventArgs e)
980                 {
981                         OnClickOpenSaveButton (this, EventArgs.Empty);
982                 }
983                 
984                 void OnDirectoryChangedDirComboBox (object sender, EventArgs e)
985                 {
986                         mwfFileView.ChangeDirectory (sender, dirComboBox.CurrentFolder);
987                 }
988                 
989                 void OnDirectoryChangedPopupButtonPanel (object sender, EventArgs e)
990                 {
991                         mwfFileView.ChangeDirectory (sender, popupButtonPanel.CurrentFolder);
992                 }
993                 
994                 void OnCheckCheckChanged (object sender, EventArgs e)
995                 {
996                         ReadOnlyChecked = readonlyCheckBox.Checked;
997                 }
998                 
999                 private void UpdateFilters ()
1000                 {
1001                         ArrayList filters = fileFilter.FilterArrayList;
1002                         
1003                         fileTypeComboBox.BeginUpdate ();
1004                         
1005                         fileTypeComboBox.Items.Clear ();
1006                         
1007                         foreach (FilterStruct fs in filters) {
1008                                 fileTypeComboBox.Items.Add (fs.filterName);
1009                         }
1010                         
1011                         fileTypeComboBox.SelectedIndex = FilterIndex - 1;
1012                         
1013                         fileTypeComboBox.EndUpdate ();
1014                         
1015                         mwfFileView.FilterArrayList = filters;
1016                         
1017                         mwfFileView.FilterIndex = FilterIndex;
1018                 }
1019                 
1020                 private void ResizeAndRelocateForHelpOrReadOnly ()
1021                 {
1022                         form.SuspendLayout ();
1023                         if (ShowHelp || ShowReadOnly) {
1024                                 mwfFileView.Size = new Size (449, 250); 
1025                                 fileNameLabel.Location = new Point (102, 298);
1026                                 fileNameComboBox.Location = new Point (195, 298);
1027                                 fileTypeLabel.Location = new Point (102, 324);
1028                                 fileTypeComboBox.Location = new Point (195, 324);
1029                                 openSaveButton.Location = new Point (475, 298);
1030                                 cancelButton.Location = new Point (475, 324);
1031                         } else {
1032                                 mwfFileView.Size = new Size (449, 282);
1033                                 fileNameLabel.Location = new Point (102, 330);
1034                                 fileNameComboBox.Location = new Point (195, 330);
1035                                 fileTypeLabel.Location = new Point (102, 356);
1036                                 fileTypeComboBox.Location = new Point (195, 356);
1037                                 openSaveButton.Location = new Point (475, 330);
1038                                 cancelButton.Location = new Point (475, 356);
1039                         }
1040                         
1041                         if (ShowHelp)
1042                                 form.Controls.Add (helpButton);
1043                         else
1044                                 form.Controls.Remove (helpButton);
1045                         
1046                         if (ShowReadOnly)
1047                                 form.Controls.Add (readonlyCheckBox);
1048                         else
1049                                 form.Controls.Remove (readonlyCheckBox);
1050                         form.ResumeLayout ();
1051                 }
1052                 
1053                 private void WriteConfigValues (CancelEventArgs ce)
1054                 {
1055                         MWFConfig.SetValue (filedialog_string, width_string, form.Width);
1056                         MWFConfig.SetValue (filedialog_string, height_string, form.Height);
1057                         MWFConfig.SetValue (filedialog_string, x_string, form.Location.X);
1058                         MWFConfig.SetValue (filedialog_string, y_string, form.Location.Y);
1059                         
1060                         if (!ce.Cancel) {
1061                                 MWFConfig.SetValue (filedialog_string, lastfolder_string, lastFolder);
1062                                 
1063                                 string[] fileNameCBItems = new string [fileNameComboBox.Items.Count];
1064                                 
1065                                 fileNameComboBox.Items.CopyTo (fileNameCBItems, 0);
1066                                 
1067                                 MWFConfig.SetValue (filedialog_string, filenames_string, fileNameCBItems);
1068                         }
1069                 }
1070                 
1071                 private void ReadConfigValues ()
1072                 {
1073                         lastFolder = (string)MWFConfig.GetValue (filedialog_string, lastfolder_string);
1074                         
1075                         if (initialDirectory != "")
1076                                 lastFolder = initialDirectory;
1077                         else
1078                         if (lastFolder == null || lastFolder == "")
1079                                 lastFolder = Environment.CurrentDirectory;
1080                         
1081                         if (RestoreDirectory)
1082                                 restoreDirectoryString = lastFolder;
1083                 }
1084         }
1085         #endregion
1086         
1087         #region PopupButtonPanel
1088         internal class PopupButtonPanel : Control, IUpdateFolder
1089         {
1090                 #region PopupButton
1091                 internal class PopupButton : Control
1092                 {
1093                         internal enum PopupButtonState
1094                         { Normal, Down, Up}
1095                         
1096                         private Image image = null;
1097                         private PopupButtonState popupButtonState = PopupButtonState.Normal;
1098                         private StringFormat text_format = new StringFormat();
1099                         private Rectangle text_rect = Rectangle.Empty;
1100                         
1101                         public PopupButton ()
1102                         {
1103                                 text_format.Alignment = StringAlignment.Center;
1104                                 text_format.LineAlignment = StringAlignment.Near;
1105                                 
1106                                 SetStyle (ControlStyles.DoubleBuffer, true);
1107                                 SetStyle (ControlStyles.AllPaintingInWmPaint, true);
1108                                 SetStyle (ControlStyles.UserPaint, true);
1109                                 SetStyle (ControlStyles.Selectable, false);
1110                         }
1111                         
1112                         public Image Image {
1113                                 set {
1114                                         image = value;
1115                                         Refresh ();
1116                                 }
1117                                 
1118                                 get {
1119                                         return image;
1120                                 }
1121                         }
1122                         
1123                         public PopupButtonState ButtonState {
1124                                 set {
1125                                         popupButtonState = value;
1126                                         Refresh ();
1127                                 }
1128                                 
1129                                 get {
1130                                         return popupButtonState;
1131                                 }
1132                         }
1133                         
1134                         protected override void OnPaint (PaintEventArgs pe)
1135                         {
1136                                 Draw (pe);
1137                                 
1138                                 base.OnPaint (pe);
1139                         }
1140                         
1141                         private void Draw (PaintEventArgs pe)
1142                         {
1143                                 Graphics gr = pe.Graphics;
1144                                 
1145                                 gr.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (BackColor), ClientRectangle);
1146                                 
1147                                 // draw image
1148                                 if (image != null) {
1149                                         int i_x = (ClientSize.Width - image.Width) / 2;
1150                                         int i_y = 4;
1151                                         gr.DrawImage (image, i_x, i_y);
1152                                 }
1153                                 
1154                                 if (Text != String.Empty) {
1155                                         if (text_rect == Rectangle.Empty)
1156                                                 text_rect = new Rectangle (0, Height - 30, Width, Height - 30); 
1157                                         
1158                                         gr.DrawString (Text, Font, ThemeEngine.Current.ResPool.GetSolidBrush (ForeColor), text_rect, text_format);
1159                                 }
1160                                 
1161                                 switch (popupButtonState) {
1162                                         case PopupButtonState.Up:
1163                                                 gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.White), 0, 0, ClientSize.Width - 1, 0);
1164                                                 gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.White), 0, 0, 0, ClientSize.Height - 1);
1165                                                 gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.Black), ClientSize.Width - 1, 0, ClientSize.Width - 1, ClientSize.Height - 1);
1166                                                 gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.Black), 0, ClientSize.Height - 1, ClientSize.Width - 1, ClientSize.Height - 1);
1167                                                 break;
1168                                                 
1169                                         case PopupButtonState.Down:
1170                                                 gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.Black), 0, 0, ClientSize.Width - 1, 0);
1171                                                 gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.Black), 0, 0, 0, ClientSize.Height - 1);
1172                                                 gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.White), ClientSize.Width - 1, 0, ClientSize.Width - 1, ClientSize.Height - 1);
1173                                                 gr.DrawLine (ThemeEngine.Current.ResPool.GetPen (Color.White), 0, ClientSize.Height - 1, ClientSize.Width - 1, ClientSize.Height - 1);
1174                                                 break;
1175                                 }
1176                         }
1177                         
1178                         protected override void OnMouseEnter (EventArgs e)
1179                         {
1180                                 if (popupButtonState != PopupButtonState.Down)
1181                                         popupButtonState = PopupButtonState.Up;
1182                                 
1183                                 PopupButtonPanel panel = Parent as PopupButtonPanel;
1184                                 
1185                                 if (panel.focusButton != null && panel.focusButton.ButtonState == PopupButtonState.Up) {
1186                                         panel.focusButton.ButtonState = PopupButtonState.Normal;
1187                                         panel.focusButton = null;
1188                                 }
1189                                 Refresh ();
1190                                 base.OnMouseEnter (e);
1191                         }
1192                         
1193                         protected override void OnMouseLeave (EventArgs e)
1194                         {
1195                                 if (popupButtonState == PopupButtonState.Up)
1196                                         popupButtonState = PopupButtonState.Normal;
1197                                 Refresh ();
1198                                 base.OnMouseLeave (e);
1199                         }
1200                         
1201                         protected override void OnClick (EventArgs e)
1202                         {
1203                                 popupButtonState = PopupButtonState.Down;
1204                                 Refresh ();
1205                                 base.OnClick (e);
1206                         }
1207                 }
1208                 #endregion
1209                 
1210                 private EventHandler on_directory_changed;
1211                 
1212                 private PopupButton recentlyusedButton;
1213                 private PopupButton desktopButton;
1214                 private PopupButton personalButton;
1215                 private PopupButton mycomputerButton;
1216                 private PopupButton networkButton;
1217                 
1218                 private PopupButton lastPopupButton = null;
1219                 private PopupButton focusButton = null;
1220                 
1221                 private string currentPath;
1222                 
1223                 private int currentFocusIndex;
1224                 
1225                 public PopupButtonPanel ()
1226                 {
1227                         SuspendLayout ();
1228                         
1229                         //BackColor = Color.FromArgb (128, 128, 128);
1230                         Size = new Size (85, 336);
1231                         
1232                         recentlyusedButton = new PopupButton ();
1233                         desktopButton = new PopupButton ();
1234                         personalButton = new PopupButton ();
1235                         mycomputerButton = new PopupButton ();
1236                         networkButton = new PopupButton ();
1237                         
1238                         recentlyusedButton.Size = new Size (81, 64);
1239                         recentlyusedButton.Image = ThemeEngine.Current.Images (UIIcon.PlacesRecentDocuments, 32);
1240                         recentlyusedButton.BackColor = BackColor;
1241                         recentlyusedButton.ForeColor = Color.Black;
1242                         recentlyusedButton.Location = new Point (2, 2);
1243                         recentlyusedButton.Text = "Recently\nused";
1244                         recentlyusedButton.Click += new EventHandler (OnClickButton);
1245                         
1246                         desktopButton.Image = ThemeEngine.Current.Images (UIIcon.PlacesDesktop, 32);
1247                         desktopButton.BackColor = BackColor;
1248                         desktopButton.ForeColor = Color.Black;
1249                         desktopButton.Size = new Size (81, 64);
1250                         desktopButton.Location = new Point (2, 66);
1251                         desktopButton.Text = "Desktop";
1252                         desktopButton.Click += new EventHandler (OnClickButton);
1253                         
1254                         personalButton.Image = ThemeEngine.Current.Images (UIIcon.PlacesPersonal, 32);
1255                         personalButton.BackColor = BackColor;
1256                         personalButton.ForeColor = Color.Black;
1257                         personalButton.Size = new Size (81, 64);
1258                         personalButton.Location = new Point (2, 130);
1259                         personalButton.Text = "Personal";
1260                         personalButton.Click += new EventHandler (OnClickButton);
1261                         
1262                         mycomputerButton.Image = ThemeEngine.Current.Images (UIIcon.PlacesMyComputer, 32);
1263                         mycomputerButton.BackColor = BackColor;
1264                         mycomputerButton.ForeColor = Color.Black;
1265                         mycomputerButton.Size = new Size (81, 64);
1266                         mycomputerButton.Location = new Point (2, 194);
1267                         mycomputerButton.Text = "My Computer";
1268                         mycomputerButton.Click += new EventHandler (OnClickButton);
1269                         
1270                         networkButton.Image = ThemeEngine.Current.Images (UIIcon.PlacesMyNetwork, 32);
1271                         networkButton.BackColor = BackColor;
1272                         networkButton.ForeColor = Color.Black;
1273                         networkButton.Size = new Size (81, 64);
1274                         networkButton.Location = new Point (2, 258);
1275                         networkButton.Text = "My Network";
1276                         networkButton.Click += new EventHandler (OnClickButton);
1277                         
1278                         Controls.Add (recentlyusedButton);
1279                         Controls.Add (desktopButton);
1280                         Controls.Add (personalButton);
1281                         Controls.Add (mycomputerButton);
1282                         Controls.Add (networkButton);
1283                         
1284                         ResumeLayout (false);
1285                         
1286                         KeyDown += new KeyEventHandler (Key_Down);
1287                         
1288                         SetStyle (ControlStyles.StandardClick, false);
1289                 }
1290                 
1291                 void OnClickButton (object sender, EventArgs e)
1292                 {
1293                         if (lastPopupButton != null && lastPopupButton != sender as PopupButton)
1294                                 lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal;
1295                         lastPopupButton = sender as PopupButton;
1296                         
1297                         if (sender == recentlyusedButton) {
1298                                 currentPath = MWFVFS.RecentlyUsedPrefix;
1299                         } else
1300                         if (sender == desktopButton) {
1301                                 currentPath = MWFVFS.DesktopPrefix;
1302                         } else
1303                         if (sender == personalButton) {
1304                                 currentPath = MWFVFS.PersonalPrefix;
1305                         } else
1306                         if (sender == mycomputerButton) {
1307                                 currentPath = MWFVFS.MyComputerPrefix;
1308                         } else
1309                         if (sender == networkButton) {
1310                                 currentPath = MWFVFS.MyNetworkPrefix;
1311                         }
1312                         
1313                         if (on_directory_changed != null)
1314                                 on_directory_changed (this, EventArgs.Empty);
1315                 }
1316                 
1317                 public string CurrentFolder {
1318                         set {
1319                                 string currentPath = value;
1320                                 if (currentPath == MWFVFS.RecentlyUsedPrefix) {
1321                                         if (lastPopupButton != recentlyusedButton) {
1322                                                 if (lastPopupButton != null)
1323                                                         lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal;
1324                                                 recentlyusedButton.ButtonState = PopupButton.PopupButtonState.Down;
1325                                                 lastPopupButton = recentlyusedButton;
1326                                         }
1327                                 } else
1328                                 if (currentPath == MWFVFS.DesktopPrefix) {
1329                                         if (lastPopupButton != desktopButton) {
1330                                                 if (lastPopupButton != null)
1331                                                         lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal;
1332                                                 desktopButton.ButtonState = PopupButton.PopupButtonState.Down;
1333                                                 lastPopupButton = desktopButton;
1334                                         }
1335                                 } else
1336                                 if (currentPath == MWFVFS.PersonalPrefix) {
1337                                         if (lastPopupButton != personalButton) {
1338                                                 if (lastPopupButton != null)
1339                                                         lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal;
1340                                                 personalButton.ButtonState = PopupButton.PopupButtonState.Down;
1341                                                 lastPopupButton = personalButton;
1342                                         }
1343                                 } else
1344                                 if (currentPath == MWFVFS.MyComputerPrefix) {
1345                                         if (lastPopupButton != mycomputerButton) {
1346                                                 if (lastPopupButton != null)
1347                                                         lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal;
1348                                                 mycomputerButton.ButtonState = PopupButton.PopupButtonState.Down;
1349                                                 lastPopupButton = mycomputerButton;
1350                                         }
1351                                 } else
1352                                 if (currentPath == MWFVFS.MyNetworkPrefix) {
1353                                         if (lastPopupButton != networkButton) {
1354                                                 if (lastPopupButton != null)
1355                                                         lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal;
1356                                                 networkButton.ButtonState = PopupButton.PopupButtonState.Down;
1357                                                 lastPopupButton = networkButton;
1358                                         }
1359                                 } else {
1360                                         if (lastPopupButton != null) {
1361                                                 lastPopupButton.ButtonState = PopupButton.PopupButtonState.Normal;
1362                                                 lastPopupButton = null;
1363                                         }
1364                                 }
1365                         }
1366                         get {
1367                                 return currentPath;
1368                         }
1369                 }
1370                 
1371                 protected override void OnPaint (PaintEventArgs e)
1372                 {
1373                         ControlPaint.DrawBorder3D (e.Graphics, ClientRectangle, Border3DStyle.Sunken);
1374                         base.OnPaint (e);
1375                 }
1376                 
1377                 protected override void OnGotFocus (EventArgs e)
1378                 {
1379                         if (lastPopupButton != recentlyusedButton) {
1380                                 recentlyusedButton.ButtonState = PopupButton.PopupButtonState.Up;
1381                                 focusButton = recentlyusedButton;
1382                         }
1383                         currentFocusIndex = 0;
1384                         
1385                         base.OnGotFocus (e);
1386                 }
1387                 
1388                 protected override void OnLostFocus (EventArgs e)
1389                 {
1390                         if (focusButton != null && focusButton.ButtonState != PopupButton.PopupButtonState.Down)
1391                                 focusButton.ButtonState = PopupButton.PopupButtonState.Normal;
1392                         base.OnLostFocus (e);
1393                 }
1394                 
1395                 protected override bool IsInputKey (Keys key)
1396                 {
1397                         switch (key) {
1398                                 case Keys.Up:
1399                                 case Keys.Down:
1400                                 case Keys.Right:
1401                                 case Keys.Left:
1402                                 case Keys.Enter:
1403                                         return true;
1404                         }
1405                         return base.IsInputKey (key);
1406                 }
1407                 
1408                 private void Key_Down (object sender, KeyEventArgs e)
1409                 {
1410                         bool update_focus = false;
1411                         
1412                         if (e.KeyCode == Keys.Left || e.KeyCode == Keys.Up) {
1413                                 currentFocusIndex --;
1414                                 
1415                                 if (currentFocusIndex < 0)
1416                                         currentFocusIndex = Controls.Count - 1;
1417                                 
1418                                 update_focus = true;
1419                         } else
1420                         if (e.KeyCode == Keys.Down || e.KeyCode == Keys.Right) {
1421                                 currentFocusIndex++;
1422                                 
1423                                 if (currentFocusIndex == Controls.Count)
1424                                         currentFocusIndex = 0;
1425                                 
1426                                 update_focus = true;
1427                         } else
1428                         if (e.KeyCode == Keys.Enter) {
1429                                 focusButton.ButtonState = PopupButton.PopupButtonState.Down;
1430                                 OnClickButton (focusButton, EventArgs.Empty);
1431                         }
1432                         
1433                         if (update_focus) {
1434                                 PopupButton newfocusButton = Controls [currentFocusIndex] as PopupButton;
1435                                 if (focusButton != null && focusButton.ButtonState != PopupButton.PopupButtonState.Down)
1436                                         focusButton.ButtonState = PopupButton.PopupButtonState.Normal;
1437                                 if (newfocusButton.ButtonState != PopupButton.PopupButtonState.Down)
1438                                         newfocusButton.ButtonState = PopupButton.PopupButtonState.Up;
1439                                 focusButton = newfocusButton;
1440                         }
1441                         
1442                         e.Handled = true;
1443                 }
1444                 
1445                 public event EventHandler DirectoryChanged {
1446                         add { on_directory_changed += value; }
1447                         remove { on_directory_changed -= value; }
1448                 }
1449         }
1450         #endregion
1451         
1452         #region DirComboBox
1453         internal class DirComboBox : ComboBox, IUpdateFolder
1454         {
1455                 #region DirComboBoxItem
1456                 internal class DirComboBoxItem
1457                 {
1458                         private int imageIndex;
1459                         private string name;
1460                         private string path;
1461                         private int xPos;
1462                         private ImageList imageList;
1463                         
1464                         public DirComboBoxItem (ImageList imageList, int imageIndex, string name, string path, int xPos)
1465                         {
1466                                 this.imageList = imageList;
1467                                 this.imageIndex = imageIndex;
1468                                 this.name = name;
1469                                 this.path = path;
1470                                 this.xPos = xPos;
1471                         }
1472                         
1473                         public int ImageIndex {
1474                                 get {
1475                                         return imageIndex;
1476                                 }
1477                         }
1478                         
1479                         public string Name {
1480                                 get {
1481                                         return name;
1482                                 }
1483                         }
1484                         
1485                         public string Path {
1486                                 get {
1487                                         return path;
1488                                 }
1489                         }
1490                         
1491                         public int XPos {
1492                                 get {
1493                                         return xPos;
1494                                 }
1495                         }
1496                         
1497                         public ImageList ImageList {
1498                                 set {
1499                                         imageList = value;
1500                                 }
1501                                 
1502                                 get {
1503                                         return imageList;
1504                                 }
1505                         }
1506                 }
1507                 #endregion
1508                 
1509                 private ImageList imageList = new ImageList();
1510                 
1511                 private string currentPath;
1512                 
1513                 private EventHandler on_directory_changed;
1514                 
1515                 private bool currentpath_internal_change = false;
1516                 
1517                 private Stack folderStack = new Stack();
1518                 
1519                 private static readonly int indent = 6;
1520                 
1521                 private DirComboBoxItem recentlyUsedDirComboboxItem;
1522                 private DirComboBoxItem desktopDirComboboxItem;
1523                 private DirComboBoxItem personalDirComboboxItem;
1524                 private DirComboBoxItem myComputerDirComboboxItem;
1525                 private DirComboBoxItem networkDirComboboxItem;
1526                 
1527                 private ArrayList myComputerItems = new ArrayList ();
1528                 
1529                 private DirComboBoxItem mainParentDirComboBoxItem = null;
1530                 private DirComboBoxItem real_parent = null;
1531                 
1532                 private MWFVFS vfs;
1533                 
1534                 public DirComboBox (MWFVFS vfs)
1535                 {
1536                         SuspendLayout ();
1537                         
1538                         DrawMode = DrawMode.OwnerDrawFixed;
1539                         
1540                         imageList.ColorDepth = ColorDepth.Depth32Bit;
1541                         imageList.ImageSize = new Size (16, 16);
1542                         imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.PlacesRecentDocuments, 16));
1543                         imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.PlacesDesktop, 16));
1544                         imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.PlacesPersonal, 16));
1545                         imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.PlacesMyComputer, 16));
1546                         imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.PlacesMyNetwork, 16));
1547                         imageList.Images.Add (ThemeEngine.Current.Images (UIIcon.NormalFolder, 16));
1548                         imageList.TransparentColor = Color.Transparent;
1549                         
1550                         recentlyUsedDirComboboxItem = new DirComboBoxItem (imageList, 0, "Recently used", MWFVFS.RecentlyUsedPrefix, 0);
1551                         desktopDirComboboxItem = new DirComboBoxItem (imageList, 1, "Desktop", MWFVFS.DesktopPrefix, 0);
1552                         personalDirComboboxItem = new DirComboBoxItem (imageList, 2, "Personal folder", MWFVFS.PersonalPrefix, indent);
1553                         myComputerDirComboboxItem = new DirComboBoxItem (imageList, 3, "My Computer", MWFVFS.MyComputerPrefix, indent);
1554                         networkDirComboboxItem = new DirComboBoxItem (imageList, 4, "My Network", MWFVFS.MyNetworkPrefix, indent);
1555                         
1556                         ArrayList al = vfs.GetMyComputerContent ();
1557                         
1558                         foreach (FSEntry fsEntry in al) {
1559                                 myComputerItems.Add (new DirComboBoxItem (MimeIconEngine.LargeIcons, fsEntry.IconIndex, fsEntry.Name, fsEntry.FullName, indent * 2));
1560                         }
1561                         
1562                         mainParentDirComboBoxItem = myComputerDirComboboxItem;
1563                         
1564                         ResumeLayout (false);
1565                 }
1566                 
1567                 public string CurrentFolder {
1568                         set {
1569                                 currentPath = value;
1570                                 
1571                                 currentpath_internal_change = true;
1572                                 
1573                                 CreateComboList ();
1574                         }
1575                         get {
1576                                 return currentPath;
1577                         }
1578                 }
1579                 
1580                 private void CreateComboList ()
1581                 {
1582                         real_parent = null;
1583                         DirComboBoxItem selection = null;
1584                         
1585                         if (currentPath == MWFVFS.RecentlyUsedPrefix) {
1586                                 mainParentDirComboBoxItem = recentlyUsedDirComboboxItem;
1587                                 selection = recentlyUsedDirComboboxItem;
1588                         } else
1589                         if (currentPath == MWFVFS.DesktopPrefix) {
1590                                 selection = desktopDirComboboxItem;
1591                                 mainParentDirComboBoxItem = desktopDirComboboxItem;
1592                         } else
1593                         if (currentPath == MWFVFS.PersonalPrefix) {
1594                                 selection = personalDirComboboxItem;
1595                                 mainParentDirComboBoxItem = personalDirComboboxItem;
1596                         } else
1597                         if (currentPath == MWFVFS.MyComputerPrefix) {
1598                                 selection = myComputerDirComboboxItem;
1599                                 mainParentDirComboBoxItem = myComputerDirComboboxItem;
1600                         } else
1601                         if (currentPath == MWFVFS.MyNetworkPrefix) {
1602                                 selection = networkDirComboboxItem;
1603                                 mainParentDirComboBoxItem = networkDirComboboxItem;
1604                         } else {
1605                                 foreach (DirComboBoxItem dci in myComputerItems) {
1606                                         if (dci.Path == currentPath) {
1607                                                 mainParentDirComboBoxItem = selection = dci;
1608                                                 break;
1609                                         }
1610                                 }
1611                         }
1612                         
1613                         BeginUpdate ();
1614                         
1615                         Items.Clear ();
1616                         
1617                         Items.Add (recentlyUsedDirComboboxItem);
1618                         Items.Add (desktopDirComboboxItem);
1619                         Items.Add (personalDirComboboxItem);
1620                         Items.Add (myComputerDirComboboxItem);
1621                         Items.AddRange (myComputerItems);
1622                         Items.Add (networkDirComboboxItem);
1623                         
1624                         if (selection == null) {
1625                                 real_parent = CreateFolderStack ();
1626                         }
1627                         
1628                         if (real_parent != null) {
1629                                 int local_indent = 0;
1630                                 
1631                                 if (real_parent == desktopDirComboboxItem)
1632                                         local_indent = 1;
1633                                 else
1634                                 if (real_parent == personalDirComboboxItem || real_parent == networkDirComboboxItem)
1635                                         local_indent = 2;
1636                                 else
1637                                         local_indent = 3;
1638                                 
1639                                 selection = AppendToParent (local_indent, real_parent);
1640                         }
1641                         
1642                         EndUpdate ();
1643                         
1644                         if (selection != null)
1645                                 SelectedItem = selection;
1646                 }
1647                 
1648                 private DirComboBoxItem CreateFolderStack ()
1649                 {
1650                         folderStack.Clear ();
1651                         
1652                         DirectoryInfo di = new DirectoryInfo (currentPath);
1653                         
1654                         folderStack.Push (di);
1655                         
1656                         while (di.Parent != null) {
1657                                 di = di.Parent;
1658                                 
1659                                 if (mainParentDirComboBoxItem != personalDirComboboxItem && di.FullName == ThemeEngine.Current.Places (UIIcon.PlacesDesktop))
1660                                         return desktopDirComboboxItem;
1661                                 else
1662                                 if (mainParentDirComboBoxItem == personalDirComboboxItem) {
1663                                         if (di.FullName == ThemeEngine.Current.Places (UIIcon.PlacesPersonal))
1664                                                 return personalDirComboboxItem;
1665                                 } else
1666                                         foreach (DirComboBoxItem dci in myComputerItems) {
1667                                                 if (dci.Path == di.FullName) {
1668                                                         return dci;
1669                                                 }
1670                                         }
1671                                 
1672                                 
1673                                 folderStack.Push (di);
1674                         }
1675                         
1676                         return null;
1677                 }
1678                 
1679                 private DirComboBoxItem AppendToParent (int nr_indents, DirComboBoxItem parentDirComboBoxItem)
1680                 {
1681                         DirComboBoxItem selection = null;
1682                         
1683                         int index = Items.IndexOf (parentDirComboBoxItem) + 1;
1684                         
1685                         int xPos = indent * nr_indents;
1686                         
1687                         while (folderStack.Count != 0) {
1688                                 DirectoryInfo dii = folderStack.Pop () as DirectoryInfo;
1689                                 
1690                                 DirComboBoxItem dci = new DirComboBoxItem (imageList, 5, dii.Name, dii.FullName, xPos);
1691                                 
1692                                 Items.Insert (index, dci);
1693                                 index++;
1694                                 selection = dci;
1695                                 xPos += indent;
1696                         }
1697                         
1698                         return selection;
1699                 }
1700                 
1701                 protected override void OnDrawItem (DrawItemEventArgs e)
1702                 {
1703                         if (e.Index == -1)
1704                                 return;
1705                         
1706                         DirComboBoxItem dcbi = Items [e.Index] as DirComboBoxItem;
1707                         
1708                         Bitmap bmp = new Bitmap (e.Bounds.Width, e.Bounds.Height, e.Graphics);
1709                         Graphics gr = Graphics.FromImage (bmp);
1710                         
1711                         Color backColor = e.BackColor;
1712                         Color foreColor = e.ForeColor;
1713                         
1714                         int xPos = dcbi.XPos;
1715                         
1716                         if ((e.State & DrawItemState.ComboBoxEdit) != 0)
1717                                 xPos = 0;
1718                         else
1719                         if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
1720                                 backColor = ThemeEngine.Current.ColorHighlight;
1721                                 foreColor = ThemeEngine.Current.ColorHighlightText;
1722                         }
1723                         
1724                         gr.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (backColor), new Rectangle (0, 0, bmp.Width, bmp.Height));
1725                         
1726                         gr.DrawString (dcbi.Name, e.Font , ThemeEngine.Current.ResPool.GetSolidBrush (foreColor), new Point (24 + xPos, (bmp.Height - e.Font.Height) / 2));
1727                         gr.DrawImage (dcbi.ImageList.Images [dcbi.ImageIndex], new Rectangle (new Point (xPos + 2, 0), new Size (16, 16)));
1728                         
1729                         e.Graphics.DrawImage (bmp, e.Bounds.X, e.Bounds.Y);
1730                         gr.Dispose ();
1731                         bmp.Dispose ();
1732                 }
1733                 
1734                 protected override void OnSelectedIndexChanged (EventArgs e)
1735                 {
1736                         if (Items.Count > 0) {
1737                                 DirComboBoxItem dcbi = Items [SelectedIndex] as DirComboBoxItem;
1738                                 
1739                                 currentPath = dcbi.Path;
1740                                 // call DirectoryChange event only if the user changes the index with the ComboBox
1741                                 
1742                                 if (!currentpath_internal_change) {
1743                                         if (on_directory_changed != null)
1744                                                 on_directory_changed (this, EventArgs.Empty);
1745                                 }
1746                         }
1747                         
1748                         currentpath_internal_change = false;
1749                 }
1750                 
1751                 public event EventHandler DirectoryChanged {
1752                         add { on_directory_changed += value; }
1753                         remove { on_directory_changed -= value; }
1754                 }
1755         }
1756         #endregion
1757         
1758         #region FilterStruct
1759         internal struct FilterStruct
1760         {
1761                 public string filterName;
1762                 public StringCollection filters;
1763                 
1764                 public FilterStruct (string filterName, string filter)
1765                 {
1766                         this.filterName = filterName;
1767                         
1768                         filters =  new StringCollection ();
1769                         
1770                         SplitFilters (filter);
1771                 }
1772                 
1773                 private void SplitFilters (string filter)
1774                 {
1775                         string[] split = filter.Split (new char [] {';'});
1776                         
1777                         filters.AddRange (split);
1778                 }
1779         }
1780         #endregion
1781         
1782         #region FileFilter
1783         internal class FileFilter
1784         {
1785                 private ArrayList filterArrayList = new ArrayList();
1786                 
1787                 private string filter;
1788                 
1789                 public FileFilter ()
1790                 {}
1791                 
1792                 public FileFilter (string filter)
1793                 {
1794                         this.filter = filter;
1795                         
1796                         SplitFilter ();
1797                 }
1798                 
1799                 public ArrayList FilterArrayList {
1800                         set {
1801                                 filterArrayList = value;
1802                         }
1803                         
1804                         get {
1805                                 return filterArrayList;
1806                         }
1807                 }
1808                 
1809                 public string Filter {
1810                         set {
1811                                 filter = value;
1812                                 
1813                                 SplitFilter ();
1814                         }
1815                         
1816                         get {
1817                                 return filter;
1818                         }
1819                 }
1820                 
1821                 private void SplitFilter ()
1822                 {
1823                         filterArrayList.Clear ();
1824                         
1825                         if (filter == null)
1826                                 throw new NullReferenceException ("Filter");
1827                         
1828                         if (filter.Length == 0)
1829                                 return;
1830                         
1831                         string[] filters = filter.Split (new char [] {'|'});
1832                         
1833                         if ((filters.Length % 2) != 0)
1834                                 throw new ArgumentException ("Filter");
1835                         
1836                         for (int i = 0; i < filters.Length; i += 2) {
1837                                 FilterStruct filterStruct = new FilterStruct (filters [i], filters [i + 1]);
1838                                 
1839                                 filterArrayList.Add (filterStruct);
1840                         }
1841                 }
1842         }
1843         #endregion
1844         
1845         #region MWFFileView             
1846         // MWFFileView
1847         internal class MWFFileView : ListView
1848         {
1849                 private ArrayList filterArrayList;
1850                 
1851                 private bool showHiddenFiles = false;
1852                 
1853                 private EventHandler on_selected_file_changed;
1854                 private EventHandler on_selected_files_changed;
1855                 private EventHandler on_directory_changed;
1856                 private EventHandler on_force_dialog_end;
1857                 
1858                 private string selectedFilesString;
1859                 
1860                 private int filterIndex = 1;
1861                 
1862                 private ToolTip toolTip;
1863                 private int oldItemIndexForToolTip = -1;
1864                 
1865                 private ContextMenu contextMenu;
1866                 
1867                 private MenuItem menuItemView;
1868                 private MenuItem menuItemNew;
1869                 
1870                 private MenuItem smallIconMenutItem;
1871                 private MenuItem tilesMenutItem;
1872                 private MenuItem largeIconMenutItem;
1873                 private MenuItem listMenutItem;
1874                 private MenuItem detailsMenutItem;
1875                 
1876                 private MenuItem newFolderMenuItem; 
1877                 private MenuItem showHiddenFilesMenuItem;
1878                 
1879                 private int previousCheckedMenuItemIndex;
1880                 
1881                 private ArrayList viewMenuItemClones = new ArrayList ();
1882                 
1883                 private FSEntry currentFSEntry = null;
1884                 
1885                 private string currentFolder;
1886                 private string currentRealFolder;
1887                 private FSEntry currentFolderFSEntry;
1888                 
1889                 // store DirectoryInfo for a back button for example
1890                 private Stack directoryStack = new Stack();
1891                 
1892                 // list of controls(components to enable or disable depending on current directoryStack.Count
1893                 private ArrayList dirStackControlsOrComponents = new ArrayList ();
1894                 
1895                 private ToolBarButton folderUpToolBarButton;
1896                 
1897                 private ArrayList registered_senders = new ArrayList ();
1898                 
1899                 private bool should_push = true;
1900                 
1901                 private MWFVFS vfs;
1902                 
1903                 private View old_view;
1904                 
1905                 private int old_menuitem_index;
1906                 private bool do_update_view = false;
1907                 
1908                 private int platform = (int) Environment.OSVersion.Platform;
1909                 
1910                 public MWFFileView (MWFVFS vfs)
1911                 {
1912                         this.vfs = vfs;
1913                         vfs.RegisterUpdateDelegate (new MWFVFS.UpdateDelegate (RealFileViewUpdate), this);
1914                         
1915                         SuspendLayout ();
1916                         
1917                         contextMenu = new ContextMenu ();
1918                         
1919                         toolTip = new ToolTip ();
1920                         toolTip.InitialDelay = 300;
1921                         toolTip.ReshowDelay = 0; 
1922                         
1923                         // contextMenu
1924                         
1925                         // View menu item
1926                         menuItemView = new MenuItem ("View");
1927                         
1928                         smallIconMenutItem = new MenuItem ("Small Icon", new EventHandler (OnClickViewMenuSubItem));
1929                         smallIconMenutItem.RadioCheck = true;
1930                         menuItemView.MenuItems.Add (smallIconMenutItem);
1931                         
1932                         tilesMenutItem = new MenuItem ("Tiles", new EventHandler (OnClickViewMenuSubItem));
1933                         tilesMenutItem.RadioCheck = true;
1934                         menuItemView.MenuItems.Add (tilesMenutItem);
1935                         
1936                         largeIconMenutItem = new MenuItem ("Large Icon", new EventHandler (OnClickViewMenuSubItem));
1937                         largeIconMenutItem.RadioCheck = true;
1938                         menuItemView.MenuItems.Add (largeIconMenutItem);
1939                         
1940                         listMenutItem = new MenuItem ("List", new EventHandler (OnClickViewMenuSubItem));
1941                         listMenutItem.RadioCheck = true;
1942                         listMenutItem.Checked = true;
1943                         menuItemView.MenuItems.Add (listMenutItem);
1944                         previousCheckedMenuItemIndex = listMenutItem.Index;
1945                         
1946                         detailsMenutItem = new MenuItem ("Details", new EventHandler (OnClickViewMenuSubItem));
1947                         detailsMenutItem.RadioCheck = true;
1948                         menuItemView.MenuItems.Add (detailsMenutItem);
1949                         
1950                         contextMenu.MenuItems.Add (menuItemView);
1951                         
1952                         contextMenu.MenuItems.Add (new MenuItem ("-"));
1953                         
1954                         // New menu item
1955                         menuItemNew = new MenuItem ("New");
1956                         
1957                         newFolderMenuItem = new MenuItem ("New Folder", new EventHandler (OnClickNewFolderMenuItem));
1958                         menuItemNew.MenuItems.Add (newFolderMenuItem);
1959                         
1960                         contextMenu.MenuItems.Add (menuItemNew);
1961                         
1962                         contextMenu.MenuItems.Add (new MenuItem ("-"));
1963                         
1964                         // Show hidden files menu item
1965                         showHiddenFilesMenuItem = new MenuItem ("Show hidden files", new EventHandler (OnClickContextMenu));
1966                         showHiddenFilesMenuItem.Checked = showHiddenFiles;
1967                         contextMenu.MenuItems.Add (showHiddenFilesMenuItem);
1968                         
1969                         LabelWrap = true;
1970                         
1971                         SmallImageList = MimeIconEngine.SmallIcons;
1972                         LargeImageList = MimeIconEngine.LargeIcons;
1973                         
1974                         View = old_view = View.List;
1975                         LabelEdit = true;
1976                         
1977                         ContextMenu = contextMenu;
1978                         
1979                         ResumeLayout (false);
1980                         
1981                         KeyDown += new KeyEventHandler (MWF_KeyDown);
1982                 }
1983                 
1984                 public string CurrentFolder {
1985                         get {
1986                                 return currentFolder;
1987                         }
1988                         set {
1989                                 currentFolder = value;
1990                         }
1991                 }
1992                 
1993                 public string CurrentRealFolder {
1994                         get {
1995                                 return currentRealFolder;
1996                         }
1997                 }
1998                 
1999                 public FSEntry CurrentFSEntry {
2000                         get {
2001                                 return currentFSEntry;
2002                         }
2003                 }
2004                 
2005                 public MenuItem[] ViewMenuItems {
2006                         get {
2007                                 MenuItem[] menuItemClones = new MenuItem [] {
2008                                         smallIconMenutItem.CloneMenu (),
2009                                         tilesMenutItem.CloneMenu (),
2010                                         largeIconMenutItem.CloneMenu (),
2011                                         listMenutItem.CloneMenu (),
2012                                         detailsMenutItem.CloneMenu ()
2013                                 };
2014                                 
2015                                 viewMenuItemClones.Add (menuItemClones);
2016                                 
2017                                 return menuItemClones;
2018                         }
2019                 }
2020                 
2021                 public ArrayList FilterArrayList {
2022                         set {
2023                                 filterArrayList = value;
2024                         }
2025                         
2026                         get {
2027                                 return filterArrayList;
2028                         }
2029                 }
2030                 
2031                 public bool ShowHiddenFiles {
2032                         set {
2033                                 showHiddenFiles = value;
2034                         }
2035                         
2036                         get {
2037                                 return showHiddenFiles;
2038                         }
2039                 }
2040                 
2041                 public int FilterIndex {
2042                         set {
2043                                 filterIndex = value;
2044                                 if (Visible)
2045                                         UpdateFileView ();
2046                         }
2047                         
2048                         get {
2049                                 return filterIndex;
2050                         }
2051                 }
2052                 
2053                 public string SelectedFilesString {
2054                         set {
2055                                 selectedFilesString = value;
2056                         }
2057                         
2058                         get {
2059                                 return selectedFilesString;
2060                         }
2061                 }
2062                 
2063                 public void PushDir ()
2064                 {
2065                         if (currentFolder != null)
2066                                 directoryStack.Push (currentFolder);
2067                         
2068                         EnableOrDisableDirstackObjects ();
2069                 }
2070                 
2071                 public void PopDir ()
2072                 {
2073                         if (directoryStack.Count == 0)
2074                                 return;
2075                         
2076                         string new_folder = directoryStack.Pop () as string;
2077                         
2078                         EnableOrDisableDirstackObjects ();
2079                         
2080                         should_push = false;
2081                         
2082                         ChangeDirectory (null, new_folder);
2083                 }
2084                 
2085                 public void RegisterSender (IUpdateFolder iud)
2086                 {
2087                         registered_senders.Add (iud);
2088                 }
2089                 
2090                 public void CreateNewFolder ()
2091                 {
2092                         if (currentFolder == MWFVFS.MyComputerPrefix ||
2093                             currentFolder == MWFVFS.RecentlyUsedPrefix)
2094                                 return;
2095                         
2096                         FSEntry fsEntry = new FSEntry ();
2097                         fsEntry.Attributes = FileAttributes.Directory;
2098                         fsEntry.FileType = FSEntry.FSEntryType.Directory;
2099                         fsEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("inode/directory");
2100                         fsEntry.LastAccessTime = DateTime.Now;
2101                         
2102                         // FIXME: when ListView.LabelEdit is available use it
2103 //                      listViewItem.BeginEdit();
2104                         
2105                         TextEntryDialog ted = new TextEntryDialog ();
2106                         ted.IconPictureBoxImage = MimeIconEngine.LargeIcons.Images.GetImage (fsEntry.IconIndex);
2107                         
2108                         string folder = "";
2109                         
2110                         if (currentFolderFSEntry.RealName != null)
2111                                 folder = currentFolderFSEntry.RealName;
2112                         else
2113                                 folder = currentFolder;
2114                         
2115                         string tmp_filename = "New Folder";
2116                         
2117                         if (Directory.Exists (Path.Combine (folder, tmp_filename))) {
2118                                 int i = 1;
2119                                 
2120                                 if ((platform == 4) || (platform == 128)) {
2121                                         tmp_filename = tmp_filename + "-" + i;
2122                                 } else {
2123                                         tmp_filename = tmp_filename + " (" + i + ")";
2124                                 }
2125                                 
2126                                 while (Directory.Exists (Path.Combine (folder, tmp_filename))) {
2127                                         i++;
2128                                         if ((platform == 4) || (platform == 128)) {
2129                                                 tmp_filename = "New Folder" + "-" + i;
2130                                         } else {
2131                                                 tmp_filename = "New Folder" + " (" + i + ")";
2132                                         }
2133                                 }
2134                         }
2135                         
2136                         ted.FileName = tmp_filename;
2137                         
2138                         if (ted.ShowDialog () == DialogResult.OK) {
2139                                 string new_folder = Path.Combine (folder, ted.FileName);
2140                                 
2141                                 if (vfs.CreateFolder (new_folder)) {
2142                                         fsEntry.FullName = new_folder;
2143                                         fsEntry.Name = ted.FileName;
2144                                         
2145                                         FileViewListViewItem listViewItem = new FileViewListViewItem (fsEntry);
2146                                         
2147                                         BeginUpdate ();
2148                                         Items.Add (listViewItem);
2149                                         EndUpdate ();
2150                                         
2151                                         listViewItem.EnsureVisible ();
2152                                 }
2153                         }
2154                 }
2155                 
2156                 public void SetSelectedIndexTo (string fname)
2157                 {
2158                         foreach (FileViewListViewItem item in Items) {
2159                                 if (item.Text == fname) {
2160                                         BeginUpdate ();
2161                                         SelectedItems.Clear ();
2162                                         item.Selected = true;
2163                                         EndUpdate ();
2164                                         break;
2165                                 }
2166                         }
2167                 }
2168                 
2169                 public void OneDirUp ()
2170                 {
2171                         string parent_folder = vfs.GetParent ();
2172                         if (parent_folder != null)
2173                                 ChangeDirectory (null, parent_folder);
2174                 }
2175                 
2176                 public void ChangeDirectory (object sender, string folder)
2177                 {
2178                         if (folder == MWFVFS.DesktopPrefix || folder == MWFVFS.RecentlyUsedPrefix)
2179                                 folderUpToolBarButton.Enabled = false;
2180                         else
2181                                 folderUpToolBarButton.Enabled = true;
2182                         
2183                         foreach (IUpdateFolder iuf in registered_senders) {
2184                                 iuf.CurrentFolder = folder;
2185                         }
2186                         
2187                         if (should_push)
2188                                 PushDir ();
2189                         else
2190                                 should_push = true;
2191                         
2192                         currentFolderFSEntry = vfs.ChangeDirectory (folder);
2193                         
2194                         currentFolder = folder;
2195                         
2196                         if (currentFolder.IndexOf ("://") != -1)
2197                                 currentRealFolder = currentFolderFSEntry.RealName;
2198                         else
2199                                 currentRealFolder = currentFolder;
2200                         
2201                         BeginUpdate ();
2202                         
2203                         Items.Clear ();
2204                         SelectedItems.Clear ();
2205                         
2206                         if (folder == MWFVFS.RecentlyUsedPrefix) {
2207                                 old_view = View;
2208                                 View = View.Details;
2209                                 old_menuitem_index = previousCheckedMenuItemIndex;
2210                                 UpdateMenuItems (detailsMenutItem);
2211                                 do_update_view = true;
2212                         } else
2213                         if (View != old_view && do_update_view) {
2214                                 UpdateMenuItems (menuItemView.MenuItems [old_menuitem_index]);
2215                                 View = old_view;
2216                                 do_update_view = false;
2217                         }
2218                         EndUpdate ();
2219
2220                         try {
2221                                 UpdateFileView ();
2222                         } catch (Exception e) {
2223                                 if (should_push)
2224                                         PopDir ();
2225                                 MessageBox.Show (e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
2226                         }
2227                 }
2228                 
2229                 public void UpdateFileView ()
2230                 {
2231                         if (filterArrayList != null && filterArrayList.Count != 0) {
2232                                 FilterStruct fs = (FilterStruct)filterArrayList [filterIndex - 1];
2233                                 
2234                                 vfs.GetFolderContent (fs.filters);
2235                         } else
2236                                 vfs.GetFolderContent ();
2237                 }
2238                 
2239                 public void RealFileViewUpdate (ArrayList directoriesArrayList, ArrayList fileArrayList)
2240                 {
2241                         BeginUpdate ();
2242                         
2243                         Items.Clear ();
2244                         SelectedItems.Clear ();
2245                         
2246                         foreach (FSEntry directoryFSEntry in directoriesArrayList) {
2247                                 if (!ShowHiddenFiles)
2248                                         if (directoryFSEntry.Name.StartsWith (".") || directoryFSEntry.Attributes == FileAttributes.Hidden)
2249                                                 continue;
2250                                 
2251                                 FileViewListViewItem listViewItem = new FileViewListViewItem (directoryFSEntry);
2252                                 
2253                                 Items.Add (listViewItem);
2254                         }
2255                         
2256                         StringCollection collection = new StringCollection ();
2257                         
2258                         foreach (FSEntry fsEntry in fileArrayList) {
2259                                 
2260                                 // remove duplicates. that can happen when you read recently used files for example
2261                                 if (collection.Contains (fsEntry.Name)) {
2262                                         
2263                                         string fileName = fsEntry.Name;
2264                                         
2265                                         if (collection.Contains (fileName)) {
2266                                                 int i = 1;
2267                                                 
2268                                                 while (collection.Contains (fileName + "(" + i + ")")) {
2269                                                         i++;
2270                                                 }
2271                                                 
2272                                                 fileName = fileName + "(" + i + ")";
2273                                         }
2274                                         
2275                                         fsEntry.Name = fileName;
2276                                 }
2277                                 
2278                                 collection.Add (fsEntry.Name);
2279                                 
2280                                 DoOneFSEntry (fsEntry);
2281                         }
2282                         
2283                         EndUpdate ();
2284                 }
2285                 
2286                 public void AddControlToEnableDisableByDirStack (object control)
2287                 {
2288                         dirStackControlsOrComponents.Add (control);
2289                 }
2290                 
2291                 public void SetFolderUpToolBarButton (ToolBarButton tb)
2292                 {
2293                         folderUpToolBarButton = tb;
2294                 }
2295                 
2296                 public void WriteRecentlyUsed (string fullfilename)
2297                 {
2298                         vfs.WriteRecentlyUsedFiles (fullfilename);
2299                 }
2300                 
2301                 private void EnableOrDisableDirstackObjects ()
2302                 {
2303                         foreach (object o in dirStackControlsOrComponents) {
2304                                 if (o is Control) {
2305                                         Control c = o as Control;
2306                                         c.Enabled = (directoryStack.Count > 1);
2307                                 } else
2308                                 if (o is ToolBarButton) {
2309                                         ToolBarButton t = o as ToolBarButton;
2310                                         t.Enabled = (directoryStack.Count > 1);
2311                                 }
2312                         }
2313                 }
2314                 
2315                 private void DoOneFSEntry (FSEntry fsEntry) 
2316                 {
2317                         if (!ShowHiddenFiles)
2318                                 if (fsEntry.Name.StartsWith (".")  || fsEntry.Attributes == FileAttributes.Hidden)
2319                                         return;
2320                         
2321                         FileViewListViewItem listViewItem = new FileViewListViewItem (fsEntry);
2322                         
2323                         Items.Add (listViewItem);
2324                 }
2325                 
2326                 private void MWF_KeyDown (object sender, KeyEventArgs e)
2327                 {
2328                         if (e.KeyCode == Keys.Back) {
2329                                 OneDirUp ();
2330                         }
2331                 }
2332                 
2333                 protected override void OnClick (EventArgs e)
2334                 {
2335                         if (!MultiSelect) {
2336                                 if (SelectedItems.Count > 0) {
2337                                         FileViewListViewItem listViewItem = SelectedItems [0] as FileViewListViewItem;
2338                                         
2339                                         FSEntry fsEntry = listViewItem.FSEntry;
2340                                         
2341                                         if (fsEntry.FileType == FSEntry.FSEntryType.File) {
2342                                                 currentFSEntry = fsEntry;
2343                                                 
2344                                                 if (on_selected_file_changed != null)
2345                                                         on_selected_file_changed (this, EventArgs.Empty);
2346                                         }
2347                                 }
2348                         }
2349                         
2350                         base.OnClick (e);
2351                 }
2352                 
2353                 protected override void OnDoubleClick (EventArgs e)
2354                 {
2355                         if (SelectedItems.Count > 0) {
2356                                 FileViewListViewItem listViewItem = SelectedItems [0] as FileViewListViewItem;
2357                                 
2358                                 FSEntry fsEntry = listViewItem.FSEntry;
2359                                 
2360                                 if (fsEntry.Attributes == FileAttributes.Directory) {
2361                                         
2362                                         ChangeDirectory (null, fsEntry.FullName);
2363                                         
2364                                         if (on_directory_changed != null)
2365                                                 on_directory_changed (this, EventArgs.Empty);
2366                                 } else {
2367                                         currentFSEntry = fsEntry;
2368                                         
2369                                         if (on_selected_file_changed != null)
2370                                                 on_selected_file_changed (this, EventArgs.Empty);
2371                                         
2372                                         if (on_force_dialog_end != null)
2373                                                 on_force_dialog_end (this, EventArgs.Empty);
2374                                         
2375                                         return;
2376                                 }
2377                         }
2378                         
2379                         base.OnDoubleClick (e);
2380                 }
2381                 
2382                 protected override void OnSelectedIndexChanged (EventArgs e)
2383                 {
2384                         if (SelectedItems.Count > 0) {
2385                                 selectedFilesString = "";
2386                                 
2387                                 if (SelectedItems.Count == 1) {
2388                                         FileViewListViewItem listViewItem = SelectedItems [0] as FileViewListViewItem;
2389                                         
2390                                         FSEntry fsEntry = listViewItem.FSEntry;
2391                                         
2392                                         if (fsEntry.Attributes != FileAttributes.Directory)
2393                                                 selectedFilesString = SelectedItems [0].Text;
2394                                 } else {
2395                                         foreach (FileViewListViewItem lvi in SelectedItems) {
2396                                                 FSEntry fsEntry = lvi.FSEntry;
2397                                                 
2398                                                 if (fsEntry.Attributes != FileAttributes.Directory)
2399                                                         selectedFilesString = selectedFilesString + "\"" + lvi.Text + " ";
2400                                         }
2401                                 }
2402                                 
2403                                 if (on_selected_files_changed != null)
2404                                         on_selected_files_changed (this, EventArgs.Empty);
2405                         }
2406                         
2407                         base.OnSelectedIndexChanged (e);
2408                 }
2409                 
2410                 protected override void OnMouseMove (MouseEventArgs e)
2411                 {
2412                         FileViewListViewItem item = GetItemAt (e.X, e.Y) as FileViewListViewItem;
2413                         
2414                         if (item != null) {
2415                                 int currentItemIndex = item.Index;
2416                                 
2417                                 if (currentItemIndex != oldItemIndexForToolTip) {
2418                                         oldItemIndexForToolTip = currentItemIndex;
2419                                         
2420                                         if (toolTip != null && toolTip.Active)
2421                                                 toolTip.Active = false;
2422                                         
2423                                         FSEntry fsEntry = item.FSEntry;
2424                                         
2425                                         string output = String.Empty;
2426                                         
2427                                         if (fsEntry.FileType == FSEntry.FSEntryType.Directory)
2428                                                 output = "Directory: " + fsEntry.FullName;
2429                                         else if (fsEntry.FileType == FSEntry.FSEntryType.Device)
2430                                                 output = "Device: "+ fsEntry.FullName;
2431                                         else if (fsEntry.FileType == FSEntry.FSEntryType.Network)
2432                                                 output = "Network: " + fsEntry.FullName;
2433                                         else
2434                                                 output = "File: " + fsEntry.FullName;
2435                                         
2436                                         toolTip.SetToolTip (this, output);      
2437                                         
2438                                         toolTip.Active = true;
2439                                 }
2440                         }
2441                         
2442                         base.OnMouseMove (e);
2443                 }
2444                 
2445                 void OnClickContextMenu (object sender, EventArgs e)
2446                 {
2447                         MenuItem senderMenuItem = sender as MenuItem;
2448                         
2449                         if (senderMenuItem == showHiddenFilesMenuItem) {
2450                                 senderMenuItem.Checked = !senderMenuItem.Checked;
2451                                 showHiddenFiles = senderMenuItem.Checked;
2452                                 UpdateFileView ();
2453                         }
2454                 }
2455                 
2456                 void OnClickViewMenuSubItem (object sender, EventArgs e)
2457                 {
2458                         MenuItem senderMenuItem = (MenuItem)sender;
2459                         
2460                         UpdateMenuItems (senderMenuItem);
2461                         
2462                         // update me
2463                         
2464                         switch (senderMenuItem.Index) {
2465                                 case 0:
2466                                         View = View.SmallIcon;
2467                                         break;
2468                                 case 1:
2469                                         View = View.LargeIcon;
2470                                         break;
2471                                 case 2:
2472                                         View = View.LargeIcon;
2473                                         break;
2474                                 case 3:
2475                                         View = View.List;
2476                                         break;
2477                                 case 4:
2478                                         View = View.Details;
2479                                         break;
2480                                 default:
2481                                         break;
2482                         }
2483                 }
2484                 
2485                 private void UpdateMenuItems (MenuItem senderMenuItem)
2486                 {
2487                         menuItemView.MenuItems [previousCheckedMenuItemIndex].Checked = false;
2488                         menuItemView.MenuItems [senderMenuItem.Index].Checked = true;
2489                         
2490                         foreach (MenuItem[] items in viewMenuItemClones) {
2491                                 items [previousCheckedMenuItemIndex].Checked = false;
2492                                 items [senderMenuItem.Index].Checked = true;
2493                         }
2494                         
2495                         previousCheckedMenuItemIndex = senderMenuItem.Index;
2496                 }
2497                 
2498                 void OnClickNewFolderMenuItem (object sender, EventArgs e)
2499                 {
2500                         CreateNewFolder ();
2501                 }
2502                 
2503                 public event EventHandler SelectedFileChanged {
2504                         add { on_selected_file_changed += value; }
2505                         remove { on_selected_file_changed -= value; }
2506                 }
2507                 
2508                 public event EventHandler SelectedFilesChanged {
2509                         add { on_selected_files_changed += value; }
2510                         remove { on_selected_files_changed -= value; }
2511                 }
2512                 
2513                 public event EventHandler DirectoryChanged {
2514                         add { on_directory_changed += value; }
2515                         remove { on_directory_changed -= value; }
2516                 }
2517                 
2518                 public event EventHandler ForceDialogEnd {
2519                         add { on_force_dialog_end += value; }
2520                         remove { on_force_dialog_end -= value; }
2521                 }
2522         }
2523         #endregion
2524         
2525         #region FileListViewItem
2526         internal class FileViewListViewItem : ListViewItem
2527         {
2528                 private FSEntry fsEntry;
2529                 
2530                 public FileViewListViewItem (FSEntry fsEntry)
2531                 {
2532                         this.fsEntry = fsEntry;
2533                         
2534                         ImageIndex = fsEntry.IconIndex;
2535                         
2536                         Text = fsEntry.Name;
2537                         
2538                         switch (fsEntry.FileType) {
2539                                 case FSEntry.FSEntryType.Directory:
2540                                         SubItems.Add ("");
2541                                         SubItems.Add ("Directory");
2542                                         SubItems.Add (fsEntry.LastAccessTime.ToShortDateString () + " " + fsEntry.LastAccessTime.ToShortTimeString ()); 
2543                                         break;
2544                                 case FSEntry.FSEntryType.File:
2545                                         long fileLen = 1;
2546                                         try {
2547                                                 if (fsEntry.FileSize > 1024)
2548                                                         fileLen = fsEntry.FileSize / 1024;
2549                                         } catch (Exception) {
2550                                                 fileLen = 1;
2551                                         }
2552                                         
2553                                         SubItems.Add (fileLen.ToString () + " KB");
2554                                         SubItems.Add ("File");
2555                                         SubItems.Add (fsEntry.LastAccessTime.ToShortDateString () + " " + fsEntry.LastAccessTime.ToShortTimeString ()); 
2556                                         break;
2557                                 case FSEntry.FSEntryType.Device:
2558                                         SubItems.Add ("");
2559                                         SubItems.Add ("Device");
2560                                         SubItems.Add (fsEntry.LastAccessTime.ToShortDateString () + " " + fsEntry.LastAccessTime.ToShortTimeString ()); 
2561                                         break;
2562                                 case FSEntry.FSEntryType.RemovableDevice:
2563                                         SubItems.Add ("");
2564                                         SubItems.Add ("RemovableDevice");
2565                                         SubItems.Add (fsEntry.LastAccessTime.ToShortDateString () + " " + fsEntry.LastAccessTime.ToShortTimeString ()); 
2566                                         break;
2567                                 default:
2568                                         break;
2569                         }
2570                 }
2571                 
2572                 public FSEntry FSEntry {
2573                         set {
2574                                 fsEntry = value;
2575                         }
2576                         
2577                         get {
2578                                 return fsEntry;
2579                         }
2580                 }
2581         }
2582         #endregion
2583         
2584         #region IUpdateFolder
2585         internal interface IUpdateFolder
2586         {
2587                 string CurrentFolder {get; set;}
2588         }
2589         #endregion
2590         
2591         #region TextEntryDialog
2592         // FIXME: When ListView.LabelEdit is implemented remove me
2593         internal class TextEntryDialog : Form
2594         {
2595                 private Label label1;
2596                 private Button okButton;
2597                 private TextBox newNameTextBox;
2598                 private PictureBox iconPictureBox;
2599                 private Button cancelButton;
2600                 private GroupBox groupBox1;
2601                 
2602                 public TextEntryDialog ()
2603                 {
2604                         groupBox1 = new GroupBox ();
2605                         cancelButton = new Button ();
2606                         iconPictureBox = new PictureBox ();
2607                         newNameTextBox = new TextBox ();
2608                         okButton = new Button ();
2609                         label1 = new Label ();
2610                         groupBox1.SuspendLayout ();
2611                         SuspendLayout ();
2612                         
2613                         // groupBox1
2614                         groupBox1.Controls.Add (newNameTextBox);
2615                         groupBox1.Controls.Add (label1);
2616                         groupBox1.Controls.Add (iconPictureBox);
2617                         groupBox1.Location = new Point (8, 8);
2618                         groupBox1.Size = new Size (232, 160);
2619                         groupBox1.TabIndex = 5;
2620                         groupBox1.TabStop = false;
2621                         groupBox1.Text = "New Name";
2622                         
2623                         // cancelButton
2624                         cancelButton.DialogResult = DialogResult.Cancel;
2625                         cancelButton.Location = new Point (168, 176);
2626                         cancelButton.TabIndex = 4;
2627                         cancelButton.Text = "Cancel";
2628                         
2629                         // iconPictureBox
2630                         iconPictureBox.BorderStyle = BorderStyle.Fixed3D;
2631                         iconPictureBox.Location = new Point (86, 24);
2632                         iconPictureBox.Size = new Size (60, 60);
2633                         iconPictureBox.TabIndex = 3;
2634                         iconPictureBox.TabStop = false;
2635                         iconPictureBox.SizeMode = PictureBoxSizeMode.CenterImage;
2636                         
2637                         // newNameTextBox
2638                         newNameTextBox.Location = new Point (16, 128);
2639                         newNameTextBox.Size = new Size (200, 20);
2640                         newNameTextBox.TabIndex = 5;
2641                         newNameTextBox.Text = "";
2642                         
2643                         // okButton
2644                         okButton.DialogResult = DialogResult.OK;
2645                         okButton.Location = new Point (80, 176);
2646                         okButton.TabIndex = 3;
2647                         okButton.Text = "OK";
2648                         
2649                         // label1
2650                         label1.Location = new Point (16, 96);
2651                         label1.Size = new Size (200, 23);
2652                         label1.TabIndex = 4;
2653                         label1.Text = "Enter Name:";
2654                         label1.TextAlign = ContentAlignment.MiddleCenter;
2655                         
2656                         // MainForm
2657                         AcceptButton = okButton;
2658                         AutoScaleBaseSize = new Size (5, 13);
2659                         CancelButton = cancelButton;
2660                         ClientSize = new Size (248, 205);
2661                         Controls.Add (groupBox1);
2662                         Controls.Add (cancelButton);
2663                         Controls.Add (okButton);
2664                         FormBorderStyle = FormBorderStyle.FixedDialog;
2665                         Text = "New Folder or File";
2666                         groupBox1.ResumeLayout (false);
2667                         ResumeLayout (false);
2668                         
2669                         newNameTextBox.Select ();
2670                 }
2671                 
2672                 public Image IconPictureBoxImage {
2673                         set {
2674                                 iconPictureBox.Image = value;
2675                         }
2676                 }
2677                 
2678                 public string FileName {
2679                         get {
2680                                 return newNameTextBox.Text;
2681                         }
2682                         set {
2683                                 newNameTextBox.Text = value;
2684                         }
2685                 }
2686         }
2687         #endregion
2688         
2689         #region MWFVFS  
2690         internal class MWFVFS
2691         {
2692                 private FileSystem fileSystem;
2693                 
2694                 private int platform = (int) Environment.OSVersion.Platform;
2695                 
2696                 public static readonly string DesktopPrefix = "Desktop://";
2697                 public static readonly string PersonalPrefix = "Personal://";
2698                 public static readonly string MyComputerPrefix = "MyComputer://";
2699                 public static readonly string RecentlyUsedPrefix = "RecentlyUsed://";
2700                 public static readonly string MyNetworkPrefix = "MyNetwork://";
2701                 public static readonly string MyComputerPersonalPrefix = "MyComputerPersonal://";
2702                 
2703                 public static Hashtable MyComputerDevicesPrefix = new Hashtable ();
2704                 
2705                 public delegate void UpdateDelegate (ArrayList folders, ArrayList files);
2706                 private UpdateDelegate updateDelegate;
2707                 private Control calling_control;
2708                 
2709                 private ThreadStart get_folder_content_thread_start;
2710                 private Thread worker;
2711                 private WorkerThread workerThread = null;
2712                 private StringCollection the_filters;
2713                 
2714                 public MWFVFS ()
2715                 {
2716                         if ((platform == 4) || (platform == 128)) {
2717                                 fileSystem = new UnixFileSystem ();
2718                         } else {
2719                                 fileSystem = new WinFileSystem ();
2720                         }
2721                 }
2722                 
2723                 public FSEntry ChangeDirectory (string folder)
2724                 {
2725                         return fileSystem.ChangeDirectory (folder);
2726                 }
2727                 
2728                 public void GetFolderContent ()
2729                 {
2730                         GetFolderContent (null);
2731                 }
2732                 
2733                 public void GetFolderContent (StringCollection filters)
2734                 {
2735                         the_filters = filters;
2736
2737                         if (workerThread != null) {
2738                                 workerThread.Stop ();
2739                                 workerThread = null;
2740                         }
2741
2742                         workerThread = new WorkerThread (fileSystem, the_filters, updateDelegate, calling_control);
2743                         
2744                         get_folder_content_thread_start = new ThreadStart (workerThread.GetFolderContentThread);
2745                         worker = new Thread (get_folder_content_thread_start);
2746                         worker.IsBackground = true;
2747                         worker.Start();
2748                 }
2749                 
2750                 internal class WorkerThread
2751                 {
2752                         private FileSystem fileSystem;
2753                         private StringCollection the_filters;
2754                         private UpdateDelegate updateDelegate;
2755                         private Control calling_control;
2756                         private readonly object lockobject = new object ();
2757                         private bool stopped = false;
2758                         
2759                         public WorkerThread (FileSystem fileSystem, StringCollection the_filters, UpdateDelegate updateDelegate, Control calling_control)
2760                         {
2761                                 this.fileSystem = fileSystem;
2762                                 this.the_filters = the_filters;
2763                                 this.updateDelegate = updateDelegate;
2764                                 this.calling_control = calling_control;
2765                         }
2766                         
2767                         public void GetFolderContentThread()
2768                         {
2769                                 ArrayList folders;
2770                                 ArrayList files;
2771                                 
2772                                 fileSystem.GetFolderContent (the_filters, out folders, out files);
2773                                 
2774                                 if (stopped)
2775                                         return;
2776                                 
2777                                 if (updateDelegate != null) {
2778                                         lock (this) {
2779                                                 object[] objectArray = new object[2];
2780                                                 
2781                                                 objectArray[0] = folders;
2782                                                 objectArray[1] = files;
2783                                                 
2784                                                 calling_control.BeginInvoke (updateDelegate, objectArray);
2785                                         }
2786                                 }
2787                         }
2788                         
2789                         public void Stop ()
2790                         {
2791                                 lock (lockobject) {
2792                                         stopped = true;
2793                                 }
2794                         }
2795                 }
2796                 
2797                 public ArrayList GetFoldersOnly ()
2798                 {
2799                         return fileSystem.GetFoldersOnly ();
2800                 }
2801                 
2802                 public void WriteRecentlyUsedFiles (string filename)
2803                 {
2804                         fileSystem.WriteRecentlyUsedFiles (filename);
2805                 }
2806                 
2807                 public ArrayList GetRecentlyUsedFiles ()
2808                 {
2809                         return fileSystem.GetRecentlyUsedFiles ();
2810                 }
2811                 
2812                 public ArrayList GetMyComputerContent ()
2813                 {
2814                         return fileSystem.GetMyComputerContent ();
2815                 }
2816                 
2817                 public ArrayList GetMyNetworkContent ()
2818                 {
2819                         return fileSystem.GetMyNetworkContent ();
2820                 }
2821                 
2822                 public bool CreateFolder (string new_folder)
2823                 {
2824                         try {
2825                                 if (Directory.Exists (new_folder)) {
2826                                         string message = "Folder \"" + new_folder + "\" already exists.";
2827                                         MessageBox.Show (message, new_folder, MessageBoxButtons.OK, MessageBoxIcon.Warning);
2828                                         return false;
2829                                 } else
2830                                         Directory.CreateDirectory (new_folder);
2831                         } catch (Exception e) {
2832                                 MessageBox.Show (e.Message, new_folder, MessageBoxButtons.OK, MessageBoxIcon.Error);
2833                                 return false;
2834                         }
2835                         
2836                         return true;
2837                 }
2838                 
2839                 public string GetParent ()
2840                 {
2841                         return fileSystem.GetParent ();
2842                 }
2843                 
2844                 public void RegisterUpdateDelegate(UpdateDelegate updateDelegate, Control control)
2845                 {
2846                         this.updateDelegate = updateDelegate;
2847                         calling_control = control;
2848                 }
2849         }
2850         #endregion
2851         
2852         #region FileSystem
2853         internal abstract class FileSystem
2854         {
2855                 protected string currentTopFolder = "";
2856                 protected FSEntry currentFolderFSEntry = null;
2857                 protected FSEntry currentTopFolderFSEntry = null;
2858                 
2859                 public FSEntry ChangeDirectory (string folder)
2860                 {
2861                         if (folder == MWFVFS.DesktopPrefix) {
2862                                 currentTopFolder = MWFVFS.DesktopPrefix;
2863                                 currentTopFolderFSEntry = currentFolderFSEntry = GetDesktopFSEntry ();
2864                         } else
2865                         if (folder == MWFVFS.PersonalPrefix) {
2866                                 currentTopFolder = MWFVFS.PersonalPrefix;
2867                                 currentTopFolderFSEntry = currentFolderFSEntry = GetPersonalFSEntry ();
2868                         } else
2869                         if (folder == MWFVFS.MyComputerPersonalPrefix) {
2870                                 currentTopFolder = MWFVFS.MyComputerPersonalPrefix;
2871                                 currentTopFolderFSEntry = currentFolderFSEntry = GetMyComputerPersonalFSEntry ();
2872                         } else
2873                         if (folder == MWFVFS.RecentlyUsedPrefix) {
2874                                 currentTopFolder = MWFVFS.RecentlyUsedPrefix;
2875                                 currentTopFolderFSEntry = currentFolderFSEntry = GetRecentlyUsedFSEntry ();
2876                         } else
2877                         if (folder == MWFVFS.MyComputerPrefix) {
2878                                 currentTopFolder = MWFVFS.MyComputerPrefix;
2879                                 currentTopFolderFSEntry = currentFolderFSEntry = GetMyComputerFSEntry ();
2880                         } else
2881                         if (folder == MWFVFS.MyNetworkPrefix) {
2882                                 currentTopFolder = MWFVFS.MyNetworkPrefix;
2883                                 currentTopFolderFSEntry = currentFolderFSEntry = GetMyNetworkFSEntry ();
2884                         } else {
2885                                 bool found = false;
2886                                 
2887                                 foreach (DictionaryEntry entry in MWFVFS.MyComputerDevicesPrefix) {
2888                                         FSEntry fsEntry = entry.Value as FSEntry;
2889                                         if (folder == fsEntry.FullName) {
2890                                                 currentTopFolder = entry.Key as string;
2891                                                 currentTopFolderFSEntry = currentFolderFSEntry = fsEntry;
2892                                                 found = true;
2893                                                 break;
2894                                         }
2895                                 }
2896                                 
2897                                 if (!found) {
2898                                         currentFolderFSEntry = GetDirectoryFSEntry (new DirectoryInfo (folder), currentTopFolderFSEntry);
2899                                 }
2900                         }
2901                         
2902                         return currentFolderFSEntry;
2903                 }
2904                 
2905                 public string GetParent ()
2906                 {
2907                         return currentFolderFSEntry.Parent;
2908                 }
2909                 
2910                 // directories_out and files_out contain FSEntry objects
2911                 public void GetFolderContent (StringCollection filters, out ArrayList directories_out, out ArrayList files_out)
2912                 {
2913                         directories_out = new ArrayList ();
2914                         files_out = new ArrayList ();
2915                         
2916                         if (currentFolderFSEntry.FullName == MWFVFS.DesktopPrefix) {
2917                                 FSEntry personalFSEntry = GetPersonalFSEntry ();
2918                                 
2919                                 directories_out.Add (personalFSEntry);
2920                                 
2921                                 FSEntry myComputerFSEntry = GetMyComputerFSEntry ();
2922                                 
2923                                 directories_out.Add (myComputerFSEntry);
2924                                 
2925                                 FSEntry myNetworkFSEntry = GetMyNetworkFSEntry ();
2926                                 
2927                                 directories_out.Add (myNetworkFSEntry);
2928                                 
2929                                 ArrayList d_out = null;
2930                                 ArrayList f_out = null;
2931                                 GetNormalFolderContent (ThemeEngine.Current.Places (UIIcon.PlacesDesktop), filters, out d_out, out f_out);
2932                                 directories_out.AddRange (d_out);
2933                                 files_out.AddRange (f_out);
2934                                 
2935                         } else
2936                         if (currentFolderFSEntry.FullName == MWFVFS.RecentlyUsedPrefix) {
2937                                 files_out = GetRecentlyUsedFiles ();
2938                         } else
2939                         if (currentFolderFSEntry.FullName == MWFVFS.MyComputerPrefix) {
2940                                 directories_out.AddRange (GetMyComputerContent ());
2941                         } else
2942                         if (currentFolderFSEntry.FullName == MWFVFS.PersonalPrefix || currentFolderFSEntry.FullName == MWFVFS.MyComputerPersonalPrefix) {
2943                                 ArrayList d_out = null;
2944                                 ArrayList f_out = null;
2945                                 GetNormalFolderContent (ThemeEngine.Current.Places (UIIcon.PlacesPersonal), filters, out d_out, out f_out);
2946                                 directories_out.AddRange (d_out);
2947                                 files_out.AddRange (f_out);
2948                         } else
2949                         if (currentFolderFSEntry.FullName == MWFVFS.MyNetworkPrefix) {
2950                                 directories_out.AddRange (GetMyNetworkContent ());
2951                         } else {
2952                                 GetNormalFolderContent (currentFolderFSEntry.FullName, filters, out directories_out, out files_out);
2953                         }
2954                 }
2955                 
2956                 public ArrayList GetFoldersOnly ()
2957                 {
2958                         ArrayList directories_out = new ArrayList ();
2959                         
2960                         if (currentFolderFSEntry.FullName == MWFVFS.DesktopPrefix) {
2961                                 FSEntry personalFSEntry = GetPersonalFSEntry ();
2962                                 
2963                                 directories_out.Add (personalFSEntry);
2964                                 
2965                                 FSEntry myComputerFSEntry = GetMyComputerFSEntry ();
2966                                 
2967                                 directories_out.Add (myComputerFSEntry);
2968                                 
2969                                 FSEntry myNetworkFSEntry = GetMyNetworkFSEntry ();
2970                                 
2971                                 directories_out.Add (myNetworkFSEntry);
2972                                 
2973                                 ArrayList d_out = GetNormalFolders (ThemeEngine.Current.Places (UIIcon.PlacesDesktop));
2974                                 directories_out.AddRange (d_out);
2975                                 
2976                         } else
2977                         if (currentFolderFSEntry.FullName == MWFVFS.RecentlyUsedPrefix) {
2978                                 //files_out = GetRecentlyUsedFiles ();
2979                         } else
2980                         if (currentFolderFSEntry.FullName == MWFVFS.MyComputerPrefix) {
2981                                 directories_out.AddRange (GetMyComputerContent ());
2982                         } else
2983                         if (currentFolderFSEntry.FullName == MWFVFS.PersonalPrefix || currentFolderFSEntry.FullName == MWFVFS.MyComputerPersonalPrefix) {
2984                                 ArrayList d_out = GetNormalFolders (ThemeEngine.Current.Places (UIIcon.PlacesPersonal));
2985                                 directories_out.AddRange (d_out);
2986                         } else
2987                         if (currentFolderFSEntry.FullName == MWFVFS.MyNetworkPrefix) {
2988                                 directories_out.AddRange (GetMyNetworkContent ());
2989                         } else {
2990                                 directories_out = GetNormalFolders (currentFolderFSEntry.FullName);
2991                         }
2992                         return directories_out;
2993                 }
2994                 
2995                 protected void GetNormalFolderContent (string from_folder, StringCollection filters, out ArrayList directories_out, out ArrayList files_out)
2996                 {
2997                         DirectoryInfo dirinfo = new DirectoryInfo (from_folder);
2998                         
2999                         directories_out = new ArrayList ();
3000                         
3001                         DirectoryInfo[] dirs = dirinfo.GetDirectories ();
3002                         
3003                         for (int i = 0; i < dirs.Length; i++) {
3004                                 directories_out.Add (GetDirectoryFSEntry (dirs [i], currentTopFolderFSEntry));
3005                         }
3006                         
3007                         files_out = new ArrayList ();
3008                         
3009                         ArrayList files = new ArrayList ();
3010                         
3011                         if (filters == null) {
3012                                 files.AddRange (dirinfo.GetFiles ());
3013                         } else {
3014                                 foreach (string s in filters)
3015                                         files.AddRange (dirinfo.GetFiles (s));
3016                         }
3017                         
3018                         for (int i = 0; i < files.Count; i++) {
3019                                 files_out.Add (GetFileFSEntry (files [i] as FileInfo));
3020                         }
3021                 }
3022                 
3023                 protected ArrayList GetNormalFolders (string from_folder)
3024                 {
3025                         DirectoryInfo dirinfo = new DirectoryInfo (from_folder);
3026                         
3027                         ArrayList directories_out = new ArrayList ();
3028                         
3029                         DirectoryInfo[] dirs = dirinfo.GetDirectories ();
3030                         
3031                         for (int i = 0; i < dirs.Length; i++) {
3032                                 directories_out.Add (GetDirectoryFSEntry (dirs [i], currentTopFolderFSEntry));
3033                         }
3034                         
3035                         return directories_out;
3036                 }
3037                 
3038                 protected virtual FSEntry GetDirectoryFSEntry (DirectoryInfo dirinfo, FSEntry topFolderFSEntry)
3039                 {
3040                         FSEntry fs = new FSEntry ();
3041                         
3042                         fs.Attributes = dirinfo.Attributes;
3043                         fs.FullName = dirinfo.FullName;
3044                         fs.Name = dirinfo.Name;
3045                         fs.MainTopNode = topFolderFSEntry;
3046                         fs.FileType = FSEntry.FSEntryType.Directory;
3047                         fs.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("inode/directory");
3048                         fs.LastAccessTime = dirinfo.LastAccessTime;
3049                         
3050                         return fs;
3051                 }
3052                 
3053                 protected virtual FSEntry GetFileFSEntry (FileInfo fileinfo)
3054                 {
3055                         FSEntry fs = new FSEntry ();
3056                         
3057                         fs.Attributes = fileinfo.Attributes;
3058                         fs.FullName = fileinfo.FullName;
3059                         fs.Name = fileinfo.Name;
3060                         fs.FileType = FSEntry.FSEntryType.File;
3061                         fs.IconIndex = MimeIconEngine.GetIconIndexForFile (fileinfo.FullName);
3062                         fs.LastAccessTime = fileinfo.LastAccessTime;
3063                         // the following catches broken symbolic links
3064                         if ((int)fs.Attributes != 0)
3065                                 fs.FileSize = fileinfo.Length;
3066                         
3067                         return fs;
3068                 }
3069                 
3070                 
3071                 protected abstract FSEntry GetDesktopFSEntry ();
3072                 
3073                 protected abstract FSEntry GetRecentlyUsedFSEntry ();
3074                 
3075                 protected abstract FSEntry GetPersonalFSEntry ();
3076                 
3077                 protected abstract FSEntry GetMyComputerPersonalFSEntry ();
3078                 
3079                 protected abstract FSEntry GetMyComputerFSEntry ();
3080                 
3081                 protected abstract FSEntry GetMyNetworkFSEntry ();
3082                 
3083                 public abstract void WriteRecentlyUsedFiles (string fileToAdd);
3084                 
3085                 public abstract ArrayList GetRecentlyUsedFiles ();
3086                 
3087                 public abstract ArrayList GetMyComputerContent ();
3088                 
3089                 public abstract ArrayList GetMyNetworkContent ();
3090         }
3091         #endregion
3092         
3093         #region UnixFileSystem
3094         internal class UnixFileSystem : FileSystem
3095         {
3096                 private MasterMount masterMount = new MasterMount ();
3097                 private FSEntry desktopFSEntry = null;
3098                 private FSEntry recentlyusedFSEntry = null;
3099                 private FSEntry personalFSEntry = null;
3100                 private FSEntry mycomputerpersonalFSEntry = null;
3101                 private FSEntry mycomputerFSEntry = null;
3102                 private FSEntry mynetworkFSEntry = null;
3103                 
3104                 public UnixFileSystem ()
3105                 {
3106                         desktopFSEntry = new FSEntry ();
3107                         
3108                         desktopFSEntry.Attributes = FileAttributes.Directory;
3109                         desktopFSEntry.FullName = MWFVFS.DesktopPrefix;
3110                         desktopFSEntry.Name = "Desktop";
3111                         desktopFSEntry.RealName = ThemeEngine.Current.Places (UIIcon.PlacesDesktop);
3112                         desktopFSEntry.FileType = FSEntry.FSEntryType.Directory;
3113                         desktopFSEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("deskop/desktop");
3114                         desktopFSEntry.LastAccessTime = DateTime.Now;
3115                         
3116                         recentlyusedFSEntry = new FSEntry ();
3117                         
3118                         recentlyusedFSEntry.Attributes = FileAttributes.Directory;
3119                         recentlyusedFSEntry.FullName = MWFVFS.RecentlyUsedPrefix;
3120                         recentlyusedFSEntry.Name = "Recently Used";
3121                         recentlyusedFSEntry.FileType = FSEntry.FSEntryType.Directory;
3122                         recentlyusedFSEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("recently/recently");
3123                         recentlyusedFSEntry.LastAccessTime = DateTime.Now;
3124                         
3125                         personalFSEntry = new FSEntry ();
3126                         
3127                         personalFSEntry.Attributes = FileAttributes.Directory;
3128                         personalFSEntry.FullName = MWFVFS.PersonalPrefix;
3129                         personalFSEntry.Name = "Personal";
3130                         personalFSEntry.MainTopNode = GetDesktopFSEntry ();
3131                         personalFSEntry.RealName = ThemeEngine.Current.Places (UIIcon.PlacesPersonal);
3132                         personalFSEntry.FileType = FSEntry.FSEntryType.Directory;
3133                         personalFSEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("directory/home");
3134                         personalFSEntry.LastAccessTime = DateTime.Now;
3135                         
3136                         mycomputerpersonalFSEntry = new FSEntry ();
3137                         
3138                         mycomputerpersonalFSEntry.Attributes = FileAttributes.Directory;
3139                         mycomputerpersonalFSEntry.FullName = MWFVFS.MyComputerPersonalPrefix;
3140                         mycomputerpersonalFSEntry.Name = "Personal";
3141                         mycomputerpersonalFSEntry.MainTopNode = GetMyComputerFSEntry ();
3142                         mycomputerpersonalFSEntry.RealName = ThemeEngine.Current.Places (UIIcon.PlacesPersonal);
3143                         mycomputerpersonalFSEntry.FileType = FSEntry.FSEntryType.Directory;
3144                         mycomputerpersonalFSEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("directory/home");
3145                         mycomputerpersonalFSEntry.LastAccessTime = DateTime.Now;
3146                         
3147                         mycomputerFSEntry = new FSEntry ();
3148                         
3149                         mycomputerFSEntry.Attributes = FileAttributes.Directory;
3150                         mycomputerFSEntry.FullName = MWFVFS.MyComputerPrefix;
3151                         mycomputerFSEntry.Name = "My Computer";
3152                         mycomputerFSEntry.MainTopNode = GetDesktopFSEntry ();
3153                         mycomputerFSEntry.FileType = FSEntry.FSEntryType.Directory;
3154                         mycomputerFSEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("workplace/workplace");
3155                         mycomputerFSEntry.LastAccessTime = DateTime.Now;
3156                         
3157                         mynetworkFSEntry = new FSEntry ();
3158                         
3159                         mynetworkFSEntry.Attributes = FileAttributes.Directory;
3160                         mynetworkFSEntry.FullName = MWFVFS.MyNetworkPrefix;
3161                         mynetworkFSEntry.Name = "My Network";
3162                         mynetworkFSEntry.MainTopNode = GetDesktopFSEntry ();
3163                         mynetworkFSEntry.FileType = FSEntry.FSEntryType.Directory;
3164                         mynetworkFSEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("network/network");
3165                         mynetworkFSEntry.LastAccessTime = DateTime.Now;
3166                 }
3167                 
3168                 public override void WriteRecentlyUsedFiles (string fileToAdd)
3169                 {
3170                         string personal_folder = ThemeEngine.Current.Places (UIIcon.PlacesPersonal);
3171                         string recently_used_path = Path.Combine (personal_folder, ".recently-used");
3172                         
3173                         if (File.Exists (recently_used_path) && new FileInfo (recently_used_path).Length > 0) {
3174                                 XmlDocument xml_doc = new XmlDocument ();
3175                                 xml_doc.Load (recently_used_path);
3176                                 
3177                                 XmlNode grand_parent_node = xml_doc.SelectSingleNode ("RecentFiles");
3178                                 
3179                                 if (grand_parent_node != null) {
3180                                         // create a new element
3181                                         XmlElement new_recent_item_node = xml_doc.CreateElement ("RecentItem");
3182                                         
3183                                         XmlElement new_child = xml_doc.CreateElement ("URI");
3184                                         UriBuilder ub = new UriBuilder ();
3185                                         ub.Path = fileToAdd;
3186                                         ub.Host = null;
3187                                         ub.Scheme = "file";
3188                                         XmlText new_text_child = xml_doc.CreateTextNode (ub.ToString ());
3189                                         new_child.AppendChild (new_text_child);
3190                                         
3191                                         new_recent_item_node.AppendChild (new_child);
3192                                         
3193                                         new_child = xml_doc.CreateElement ("Mime-Type");
3194                                         new_text_child = xml_doc.CreateTextNode (Mime.GetMimeTypeForFile (fileToAdd));
3195                                         new_child.AppendChild (new_text_child);
3196                                         
3197                                         new_recent_item_node.AppendChild (new_child);
3198                                         
3199                                         new_child = xml_doc.CreateElement ("Timestamp");
3200                                         long seconds = (long)(DateTime.UtcNow - new DateTime (1970, 1, 1)).TotalSeconds;
3201                                         new_text_child = xml_doc.CreateTextNode (seconds.ToString ());
3202                                         new_child.AppendChild (new_text_child);
3203                                         
3204                                         new_recent_item_node.AppendChild (new_child);
3205                                         
3206                                         new_child = xml_doc.CreateElement ("Groups");
3207                                         
3208                                         new_recent_item_node.AppendChild (new_child);
3209                                         
3210                                         // now search the nodes in grand_parent_node for another instance of the new uri and if found remove it
3211                                         // so that the new node is the first one
3212                                         foreach (XmlNode n in grand_parent_node.ChildNodes) {
3213                                                 XmlNode uri_node = n.SelectSingleNode ("URI");
3214                                                 if (uri_node != null) {
3215                                                         XmlNode uri_node_child = uri_node.FirstChild;
3216                                                         if (uri_node_child is XmlText)
3217                                                                 if (ub.ToString () == ((XmlText)uri_node_child).Data) {
3218                                                                         grand_parent_node.RemoveChild (n);
3219                                                                         break;
3220                                                                 }
3221                                                 }
3222                                         }
3223                                         
3224                                         // prepend the new recent item to the grand parent node list
3225                                         grand_parent_node.PrependChild (new_recent_item_node);
3226                                         
3227                                         // limit the # of RecentItems to 10
3228                                         if (grand_parent_node.ChildNodes.Count > 10) {
3229                                                 while (grand_parent_node.ChildNodes.Count > 10)
3230                                                         grand_parent_node.RemoveChild (grand_parent_node.LastChild);
3231                                         }
3232                                         
3233                                         try {
3234                                                 xml_doc.Save (recently_used_path);
3235                                         } catch (Exception) {
3236                                         }
3237                                 }
3238                         } else {
3239                                 XmlDocument xml_doc = new XmlDocument ();
3240                                 xml_doc.AppendChild (xml_doc.CreateXmlDeclaration ("1.0", "", ""));
3241                                 
3242                                 XmlElement recentFiles_element = xml_doc.CreateElement ("RecentFiles");
3243                                 
3244                                 XmlElement new_recent_item_node = xml_doc.CreateElement ("RecentItem");
3245                                 
3246                                 XmlElement new_child = xml_doc.CreateElement ("URI");
3247                                 UriBuilder ub = new UriBuilder ();
3248                                 ub.Path = fileToAdd;
3249                                 ub.Host = null;
3250                                 ub.Scheme = "file";
3251                                 XmlText new_text_child = xml_doc.CreateTextNode (ub.ToString ());
3252                                 new_child.AppendChild (new_text_child);
3253                                 
3254                                 new_recent_item_node.AppendChild (new_child);
3255                                 
3256                                 new_child = xml_doc.CreateElement ("Mime-Type");
3257                                 new_text_child = xml_doc.CreateTextNode (Mime.GetMimeTypeForFile (fileToAdd));
3258                                 new_child.AppendChild (new_text_child);
3259                                 
3260                                 new_recent_item_node.AppendChild (new_child);
3261                                 
3262                                 new_child = xml_doc.CreateElement ("Timestamp");
3263                                 long seconds = (long)(DateTime.UtcNow - new DateTime (1970, 1, 1)).TotalSeconds;
3264                                 new_text_child = xml_doc.CreateTextNode (seconds.ToString ());
3265                                 new_child.AppendChild (new_text_child);
3266                                 
3267                                 new_recent_item_node.AppendChild (new_child);
3268                                 
3269                                 new_child = xml_doc.CreateElement ("Groups");
3270                                 
3271                                 new_recent_item_node.AppendChild (new_child);
3272                                 
3273                                 recentFiles_element.AppendChild (new_recent_item_node);
3274                                 
3275                                 xml_doc.AppendChild (recentFiles_element);
3276                                 
3277                                 try {
3278                                         xml_doc.Save (recently_used_path);
3279                                 } catch (Exception) {
3280                                 }
3281                         }
3282                 }
3283                 
3284                 // return an ArrayList with FSEntry objects
3285                 public override ArrayList GetRecentlyUsedFiles ()
3286                 {
3287                         // check for GNOME and KDE
3288                         string personal_folder = ThemeEngine.Current.Places (UIIcon.PlacesPersonal);
3289                         string recently_used_path = Path.Combine (personal_folder, ".recently-used");
3290                         
3291                         ArrayList files_al = new ArrayList ();
3292                         
3293                         // GNOME
3294                         if (File.Exists (recently_used_path)) {
3295                                 try {
3296                                         XmlTextReader xtr = new XmlTextReader (recently_used_path);
3297                                         while (xtr.Read ()) {
3298                                                 if (xtr.NodeType == XmlNodeType.Element && xtr.Name.ToUpper () == "URI") {
3299                                                         xtr.Read ();
3300                                                         Uri uri = new Uri (xtr.Value);
3301                                                         if (!files_al.Contains (uri.LocalPath))
3302                                                                 if (File.Exists (uri.LocalPath))
3303                                                                         files_al.Add (GetFileFSEntry (new FileInfo (uri.LocalPath)));
3304                                                 }
3305                                         }
3306                                         xtr.Close ();
3307                                 } catch (Exception) {
3308                                         
3309                                 }
3310                         }
3311                         
3312                         // KDE
3313                         string full_kde_recent_document_dir = personal_folder + "/.kde/share/apps/RecentDocuments";
3314                         
3315                         if (Directory.Exists (full_kde_recent_document_dir)) {
3316                                 string[] files = Directory.GetFiles (full_kde_recent_document_dir, "*.desktop");
3317                                 
3318                                 foreach (string file_name in files) {
3319                                         StreamReader sr = new StreamReader (file_name);
3320                                         
3321                                         string line = sr.ReadLine ();
3322                                         
3323                                         while (line != null) {
3324                                                 line = line.Trim ();
3325                                                 
3326                                                 if (line.StartsWith ("URL=")) {
3327                                                         line = line.Replace ("URL=", "");
3328                                                         line = line.Replace ("$HOME", personal_folder);
3329                                                         
3330                                                         Uri uri = new Uri (line);
3331                                                         if (!files_al.Contains (uri.LocalPath))
3332                                                                 if (File.Exists (uri.LocalPath))
3333                                                                         files_al.Add (GetFileFSEntry (new FileInfo (uri.LocalPath)));
3334                                                         break;
3335                                                 }
3336                                                 
3337                                                 line = sr.ReadLine ();
3338                                         }
3339                                         
3340                                         sr.Close ();
3341                                 }
3342                         }
3343                         
3344                         
3345                         return files_al;
3346                 }
3347                 
3348                 // return an ArrayList with FSEntry objects
3349                 public override ArrayList GetMyComputerContent ()
3350                 {
3351                         ArrayList my_computer_content_arraylist = new ArrayList ();
3352                         
3353                         if (masterMount.ProcMountAvailable) {
3354                                 masterMount.GetMounts ();
3355                                 
3356                                 foreach (MasterMount.Mount mount in masterMount.Block_devices) {
3357                                         FSEntry fsEntry = new FSEntry ();
3358                                         fsEntry.FileType = FSEntry.FSEntryType.Device;
3359                                         
3360                                         fsEntry.FullName = mount.mount_point;
3361                                         
3362                                         fsEntry.Name = "HDD (" +  mount.fsType + ", " + mount.device_short + ")";
3363                                         
3364                                         fsEntry.FsType = mount.fsType;
3365                                         fsEntry.DeviceShort = mount.device_short;
3366                                         
3367                                         fsEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("harddisk/harddisk");
3368                                         
3369                                         fsEntry.Attributes = FileAttributes.Directory;
3370                                         
3371                                         fsEntry.MainTopNode = GetMyComputerFSEntry ();
3372                                         
3373                                         my_computer_content_arraylist.Add (fsEntry);
3374                                         
3375                                         if (!MWFVFS.MyComputerDevicesPrefix.Contains (fsEntry.FullName + "://"))
3376                                                 MWFVFS.MyComputerDevicesPrefix.Add (fsEntry.FullName + "://", fsEntry);
3377                                 }
3378                                 
3379                                 foreach (MasterMount.Mount mount in masterMount.Removable_devices) {
3380                                         FSEntry fsEntry = new FSEntry ();
3381                                         fsEntry.FileType = FSEntry.FSEntryType.RemovableDevice;
3382                                         
3383                                         fsEntry.FullName = mount.mount_point;
3384                                         
3385                                         bool is_dvd_cdrom = mount.fsType == MasterMount.FsTypes.usbfs ? false : true;
3386                                         string type_name = is_dvd_cdrom ? "DVD/CD-Rom" : "USB";
3387                                         string mime_type = is_dvd_cdrom ? "cdrom/cdrom" : "removable/removable";
3388                                         
3389                                         fsEntry.Name = type_name +" (" + mount.device_short + ")";
3390                                         
3391                                         fsEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType (mime_type);
3392                                         
3393                                         fsEntry.FsType = mount.fsType;
3394                                         fsEntry.DeviceShort = mount.device_short;
3395                                         
3396                                         fsEntry.Attributes = FileAttributes.Directory;
3397                                         
3398                                         fsEntry.MainTopNode = GetMyComputerFSEntry ();
3399                                         
3400                                         my_computer_content_arraylist.Add (fsEntry);
3401                                         
3402                                         string contain_string = fsEntry.FullName + "://";
3403                                         if (!MWFVFS.MyComputerDevicesPrefix.Contains (contain_string))
3404                                                 MWFVFS.MyComputerDevicesPrefix.Add (contain_string, fsEntry);
3405                                 }
3406                         }
3407                         
3408                         my_computer_content_arraylist.Add (GetMyComputerPersonalFSEntry ());
3409                         
3410                         return my_computer_content_arraylist;
3411                 }
3412                 
3413                 public override ArrayList GetMyNetworkContent ()
3414                 {
3415                         ArrayList fsEntries = new ArrayList ();
3416                         
3417                         foreach (MasterMount.Mount mount in masterMount.Network_devices) {
3418                                 FSEntry fsEntry = new FSEntry ();
3419                                 fsEntry.FileType = FSEntry.FSEntryType.Network;
3420                                 
3421                                 fsEntry.FullName = mount.mount_point;
3422                                 
3423                                 fsEntry.FsType = mount.fsType;
3424                                 fsEntry.DeviceShort = mount.device_short;
3425                                 
3426                                 fsEntry.Name = "Network (" + mount.fsType + ", " + mount.device_short + ")";
3427                                 
3428                                 switch (mount.fsType) {
3429                                         case MasterMount.FsTypes.nfs:
3430                                                 fsEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("nfs/nfs");
3431                                                 break;
3432                                         case MasterMount.FsTypes.smbfs:
3433                                                 fsEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("smb/smb");
3434                                                 break;
3435                                         case MasterMount.FsTypes.ncpfs:
3436                                                 fsEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("network/network");
3437                                                 break;
3438                                         case MasterMount.FsTypes.cifs:
3439                                                 fsEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("network/network");
3440                                                 break;
3441                                         default:
3442                                                 break;
3443                                 }
3444                                 
3445                                 fsEntry.Attributes = FileAttributes.Directory;
3446                                 
3447                                 fsEntry.MainTopNode = GetMyNetworkFSEntry ();
3448                                 
3449                                 fsEntries.Add (fsEntry);
3450                         }
3451                         return fsEntries;
3452                 }
3453                 
3454                 protected override FSEntry GetDesktopFSEntry ()
3455                 {
3456                         return desktopFSEntry;
3457                 }
3458                 
3459                 protected override FSEntry GetRecentlyUsedFSEntry ()
3460                 {
3461                         return recentlyusedFSEntry;
3462                 }
3463                 
3464                 protected override FSEntry GetPersonalFSEntry ()
3465                 {
3466                         return personalFSEntry;
3467                 }
3468                 
3469                 protected override FSEntry GetMyComputerPersonalFSEntry ()
3470                 {
3471                         return mycomputerpersonalFSEntry;
3472                 }
3473                 
3474                 protected override FSEntry GetMyComputerFSEntry ()
3475                 {
3476                         return mycomputerFSEntry;
3477                 }
3478                 
3479                 protected override FSEntry GetMyNetworkFSEntry ()
3480                 {
3481                         return mynetworkFSEntry;
3482                 }
3483         }
3484         #endregion
3485         
3486         #region WinFileSystem
3487         internal class WinFileSystem : FileSystem
3488         {
3489                 private FSEntry desktopFSEntry = null;
3490                 private FSEntry recentlyusedFSEntry = null;
3491                 private FSEntry personalFSEntry = null;
3492                 private FSEntry mycomputerpersonalFSEntry = null;
3493                 private FSEntry mycomputerFSEntry = null;
3494                 private FSEntry mynetworkFSEntry = null;
3495                 
3496                 public WinFileSystem ()
3497                 {
3498                         desktopFSEntry = new FSEntry ();
3499                         
3500                         desktopFSEntry.Attributes = FileAttributes.Directory;
3501                         desktopFSEntry.FullName = MWFVFS.DesktopPrefix;
3502                         desktopFSEntry.Name = "Desktop";
3503                         desktopFSEntry.RealName = ThemeEngine.Current.Places (UIIcon.PlacesDesktop);
3504                         desktopFSEntry.FileType = FSEntry.FSEntryType.Directory;
3505                         desktopFSEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("deskop/desktop");
3506                         desktopFSEntry.LastAccessTime = DateTime.Now;
3507                         
3508                         recentlyusedFSEntry = new FSEntry ();
3509                         
3510                         recentlyusedFSEntry.Attributes = FileAttributes.Directory;
3511                         recentlyusedFSEntry.FullName = MWFVFS.RecentlyUsedPrefix;
3512                         recentlyusedFSEntry.RealName = ThemeEngine.Current.Places (UIIcon.PlacesRecentDocuments);
3513                         recentlyusedFSEntry.Name = "Recently Used";
3514                         recentlyusedFSEntry.FileType = FSEntry.FSEntryType.Directory;
3515                         recentlyusedFSEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("recently/recently");
3516                         recentlyusedFSEntry.LastAccessTime = DateTime.Now;
3517                         
3518                         personalFSEntry = new FSEntry ();
3519                         
3520                         personalFSEntry.Attributes = FileAttributes.Directory;
3521                         personalFSEntry.FullName = MWFVFS.PersonalPrefix;
3522                         personalFSEntry.Name = "Personal";
3523                         personalFSEntry.MainTopNode = GetDesktopFSEntry ();
3524                         personalFSEntry.RealName = ThemeEngine.Current.Places (UIIcon.PlacesPersonal);
3525                         personalFSEntry.FileType = FSEntry.FSEntryType.Directory;
3526                         personalFSEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("directory/home");
3527                         personalFSEntry.LastAccessTime = DateTime.Now;
3528                         
3529                         mycomputerpersonalFSEntry = new FSEntry ();
3530                         
3531                         mycomputerpersonalFSEntry.Attributes = FileAttributes.Directory;
3532                         mycomputerpersonalFSEntry.FullName = MWFVFS.MyComputerPersonalPrefix;
3533                         mycomputerpersonalFSEntry.Name = "Personal";
3534                         mycomputerpersonalFSEntry.MainTopNode = GetMyComputerFSEntry ();
3535                         mycomputerpersonalFSEntry.RealName = ThemeEngine.Current.Places (UIIcon.PlacesPersonal);
3536                         mycomputerpersonalFSEntry.FileType = FSEntry.FSEntryType.Directory;
3537                         mycomputerpersonalFSEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("directory/home");
3538                         mycomputerpersonalFSEntry.LastAccessTime = DateTime.Now;
3539                         
3540                         mycomputerFSEntry = new FSEntry ();
3541                         
3542                         mycomputerFSEntry.Attributes = FileAttributes.Directory;
3543                         mycomputerFSEntry.FullName = MWFVFS.MyComputerPrefix;
3544                         mycomputerFSEntry.Name = "My Computer";
3545                         mycomputerFSEntry.MainTopNode = GetDesktopFSEntry ();
3546                         mycomputerFSEntry.FileType = FSEntry.FSEntryType.Directory;
3547                         mycomputerFSEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("workplace/workplace");
3548                         mycomputerFSEntry.LastAccessTime = DateTime.Now;
3549                         
3550                         mynetworkFSEntry = new FSEntry ();
3551                         
3552                         mynetworkFSEntry.Attributes = FileAttributes.Directory;
3553                         mynetworkFSEntry.FullName = MWFVFS.MyNetworkPrefix;
3554                         mynetworkFSEntry.Name = "My Network";
3555                         mynetworkFSEntry.MainTopNode = GetDesktopFSEntry ();
3556                         mynetworkFSEntry.FileType = FSEntry.FSEntryType.Directory;
3557                         mynetworkFSEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("network/network");
3558                         mynetworkFSEntry.LastAccessTime = DateTime.Now;
3559                 }
3560                 
3561                 public override void WriteRecentlyUsedFiles (string fileToAdd)
3562                 {
3563                         // TODO: Implement this method
3564                         // use SHAddToRecentDocs ?
3565                 }
3566                 
3567                 public override ArrayList GetRecentlyUsedFiles ()
3568                 {
3569                         ArrayList al = new ArrayList ();
3570                         
3571                         DirectoryInfo di = new DirectoryInfo (recentlyusedFSEntry.RealName);
3572                         
3573                         FileInfo[] fileinfos = di.GetFiles ();
3574                         
3575                         foreach (FileInfo fi in fileinfos) {
3576                                 al.Add (GetFileFSEntry (fi));
3577                         }
3578                         
3579                         return al;
3580                 }
3581                 
3582                 public override ArrayList GetMyComputerContent ()
3583                 {
3584                         string[] logical_drives = Directory.GetLogicalDrives ();
3585                         
3586                         ArrayList my_computer_content_arraylist = new ArrayList ();
3587                         
3588                         foreach (string drive in logical_drives) {
3589                                 FSEntry fsEntry = new FSEntry ();
3590                                 fsEntry.FileType = FSEntry.FSEntryType.Device;
3591                                 
3592                                 fsEntry.FullName = drive;
3593                                 
3594                                 fsEntry.Name = drive;
3595                                 
3596                                 fsEntry.IconIndex = MimeIconEngine.GetIconIndexForMimeType ("harddisk/harddisk");
3597                                 
3598                                 fsEntry.Attributes = FileAttributes.Directory;
3599                                 
3600                                 fsEntry.MainTopNode = GetMyComputerFSEntry ();
3601                                 
3602                                 my_computer_content_arraylist.Add (fsEntry);
3603                                 
3604                                 string contain_string = fsEntry.FullName + "://";
3605                                 if (!MWFVFS.MyComputerDevicesPrefix.Contains (contain_string))
3606                                         MWFVFS.MyComputerDevicesPrefix.Add (contain_string, fsEntry);
3607                         }
3608                         
3609                         my_computer_content_arraylist.Add (GetMyComputerPersonalFSEntry ());
3610                         
3611                         return my_computer_content_arraylist;
3612                 }
3613                 
3614                 public override ArrayList GetMyNetworkContent ()
3615                 {
3616                         // TODO: Implement this method
3617                         return new ArrayList ();
3618                 }
3619                 protected override FSEntry GetDesktopFSEntry ()
3620                 {
3621                         return desktopFSEntry;
3622                 }
3623                 
3624                 protected override FSEntry GetRecentlyUsedFSEntry ()
3625                 {
3626                         return recentlyusedFSEntry;
3627                 }
3628                 
3629                 protected override FSEntry GetPersonalFSEntry ()
3630                 {
3631                         return personalFSEntry;
3632                 }
3633                 
3634                 protected override FSEntry GetMyComputerPersonalFSEntry ()
3635                 {
3636                         return mycomputerpersonalFSEntry;
3637                 }
3638                 
3639                 protected override FSEntry GetMyComputerFSEntry ()
3640                 {
3641                         return mycomputerFSEntry;
3642                 }
3643                 
3644                 protected override FSEntry GetMyNetworkFSEntry ()
3645                 {
3646                         return mynetworkFSEntry;
3647                 }
3648         }
3649         #endregion
3650         
3651         #region FSEntry
3652         internal class FSEntry
3653         {
3654                 public enum FSEntryType
3655                 {
3656                         Desktop,
3657                         RecentlyUsed,
3658                         MyComputer,
3659                         File,
3660                         Directory,
3661                         Device,
3662                         RemovableDevice,
3663                         Network
3664                 }
3665                 
3666                 private MasterMount.FsTypes fsType;
3667                 private string device_short;
3668                 private string fullName;
3669                 private string name;
3670                 private string realName = null;
3671                 private FileAttributes attributes = FileAttributes.Normal;
3672                 private long fileSize;
3673                 private FSEntryType fileType;
3674                 private DateTime lastAccessTime;
3675                 private FSEntry mainTopNode = null;
3676                 
3677                 private int iconIndex;
3678                 
3679                 private string parent;
3680                 
3681                 public MasterMount.FsTypes FsType {
3682                         set {
3683                                 fsType = value;
3684                         }
3685                         
3686                         get {
3687                                 return fsType;
3688                         }
3689                 }
3690                 
3691                 public string DeviceShort {
3692                         set {
3693                                 device_short = value;
3694                         }
3695                         
3696                         get {
3697                                 return device_short;
3698                         }
3699                 }
3700                 
3701                 public string FullName {
3702                         set {
3703                                 fullName = value;
3704                         }
3705                         
3706                         get {
3707                                 return fullName;
3708                         }
3709                 }
3710                 
3711                 public string Name {
3712                         set {
3713                                 name = value;
3714                         }
3715                         
3716                         get {
3717                                 return name;
3718                         }
3719                 }
3720                 
3721                 public string RealName {
3722                         set {
3723                                 realName = value;
3724                         }
3725                         
3726                         get {
3727                                 return realName;
3728                         }
3729                 }
3730                 
3731                 public FileAttributes Attributes {
3732                         set {
3733                                 attributes = value;
3734                         }
3735                         
3736                         get {
3737                                 return attributes;
3738                         }
3739                 }
3740                 
3741                 public long FileSize {
3742                         set {
3743                                 fileSize = value;
3744                         }
3745                         
3746                         get {
3747                                 return fileSize;
3748                         }
3749                 }
3750                 
3751                 public FSEntryType FileType {
3752                         set {
3753                                 fileType = value;
3754                         }
3755                         
3756                         get {
3757                                 return fileType;
3758                         }
3759                 }
3760                 
3761                 public DateTime LastAccessTime {
3762                         set {
3763                                 lastAccessTime = value;
3764                         }
3765                         
3766                         get {
3767                                 return lastAccessTime;
3768                         }
3769                 }
3770                 
3771                 public int IconIndex {
3772                         set {
3773                                 iconIndex = value;
3774                         }
3775                         
3776                         get {
3777                                 return iconIndex;
3778                         }
3779                 }
3780                 
3781                 public FSEntry MainTopNode {
3782                         set {
3783                                 mainTopNode = value;
3784                         }
3785                         
3786                         get {
3787                                 return mainTopNode;
3788                         }
3789                 }
3790                 
3791                 public string Parent {
3792                         set {
3793                                 parent = value;
3794                         }
3795                         
3796                         get {
3797                                 parent = GetParent ();
3798                                 
3799                                 return parent;
3800                         }
3801                 }
3802                 
3803                 private string GetParent ()
3804                 {
3805                         if (fullName == MWFVFS.PersonalPrefix) {
3806                                 return MWFVFS.DesktopPrefix;
3807                         } else
3808                         if (fullName == MWFVFS.MyComputerPersonalPrefix) {
3809                                 return MWFVFS.MyComputerPrefix;
3810                         } else
3811                         if (fullName == MWFVFS.MyComputerPrefix) {
3812                                 return MWFVFS.DesktopPrefix;
3813                         } else
3814                         if (fullName == MWFVFS.MyNetworkPrefix) {
3815                                 return MWFVFS.DesktopPrefix;
3816                         } else
3817                         if (fullName == MWFVFS.DesktopPrefix) {
3818                                 return null;
3819                         } else
3820                         if (fullName == MWFVFS.RecentlyUsedPrefix) {
3821                                 return null;
3822                         } else {
3823                                 foreach (DictionaryEntry entry in MWFVFS.MyComputerDevicesPrefix) {
3824                                         FSEntry fsEntry = entry.Value as FSEntry;
3825                                         if (fullName == fsEntry.FullName) {
3826                                                 return fsEntry.MainTopNode.FullName;
3827                                         }
3828                                 }
3829                                 
3830                                 DirectoryInfo dirInfo = new DirectoryInfo (fullName);
3831                                 
3832                                 DirectoryInfo dirInfoParent = dirInfo.Parent;
3833                                 
3834                                 if (dirInfoParent != null) {
3835                                         FSEntry fsEntry = MWFVFS.MyComputerDevicesPrefix [dirInfoParent.FullName + "://"] as FSEntry;
3836                                         
3837                                         if (fsEntry != null) {
3838                                                 return fsEntry.FullName;
3839                                         }
3840                                         
3841                                         if (mainTopNode != null) {
3842                                                 if (dirInfoParent.FullName == ThemeEngine.Current.Places (UIIcon.PlacesDesktop) &&
3843                                                     mainTopNode.FullName == MWFVFS.DesktopPrefix) {
3844                                                         return mainTopNode.FullName;
3845                                                 } else
3846                                                 if (dirInfoParent.FullName == ThemeEngine.Current.Places (UIIcon.PlacesPersonal) &&
3847                                                     mainTopNode.FullName == MWFVFS.PersonalPrefix) {
3848                                                         return mainTopNode.FullName;
3849                                                 } else
3850                                                 if (dirInfoParent.FullName == ThemeEngine.Current.Places (UIIcon.PlacesPersonal) &&
3851                                                     mainTopNode.FullName == MWFVFS.MyComputerPersonalPrefix) {
3852                                                         return mainTopNode.FullName;
3853                                                 }
3854                                         }
3855                                         
3856                                         return dirInfoParent.FullName;
3857                                 }
3858                         }
3859                         
3860                         return null;
3861                 }
3862         }
3863         #endregion
3864         
3865         #region MasterMount
3866         // Alexsantas little *nix helper
3867         internal class MasterMount
3868         {
3869                 // add more...
3870                 internal enum FsTypes
3871                 {
3872                         none,
3873                         ext2,
3874                         ext3,
3875                         hpfs,
3876                         iso9660,
3877                         jfs,
3878                         minix,
3879                         msdos,
3880                         ntfs,
3881                         reiserfs,
3882                         ufs,
3883                         umsdos,
3884                         vfat,
3885                         sysv,
3886                         xfs,
3887                         ncpfs,
3888                         nfs,
3889                         smbfs,
3890                         usbfs,
3891                         cifs
3892                 }
3893                 
3894                 internal struct Mount
3895                 {
3896                         public string device_or_filesystem;
3897                         public string device_short;
3898                         public string mount_point;
3899                         public FsTypes fsType;
3900                 }
3901                 
3902                 bool proc_mount_available = false;
3903                 
3904                 ArrayList block_devices = new ArrayList ();
3905                 ArrayList network_devices = new ArrayList ();
3906                 ArrayList removable_devices = new ArrayList ();
3907                 
3908                 private int platform = (int) Environment.OSVersion.Platform;
3909                 private MountComparer mountComparer = new MountComparer ();
3910                 
3911                 public MasterMount ()
3912                 {
3913                         // maybe check if the current user can access /proc/mounts
3914                         if ((platform == 4) || (platform == 128))
3915                                 if (File.Exists ("/proc/mounts"))
3916                                         proc_mount_available = true;
3917                 }
3918                 
3919                 public ArrayList Block_devices {
3920                         get {
3921                                 return block_devices;
3922                         }
3923                 }
3924                 
3925                 public ArrayList Network_devices {
3926                         get {
3927                                 return network_devices;
3928                         }
3929                 }
3930                 
3931                 public ArrayList Removable_devices {
3932                         get {
3933                                 return removable_devices;
3934                         }
3935                 }
3936                 
3937                 public bool ProcMountAvailable {
3938                         get {
3939                                 return proc_mount_available;
3940                         }
3941                 }
3942                 
3943                 public void GetMounts ()
3944                 {
3945                         if (!proc_mount_available)
3946                                 return;
3947                         
3948                         block_devices.Clear ();
3949                         network_devices.Clear ();
3950                         removable_devices.Clear ();
3951                         
3952                         try {
3953                                 StreamReader sr = new StreamReader ("/proc/mounts");
3954                                 
3955                                 string line = sr.ReadLine ();
3956                                 
3957                                 ArrayList lines = new ArrayList ();
3958                                 while (line != null) {
3959                                         if (lines.IndexOf (line) == -1) { // Avoid duplicates
3960                                                 ProcessProcMountLine (line);
3961                                                 lines.Add (line);
3962                                         }
3963                                         line = sr.ReadLine ();
3964                                 }
3965                                 
3966                                 sr.Close ();
3967                                 
3968                                 block_devices.Sort (mountComparer);
3969                                 network_devices.Sort (mountComparer);
3970                                 removable_devices.Sort (mountComparer);
3971                         } catch {
3972                                 // bla
3973                         }
3974                 }
3975                 
3976                 private void ProcessProcMountLine (string line)
3977                 {
3978                         string[] split = line.Split (new char [] {' '});
3979                         
3980                         if (split != null && split.Length > 0) {
3981                                 Mount mount = new Mount ();
3982                                 
3983                                 if (split [0].StartsWith ("/dev/"))
3984                                         mount.device_short = split [0].Replace ("/dev/", "");
3985                                 else 
3986                                         mount.device_short = split [0];
3987                                 
3988                                 mount.device_or_filesystem = split [0];
3989                                 mount.mount_point = split [1];
3990                                 
3991                                 // TODO: other removable devices, floppy
3992                                 // ssh
3993                                 
3994                                 // network mount
3995                                 if (split [2] == "nfs") {
3996                                         mount.fsType = FsTypes.nfs;
3997                                         network_devices.Add (mount);
3998                                 } else if (split [2] == "smbfs") {
3999                                         mount.fsType = FsTypes.smbfs;
4000                                         network_devices.Add (mount);
4001                                 } else if (split [2] == "cifs") {
4002                                         mount.fsType = FsTypes.cifs;
4003                                         network_devices.Add (mount);
4004                                 } else if (split [2] == "ncpfs") {
4005                                         mount.fsType = FsTypes.ncpfs;
4006                                         network_devices.Add (mount);
4007                                         
4008                                 } else if (split [2] == "iso9660") { //cdrom
4009                                         mount.fsType = FsTypes.iso9660;
4010                                         removable_devices.Add (mount);
4011                                 } else if (split [2] == "usbfs") { //usb ? not tested
4012                                         mount.fsType = FsTypes.usbfs;
4013                                         removable_devices.Add (mount);
4014                                         
4015                                 } else if (split [0].StartsWith ("/")) { //block devices
4016                                         if (split [1].StartsWith ("/dev/"))  // root static, do not add
4017                                                 return;
4018                                         
4019                                         if (split [2] == "ext2")
4020                                                 mount.fsType = FsTypes.ext2;
4021                                         else if (split [2] == "ext3")
4022                                                 mount.fsType = FsTypes.ext3;
4023                                         else if (split [2] == "reiserfs")
4024                                                 mount.fsType = FsTypes.reiserfs;
4025                                         else if (split [2] == "xfs")
4026                                                 mount.fsType = FsTypes.xfs;
4027                                         else if (split [2] == "vfat")
4028                                                 mount.fsType = FsTypes.vfat;
4029                                         else if (split [2] == "ntfs")
4030                                                 mount.fsType = FsTypes.ntfs;
4031                                         else if (split [2] == "msdos")
4032                                                 mount.fsType = FsTypes.msdos;
4033                                         else if (split [2] == "umsdos")
4034                                                 mount.fsType = FsTypes.umsdos;
4035                                         else if (split [2] == "hpfs")
4036                                                 mount.fsType = FsTypes.hpfs;
4037                                         else if (split [2] == "minix")
4038                                                 mount.fsType = FsTypes.minix;
4039                                         else if (split [2] == "jfs")
4040                                                 mount.fsType = FsTypes.jfs;
4041                                         
4042                                         block_devices.Add (mount);
4043                                 }
4044                         }
4045                 }
4046                 
4047                 public class MountComparer : IComparer
4048                 {
4049                         public int Compare (object mount1, object mount2)
4050                         {
4051                                 return String.Compare (((Mount)mount1).device_short, ((Mount)mount2).device_short);
4052                         }
4053                 }
4054         }
4055         #endregion
4056                 
4057         #region MWFConfig
4058         // easy to use class to store and read internal MWF config settings.
4059         // the config values are stored in the users home dir as a hidden xml file called "mwf_config".
4060         // currently supports int, string, byte, color and arrays (including byte arrays)
4061         // don't forget, when you read a value you still have to cast this value.
4062         //
4063         // usage:
4064         // MWFConfig.SetValue ("SomeClass", "What", value);
4065         // object o = MWFConfig.GetValue ("SomeClass", "What");
4066         //
4067         // example:
4068         // 
4069         // string[] configFileNames = (string[])MWFConfig.GetValue ("FileDialog", "FileNames");
4070         // MWFConfig.SetValue ("FileDialog", "LastFolder", "/home/user");
4071         
4072         internal class MWFConfig
4073         {
4074                 private static MWFConfigInstance Instance = new MWFConfigInstance ();
4075                 
4076                 private static object lock_object = new object();
4077                 
4078                 public static object GetValue (string class_name, string value_name)
4079                 {
4080                         lock (lock_object) {
4081                                 return Instance.GetValue (class_name, value_name);
4082                         }
4083                 }
4084                 
4085                 public static void SetValue (string class_name, string value_name, object value)
4086                 {
4087                         lock (lock_object) {
4088                                 Instance.SetValue (class_name, value_name, value);
4089                         }
4090                 }
4091                 
4092                 public static void Flush ()
4093                 {
4094                         lock (lock_object) {
4095                                 Instance.Flush ();
4096                         }
4097                 }
4098                 
4099                 public static void RemoveClass (string class_name)
4100                 {
4101                         lock (lock_object) {
4102                                 Instance.RemoveClass (class_name);
4103                         }
4104                 }
4105                 
4106                 public static void RemoveClassValue (string class_name, string value_name)
4107                 {
4108                         lock (lock_object) {
4109                                 Instance.RemoveClassValue (class_name, value_name);
4110                         }
4111                 }
4112                 
4113                 public static void RemoveAllClassValues (string class_name)
4114                 {
4115                         lock (lock_object) {
4116                                 Instance.RemoveAllClassValues (class_name);
4117                         }
4118                 }
4119         
4120                 internal class MWFConfigInstance
4121                 {
4122                         private Hashtable classes_hashtable = new Hashtable ();
4123                         
4124                         private string path;
4125                         private string fullFileName;
4126                         private XmlTextReader xtr;
4127                         private XmlTextWriter xtw;
4128                         
4129                         private static string defaultFileName;
4130                         
4131                         private readonly string configName = "MWFConfig";
4132                         
4133                         private int platform = (int) Environment.OSVersion.Platform;
4134                         
4135                         public MWFConfigInstance ()
4136                         {
4137                                 if ((platform == 4) || (platform == 128)) {
4138                                         defaultFileName = ".mwf_config";
4139                                 } else {
4140                                         defaultFileName = "mwf_config";
4141                                 }
4142                                 
4143                                 Open (defaultFileName);
4144                         }
4145                         
4146                         // only for testing
4147                         public MWFConfigInstance (string fileName)
4148                         {
4149                                 Open (fileName);
4150                         }
4151                         
4152                         ~MWFConfigInstance ()
4153                         {
4154                                 Flush ();
4155                         }
4156                         
4157                         public object GetValue (string class_name, string value_name)
4158                         {
4159                                 ClassEntry class_entry = classes_hashtable [class_name] as ClassEntry;
4160                                 
4161                                 if (class_entry != null)
4162                                         return class_entry.GetValue (value_name);
4163                                 
4164                                 return null;
4165                         }
4166                         
4167                         public void SetValue (string class_name, string value_name, object value)
4168                         {
4169                                 ClassEntry class_entry = classes_hashtable [class_name] as ClassEntry;
4170                                 
4171                                 if (class_entry == null) {
4172                                         class_entry = new ClassEntry ();
4173                                         class_entry.ClassName = class_name;
4174                                         classes_hashtable [class_name] = class_entry;
4175                                 }
4176                                 
4177                                 class_entry.SetValue (value_name, value);
4178                         }
4179                         
4180                         private void Open (string fileName)
4181                         {
4182                                 path = Path.GetDirectoryName (fileName);
4183                                 
4184                                 if (path == null || path == String.Empty) {
4185                                         path = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
4186                                         
4187                                         fullFileName = Path.Combine (path, fileName);
4188                                 } else
4189                                         fullFileName = fileName;
4190                                 
4191                                 try {
4192                                         xtr = new XmlTextReader (fullFileName);
4193                                         
4194                                         ReadConfig ();
4195                                         
4196                                         xtr.Close ();
4197                                 } catch (Exception) {
4198                                 }
4199                         }
4200                         
4201                         public void Flush ()
4202                         {
4203                                 try {
4204                                         xtw = new XmlTextWriter (fullFileName, null);
4205                                         xtw.Formatting = Formatting.Indented;
4206                                         
4207                                         WriteConfig ();
4208                                         
4209                                         xtw.Close ();
4210                                         
4211                                         if ((platform != 4) && (platform != 128))
4212                                                 File.SetAttributes (fullFileName, FileAttributes.Hidden);
4213                                 } catch (Exception) {}
4214                         }
4215                         
4216                         public void RemoveClass (string class_name)
4217                         {
4218                                 ClassEntry class_entry = classes_hashtable [class_name] as ClassEntry;
4219                                 
4220                                 if (class_entry != null) {
4221                                         class_entry.RemoveAllClassValues ();
4222                                         
4223                                         classes_hashtable.Remove (class_name);
4224                                 }
4225                         }
4226                         
4227                         public void RemoveClassValue (string class_name, string value_name)
4228                         {
4229                                 ClassEntry class_entry = classes_hashtable [class_name] as ClassEntry;
4230                                 
4231                                 if (class_entry != null) {
4232                                         class_entry.RemoveClassValue (value_name);
4233                                 }
4234                         }
4235                         
4236                         public void RemoveAllClassValues (string class_name)
4237                         {
4238                                 ClassEntry class_entry = classes_hashtable [class_name] as ClassEntry;
4239                                 
4240                                 if (class_entry != null) {
4241                                         class_entry.RemoveAllClassValues ();
4242                                 }
4243                         }
4244                         
4245                         private void ReadConfig ()
4246                         {
4247                                 if (!CheckForMWFConfig ())
4248                                         return;
4249                                 
4250                                 while (xtr.Read ()) {
4251                                         switch (xtr.NodeType) {
4252                                                 case XmlNodeType.Element:
4253                                                         ClassEntry class_entry = classes_hashtable [xtr.Name] as ClassEntry;
4254                                                         
4255                                                         if (class_entry == null) {
4256                                                                 class_entry = new ClassEntry ();
4257                                                                 class_entry.ClassName = xtr.Name;
4258                                                                 classes_hashtable [xtr.Name] = class_entry;
4259                                                         }
4260                                                         
4261                                                         class_entry.ReadXml (xtr);
4262                                                         break;
4263                                         }
4264                                 }
4265                         }
4266                         
4267                         private bool CheckForMWFConfig ()
4268                         {
4269                                 if (xtr.Read ()) {
4270                                         if (xtr.NodeType == XmlNodeType.Element) {
4271                                                 if (xtr.Name == configName)
4272                                                         return true;
4273                                         }
4274                                 }
4275                                 
4276                                 return false;
4277                         }
4278                         
4279                         private void WriteConfig ()
4280                         {
4281                                 if (classes_hashtable.Count == 0)
4282                                         return;
4283                                 
4284                                 xtw.WriteStartElement (configName);
4285                                 foreach (DictionaryEntry entry in classes_hashtable) {
4286                                         ClassEntry class_entry = entry.Value as ClassEntry;
4287                                         
4288                                         class_entry.WriteXml (xtw);
4289                                 }
4290                                 xtw.WriteEndElement ();
4291                         }
4292                         
4293                         internal class ClassEntry
4294                         {
4295                                 private Hashtable classvalues_hashtable = new Hashtable ();
4296                                 private string className;
4297                                 
4298                                 public string ClassName {
4299                                         set {
4300                                                 className = value;
4301                                         }
4302                                         
4303                                         get {
4304                                                 return className;
4305                                         }
4306                                 }
4307                                 
4308                                 public void SetValue (string value_name, object value)
4309                                 {
4310                                         ClassValue class_value = classvalues_hashtable [value_name] as ClassValue;
4311                                         
4312                                         if (class_value == null) {
4313                                                 class_value = new ClassValue ();
4314                                                 class_value.Name = value_name;
4315                                                 classvalues_hashtable [value_name] = class_value;
4316                                         }
4317                                         
4318                                         class_value.SetValue (value);
4319                                 }
4320                                 
4321                                 public object GetValue (string value_name)
4322                                 {
4323                                         ClassValue class_value = classvalues_hashtable [value_name] as ClassValue;
4324                                         
4325                                         if (class_value == null) {
4326                                                 return null;
4327                                         }
4328                                         
4329                                         return class_value.GetValue ();
4330                                 }
4331                                 
4332                                 public void RemoveAllClassValues ()
4333                                 {
4334                                         classvalues_hashtable.Clear ();
4335                                 }
4336                                 
4337                                 public void RemoveClassValue (string value_name)
4338                                 {
4339                                         ClassValue class_value = classvalues_hashtable [value_name] as ClassValue;
4340                                         
4341                                         if (class_value != null) {
4342                                                 classvalues_hashtable.Remove (value_name);
4343                                         }
4344                                 }
4345                                 
4346                                 public void ReadXml (XmlTextReader xtr)
4347                                 {
4348                                         while (xtr.Read ()) {
4349                                                 switch (xtr.NodeType) {
4350                                                         case XmlNodeType.Element:
4351                                                                 string name = xtr.GetAttribute ("name");
4352                                                                 
4353                                                                 ClassValue class_value = classvalues_hashtable [name] as ClassValue;
4354                                                                 
4355                                                                 if (class_value == null) {
4356                                                                         class_value = new ClassValue ();
4357                                                                         class_value.Name = name;
4358                                                                         classvalues_hashtable [name] = class_value;
4359                                                                 }
4360                                                                 
4361                                                                 class_value.ReadXml (xtr);
4362                                                                 break;
4363                                                                 
4364                                                         case XmlNodeType.EndElement:
4365                                                                 return;
4366                                                 }
4367                                         }
4368                                 }
4369                                 
4370                                 public void WriteXml (XmlTextWriter xtw)
4371                                 {
4372                                         if (classvalues_hashtable.Count == 0)
4373                                                 return;
4374                                         
4375                                         xtw.WriteStartElement (className);
4376                                         
4377                                         foreach (DictionaryEntry entry in classvalues_hashtable) {
4378                                                 ClassValue class_value = entry.Value as ClassValue;
4379                                                 
4380                                                 class_value.WriteXml (xtw);
4381                                         }
4382                                         
4383                                         xtw.WriteEndElement ();
4384                                 }
4385                         }
4386                         
4387                         internal class ClassValue
4388                         {
4389                                 private object value;
4390                                 private string name;
4391                                 
4392                                 public string Name {
4393                                         set {
4394                                                 name = value;
4395                                         }
4396                                         
4397                                         get {
4398                                                 return name;
4399                                         }
4400                                 }
4401                                 
4402                                 public void SetValue (object value)
4403                                 {
4404                                         this.value = value;
4405                                 }
4406                                 public object GetValue ()
4407                                 {
4408                                         return value;
4409                                 }
4410                                 
4411                                 public void ReadXml (XmlTextReader xtr)
4412                                 {
4413                                         string type;
4414                                         string single_value;
4415                                         
4416                                         type = xtr.GetAttribute ("type");
4417                                         
4418                                         if (type == "byte_array" || type.IndexOf ("-array") == -1) {
4419                                                 single_value = xtr.ReadString ();
4420                                                 
4421                                                 if (type == "string") {
4422                                                         value = single_value;
4423                                                 } else
4424                                                 if (type == "int") {
4425                                                         value = Int32.Parse (single_value);
4426                                                 } else
4427                                                 if (type == "byte") {
4428                                                         value = Byte.Parse (single_value);
4429                                                 } else
4430                                                 if (type == "color") {
4431                                                         int color = Int32.Parse (single_value);
4432                                                         value = Color.FromArgb (color);
4433                                                 } else
4434                                                 if (type == "byte-array") {
4435                                                         byte[] b_array = Convert.FromBase64String (single_value);
4436                                                         value = b_array;
4437                                                 }
4438                                         } else {
4439                                                 ReadXmlArrayValues (xtr, type);
4440                                         }
4441                                 }
4442                                 
4443                                 private void ReadXmlArrayValues (XmlTextReader xtr, string type)
4444                                 {
4445                                         ArrayList al = new ArrayList ();
4446                                         
4447                                         while (xtr.Read ()) {
4448                                                 switch (xtr.NodeType) {
4449                                                         case XmlNodeType.Element:
4450                                                                 string single_value = xtr.ReadString ();
4451                                                                 
4452                                                                 if (type == "int-array") {
4453                                                                         int int_val = Int32.Parse (single_value);
4454                                                                         al.Add (int_val);
4455                                                                 } else
4456                                                                 if (type == "string-array") {
4457                                                                         string str_val = single_value;
4458                                                                         al.Add (str_val);
4459                                                                 }
4460                                                                 break;
4461                                                                 
4462                                                         case XmlNodeType.EndElement:
4463                                                                 if (xtr.Name == "value") {
4464                                                                         if (type == "int-array") {
4465                                                                                 value = al.ToArray (typeof(int));
4466                                                                         } else
4467                                                                         if (type == "string-array") {
4468                                                                                 value = al.ToArray (typeof(string));
4469                                                                         } 
4470                                                                         return;
4471                                                                 }
4472                                                                 break;
4473                                                 }
4474                                         }
4475                                 }
4476                                 
4477                                 public void WriteXml (XmlTextWriter xtw)
4478                                 {
4479                                         xtw.WriteStartElement ("value");
4480                                         xtw.WriteAttributeString ("name", name);
4481                                         if (value is Array) {
4482                                                 WriteArrayContent (xtw);
4483                                         } else {
4484                                                 WriteSingleContent (xtw);
4485                                         }
4486                                         xtw.WriteEndElement ();
4487                                 }
4488                                 
4489                                 private void WriteSingleContent (XmlTextWriter xtw)
4490                                 {
4491                                         string type_string = "";
4492                                         
4493                                         if (value is string)
4494                                                 type_string = "string";
4495                                         else
4496                                         if (value is int)
4497                                                 type_string = "int";
4498                                         else
4499                                         if (value is byte)
4500                                                 type_string = "byte";
4501                                         else
4502                                         if (value is Color)
4503                                                 type_string = "color";
4504                                         
4505                                         xtw.WriteAttributeString ("type", type_string);
4506                                         
4507                                         if (value is Color)
4508                                                 xtw.WriteString (((Color)value).ToArgb ().ToString ());
4509                                         else
4510                                                 xtw.WriteString (value.ToString ());
4511                                 }
4512                                 
4513                                 private void WriteArrayContent (XmlTextWriter xtw)
4514                                 {
4515                                         string type_string = "";
4516                                         string type_name = "";
4517                                         
4518                                         if (value is string[]) {
4519                                                 type_string = "string-array";
4520                                                 type_name = "string";
4521                                         } else
4522                                         if (value is int[]) {
4523                                                 type_string = "int-array";
4524                                                 type_name = "int";
4525                                         } else
4526                                         if (value is byte[]) {
4527                                                 type_string = "byte-array";
4528                                                 type_name = "byte";
4529                                         }
4530                                         
4531                                         xtw.WriteAttributeString ("type", type_string);
4532                                         
4533                                         if (type_string != "byte-array") {
4534                                                 Array array = value as Array;
4535                                                 
4536                                                 foreach (object o in array) {
4537                                                         xtw.WriteStartElement (type_name);
4538                                                         xtw.WriteString (o.ToString ());
4539                                                         xtw.WriteEndElement ();
4540                                                 }
4541                                         } else {
4542                                                 byte[] b_array = value as byte [];
4543                                                 
4544                                                 xtw.WriteString (Convert.ToBase64String (b_array, 0, b_array.Length));
4545                                         }
4546                                 }
4547                         }
4548                 }
4549         }
4550         #endregion
4551 }
4552
4553