Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.Netron/3.0.2672.12446/Netron.Diagramming.Core-3.0.2672.12446/Core/ControllerBase.cs @ 2768

Last change on this file since 2768 was 2768, checked in by mkommend, 14 years ago

added solution folders and sources for the netron library (ticket #867)

File size: 59.1 KB
Line 
1using System;
2using System.Drawing;
3using System.Collections.Generic;
4using System.Text;
5using System.Windows.Forms;
6using System.ComponentModel;
7using System.Diagnostics;
8namespace Netron.Diagramming.Core
9{
10    // ----------------------------------------------------------------------
11    /// <summary>
12    /// Abstract base implementation of the <see cref="IController"/>
13    /// interface.
14    /// </summary>
15    // ----------------------------------------------------------------------
16    public abstract class ControllerBase : IUndoSupport, IController
17    {
18        #region Events
19
20        // ------------------------------------------------------------------
21        /// <summary>
22        /// Occurs when the context menu is shown.
23        /// </summary>
24        // ------------------------------------------------------------------
25        public event EventHandler<EntityMenuEventArgs> OnShowContextMenu;
26
27        // ------------------------------------------------------------------
28        /// <summary>
29        /// Occurs when a tool is asked to be deactivated.
30        /// </summary>
31        // ------------------------------------------------------------------
32        public event EventHandler<ToolEventArgs> OnToolDeactivate;
33
34        // ------------------------------------------------------------------
35        /// <summary>
36        /// Occurs when a tool is asked to be activated.
37        /// </summary>
38        // ------------------------------------------------------------------
39        public event EventHandler<ToolEventArgs> OnToolActivate;
40
41        // ------------------------------------------------------------------
42        /// <summary>
43        /// Occurs when the history has changed in the undo/redo mechanism.
44        /// </summary>
45        // ------------------------------------------------------------------
46        public event EventHandler<HistoryChangeEventArgs> OnHistoryChange;
47
48        // ------------------------------------------------------------------
49        /// <summary>
50        /// Occurs when the something got selected and the properties of it
51        /// can/should be shown.
52        /// </summary>
53        // ------------------------------------------------------------------
54        public event EventHandler<SelectionEventArgs> OnShowSelectionProperties;
55
56        // ------------------------------------------------------------------
57        /// <summary>
58        /// Occurs when an entity is added.
59        /// <remarks>This event usually is bubbled from one of the
60        /// layers.</remarks>
61        /// </summary>
62        // ------------------------------------------------------------------
63        public event EventHandler<EntityEventArgs> OnEntityAdded;
64
65        // ------------------------------------------------------------------
66        /// <summary>
67        /// Occurs when an entity is removed.
68        /// <remarks>This event usually is bubbled from one of the
69        /// layers.</remarks>
70        /// </summary>
71        // ------------------------------------------------------------------
72        public event EventHandler<EntityEventArgs> OnEntityRemoved;
73
74        // ------------------------------------------------------------------
75        /// <summary>
76        /// Occurs when the controller receives a mouse-down notification of
77        /// the surface. This event is raised before the
78        /// event is broadcasted down to the tools.
79        /// </summary>
80        // ------------------------------------------------------------------
81        public event EventHandler<MouseEventArgs> OnMouseDown;
82
83        // ------------------------------------------------------------------
84        /// <summary>
85        /// Occurs when the Ambience has changed.
86        /// </summary>
87        // ------------------------------------------------------------------
88        public event EventHandler<AmbienceEventArgs> OnAmbienceChanged;
89       
90       
91        #endregion
92
93        #region Tool Names
94
95        public const string AlignBottomEdgesToolName =
96            "Align Bottom Edges Tool";
97
98        public const string AlignCentersHorizToolName =
99            "Align Centers Horizontally";
100
101        public const string AlignCentersVertToolName =
102            "Align Centers Vertically";
103
104        public const string AlignLeftEdgesToolName =
105            "Align Left Edges Tool";
106
107        public const string AlignRightEdgesToolName =
108            "Align Right Edges Tool";
109
110        public const string AlignTopEdgesToolName =
111            "Align Top Edges Tool";
112
113        public const string ComplexRectangleToolName = "ComplexRectangle Tool";
114        public const string ConnectionToolName = "Connection Tool";
115        public const string ConnectorMoverToolName = "Connector Mover Tool";
116        public const string ContextToolName = "Context Tool";
117        public const string CopyToolName = "Copy Tool";
118        public const string CutToolName = "Cut Tool";
119        public const string DeleteToolName = "Delete Tool";         
120        public const string DragDropToolName = "DragDrop Tool";
121        public const string EllipseToolName = "Ellipse Tool";
122        public const string GroupToolName = "Group Tool";
123        public const string HitToolName = "Hit Tool";
124        public const string HoverToolName = "Hover Tool";
125        public const string ImageExportToolName = "Image Export Tool";
126        public const string MoveToolName = "Move Tool";
127        public const string MultiLineToolName = "MultiLine Tool";
128        public const string PanToolName = "Pan Tool";
129        public const string PasteToolName = "Paste Tool";
130        public const string PolygonToolName = "Polygon Tool";
131        public const string RectangleToolName = "Rectangle Tool";
132        public const string ScribbleToolName = "Scribble Tool";
133        public const string SelectionToolName = "Selection Tool";
134        public const string SendBackwardsToolName = "SendBackwards Tool";
135        public const string SendForwardsToolName = "SendForwards Tool";
136        public const string SendToBackToolName = "SendToBack Tool";
137        public const string SendToFrontToolName = "SendToFront Tool";
138        public const string TransformToolName = "Transform Tool";       
139        public const string UngroupToolName = "Ungroup Tool";
140        public const string ZoomAreaToolName = "Zoom Area Tool";
141        public const string ZoomInToolName = "Zoom In Tool";
142        public const string ZoomOutToolName = "Zoom Out Tool";       
143
144        #endregion
145
146        #region Fields
147
148        private bool eventsEnabled = true;
149        private bool controllerEnabled = true;
150
151        private IModel mModel;
152        private UndoManager mUndoManager;
153        ITool activeTool;
154
155        /// <summary>
156        /// the View field
157        /// </summary>
158        private IView mView;
159        private CollectionBase<IMouseListener> mouseListeners;
160        private CollectionBase<IKeyboardListener> keyboardListeners;
161        private CollectionBase<IDragDropListener> dragdropListeners;
162        private IDiagramControl parentControl;
163        private CollectionBase<ITool> registeredTools;
164        private CollectionBase<IActivity> registeredActivity;
165       
166        #endregion
167
168        #region Properties
169
170        /// <summary>
171        /// Gets or sets a value indicating whether this <see cref="T:ControllerBase"/> is enabled.
172        /// </summary>
173        /// <value><c>true</c> if enabled; otherwise, <c>false</c>.</value>
174        public bool Enabled
175        {
176            get
177            {
178                return controllerEnabled;
179            }
180            set
181            {
182                controllerEnabled = value;
183            }
184        }
185
186        // ------------------------------------------------------------------
187        /// <summary>
188        /// Gets the currently active tool.  This can be 'null'!!!
189        /// </summary>
190        // ------------------------------------------------------------------
191        public ITool ActiveTool
192        {
193            get
194            {
195                return this.activeTool;
196            }
197        }
198
199        /// <summary>
200        /// Gets or sets the parent control.
201        /// </summary>
202        /// <value>The parent control.</value>
203         public IDiagramControl ParentControl
204        {
205            get { return parentControl; }
206            internal set { parentControl = value; }
207        }
208        /// <summary>
209        /// Gets the registered tools.
210        /// </summary>
211        /// <value>The tools.</value>
212        public CollectionBase<ITool> Tools
213        {
214            get { return registeredTools; }
215        }
216
217
218
219        /// <summary>
220        /// Gets the undo manager.
221        /// </summary>
222        /// <value>The undo manager.</value>
223        public  UndoManager UndoManager
224        {
225            get
226            {
227                return mUndoManager;
228            }
229
230        }
231
232        /// <summary>
233        /// Gets or sets the model
234        /// </summary>
235        /// <value></value>
236        public IModel Model
237        {
238            get
239            {
240                return mModel;
241            }
242            set
243            {
244                AttachToModel(value);
245            }
246        }
247
248        /// <summary>
249        /// Gets or sets the view.
250        /// </summary>
251        /// <value>The view.</value>
252        public IView View
253        {
254            get
255            {
256                return mView;
257            }
258            set
259            {
260                AttachToView(value);
261            }
262        }
263
264        /// <summary>
265        /// Attaches to the given view.
266        /// </summary>
267        /// <param name="view">The view.</param>
268        private void AttachToView(IView view)
269        {
270            if (view == null)
271                throw new ArgumentNullException();
272
273            mView = view;
274        }
275        #endregion
276
277        #region Constructor
278
279        // ------------------------------------------------------------------
280        /// <summary>
281        /// Default constructor.
282        /// </summary>
283        // ------------------------------------------------------------------
284        protected ControllerBase(IDiagramControl surface)
285        {
286            //doesn't work if you supply a null reference
287            if (surface == null)
288            {
289                throw new NullReferenceException(
290                    "The diagram control assigned to the controller " +
291                    "cannot be 'null'");
292            }
293           
294            //create the undo/redo manager
295            mUndoManager = new UndoManager(15);
296            mUndoManager.OnHistoryChange += new EventHandler(
297                mUndoManager_OnHistoryChange);
298
299            #region Instantiation of listeners
300            mouseListeners = new CollectionBase<IMouseListener>();
301            keyboardListeners = new CollectionBase<IKeyboardListener>();
302            dragdropListeners = new CollectionBase<IDragDropListener>();
303            #endregion
304
305            //keep a reference to the parent control
306            parentControl = surface;
307
308            AttachToSurface(parentControl);
309           
310           
311
312            //Make sure the static selection class knows about the model
313            Selection.Controller = this;
314            //Initialize the colorscheme
315            ArtPalette.Init();
316
317            #region Tools: the registration order matters!
318            /*
319             The order in in which the tools are added matters, at least
320             some of them.
321               * The TransformTool should come before the HitTool and the
322                 MoveTool after the HitTool.
323               * The order of the drawing tools does not matter.
324               * It's also important to remark that the tools do not depend
325                 on the Model.
326             */
327
328            registeredTools = new CollectionBase<ITool>();
329
330            this.AddTool(new TransformTool(TransformToolName));
331
332            this.AddTool(new HitTool(HitToolName));
333
334            this.AddTool(new MoveTool(MoveToolName));
335
336            this.AddTool(new RectangleTool(RectangleToolName));
337
338            this.AddTool(new ComplexRectangleTool(ComplexRectangleToolName));
339
340            this.AddTool(new EllipseTool(EllipseToolName));
341
342            this.AddTool(new SelectionTool(SelectionToolName));
343
344            this.AddTool(new DragDropTool(DragDropToolName));
345
346            this.AddTool(new ConnectionTool(ConnectionToolName));
347
348            this.AddTool(new ConnectorMoverTool(ConnectorMoverToolName));
349
350            this.AddTool( new GroupTool(GroupToolName));
351
352            this.AddTool(new UngroupTool(UngroupToolName));
353
354            this.AddTool(new SendToBackTool(SendToBackToolName));
355
356            this.AddTool(new SendBackwardsTool(SendBackwardsToolName));
357
358            this.AddTool(new SendForwardsTool(SendForwardsToolName));
359
360            this.AddTool(new SendToFrontTool(SendToFrontToolName));         
361
362            this.AddTool(new HoverTool(HoverToolName));           
363
364            this.AddTool(new ContextTool(ContextToolName));
365
366            this.AddTool(new CopyTool(CopyToolName));
367
368            this.AddTool(new CutTool(CutToolName));
369
370            this.AddTool(new PasteTool(PasteToolName));
371
372            this.AddTool(new DeleteTool(DeleteToolName));
373
374            this.AddTool(new ScribbleTool(ScribbleToolName));
375
376            this.AddTool(new PolygonTool(PolygonToolName));
377
378            this.AddTool(new MultiLineTool(MultiLineToolName));
379
380            this.AddTool(new AlignBottomEdgesTool(AlignBottomEdgesToolName));
381
382            this.AddTool(
383                new AlignCentersHorizontallyTool(AlignCentersHorizToolName));
384
385            this.AddTool(
386                new AlignCentersVerticallyTool(AlignCentersVertToolName));
387
388            this.AddTool( new AlignLeftEdgesTool(AlignLeftEdgesToolName));
389
390            this.AddTool(new AlignRightEdgesTool(AlignRightEdgesToolName));
391
392            this.AddTool(new AlignTopEdgesTool(AlignTopEdgesToolName));
393
394            this.AddTool(new ZoomAreaTool(ZoomAreaToolName));
395
396            this.AddTool(new ZoomInTool(ZoomInToolName));
397
398            this.AddTool(new ZoomOutTool(ZoomOutToolName));
399
400            this.AddTool(new PanTool(PanToolName));
401
402            this.AddTool(new ImageExportTool(ImageExportToolName));
403
404            #endregion
405
406            #region Hotkeys
407            HotKeys keys = new HotKeys(this);
408            this.keyboardListeners.Add(keys);
409            #endregion
410
411            #region Activities
412            // This is in a way a waste of memory; the layouts should not
413            // necessarily be loaded before they are actually requested.
414            // You could register only the (string) names instead.
415            // But for just a few algorithms this is OK and the advantage
416            // of this registration is that one can register actions from
417            // outside the library, in the hosting form for example.
418            registeredActivity = new CollectionBase<IActivity>();
419            AddActivity(new RandomLayout(this));
420            AddActivity(new FruchtermanReingoldLayout(this));
421            AddActivity(new StandardTreeLayout(this));
422            AddActivity(new RadialTreeLayout(this));
423            AddActivity(new BalloonTreeLayout(this));
424            AddActivity(new ForceDirectedLayout(this));
425            #endregion
426        }
427
428        #endregion
429
430        // ------------------------------------------------------------------
431        /// <summary>
432        /// Attaches the given model to the controller.
433        /// </summary>
434        /// <param name="model">IModel</param>
435        // ------------------------------------------------------------------
436        protected virtual void AttachToModel(IModel model)
437        {
438            if (model == null)
439                throw new ArgumentNullException();
440
441            mModel = model;
442            mModel.OnEntityAdded +=
443                new EventHandler<EntityEventArgs>(mModel_OnEntityAdded);
444            mModel.OnEntityRemoved +=
445                new EventHandler<EntityEventArgs>(mModel_OnEntityRemoved);
446            mModel.OnAmbienceChanged +=
447                new EventHandler<AmbienceEventArgs>(mModel_OnAmbienceChanged);
448        }
449
450        // ------------------------------------------------------------------
451        /// <summary>
452        /// Passes the OnAmbienceChanged event on.
453        /// </summary>
454        /// <param name="sender">object</param>
455        /// <param name="e">AmbienceEventArgs</param>
456        // ------------------------------------------------------------------
457        void mModel_OnAmbienceChanged(
458            object sender,
459            AmbienceEventArgs e)
460        {
461            RaiseOnAmbienceChanged(e);
462        }
463
464        // ------------------------------------------------------------------
465        /// <summary>
466        /// Passes the OnEntityRemoved event on.
467        /// </summary>
468        /// <param name="sender">object</param>
469        /// <param name="e">EntityEventArgs</param>
470        // ------------------------------------------------------------------
471        void mModel_OnEntityRemoved(
472            object sender,
473            EntityEventArgs e)
474        {
475            RaiseOnEntityRemoved(e);
476        }
477
478        // ------------------------------------------------------------------
479        /// <summary>
480        /// Passes the OnEntityAdded event on.
481        /// </summary>
482        /// <param name="sender">object</param>
483        /// <param name="e">EntityEventArgs</param>
484        // ------------------------------------------------------------------
485        void mModel_OnEntityAdded(
486            object sender,
487            EntityEventArgs e)
488        {
489            RaiseOnEntityAdded(e);
490        }
491
492        // ------------------------------------------------------------------
493        /// <summary>
494        /// Bubbles the OnHistoryChange event.
495        /// </summary>
496        /// <param name="sender">The source of the event.</param>
497        /// <param name="e">The <see cref="T:System.EventArgs"/> instance
498        /// containing the event data.</param>
499        // ------------------------------------------------------------------
500        void mUndoManager_OnHistoryChange(object sender, EventArgs e)
501        {
502            RaiseOnHistoryChange();
503        }
504
505        #region Methods
506
507        // ------------------------------------------------------------------
508        /// <summary>
509        /// Activates the text editor for the given text provider.
510        /// </summary>
511        /// <param name="textProvider">ITextProvider</param>
512        /// <returns>bool: True if sucessful, false if not.</returns>
513        // ------------------------------------------------------------------
514        public abstract bool ActivateTextEditor(ITextProvider textProvider);
515
516        // ------------------------------------------------------------------
517        /// <summary>
518        /// Changes the paint style of the selected entities.
519        /// </summary>
520        /// <param name="paintStyle">IPaintStyle</param>
521        // ------------------------------------------------------------------
522        public void ChangeStyle(IPaintStyle paintStyle)
523        {
524
525            // Note that you need a copy of the selected item otherwise the
526            // undo/redo will fail once the selection has changed
527            FillStyleCommand cmd = new FillStyleCommand(
528                this,
529                Selection.SelectedItems.Copy(),
530                paintStyle);           
531
532            this.UndoManager.AddUndoCommand(cmd);
533            cmd.Redo();
534        }
535
536        // ------------------------------------------------------------------
537        /// <summary>
538        /// Changes the pen style  of the selected entities.
539        /// </summary>
540        /// <param name="penStyle">The pen style.</param>
541        // ------------------------------------------------------------------
542        public void ChangeStyle(IPenStyle penStyle)
543        {
544            PenStyleCommand cmd = new PenStyleCommand(
545                this,
546                Selection.SelectedItems.Copy(),
547                penStyle);
548
549            this.UndoManager.AddUndoCommand(cmd);
550
551            cmd.Redo();
552        }
553
554        #region Event Raisers
555
556        // ------------------------------------------------------------------
557        /// <summary>
558        /// Raises the OnShowContextMenu event
559        /// </summary>
560        /// <param name="e">EntityMenuEventArgs</param>
561        // ------------------------------------------------------------------
562        public virtual void RaiseOnShowContextMenu(EntityMenuEventArgs e)
563        {
564            EventHandler<EntityMenuEventArgs> handler = OnShowContextMenu;
565            if (handler != null)
566            {
567                handler(this, e);
568            }
569        }
570
571        // ------------------------------------------------------------------
572        /// <summary>
573        /// Raises the OnHistory change.
574        /// </summary>
575        // ------------------------------------------------------------------
576        public virtual void RaiseOnHistoryChange()
577        {
578            EventHandler<HistoryChangeEventArgs> handler = OnHistoryChange;
579            if (handler != null)
580            {
581                handler(this, new HistoryChangeEventArgs(
582                    this.UndoManager.RedoText,
583                    this.UndoManager.UndoText));
584            }
585        }
586
587        // ------------------------------------------------------------------
588        /// <summary>
589        /// Raises the <see cref="OnToolDeactivate"/> event.
590        /// </summary>
591        /// <param name="e">ConnectionCollection event argument</param>
592        // ------------------------------------------------------------------
593        public virtual void RaiseOnToolDeactivate(ToolEventArgs e)
594        {
595            EventHandler<ToolEventArgs> handler = OnToolDeactivate;
596            if (handler != null)
597            {
598                handler(this, e);
599            }
600        }
601
602        // ------------------------------------------------------------------
603        /// <summary>
604        /// Raises the <see cref="OnToolActivate"/> event
605        /// </summary>
606        /// <param name="e">ConnectionCollection event argument</param>
607        // ------------------------------------------------------------------
608        public virtual void RaiseOnToolActivate(ToolEventArgs e)
609        {
610            EventHandler<ToolEventArgs> handler = OnToolActivate;
611            if (handler != null)
612            {
613                handler(this, e);
614            }
615        }
616
617        // ------------------------------------------------------------------
618        /// <summary>
619        /// Raises the OnShowSelectionProperties event.
620        /// </summary>
621        /// <param name="e">The
622        /// <see cref="T:Netron.Diagramming.Core.SelectionEventArgs"/>
623        /// instance containing the event data.</param>
624        // ------------------------------------------------------------------
625        public virtual void RaiseOnShowSelectionProperties(SelectionEventArgs e)
626        {
627            EventHandler<SelectionEventArgs> handler = OnShowSelectionProperties;
628            if(handler != null)
629            {
630                handler(this, e);
631            }
632        }
633
634        // ------------------------------------------------------------------
635        /// <summary>
636        /// Raises the <see cref="OnMouseDown "/> event.
637        /// </summary>
638        /// <param name="e">The
639        /// <see cref="T:System.Windows.Forms.MouseEventArgs"/> instance
640        /// containing the event data.</param>
641        // ------------------------------------------------------------------
642        protected virtual void RaiseOnMouseDown(MouseEventArgs e)
643        {
644            if(OnMouseDown != null)
645                OnMouseDown(this, e);
646        }
647
648        // ------------------------------------------------------------------
649        /// <summary>
650        /// Raises the <see cref="OnEntityAdded"/> event.
651        /// </summary>
652        /// <param name="e">The
653        /// <see cref="T:Netron.Diagramming.Core.EntityEventArgs"/> instance
654        /// containing the event data.</param>
655        // ------------------------------------------------------------------
656        protected virtual void RaiseOnEntityAdded(EntityEventArgs e)
657        {
658            EventHandler<EntityEventArgs> handler = OnEntityAdded;
659            if (handler != null)
660            {
661                handler(this, e);
662            }
663        }
664
665        // ------------------------------------------------------------------
666        /// <summary>
667        /// Raises the <see cref="OnEntityRemoved"/> event.
668        /// </summary>
669        /// <param name="e">The
670        /// <see cref="T:Netron.Diagramming.Core.EntityEventArgs"/> instance
671        /// containing the event data.</param>
672        // ------------------------------------------------------------------
673        protected virtual void RaiseOnEntityRemoved(EntityEventArgs e)
674        {
675            EventHandler<EntityEventArgs> handler = OnEntityRemoved;
676            if (handler != null)
677            {
678                handler(this, e);
679            }
680        }
681
682        // ------------------------------------------------------------------
683        /// <summary>
684        /// Raises the <see cref="OnAmbienceChanged"/> event.
685        /// </summary>
686        /// <param name="e">AmbienceEventArgs</param>
687        // ------------------------------------------------------------------
688        protected virtual void RaiseOnAmbienceChanged(AmbienceEventArgs e)
689        {
690            EventHandler<AmbienceEventArgs> handler = OnAmbienceChanged;
691            if(handler != null)
692            {
693                handler(this, e);
694            }
695        }
696
697        #endregion
698
699        #region Tool (de)activation methods
700
701        // ------------------------------------------------------------------
702        /// <summary>
703        /// Deactivates the given tool.
704        /// </summary>
705        /// <param name="tool">a registered ITool</param>
706        /// <returns>bool: True if successful.</returns>
707        // ------------------------------------------------------------------
708        public bool DeactivateTool(ITool tool)
709        {
710            bool flag = false;
711            if (tool != null && tool.Enabled && tool.IsActive)
712            {
713                //IEnumerator iEnumerator = tools.GetEnumerator();
714                //Tool tool2 = null;
715                //while (iEnumerator.MoveNext())
716                //{
717                //    tool2 = iEnumerator.Current is Tool;
718                //    if (tool2 != null && tool2 != tool)
719                //    {
720                //        tool2.ToolDeactivating(tool);
721                //    }
722                //}
723                flag = tool.DeactivateTool();
724                if (flag && eventsEnabled)
725                {
726                    RaiseOnToolDeactivate(new ToolEventArgs(tool));
727                }
728            }
729            return flag;
730        }
731
732        // ------------------------------------------------------------------
733        /// <summary>
734        /// Deactivates all tools.
735        /// </summary>
736        /// <returns>bool: True if successful.</returns>
737        // ------------------------------------------------------------------
738        public bool DeactivateAllTools()
739        {
740            bool successful = true;
741
742            // If the deactivation of any tool returns false, then we will
743            // return false.
744            foreach (ITool tool in this.Tools)
745            {
746                successful = successful & this.DeactivateTool(tool);
747            }
748            this.activeTool = null;
749            return successful;
750        }
751
752        // ------------------------------------------------------------------
753        /// <summary>
754        /// Activates the tool with the given name
755        /// </summary>
756        /// <param name="toolName"></param>
757        // ------------------------------------------------------------------
758        public void ActivateTool(string toolName)
759        {
760            if(!controllerEnabled)
761                return;
762
763            //using anonymous method here
764            Predicate<ITool> predicate = delegate(ITool tool)
765            {
766                if (tool.Name.ToLower() == toolName.ToLower())//not case sensitive
767                    return true;
768                else
769                    return false;
770            };
771
772            // First deactivate the current tool.
773            if (this.activeTool != null)
774            {
775                this.activeTool.DeactivateTool();
776            }
777            ITool foundTool= this.registeredTools.Find(predicate);
778            ActivateTool(foundTool);
779        }
780
781        // ------------------------------------------------------------------
782        /// <summary>
783        /// Suspends all tools
784        /// </summary>
785        // ------------------------------------------------------------------
786        public void SuspendAllTools()
787        {
788            foreach(ITool tool in this.Tools)
789            {
790                tool.IsSuspended = true;
791            }
792        }
793
794        // ------------------------------------------------------------------
795        /// <summary>
796        /// Unsuspends all tools.
797        /// </summary>
798        // ------------------------------------------------------------------
799        public void UnsuspendAllTools()
800        {
801            foreach(ITool tool in this.Tools)
802            {
803                tool.IsSuspended = false;
804            }
805        }
806
807        // ------------------------------------------------------------------
808        /// <summary>
809        /// Activates a registered tool
810        /// </summary>
811        /// <param name="tool">a registered ITool</param>
812        /// <returns>bool: Returns if the activation was successful.  True is
813        /// returned if it was, false if not.</returns>
814        // ------------------------------------------------------------------
815        private bool ActivateTool(ITool tool)
816    {
817            if(!controllerEnabled)
818                return false;
819      bool flag = false;
820      if (tool != null && tool.CanActivate)
821      {                 
822        flag = tool.ActivateTool();
823                this.activeTool = tool;
824        if (flag && eventsEnabled )
825        {
826          RaiseOnToolActivate(new ToolEventArgs(tool));
827        }
828      }
829      return flag;
830    }
831
832        #endregion
833
834        // ------------------------------------------------------------------
835        /// <summary>
836        /// Adds the given tool.
837        /// </summary>
838        /// <param name="tool">The tool.</param>
839        // ------------------------------------------------------------------
840        public void AddTool(ITool tool)
841        {
842            tool.Controller = this;
843            // Add the tool to the collection even if it doesn't attach to
844            // anything (yet)
845            registeredTools.Add(tool);
846
847            IMouseListener mouseTool = null;
848            if ((mouseTool = tool as IMouseListener) != null)
849                mouseListeners.Add(mouseTool);                   
850
851            IKeyboardListener keyboardTool = null;
852            if ((keyboardTool = tool as IKeyboardListener) != null)
853                keyboardListeners.Add(keyboardTool);
854
855            IDragDropListener dragdropTool = null;
856            if ((dragdropTool = tool as IDragDropListener) != null)
857                dragdropListeners.Add(dragdropTool);
858
859            // Watch when the tool is (de)activated so we can pass it on.
860            tool.OnToolActivate +=
861                new EventHandler<ToolEventArgs>(AddedTool_OnToolActivate);
862
863            tool.OnToolDeactivate +=
864                new EventHandler<ToolEventArgs>(AddedTool_OnToolDeactivate);
865        }
866
867        // ------------------------------------------------------------------
868        /// <summary>
869        /// Called when an added tool is deactivated.  The event is passed on
870        /// by calling RaiseOnToolDeactivate.
871        /// </summary>
872        /// <param name="sender">object</param>
873        /// <param name="e">ToolEventArgs</param>
874        // ------------------------------------------------------------------
875        void AddedTool_OnToolDeactivate(object sender, ToolEventArgs e)
876        {
877            ITool nextActiveToolInList = null;
878            if (this.activeTool == e.Properties)
879            {
880                foreach (ITool tool in this.Tools)
881                {
882                    if (tool.IsActive)
883                    {
884                        nextActiveToolInList = tool;
885                        break;
886                    }
887                }
888                activeTool = nextActiveToolInList;
889            }
890            this.RaiseOnToolDeactivate(e);
891        }
892
893        // ------------------------------------------------------------------
894        /// <summary>
895        /// Called when an added tool is activated.  The event is passed on
896        /// by calling RaiseOnToolActivate.
897        /// </summary>
898        /// <param name="sender">object</param>
899        /// <param name="e">ToolEventArgs</param>
900        // ------------------------------------------------------------------
901        void AddedTool_OnToolActivate(object sender, ToolEventArgs e)
902        {
903            this.RaiseOnToolActivate(e);
904        }
905
906        #region Activity
907
908        // ------------------------------------------------------------------
909        /// <summary>
910        /// Adds the given activity to the controller.
911        /// </summary>
912        /// <param name="activity">The activity.</param>
913        // ------------------------------------------------------------------
914        public void AddActivity(IActivity activity)
915        {
916           
917            registeredActivity.Add(activity);
918        }
919
920        // ------------------------------------------------------------------
921        /// <summary>
922        /// Runs the given activity.
923        /// </summary>
924        /// <param name="activity">The activity.</param>
925        // ------------------------------------------------------------------
926        protected void RunActivity(IActivity activity)
927        {
928            if (activity == null) return;
929            PrepareActivity(activity);
930           
931            activity.Run();
932           
933        }
934
935        // ------------------------------------------------------------------
936        /// <summary>
937        /// Runs the given activity.
938        /// </summary>
939        /// <param name="activity">The activity.</param>
940        /// <param name="milliseconds">The milliseconds.</param>
941        // ------------------------------------------------------------------
942        protected void RunActivity(IActivity activity, int milliseconds)
943        {
944            if (activity == null) return;
945            PrepareActivity(activity);
946            activity.Run(milliseconds);
947        }
948
949        // ------------------------------------------------------------------
950        /// <summary>
951        /// Prepares the activity.
952        /// </summary>
953        /// <param name="activity">The activity.</param>
954        // ------------------------------------------------------------------
955        private void PrepareActivity(IActivity activity)
956        {
957            if (activity is IAction)
958                (activity as IAction).Model = this.Model;
959            if (activity is ILayout)
960            {
961                (activity as ILayout).Bounds = parentControl.ClientRectangle;
962                (activity as ILayout).Center = new PointF(parentControl.ClientRectangle.Width / 2, parentControl.ClientRectangle.Height / 2);
963            }
964        }
965
966        // ------------------------------------------------------------------
967        /// <summary>
968        /// Runs the activity with the name specified.  If no activity could
969        /// by found with the given name then an exception is thrown.
970        /// </summary>
971        /// <param name="activityName">string: The name of the
972        /// activity to run.</param>
973        // ------------------------------------------------------------------
974        public void RunActivity(string activityName)
975        {
976            if (!controllerEnabled)
977                return;
978
979            this.View.CurrentCursor = Cursors.WaitCursor;
980            controllerEnabled = false;
981           
982            IActivity foundActivity = FindActivity(activityName);
983            if (foundActivity != null)
984            {
985                RunActivity(foundActivity);
986            }
987
988            controllerEnabled = true;
989            this.View.CurrentCursor = Cursors.Default;
990
991            // After returning the canvas back to "normal", if the activity
992            // wasn't found throw an exception (as specified by IController).
993            if (foundActivity == null)
994            {
995                throw new Exception("Activity '" + activityName +
996                    "' could not be found.");
997            }
998        }
999
1000        // ------------------------------------------------------------------
1001        /// <summary>
1002        /// Finds the activity with the given name.
1003        /// </summary>
1004        /// <param name="name">The name.</param>
1005        /// <returns>IActivity</returns>
1006        // ------------------------------------------------------------------
1007        protected IActivity FindActivity(string name)
1008        {
1009            //using anonymous method here
1010            Predicate<IActivity> predicate = delegate(IActivity activity)
1011            {
1012                if (activity.Name.ToLower() == name.ToLower())//not case sensitive
1013                    return true;
1014                else
1015                    return false;
1016            };
1017            return this.registeredActivity.Find(predicate);
1018
1019        }
1020
1021        // ------------------------------------------------------------------
1022        /// <summary>
1023        /// Runs the given activity for the specified time span.
1024        /// </summary>
1025        /// <param name="name">The name.</param>
1026        /// <param name="milliseconds">The milliseconds.</param>
1027        // ------------------------------------------------------------------
1028        public void RunActivity(string name, int milliseconds)
1029        {
1030            if (!controllerEnabled)
1031                return;
1032
1033            IActivity foundActivity = FindActivity(name);
1034            if (foundActivity != null)
1035                RunActivity(foundActivity, milliseconds);
1036        }
1037
1038        #endregion
1039
1040        // ------------------------------------------------------------------
1041        /// <summary>
1042        /// Attaches this controller to the surface.
1043        /// </summary>
1044        /// <param name="surface">The surface.</param>
1045        // ------------------------------------------------------------------
1046        protected virtual void AttachToSurface(IDiagramControl surface)
1047        {
1048            #region Mouse events
1049            surface.MouseDown += new MouseEventHandler(OnSurfaceMouseDown);
1050            surface.MouseUp += new MouseEventHandler(OnSurfaceMouseUp);
1051            surface.MouseMove += new MouseEventHandler(OnSurfaceMouseMove);
1052            surface.MouseHover += new EventHandler(OnSurfaceMouseHover);
1053            surface.MouseWheel += new MouseEventHandler(surface_MouseWheel);
1054            #endregion
1055
1056            #region Keyboard events
1057            surface.KeyDown += new KeyEventHandler(surface_KeyDown);
1058            surface.KeyUp += new KeyEventHandler(surface_KeyUp);
1059            surface.KeyPress += new KeyPressEventHandler(surface_KeyPress);
1060            #endregion
1061
1062            #region Dragdrop events
1063            surface.DragDrop += new DragEventHandler(surface_DragDrop);
1064            surface.DragEnter += new DragEventHandler(surface_DragEnter);
1065            surface.DragLeave += new EventHandler(surface_DragLeave);
1066            surface.DragOver += new DragEventHandler(surface_DragOver);
1067            surface.GiveFeedback +=
1068                new GiveFeedbackEventHandler(surface_GiveFeedback);
1069            #endregion
1070        }
1071
1072        // ------------------------------------------------------------------
1073        /// <summary>
1074        /// Handles the MouseWheel event of the surface control.
1075        /// <remarks>In the WinForm implementation this routine is not called
1076        /// because it gives some flickering effects; the hotkeys are
1077        /// implemented in the overriden OnMouseWheel method instead.</remarks>
1078        /// </summary>
1079        /// <param name="sender">The source of the event.</param>
1080        /// <param name="e">The
1081        /// <see cref="T:System.Windows.Forms.MouseEventArgs"/> instance
1082        /// containing the event data.</param>
1083        // ------------------------------------------------------------------
1084        void surface_MouseWheel(object sender, MouseEventArgs e)
1085        {
1086            Point p = View.Origin;
1087            SizeF magnification = View.Magnification;
1088            int newValue = 0;
1089
1090
1091            if ((Control.ModifierKeys & Keys.Control) == Keys.Control)
1092            {
1093                #region Zooming
1094
1095                SizeF s = magnification;
1096
1097                // If zooming in, e.Delta is < 0 so a value of 1.1 is used to
1098                // offset the current magnification by.  One mouse wheel
1099                // position on my PC corresponds to a delta of 120 (positive
1100                // for zooming out, neg for zooming in).
1101                float alpha = e.Delta > 0 ? 1.1F : 0.9F;
1102                View.Magnification = new SizeF(
1103                    s.Width * alpha,
1104                    s.Height * alpha);
1105
1106                float w = (float)parentControl.AutoScrollPosition.X /
1107                    (float)parentControl.AutoScrollMinSize.Width;
1108
1109                float h = (float)parentControl.AutoScrollPosition.Y /
1110                    (float)parentControl.AutoScrollMinSize.Height;
1111
1112                // Resize the scrollbars proportionally to keep the actual
1113                // canvas constant.
1114                //s = new SizeF(
1115                //    parentControl.AutoScrollMinSize.Width * alpha,
1116                //    parentControl.AutoScrollMinSize.Height * alpha);
1117
1118                //parentControl.AutoScrollMinSize = Size.Round(s);
1119                RectangleF pageBounds = Model.CurrentPage.Bounds;
1120                pageBounds.Inflate(s);
1121                SizeF deltaSize = new SizeF(
1122                    pageBounds.Width - parentControl.ClientRectangle.Width,
1123                    pageBounds.Height - parentControl.ClientRectangle.Height);
1124
1125                if ((deltaSize.Width > 0) && (deltaSize.Height > 0))
1126                {
1127                    parentControl.AutoScrollMinSize = Size.Round(deltaSize);
1128                }
1129
1130                //Point v = Origin;
1131                //v.Offset(
1132                //    Convert.ToInt32((alpha - 1) * v.X),
1133                //    Convert.ToInt32((alpha - 1) * v.Y));
1134                //v.X = (int)Math.Round((double)(v.X - alpha));
1135                //v.Y = (int)Math.Round((double)(v.Y - alpha));
1136                //Origin = v;
1137
1138                #endregion
1139            }
1140            else if ( (Control.ModifierKeys & Keys.Shift) == Keys.Shift)
1141               
1142            {
1143                #region Pan horizontal
1144                newValue = p.X - Math.Sign(e.Delta) * 20;
1145                if (newValue > 0)
1146                    View.Origin = new Point(newValue, p.Y);
1147                else
1148                    View.Origin = new Point(
1149                        0,
1150                        View.Origin.Y);
1151
1152                #endregion
1153            }
1154            else
1155            {
1156                #region Default vertical scroll
1157                newValue = View.Origin.Y -
1158                    Math.Sign(e.Delta) * 20;
1159
1160                if (newValue > 0)
1161                    View.Origin = new Point(
1162                        View.Origin.X,
1163                        newValue);
1164                else
1165                    View.Origin = new Point(
1166                        View.Origin.X,
1167                        0);
1168                #endregion
1169            }
1170
1171            this.parentControl.AutoScrollPosition = View.Origin;
1172            //View.Invalidate();
1173             
1174        }       
1175     
1176        #region DragDrop event handlers
1177
1178        /// <summary>
1179        /// Handles the GiveFeedback event of the surface control.
1180        /// </summary>
1181        /// <param name="sender">The source of the event.</param>
1182        /// <param name="e">The <see cref="T:System.Windows.Forms.GiveFeedbackEventArgs"/> instance containing the event data.</param>
1183        void surface_GiveFeedback(object sender, GiveFeedbackEventArgs e)
1184        {
1185            if (!controllerEnabled)
1186            {
1187                return;
1188            }
1189
1190            foreach (IDragDropListener listener in dragdropListeners)
1191            {
1192                listener.GiveFeedback(e);
1193            }           
1194        }
1195        /// <summary>
1196        /// Handles the DragOver event of the surface control.
1197        /// </summary>
1198        /// <param name="sender">The source of the event.</param>
1199        /// <param name="e">The <see cref="T:System.Windows.Forms.DragEventArgs"/> instance containing the event data.</param>
1200        void surface_DragOver(object sender, DragEventArgs e)
1201        {
1202            if (!controllerEnabled)
1203            {
1204                return;
1205            }
1206
1207            foreach (IDragDropListener listener in dragdropListeners)
1208            {
1209                listener.OnDragOver(e);
1210            }           
1211        }
1212
1213        /// <summary>
1214        /// Handles the DragLeave event of the surface control.
1215        /// </summary>
1216        /// <param name="sender">The source of the event.</param>
1217        /// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
1218        void surface_DragLeave(object sender, EventArgs e)
1219        {
1220            if (!controllerEnabled)
1221            {
1222                return;
1223            }
1224
1225            foreach (IDragDropListener listener in dragdropListeners)
1226            {
1227                listener.OnDragLeave(e);
1228            }           
1229        }
1230
1231        /// <summary>
1232        /// Handles the DragEnter event of the surface control.
1233        /// </summary>
1234        /// <param name="sender">The source of the event.</param>
1235        /// <param name="e">The <see cref="T:System.Windows.Forms.DragEventArgs"/> instance containing the event data.</param>
1236        void surface_DragEnter(object sender, DragEventArgs e)
1237        {
1238            if (!controllerEnabled)
1239            {
1240                return;
1241            }
1242
1243            foreach (IDragDropListener listener in dragdropListeners)
1244            {
1245                listener.OnDragEnter(e);
1246            }           
1247        }
1248
1249        /// <summary>
1250        /// Handles the DragDrop event of the surface control.
1251        /// </summary>
1252        /// <param name="sender">The source of the event.</param>
1253        /// <param name="e">The <see cref="T:System.Windows.Forms.DragEventArgs"/> instance containing the event data.</param>
1254        void surface_DragDrop(object sender, DragEventArgs e)
1255        {
1256            if (!controllerEnabled)
1257            {
1258                return;
1259            }
1260
1261            foreach (IDragDropListener listener in dragdropListeners)
1262            {
1263                listener.OnDragDrop(e);
1264            }           
1265        }
1266        #endregion
1267
1268        #region Keyboard event handlers
1269        void surface_KeyPress(object sender, KeyPressEventArgs e)
1270        {
1271           
1272            foreach (IKeyboardListener listener in keyboardListeners)
1273            {
1274                listener.KeyPress(e);
1275            }
1276
1277            foreach (IDiagramEntity entity in Selection.SelectedItems)
1278            {
1279                if (entity is IKeyboardListener)
1280                {
1281                    (entity as IKeyboardListener).KeyPress(e);
1282                }
1283            }
1284        }
1285
1286        void surface_KeyUp(object sender, KeyEventArgs e)
1287        {
1288           
1289            foreach (IKeyboardListener listener in keyboardListeners)
1290            {
1291                listener.KeyUp(e);
1292            }
1293
1294            foreach (IDiagramEntity entity in Selection.SelectedItems)
1295            {
1296                if (entity is IKeyboardListener)
1297                {
1298                    (entity as IKeyboardListener).KeyUp(e);
1299                }
1300            }
1301        }
1302
1303        void surface_KeyDown(object sender, KeyEventArgs e)
1304        {
1305             foreach (IKeyboardListener listener in keyboardListeners)
1306            {
1307                listener.KeyDown(e);
1308            }
1309
1310            foreach (IDiagramEntity entity in Selection.SelectedItems)
1311            {
1312                if (entity is IKeyboardListener)
1313                {
1314                    (entity as IKeyboardListener).KeyDown(e);
1315                }
1316            }
1317        }
1318       
1319        #endregion
1320
1321        #region Mouse event handlers
1322        /// <summary>
1323        /// Implements the observer pattern for the mouse hover event,
1324        /// communicating the event to all listeners implementing the
1325        /// necessary interface.
1326        /// </summary>
1327        /// <param name="sender">The source of the event.</param>
1328        /// <param name="e">The <see cref="T:System.EventArgs"/> instance
1329        /// containing the event data.</param>
1330        protected virtual void OnSurfaceMouseHover(object sender, EventArgs e)
1331        {
1332            //if (eventsEnabled)
1333            //    RaiseOnMouseHover(e);
1334            //if (!controllerEnabled)
1335            //    return; 
1336        }
1337        /// <summary>
1338        /// Implements the observer pattern for the mouse down event,
1339        /// communicating the event to all listeners implementing the
1340        /// necessary interface.
1341        /// </summary>
1342        /// <param name="sender">The source of the event.</param>
1343        /// <param name="e">The
1344        /// <see cref="T:System.Windows.Forms.MouseEventArgs"/> instance
1345        /// containing the event data.</param>
1346        protected virtual void OnSurfaceMouseDown(
1347            object sender,
1348            MouseEventArgs e)
1349        {
1350            #region Coordinates logic
1351            // Get a point adjusted by the current scroll position and zoom factor           
1352            Point p = Point.Round(
1353                this.View.ViewToWorld(this.View.DeviceToView(e.Location)));
1354
1355            MouseEventArgs ce =
1356                new MouseEventArgs(
1357                e.Button,
1358                e.Clicks,
1359                p.X,
1360                p.Y,
1361                e.Delta);           
1362            #endregion
1363
1364            if (eventsEnabled)
1365                RaiseOnMouseDown(ce);
1366            if(!controllerEnabled)
1367                return;           
1368            this.parentControl.Focus();
1369
1370            //(parentControl as Win.DiagramControl).toolTip.Show("Yihaaa", parentControl as Win.DiagramControl, ce.Location);
1371
1372            //this selection process will work independently of the tools because
1373            //some tools need the current selection or hit entity
1374            //On the other hand, when drawing a simple rectangle for example the selection
1375            //should be off, so there is an overhead.
1376            //Selection.CollectEntitiesAt(e.Location);
1377
1378            //raise the event to give the host the opportunity to show the properties of the selected item(s)
1379            //Note that if the selection is empty the property grid will show 'nothing'.
1380            RaiseOnShowSelectionProperties(new SelectionEventArgs(Selection.SelectedItems.ToArray()));
1381
1382            foreach(IMouseListener listener in mouseListeners)
1383            {
1384                if (listener.MouseDown(ce))
1385                    break;
1386            }
1387        }
1388        /// <summary>
1389        /// Handles the MouseMove event of the surface control.
1390        /// </summary>
1391        /// <param name="sender">The source of the event.</param>
1392        /// <param name="e">The
1393        /// <see cref="T:System.Windows.Forms.MouseEventArgs"/> instance
1394        /// containing the event data.</param>
1395        protected virtual void OnSurfaceMouseMove(object sender, MouseEventArgs e)
1396        {
1397            if(!controllerEnabled)
1398                return;
1399
1400            #region Coordinates logic
1401            // Get a point adjusted by the current scroll position and zoom
1402            // factor.
1403            //Point p = new Point(e.X - parentControl.AutoScrollPosition.X, e.Y - parentControl.AutoScrollPosition.Y);
1404            Point p = Point.Round(this.View.ViewToWorld(
1405                this.View.DeviceToView(e.Location)));
1406
1407            MouseEventArgs ce = new MouseEventArgs(
1408                e.Button,
1409                e.Clicks,
1410                p.X,
1411                p.Y,
1412                e.Delta);
1413                   
1414            #endregion
1415            foreach (IMouseListener listener in mouseListeners)
1416            {
1417                listener.MouseMove(ce);
1418            }
1419        }
1420
1421        /// <summary>
1422        /// Handles the MouseUp event of the surface control.
1423        /// </summary>
1424        /// <param name="sender">The source of the event.</param>
1425        /// <param name="e">The <see cref="T:System.Windows.Forms.MouseEventArgs"/> instance containing the event data.</param>
1426        protected virtual void OnSurfaceMouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
1427        {
1428            if(!controllerEnabled)
1429                return;
1430            #region Coordinates logic
1431            // Get a point adjusted by the current scroll position and zoom factor
1432            //Point p = new Point(e.X - parentControl.AutoScrollPosition.X, e.Y - parentControl.AutoScrollPosition.Y);
1433            Point p = Point.Round(this.View.ViewToWorld(this.View.DeviceToView(e.Location)));
1434            MouseEventArgs ce = new MouseEventArgs(e.Button, e.Clicks, p.X, p.Y, e.Delta);
1435            #endregion
1436            foreach (IMouseListener listener in mouseListeners)
1437            {
1438                listener.MouseUp(ce);
1439            }
1440        }
1441
1442       
1443        #endregion
1444
1445        // ------------------------------------------------------------------
1446        /// <summary>
1447        /// Undo of the last action
1448        /// </summary>
1449        /// <remarks>Calling this on a class level will call the Undo method
1450        /// of the last ICommand in the stack.</remarks>
1451        // ------------------------------------------------------------------
1452        public void Undo()
1453        {
1454            // Reset the tracker or show the tracker after the undo operation
1455            // since the undo does not take care of it
1456            this.View.ResetTracker();
1457            mUndoManager.Undo();
1458            this.View.ShowTracker();
1459            this.View.Invalidate();
1460        }
1461
1462        // ------------------------------------------------------------------
1463        /// <summary>
1464        /// Performs the actual action or redo in case the actions was undone
1465        /// before.
1466        /// </summary>
1467        /// <remarks>Calling this on a class level will call the Redo method
1468        /// of the last ICommand in the stack.</remarks>
1469        // ------------------------------------------------------------------
1470        public void Redo()
1471        {
1472            mUndoManager.Redo();
1473            this.View.ShowTracker();
1474        }
1475
1476        // ------------------------------------------------------------------
1477        /// <summary>
1478        /// Selects all entities on the current page.  The selection is
1479        /// cleared first.
1480        /// </summary>
1481        // ------------------------------------------------------------------
1482        public void SelectAll()
1483        {
1484            this.View.ResetTracker();
1485            Selection.Clear();
1486            Selection.SelectedItems = this.Model.CurrentPage.Entities;
1487            this.View.ShowTracker();
1488            this.View.Invalidate();
1489        }
1490
1491        // ------------------------------------------------------------------
1492        /// <summary>
1493        /// Navigates to the next page.  Nothing is performed if the last page
1494        /// is currently selected and 'wrap' is false.  If 'wrap' is true,
1495        /// then the first page is selected.
1496        /// </summary>
1497        /// <param name="wrap">bool: Specifies if the collection is wrapped
1498        /// when the end is reached.</param>
1499        // ------------------------------------------------------------------
1500        public void GoForward(bool wrap)
1501        {
1502            // We can't go anywhere if there's only one page!
1503            if (Model.Pages.Count == 1)
1504            {
1505                return;
1506            }
1507
1508            int index = Model.Pages.IndexOf(Model.CurrentPage);
1509
1510            int newIndex = 0;  // The index of the page to select.
1511
1512            if (index >= (Model.Pages.Count - 1))
1513            {
1514                // The last page is currently active, so if 'wrap' is
1515                // false then just return.
1516                if (wrap == false)
1517                {
1518                    return;
1519                }
1520
1521                // Otherwise, if 'wrap' is true then we want the first page
1522                // in the collection to be active.
1523                newIndex = 0;
1524            }
1525            else
1526            {
1527                newIndex = index + 1;
1528            }
1529
1530            DeactivateAllTools();
1531            View.HideTracker();  // Just in case there are selected items.
1532            Model.SetCurrentPage(Model.Pages[newIndex]);
1533            View.Invalidate();
1534        }
1535
1536        // ------------------------------------------------------------------
1537        /// <summary>
1538        /// Navigates to the previous page.  Nothing is performed if the first
1539        /// page is currently selected and 'wrap' is false.  If 'wrap' is
1540        /// true, then the last page is selected if the current page is the
1541        /// first page.
1542        /// </summary>
1543        /// <param name="wrap">bool: Specifies if the collection is wrapped
1544        /// when the start is reached.</param>
1545        // ------------------------------------------------------------------
1546        public void GoBack(bool wrap)
1547        {
1548            // We can't go anywhere if there's only one page!
1549            if (Model.Pages.Count == 1)
1550            {
1551                return;
1552            }
1553
1554            int index = Model.Pages.IndexOf(Model.CurrentPage);
1555
1556            int newIndex = 0;  // The index of the page to select.
1557
1558            if (index == 0)
1559            {
1560                // The first page is currently active, so if 'wrap' is
1561                // false then just return.
1562                if (wrap == false)
1563                {
1564                    return;
1565                }
1566
1567                // Otherwise, since 'wrap' is true then we want the last page
1568                // in the collection to be active.
1569                newIndex = Model.Pages.Count - 1;
1570            }
1571            else
1572            {
1573                newIndex = index - 1;
1574            }
1575
1576            DeactivateAllTools();
1577            View.HideTracker();  // Just in case there are selected items.
1578            Model.SetCurrentPage(Model.Pages[newIndex]);
1579            View.Invalidate();
1580        }
1581        #endregion
1582             
1583    }
1584}
Note: See TracBrowser for help on using the repository browser.