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.Security.Permissions;
34 namespace System.Web.UI.WebControls {
36 // CAS - no inheritance demand required because the class is sealed
37 [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
38 public sealed class RepeatInfo {
40 // What is baseControl for ?
41 public void RenderRepeater (HtmlTextWriter w, IRepeatInfoUser user, Style controlStyle, WebControl baseControl)
45 if (RepeatDirection == RepeatDirection.Vertical)
46 RenderVert (w, user, controlStyle, baseControl);
48 RenderHoriz (w, user, controlStyle, baseControl);
51 void RenderBr (HtmlTextWriter w)
62 void RenderVert (HtmlTextWriter w, IRepeatInfoUser user, Style controlStyle, WebControl baseControl)
64 int itms = user.RepeatedItemCount;
65 // total number of rows/columns in our table
66 int cols = RepeatColumns == 0 ? 1 : RepeatColumns;
67 // this gets ceil (itms / cols)
68 int rows = (itms + cols - 1) / cols;
69 bool sep = user.HasSeparators;
70 bool oti = OuterTableImplied;
71 int hdr_span = cols * ((sep && cols != 1) ? 2 : 1);
73 bool table = RepeatLayout == RepeatLayout.Table && !oti;
76 bool show_empty_trailing_items = true;
77 bool show_empty_trailing_sep = true;
79 bool show_empty_trailing_items = false;
80 bool show_empty_trailing_sep = false;
84 RenderBeginTag (w, controlStyle, baseControl);
89 user.RenderItem (ListItemType.Header, -1, this, w);
91 w.RenderBeginTag (HtmlTextWriterTag.Tr);
92 // Make sure the header takes up the full width. We have two
93 // columns per item if we are using separators, otherwise
96 w.AddAttribute (HtmlTextWriterAttribute.Colspan, hdr_span.ToString ());
98 Style s = user.GetItemStyle (ListItemType.Header, -1);
100 s.AddAttributesToRender (w);
102 w.RenderBeginTag (HtmlTextWriterTag.Td);
103 user.RenderItem (ListItemType.Header, -1, this, w);
104 w.RenderEndTag (); // td
105 w.RenderEndTag (); // tr
107 user.RenderItem (ListItemType.Header, -1, this, w);
112 for (int r = 0; r < rows; r ++) {
114 w.RenderBeginTag (HtmlTextWriterTag.Tr);
116 for (int c = 0; c < cols; c ++) {
117 // Find the item number we are in according to the repeat
119 int item = index_vert (rows, cols, r, c, itms);
121 // This item is blank because there there not enough items
122 // to make a full row.
123 if (!show_empty_trailing_items && item >= itms)
129 s = user.GetItemStyle (ListItemType.Item, item);
131 s.AddAttributesToRender (w);
132 w.RenderBeginTag (HtmlTextWriterTag.Td);
136 user.RenderItem (ListItemType.Item, item, this, w);
139 w.RenderEndTag (); // td
141 if (sep && cols != 1) {
143 if (item < itms - 1) {
144 Style s = user.GetItemStyle (ListItemType.Separator, item);
146 s.AddAttributesToRender (w);
148 if (item < itms - 1 || show_empty_trailing_sep)
149 w.RenderBeginTag (HtmlTextWriterTag.Td);
153 user.RenderItem (ListItemType.Separator, item, this, w);
155 if (table && (item < itms - 1 || show_empty_trailing_sep))
156 w.RenderEndTag (); // td
161 w.RenderEndTag (); // tr
162 } else if (r != rows - 1) {
166 if (sep && r != rows - 1 /* no sep on last item */ && cols == 1) {
168 w.RenderBeginTag (HtmlTextWriterTag.Tr);
169 Style s = user.GetItemStyle (ListItemType.Separator, r);
171 s.AddAttributesToRender (w);
173 w.RenderBeginTag (HtmlTextWriterTag.Td);
176 /* 2.0 doesn't render this <br /> */
181 user.RenderItem (ListItemType.Separator, r, this, w);
184 w.RenderEndTag (); // td
185 w.RenderEndTag (); // tr
193 if (user.HasFooter) {
195 user.RenderItem (ListItemType.Footer, -1, this, w);
197 w.RenderBeginTag (HtmlTextWriterTag.Tr);
199 w.AddAttribute (HtmlTextWriterAttribute.Colspan, hdr_span.ToString ());
201 Style s = user.GetItemStyle (ListItemType.Footer, -1);
203 s.AddAttributesToRender (w);
205 w.RenderBeginTag (HtmlTextWriterTag.Td);
206 user.RenderItem (ListItemType.Footer, -1, this, w);
207 w.RenderEndTag (); // td
208 w.RenderEndTag (); // tr
210 // avoid dups on 0 items
213 user.RenderItem (ListItemType.Footer, -1, this, w);
217 w.RenderEndTag (); // table/span
221 void RenderHoriz (HtmlTextWriter w, IRepeatInfoUser user, Style controlStyle, WebControl baseControl)
223 int itms = user.RepeatedItemCount;
224 // total number of rows/columns in our table
225 int cols = RepeatColumns == 0 ? itms : RepeatColumns;
226 // this gets ceil (itms / cols)
227 int rows = cols == 0 ? 0 : (itms + cols - 1) / cols;
228 bool sep = user.HasSeparators;
229 //bool oti = OuterTableImplied;
230 int hdr_span = cols * (sep ? 2 : 1);
232 bool table = RepeatLayout == RepeatLayout.Table;
235 bool show_empty_trailing_items = true;
236 bool show_empty_trailing_sep = true;
238 bool show_empty_trailing_items = false;
239 bool show_empty_trailing_sep = false;
242 RenderBeginTag (w, controlStyle, baseControl);
245 if (user.HasHeader) {
247 w.RenderBeginTag (HtmlTextWriterTag.Tr);
248 // Make sure the header takes up the full width. We have two
249 // columns per item if we are using separators, otherwise
252 w.AddAttribute (HtmlTextWriterAttribute.Colspan, hdr_span.ToString ());
254 Style s = user.GetItemStyle (ListItemType.Header, -1);
256 s.AddAttributesToRender (w);
258 w.RenderBeginTag (HtmlTextWriterTag.Td);
259 user.RenderItem (ListItemType.Header, -1, this, w);
260 w.RenderEndTag (); // td
261 w.RenderEndTag (); // tr
263 user.RenderItem (ListItemType.Header, -1, this, w);
264 if (!table && RepeatColumns != 0 && itms != 0)
269 for (int r = 0; r < rows; r ++) {
271 w.RenderBeginTag (HtmlTextWriterTag.Tr);
273 for (int c = 0; c < cols; c ++) {
274 // Find the item number we are in according to the repeat
276 int item = r * cols + c;
278 // This item is blank because there there not enough items
279 // to make a full row.
280 if (!show_empty_trailing_items && item >= itms)
286 s = user.GetItemStyle (ListItemType.Item, item);
289 s.AddAttributesToRender (w);
290 w.RenderBeginTag (HtmlTextWriterTag.Td);
294 user.RenderItem (ListItemType.Item, item, this, w);
297 w.RenderEndTag (); // td
301 if (item < itms - 1) {
302 Style s = user.GetItemStyle (ListItemType.Separator, item);
304 s.AddAttributesToRender (w);
306 if (item < itms - 1 || show_empty_trailing_sep)
307 w.RenderBeginTag (HtmlTextWriterTag.Td);
311 user.RenderItem (ListItemType.Separator, item, this, w);
313 if (table && (item < itms - 1 || show_empty_trailing_sep))
314 w.RenderEndTag (); // td
320 w.RenderEndTag (); // tr
321 } else if (!(r == rows -1 && RepeatColumns == 0))
327 if (user.HasFooter) {
329 w.RenderBeginTag (HtmlTextWriterTag.Tr);
331 w.AddAttribute (HtmlTextWriterAttribute.Colspan, hdr_span.ToString ());
333 Style s = user.GetItemStyle (ListItemType.Footer, -1);
335 s.AddAttributesToRender (w);
337 w.RenderBeginTag (HtmlTextWriterTag.Td);
338 user.RenderItem (ListItemType.Footer, -1, this, w);
339 w.RenderEndTag (); // td
340 w.RenderEndTag (); // tr
342 user.RenderItem (ListItemType.Footer, -1, this, w);
346 w.RenderEndTag (); // table/span
350 int index_vert (int rows, int cols, int r, int c, int items)
352 int last = items % cols;
356 if (r == rows - 1 && c >= last)
363 add = last * rows + (c-last) * (rows-1);
371 void RenderBeginTag (HtmlTextWriter w, Style s, WebControl wc)
374 if (RepeatLayout == RepeatLayout.Table)
380 c.CopyBaseAttributes (wc);
382 c.RenderBeginTag (w);
386 bool outer_table_implied;
387 public bool OuterTableImplied {
389 return outer_table_implied;
392 outer_table_implied = value;
397 public int RepeatColumns {
406 RepeatDirection dir = RepeatDirection.Vertical;
407 public RepeatDirection RepeatDirection {
412 if (value != RepeatDirection.Horizontal &&
413 value != RepeatDirection.Vertical)
414 throw new ArgumentOutOfRangeException ();
421 public RepeatLayout RepeatLayout {
426 if (value != RepeatLayout.Flow &&
427 value != RepeatLayout.Table)
428 throw new ArgumentOutOfRangeException ();
433 [Conditional ("DEBUG_REPEAT_INFO")]
434 internal void PrintValues (IRepeatInfoUser riu)
436 string s = String.Format ("Layout {0}; Direction {1}; Cols {2}; OuterTableImplied {3}\n" +
437 "User: itms {4}, hdr {5}; ftr {6}; sep {7}", RepeatLayout, RepeatDirection,
438 RepeatColumns, OuterTableImplied, riu.RepeatedItemCount, riu.HasSeparators, riu.HasHeader,
439 riu.HasFooter, riu.HasSeparators
441 Console.WriteLine (s);
442 if (HttpContext.Current != null)
443 HttpContext.Current.Trace.Write (s);