source: trunk/CrypPlugins/WorkspaceManager/WorkspaceManager.cs @ 2116

Last change on this file since 2116 was 2116, checked in by Sven Rech, 11 years ago

Added some settings to CrypWin.
Now its possible to disable/hide some functionality.

File size: 21.9 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.Core;
23using Cryptool.PluginBase.Editor;
24using Cryptool.UiPluginBase;
25using Cryptool.PluginBase.IO;
26using Cryptool.PluginBase;
27
28using WorkspaceManager.Model;
29using WorkspaceManager.View;
30using WorkspaceManager.Execution;
31using WorkspaceManager.View.Container;
32using WorkspaceManager.View.Converter;
33using System.Windows;
34using System.Windows.Threading;
35using System.Threading;
36using System.Windows.Controls;
37using System.Windows.Media;
38using Cryptool.PluginBase.Miscellaneous;
39
40//Disable warnings for unused or unassigned fields and events:
41#pragma warning disable 0169, 0414, 0067
42
43namespace WorkspaceManager
44{
45    /// <summary>
46    /// Workspace Manager - PluginEditor based on MVC Pattern
47    /// </summary>
48    [EditorInfo("cwm")]
49    [Author("Viktor Matkovic,Nils Kopal", "nils.kopal@cryptool.org", "Universität Duisburg-Essen", "http://www.uni-due.de")]
50    [PluginInfo("WorkspaceManager.Resources.Attributes", false, "Workspace Manager", "Graphical plugin editor for the CrypTool workspace", null,
51      "AnotherEditor/icon.png",
52      "AnotherEditor/Images/addWorkspace.png",
53      "AnotherEditor/Images/deleteWorkspace.png",
54      "AnotherEditor/Images/importSubWorkspace.png")]
55    public class WorkspaceManager : IEditor
56    {
57
58        /// <summary>
59        /// Create a new Instance of the Editor
60        /// </summary>
61        public WorkspaceManager()
62        {
63            Settings = new WorkspaceManagerSettings();
64            WorkspaceModel = new WorkspaceModel();
65            WorkspaceModel.WorkspaceManagerEditor = this;
66            WorkspaceSpaceEditorView = new WorkSpaceEditorView(WorkspaceModel);
67            HasChanges = false;                               
68        }
69
70        #region private Members
71
72        private WorkspaceModel WorkspaceModel = null;
73        private WorkSpaceEditorView WorkspaceSpaceEditorView = null;
74        private ExecutionEngine ExecutionEngine = null;
75        private volatile bool executing = false;
76        private volatile bool stopping = false;
77
78        #endregion
79
80        /// <summary>
81        /// Is this Editor executing?
82        /// </summary>
83        public bool isExecuting(){
84            return executing;
85        }
86
87        #region IEditor Members
88
89        /// <summary>
90        ///
91        /// </summary>
92        public event ChangeDisplayLevelHandler OnChangeDisplayLevel;
93
94        /// <summary>
95        ///
96        /// </summary>
97        public event SelectedPluginChangedHandler OnSelectedPluginChanged;
98
99        /// <summary>
100        ///
101        /// </summary>
102        public event ProjectTitleChangedHandler OnProjectTitleChanged;
103
104        /// <summary>
105        ///
106        /// </summary>
107        public event OpenProjectFileHandler OnOpenProjectFile;
108
109        /// <summary>
110        ///
111        /// </summary>
112        public event EditorSpecificPluginsChanged OnEditorSpecificPluginsChanged;
113
114        /// <summary>
115        /// Called by clicking on the new button of CrypTool
116        /// Creates a new Model
117        /// </summary>
118        public void New()
119        {
120            foreach (PluginModel pluginModel in new List<PluginModel>(WorkspaceModel.AllPluginModels))
121            {
122                WorkspaceModel.deletePluginModel(pluginModel);
123            }
124            this.HasChanges = false;
125            this.OnProjectTitleChanged.BeginInvoke(this, "unnamed project", null, null);
126        }
127
128        /// <summary>
129        /// Called by clicking on the open button of CrypTool
130        /// loads a serialized model
131        /// </summary>
132        /// <param name="fileName"></param>
133        public void Open(string fileName)
134        {
135            try
136            {
137                New();
138                GuiLogMessage("Loading Model: " + fileName, NotificationLevel.Info);               
139                WorkspaceModel = ModelPersistance.loadModel(fileName,this);               
140                WorkspaceSpaceEditorView.Load(WorkspaceModel);
141                HasChanges = false;
142                this.OnProjectTitleChanged.BeginInvoke(this, System.IO.Path.GetFileName(fileName), null, null);
143            }
144            catch (Exception ex)
145            {
146                GuiLogMessage("Could not load Model:" + ex.ToString(), NotificationLevel.Error);
147            }
148        }
149
150        /// <summary>
151        /// Called by clicking on the save button of CrypTool
152        /// serializes the current model
153        /// </summary>
154        /// <param name="fileName"></param>
155        public void Save(string fileName)
156        {
157            try
158            {
159                GuiLogMessage("Saving Model: " + fileName, NotificationLevel.Info);
160                ModelPersistance.saveModel(this.WorkspaceModel, fileName);
161                HasChanges = false;
162                this.OnProjectTitleChanged.BeginInvoke(this, System.IO.Path.GetFileName(fileName), null, null);
163            }
164            catch (Exception ex)
165            {
166                GuiLogMessage("Could not save Model:" + ex.ToString(), NotificationLevel.Error);               
167            }
168           
169        }
170
171        /// <summary>
172        /// Called by double clicking on a plugin symbol of CrypTool
173        /// Adds a new PluginModel wrapping an instance of the selected plugin
174        /// </summary>
175        /// <param name="type"></param>
176        public void Add(Type type)
177        {
178            /*if (!executing)
179            {
180                PluginModel newPluginModel = WorkspaceModel.newPluginModel(new Point(10, 10), 100, 100, type);
181                GuiLogMessage("Added by double click: " + newPluginModel.Name, NotificationLevel.Info);
182                HasChanges = true;
183            }*/
184        }
185
186        /// <summary>
187        ///
188        /// </summary>
189        /// <param name="espi"></param>
190        public void AddEditorSpecific(EditorSpecificPluginInfo espi)
191        {
192            //to be implemented
193        }
194
195        /// <summary>
196        ///
197        /// </summary>
198        /// <param name="espi"></param>
199        public void DeleteEditorSpecific(EditorSpecificPluginInfo espi)
200        {
201            //to be implemented   
202        }
203
204        /// <summary>
205        /// Undo changes
206        /// </summary>
207        public void Undo()
208        {
209            //to be implemented
210        }
211
212        /// <summary>
213        /// Redo changes
214        /// </summary>
215        public void Redo()
216        {
217            //to be implemented
218        }
219
220        /// <summary>
221        /// Show the Help site
222        /// </summary>
223        public void ShowHelp()
224        {
225            //to be implemented
226        }
227
228        /// <summary>
229        /// Show the Description of the selected plugin
230        /// </summary>
231        public void ShowSelectedPluginDescription()
232        {
233            //to be implemented
234        }
235
236        /// <summary>
237        /// Is Undo possible
238        /// </summary>
239        public bool CanUndo
240        {
241            get;
242            set;
243        }
244
245        /// <summary>
246        /// Is Redo possible?
247        /// </summary>
248        public bool CanRedo
249        {
250            get;
251            set;
252        }
253
254        /// <summary>
255        /// Can the ExecutionEngine be started?
256        /// </summary>
257        public bool CanExecute
258        {
259            get{return !executing;}
260        }
261
262        /// <summary>
263        /// Can the ExecutionEngine be stopped?
264        /// </summary>
265        public bool CanStop
266        {
267            get { return executing; }
268        }
269
270        /// <summary>
271        /// Does this Editor has changes?
272        /// </summary>
273        public bool HasChanges
274        {
275            get;
276            set;
277        }
278
279        /// <summary>
280        /// DisplayLevel
281        /// </summary>
282        public DisplayLevel DisplayLevel
283        {
284            get;
285            set;
286           
287        }
288
289        /// <summary>
290        ///
291        /// </summary>
292        public List<EditorSpecificPluginInfo> EditorSpecificPlugins
293        {
294            get;
295            set;
296        }
297
298        public bool ReadOnly { get; set; }
299
300        #endregion
301
302        #region IPlugin Members
303
304        /// <summary>
305        ///
306        /// </summary>
307        public event StatusChangedEventHandler OnPluginStatusChanged;
308
309        /// <summary>
310        ///
311        /// </summary>
312        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
313
314        /// <summary>
315        ///
316        /// </summary>
317        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
318
319        /// <summary>
320        /// Settings of this editor
321        /// </summary>
322        public ISettings Settings
323        {
324            get;
325            set;
326        }
327
328        /// <summary>
329        /// The Presentation of this editor
330        /// </summary>
331        public System.Windows.Controls.UserControl Presentation
332        {
333            get {return WorkspaceSpaceEditorView;}
334            set { WorkspaceSpaceEditorView = (WorkSpaceEditorView)value; }
335        }
336
337        /// <summary>
338        /// The QuickWatchPresentation of this editor
339        /// </summary>
340        public System.Windows.Controls.UserControl QuickWatchPresentation
341        {
342            get;
343            set;
344        }
345
346        /// <summary>
347        /// Called before execution
348        /// </summary>
349        public void PreExecution()
350        {
351            //to be implemented
352        }
353
354        /// <summary>
355        /// Starts the ExecutionEngine to execute the model
356        /// </summary>
357        public void Execute()
358        {
359            if (executing)
360            {
361                return;
362            }
363            EventsHelper.AsynchronousPropertyChanged = false;
364            try
365            {
366                GuiLogMessage("Execute Model now!", NotificationLevel.Info);
367                executing = true;
368
369                if (((WorkspaceManagerSettings)this.Settings).SynchronousEvents)
370                {
371                    EventsHelper.AsynchronousProgressChanged = false;
372                    EventsHelper.AsynchronousGuiLogMessage = false;
373                    EventsHelper.AsynchronousStatusChanged = false;
374                }
375
376                //Get the gui Thread
377                this.WorkspaceSpaceEditorView.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
378                {
379                    this.WorkspaceSpaceEditorView.ResetConnections();
380                    this.WorkspaceSpaceEditorView.State = EditorState.BUSY;                   
381                }
382                , null);
383
384                this.ExecutionEngine = new ExecutionEngine(this);
385
386                try
387                {
388                    ExecutionEngine.GuiUpdateInterval = int.Parse(((WorkspaceManagerSettings)this.Settings).GuiUpdateInterval);
389                    if (ExecutionEngine.GuiUpdateInterval <= 0)
390                    {
391                        GuiLogMessage("GuiUpdateInterval can not be <=0; Use GuiUpdateInterval = 1", NotificationLevel.Warning);
392                        ExecutionEngine.GuiUpdateInterval = 1;
393                    }
394                }
395                catch (Exception ex)
396                {
397                    GuiLogMessage("Could not set GuiUpdateInterval: " + ex.Message, NotificationLevel.Warning);
398                    ExecutionEngine.GuiUpdateInterval = 100;
399                }
400
401                try
402                {
403                    ExecutionEngine.SleepTime = int.Parse(((WorkspaceManagerSettings)this.Settings).SleepTime);
404                    if (ExecutionEngine.SleepTime < 0)
405                    {
406                        GuiLogMessage("SleepTime can not be <=0; Use GuiUpdateInterval = 0", NotificationLevel.Warning);
407                        ExecutionEngine.SleepTime = 0;
408                    }
409                }
410                catch (Exception ex)
411                {
412                    GuiLogMessage("Could not set SleepTime: " + ex.Message, NotificationLevel.Warning);
413                    ExecutionEngine.GuiUpdateInterval = 0;
414                }
415
416                int schedulers=0;
417                try
418                {
419                   schedulers = int.Parse(((WorkspaceManagerSettings)this.Settings).Threads);
420                    if (ExecutionEngine.SleepTime < 0)
421                    {
422                        GuiLogMessage("Schedulers can not be <=0; Use Schedulers = 1", NotificationLevel.Warning);
423                        schedulers = 1;
424                    }
425                }
426                catch (Exception ex)
427                {
428                    GuiLogMessage("Could not set Schedulers: " + ex.Message, NotificationLevel.Warning);
429                    schedulers = 1;
430                }
431
432                ExecutionEngine.BenchmarkPlugins = ((WorkspaceManagerSettings)this.Settings).BenchmarkPlugins;
433                ExecutionEngine.ThreadPriority = ((WorkspaceManagerSettings)this.Settings).ThreadPriority;
434
435                ExecutionEngine.Execute(WorkspaceModel, schedulers);               
436            }
437            catch (Exception ex)
438            {
439                GuiLogMessage("Exception during the execution: " + ex.Message, NotificationLevel.Error);
440                executing = false;
441                if (((WorkspaceManagerSettings)this.Settings).SynchronousEvents)
442                {
443                    EventsHelper.AsynchronousProgressChanged = true;
444                    EventsHelper.AsynchronousGuiLogMessage = true;
445                    EventsHelper.AsynchronousStatusChanged = true;
446                }
447            }
448        }
449
450        /// <summary>
451        /// Called after the execution
452        /// </summary>
453        public void PostExecution()
454        {
455            //to be implemented
456        }
457
458        /// <summary>
459        /// Pause the execution
460        /// </summary>
461        public void Pause()
462        {   
463            //to be implemented
464        }
465
466        /// <summary>
467        /// Stop the ExecutionEngine
468        /// </summary>
469        public void Stop()
470        {
471            if (!executing || stopping)
472            {
473                return;
474            }
475
476            stopping = true;
477
478            Thread stopThread = new Thread(new ThreadStart(waitingStop));
479            stopThread.Start(); 
480
481            EventsHelper.AsynchronousPropertyChanged = true;
482
483            if (((WorkspaceManagerSettings)this.Settings).SynchronousEvents)
484            {
485                EventsHelper.AsynchronousProgressChanged = true;
486                EventsHelper.AsynchronousGuiLogMessage = true;
487                EventsHelper.AsynchronousStatusChanged = true;
488            }
489
490                       
491        }
492
493        /// <summary>
494        /// Stops the execution engine and blocks until this work is done
495        /// </summary>
496        private void waitingStop()
497        {
498            try
499            {
500                GuiLogMessage("Executing stopped by User!", NotificationLevel.Info);
501                ExecutionEngine.Stop();
502                //Get the gui Thread
503                this.WorkspaceSpaceEditorView.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
504                {
505                    this.WorkspaceSpaceEditorView.ResetConnections();
506                    this.WorkspaceSpaceEditorView.State = EditorState.READY;
507                }
508                , null);
509            }
510            catch (Exception ex)
511            {
512                GuiLogMessage("Exception during the stopping of the execution: " + ex.Message, NotificationLevel.Error);
513            }
514            executing = false;
515            this.ExecutionEngine = null;
516            GC.Collect();
517            stopping = false;
518        }
519
520        /// <summary>
521        /// Called to initialize the editor
522        /// </summary>
523        public void Initialize()
524        {
525            //to be implemented
526        }
527
528        /// <summary>
529        /// Called when the editor is disposed
530        /// </summary>
531        public void Dispose()
532        {
533            if (ExecutionEngine != null && ExecutionEngine.IsRunning)
534            {
535                ExecutionEngine.Stop();
536            }
537            EventsHelper.AsynchronousPropertyChanged = true;
538        }
539
540        #endregion
541
542        #region INotifyPropertyChanged Members
543
544        /// <summary>
545        ///
546        /// </summary>
547        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
548
549        #endregion
550
551        #region IApplication Members
552
553        /// <summary>
554        ///
555        /// </summary>
556        private PluginManager pluginManager;
557        public PluginManager PluginManager
558        {
559            get { return pluginManager; }
560            set
561            {
562                pluginManager = value;
563                DragDropDataObjectToPluginConverter.PluginManager = value;
564            }         
565        }
566
567        #endregion
568
569        #region GuiLogMessage, Progress
570
571        /// <summary>
572        /// Loggs a message to the logging mechanism of CrypTool
573        /// </summary>
574        /// <param name="Message"></param>
575        /// <param name="notificationLevel"></param>
576        public void GuiLogMessage(string Message, NotificationLevel notificationLevel)
577        {
578            if (OnGuiLogNotificationOccured != null)
579            {
580                GuiLogEventArgs args = new GuiLogEventArgs(Message, this, notificationLevel);
581                args.Title = "-";
582                OnGuiLogNotificationOccured(this, args);
583            }
584        }
585
586        /// <summary>
587        /// GuiLogNotificationOccured
588        /// </summary>
589        /// <param name="sender"></param>
590        /// <param name="args"></param>
591        public void GuiLogNotificationOccured(IPlugin sender, GuiLogEventArgs args)
592        {
593            //Check if the logging event is Warning or Error and set the State of the PluginModel to
594            //the corresponding PluginModelState
595            if (args.NotificationLevel == NotificationLevel.Warning)
596            {               
597                foreach (PluginModel pluginModel in this.WorkspaceModel.AllPluginModels)
598                {
599                    if (pluginModel.Plugin == sender)
600                    {
601                        pluginModel.State = PluginModelState.Warning;
602                        pluginModel.GuiNeedsUpdate = true;
603                    }
604                }
605            }
606
607            if (args.NotificationLevel == NotificationLevel.Error)
608            {               
609                foreach (PluginModel pluginModel in this.WorkspaceModel.AllPluginModels)
610                {
611                    if (pluginModel.Plugin == sender)
612                    {
613                        pluginModel.State = PluginModelState.Error;
614                        pluginModel.GuiNeedsUpdate = true;
615                    }
616                }
617            }
618
619            if (OnGuiLogNotificationOccured != null)
620            {
621                switch (((WorkspaceManagerSettings)this.Settings).LogLevel)
622                {
623                    case 3://Error
624                        if (args.NotificationLevel == NotificationLevel.Debug ||
625                            args.NotificationLevel == NotificationLevel.Info ||
626                            args.NotificationLevel == NotificationLevel.Warning)
627                        {
628                            return;
629                        }
630                        break;
631
632                    case 2://Warning
633                        if (args.NotificationLevel == NotificationLevel.Debug ||
634                            args.NotificationLevel == NotificationLevel.Info)
635                        {
636                            return;
637                        }
638                        break;
639
640                    case 1://Info
641                        if (args.NotificationLevel == NotificationLevel.Debug)
642                        {
643                            return;
644                        }
645                        break;
646                }
647                OnGuiLogNotificationOccured(sender, args);
648            }
649               
650        }
651
652        /// <summary>
653        /// Progress of this editor
654        /// </summary>
655        /// <param name="Value"></param>
656        /// <param name="MaxValue"></param>
657        private void Progress(int Value, int MaxValue)
658        {
659            if (OnPluginProgressChanged != null)
660            {
661                OnPluginProgressChanged(this, new PluginProgressEventArgs(Value, MaxValue));
662            }
663        }
664        #endregion GuiLogMessage, Progress
665
666        /// <summary>
667        /// Selected Plugin changed by View
668        /// </summary>
669        /// <param name="args"></param>
670        public void onSelectedPluginChanged(PluginChangedEventArgs args)
671        {
672            this.OnSelectedPluginChanged(this, args);
673        }
674
675        #region IEditor Members
676
677
678        public void Active()
679        {           
680        }
681
682        #endregion
683
684        #region IEditor Members
685
686
687        public event OpenTabHandler OnOpenTab;
688
689        #endregion
690    }
691}
692
693//Restore warnings for unused or unassigned fields and events:
694#pragma warning restore 0169, 0414, 0067
Note: See TracBrowser for help on using the repository browser.