Move Mono.CompilerServices.SymbolWriter to build after 2.1 raw mscorlib
[mono.git] / mcs / class / System.Design / System.ComponentModel.Design / SelectionService.cs
1 //
2 // System.ComponentModel.Design.SelectionService
3 //
4 // Authors:
5 //        Ivan N. Zlatev (contact i-nZ.net)
6 //
7 // (C) 2006-2007 Ivan N. Zlatev
8
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29 using System;
30 using System.Collections;
31 using System.ComponentModel;
32 using System.ComponentModel.Design;
33 using System.Windows.Forms;
34
35 namespace System.ComponentModel.Design
36 {
37         
38         internal class SelectionService : ISelectionService
39         {
40                 
41                 private IServiceProvider _serviceProvider;
42                 private ArrayList _selection;
43                 private IComponent _primarySelection;
44                 
45                 public SelectionService (IServiceProvider provider)
46                 {
47                         _serviceProvider = provider;
48                         _selection = new ArrayList();
49
50                         IComponentChangeService changeService = provider.GetService (typeof (IComponentChangeService)) as IComponentChangeService;
51                         if (changeService != null)
52                                 changeService.ComponentRemoving += new ComponentEventHandler (OnComponentRemoving);
53                 }
54                 
55                 private void OnComponentRemoving (object sender, ComponentEventArgs args)
56                 {
57                         if (this.GetComponentSelected (args.Component))
58 #if NET_2_0
59                                 this.SetSelectedComponents (new IComponent[] { args.Component }, SelectionTypes.Remove);
60 #else
61                                 this.SetSelectedComponents (new IComponent[] { this.RootComponent }, SelectionTypes.Click);
62 #endif
63                 }
64                 
65                 public event EventHandler SelectionChanging;
66                 public event EventHandler SelectionChanged;
67                 
68                 public ICollection GetSelectedComponents() 
69                 {
70                         if (_selection != null)
71                                 return _selection.ToArray ();
72
73                         return new object[0];
74                 }
75
76                 protected virtual void OnSelectionChanging ()
77                 {
78                         if (SelectionChanging != null)
79                                 SelectionChanging (this, EventArgs.Empty);
80                 }
81                 
82                 protected virtual void OnSelectionChanged ()
83                 {
84                         if (SelectionChanged != null)
85                                 SelectionChanged (this, EventArgs.Empty);
86                 }
87
88                 public object PrimarySelection {
89                         get { return _primarySelection; }
90                 }
91                 
92                 public int SelectionCount {
93                         get {
94                                 if (_selection != null)
95                                         return _selection.Count;
96
97                                 return 0;
98                         }
99                 }
100
101
102                 private IComponent RootComponent {
103                         get {
104                                 if (_serviceProvider != null) {
105                                         IDesignerHost designerHost = _serviceProvider.GetService (typeof (IDesignerHost)) as IDesignerHost;
106                                         if (designerHost != null)
107                                                 return designerHost.RootComponent;
108                                 }
109                                 return null;
110                         }
111                 }
112                 
113                 public bool GetComponentSelected (object component) 
114                 {
115                         if (_selection != null)
116                                 return _selection.Contains (component);
117
118                         return false;
119                 }
120
121                 public void SetSelectedComponents (ICollection components) 
122                 {
123 #if NET_2_0
124                         SetSelectedComponents (components, SelectionTypes.Auto);
125 #else                   
126                         SetSelectedComponents (components, SelectionTypes.Normal);
127 #endif
128                 }
129
130                 // If the array is a null reference or does not contain any components,
131                 // SetSelectedComponents selects the top-level component in the designer.
132                 //
133                 public void SetSelectedComponents (ICollection components, SelectionTypes selectionType)
134                 {
135                         bool primary, add, remove, replace, toggle, auto;
136                         primary = add = remove = replace = toggle = auto = false;
137                         
138                         OnSelectionChanging ();
139
140                         if (_selection == null)
141                                 throw new InvalidOperationException("_selection == null");
142                         
143                         if (components == null || components.Count == 0) {
144                                 components = new ArrayList ();
145                                 ((ArrayList) components).Add (this.RootComponent);
146                                 selectionType = SelectionTypes.Replace;
147                         }
148                         
149                         if (!Enum.IsDefined (typeof (SelectionTypes), selectionType)) {
150 #if NET_2_0     
151                                 selectionType = SelectionTypes.Auto;
152 #else
153                                 selectionType = SelectionTypes.Normal;                                  
154 #endif
155                         }
156
157 #if NET_2_0             
158                         auto = ((selectionType & SelectionTypes.Auto) == SelectionTypes.Auto);
159 #else
160                         if ((selectionType & SelectionTypes.Normal) == SelectionTypes.Normal ||
161                                 (selectionType & SelectionTypes.MouseDown) == SelectionTypes.MouseDown ||
162                                 (selectionType & SelectionTypes.MouseUp) == SelectionTypes.MouseUp) {
163
164                                         auto = true;
165                         }               
166 #endif                  
167                         
168                         
169                         if (auto) {
170                                 if ((((Control.ModifierKeys & Keys.Control) == Keys.Control) || ((Control.ModifierKeys & Keys.Shift) == Keys.Shift))) {
171                                         toggle = true;
172                                 }
173                                 else if (components.Count == 1) {
174                                         object component = null;
175                                         foreach (object c in components) {
176                                                 component = c;
177                                                 break;
178                                         }
179
180                                         if (this.GetComponentSelected (component))
181                                                 primary = true;
182                                         else
183                                                 replace = true;
184                                 }
185                                 else {
186                                         replace = true;
187                                 }
188                         }
189                         else {
190 #if NET_2_0                        
191                                 primary = ((selectionType & SelectionTypes.Primary) == SelectionTypes.Primary);
192                                 add = ((selectionType & SelectionTypes.Add) == SelectionTypes.Add);
193                                 remove = ((selectionType & SelectionTypes.Remove) == SelectionTypes.Remove);
194                                 toggle = ((selectionType & SelectionTypes.Toggle) == SelectionTypes.Toggle);
195 #else
196                                 primary = ((selectionType & SelectionTypes.Click) == SelectionTypes.Click);
197 #endif                          
198                                 replace = ((selectionType & SelectionTypes.Replace) == SelectionTypes.Replace);
199                                 
200                         }
201
202                         
203                         if (replace) {
204                                 _selection.Clear ();
205                                 add = true;
206                         }
207                                                 
208                         if (add) {
209                                 foreach (object component in components) {
210                                         if (component is IComponent && !_selection.Contains (component)) {
211                                                 _selection.Add (component);
212                                                 _primarySelection = (IComponent) component;
213                                         }
214                                 }
215                         }
216
217                         if (remove) {
218                                 bool rootRemoved = false;
219                                 foreach (object component in components) {
220                                         if (component is IComponent && _selection.Contains (component))
221                                                 _selection.Remove (component);
222                                         if (component == this.RootComponent)
223                                                 rootRemoved = true;
224                                 }
225                                 if (_selection.Count == 0) {
226                                         if (rootRemoved) {
227                                                 _primarySelection = null;
228                                         } else {
229                                                 _primarySelection = this.RootComponent;
230                                                 _selection.Add (this.RootComponent);
231                                         }
232                                 }
233                         }
234
235                         if (toggle) {
236                                 foreach (object component in components) {
237                                         if (component is IComponent) {
238                                                 if (_selection.Contains (component)) {
239                                                         _selection.Remove (component);
240                                                         if (component == _primarySelection)
241                                                                 _primarySelection = this.RootComponent;
242                                                 }
243                                                 else {
244                                                         _selection.Add (component);
245                                                         _primarySelection = (IComponent) component;
246                                                 }
247                                         }
248                                 }
249                         }
250                                 
251                         if (primary) {
252                                 object primarySelection = null;
253
254                                 foreach (object component in components) {
255                                         primarySelection = component;
256                                         break;
257                                 }
258
259                                 if (!this.GetComponentSelected (primarySelection))
260                                         _selection.Add (primarySelection);
261
262                                 _primarySelection = (IComponent) primarySelection;
263                         }                               
264                                                 
265                         OnSelectionChanged ();
266                 }
267         }
268 }