error messages review
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / CurrencyManager.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2005 Novell, Inc.
21 //
22 // Authors:
23 //      Jackson Harper (jackson@ximian.com)
24 //
25
26 using System;
27 using System.Reflection;
28 using System.Collections;
29 using System.ComponentModel;
30
31 namespace System.Windows.Forms {
32         [DefaultMember("Item")]
33         public class CurrencyManager : BindingManagerBase {
34
35                 protected Type finalType;
36                 protected int listposition;
37
38                 private IList list;
39                 private bool binding_suspended;
40
41                 internal CurrencyManager (object data_source)
42                 {                       
43                         if (data_source is IListSource) {
44                                 list = ((IListSource) data_source).GetList ();
45                         } else if (data_source is IList) {
46                                 list = (IList) data_source;
47                         } else {
48                                 throw new Exception ("Attempted to create currency manager " +
49                                         "from invalid type: " + data_source.GetType ());
50                         }
51
52                         if (data_source as ArrayList != null) {
53                                 finalType = ((ArrayList)data_source).GetType ();
54                         } else {
55                                 if (data_source as Array != null) {
56                                         finalType = ((Array) data_source).GetType ();
57                                 } else {
58                                         finalType = null;
59                                 }
60                         }
61                 }               
62
63                 public IList List {
64                         get { return list; }
65                 }
66
67                 public override object Current {
68                         get {
69                                 return list [listposition];
70                         }
71                 }
72
73                 public override int Count {
74                         get { return list.Count; }
75                 }
76
77                 public override int Position {
78                         get {
79                                 return listposition;
80                         } 
81                         set {
82                                 if (value < 0)
83                                         value = 0;
84                                 if (value == list.Count)
85                                         value = list.Count - 1;
86                                 if (listposition == value)
87                                         return;
88                                 listposition = value;
89                                 OnCurrentChanged (EventArgs.Empty);
90                                 OnPositionChanged (EventArgs.Empty);
91                         }
92                 }
93                 
94                 internal string ListName {
95                         get {
96                                 ITypedList typed = list as ITypedList;
97                                 
98                                 if (typed == null) {
99                                         return finalType.Name;
100                                 } else {
101                                         return typed.GetListName (null);
102                                 }
103                         }               
104                 }
105
106                 public override PropertyDescriptorCollection GetItemProperties ()
107                 {
108                         ITypedList typed = list as ITypedList;
109
110                         if (list is Array) {
111                                 Type element = list.GetType ().GetElementType ();
112                                 return TypeDescriptor.GetProperties (element);
113                         }
114
115                         if (typed != null) {
116                                 return typed.GetItemProperties (null);
117                         }
118
119                         PropertyInfo [] props = finalType.GetProperties ();
120                         for (int i = 0; i < props.Length; i++) {
121                                 if (props [i].Name == "Item") {
122                                         Type t = props [i].PropertyType;
123                                         if (t == typeof (object))
124                                                 continue;
125                                         return GetBrowsableProperties (t);
126                                 }
127                         }
128
129                         if (list.Count > 0) {
130                                 return GetBrowsableProperties (list [0].GetType ());
131                         }
132                         
133                         return new PropertyDescriptorCollection (null);
134                 }
135
136                 public override void RemoveAt (int index)
137                 {
138                         list.RemoveAt (index);
139                 }
140
141                 public override void SuspendBinding ()
142                 {
143                         binding_suspended = true;
144                 }
145                 
146                 public override void ResumeBinding ()
147                 {
148                         binding_suspended = false;
149                 }
150
151                 internal override bool IsSuspended {
152                         get { return binding_suspended; }
153                 }
154                 
155                 internal bool CanAddRows {
156                         get {
157                                 if (list as IBindingList == null) {
158                                         return false;
159                                 }
160                                 
161                                 return true;
162                         }
163                 }
164
165                 public override void AddNew ()
166                 {
167                         if (list as IBindingList == null)
168                                 throw new NotSupportedException ();
169                                 
170                         (list as IBindingList).AddNew ();
171                 }
172
173                 public override void CancelCurrentEdit ()
174                 {
175                         IEditableObject editable = Current as IEditableObject;
176
177                         if (editable == null)
178                                 return;
179                         editable.CancelEdit ();
180                         OnItemChanged (new ItemChangedEventArgs (Position));
181                 }
182                 
183                 public override void EndCurrentEdit ()
184                 {
185                         IEditableObject editable = Current as IEditableObject;
186
187                         if (editable == null)
188                                 return;
189                         editable.EndEdit ();
190                 }
191
192                 protected internal override void OnCurrentChanged (EventArgs e)
193                 {
194                         PullData ();
195
196                         if (onCurrentChangedHandler != null) {
197                                 onCurrentChangedHandler (this, e);
198                         }
199                 }
200
201                 protected virtual void OnItemChanged (ItemChangedEventArgs e)
202                 {
203                         PushData ();
204
205                         if (ItemChanged != null)
206                                 ItemChanged (this, e);
207                 }
208
209                 protected virtual void OnPositionChanged (EventArgs e)
210                 {
211                         if (onPositionChangedHandler == null)
212                                 return;
213                         onPositionChangedHandler (this, e);
214                 }
215
216                 protected internal override string GetListName (ArrayList accessors)
217                 {
218                         if (list is ITypedList) {
219                                 PropertyDescriptor [] pds;
220                                 pds = new PropertyDescriptor [accessors.Count];
221                                 accessors.CopyTo (pds, 0);
222                                 return ((ITypedList) list).GetListName (pds);
223                         }
224                         return String.Empty;
225                 }
226
227                 [MonoTODO ("Not totally sure how this works, its doesn't seemt to do a pull/push like i originally assumed")]
228                 protected override void UpdateIsBinding ()
229                 {
230                         UpdateItem ();
231
232                         foreach (Binding binding in Bindings)
233                                 binding.UpdateIsBinding ();
234                 }
235
236                 private void UpdateItem ()
237                 {
238                         // Probably should be validating or something here
239                         EndCurrentEdit ();
240                 }
241                 
242                 internal object GetItem (int index)
243                 {
244                         return list [index];
245                 }               
246                 
247                 private PropertyDescriptorCollection GetBrowsableProperties (Type t)
248                 {
249                         Attribute [] att = new System.Attribute [1];
250                         att [0] = new BrowsableAttribute (true);
251                         return TypeDescriptor.GetProperties (t, att);
252                 }
253
254                 public event ItemChangedEventHandler ItemChanged;
255         }
256 }
257