source: trunk/CrypPlugins/WorkspaceManager/Model/PluginModel.cs @ 1879

Last change on this file since 1879 was 1879, checked in by kopal, 11 years ago

ConnectorModel, ConnectionModel, ImageModel and TextModel now also have a Parent Model Element

File size: 19.6 KB
Line 
1/*                             
2   Copyright 2010 Nils Kopal, Viktor M.
3
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15*/
16
17
18using System;
19using System.Collections.Generic;
20using System.Linq;
21using System.Text;
22using Cryptool.PluginBase;
23using System.Threading;
24using System.Windows.Controls;
25using Gears4Net;
26using WorkspaceManager.Execution;
27using System.Windows.Threading;
28using Cryptool.PluginBase.IO;
29using System.Reflection;
30using System.ComponentModel;
31
32namespace WorkspaceManager.Model
33{
34    /// <summary>
35    /// Log updated event
36    /// </summary>
37    public class LogUpdated : EventArgs
38    {}
39
40    /// <summary>
41    /// Class to represent and wrap a IPlugin in our model graph
42    /// </summary>
43    [Serializable]
44    public class PluginModel : VisualElementModel
45    {
46        #region private members
47
48        [NonSerialized]
49        private PluginProtocol pluginProtocol;
50        [NonSerialized]
51        private IPlugin plugin;         
52        private int imageIndex = 0;
53        [NonSerialized]
54        private PluginModelState state = PluginModelState.Normal;
55        private string PluginTypeName = null;
56        private string PluginTypeAssemblyName = null;
57       
58        #endregion
59
60        #region public members
61
62        [field: NonSerialized]
63        public event EventHandler<LogUpdated> LogUpdated;
64
65        /// <summary>
66        /// State of the Plugin
67        /// </summary>
68       
69        public PluginModelState State {
70            get { return state; } 
71            set { state = value; }
72        }
73
74        /// <summary>
75        /// All ingoing connectors of this PluginModel
76        /// </summary>
77        public List<ConnectorModel> InputConnectors = null;
78
79        /// <summary>
80        /// All outgoing connectors of this PluginModel
81        /// </summary>
82        public List<ConnectorModel> OutputConnectors = null;
83
84        /// <summary>
85        /// The wrapped IPlugin of this PluginModel
86        /// if there is currently no plugin instance it
87        /// will automatically create one. Otherwise
88        /// this acts as singleton and returns the created
89        /// instance
90        /// </summary>       
91        public IPlugin Plugin{
92            get { 
93                if(plugin==null && PluginType != null){
94                    plugin = PluginType.CreateObject();                   
95                }
96                return plugin;
97            }
98
99            private set
100            {
101                plugin = value;
102            }
103        }
104
105        /// <summary>
106        /// The Type of the Wrapped IPlugin of this PluginModel
107        /// Depending on this the Plugin of this PluginModel will be instanciated
108        /// </summary>       
109        public Type PluginType{
110            get{
111                if (this.PluginTypeName != null){
112                    Assembly assembly = Assembly.Load(PluginTypeAssemblyName);
113                    Type t = assembly.GetType(PluginTypeName);
114                    return t;
115                }
116                else
117                {
118                    return null;
119                }
120            } 
121            set{
122                this.PluginTypeName = value.FullName;
123                this.PluginTypeAssemblyName = value.Assembly.FullName;
124            }
125        }
126
127        /// <summary>
128        /// Should this plugin may be startet again when it
129        /// is startable?
130        /// </summary>
131        public bool RepeatStart;
132
133        /// <summary>
134        /// Is the wrapped plugin startable
135        /// </summary>
136        public bool Startable;
137       
138        /// <summary>
139        /// Is the Plugin actually minimized?
140        /// </summary>
141        public bool Minimized { get; set; }
142
143        /// <summary>
144        /// The execution state of the progress of the wrapped plugin
145        /// </summary>
146        public double PercentageFinished { get; set; }
147
148        /// <summary>
149        /// Create a new PluginModel
150        /// </summary>
151        public PluginModel()
152        {
153            this.InputConnectors = new List<ConnectorModel>();
154            this.OutputConnectors = new List<ConnectorModel>();
155        }
156     
157        /// <summary>
158        /// The WorkspaceModel of this PluginModel
159        /// </summary>
160        public WorkspaceModel WorkspaceModel { get; set; }
161
162        /// <summary>
163        /// Generates all Connectors of this Plugin.
164        /// </summary>
165        public void generateConnectors()
166        {
167
168            if (Plugin != null)
169            {   
170                foreach (PropertyInfoAttribute propertyInfoAttribute in Plugin.GetProperties())
171                {
172                    if (propertyInfoAttribute.Direction.Equals(Direction.InputData))
173                    {
174                        ConnectorModel connectorModel = new ConnectorModel();
175                        connectorModel.ConnectorType = propertyInfoAttribute.PropertyInfo.PropertyType;
176                        connectorModel.WorkspaceModel = WorkspaceModel;
177                        connectorModel.PluginModel = this;
178                        connectorModel.IsMandatory = propertyInfoAttribute.Mandatory;
179                        connectorModel.PropertyName = propertyInfoAttribute.PropertyName;
180                        connectorModel.Name = propertyInfoAttribute.PropertyName;
181                        connectorModel.ToolTip = propertyInfoAttribute.ToolTip;
182                        connectorModel.IControl = false;
183                        connectorModel.PluginModel.Plugin.PropertyChanged += connectorModel.PropertyChangedOnPlugin;
184                        connectorModel.Parent = this;
185                        InputConnectors.Add(connectorModel);
186                        WorkspaceModel.AllConnectorModels.Add(connectorModel);
187                    }
188                    else if (propertyInfoAttribute.Direction.Equals(Direction.ControlSlave))
189                    {
190                        ConnectorModel connectorModel = new ConnectorModel();
191                        connectorModel.ConnectorType = propertyInfoAttribute.PropertyInfo.PropertyType;
192                        connectorModel.WorkspaceModel = WorkspaceModel;
193                        connectorModel.PluginModel = this;
194                        connectorModel.IsMandatory = propertyInfoAttribute.Mandatory;
195                        connectorModel.PropertyName = propertyInfoAttribute.PropertyName;
196                        connectorModel.Name = propertyInfoAttribute.PropertyName;
197                        connectorModel.ToolTip = propertyInfoAttribute.ToolTip;
198                        connectorModel.IControl = true;
199                        connectorModel.PluginModel.Plugin.PropertyChanged += connectorModel.PropertyChangedOnPlugin;
200                        connectorModel.Parent = this;
201                        InputConnectors.Add(connectorModel);
202                        WorkspaceModel.AllConnectorModels.Add(connectorModel);
203                    }
204                    else if (propertyInfoAttribute.Direction.Equals(Direction.OutputData))
205                    {
206                        ConnectorModel connectorModel = new ConnectorModel();
207                        connectorModel.ConnectorType = propertyInfoAttribute.PropertyInfo.PropertyType;
208                        connectorModel.WorkspaceModel = WorkspaceModel;
209                        connectorModel.PluginModel = this;
210                        connectorModel.IsMandatory = propertyInfoAttribute.Mandatory;
211                        connectorModel.PropertyName = propertyInfoAttribute.PropertyName;
212                        connectorModel.Name = propertyInfoAttribute.PropertyName;
213                        connectorModel.ToolTip = propertyInfoAttribute.ToolTip;
214                        connectorModel.Outgoing = true;
215                        connectorModel.IControl = false;
216                        connectorModel.PluginModel.Plugin.PropertyChanged += connectorModel.PropertyChangedOnPlugin;
217                        connectorModel.Parent = this;
218                        OutputConnectors.Add(connectorModel);
219                        WorkspaceModel.AllConnectorModels.Add(connectorModel);
220                    }
221                    else if (propertyInfoAttribute.Direction.Equals(Direction.ControlMaster))
222                    {
223                        ConnectorModel connectorModel = new ConnectorModel();
224                        connectorModel.ConnectorType = propertyInfoAttribute.PropertyInfo.PropertyType;
225                        connectorModel.WorkspaceModel = WorkspaceModel;
226                        connectorModel.PluginModel = this;
227                        connectorModel.IsMandatory = propertyInfoAttribute.Mandatory;
228                        connectorModel.PropertyName = propertyInfoAttribute.PropertyName;
229                        connectorModel.Name = propertyInfoAttribute.PropertyName;
230                        connectorModel.ToolTip = propertyInfoAttribute.ToolTip;
231                        connectorModel.Outgoing = true;
232                        connectorModel.IControl = true;
233                        connectorModel.PluginModel.Plugin.PropertyChanged += connectorModel.PropertyChangedOnPlugin;
234                        connectorModel.Parent = this;
235                        OutputConnectors.Add(connectorModel);
236                        WorkspaceModel.AllConnectorModels.Add(connectorModel);
237                    }
238                }
239
240                Dictionary<string, DynamicProperty> dictionary = Plugin.GetDynamicPropertyList();
241                if (dictionary != null)
242                {
243                    DynamicPropertyInfoAttribute dynamicPropertyInfoAttribute = Plugin.GetDynamicPropertyInfo();
244                    foreach (DynamicProperty dynamicProperty in dictionary.Values)
245                    {
246
247                        if (dynamicProperty.PInfo.Direction.Equals(Direction.InputData))
248                        {
249                            ConnectorModel connectorModel = new ConnectorModel();
250                            connectorModel.ConnectorType = dynamicProperty.Type;
251                            connectorModel.WorkspaceModel = WorkspaceModel;
252                            connectorModel.PluginModel = this;
253                            connectorModel.IsMandatory = dynamicProperty.PInfo.Mandatory;
254                            connectorModel.PropertyName = dynamicProperty.Name;
255                            connectorModel.Name = dynamicProperty.Name;
256                            connectorModel.ToolTip = dynamicProperty.PInfo.ToolTip;
257                            EventInfo eventinfo = Plugin.GetType().GetEvent(dynamicPropertyInfoAttribute.UpdateDynamicPropertiesEvent);
258                            connectorModel.IsDynamic = true;
259                            connectorModel.DynamicGetterName = dynamicPropertyInfoAttribute.MethodGetValue;
260                            connectorModel.DynamicSetterName = dynamicPropertyInfoAttribute.MethodSetValue;
261                            connectorModel.PluginModel.Plugin.PropertyChanged += connectorModel.PropertyChangedOnPlugin;
262                            connectorModel.Parent = this;
263                            eventinfo.AddEventHandler(Plugin, new DynamicPropertiesChanged(connectorModel.PropertyTypeChangedOnPlugin));                           
264                            InputConnectors.Add(connectorModel);
265                            WorkspaceModel.AllConnectorModels.Add(connectorModel);
266                        }
267                        else if (dynamicProperty.PInfo.Direction.Equals(Direction.OutputData))
268                        {
269                            ConnectorModel connectorModel = new ConnectorModel();
270                            connectorModel.ConnectorType = dynamicProperty.Type;
271                            connectorModel.WorkspaceModel = WorkspaceModel;
272                            connectorModel.PluginModel = this;
273                            connectorModel.IsMandatory = dynamicProperty.PInfo.Mandatory;
274                            connectorModel.PropertyName = dynamicProperty.Name;
275                            connectorModel.Name = dynamicProperty.Name;
276                            connectorModel.ToolTip = dynamicProperty.PInfo.ToolTip;
277                             EventInfo eventinfo = Plugin.GetType().GetEvent(dynamicPropertyInfoAttribute.UpdateDynamicPropertiesEvent);
278                            eventinfo.AddEventHandler(Plugin, new DynamicPropertiesChanged(connectorModel.PropertyTypeChangedOnPlugin));
279                            connectorModel.IsDynamic = true;
280                            connectorModel.DynamicGetterName = dynamicPropertyInfoAttribute.MethodGetValue;
281                            connectorModel.DynamicSetterName = dynamicPropertyInfoAttribute.MethodSetValue;
282                            connectorModel.PluginModel.Plugin.PropertyChanged += connectorModel.PropertyChangedOnPlugin;
283                            connectorModel.Parent = this;
284                            connectorModel.Outgoing = true;
285                            OutputConnectors.Add(connectorModel);
286                            WorkspaceModel.AllConnectorModels.Add(connectorModel);
287
288                        }
289                    }
290                }
291            }
292        }
293        /// <summary>
294        /// Get the Image of the Plugin
295        /// </summary>
296        /// <returns></returns>
297        public Image getImage()
298        {
299            return Plugin.GetImage(imageIndex);
300        }
301
302        /// <summary>
303        /// Returns the Presentation of the wrapped IPlugin
304        /// </summary>
305        public UserControl PluginPresentation
306        {
307            get
308            {
309                if(this.Plugin.Presentation != null){
310                    return this.Plugin.Presentation;
311                }else{
312                    return this.Plugin.QuickWatchPresentation;
313                }
314            }
315        }
316             
317        /// <summary>
318        /// Should be called by the UI-Thread to paint changes of the PluginModel
319        /// </summary>
320        public void paint()
321        {
322            //Enter some Code which calls the paint method of the IPlugin
323        }       
324
325        /// <summary>
326        /// Progress of the plugin changed
327        /// </summary>
328        /// <param name="sender"></param>
329        /// <param name="args"></param>
330        public void PluginProgressChanged(IPlugin sender, PluginProgressEventArgs args)
331        {
332            //Calculate % of the plugins process
333            this.PercentageFinished = args.Value / args.Max;
334            //Tell the ExecutionEngine that this plugin needs a gui update
335            this.GuiNeedsUpdate = true;
336        }
337
338        /// <summary>
339        /// Status of the plugin changed
340        /// </summary>
341        /// <param name="sender"></param>
342        /// <param name="args"></param>
343        public void PluginStatusChanged(IPlugin sender, StatusEventArgs args)
344        {
345            if (args.StatusChangedMode == StatusChangedMode.ImageUpdate)
346            {
347                this.imageIndex = args.ImageIndex;
348            }
349               
350            if (this.WorkspaceModel.WorkspaceManagerEditor.isExecuting())
351            {
352                this.GuiNeedsUpdate = true;
353            }
354            else
355            {
356                this.WorkspaceModel.WorkspaceManagerEditor.Presentation.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
357                {
358                    this.UpdateableView.update();
359                }, null);
360            }           
361        }
362
363        /// <summary>
364        /// The pluginProtocol of the current ExecutionEngine run to set/get
365        /// </summary>
366        public PluginProtocol PluginProtocol {
367            get { return pluginProtocol; }
368            set { pluginProtocol = value;}
369        }
370
371        /// <summary>
372        /// All occured log events of this plugin
373        /// </summary>
374        [NonSerialized]
375        public List<GuiLogEventArgs> GuiLogEvents = new List<GuiLogEventArgs>();
376
377        /// <summary>
378        /// GuiLogNotificationOccured
379        /// saves the plugins log events and tells the gui that it needs
380        /// an update. If the Workspace is not executing an event is invoked
381        /// </summary>
382        /// <param name="sender"></param>
383        /// <param name="args"></param>
384        public void GuiLogNotificationOccured(IPlugin sender, GuiLogEventArgs args)
385        {
386            switch (((WorkspaceManagerSettings)this.WorkspaceModel.WorkspaceManagerEditor.Settings).LogLevel)
387            {
388                case 3://Error
389                    if (args.NotificationLevel == NotificationLevel.Debug ||
390                        args.NotificationLevel == NotificationLevel.Info ||
391                        args.NotificationLevel == NotificationLevel.Warning)
392                    {
393                        return;
394                    }
395                    break;
396
397                case 2://Warning
398                    if (args.NotificationLevel == NotificationLevel.Debug ||
399                        args.NotificationLevel == NotificationLevel.Info)
400                    {
401                        return;
402                    }
403                    break;
404
405                case 1://Info
406                    if (args.NotificationLevel == NotificationLevel.Debug)
407                    {
408                        return;
409                    }
410                    break;
411            }
412            if (sender == this.plugin)
413            {
414                this.GuiLogEvents.Add(args);
415                this.GuiNeedsUpdate = true;
416            }
417
418            if (this.LogUpdated != null)
419            {
420                if(!this.WorkspaceModel.WorkspaceManagerEditor.isExecuting())
421                    this.LogUpdated.Invoke(this, new LogUpdated {});
422            }
423        }
424
425        /// <summary>
426        /// Called if a Setting of a Plugin is changed and notifies the Editor that
427        /// there is a change
428        /// </summary>
429        /// <param name="sender"></param>
430        /// <param name="propertyChangedEventArgs"></param>
431        public void SettingsPropertyChanged(Object sender, PropertyChangedEventArgs propertyChangedEventArgs)
432        {
433            this.WorkspaceModel.WorkspaceManagerEditor.HasChanges = true;
434        }
435
436        /// <summary>
437        /// Get the children of this PluginModel by iterating through all PluginModels of
438        /// the WorkSpace this PluginModel belongs to. All Plugins having this one as Parent
439        /// are returned in this list
440        /// </summary>
441        /// <returns></returns>
442        public List<PluginModel> getChildren()
443        {
444            List<PluginModel> children = new List<PluginModel>();
445         
446            foreach (PluginModel pluginModel in this.WorkspaceModel.AllPluginModels)
447            {
448                if (pluginModel.Parent == this)
449                {
450                    children.Add(pluginModel);
451                }
452            }           
453            return children;
454        }
455
456        #endregion
457    }
458
459    /// <summary>
460    /// The internal state of a Plugin Model
461    /// </summary>
462    public enum PluginModelState{
463        Normal,
464        Warning,
465        Error
466    }
467}
Note: See TracBrowser for help on using the repository browser.