[runtime] Fix corlib out of date error with disabled COM
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Presentation / System / Activities / Presentation / Model / ModelTypeConverter.cs
1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //-----------------------------------------------------------------------------
4
5 namespace System.Activities.Presentation.Model
6 {
7
8     using System;
9     using System.Collections;
10     using System.Collections.Generic;
11     using System.ComponentModel;
12     using System.Globalization;
13     using System.Diagnostics.CodeAnalysis;
14
15     // This is a type converter that wraps another type converter.  In the
16     // editing model, we expose all properties as ModelItem objects, so we need
17     // to unwrap them before handing them to a type converter.  This type
18     // converter provides that unwrapping seamlessly.
19
20     [SuppressMessage("XAML", "XAML1004", Justification = "This is internal, and is always available through TypeConverter.GetConverter, not used in xaml")]
21     class ModelTypeConverter : TypeConverter
22     {
23
24         ModelTreeManager modelTreeManager;
25         TypeConverter converter;
26
27         internal ModelTypeConverter(ModelTreeManager modelTreeManager, TypeConverter converter)
28         {
29             this.modelTreeManager = modelTreeManager;
30             this.converter = converter;
31         }
32
33         // Wraps the given type descriptor context with the set of this.modelTreeManagers
34         // available in the editing context.
35         ITypeDescriptorContext WrapContext(ITypeDescriptorContext context)
36         {
37             return new ModelTypeDescriptorContextWrapper(context, this.modelTreeManager);
38         }
39
40         // Returns true if the converter can convert from the given source type.
41         public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
42         {
43             if (sourceType == null)
44             {
45                 throw FxTrace.Exception.AsError(new ArgumentNullException("sourceType"));
46             }
47             return this.converter.CanConvertFrom(WrapContext(context), sourceType);
48         }
49
50         // Returns true if the converter can convert to the given target type.
51         public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
52         {
53             if (destinationType == null)
54             {
55                 throw FxTrace.Exception.AsError(new ArgumentNullException("destinationType"));
56             }
57             return this.converter.CanConvertTo(WrapContext(context), destinationType);
58         }
59
60         // Performs the actual conversion from one type to antother.  If the value provided
61         // is a ModelItem, it will be unwrapped first.  The return value is a ModelItem.
62         public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
63         {
64             ModelItem item = value as ModelItem;
65             if (item != null)
66             {
67                 value = item.GetCurrentValue();
68             }
69             object convertedValue = this.converter.ConvertFrom(WrapContext(context), culture, value);
70
71             if (convertedValue != null)
72             {
73                 convertedValue = this.modelTreeManager.CreateModelItem(null, convertedValue);
74             }
75
76             return convertedValue;
77         }
78
79         // Performs the actual conversion to another type.  If the value provided is an item, it will
80         // be uwrapped first.  The return value is the raw data type.
81         public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
82         {
83             ModelItem item = value as ModelItem;
84             if (item != null)
85             {
86                 value = item.GetCurrentValue();
87             }
88             if (value != null)
89             {
90                 return this.converter.ConvertTo(WrapContext(context), culture, value, destinationType);
91             }
92             return null;
93         }
94
95         // Creates an instance of an object using a dictionary of property values.  The
96         // return value is a wrapped model item.
97         public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
98         {
99             object value = this.converter.CreateInstance(WrapContext(context), propertyValues);
100             if (value != null)
101             {
102                 value = this.modelTreeManager.CreateModelItem(null, value);
103             }
104             return value;
105         }
106
107         // Returns true if the CreateInstance method can be used to create new instances of
108         // objects.
109         public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
110         {
111             return this.converter.GetCreateInstanceSupported(WrapContext(context));
112         }
113
114         // Returns child properties for a type converter.  This will wrap all properties returned.
115         public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
116         {
117
118             if (value == null)
119             {
120                 throw FxTrace.Exception.AsError( new ArgumentNullException("value"));
121             }
122
123             ModelItem item = value as ModelItem;
124             if (item != null)
125             {
126                 value = item.GetCurrentValue();
127             }
128
129             PropertyDescriptorCollection props = this.converter.GetProperties(WrapContext(context), value, attributes);
130             if (props != null && props.Count > 0)
131             {
132
133                 if (item == null)
134                 {
135                     // We will need the item for this object.
136                     item = this.modelTreeManager.CreateModelItem(null, value);
137                 }
138
139                 // Search our item for each property and wrap it.  If
140                 // a property is not offered by the model, ommit it.
141
142                 List<PropertyDescriptor> newProps = new List<PropertyDescriptor>(props.Count);
143                 foreach (PropertyDescriptor p in props)
144                 {
145                     ModelProperty modelProp = item.Properties.Find(p.Name);
146                     if (modelProp != null)
147                     {
148                         newProps.Add(new ModelPropertyDescriptor(modelProp));
149                     }
150                 }
151
152                 props = new PropertyDescriptorCollection(newProps.ToArray(), true);
153             }
154
155             return props;
156         }
157
158         // Returns true if GetProperties will return child properties for the
159         // object.
160         public override bool GetPropertiesSupported(ITypeDescriptorContext context)
161         {
162             return this.converter.GetPropertiesSupported(WrapContext(context));
163         }
164
165         // Returns a set of standard values this type converter offers.
166         public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
167         {
168             StandardValuesCollection values = this.converter.GetStandardValues(WrapContext(context));
169
170             // Some type converters return null here, which isn't supposed to 
171             // be allowed. Fix them
172
173             object[] wrappedValues;
174
175             if (values == null)
176             {
177                 wrappedValues = new object[0];
178             }
179             else
180             {
181                 wrappedValues = new object[values.Count];
182                 int idx = 0;
183                 foreach (object value in values)
184                 {
185                     object wrappedValue;
186                     if (value != null)
187                     {
188                         wrappedValue = this.modelTreeManager.CreateModelItem(null, value);
189                     }
190                     else
191                     {
192                         wrappedValue = value;
193                     }
194
195                     wrappedValues[idx++] = wrappedValue;
196                 }
197             }
198
199             return new StandardValuesCollection(wrappedValues);
200         }
201
202         // Returns true if the set of standard values cannot be customized.
203         public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
204         {
205             return this.converter.GetStandardValuesExclusive(WrapContext(context));
206         }
207
208         // Returns true if this type converter offers a set of standard values.
209         public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
210         {
211             return this.converter.GetStandardValuesSupported(WrapContext(context));
212         }
213
214         // Returns true if the given value is a valid value for this type converter.
215         public override bool IsValid(ITypeDescriptorContext context, object value)
216         {
217             ModelItem item = value as ModelItem;
218             if (item != null)
219             {
220                 value = item.GetCurrentValue();
221             }
222             return this.converter.IsValid(WrapContext(context), value);
223         }
224     }
225 }