2008-06-18 Ivan N. Zlatev <contact@i-nz.net>
[mono.git] / mcs / class / System.Design / System.ComponentModel.Design / MenuCommandService.cs
1 //
2 // System.ComponentModel.Design.MenuCommandService.cs
3 //
4 // Author:
5 //      Atsushi Enomoto  <atsushi@ximian.com>
6 //      Ivan N. Zlatev   <contact@i-nz.net>
7 //
8 // Copyright (C) 2007 Novell, Inc
9 // Copyright (C) Ivan N. Zlatev
10 //
11
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 #if NET_2_0
34
35 using System;
36 using System.Collections;
37 using System.Collections.Generic;
38 using System.ComponentModel.Design;
39 using System.ComponentModel;
40
41 namespace System.ComponentModel.Design
42 {
43         public class MenuCommandService : IMenuCommandService, IDisposable
44         {
45                 private IServiceProvider _serviceProvider;
46                 private DesignerVerbCollection _globalVerbs;
47                 private DesignerVerbCollection _verbs;
48                 private Dictionary <CommandID, MenuCommand> _commands;
49
50                 public MenuCommandService (IServiceProvider serviceProvider)
51                 {
52                         if (serviceProvider == null)
53                                 throw new ArgumentNullException ("serviceProvider");
54                         _serviceProvider = serviceProvider;
55                         ISelectionService selectionSvc = _serviceProvider.GetService (typeof (ISelectionService)) as ISelectionService;
56                         if (selectionSvc != null)
57                                 selectionSvc.SelectionChanged += OnSelectionChanged;
58                 }
59
60                 private void OnSelectionChanged (object sender, EventArgs arg)
61                 {
62                         this.OnCommandsChanged (new MenuCommandsChangedEventArgs (MenuCommandsChangedType.CommandChanged, null));
63                         // The commands will be updated whenever they are requested/modified.
64                 }
65
66                 public event MenuCommandsChangedEventHandler MenuCommandsChanged;
67
68                 public virtual DesignerVerbCollection Verbs {
69                         get {
70                                 this.EnsureVerbs ();
71                                 return _verbs;
72                         }
73                 }
74
75                 public virtual void AddCommand (MenuCommand command)
76                 {
77                         if (command == null)
78                                 throw new ArgumentNullException ("command");
79
80                         if (_commands == null)
81                                 _commands = new Dictionary <CommandID, MenuCommand> ();
82                         _commands.Add (command.CommandID, command);
83                         this.OnCommandsChanged (new MenuCommandsChangedEventArgs (MenuCommandsChangedType.CommandAdded, command));
84                 }
85
86                 public virtual void AddVerb (DesignerVerb verb)
87                 {
88                         if (verb == null)
89                                 throw new ArgumentNullException ("verb");
90                         this.EnsureVerbs ();
91                         if (!_verbs.Contains (verb)) {
92                                 if (_globalVerbs == null)
93                                         _globalVerbs = new DesignerVerbCollection ();
94                                 _globalVerbs.Add (verb);
95                         }
96                         this.OnCommandsChanged (new MenuCommandsChangedEventArgs (MenuCommandsChangedType.CommandAdded, verb));
97                 }
98
99                 public void Dispose ()
100                 {
101                         Dispose (true);
102                 }
103
104                 protected virtual void Dispose (bool disposing)
105                 {
106                         if (disposing) {
107                                 if (_globalVerbs != null) {
108                                         _globalVerbs.Clear ();
109                                         _globalVerbs = null;
110                                 }
111                                 if (_verbs != null) {
112                                         _verbs.Clear ();
113                                         _verbs = null;
114                                 }
115                                 if (_commands != null) {
116                                         _commands.Clear ();
117                                         _commands = null;
118                                 }
119                                 if (_serviceProvider != null) {
120                                         ISelectionService selectionSvc = _serviceProvider.GetService (typeof (ISelectionService)) as ISelectionService;
121                                         if (selectionSvc != null)
122                                                 selectionSvc.SelectionChanged -= OnSelectionChanged;
123                                         _serviceProvider = null;
124                                 }
125                         }
126                 }
127
128                 protected void EnsureVerbs ()
129                 {
130                         DesignerVerbCollection selectionVerbs = null;
131
132                         ISelectionService selectionSvc = this.GetService (typeof (ISelectionService)) as ISelectionService;
133                         IDesignerHost host = this.GetService (typeof (IDesignerHost)) as IDesignerHost;
134                         if (selectionSvc != null && host != null && selectionSvc.SelectionCount == 1) {
135                                 IComponent primarySelection = selectionSvc.PrimarySelection as IComponent;
136                                 if (primarySelection != null) {
137                                         IDesigner designer = host.GetDesigner (primarySelection);
138                                         if (designer != null)
139                                                 selectionVerbs = designer.Verbs;
140                                 }
141                         }
142
143                         // Designer provided verbs have the higher precedence than the global
144                         //
145                         Dictionary <string, DesignerVerb> allVerbs = new Dictionary <string, DesignerVerb> ();
146                         if (_globalVerbs != null) {
147                                 foreach (DesignerVerb verb in _globalVerbs)
148                                         allVerbs[verb.Text] = verb;
149                         }
150                         if (selectionVerbs != null) {
151                                 foreach (DesignerVerb verb in selectionVerbs)
152                                         allVerbs[verb.Text] = verb;
153                         }
154
155                         if (_verbs == null)
156                                 _verbs = new DesignerVerbCollection ();
157                         else
158                                 _verbs.Clear ();
159
160                         foreach (DesignerVerb verb in allVerbs.Values)
161                                 _verbs.Add (verb);
162                 }
163
164                 protected MenuCommand FindCommand (Guid guid, int id)
165                 {
166                         return this.FindCommand (new CommandID (guid, id));
167                 }
168
169                 public MenuCommand FindCommand (CommandID commandID)
170                 {
171                         if (commandID == null)
172                                 throw new ArgumentNullException ("commandID");
173
174                         MenuCommand command = null;
175                         if (_commands != null)
176                                 _commands.TryGetValue (commandID, out command);
177                         if (command == null) {
178                                 this.EnsureVerbs ();
179                                 foreach (DesignerVerb verb in _verbs) {
180                                         if (verb.CommandID.Equals (commandID)) {
181                                                 command = (MenuCommand) verb;
182                                                 break;
183                                         }
184                                 }
185                         }
186                         return command;
187                 }
188
189                 protected ICollection GetCommandList (Guid guid)
190                 {
191                         List<MenuCommand> list = new List<MenuCommand> ();
192                         if (_commands != null) {
193                                 foreach (MenuCommand command in _commands.Values) {
194                                         if (command.CommandID.Guid == guid)
195                                                 list.Add (command);
196                                 }
197                         }
198                         return list;
199                 }
200
201                 public virtual bool GlobalInvoke (CommandID commandID)
202                 {
203                         if (commandID == null)
204                                 throw new ArgumentNullException ("commandID");
205
206                         MenuCommand command = this.FindCommand (commandID);
207                         if (command != null) {
208                                 command.Invoke ();
209                                 return true;
210                         }
211                         return false;
212                 }
213
214                 public virtual bool GlobalInvoke (CommandID commandID, object arg)
215                 {
216                         if (commandID == null)
217                                 throw new ArgumentNullException ("commandID");
218
219                         MenuCommand command = this.FindCommand (commandID);
220                         if (command != null) {
221                                 command.Invoke (arg);
222                                 return true;
223                         }
224                         return false;
225                 }
226
227                 protected virtual void OnCommandsChanged (MenuCommandsChangedEventArgs e)
228                 {
229                         if (MenuCommandsChanged != null)
230                                 MenuCommandsChanged (this, e);
231                 }
232
233                 public virtual void RemoveCommand (MenuCommand command)
234                 {
235                         if (command == null)
236                                 throw new ArgumentNullException ("command");
237                         if (_commands != null)
238                                 _commands.Remove (command.CommandID);
239
240                         this.OnCommandsChanged (new MenuCommandsChangedEventArgs (MenuCommandsChangedType.CommandRemoved, null));
241                 }
242
243                 public virtual void RemoveVerb (DesignerVerb verb)
244                 {
245                         if (verb == null)
246                                 throw new ArgumentNullException ("verb");
247
248                         if (_globalVerbs.Contains (verb))
249                                 _globalVerbs.Remove (verb);
250
251                         this.OnCommandsChanged (new MenuCommandsChangedEventArgs (MenuCommandsChangedType.CommandRemoved, verb));
252                 }
253
254                 public virtual void ShowContextMenu (CommandID menuID, int x, int y)
255                 {
256                 }
257
258                 protected object GetService (Type serviceType)
259                 {
260                         if (_serviceProvider != null)
261                                 return _serviceProvider.GetService (serviceType);
262                         return null;
263                 }
264         }
265 }
266 #endif