MainForm.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. using System.Runtime.Serialization;
  9. using System.Diagnostics;
  10. using System.Security;
  11. using Microsoft.Win32;
  12. using DocToolkit;
  13. namespace DrawTools
  14. {
  15. partial class MainForm : Form
  16. {
  17. #region Members
  18. private DrawArea drawArea;
  19. private DocManager docManager;
  20. private DragDropManager dragDropManager;
  21. private MruManager mruManager;
  22. private PersistWindowState persistState;
  23. private string argumentFile = ""; // file name from command line
  24. const string registryPath = "Software\\AlexF\\DrawTools";
  25. #endregion
  26. #region Properties
  27. /// <summary>
  28. /// File name from the command line
  29. /// </summary>
  30. public string ArgumentFile
  31. {
  32. get
  33. {
  34. return argumentFile;
  35. }
  36. set
  37. {
  38. argumentFile = value;
  39. }
  40. }
  41. /// <summary>
  42. /// Get reference to Edit menu item.
  43. /// Used to show context menu in DrawArea class.
  44. /// </summary>
  45. /// <value></value>
  46. public ToolStripMenuItem ContextParent
  47. {
  48. get
  49. {
  50. return editToolStripMenuItem;
  51. }
  52. }
  53. #endregion
  54. #region Constructor
  55. public MainForm()
  56. {
  57. InitializeComponent();
  58. persistState = new PersistWindowState(registryPath, this);
  59. }
  60. #endregion
  61. #region Toolbar Event Handlers
  62. private void toolStripButtonNew_Click(object sender, EventArgs e)
  63. {
  64. CommandNew();
  65. }
  66. private void toolStripButtonOpen_Click(object sender, EventArgs e)
  67. {
  68. CommandOpen();
  69. }
  70. private void toolStripButtonSave_Click(object sender, EventArgs e)
  71. {
  72. CommandSave();
  73. }
  74. private void toolStripButtonPointer_Click(object sender, EventArgs e)
  75. {
  76. CommandPointer();
  77. }
  78. private void toolStripButtonRectangle_Click(object sender, EventArgs e)
  79. {
  80. CommandRectangle();
  81. }
  82. private void toolStripButtonEllipse_Click(object sender, EventArgs e)
  83. {
  84. CommandEllipse();
  85. }
  86. private void toolStripButtonLine_Click(object sender, EventArgs e)
  87. {
  88. CommandLine();
  89. }
  90. private void toolStripButtonPencil_Click(object sender, EventArgs e)
  91. {
  92. CommandPolygon();
  93. }
  94. private void toolStripButtonAbout_Click(object sender, EventArgs e)
  95. {
  96. CommandAbout();
  97. }
  98. private void toolStripButtonUndo_Click(object sender, EventArgs e)
  99. {
  100. CommandUndo();
  101. }
  102. private void toolStripButtonRedo_Click(object sender, EventArgs e)
  103. {
  104. CommandRedo();
  105. }
  106. #endregion Toolbar Event Handlers
  107. #region Menu Event Handlers
  108. private void newToolStripMenuItem_Click(object sender, EventArgs e)
  109. {
  110. CommandNew();
  111. }
  112. private void openToolStripMenuItem_Click(object sender, EventArgs e)
  113. {
  114. CommandOpen();
  115. }
  116. private void saveToolStripMenuItem_Click(object sender, EventArgs e)
  117. {
  118. CommandSave();
  119. }
  120. private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
  121. {
  122. CommandSaveAs();
  123. }
  124. private void exitToolStripMenuItem_Click(object sender, EventArgs e)
  125. {
  126. this.Close();
  127. }
  128. private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
  129. {
  130. drawArea.GraphicsList.SelectAll();
  131. drawArea.Refresh();
  132. }
  133. private void unselectAllToolStripMenuItem_Click(object sender, EventArgs e)
  134. {
  135. drawArea.GraphicsList.UnselectAll();
  136. drawArea.Refresh();
  137. }
  138. private void deleteToolStripMenuItem_Click(object sender, EventArgs e)
  139. {
  140. CommandDelete command = new CommandDelete(drawArea.GraphicsList);
  141. if (drawArea.GraphicsList.DeleteSelection())
  142. {
  143. drawArea.SetDirty();
  144. drawArea.Refresh();
  145. drawArea.AddCommandToHistory(command);
  146. }
  147. }
  148. private void deleteAllToolStripMenuItem_Click(object sender, EventArgs e)
  149. {
  150. CommandDeleteAll command = new CommandDeleteAll(drawArea.GraphicsList);
  151. if (drawArea.GraphicsList.Clear())
  152. {
  153. drawArea.SetDirty();
  154. drawArea.Refresh();
  155. drawArea.AddCommandToHistory(command);
  156. }
  157. }
  158. private void moveToFrontToolStripMenuItem_Click(object sender, EventArgs e)
  159. {
  160. if (drawArea.GraphicsList.MoveSelectionToFront())
  161. {
  162. drawArea.SetDirty();
  163. drawArea.Refresh();
  164. }
  165. }
  166. private void moveToBackToolStripMenuItem_Click(object sender, EventArgs e)
  167. {
  168. if (drawArea.GraphicsList.MoveSelectionToBack())
  169. {
  170. drawArea.SetDirty();
  171. drawArea.Refresh();
  172. }
  173. }
  174. private void propertiesToolStripMenuItem_Click(object sender, EventArgs e)
  175. {
  176. if (drawArea.GraphicsList.ShowPropertiesDialog(drawArea))
  177. {
  178. drawArea.SetDirty();
  179. drawArea.Refresh();
  180. }
  181. }
  182. private void pointerToolStripMenuItem_Click(object sender, EventArgs e)
  183. {
  184. CommandPointer();
  185. }
  186. private void rectangleToolStripMenuItem_Click(object sender, EventArgs e)
  187. {
  188. CommandRectangle();
  189. }
  190. private void ellipseToolStripMenuItem_Click(object sender, EventArgs e)
  191. {
  192. CommandEllipse();
  193. }
  194. private void lineToolStripMenuItem_Click(object sender, EventArgs e)
  195. {
  196. CommandLine();
  197. }
  198. private void pencilToolStripMenuItem_Click(object sender, EventArgs e)
  199. {
  200. CommandPolygon();
  201. }
  202. private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
  203. {
  204. CommandAbout();
  205. }
  206. private void undoToolStripMenuItem_Click(object sender, EventArgs e)
  207. {
  208. CommandUndo();
  209. }
  210. private void redoToolStripMenuItem_Click(object sender, EventArgs e)
  211. {
  212. CommandRedo();
  213. }
  214. #endregion Menu Event Handlers
  215. #region DocManager Event Handlers
  216. /// <summary>
  217. /// Load document from the stream supplied by DocManager
  218. /// </summary>
  219. /// <param name="sender"></param>
  220. /// <param name="args"></param>
  221. private void docManager_LoadEvent(object sender, SerializationEventArgs e)
  222. {
  223. // DocManager asks to load document from supplied stream
  224. try
  225. {
  226. drawArea.GraphicsList = (GraphicsList)e.Formatter.Deserialize(e.SerializationStream);
  227. }
  228. catch (ArgumentNullException ex)
  229. {
  230. HandleLoadException(ex, e);
  231. }
  232. catch (SerializationException ex)
  233. {
  234. HandleLoadException(ex, e);
  235. }
  236. catch (SecurityException ex)
  237. {
  238. HandleLoadException(ex, e);
  239. }
  240. }
  241. /// <summary>
  242. /// Save document to stream supplied by DocManager
  243. /// </summary>
  244. /// <param name="sender"></param>
  245. /// <param name="args"></param>
  246. private void docManager_SaveEvent(object sender, SerializationEventArgs e)
  247. {
  248. // DocManager asks to save document to supplied stream
  249. try
  250. {
  251. e.Formatter.Serialize(e.SerializationStream, drawArea.GraphicsList);
  252. }
  253. catch (ArgumentNullException ex)
  254. {
  255. HandleSaveException(ex, e);
  256. }
  257. catch (SerializationException ex)
  258. {
  259. HandleSaveException(ex, e);
  260. }
  261. catch (SecurityException ex)
  262. {
  263. HandleSaveException(ex, e);
  264. }
  265. }
  266. #endregion
  267. #region Event Handlers
  268. private void MainForm_Load(object sender, EventArgs e)
  269. {
  270. // Create draw area
  271. drawArea = new DrawArea();
  272. drawArea.Location = new System.Drawing.Point(0, 0);
  273. drawArea.Size = new System.Drawing.Size(10, 10);
  274. drawArea.Owner = this;
  275. this.Controls.Add(drawArea);
  276. // Helper objects (DocManager and others)
  277. InitializeHelperObjects();
  278. drawArea.Initialize(this, docManager);
  279. ResizeDrawArea();
  280. LoadSettingsFromRegistry();
  281. // Submit to Idle event to set controls state at idle time
  282. Application.Idle += delegate(object o, EventArgs a)
  283. {
  284. SetStateOfControls();
  285. };
  286. // Open file passed in the command line
  287. if (ArgumentFile.Length > 0)
  288. OpenDocument(ArgumentFile);
  289. // Subscribe to DropDownOpened event for each popup menu
  290. // (see details in MainForm_DropDownOpened)
  291. foreach (ToolStripItem item in menuStrip1.Items)
  292. {
  293. if (item.GetType() == typeof(ToolStripMenuItem))
  294. {
  295. ((ToolStripMenuItem)item).DropDownOpened += MainForm_DropDownOpened;
  296. }
  297. }
  298. }
  299. /// <summary>
  300. /// Resize draw area when form is resized
  301. /// </summary>
  302. private void MainForm_Resize(object sender, EventArgs e)
  303. {
  304. if (this.WindowState != FormWindowState.Minimized &&
  305. drawArea != null )
  306. {
  307. ResizeDrawArea();
  308. }
  309. }
  310. /// <summary>
  311. /// Form is closing
  312. /// </summary>
  313. private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
  314. {
  315. if ( e.CloseReason == CloseReason.UserClosing )
  316. {
  317. if (!docManager.CloseDocument())
  318. e.Cancel = true;
  319. }
  320. SaveSettingsToRegistry();
  321. }
  322. /// <summary>
  323. /// Popup menu item (File, Edit ...) is opened.
  324. /// </summary>
  325. /// <param name="sender"></param>
  326. /// <param name="e"></param>
  327. void MainForm_DropDownOpened(object sender, EventArgs e)
  328. {
  329. // Reset active tool to pointer.
  330. // This prevents bug in rare case when non-pointer tool is active, user opens
  331. // main main menu and after this clicks in the drawArea. MouseDown event is not
  332. // raised in this case (why ??), and MouseMove event works incorrectly.
  333. drawArea.ActiveTool = DrawArea.DrawToolType.Pointer;
  334. }
  335. #endregion Event Handlers
  336. #region Other Functions
  337. /// <summary>
  338. /// Set state of controls.
  339. /// Function is called at idle time.
  340. /// </summary>
  341. public void SetStateOfControls()
  342. {
  343. // Select active tool
  344. toolStripButtonPointer.Checked = (drawArea.ActiveTool == DrawArea.DrawToolType.Pointer);
  345. toolStripButtonRectangle.Checked = (drawArea.ActiveTool == DrawArea.DrawToolType.Rectangle);
  346. toolStripButtonEllipse.Checked = (drawArea.ActiveTool == DrawArea.DrawToolType.Ellipse);
  347. toolStripButtonLine.Checked = (drawArea.ActiveTool == DrawArea.DrawToolType.Line);
  348. toolStripButtonPencil.Checked = (drawArea.ActiveTool == DrawArea.DrawToolType.Polygon);
  349. pointerToolStripMenuItem.Checked = (drawArea.ActiveTool == DrawArea.DrawToolType.Pointer);
  350. rectangleToolStripMenuItem.Checked = (drawArea.ActiveTool == DrawArea.DrawToolType.Rectangle);
  351. ellipseToolStripMenuItem.Checked = (drawArea.ActiveTool == DrawArea.DrawToolType.Ellipse);
  352. lineToolStripMenuItem.Checked = (drawArea.ActiveTool == DrawArea.DrawToolType.Line);
  353. pencilToolStripMenuItem.Checked = (drawArea.ActiveTool == DrawArea.DrawToolType.Polygon);
  354. bool objects = (drawArea.GraphicsList.Count > 0);
  355. bool selectedObjects = (drawArea.GraphicsList.SelectionCount > 0);
  356. // File operations
  357. saveToolStripMenuItem.Enabled = objects;
  358. toolStripButtonSave.Enabled = objects;
  359. saveAsToolStripMenuItem.Enabled = objects;
  360. // Edit operations
  361. deleteToolStripMenuItem.Enabled = selectedObjects;
  362. deleteAllToolStripMenuItem.Enabled = objects;
  363. selectAllToolStripMenuItem.Enabled = objects;
  364. unselectAllToolStripMenuItem.Enabled = objects;
  365. moveToFrontToolStripMenuItem.Enabled = selectedObjects;
  366. moveToBackToolStripMenuItem.Enabled = selectedObjects;
  367. propertiesToolStripMenuItem.Enabled = selectedObjects;
  368. // Undo, Redo
  369. undoToolStripMenuItem.Enabled = drawArea.CanUndo;
  370. toolStripButtonUndo.Enabled = drawArea.CanUndo;
  371. redoToolStripMenuItem.Enabled = drawArea.CanRedo;
  372. toolStripButtonRedo.Enabled = drawArea.CanRedo;
  373. }
  374. /// <summary>
  375. /// Set draw area to all form client space except toolbar
  376. /// </summary>
  377. private void ResizeDrawArea()
  378. {
  379. Rectangle rect = this.ClientRectangle;
  380. drawArea.Left = rect.Left;
  381. drawArea.Top = rect.Top + menuStrip1.Height + toolStrip1.Height;
  382. drawArea.Width = rect.Width;
  383. drawArea.Height = rect.Height - menuStrip1.Height - toolStrip1.Height; ;
  384. }
  385. /// <summary>
  386. /// Initialize helper objects from the DocToolkit Library.
  387. ///
  388. /// Called from Form1_Load. Initialized all objects except
  389. /// PersistWindowState wich must be initialized in the
  390. /// form constructor.
  391. /// </summary>
  392. private void InitializeHelperObjects()
  393. {
  394. // DocManager
  395. DocManagerData data = new DocManagerData();
  396. data.FormOwner = this;
  397. data.UpdateTitle = true;
  398. data.FileDialogFilter = "DrawTools files (*.dtl)|*.dtl|All Files (*.*)|*.*";
  399. data.NewDocName = "Untitled.dtl";
  400. data.RegistryPath = registryPath;
  401. docManager = new DocManager(data);
  402. docManager.RegisterFileType("dtl", "dtlfile", "DrawTools File");
  403. // Subscribe to DocManager events.
  404. docManager.SaveEvent += docManager_SaveEvent;
  405. docManager.LoadEvent += docManager_LoadEvent;
  406. // Make "inline subscription" using anonymous methods.
  407. docManager.OpenEvent += delegate(object sender, OpenFileEventArgs e)
  408. {
  409. // Update MRU List
  410. if (e.Succeeded)
  411. mruManager.Add(e.FileName);
  412. else
  413. mruManager.Remove(e.FileName);
  414. };
  415. docManager.DocChangedEvent += delegate(object o, EventArgs e)
  416. {
  417. drawArea.Refresh();
  418. drawArea.ClearHistory();
  419. };
  420. docManager.ClearEvent += delegate(object o, EventArgs e)
  421. {
  422. if (drawArea.GraphicsList != null)
  423. {
  424. drawArea.GraphicsList.Clear();
  425. drawArea.ClearHistory();
  426. drawArea.Refresh();
  427. }
  428. };
  429. docManager.NewDocument();
  430. // DragDropManager
  431. dragDropManager = new DragDropManager(this);
  432. dragDropManager.FileDroppedEvent += delegate(object sender, FileDroppedEventArgs e)
  433. {
  434. OpenDocument(e.FileArray.GetValue(0).ToString());
  435. };
  436. // MruManager
  437. mruManager = new MruManager();
  438. mruManager.Initialize(
  439. this, // owner form
  440. recentFilesToolStripMenuItem, // Recent Files menu item
  441. fileToolStripMenuItem, // parent
  442. registryPath); // Registry path to keep MRU list
  443. mruManager.MruOpenEvent += delegate(object sender, MruFileOpenEventArgs e)
  444. {
  445. OpenDocument(e.FileName);
  446. };
  447. }
  448. /// <summary>
  449. /// Handle exception from docManager_LoadEvent function
  450. /// </summary>
  451. /// <param name="ex"></param>
  452. /// <param name="fileName"></param>
  453. private void HandleLoadException(Exception ex, SerializationEventArgs e)
  454. {
  455. MessageBox.Show(this,
  456. "Open File operation failed. File name: " + e.FileName + "\n" +
  457. "Reason: " + ex.Message,
  458. Application.ProductName);
  459. e.Error = true;
  460. }
  461. /// <summary>
  462. /// Handle exception from docManager_SaveEvent function
  463. /// </summary>
  464. /// <param name="ex"></param>
  465. /// <param name="fileName"></param>
  466. private void HandleSaveException(Exception ex, SerializationEventArgs e)
  467. {
  468. MessageBox.Show(this,
  469. "Save File operation failed. File name: " + e.FileName + "\n" +
  470. "Reason: " + ex.Message,
  471. Application.ProductName);
  472. e.Error = true;
  473. }
  474. /// <summary>
  475. /// Open document.
  476. /// Used to open file passed in command line or dropped into the window
  477. /// </summary>
  478. /// <param name="file"></param>
  479. public void OpenDocument(string file)
  480. {
  481. docManager.OpenDocument(file);
  482. }
  483. /// <summary>
  484. /// Load application settings from the Registry
  485. /// </summary>
  486. void LoadSettingsFromRegistry()
  487. {
  488. try
  489. {
  490. RegistryKey key = Registry.CurrentUser.CreateSubKey(registryPath);
  491. DrawObject.LastUsedColor = Color.FromArgb((int)key.GetValue(
  492. "Color",
  493. Color.Black.ToArgb()));
  494. DrawObject.LastUsedPenWidth = (int)key.GetValue(
  495. "Width",
  496. 1);
  497. }
  498. catch (ArgumentNullException ex)
  499. {
  500. HandleRegistryException(ex);
  501. }
  502. catch (SecurityException ex)
  503. {
  504. HandleRegistryException(ex);
  505. }
  506. catch (ArgumentException ex)
  507. {
  508. HandleRegistryException(ex);
  509. }
  510. catch (ObjectDisposedException ex)
  511. {
  512. HandleRegistryException(ex);
  513. }
  514. catch (UnauthorizedAccessException ex)
  515. {
  516. HandleRegistryException(ex);
  517. }
  518. }
  519. /// <summary>
  520. /// Save application settings to the Registry
  521. /// </summary>
  522. void SaveSettingsToRegistry()
  523. {
  524. try
  525. {
  526. RegistryKey key = Registry.CurrentUser.CreateSubKey(registryPath);
  527. key.SetValue("Color", DrawObject.LastUsedColor.ToArgb());
  528. key.SetValue("Width", DrawObject.LastUsedPenWidth);
  529. }
  530. catch (SecurityException ex)
  531. {
  532. HandleRegistryException(ex);
  533. }
  534. catch (ArgumentException ex)
  535. {
  536. HandleRegistryException(ex);
  537. }
  538. catch (ObjectDisposedException ex)
  539. {
  540. HandleRegistryException(ex);
  541. }
  542. catch (UnauthorizedAccessException ex)
  543. {
  544. HandleRegistryException(ex);
  545. }
  546. }
  547. private void HandleRegistryException(Exception ex)
  548. {
  549. Trace.WriteLine("Registry operation failed: " + ex.Message);
  550. }
  551. /// <summary>
  552. /// Set Pointer draw tool
  553. /// </summary>
  554. private void CommandPointer()
  555. {
  556. drawArea.ActiveTool = DrawArea.DrawToolType.Pointer;
  557. }
  558. /// <summary>
  559. /// Set Rectangle draw tool
  560. /// </summary>
  561. private void CommandRectangle()
  562. {
  563. drawArea.ActiveTool = DrawArea.DrawToolType.Rectangle;
  564. }
  565. /// <summary>
  566. /// Set Ellipse draw tool
  567. /// </summary>
  568. private void CommandEllipse()
  569. {
  570. drawArea.ActiveTool = DrawArea.DrawToolType.Ellipse;
  571. }
  572. /// <summary>
  573. /// Set Line draw tool
  574. /// </summary>
  575. private void CommandLine()
  576. {
  577. drawArea.ActiveTool = DrawArea.DrawToolType.Line;
  578. }
  579. /// <summary>
  580. /// Set Polygon draw tool
  581. /// </summary>
  582. private void CommandPolygon()
  583. {
  584. drawArea.ActiveTool = DrawArea.DrawToolType.Polygon;
  585. }
  586. /// <summary>
  587. /// Show About dialog
  588. /// </summary>
  589. private void CommandAbout()
  590. {
  591. FrmAbout frm = new FrmAbout();
  592. frm.ShowDialog(this);
  593. }
  594. /// <summary>
  595. /// Open new file
  596. /// </summary>
  597. private void CommandNew()
  598. {
  599. docManager.NewDocument();
  600. }
  601. /// <summary>
  602. /// Open file
  603. /// </summary>
  604. private void CommandOpen()
  605. {
  606. docManager.OpenDocument("");
  607. }
  608. /// <summary>
  609. /// Save file
  610. /// </summary>
  611. private void CommandSave()
  612. {
  613. docManager.SaveDocument(DocManager.SaveType.Save);
  614. }
  615. /// <summary>
  616. /// Save As
  617. /// </summary>
  618. private void CommandSaveAs()
  619. {
  620. docManager.SaveDocument(DocManager.SaveType.SaveAs);
  621. }
  622. /// <summary>
  623. /// Undo
  624. /// </summary>
  625. private void CommandUndo()
  626. {
  627. drawArea.Undo();
  628. }
  629. /// <summary>
  630. /// Redo
  631. /// </summary>
  632. private void CommandRedo()
  633. {
  634. drawArea.Redo();
  635. }
  636. #endregion
  637. }
  638. }