2004-05-26 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / PagedDataSource.cs
1 /**
2  * Namespace: System.Web.UI.WebControls
3  * Class:     PagedDataSource
4  *
5  * Author:  Gaurav Vaish
6  * Maintainer: gvaish@iitk.ac.in
7  * Contact: <my_scripts2001@yahoo.com>, <gvaish@iitk.ac.in>
8  * Implementation: yes
9  * Status:  100%
10  *
11  * (C) Gaurav Vaish (2002)
12  */
13
14 using System;
15 using System.ComponentModel;
16 using System.Collections;
17 using System.Web;
18 using System.Web.UI;
19
20 namespace System.Web.UI.WebControls
21 {
22         public sealed class PagedDataSource : ICollection, IEnumerable, ITypedList
23         {
24                 private int  pageSize;
25                 private bool allowPaging;
26                 private int  currentPageIndex;
27                 private bool allowCustomPaging;
28                 private int  virtualCount;
29
30                 private IEnumerable dataSource;
31
32                 public PagedDataSource()
33                 {
34                         Initialize();
35                 }
36
37                 private void Initialize()
38                 {
39                         pageSize          = 10;
40                         allowPaging       = false;
41                         currentPageIndex  = 0;
42                         allowCustomPaging = false;
43                         virtualCount      = 0;
44                 }
45
46                 public bool AllowCustomPaging
47                 {
48                         get
49                         {
50                                 return allowCustomPaging;
51                         }
52                         set
53                         {
54                                 allowCustomPaging = value;
55                         }
56                 }
57
58                 public bool AllowPaging
59                 {
60                         get
61                         {
62                                 return allowPaging;
63                         }
64                         set
65                         {
66                                 allowPaging = value;
67                         }
68                 }
69
70                 public int Count
71                 {
72                         get
73                         {
74                                 if(dataSource != null)
75                                 {
76                                         if(!IsPagingEnabled)
77                                         {
78                                                 return DataSourceCount;
79                                         }
80                                         if(IsCustomPagingEnabled)
81                                         {
82                                                 return pageSize;
83                                         }
84                                         if(IsLastPage)
85                                         {
86                                                 return (DataSourceCount - FirstIndexInPage);
87                                         }
88                                         return pageSize;
89                                 }
90                                 return 0;
91                         }
92                 }
93
94                 public int CurrentPageIndex
95                 {
96                         get
97                         {
98                                 return currentPageIndex;
99                         }
100
101                         set
102                         {
103                                 currentPageIndex = value;
104                         }
105                 }
106
107                 public IEnumerable DataSource
108                 {
109                         get
110                         {
111                                 return dataSource;
112                         }
113                         set
114                         {
115                                 dataSource = value;
116                         }
117                 }
118
119                 public int DataSourceCount
120                 {
121                         get
122                         {
123                                 if(dataSource != null)
124                                 {
125                                         if(IsCustomPagingEnabled)
126                                         {
127                                                 return virtualCount;
128                                         }
129                                         if(dataSource is ICollection)
130                                         {
131                                                 return ((ICollection)dataSource).Count;
132                                         }
133                                         throw new HttpException(HttpRuntime.FormatResourceString("PagedDataSource_Cannot_Get_Count"));
134                                 }
135                                 return 0;
136                         }
137                 }
138
139                 public int FirstIndexInPage
140                 {
141                         get
142                         {
143                                 if(dataSource != null && IsPagingEnabled && !IsCustomPagingEnabled)
144                                 {
145                                         return (currentPageIndex * pageSize);
146                                 }
147                                 return 0;
148                         }
149                 }
150
151                 public bool IsCustomPagingEnabled
152                 {
153                         get
154                         {
155                                 return (IsPagingEnabled && allowCustomPaging);
156                         }
157                 }
158
159                 public bool IsFirstPage
160                 {
161                         get
162                         {
163                                 return (!IsPagingEnabled || (CurrentPageIndex == 0));
164                         }
165                 }
166
167                 public bool IsLastPage
168                 {
169                         get
170                         {
171                                 return (!IsPagingEnabled || (CurrentPageIndex == (PageCount - 1)));
172                         }
173                 }
174
175                 public bool IsPagingEnabled
176                 {
177                         get
178                         {
179                                 return (allowPaging && pageSize != 0);
180                         }
181                 }
182
183                 public bool IsReadOnly
184                 {
185                         get
186                         {
187                                 return false;
188                         }
189                 }
190
191                 public bool IsSynchronized
192                 {
193                         get
194                         {
195                                 return false;
196                         }
197                 }
198
199                 public int PageCount
200                 {
201                         get
202                         {
203                                 if(dataSource != null) {
204                                         if(!IsPagingEnabled)
205                                                 return 1;
206                                         
207                                         int total = DataSourceCount;
208                                         return (total + pageSize - 1)/pageSize;
209                                 }
210                                 return 0;
211                         }
212                 }
213
214                 public int PageSize
215                 {
216                         get
217                         {
218                                 return pageSize;
219                         }
220                         set
221                         {
222                                 pageSize = value;
223                         }
224                 }
225
226                 public object SyncRoot
227                 {
228                         get
229                         {
230                                 return this;
231                         }
232                 }
233
234                 public int VirtualCount
235                 {
236                         get
237                         {
238                                 return virtualCount;
239                         }
240                         set
241                         {
242                                 virtualCount = value;
243                         }
244                 }
245
246                 public void CopyTo(Array array, int index)
247                 {
248                         IEnumerator enumerator = this.GetEnumerator();
249                         if(enumerator == null) return;
250
251                         while(enumerator.MoveNext())
252                                 array.SetValue(enumerator.Current, index++);
253                 }
254
255                 public IEnumerator GetEnumerator()
256                 {
257                         int fInd = FirstIndexInPage;
258                         int count = -1;
259                         if(dataSource is ICollection)
260                         {
261                                 count = Count;
262                         }
263
264                         if(dataSource is IList)
265                         {
266                                 return (new PrivateListEnumerator((IList)dataSource, fInd, count));
267                         }
268                         if(dataSource is Array)
269                         {
270                                 return (new PrivateArrayEnumerator((object[])dataSource, fInd, count));
271                         }
272                         if(dataSource is ICollection)
273                         {
274                                 return (new PrivateICollectionEnumerator((ICollection)dataSource, fInd, count));
275                         }
276                         if(allowCustomPaging)
277                         {
278                                 return (new PrivateIEnumeratorEnumerator(dataSource.GetEnumerator(), Count));
279                         }
280                         return dataSource.GetEnumerator();
281                 }
282
283                 class PrivateIEnumeratorEnumerator : IEnumerator
284                 {
285                         private int index;
286                         private int max;
287
288                         private IEnumerator enumerator;
289
290                         public PrivateIEnumeratorEnumerator(IEnumerator enumerator, int count)
291                         {
292                                 this.enumerator = enumerator;
293                                 index = -1;
294                                 max   = count;
295                         }
296
297                         public bool MoveNext()
298                         {
299                                 enumerator.MoveNext();
300                                 index++;
301                                 return (index < max);
302                         }
303
304                         public void Reset()
305                         {
306                                 index = -1;
307                                 enumerator.Reset();
308                         }
309
310                         public object Current
311                         {
312                                 get
313                                 {
314                                         return enumerator.Current;
315                                 }
316                         }
317                 }
318
319                 class PrivateICollectionEnumerator : IEnumerator
320                 {
321                         private int index;
322                         private int start;
323                         private int max;
324
325                         private ICollection collection;
326                         private IEnumerator collEnum;
327
328                         public PrivateICollectionEnumerator(ICollection collection, int start, int count)
329                         {
330                                 this.collection = collection;
331                                 this.start  = start;
332                                 index = -1;
333                                 max = start + count;
334                                 if(max > collection.Count)
335                                 {
336                                         max = collection.Count;
337                                 }
338                         }
339
340                         public bool MoveNext()
341                         {
342                                 if(collEnum == null)
343                                 {
344                                         int cIndex = 0;
345                                         collEnum = collection.GetEnumerator();
346                                         while(cIndex < start)
347                                         {
348                                                 collEnum.MoveNext();
349                                                 cIndex++;
350                                         }
351                                 }
352                                 collEnum.MoveNext();
353                                 index++;
354                                 return (start + index < max);
355                         }
356
357                         public void Reset()
358                         {
359                                 index = -1;
360                                 collEnum = null;
361                         }
362
363                         public object Current
364                         {
365                                 get
366                                 {
367                                         return collEnum.Current;
368                                 }
369                         }
370                 }
371
372                 class PrivateArrayEnumerator : IEnumerator
373                 {
374                         private int index;
375                         private int start;
376                         private int max;
377                         private object[] values;
378
379                         public PrivateArrayEnumerator(object[] values, int start, int count)
380                         {
381                                 this.values = values;
382                                 this.start  = start;
383                                 index = -1;
384                                 max = start + count;
385                                 if(max > this.values.Length)
386                                 {
387                                         max = this.values.Length;
388                                 }
389                         }
390
391                         public bool MoveNext()
392                         {
393                                 index++;
394                                 return (index + start < max);
395                         }
396
397                         public void Reset()
398                         {
399                                 index = -1;
400                         }
401
402                         public object Current
403                         {
404                                 get
405                                 {
406                                         if(index >= 0)
407                                         {
408                                                 return values[index + start];
409                                         }
410                                         throw new InvalidOperationException("Enumerator_MoveNext_Not_Called");
411                                 }
412                         }
413                 }
414
415                 class PrivateListEnumerator : IEnumerator
416                 {
417                         private int   index;
418                         private int   start;
419                         private int   max;
420                         private IList collection;
421
422                         public PrivateListEnumerator(IList list, int start, int count)
423                         {
424                                 collection = list;
425                                 this.start = start;
426                                 index = -1;
427                                 max = start + count;
428                                 if(max > list.Count)
429                                 {
430                                         max = list.Count;
431                                 }
432                         }
433
434                         public bool MoveNext()
435                         {
436                                 index++;
437                                 return (index + start < max);
438                         }
439
440                         public void Reset()
441                         {
442                                 index = -1;
443                         }
444
445                         public object Current
446                         {
447                                 get
448                                 {
449                                         if(index >= 0)
450                                         {
451                                                 return collection[index + start];
452                                         }
453                                         throw new InvalidOperationException("Enumerator_MoveNext_Not_Called");
454                                 }
455                         }
456                 }
457
458                 public string GetListName(PropertyDescriptor[] listAccessors)
459                 {
460                         return String.Empty;
461                 }
462
463                 public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
464                 {
465                         if(dataSource != null)
466                         {
467                                 if(dataSource is ITypedList)
468                                 {
469                                         return ((ITypedList)dataSource).GetItemProperties(listAccessors);
470                                 }
471                         }
472                         return null;
473                 }
474         }
475 }