source: trunk/CrypPlugins/WorkspaceManager/Model/Elements/PluginModel.cs @ 2616

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