In .:
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / WebControl.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. (http://www.novell.com)
21 //
22 // Authors:
23 //      Peter Bartok    (pbartok@novell.com)
24 //
25 //
26
27 using System.ComponentModel;
28 using System.Drawing;
29 using System.Security.Permissions;
30
31 namespace System.Web.UI.WebControls {
32
33         // CAS
34         [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
35         [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
36         // attributes
37 #if NET_2_0
38         [PersistChildrenAttribute (false, false)]
39         [ParseChildrenAttribute (true, ChildControlType = typeof(Control))]
40         [Themeable (true)]
41 #else   
42         [PersistChildrenAttribute (false)]
43         [ParseChildrenAttribute (true)]
44 #endif          
45         public class WebControl : Control, IAttributeAccessor {
46                 Style style;
47                 HtmlTextWriterTag tag;
48                 string tag_name;
49                 AttributeCollection attributes;
50                 StateBag attribute_state;
51                 bool enabled;
52
53                 public WebControl (HtmlTextWriterTag tag) 
54                 {
55                         this.tag = tag;
56                         this.enabled = true;
57                 }
58
59                 protected WebControl () : this (HtmlTextWriterTag.Span) 
60                 {
61                 }
62
63                 protected WebControl (string tag) 
64                 {
65                         this.tag = HtmlTextWriterTag.Unknown;
66                         this.tag_name = tag;
67                         this.enabled = true;
68                 }
69
70 #if ONLY_1_1
71                 [Bindable(true)]
72 #endif          
73                 [DefaultValue("")]
74                 [WebSysDescription ("")]
75                 [WebCategory ("Behavior")]
76                 public virtual string AccessKey {
77                         get {
78                                 return ViewState.GetString ("AccessKey", string.Empty);
79                         }
80                         set {
81                                 if (value == null || value.Length < 2)
82                                         ViewState ["AccessKey"] = value;
83                                 else
84                                         throw new ArgumentException ("AccessKey can only be null, empty or a single character", "value");
85                         }
86                 }
87
88                 [Browsable(false)]
89                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
90                 [WebSysDescription ("")]
91                 [WebCategory ("Behavior")]
92                 public AttributeCollection Attributes {
93                         get {
94                                 if (attributes == null) {
95                                         attribute_state = new StateBag (true);
96                                         if (IsTrackingViewState)
97                                                 attribute_state.TrackViewState ();
98                                         
99                                         attributes = new AttributeCollection (attribute_state);
100                                 }
101                                 return attributes;
102                         }
103                 }
104
105 #if ONLY_1_1
106                 [Bindable(true)]
107 #endif          
108                 [DefaultValue(typeof (Color), "")]
109                 [TypeConverter(typeof(System.Web.UI.WebControls.WebColorConverter))]
110                 [WebSysDescription ("")]
111                 [WebCategory ("Appearance")]
112                 public virtual Color BackColor {
113                         get {
114                                 if (style == null) 
115                                         return Color.Empty;
116                                 
117                                 return style.BackColor;
118                         }
119                         set {
120                                 ControlStyle.BackColor = value;
121                         }
122                 }
123
124 #if ONLY_1_1
125                 [Bindable(true)]
126 #endif          
127                 [DefaultValue(typeof (Color), "")]
128                 [TypeConverter(typeof(System.Web.UI.WebControls.WebColorConverter))]
129                 [WebSysDescription ("")]
130                 [WebCategory ("Appearance")]
131                 public virtual Color BorderColor {
132                         get {
133                                 if (style == null) 
134                                         return Color.Empty;
135
136                                 return style.BorderColor;
137                         }
138
139                         set {
140                                 ControlStyle.BorderColor = value;
141                         }
142                 }
143
144 #if ONLY_1_1
145                 [Bindable(true)]
146 #endif          
147                 [DefaultValue(BorderStyle.NotSet)]
148                 [WebSysDescription ("")]
149                 [WebCategory ("Appearance")]
150                 public virtual BorderStyle BorderStyle {
151                         get {
152                                 if (style == null) 
153                                         return BorderStyle.NotSet;
154                                 
155                                 return style.BorderStyle;
156                         }
157                         set {
158                                 if (value < BorderStyle.NotSet || value > BorderStyle.Outset)
159                                         throw new ArgumentOutOfRangeException ("value");
160
161                                 ControlStyle.BorderStyle = value;
162                         }
163                 }
164
165 #if ONLY_1_1
166                 [Bindable(true)]
167 #endif          
168                 [DefaultValue(typeof (Unit), "")]
169                 [WebSysDescription ("")]
170                 [WebCategory ("Appearance")]
171                 public virtual Unit BorderWidth {
172                         get {
173                                 if (style == null) 
174                                         return Unit.Empty;
175
176                                 return style.BorderWidth;
177                         }
178                         set {
179                                 ControlStyle.BorderWidth = value;
180                         }
181                 }
182
183                 [Browsable(false)]
184                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
185                 [WebSysDescription ("")]
186                 [WebCategory ("Appearance")]
187                 public Style ControlStyle {
188                         get {
189                                 if (style == null) {
190                                         style = this.CreateControlStyle ();
191
192                                         if (IsTrackingViewState)
193                                                 style.TrackViewState ();
194                                 }
195
196                                 return style;
197                         }
198                 }
199
200                 [Browsable(false)]
201                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
202 #if NET_2_0
203                 [EditorBrowsable (EditorBrowsableState.Never)]
204 #endif
205                 public bool ControlStyleCreated {
206                         get {
207                                 return style != null;
208                         }
209                 }
210
211 #if ONLY_1_1
212                 [Bindable(true)]
213 #endif          
214                 [DefaultValue("")]
215                 [WebSysDescription ("")]
216                 [WebCategory ("Appearance")]
217                 public virtual string CssClass {
218                         get {
219                                 if (style == null) 
220                                         return string.Empty;
221                                 
222                                 return style.CssClass;
223                         }
224                         set {
225                                 ControlStyle.CssClass = value;
226                         }
227                 }
228
229                 [Bindable(true)]
230                 [DefaultValue(true)]
231 #if NET_2_0
232                 [Themeable (false)]
233 #endif          
234                 public virtual bool Enabled {
235                         get {
236                                 return enabled;
237                         }
238
239                         set {
240                                 if (enabled != value) {
241                                         ViewState ["Enabled"] = value;
242                                         enabled = value;
243                                 }
244                         }
245                 }
246
247 #if NET_2_0
248                 [Browsable (true)]
249                 [MonoTODO]
250                 public virtual new bool EnableTheming
251                 {
252                         get { return base.EnableTheming; }
253                         set { EnableTheming = value; }
254                 }
255 #endif          
256
257 #if ONLY_1_1
258                 [DefaultValue(null)]
259 #endif          
260                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
261                 [NotifyParentProperty(true)]
262                 [WebSysDescription ("")]
263                 [WebCategory ("Appearance")]
264                 public virtual FontInfo Font {
265                         get {
266                                 // Oddly enough, it looks like we have to let it create the style
267                                 // since we can't create a FontInfo without a style owner
268                                 return ControlStyle.Font;
269                         }
270                 }
271
272 #if ONLY_1_1
273                 [Bindable(true)]
274 #endif          
275                 [DefaultValue(typeof (Color), "")]
276                 [TypeConverter(typeof(System.Web.UI.WebControls.WebColorConverter))]
277                 [WebSysDescription ("")]
278                 [WebCategory ("Appearance")]
279                 public virtual Color ForeColor {
280                         get {
281                                 if (style == null) 
282                                         return Color.Empty;
283                                 
284                                 return style.ForeColor;
285                         }
286                         set {
287                                 ControlStyle.ForeColor = value;
288                         }
289                 }
290
291 #if NET_2_0
292                 [Browsable (false)]
293                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
294                 [MonoTODO]
295                 public bool HasAttributes 
296                 {
297                         get {
298                                 throw new NotImplementedException ();
299                         }
300                 }
301 #endif          
302                 
303 #if ONLY_1_1
304                 [Bindable(true)]
305 #endif          
306                 [DefaultValue(typeof (Unit), "")]
307                 [WebSysDescription ("")]
308                 [WebCategory ("Layout")]
309                 public virtual Unit Height {
310                         get {
311                                 if (style == null) 
312                                         return Unit.Empty;
313                                 
314                                 return style.Height;
315                         }
316                         set {
317                                 ControlStyle.Height = value;
318                         }
319                 }
320
321 #if NET_2_0
322                 [Browsable (true)]
323                 [MonoTODO]
324                 public virtual new string SkinID
325                 {
326                         get { return base.SkinID; }
327                         set { base.SkinID = value; }
328                 }
329 #endif          
330                 
331                 [Browsable(false)]
332                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
333                 [WebSysDescription ("")]
334                 [WebCategory ("Style")]
335                 public CssStyleCollection Style {
336                         get {
337                                 return Attributes.CssStyle;
338                         }
339                 }
340
341                 [DefaultValue((short)0)]
342                 [WebSysDescription ("")]
343                 [WebCategory ("Behavior")]
344                 public virtual short TabIndex {
345                         get {
346                                 return ViewState.GetShort ("TabIndex", 0);
347                         }
348                         set {
349                                 ViewState ["TabIndex"] = value;
350                         }
351                 }
352
353 #if ONLY_1_1
354                 [Bindable(true)]
355 #endif          
356                 [DefaultValue("")]
357 #if NET_2_0
358                 [Localizable (true)]
359 #endif          
360                 [WebSysDescription ("")]
361                 [WebCategory ("Behavior")]
362                 public virtual string ToolTip {
363                         get {
364                                 return ViewState.GetString ("ToolTip", string.Empty);
365                         }
366                         set {
367                                 ViewState ["ToolTip"] = value;
368                         }
369                 }
370
371 #if ONLY_1_1
372                 [Bindable(true)]
373 #endif          
374                 [DefaultValue(typeof (Unit), "")]
375                 [WebSysDescription ("")]
376                 [WebCategory ("Layout")]
377                 public virtual Unit Width {
378                         get {
379                                 if (style == null) 
380                                         return Unit.Empty;
381                                 
382                                 return style.Width;
383                         }
384                         set {
385                                 ControlStyle.Width = value;
386                         }
387                 }
388
389                 [Browsable(false)]
390                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
391                 protected virtual HtmlTextWriterTag TagKey {
392                         get {
393                                 return tag;
394                         }
395                 }
396
397                 [Browsable(false)]
398                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
399                 protected virtual string TagName {
400                         get {
401                                 // do this here to avoid potentially costly lookups on every control
402                                 if (tag_name == null)
403                                         tag_name = HtmlTextWriter.StaticGetTagName (TagKey);
404                                 
405                                 return tag_name;
406                         }
407                 }
408
409 #if NET_2_0
410                 [MonoTODO]
411                 protected internal bool IsEnabled 
412                 {
413                         get {
414                                 throw new NotImplementedException ();
415                         }
416                 }
417 #endif          
418                 
419
420                 public void ApplyStyle (Style s) 
421                 {
422                         if (s != null && !s.IsEmpty)
423                                 ControlStyle.CopyFrom(s);
424                 }
425
426                 public void CopyBaseAttributes (WebControl controlSrc) 
427                 {
428                         object o;
429
430                         if (controlSrc == null) 
431                                 return;
432
433                         o = controlSrc.ViewState ["Enabled"];
434                         if (o != null) {
435                                 enabled = (bool)o;
436                         }
437
438                         o = controlSrc.ViewState ["AccessKey"];
439                         if (o != null)
440                                 ViewState ["AccessKey"] = o;
441
442                         o = controlSrc.ViewState ["TabIndex"];
443                         if (o != null)
444                                 ViewState ["TabIndex"] = o;
445
446                         o = controlSrc.ViewState ["ToolTip"];
447                         if (o != null)
448                                 ViewState ["ToolTip"] = o;
449
450                         if (controlSrc.attributes != null)
451                                 foreach (string s in controlSrc.attributes.Keys)
452                                         Attributes [s] = controlSrc.attributes [s];
453                 }
454
455                 public void MergeStyle (Style s) 
456                 {
457                         if (s != null && !s.IsEmpty)
458                                 ControlStyle.MergeWith(s);
459                 }
460
461                 public virtual void RenderBeginTag (HtmlTextWriter writer)
462                 {
463                         AddAttributesToRender (writer);
464                         
465                         if (TagKey == HtmlTextWriterTag.Unknown)
466                                 writer.RenderBeginTag (TagName);
467                         else
468                                 writer.RenderBeginTag (TagKey);
469                         
470                 }
471
472                 public virtual void RenderEndTag (HtmlTextWriter writer) 
473                 {
474                         writer.RenderEndTag ();
475                 }
476
477                 protected virtual void AddAttributesToRender (HtmlTextWriter writer) 
478                 {
479                         if (ID != null)
480                                 writer.AddAttribute(HtmlTextWriterAttribute.Id, ClientID);
481
482                         if (AccessKey != string.Empty)
483                                 writer.AddAttribute (HtmlTextWriterAttribute.Accesskey, AccessKey);
484
485                         if (!enabled)
486                                 writer.AddAttribute (HtmlTextWriterAttribute.Disabled, "disabled");
487
488                         if (ToolTip != string.Empty)
489                                 writer.AddAttribute (HtmlTextWriterAttribute.Title, ToolTip);
490
491                         if (TabIndex != 0)
492                                 writer.AddAttribute (HtmlTextWriterAttribute.Tabindex, TabIndex.ToString ());
493
494                         if (style != null && !style.IsEmpty)
495                                 style.AddAttributesToRender(writer, this);
496
497                         if (attributes != null)
498                                 foreach(string s in attributes.Keys)
499                                         writer.AddAttribute (s, attributes [s]);
500                 }
501
502                 protected virtual Style CreateControlStyle() 
503                 {
504                         style = new Style (ViewState);
505                         return style;
506                 }
507
508                 protected override void LoadViewState (object savedState) 
509                 {
510                         if (savedState == null) {
511                                 base.LoadViewState(null);
512                                 return;
513                         }
514
515                         Triplet triplet = (Triplet) savedState;
516
517                         base.LoadViewState (triplet.First);
518                         
519                         if (triplet.Second != null) {
520                                 if (attribute_state == null) {
521                                         attribute_state = new StateBag ();
522                                         if (IsTrackingViewState) 
523                                                 attribute_state.TrackViewState ();
524                                 }
525                                 attribute_state.LoadViewState (triplet.Second);
526                                 attributes = new AttributeCollection(attribute_state);
527                         }
528
529                         if (triplet.Third != null) {
530                                 if (style == null)
531                                         style = CreateControlStyle ();
532
533                                 style.LoadViewState (triplet.Third);
534                         }
535
536                         enabled = ViewState.GetBool("Enabled", true);
537                 }
538
539 #if NET_2_0
540                 protected internal
541 #else           
542                 protected
543 #endif          
544                 override void Render (HtmlTextWriter writer)
545                 {
546                         RenderBeginTag (writer);
547                         RenderContents (writer);
548                         RenderEndTag (writer);
549                 }
550
551 #if NET_2_0
552                 protected internal
553 #else           
554                 protected
555 #endif          
556                 virtual void RenderContents (HtmlTextWriter writer)
557                 {
558                         base.Render (writer);
559                 }
560
561                 protected override object SaveViewState () 
562                 {
563                         object view_state;
564                         object attr_view_state = null;
565                         object style_view_state = null;
566
567                         view_state = base.SaveViewState ();
568
569                         if (attribute_state != null)
570                                 attr_view_state = attribute_state.SaveViewState ();
571                 
572                         if (style != null)
573                                 style_view_state = style.SaveViewState ();
574                         
575                         if (view_state == null && attr_view_state == null && style_view_state == null)
576                                 return null;
577                         
578                         return new Triplet (view_state, attr_view_state, style_view_state);
579                 }
580
581                 protected override void TrackViewState() 
582                 {
583                         if (style != null)
584                                 style.TrackViewState ();
585
586                         if (attribute_state != null)
587                                 attribute_state.TrackViewState ();
588
589                         base.TrackViewState ();
590                 }
591
592                 string IAttributeAccessor.GetAttribute (string key) 
593                 {
594                         if (attributes != null)
595                                 return attributes [key];
596
597                         return null;
598                 }
599
600                 void IAttributeAccessor.SetAttribute (string key, string value) 
601                 {
602                         Attributes [key] = value;
603                 }
604         }
605 }