Mark tests as not working under TARGET_JVM
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / CheckBox.cs
1 //
2 // System.Web.UI.WebControls.CheckBox.cs
3 //
4 // Author:
5 //      Dick Porter  <dick@ximian.com>
6 //
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System.Collections;
30 using System.Collections.Specialized;
31 using System.ComponentModel;
32 using System.Globalization;
33 using System.Security.Permissions;
34
35 namespace System.Web.UI.WebControls {
36         // CAS
37         [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
38         [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
39         // attributes
40         [Designer ("System.Web.UI.Design.WebControls.CheckBoxDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
41         [DataBindingHandler ("System.Web.UI.Design.TextDataBindingHandler, " + Consts.AssemblySystem_Design)]
42         [DefaultEvent ("CheckedChanged")]
43         [DefaultProperty ("Text")]
44 #if NET_2_0
45         [ControlValueProperty ("Checked", null)]
46         [SupportsEventValidation]
47 #endif          
48         public class CheckBox : WebControl, IPostBackDataHandler
49 #if NET_2_0
50         , ICheckBoxControl
51 #endif
52         {
53                 string render_type;
54                 AttributeCollection common_attrs;
55
56 #if NET_2_0
57                 AttributeCollection inputAttributes;
58                 StateBag inputAttributesState;
59                 AttributeCollection labelAttributes;
60                 StateBag labelAttributesState;
61 #endif
62                 
63                 public CheckBox () : base (HtmlTextWriterTag.Input)
64                 {
65                         render_type = "checkbox";
66                 }
67
68                 internal CheckBox (string render_type) : base (HtmlTextWriterTag.Input)
69                 {
70                         this.render_type = render_type;
71                 }
72
73                 [DefaultValue (false)]
74 #if NET_2_0
75                 [Themeable (false)]
76 #endif          
77                 [WebSysDescription ("")]
78                 [WebCategory ("Behavior")]
79                 public virtual bool AutoPostBack 
80                 {
81                         get {
82                                 return (ViewState.GetBool ("AutoPostBack",
83                                                            false));
84                         }
85                         set {
86                                 ViewState["AutoPostBack"] = value;
87                         }
88                 }
89
90 #if NET_2_0
91                 [DefaultValue (false)]
92                 [Themeable (false)]
93                 [WebSysDescription ("")]
94                 [WebCategory ("Behavior")]
95                 public virtual bool CausesValidation 
96                 {
97                         get { return ViewState.GetBool ("CausesValidation", false); }
98                         set { ViewState ["CausesValidation"] = value; }
99                 }
100 #endif          
101                 
102
103                 [DefaultValue (false)]
104 #if NET_2_0
105                 [Bindable (true, BindingDirection.TwoWay)]
106                 [Themeable (false)]
107 #else           
108                 [Bindable (true)]
109 #endif          
110                 [WebSysDescription ("")]
111                 [WebCategory ("Behavior")]
112                 public virtual bool Checked 
113                 {
114                         get {
115                                 return (ViewState.GetBool ("Checked", false));
116                         }
117                         set {
118                                 ViewState["Checked"] = value;
119                         }
120                 }
121
122 #if NET_2_0
123                 [Browsable (false)]
124                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
125                 public AttributeCollection InputAttributes 
126                 {
127                         get {
128                                 if (inputAttributes == null) {
129                                         if (inputAttributesState == null) {
130                                                 inputAttributesState = new StateBag (true);
131                                                 if (IsTrackingViewState)
132                                                         inputAttributesState.TrackViewState();
133                                         }
134                                         inputAttributes = new AttributeCollection (inputAttributesState);
135                                 }
136                                 return inputAttributes;
137                         }
138                 }
139
140                 [Browsable (false)]
141                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
142                 public AttributeCollection LabelAttributes
143                 {
144                         get {
145                                 if (labelAttributes == null) {
146                                         if (labelAttributesState == null) {
147                                                 labelAttributesState = new StateBag (true);
148                                                 if (IsTrackingViewState)
149                                                         labelAttributesState.TrackViewState();
150                                         }
151                                         labelAttributes = new AttributeCollection (labelAttributesState);
152                                 }
153                                 return labelAttributes;
154                         }
155                 }
156 #endif          
157
158                 [DefaultValue ("")]
159                 [Bindable (true)]
160 #if NET_2_0
161                 [Localizable (true)]
162 #endif          
163                 [WebSysDescription ("")]
164                 [WebCategory ("Appearance")]
165                 public virtual string Text 
166                 {
167                         get {
168                                 return (ViewState.GetString ("Text",
169                                                              String.Empty));
170                         }
171                         set {
172                                 ViewState["Text"] = value;
173                         }
174                 }
175
176                 [DefaultValue (TextAlign.Right)]
177 #if ONLY_1_1
178                 [Bindable (true)]
179 #endif          
180                 [WebSysDescription ("")]
181                 [WebCategory ("Appearance")]
182                 public virtual TextAlign TextAlign
183                 {
184                         get { return (TextAlign) ViewState.GetInt ("TextAlign", (int)TextAlign.Right); }
185                         set {
186                                 if (value != TextAlign.Left &&
187                                     value != TextAlign.Right) {
188                                         throw new ArgumentOutOfRangeException ("value");
189                                 }
190                                 
191                                 ViewState["TextAlign"] = value;
192                         }
193                 }
194
195 #if NET_2_0
196                 [Themeable (false)]
197                 [DefaultValue ("")]
198                 [WebSysDescription ("")]
199                 [WebCategoryAttribute ("Behavior")]
200                 public virtual string ValidationGroup
201                 {
202                         get { return ViewState.GetString ("ValidationGroup", String.Empty); }
203                         set { ViewState["ValidationGroup"] = value; }
204                 }
205 #endif          
206
207                 private static readonly object EventCheckedChanged = new object ();
208                 [WebSysDescription ("")]
209                 [WebCategory ("Action")]
210                 public event EventHandler CheckedChanged 
211                 {
212                         add {
213                                 Events.AddHandler (EventCheckedChanged, value);
214                         }
215                         remove {
216                                 Events.RemoveHandler (EventCheckedChanged, value);
217                         }
218                 }
219
220                 protected virtual void OnCheckedChanged (EventArgs e)
221                 {
222                         EventHandler handler = (EventHandler)Events[EventCheckedChanged];
223                         
224                         if (handler != null) {
225                                 handler (this, e);
226                         }
227                 }
228
229                 internal virtual string NameAttribute 
230                 {
231                         get {
232                                 return (this.UniqueID);
233                         }
234                 }
235                 
236 #if NET_2_0
237                 protected override void LoadViewState (object savedState)
238                 {
239                         if (savedState == null) {
240                                 base.LoadViewState (null);
241                                 return;
242                         }
243
244                         Triplet saved = (Triplet) savedState;
245                         base.LoadViewState (saved.First);
246
247                         if (saved.Second != null) {
248                                 if (inputAttributesState == null) {
249                                         inputAttributesState = new StateBag(true);
250                                         inputAttributesState.TrackViewState ();
251                                 }
252                                 inputAttributesState.LoadViewState (saved.Second);
253                         }
254
255                         if (saved.Third != null) {
256                                 if (labelAttributesState == null) {
257                                         labelAttributesState = new StateBag(true);
258                                         labelAttributesState.TrackViewState ();
259                                 }
260                                 labelAttributesState.LoadViewState (saved.Third);
261                         }
262                 }
263
264                 protected override object SaveViewState ()
265                 {
266                         object baseView = base.SaveViewState ();
267                         object inputAttrView = null;
268                         object labelAttrView = null;
269
270                         if (inputAttributesState != null)
271                                 inputAttrView = inputAttributesState.SaveViewState ();
272
273                         if (labelAttributesState != null)
274                                 labelAttrView = labelAttributesState.SaveViewState ();
275
276                         if (baseView == null && inputAttrView == null && labelAttrView == null)
277                                 return null;
278
279                         return new Triplet (baseView, inputAttrView, labelAttrView);            
280                 }
281
282                 protected override void TrackViewState ()
283                 {
284                         base.TrackViewState();
285                         if (inputAttributesState != null)
286                                 inputAttributesState.TrackViewState ();
287                         if (labelAttributesState != null)
288                                 labelAttributesState.TrackViewState ();
289                 }
290 #endif          
291
292 #if NET_2_0
293                 protected internal
294 #else           
295                 protected
296 #endif          
297                 override void OnPreRender (EventArgs e)
298                 {
299                         base.OnPreRender (e);
300
301                         if (Page != null && Enabled) {
302                                 Page.RegisterRequiresPostBack (this);
303                         }
304 #if NET_2_0
305                         if (Page != null && Enabled)
306                                 Page.RegisterEnabledControl (this);
307 #endif
308                 }
309
310                 static bool IsInputOrCommonAttr (string attname)
311                 {
312                         attname = attname.ToUpper (CultureInfo.InvariantCulture);
313                         switch (attname) {
314                         case "VALUE":
315                         case "CHECKED":
316                         case "SIZE":
317                         case "MAXLENGTH":
318                         case "SRC":
319                         case "ALT":
320                         case "USEMAP":
321                         case "DISABLED":
322                         case "READONLY":
323                         case "ACCEPT":
324                         case "ACCESSKEY":
325                         case "TABINDEX":
326                         case "ONFOCUS":
327                         case "ONBLUR":
328                         case "ONSELECT":
329                         case "ONCHANGE":
330                         case "ONCLICK":
331                         case "ONDBLCLICK":
332                         case "ONMOUSEDOWN":
333                         case "ONMOUSEUP":
334                         case "ONMOUSEOVER":
335                         case "ONMOUSEMOVE":
336                         case "ONMOUSEOUT":
337                         case "ONKEYPRESS":
338                         case "ONKEYDOWN":
339                         case "ONKEYUP":
340                                 return true;
341                         default:
342                                 return false;
343                         }
344                 }
345
346                 bool AddAttributesForSpan (HtmlTextWriter writer)
347                 {
348                         ICollection k = Attributes.Keys;
349                         string [] keys = new string [k.Count];
350                         k.CopyTo (keys, 0);
351                         foreach (string key in keys) {
352                                 if (!IsInputOrCommonAttr (key))
353                                         continue;
354                                 if (common_attrs == null)
355                                         common_attrs = new AttributeCollection (new StateBag ());
356                                 common_attrs [key] = Attributes [key];
357                                 Attributes.Remove (key);
358                         }
359                         if (Attributes.Count > 0) {
360                                 Attributes.AddAttributes (writer);
361                                 return true;
362                         }
363                         return false;
364                 }
365 #if NET_2_0
366                 protected internal
367 #else           
368                 protected
369 #endif          
370                 override void Render (HtmlTextWriter w)
371                 {
372                         if (Page != null)
373                                 Page.VerifyRenderingInServerForm (this);
374                         
375                         bool need_span = ControlStyleCreated && !ControlStyle.IsEmpty;
376                         if (need_span) {
377 #if NET_2_0
378                                 AddDisplayStyleAttribute (w);
379 #endif
380                                 ControlStyle.AddAttributesToRender (w, this);
381                         }
382
383                         if (!Enabled) {
384                                 w.AddAttribute (HtmlTextWriterAttribute.Disabled, "disabled");
385                                 need_span = true;
386                         }
387
388                         string tt = ToolTip;
389                         if (tt != ""){
390                                 w.AddAttribute ("title", tt);
391                                 need_span = true;
392                         }
393
394                         if (Attributes.Count > 0 && AddAttributesForSpan (w))
395                                 need_span = true;
396
397                         if (need_span)
398                                 w.RenderBeginTag (HtmlTextWriterTag.Span);
399
400                         TextAlign align = TextAlign;
401                         if (align == TextAlign.Right) {
402                                 RenderInput (w);
403                                 RenderLabel (w);
404                         } else {
405                                 RenderLabel (w);
406                                 RenderInput (w);
407                         }
408
409                         if (need_span)
410                                 w.RenderEndTag ();
411                 }
412
413                 private void RenderInput (HtmlTextWriter w) {
414
415                         if (ClientID != null && ClientID.Length > 0)
416                                 w.AddAttribute (HtmlTextWriterAttribute.Id, ClientID);
417                         w.AddAttribute (HtmlTextWriterAttribute.Type, render_type);
418                         string nameAttr = NameAttribute;
419                         if (nameAttr != null && nameAttr.Length > 0)
420                                 w.AddAttribute (HtmlTextWriterAttribute.Name, nameAttr);
421                         InternalAddAttributesToRender (w);
422 #if NET_2_0
423                         AddAttributesToRender (w);
424                         if (inputAttributes != null)
425                                 inputAttributes.AddAttributes (w);
426 #endif
427                         if (Checked)
428                                 w.AddAttribute (HtmlTextWriterAttribute.Checked, "checked");
429
430                         if (AutoPostBack) {
431 #if NET_2_0
432                                 w.AddAttribute (HtmlTextWriterAttribute.Onclick, Page.ClientScript.GetPostBackEventReference (GetPostBackOptions (), true));
433 #else
434                                         w.AddAttribute (HtmlTextWriterAttribute.Onclick,
435                                                         Page.ClientScript.GetPostBackEventReference (this, String.Empty));
436 #endif
437                                 w.AddAttribute ("language", "javascript");
438                         }
439
440                         if (AccessKey.Length > 0)
441                                 w.AddAttribute (HtmlTextWriterAttribute.Accesskey, AccessKey);
442
443                         if (TabIndex != 0)
444                                 w.AddAttribute (HtmlTextWriterAttribute.Tabindex,
445                                                          TabIndex.ToString (NumberFormatInfo.InvariantInfo));
446
447                         if (common_attrs != null)
448                                 common_attrs.AddAttributes (w);
449                         w.RenderBeginTag (HtmlTextWriterTag.Input);
450                         w.RenderEndTag ();
451                 }
452
453                 private void RenderLabel (HtmlTextWriter w) {
454                         string text = Text;
455                         if (text.Length > 0) {
456 #if NET_2_0
457                                 if (labelAttributes != null)
458                                         labelAttributes.AddAttributes (w);
459 #endif
460                                 w.AddAttribute (HtmlTextWriterAttribute.For, ClientID);
461                                 w.RenderBeginTag (HtmlTextWriterTag.Label);
462                                 w.Write (text);
463                                 w.RenderEndTag ();
464                         }
465                 }
466
467 #if NET_2_0
468                 protected virtual
469 #endif
470                 bool LoadPostData (string postDataKey, NameValueCollection postCollection)
471                 {
472                         if (!Enabled)
473                                 return false;
474
475                         string postedValue = postCollection[postDataKey];
476                         bool postedBool = ((postedValue != null) &&
477                                            (postedValue.Length > 0));
478                         
479                         if (Checked != postedBool) {
480                                 Checked = postedBool;
481                                 return (true);
482                         }
483
484                         return (false);
485                 }
486
487 #if NET_2_0
488                 protected virtual
489 #endif
490                 void RaisePostDataChangedEvent ()
491                 {
492 #if NET_2_0
493                         if (CausesValidation)
494                                 Page.Validate (ValidationGroup);
495 #endif
496                         OnCheckedChanged (EventArgs.Empty);
497                 }
498
499                 bool IPostBackDataHandler.LoadPostData (string postDataKey, NameValueCollection postCollection)
500                 {
501                         return LoadPostData (postDataKey, postCollection);
502                 }
503                 
504                 void IPostBackDataHandler.RaisePostDataChangedEvent ()
505                 {
506                         RaisePostDataChangedEvent ();
507                 }
508
509 #if NET_2_0
510                 PostBackOptions GetPostBackOptions () {
511                         PostBackOptions options = new PostBackOptions (this);
512                         options.ActionUrl = null;
513                         options.ValidationGroup = null;
514                         options.Argument = "";
515                         options.RequiresJavaScriptProtocol = false;
516                         options.ClientSubmit = true;
517                         options.PerformValidation = CausesValidation && Page != null && Page.AreValidatorsUplevel (ValidationGroup);
518                         if (options.PerformValidation)
519                                 options.ValidationGroup = ValidationGroup;
520
521                         return options;
522                 }
523
524                 protected override void AddAttributesToRender (HtmlTextWriter writer)
525                 {
526                 }
527 #endif
528
529                 internal virtual void InternalAddAttributesToRender (HtmlTextWriter w)
530                 {
531                         if (!Enabled)
532                                 w.AddAttribute (HtmlTextWriterAttribute.Disabled, "disabled");
533                 }
534         }
535 }