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