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