Merge pull request #2916 from ludovic-henry/fix-40306
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / DataControlField.cs
1 //
2 // System.Web.UI.WebControls.DataControlField.cs
3 //
4 // Authors:
5 //      Sanjay Gupta (gsanjay@novell.com)
6 //      Lluis Sanchez Gual (lluis@novell.com)
7 //
8 // (C) 2004-2010 Novell, Inc. (http://www.novell.com)
9 //
10
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31 using System.Collections;
32 using System.Collections.Specialized;
33 using System.Web.UI;
34 using System.ComponentModel;
35 using System.Security.Permissions;
36
37 namespace System.Web.UI.WebControls
38 {
39         [DefaultPropertyAttribute ("HeaderText")]
40         [TypeConverterAttribute (typeof(ExpandableObjectConverter))]
41         [AspNetHostingPermissionAttribute (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
42         [AspNetHostingPermissionAttribute (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
43         public abstract class DataControlField : IStateManager, IDataSourceViewSchemaAccessor
44         {
45                 static readonly object fieldChangedEvent = new object ();
46                 
47                 bool tracking = false;
48                 StateBag viewState;
49                 Control control;
50                 Style controlStyle;
51                 TableItemStyle footerStyle;
52                 TableItemStyle headerStyle;
53                 TableItemStyle itemStyle;
54                 bool sortingEnabled;
55                 EventHandlerList events = new EventHandlerList ();
56                 
57                 internal event EventHandler FieldChanged {
58                         add { events.AddHandler (fieldChangedEvent, value); }
59                         remove { events.RemoveHandler (fieldChangedEvent, value); }
60                 }
61                 
62                 protected DataControlField()
63                 { 
64                         viewState = new StateBag ();
65                 }
66                 
67                 internal void SetDirty ()
68                 {
69                         viewState.SetDirty (true);
70                 }
71                 
72                 protected StateBag ViewState {
73                         get { return viewState; }
74                 }
75
76                 public virtual void ExtractValuesFromCell (IOrderedDictionary dictionary,
77                         DataControlFieldCell cell, DataControlRowState rowState, bool includeReadOnly)
78                 {
79                 }
80
81                 public virtual bool Initialize (bool sortingEnabled, Control control)
82                 {
83                         this.sortingEnabled = sortingEnabled;
84                         this.control = control;
85                         return false;
86                 }
87
88                 public virtual void InitializeCell (DataControlFieldCell cell,
89                         DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
90                 {
91                         if (cellType == DataControlCellType.Header) {
92                                 if (HeaderText.Length > 0 && sortingEnabled && SortExpression.Length > 0)
93                                         cell.Controls.Add ((Control) DataControlButton.CreateButton (String.IsNullOrEmpty (HeaderImageUrl) ? ButtonType.Link : ButtonType.Image, control, HeaderText, HeaderImageUrl, DataControlCommands.SortCommandName, SortExpression, true));
94                                 else if (HeaderImageUrl.Length > 0) {
95                                         Image image = new Image ();
96                                         image.ImageUrl = HeaderImageUrl;
97                                         cell.Controls.Add (image);
98                                 } else
99                                         cell.Text = HeaderText.Length > 0 ? HeaderText : " ";
100                         } else if (cellType == DataControlCellType.Footer) {
101                                 string footerText = FooterText;
102                                 cell.Text = (footerText.Length > 0) ? footerText : " ";
103                         }
104                 }
105                 
106                 protected internal DataControlField CloneField ()
107                 {
108                         DataControlField field = CreateField ();
109                         CopyProperties (field);
110                         return field;
111                 }
112                 
113                 protected abstract DataControlField CreateField ();
114                 
115                 protected virtual void CopyProperties (DataControlField newField)
116                 {
117                         newField.AccessibleHeaderText = AccessibleHeaderText;
118                         newField.ControlStyle.CopyFrom (ControlStyle);
119                         newField.FooterStyle.CopyFrom (FooterStyle);
120                         newField.FooterText = FooterText;
121                         newField.HeaderImageUrl = HeaderImageUrl;
122                         newField.HeaderStyle.CopyFrom (HeaderStyle);
123                         newField.HeaderText = HeaderText;
124                         newField.InsertVisible = InsertVisible;
125                         newField.ItemStyle.CopyFrom (ItemStyle);
126                         newField.ShowHeader = ShowHeader;
127                         newField.SortExpression = SortExpression;
128                         newField.Visible = Visible;
129                 }
130                 
131                 protected virtual void OnFieldChanged ()
132                 {
133                         EventHandler eh = events [fieldChangedEvent] as EventHandler;
134                         
135                         if (eh != null)
136                                 eh (this, EventArgs.Empty);
137                 }       
138         
139                 protected virtual void LoadViewState (object savedState)
140                 {
141                         if (savedState == null)
142                                 return;
143                                 
144                         object [] states = (object []) savedState;
145                         viewState.LoadViewState (states[0]);
146                         
147                         if (states[1] != null)
148                                 ((IStateManager)ControlStyle).LoadViewState (states[1]);
149                         if (states[2] != null)
150                                 ((IStateManager)FooterStyle).LoadViewState (states[2]);
151                         if (states[3] != null)
152                                 ((IStateManager)HeaderStyle).LoadViewState (states[3]);
153                         if (states[4] != null)
154                                 ((IStateManager)ItemStyle).LoadViewState (states[4]);
155                 }
156
157                 protected virtual object SaveViewState ()
158                 {
159                         object[] state = new object [5];
160                         state [0] = viewState.SaveViewState ();
161                         if (controlStyle != null)
162                                 state [1] = ((IStateManager) controlStyle).SaveViewState ();
163                         if (footerStyle != null)
164                                 state [2] = ((IStateManager) footerStyle).SaveViewState ();
165                         if (headerStyle != null)
166                                 state [3] = ((IStateManager) headerStyle).SaveViewState ();
167                         if (itemStyle != null)
168                                 state [4] = ((IStateManager) itemStyle).SaveViewState ();
169                         
170                         if (state [0] == null && state [1] == null && state [2] == null && 
171                                 state [3] == null && state [4] == null)
172                                 return null;
173                                 
174                         return state;
175                 }
176
177                 protected virtual void TrackViewState ()
178                 {
179                         if (controlStyle != null) ((IStateManager) controlStyle).TrackViewState ();
180                         if (footerStyle != null) ((IStateManager) footerStyle).TrackViewState ();
181                         if (headerStyle != null) ((IStateManager) headerStyle).TrackViewState ();
182                         if (itemStyle != null) ((IStateManager) itemStyle).TrackViewState ();
183                         viewState.TrackViewState ();
184                         tracking = true;                        
185                 }
186                 
187                 public virtual void ValidateSupportsCallback ()
188                 {
189                         throw new NotSupportedException ("Callback not supported");
190                 }
191
192                 void IStateManager.LoadViewState (object savedState)
193                 {
194                         LoadViewState (savedState);
195                 }
196
197                 object IStateManager.SaveViewState ()
198                 {
199                         return SaveViewState ();
200                 }
201
202                 void IStateManager.TrackViewState ()
203                 {
204                         TrackViewState ();
205                 }
206                 
207                 internal Exception GetNotSupportedPropException (string propName)
208                 {
209                         return new System.NotSupportedException ("The property '" + propName + "' is not supported in " + GetType().Name); 
210                 }
211
212                 internal bool ControlStyleCreated { get { return controlStyle != null; } }
213                 
214                 internal bool HeaderStyleCreated { get { return headerStyle != null; } }
215                 
216                 internal bool FooterStyleCreated { get { return footerStyle != null; } }
217                 
218                 internal bool ItemStyleCreated { get { return itemStyle != null; } }
219
220                 [MonoTODO ("Render this")]
221                 [DefaultValueAttribute ("")]
222                 [LocalizableAttribute (true)]
223                 [WebCategoryAttribute ("Accessibility")]
224                 public virtual string AccessibleHeaderText {
225                         get {
226                                 object val = viewState ["accessibleHeaderText"];
227                                 return val != null ? (string) val : String.Empty;
228                         }
229                         set { 
230                                 viewState ["accessibleHeaderText"] = value;
231                                 OnFieldChanged ();
232                         }
233                 }
234
235                 protected Control Control {
236                         get { return control; }
237                 }
238
239                 [WebCategoryAttribute ("Styles")]
240                 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
241                 [DefaultValueAttribute (null)]
242                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
243                 public Style ControlStyle {
244                         get {
245                                 if (controlStyle == null) {
246                                         controlStyle = new Style ();
247                                         if (IsTrackingViewState)
248                                                 controlStyle.TrackViewState();
249                                 }
250                                 return controlStyle;
251                         }
252                 }
253         
254                 protected bool DesignMode {
255                         get { return control != null && control.Site != null ? control.Site.DesignMode : false; }
256                 }
257
258                 [DefaultValueAttribute (null)]
259                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
260                 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
261                 [WebCategoryAttribute ("Styles")]
262                 public TableItemStyle FooterStyle {
263                         get {
264                                 if (footerStyle == null) {
265                                         footerStyle = new TableItemStyle ();
266                                         if (IsTrackingViewState)
267                                                 footerStyle.TrackViewState();
268                                 }
269                                 return footerStyle;
270                         }
271                 }
272
273                 [LocalizableAttribute (true)]
274                 [WebCategoryAttribute ("Appearance")]
275                 [DefaultValue ("")]
276                 public virtual string FooterText {
277                         get {
278                                 object val = viewState ["footerText"];
279                                 return val != null ? (string) val : String.Empty;
280                         }
281                         set { 
282                                 viewState ["footerText"] = value;
283                                 OnFieldChanged ();
284                         }
285                 }
286
287                 [UrlPropertyAttribute]
288                 [DefaultValueAttribute ("")]
289                 [EditorAttribute ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
290                 [WebCategoryAttribute ("Appearance")]
291                 public virtual string HeaderImageUrl {
292                         get {
293                                 object val = viewState ["headerImageUrl"];
294                                 return val != null ? (string) val : String.Empty;
295                         }
296                         set { 
297                                 viewState ["headerImageUrl"] = value;
298                                 OnFieldChanged ();
299                         }
300                 }
301
302                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
303                 [WebCategoryAttribute ("Styles")]
304                 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
305                 [DefaultValueAttribute (null)]
306                 public TableItemStyle HeaderStyle {
307                         get {
308                                 if (headerStyle == null) {
309                                         headerStyle = new TableItemStyle ();
310                                         if (IsTrackingViewState)
311                                                 headerStyle.TrackViewState();
312                                 }
313                                 return headerStyle;
314                         }
315                 }
316
317                 [DefaultValueAttribute ("")]
318                 [LocalizableAttribute (true)]
319                 [WebCategoryAttribute ("Appearance")]
320                 public virtual string HeaderText {
321                         get {
322                                 object val = viewState ["headerText"];
323                                 return val != null ? (string) val : String.Empty;
324                         }
325                         set { 
326                                 viewState ["headerText"] = value;
327                                 OnFieldChanged ();
328                         }
329                 }
330
331                 [WebCategoryAttribute ("Behavior")]
332                 [DefaultValueAttribute (true)]
333                 public virtual bool InsertVisible {
334                         get {
335                                 object val = viewState ["InsertVisible"];
336                                 return val != null ? (bool) val : true;
337                         }
338                         set { 
339                                 viewState ["InsertVisible"] = value;
340                                 OnFieldChanged ();
341                         }
342                 }
343
344                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
345                 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
346                 [WebCategoryAttribute ("Styles")]
347                 [DefaultValueAttribute (null)]
348                 public TableItemStyle ItemStyle {
349                         get {
350                                 if (itemStyle == null) {
351                                         itemStyle = new TableItemStyle ();
352                                         if (IsTrackingViewState)
353                                                 itemStyle.TrackViewState();
354                                 }
355                                 return itemStyle;
356                         }
357                 }
358
359                 [WebCategoryAttribute ("Behavior")]
360                 [DefaultValueAttribute (true)]
361                 public virtual bool ShowHeader {
362                         get {
363                                 object val = viewState ["showHeader"];
364                                 return val != null ? (bool) val : true;
365                         }
366                         set { 
367                                 viewState ["showHeader"] = value;
368                                 OnFieldChanged ();
369                         }
370                 }
371
372                 [DefaultValueAttribute ("")]
373 //              [TypeConverterAttribute ("System.Web.UI.Design.DataSourceViewSchemaConverter, " + Consts.AssemblySystem_Design)]
374                 [WebCategoryAttribute ("Behavior")]
375                 public virtual string SortExpression {
376                         get {
377                                 object val = viewState ["sortExpression"];
378                                 return val != null ? (string) val : String.Empty;
379                         }
380                         set { 
381                                 viewState ["sortExpression"] = value;
382                                 OnFieldChanged ();
383                         }
384                 }
385
386                 [WebCategoryAttribute ("Behavior")]
387                 [DefaultValueAttribute (true)]
388                 public bool Visible {
389                         get {
390                                 object val = viewState ["visible"];
391                                 return val != null ? (bool) val : true;
392                         }
393                         set { 
394                                 if (value == Visible)
395                                         return;
396                                 viewState ["visible"] = value;
397                                 OnFieldChanged ();
398                         }
399                 }
400
401                 protected bool IsTrackingViewState
402                 {
403                         get { return tracking; }
404                 }
405
406                 bool IStateManager.IsTrackingViewState
407                 {
408                         get { return IsTrackingViewState; }
409                 }
410
411                 object IDataSourceViewSchemaAccessor.DataSourceViewSchema {
412                         get { return viewState ["dataSourceViewSchema"]; }
413                         set { 
414                                 viewState ["dataSourceViewSchema"] = value;
415                         }
416                 }
417
418                 public override string ToString ()
419                 {
420                         if (string.IsNullOrEmpty (HeaderText))
421                                 return base.ToString ();
422                         return HeaderText;
423                 }
424         }
425 }