You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			459 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			459 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //------------------------------------------------------------------------------
 | |
| // <copyright file="TextView.cs" company="Microsoft">
 | |
| //     Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| // </copyright>                                                                
 | |
| //------------------------------------------------------------------------------
 | |
| 
 | |
| using System;
 | |
| using System.Text;
 | |
| using System.Diagnostics;
 | |
| using System.Collections;
 | |
| using System.ComponentModel;
 | |
| using System.ComponentModel.Design;
 | |
| using System.Drawing;
 | |
| using System.Drawing.Design;
 | |
| using System.Globalization;
 | |
| using System.IO;
 | |
| using System.Web;
 | |
| using System.Web.UI;
 | |
| using System.Web.UI.Design.WebControls;
 | |
| using System.Web.UI.HtmlControls;
 | |
| using System.Security.Permissions;
 | |
| 
 | |
| namespace System.Web.UI.MobileControls
 | |
| {
 | |
| 
 | |
|     /*
 | |
|      * Mobile TextView class.
 | |
|      * The TextView control is for displaying large fields of text data.
 | |
|      * It supports internal pagination.
 | |
|      *
 | |
|      * Copyright (c) 2000 Microsoft Corporation
 | |
|      */
 | |
|     /// <include file='doc\TextView.uex' path='docs/doc[@for="TextView"]/*' />
 | |
|     [
 | |
|         DataBindingHandler("System.Web.UI.Design.TextDataBindingHandler, " + AssemblyRef.SystemDesign),
 | |
|         DefaultProperty("Text"),
 | |
|         Designer(typeof(System.Web.UI.Design.MobileControls.TextViewDesigner)),
 | |
|         DesignerAdapter("System.Web.UI.Design.MobileControls.Adapters.DesignerTextViewAdapter"),
 | |
|         ToolboxData("<{0}:TextView runat=\"server\">TextView</{0}:TextView>"),
 | |
|         ToolboxItem("System.Web.UI.Design.WebControlToolboxItem, " + AssemblyRef.SystemDesign)
 | |
|     ]
 | |
|     [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
 | |
|     [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
 | |
|     [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")]
 | |
|     public class TextView : PagedControl
 | |
|     {
 | |
|         private bool _haveContent = false;
 | |
|         private ArrayList _elements = new ArrayList();
 | |
| 
 | |
|         /// <include file='doc\TextView.uex' path='docs/doc[@for="TextView.Text"]/*' />
 | |
|         [
 | |
|             Bindable(true),
 | |
|             DefaultValue(""),
 | |
|             MobileCategory(SR.Category_Appearance),
 | |
|             MobileSysDescription(SR.TextView_Text),
 | |
|             PersistenceMode(PersistenceMode.InnerDefaultProperty)
 | |
|         ]
 | |
|         public String Text
 | |
|         {
 | |
| 
 | |
|             get
 | |
|             {
 | |
|                 return InnerText;
 | |
|             }
 | |
| 
 | |
|             set
 | |
|             {
 | |
|                 InnerText = value;
 | |
|                 if (_haveContent)
 | |
|                 {
 | |
|                     _elements = null;
 | |
|                     _haveContent = false;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\TextView.uex' path='docs/doc[@for="TextView.ItemCount"]/*' />
 | |
|         [
 | |
|             Bindable(false),
 | |
|             Browsable(false),
 | |
|             DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
 | |
|         ]
 | |
|         public new int ItemCount
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return base.ItemCount;
 | |
|             }
 | |
|             set
 | |
|             {
 | |
|                 base.ItemCount = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\TextView.uex' path='docs/doc[@for="TextView.ItemsPerPage"]/*' />
 | |
|         [
 | |
|             Bindable(false),
 | |
|             Browsable(false),
 | |
|             DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),            
 | |
|         ]
 | |
|         public new int ItemsPerPage
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return base.ItemsPerPage;
 | |
|             }
 | |
|             set
 | |
|             {
 | |
|                 base.ItemsPerPage = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\TextView.uex' path='docs/doc[@for="TextView.LoadItems"]/*' />
 | |
|         [
 | |
|             Browsable(false)
 | |
|         ]
 | |
|         public new event LoadItemsEventHandler LoadItems
 | |
|         {
 | |
|             add
 | |
|             {
 | |
|                 base.LoadItems += value;
 | |
|             }
 | |
|             remove
 | |
|             {
 | |
|                 base.LoadItems -= value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // Note that this value doesn't relate to device specific info
 | |
|         // because this is simply a unit size to define how many characters
 | |
|         // to be counted as an item for pagination.  Depending on each
 | |
|         // device's page weight, different numbers of items will be returned
 | |
|         // for display.
 | |
|         private static readonly int PagingUnitSize = ControlPager.DefaultWeight;  // chars
 | |
| 
 | |
|         private int _length = 0;
 | |
|         private int _pageBeginElement;
 | |
|         private int _pageBeginOffset;
 | |
|         private int _pageEndElement;
 | |
|         private int _pageEndOffset;
 | |
|         private bool _paginated = false;
 | |
| 
 | |
|         private ArrayList Elements
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_elements == null)
 | |
|                 {
 | |
|                     _elements = new ArrayList();
 | |
|                 }
 | |
|                 return _elements;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void InternalPaginate()
 | |
|         {
 | |
|             if (_paginated)
 | |
|             {
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             _paginated = true;
 | |
| 
 | |
|             _pageBeginElement = 0;
 | |
|             _pageEndOffset = 0;
 | |
|             _pageEndElement = 0;
 | |
|             _pageBeginOffset = 0;
 | |
| 
 | |
|             if (_elements == null || _elements.Count == 0)
 | |
|             {
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             int firstBlockIndex = FirstVisibleItemIndex;
 | |
|             int visibleBlockCount = VisibleItemCount;
 | |
|             int blockLimit = firstBlockIndex + visibleBlockCount;
 | |
|             bool isLastPage = blockLimit >= InternalItemCount;
 | |
| 
 | |
|             int block = 0;
 | |
|             int blockElement = 0;
 | |
|             int blockOffset = 0;
 | |
|             int currentPosition = 0;
 | |
|             int elementIndex = 0;
 | |
|             TextViewElement element = GetElement(0);
 | |
|             int elementLength = element.Text.Length;
 | |
|             int blockSize = 0;
 | |
| 
 | |
|             //fill the number of blocks for this page
 | |
|             while (block < blockLimit)
 | |
|             {
 | |
|                 if (block == firstBlockIndex)
 | |
|                 {
 | |
|                     _pageBeginElement = blockElement;
 | |
|                     _pageBeginOffset = blockOffset;
 | |
|                     if (isLastPage)
 | |
|                     {
 | |
|                         _pageEndElement = _elements.Count - 1;
 | |
|                         _pageEndOffset = GetElement(_pageEndElement).Text.Length;
 | |
|                         return;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 while (elementLength - currentPosition <= PagingUnitSize - blockSize ||
 | |
|                             (blockElement == elementIndex && element.Url != null))
 | |
|                 {
 | |
|                     elementIndex++;
 | |
|                     if (elementIndex == _elements.Count)
 | |
|                     {
 | |
|                         break;
 | |
|                     }
 | |
|                     blockSize += elementLength - currentPosition;
 | |
|                     element = GetElement(elementIndex);
 | |
|                     elementLength = element.Text.Length;
 | |
|                     currentPosition = 0;
 | |
|                 }
 | |
| 
 | |
|                 if (elementIndex == _elements.Count)
 | |
|                 {
 | |
|                     _pageEndElement = _elements.Count - 1;
 | |
|                     _pageEndOffset = GetElement(_pageEndElement).Text.Length;
 | |
|                     return;
 | |
|                 }
 | |
| 
 | |
|                 int nextBlockStart;
 | |
|                 if (element.Url != null)
 | |
|                 {
 | |
|                     nextBlockStart = 0;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     int i;
 | |
|                     for (i = currentPosition + (PagingUnitSize - blockSize) - 1; i >= currentPosition; i--)
 | |
|                     {
 | |
|                         char c = element.Text[i];
 | |
|                         if (Char.IsWhiteSpace(c) || Char.IsPunctuation(c))
 | |
|                         {
 | |
|                             break;
 | |
|                         }
 | |
|                     }
 | |
| 
 | |
|                     if (i < currentPosition)
 | |
|                     {
 | |
|                         nextBlockStart = currentPosition;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         nextBlockStart = i + 1;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 block++;
 | |
|                 blockElement = elementIndex;
 | |
|                 blockOffset = nextBlockStart;
 | |
|                 currentPosition = nextBlockStart;
 | |
|                 blockSize = 0;
 | |
|             }
 | |
| 
 | |
|             _pageEndElement = blockElement;
 | |
|             _pageEndOffset = blockOffset;
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\TextView.uex' path='docs/doc[@for="TextView.FirstVisibleElementIndex"]/*' />
 | |
|         [
 | |
|             Browsable(false),
 | |
|             DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
 | |
|         ]
 | |
|         public int FirstVisibleElementIndex
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _pageBeginElement;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\TextView.uex' path='docs/doc[@for="TextView.FirstVisibleElementOffset"]/*' />
 | |
|         [
 | |
|             Browsable(false),
 | |
|             DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
 | |
|         ]
 | |
|         public int FirstVisibleElementOffset
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _pageBeginOffset;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\TextView.uex' path='docs/doc[@for="TextView.LastVisibleElementIndex"]/*' />
 | |
|         [
 | |
|             Browsable(false),
 | |
|             DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
 | |
|         ]    
 | |
|         public int LastVisibleElementIndex
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _pageEndElement;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\TextView.uex' path='docs/doc[@for="TextView.LastVisibleElementOffset"]/*' />
 | |
|         [
 | |
|             Browsable(false),
 | |
|             DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
 | |
|         ]
 | |
|         public int LastVisibleElementOffset
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _pageEndOffset;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\TextView.uex' path='docs/doc[@for="TextView.OnRender"]/*' />
 | |
|         protected override void OnRender(HtmlTextWriter writer)
 | |
|         {
 | |
|             BuildContents();
 | |
|             InternalPaginate();
 | |
|             base.OnRender(writer);
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\TextView.uex' path='docs/doc[@for="TextView.GetElement"]/*' />
 | |
|         public TextViewElement GetElement(int index)
 | |
|         {
 | |
|             return (TextViewElement)_elements[index];
 | |
|         }
 | |
| 
 | |
|         private StringBuilder _translateBuilder;
 | |
|         private StringWriter _translateWriter;
 | |
| 
 | |
|         internal void AddElement(String text, String href, bool isBold, bool isUnderline, bool breakAfter)
 | |
|         {
 | |
| 
 | |
|             // Convert text if it has special characters.
 | |
| 
 | |
|             if (text.IndexOf('&') >= 0)
 | |
|             {
 | |
|                 if (_translateWriter != null)
 | |
|                 {
 | |
|                     _translateBuilder.Length = 0;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     _translateBuilder = new StringBuilder();
 | |
|                     _translateWriter = new StringWriter(_translateBuilder, CultureInfo.InvariantCulture);
 | |
|                 }
 | |
| 
 | |
|                 TranslateAndAppendText(text, _translateWriter);
 | |
|                 _translateWriter.Flush();
 | |
|                 text = _translateBuilder.ToString();
 | |
|             }
 | |
| 
 | |
|             _length += text.Length;
 | |
|             Elements.Add(new TextViewElement(text, href, isBold, isUnderline, breakAfter));
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\TextView.uex' path='docs/doc[@for="TextView.InternalItemCount"]/*' />
 | |
|         protected override int InternalItemCount
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return (_length + PagingUnitSize - 1) / PagingUnitSize;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\TextView.uex' path='docs/doc[@for="TextView.ItemWeight"]/*' />
 | |
|         protected override int ItemWeight
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return PagingUnitSize;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <include file='doc\TextView.uex' path='docs/doc[@for="TextView.PaginateRecursive"]/*' />
 | |
|         public override void PaginateRecursive(ControlPager pager)
 | |
|         {
 | |
|             BuildContents();
 | |
|             base.PaginateRecursive(pager);
 | |
|         }
 | |
| 
 | |
|         private void BuildContents()
 | |
|         {
 | |
|             if (!_haveContent)
 | |
|             {
 | |
|                 _haveContent = true;
 | |
|                 String text = Text;
 | |
| 
 | |
|                 if (text.Length > 0)
 | |
|                 {
 | |
|                     TextViewLiteralTextParser parser = new TextViewLiteralTextParser(this);
 | |
|                     parser.Parse(text);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         internal override bool AllowMultiLines
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return true;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         internal override bool AllowInnerMarkup
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return true;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         internal override bool TrimInnerText
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return false;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private class TextViewLiteralTextParser : LiteralTextParser
 | |
|         {
 | |
|             TextView _parent;
 | |
|             bool _hasElements = false;
 | |
| 
 | |
|             public TextViewLiteralTextParser(TextView parent)
 | |
|             {
 | |
|                 _parent = parent;
 | |
|             }
 | |
| 
 | |
|             protected override void ProcessElement(LiteralElement element)
 | |
|             {
 | |
|                 String text = element.Text != null ? element.Text : String.Empty;
 | |
|                 String href = null;
 | |
| 
 | |
|                 if(element.Type == LiteralElementType.Anchor) {
 | |
|                     href = element.GetAttribute("href");
 | |
|                 }
 | |
|                 _parent.AddElement(text,
 | |
|                            href,
 | |
|                            ((element.Format & LiteralFormat.Bold) == LiteralFormat.Bold),
 | |
|                            ((element.Format & LiteralFormat.Italic) == LiteralFormat.Italic),
 | |
|                            element.BreakAfter);
 | |
|                 _hasElements = true;
 | |
|             }
 | |
| 
 | |
|             protected override void ProcessTagInnerText(String text)
 | |
|             {
 | |
|                 Debug.Assert(false);
 | |
|             }
 | |
| 
 | |
|             protected override bool IgnoreWhiteSpaceElement(LiteralElement element)
 | |
|             {
 | |
|                 return !_hasElements;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 |