2005-09-23 Sebastien Pouliot <sebastien@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / PagedDataSource.cs
1 // System.Web.UI.WebControls.PagedDataSource.cs
2 //
3 // Author: Duncan Mak (duncan@novell.com)
4 //         Jackson Harper  (jackson@ximian.com) 
5 //
6 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
15 // 
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
18 // 
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 //
27
28 using System.Collections;
29 using System.ComponentModel;
30 using System.Security.Permissions;
31
32 namespace System.Web.UI.WebControls {
33
34         // CAS - no inheritance demand required because the class is sealed
35         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
36         public sealed class PagedDataSource : ICollection, IEnumerable, ITypedList
37         {
38                 int page_size, current_page_index, virtual_count;
39                 bool allow_paging, allow_custom_paging;
40                 IEnumerable source;
41                 
42                 public PagedDataSource ()
43                 {
44                         page_size = 10;
45                         allow_paging = false;
46                         current_page_index = 0;
47                         allow_custom_paging = false;
48                         virtual_count = 0;
49                 }
50
51                 public bool AllowCustomPaging {
52                         get { return allow_custom_paging; }
53                         set { allow_custom_paging = value; }
54                 }
55
56                 public bool AllowPaging {
57                         get { return allow_paging; }
58                         set { allow_paging = value; }
59                 }
60
61                 public int Count {
62                         get {
63                                 if (DataSource == null)
64                                         return 0;
65                                 
66                                 if (IsPagingEnabled == true) {
67                                         if (IsCustomPagingEnabled == true || IsLastPage == false)
68                                                 return PageSize;
69
70                                         if (IsCustomPagingEnabled == false && IsLastPage == true)
71                                                 return FirstIndexInPage - DataSourceCount;
72                                 }
73
74                                 return DataSourceCount;
75                         }
76                 }                                               
77
78                 public int CurrentPageIndex {
79                         get { return current_page_index; }
80                         set { current_page_index = value; }
81                 }
82
83                 public IEnumerable DataSource {
84                         get { return source; }
85                         set { source = value; }
86                 }
87
88                 public int DataSourceCount {
89                         get {
90                                 if (source == null)
91                                         return 0;
92                                 
93                                 if (IsCustomPagingEnabled)
94                                         return virtual_count;
95
96                                 if (source is ICollection)
97                                         return ((ICollection) source).Count;
98
99                                 throw new HttpException ("The data source must implement ICollection");
100                         }
101                 }
102
103                 public int FirstIndexInPage {
104                         get {
105                                 if (!IsPagingEnabled || IsCustomPagingEnabled || DataSource == null)
106                                         return 0;
107                                 
108                                 return current_page_index * page_size;
109                         }
110                 }
111
112                 public bool IsCustomPagingEnabled {
113                         get { return IsPagingEnabled && AllowCustomPaging; }
114                 }
115
116                 public bool IsFirstPage {
117                         get { 
118                                 if (!AllowPaging)
119                                         return true;
120                                 
121                                 return CurrentPageIndex == 0; 
122                         }
123                 }
124
125                 public bool IsLastPage {
126                         get {
127                                 if (!AllowPaging)
128                                         return true;
129
130                                 if (PageCount == 0)
131                                         return false;
132
133                                 return CurrentPageIndex == PageCount - 1;
134                         }
135                 }
136
137                 public bool IsPagingEnabled {
138                         get { return AllowPaging && (PageSize != 0); }
139                 }
140
141                 public bool IsReadOnly {
142                         get { return false; } // as documented
143                 }
144
145                 public bool IsSynchronized {
146                         get { return false; } // as documented
147                 }
148
149                 public int PageCount {
150                         get {
151                                 if (DataSource == null)
152                                         return 0;
153
154                                 if (!IsPagingEnabled || DataSourceCount == 0 || PageSize == 0)
155                                         return 1;
156
157                                 return (DataSourceCount + PageSize - 1) / PageSize;
158                         }
159                 }
160                 
161                 public int PageSize {
162                         get { return page_size; }
163                         set { page_size = value; }
164                 }
165
166                 public object SyncRoot {
167                         get { return this; }
168                 }
169
170                 public int VirtualCount {
171                         get { return virtual_count; }
172                         set { virtual_count = value; }
173                 }
174 #if NET_2_0
175                 [MonoTODO]
176                 public bool AllowServerPaging {
177                         get {
178                                 throw new NotImplementedException ();
179                         }
180                         set {
181                                 throw new NotImplementedException ();
182                         }
183                 }
184
185                 [MonoTODO]
186                 public DataSourceSelectArguments DataSourceSelectArguments {
187                         get {
188                                 throw new NotImplementedException ();
189                         }
190                         set {
191                                 throw new NotImplementedException ();
192                         }
193                 }
194                 [MonoTODO]
195                 public DataSourceView DataSourceView {
196                         get {
197                                 throw new NotImplementedException ();
198                         }
199                         set {
200                                 throw new NotImplementedException ();
201                         }
202                 }
203
204                 [MonoTODO]
205                 public void SetItemCountFromPageIndex (int highestPageIndex)
206                 {
207                         throw new NotImplementedException ();
208                 }
209 #endif
210
211                 public void CopyTo (Array array, int index)
212                 {
213                         foreach (object o in source)
214                                 array.SetValue (o, index++);
215                 }
216
217                 public IEnumerator GetEnumerator ()
218                 {
219                         ICollection col = source as ICollection;
220                         if (col != null)
221                                 return GetEnumeratorEnum (col.GetEnumerator (),
222                                                 FirstIndexInPage, FirstIndexInPage + PageSize);
223
224                         IList list = source as IList;
225                         if (list != null)
226                                 return GetListEnum (list, FirstIndexInPage,
227                                                 FirstIndexInPage + PageSize);
228
229                         return source.GetEnumerator ();
230                 }
231
232                 public PropertyDescriptorCollection GetItemProperties (
233                         PropertyDescriptor [] list_accessors)
234                 {
235                         ITypedList typed = DataSource as ITypedList;
236                         if (typed == null)
237                                 return null;
238                         return typed.GetItemProperties (list_accessors);
239                 }
240
241                 public string GetListName (PropertyDescriptor [] list_accessors)
242                 {
243                         return String.Empty; // as documented
244                 }
245
246                 private IEnumerator GetListEnum (IList list, int start, int end)
247                 {
248                         if (!AllowPaging)
249                                 end = list.Count;
250                         for (int i = start; i < end; i++)
251                                 yield return list [i];
252                 }
253
254                 private IEnumerator GetEnumeratorEnum (IEnumerator e, int start, int end)
255                 {
256                         for (int i = 0; i < start; i++)
257                                 e.MoveNext ();
258                         for (int i = start; (!allow_paging || i < end) && e.MoveNext (); i++)
259                                 yield return e.Current;
260                 }
261         }
262 }