Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Operators.Views.GraphVisualization/3.3/OperatorGraphVisualization/OperatorGraphVisualizationInfo.cs @ 4019

Last change on this file since 4019 was 3742, checked in by gkronber, 14 years ago

Fixed GPL license headers and deleted files which are not referenced by projects. #893

File size: 21.3 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.Core;
27using Netron.Diagramming.Core;
28using System.Drawing;
29using HeuristicLab.Collections;
30using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
31using HeuristicLab.Common;
32
33namespace HeuristicLab.Operators.Views.GraphVisualization {
34  [StorableClass]
35  public sealed class OperatorGraphVisualizationInfo : GraphVisualizationInfo {
36    [Storable]
37    private BidirectionalLookup<IOperator, IOperatorShapeInfo> operatorShapeInfoMapping;
38    private BidirectionalLookup<IOperator, IKeyedItemCollection<string, IParameter>> operatorParameterCollectionMapping;
39    private Dictionary<IParameter, IOperator> parameterOperatorMapping;
40
41    private OperatorGraphVisualizationInfo()
42      : base() {
43      this.operatorShapeInfoMapping = new BidirectionalLookup<IOperator, IOperatorShapeInfo>();
44      this.operatorParameterCollectionMapping = new BidirectionalLookup<IOperator, IKeyedItemCollection<string, IParameter>>();
45      this.parameterOperatorMapping = new Dictionary<IParameter, IOperator>();
46    }
47
48    [StorableConstructor]
49    private OperatorGraphVisualizationInfo(bool deserializing)
50      : base() {
51      this.operatorParameterCollectionMapping = new BidirectionalLookup<IOperator, IKeyedItemCollection<string, IParameter>>();
52      this.parameterOperatorMapping = new Dictionary<IParameter, IOperator>();
53    }
54
55    public OperatorGraphVisualizationInfo(OperatorGraph operatorGraph)
56      : this() {
57      this.operatorGraph = operatorGraph;
58      this.RegisterOperatorGraphEvents();
59
60      foreach (IOperator op in operatorGraph.Operators)
61        if (!this.operatorShapeInfoMapping.ContainsFirst(op))  //could be added by referencing parameters
62          this.AddOperator(op);
63
64      this.UpdateInitialShape();
65    }
66
67    [StorableHook(HookType.AfterDeserialization)]
68    private void DeserializationHook() {
69      this.operatorGraph.DeserializationFinished += new EventHandler(operatorGraph_DeserializationFinished);
70
71      IOperator op;
72      IOperatorShapeInfo shapeInfo;
73      foreach (KeyValuePair<IOperator, IOperatorShapeInfo> pair in this.operatorShapeInfoMapping.FirstEnumerable) {
74        op = pair.Key;
75        shapeInfo = pair.Value;
76        shapeInfo.Icon = new Bitmap(op.ItemImage);
77        this.RegisterOperatorEvents(op);
78        this.operatorParameterCollectionMapping.Add(op, op.Parameters);
79      }
80
81      foreach (IOperator oper in this.operatorShapeInfoMapping.FirstValues) {
82        foreach (IParameter param in oper.Parameters) {
83          IValueParameter opParam = param as IValueParameter;
84          this.parameterOperatorMapping.Add(param, oper);
85          if (opParam != null && typeof(IOperator).IsAssignableFrom(param.DataType))
86            this.RegisterOperatorParameterEvents(opParam);
87          else
88            this.RegisterParameterEvents(param);
89        }
90      }
91    }
92
93    private void operatorGraph_DeserializationFinished(object sender, EventArgs e) {
94      this.RegisterOperatorGraphEvents();
95      if (this.operatorGraph.InitialOperator != null) {
96        IOperatorShapeInfo newInitialShapeInfo = this.operatorShapeInfoMapping.GetByFirst(this.operatorGraph.InitialOperator);
97        if (newInitialShapeInfo != null) {
98          oldInitialShapeColor = newInitialShapeInfo.Color;
99          newInitialShapeInfo.Color = Color.LightGreen;
100        }
101        oldInitialShape = this.InitialShape;
102        this.OnInitialShapeChanged();
103      }
104      this.operatorGraph.DeserializationFinished -= new EventHandler(operatorGraph_DeserializationFinished);
105    }
106
107    public override IDeepCloneable Clone(Cloner cloner) {
108      OperatorGraphVisualizationInfo clone = (OperatorGraphVisualizationInfo)base.Clone(cloner);
109      clone.operatorGraph = (OperatorGraph)cloner.Clone(this.operatorGraph);
110      clone.RegisterOperatorGraphEvents();
111      clone.oldInitialShape = (IOperatorShapeInfo)cloner.Clone(this.oldInitialShape);
112      clone.oldInitialShapeColor = this.oldInitialShapeColor;
113
114      IOperator op;
115      IOperatorShapeInfo shapeInfo;
116      foreach (KeyValuePair<IOperator, IOperatorShapeInfo> pair in this.operatorShapeInfoMapping.FirstEnumerable) {
117        op = (IOperator)cloner.Clone(pair.Key);
118        shapeInfo = (IOperatorShapeInfo)cloner.Clone(pair.Value);
119        clone.RegisterOperatorEvents(op);
120        clone.operatorParameterCollectionMapping.Add(op, pair.Key.Parameters);
121        clone.operatorShapeInfoMapping.Add(op, shapeInfo);
122      }
123
124      foreach (IOperator oper in clone.operatorShapeInfoMapping.FirstValues) {
125        foreach (IParameter param in oper.Parameters) {
126          clone.parameterOperatorMapping.Add(param, oper);
127          IValueParameter opParam = param as IValueParameter;
128          if (opParam != null && typeof(IOperator).IsAssignableFrom(param.DataType))
129            clone.RegisterOperatorParameterEvents(opParam);
130          else
131            clone.RegisterParameterEvents(param);
132        }
133      }
134      if (this.operatorGraph.InitialOperator != null) {
135        IOperatorShapeInfo newInitialShapeInfo = this.operatorShapeInfoMapping.GetByFirst(this.operatorGraph.InitialOperator);
136        if (newInitialShapeInfo != null) {
137          oldInitialShapeColor = newInitialShapeInfo.Color;
138          newInitialShapeInfo.Color = Color.LightGreen;
139        }
140        oldInitialShape = this.InitialShape;
141        this.OnInitialShapeChanged();
142      }
143      return clone;
144    }
145
146    internal IOperator GetOperatorForShapeInfo(IOperatorShapeInfo shapeInfo) {
147      return this.operatorShapeInfoMapping.GetBySecond(shapeInfo);
148    }
149
150    private void operatorGraph_InitialOperatorChanged(object sender, EventArgs e) {
151      this.UpdateInitialShape();
152    }
153
154    private void UpdateInitialShape() {
155      IOperatorShapeInfo old = this.oldInitialShape as OperatorShapeInfo;
156      if (old != null)
157        old.Color = oldInitialShapeColor;
158
159      OperatorShapeInfo newInitialShapeInfo = this.InitialShape as OperatorShapeInfo;
160      if (newInitialShapeInfo != null) {
161        oldInitialShapeColor = newInitialShapeInfo.Color;
162        newInitialShapeInfo.Color = Color.LightGreen;
163      }
164
165      oldInitialShape = this.InitialShape;
166      this.OnInitialShapeChanged();
167    }
168
169    private IShapeInfo oldInitialShape;
170    private Color oldInitialShapeColor;
171    public override IShapeInfo InitialShape {
172      get {
173        IOperator op = this.operatorGraph.InitialOperator;
174        if (op == null)
175          return null;
176        return this.operatorShapeInfoMapping.GetByFirst(op);
177      }
178      set {
179        if (value == null)
180          this.OperatorGraph.InitialOperator = null;
181        else {
182          IOperatorShapeInfo shapeInfo = (IOperatorShapeInfo)value;
183          this.OperatorGraph.InitialOperator = this.operatorShapeInfoMapping.GetBySecond(shapeInfo);
184        }
185      }
186    }
187
188    [Storable]
189    private OperatorGraph operatorGraph;
190    public OperatorGraph OperatorGraph {
191      get { return this.operatorGraph; }
192    }
193
194    private void RegisterOperatorGraphEvents() {
195      this.operatorGraph.InitialOperatorChanged += new EventHandler(operatorGraph_InitialOperatorChanged);
196      this.operatorGraph.Operators.ItemsAdded += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsAdded);
197      this.operatorGraph.Operators.ItemsRemoved += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsRemoved);
198      this.operatorGraph.Operators.CollectionReset += new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_CollectionReset);
199    }
200
201    private void DeregisterOperatorGraphEvents() {
202      this.operatorGraph.InitialOperatorChanged -= new EventHandler(operatorGraph_InitialOperatorChanged);
203      this.operatorGraph.Operators.ItemsAdded -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsAdded);
204      this.operatorGraph.Operators.ItemsRemoved -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_ItemsRemoved);
205      this.operatorGraph.Operators.CollectionReset -= new HeuristicLab.Collections.CollectionItemsChangedEventHandler<IOperator>(Operators_CollectionReset);
206    }
207
208    #region methods to manipulate operatorgraph by the shape info
209    internal void AddShapeInfo(IOperator op, IOperatorShapeInfo shapeInfo) {
210      this.RegisterOperatorEvents(op);
211      this.operatorParameterCollectionMapping.Add(op, op.Parameters);
212      this.operatorShapeInfoMapping.Add(op, shapeInfo);
213      this.shapeInfos.Add(shapeInfo);
214
215      foreach (IParameter param in op.Parameters)
216        this.AddParameter(op, param);
217
218      this.operatorGraph.Operators.Add(op);
219    }
220
221    public override void RemoveShapeInfo(IShapeInfo shapeInfo) {
222      IOperatorShapeInfo opShapeInfo = (IOperatorShapeInfo)shapeInfo;
223      if (this.operatorShapeInfoMapping.ContainsSecond(opShapeInfo)) {
224        IOperator op = this.operatorShapeInfoMapping.GetBySecond(opShapeInfo);
225        this.operatorGraph.Operators.Remove(op);
226      }
227    }
228
229    public override void RemoveConnectionInfo(IConnectionInfo connectionInfo) {
230      IOperatorShapeInfo shapeInfo = (IOperatorShapeInfo)connectionInfo.From;
231      IOperator op = this.operatorShapeInfoMapping.GetBySecond(shapeInfo);
232      IValueParameter param = (IValueParameter)op.Parameters[connectionInfo.ConnectorFrom];
233      param.Value = null;
234    }
235
236    public override void AddConnectionInfo(IConnectionInfo connectionInfo) {
237      IOperatorShapeInfo shapeInfo = (IOperatorShapeInfo)connectionInfo.From;
238      IOperator op = this.operatorShapeInfoMapping.GetBySecond(shapeInfo);
239      IOperatorShapeInfo shapeInfoTo = (IOperatorShapeInfo)connectionInfo.To;
240      IOperator opTo = this.operatorShapeInfoMapping.GetBySecond(shapeInfoTo);
241      IValueParameter param = (IValueParameter)op.Parameters.Where(p => p.Name == connectionInfo.ConnectorFrom).SingleOrDefault();
242      if (param != null)
243        param.Value = opTo;
244    }
245    #endregion
246
247    #region operator events
248    private void AddOperator(IOperator op) {
249      if (!this.operatorShapeInfoMapping.ContainsFirst(op)) {
250        this.RegisterOperatorEvents(op);
251        IOperatorShapeInfo shapeInfo = OperatorShapeInfoFactory.CreateOperatorShapeInfo(op);
252        this.operatorParameterCollectionMapping.Add(op, op.Parameters);
253        this.operatorShapeInfoMapping.Add(op, shapeInfo);
254        this.shapeInfos.Add(shapeInfo);
255        foreach (IParameter param in op.Parameters)
256          this.AddParameter(op, param);
257      }
258    }
259    private void RemoveOperator(IOperator op) {
260      this.DeregisterOperatorEvents(op);
261      foreach (IParameter param in op.Parameters)
262        this.RemoveParameter(op, param);
263
264      IOperatorShapeInfo shapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
265      this.operatorParameterCollectionMapping.RemoveByFirst(op);
266      this.operatorShapeInfoMapping.RemoveByFirst(op);
267      this.shapeInfos.Remove(shapeInfo);
268    }
269
270    private void OperatorBreakpointChanged(object sender, EventArgs e) {
271      IOperator op = (IOperator)sender;
272      IOperatorShapeInfo operatorShapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
273      if (op.Breakpoint) {
274        operatorShapeInfo.LineColor = Color.Red;
275        operatorShapeInfo.LineWidth = 2;
276      } else {
277        operatorShapeInfo.LineColor = Color.Black;
278        operatorShapeInfo.LineWidth = 1;
279      }
280    }
281
282    private void OperatorItemImageChanged(object sender, EventArgs e) {
283      IOperator op = (IOperator)sender;
284      IOperatorShapeInfo operatorShapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
285      operatorShapeInfo.Icon = new Bitmap(op.ItemImage);
286    }
287
288    private void OperatorNameChanged(object sender, EventArgs e) {
289      IOperator op = (IOperator)sender;
290      IOperatorShapeInfo operatorShapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
291      operatorShapeInfo.Title = op.Name;
292    }
293
294    private void Operators_ItemsAdded(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IOperator> e) {
295      foreach (IOperator op in e.Items)
296        this.AddOperator(op);
297    }
298    private void Operators_ItemsRemoved(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IOperator> e) {
299      foreach (IOperator op in e.Items)
300        this.RemoveOperator(op);
301    }
302    private void Operators_CollectionReset(object sender, HeuristicLab.Collections.CollectionItemsChangedEventArgs<IOperator> e) {
303      foreach (IOperator op in e.OldItems)
304        this.RemoveOperator(op);
305      foreach (IOperator op in e.Items)
306        this.AddOperator(op);
307    }
308
309    private void RegisterOperatorEvents(IOperator op) {
310      op.Parameters.ItemsAdded += new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsAdded);
311      op.Parameters.ItemsRemoved += new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsRemoved);
312      op.Parameters.ItemsReplaced += new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsReplaced);
313      op.Parameters.CollectionReset += new CollectionItemsChangedEventHandler<IParameter>(Parameters_CollectionReset);
314      op.NameChanged += new EventHandler(OperatorNameChanged);
315      op.ItemImageChanged += new EventHandler(OperatorItemImageChanged);
316      op.BreakpointChanged += new EventHandler(OperatorBreakpointChanged);
317    }
318
319    private void DeregisterOperatorEvents(IOperator op) {
320      op.Parameters.ItemsAdded -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsAdded);
321      op.Parameters.ItemsRemoved -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsRemoved);
322      op.Parameters.ItemsReplaced -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_ItemsReplaced);
323      op.Parameters.CollectionReset -= new CollectionItemsChangedEventHandler<IParameter>(Parameters_CollectionReset);
324      op.NameChanged -= new EventHandler(OperatorNameChanged);
325      op.ItemImageChanged -= new EventHandler(OperatorItemImageChanged);
326      op.BreakpointChanged -= new EventHandler(OperatorBreakpointChanged);
327    }
328    #endregion
329
330    #region parameter events
331    private void AddParameter(IOperator op, IParameter param) {
332      this.parameterOperatorMapping.Add(param, op);
333      IValueParameter opParam = param as IValueParameter;
334      if (opParam != null && typeof(IOperator).IsAssignableFrom(param.DataType)) {
335        this.RegisterOperatorParameterEvents(opParam);
336        IOperatorShapeInfo shapeInfoFrom = this.operatorShapeInfoMapping.GetByFirst(op);
337        shapeInfoFrom.AddConnector(param.Name);
338
339        if (opParam.Value != null) {
340          if (!this.operatorShapeInfoMapping.ContainsFirst((IOperator)opParam.Value))
341            this.AddOperator((IOperator)opParam.Value);
342          IOperatorShapeInfo shapeInfoTo = this.operatorShapeInfoMapping.GetByFirst((IOperator)opParam.Value);
343          this.connectionInfos.Add(new ConnectionInfo(shapeInfoFrom, param.Name, shapeInfoTo, OperatorShapeInfoFactory.PredecessorConnector));
344        }
345      } else
346        this.RegisterParameterEvents(param);
347    }
348
349    private void RemoveParameter(IOperator op, IParameter param) {
350      IValueParameter opParam = param as IValueParameter;
351      if (opParam != null && typeof(IOperator).IsAssignableFrom(param.DataType)) {
352        this.DeregisterOperatorParameterEvents(opParam);
353        IOperatorShapeInfo shapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
354        this.connectionInfos.RemoveWhere(c => c.From == shapeInfo && c.ConnectorFrom == param.Name);
355        this.connectionInfos.RemoveWhere(c => c.To == shapeInfo && c.ConnectorTo == param.Name);
356        shapeInfo.RemoveConnector(param.Name);
357      } else
358        this.DeregisterParameterEvents(param);
359
360      this.parameterOperatorMapping.Remove(param);
361    }
362
363    private void opParam_ValueChanged(object sender, EventArgs e) {
364      IValueParameter opParam = (IValueParameter)sender;
365      if (this.parameterOperatorMapping.ContainsKey(opParam)) {
366        IOperator op = this.parameterOperatorMapping[opParam];
367        IOperatorShapeInfo shapeInfoFrom = this.operatorShapeInfoMapping.GetByFirst(op);
368        KeyValuePair<IOperatorShapeInfo, string> connectionFrom = new KeyValuePair<IOperatorShapeInfo, string>(shapeInfoFrom, opParam.Name);
369
370        this.connectionInfos.RemoveWhere(c => c.From == shapeInfoFrom && c.ConnectorFrom == opParam.Name);
371        if (opParam.Value != null) {
372          if (!this.operatorShapeInfoMapping.ContainsFirst((IOperator)opParam.Value))
373            this.AddOperator((IOperator)opParam.Value);
374          IOperatorShapeInfo shapeInfoTo = this.operatorShapeInfoMapping.GetByFirst((IOperator)opParam.Value);
375          base.AddConnectionInfo(new ConnectionInfo(shapeInfoFrom, opParam.Name, shapeInfoTo, OperatorShapeInfoFactory.PredecessorConnector));
376        }
377      }
378    }
379
380    private void Parameters_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
381      IKeyedItemCollection<string, IParameter> parameterCollection = sender as IKeyedItemCollection<string, IParameter>;
382      IOperator op = this.operatorParameterCollectionMapping.GetBySecond(parameterCollection);
383      foreach (IParameter param in e.Items)
384        AddParameter(op, param);
385      this.UpdateParameterLabels(op);
386    }
387    private void Parameters_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
388      IKeyedItemCollection<string, IParameter> parameterCollection = sender as IKeyedItemCollection<string, IParameter>;
389      IOperator op = this.operatorParameterCollectionMapping.GetBySecond(parameterCollection);
390      foreach (IParameter param in e.Items)
391        RemoveParameter(op, param);
392      this.UpdateParameterLabels(op);
393    }
394    private void Parameters_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
395      IKeyedItemCollection<string, IParameter> parameterCollection = sender as IKeyedItemCollection<string, IParameter>;
396      IOperator op = this.operatorParameterCollectionMapping.GetBySecond(parameterCollection);
397      foreach (IParameter param in e.OldItems)
398        RemoveParameter(op, param);
399      foreach (IParameter param in e.Items)
400        AddParameter(op, param);
401      this.UpdateParameterLabels(op);
402    }
403    private void Parameters_CollectionReset(object sender, CollectionItemsChangedEventArgs<IParameter> e) {
404      IKeyedItemCollection<string, IParameter> parameterCollection = sender as IKeyedItemCollection<string, IParameter>;
405      IOperator op = this.operatorParameterCollectionMapping.GetBySecond(parameterCollection);
406      foreach (IParameter param in e.OldItems)
407        RemoveParameter(op, param);
408      foreach (IParameter param in e.Items)
409        AddParameter(op, param);
410      this.UpdateParameterLabels(op);
411    }
412
413    private void RegisterOperatorParameterEvents(IValueParameter opParam) {
414      opParam.ValueChanged += new EventHandler(opParam_ValueChanged);
415    }
416    private void DeregisterOperatorParameterEvents(IValueParameter opParam) {
417      opParam.ValueChanged -= new EventHandler(opParam_ValueChanged);
418    }
419    private void RegisterParameterEvents(IParameter param) {
420      param.ToStringChanged += new EventHandler(param_ToStringChanged);
421      param.NameChanged += new EventHandler(param_NameChanged);
422    }
423    private void DeregisterParameterEvents(IParameter param) {
424      param.ToStringChanged -= new EventHandler(param_ToStringChanged);
425      param.NameChanged -= new EventHandler(param_NameChanged);
426    }
427
428    private void param_NameChanged(object sender, EventArgs e) {
429      IParameter param = (IParameter)sender;
430      IOperator op = this.parameterOperatorMapping[param];
431      this.UpdateParameterLabels(op);
432    }
433    private void param_ToStringChanged(object sender, EventArgs e) {
434      IParameter param = (IParameter)sender;
435      IOperator op = this.parameterOperatorMapping[param];
436      this.UpdateParameterLabels(op);
437    }
438
439    private void UpdateParameterLabels(IOperator op) {
440      IEnumerable<IParameter> parameters = op.Parameters.Where(p => !(p is IValueParameter && typeof(IOperator).IsAssignableFrom(p.DataType)));
441      IOperatorShapeInfo operatorShapeInfo = this.operatorShapeInfoMapping.GetByFirst(op);
442      if (parameters.Count() > 0)
443        operatorShapeInfo.UpdateLabels(parameters.Select(p => p.ToString()));
444      else
445        operatorShapeInfo.UpdateLabels(new List<string>());
446    }
447    #endregion
448  }
449}
Note: See TracBrowser for help on using the repository browser.