PageRenderTime 46ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/src/Menus/FileMenu.cs

https://bitbucket.org/tuldok89/openpdn
C# | 509 lines | 373 code | 65 blank | 71 comment | 19 complexity | 1949eba409de5de3be79de6d741c3fea MD5 | raw file
  1. /////////////////////////////////////////////////////////////////////////////////
  2. // Paint.NET //
  3. // Copyright (C) dotPDN LLC, Rick Brewster, Tom Jackson, and contributors. //
  4. // Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
  5. // See src/Resources/Files/License.txt for full licensing and attribution //
  6. // details. //
  7. // . //
  8. /////////////////////////////////////////////////////////////////////////////////
  9. using PaintDotNet.Actions;
  10. using PaintDotNet.Base;
  11. using PaintDotNet.SystemLayer;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Drawing;
  15. using System.Drawing.Drawing2D;
  16. using System.IO;
  17. using System.Reflection;
  18. using System.Text;
  19. using System.Windows.Forms;
  20. namespace PaintDotNet.Menus
  21. {
  22. internal sealed class FileMenu
  23. : PdnMenuItem
  24. {
  25. private PdnMenuItem _menuFileNew;
  26. private PdnMenuItem _menuFileOpen;
  27. private PdnMenuItem _menuFileOpenRecent;
  28. private PdnMenuItem _menuFileOpenRecentSentinel;
  29. private PdnMenuItem _menuFileAcquire;
  30. private PdnMenuItem _menuFileAcquireFromScannerOrCamera;
  31. private PdnMenuItem _menuFileClose;
  32. private ToolStripSeparator _menuFileSeparator1;
  33. private PdnMenuItem _menuFileSave;
  34. private PdnMenuItem _menuFileSaveAs;
  35. private ToolStripSeparator _menuFileSeparator2;
  36. private PdnMenuItem _menuFilePrint;
  37. private ToolStripSeparator _menuFileSeparator3;
  38. private PdnMenuItem _menuFileViewPluginLoadErrors;
  39. private ToolStripSeparator _menuFileSeparator4;
  40. private PdnMenuItem _menuFileExit;
  41. private bool OnCtrlF4Typed(Keys keys)
  42. {
  43. _menuFileClose.PerformClick();
  44. return true;
  45. }
  46. public FileMenu()
  47. {
  48. PdnBaseForm.RegisterFormHotKey(Keys.Control | Keys.F4, OnCtrlF4Typed);
  49. InitializeComponent();
  50. }
  51. private void InitializeComponent()
  52. {
  53. _menuFileNew = new PdnMenuItem();
  54. _menuFileOpen = new PdnMenuItem();
  55. _menuFileOpenRecent = new PdnMenuItem();
  56. _menuFileOpenRecentSentinel = new PdnMenuItem();
  57. _menuFileAcquire = new PdnMenuItem();
  58. _menuFileAcquireFromScannerOrCamera = new PdnMenuItem();
  59. _menuFileClose = new PdnMenuItem();
  60. _menuFileSeparator1 = new ToolStripSeparator();
  61. _menuFileSave = new PdnMenuItem();
  62. _menuFileSaveAs = new PdnMenuItem();
  63. _menuFileSeparator2 = new ToolStripSeparator();
  64. _menuFilePrint = new PdnMenuItem();
  65. _menuFileSeparator3 = new ToolStripSeparator();
  66. _menuFileViewPluginLoadErrors = new PdnMenuItem();
  67. _menuFileSeparator4 = new ToolStripSeparator();
  68. _menuFileExit = new PdnMenuItem();
  69. //
  70. // FileMenu
  71. //
  72. DropDownItems.AddRange(GetMenuItemsToAdd(true));
  73. Name = "Menu.File";
  74. Text = PdnResources.GetString("Menu.File.Text");
  75. //
  76. // menuFileNew
  77. //
  78. _menuFileNew.Name = "New";
  79. _menuFileNew.ShortcutKeys = Keys.Control | Keys.N;
  80. _menuFileNew.Click += MenuFileNewClick;
  81. //
  82. // menuFileOpen
  83. //
  84. _menuFileOpen.Name = "Open";
  85. _menuFileOpen.ShortcutKeys = Keys.Control | Keys.O;
  86. _menuFileOpen.Click += MenuFileOpenClick;
  87. //
  88. // menuFileOpenRecent
  89. //
  90. _menuFileOpenRecent.Name = "OpenRecent";
  91. _menuFileOpenRecent.DropDownItems.AddRange(
  92. new ToolStripItem[]
  93. {
  94. _menuFileOpenRecentSentinel
  95. });
  96. _menuFileOpenRecent.DropDownOpening += MenuFileOpenRecentDropDownOpening;
  97. //
  98. // menuFileOpenRecentSentinel
  99. //
  100. _menuFileOpenRecentSentinel.Text = "sentinel";
  101. //
  102. // menuFileAcquire
  103. //
  104. _menuFileAcquire.Name = "Acquire";
  105. _menuFileAcquire.DropDownItems.AddRange(
  106. new ToolStripItem[]
  107. {
  108. _menuFileAcquireFromScannerOrCamera
  109. });
  110. _menuFileAcquire.DropDownOpening += MenuFileAcquireDropDownOpening;
  111. //
  112. // menuFileAcquireFromScannerOrCamera
  113. //
  114. _menuFileAcquireFromScannerOrCamera.Name = "FromScannerOrCamera";
  115. _menuFileAcquireFromScannerOrCamera.Click += MenuFileAcquireFromScannerOrCameraClick;
  116. //
  117. // menuFileClose
  118. //
  119. _menuFileClose.Name = "Close";
  120. _menuFileClose.Click += MenuFileCloseClick;
  121. _menuFileClose.ShortcutKeys = Keys.Control | Keys.W;
  122. //
  123. // menuFileSave
  124. //
  125. _menuFileSave.Name = "Save";
  126. _menuFileSave.ShortcutKeys = Keys.Control | Keys.S;
  127. _menuFileSave.Click += MenuFileSaveClick;
  128. //
  129. // menuFileSaveAs
  130. //
  131. _menuFileSaveAs.Name = "SaveAs";
  132. _menuFileSaveAs.ShortcutKeys = Keys.Control | Keys.Shift | Keys.S;
  133. _menuFileSaveAs.Click += MenuFileSaveAsClick;
  134. //
  135. // menuFilePrint
  136. //
  137. _menuFilePrint.Name = "Print";
  138. _menuFilePrint.ShortcutKeys = Keys.Control | Keys.P;
  139. _menuFilePrint.Click += MenuFilePrintClick;
  140. //
  141. // menuFileViewPluginLoadErrors
  142. //
  143. _menuFileViewPluginLoadErrors.Name = "ViewPluginLoadErrors";
  144. _menuFileViewPluginLoadErrors.Click += MenuFileViewPluginLoadErrorsClick;
  145. //
  146. // menuFileExit
  147. //
  148. _menuFileExit.Name = "Exit";
  149. _menuFileExit.Click += MenuFileExitClick;
  150. }
  151. private ToolStripItem[] GetMenuItemsToAdd(bool includeLoadErrors)
  152. {
  153. var items = new List<ToolStripItem>
  154. {
  155. _menuFileNew,
  156. _menuFileOpen,
  157. _menuFileOpenRecent,
  158. _menuFileAcquire,
  159. _menuFileClose,
  160. _menuFileSeparator1,
  161. _menuFileSave,
  162. _menuFileSaveAs,
  163. _menuFileSeparator2,
  164. _menuFilePrint,
  165. _menuFileSeparator3
  166. };
  167. if (includeLoadErrors)
  168. {
  169. items.Add(_menuFileViewPluginLoadErrors);
  170. items.Add(_menuFileSeparator4);
  171. }
  172. items.Add(_menuFileExit);
  173. return items.ToArray();
  174. }
  175. private static List<Triple<Assembly, Type, Exception>> RemoveDuplicates(IEnumerable<Triple<Assembly, Type, Exception>> allErrors)
  176. {
  177. // Exception has reference identity, but we want to collate based on the message contents
  178. var internedList = new Set<Triple<Assembly, Type, string>>();
  179. var noDupesList = new List<Triple<Assembly, Type, Exception>>();
  180. foreach (Triple<Assembly, Type, Exception> t in allErrors)
  181. {
  182. Triple<Assembly, Type, string> interned = Triple.Create(
  183. t.First, t.Second, string.Intern(t.Third.ToString()));
  184. if (internedList.Contains(interned)) continue;
  185. internedList.Add(interned);
  186. noDupesList.Add(t);
  187. }
  188. return noDupesList;
  189. }
  190. private void MenuFileViewPluginLoadErrorsClick(object sender, EventArgs e)
  191. {
  192. IList<Triple<Assembly, Type, Exception>> allErrors = AppWorkspace.GetEffectLoadErrors();
  193. IList<Triple<Assembly, Type, Exception>> errors = RemoveDuplicates(allErrors);
  194. using (var errorsDialog = new Form())
  195. {
  196. errorsDialog.Icon = Utility.ImageToIcon(PdnResources.GetImageResource("Icons.MenuFileViewPluginLoadErrorsIcon.png").Reference);
  197. errorsDialog.Text = PdnResources.GetString("Effects.PluginLoadErrorsDialog.Text");
  198. var messageLabel = new Label
  199. {
  200. Name = "messageLabel",
  201. Text = PdnResources.GetString("Effects.PluginLoadErrorsDialog.Message.Text")
  202. };
  203. var errorsBox = new TextBox();
  204. errorsBox.Font = new Font(FontFamily.GenericMonospace, errorsBox.Font.Size);
  205. errorsBox.ReadOnly = true;
  206. errorsBox.Multiline = true;
  207. errorsBox.ScrollBars = ScrollBars.Vertical;
  208. var allErrorsText = new StringBuilder();
  209. string headerTextFormat = PdnResources.GetString("EffectErrorMessage.HeaderFormat");
  210. for (int i = 0; i < errors.Count; ++i)
  211. {
  212. Assembly assembly = errors[i].First;
  213. Type type = errors[i].Second;
  214. Exception exception = errors[i].Third;
  215. string headerText = string.Format(headerTextFormat, i + 1, errors.Count);
  216. string errorText = AppWorkspace.GetLocalizedEffectErrorMessage(assembly, type, exception);
  217. allErrorsText.Append(headerText);
  218. allErrorsText.Append(Environment.NewLine);
  219. allErrorsText.Append(errorText);
  220. if (i != errors.Count - 1)
  221. {
  222. allErrorsText.Append(Environment.NewLine);
  223. }
  224. }
  225. errorsBox.Text = allErrorsText.ToString();
  226. errorsDialog.Layout +=
  227. delegate
  228. {
  229. int hMargin = UI.ScaleWidth(8);
  230. int vMargin = UI.ScaleHeight(8);
  231. int insetWidth = errorsDialog.ClientSize.Width - (hMargin * 2);
  232. messageLabel.Location = new Point(hMargin, vMargin);
  233. messageLabel.Width = insetWidth;
  234. messageLabel.Size = messageLabel.GetPreferredSize(new Size(messageLabel.Width, 1));
  235. errorsBox.Location = new Point(hMargin, messageLabel.Bottom + vMargin);
  236. errorsBox.Width = insetWidth;
  237. errorsBox.Height = errorsDialog.ClientSize.Height - vMargin - errorsBox.Top;
  238. };
  239. errorsDialog.StartPosition = FormStartPosition.CenterParent;
  240. errorsDialog.ShowInTaskbar = false;
  241. errorsDialog.MinimizeBox = false;
  242. errorsDialog.Width *= 2;
  243. errorsDialog.Size = UI.ScaleSize(errorsDialog.Size);
  244. errorsDialog.Controls.Add(messageLabel);
  245. errorsDialog.Controls.Add(errorsBox);
  246. errorsDialog.ShowDialog(AppWorkspace);
  247. }
  248. }
  249. protected override void OnDropDownOpening(EventArgs e)
  250. {
  251. DropDownItems.Clear();
  252. IList<Triple<Assembly, Type, Exception>> pluginLoadErrors = AppWorkspace.GetEffectLoadErrors();
  253. DropDownItems.AddRange(GetMenuItemsToAdd(pluginLoadErrors.Count > 0));
  254. _menuFileNew.Enabled = true;
  255. _menuFileOpen.Enabled = true;
  256. _menuFileOpenRecent.Enabled = true;
  257. _menuFileOpenRecentSentinel.Enabled = true;
  258. _menuFileAcquire.Enabled = true;
  259. _menuFileAcquireFromScannerOrCamera.Enabled = true;
  260. _menuFileExit.Enabled = true;
  261. if (AppWorkspace.ActiveDocumentWorkspace != null)
  262. {
  263. _menuFileSave.Enabled = true;
  264. _menuFileSaveAs.Enabled = true;
  265. _menuFileClose.Enabled = true;
  266. _menuFilePrint.Enabled = true;
  267. }
  268. else
  269. {
  270. _menuFileSave.Enabled = false;
  271. _menuFileSaveAs.Enabled = false;
  272. _menuFileClose.Enabled = false;
  273. _menuFilePrint.Enabled = false;
  274. }
  275. base.OnDropDownOpening(e);
  276. }
  277. private void MenuFileOpenClick(object sender, EventArgs e)
  278. {
  279. AppWorkspace.PerformAction(new OpenFileAction());
  280. }
  281. private static void DoExit()
  282. {
  283. Startup.CloseApplication();
  284. }
  285. private static void MenuFileExitClick(object sender, EventArgs e)
  286. {
  287. DoExit();
  288. }
  289. private void MenuFileCloseClick(object sender, EventArgs e)
  290. {
  291. if (AppWorkspace.DocumentWorkspaces.Length > 0)
  292. {
  293. AppWorkspace.PerformAction(new CloseWorkspaceAction());
  294. }
  295. else
  296. {
  297. DoExit();
  298. }
  299. }
  300. private void MenuFileSaveAsClick(object sender, EventArgs e)
  301. {
  302. if (AppWorkspace.ActiveDocumentWorkspace != null)
  303. {
  304. AppWorkspace.ActiveDocumentWorkspace.DoSaveAs();
  305. }
  306. }
  307. private void MenuFileSaveClick(object sender, EventArgs e)
  308. {
  309. if (AppWorkspace.ActiveDocumentWorkspace != null)
  310. {
  311. AppWorkspace.ActiveDocumentWorkspace.DoSave();
  312. }
  313. }
  314. private void MenuFileAcquireDropDownOpening(object sender, EventArgs e)
  315. {
  316. // We only disable the scanner menu item if we know for sure a scanner is not available
  317. // If WIA isn't available we leave the menu item enabled. That way we can give an
  318. // informative error message when the user clicks on it and say "scanning requires XP SP1"
  319. // Otherwise the user is confused and will make scathing posts on our forum.
  320. bool scannerEnabled = true;
  321. if (ScanningAndPrinting.IsComponentAvailable)
  322. {
  323. if (!ScanningAndPrinting.CanScan)
  324. {
  325. scannerEnabled = false;
  326. }
  327. }
  328. _menuFileAcquireFromScannerOrCamera.Enabled = scannerEnabled;
  329. }
  330. private void MenuFilePrintClick(object sender, EventArgs e)
  331. {
  332. if (AppWorkspace.ActiveDocumentWorkspace != null)
  333. {
  334. AppWorkspace.ActiveDocumentWorkspace.PerformAction(new PrintAction());
  335. }
  336. }
  337. /*
  338. private void MenuFileOpenInNewWindow_Click(object sender, System.EventArgs e)
  339. {
  340. string fileName;
  341. string startingDir = Path.GetDirectoryName(AppWorkspace.ActiveDocumentWorkspace.FilePath);
  342. DialogResult result = DocumentWorkspace.ChooseFile(AppWorkspace, out fileName, startingDir);
  343. if (result == DialogResult.OK)
  344. {
  345. Startup.StartNewInstance(AppWorkspace, fileName);
  346. }
  347. }
  348. */ //SUSPECTED UNUSED METHOD
  349. /*
  350. private void MenuFileNewWindow_Click(object sender, System.EventArgs e)
  351. {
  352. Startup.StartNewInstance(AppWorkspace, null);
  353. }
  354. */ //SUSPECTED UNUSED METHOD
  355. private void MenuFileOpenRecentDropDownOpening(object sender, EventArgs e)
  356. {
  357. AppWorkspace.MostRecentFiles.LoadMruList();
  358. MostRecentFile[] filesReverse = AppWorkspace.MostRecentFiles.GetFileList();
  359. var files = new MostRecentFile[filesReverse.Length];
  360. int i;
  361. for (i = 0; i < filesReverse.Length; ++i)
  362. {
  363. files[files.Length - i - 1] = filesReverse[i];
  364. }
  365. foreach (ToolStripItem mi in _menuFileOpenRecent.DropDownItems)
  366. {
  367. mi.Click -= MenuFileOpenRecentFileClick;
  368. }
  369. _menuFileOpenRecent.DropDownItems.Clear();
  370. i = 0;
  371. foreach (MostRecentFile mrf in files)
  372. {
  373. string menuName = i < 9 ? "&" : "";
  374. menuName += (1 + i) + " " + Path.GetFileName(mrf.FileName);
  375. var mi = new ToolStripMenuItem(menuName);
  376. mi.Click += MenuFileOpenRecentFileClick;
  377. mi.ImageScaling = ToolStripItemImageScaling.None;
  378. mi.Image = (Image)mrf.Thumb.Clone();
  379. _menuFileOpenRecent.DropDownItems.Add(mi);
  380. ++i;
  381. }
  382. if (_menuFileOpenRecent.DropDownItems.Count == 0)
  383. {
  384. var none = new ToolStripMenuItem(PdnResources.GetString("Menu.File.OpenRecent.None")) {Enabled = false};
  385. _menuFileOpenRecent.DropDownItems.Add(none);
  386. }
  387. else
  388. {
  389. var separator = new ToolStripSeparator();
  390. _menuFileOpenRecent.DropDownItems.Add(separator);
  391. var clearList = new ToolStripMenuItem
  392. {
  393. Text = PdnResources.GetString("Menu.File.OpenRecent.ClearThisList")
  394. };
  395. _menuFileOpenRecent.DropDownItems.Add(clearList);
  396. Image deleteIcon = PdnResources.GetImageResource("Icons.MenuEditEraseSelectionIcon.png").Reference;
  397. clearList.ImageTransparentColor = Utility.TransparentKey;
  398. clearList.ImageAlign = ContentAlignment.MiddleCenter;
  399. clearList.ImageScaling = ToolStripItemImageScaling.None;
  400. int iconSize = AppWorkspace.MostRecentFiles.IconSize;
  401. var bitmap = new Bitmap(iconSize + 2, iconSize + 2);
  402. using (Graphics g = Graphics.FromImage(bitmap))
  403. {
  404. g.Clear(clearList.ImageTransparentColor);
  405. var offset = new Point((bitmap.Width - deleteIcon.Width) / 2,
  406. (bitmap.Height - deleteIcon.Height) / 2);
  407. g.CompositingMode = CompositingMode.SourceCopy;
  408. g.DrawImage(deleteIcon, offset.X, offset.Y, deleteIcon.Width, deleteIcon.Height);
  409. }
  410. clearList.Image = bitmap;
  411. clearList.Click += ClearListClick;
  412. }
  413. }
  414. private void MenuFileOpenRecentFileClick(object sender, EventArgs e)
  415. {
  416. try
  417. {
  418. var mi = (ToolStripMenuItem)sender;
  419. int spaceIndex = mi.Text.IndexOf(" ");
  420. string indexString = mi.Text.Substring(1, spaceIndex - 1);
  421. int index = int.Parse(indexString) - 1;
  422. MostRecentFile[] recentFiles = AppWorkspace.MostRecentFiles.GetFileList();
  423. string fileName = recentFiles[recentFiles.Length - index - 1].FileName;
  424. AppWorkspace.OpenFileInNewWorkspace(fileName);
  425. }
  426. catch (Exception)
  427. {
  428. }
  429. }
  430. private void MenuFileNewClick(object sender, EventArgs e)
  431. {
  432. AppWorkspace.PerformAction(new NewImageAction());
  433. }
  434. private void MenuFileAcquireFromScannerOrCameraClick(object sender, EventArgs e)
  435. {
  436. AppWorkspace.PerformAction(new AcquireFromScannerOrCameraAction());
  437. }
  438. private void ClearListClick(object sender, EventArgs e)
  439. {
  440. AppWorkspace.PerformAction(new ClearMruListAction());
  441. }
  442. }
  443. }