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

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