2003-10-25 Ben Maurer <bmaurer@users.sourceforge.net>
[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));
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                                 {
205                                         int total = DataSourceCount;
206                                         if(!IsPagingEnabled)
207                                         {
208                                                 return total;
209                                         }
210                                         return (total + pageSize - 1)/pageSize;
211                                 }
212                                 return 0;
213                         }
214                 }
215
216                 public int PageSize
217                 {
218                         get
219                         {
220                                 return pageSize;
221                         }
222                         set
223                         {
224                                 pageSize = value;
225                         }
226                 }
227
228                 public object SyncRoot
229                 {
230                         get
231                         {
232                                 return this;
233                         }
234                 }
235
236                 public int VirtualCount
237                 {
238                         get
239                         {
240                                 return virtualCount;
241                         }
242                         set
243                         {
244                                 virtualCount = value;
245                         }
246                 }
247
248                 public void CopyTo(Array array, int index)
249                 {
250                         foreach(object current in this)
251                         {
252                                 array.SetValue(array, index++);
253                         }
254                 }
255
256                 public IEnumerator GetEnumerator()
257                 {
258                         int fInd = FirstIndexInPage;
259                         int count = -1;
260                         if(dataSource is ICollection)
261                         {
262                                 count = Count;
263                         }
264
265                         if(dataSource is IList)
266                         {
267                                 return (new PrivateListEnumerator((IList)dataSource, fInd, count));
268                         }
269                         if(dataSource is Array)
270                         {
271                                 return (new PrivateArrayEnumerator((object[])dataSource, fInd, count));
272                         }
273                         if(dataSource is ICollection)
274                         {
275                                 return (new PrivateICollectionEnumerator((ICollection)dataSource, fInd, count));
276                         }
277                         if(allowCustomPaging)
278                         {
279                                 return (new PrivateIEnumeratorEnumerator(dataSource.GetEnumerator(), Count));
280                         }
281                         return dataSource.GetEnumerator();
282                 }
283
284                 class PrivateIEnumeratorEnumerator : IEnumerator
285                 {
286                         private int index;
287                         private int max;
288
289                         private IEnumerator enumerator;
290
291                         public PrivateIEnumeratorEnumerator(IEnumerator enumerator, int count)
292                         {
293                                 this.enumerator = enumerator;
294                                 index = -1;
295                                 max   = count;
296                         }
297
298                         public bool MoveNext()
299                         {
300                                 enumerator.MoveNext();
301                                 index++;
302                                 return (index < max);
303                         }
304
305                         public void Reset()
306                         {
307                                 index = -1;
308                                 enumerator.Reset();
309                         }
310
311                         public object Current
312                         {
313                                 get
314                                 {
315                                         return enumerator.Current;
316                                 }
317                         }
318                 }
319
320                 class PrivateICollectionEnumerator : IEnumerator
321                 {
322                         private int index;
323                         private int start;
324                         private int max;
325
326                         private ICollection collection;
327                         private IEnumerator collEnum;
328
329                         public PrivateICollectionEnumerator(ICollection collection, int start, int count)
330                         {
331                                 this.collection = collection;
332                                 this.start  = start;
333                                 index = -1;
334                                 max = start + count;
335                                 if(max > collection.Count)
336                                 {
337                                         max = collection.Count;
338                                 }
339                         }
340
341                         public bool MoveNext()
342                         {
343                                 if(collEnum == null)
344                                 {
345                                         int cIndex = 0;
346                                         collEnum = collection.GetEnumerator();
347                                         while(cIndex < start)
348                                         {
349                                                 collEnum.MoveNext();
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 }