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

Last change on this file since 2444 was 2444, checked in by kopal, 11 years ago
File size: 27.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;
39using WorkspaceManager.View.VisualComponents;
40using System.Windows.Media.Imaging;
41using System.Printing;
42using System.Windows.Documents;
43using System.Windows.Markup;
44
45//Disable warnings for unused or unassigned fields and events:
46#pragma warning disable 0169, 0414, 0067
47
48namespace WorkspaceManager
49{
50    /// <summary>
51    /// Workspace Manager - PluginEditor based on MVC Pattern
52    /// </summary>
53    [EditorInfo("cwm")]
54    [Author("Viktor Matkovic,Nils Kopal", "nils.kopal@cryptool.org", "Universität Duisburg-Essen", "http://www.uni-due.de")]
55    [PluginInfo("WorkspaceManager.Resources.Attributes", false, "Workspace Manager", "Graphical plugin editor for the CrypTool workspace", null,
56      "AnotherEditor/icon.png",
57      "AnotherEditor/Images/addWorkspace.png",
58      "AnotherEditor/Images/deleteWorkspace.png",
59      "AnotherEditor/Images/importSubWorkspace.png")]
60    public class WorkspaceManager : IEditor
61    {
62
63        /// <summary>
64        /// Create a new Instance of the Editor
65        /// </summary>
66        public WorkspaceManager()
67        {
68            Settings = new WorkspaceManagerSettings(this);
69            WorkspaceModel = new WorkspaceModel();
70            WorkspaceModel.WorkspaceManagerEditor = this;
71            WorkspaceSpaceEditorView = new WorkSpaceEditorView(WorkspaceModel);
72            HasChanges = false;                               
73        }
74
75        #region private Members
76
77        private WorkspaceModel WorkspaceModel = null;
78        private WorkSpaceEditorView WorkspaceSpaceEditorView = null;
79        private ExecutionEngine ExecutionEngine = null;
80        private volatile bool executing = false;
81        private volatile bool stopping = false;
82
83        #endregion
84
85        /// <summary>
86        /// Is this Editor executing?
87        /// </summary>
88        public bool isExecuting(){
89            return executing;
90        }
91
92        #region IEditor Members
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            if (this.OnProjectTitleChanged != null)
132            {
133                this.OnProjectTitleChanged.BeginInvoke(this, "unnamed project", null, null);
134            }
135        }
136
137        /// <summary>
138        /// Open the given model in the editor
139        /// </summary>
140        /// <param name="fileName"></param>
141        public void Open(WorkspaceModel model)
142        {
143            try
144            {
145                New();
146                WorkspaceSpaceEditorView.Load(model);
147                WorkspaceModel = model;
148            }
149            catch (Exception ex)
150            {
151                GuiLogMessage("Could not open Model:" + ex.ToString(), NotificationLevel.Error);
152            }
153        }
154       
155        /// <summary>
156        /// Called by clicking on the open button of CrypTool
157        /// loads a serialized model
158        /// </summary>
159        /// <param name="fileName"></param>
160        public void Open(string fileName)
161        {
162            try
163            {
164                New();
165                GuiLogMessage("Loading Model: " + fileName, NotificationLevel.Info);               
166                WorkspaceModel = ModelPersistance.loadModel(fileName,this);               
167                WorkspaceSpaceEditorView.Load(WorkspaceModel);
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 load Model:" + ex.ToString(), NotificationLevel.Error);
175            }
176        }
177
178        /// <summary>
179        /// Called by clicking on the save button of CrypTool
180        /// serializes the current model
181        /// </summary>
182        /// <param name="fileName"></param>
183        public void Save(string fileName)
184        {
185            try
186            {
187                GuiLogMessage("Saving Model: " + fileName, NotificationLevel.Info);
188                ModelPersistance.saveModel(this.WorkspaceModel, fileName);
189                HasChanges = false;
190                this.OnProjectTitleChanged.BeginInvoke(this, System.IO.Path.GetFileName(fileName), null, null);
191                CurrentFilename = fileName;
192            }
193            catch (Exception ex)
194            {
195                GuiLogMessage("Could not save Model:" + ex.ToString(), NotificationLevel.Error);               
196            }
197           
198        }
199
200        /// <summary>
201        /// Called by double clicking on a plugin symbol of CrypTool
202        /// Adds a new PluginModel wrapping an instance of the selected plugin
203        /// </summary>
204        /// <param name="type"></param>
205        public void Add(Type type)
206        {
207            /*if (!executing)
208            {
209                PluginModel newPluginModel = WorkspaceModel.newPluginModel(new Point(10, 10), 100, 100, type);
210                GuiLogMessage("Added by double click: " + newPluginModel.Name, NotificationLevel.Info);
211                HasChanges = true;
212            }*/
213        }
214
215        /// <summary>
216        ///
217        /// </summary>
218        /// <param name="espi"></param>
219        public void AddEditorSpecific(EditorSpecificPluginInfo espi)
220        {
221            //to be implemented
222        }
223
224        /// <summary>
225        ///
226        /// </summary>
227        /// <param name="espi"></param>
228        public void DeleteEditorSpecific(EditorSpecificPluginInfo espi)
229        {
230            //to be implemented   
231        }
232
233        /// <summary>
234        /// Undo changes
235        /// </summary>
236        public void Undo()
237        {
238            //to be implemented
239        }
240
241        /// <summary>
242        /// Redo changes
243        /// </summary>
244        public void Redo()
245        {
246            //to be implemented
247        }
248
249        public void Cut()
250        {
251           
252        }
253
254        public void Copy()
255        {
256           
257        }
258
259        public void Paste()
260        {
261           
262        }
263
264        public void Remove()
265        {
266           
267        }
268
269        public void Print()
270        {
271            try
272            {
273                Matrix m = PresentationSource.FromVisual(Application.Current.MainWindow).CompositionTarget.TransformToDevice;
274                double dx = m.M11 * 96;
275                double dy = m.M22 * 96;
276                this.GuiLogMessage("dx=" + dx + " dy=" + dy, NotificationLevel.Debug);
277                const int factor = 4;
278                ModifiedCanvas control = (ModifiedCanvas)((WorkSpaceEditorView)this.Presentation).scrollViewer.Content;
279                PrintDialog dialog = new PrintDialog();
280                dialog.PageRangeSelection = PageRangeSelection.AllPages;
281                dialog.UserPageRangeEnabled = true;
282
283                Nullable<Boolean> print = dialog.ShowDialog();
284                if (print == true)
285                {
286                    this.GuiLogMessage("Printing document \"" + this.CurrentFilename + "\" now", NotificationLevel.Info);
287                   
288                    PrintCapabilities capabilities = dialog.PrintQueue.GetPrintCapabilities(dialog.PrintTicket);
289                    System.Windows.Size pageSize = new System.Windows.Size(dialog.PrintableAreaWidth, dialog.PrintableAreaHeight);
290                    System.Windows.Size visibleSize = new System.Windows.Size(capabilities.PageImageableArea.ExtentWidth, capabilities.PageImageableArea.ExtentHeight);
291
292                    FixedDocument fixedDoc = new FixedDocument();
293                    control.Measure(new System.Windows.Size(double.PositiveInfinity, double.PositiveInfinity));
294                    control.Arrange(new Rect(new System.Windows.Point(0, 0), control.DesiredSize));
295                    System.Windows.Size size = control.DesiredSize;
296
297                    RenderTargetBitmap bmp = new RenderTargetBitmap((int)size.Width * factor, (int)size.Height * factor, dx * factor, dy * factor, PixelFormats.Pbgra32);
298                    bmp.Render(control);
299
300
301                    double xOffset = 0;
302                    double yOffset = 0;
303                    while (xOffset < size.Width)
304                    {
305                        yOffset = 0;
306                        while (yOffset < size.Height)
307                        {
308                            PageContent pageContent = new PageContent();
309                            FixedPage page = new FixedPage();
310                            ((IAddChild)pageContent).AddChild(page);
311                            fixedDoc.Pages.Add(pageContent);
312                            page.Width = pageSize.Width;
313                            page.Height = pageSize.Height;
314                            int width = (xOffset + visibleSize.Width) > size.Width ? (int)(size.Width - xOffset) : (int)visibleSize.Width;
315                            int height = (yOffset + visibleSize.Height) > size.Height ? (int)(size.Height - yOffset) : (int)visibleSize.Height;
316                            System.Windows.Controls.Image croppedImage = new System.Windows.Controls.Image();                           
317                            CroppedBitmap cb = new CroppedBitmap(bmp, new Int32Rect((int)xOffset * factor, (int)yOffset *factor, width * factor, height * factor));
318                            croppedImage.Source = cb;
319                            croppedImage.Width = width;
320                            croppedImage.Height = height;
321                            page.Children.Add(croppedImage);
322                            yOffset += visibleSize.Height;
323                        }
324                        xOffset += visibleSize.Width;
325                    }
326                    dialog.PrintDocument(fixedDoc.DocumentPaginator, "WorkspaceManager_" + this.CurrentFilename);
327                    this.GuiLogMessage("Printed \"" + fixedDoc.DocumentPaginator.PageCount + "\" pages of document \"" + this.CurrentFilename + "\"", NotificationLevel.Info);
328                }
329            }
330            catch (Exception ex)
331            {
332                this.GuiLogMessage("Exception while printing: " + ex.Message, NotificationLevel.Error);
333            }
334        }
335
336        /// <summary>
337        /// Show the Help site
338        /// </summary>
339        public void ShowHelp()
340        {
341            //to be implemented
342        }
343
344        /// <summary>
345        /// Show the Description of the selected plugin
346        /// </summary>
347        public void ShowSelectedPluginDescription()
348        {
349            //to be implemented
350        }
351
352        /// <summary>
353        /// Is Undo possible
354        /// </summary>
355        public bool CanUndo
356        {
357            get;
358            set;
359        }
360
361        /// <summary>
362        /// Is Redo possible?
363        /// </summary>
364        public bool CanRedo
365        {
366            get;
367            set;
368        }
369
370        public bool CanCut
371        {
372            get { return false; }
373        }
374
375        public bool CanCopy
376        {
377            get { return false; }
378        }
379
380        public bool CanPaste
381        {
382            get { return false; }
383        }
384
385        public bool CanRemove
386        {
387            get { return false; }
388        }
389
390        /// <summary>
391        /// Can the ExecutionEngine be started?
392        /// </summary>
393        public bool CanExecute
394        {
395            get{return !executing;}
396        }
397
398        /// <summary>
399        /// Can the ExecutionEngine be stopped?
400        /// </summary>
401        public bool CanStop
402        {
403            get { return executing; }
404        }
405
406        /// <summary>
407        /// Does this Editor has changes?
408        /// </summary>
409        public bool HasChanges
410        {
411            get;
412            set;
413        }
414
415        public bool CanPrint
416        {
417            get { return true; }
418        }
419
420        public string SamplesDir
421        {
422            set {  }
423        }
424
425        /// <summary>
426        ///
427        /// </summary>
428        public List<EditorSpecificPluginInfo> EditorSpecificPlugins
429        {
430            get;
431            set;
432        }
433
434        public bool ReadOnly { get; set; }
435
436        #endregion
437
438        #region IPlugin Members
439
440        /// <summary>
441        ///
442        /// </summary>
443        public event StatusChangedEventHandler OnPluginStatusChanged;
444
445        /// <summary>
446        ///
447        /// </summary>
448        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
449
450        /// <summary>
451        ///
452        /// </summary>
453        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
454
455        /// <summary>
456        /// Settings of this editor
457        /// </summary>
458        public ISettings Settings
459        {
460            get;
461            set;
462        }
463
464        /// <summary>
465        /// The Presentation of this editor
466        /// </summary>
467        public System.Windows.Controls.UserControl Presentation
468        {
469            get {return WorkspaceSpaceEditorView;}
470            set { WorkspaceSpaceEditorView = (WorkSpaceEditorView)value; }
471        }
472
473        /// <summary>
474        /// The QuickWatchPresentation of this editor
475        /// </summary>
476        public System.Windows.Controls.UserControl QuickWatchPresentation
477        {
478            get;
479            set;
480        }
481
482        /// <summary>
483        /// Called before execution
484        /// </summary>
485        public void PreExecution()
486        {
487            //to be implemented
488        }
489
490        /// <summary>
491        /// Starts the ExecutionEngine to execute the model
492        /// </summary>
493        public void Execute()
494        {
495            if (executing)
496            {
497                return;
498            }
499            EventsHelper.AsynchronousPropertyChanged = false;
500            try
501            {
502                GuiLogMessage("Execute Model now!", NotificationLevel.Info);
503                executing = true;
504
505                if (((WorkspaceManagerSettings)this.Settings).SynchronousEvents)
506                {
507                    EventsHelper.AsynchronousProgressChanged = false;
508                    EventsHelper.AsynchronousGuiLogMessage = false;
509                    EventsHelper.AsynchronousStatusChanged = false;
510                }
511
512                //Get the gui Thread
513                this.WorkspaceSpaceEditorView.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
514                {
515                    this.WorkspaceSpaceEditorView.ResetConnections();
516                    this.WorkspaceSpaceEditorView.State = EditorState.BUSY;                   
517                }
518                , null);
519
520                this.ExecutionEngine = new ExecutionEngine(this);
521
522                try
523                {
524                    ExecutionEngine.GuiUpdateInterval = int.Parse(((WorkspaceManagerSettings)this.Settings).GuiUpdateInterval);
525                    if (ExecutionEngine.GuiUpdateInterval <= 0)
526                    {
527                        GuiLogMessage("GuiUpdateInterval can not be <=0; Use GuiUpdateInterval = 1", NotificationLevel.Warning);
528                        ExecutionEngine.GuiUpdateInterval = 1;
529                    }
530                }
531                catch (Exception ex)
532                {
533                    GuiLogMessage("Could not set GuiUpdateInterval: " + ex.Message, NotificationLevel.Warning);
534                    ExecutionEngine.GuiUpdateInterval = 100;
535                }
536
537                try
538                {
539                    ExecutionEngine.SleepTime = int.Parse(((WorkspaceManagerSettings)this.Settings).SleepTime);
540                    if (ExecutionEngine.SleepTime < 0)
541                    {
542                        GuiLogMessage("SleepTime can not be <=0; Use GuiUpdateInterval = 0", NotificationLevel.Warning);
543                        ExecutionEngine.SleepTime = 0;
544                    }
545                }
546                catch (Exception ex)
547                {
548                    GuiLogMessage("Could not set SleepTime: " + ex.Message, NotificationLevel.Warning);
549                    ExecutionEngine.GuiUpdateInterval = 0;
550                }
551
552                int schedulers=0;
553                try
554                {
555                   schedulers = int.Parse(((WorkspaceManagerSettings)this.Settings).Threads);
556                    if (ExecutionEngine.SleepTime < 0)
557                    {
558                        GuiLogMessage("Schedulers can not be <=0; Use Schedulers = 1", NotificationLevel.Warning);
559                        schedulers = 1;
560                    }
561                }
562                catch (Exception ex)
563                {
564                    GuiLogMessage("Could not set Schedulers: " + ex.Message, NotificationLevel.Warning);
565                    schedulers = 1;
566                }
567
568                ExecutionEngine.BenchmarkPlugins = ((WorkspaceManagerSettings)this.Settings).BenchmarkPlugins;
569                ExecutionEngine.ThreadPriority = ((WorkspaceManagerSettings)this.Settings).ThreadPriority;
570
571                ExecutionEngine.Execute(WorkspaceModel, schedulers);               
572            }
573            catch (Exception ex)
574            {
575                GuiLogMessage("Exception during the execution: " + ex.Message, NotificationLevel.Error);
576                executing = false;
577                if (((WorkspaceManagerSettings)this.Settings).SynchronousEvents)
578                {
579                    EventsHelper.AsynchronousProgressChanged = true;
580                    EventsHelper.AsynchronousGuiLogMessage = true;
581                    EventsHelper.AsynchronousStatusChanged = true;
582                }
583            }
584        }
585
586        /// <summary>
587        /// Called after the execution
588        /// </summary>
589        public void PostExecution()
590        {
591            //to be implemented
592        }
593
594        /// <summary>
595        /// Pause the execution
596        /// </summary>
597        public void Pause()
598        {   
599            //to be implemented
600        }
601
602        /// <summary>
603        /// Stop the ExecutionEngine
604        /// </summary>
605        public void Stop()
606        {
607            if (!executing || stopping)
608            {
609                return;
610            }
611
612            stopping = true;
613
614            Thread stopThread = new Thread(new ThreadStart(waitingStop));
615            stopThread.Start(); 
616
617            EventsHelper.AsynchronousPropertyChanged = true;
618
619            if (((WorkspaceManagerSettings)this.Settings).SynchronousEvents)
620            {
621                EventsHelper.AsynchronousProgressChanged = true;
622                EventsHelper.AsynchronousGuiLogMessage = true;
623                EventsHelper.AsynchronousStatusChanged = true;
624            }
625
626                       
627        }
628
629        /// <summary>
630        /// Stops the execution engine and blocks until this work is done
631        /// </summary>
632        private void waitingStop()
633        {
634            try
635            {
636                GuiLogMessage("Executing stopped by User!", NotificationLevel.Info);
637                ExecutionEngine.Stop();
638                //Get the gui Thread
639                this.WorkspaceSpaceEditorView.Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
640                {
641                    this.WorkspaceSpaceEditorView.ResetConnections();
642                    this.WorkspaceSpaceEditorView.State = EditorState.READY;
643                }
644                , null);
645            }
646            catch (Exception ex)
647            {
648                GuiLogMessage("Exception during the stopping of the execution: " + ex.Message, NotificationLevel.Error);
649            }
650            executing = false;
651            this.ExecutionEngine = null;
652            GC.Collect();
653            stopping = false;
654        }
655
656        /// <summary>
657        /// Called to initialize the editor
658        /// </summary>
659        public void Initialize()
660        {
661            //to be implemented
662        }
663
664        /// <summary>
665        /// Called when the editor is disposed
666        /// </summary>
667        public void Dispose()
668        {
669            if (ExecutionEngine != null && ExecutionEngine.IsRunning)
670            {
671                ExecutionEngine.Stop();
672            }
673            EventsHelper.AsynchronousPropertyChanged = true;
674        }
675
676        #endregion
677
678        #region INotifyPropertyChanged Members
679
680        /// <summary>
681        ///
682        /// </summary>
683        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
684
685        #endregion
686
687        #region IApplication Members
688
689        /// <summary>
690        ///
691        /// </summary>
692        private PluginManager pluginManager;
693        public PluginManager PluginManager
694        {
695            get { return pluginManager; }
696            set
697            {
698                pluginManager = value;
699                DragDropDataObjectToPluginConverter.PluginManager = value;
700            }         
701        }
702
703        #endregion
704
705        #region GuiLogMessage, Progress
706
707        /// <summary>
708        /// Loggs a message to the logging mechanism of CrypTool
709        /// </summary>
710        /// <param name="Message"></param>
711        /// <param name="notificationLevel"></param>
712        public void GuiLogMessage(string Message, NotificationLevel notificationLevel)
713        {
714            if (OnGuiLogNotificationOccured != null)
715            {
716                GuiLogEventArgs args = new GuiLogEventArgs(Message, this, notificationLevel);
717                args.Title = "-";
718                OnGuiLogNotificationOccured(this, args);
719            }
720        }
721
722        /// <summary>
723        /// GuiLogNotificationOccured
724        /// </summary>
725        /// <param name="sender"></param>
726        /// <param name="args"></param>
727        public void GuiLogNotificationOccured(IPlugin sender, GuiLogEventArgs args)
728        {
729            //Check if the logging event is Warning or Error and set the State of the PluginModel to
730            //the corresponding PluginModelState
731            if (args.NotificationLevel == NotificationLevel.Warning)
732            {               
733                foreach (PluginModel pluginModel in this.WorkspaceModel.AllPluginModels)
734                {
735                    if (pluginModel.Plugin == sender)
736                    {
737                        pluginModel.State = PluginModelState.Warning;
738                        pluginModel.GuiNeedsUpdate = true;
739                    }
740                }
741            }
742
743            if (args.NotificationLevel == NotificationLevel.Error)
744            {               
745                foreach (PluginModel pluginModel in this.WorkspaceModel.AllPluginModels)
746                {
747                    if (pluginModel.Plugin == sender)
748                    {
749                        pluginModel.State = PluginModelState.Error;
750                        pluginModel.GuiNeedsUpdate = true;
751                    }
752                }
753            }
754
755            if (OnGuiLogNotificationOccured != null)
756            {
757                switch (((WorkspaceManagerSettings)this.Settings).LogLevel)
758                {
759                    case 3://Error
760                        if (args.NotificationLevel == NotificationLevel.Debug ||
761                            args.NotificationLevel == NotificationLevel.Info ||
762                            args.NotificationLevel == NotificationLevel.Warning)
763                        {
764                            return;
765                        }
766                        break;
767
768                    case 2://Warning
769                        if (args.NotificationLevel == NotificationLevel.Debug ||
770                            args.NotificationLevel == NotificationLevel.Info)
771                        {
772                            return;
773                        }
774                        break;
775
776                    case 1://Info
777                        if (args.NotificationLevel == NotificationLevel.Debug)
778                        {
779                            return;
780                        }
781                        break;
782                }
783                OnGuiLogNotificationOccured(sender, args);
784            }
785               
786        }
787
788        /// <summary>
789        /// Progress of this editor
790        /// </summary>
791        /// <param name="Value"></param>
792        /// <param name="MaxValue"></param>
793        private void Progress(int Value, int MaxValue)
794        {
795            if (OnPluginProgressChanged != null)
796            {
797                OnPluginProgressChanged(this, new PluginProgressEventArgs(Value, MaxValue));
798            }
799        }
800        #endregion GuiLogMessage, Progress
801
802        /// <summary>
803        /// Selected Plugin changed by View
804        /// </summary>
805        /// <param name="args"></param>
806        public void onSelectedPluginChanged(PluginChangedEventArgs args)
807        {
808            this.OnSelectedPluginChanged(this, args);
809        }
810
811        #region IEditor Members
812
813
814        public void Active()
815        {
816            var b = true;
817        }
818
819        #endregion
820
821        #region IEditor Members
822
823
824        public event OpenTabHandler OnOpenTab;
825
826        #endregion
827    }
828}
829
830//Restore warnings for unused or unassigned fields and events:
831#pragma warning restore 0169, 0414, 0067
Note: See TracBrowser for help on using the repository browser.