2 // System.Web.UI.WebControls.RepeatInfo.cs
5 // Ben Maurer (bmaurer@novell.com)
7 // (C) 2005 Novell, Inc (http://www.novell.com)
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
29 //#define DEBUG_REPEAT_INFO
31 using System.Diagnostics;
32 using System.ComponentModel;
33 using System.Security.Permissions;
35 namespace System.Web.UI.WebControls {
37 // CAS - no inheritance demand required because the class is sealed
38 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
39 public sealed class RepeatInfo {
41 // What is baseControl for ?
42 public void RenderRepeater (HtmlTextWriter w, IRepeatInfoUser user, Style controlStyle, WebControl baseControl)
46 if (RepeatDirection == RepeatDirection.Vertical)
47 RenderVert (w, user, controlStyle, baseControl);
49 RenderHoriz (w, user, controlStyle, baseControl);
52 void RenderBr (HtmlTextWriter w)
63 void RenderVert (HtmlTextWriter w, IRepeatInfoUser user, Style controlStyle, WebControl baseControl)
65 int itms = user.RepeatedItemCount;
66 // total number of rows/columns in our table
67 int cols = RepeatColumns == 0 ? 1 : RepeatColumns;
68 // this gets ceil (itms / cols)
69 int rows = (itms + cols - 1) / cols;
70 bool sep = user.HasSeparators;
71 bool oti = OuterTableImplied;
72 int hdr_span = cols * ((sep && cols != 1) ? 2 : 1);
74 bool table = RepeatLayout == RepeatLayout.Table && !oti;
77 bool show_empty_trailing_items = true;
78 bool show_empty_trailing_sep = true;
80 bool show_empty_trailing_items = false;
81 bool show_empty_trailing_sep = false;
85 RenderBeginTag (w, controlStyle, baseControl);
87 if (Caption.Length > 0) {
88 if (CaptionAlign != TableCaptionAlign.NotSet)
89 w.AddAttribute (HtmlTextWriterAttribute.Align, CaptionAlign.ToString());
91 w.RenderBeginTag (HtmlTextWriterTag.Caption);
100 user.RenderItem (ListItemType.Header, -1, this, w);
102 w.RenderBeginTag (HtmlTextWriterTag.Tr);
103 // Make sure the header takes up the full width. We have two
104 // columns per item if we are using separators, otherwise
107 w.AddAttribute (HtmlTextWriterAttribute.Colspan, hdr_span.ToString (), false);
109 if (UseAccessibleHeader)
110 w.AddAttribute ("scope", "col", false);
112 Style s = user.GetItemStyle (ListItemType.Header, -1);
114 s.AddAttributesToRender (w);
116 if (UseAccessibleHeader)
117 w.RenderBeginTag (HtmlTextWriterTag.Th);
119 w.RenderBeginTag (HtmlTextWriterTag.Td);
121 user.RenderItem (ListItemType.Header, -1, this, w);
122 w.RenderEndTag (); // td
123 w.RenderEndTag (); // tr
125 user.RenderItem (ListItemType.Header, -1, this, w);
130 for (int r = 0; r < rows; r ++) {
132 w.RenderBeginTag (HtmlTextWriterTag.Tr);
134 for (int c = 0; c < cols; c ++) {
135 // Find the item number we are in according to the repeat
137 int item = index_vert (rows, cols, r, c, itms);
139 // This item is blank because there there not enough items
140 // to make a full row.
141 if (!show_empty_trailing_items && item >= itms)
147 s = user.GetItemStyle (ListItemType.Item, item);
149 s.AddAttributesToRender (w);
150 w.RenderBeginTag (HtmlTextWriterTag.Td);
154 user.RenderItem (ListItemType.Item, item, this, w);
157 w.RenderEndTag (); // td
159 if (sep && cols != 1) {
161 if (item < itms - 1) {
162 Style s = user.GetItemStyle (ListItemType.Separator, item);
164 s.AddAttributesToRender (w);
166 if (item < itms - 1 || show_empty_trailing_sep)
167 w.RenderBeginTag (HtmlTextWriterTag.Td);
171 user.RenderItem (ListItemType.Separator, item, this, w);
173 if (table && (item < itms - 1 || show_empty_trailing_sep))
174 w.RenderEndTag (); // td
179 w.RenderEndTag (); // tr
180 } else if (r != rows - 1) {
184 if (sep && r != rows - 1 /* no sep on last item */ && cols == 1) {
186 w.RenderBeginTag (HtmlTextWriterTag.Tr);
187 Style s = user.GetItemStyle (ListItemType.Separator, r);
189 s.AddAttributesToRender (w);
191 w.RenderBeginTag (HtmlTextWriterTag.Td);
194 /* 2.0 doesn't render this <br /> */
199 user.RenderItem (ListItemType.Separator, r, this, w);
202 w.RenderEndTag (); // td
203 w.RenderEndTag (); // tr
211 if (user.HasFooter) {
213 user.RenderItem (ListItemType.Footer, -1, this, w);
215 w.RenderBeginTag (HtmlTextWriterTag.Tr);
217 w.AddAttribute (HtmlTextWriterAttribute.Colspan, hdr_span.ToString (), false);
219 Style s = user.GetItemStyle (ListItemType.Footer, -1);
221 s.AddAttributesToRender (w);
223 w.RenderBeginTag (HtmlTextWriterTag.Td);
224 user.RenderItem (ListItemType.Footer, -1, this, w);
225 w.RenderEndTag (); // td
226 w.RenderEndTag (); // tr
228 // avoid dups on 0 items
231 user.RenderItem (ListItemType.Footer, -1, this, w);
235 w.RenderEndTag (); // table/span
239 void RenderHoriz (HtmlTextWriter w, IRepeatInfoUser user, Style controlStyle, WebControl baseControl)
241 int itms = user.RepeatedItemCount;
242 // total number of rows/columns in our table
243 int cols = RepeatColumns == 0 ? itms : RepeatColumns;
244 // this gets ceil (itms / cols)
245 int rows = cols == 0 ? 0 : (itms + cols - 1) / cols;
246 bool sep = user.HasSeparators;
247 //bool oti = OuterTableImplied;
248 int hdr_span = cols * (sep ? 2 : 1);
250 bool table = RepeatLayout == RepeatLayout.Table;
253 bool show_empty_trailing_items = true;
254 bool show_empty_trailing_sep = true;
256 bool show_empty_trailing_items = false;
257 bool show_empty_trailing_sep = false;
260 RenderBeginTag (w, controlStyle, baseControl);
262 if (Caption.Length > 0) {
263 if (CaptionAlign != TableCaptionAlign.NotSet)
264 w.AddAttribute (HtmlTextWriterAttribute.Align, CaptionAlign.ToString());
266 w.RenderBeginTag (HtmlTextWriterTag.Caption);
273 if (user.HasHeader) {
275 w.RenderBeginTag (HtmlTextWriterTag.Tr);
276 // Make sure the header takes up the full width. We have two
277 // columns per item if we are using separators, otherwise
280 w.AddAttribute (HtmlTextWriterAttribute.Colspan, hdr_span.ToString (), false);
282 if (UseAccessibleHeader)
283 w.AddAttribute ("scope", "col", false);
285 Style s = user.GetItemStyle (ListItemType.Header, -1);
287 s.AddAttributesToRender (w);
289 if (UseAccessibleHeader)
290 w.RenderBeginTag (HtmlTextWriterTag.Th);
292 w.RenderBeginTag (HtmlTextWriterTag.Td);
294 user.RenderItem (ListItemType.Header, -1, this, w);
295 w.RenderEndTag (); // td
296 w.RenderEndTag (); // tr
298 user.RenderItem (ListItemType.Header, -1, this, w);
299 if (!table && RepeatColumns != 0 && itms != 0)
304 for (int r = 0; r < rows; r ++) {
306 w.RenderBeginTag (HtmlTextWriterTag.Tr);
308 for (int c = 0; c < cols; c ++) {
309 // Find the item number we are in according to the repeat
311 int item = r * cols + c;
313 // This item is blank because there there not enough items
314 // to make a full row.
315 if (!show_empty_trailing_items && item >= itms)
321 s = user.GetItemStyle (ListItemType.Item, item);
324 s.AddAttributesToRender (w);
325 w.RenderBeginTag (HtmlTextWriterTag.Td);
329 user.RenderItem (ListItemType.Item, item, this, w);
332 w.RenderEndTag (); // td
336 if (item < itms - 1) {
337 Style s = user.GetItemStyle (ListItemType.Separator, item);
339 s.AddAttributesToRender (w);
341 if (item < itms - 1 || show_empty_trailing_sep)
342 w.RenderBeginTag (HtmlTextWriterTag.Td);
346 user.RenderItem (ListItemType.Separator, item, this, w);
348 if (table && (item < itms - 1 || show_empty_trailing_sep))
349 w.RenderEndTag (); // td
355 w.RenderEndTag (); // tr
356 } else if (!(r == rows -1 && RepeatColumns == 0))
362 if (user.HasFooter) {
364 w.RenderBeginTag (HtmlTextWriterTag.Tr);
366 w.AddAttribute (HtmlTextWriterAttribute.Colspan, hdr_span.ToString (), false);
368 Style s = user.GetItemStyle (ListItemType.Footer, -1);
370 s.AddAttributesToRender (w);
372 w.RenderBeginTag (HtmlTextWriterTag.Td);
373 user.RenderItem (ListItemType.Footer, -1, this, w);
374 w.RenderEndTag (); // td
375 w.RenderEndTag (); // tr
377 user.RenderItem (ListItemType.Footer, -1, this, w);
381 w.RenderEndTag (); // table/span
385 int index_vert (int rows, int cols, int r, int c, int items)
387 int last = items % cols;
391 if (r == rows - 1 && c >= last)
398 add = last * rows + (c-last) * (rows-1);
406 void RenderBeginTag (HtmlTextWriter w, Style s, WebControl wc)
409 if (RepeatLayout == RepeatLayout.Table)
415 c.CopyBaseAttributes (wc);
417 c.Enabled = wc.Enabled;
418 c.RenderBeginTag (w);
422 bool outer_table_implied;
423 public bool OuterTableImplied {
425 return outer_table_implied;
428 outer_table_implied = value;
433 public int RepeatColumns {
442 RepeatDirection dir = RepeatDirection.Vertical;
443 public RepeatDirection RepeatDirection {
448 if (value != RepeatDirection.Horizontal &&
449 value != RepeatDirection.Vertical)
450 throw new ArgumentOutOfRangeException ();
457 public RepeatLayout RepeatLayout {
462 if (value != RepeatLayout.Flow &&
463 value != RepeatLayout.Table)
464 throw new ArgumentOutOfRangeException ();
469 [Conditional ("DEBUG_REPEAT_INFO")]
470 internal void PrintValues (IRepeatInfoUser riu)
472 string s = String.Format ("Layout {0}; Direction {1}; Cols {2}; OuterTableImplied {3}\n" +
473 "User: itms {4}, hdr {5}; ftr {6}; sep {7}", RepeatLayout, RepeatDirection,
474 RepeatColumns, OuterTableImplied, riu.RepeatedItemCount, riu.HasSeparators, riu.HasHeader,
475 riu.HasFooter, riu.HasSeparators
477 Console.WriteLine (s);
478 if (HttpContext.Current != null)
479 HttpContext.Current.Trace.Write (s);
482 private string caption = "";
483 private TableCaptionAlign captionAlign = TableCaptionAlign.NotSet;
484 private bool useAccessibleHeader = false;
486 [WebSysDescription ("")]
487 [WebCategory ("Accessibility")]
488 public string Caption {
489 get {return caption;}
490 set { caption = value; }
493 [WebSysDescription ("")]
494 [DefaultValue (TableCaptionAlign.NotSet)]
495 [WebCategory ("Accessibility")]
496 public TableCaptionAlign CaptionAlign {
497 get {return captionAlign;}
498 set { captionAlign = value; }
501 [WebSysDescription ("")]
502 [DefaultValue (false)]
503 [WebCategory ("Accessibility")]
504 public bool UseAccessibleHeader {
505 get {return useAccessibleHeader;}
506 set { useAccessibleHeader = value; }