5d757d2c3500c2d5c4d0153d4d32928aebb3cd5a
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ListViewGroup.cs
1 //
2 //  ListViewGroup.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
28 using System;
29 using System.Text;
30 using System.Runtime.Serialization;
31 using System.ComponentModel;
32 using System.Drawing;
33
34 namespace System.Windows.Forms
35 {
36         [SerializableAttribute]
37         [ToolboxItem(false)]
38         [DesignTimeVisible(false)]
39         [DefaultProperty("Header")]
40         [TypeConverter (typeof (ListViewGroupConverter))]
41         public sealed class ListViewGroup : ISerializable
42         {
43                 internal string header = string.Empty;
44                 private string name = null;
45                 private HorizontalAlignment header_alignment = HorizontalAlignment.Left;
46                 private ListView list_view_owner = null;
47                 private ListView.ListViewItemCollection items = null;
48                 private object tag = null;
49                 private Rectangle header_bounds = Rectangle.Empty;
50                 internal int starting_row;      // At which row the group starts
51                 internal int starting_item;     // The first display item in group
52                 internal int rows;
53                 internal int current_item;      // Current item when doing layout
54                 internal Point items_area_location;
55                 bool is_default_group;
56                 int item_count; // Used by default group to store item count
57
58                 #region ListViewGroup constructors
59
60                 public ListViewGroup () : this ("ListViewGroup", HorizontalAlignment.Left)
61                 {
62                 }
63
64                 public ListViewGroup (string header) : this (header, HorizontalAlignment.Left)
65                 {
66                 }
67
68                 public ListViewGroup (string key, string headerText) : this (headerText, HorizontalAlignment.Left)
69                 {
70                         name = key;
71                 }
72
73                 public ListViewGroup (string header, HorizontalAlignment headerAlignment)
74                 {
75                         this.header = header;
76                         header_alignment = headerAlignment;
77                         items = new ListView.ListViewItemCollection (list_view_owner, this);
78                 }
79
80                 private ListViewGroup(SerializationInfo info, StreamingContext context)
81                 {
82                         header = info.GetString("Header");
83                         name = info.GetString("Name");
84                         header_alignment = (HorizontalAlignment)info.GetInt32("HeaderAlignment");
85                         tag = info.GetValue("Tag", typeof(object));
86
87                         int count = info.GetInt32("ListViewItemCount");
88                         if (count > 0) {
89                                 if(items == null)
90                                 items = new ListView.ListViewItemCollection(list_view_owner);
91
92                                 for (int i = 0; i < count; i++)
93                                 {
94                                         items.Add((ListViewItem)info.GetValue(string.Format("ListViewItem_{0}", i), typeof(ListViewItem)));
95                                 }
96                         }
97                 }
98
99                 #endregion
100
101                 #region ListViewGroup properties
102
103                 public string Header {
104                         get { return header; }
105                         set {
106                                 if (!header.Equals(value)) {
107                                         header = value;
108
109                                         if (list_view_owner != null)
110                                                 list_view_owner.Redraw(true);
111                                 }
112                         }
113                 }
114
115                 [DefaultValue (HorizontalAlignment.Left)]
116                 public HorizontalAlignment HeaderAlignment {
117                         get { return header_alignment; }
118                         set {
119                                 if (!header_alignment.Equals(value)) {
120                                         if (value != HorizontalAlignment.Left && value != HorizontalAlignment.Right &&
121                                                 value != HorizontalAlignment.Center)
122                                                 throw new InvalidEnumArgumentException("HeaderAlignment", (int)value, typeof(HorizontalAlignment));
123
124                                         header_alignment = value;
125
126                                         if (list_view_owner != null)
127                                                 list_view_owner.Redraw(true);
128                                 }
129                         }
130                 }
131
132                 [Browsable(false)]
133                 public ListView.ListViewItemCollection Items {
134                         get {
135                                 return items;
136                         }
137                 }
138
139                 [DesignerSerializationVisibility(0)]
140                 [Browsable(false)]
141                 public ListView ListView {
142                         get { return list_view_owner; }
143                 }
144
145                 internal ListView ListViewOwner {
146                         get { return list_view_owner; }
147                         set { 
148                                 list_view_owner = value; 
149                                 if (!is_default_group)
150                                         items.Owner = value;
151                         }
152                 }
153
154                 internal Rectangle HeaderBounds {
155                         get {
156                                 Rectangle retval = header_bounds;
157                                 retval.X -= list_view_owner.h_marker;
158                                 retval.Y -= list_view_owner.v_marker;
159                                 return retval;
160                         }
161                         set { 
162                                 if (list_view_owner != null)
163                                         list_view_owner.item_control.Invalidate (HeaderBounds);
164
165                                 header_bounds = value; 
166
167                                 if (list_view_owner != null)
168                                         list_view_owner.item_control.Invalidate (HeaderBounds);
169
170                         }
171                 }
172
173                 internal bool IsDefault {
174                         get {
175                                 return is_default_group;
176                         }
177                         set {
178                                 is_default_group = value;
179                         }
180                 }
181
182                 internal int ItemCount {
183                         get {
184                                 return is_default_group ? item_count : items.Count;
185                         }
186                         set {
187                                 if (!is_default_group)
188                                         throw new InvalidOperationException ("ItemCount cannot be set for non-default groups.");
189
190                                 item_count = value;
191                         }
192                 }
193
194                 internal int GetActualItemCount ()
195                 {
196                         if (is_default_group)
197                                 return item_count;
198
199                         int count = 0;
200                         for (int i = 0; i < items.Count; i++)
201                                 if (items [i].ListView != null) // Ignore.
202                                         count++;
203
204                         return count;
205                 }
206
207                 [Browsable(true)]
208                 [DefaultValue("")]
209                 public string Name {
210                         get { return name; }
211                         set { name = value; }
212                 }
213
214                 [TypeConverter(typeof(StringConverter))]
215                 [DefaultValue(null)]
216                 [Localizable(false)]
217                 [Bindable(true)]
218                 public Object Tag {
219                         get { return tag; }
220                         set { tag = value; }
221                 }
222
223                 #endregion
224
225                 public override string ToString()
226                 {
227                         return header;
228                 }
229
230                 #region ISerializable Members
231
232                 void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
233                 {
234                         info.AddValue("Header", header);
235                         info.AddValue("Name", name);
236                         info.AddValue("HeaderAlignment", header_alignment);
237                         info.AddValue("Tag", tag);
238
239                         info.AddValue("ListViewItemCount", items.Count);
240
241                         int i = 0;
242                         foreach (ListViewItem item in items)
243                         {
244                                 info.AddValue(string.Format("ListViewItem_{0}", i), item);
245                                 i++;
246                         }
247                 }
248
249                 #endregion
250         }
251
252         internal class ListViewGroupConverter : TypeConverter
253         {
254                 public override bool GetStandardValuesSupported (ITypeDescriptorContext context)
255                 {
256                         return true;
257                 }
258
259                 // Weird
260                 public override StandardValuesCollection GetStandardValues (ITypeDescriptorContext context)
261                 {
262                         return new StandardValuesCollection (new object [] {});
263                 }
264         }
265 }