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