1 namespace System.Workflow.Activities
2 {
3     using System;
4     using System.Text;
5     using System.Reflection;
6     using System.Collections;
7     using System.Collections.Generic;
8     using System.Collections.ObjectModel;
9     using System.CodeDom;
10     using System.ComponentModel;
11     using System.ComponentModel.Design;
12     using System.Drawing.Design;
13     using System.Drawing;
14     using System.Drawing.Drawing2D;
15     using System.Diagnostics;
16     using System.IO;
17     using System.Windows.Forms;
18     using System.Workflow.ComponentModel;
19     using System.Workflow.ComponentModel.Design;
20     using System.Runtime.Serialization;
21     using Microsoft.Win32;
22     using System.Runtime.InteropServices;
23     using System.Workflow.ComponentModel.Serialization;
24     using System.Globalization;
25     using System.ComponentModel.Design.Serialization;
26     using System.Resources;
27 
28     #region StateDesigner Class
29     [DesignerSerializer(typeof(StateDesignerLayoutSerializer), typeof(WorkflowMarkupSerializer))]
30     [ActivityDesignerTheme(typeof(StateDesignerTheme))]
31     [System.Runtime.InteropServices.ComVisible(false)]
32     internal partial class StateDesigner : FreeformActivityDesigner
33     {
34         #region Fields
35 
36         internal static readonly Image CompletedState = DR.GetImage(DR.CompletedState);
37         internal static readonly Image InitialState = DR.GetImage(DR.InitialState);
38         private const string ActiveDesignerNamePropertyName = "ActiveDesignerName";
39 
40         // 30 is the margin around the designer
41         // this value comes from DefaultWorkflowLayout.Separator, but this
42         // class is internal
43         internal static Size Separator = new Size(30, 30);
44         private const int DefaultStateDesignerAutoLayoutDistance = 16;
45 
46         private ActivityDesigner _activeDesigner;
47 
48         private bool _dragDropActive;
49         internal bool _ensuringVisible;
50         private Layout _rootDesignerLayout;
51         private DesignerLinkLayout _designerLinkLayout;
52         private StateDesigner _rootStateDesigner;
53         private Size _stateSize;
54         private Point _stateLocation;
55         private Size _stateMinimumSize;
56         private Size _minimumSize = Size.Empty;
57         private bool _performingLayout = false;
58 
59         private EventHandlersLayout _eventHandlersLayout;
60         private EventDrivenLayout _eventDrivenLayout;
61         private Dictionary<Activity, DesignerLayout> _designerLayouts;
62         private StatesLayout _statesLayout;
63         private TitleBarLayout _titleBarLayout;
64         private ContainedDesignersParser _designersParser;
65         private ISelectionService _selectionService;
66         private ActivityDesignerVerbCollection _verbs;
67         private string _helpText;
68         private bool _needsAutoLayout = false;
69 
70         //
71 
72 
73 
74 
75 
76 
77 
78         private bool _addingSetState = true;
79         private bool _removingSetState = true;
80 
81         #endregion
82 
83         #region Constructor
84         /// <summary>
85         /// Default constructor for the StateDesigner
86         /// </summary>
StateDesigner()87         public StateDesigner()
88         {
89         }
90 
Initialize(Activity activity)91         protected override void Initialize(Activity activity)
92         {
93             base.Initialize(activity);
94             EnsureDesignerExtender();
95             _titleBarLayout = new TitleBarLayout(this);
96             _eventDrivenLayout = new EventDrivenLayout(this, _titleBarLayout);
97             _eventHandlersLayout = new EventHandlersLayout(this);
98             _statesLayout = new StatesLayout(this, _titleBarLayout, _eventHandlersLayout);
99             _designerLinkLayout = new DesignerLinkLayout(this);
100             _designerLinkLayout.MouseDown += new MouseEventHandler(this.StateDesignerLinkMouseDown);
101             this.AutoSizeMargin = new Size(16, 24);
102             this.AutoSize = true;
103         }
104 
EnsureDesignerExtender()105         private void EnsureDesignerExtender()
106         {
107             bool addExtender = true;
108             IExtenderListService extenderListService = GetService(typeof(IExtenderListService)) as IExtenderListService;
109             if (extenderListService != null)
110             {
111                 foreach (IExtenderProvider extenderProvider in extenderListService.GetExtenderProviders())
112                 {
113                     if (extenderProvider.GetType() == typeof(StateDesignerPropertyExtender))
114                     {
115                         addExtender = false;
116                         break;
117                     }
118                 }
119             }
120 
121             if (addExtender)
122             {
123                 IExtenderProviderService extenderProviderService = GetService(typeof(IExtenderProviderService)) as IExtenderProviderService;
124                 if (extenderProviderService != null)
125                 {
126                     extenderProviderService.AddExtenderProvider(new StateDesignerPropertyExtender());
127                     TypeDescriptor.Refresh(Activity);
128                 }
129             }
130         }
131 
Dispose(bool disposing)132         protected override void Dispose(bool disposing)
133         {
134             if (disposing)
135             {
136                 _designerLinkLayout.MouseDown -= new MouseEventHandler(this.StateDesignerLinkMouseDown);
137             }
138 
139             base.Dispose(disposing);
140         }
141 
142         #endregion
143 
144         #region Properties
145 
146         #region Public Properties
147 
148         public override bool CanExpandCollapse
149         {
150             get
151             {
152                 return false;
153             }
154         }
155 
156         public override object FirstSelectableObject
157         {
158             get
159             {
160                 if (!IsVisible)
161                     return null;
162 
163                 if (this.HasActiveDesigner)
164                     return this.ActiveDesigner.Activity;
165 
166                 if (this.DesignersParser.Ordered.Count > 0)
167                     return this.DesignersParser.Ordered[0].Activity;
168 
169                 return null;
170             }
171         }
172 
173         public override object LastSelectableObject
174         {
175             get
176             {
177                 if (!IsVisible)
178                     return null;
179 
180                 if (this.HasActiveDesigner)
181                     return this.ActiveDesigner.Activity;
182 
183                 if (this.DesignersParser.Ordered.Count > 0)
184                     return this.DesignersParser.Ordered[this.DesignersParser.Ordered.Count - 1].Activity;
185 
186                 return null;
187             }
188         }
189 
190         public override Point Location
191         {
192             get
193             {
194                 return base.Location;
195             }
196             set
197             {
198                 if (base.Location == value)
199                     return;
200 
201                 if (this.HasActiveDesigner && !this.PerformingLayout && !this.IsRootStateDesigner)
202                 {
203                     this._stateLocation = value;
204                 }
205                 else
206                 {
207                     if (this.IsRootStateDesigner)
208                     {
209                         bool previousPerformingLayout = this.PerformingLayout;
210                         this.PerformingLayout = true;
211                         try
212                         {
213                             base.Location = value;
214                         }
215                         finally
216                         {
217                             this.PerformingLayout = previousPerformingLayout;
218                         }
219                     }
220                     else
221                     {
222                         base.Location = value;
223                     }
224 
225                     // note that we must use base.Location instead of
226                     // value in the line below, because the
227                     // base implementation of the Location property may
228                     // auto adjust the value depending on auto layouting
229                     // characteristics
230                     this.RootDesignerLayout.MoveLayout(base.Location);
231                     Invalidate();
232                 }
233             }
234         }
235 
236         public override Size Size
237         {
238             get
239             {
240                 return base.Size;
241             }
242             set
243             {
244                 if (this.HasActiveDesigner && !this.PerformingLayout && !this.IsRootStateDesigner)
245                 {
246                     this._stateSize = value;
247                 }
248                 else
249                 {
250                     if (this.IsRootStateDesigner)
251                     {
252                         bool previousPerformingLayout = this.PerformingLayout;
253                         this.PerformingLayout = true;
254                         try
255                         {
256                             base.Size = value;
257                         }
258                         finally
259                         {
260                             this.PerformingLayout = previousPerformingLayout;
261                         }
262                     }
263                     else
264                     {
265                         base.Size = value;
266                     }
267 
268                     Size newSize = base.Size;
269                     this.RootDesignerLayout.ResizeLayout(newSize);
270                 }
271             }
272         }
273 
274         public override string Text
275         {
276             get
277             {
278                 string text = base.Text;
279                 if (String.IsNullOrEmpty(text))
280                 {
281                     text = this.Activity.GetType().Name;
282                 }
283                 return text;
284             }
285         }
286 
287         #endregion
288 
289         #region Protected Properties
290 
291         public override Image Image
292         {
293             get
294             {
295                 StateActivity state = this.Activity as StateActivity;
296                 if (state != null)
297                 {
298                     if (StateMachineHelpers.IsLeafState(state))
299                     {
300                         if (StateMachineHelpers.IsInitialState(state))
301                         {
302                             if (!StateMachineHelpers.IsCompletedState(state))
303                                 return GetInitialStateDesignerImage(this);
304                         }
305                         else
306                         {
307                             if (StateMachineHelpers.IsCompletedState(state))
308                                 return GetCompletedStateDesignerImage(this);
309                         }
310                     }
311                 }
312                 return base.Image;
313             }
314             protected set
315             {
316                 base.Image = value;
317             }
318         }
319 
320         protected override Rectangle ExpandButtonRectangle
321         {
322             get
323             {
324                 return Rectangle.Empty;
325             }
326         }
327 
328         /// <summary>
329         /// Gets the array of glyphs with which to adorn the designer.
330         /// </summary>
331         protected override ActivityDesignerGlyphCollection Glyphs
332         {
333             get
334             {
335                 ActivityDesignerGlyphCollection glyphs = new ActivityDesignerGlyphCollection();
336 
337                 glyphs.AddRange(base.Glyphs);
338 
339                 if (!this.HasActiveDesigner)
340                 {
341                     foreach (EventDrivenDesigner eventDrivenDesigner in this.DesignersParser.EventDrivenDesigners)
342                     {
343                         Layout selectedLayout = this.RootDesignerLayout.GetLayout(eventDrivenDesigner);
344                         if (selectedLayout != null)
345                         {
346                             if (eventDrivenDesigner.IsSelected)
347                             {
348                                 LayoutSelectionGlyph glyph = new LayoutSelectionGlyph(selectedLayout);
349                                 glyphs.Add(glyph);
350                             }
351                             if (!eventDrivenDesigner.Activity.Enabled)
352                             {
353                                 CommentLayoutGlyph glyph = new CommentLayoutGlyph(selectedLayout);
354                                 glyphs.Add(glyph);
355                             }
356                         }
357                     }
358 
359                     foreach (StateInitializationDesigner stateInitializationDesigner in this.DesignersParser.StateInitializationDesigners)
360                     {
361                         Layout selectedLayout = this.RootDesignerLayout.GetLayout(stateInitializationDesigner);
362                         if (selectedLayout != null)
363                         {
364                             if (stateInitializationDesigner.IsSelected)
365                             {
366                                 LayoutSelectionGlyph glyph = new LayoutSelectionGlyph(selectedLayout);
367                                 glyphs.Add(glyph);
368                             }
369                             if (!stateInitializationDesigner.Activity.Enabled)
370                             {
371                                 CommentLayoutGlyph glyph = new CommentLayoutGlyph(selectedLayout);
372                                 glyphs.Add(glyph);
373                             }
374                         }
375                     }
376 
377                     foreach (StateFinalizationDesigner stateFinalizationDesigner in this.DesignersParser.StateFinalizationDesigners)
378                     {
379                         Layout selectedLayout = this.RootDesignerLayout.GetLayout(stateFinalizationDesigner);
380                         if (selectedLayout != null)
381                         {
382                             if (stateFinalizationDesigner.IsSelected)
383                             {
384                                 LayoutSelectionGlyph glyph = new LayoutSelectionGlyph(selectedLayout);
385                                 glyphs.Add(glyph);
386                             }
387                             if (!stateFinalizationDesigner.Activity.Enabled)
388                             {
389                                 CommentLayoutGlyph glyph = new CommentLayoutGlyph(selectedLayout);
390                                 glyphs.Add(glyph);
391                             }
392                         }
393                     }
394                 }
395 
396                 return glyphs;
397             }
398         }
399         protected override Rectangle ImageRectangle
400         {
401             get
402             {
403                 if (this.HasActiveDesigner && !this.IsRootStateDesigner)
404                     return new Rectangle(-1, -1, 1, 1); // Create a rectangle outside the window to hide the icon
405 
406                 return _titleBarLayout.ImageLayout.Bounds;
407             }
408         }
409 
410         protected override Rectangle TextRectangle
411         {
412             get
413             {
414                 if (this.HasActiveDesigner && !this.IsRootStateDesigner)
415                     return Rectangle.Empty;
416                 else
417                     return _titleBarLayout.TextLayout.Bounds;
418             }
419         }
420 
421         protected override ActivityDesignerVerbCollection Verbs
422         {
423             get
424             {
425                 ActivityDesignerVerbCollection verbs = new ActivityDesignerVerbCollection();
426 
427                 verbs.AddRange(base.Verbs);
428 
429                 if (_verbs == null)
430                 {
431                     _verbs = new ActivityDesignerVerbCollection();
432 
433                     ActivityDesignerVerb stateMachineView = new ActivityDesignerVerb(this,
434                         DesignerVerbGroup.General,
435                         DR.GetString(DR.StateMachineView),
436                         new EventHandler(OnStateMachineView),
437                         new EventHandler(OnStatusStateMachineView));
438                     _verbs.Add(stateMachineView);
439 
440                     ActivityDesignerVerb setAsInitialState = new ActivityDesignerVerb(this,
441                         DesignerVerbGroup.General,
442                         DR.GetString(DR.SetAsInitialState),
443                         new EventHandler(OnSetAsInitialState),
444                         new EventHandler(OnStatusSetAsInitialState));
445                     _verbs.Add(setAsInitialState);
446 
447                     ActivityDesignerVerb setAsCompletedState = new ActivityDesignerVerb(this,
448                         DesignerVerbGroup.General,
449                         DR.GetString(DR.SetAsCompletedState),
450                         new EventHandler(OnSetAsCompletedState),
451                         new EventHandler(OnStatusSetAsCompletedState));
452                     _verbs.Add(setAsCompletedState);
453 
454                     ActivityDesignerVerb addState = new ActivityDesignerVerb(this,
455                         DesignerVerbGroup.General,
456                         DR.GetString(DR.AddState),
457                         new EventHandler(OnAddState),
458                         new EventHandler(OnStatusAddState));
459                     _verbs.Add(addState);
460 
461                     ActivityDesignerVerb addEventDrivenVerb = new ActivityDesignerVerb(this,
462                         DesignerVerbGroup.General,
463                         DR.GetString(DR.AddEventDriven),
464                         new EventHandler(OnAddEventDriven),
465                         new EventHandler(OnStatusAddEventDriven));
466                     _verbs.Add(addEventDrivenVerb);
467 
468                     ActivityDesignerVerb addStateInitialization = new ActivityDesignerVerb(this,
469                         DesignerVerbGroup.General,
470                         DR.GetString(DR.AddStateInitialization),
471                         new EventHandler(OnAddStateInitialization),
472                         new EventHandler(OnStatusAddStateInitialization));
473                     _verbs.Add(addStateInitialization);
474 
475                     ActivityDesignerVerb addStateFinalization = new ActivityDesignerVerb(this,
476                         DesignerVerbGroup.General,
477                         DR.GetString(DR.AddStateFinalization),
478                         new EventHandler(OnAddStateFinalization),
479                         new EventHandler(OnStatusAddStateFinalization));
480                     _verbs.Add(addStateFinalization);
481                 }
482 
483                 verbs.AddRange(this._verbs);
484 
485                 return verbs;
486             }
487         }
488 
489         protected override bool ShowConnectorsInForeground
490         {
491             get
492             {
493                 return true;
494             }
495         }
496 
497         #endregion Protected Properties
498 
499         #region Private Properties
500 
501         internal ActivityDesigner ActiveDesigner
502         {
503             get
504             {
505                 return _activeDesigner;
506             }
507             set
508             {
509                 if (_activeDesigner == value)
510                     return;
511 
512                 // if we're setting to a new active designer then we need to make sure
513                 // that we don't have one active yet.
514                 Debug.Assert((value == null) || (value != null && _activeDesigner == null));
515 
516                 _activeDesigner = value;
517 
518                 // Don't use AutoSize in the EventDriven view
519                 this.AutoSize = (value == null);
520 
521                 RefreshDesignerVerbs();
522 
523                 if (IsRootStateDesigner)
524                 {
525                     PerformLayout();
526                 }
527                 else
528                 {
529                     StateDesigner parentStateDesigner = ParentDesigner as StateDesigner;
530                     if (value == null)
531                         SetActiveDesignerHelper(parentStateDesigner, null);
532                     else
533                         SetActiveDesignerHelper(parentStateDesigner, this);
534                 }
535 
536                 // When switching back and forth between
537                 // the EventDriven view or State Machine View
538                 // we preserve the location of the StateDesigner
539                 if (_activeDesigner == null)
540                 {
541                     // Important: _minimumSize needs to be restored before
542                     // this.Size, because base.Size honors _minimumSize
543                     _minimumSize = _stateMinimumSize;
544                     this.Location = _stateLocation;
545                     this.Size = _stateSize;
546                 }
547                 else
548                 {
549                     _stateLocation = this.Location;
550                     _stateSize = this.Size;
551                     _stateMinimumSize = _minimumSize;
552                     _minimumSize = Size.Empty;
553                 }
554             }
555         }
556 
557         // This property is used to signal to the OnConnectorAdded method
558         // it is necessary to add a SetState activity or not. For example,
559         // when the user manually draws a connector, we need to add a corresponding
560         // SetState activity, but when the user adds a SetState activity directly
561         // to the event driven, we have code that will automatically create a
562         // corresponding connector. When this happens OnConnectorAdded gets called
563         // but we cannot add another SetState, otherwise we will end up with
564         // duplicate SetState activities.
565         internal bool AddingSetState
566         {
567             get
568             {
569                 return _addingSetState;
570             }
571             set
572             {
573                 _addingSetState = value;
574             }
575         }
576 
577         internal bool RemovingSetState
578         {
579             get
580             {
581                 return _removingSetState;
582             }
583             set
584             {
585                 _removingSetState = value;
586             }
587         }
588 
589         internal bool PerformingLayout
590         {
591             get
592             {
593                 return this.RootStateDesigner._performingLayout;
594             }
595             set
596             {
597                 Debug.Assert(this.IsRootStateDesigner);
598                 this._performingLayout = value;
599             }
600         }
601 
602         internal Dictionary<Activity, DesignerLayout> DesignerLayouts
603         {
604             get
605             {
606                 if (_designerLayouts == null)
607                 {
608                     _designerLayouts = new Dictionary<Activity, DesignerLayout>();
609                 }
610                 return _designerLayouts;
611             }
612         }
613 
614         private ContainedDesignersParser DesignersParser
615         {
616             get
617             {
618                 if (_designersParser == null)
619                 {
620                     _designersParser = new ContainedDesignersParser(this.ContainedDesigners);
621                 }
622                 return _designersParser;
623             }
624             set
625             {
626                 _designersParser = value;
627             }
628         }
629 
630         internal bool HasActiveDesigner
631         {
632             get
633             {
634                 return (this.ActiveDesigner != null);
635             }
636         }
637 
638         private bool IsStateCustomActivity
639         {
640             get
641             {
642                 StateActivity state = (StateActivity)this.Activity;
643                 if (StateMachineHelpers.IsStateMachine(state) ||
644                     state.Parent != null)
645                     return false;
646                 else
647                     return true;
648             }
649         }
650 
651         internal virtual string HelpText
652         {
653             get
654             {
655                 if (_helpText == null)
656                 {
657                     _helpText = DR.GetString(DR.StateHelpText);
658                 }
659                 return _helpText;
660             }
661         }
662 
663         private bool DragDropActive
664         {
665             get
666             {
667                 return _dragDropActive;
668             }
669             set
670             {
671                 if (value == _dragDropActive)
672                     return;
673                 _dragDropActive = value;
674                 Invalidate();
675             }
676         }
677 
678         private DesignerLinkLayout InlineLayout
679         {
680             get
681             {
682                 return _designerLinkLayout;
683             }
684         }
685 
686         internal bool IsRootStateDesigner
687         {
688             get
689             {
690                 // if the site is null, then it means
691                 // that the designer was created buy not
692                 // added to the WorkflowView yet. In
693                 // this case we cannot assume that just because
694                 // the activity is the root just because
695                 // it doesn't have a parent
696                 return (this.Activity.Site != null) &&
697                     StateMachineHelpers.IsRootState((StateActivity)this.Activity);
698             }
699         }
700 
701         internal ReadOnlyCollection<Rectangle> EventHandlersBounds
702         {
703             get
704             {
705                 List<Rectangle> excluded = new List<Rectangle>();
706                 foreach (DesignerLayout layout in this.DesignerLayouts.Values)
707                 {
708                     Rectangle bounds = layout.Bounds;
709                     bounds.Inflate(0, 4);
710                     excluded.Add(bounds);
711                 }
712                 return excluded.AsReadOnly();
713             }
714         }
715 
716         internal StateDesigner RootStateDesigner
717         {
718             get
719             {
720                 if (_rootStateDesigner == null)
721                 {
722                     StateActivity rootState = StateMachineHelpers.GetRootState((StateActivity)this.Activity);
723                     _rootStateDesigner = GetDesigner(rootState) as StateDesigner;
724                 }
725                 return _rootStateDesigner;
726             }
727         }
728 
729         public override Size MinimumSize
730         {
731             get
732             {
733                 return _minimumSize;
734             }
735         }
736 
737         private Layout RootDesignerLayout
738         {
739             get
740             {
741                 if (_rootDesignerLayout == null)
742                 {
743                     RefreshRootDesignerLayout();
744                 }
745                 return _rootDesignerLayout;
746             }
747             set
748             {
749                 _rootDesignerLayout = value;
750             }
751         }
752 
753         internal ISelectionService SelectionService
754         {
755             get
756             {
757                 if (_selectionService == null)
758                 {
759                     _selectionService = (ISelectionService)this.GetService(typeof(ISelectionService));
760                     _selectionService.SelectionChanged += new EventHandler(SelectionChanged);
761                 }
762                 return _selectionService;
763             }
764         }
765 
766         internal virtual ReadOnlyCollection<Type> ValidChildTypes
767         {
768             get
769             {
770                 List<Type> validChildTypes = new List<Type>();
771                 validChildTypes.Add(typeof(StateActivity));
772                 validChildTypes.Add(typeof(EventDrivenActivity));
773                 StateActivity state = (StateActivity)this.Activity;
774                 if (StateMachineHelpers.IsLeafState(state))
775                 {
776                     if (this.DesignersParser.StateInitializationDesigners.Count == 0)
777                         validChildTypes.Add(typeof(StateInitializationActivity));
778                     if (this.DesignersParser.StateFinalizationDesigners.Count == 0)
779                         validChildTypes.Add(typeof(StateFinalizationActivity));
780                 }
781                 return validChildTypes.AsReadOnly();
782             }
783         }
784 
785         internal Cursor Cursor
786         {
787             get
788             {
789                 return this.ParentView.Cursor;
790             }
791             set
792             {
793                 this.ParentView.Cursor = value;
794             }
795         }
796 
797         private Point TopConnectionPoint
798         {
799             get
800             {
801                 Rectangle bounds = this.Bounds;
802                 int midHorz = bounds.X + (bounds.Width / 2);
803                 Point point = new Point(midHorz, bounds.Top);
804                 return point;
805             }
806         }
807 
808         private Point BottomConnectionPoint
809         {
810             get
811             {
812                 Rectangle bounds = this.Bounds;
813                 int midHorz = bounds.X + (bounds.Width / 2);
814                 Point point = new Point(midHorz, bounds.Bottom);
815                 return point;
816             }
817         }
818 
819         private bool NeedsAutoLayout
820         {
821             get
822             {
823                 return _needsAutoLayout;
824             }
825             set
826             {
827                 _needsAutoLayout = value;
828             }
829         }
830 
831         #endregion Private Properties
832 
833         #endregion
834 
835         #region Methods
836 
837         #region Public Methods
838 
CanInsertActivities(HitTestInfo insertLocation, ReadOnlyCollection<Activity> activitiesToInsert)839         public override bool CanInsertActivities(HitTestInfo insertLocation, ReadOnlyCollection<Activity> activitiesToInsert)
840         {
841             if (this.HasActiveDesigner ||
842                 this.IsStateCustomActivity)
843                 return false;
844 
845             StateActivity state = (StateActivity)this.Activity;
846             if (StateMachineHelpers.IsLeafState(state) &&
847                 StateMachineHelpers.IsCompletedState(state))
848                 return false;
849 
850             ReadOnlyCollection<Type> validChildTypes = ValidChildTypes;
851             foreach (Activity activity in activitiesToInsert)
852             {
853                 bool contains = false;
854                 foreach (Type type in validChildTypes)
855                 {
856                     if (type.IsInstanceOfType(activity))
857                     {
858                         contains = true;
859                         break;
860                     }
861                 }
862                 if (!contains)
863                     return false;
864             }
865             return base.CanInsertActivities(insertLocation, activitiesToInsert);
866         }
867 
CanBeParentedTo(CompositeActivityDesigner parentActivityDesigner)868         public override bool CanBeParentedTo(CompositeActivityDesigner parentActivityDesigner)
869         {
870             if (parentActivityDesigner == null)
871                 throw new ArgumentNullException("parentActivityDesigner");
872 
873             CompositeActivity parentActivity = parentActivityDesigner.Activity as CompositeActivity;
874             if (parentActivity == null)
875                 return false;
876 
877             if (!(parentActivity is StateActivity))
878                 return false;
879 
880             return base.CanBeParentedTo(parentActivityDesigner);
881         }
882 
EnsureVisibleContainedDesigner(ActivityDesigner containedDesigner)883         public override void EnsureVisibleContainedDesigner(ActivityDesigner containedDesigner)
884         {
885             if (containedDesigner == null)
886                 throw new ArgumentNullException("containedDesigner");
887 
888             // call base
889             base.EnsureVisibleContainedDesigner(containedDesigner);
890 
891             //
892 
893 
894 
895             if (!_ensuringVisible)
896             {
897                 if (containedDesigner is StateDesigner)
898                 {
899                     SetActiveDesigner(null);
900                 }
901                 else
902                 {
903                     SetActiveDesigner(containedDesigner);
904                 }
905                 SetParentTreeEnsuringVisible(true);
906             }
907             _ensuringVisible = false;
908         }
909 
GetNextSelectableObject(object current, DesignerNavigationDirection direction)910         public override object GetNextSelectableObject(object current, DesignerNavigationDirection direction)
911         {
912             Activity activity = current as Activity;
913             if (activity == null)
914                 return null;
915 
916             // Workaround: there is a special case code in
917             // WorkflowView.EnsureVisible that calls EnsureVisible
918             // in the wrong order, causing the EnsureVisible flag
919             // to be in the wrong state
920             SetParentTreeEnsuringVisible(false);
921 
922             ActivityDesigner designer = GetDesigner(activity);
923 
924             List<ActivityDesigner> ordered = this.DesignersParser.Ordered;
925             int indexOf = ordered.IndexOf(designer);
926             if (indexOf < 0)
927                 return null;
928 
929             if (current is EventDrivenActivity ||
930                 current is StateInitializationActivity ||
931                 current is StateFinalizationActivity)
932             {
933                 if (direction == DesignerNavigationDirection.Left || direction == DesignerNavigationDirection.Right)
934                     return null;
935 
936                 if (direction == DesignerNavigationDirection.Down)
937                 {
938                     if (indexOf < (ordered.Count - 1))
939                         return ordered[indexOf + 1].Activity;
940                     else
941                         return null;
942                 }
943                 else
944                 {
945                     if (indexOf > 0)
946                         return ordered[indexOf - 1].Activity;
947                     else
948                         return null;
949                 }
950             }
951             else
952             {
953                 StateActivity currentState = current as StateActivity;
954                 Debug.Assert(currentState != null);
955                 if (StateMachineHelpers.IsLeafState(currentState))
956                 {
957                     if (direction == DesignerNavigationDirection.Right)
958                     {
959                         if (this.DesignersParser.StateDesigners.Count > 0)
960                             return this.DesignersParser.StateDesigners[0].Activity;
961                     }
962                     else if (direction == DesignerNavigationDirection.Up)
963                     {
964                         if (indexOf > 0)
965                             return ordered[indexOf - 1].Activity;
966                     }
967                     else if (direction == DesignerNavigationDirection.Down)
968                     {
969                         if (indexOf < (ordered.Count - 1))
970                             return ordered[indexOf + 1].Activity;
971                     }
972                 }
973                 else
974                 {
975                     if (direction == DesignerNavigationDirection.Left || direction == DesignerNavigationDirection.Up)
976                     {
977                         if (indexOf > 0)
978                             return ordered[indexOf - 1].Activity;
979                     }
980                     else
981                     {
982                         if (indexOf < (ordered.Count - 1))
983                             return ordered[indexOf + 1].Activity;
984                     }
985                 }
986             }
987 
988             return null;
989         }
990 
HitTest(Point point)991         public override HitTestInfo HitTest(Point point)
992         {
993             // get the base class hit test
994             HitTestInfo hitTestInfo = base.HitTest(point);
995 
996             // first we check if one of our layouts got the hit
997             HitTestInfo hitInfo = this.RootDesignerLayout.HitTest(point);
998             if (!hitInfo.Equals(HitTestInfo.Nowhere))
999                 return hitInfo;
1000 
1001             return hitTestInfo;
1002         }
1003 
IsContainedDesignerVisible(ActivityDesigner containedDesigner)1004         public override bool IsContainedDesignerVisible(ActivityDesigner containedDesigner)
1005         {
1006             if (this.HasActiveDesigner)
1007             {
1008                 if (containedDesigner == this.ActiveDesigner)
1009                     return true;
1010             }
1011             else
1012             {
1013                 if (containedDesigner is StateDesigner)
1014                     return true;
1015             }
1016 
1017             return false;
1018         }
1019 
1020         #endregion
1021 
1022         #region Protected Methods
1023 
CanResizeContainedDesigner(ActivityDesigner containedDesigner)1024         protected override bool CanResizeContainedDesigner(ActivityDesigner containedDesigner)
1025         {
1026             if (this.HasActiveDesigner)
1027                 return false;
1028 
1029             return base.CanResizeContainedDesigner(containedDesigner);
1030         }
1031 
CreateConnector(ConnectionPoint source, ConnectionPoint target)1032         protected override Connector CreateConnector(ConnectionPoint source, ConnectionPoint target)
1033         {
1034             return new StateDesignerConnector(source, target);
1035         }
1036 
CanConnect(ConnectionPoint source, ConnectionPoint target)1037         protected override bool CanConnect(ConnectionPoint source, ConnectionPoint target)
1038         {
1039             DesignerLayoutConnectionPoint sourceDesignerLayoutConnectionPoint = source as DesignerLayoutConnectionPoint;
1040             DesignerLayoutConnectionPoint targetDesignerLayoutConnectionPoint = target as DesignerLayoutConnectionPoint;
1041 
1042             if (sourceDesignerLayoutConnectionPoint == null)
1043             {
1044                 if (!IsValidTargetConnectionPoint(source))
1045                     return false;
1046             }
1047             else
1048             {
1049                 if (sourceDesignerLayoutConnectionPoint.DesignerLayout.ActivityDesigner is StateFinalizationDesigner)
1050                     return false;
1051             }
1052 
1053             if (targetDesignerLayoutConnectionPoint == null)
1054             {
1055                 if (!IsValidTargetConnectionPoint(target))
1056                     return false;
1057             }
1058             else
1059             {
1060                 if (targetDesignerLayoutConnectionPoint.DesignerLayout.ActivityDesigner is StateFinalizationDesigner)
1061                     return false;
1062             }
1063 
1064             bool canConnect =
1065                 (sourceDesignerLayoutConnectionPoint == null && targetDesignerLayoutConnectionPoint != null) ||
1066                 (sourceDesignerLayoutConnectionPoint != null && targetDesignerLayoutConnectionPoint == null);
1067 
1068             return canConnect;
1069         }
1070 
IsValidTargetConnectionPoint(ConnectionPoint target)1071         private bool IsValidTargetConnectionPoint(ConnectionPoint target)
1072         {
1073             StateDesigner stateDesigner = target.AssociatedDesigner as StateDesigner;
1074             if (stateDesigner == null)
1075                 return false;
1076             StateActivity state = (StateActivity)stateDesigner.Activity;
1077             return StateMachineHelpers.IsLeafState(state);
1078         }
1079 
GetConnectionPoints(DesignerEdges edges)1080         public override ReadOnlyCollection<ConnectionPoint> GetConnectionPoints(DesignerEdges edges)
1081         {
1082             List<ConnectionPoint> connectionPoints = new List<ConnectionPoint>();
1083             // In the EventDriven view we don't allow free form connectors
1084             if (!this.HasActiveDesigner)
1085             {
1086                 if (!this.IsRootStateDesigner)
1087                 {
1088                     if ((edges & DesignerEdges.Top) > 0)
1089                         connectionPoints.Add(new ConnectionPoint(this, DesignerEdges.Top, 0));
1090 
1091                     if ((edges & DesignerEdges.Bottom) > 0)
1092                         connectionPoints.Add(new ConnectionPoint(this, DesignerEdges.Bottom, 0));
1093                 }
1094 
1095                 int leftConnectionIndex = 0, rightConnectionIndex = 0;
1096                 foreach (DesignerLayout layout in this.DesignerLayouts.Values)
1097                 {
1098                     if (!this.IsRootStateDesigner)
1099                     {
1100                         if ((edges & DesignerEdges.Left) > 0 && layout.LeftConnectionPoint != Point.Empty)
1101                         {
1102                             connectionPoints.Add(new DesignerLayoutConnectionPoint(this, leftConnectionIndex, (CompositeActivity)layout.ActivityDesigner.Activity, DesignerEdges.Left));
1103                             leftConnectionIndex += 1;
1104                         }
1105                     }
1106 
1107                     if ((edges & DesignerEdges.Right) > 0 && layout.RightConnectionPoint != Point.Empty)
1108                     {
1109                         connectionPoints.Add(new DesignerLayoutConnectionPoint(this, rightConnectionIndex, (CompositeActivity)layout.ActivityDesigner.Activity, DesignerEdges.Right));
1110                         rightConnectionIndex += 1;
1111                     }
1112                 }
1113             }
1114 
1115             return connectionPoints.AsReadOnly();
1116         }
1117 
GetConnections(DesignerEdges edges)1118         protected override ReadOnlyCollection<Point> GetConnections(DesignerEdges edges)
1119         {
1120             List<Point> connections = new List<Point>();
1121             if ((edges & DesignerEdges.Top) > 0)
1122                 connections.Add(this.TopConnectionPoint);
1123 
1124             if ((edges & DesignerEdges.Bottom) > 0)
1125                 connections.Add(this.BottomConnectionPoint);
1126 
1127             foreach (DesignerLayout layout in this.DesignerLayouts.Values)
1128             {
1129                 if (!this.IsRootStateDesigner)
1130                 {
1131                     if ((edges & DesignerEdges.Left) > 0 && layout.LeftConnectionPoint != Point.Empty)
1132                         connections.Add(layout.LeftConnectionPoint);
1133                 }
1134                 if ((edges & DesignerEdges.Right) > 0 && layout.RightConnectionPoint != Point.Empty)
1135                     connections.Add(layout.RightConnectionPoint);
1136             }
1137 
1138             return connections.AsReadOnly();
1139         }
1140 
OnConnectorAdded(ConnectorEventArgs e)1141         protected override void OnConnectorAdded(ConnectorEventArgs e)
1142         {
1143             base.OnConnectorAdded(e);
1144 
1145             StateDesignerConnector connector = e.Connector as StateDesignerConnector;
1146             if (connector == null)
1147                 return;
1148 
1149             // We need to make sure that the source connection point
1150             // is always the event handler
1151             DesignerLayoutConnectionPoint sourceDesignerLayoutConnectionPoint = connector.Source as DesignerLayoutConnectionPoint;
1152             DesignerLayoutConnectionPoint targetDesignerLayoutConnectionPoint = connector.Target as DesignerLayoutConnectionPoint;
1153             if (sourceDesignerLayoutConnectionPoint == null)
1154             {
1155                 Debug.Assert(targetDesignerLayoutConnectionPoint != null);
1156                 ConnectionPoint source = connector.Source;
1157                 connector.Source = connector.Target;
1158                 connector.Target = source;
1159             }
1160             else
1161             {
1162                 Debug.Assert(targetDesignerLayoutConnectionPoint == null);
1163             }
1164 
1165             ConnectionPoint target = connector.Target;
1166             sourceDesignerLayoutConnectionPoint = (DesignerLayoutConnectionPoint)connector.Source;
1167             if (this.RootStateDesigner.AddingSetState)
1168             {
1169                 SetStateActivity setState = new SetStateActivity();
1170                 setState.TargetStateName = target.AssociatedDesigner.Activity.QualifiedName;
1171                 CompositeActivityDesigner compositeDesigner = (CompositeActivityDesigner)StateDesigner.GetDesigner(sourceDesignerLayoutConnectionPoint.EventHandler);
1172                 List<Activity> activitiesToInsert = new List<Activity>();
1173                 activitiesToInsert.Add(setState);
1174                 compositeDesigner.InsertActivities(new HitTestInfo(compositeDesigner, HitTestLocations.Designer), activitiesToInsert.AsReadOnly());
1175                 connector.SetStateName = setState.QualifiedName;
1176             }
1177             connector.TargetStateName = target.AssociatedDesigner.Activity.QualifiedName;
1178             connector.SourceStateName = sourceDesignerLayoutConnectionPoint.EventHandler.Parent.QualifiedName;
1179             connector.EventHandlerName = sourceDesignerLayoutConnectionPoint.EventHandler.QualifiedName;
1180         }
1181 
OnConnectorRemoved(ConnectorEventArgs e)1182         protected override void OnConnectorRemoved(ConnectorEventArgs e)
1183         {
1184             base.OnConnectorRemoved(e);
1185 
1186             StateDesignerConnector connector = e.Connector as StateDesignerConnector;
1187             if (connector == null || string.IsNullOrEmpty(connector.SetStateName) || !this.RootStateDesigner.RemovingSetState)
1188                 return;
1189 
1190             DesignerLayoutConnectionPoint sourceDesignerLayoutConnectionPoint = connector.Source as DesignerLayoutConnectionPoint;
1191             if (sourceDesignerLayoutConnectionPoint != null)
1192             {
1193                 CompositeActivityDesigner compositeDesigner = StateDesigner.GetDesigner(sourceDesignerLayoutConnectionPoint.EventHandler) as CompositeActivityDesigner;
1194                 if (compositeDesigner != null && sourceDesignerLayoutConnectionPoint.EventHandler != null)
1195                 {
1196                     Activity setStateActivity = StateDesigner.FindActivityByQualifiedName(sourceDesignerLayoutConnectionPoint.EventHandler, connector.SetStateName);
1197                     if (setStateActivity != null)
1198                     {
1199                         List<Activity> activitiesToRemove = new List<Activity>();
1200                         activitiesToRemove.Add(setStateActivity);
1201                         CompositeActivityDesigner setStateParentDesigner = StateDesigner.GetDesigner(setStateActivity.Parent) as CompositeActivityDesigner;
1202                         if (setStateParentDesigner != null)
1203                             setStateParentDesigner.RemoveActivities(activitiesToRemove.AsReadOnly());
1204                     }
1205                 }
1206             }
1207         }
1208 
OnConnectorChanged(ConnectorEventArgs e)1209         protected override void OnConnectorChanged(ConnectorEventArgs e)
1210         {
1211             base.OnConnectorChanged(e);
1212 
1213             Connector connector = e.Connector;
1214 
1215             StateDesignerConnector stateDesignerConnector = connector as StateDesignerConnector;
1216             if (stateDesignerConnector == null)
1217                 return;
1218 
1219             if (!stateDesignerConnector.Target.AssociatedDesigner.Activity.QualifiedName.Equals(stateDesignerConnector.TargetStateName))
1220             {
1221                 StateActivity rootState = (StateActivity)this.RootStateDesigner.Activity;
1222                 // target state has changed
1223                 SetStateActivity setState = FindActivityByQualifiedName(rootState, stateDesignerConnector.SetStateName) as SetStateActivity;
1224                 if (setState != null)
1225                 {
1226                     StateActivity targetState = (StateActivity)stateDesignerConnector.Target.AssociatedDesigner.Activity;
1227                     PropertyDescriptor property = GetPropertyDescriptor(setState, SetStateActivity.TargetStateNamePropertyName);
1228                     property.SetValue(setState, targetState.QualifiedName);
1229                     stateDesignerConnector.TargetStateName = targetState.QualifiedName;
1230                 }
1231             }
1232 
1233             StateDesigner.DesignerLayoutConnectionPoint sourceConnectionPoint = (StateDesigner.DesignerLayoutConnectionPoint)stateDesignerConnector.Source;
1234             if (!sourceConnectionPoint.EventHandler.QualifiedName.Equals(stateDesignerConnector.EventHandlerName))
1235             {
1236                 StateActivity rootState = (StateActivity)this.RootStateDesigner.Activity;
1237                 // source state has changed
1238                 SetStateActivity setState = FindActivityByQualifiedName(rootState, stateDesignerConnector.SetStateName) as SetStateActivity;
1239                 if (setState != null)
1240                 {
1241                     IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;
1242                     DesignerTransaction transaction = null;
1243                     if (designerHost != null)
1244                         transaction = designerHost.CreateTransaction(SR.GetMoveSetState());
1245 
1246                     try
1247                     {
1248                         CompositeActivityDesigner previousSetStateParentDesigner = (CompositeActivityDesigner)StateDesigner.GetDesigner(setState.Parent);
1249                         List<Activity> activitiesToRemove = new List<Activity>();
1250                         activitiesToRemove.Add(setState);
1251                         previousSetStateParentDesigner.RemoveActivities(activitiesToRemove.AsReadOnly());
1252 
1253                         DesignerLayoutConnectionPoint source = (DesignerLayoutConnectionPoint)stateDesignerConnector.Source;
1254                         CompositeActivityDesigner newSetStateParentDesigner = (CompositeActivityDesigner)StateDesigner.GetDesigner(source.EventHandler);
1255                         List<Activity> activitiesToInsert = new List<Activity>();
1256                         activitiesToInsert.Add(setState);
1257                         newSetStateParentDesigner.InsertActivities(new HitTestInfo(newSetStateParentDesigner, HitTestLocations.Designer), activitiesToInsert.AsReadOnly());
1258 
1259                         stateDesignerConnector.EventHandlerName = source.EventHandler.QualifiedName;
1260                         stateDesignerConnector.SourceStateName = source.EventHandler.Parent.QualifiedName;
1261 
1262                         if (transaction != null)
1263                             transaction.Commit();
1264                     }
1265                     catch
1266                     {
1267                         if (transaction != null)
1268                             transaction.Cancel();
1269 
1270                         throw;
1271                     }
1272                 }
1273             }
1274         }
1275 
1276         #region Drag & Drop
1277 
OnDragEnter(ActivityDragEventArgs e)1278         protected override void OnDragEnter(ActivityDragEventArgs e)
1279         {
1280             base.OnDragEnter(e);
1281 
1282             this.DragDropActive = CanDrop(e);
1283             e.Effect = CheckDragEffect(e);
1284             e.DragImageSnapPoint = GetDragImageSnapPoint(e);
1285         }
1286 
OnDragOver(ActivityDragEventArgs e)1287         protected override void OnDragOver(ActivityDragEventArgs e)
1288         {
1289             base.OnDragOver(e);
1290 
1291             this.DragDropActive = CanDrop(e);
1292             e.Effect = CheckDragEffect(e);
1293             e.DragImageSnapPoint = GetDragImageSnapPoint(e);
1294         }
1295 
OnDragLeave()1296         protected override void OnDragLeave()
1297         {
1298             base.OnDragLeave();
1299             this.DragDropActive = false;
1300         }
1301 
OnDragDrop(ActivityDragEventArgs e)1302         protected override void OnDragDrop(ActivityDragEventArgs e)
1303         {
1304             if (this.DragDropActive)
1305             {
1306                 base.OnDragDrop(e);
1307                 this.DragDropActive = false;
1308             }
1309         }
1310 
1311         #endregion
1312 
1313         #region Mouse events handlers
1314 
OnMouseDown(MouseEventArgs e)1315         protected override void OnMouseDown(MouseEventArgs e)
1316         {
1317             base.OnMouseDown(e);
1318             this.RootDesignerLayout.OnMouseDown(e);
1319         }
1320 
OnMouseUp(MouseEventArgs e)1321         protected override void OnMouseUp(MouseEventArgs e)
1322         {
1323             base.OnMouseDown(e);
1324             this.RootDesignerLayout.OnMouseUp(e);
1325         }
1326 
OnMouseLeave()1327         protected override void OnMouseLeave()
1328         {
1329             base.OnMouseLeave();
1330             this.RootDesignerLayout.OnMouseLeave();
1331         }
1332 
OnMouseMove(MouseEventArgs e)1333         protected override void OnMouseMove(MouseEventArgs e)
1334         {
1335             base.OnMouseMove(e);
1336             this.RootDesignerLayout.OnMouseMove(e);
1337         }
1338 
OnMouseDoubleClick(MouseEventArgs e)1339         protected override void OnMouseDoubleClick(MouseEventArgs e)
1340         {
1341             base.OnMouseDoubleClick(e);
1342             this.RootDesignerLayout.OnMouseDoubleClick(e);
1343         }
1344 
1345         #endregion Mouse event handlers
1346 
OnContainedActivitiesChanged(ActivityCollectionChangeEventArgs listChangeArgs)1347         protected override void OnContainedActivitiesChanged(ActivityCollectionChangeEventArgs listChangeArgs)
1348         {
1349             base.OnContainedActivitiesChanged(listChangeArgs);
1350 
1351             if (this.ActiveDesigner != null &&
1352                 listChangeArgs.RemovedItems.Contains(this.ActiveDesigner.Activity))
1353             {
1354                 SetActiveDesigner(null);
1355             }
1356 
1357             this.DesignersParser = null;
1358         }
1359 
OnLayoutPosition(ActivityDesignerLayoutEventArgs e)1360         protected override void OnLayoutPosition(ActivityDesignerLayoutEventArgs e)
1361         {
1362             try
1363             {
1364                 if (this.IsRootStateDesigner)
1365                 {
1366                     if (this.ActiveDesigner == null)
1367                     {
1368                         // UpdateConnectors depends on having the
1369                         // RootDesignerLayout refreshed at least once
1370                         this.UpdateConnectors();
1371                     }
1372                 }
1373 
1374                 Graphics graphics = e.Graphics;
1375                 ActivityDesignerTheme designerTheme = e.DesignerTheme;
1376                 AmbientTheme ambientTheme = e.AmbientTheme;
1377                 this.RootDesignerLayout.Location = this.Location;
1378                 this.RootDesignerLayout.OnLayoutPosition(graphics, designerTheme, ambientTheme);
1379 
1380                 if (!this.HasActiveDesigner)
1381                     RelocateStates();
1382 
1383                 base.OnLayoutPosition(e);
1384 
1385                 if (!this.HasActiveDesigner && this.NeedsAutoLayout)
1386                     RepositionStates();
1387 
1388                 if (IsRootDesigner && InvokingDesigner == null)
1389                     RecalculateRootDesignerSize();
1390 
1391             }
1392 #if DEBUG
1393             catch (Exception exception)
1394             {
1395                 Trace.WriteLine(String.Format(
1396                     System.Globalization.CultureInfo.InvariantCulture,
1397                     "Unhandled exception in {0}.OnLayoutPosition: {1}",
1398                     typeof(StateDesigner), exception));
1399                 throw;
1400             }
1401 #endif
1402             finally
1403             {
1404                 if (this.IsRootStateDesigner)
1405                     this.PerformingLayout = false;
1406             }
1407         }
1408 
RelocateStates()1409         private void RelocateStates()
1410         {
1411             // make sure that if we add event handlers, the states
1412             // are moved down so they're still visible
1413             int minimumY = _eventHandlersLayout.Bounds.Bottom + DefaultStateDesignerAutoLayoutDistance;
1414             int deltaY = 0;
1415             Rectangle moveBounds = Rectangle.Empty;
1416             int freeSpaceHeight = int.MaxValue;
1417             foreach (ActivityDesigner designer in this.ContainedDesigners)
1418             {
1419                 if (IsContainedDesignerVisible(designer))
1420                 {
1421                     StateDesigner stateDesigner = designer as StateDesigner;
1422                     if (stateDesigner != null)
1423                     {
1424                         if (stateDesigner.Location.Y < minimumY)
1425                         {
1426                             deltaY = Math.Max(deltaY, minimumY - stateDesigner.Location.Y);
1427                             if (moveBounds.IsEmpty)
1428                                 moveBounds = stateDesigner.Bounds;
1429                             else
1430                                 moveBounds = Rectangle.Union(moveBounds, stateDesigner.Bounds);
1431                         }
1432                         else
1433                         {
1434                             freeSpaceHeight = Math.Min(freeSpaceHeight, stateDesigner.Location.Y - minimumY);
1435                         }
1436                     }
1437                 }
1438             }
1439             if (freeSpaceHeight == int.MaxValue)
1440                 freeSpaceHeight = 0;
1441 
1442             if (deltaY > 0)
1443             {
1444                 int maximumY = int.MinValue;
1445                 foreach (ActivityDesigner designer in this.ContainedDesigners)
1446                 {
1447                     if (IsContainedDesignerVisible(designer))
1448                     {
1449                         StateDesigner stateDesigner = designer as StateDesigner;
1450                         if (stateDesigner != null)
1451                         {
1452                             Point location = stateDesigner.Location;
1453                             if (stateDesigner.Location.Y < minimumY)
1454                                 stateDesigner.Location = new Point(location.X, location.Y + deltaY);
1455                             else
1456                                 stateDesigner.Location = new Point(location.X, location.Y + moveBounds.Height + DefaultStateDesignerAutoLayoutDistance - freeSpaceHeight);
1457                             maximumY = Math.Max(maximumY, stateDesigner.Bounds.Bottom);
1458                         }
1459                     }
1460                 }
1461                 if (maximumY > this.Bounds.Bottom)
1462                 {
1463                     Size newSize = new Size(this.Size.Width, this.Size.Height + ((maximumY + DefaultStateDesignerAutoLayoutDistance) - this.Bounds.Bottom));
1464                     this.Size = newSize;
1465                 }
1466             }
1467         }
1468 
RepositionStates()1469         private void RepositionStates()
1470         {
1471             Debug.Assert(!this.HasActiveDesigner && this.NeedsAutoLayout);
1472 
1473             int maximumY = _eventHandlersLayout.Bounds.Bottom + DefaultStateDesignerAutoLayoutDistance;
1474             foreach (ActivityDesigner designer in this.ContainedDesigners)
1475             {
1476                 if (IsContainedDesignerVisible(designer))
1477                 {
1478                     StateDesigner stateDesigner = designer as StateDesigner;
1479                     if (stateDesigner == null)
1480                         continue;
1481 
1482                     int x = this.Location.X + DefaultStateDesignerAutoLayoutDistance;
1483                     int y = maximumY;
1484                     stateDesigner.Location = new Point(x, y);
1485                     maximumY = stateDesigner.Bounds.Bottom + DefaultStateDesignerAutoLayoutDistance;
1486                 }
1487             }
1488             this.NeedsAutoLayout = false;
1489         }
1490 
RecalculateRootDesignerSize()1491         private void RecalculateRootDesignerSize()
1492         {
1493             Debug.Assert(IsRootDesigner && InvokingDesigner == null);
1494 
1495             // Make sure that the root designer has enough
1496             // space to show all contained designers
1497             Size newSize = Size.Empty;
1498             foreach (ActivityDesigner designer in this.ContainedDesigners)
1499             {
1500                 if (IsContainedDesignerVisible(designer))
1501                 {
1502                     Rectangle bounds = designer.Bounds;
1503                     bounds.Offset(Separator.Width - this.Location.X, Separator.Height - this.Location.Y);
1504                     newSize.Width = Math.Max(newSize.Width, bounds.Right);
1505                     newSize.Height = Math.Max(newSize.Height, bounds.Bottom);
1506                 }
1507             }
1508             newSize.Width = Math.Max(newSize.Width, this.MinimumSize.Width);
1509             newSize.Height = Math.Max(newSize.Height, this.MinimumSize.Height);
1510             this.Size = newSize;
1511         }
1512 
OnLayoutSize(ActivityDesignerLayoutEventArgs e)1513         protected override Size OnLayoutSize(ActivityDesignerLayoutEventArgs e)
1514         {
1515 #if DEBUG
1516             try
1517             {
1518 #endif
1519             if (this.IsRootStateDesigner)
1520                 this.PerformingLayout = true;
1521 
1522             if (this.HasActiveDesigner)
1523             {
1524                 // If we are in the event driven view,
1525                 // then we need to make sure that the size
1526                 // of this designer will be as small as possible
1527                 _minimumSize = Size.Empty;
1528                 this.Size = Size.Empty;
1529             }
1530             else
1531             {
1532                 this.NeedsAutoLayout = this.Size.IsEmpty;
1533             }
1534 
1535             Size newSize = base.OnLayoutSize(e);
1536 
1537             Graphics graphics = e.Graphics;
1538             ActivityDesignerTheme designerTheme = e.DesignerTheme;
1539             AmbientTheme ambientTheme = e.AmbientTheme;
1540 
1541             RefreshRootDesignerLayout();
1542 
1543             this.RootDesignerLayout.OnLayoutSize(graphics, designerTheme, ambientTheme, newSize);
1544             _minimumSize = this.RootDesignerLayout.MinimumSize;
1545 
1546             return this.RootDesignerLayout.Size;
1547 #if DEBUG
1548             }
1549             catch (Exception exception)
1550             {
1551                 Trace.WriteLine(String.Format(
1552                     System.Globalization.CultureInfo.InvariantCulture,
1553                     "Unhandled exception in {0}.OnLayoutSize: {1}",
1554                     typeof(StateDesigner), exception));
1555                 throw;
1556             }
1557 #endif
1558         }
1559 
OnPaint(ActivityDesignerPaintEventArgs e)1560         protected override void OnPaint(ActivityDesignerPaintEventArgs e)
1561         {
1562             Graphics graphics = e.Graphics;
1563             ActivityDesignerTheme designerTheme = e.DesignerTheme;
1564             AmbientTheme ambientTheme = e.AmbientTheme;
1565 
1566 #if DEBUG
1567             try
1568             {
1569 #endif
1570             this.RootDesignerLayout.OnPaint(graphics, designerTheme, ambientTheme);
1571             this.PaintContainedDesigners(e);
1572 #if DEBUG
1573             }
1574             catch (Exception exception)
1575             {
1576                 Trace.WriteLine(String.Format(
1577                     System.Globalization.CultureInfo.InvariantCulture,
1578                     "Unhandled exception in {0}.OnPaint: {1}",
1579                     typeof(StateDesigner), exception));
1580             }
1581 #endif
1582         }
1583 
OnThemeChange(ActivityDesignerTheme newTheme)1584         protected override void OnThemeChange(ActivityDesignerTheme newTheme)
1585         {
1586             base.OnThemeChange(newTheme);
1587             this.Image = GetDesignerImage(this);
1588         }
1589 
1590         #endregion
1591 
1592         #region Private Methods
1593 
1594         #region Drag & Drop
1595 
CanDrop(ActivityDragEventArgs e)1596         private bool CanDrop(ActivityDragEventArgs e)
1597         {
1598             if (e.Activities.Count == 0)
1599                 return false;
1600 
1601             if (this.HasActiveDesigner)
1602                 return false;
1603 
1604             if (!CanInsertActivities(new HitTestInfo(this, HitTestLocations.Designer), e.Activities))
1605                 return false;
1606 
1607             bool ctrlKeyPressed = ((e.KeyState & 8) == 8);
1608             if (!ctrlKeyPressed && (e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)
1609             {
1610                 HitTestInfo moveLocation = new HitTestInfo(this, HitTestLocations.Designer);
1611                 foreach (Activity activity in e.Activities)
1612                 {
1613                     if (activity.Site != null)
1614                     {
1615                         ActivityDesigner activityDesigner = StateDesigner.GetDesigner(activity);
1616                         if (activityDesigner == null || activityDesigner.ParentDesigner == null || !activityDesigner.ParentDesigner.CanMoveActivities(moveLocation, new List<Activity>(new Activity[] { activity }).AsReadOnly()))
1617                         {
1618                             return false;
1619                         }
1620                     }
1621                 }
1622             }
1623 
1624             return true;
1625         }
1626 
CheckDragEffect(ActivityDragEventArgs e)1627         private DragDropEffects CheckDragEffect(ActivityDragEventArgs e)
1628         {
1629             if (e.Activities.Count == 0 || (!this.DragDropActive))
1630             {
1631                 return DragDropEffects.None;
1632             }
1633             else
1634             {
1635                 bool ctrlKeyPressed = ((e.KeyState & 8) == 8);
1636                 if (ctrlKeyPressed && (e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)
1637                     return DragDropEffects.Copy;
1638                 else if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)
1639                     return DragDropEffects.Move;
1640             }
1641 
1642             return e.Effect;
1643         }
1644 
GetDragImageSnapPoint(ActivityDragEventArgs e)1645         private Point GetDragImageSnapPoint(ActivityDragEventArgs e)
1646         {
1647             Point snapPoint = new Point(e.Y, e.Y);
1648             if (!this.HasActiveDesigner)
1649             {
1650                 int eventHandlersLayoutBottom = this._statesLayout.EventHandlersLayout.Bounds.Bottom;
1651                 if (snapPoint.Y <= eventHandlersLayoutBottom)
1652                     snapPoint.Y = eventHandlersLayoutBottom + 1;
1653             }
1654 
1655             return snapPoint;
1656         }
1657 
1658         #endregion
1659 
UpdateConnectors()1660         private void UpdateConnectors()
1661         {
1662             try
1663             {
1664                 Debug.Assert(this.IsRootStateDesigner);
1665                 Debug.Assert(this.ActiveDesigner == null);
1666 
1667                 this.RootStateDesigner.RemovingSetState = false;
1668 
1669                 StateActivity rootState = (StateActivity)this.Activity;
1670                 ReadOnlyCollection<TransitionInfo> transitions = TransitionInfo.ParseStateMachine(rootState);
1671                 Connector[] connectors = new Connector[this.Connectors.Count];
1672                 this.Connectors.CopyTo(connectors, 0);
1673                 foreach (Connector connector in connectors)
1674                 {
1675                     StateDesignerConnector stateDesignerConnector = connector as StateDesignerConnector;
1676                     if (stateDesignerConnector == null)
1677                     {
1678                         RemoveConnector(connector);
1679                         continue;
1680                     }
1681 
1682                     bool foundMatchingTransition = false;
1683                     foreach (TransitionInfo transitionInfo in transitions)
1684                     {
1685                         if (transitionInfo.Matches(stateDesignerConnector))
1686                         {
1687                             transitionInfo.Connector = stateDesignerConnector;
1688                             foundMatchingTransition = true;
1689                             break;
1690                         }
1691                     }
1692 
1693                     if (!foundMatchingTransition)
1694                         RemoveConnector(connector);
1695                 }
1696 
1697                 foreach (TransitionInfo transitionInfo in transitions)
1698                 {
1699                     if (transitionInfo.Connector == null && transitionInfo.TargetState != null)
1700                     {
1701                         DesignerLayoutConnectionPoint source = GetEventHandlerConnectionPoint(transitionInfo.EventHandler);
1702                         ConnectionPoint target = GetTargetStateConnectionPoint(transitionInfo.TargetState);
1703 
1704                         if (source != null && target != null)
1705                         {
1706                             this.RootStateDesigner.AddingSetState = false;
1707                             try
1708                             {
1709                                 StateDesignerConnector stateDesignerConnector = (StateDesignerConnector)this.AddConnector(source, target);
1710                                 stateDesignerConnector.SetStateName = transitionInfo.SetState.QualifiedName;
1711                                 stateDesignerConnector.TargetStateName = transitionInfo.SetState.TargetStateName;
1712                                 if (transitionInfo.EventHandler != null)
1713                                     stateDesignerConnector.EventHandlerName = transitionInfo.EventHandler.QualifiedName;
1714                             }
1715                             finally
1716                             {
1717                                 this.RootStateDesigner.AddingSetState = true;
1718                             }
1719                         }
1720                     }
1721                 }
1722 
1723             }
1724 #if DEBUG
1725             catch (Exception exception)
1726             {
1727                 Trace.WriteLine(String.Format(
1728                     System.Globalization.CultureInfo.InvariantCulture,
1729                     "Unhandled exception in {0}.UpdateConnectors: {1}",
1730                     typeof(StateDesigner), exception));
1731                 throw;
1732             }
1733 #endif
1734             finally
1735             {
1736                 this.RemovingSetState = true;
1737             }
1738         }
1739 
FindConnector(TransitionInfo transitionInfo)1740         internal StateDesignerConnector FindConnector(TransitionInfo transitionInfo)
1741         {
1742             foreach (Connector connector in this.Connectors)
1743             {
1744                 StateDesignerConnector stateDesignerConnector = connector as StateDesignerConnector;
1745                 if (stateDesignerConnector != null)
1746                 {
1747                     if (transitionInfo.Matches(stateDesignerConnector))
1748                         return stateDesignerConnector;
1749                 }
1750             }
1751             return null;
1752         }
1753 
GetEventHandlerConnectionPoint(CompositeActivity eventHandler)1754         private DesignerLayoutConnectionPoint GetEventHandlerConnectionPoint(CompositeActivity eventHandler)
1755         {
1756             Debug.Assert(eventHandler != null);
1757             StateDesigner sourceStateDesigner = (StateDesigner)GetDesigner(eventHandler.Parent);
1758             DesignerLayout eventHandlerLayout;
1759             if (!sourceStateDesigner.DesignerLayouts.TryGetValue(eventHandler, out eventHandlerLayout))
1760                 return null;
1761 
1762             int connectionIndex = 0;
1763             foreach (DesignerLayout layout in sourceStateDesigner.DesignerLayouts.Values)
1764             {
1765                 if (layout == eventHandlerLayout)
1766                 {
1767                     // we add one so we connect to the Right side by default
1768                     break;
1769                 }
1770 
1771                 connectionIndex++;
1772             }
1773 
1774             return new DesignerLayoutConnectionPoint(sourceStateDesigner, connectionIndex, eventHandler, DesignerEdges.Right);
1775         }
1776 
GetTargetStateConnectionPoint(StateActivity targetState)1777         private ConnectionPoint GetTargetStateConnectionPoint(StateActivity targetState)
1778         {
1779             //
1780             Debug.Assert(targetState != null);
1781             StateDesigner targetStateDesigner = (StateDesigner)GetDesigner(targetState);
1782             return new ConnectionPoint(targetStateDesigner, DesignerEdges.Top, 0);
1783         }
1784 
StateDesignerLinkMouseDown(object sender, MouseEventArgs e)1785         internal void StateDesignerLinkMouseDown(object sender, MouseEventArgs e)
1786         {
1787             IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;
1788             DesignerTransaction transaction = null;
1789             if (designerHost != null)
1790                 transaction = designerHost.CreateTransaction(SR.GetString(SR.UndoSwitchViews));
1791 
1792             try
1793             {
1794                 ISelectionService selectionService = this.GetService(typeof(ISelectionService)) as ISelectionService;
1795                 if (selectionService != null)
1796                     selectionService.SetSelectedComponents(new object[] { this.Activity }, SelectionTypes.Primary);
1797 
1798                 SetLeafActiveDesigner(this, null);
1799 
1800                 if (transaction != null)
1801                     transaction.Commit();
1802             }
1803             catch
1804             {
1805                 if (transaction != null)
1806                     transaction.Cancel();
1807 
1808                 throw;
1809             }
1810         }
1811 
RefreshRootDesignerLayout()1812         private void RefreshRootDesignerLayout()
1813         {
1814             if (!this.HasActiveDesigner)
1815             {
1816                 _eventHandlersLayout.Layouts.Clear();
1817                 this.DesignerLayouts.Clear();
1818                 _designersParser = new ContainedDesignersParser(this.ContainedDesigners);
1819 
1820                 foreach (StateInitializationDesigner stateInitializationDesigner in this.DesignersParser.StateInitializationDesigners)
1821                 {
1822                     DesignerLayout layout = new DesignerLayout(stateInitializationDesigner);
1823                     this.DesignerLayouts[stateInitializationDesigner.Activity] = layout;
1824                     _eventHandlersLayout.Layouts.Add(layout);
1825                 }
1826 
1827                 // we now add the EventDrivenDesigners
1828                 foreach (EventDrivenDesigner eventDrivenDesigner in this.DesignersParser.EventDrivenDesigners)
1829                 {
1830                     DesignerLayout layout = new DesignerLayout(eventDrivenDesigner);
1831                     this.DesignerLayouts[eventDrivenDesigner.Activity] = layout;
1832                     _eventHandlersLayout.Layouts.Add(layout);
1833                 }
1834 
1835                 foreach (StateFinalizationDesigner stateFinalizationDesigner in this.DesignersParser.StateFinalizationDesigners)
1836                 {
1837                     DesignerLayout layout = new DesignerLayout(stateFinalizationDesigner);
1838                     this.DesignerLayouts[stateFinalizationDesigner.Activity] = layout;
1839                     _eventHandlersLayout.Layouts.Add(layout);
1840                 }
1841 
1842                 this.RootDesignerLayout = _statesLayout;
1843             }
1844             else
1845                 this.RootDesignerLayout = _eventDrivenLayout;
1846         }
1847 
OnStateMachineView(object sender, EventArgs e)1848         internal void OnStateMachineView(object sender, EventArgs e)
1849         {
1850             SetLeafActiveDesigner(this, null);
1851         }
1852 
OnSetAsInitialState(object sender, EventArgs e)1853         internal void OnSetAsInitialState(object sender, EventArgs e)
1854         {
1855             IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;
1856             DesignerTransaction transaction = null;
1857             StateActivity state = (StateActivity)this.Activity;
1858             if (designerHost != null)
1859                 transaction = designerHost.CreateTransaction(SR.GetUndoSetAsInitialState(state.Name));
1860 
1861             try
1862             {
1863                 StateActivity rootState = StateMachineHelpers.GetRootState(state);
1864 
1865                 PropertyDescriptor initialStateProperty = GetPropertyDescriptor(rootState, StateMachineWorkflowActivity.InitialStateNamePropertyName);
1866                 initialStateProperty.SetValue(rootState, state.Name);
1867 
1868                 string completedStateName = StateMachineHelpers.GetCompletedStateName(rootState);
1869                 if (completedStateName == state.Name)
1870                 {
1871                     PropertyDescriptor completedStateProperty = GetPropertyDescriptor(rootState, StateMachineWorkflowActivity.CompletedStateNamePropertyName);
1872                     completedStateProperty.SetValue(rootState, "");
1873                 }
1874 
1875                 if (transaction != null)
1876                     transaction.Commit();
1877             }
1878             catch
1879             {
1880                 if (transaction != null)
1881                     transaction.Cancel();
1882 
1883                 throw;
1884             }
1885         }
1886 
OnSetAsCompletedState(object sender, EventArgs e)1887         internal void OnSetAsCompletedState(object sender, EventArgs e)
1888         {
1889             IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;
1890             DesignerTransaction transaction = null;
1891             StateActivity state = (StateActivity)this.Activity;
1892             if (designerHost != null)
1893                 transaction = designerHost.CreateTransaction(SR.GetUndoSetAsCompletedState(state.Name));
1894 
1895             try
1896             {
1897                 StateActivity rootState = StateMachineHelpers.GetRootState(state);
1898 
1899                 PropertyDescriptor completedStateProperty = GetPropertyDescriptor(rootState, StateMachineWorkflowActivity.CompletedStateNamePropertyName);
1900                 completedStateProperty.SetValue(rootState, state.Name);
1901 
1902                 string initialStateName = StateMachineHelpers.GetInitialStateName(rootState);
1903                 if (initialStateName == state.Name)
1904                 {
1905                     PropertyDescriptor initialStateProperty = GetPropertyDescriptor(rootState, StateMachineWorkflowActivity.InitialStateNamePropertyName);
1906                     initialStateProperty.SetValue(rootState, "");
1907                 }
1908 
1909                 if (transaction != null)
1910                     transaction.Commit();
1911             }
1912             catch
1913             {
1914                 if (transaction != null)
1915                     transaction.Cancel();
1916 
1917                 throw;
1918             }
1919         }
1920 
GetPropertyDescriptor(Activity activity, string propertyName)1921         private static PropertyDescriptor GetPropertyDescriptor(Activity activity, string propertyName)
1922         {
1923             PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(activity);
1924             PropertyDescriptor property = properties.Find(propertyName, false);
1925             return property;
1926         }
1927 
OnAddEventDriven(object sender, EventArgs e)1928         internal void OnAddEventDriven(object sender, EventArgs e)
1929         {
1930             EventDrivenActivity eventDriven = new EventDrivenActivity();
1931             AddChild(eventDriven);
1932         }
1933 
OnAddState(object sender, EventArgs e)1934         internal void OnAddState(object sender, EventArgs e)
1935         {
1936             StateActivity state = new StateActivity();
1937             AddChild(state);
1938         }
1939 
OnAddStateInitialization(object sender, EventArgs e)1940         internal void OnAddStateInitialization(object sender, EventArgs e)
1941         {
1942             StateInitializationActivity stateInitialization = new StateInitializationActivity();
1943             AddChild(stateInitialization);
1944         }
1945 
OnAddStateFinalization(object sender, EventArgs e)1946         internal void OnAddStateFinalization(object sender, EventArgs e)
1947         {
1948             StateFinalizationActivity stateFinalization = new StateFinalizationActivity();
1949             AddChild(stateFinalization);
1950         }
1951 
AddChild(Activity child)1952         internal void AddChild(Activity child)
1953         {
1954             CompositeActivity compositeActivity = this.Activity as CompositeActivity;
1955             if (compositeActivity != null && child != null)
1956             {
1957                 // Record the current number of child activities
1958                 int designerCount = ContainedDesigners.Count;
1959 
1960                 HitTestInfo hitTestInfo = new HitTestInfo(this, HitTestLocations.Designer);
1961 
1962                 CompositeActivityDesigner.InsertActivities(
1963                     this,
1964                     hitTestInfo,
1965                     new List<Activity>(new Activity[] { child }).AsReadOnly(),
1966                     string.Format(System.Globalization.CultureInfo.InvariantCulture,
1967                     DR.GetString(DR.AddingChild),
1968                     child.GetType().Name));
1969 
1970                 // If the number of child activities has increased, the branch add was successful, so
1971                 // make sure the highest indexed branch is visible
1972                 if (ContainedDesigners.Count > designerCount && ContainedDesigners.Count > 0)
1973                     ContainedDesigners[ContainedDesigners.Count - 1].EnsureVisible();
1974 
1975                 this.SelectionService.SetSelectedComponents(new object[] { child }, SelectionTypes.Primary);
1976             }
1977         }
1978 
1979         //
1980 
1981 
1982 
1983 
1984 
GetIsEditable()1985         private bool GetIsEditable()
1986         {
1987             return true;
1988         }
1989 
OnStatusSetAsInitialState(object sender, EventArgs e)1990         internal void OnStatusSetAsInitialState(object sender, EventArgs e)
1991         {
1992             ActivityDesignerVerb verb = sender as ActivityDesignerVerb;
1993             if (verb != null)
1994             {
1995                 bool enabled = false;
1996                 if (!this.HasActiveDesigner)
1997                 {
1998                     StateActivity state = (StateActivity)this.Activity;
1999                     StateActivity rootState = StateMachineHelpers.GetRootState(state);
2000                     enabled = StateMachineHelpers.IsLeafState(state) &&
2001                         StateMachineHelpers.IsStateMachine(rootState) &&
2002                         !StateMachineHelpers.IsInitialState(state);
2003                 }
2004                 verb.Visible = enabled;
2005                 verb.Enabled = enabled;
2006             }
2007         }
2008 
OnStatusSetAsCompletedState(object sender, EventArgs e)2009         internal void OnStatusSetAsCompletedState(object sender, EventArgs e)
2010         {
2011             ActivityDesignerVerb verb = sender as ActivityDesignerVerb;
2012             if (verb != null)
2013             {
2014                 bool enabled = false;
2015                 if (!this.HasActiveDesigner)
2016                 {
2017                     StateActivity state = (StateActivity)this.Activity;
2018                     StateActivity rootState = StateMachineHelpers.GetRootState(state);
2019                     enabled =
2020                         StateMachineHelpers.IsLeafState(state) &&
2021                         StateMachineHelpers.IsStateMachine(rootState) &&
2022                         !StateMachineHelpers.IsCompletedState(state) &&
2023                         (state.Activities.Count == 0);
2024                 }
2025                 verb.Visible = enabled;
2026                 verb.Enabled = enabled;
2027             }
2028         }
OnStatusAddState(object sender, EventArgs e)2029         internal void OnStatusAddState(object sender, EventArgs e)
2030         {
2031             ActivityDesignerVerb verb = sender as ActivityDesignerVerb;
2032             if (verb != null)
2033             {
2034                 bool enabled;
2035                 StateActivity state = (StateActivity)this.Activity;
2036                 bool isInitialState = false;
2037                 bool isCompletedState = false;
2038                 if (StateMachineHelpers.IsLeafState(state))
2039                 {
2040                     isInitialState = StateMachineHelpers.IsInitialState(state);
2041                     isCompletedState = StateMachineHelpers.IsCompletedState(state);
2042                 }
2043 
2044                 enabled = GetIsEditable() && (!this.HasActiveDesigner) && !isInitialState && !isCompletedState && !IsLocked && !IsStateCustomActivity;
2045                 verb.Visible = enabled;
2046                 verb.Enabled = enabled;
2047             }
2048         }
2049 
OnStatusAddEventDriven(object sender, EventArgs e)2050         internal void OnStatusAddEventDriven(object sender, EventArgs e)
2051         {
2052             ActivityDesignerVerb verb = sender as ActivityDesignerVerb;
2053             if (verb != null)
2054             {
2055                 bool enabled;
2056                 StateActivity state = (StateActivity)this.Activity;
2057                 bool isCompletedState = (StateMachineHelpers.IsLeafState(state) && StateMachineHelpers.IsCompletedState(state));
2058                 enabled = GetIsEditable() && (!this.HasActiveDesigner) && !isCompletedState && !IsLocked && !IsStateCustomActivity;
2059                 verb.Visible = enabled;
2060                 verb.Enabled = enabled;
2061             }
2062         }
2063 
OnStatusAddStateInitialization(object sender, EventArgs e)2064         internal void OnStatusAddStateInitialization(object sender, EventArgs e)
2065         {
2066             ActivityDesignerVerb verb = sender as ActivityDesignerVerb;
2067             if (verb != null)
2068             {
2069                 bool enabled;
2070                 StateActivity state = (StateActivity)this.Activity;
2071                 bool isLeafState = (StateMachineHelpers.IsLeafState(state));
2072                 bool isCompletedState = (isLeafState && StateMachineHelpers.IsCompletedState(state));
2073                 bool hasStateInitialization = this.DesignersParser.StateInitializationDesigners.Count > 0;
2074                 enabled = GetIsEditable() && (!this.HasActiveDesigner) && isLeafState && !isCompletedState && !hasStateInitialization && !IsLocked && !IsStateCustomActivity;
2075                 verb.Visible = enabled;
2076                 verb.Enabled = enabled;
2077             }
2078         }
2079 
OnStatusAddStateFinalization(object sender, EventArgs e)2080         internal void OnStatusAddStateFinalization(object sender, EventArgs e)
2081         {
2082             ActivityDesignerVerb verb = sender as ActivityDesignerVerb;
2083             if (verb != null)
2084             {
2085                 bool enabled;
2086                 StateActivity state = (StateActivity)this.Activity;
2087                 bool isLeafState = (StateMachineHelpers.IsLeafState(state));
2088                 bool isCompletedState = (isLeafState && StateMachineHelpers.IsCompletedState(state));
2089                 bool hasStateFinalization = this.DesignersParser.StateFinalizationDesigners.Count > 0;
2090                 enabled = GetIsEditable() && (!this.HasActiveDesigner) && isLeafState && !isCompletedState && !hasStateFinalization && !IsLocked && !IsStateCustomActivity;
2091                 verb.Visible = enabled;
2092                 verb.Enabled = enabled;
2093             }
2094         }
2095 
OnStatusStateMachineView(object sender, EventArgs e)2096         internal void OnStatusStateMachineView(object sender, EventArgs e)
2097         {
2098             ActivityDesignerVerb verb = sender as ActivityDesignerVerb;
2099             if (verb != null)
2100             {
2101                 bool enabled = this.HasActiveDesigner;
2102                 verb.Visible = enabled;
2103                 verb.Enabled = enabled;
2104             }
2105         }
2106 
SelectionChanged(object sender, EventArgs e)2107         private void SelectionChanged(object sender, EventArgs e)
2108         {
2109             if (this.HasActiveDesigner)
2110             {
2111                 StateActivity state = (StateActivity)this.Activity;
2112                 Activity selection = this.SelectionService.PrimarySelection as Activity;
2113                 if (selection != null &&
2114                     state.Activities.Contains(selection) &&
2115                     this.ActiveDesigner.Activity != selection)
2116                 {
2117                     ActivityDesigner activityDesigner = GetDesigner(selection);
2118                     if (!(activityDesigner is StateDesigner))
2119                         SetActiveDesigner(activityDesigner);
2120                 }
2121             }
2122             else
2123             {
2124                 if (this.Activity == this.SelectionService.PrimarySelection)
2125                     RefreshDesignerVerbs();
2126             }
2127         }
2128 
SetActiveDesigner(ActivityDesigner designer)2129         private void SetActiveDesigner(ActivityDesigner designer)
2130         {
2131             string activeDesignerName = null;
2132             if (designer == null)
2133             {
2134                 if (!this.HasActiveDesigner)
2135                     return; // Nothing to do
2136             }
2137             else
2138             {
2139                 activeDesignerName = designer.Activity.QualifiedName;
2140                 if (this.HasActiveDesigner && (this.ActiveDesigner.Activity.QualifiedName == activeDesignerName))
2141                     return; // Nothing to do.
2142             }
2143 
2144             IDesignerHost designerHost = GetService(typeof(IDesignerHost)) as IDesignerHost;
2145             DesignerTransaction transaction = null;
2146             if (designerHost != null)
2147                 transaction = designerHost.CreateTransaction(SR.GetString(SR.UndoSwitchViews));
2148 
2149             try
2150             {
2151                 StateDesigner rootDesigner = this.RootStateDesigner;
2152                 SetLeafActiveDesigner(rootDesigner, null);
2153                 SetActiveDesignerHelper(this, designer);
2154 
2155                 if (transaction != null)
2156                     transaction.Commit();
2157             }
2158             catch
2159             {
2160                 if (transaction != null)
2161                     transaction.Cancel();
2162 
2163                 throw;
2164             }
2165         }
2166 
SetLeafActiveDesigner(StateDesigner parentDesigner, ActivityDesigner activityDesigner)2167         private void SetLeafActiveDesigner(StateDesigner parentDesigner, ActivityDesigner activityDesigner)
2168         {
2169             StateDesigner stateDesigner = parentDesigner;
2170             while (true)
2171             {
2172                 StateDesigner childStateDesigner = stateDesigner.ActiveDesigner as StateDesigner;
2173                 if (childStateDesigner == null)
2174                     break;
2175                 stateDesigner = childStateDesigner;
2176             }
2177             SetActiveDesignerHelper(stateDesigner, activityDesigner);
2178         }
2179 
SetParentTreeEnsuringVisible(bool value)2180         private void SetParentTreeEnsuringVisible(bool value)
2181         {
2182             _ensuringVisible = value;
2183             StateDesigner stateDesigner = this.ParentDesigner as StateDesigner;
2184             while (stateDesigner != null)
2185             {
2186                 stateDesigner._ensuringVisible = value;
2187                 stateDesigner = stateDesigner.ParentDesigner as StateDesigner;
2188             }
2189         }
2190 
SetActiveDesignerByName(string activeDesignerName)2191         private void SetActiveDesignerByName(string activeDesignerName)
2192         {
2193             ActivityDesigner activeDesigner = null;
2194             if (!String.IsNullOrEmpty(activeDesignerName))
2195             {
2196                 foreach (ActivityDesigner activityDesigner in this.ContainedDesigners)
2197                 {
2198                     if (activityDesigner.Activity.QualifiedName == activeDesignerName)
2199                     {
2200                         activeDesigner = activityDesigner;
2201                         break;
2202                     }
2203                 }
2204             }
2205             this.ActiveDesigner = activeDesigner;
2206         }
2207 
SetActiveDesignerHelper(StateDesigner stateDesigner, ActivityDesigner activeDesigner)2208         private void SetActiveDesignerHelper(StateDesigner stateDesigner, ActivityDesigner activeDesigner)
2209         {
2210             WorkflowDesignerLoader workflowDesignerLoader = GetService(typeof(WorkflowDesignerLoader)) as WorkflowDesignerLoader;
2211             if (workflowDesignerLoader != null && workflowDesignerLoader.InDebugMode)
2212             {
2213                 stateDesigner.ActiveDesigner = activeDesigner;
2214             }
2215             else
2216             {
2217                 PropertyDescriptor activeDesignerProperty = GetPropertyDescriptor(stateDesigner.Activity, ActiveDesignerNamePropertyName);
2218                 if (activeDesigner == null)
2219                     activeDesignerProperty.SetValue(stateDesigner.Activity, null);
2220                 else
2221                     activeDesignerProperty.SetValue(stateDesigner.Activity, activeDesigner.Activity.QualifiedName);
2222             }
2223         }
2224 
2225         #endregion Private Methods
2226 
2227         #region Static Private Methods
GetService(ActivityDesigner designer, Type serviceType)2228         private static object GetService(ActivityDesigner designer, Type serviceType)
2229         {
2230             if (designer == null)
2231                 throw new ArgumentNullException("designer");
2232 
2233             if (serviceType == null)
2234                 throw new ArgumentNullException("serviceType");
2235 
2236             Activity activity = designer.Activity;
2237 
2238             object service = null;
2239             if (activity != null && activity.Site != null)
2240             {
2241                 service = activity.Site.GetService(serviceType);
2242             }
2243 
2244             return service;
2245         }
2246 
GetDesigner(Activity activity)2247         internal static ActivityDesigner GetDesigner(Activity activity)
2248         {
2249             ActivityDesigner designer = null;
2250 
2251             if (activity != null && activity.Site != null)
2252             {
2253                 IDesignerHost designerHost = activity.Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
2254                 if (designerHost != null)
2255                     designer = designerHost.GetDesigner(activity) as ActivityDesigner;
2256             }
2257 
2258             return designer;
2259         }
2260 
GetDesignerImage(ActivityDesigner designer)2261         internal static Image GetDesignerImage(ActivityDesigner designer)
2262         {
2263             Image image = null;
2264             if (designer.DesignerTheme != null && designer.DesignerTheme.DesignerImage != null)
2265                 image = designer.DesignerTheme.DesignerImage;
2266             else
2267                 if (designer.Image == null)
2268                     image = ActivityToolboxItem.GetToolboxImage(designer.Activity.GetType());
2269                 else
2270                     image = designer.Image;
2271 
2272             return image;
2273         }
2274 
GetInitialStateDesignerImage(StateDesigner stateDesigner)2275         internal static Image GetInitialStateDesignerImage(StateDesigner stateDesigner)
2276         {
2277             StateMachineTheme stateDesignerTheme = stateDesigner.DesignerTheme as StateMachineTheme;
2278             if (stateDesignerTheme != null && stateDesignerTheme.InitialStateDesignerImage != null)
2279                 return stateDesignerTheme.InitialStateDesignerImage;
2280             else
2281                 return StateDesigner.InitialState;
2282         }
2283 
GetCompletedStateDesignerImage(StateDesigner stateDesigner)2284         internal static Image GetCompletedStateDesignerImage(StateDesigner stateDesigner)
2285         {
2286             StateMachineTheme stateDesignerTheme = stateDesigner.DesignerTheme as StateMachineTheme;
2287             if (stateDesignerTheme != null && stateDesignerTheme.CompletedStateDesignerImage != null)
2288                 return stateDesignerTheme.CompletedStateDesignerImage;
2289             else
2290                 return StateDesigner.CompletedState;
2291         }
2292 
OnGetPropertyValue(ExtendedPropertyInfo extendedProperty, object extendee)2293         internal object OnGetPropertyValue(ExtendedPropertyInfo extendedProperty, object extendee)
2294         {
2295             object value = null;
2296             if (extendedProperty.Name.Equals("Location", StringComparison.Ordinal))
2297                 value = (ActiveDesigner == null) ? Location : this._stateLocation;
2298             else if (extendedProperty.Name.Equals("Size", StringComparison.Ordinal))
2299                 value = (ActiveDesigner == null) ? Size : this._stateSize;
2300             return value;
2301         }
2302 
2303         // We have this method here, instead of using Activity.GetActivityByName
2304         // because the Activity method ignores activities like FaultHandlers.
2305         // When in designer mode, we need to search the entire activity tree.
FindActivityByQualifiedName(Activity activity, string qualifiedName)2306         private static Activity FindActivityByQualifiedName(Activity activity, string qualifiedName)
2307         {
2308             Queue<Activity> activities = new Queue<Activity>();
2309             activities.Enqueue(activity);
2310             while (activities.Count > 0)
2311             {
2312                 activity = activities.Dequeue();
2313                 if (activity.QualifiedName.Equals(qualifiedName))
2314                     return activity;
2315 
2316                 CompositeActivity compositeActivity = activity as CompositeActivity;
2317                 if (compositeActivity != null)
2318                     foreach (Activity childActivity in compositeActivity.Activities)
2319                         activities.Enqueue(childActivity);
2320             }
2321             return null;
2322         }
2323 
2324         #endregion
2325 
2326         #endregion Methods
2327 
2328         #region Class StateDesignerPropertyExtender
2329         [ProvideProperty("ActiveDesignerName", typeof(Activity))]
2330         private sealed class StateDesignerPropertyExtender : IExtenderProvider
2331         {
2332             #region Properties
2333             [DesignOnly(true)]
2334             [MergableProperty(false)]
2335             [Browsable(false)]
2336             [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
GetActiveDesignerName(Activity activity)2337             public string GetActiveDesignerName(Activity activity)
2338             {
2339                 string activeDesignerName = null;
2340                 StateDesigner designer = (StateDesigner)StateDesigner.GetDesigner(activity);
2341                 if (designer != null)
2342                 {
2343                     ActivityDesigner activeDesigner = designer.ActiveDesigner;
2344                     if (activeDesigner != null)
2345                     {
2346                         activeDesignerName = activeDesigner.Activity.QualifiedName;
2347                     }
2348                 }
2349                 return activeDesignerName;
2350             }
2351 
SetActiveDesignerName(Activity activity, string activeDesignerName)2352             public void SetActiveDesignerName(Activity activity, string activeDesignerName)
2353             {
2354                 StateDesigner designer = (StateDesigner)StateDesigner.GetDesigner(activity);
2355                 if (designer != null)
2356                 {
2357                     designer.SetActiveDesignerByName(activeDesignerName);
2358                 }
2359             }
2360 
2361 
2362             #endregion
IExtenderProvider.CanExtend(object extendee)2363             bool IExtenderProvider.CanExtend(object extendee)
2364             {
2365                 bool canExtend = false;
2366 
2367                 StateActivity activity = extendee as StateActivity;
2368                 if (activity != null)
2369                 {
2370                     StateDesigner designer = StateDesigner.GetDesigner(activity) as StateDesigner;
2371                     if (designer != null)
2372                     {
2373                         canExtend = true;
2374                     }
2375                 }
2376                 return canExtend;
2377             }
2378         }
2379         #endregion
2380     }
2381     #endregion StateDesigner Class
2382 
2383     #region Class StateDesignerLayoutSerializer
2384     internal class StateDesignerLayoutSerializer : FreeformActivityDesignerLayoutSerializer
2385     {
GetProperties(WorkflowMarkupSerializationManager serializationManager, object obj)2386         protected override PropertyInfo[] GetProperties(WorkflowMarkupSerializationManager serializationManager, object obj)
2387         {
2388             List<PropertyInfo> properties = new List<PropertyInfo>();
2389             StateDesigner stateDesigner = obj as StateDesigner;
2390             if (stateDesigner != null)
2391             {
2392                 foreach (PropertyInfo property in base.GetProperties(serializationManager, obj))
2393                 {
2394                     if (property.Name.Equals("Location", StringComparison.Ordinal) ||
2395                         property.Name.Equals("Size", StringComparison.Ordinal))
2396                     {
2397                         properties.Add(new ExtendedPropertyInfo(property, new GetValueHandler(stateDesigner.OnGetPropertyValue)));
2398                     }
2399                     else
2400                     {
2401                         properties.Add(property);
2402                     }
2403                 }
2404             }
2405             else
2406             {
2407                 properties.AddRange(base.GetProperties(serializationManager, obj));
2408             }
2409 
2410             return properties.ToArray();
2411         }
2412     }
2413     #endregion
2414 
2415     #region Class ExtendedPropertyInfo
2416     //
GetValueHandler(ExtendedPropertyInfo extendedProperty, object extendee)2417     internal delegate object GetValueHandler(ExtendedPropertyInfo extendedProperty, object extendee);
2418 
2419     internal sealed class ExtendedPropertyInfo : PropertyInfo
2420     {
2421         #region Members and Constructors
2422         private PropertyInfo realPropertyInfo = null;
2423         private GetValueHandler OnGetValue;
2424 
ExtendedPropertyInfo(PropertyInfo propertyInfo, GetValueHandler getValueHandler)2425         internal ExtendedPropertyInfo(PropertyInfo propertyInfo, GetValueHandler getValueHandler)
2426         {
2427             this.realPropertyInfo = propertyInfo;
2428             this.OnGetValue = getValueHandler;
2429         }
2430         #endregion
2431 
2432         #region Property Info overrides
2433         public override string Name
2434         {
2435             get
2436             {
2437                 return this.realPropertyInfo.Name;
2438             }
2439         }
2440 
2441         public override Type DeclaringType
2442         {
2443             get
2444             {
2445                 return this.realPropertyInfo.DeclaringType;
2446             }
2447         }
2448 
2449         public override Type ReflectedType
2450         {
2451             get
2452             {
2453                 return this.realPropertyInfo.ReflectedType;
2454             }
2455         }
2456 
2457         public override Type PropertyType
2458         {
2459             get
2460             {
2461                 return this.realPropertyInfo.PropertyType;
2462             }
2463         }
2464 
GetAccessors(bool nonPublic)2465         public override MethodInfo[] GetAccessors(bool nonPublic)
2466         {
2467             return this.realPropertyInfo.GetAccessors(nonPublic);
2468         }
2469 
GetGetMethod(bool nonPublic)2470         public override MethodInfo GetGetMethod(bool nonPublic)
2471         {
2472             return this.realPropertyInfo.GetGetMethod(nonPublic);
2473         }
2474 
GetSetMethod(bool nonPublic)2475         public override MethodInfo GetSetMethod(bool nonPublic)
2476         {
2477             return this.realPropertyInfo.GetSetMethod(nonPublic);
2478         }
2479 
GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture)2480         public override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture)
2481         {
2482             if (OnGetValue != null)
2483                 return OnGetValue(this, obj);
2484             else
2485                 return null;
2486         }
2487 
SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture)2488         public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture)
2489         {
2490             this.realPropertyInfo.SetValue(obj, value, invokeAttr, binder, index, culture);
2491         }
2492 
GetIndexParameters()2493         public override ParameterInfo[] GetIndexParameters()
2494         {
2495             return this.realPropertyInfo.GetIndexParameters();
2496         }
2497 
2498         public override PropertyAttributes Attributes
2499         {
2500             get
2501             {
2502                 return this.realPropertyInfo.Attributes;
2503             }
2504         }
2505 
2506         public override bool CanRead
2507         {
2508             get
2509             {
2510                 return this.realPropertyInfo.CanRead;
2511             }
2512         }
2513 
2514         public override bool CanWrite
2515         {
2516             get
2517             {
2518                 return this.realPropertyInfo.CanWrite;
2519             }
2520         }
2521         #endregion
2522 
2523         #region MemberInfo Overrides
GetCustomAttributes(bool inherit)2524         public override object[] GetCustomAttributes(bool inherit)
2525         {
2526             return this.realPropertyInfo.GetCustomAttributes(inherit);
2527         }
2528 
GetCustomAttributes(Type attributeType, bool inherit)2529         public override object[] GetCustomAttributes(Type attributeType, bool inherit)
2530         {
2531             return this.realPropertyInfo.GetCustomAttributes(attributeType, inherit);
2532         }
2533 
IsDefined(Type attributeType, bool inherit)2534         public override bool IsDefined(Type attributeType, bool inherit)
2535         {
2536             return this.realPropertyInfo.IsDefined(attributeType, inherit);
2537         }
2538         #endregion
2539 
2540 
2541     }
2542     #endregion
2543 
2544     #region Class ImageBrowserEditor
2545     internal sealed class ImageBrowserEditor : UITypeEditor
2546     {
GetEditStyle(ITypeDescriptorContext context)2547         public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
2548         {
2549             return UITypeEditorEditStyle.Modal;
2550         }
2551 
EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)2552         public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
2553         {
2554             OpenFileDialog fileDialog = new OpenFileDialog();
2555             fileDialog.AddExtension = true;
2556             fileDialog.DefaultExt = StateMachineTheme.DefaultThemeFileExtension;
2557             fileDialog.CheckFileExists = true;
2558             fileDialog.Filter = DR.GetString(DR.ImageFileFilter);
2559             if (fileDialog.ShowDialog() == DialogResult.OK)
2560                 return fileDialog.FileName;
2561             else
2562                 return value;
2563         }
2564     }
2565     #endregion
2566 
2567     #region StateMachineTheme
2568     internal class StateMachineTheme : CompositeDesignerTheme
2569     {
2570         internal const string DefaultThemeFileExtension = "*.wtm";
2571 
2572         private Color _connectorColor = Color.Black;
2573         private Pen _connectorPen;
2574         private Size _connectorSize = new Size(20, 20);
2575         private string _initialStateDesignerImagePath;
2576         private string _completedStateDesignerImagePath;
2577         private Image _initialStateDesignerImage;
2578         private Image _completedStateDesignerImage;
2579 
StateMachineTheme(WorkflowTheme theme)2580         public StateMachineTheme(WorkflowTheme theme)
2581             : base(theme)
2582         {
2583         }
2584 
2585         public override Size ConnectorSize
2586         {
2587             get
2588             {
2589                 return _connectorSize;
2590             }
2591         }
2592 
Dispose(bool disposing)2593         protected override void Dispose(bool disposing)
2594         {
2595             try
2596             {
2597                 if (this._connectorPen != null)
2598                 {
2599                     this._connectorPen.Dispose();
2600                     this._connectorPen = null;
2601                 }
2602             }
2603             finally
2604             {
2605                 base.Dispose(disposing);
2606             }
2607         }
2608 
2609         [SRDescription(SR.ConnectorColorDescription)]
2610         [SRCategory(SR.ForegroundCategory)]
2611         public Color ConnectorColor
2612         {
2613             get
2614             {
2615                 return _connectorColor;
2616             }
2617             set
2618             {
2619                 _connectorColor = value;
2620             }
2621         }
2622 
2623         [SRDescription(SR.InitialStateImagePathDescription)]
2624         [SRCategory(SR.ForegroundCategory)]
2625         [Editor(typeof(ImageBrowserEditor), typeof(UITypeEditor))]
2626         public virtual string InitialStateDesignerImagePath
2627         {
2628             get
2629             {
2630                 return _initialStateDesignerImagePath;
2631             }
2632             set
2633             {
2634                 if (ReadOnly)
2635                     throw new InvalidOperationException(DR.GetString(DR.ThemePropertyReadOnly));
2636 
2637                 if (value != null && value.Length > 0 && value.Contains(Path.DirectorySeparatorChar.ToString()) && Path.IsPathRooted(value))
2638                 {
2639                     value = GetRelativePath(ContainingTheme.ContainingFileDirectory, value);
2640 
2641                     if (!IsValidImageResource(this, ContainingTheme.ContainingFileDirectory, value))
2642                         throw new InvalidOperationException(DR.GetString(DR.Error_InvalidImageResource));
2643                 }
2644 
2645                 this._initialStateDesignerImagePath = value;
2646                 if (this._initialStateDesignerImage != null)
2647                 {
2648                     this._initialStateDesignerImage.Dispose();
2649                     this._initialStateDesignerImage = null;
2650                 }
2651             }
2652         }
2653 
2654         [SRDescription(SR.CompletedStateImagePathDescription)]
2655         [SRCategory(SR.ForegroundCategory)]
2656         [Editor(typeof(ImageBrowserEditor), typeof(UITypeEditor))]
2657         public virtual string CompletedStateDesignerImagePath
2658         {
2659             get
2660             {
2661                 return _completedStateDesignerImagePath;
2662             }
2663             set
2664             {
2665                 if (ReadOnly)
2666                     throw new InvalidOperationException(DR.GetString(DR.ThemePropertyReadOnly));
2667 
2668                 if (value != null && value.Length > 0 && value.Contains(Path.DirectorySeparatorChar.ToString()) && Path.IsPathRooted(value))
2669                 {
2670                     value = GetRelativePath(ContainingTheme.ContainingFileDirectory, value);
2671 
2672                     if (!IsValidImageResource(this, ContainingTheme.ContainingFileDirectory, value))
2673                         throw new InvalidOperationException(DR.GetString(DR.Error_InvalidImageResource));
2674                 }
2675 
2676                 this._completedStateDesignerImagePath = value;
2677                 if (this._completedStateDesignerImage != null)
2678                 {
2679                     this._completedStateDesignerImage.Dispose();
2680                     this._completedStateDesignerImage = null;
2681                 }
2682             }
2683         }
2684 
2685         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
2686         [Browsable(false)]
2687         public Pen ConnectorPen
2688         {
2689             get
2690             {
2691                 if (this._connectorPen == null)
2692                     this._connectorPen = new Pen(this._connectorColor, BorderWidth);
2693                 return this._connectorPen;
2694             }
2695         }
2696 
2697         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
2698         [Browsable(false)]
2699         public Image InitialStateDesignerImage
2700         {
2701             get
2702             {
2703                 if (_initialStateDesignerImage == null && !String.IsNullOrEmpty(_initialStateDesignerImagePath))
2704                     _initialStateDesignerImage = GetImageFromPath(this, ContainingTheme.ContainingFileDirectory, _initialStateDesignerImagePath);
2705                 return _initialStateDesignerImage;
2706             }
2707         }
2708 
2709         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
2710         [Browsable(false)]
2711         public Image CompletedStateDesignerImage
2712         {
2713             get
2714             {
2715                 if (_completedStateDesignerImage == null && !String.IsNullOrEmpty(_completedStateDesignerImagePath))
2716                     _completedStateDesignerImage = GetImageFromPath(this, ContainingTheme.ContainingFileDirectory, _completedStateDesignerImagePath);
2717                 return _completedStateDesignerImage;
2718             }
2719         }
2720 
IsValidImageResource(DesignerTheme designerTheme, string directory, string path)2721         internal static bool IsValidImageResource(DesignerTheme designerTheme, string directory, string path)
2722         {
2723             Image image = GetImageFromPath(designerTheme, directory, path);
2724             bool validImage = (image != null);
2725             if (image != null)
2726                 image.Dispose();
2727             return validImage;
2728         }
2729 
GetRelativePath(string pathFrom, string pathTo)2730         internal static string GetRelativePath(string pathFrom, string pathTo)
2731         {
2732             Uri uri = new Uri(pathFrom);
2733             string relativePath = Uri.UnescapeDataString(uri.MakeRelativeUri(new Uri(pathTo)).ToString());
2734             relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
2735             if (!relativePath.Contains(Path.DirectorySeparatorChar.ToString()))
2736                 relativePath = "." + Path.DirectorySeparatorChar + relativePath;
2737             return relativePath;
2738         }
2739 
GetImageFromPath(DesignerTheme designerTheme, string directory, string path)2740         internal static Image GetImageFromPath(DesignerTheme designerTheme, string directory, string path)
2741         {
2742             Bitmap image = null;
2743             if (path.Contains(Path.DirectorySeparatorChar.ToString()) && directory.Length > 0)
2744             {
2745                 string imageFilePath = System.Web.HttpUtility.UrlDecode((new Uri(new Uri(directory), path).LocalPath));
2746                 if (File.Exists(imageFilePath))
2747                 {
2748                     try
2749                     {
2750                         image = new Bitmap(imageFilePath);
2751                     }
2752                     catch
2753                     {
2754                     }
2755                 }
2756             }
2757             else if (designerTheme.DesignerType != null)
2758             {
2759                 int index = path.LastIndexOf('.');
2760                 if (index > 0)
2761                 {
2762                     string nameSpace = path.Substring(0, index);
2763                     string name = path.Substring(index + 1);
2764                     if (nameSpace != null && nameSpace.Length > 0 &&
2765                         name != null && name.Length > 0)
2766                     {
2767                         try
2768                         {
2769                             ResourceManager resourceManager = new ResourceManager(nameSpace, designerTheme.DesignerType.Assembly);
2770                             image = resourceManager.GetObject(name) as Bitmap;
2771                         }
2772                         catch
2773                         {
2774                         }
2775                     }
2776                 }
2777             }
2778 
2779             if (image != null)
2780                 image.MakeTransparent(DR.TransparentColor);
2781 
2782             return image;
2783         }
2784 
2785     }
2786     #endregion
2787 
2788     #region StateDesignerTheme
2789     internal sealed class StateDesignerTheme : StateMachineTheme
2790     {
StateDesignerTheme(WorkflowTheme theme)2791         public StateDesignerTheme(WorkflowTheme theme)
2792             : base(theme)
2793         {
2794             this.ShowDropShadow = false;
2795             this.ConnectorStartCap = LineAnchor.DiamondAnchor;
2796             this.ConnectorEndCap = LineAnchor.ArrowAnchor;
2797             this.ForeColor = Color.FromArgb(0xFF, 0x10, 0x10, 0x10);
2798             this.BorderColor = Color.FromArgb(0xFF, 0x49, 0x77, 0xb4);
2799             this.BorderStyle = DashStyle.Solid;
2800             this.BackColorStart = Color.FromArgb(0xd0, 0xff, 0xff, 0xff);
2801             this.BackColorEnd = Color.FromArgb(0xd0, 0xff, 0xff, 0xff);
2802         }
2803     }
2804     #endregion
2805 }
2806