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