Clover.NET coverage report - Coverage

Coverage timestamp: viernes, 12 de agosto de 2005 12:53:38 PM

File Stats: LOC: 578   Methods: 30
NCLOC: 340 Classes: 2
 
Source File Conditionals Statements Methods TOTAL
Web\WebControls\DataGrid.cs 84,8 % 80,7 % 86,7 % 82,4 %
coverage coverage
1   #region Copyright
2   /*
3   ShowX. Maps business objects into presentation layer.
4   Copyright (C) 2005 Jesus Diaz.
5  
6   This library is free software; you can redistribute it and/or
7   modify it under the terms of the GNU Lesser General Public
8   License as published by the Free Software Foundation; either
9   version 2.1 of the License, or (at your option) any later version.
10  
11   This library is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   Lesser General Public License for more details.
15  
16   You should have received a copy of the GNU Lesser General Public
17   License along with this library; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19  
20   For project details see: http://showx.sourceforge.net
21   */
22   #endregion
23  
24   using System;
25   using System.Collections;
26   using System.ComponentModel;
27   using System.Reflection;
28   using System.Web.UI;
29   using System.Web.UI.WebControls;
30   using ShowX.Config;
31   using ShowX.Web.WebBuilders;
32  
33   namespace ShowX.Web.WebControls
34   {
35   /// <summary>
36   /// Enumerates the valid operations to enable on an ShowX DataGrid.
37   /// </summary>
38   [Flags]
39   public enum DataGridOps {
40  
41   /// <summary>
42   /// Zero operations can be done over the DataGrid.
43   /// </summary>
44   None = 0,
45   /// <summary>
46   /// The DataGrid supports inplace editing, but doesn't support deletion.
47   /// </summary>
48   InplaceEditing = 2,
49   /// <summary>
50   /// The DataGrid supports deletion, but doesn't support inplace editing.
51   /// </summary>
52   Deletion = 4,
53   /// <summary>
54   /// The DataGrid supports all the operations (inplace editing and deletion).
55   /// </summary>
56   All = 8
57   }
58  
59   /// <summary>
60   /// Delegate to represent event to raise when queried results are obtained.
61   /// </summary>
62   public delegate void OnDeleteElemEventHandler(object elem);
63  
64   /// <summary>
65   /// DataGrid control inherit from System.Web.UI.WebControls.DataGrid and
66   /// builds himself from an ShowX type. The paging, sorting, editing and update
67   /// of the elements are automatically done.
68   /// </summary>
69   [DefaultProperty("Text"),
70   ToolboxData("<{0}:DataGrid runat=server></{0}:DataGrid>")]
71   public class DataGrid : System.Web.UI.WebControls.DataGrid
72   {
73  
74   /// <summary>
75   /// Event to to raise when queried results are obtained.
76   /// </summary>
77   public event OnDeleteElemEventHandler OnDeleteElem;
78  
79   #region Protected methods and variables
80  
81   TableItemStyle childControlStyle;
82  
83   /// <summary>
84   /// Temporal Data source.
85   /// </summary>
86   protected ArrayList dataSource;
87  
88   /// <summary>
89   /// Keeps track of the context in which this DataGrid operates.
90   /// </summary>
91   protected object context;
92  
93   /// <summary>
94   /// Do sort over a certain column of the data grid. the sort is made by
95   /// reflexion, over the type of the property associated to the column. If the
96   /// type is not a basic one, it has to implement the IComparable interfaz,
97   /// otherwise sorting will not work
98   /// </summary>
99   /// <param name="SortExpression">Expression to sort with. In columns generated
100   /// with DataGridBuilder class, this expression is the name of the ShowX
101   /// property associated to this column.</param>
102 56 protected void dgSort (string SortExpression)
103   {
104 56 if (SortExpression == null) return;
105  
106 27 PropertyInfo pInfo = Type.GetProperty(SortExpression);
107  
108 0 if (pInfo == null) return;
109  
110 27 dataSource.Sort(new CmpByProperty(pInfo,InvertSort));
111   }
112  
113   #endregion
114  
115   /// <summary>
116   /// Constructor
117   /// </summary>
118 35 public DataGrid()
119   {
120 35 EditItemIndex = -1;
121 35 AutoGenerateColumns = false;
122 35 InvertSort = false;
123 35 AllowPaging = true;
124 35 AllowSorting = true;
125   }
126  
127   /// <summary>
128   /// Reflex the ShowX type assigned to this DataGrid
129   /// </summary>
130   [Bindable(true), Category("Business"), DefaultValue("")]
131   protected Type Type
132   {
133 160 get
134   {
135 160 return (Type)(ViewState["ShowXObjectBrowserType"]);
136   }
137  
138 9 set
139   {
140 9 ViewState["ShowXObjectBrowserType"] = value;
141 9 this.ChildControlsCreated = false;
142 9 this.CurrentPageIndex = 0;
143 9 this.EditItemIndex = -1;
144 9 this.CreateChildControls();
145   }
146   }
147  
148   /// <summary>
149   /// <p>
150   /// BuildDataGrid allow to atomify the action of setting the type and the
151   /// context (optional) to a ShowX DataGrid. This is necesary because the two
152   /// approaches present a crossroad: when do you know that you have all the
153   /// information you need to build the DataGrid? When the type is assigned, or
154   /// when the context? But what if you don't need a context?
155   /// </p>
156   /// <p>The solution proposed is a single method overloaded, that recieves
157   /// one or two parameters (the type and, optionally, the context), gatering
158   /// all the needed information at once.</p>
159   /// </summary>
160   /// <param name="type">Type to associate to this DataGrid.</param>
161 9 public void BuildDataGrid(Type type)
162   {
163 9 this.Type = type;
164   }
165  
166   /// <summary>
167   /// See the comments of <c>BuildDataGrid(Type)</c>.
168   /// </summary>
169   /// <param name="type">Type to associate to this DataGrid.</param>
170   /// <param name="context">Context to associate to this DataGrid.</param>
171 0 public void BuildDataGrid(Type type, object context)
172   {
173   this.context = context;
174   this.Type = type;
175   }
176  
177   /// <summary>
178   /// Reflex whether the datagrid is read only or not
179   /// </summary>
180   [Bindable(true), Category("Business"), DefaultValue(DataGridOps.All)]
181   public DataGridOps DataGridOps
182   {
183 459 get
184   {
185 459 return (ViewState["ShowXObjectBrowserDataGridOps"]==null)
186   ? DataGridOps.All
187   :(DataGridOps)(ViewState["ShowXObjectBrowserDataGridOps"]);
188   }
189 0 set { ViewState["ShowXObjectBrowserDataGridOps"] = value; }
190   }
191  
192   /// <summary>
193   /// Reflex whether the context in wich occurs the operations over this
194   /// control.
195   /// </summary>
196   public object XContext
197   {
198 77 get
199   {
200 77 return this.context;
201   }
202   }
203  
204   /// <summary>
205   /// Specify DateTime format to output DateTime fields on DataGrid.
206   /// </summary>
207   [Bindable(true), Category("Business"), DefaultValue("")]
208   public string DateTimeFormat
209   {
210 221 get {
211 221 return (ViewState["ShowXObjectBrowserDateTimeFormat"] == null)
212   ? ""
213   :(string)(ViewState["ShowXObjectBrowserDateTimeFormat"]);
214   }
215 25 set { ViewState["ShowXObjectBrowserDateTimeFormat"] = value; }
216   }
217  
218   /// <summary>
219   /// Reflex the ShowX type view assigned to this DataGrid
220   /// </summary>
221   [Bindable(true), Category("Business"), DefaultValue("")]
222   public string ActiveView
223   {
224 35 get
225   {
226 35 return (ViewState["ShowXObjectBrowserActiveView"] == null)
227   ? string.Empty
228   : (string)(ViewState["ShowXObjectBrowserActiveView"]);
229   }
230 0 set { ViewState["ShowXObjectBrowserActiveView"] = value; }
231   }
232  
233   /// <summary>
234   /// Define the child controls style.
235   /// </summary>
236   [Bindable(true), Category("Style"), Browsable(true)]
237   [PersistenceMode(PersistenceMode.InnerProperty),
238   TemplateContainer(typeof(AdminElement))]
239   public TableItemStyle ChildControlStyle
240   {
241 146 get
242   {
243 146 if (childControlStyle == null)
244 0 childControlStyle = new TableItemStyle();
245  
246 146 return childControlStyle;
247   }
248 35 set
249   {
250 35 childControlStyle = value;
251   }
252   }
253  
254   /// <summary>
255   /// Reflex the SortExpression last used to sort DataGrid
256   /// </summary>
257   public string SortExpression
258   {
259 67 get
260   {
261 67 return (string)(ViewState["ShowXObjectBrowserSortExpression"]);
262   }
263  
264 11 set
265   {
266 11 ViewState["ShowXObjectBrowserSortExpression"] = value;
267   }
268   }
269  
270   /// <summary>
271   /// Keeps track whether we have to do a invert sort or not (when we use two
272   /// consecutive times the same sort expression, the order of elements should
273   /// switch).
274   /// </summary>
275   public bool InvertSort
276   {
277 33 get {
278 33 return (bool)(ViewState["ShowXObjectBrowserInvertSort"]);
279   }
280  
281 81 set {
282 81 ViewState["ShowXObjectBrowserInvertSort"] = value;
283   }
284   }
285  
286   /// <summary>
287   /// CreateChildControls create the columns of the DataGrid.
288   /// </summary>
289 35 protected override void CreateChildControls()
290   {
291 0 if ((Type == null) || this.ChildControlsCreated) return;
292  
293 35 DataGridBuilder dgBuilder = new DataGridBuilder(Type,this);
294 35 this.Columns.Clear();
295  
296 35 dgBuilder.BuildColumns();
297 35 ChildControlsCreated = true;
298  
299 35 this.ItemCreated += new DataGridItemEventHandler(dg_ItemCreated);
300 35 this.CancelCommand += new DataGridCommandEventHandler(this.dg_CancelCommand);
301 35 this.EditCommand += new DataGridCommandEventHandler(this.dg_EditCommand);
302 35 this.UpdateCommand += new DataGridCommandEventHandler(this.dg_UpdateCommand);
303 35 this.PageIndexChanged += new DataGridPageChangedEventHandler(dg_PageIndexChanged);
304 35 this.SortCommand += new DataGridSortCommandEventHandler(dg_SortCommand);
305 35 this.DeleteCommand += new DataGridCommandEventHandler(dg_DeleteCommand);
306  
307 35 DataBind();
308   }
309  
310   /// <summary>
311   /// Override DataGrid Databind. Provides sorting over data.
312   /// </summary>
313 56 public override void DataBind()
314   {
315 56 dataSource = Configuration.Session.MethodCaller.InvokeMethodGetAllX(Type,
316   XContext);
317  
318 56 this.DataSource = dataSource;
319 56 dgSort(SortExpression);
320 56 base.DataBind();
321   }
322  
323  
324  
325   #region DataGrid event handlers
326  
327 2 private void dg_UpdateCommand(object source, DataGridCommandEventArgs e)
328   {
329 2 ArrayList values = new ArrayList();
330 2 bool validated = true;
331  
332 2 int dbpk = int.Parse((e.Item.Cells[0].Controls[0] as Literal).Text);
333  
334 2 values.Add(dbpk);
335  
336 20 for (int i=1; i < e.Item.Cells.Count; i++) {
337  
338 0 if (e.Item.Cells[i].Controls.Count == 0) continue;
339  
340 18 if (e.Item.Cells[i].Controls[0] is TextField) {
341  
342 4 TextField tf = e.Item.Cells[i].Controls[0] as TextField;
343  
344 4 if (tf.Validate(XContext)) {
345 3 values.Add(tf.InputText);
346   }
347   else
348 1 validated = false;
349  
350   }
351 14 else if (e.Item.Cells[i].Controls[0] is CheckBox)
352 2 values.Add((e.Item.Cells[i].Controls[0] as CheckBox).Checked);
353 12 else if (e.Item.Cells[i].Controls[0] is ChangePassword) {
354  
355 2 ChangePassword cp = e.Item.Cells[i].Controls[0] as ChangePassword;
356  
357 2 if (cp.Validate(XContext))
358 1 values.Add(cp.Password);
359   else
360 1 validated = false;
361   }
362 10 else if (e.Item.Cells[i].Controls[0] is
363   ShowX.Web.WebControls.CheckBoxList) {
364  
365 2 ShowX.Web.WebControls.CheckBoxList cblist = e.Item.Cells[i]
366   .Controls[0] as ShowX.Web.WebControls.CheckBoxList;
367 2 ArrayList sel = new ArrayList();
368  
369 2 foreach (ListItem li in cblist.Items) {
370  
371 6 if (li.Selected)
372 2 sel.Add(Configuration.Session.MethodCaller
373   .InvokeMethodGetXByID(cblist.CollectionMap
374   .ContainedType,XContext,int.Parse(li.Value)));
375   }
376  
377 2 if (cblist.Validate(XContext))
378 1 values.Add(sel);
379   else
380 1 validated = false;
381   }
382 8 else if (e.Item.Cells[i].Controls[0] is ShowX.Web.WebControls
383   .Calendar) {
384  
385 2 values.Add((e.Item.Cells[i].Controls[0] as ShowX.Web.WebControls
386   .Calendar).SelectedDate);
387   }
388 6 else if ((e.Item.Cells[i].Controls.Count == 2)
389   && (e.Item.Cells[i].Controls[0] is DropDownList)) {
390   //This is a template column with a drop down list
391  
392 0 DropDownList ddl = e.Item.Cells[i].Controls[0] as DropDownList;
393 0 Literal fkPropertyName = e.Item.Cells[i].Controls[1] as Literal;
394  
395 0 int selfkId = int.Parse(ddl.SelectedValue);
396  
397 0 PropertyInfo pInfo = Configuration.Session.MappingHandler
398   .GetFK(Type,fkPropertyName.Text);
399  
400 0 object fkInstance = Configuration.Session.MethodCaller
401   .InvokeMethodGetXByID(pInfo.PropertyType,XContext,selfkId);
402  
403 0 values.Add(fkInstance);
404   }
405   }
406  
407 2 if (validated) {
408  
409 1 Configuration.Session.MethodCaller
410   .InvokeMethodGetUpdateX(Type,XContext, values.ToArray());
411 1 this.EditItemIndex = -1;
412 1 DataBind();
413   }
414   }
415  
416 0 private void dg_CancelCommand(object source, DataGridCommandEventArgs e)
417   {
418   this.EditItemIndex = -1;
419   DataBind();
420   }
421  
422 2 private void dg_EditCommand(Object sender, DataGridCommandEventArgs e)
423   {
424 2 this.EditItemIndex = e.Item.ItemIndex;
425 2 DataBind();
426   }
427  
428 11 private void dg_SortCommand(object source, DataGridSortCommandEventArgs e)
429   {
430 11 if (SortExpression == e.SortExpression) {
431  
432 6 InvertSort = !InvertSort;
433   }
434   else {
435  
436 5 InvertSort = false;
437   }
438  
439 11 SortExpression = e.SortExpression;
440  
441 11 DataBind();
442   }
443  
444 1 private void dg_PageIndexChanged(object source, DataGridPageChangedEventArgs e)
445   {
446 1 this.CurrentPageIndex = e.NewPageIndex;
447 1 this.EditItemIndex = -1;
448  
449 1 DataBind();
450   }
451  
452 354 private void dg_ItemCreated(object sender, DataGridItemEventArgs e)
453   {
454 354 if ((((this.DataGridOps & DataGridOps.All) != 0) ||
455   ((this.DataGridOps & DataGridOps.Deletion) != 0))
456   && (e.Item.ItemType == ListItemType.Item
457   || e.Item.ItemType == ListItemType.AlternatingItem)) {
458  
459 126 WebControl wc = e.Item.Cells[this.Columns.Count-1].Controls[0] as WebControl;
460 126 wc.Attributes.Add("onclick",
461   "return confirm(\"Are you sure you want to remove element?\");");
462   }
463   }
464  
465 6 private void dg_DeleteCommand(object source, DataGridCommandEventArgs e)
466   {
467 6 int dbpk = int.Parse((e.Item.Cells[0].Controls[0] as Literal).Text);
468  
469   //Element is the last on a page. The CurrentPageIndex should be adjusted.
470 6 if ((this.PageSize == 1) || (e.Item.DataSetIndex + 1) % this.PageSize == 1)
471 5 this.CurrentPageIndex = Math.Max(0,CurrentPageIndex-1);
472  
473 6 Configuration.Session.MethodCaller.InvokeMethodDelX(Type,XContext,dbpk);
474  
475 6 DataBind();
476  
477 6 if (this.OnDeleteElem != null)
478 0 OnDeleteElem(null);
479   }
480  
481  
482   #endregion
483  
484   }
485  
486   #region Helper classes
487  
488   /// <summary>
489   /// This class is in charge of compare two types of elements, for sorting over
490   /// DataGrid
491   /// </summary>
492   public class CmpByProperty : IComparer
493   {
494   /// <summary>
495   /// Property to use on comparing
496   /// </summary>
497   PropertyInfo propertyInfo;
498  
499   /// <summary>
500   /// Keep track whether a normal or an invert comparison should be made
501   /// </summary>
502   bool invertSort;
503  
504   /// <summary>
505   /// Construcotr
506   /// </summary>
507   /// <param name="propertyInfo">Property to use on comparing</param>
508   /// <param name="invertSort">Keep track whether a normal or an invert
509   /// comparison should be made</param>
510 27 public CmpByProperty(PropertyInfo propertyInfo, bool invertSort)
511   {
512 27 this.propertyInfo = propertyInfo;
513 27 this.invertSort = invertSort;
514   }
515  
516   /// <summary>
517   /// Compare two objects, with the sematic of the Compare method from
518   /// IComparer interface. The comparison will not work if the type of the
519   /// objects (the PropertyType of the propertyInfo associated to this class)
520   /// is not a basic one or not implements the IComparable interface.
521   /// </summary>
522   /// <param name="o1">Object to compare</param>
523   /// <param name="o2">Object to compare</param>
524   /// <returns>1 if o1 is greater than o2, -1 if o1 is less than o2, and 0 if
525   /// o1 and o2 are equal</returns>
526 428 public int Compare(object o1, object o2)
527   {
528 428 object result1 = propertyInfo.GetValue(o1,null);
529 428 object result2 = propertyInfo.GetValue(o2,null);
530 428 int result = 0;
531  
532 428 if (propertyInfo.PropertyType is IComparable) {
533  
534 0 result = ((IComparable)result1).CompareTo((IComparable)result2);
535   }
536   else {
537  
538 428 switch(propertyInfo.PropertyType.ToString()) {
539  
540   case "System.String":
541 156 result = ((String)result1).CompareTo((String)result2);
542 156 break;
543   case "System.Int32":
544 88 result = ((int)result1).CompareTo((int)result2);
545 88 break;
546   case "System.Int16":
547 0 result = ((int)result1).CompareTo((int)result2);
548 0 break;
549   case "System.Int64":
550 0 result = ((int)result1).CompareTo((int)result2);
551 0 break;
552   case "System.Char":
553 0 result = ((char)result1).CompareTo((char)result2);
554 0 break;
555   case "System.Double":
556 0 result = ((double)result1).CompareTo((double)result2);
557 0 break;
558   case "System.Decimal":
559 0 result = ((decimal)result1).CompareTo((decimal)result2);
560 0 break;
561   case "System.Boolean":
562 56 result = ((bool)result1).CompareTo((bool)result2);
563 56 break;
564   case "System.DateTime":
565 128 result = ((DateTime)result1).CompareTo((DateTime)result2);
566 128 break;
567   }
568   }
569  
570 428 if (invertSort && (result != 0)) result = -result;
571  
572 428 return result;
573   }
574   }
575  
576   #endregion
577   }
578