Merge pull request #1225 from strawd/bug22307
[mono.git] / mcs / class / System.Windows.Forms / System.Windows.Forms / ListViewGroupCollection.cs
1 //
2 //  ListViewGroupCollection.cs
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 // 
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 // 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 //
23 // Copyright (c) 2006 Daniel Nauck
24 //
25 // Author:
26 //      Daniel Nauck    (dna(at)mono-project(dot)de)
27 //      Carlos Alberto Cortez <calberto.cortez@gmail.com>
28
29 using System;
30 using System.Text;
31 using System.Collections;
32 using System.Collections.Generic;
33 using System.ComponentModel;
34
35 namespace System.Windows.Forms
36 {
37         [ListBindable(false)]
38         public class ListViewGroupCollection : IList, ICollection, IEnumerable
39         {
40                 private List<ListViewGroup> list = null;
41                 private ListView list_view_owner = null;
42                 private ListViewGroup default_group;
43
44                 ListViewGroupCollection()
45                 {
46                         list = new List<ListViewGroup> ();
47
48                         default_group = new ListViewGroup ("Default Group");
49                         default_group.IsDefault = true;
50                 }
51
52                 internal ListViewGroupCollection(ListView listViewOwner) : this()
53                 {
54                         list_view_owner = listViewOwner;
55                         default_group.ListViewOwner = listViewOwner;
56                 }
57
58                 internal ListView ListViewOwner {
59                         get { return list_view_owner; }
60                         set { list_view_owner = value; }
61                 }
62
63                 #region IEnumerable Members
64
65                 public IEnumerator GetEnumerator()
66                 {
67                         return list.GetEnumerator();
68                 }
69
70                 #endregion
71
72                 #region ICollection Members
73
74                 public void CopyTo(Array array, int index)
75                 {
76                         ((ICollection) list).CopyTo(array, index);
77                 }
78
79                 public int Count {
80                         get { return list.Count; }
81                 }
82
83                 bool ICollection.IsSynchronized {
84                         get { return true; }
85                 }
86
87                 object ICollection.SyncRoot {
88                         get { return this; }
89                 }
90
91                 #endregion
92
93                 #region IList Members
94
95                 int IList.Add(object value)
96                 {
97                         if (!(value is ListViewGroup))
98                                 throw new ArgumentException("value");
99
100                         return Add((ListViewGroup)value);               
101                 }
102
103                 public int Add(ListViewGroup group)
104                 {
105                         if (Contains(group))
106                                 return -1;
107
108                         AddGroup (group);
109
110                         if (this.list_view_owner != null)
111                                 list_view_owner.Redraw(true);
112
113                         return list.Count - 1;
114                 }
115
116                 public ListViewGroup Add(string key, string headerText)
117                 {
118                         ListViewGroup newGroup = new ListViewGroup(key, headerText);
119                         Add(newGroup);
120
121                         return newGroup;
122                 }
123
124                 public void Clear()
125                 {
126                         foreach (ListViewGroup group in list)
127                                 group.ListViewOwner = null;
128
129                         list.Clear ();
130
131                         if(list_view_owner != null)
132                                 list_view_owner.Redraw(true);
133                 }
134
135                 bool IList.Contains(object value)
136                 {
137                         if (value is ListViewGroup)
138                                 return Contains((ListViewGroup)value);
139                         else
140                                 return false;
141                 }
142
143                 public bool Contains(ListViewGroup value)
144                 {
145                         return list.Contains(value);
146                 }
147
148                 int IList.IndexOf(object value)
149                 {
150                         if (value is ListViewGroup)
151                                 return IndexOf((ListViewGroup)value);
152                         else
153                                 return -1;
154                 }
155
156                 public int IndexOf(ListViewGroup value)
157                 {
158                         return list.IndexOf(value);
159                 }
160
161                 void IList.Insert(int index, object value)
162                 {
163                         if (value is ListViewGroup)
164                                 Insert(index, (ListViewGroup)value);
165                 }
166
167                 public void Insert(int index, ListViewGroup group)
168                 {
169                         if (Contains(group))
170                                 return;
171
172                         CheckListViewItemsInGroup(group);
173                         group.ListViewOwner = list_view_owner;
174                         list.Insert(index, group);
175
176                         if(list_view_owner != null)
177                                 list_view_owner.Redraw(true);
178                 }
179
180                 bool IList.IsFixedSize {
181                         get { return false; }
182                 }
183
184                 bool IList.IsReadOnly {
185                         get { return false; }
186                 }
187
188                 void IList.Remove(object value)
189                 {
190                         Remove((ListViewGroup)value);
191                 }
192
193                 public void Remove (ListViewGroup group)
194                 {
195                         int idx = list.IndexOf (group);
196                         if (idx != -1)
197                                 RemoveAt (idx);
198                 }
199
200                 public void RemoveAt (int index)
201                 {
202                         if (list.Count <= index || index < 0)
203                                 return;
204
205                         ListViewGroup group = list [index];
206                         group.ListViewOwner = null;
207
208                         list.RemoveAt (index);
209                         if (list_view_owner != null)
210                                 list_view_owner.Redraw (true);
211                 }
212
213                 object IList.this[int index] {
214                         get { return this[index]; }
215                         set {
216                                 if (value is ListViewGroup)
217                                         this[index] = (ListViewGroup)value;
218                         }
219                 }
220
221                 public ListViewGroup this[int index] {
222                         get {
223                                 if (list.Count <= index || index < 0)
224                                         throw new ArgumentOutOfRangeException("index");
225
226                                 return list [index];
227                         }
228                         set {
229                                 if (list.Count <= index || index < 0)
230                                         throw new ArgumentOutOfRangeException("index");
231
232                                 if (Contains (value))
233                                         return;
234
235                                 if (value != null)
236                                         CheckListViewItemsInGroup (value);
237
238                                 list [index] = value;
239                                         
240                                 if (list_view_owner != null)
241                                         list_view_owner.Redraw(true);
242                         }
243                 }
244
245                 public ListViewGroup this [string key] {
246                         get {
247                                 int idx = IndexOfKey (key);
248                                 if (idx != -1)
249                                         return this [idx];
250
251                                 return null;
252                         }
253                         set {
254                                 int idx = IndexOfKey (key);
255                                 if (idx == -1)
256                                         return;
257
258                                 this [idx] = value;
259                         }
260                 }
261
262                 int IndexOfKey (string key)
263                 {
264                         for (int i = 0; i < list.Count; i++)
265                                 if (list [i].Name == key)
266                                         return i;
267
268                         return -1;
269                 }
270
271                 #endregion
272
273                 public void AddRange(ListViewGroup[] groups)
274                 {
275                         foreach (ListViewGroup group in groups)
276                                 AddGroup (group);
277
278                         if (list_view_owner != null)
279                                 list_view_owner.Redraw (true);
280                 }
281
282                 public void AddRange(ListViewGroupCollection groups)
283                 {
284                         foreach (ListViewGroup group in groups)
285                                 AddGroup (group);
286
287                         if (list_view_owner != null)
288                                 list_view_owner.Redraw (true);
289                 }
290
291                 internal ListViewGroup GetInternalGroup (int index) 
292                 {
293                         if (index == 0)
294                                 return default_group;
295
296                         return list [index - 1];
297                 }
298
299                 internal int InternalCount {
300                         get {
301                                 return list.Count + 1;
302                         }
303                 }
304
305                 internal ListViewGroup DefaultGroup {
306                         get {
307                                 return default_group;
308                         }
309                 }
310
311                 void AddGroup (ListViewGroup group)
312                 {
313                         if (Contains (group))
314                                 return;
315
316                         CheckListViewItemsInGroup (group);
317                         group.ListViewOwner = list_view_owner;
318                         list.Add (group);
319                 }
320
321                 private void CheckListViewItemsInGroup(ListViewGroup value)
322                 {
323                         //check for correct ListView
324                         foreach (ListViewItem item in value.Items)
325                         {
326                                 if (item.ListView != null && item.ListView != this.list_view_owner)
327                                         throw new ArgumentException("ListViewItem belongs to a ListView control other than the one that owns this ListViewGroupCollection.",
328                                                 "ListViewGroup");
329                         }
330                 }
331         }
332 }