PageRenderTime 75ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/mcs/class/Managed.Windows.Forms/System.Windows.Forms/FileDialog.cs

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