2010-07-23 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / TableStyle.cs
1 //
2 // System.Web.UI.WebControls.TableStyle.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.Globalization;
31 using System.Security.Permissions;
32 using System.Web.UI;
33 using System.Web.Util;
34
35 namespace System.Web.UI.WebControls {
36
37         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
38         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
39         public class TableStyle : Style {
40
41                 [Flags]
42                 enum TableStyles
43                 {
44                         BackImageUrl = 0x00010000,
45                         CellPadding = 0x00020000,
46                         CellSpacing = 0x00040000,
47                         GridLines = 0x00080000,
48                         HorizontalAlign = 0x00100000,
49                 }
50
51                 public TableStyle ()
52                 {
53                 }
54
55                 public TableStyle (StateBag bag)
56                         : base (bag)
57                 {
58                 }
59
60
61 #if NET_2_0
62                 [NotifyParentProperty (true)]
63                 [UrlProperty]
64 #else
65                 [Bindable (true)]
66 #endif
67                 [DefaultValue ("")]
68                 [WebSysDescription ("")]
69                 [WebCategory ("Appearance")]
70                 public virtual string BackImageUrl {
71                         get {
72                                 if (!CheckBit ((int) TableStyles.BackImageUrl))
73                                         return String.Empty;
74                                 return (string) ViewState ["BackImageUrl"];
75                         }
76                         set {
77                                 if (value == null)
78                                         throw new ArgumentNullException ("BackImageUrl");
79                                 ViewState ["BackImageUrl"] = value;
80                                 SetBit ((int) TableStyles.BackImageUrl);
81                         }
82                 }
83
84 #if NET_2_0
85                 [NotifyParentProperty (true)]
86 #else
87                 [Bindable (true)]
88 #endif
89                 [DefaultValue (-1)]
90                 [WebSysDescription ("")]
91                 [WebCategory ("Appearance")]
92                 public virtual int CellPadding {
93                         get {
94                                 if (!CheckBit ((int) TableStyles.CellPadding))
95                                         return -1;
96                                 return (int) ViewState ["CellPadding"];
97                         }
98                         set {
99                                 if (value < -1)
100                                         throw new ArgumentOutOfRangeException ("< -1");
101                                 ViewState ["CellPadding"] = value;
102                                 SetBit ((int) TableStyles.CellPadding);
103                         }
104                 }
105
106 #if NET_2_0
107                 [NotifyParentProperty (true)]
108 #else
109                 [Bindable (true)]
110 #endif
111                 [DefaultValue (-1)]
112                 [WebSysDescription ("")]
113                 [WebCategory ("Appearance")]
114                 public virtual int CellSpacing {
115                         get {
116                                 if (!CheckBit ((int) TableStyles.CellSpacing))
117                                         return -1;
118                                 return (int) ViewState ["CellSpacing"];
119                         }
120                         set {
121                                 if (value < -1)
122                                         throw new ArgumentOutOfRangeException ("< -1");
123                                 ViewState ["CellSpacing"] = value;
124                                 SetBit ((int) TableStyles.CellSpacing);
125                         }
126                 }
127
128                 // LAMESPEC: default is documented to be Both
129 #if NET_2_0
130                 [NotifyParentProperty (true)]
131 #else
132                 [Bindable (true)]
133 #endif
134                 [DefaultValue (GridLines.None)]
135                 [WebSysDescription ("")]
136                 [WebCategory ("Appearance")]
137                 public virtual GridLines GridLines {
138                         get {
139                                 if (!CheckBit ((int) TableStyles.GridLines))
140                                         return GridLines.None;
141                                 return (GridLines) ViewState ["GridLines"];
142                         }
143                         set {
144                                 // avoid reflection
145                                 if ((value < GridLines.None) || (value > GridLines.Both)) {
146                                         // LAMESPEC: documented as ArgumentException
147                                         throw new ArgumentOutOfRangeException (Locale.GetText ("Invalid GridLines value."));
148                                 }
149                                 ViewState ["GridLines"] = value;
150                                 SetBit ((int) TableStyles.GridLines);
151                         }
152                 }
153
154 #if NET_2_0
155                 [NotifyParentProperty (true)]
156 #else
157                 [Bindable (true)]
158 #endif
159                 [DefaultValue (HorizontalAlign.NotSet)]
160                 [WebSysDescription ("")]
161                 [WebCategory ("Layout")]
162                 public virtual HorizontalAlign HorizontalAlign {
163                         get {
164                                 if (!CheckBit ((int) TableStyles.HorizontalAlign))
165                                         return HorizontalAlign.NotSet;
166                                 return (HorizontalAlign) ViewState ["HorizontalAlign"];
167                         }
168                         set {
169                                 // avoid reflection
170                                 if ((value < HorizontalAlign.NotSet) || (value > HorizontalAlign.Justify)) {
171                                         // LAMESPEC: documented as ArgumentException
172                                         throw new ArgumentOutOfRangeException (Locale.GetText ("Invalid HorizontalAlign value."));
173                                 }
174                                 ViewState ["HorizontalAlign"] = value;
175                                 SetBit ((int) TableStyles.HorizontalAlign);
176                         }
177                 }
178 #if NET_4_0
179                 [MonoTODO ("collapse style should be rendered only for browsers which support that.")]
180 #endif
181                 public override void AddAttributesToRender (HtmlTextWriter writer, WebControl owner)
182                 {
183                         base.AddAttributesToRender (writer, owner);
184                         if (writer == null)
185                                 return;
186
187                         // note: avoid calling properties multiple times
188                         int i = CellSpacing;
189                         if (i != -1) {
190                                 writer.AddAttribute (HtmlTextWriterAttribute.Cellspacing, i.ToString (Helpers.InvariantCulture), false);
191                                 if (i == 0)
192                                         writer.AddStyleAttribute(HtmlTextWriterStyle.BorderCollapse, "collapse");
193                         }
194
195                         i = CellPadding;
196                         if (i != -1)
197                                 writer.AddAttribute (HtmlTextWriterAttribute.Cellpadding, i.ToString (Helpers.InvariantCulture), false);
198                         
199                         GridLines g = GridLines;
200                         switch (g) {
201                         case GridLines.Horizontal:
202                                 writer.AddAttribute (HtmlTextWriterAttribute.Rules, "rows", false);
203                                 break;
204                         case GridLines.Vertical:
205                                 writer.AddAttribute (HtmlTextWriterAttribute.Rules, "cols", false);
206                                 break;
207                         case GridLines.Both:
208                                 writer.AddAttribute (HtmlTextWriterAttribute.Rules, "all", false);
209                                 break;
210                         }
211
212                         // note: avoid ToString on the enum
213                         switch (HorizontalAlign) {
214                         case HorizontalAlign.Left:
215                                 writer.AddAttribute (HtmlTextWriterAttribute.Align, "left", false);
216                                 break;
217                         case HorizontalAlign.Center:
218                                 writer.AddAttribute (HtmlTextWriterAttribute.Align, "center", false);
219                                 break;
220                         case HorizontalAlign.Right:
221                                 writer.AddAttribute (HtmlTextWriterAttribute.Align, "right", false);
222                                 break;
223                         case HorizontalAlign.Justify:
224                                 writer.AddAttribute (HtmlTextWriterAttribute.Align, "justify", false);
225                                 break;
226                         }
227 #if NET_4_0
228                         if (g != GridLines.None && BorderWidth.IsEmpty)
229                                 writer.AddAttribute (HtmlTextWriterAttribute.Border, "1", false);
230 #else
231                         // border (=0) is always present (and base class doesn't seems to add it)
232                         // but border is "promoted" to 1 if gridlines are present (with BorderWidth == 0)
233                         if (g == GridLines.None) {
234                                 writer.AddAttribute (HtmlTextWriterAttribute.Border, "0", false);
235                         } else if (BorderWidth.IsEmpty) {
236                                 writer.AddAttribute (HtmlTextWriterAttribute.Border, "1", false);
237                         } else {
238                                 writer.AddAttribute (HtmlTextWriterAttribute.Border, BorderWidth.Value.ToString (Helpers.InvariantCulture));
239                         }
240 #endif
241 #if !NET_2_0
242                         string s = BackImageUrl;
243                         if (s.Length > 0) {
244                                 if (owner != null)
245                                         s = owner.ResolveClientUrl (s);
246                                 s = String.Concat ("url(", s, ")");
247                                 writer.AddStyleAttribute (HtmlTextWriterStyle.BackgroundImage, s);
248                         }
249 #endif
250                 }
251
252                 void Copy (string name, TableStyles s, Style source)
253                 {
254                         if (source.CheckBit ((int) s)) {
255                                 object o = source.ViewState [name];
256                                 if (o != null) {
257                                         ViewState [name] = o;
258                                         SetBit ((int) s);
259                                 }
260                         }
261                 }
262
263                 public override void CopyFrom (Style s)
264                 {
265                         // note: styles is copied in base
266                         base.CopyFrom (s);
267                         if ((s != null) && !s.IsEmpty) {
268                                 Copy ("BackImageUrl", TableStyles.BackImageUrl, s);
269                                 Copy ("CellPadding", TableStyles.CellPadding, s);
270                                 Copy ("CellSpacing", TableStyles.CellSpacing, s);
271                                 Copy ("GridLines", TableStyles.GridLines, s);
272                                 Copy ("HorizontalAlign", TableStyles.HorizontalAlign, s);
273                         }
274                 }
275
276                 void Merge (string name, TableStyles s, Style source)
277                 {
278                         if ((!CheckBit ((int) s)) && (source.CheckBit ((int) s))) {
279                                 object o = source.ViewState [name];
280                                 if (o != null) {
281                                         ViewState [name] = o;
282                                         SetBit ((int) s);
283                                 }
284                         }
285                 }
286
287                 public override void MergeWith (Style s)
288                 {
289                         // if we're empty then it's like a copy
290                         if (IsEmpty) {
291                                 CopyFrom (s);
292                         } else {
293                                 base.MergeWith (s);
294                                 if ((s != null) && !s.IsEmpty) {
295                                         Merge ("BackImageUrl", TableStyles.BackImageUrl, s);
296                                         Merge ("CellPadding", TableStyles.CellPadding, s);
297                                         Merge ("CellSpacing", TableStyles.CellSpacing, s);
298                                         Merge ("GridLines", TableStyles.GridLines, s);
299                                         Merge ("HorizontalAlign", TableStyles.HorizontalAlign, s);
300                                 }
301                         }
302                 }
303
304                 public override void Reset ()
305                 {
306                         if (CheckBit ((int) TableStyles.BackImageUrl))
307                                 ViewState.Remove ("BackImageUrl");
308                         if (CheckBit ((int) TableStyles.CellPadding))
309                                 ViewState.Remove ("CellPadding");
310                         if (CheckBit ((int) TableStyles.CellSpacing))
311                                 ViewState.Remove ("CellSpacing");
312                         if (CheckBit ((int) TableStyles.GridLines))
313                                 ViewState.Remove ("GridLines");
314                         if (CheckBit ((int) TableStyles.HorizontalAlign))
315                                 ViewState.Remove ("HorizontalAlign");
316                         // call base at the end because "styles" will reset there
317                         base.Reset ();
318                 }
319 #if NET_2_0
320                 protected override void FillStyleAttributes (CssStyleCollection attributes, IUrlResolutionService urlResolver)
321                 {
322                         if (attributes != null) {
323                                 string url = BackImageUrl;
324                                 if (url.Length > 0) {
325                                         if (urlResolver != null)
326                                                 url = urlResolver.ResolveClientUrl (url);
327                                         attributes.Add (HtmlTextWriterStyle.BackgroundImage, url);
328                                 }
329                         }
330                         base.FillStyleAttributes (attributes, urlResolver);
331                 }
332 #endif
333
334         }
335 }