Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.MainForm/3.2/MainFormManager.cs @ 3350

Last change on this file since 3350 was 3350, checked in by mkommend, 14 years ago

implemented first version of View.ReadOnly and adapted some views to the new mechanism (ticket #973)

File size: 9.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Text;
26using HeuristicLab.PluginInfrastructure;
27using System.Diagnostics;
28
29namespace HeuristicLab.MainForm {
30  public static class MainFormManager {
31    private static object locker;
32    private static IMainForm mainform;
33    private static HashSet<Type> views;
34    private static Dictionary<Type, Type> defaultViews;
35
36    static MainFormManager() {
37      locker = new object();
38      mainform = null;
39      views = new HashSet<Type>();
40      defaultViews = new Dictionary<Type, Type>();
41    }
42
43    public static void RegisterMainForm(IMainForm mainForm) {
44      lock (locker) {
45        if (MainFormManager.mainform != null)
46          throw new ArgumentException("A mainform was already associated with the mainform manager.");
47        if (mainForm == null)
48          throw new ArgumentException("Could not associate null as a mainform in the mainform manager.");
49
50        MainFormManager.mainform = mainForm;
51        IEnumerable<Type> types =
52          from t in ApplicationManager.Manager.GetTypes(typeof(IView))
53          where !t.IsAbstract && !t.IsInterface && ContentAttribute.HasContentAttribute(t)
54          select t;
55
56        foreach (Type viewType in types) {
57          views.Add(viewType);
58          foreach (Type contentType in ContentAttribute.GetDefaultViewableTypes(viewType)) {
59            if (defaultViews.ContainsKey(contentType))
60              throw new ArgumentException("DefaultView for type " + contentType + " is " + defaultViews[contentType] +
61                ". Can't register additional DefaultView " + viewType + ".");
62            defaultViews[contentType] = viewType;
63          }
64        }
65      }
66    }
67
68    public static IMainForm MainForm {
69      get { return mainform; }
70    }
71
72    public static T GetMainForm<T>() where T : IMainForm {
73      return (T)mainform;
74    }
75
76    public static IEnumerable<Type> GetViewTypes(Type contentType) {
77      List<Type> viewTypes = (from v in views
78                              where ContentAttribute.CanViewType(v, contentType)
79                              select v).ToList();
80      //transform generic type definitions to generic types
81      for (int i = 0; i < viewTypes.Count; i++) {
82        viewTypes[i] = TransformGenericTypeDefinition(viewTypes[i], contentType);
83      }
84      return viewTypes.Where(t => t != null);
85    }
86
87    public static IEnumerable<Type> GetViewTypes(Type contentType, bool returnOnlyMostSpecificViewTypes) {
88      List<Type> viewTypes = new List<Type>(GetViewTypes(contentType));
89      if (returnOnlyMostSpecificViewTypes) {
90        Type defaultViewType = null;
91        try {
92          defaultViewType = GetDefaultViewType(contentType);
93        }
94        catch (InvalidOperationException) { }
95
96        foreach (Type viewType in viewTypes.ToList()) {
97          if ((viewType != defaultViewType) && viewTypes.Any(t => t.IsSubclassOf(viewType)))
98            viewTypes.Remove(viewType);
99        }
100      }
101      return viewTypes;
102    }
103
104    public static bool ViewCanViewObject(IView view, object content) {
105      return ContentAttribute.CanViewType(view.GetType(), content.GetType());
106    }
107
108    public static Type GetDefaultViewType(Type contentType) {
109      //check base classes for default view
110      Type type = contentType;
111      while (type != null) {
112        //check classes
113        foreach (Type defaultContentType in defaultViews.Keys) {
114          if (type == defaultContentType || type.CheckGenericTypes(defaultContentType))
115            return TransformGenericTypeDefinition(defaultViews[defaultContentType], contentType);
116        }
117
118        //check interfaces
119        IEnumerable<Type> nonInheritedInterfaces = type.GetInterfaces().Where(i => !i.IsAssignableFrom(type.BaseType));
120        List<Type> defaultViewList = new List<Type>();
121        foreach (Type defaultContentType in defaultViews.Keys) {
122          if (nonInheritedInterfaces.Contains(defaultContentType) || nonInheritedInterfaces.Any(i => i.CheckGenericTypes(defaultContentType)))
123            defaultViewList.Add(defaultViews[defaultContentType]);
124        }
125
126        //return only most spefic view as default view
127        foreach (Type viewType in defaultViewList.ToList()) {
128          if (defaultViewList.Any(t => t.IsSubclassOf(viewType)))
129            defaultViewList.Remove(viewType);
130        }
131
132        if (defaultViewList.Count == 1)
133          return TransformGenericTypeDefinition(defaultViewList[0], contentType);
134        else if (defaultViewList.Count > 1)
135          throw new InvalidOperationException("Could not determine which is the default view for type " + contentType.ToString() + ". Because more than one implemented interfaces have a default view.");
136
137        type = type.BaseType;
138      }
139
140      return null;
141    }
142
143    public static IView CreateDefaultView(object content) {
144      Type t = GetDefaultViewType(content.GetType());
145      if (t == null)
146        return null;
147
148      return (IView)Activator.CreateInstance(t, content);
149    }
150    public static IView CreateDefaultView(object content, bool readOnly) {
151      IView view = CreateDefaultView(content);
152      if (view != null)
153        view.ReadOnly = readOnly;
154      return null;
155    }
156
157    public static IView CreateView(Type viewType) {
158      if (!typeof(IView).IsAssignableFrom(viewType))
159        throw new ArgumentException("View can not be created becaues given type " + viewType.ToString() + " is not of type IView.");
160      if (viewType.IsGenericTypeDefinition)
161        throw new ArgumentException("View can not be created becaues given type " + viewType.ToString() + " is a generic type definition.");
162
163      return (IView)Activator.CreateInstance(viewType);
164    }
165    public static IView CreateView(Type viewType, bool readOnly) {
166      IView view = CreateView(viewType);
167      view.ReadOnly = readOnly;
168      return view;
169    }
170
171    public static IView CreateView(Type viewType, object content) {
172      if (!typeof(IView).IsAssignableFrom(viewType))
173        throw new ArgumentException("View can not be created becaues given type " + viewType.ToString() + " is not of type IView.");
174      Type view = viewType;
175      if (view.IsGenericTypeDefinition)
176        view = TransformGenericTypeDefinition(view, content.GetType());
177
178      return (IView)Activator.CreateInstance(view, content);
179    }
180    public static IView CreateView(Type viewType, object content, bool readOnly) {
181      IView view = CreateView(viewType, content);
182      view.ReadOnly = readOnly;
183      return view;
184    }
185
186    private static Type TransformGenericTypeDefinition(Type viewType, Type contentType) {
187      if (contentType.IsGenericTypeDefinition)
188        throw new ArgumentException("The content type " + contentType.ToString() + " must not be a generic type definition.");
189
190      if (!viewType.IsGenericTypeDefinition)
191        return viewType;
192
193      Type contentTypeBaseType = null;
194      foreach (Type type in ContentAttribute.GetViewableTypes(viewType)) {
195        contentTypeBaseType = contentType;
196        while (contentTypeBaseType != null && (!contentTypeBaseType.IsGenericType ||
197              type.GetGenericTypeDefinition() != contentTypeBaseType.GetGenericTypeDefinition()))
198          contentTypeBaseType = contentTypeBaseType.BaseType;
199
200        //check interfaces for generic type arguments
201        if (contentTypeBaseType == null) {
202          IEnumerable<Type> implementedInterfaces = contentType.GetInterfaces().Where(t => t.IsGenericType);
203          foreach (Type implementedInterface in implementedInterfaces) {
204            if (implementedInterface.CheckGenericTypes(type))
205              contentTypeBaseType = implementedInterface;
206          }
207        }
208        if (contentTypeBaseType != null) break;
209      }
210
211      if (!contentTypeBaseType.IsGenericType)
212        throw new ArgumentException("Neither content type itself nor any of its base classes is a generic type. Could not determine generic type argument for the view.");
213
214      Type[] viewTypeGenericArguments = viewType.GetGenericArguments();
215      Type[] contentTypeGenericArguments = contentTypeBaseType.GetGenericArguments();
216
217      if (contentTypeGenericArguments.Length != viewTypeGenericArguments.Length)
218        throw new ArgumentException("Neiter the type (" + contentType.ToString() + ") nor any of its base types specifies " +
219          viewTypeGenericArguments.Length + " generic type arguments.");
220
221      for (int i = 0; i < viewTypeGenericArguments.Length; i++) {
222        foreach (Type typeConstraint in viewTypeGenericArguments[i].GetGenericParameterConstraints()) {
223          if (!typeConstraint.IsAssignableFrom(contentTypeGenericArguments[i]))
224            return null;
225        }
226      }
227
228      Type returnType = viewType.MakeGenericType(contentTypeGenericArguments);
229      return returnType;
230    }
231  }
232}
Note: See TracBrowser for help on using the repository browser.