Free cookie consent management tool by TermsFeed Policy Generator

source: tags/3.3.3/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/Netron.Diagramming.Core-3.0.2672.12446/Core/Scene graph/Model.cs @ 13398

Last change on this file since 13398 was 4068, checked in by swagner, 14 years ago

Sorted usings and removed unused usings in entire solution (#1094)

File size: 41.6 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.ComponentModel;
4using System.Diagnostics;
5using System.Drawing;
6using System.Windows.Forms;
7namespace Netron.Diagramming.Core {
8  // ----------------------------------------------------------------------
9  /// <summary>
10  /// Implementation of the <see cref="IModel"/> interface; the 'database'
11  /// of the control.
12  /// </summary>
13  // ----------------------------------------------------------------------
14  public partial class Model :
15      IModel,
16      IDisposable {
17    #region Events
18
19    // ------------------------------------------------------------------
20    /// <summary>
21    /// Occurs when the current page has changed.
22    /// </summary>
23    // ------------------------------------------------------------------
24    public event CurrentPageChangedEventHandler OnCurrentPageChanged;
25
26    /// <summary>
27    /// Occurs when an entity is removed from the model
28    /// </summary>
29    public event EventHandler<EntityEventArgs> OnEntityRemoved;
30    /// <summary>
31    /// Occurs when an entity is added to the model.
32    /// </summary>
33    public event EventHandler<EntityEventArgs> OnEntityAdded;
34    /// <summary>
35    /// Occurs when an element of the diagram requests a refresh of a region/rectangle of the canvas
36    /// </summary>
37    public event EventHandler<RectangleEventArgs> OnInvalidateRectangle;
38    /// <summary>
39    /// Occurs when an element of the diagram requests a refresh
40    /// </summary>
41    public event EventHandler OnInvalidate;
42    /// <summary>
43    /// Occurs when the ConnectionCollection has changed
44    /// </summary>
45    public event EventHandler<ConnectionCollectionEventArgs> OnConnectionCollectionChanged;
46    /// <summary>
47    /// Occurs when the cursor is changed and the surface is supposed to set the cursor accordingly.
48    /// </summary>
49    public event EventHandler<CursorEventArgs> OnCursorChange;
50    /// <summary>
51    /// Raises the <see cref="OnConnectionCollectionChanged"/> event
52    /// </summary>
53    /// <param name="e">ConnectionCollection event argument</param>
54    private void RaiseOnConnectionCollectionChanged(ConnectionCollectionEventArgs e) {
55      EventHandler<ConnectionCollectionEventArgs> handler = OnConnectionCollectionChanged;
56      if (handler != null) {
57        handler(this, e);
58      }
59    }
60
61    public void RaiseOnCursorChange(Cursor cursor) {
62      EventHandler<CursorEventArgs> handler = OnCursorChange;
63      if (handler != null)
64        handler(this, new CursorEventArgs(cursor));
65    }
66
67    /// <summary>
68    /// Raises the on invalidate.
69    /// </summary>
70    public void RaiseOnInvalidate() {
71      if (OnInvalidate != null)
72        OnInvalidate(this, EventArgs.Empty);
73    }
74    /// <summary>
75    /// Raises the OnInvalidateRectangle event.
76    /// </summary>
77    /// <param name="rectangle">The rectangle.</param>
78    public void RaiseOnInvalidateRectangle(Rectangle rectangle) {
79      EventHandler<RectangleEventArgs> handler = OnInvalidateRectangle;
80      if (handler != null) {
81        handler(this, new RectangleEventArgs(rectangle));
82      }
83    }
84    /// <summary>
85    /// Occurs when the bounding region (aka client-rectangle) of the canvas has changed
86    /// </summary>
87    public event EventHandler<RectangleEventArgs> OnRectangleChanged;
88    /// <summary>
89    /// Raises the <see cref="OnRectangleChanged"/> event.
90    /// </summary>
91    /// <param name="e"></param>
92    private void RaiseOnRectangleChanged(RectangleEventArgs e) {
93      EventHandler<RectangleEventArgs> handler = OnRectangleChanged;
94      if (handler != null) {
95        handler(this, e);
96      }
97    }
98    /// <summary>
99    /// Occurs when the diagram info (aka user metadata) has changed
100    /// </summary>
101    public event EventHandler<DiagramInformationEventArgs> OnDiagramInformationChanged;
102    /// <summary>
103    /// Raises the <see cref="OnDiagramInformationChanged"/> event.
104    /// </summary>
105    /// <param name="e"></param>
106    private void RaiseOnDiagramInformationChanged(DiagramInformationEventArgs e) {
107      EventHandler<DiagramInformationEventArgs> handler = OnDiagramInformationChanged;
108      if (handler != null) {
109        handler(this, e);
110      }
111    }
112
113    /// <summary>
114    /// Occurs when the Ambience has changed
115    /// </summary>
116    public event EventHandler<AmbienceEventArgs> OnAmbienceChanged;
117    /// <summary>
118    /// Raises the <see cref="OnAmbienceChanged"/> event
119    /// </summary>
120    /// <param name="e"></param>
121    private void RaiseOnAmbienceChanged(AmbienceEventArgs e) {
122      EventHandler<AmbienceEventArgs> handler = OnAmbienceChanged;
123      if (handler != null) {
124        handler(this, e);
125      }
126    }
127
128    /// <summary>
129    /// Raises the <see cref="OnEntityAdded"/> event
130    /// </summary>
131    /// <param name="e">The <see cref="T:Netron.Diagramming.Core.EntityEventArgs"/> instance containing the event data.</param>
132    private void RaiseOnEntityAdded(EntityEventArgs e) {
133      EventHandler<EntityEventArgs> handler = OnEntityAdded;
134      if (handler != null) {
135        handler(this, e);
136      }
137    }
138
139    /// <summary>
140    /// Raises the <see cref="OnEntityRemoved"/> event.
141    /// </summary>
142    /// <param name="e">The <see cref="T:Netron.Diagramming.Core.EntityEventArgs"/> instance containing the event data.</param>
143    private void RaiseOnEntityRemoved(EntityEventArgs e) {
144      EventHandler<EntityEventArgs> handler = OnEntityRemoved;
145      if (handler != null) {
146        handler(this, e);
147      }
148    }
149
150    // ------------------------------------------------------------------
151    /// <summary>
152    /// Raises the <see cref="OnCurrentPageChanged"/> event.
153    /// </summary>
154    /// <param name="e">PageEventArgs</param>
155    // ------------------------------------------------------------------
156    protected virtual void RaiseOnCurrentPageChanged(PageEventArgs e) {
157      if (this.OnCurrentPageChanged != null) {
158        OnCurrentPageChanged(this, e);
159      }
160    }
161
162    #endregion
163
164    #region Fields
165
166    // ------------------------------------------------------------------
167    /// <summary>
168    /// Implementation of IVersion - the current version of
169    /// Model.
170    /// </summary>
171    // ------------------------------------------------------------------
172    protected const double modelVersion = 1.0;
173
174    // ------------------------------------------------------------------
175    /// <summary>
176    /// Specifies if all shape's connectors are shown.
177    /// </summary>
178    // ------------------------------------------------------------------
179    protected bool mShowConnectors = true;
180
181    private GraphicsUnit measurementUnits = GraphicsUnit.Pixel;
182    /// <summary>
183    /// the LayoutRoot field
184    /// </summary>
185    private IShape mLayoutRoot;
186    /// <summary>
187    /// the DefaultPage field
188    /// </summary>
189    [NonSerialized]
190    private IPage mDefaultPage;
191    /// <summary>
192    /// the page collection
193    /// </summary>
194    [NonSerialized]
195    private CollectionBase<IPage> mPages;
196    ///<summary>
197    /// the shapes of the diagram
198    /// </summary>
199    //[NonSerialized]
200    //private CollectionBase<IShape> mShapes;
201    /// <summary>
202    /// the bounding rectangle
203    /// </summary>
204    [NonSerialized]
205    private Rectangle mRectangle;
206    /// <summary>
207    /// the metadata of the diagram
208    /// </summary>
209    [NonSerialized]
210    private DocumentInformation mInformation;
211
212    /// <summary>
213    /// the collection of to-be-painted diagram entities
214    /// </summary>
215    //[NonSerialized]
216    //private CollectionBase<IDiagramEntity> Paintables;
217    /// <summary>
218    /// the CurrentPage field
219    /// </summary>
220    [NonSerialized]
221    private IPage mCurrentPage;
222
223    private float mMeasurementScale = 1.0F;
224    #endregion
225
226    #region Properties
227
228    // ------------------------------------------------------------------
229    /// <summary>
230    /// Gets the current version.
231    /// </summary>
232    // ------------------------------------------------------------------
233    public virtual double Version {
234      get {
235        return modelVersion;
236      }
237    }
238
239    private Selection selection;
240    public Selection Selection {
241      get { return this.selection; }
242      set { this.selection = value; }
243    }
244
245    // ------------------------------------------------------------------
246    /// <summary>
247    /// Specifies if all shape's connectors are shown.
248    /// </summary>
249    // ------------------------------------------------------------------
250    public bool ShowConnectors {
251      get {
252        return this.mShowConnectors;
253      }
254      set {
255        this.mShowConnectors = value;
256        foreach (IPage page in this.mPages) {
257          foreach (IShape shape in page.Shapes) {
258            shape.ShowConnectors = this.mShowConnectors;
259          }
260        }
261      }
262    }
263
264    [Browsable(true)]
265    [Description("Scaling value for logical units.")]
266    public float MeasurementScale {
267      get {
268        return mMeasurementScale;
269      }
270
271      set {
272        mMeasurementScale = value;
273      }
274    }
275
276    [BrowsableAttribute(true)]
277    [Description("Logical unit of measurement")]
278    public GraphicsUnit MeasurementUnits {
279      get {
280        return measurementUnits;
281      }
282
283      set {
284        measurementUnits = value;
285      }
286    }
287
288    // ------------------------------------------------------------------
289    /// <summary>
290    /// Gets or sets the LayoutRoot
291    /// </summary>
292    // ------------------------------------------------------------------
293    public IShape LayoutRoot {
294      get { return mLayoutRoot; }
295      set {
296        mLayoutRoot = value;
297
298      }
299    }
300
301    // ------------------------------------------------------------------       
302    /// <summary>
303    /// Gets the current page.  Use 'SetCurrentPage(IPage page)' or
304    /// 'SetCurrentPage(int index)' to set the current page.
305    /// </summary>
306    // ------------------------------------------------------------------
307    public IPage CurrentPage {
308      get { return mCurrentPage; }
309    }
310
311    // ------------------------------------------------------------------
312    /// <summary>
313    /// Gets the paintables.
314    /// </summary>
315    /// <value>The paintables.</value>
316    // ------------------------------------------------------------------
317    public CollectionBase<IDiagramEntity> Paintables {
318      get {
319        return mCurrentPage.Entities;
320      }
321    }
322
323    // ------------------------------------------------------------------
324    /// <summary>
325    /// Gets the pages of the diagram control.  Use method 'AddPage' to
326    /// add a page so the page gets attached to this Model.
327    /// </summary>
328    /// <value>The pages.</value>
329    // ------------------------------------------------------------------
330    public CollectionBase<IPage> Pages {
331      get { return mPages; }
332    }
333
334    // ------------------------------------------------------------------
335    /// <summary>
336    /// Gets or sets the default page
337    /// </summary>
338    // ------------------------------------------------------------------
339    public IPage DefaultPage {
340      get { return mDefaultPage; }
341      set { mDefaultPage = value; }
342    }
343
344    // ------------------------------------------------------------------
345    /// <summary>
346    /// Gets the shapes of the current page.
347    /// </summary>
348    // ------------------------------------------------------------------
349    public CollectionBase<IShape> Shapes {
350      get {
351        return CurrentPage.Shapes;
352        //return mShapes;
353      }
354      //internal set
355      //{
356      //    mShapes = value;
357      //}
358    }
359
360    // ------------------------------------------------------------------
361    /// <summary>
362    /// Gets or sets the information of the diagram
363    /// </summary>
364    // ------------------------------------------------------------------
365    internal DocumentInformation Information {
366      get {
367        return mInformation;
368      }
369      set {
370        mInformation = value;
371      }
372    }
373
374    // ------------------------------------------------------------------
375    /// <summary>
376    /// Gets the bounding rectangle of the diagram (client rectangle)
377    /// </summary>
378    // ------------------------------------------------------------------
379    public Rectangle Rectangle {
380      get {
381        return mRectangle;
382      }
383      set {
384        mRectangle = value;
385        RaiseOnRectangleChanged(new RectangleEventArgs(value));
386      }
387    }
388
389    // ------------------------------------------------------------------
390    /// <summary>
391    /// Gets the horizontal coordinate of the diagram
392    /// </summary>
393    // ------------------------------------------------------------------
394    public float X {
395      get {
396        return mRectangle.X;
397      }
398    }
399
400    // ------------------------------------------------------------------
401    /// <summary>
402    /// Gets the verticle coordinate of the diagram
403    /// </summary>
404    // ------------------------------------------------------------------
405    public float Y {
406      get {
407        return mRectangle.Y;
408      }
409
410    }
411
412    // ------------------------------------------------------------------
413    /// <summary>
414    /// Gets the width of the diagram
415    /// </summary>
416    // ------------------------------------------------------------------
417    public float Width {
418      get {
419        return mRectangle.Width;
420      }
421    }
422
423    // ------------------------------------------------------------------
424    /// <summary>
425    /// Gets the height of the diagram
426    /// </summary>
427    // ------------------------------------------------------------------
428    public float Height {
429      get {
430        return mRectangle.Height;
431      }
432    }
433
434    // ------------------------------------------------------------------
435    /// <summary>
436    /// Gets or sets the collection of connections
437    /// </summary>
438    // ------------------------------------------------------------------
439    public CollectionBase<IConnection> Connections {
440      get {
441        return CurrentPage.Connections;
442      }
443
444    }
445    #endregion
446
447    #region Constructor
448
449    // ------------------------------------------------------------------
450    /// <summary>
451    /// Default constructor
452    /// </summary>
453    // ------------------------------------------------------------------
454    public Model() {
455      //here I'll have to work on the scene graph
456      //this.mShapes = new CollectionBase<IShape>();
457      //the default page
458
459      //the page collection
460      mPages = new CollectionBase<IPage>();
461      Page p = new Page("Default Page", this);
462      p.Ambience.PageColor = ArtPalette.DefaultPageColor;
463      mPages.Add(p);
464
465      Init();
466    }
467
468    #endregion
469
470    // ------------------------------------------------------------------
471    /// <summary>
472    /// Initializes this object
473    /// <remarks>See also the <see cref="OnDeserialized"/> event for
474    /// post-deserialization actions to which this method is related.
475    /// </remarks>
476    /// </summary>
477    // ------------------------------------------------------------------
478    private void Init() {
479      if (mPages == null) {
480        throw new InconsistencyException(
481            "The page collection is 'null'.");
482      }
483      if (mPages.Count == 0) {
484        throw new InconsistencyException(
485            "The page collection should contain at least one page.");
486      }
487
488      foreach (IPage page in mPages)
489        AttachToPage(page);
490      mDefaultPage = mPages[0];
491      // Initially the current page is the zero-th page in the
492      // collection.
493      SetCurrentPage(0);
494    }
495
496    // ------------------------------------------------------------------
497    /// <summary>
498    /// Adds a page.  This should be used when adding pages rather than
499    /// though the Pages property so the page gets attached to the Model.
500    /// </summary>
501    /// <param name="page">IPage: The page to add.</param>
502    /// <returns>IPage</returns>
503    // ------------------------------------------------------------------
504    public IPage AddPage(IPage page) {
505      mPages.Add(page);
506      AttachToPage(page);
507      return page;
508    }
509
510    // ------------------------------------------------------------------
511    /// <summary>
512    /// Adds a page.  This should be used when adding pages rather than
513    /// though the Pages property so the page gets attached to the Model.
514    /// The page name is set to "Page" plus the new number of pages.
515    /// For example, if there are currently two pages, then "Page3" is
516    /// set as the new page name.
517    /// </summary>
518    /// <returns>IPage</returns>
519    // ------------------------------------------------------------------
520    public IPage AddPage() {
521      string pageName = this.GetDefaultNewPageName();
522      Page page = new Page(pageName, this);
523      return AddPage(page);
524    }
525
526    // ------------------------------------------------------------------
527    /// <summary>
528    /// Deletes the page specified if it is not the default page.
529    /// </summary>
530    /// <param name="page">IPage: The page to remove.</param>
531    /// <param name="allowWarnings">bool: Specifies if the user should
532    /// be given the option to cancel the action if the current page
533    /// has entities.  Also, when set to true, if the current page is
534    /// the default page, then a message box is shown informing the
535    /// user that the default page cannot be deleted.</param>
536    /// <returns>bool: If the delete was successful.  True is returned
537    /// if the current page was removed.</returns>
538    // ------------------------------------------------------------------
539    public bool RemovePage(IPage page, bool allowWarnings) {
540      if (page == this.DefaultPage) {
541        if (allowWarnings) {
542          MessageBox.Show(
543          "The default page cannot be deleted.",
544          "Delete Page Error",
545          MessageBoxButtons.OK,
546          MessageBoxIcon.Error);
547        }
548        return false;
549      }
550
551      int pageIndex = 0;
552      int newCurrentPageIndex = 0;
553
554      // Ask the user if they really want to remove the page if
555      // it has entities if 'allowWarnings' is true.
556      if ((allowWarnings) && (page.Entities.Count > 0)) {
557        if (MessageBox.Show(
558            "Are you sure you want to delete this page?",
559            "Confirm Delete",
560            MessageBoxButtons.YesNo,
561            MessageBoxIcon.Question,
562            MessageBoxDefaultButton.Button1) == DialogResult.No) {
563          return false;
564        }
565      }
566
567      // Now we can continue with deleting the page.
568      // If the page specified is the current page, then we need to set
569      // the current page to another page.  Let's use the previous one
570      // in the list. 
571      if (page == CurrentPage) {
572        pageIndex = Pages.IndexOf(page);
573
574        if (pageIndex > 0) {
575          newCurrentPageIndex = pageIndex - 1;
576        }
577        SetCurrentPage(newCurrentPageIndex);
578      }
579
580      Pages.Remove(page);
581      return true;
582    }
583
584    // ------------------------------------------------------------------
585    /// <summary>
586    /// Returns a new page name that's unique from all the others.
587    /// </summary>
588    /// <returns>string: Returns "Page" plus the number of pages IF A
589    /// NEW PAGE WERE ADDED.  For example, if there are currently two
590    /// pages, then "Page3" is returned.</returns>
591    // ------------------------------------------------------------------
592    public string GetDefaultNewPageName() {
593      string name = "Page" + (Pages.Count + 1).ToString();
594      return name;
595    }
596
597    // ------------------------------------------------------------------
598    /// <summary>
599    /// Sets the current page.
600    /// </summary>
601    /// <param name="page">The page.</param>
602    // ------------------------------------------------------------------
603    public void SetCurrentPage(IPage page) {
604      mCurrentPage = page;
605      RaiseOnAmbienceChanged(new AmbienceEventArgs(page.Ambience));
606      RaiseOnCurrentPageChanged(new PageEventArgs(page));
607
608      //change the paintables as well           
609      //Paintables = new CollectionBase<IDiagramEntity>();
610
611      #region Reload of the z-order, usually only necessary after deserialization
612
613      CollectionBase<IDiagramEntity> collected = new CollectionBase<IDiagramEntity>();
614      //pick up the non-group entities
615      foreach (IDiagramEntity entity in Paintables)
616        if (!typeof(IGroup).IsInstanceOfType(entity))
617          collected.Add(entity);
618
619      if (collected.Count > 0) {
620        Algorithms.SortInPlace<IDiagramEntity>(collected, new SceneIndexComparer<IDiagramEntity>());
621        //Paintables.AddRange(collected);
622      }
623      #endregion
624
625    }
626
627    // ------------------------------------------------------------------
628    /// <summary>
629    /// Sets the current page.
630    /// </summary>
631    /// <param name="pageIndex">Index of the page.</param>
632    // ------------------------------------------------------------------
633    public void SetCurrentPage(int pageIndex) {
634      if (mPages == null ||
635          mPages.Count == 0 ||
636          pageIndex >= mPages.Count ||
637          pageIndex < 0) {
638        throw new IndexOutOfRangeException(
639            "The page index is outside the page range.");
640      }
641      SetCurrentPage(mPages[pageIndex]);
642    }
643
644    // ------------------------------------------------------------------
645    /// <summary>
646    /// Attaches this model to the page specified.  The Model property for
647    /// the page is set and the IPage events needed by this are registered
648    /// for here (OnEntityAdded, OnEntityRemoved, OnClear, and
649    /// OnAmbienceChanged).
650    /// </summary>
651    /// <param name="page">IPage: The page to attach this model to.</param>
652    // ------------------------------------------------------------------
653    private void AttachToPage(IPage page) {
654      page.OnEntityAdded += new EventHandler<EntityEventArgs>(mDefaultPage_OnEntityAdded);
655      page.OnEntityRemoved += new EventHandler<EntityEventArgs>(mDefaultPage_OnEntityRemoved);
656      page.OnClear += new EventHandler(mDefaultPage_OnClear);
657      page.OnAmbienceChanged += new EventHandler<AmbienceEventArgs>(mDefaultPage_OnAmbienceChanged);
658      page.Model = this;
659    }
660
661    void mDefaultPage_OnAmbienceChanged(object sender, AmbienceEventArgs e) {
662      RaiseOnAmbienceChanged(e);
663    }
664
665    #region Paintables transfers on Page changes
666
667    // ------------------------------------------------------------------
668    /// <summary>
669    /// Handles the OnClear event of the DefaultPage.
670    /// </summary>
671    /// <param name="sender">The source of the event.</param>
672    /// <param name="e">The <see cref="T:System.EventArgs"/> instance
673    /// containing the event data.</param>
674    // ------------------------------------------------------------------
675    void mDefaultPage_OnClear(object sender, EventArgs e) {
676      Paintables.Clear();
677    }
678
679    // ------------------------------------------------------------------
680    /// <summary>
681    /// Handles the OnEntityRemoved event of the DefaultPage.
682    /// </summary>
683    /// <param name="sender">The source of the event.</param>
684    /// <param name="e">The
685    /// <see cref="T:Netron.Diagramming.Core.EntityEventArgs"/> instance
686    /// containing the event data.</param>
687    // ------------------------------------------------------------------
688    void mDefaultPage_OnEntityRemoved(object sender, EntityEventArgs e) {
689      if (Paintables.Contains(e.Entity)) {
690        //shift the entities above the one to be removed
691        int index = e.Entity.SceneIndex;
692        foreach (IDiagramEntity entity in Paintables) {
693          if (entity.SceneIndex > index)
694            entity.SceneIndex--;
695        }
696        Paintables.Remove(e.Entity);
697      }
698      //if the selection contains the shape we have to remove it from the selection
699      if (Selection.SelectedItems.Contains(e.Entity)) {
700        Selection.SelectedItems.Remove(e.Entity);
701      }
702      RaiseOnEntityRemoved(e);
703    }
704
705    // ------------------------------------------------------------------
706    /// <summary>
707    /// Handles the OnEntityAdded event of the Page and adds the new
708    /// entity to the Paintables.
709    /// </summary>
710    /// <param name="sender">The source of the event.</param>
711    /// <param name="e">The
712    /// <see cref="T:Netron.Diagramming.Core.EntityEventArgs"/> instance
713    /// containing the event data.</param>
714    // ------------------------------------------------------------------
715    void mDefaultPage_OnEntityAdded(object sender, EntityEventArgs e) {
716      //don't add it if it's already there or if it's a group (unless you want to deploy something special to emphasize a group shape).
717      if (!Paintables.Contains(e.Entity)) {
718        if ((e.Entity is IGroup) && !(e.Entity as IGroup).EmphasizeGroup) {
719          return;
720        }
721        //set the new entity on top of the stack
722        e.Entity.SceneIndex = Paintables.Count;
723        Paintables.Add(e.Entity);
724      }
725      #region Addition callback
726      IAdditionCallback callback = e.Entity.GetService(typeof(IAdditionCallback)) as IAdditionCallback;
727      if (callback != null)
728        callback.OnAddition();
729      #endregion
730      RaiseOnEntityAdded(e);
731    }
732    #endregion
733
734    #region Methods
735
736    #region Ordering methods
737    /// <summary>
738    /// Re-sets the scene-index of the paintables
739    /// </summary>
740    private void ReAssignSceneIndex(CollectionBase<IDiagramEntity> entities) {
741      for (int i = 0; i < entities.Count; i++) {
742        entities[i].SceneIndex = i;
743      }
744    }
745    /// <summary>
746    /// Sends to entity to the bottom of the z-order stack.
747    /// </summary>
748    /// <param name="entity">The entity.</param>
749    public void SendToBack(IDiagramEntity entity) {
750      ILayer layer = CurrentPage.GetLayer(entity);
751      if (layer != null) {
752        layer.Entities.Remove(entity);
753        layer.Entities.Insert(0, entity);
754        ReAssignSceneIndex(layer.Entities);
755        Rectangle rec = entity.Rectangle;
756        rec.Inflate(20, 20);
757        this.RaiseOnInvalidateRectangle(Rectangle);
758      }
759      //if(Paintables.Contains(entity))
760      //{
761      //    Paintables.Remove(entity);
762      //    Paintables.Insert(0, entity);
763      //    ReAssignSceneIndex();
764      //    Rectangle rec = entity.Rectangle;
765      //    rec.Inflate(20, 20);
766      //    this.RaiseOnInvalidateRectangle(Rectangle);
767      //}
768    }
769
770    /// <summary>
771    /// Sends the entity down the z-order stack with the specified amount.
772    /// </summary>
773    /// <param name="entity">The entity.</param>
774    /// <param name="zShift">The z shift.</param>
775    public void SendBackwards(IDiagramEntity entity, int zShift) {
776      ILayer layer = CurrentPage.GetLayer(entity);
777      if (layer != null) {
778        int newpos = layer.Entities.IndexOf(entity) - zShift;
779        //if this is the first in the row you cannot move it lower
780        if (newpos >= 0) {
781          layer.Entities.Remove(entity);
782          layer.Entities.Insert(newpos, entity);
783          ReAssignSceneIndex(layer.Entities);
784          Rectangle rec = entity.Rectangle;
785          rec.Inflate(20, 20);
786          this.RaiseOnInvalidateRectangle(Rectangle);
787        }
788      }
789
790      //if (Paintables.Contains(entity))
791      //{
792      //    int newpos = Paintables.IndexOf(entity) - zShift;
793      //    //if this is the first in the row you cannot move it lower
794      //    if (newpos >= 0)
795      //    {
796      //        Paintables.Remove(entity);
797      //        Paintables.Insert(newpos, entity);
798      //        ReAssignSceneIndex(Paintables);
799      //        Rectangle rec = entity.Rectangle;
800      //        rec.Inflate(20, 20);
801      //        this.RaiseOnInvalidateRectangle(Rectangle);
802      //    }
803      //}
804    }
805    /// <summary>
806    /// Sends the entity one level down the z-order stack.
807    /// </summary>
808    /// <param name="entity">The entity.</param>
809    public void SendBackwards(IDiagramEntity entity) {
810      SendBackwards(entity, 1);
811    }
812
813    /// <summary>
814    /// Sends the entity to the top of the z-order stack.
815    /// </summary>
816    /// <param name="entity">The entity.</param>
817    public void SendForwards(IDiagramEntity entity) {
818      SendForwards(entity, 1);
819    }
820    /// <summary>
821    /// Sends the entity up the z-order stack with the specified amount.
822    /// </summary>
823    /// <param name="entity">The entity.</param>
824    /// <param name="zShift">The z shift.</param>
825    public void SendForwards(IDiagramEntity entity, int zShift) {
826      ILayer layer = CurrentPage.GetLayer(entity);
827      if (layer != null) {
828        int newpos = layer.Entities.IndexOf(entity) + zShift;
829        //if this is the last in the row you cannot move it higher
830        if (newpos < layer.Entities.Count) {
831          layer.Entities.Remove(entity);
832          layer.Entities.Insert(newpos, entity); //does it works when this is an addition at the top?
833          ReAssignSceneIndex(layer.Entities);
834          Rectangle rec = entity.Rectangle;
835          rec.Inflate(20, 20);
836          this.RaiseOnInvalidateRectangle(Rectangle);
837        }
838      }
839
840      //if (Paintables.Contains(entity) && zShift>=1)
841      //{
842      //    int newpos = Paintables.IndexOf(entity) + zShift;
843      //    //if this is the last in the row you cannot move it higher
844      //    if (newpos < Paintables.Count)
845      //    {
846      //        Paintables.Remove(entity);
847      //        Paintables.Insert(newpos, entity); //does it works when this is an addition at the top?
848      //        ReAssignSceneIndex(Paintables);
849      //        Rectangle rec = entity.Rectangle;
850      //        rec.Inflate(20, 20);
851      //        this.RaiseOnInvalidateRectangle(Rectangle);
852      //    }
853      //}
854    }
855
856    /// <summary>
857    /// Sends the entity to the front of the z-order stack.
858    /// </summary>
859    /// <param name="entity">The entity.</param>
860    public void SendToFront(IDiagramEntity entity) {
861      ILayer layer = CurrentPage.GetLayer(entity);
862      if (layer != null) {
863        layer.Entities.Remove(entity);
864        layer.Entities.Add(entity);
865        ReAssignSceneIndex(layer.Entities);
866        Rectangle rec = entity.Rectangle;
867        rec.Inflate(20, 20);
868        this.RaiseOnInvalidateRectangle(Rectangle);
869      }
870
871      //if(Paintables.Contains(entity))
872      //{
873      //    Paintables.Remove(entity);
874      //    Paintables.Add(entity);
875      //    ReAssignSceneIndex(Paintables);
876      //    Rectangle rec = entity.Rectangle;
877      //    rec.Inflate(20, 20);
878      //    this.RaiseOnInvalidateRectangle(Rectangle);
879      //}
880    }
881    #endregion
882
883    #region Diagram manipulation actions
884
885    // ------------------------------------------------------------------
886    /// <summary>
887    /// Returns the number of shapes in the current page that are of
888    /// the type specified.
889    /// </summary>
890    /// <param name="type">Type</param>
891    /// <returns>int</returns>
892    // ------------------------------------------------------------------
893    public int NumberOfShapes(Type type) {
894      int count = 0;
895      foreach (IShape shape in Shapes) {
896        if (shape.GetType() == type) {
897          count++;
898        }
899      }
900      return count;
901    }
902
903    // ------------------------------------------------------------------
904    /// <summary>
905    /// Gets the shape at the specified location.  If no shape could be
906    /// found then 'null' is returned.
907    /// </summary>
908    /// <param name="surfacePoint">Point: The location in world
909    /// coordinates.</param>
910    /// <returns>IShape</returns>
911    // ------------------------------------------------------------------
912    public IShape GetShapeAt(Point surfacePoint) {
913      foreach (IShape shape in this.CurrentPage.Shapes) {
914        if (shape.Hit(surfacePoint)) {
915          return shape;
916        }
917      }
918      return null;
919    }
920
921    // ------------------------------------------------------------------
922    /// <summary>
923    /// Adds an entity to the diagram.  The magnification level for the
924    /// entity is set to the current magnification level of the current
925    /// page.
926    /// </summary>
927    /// <param name="entity">IDiagramEntity: The entity to add.</param>
928    /// <returns>IDiagramEntity: The added entity.</returns>
929    // ------------------------------------------------------------------
930    public IDiagramEntity AddEntity(IDiagramEntity entity) {
931      SetModel(entity);
932      //By default the new entity is added to the default layer in the
933      // current page.
934      CurrentPage.DefaultLayer.Entities.Add(entity);
935      entity.Attached(CurrentPage.DefaultLayer);
936      entity.Magnification = CurrentPage.Magnification;
937      return entity;
938    }
939
940    // ------------------------------------------------------------------
941    /// <summary>
942    /// Adds a shape to the diagram
943    /// </summary>
944    /// <param name="shape">IShape: The shape to add.</param>
945    /// <returns>IShape: The added shape.</returns>
946    // ------------------------------------------------------------------
947    public IShape AddShape(IShape shape) {
948
949      SetModel(shape);
950      // By default the new shape is added to the default layer in the
951      // current page.
952      CurrentPage.DefaultLayer.Entities.Add(shape);
953      shape.Attached(CurrentPage.DefaultLayer);
954      shape.ShowConnectors = this.mShowConnectors;
955      return shape;
956
957    }
958
959    // ------------------------------------------------------------------
960    /// <summary>
961    /// Adds a connection to the diagram
962    /// </summary>
963    /// <param name="connection">a connection</param>
964    // ------------------------------------------------------------------
965    public IConnection AddConnection(IConnection connection) {
966      SetModel(connection);
967      CurrentPage.DefaultLayer.Entities.Add(connection);
968      connection.Attached(CurrentPage.DefaultLayer);
969      return connection;
970    }
971
972    // ------------------------------------------------------------------
973    /// <summary>
974    /// Adds a connection between two shape connectors.       
975    /// </summary>
976    /// <param name="from">From connector.</param>
977    /// <param name="to">To connector.</param>
978    // ------------------------------------------------------------------
979    public IConnection AddConnection(IConnector from, IConnector to) {
980      Connection con = new Connection(from.Point, to.Point);
981      this.AddConnection(con);
982      return con;
983    }
984
985    // ------------------------------------------------------------------
986    /// <summary>
987    /// Sets the model (recursively) on the given entity.
988    /// </summary>
989    /// <param name="entity">The entity.</param>
990    // ------------------------------------------------------------------
991    public void SetModel(IDiagramEntity entity) {
992      if (entity is IConnector) {
993        (entity as IConnector).Model = this;
994      } else if (entity is IConnection) {
995        IConnection con = entity as IConnection;
996        con.Model = this;
997        Debug.Assert(con.From != null, "The 'From' connector is not set.");
998        con.From.Model = this;
999        Debug.Assert(con.From != null, "The 'To' connector is not set.");
1000        con.To.Model = this;
1001      } else if (entity is IShape) {
1002        IShape shape = entity as IShape;
1003        shape.Model = this;
1004        foreach (IConnector co in shape.Connectors) {
1005          co.Model = this;
1006        }
1007      } else if (entity is IGroup) {
1008        IGroup group = entity as IGroup;
1009        group.Model = this;
1010        foreach (IDiagramEntity child in group.Entities) {
1011          SetModel(child);
1012        }
1013      }
1014    }
1015
1016    // ------------------------------------------------------------------
1017    /// <summary>
1018    /// Removes the shape from the diagram.
1019    /// </summary>
1020    /// <param name="shape">The shape.</param>
1021    // ------------------------------------------------------------------
1022    public void RemoveShape(IShape shape) {
1023      //remove it from the layer(s)
1024      foreach (IPage page in mPages) {
1025        foreach (ILayer layer in page.Layers) {
1026          if (layer.Entities.Contains(shape)) {
1027            layer.Entities.Remove(shape);
1028            shape.Detached(CurrentPage.DefaultLayer);
1029          }
1030        }
1031      }
1032
1033      // The old way, when there weren't multiple pages and layers.
1034      //if (CurrentPage.DefaultLayer.Entities.Contains(shape))
1035      //{
1036      //    CurrentPage.DefaultLayer.Entities.Remove(shape);
1037      //    shape.Detached(CurrentPage.DefaultLayer);
1038      //}
1039    }
1040
1041    // ------------------------------------------------------------------
1042    /// <summary>
1043    /// Removes all entities that are currently selected.
1044    /// </summary>
1045    /// <param name="entity">The entity.</param>
1046    // ------------------------------------------------------------------
1047    public void RemoveSelectedItems() {
1048      if (this.Selection.SelectedItems.Count < 1) {
1049        return;
1050      }
1051
1052      int numberOfItems = this.Selection.SelectedItems.Count;
1053      for (int i = 0; i < numberOfItems - 1; i++) {
1054        IDiagramEntity entity = Selection.SelectedItems[0];
1055        foreach (IPage page in mPages) {
1056          foreach (ILayer layer in page.Layers) {
1057            if (layer.Entities.Contains(entity)) {
1058              layer.Entities.Remove(entity);
1059              entity.Detached(DefaultPage.DefaultLayer);
1060            }
1061          }
1062        }
1063      }
1064    }
1065
1066    // ------------------------------------------------------------------
1067    /// <summary>
1068    /// Removes the specified entity.
1069    /// </summary>
1070    /// <param name="entity">The entity.</param>
1071    // ------------------------------------------------------------------
1072    public void Remove(IDiagramEntity entity) {
1073      if (CurrentPage.DefaultLayer.Entities.Contains(entity)) {
1074        CurrentPage.DefaultLayer.Entities.Remove(entity);
1075        entity.Detached(CurrentPage.DefaultLayer);
1076      }
1077    }
1078
1079    // ------------------------------------------------------------------
1080    /// <summary>
1081    /// Adds a collection of entities to the diagram
1082    /// </summary>
1083    /// <param name="collection">The collection.</param>
1084    // ------------------------------------------------------------------
1085    public void AddEntities(CollectionBase<IDiagramEntity> collection) {
1086      foreach (IDiagramEntity entity in collection) {
1087        SetModel(entity);
1088        CurrentPage.DefaultLayer.Entities.Add(entity);
1089        entity.Attached(CurrentPage.DefaultLayer);
1090      }
1091    }
1092
1093    // ------------------------------------------------------------------
1094    /// <summary>
1095    /// Unwraps an entity
1096    /// <list type="bullet">
1097    /// <term>Uid</term><description>Generates a new <see cref="IDiagramEntity.Uid"/> for the entity. </description>
1098    /// <tem>Model</tem><description>Assigns the Model property to the entity.</description>
1099    ///
1100    /// </list>
1101    /// </summary>
1102    // ------------------------------------------------------------------
1103    public void Unwrap(IDiagramEntity entity) {
1104      //set a new unique identifier for this copied object
1105      entity.NewUid(true);
1106      //this assignment will be recursive if needed
1107      SetModel(entity);
1108      CurrentPage.DefaultLayer.Entities.Add(entity);
1109      entity.Attached(CurrentPage.DefaultLayer);
1110
1111    }
1112
1113    // ------------------------------------------------------------------
1114    /// <summary>
1115    /// Unwraps the specified collection.
1116    /// </summary>
1117    /// <param name="collection">The collection.</param>
1118    // ------------------------------------------------------------------
1119    public void Unwrap(CollectionBase<IDiagramEntity> collection) {
1120      if (collection == null)
1121        return;
1122      foreach (IDiagramEntity entity in collection) {
1123        Unwrap(entity);
1124      }
1125      //reconnect the connectors, just like the deserialization of a filed diagram
1126      Dictionary<Guid, Anchor>.Enumerator enumer = Anchors.GetEnumerator();
1127      System.Collections.Generic.KeyValuePair<Guid, Anchor> pair;
1128      Anchor anchor;
1129      while (enumer.MoveNext()) {
1130        pair = enumer.Current;
1131        anchor = pair.Value;
1132        if (anchor.Parent != Guid.Empty) //there's a parent connector
1133                {
1134          if (Anchors.ContainsKey(anchor.Parent)) {
1135            Anchors.GetAnchor(anchor.Parent).Instance.AttachConnector(anchor.Instance);
1136          }
1137        }
1138      }
1139      //clean up the anchoring matrix
1140      Anchors.Clear();
1141    }
1142
1143    // ------------------------------------------------------------------
1144    /// <summary>
1145    /// Clears the current page.
1146    /// </summary>
1147    // ------------------------------------------------------------------
1148    public void Clear() {
1149      //clear the scene-graph
1150      this.CurrentPage.DefaultLayer.Entities.Clear();
1151    }
1152    #endregion
1153
1154    #endregion
1155
1156    #region Standard IDispose implementation
1157
1158    // ------------------------------------------------------------------
1159    /// <summary>
1160    /// Disposes the view.
1161    /// </summary>
1162    // ------------------------------------------------------------------
1163    public void Dispose() {
1164      Dispose(true);
1165      GC.SuppressFinalize(this);
1166    }
1167
1168    // ------------------------------------------------------------------
1169    /// <summary>
1170    /// Disposes the view.
1171    /// </summary>
1172    /// <param name="disposing">if set to <c>true</c> [disposing].</param>
1173    // ------------------------------------------------------------------
1174    private void Dispose(bool disposing) {
1175      if (disposing) {
1176
1177      }
1178
1179    }
1180
1181    #endregion
1182  }
1183}
Note: See TracBrowser for help on using the repository browser.