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