2010-07-23 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / Table.cs
1 //
2 // System.Web.UI.WebControls.Table.cs
3 //
4 // Author:
5 //      Sebastien Pouliot  <sebastien@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.ComponentModel;
30 using System.Security.Permissions;
31
32 namespace System.Web.UI.WebControls {
33
34         // CAS
35         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
36         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
37         // attributes
38         [DefaultProperty ("Rows")]
39         [Designer ("System.Web.UI.Design.WebControls.TableDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
40         [ParseChildren (true, "Rows")]
41 #if NET_2_0
42         [SupportsEventValidation]
43         public class Table : WebControl, IPostBackEventHandler
44         {
45 #else
46         public class Table : WebControl
47         {
48 #endif
49                 TableRowCollection rows;
50 #if NET_2_0
51                 bool generateTableSections;
52 #endif
53
54                 public Table ()
55                         : base (HtmlTextWriterTag.Table)
56                 {
57                 }
58
59 #if NET_2_0
60                 internal bool GenerateTableSections {
61                         get { return generateTableSections; }
62                         set { generateTableSections = value; }
63                 }
64                 
65                 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
66                 [UrlProperty]
67 #else
68                 [Bindable (true)]
69                 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
70 #endif
71                 [DefaultValue ("")]
72                 [WebSysDescription ("")]
73                 [WebCategory ("Appearance")]
74                 public virtual string BackImageUrl {
75                         get {
76                                 if (!ControlStyleCreated)
77                                         return String.Empty; // default value
78                                 return TableStyle.BackImageUrl;
79                         }
80                         set { TableStyle.BackImageUrl = value; }
81                 }
82
83                 // note: it seems that Caption and CaptionAlign appeared in 1.1 SP1
84
85                 [DefaultValue ("")]
86 #if NET_2_0
87                 [Localizable (true)]
88 #endif
89                 [WebSysDescription ("")]
90                 [WebCategory ("Accessibility")]
91                 public virtual string Caption {
92                         get {
93                                 object o = ViewState ["Caption"];
94                                 return (o == null) ? String.Empty : (string) o;
95                         }
96                         set {
97                                 if (value == null)
98                                         ViewState.Remove ("Caption");
99                                 else
100                                         ViewState ["Caption"] = value;
101                         }
102                 }
103
104                 [DefaultValue (TableCaptionAlign.NotSet)]
105                 [WebCategory ("Accessibility")]
106                 public virtual TableCaptionAlign CaptionAlign {
107                         get {
108                                 object o = ViewState ["CaptionAlign"];
109                                 return (o == null) ? TableCaptionAlign.NotSet : (TableCaptionAlign) o;
110                         }
111                         set {
112                                 if ((value < TableCaptionAlign.NotSet) || (value > TableCaptionAlign.Right)) {
113                                         throw new ArgumentOutOfRangeException (Locale.GetText ("Invalid TableCaptionAlign value."));
114                                 }
115                                 ViewState ["CaptionAlign"] = value;
116                         }
117                 }
118
119 #if ONLY_1_1
120                 [Bindable (true)]
121 #endif
122                 [DefaultValue (-1)]
123                 [WebSysDescription ("")]
124                 [WebCategory ("Appearance")]
125                 public virtual int CellPadding {
126                         get {
127                                 if (!ControlStyleCreated)
128                                         return -1; // default value
129                                 return TableStyle.CellPadding;
130                         }
131                         set { TableStyle.CellPadding = value; }
132                 }
133
134 #if ONLY_1_1
135                 [Bindable (true)]
136 #endif
137                 [DefaultValue (-1)]
138                 [WebSysDescription ("")]
139                 [WebCategory ("Appearance")]
140                 public virtual int CellSpacing {
141                         get {
142                                 if (!ControlStyleCreated)
143                                         return -1; // default value
144                                 return TableStyle.CellSpacing;
145                         }
146                         set { TableStyle.CellSpacing = value; }
147                 }
148
149 #if ONLY_1_1
150                 [Bindable (true)]
151 #endif
152                 [DefaultValue (GridLines.None)]
153                 [WebSysDescription ("")]
154                 [WebCategory ("Appearance")]
155                 public virtual GridLines GridLines {
156                         get {
157                                 if (!ControlStyleCreated)
158                                         return GridLines.None; // default value
159                                 return TableStyle.GridLines;
160                         }
161                         set { TableStyle.GridLines = value; }
162                 }
163
164 #if ONLY_1_1
165                 [Bindable (true)]
166 #endif
167                 [DefaultValue (HorizontalAlign.NotSet)]
168                 [WebSysDescription ("")]
169                 [WebCategory ("Layout")]
170                 public virtual HorizontalAlign HorizontalAlign {
171                         get {
172                                 if (!ControlStyleCreated)
173                                         return HorizontalAlign.NotSet; // default value
174                                 return TableStyle.HorizontalAlign;
175                         }
176                         set { TableStyle.HorizontalAlign = value; }
177                 }
178
179                 [MergableProperty (false)]
180                 [PersistenceMode (PersistenceMode.InnerDefaultProperty)]
181                 [WebSysDescription ("")]
182                 public virtual TableRowCollection Rows {
183                         get {
184                                 if (rows == null)
185                                         rows = new TableRowCollection (this);
186                                 return rows;
187                         }
188                 }
189
190                 private TableStyle TableStyle {
191                         get { return (ControlStyle as TableStyle); }
192                 }
193 #if NET_4_0
194                 public override bool SupportsDisabledAttribute {
195                         get { return RenderingCompatibilityLessThan40; }
196                 }
197 #endif
198                 protected override void AddAttributesToRender (HtmlTextWriter writer)
199                 {
200                         base.AddAttributesToRender (writer);
201 #if !NET_4_0
202                         if (!ControlStyleCreated || TableStyle.IsEmpty) {
203                                 // for some reason border=X seems to be always present
204                                 // and isn't rendered as a style attribute
205                                 writer.AddAttribute (HtmlTextWriterAttribute.Border, "0", false);
206                         }
207 #endif
208                 }
209
210                 protected override ControlCollection CreateControlCollection ()
211                 {
212                         return new RowControlCollection (this);
213                 }
214
215                 protected override Style CreateControlStyle ()
216                 {
217                         return new TableStyle (ViewState);
218                 }
219
220 #if NET_2_0
221                 protected internal
222 #else           
223                 protected
224 #endif          
225                 override void RenderContents (HtmlTextWriter writer)
226                 {
227 #if NET_2_0
228                         TableRowSection currentTableSection = TableRowSection.TableHeader;
229                         TableRowSection rowSection;
230                         bool sectionStarted = false;
231 #endif
232                         
233                         if (Rows.Count > 0) {
234                                 foreach (TableRow row in Rows) {
235 #if NET_2_0
236                                         if (generateTableSections) {
237                                                 rowSection = row.TableSection;
238                                                 if (rowSection < currentTableSection)
239                                                         throw new HttpException ("The table " + ID + " must contain row sections in order of header, body, then footer.");
240
241                                                 if (currentTableSection != rowSection) {
242                                                         if (sectionStarted) {
243                                                                 writer.RenderEndTag ();
244                                                                 sectionStarted = false;
245                                                         }
246                                                         
247                                                         currentTableSection = rowSection;
248                                                 }
249                                                 
250                                                 if (!sectionStarted) {
251                                                         switch (rowSection) {
252                                                                 case TableRowSection.TableHeader:
253                                                                         writer.RenderBeginTag (HtmlTextWriterTag.Thead);
254                                                                         break;
255
256                                                                 case TableRowSection.TableBody:
257                                                                         writer.RenderBeginTag (HtmlTextWriterTag.Tbody);
258                                                                         break;
259
260                                                                 case TableRowSection.TableFooter:
261                                                                         writer.RenderBeginTag (HtmlTextWriterTag.Tfoot);
262                                                                         break;
263                                                         }
264                                                         sectionStarted = true;
265                                                 }
266                                         }
267 #endif
268                                         if (row != null)
269                                                 row.RenderControl (writer);
270                                 }
271
272 #if NET_2_0
273                                 if (sectionStarted)
274                                         writer.RenderEndTag ();
275 #endif
276                         }
277                 }
278
279
280                 // new in Fx 1.1 SP1 (to support Caption and CaptionAlign)
281
282                 public override void RenderBeginTag (HtmlTextWriter writer)
283                 {
284                         base.RenderBeginTag (writer);
285
286                         string s = Caption;
287                         if (s.Length > 0) {
288                                 TableCaptionAlign tca = CaptionAlign;
289                                 if (tca != TableCaptionAlign.NotSet)
290                                         writer.AddAttribute (HtmlTextWriterAttribute.Align, tca.ToString ());
291                                 
292                                 writer.RenderBeginTag (HtmlTextWriterTag.Caption);
293                                 writer.Write (s);
294                                 writer.RenderEndTag ();
295                         }
296 // #if !NET_4_0
297 //                      else if (HasControls ()) {
298 //                              writer.Indent++;
299 //                      }
300 // #endif
301                 }
302
303 #if NET_2_0
304                 void IPostBackEventHandler.RaisePostBackEvent (string argument)
305                 {
306                         RaisePostBackEvent (argument);
307                 }
308
309                 protected virtual void RaisePostBackEvent (string argument)
310                 {
311                         ValidateEvent (UniqueID, argument);
312                 }
313 #endif
314
315                 // inner class
316                 protected class RowControlCollection : ControlCollection {
317
318                         internal RowControlCollection (Table owner)
319                                 : base (owner)
320                         {
321                         }
322
323
324                         public override void Add (Control child)
325                         {
326                                 if (child == null)
327                                         throw new NullReferenceException ("null");
328                                 if (!(child is TableRow))
329                                         throw new ArgumentException ("child", Locale.GetText ("Must be an TableRow instance."));
330
331                                 base.Add (child);
332                         }
333
334                         public override void AddAt (int index, Control child)
335                         {
336                                 if (child == null)
337                                         throw new NullReferenceException ("null");
338                                 if (!(child is TableRow))
339                                         throw new ArgumentException ("child", Locale.GetText ("Must be an TableRow instance."));
340
341                                 base.AddAt (index, child);
342                         }
343                 }
344         }
345 }