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

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

added print button

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