0ba114d14c7338543e4afdf31aa7d64a4cfde6a9
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Presentation / System / Activities / Presentation / Model / MorphHelper.cs
1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //----------------------------------------------------------------
4
5 namespace System.Activities.Presentation.Model
6 {
7     using System;
8     using System.Activities.Presentation.Internal.PropertyEditing;
9     using System.Collections.Generic;
10     using System.ComponentModel;
11     using System.Linq;
12     using System.Activities.Presentation;
13     using System.Diagnostics.CodeAnalysis;
14     using System.Runtime;
15
16     public delegate object PropertyValueMorphHelper(ModelItem originalValue, ModelProperty newModelProperty);
17
18     public static class MorphHelper
19     {
20         [SuppressMessage(FxCop.Category.Naming, FxCop.Rule.IdentifiersShouldBeSpelledCorrectly,
21                            Justification = "Morph is the right word here")]
22
23         static Dictionary<Type, PropertyValueMorphHelper> morphExtensions = new Dictionary<Type, PropertyValueMorphHelper>();
24
25         [SuppressMessage(FxCop.Category.Naming, FxCop.Rule.IdentifiersShouldBeSpelledCorrectly,
26                             Justification = "Morph is the right word here")]
27         public static void AddPropertyValueMorphHelper(Type propertyType, PropertyValueMorphHelper extension)
28         {
29             if (propertyType == null)
30             {
31                 throw FxTrace.Exception.AsError(new ArgumentNullException("propertyType"));
32             }
33             if (extension == null)
34             {
35                 throw FxTrace.Exception.AsError(new ArgumentNullException("extension"));
36             }
37             morphExtensions[propertyType] = extension;
38         }
39
40         [SuppressMessage(FxCop.Category.Naming, FxCop.Rule.IdentifiersShouldBeSpelledCorrectly,
41                             Justification = "Morph is the right word here")]
42         public static PropertyValueMorphHelper GetPropertyValueMorphHelper(Type propertyType)
43         {
44             if (propertyType == null)
45             {
46                 throw FxTrace.Exception.AsError(new ArgumentNullException("propertyType"));
47             }
48             PropertyValueMorphHelper extension = null;
49             morphExtensions.TryGetValue(propertyType, out extension);
50             if (extension == null && propertyType.IsGenericType)
51             {
52                 morphExtensions.TryGetValue(propertyType.GetGenericTypeDefinition(), out extension);
53             }
54             return extension;
55         }
56
57         [SuppressMessage(FxCop.Category.Naming, FxCop.Rule.IdentifiersShouldBeSpelledCorrectly,
58                             Justification = "Morph is the right word here")]
59         // This updates back links
60         public static void MorphObject(ModelItem oldModelItem, ModelItem newModelitem)
61         {
62             if (oldModelItem == null)
63             {
64                 throw FxTrace.Exception.AsError(new ArgumentNullException("oldModelItem"));
65             }
66             if (newModelitem == null)
67             {
68                 throw FxTrace.Exception.AsError(new ArgumentNullException("newModelitem"));
69             }
70
71             var collectionParents = from parent in oldModelItem.Parents
72                                     where parent is ModelItemCollection
73                                     select (ModelItemCollection)parent;
74             foreach (ModelItemCollection collectionParent in collectionParents.ToList())
75             {
76                 int index = collectionParent.IndexOf(oldModelItem);
77                 collectionParent.Remove(oldModelItem);
78                 collectionParent.Insert(index, newModelitem);
79             }
80             foreach (ModelProperty modelProperty in oldModelItem.Sources.ToList())
81             {
82                 modelProperty.SetValue(newModelitem);
83             }
84
85
86         }
87
88         [SuppressMessage(FxCop.Category.Naming, FxCop.Rule.IdentifiersShouldBeSpelledCorrectly,
89                             Justification = "Morph is the right word here")]
90         // this updates forward links
91         public static void MorphProperties(ModelItem oldModelItem, ModelItem newModelitem)
92         {
93             if (oldModelItem == null)
94             {
95                 throw FxTrace.Exception.AsError(new ArgumentNullException("oldModelItem"));
96             }
97             if (newModelitem == null)
98             {
99                 throw FxTrace.Exception.AsError(new ArgumentNullException("newModelitem"));
100             }
101
102             foreach (ModelProperty modelProperty in oldModelItem.Properties)
103             {
104                 ModelProperty propertyInNewModelItem = newModelitem.Properties[modelProperty.Name];
105                 if (propertyInNewModelItem != null)
106                 {
107                     Console.WriteLine(propertyInNewModelItem.Name);
108                     if (CanCopyProperty(modelProperty, propertyInNewModelItem))
109                     {
110                         if (propertyInNewModelItem.PropertyType.Equals(modelProperty.PropertyType))
111                         {
112                             propertyInNewModelItem.SetValue(modelProperty.Value);
113                             modelProperty.SetValue(null);
114                         }
115                         else // See if there is morph helper for this type.
116                         {
117                             PropertyValueMorphHelper extension = GetPropertyValueMorphHelper(modelProperty.PropertyType);
118                             if (extension != null)
119                             {
120                                 propertyInNewModelItem.SetValue(extension(modelProperty.Value, propertyInNewModelItem));
121                                 modelProperty.SetValue(null);
122                             }
123                         }
124
125                     }
126                 }
127
128             }
129         }
130
131         static bool CanCopyProperty(ModelProperty modelProperty, ModelProperty propertyInNewModelItem)
132         {
133             bool canCopyProperty = false;
134             DesignerSerializationVisibilityAttribute designerSerializationVisibility = ExtensibilityAccessor.GetAttribute<DesignerSerializationVisibilityAttribute>(modelProperty.Attributes);
135             if (modelProperty.Value == null)
136             {
137                 canCopyProperty = false;
138             }
139             else if (designerSerializationVisibility != null && designerSerializationVisibility.Visibility != DesignerSerializationVisibility.Visible)
140             {
141                 canCopyProperty = false;
142             }
143             else if (propertyInNewModelItem != null && !propertyInNewModelItem.IsAttached && !propertyInNewModelItem.IsReadOnly)
144             {
145                 canCopyProperty = true;
146             }
147             return canCopyProperty;
148         }
149
150     }
151 }
152