Page.Validate() is called when CausesValidation=true
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / Unit.cs
1 //
2 // System.Web.UI.WebControls.Unit.cs
3 //
4 // Authors:
5 //   Miguel de Icaza (miguel@novell.com)
6 //   Ben Maurer (bmaurer@ximian.com).
7 //
8 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
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
30 using System.Globalization;
31 using System.ComponentModel;
32 using System.Security.Permissions;
33
34 namespace System.Web.UI.WebControls {
35
36         [TypeConverter(typeof (UnitConverter))]
37 #if NET_2_0
38         [Serializable]
39 #else
40         // CAS
41         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
42 #endif
43         public struct Unit {
44                 UnitType type;
45                 double value;
46                 public static readonly Unit Empty;
47                 
48                 public Unit (double value, UnitType type)
49                 {
50                         if (value < -32768 || value > 32767)
51                                 throw new ArgumentOutOfRangeException ("value");
52
53                         this.type = type;
54                         if (type == UnitType.Pixel)
55                                 this.value = (int) value;
56                         else
57                                 this.value = value;
58                 }
59
60                 public Unit (double value) : this (value, UnitType.Pixel)
61                 {
62                 }
63                 
64                 public Unit (int value) : this ((double) value, UnitType.Pixel)
65                 {
66                 }
67
68                 internal Unit (string value, char sep)
69                 {
70                         if (value == null || value == String.Empty){
71                                 type = (UnitType) 0;
72                                 this.value = 0.0;
73                                 return;
74                         }
75
76                         int count = value.Length;
77                         int i = 0;
78                         int sign = 1;
79                         
80                         while (i < count && Char.IsWhiteSpace (value [i]))
81                                 i++;
82                         if (value [i] == '-'){
83                                 sign = -1;
84                                 i++;
85                                 if (!Char.IsDigit (value [i]))
86                                         throw new ArgumentOutOfRangeException ("value");
87                         } else if (!Char.IsDigit (value [i])) {
88                                 throw new FormatException ();
89                         }
90
91                         double dv = 0;
92                         for (; i < count; i++){
93                                 char c = value [i];
94                                 if (!Char.IsDigit (c))
95                                         break;
96                                 dv = dv * 10 + ((int) c) - ((int) '0');
97                         }
98                         dv *= sign;
99                         this.value = dv;
100                         dv = 0;
101                         if (i < count && value [i] == sep){
102                                 i++;
103                                 double factor = .1;
104                                 for (; i < count; i++){
105                                         char c = value [i];
106                                         if (!Char.IsDigit (c))
107                                                 break;
108                                         dv = dv + (((int) c) - ((int) '0')) * factor;
109                                         factor = factor *.1;
110                                 }
111                                 this.value += dv;
112                         }
113                         
114                         while (i < count && Char.IsWhiteSpace (value [i]))
115                                 i++;
116
117                         if (i == count){
118                                 type = UnitType.Pixel;
119                                 return;
120                         }
121
122                         if (value [i] == '%'){
123                                 type = UnitType.Percentage;
124                                 i++;
125                                 while (i < count && Char.IsWhiteSpace (value [i]))
126                                         i++;
127                                 if (i != count)
128                                         throw new ArgumentOutOfRangeException ("value");
129                                 return;
130                         }
131                         
132                         int j = i;
133                         while (j < count && Char.IsLetter (value [j]))
134                                 j++;
135                         string code = value.Substring (i, j-i);
136                         switch (code.ToLower (CultureInfo.InvariantCulture)){
137                         case "in": type = UnitType.Inch; break;
138                         case "cm": type = UnitType.Cm; break;
139                         case "mm": type = UnitType.Mm; break;
140                         case "pt": type = UnitType.Point; break;
141                         case "pc": type = UnitType.Pica; break;
142                         case "em": type = UnitType.Em; break;
143                         case "ex": type = UnitType.Ex; break;
144                         case "px":
145                                 type = UnitType.Pixel;
146                                 if (dv != 0)
147                                         throw new FormatException ("Pixel units do not allow floating point values");
148                                 break;
149                         default:
150                                 throw new ArgumentOutOfRangeException ("value");
151                         }
152
153                         while (j < count && Char.IsWhiteSpace (value [j]))
154                                 j++;
155                         if (j != count)
156                                 throw new ArgumentOutOfRangeException ("value");
157                 }
158
159                 
160                 public Unit (string value) : this (value, '.')
161                 {
162                 }
163
164                 public Unit (string value, CultureInfo culture) : this (value, culture.NumberFormat.NumberDecimalSeparator [0])
165                 {
166                 }
167
168                 internal Unit (string value, CultureInfo culture, UnitType t) : this (value, '.')
169                 {
170                 }
171                 
172                 public bool IsEmpty {
173                         get {
174                                 return type == 0;
175                         }
176                 }
177
178                 public UnitType Type {
179                         get {
180                                 if (type == 0)
181                                         return UnitType.Pixel;
182                                 return type;
183                         }
184                 }
185
186                 public double Value {
187                         get {
188                                 return value;
189                         }
190                 }
191                 
192                 public static Unit Parse (string s)
193                 {
194                         return new Unit (s);
195                 }
196
197                 public static System.Web.UI.WebControls.Unit Parse (string s, System.Globalization.CultureInfo culture)
198                 {
199                         return new Unit (s, culture);
200                 }
201                 
202
203                 public static Unit Percentage (double n)
204                 {
205                         return new Unit (n, UnitType.Percentage);
206                 }
207                 
208                 public static Unit Pixel (int n)
209                 {
210                         return new Unit (n);
211                 }
212                 
213                 public static Unit Point (int n)
214                 {
215                         return new Unit (n, UnitType.Point);
216                 }
217                                 
218                 public override bool Equals (object obj)
219                 {
220                         if (obj is Unit){
221                                 Unit other = (Unit) obj;
222                                 return (other.type == type && other.value == value);
223                         }
224                         return false;
225                 }
226                 
227                 public override int GetHashCode ()
228                 {
229                         return Type.GetHashCode () ^ Value.GetHashCode ();
230                 }
231                 
232                 public static bool operator == (Unit left, Unit right)
233                 {
234                         return left.Type == right.Type && left.Value == right.Value;
235                 }
236
237                 public static bool operator != (Unit left, Unit right)
238                 {
239                         return left.Type != right.Type || left.Value != right.Value;
240                 }
241                 
242                 public static implicit operator Unit (int n)
243                 {
244                         return new Unit (n);
245                 }
246
247                 string GetExtension ()
248                 {
249                         switch (type){
250                         case UnitType.Pixel: return "px";
251                         case UnitType.Point: return "pt";
252                         case UnitType.Pica: return "pc";
253                         case UnitType.Inch: return "in";
254                         case UnitType.Mm: return "mm";
255                         case UnitType.Cm: return "cm";
256                         case UnitType.Percentage: return "%";
257                         case UnitType.Em: return "em";
258                         case UnitType.Ex: return "ex";
259                         default: return "";
260                         }
261                 }
262
263                 public string ToString (CultureInfo culture)
264                 {
265                         if (type == 0)
266                                 return "";
267                         
268                         string ex = GetExtension ();
269                         
270                         return String.Format (culture, "{0}{1}", value, ex);
271                 }
272                         
273                 public override string ToString ()
274                 {
275                         return ToString (CultureInfo.InvariantCulture);
276                 }
277
278 #if NET_2_0
279                 public string ToString (IFormatProvider provider)
280                 {
281                         if (type == 0)
282                                 return "";
283
284                         string ex = GetExtension ();
285
286                         return String.Format (provider, "{0}{1}", value, ex);
287                 }
288 #endif
289         }
290
291 }