Merge pull request #2928 from alexrp/master
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Presentation / System / Activities / Presentation / Base / Core / Internal / PropertyEditing / Views / AlphabeticalViewManager.cs
1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //----------------------------------------------------------------
4 namespace System.Activities.Presentation.Internal.PropertyEditing.Views 
5 {
6     using System;
7     using System.Collections.Generic;
8
9     using System.Activities.Presentation.Model;
10     using System.Activities.Presentation.PropertyEditing;
11
12     using System.Activities.Presentation.Internal.PropertyEditing.Model;
13     using System.Activities.Presentation.Internal.PropertyEditing.Selection;
14
15     // <summary>
16     // IPropertyViewManager we use to display an alphabetical list of properties
17     // </summary>
18     internal class AlphabeticalViewManager : IPropertyViewManager 
19     {
20
21         public static readonly AlphabeticalViewManager Instance = new AlphabeticalViewManager();
22         private AlphabeticalViewManager() 
23         {
24         }
25
26         // <summary>
27         // AlphabeticalViewManager doesn't show category headers
28         // </summary>
29         public bool ShowCategoryHeaders 
30         { get { return false; } }
31
32         // <summary>
33         // AlphabeticalViewManager always uses PropertyEntryNameComparer instance
34         // </summary>
35         private IComparer<PropertyEntry> PropertyComparer 
36         {
37             get {
38                 return PropertyEntryNameComparer.Instance;
39             }
40         }
41
42         // IPropertyViewManager Members
43
44         // <summary>
45         // Add a property into the correct category within the specified CategoryList.
46         // </summary>
47         // <param name="propertySet">Specified property (passed in as a set for multi-select scenarios)</param>
48         // <param name="propertyName">Name of the current property (perf optimization)</param>
49         // <param name="categoryList">CategoryList instance to populate</param>
50         // <returns>Wrapped ModelPropertyEntry for the specified propertySet</returns>
51         public ModelPropertyEntry AddProperty(IEnumerable<ModelProperty> propertySet, string propertyName, CategoryList categoryList) 
52         {
53             string categoryName = System.Activities.Presentation.Internal.Properties.Resources.PropertyCategoryAllProperties;
54             ModelCategoryEntry category = categoryList.FindCategory(categoryName) as ModelCategoryEntry;
55
56             bool reuseEntries = ExtensibilityAccessor.IsEditorReusable(propertySet);
57             if (reuseEntries && category != null) 
58             {
59                 ModelPropertyEntry foundProperty;
60                 if ((foundProperty = (ModelPropertyEntry)category[propertyName]) != null) {
61                     if (foundProperty.PropertyType != null && foundProperty.PropertyType.Equals(System.Activities.Presentation.Internal.PropertyEditing.Model.ModelUtilities.GetPropertyType(propertySet)))
62                     {
63                         // Found a match for the property, so reuse it
64
65                         bool oldIsBrowsable = foundProperty.IsBrowsable;
66
67                         foundProperty.SetUnderlyingModelProperty(propertySet);
68
69                         // If the IsBrowsable or IsAdvanced value of the property changed,
70                         // refresh the property within the category, because how and whether
71                         // this property should be rendered may have changed.
72                         // Note that refreshing a selected property also nullifies its stickiness
73                         // (ie. it resets CategoryList.PropertySelectionMode)
74                         if (oldIsBrowsable != foundProperty.IsBrowsable) 
75                         {
76                             category.Refresh(foundProperty, category.BasicProperties, this.PropertyComparer);
77                         }
78
79                         return foundProperty;
80                     }
81                 }
82             }
83
84             if (category == null) 
85             {
86                 category = new ModelCategoryEntry(categoryName);
87                 categoryList.InsertAlphabetically(category);
88             }
89
90             ModelPropertyEntry property = new ModelPropertyEntry(propertySet, null);
91             category.Add(property, category.BasicProperties, this.PropertyComparer);
92             return property;
93         }
94
95         // <summary>
96         // Scans the list of categories in the specified CategoryList and returns a set of
97         // CategoryEditor types that should be present in the list based on the properties
98         // in it.
99         // </summary>
100         // <param name="ownerType">Type of the currently displayed item</param>
101         // <param name="categoryList">CategoryList to examine</param>
102         // <returns>Set of expected CategoryEditor types</returns>
103         public Dictionary<Type, object> GetCategoryEditors(Type ownerType, CategoryList categoryList) 
104         {
105             // No category editors in alpha-view
106             return new Dictionary<Type, object>();
107         }
108
109         // <summary>
110         // Returns a SelectionPath pointing to the first visible property
111         // in the list or null if no such property exists.
112         // </summary>
113         // <param name="categoryList">CategoryList for reference</param>
114         // <returns>SelectionPath pointing to the first visible property
115         // in the list or null if no such property exists.</returns>
116         public SelectionPath GetDefaultSelectionPath(CategoryList categoryList) 
117         {
118             if (categoryList.Count > 0) 
119             {
120                 CategoryEntry firstCategory = categoryList[0];
121
122                 if (firstCategory != null) 
123                 {
124                     foreach (ModelPropertyEntry firstProperty in firstCategory.Properties) 
125                     {
126                         if (firstProperty != null && firstProperty.IsBrowsable && firstProperty.MatchesFilter)
127                         {
128                             return PropertySelectionPathInterpreter.Instance.ConstructSelectionPath(firstProperty);
129                         }
130                     }
131                 }
132             }
133
134             return null;
135         }
136
137         // Blend's CollectionEditor compatibility APIs
138
139         //
140         // Since Blend's API uses PropertyEntries instead of ModelProperties, we need
141         // to provide methods that consume those instead.  Ideally, with the two code
142         // bases merged, we wouldn't need these at all.
143         //
144
145         // <summary>
146         // Gets the category name of the specified property
147         // </summary>
148         // <param name="property">Property to examine</param>
149         // <returns>Category name the property belongs to.</returns>
150         public string GetCategoryName(PropertyEntry property) 
151         {
152             return System.Activities.Presentation.Internal.Properties.Resources.PropertyCategoryAllProperties;
153         }
154
155         // <summary>
156         // Adds the specified property into the specified category.
157         // </summary>
158         // <param name="property">Property to add</param>
159         // <param name="category">Category to populate</param>
160         public void AddProperty(PropertyEntry property, ModelCategoryEntry category) 
161         {
162             category.Add(property, category.BasicProperties, this.PropertyComparer);
163         }
164
165     }
166 }