ed7ed08ff4e48f66622bd3a8b38c0335913b9c9f
[mono.git] / mcs / class / referencesource / System.Workflow.ComponentModel / AuthoringOM / Design / StructuredCompositeActivityDesigner.cs
1 #pragma warning disable 1634, 1691
2 namespace System.Workflow.ComponentModel.Design
3 {
4     using System;
5     using System.IO;
6     using System.Drawing;
7     using System.CodeDom;
8     using System.Diagnostics;
9     using System.Collections;
10     using System.Collections.Generic;
11     using System.Windows.Forms;
12     using System.ComponentModel;
13     using System.Globalization;
14     using System.Drawing.Design;
15     using System.Drawing.Imaging;
16     using System.Drawing.Drawing2D;
17     using System.Windows.Forms.Design;
18     using System.ComponentModel.Design;
19     using System.Collections.Specialized;
20     using System.ComponentModel.Design.Serialization;
21     using System.Workflow.ComponentModel.Compiler;
22     using System.Workflow.ComponentModel.Serialization;
23     using System.Collections.ObjectModel;
24     using System.Reflection;
25     using System.Workflow.ComponentModel.Design;
26     using System.Runtime.Serialization.Formatters.Binary;
27
28     //
29
30
31
32     #region StructuredCompositeActivityDesigner Class
33     /// <summary>
34     /// Base class for CompositActivityDesigner which have a structured layouts where contained ContainedDesigners
35     /// are connected to each other using connectors. Class is used when the user needs to provide different types 
36     /// of layouts for CompositeActivityDesigner
37     /// </summary>
38     [Obsolete("The System.Workflow.* types are deprecated.  Instead, please use the new types from System.Activities.*")]
39     public abstract class StructuredCompositeActivityDesigner : CompositeActivityDesigner
40     {
41         #region Fields
42         private int currentDropTarget = -1;
43
44         private List<DesignerView> views = null;
45         private DesignerView activeView;
46         private ItemPalette itemPalette = null;
47         #endregion
48
49         #region Properties
50
51         #region Public Properties
52         public override ReadOnlyCollection<ActivityDesigner> ContainedDesigners
53         {
54             get
55             {
56                 List<ActivityDesigner> containedDesigners = new List<ActivityDesigner>();
57                 ActivityDesigner activeDesigner = ActiveDesigner;
58                 if (activeDesigner != null)
59                 {
60                     if (activeDesigner == this)
61                     {
62                         //We need to remove the secondary activities
63                         containedDesigners.AddRange(base.ContainedDesigners);
64
65                         List<ActivityDesigner> designersToRemove = new List<ActivityDesigner>();
66                         IList<ActivityDesigner> mappedDesigners = DesignersFromSupportedViews;
67
68                         foreach (ActivityDesigner containedDesigner in containedDesigners)
69                         {
70                             bool isAlternateFlowActivityAttribute = Helpers.IsAlternateFlowActivity(containedDesigner.Activity);
71                             if (mappedDesigners.Contains(containedDesigner) || isAlternateFlowActivityAttribute)
72                                 designersToRemove.Add(containedDesigner);
73                         }
74
75                         foreach (ActivityDesigner activityDesigner in designersToRemove)
76                             containedDesigners.Remove(activityDesigner);
77                     }
78                     else
79                     {
80                         containedDesigners.Add(activeDesigner);
81                     }
82                 }
83
84                 return containedDesigners.AsReadOnly();
85             }
86         }
87
88         public override object FirstSelectableObject
89         {
90             get
91             {
92                 ActivityDesigner activeDesigner = ActiveDesigner;
93                 if (activeDesigner != null && activeDesigner != this)
94                     return activeDesigner.Activity;
95                 else
96                     return base.FirstSelectableObject;
97             }
98         }
99
100         public override object LastSelectableObject
101         {
102             get
103             {
104                 ActivityDesigner activeDesigner = ActiveDesigner;
105                 if (activeDesigner != null && activeDesigner != this && activeDesigner is CompositeActivityDesigner)
106                     return ((CompositeActivityDesigner)activeDesigner).LastSelectableObject;
107                 else
108                     return base.LastSelectableObject;
109             }
110         }
111
112         /// <summary>
113         /// Gets the ActiveView supported by the designer
114         /// </summary>
115         [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
116         public DesignerView ActiveView
117         {
118             get
119             {
120                 if (this.activeView == null)
121                     this.activeView = ValidatedViews[0];
122                 return this.activeView;
123             }
124
125             set
126             {
127                 if (this.activeView == value || value == null)
128                     return;
129
130                 DesignerView previousView = this.activeView;
131
132                 this.activeView = value;
133
134                 value.OnActivate();
135
136                 ActivityDesigner designer = value.AssociatedDesigner;
137                 if (designer == null)
138                 {
139                     value.OnDeactivate();
140                     this.activeView = previousView;
141                     return;
142                 }
143
144                 if (previousView != null)
145                     previousView.OnDeactivate();
146
147                 OnViewChanged(this.activeView);
148
149                 //When we change the view we want to make sure that if we hide any of the child
150                 //activities with errors we want to reveal these activities
151                 DesignerHelpers.RefreshDesignerActions(Activity.Site);
152
153                 //Keep the dynamic action and designer verbs in sync
154                 RefreshDesignerVerbs();
155             }
156         }
157
158         public override Size MinimumSize
159         {
160             get
161             {
162                 Size minimumSize = base.MinimumSize;
163
164                 ActivityDesigner activeDesigner = ActiveDesigner;
165                 if (activeDesigner != null && activeDesigner != this && Expanded)
166                 {
167                     minimumSize.Width = Math.Max(minimumSize.Width, 160);
168                     minimumSize.Height = Math.Max(minimumSize.Height, 160);
169                 }
170
171                 return minimumSize;
172             }
173         }
174
175         /// <summary>
176         /// Gets the array of views supported by the current designer
177         /// </summary>
178         public virtual ReadOnlyCollection<DesignerView> Views
179         {
180             get
181             {
182                 if (this.views == null)
183                 {
184                     this.views = new List<DesignerView>();
185                     this.views.AddRange(SecondaryViewProvider.GetViews(this));
186                 }
187
188                 return this.views.AsReadOnly();
189             }
190         }
191         #endregion
192
193         #region Protected Properties
194         /// <summary>
195         /// Gets the index of the cuurent drop target in the array of drop targets returned by method GetDropTargets
196         /// This property is only used when the drag drop operation is in progress
197         /// </summary>
198         protected virtual int CurrentDropTarget
199         {
200             get
201             {
202                 return this.currentDropTarget;
203             }
204
205             set
206             {
207                 this.currentDropTarget = value;
208                 Invalidate();
209             }
210         }
211
212         protected override bool ShowSmartTag
213         {
214             get
215             {
216                 return (!String.IsNullOrEmpty(Text) && !TextRectangle.Size.IsEmpty && Views.Count > 1);
217             }
218         }
219
220         protected override ReadOnlyCollection<ActivityDesignerVerb> SmartTagVerbs
221         {
222             get
223             {
224                 List<ActivityDesignerVerb> smartTagVerbs = new List<ActivityDesignerVerb>(base.SmartTagVerbs);
225
226                 //Return smarttag actions only if there is more than one view
227                 if (Views.Count > 1)
228                 {
229                     for (int i = 0; i < Views.Count; i++)
230                     {
231                         DesignerView view = Views[i];
232                         ActivityDesignerVerb smartVerb = new ActivityDesignerVerb(this, DesignerVerbGroup.Actions, view.Text, new EventHandler(OnSmartTagVerb), new EventHandler(OnSmartTagVerbStatus));
233                         smartVerb.Properties[DesignerUserDataKeys.DesignerView] = view;
234                         smartVerb.Properties[DesignerUserDataKeys.Image] = view.Image;
235                         smartTagVerbs.Add(smartVerb);
236                     }
237                 }
238
239                 return smartTagVerbs.AsReadOnly();
240             }
241         }
242         #endregion
243
244         #region Private Properties
245         internal ActivityDesigner ActiveDesigner
246         {
247             get
248             {
249                 if (ActiveView != null)
250                     return ActiveView.AssociatedDesigner;
251                 else
252                     return null;
253             }
254         }
255
256         internal override bool SmartTagVisible
257         {
258             get
259             {
260                 if (this.itemPalette != null && this.itemPalette.IsVisible)
261                     return true;
262
263                 return base.SmartTagVisible;
264             }
265
266             set
267             {
268                 base.SmartTagVisible = value;
269             }
270         }
271
272         private ReadOnlyCollection<DesignerView> ValidatedViews
273         {
274             get
275             {
276                 ReadOnlyCollection<DesignerView> views = Views;
277                 if (views.Count == 0)
278 #pragma warning suppress 56503
279                     throw new InvalidOperationException(DR.GetString(DR.Error_MultiviewSequentialActivityDesigner));
280                 return views;
281             }
282         }
283
284         private IList<ActivityDesigner> DesignersFromSupportedViews
285         {
286             get
287             {
288                 List<ActivityDesigner> mappedDesigners = new List<ActivityDesigner>();
289                 foreach (DesignerView view in ValidatedViews)
290                 {
291                     ActivityDesigner mappedDesigner = view.AssociatedDesigner;
292                     if (mappedDesigner != null)
293                         mappedDesigners.Add(mappedDesigner);
294                 }
295
296                 return mappedDesigners.AsReadOnly();
297             }
298         }
299         #endregion
300
301         #endregion
302
303         #region Methods
304
305         #region Public Methods
306         public override bool CanInsertActivities(HitTestInfo insertLocation, ReadOnlyCollection<Activity> activitiesToInsert)
307         {
308             if (insertLocation == null)
309                 throw new ArgumentNullException("insertLocation");
310
311             if (activitiesToInsert == null)
312                 throw new ArgumentNullException("activitiesToInsert");
313
314             ActivityDesigner hostedDesigner = (ActiveView != null) ? ActiveView.AssociatedDesigner : null;
315             if (hostedDesigner != this)
316                 return false;
317
318             IList<Type> secondaryViewTypes = SecondaryViewProvider.GetActivityTypes(this);
319             foreach (Activity activity in activitiesToInsert)
320             {
321                 if (activity == null)
322                     throw new ArgumentException("activitiesToInsert", SR.GetString(SR.Error_CollectionHasNullEntry));
323
324                 if (secondaryViewTypes.Contains(activity.GetType()))
325                     return false;
326             }
327
328             return base.CanInsertActivities(GetUpdatedLocation(insertLocation), activitiesToInsert);
329         }
330
331         public override void InsertActivities(HitTestInfo insertLocation, ReadOnlyCollection<Activity> activitiesToInsert)
332         {
333             if (insertLocation == null)
334                 throw new ArgumentNullException("insertLocation");
335
336             if (activitiesToInsert == null)
337                 throw new ArgumentNullException("activitiesToInsert");
338
339             base.InsertActivities(GetUpdatedLocation(insertLocation), activitiesToInsert);
340         }
341
342         public override void MoveActivities(HitTestInfo moveLocation, ReadOnlyCollection<Activity> activitiesToMove)
343         {
344             if (moveLocation == null)
345                 throw new ArgumentNullException("moveLocation");
346
347             if (activitiesToMove == null)
348                 throw new ArgumentNullException("activitiesToMove");
349
350             base.MoveActivities(GetUpdatedLocation(moveLocation), activitiesToMove);
351         }
352
353         public override bool CanRemoveActivities(ReadOnlyCollection<Activity> activitiesToRemove)
354         {
355             if (activitiesToRemove == null)
356                 throw new ArgumentNullException("activitiesToRemove");
357
358             return base.CanRemoveActivities(activitiesToRemove);
359         }
360
361         public override void EnsureVisibleContainedDesigner(ActivityDesigner containedDesigner)
362         {
363             if (containedDesigner == null)
364                 throw new ArgumentNullException("containedDesigner");
365
366             //we could be collapsed, make sure the view itself is visible
367             this.Expanded = true;
368
369             ActivityDesigner activeDesigner = ActiveDesigner;
370             if (containedDesigner != activeDesigner && containedDesigner != this)
371             {
372                 DesignerView viewToActivate = null;
373                 ReadOnlyCollection<DesignerView> views = ValidatedViews;
374
375                 //Go thru the views and check if the child designer is one of the views
376                 foreach (DesignerView view in views)
377                 {
378                     if (containedDesigner == view.AssociatedDesigner)
379                     {
380                         viewToActivate = view;
381                         break;
382                     }
383                 }
384
385                 //This means that the child designer is in our main flow
386                 if (viewToActivate == null)
387                     viewToActivate = views[0];
388
389                 ActiveView = viewToActivate;
390
391                 //Invoking a verb might change the shown view so we map again
392                 CompositeActivityDesigner activeCompositeDesigner = ActiveDesigner as CompositeActivityDesigner;
393                 if (activeCompositeDesigner != null)
394                 {
395                     if (activeCompositeDesigner != this)
396                         activeCompositeDesigner.EnsureVisibleContainedDesigner(containedDesigner);
397                     else
398                         base.EnsureVisibleContainedDesigner(containedDesigner);
399                 }
400             }
401         }
402
403         public override object GetNextSelectableObject(object current, DesignerNavigationDirection direction)
404         {
405             object nextObject = null;
406
407             ActivityDesigner activeDesigner = ActiveDesigner;
408             if (activeDesigner != null)
409             {
410                 if (activeDesigner != this)
411                 {
412                     if (current != activeDesigner.Activity && activeDesigner is CompositeActivityDesigner)
413                         nextObject = ((CompositeActivityDesigner)activeDesigner).GetNextSelectableObject(current, direction);
414                 }
415                 else
416                 {
417                     nextObject = base.GetNextSelectableObject(current, direction);
418                 }
419             }
420
421             return nextObject;
422         }
423         #endregion
424
425         #region Protected Methods
426         protected override void Initialize(Activity activity)
427         {
428             base.Initialize(activity);
429
430             ActiveView = ValidatedViews[0];
431         }
432
433         /// <summary>
434         /// Returns the collection of points which represents the inner connections of the designer. The designer can have connectors
435         /// within it, the points returned are the connection points used for connectable designer.
436         /// </summary>
437         /// <param name="edges">Designer Edge along which the connection point lies</param>
438         /// <returns>List of connection Points</returns>
439         protected virtual ReadOnlyCollection<Point> GetInnerConnections(DesignerEdges edges)
440         {
441             List<Point> connectionPoints = new List<Point>(GetConnections(edges));
442             if (connectionPoints.Count > 0 && (edges & DesignerEdges.Top) > 0)
443                 connectionPoints[0] = new Point(connectionPoints[0].X, connectionPoints[0].Y + TitleHeight);
444             return connectionPoints.AsReadOnly();
445         }
446
447         /// <summary>
448         /// Returns array of rectangles representing the valid drop locations with the designer
449         /// </summary>
450         /// <param name="dropPoint"></param>
451         /// <returns></returns>
452         protected virtual Rectangle[] GetDropTargets(Point dropPoint)
453         {
454             return new Rectangle[] { Bounds };
455         }
456
457         protected override void OnContainedActivitiesChanging(ActivityCollectionChangeEventArgs listChangeArgs)
458         {
459             base.OnContainedActivitiesChanging(listChangeArgs);
460
461             if (listChangeArgs.Action == ActivityCollectionChangeAction.Remove && listChangeArgs.RemovedItems[0] != null)
462             {
463                 ActivityDesigner activeDesigner = ActiveDesigner;
464                 if (activeDesigner != null && listChangeArgs.RemovedItems[0] == activeDesigner.Activity)
465                     ActiveView = ValidatedViews[0];
466                 SecondaryViewProvider.OnViewRemoved(this, listChangeArgs.RemovedItems[0].GetType());
467             }
468         }
469
470         protected void DrawConnectors(Graphics graphics, Pen pen, Point[] points, LineAnchor startCap, LineAnchor endCap)
471         {
472             Size arrowCapSize = Size.Empty;
473             Size maxCapSize = Size.Empty;
474
475             CompositeDesignerTheme compositeDesignerTheme = DesignerTheme as CompositeDesignerTheme;
476             if (compositeDesignerTheme != null)
477             {
478                 arrowCapSize = new Size(compositeDesignerTheme.ConnectorSize.Width / 3, compositeDesignerTheme.ConnectorSize.Height / 3);
479                 maxCapSize = compositeDesignerTheme.ConnectorSize;
480             }
481             ActivityDesignerPaint.DrawConnectors(graphics, pen, points, arrowCapSize, maxCapSize, startCap, endCap);
482         }
483
484         protected override void OnDragEnter(ActivityDragEventArgs e)
485         {
486             base.OnDragEnter(e);
487
488             CurrentDropTarget = CanDrop(e);
489             e.Effect = CheckDragEffect(e);
490             e.DragImageSnapPoint = SnapInToDropTarget(e);
491         }
492
493         protected override void OnDragOver(ActivityDragEventArgs e)
494         {
495             base.OnDragOver(e);
496
497             CurrentDropTarget = CanDrop(e);
498             e.Effect = CheckDragEffect(e);
499             e.DragImageSnapPoint = SnapInToDropTarget(e);
500         }
501
502         protected override void OnDragLeave()
503         {
504             base.OnDragLeave();
505
506             //Clear earlier drop target information
507             CurrentDropTarget = -1;
508         }
509
510         protected override void OnDragDrop(ActivityDragEventArgs e)
511         {
512             base.OnDragDrop(e);
513
514             bool ctrlKeyPressed = ((e.KeyState & 8) == 8);
515             if (ctrlKeyPressed && (e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)
516                 e.Effect = DragDropEffects.Copy;
517             else if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)
518                 e.Effect = DragDropEffects.Move;
519
520             //If the component is sited then that means that we are moving it 
521             try
522             {
523                 CompositeActivityDesigner.InsertActivities(this, new ConnectorHitTestInfo(this, HitTestLocations.Designer, CurrentDropTarget), e.Activities, SR.GetString(SR.DragDropActivities));
524             }
525             finally
526             {
527                 CurrentDropTarget = -1;
528             }
529         }
530
531         protected override void OnLayoutPosition(ActivityDesignerLayoutEventArgs e)
532         {
533             if (e == null)
534                 throw new ArgumentNullException("e");
535
536             base.OnLayoutPosition(e);
537
538             if (Expanded)
539             {
540                 ActivityDesigner activeDesigner = ActiveDesigner;
541                 if (activeDesigner != null && activeDesigner != this)
542                 {
543                     Point location = Location;
544                     location.X += (Size.Width - activeDesigner.Size.Width) / 2;
545                     location.Y += e.AmbientTheme.SelectionSize.Height;
546                     activeDesigner.Location = location;
547                 }
548
549                 int titleHeight = TitleHeight;
550                 foreach (ActivityDesigner activityDesigner in ContainedDesigners)
551                     activityDesigner.Location = new Point(activityDesigner.Location.X, activityDesigner.Location.Y + titleHeight);
552             }
553         }
554
555         protected override Size OnLayoutSize(ActivityDesignerLayoutEventArgs e)
556         {
557             Size containerSize = base.OnLayoutSize(e);
558
559             if (Expanded)
560             {
561                 ActivityDesigner activeDesigner = ActiveDesigner;
562                 if (activeDesigner != null && activeDesigner != this)
563                 {
564                     containerSize.Width = Math.Max(containerSize.Width, activeDesigner.Size.Width);
565                     containerSize.Height += activeDesigner.Size.Height;
566
567                     containerSize.Width += 2 * e.AmbientTheme.SelectionSize.Width;
568                     containerSize.Width += 3 * e.AmbientTheme.Margin.Width;
569                     containerSize.Height += e.AmbientTheme.Margin.Height;
570                     containerSize.Height += 2 * e.AmbientTheme.SelectionSize.Height;
571                 }
572             }
573
574             return containerSize;
575         }
576
577         protected override void SaveViewState(BinaryWriter writer)
578         {
579             if (writer == null)
580                 throw new ArgumentNullException("writer");
581
582             List<DesignerView> views = new List<DesignerView>(ValidatedViews);
583             writer.Write("ActiveView");
584             writer.Write(views.IndexOf(this.activeView));
585
586             base.SaveViewState(writer);
587         }
588
589         protected override void LoadViewState(BinaryReader reader)
590         {
591             if (reader == null)
592                 throw new ArgumentNullException("reader");
593
594             string str = reader.ReadString();
595             if (str != null && str.Equals("ActiveView", StringComparison.Ordinal))
596             {
597                 int activeDesignerIndex = reader.ReadInt32();
598                 ReadOnlyCollection<DesignerView> views = ValidatedViews;
599                 if (activeDesignerIndex != -1 && activeDesignerIndex < views.Count)
600                     ActiveView = views[activeDesignerIndex];
601             }
602
603             base.LoadViewState(reader);
604         }
605
606         /// <summary>
607         /// Called when the current view of the designer changes
608         /// </summary>
609         /// <param name="view">View which is being set.</param>
610         protected virtual void OnViewChanged(DesignerView view)
611         {
612             PerformLayout();
613         }
614
615         protected override void OnShowSmartTagVerbs(Point smartTagPoint)
616         {
617             if (this.itemPalette == null)
618             {
619                 this.itemPalette = new ItemPalette();
620                 this.itemPalette.Closed += new EventHandler(OnPaletteClosed);
621                 this.itemPalette.SelectionChanged += new SelectionChangeEventHandler<SelectionChangeEventArgs>(OnSmartAction);
622             }
623
624             //we need to update the font every time the menu is shown
625             this.itemPalette.SetFont(WorkflowTheme.CurrentTheme.AmbientTheme.Font);
626
627             this.itemPalette.Items.Clear();
628
629             foreach (ActivityDesignerVerb smartVerb in SmartTagVerbs)
630             {
631                 Image image = smartVerb.Properties[DesignerUserDataKeys.Image] as Image;
632                 ItemInfo smartVerbItem = new ItemInfo(smartVerb.Id, image, smartVerb.Text);
633                 smartVerbItem.UserData[DesignerUserDataKeys.DesignerVerb] = smartVerb;
634                 this.itemPalette.Items.Add(smartVerbItem);
635             }
636
637             Point location = PointToScreen(smartTagPoint);
638             this.itemPalette.Show(location);
639         }
640
641         protected override void OnActivityChanged(ActivityChangedEventArgs e)
642         {
643             ReadOnlyCollection<DesignerView> newViews = SecondaryViewProvider.GetViews(this);
644             ReadOnlyCollection<DesignerView> oldViews = Views;
645             if (newViews.Count != oldViews.Count)
646             {
647                 this.views = null;
648
649                 //
650
651
652                 PerformLayout();
653             }
654
655             base.OnActivityChanged(e);
656         }
657         #endregion
658
659         #region Private Methods
660         internal override void OnPaintContainedDesigners(ActivityDesignerPaintEventArgs e)
661         {
662             //Draw all the activity designers contained by the activity designer
663             //We know that all the children which are in drawing range will be always
664             //consecutive both for parallel and for sequential containers hence
665             //once we go in the invisible range we bail out of drawing logic for rest of
666             //the children
667             bool bDrawingVisibleChildren = false;
668
669             foreach (ActivityDesigner activityDesigner in ContainedDesigners)
670             {
671                 Rectangle designerBounds = activityDesigner.Bounds;
672                 if (e.ViewPort.IntersectsWith(designerBounds))
673                 {
674                     bDrawingVisibleChildren = true;
675                     using (PaintEventArgs paintEventArgs = new PaintEventArgs(e.Graphics, e.ViewPort))
676                     {
677                         ((IWorkflowDesignerMessageSink)activityDesigner).OnPaint(paintEventArgs, e.ViewPort);
678                     }
679                 }
680                 else
681                 {
682                     if (bDrawingVisibleChildren)
683                         break;
684                 }
685             }
686         }
687
688         private Point SnapInToDropTarget(ActivityDragEventArgs e)
689         {
690             if (CurrentDropTarget >= 0)
691             {
692                 Rectangle[] dropTargets = GetDropTargets(new Point(e.X, e.Y));
693                 if (CurrentDropTarget < dropTargets.Length)
694                 {
695                     Rectangle dropConnector = dropTargets[CurrentDropTarget];
696                     return new Point(dropConnector.Left + dropConnector.Width / 2, dropConnector.Top + dropConnector.Height / 2);
697                 }
698             }
699
700             return Point.Empty;
701         }
702
703         private int CanDrop(ActivityDragEventArgs e)
704         {
705             if (e.Activities.Count == 0)
706                 return -1;
707
708             Point dropPoint = new Point(e.X, e.Y);
709             int dropIndex = -1;
710             Rectangle[] dropTargets = GetDropTargets(dropPoint);
711             for (int i = 0; i < dropTargets.Length; i++)
712             {
713                 if (dropTargets[i].Contains(dropPoint))
714                 {
715                     dropIndex = i;
716                     break;
717                 }
718             }
719
720             if (dropIndex >= 0 && !CanInsertActivities(new ConnectorHitTestInfo(this, HitTestLocations.Designer, dropIndex), e.Activities))
721                 dropIndex = -1;
722
723             bool ctrlKeyPressed = ((e.KeyState & 8) == 8);
724             if (dropIndex >= 0 && !ctrlKeyPressed && (e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)
725             {
726                 ConnectorHitTestInfo moveLocation = new ConnectorHitTestInfo(this, HitTestLocations.Designer, dropIndex);
727                 foreach (Activity activity in e.Activities)
728                 {
729                     if (activity.Site != null)
730                     {
731                         ActivityDesigner activityDesigner = ActivityDesigner.GetDesigner(activity);
732                         if (activityDesigner == null || activityDesigner.ParentDesigner == null || !activityDesigner.ParentDesigner.CanMoveActivities(moveLocation, new List<Activity>(new Activity[] { activity }).AsReadOnly()))
733                         {
734                             dropIndex = -1;
735                             break;
736                         }
737                     }
738                 }
739             }
740
741             return dropIndex;
742         }
743
744         private DragDropEffects CheckDragEffect(ActivityDragEventArgs e)
745         {
746             if (e.Activities.Count == 0)
747             {
748                 return DragDropEffects.None;
749             }
750             else if (CurrentDropTarget >= 0)
751             {
752                 bool ctrlKeyPressed = ((e.KeyState & 8) == 8);
753                 if (ctrlKeyPressed && (e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)
754                     return DragDropEffects.Copy;
755                 else if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)
756                     return DragDropEffects.Move;
757             }
758
759             return e.Effect;
760         }
761
762         private void OnSmartTagVerbStatus(object sender, EventArgs e)
763         {
764             ActivityDesignerVerb verb = sender as ActivityDesignerVerb;
765
766             DesignerView view = verb.Properties[DesignerUserDataKeys.DesignerView] as DesignerView;
767             if (view != null)
768                 verb.Checked = (view == ActiveView);
769         }
770
771         private void OnSmartTagVerb(object sender, EventArgs e)
772         {
773             ActivityDesignerVerb verb = sender as ActivityDesignerVerb;
774
775             DesignerView view = verb.Properties[DesignerUserDataKeys.DesignerView] as DesignerView;
776             if (view != null)
777             {
778                 ActiveView = view;
779
780                 if (Expanded && view.AssociatedDesigner != null)
781                 {
782                     ISelectionService selectionService = GetService(typeof(ISelectionService)) as ISelectionService;
783                     if (selectionService != null)
784                         selectionService.SetSelectedComponents(new object[] { view.AssociatedDesigner.Activity }, SelectionTypes.Replace);
785                 }
786             }
787         }
788
789         private void OnSmartAction(object sender, SelectionChangeEventArgs e)
790         {
791             ItemInfo itemInfo = e.CurrentItem as ItemInfo;
792             if (itemInfo != null)
793             {
794                 ActivityDesignerVerb smartVerb = itemInfo.UserData[DesignerUserDataKeys.DesignerVerb] as ActivityDesignerVerb;
795                 if (smartVerb != null)
796                     smartVerb.Invoke();
797             }
798         }
799
800         private void OnPaletteClosed(object sender, EventArgs e)
801         {
802             Invalidate(DesignerSmartTag.GetBounds(this, true));
803         }
804
805         private HitTestInfo GetUpdatedLocation(HitTestInfo location)
806         {
807             int lockedActivityOffset = 0;
808             foreach (DesignerView secondaryView in Views)
809             {
810                 if (secondaryView.AssociatedDesigner != null &&
811                     this != secondaryView.AssociatedDesigner &&
812                     Helpers.IsActivityLocked(secondaryView.AssociatedDesigner.Activity))
813                 {
814                     lockedActivityOffset++;
815                 }
816             }
817
818             return new ConnectorHitTestInfo(this, location.HitLocation, lockedActivityOffset + location.MapToIndex());
819         }
820         #endregion
821
822         #endregion
823     }
824     #endregion
825
826 }