2010-03-06 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
179
180                 public override void AddAttributesToRender (HtmlTextWriter writer, WebControl owner)
181                 {
182                         base.AddAttributesToRender (writer, owner);
183                         if (writer == null)
184                                 return;
185
186                         // note: avoid calling properties multiple times
187                         int i = CellPadding;
188                         if (i != -1)
189                                 writer.AddAttribute (HtmlTextWriterAttribute.Cellpadding, i.ToString (Helpers.InvariantCulture), false);
190                         
191                         i = CellSpacing;
192                         if (i != -1) {
193                                 writer.AddAttribute (HtmlTextWriterAttribute.Cellspacing, i.ToString (Helpers.InvariantCulture), false);
194                                 if (i == 0) {
195                                         writer.AddStyleAttribute(HtmlTextWriterStyle.BorderCollapse, "collapse");
196                                 }
197                         }
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
228                         // border (=0) is always present (and base class doesn't seems to add it)
229                         // but border is "promoted" to 1 if gridlines are present (with BorderWidth == 0)
230                         if (g == GridLines.None) {
231                                 writer.AddAttribute (HtmlTextWriterAttribute.Border, "0", false);
232                         } else if (BorderWidth.IsEmpty) {
233                                 writer.AddAttribute (HtmlTextWriterAttribute.Border, "1", false);
234                         } else {
235                                 writer.AddAttribute (HtmlTextWriterAttribute.Border, BorderWidth.Value.ToString (Helpers.InvariantCulture));
236                         }
237
238 #if !NET_2_0
239                         string s = BackImageUrl;
240                         if (s.Length > 0) {
241                                 if (owner != null)
242                                         s = owner.ResolveClientUrl (s);
243                                 s = String.Concat ("url(", s, ")");
244                                 writer.AddStyleAttribute (HtmlTextWriterStyle.BackgroundImage, s);
245                         }
246 #endif
247                 }
248
249                 void Copy (string name, TableStyles s, Style source)
250                 {
251                         if (source.CheckBit ((int) s)) {
252                                 object o = source.ViewState [name];
253                                 if (o != null) {
254                                         ViewState [name] = o;
255                                         SetBit ((int) s);
256                                 }
257                         }
258                 }
259
260                 public override void CopyFrom (Style s)
261                 {
262                         // note: styles is copied in base
263                         base.CopyFrom (s);
264                         if ((s != null) && !s.IsEmpty) {
265                                 Copy ("BackImageUrl", TableStyles.BackImageUrl, s);
266                                 Copy ("CellPadding", TableStyles.CellPadding, s);
267                                 Copy ("CellSpacing", TableStyles.CellSpacing, s);
268                                 Copy ("GridLines", TableStyles.GridLines, s);
269                                 Copy ("HorizontalAlign", TableStyles.HorizontalAlign, s);
270                         }
271                 }
272
273                 void Merge (string name, TableStyles s, Style source)
274                 {
275                         if ((!CheckBit ((int) s)) && (source.CheckBit ((int) s))) {
276                                 object o = source.ViewState [name];
277                                 if (o != null) {
278                                         ViewState [name] = o;
279                                         SetBit ((int) s);
280                                 }
281                         }
282                 }
283
284                 public override void MergeWith (Style s)
285                 {
286                         // if we're empty then it's like a copy
287                         if (IsEmpty) {
288                                 CopyFrom (s);
289                         } else {
290                                 base.MergeWith (s);
291                                 if ((s != null) && !s.IsEmpty) {
292                                         Merge ("BackImageUrl", TableStyles.BackImageUrl, s);
293                                         Merge ("CellPadding", TableStyles.CellPadding, s);
294                                         Merge ("CellSpacing", TableStyles.CellSpacing, s);
295                                         Merge ("GridLines", TableStyles.GridLines, s);
296                                         Merge ("HorizontalAlign", TableStyles.HorizontalAlign, s);
297                                 }
298                         }
299                 }
300
301                 public override void Reset ()
302                 {
303                         if (CheckBit ((int) TableStyles.BackImageUrl))
304                                 ViewState.Remove ("BackImageUrl");
305                         if (CheckBit ((int) TableStyles.CellPadding))
306                                 ViewState.Remove ("CellPadding");
307                         if (CheckBit ((int) TableStyles.CellSpacing))
308                                 ViewState.Remove ("CellSpacing");
309                         if (CheckBit ((int) TableStyles.GridLines))
310                                 ViewState.Remove ("GridLines");
311                         if (CheckBit ((int) TableStyles.HorizontalAlign))
312                                 ViewState.Remove ("HorizontalAlign");
313                         // call base at the end because "styles" will reset there
314                         base.Reset ();
315                 }
316 #if NET_2_0
317                 protected override void FillStyleAttributes (CssStyleCollection attributes, IUrlResolutionService urlResolver)
318                 {
319                         if (attributes != null) {
320                                 string url = BackImageUrl;
321                                 if (url.Length > 0) {
322                                         if (urlResolver != null)
323                                                 url = urlResolver.ResolveClientUrl (url);
324                                         attributes.Add (HtmlTextWriterStyle.BackgroundImage, url);
325                                 }
326                         }
327                         base.FillStyleAttributes (attributes, urlResolver);
328                 }
329 #endif
330
331         }
332 }