Field.cs :  » PDF » PDF-Clown » it » stefanochizzolini » clown » documents » interaction » forms » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » PDF » PDF Clown 
PDF Clown » it » stefanochizzolini » clown » documents » interaction » forms » Field.cs
/*
  Copyright 2008 Stefano Chizzolini. http://clown.stefanochizzolini.it

  Contributors:
    * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it)

  This file should be part of the source code distribution of "PDF Clown library"
  (the Program): see the accompanying README files for more info.

  This Program is free software; you can redistribute it and/or modify it under
  the terms of the GNU General Public License as published by the Free Software
  Foundation; either version 2 of the License, or (at your option) any later version.

  This Program is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY, either expressed or implied; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.

  You should have received a copy of the GNU General Public License along with this
  Program (see README files); if not, go to the GNU website (http://www.gnu.org/).

  Redistribution and use, with or without modification, are permitted provided that such
  redistributions retain the above copyright notice, license and disclaimer, along with
  this list of conditions.
*/

using it.stefanochizzolini.clown.bytes;
using it.stefanochizzolini.clown.documents;
using it.stefanochizzolini.clown.documents.interaction.annotations;
using it.stefanochizzolini.clown.files;
using it.stefanochizzolini.clown.objects;

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace it.stefanochizzolini.clown.documents.interaction.forms{
  /**
    <summary>Interactive form field [PDF:1.6:8.6.2].</summary>
  */
  public abstract class Field
    : PdfObjectWrapper<PdfDictionary>
  {
    /*
      NOTE: Inheritable attributes are NOT early-collected, as they are NOT part
      of the explicit representation of a page. They are retrieved everytime
      clients call.
    */
    #region types
    /**
      <summary>Field flags [PDF:1.6:8.6.2].</summary>
    */
    public enum FlagsEnum
    {
      /**
        <summary>The user may not change the value of the field.</summary>
      */
      ReadOnly = 0x1,
      /**
        <summary>The field must have a value at the time it is exported by a submit-form action.</summary>
      */
      Required = 0x2,
      /**
        <summary>The field must not be exported by a submit-form action.</summary>
      */
      NoExport = 0x4,
      /**
        <summary>(Text fields only) The field can contain multiple lines of text.</summary>
      */
      Multiline = 0x1000,
      /**
        <summary>(Text fields only) The field is intended for entering a secure password
        that should not be echoed visibly to the screen.</summary>
      */
      Password = 0x2000,
      /**
        <summary>(Radio buttons only) Exactly one radio button must be selected at all times.</summary>
      */
      NoToggleToOff = 0x4000,
      /**
        <summary>(Button fields only) The field is a set of radio buttons (otherwise, a check box).</summary>
        <remarks>This flag is meaningful only if the Pushbutton flag isn't selected.</remarks>
      */
      Radio = 0x8000,
      /**
        <summary>(Button fields only) The field is a pushbutton that does not retain a permanent value.</summary>
      */
      Pushbutton = 0x10000,
      /**
        <summary>(Choice fields only) The field is a combo box (otherwise, a list box).</summary>
      */
      Combo = 0x20000,
      /**
        <summary>(Choice fields only) The combo box includes an editable text box as well as a dropdown list
        (otherwise, it includes only a drop-down list).</summary>
      */
      Edit = 0x40000,
      /**
        <summary>(Choice fields only) The field's option items should be sorted alphabetically.</summary>
      */
      Sort = 0x80000,
      /**
        <summary>(Text fields only) Text entered in the field represents the pathname of a file
        whose contents are to be submitted as the value of the field.</summary>
      */
      FileSelect = 0x100000,
      /**
        <summary>(Choice fields only) More than one of the field's option items may be selected simultaneously.</summary>
      */
      MultiSelect = 0x200000,
      /**
        <summary>(Choice and text fields only) Text entered in the field is not spell-checked.</summary>
      */
      DoNotSpellCheck = 0x400000,
      /**
        <summary>(Text fields only) The field does not scroll to accommodate more text
        than fits within its annotation rectangle.</summary>
        <remarks>Once the field is full, no further text is accepted.</remarks>
      */
      DoNotScroll = 0x800000,
      /**
        <summary>(Text fields only) The field is automatically divided into as many equally spaced positions,
        or combs, as the value of MaxLen, and the text is laid out into those combs.</summary>
      */
      Comb = 0x1000000,
      /**
        <summary>(Text fields only) The value of the field should be represented as a rich text string.</summary>
      */
      RichText = 0x2000000,
      /**
        <summary>(Button fields only) A group of radio buttons within a radio button field that use
        the same value for the on state will turn on and off in unison
        (otherwise, the buttons are mutually exclusive).</summary>
      */
      RadiosInUnison = 0x2000000,
      /**
        <summary>(Choice fields only) The new value is committed as soon as a selection is made with the pointing device.</summary>
      */
      CommitOnSelChange = 0x4000000
    };
    #endregion

    #region static
    #region interface
    #region public
    /**
      <summary>Wraps a field reference into a field object.</summary>
      <param name="reference">Reference to a field object.</param>
      <returns>Field object associated to the reference.</returns>
    */
    public static Field Wrap(
      PdfReference reference
      )
    {
      /*
        NOTE: This is a factory method for any field-derived object.
      */
      if(reference == null)
        return null;

      PdfDictionary dataObject = (PdfDictionary)reference.DataObject;
      PdfName fieldType = (PdfName)dataObject[PdfName.FT];
      PdfInteger fieldFlags = (PdfInteger)dataObject[PdfName.Ff];
      FlagsEnum fieldFlagsValue = (FlagsEnum)(fieldFlags == null ? 0 : fieldFlags.RawValue);
      if(fieldType.Equals(PdfName.Btn)) // Button.
      {
        if((fieldFlagsValue & FlagsEnum.Pushbutton) == FlagsEnum.Pushbutton) // Pushbutton.
          return new PushButton(reference);
        if((fieldFlagsValue & FlagsEnum.Radio) == FlagsEnum.Radio) // Radio.
          return new RadioButton(reference);
        // Check box.
        return new CheckBox(reference);
      }
      if(fieldType.Equals(PdfName.Tx)) // Text.
        return new TextField(reference);
      if(fieldType.Equals(PdfName.Ch)) // Choice.
      {
        if((fieldFlagsValue & FlagsEnum.Combo) > 0) // Combo box.
          return new ComboBox(reference);
        // List box.
        return new ListBox(reference);
      }
      if(fieldType.Equals(PdfName.Sig)) // Signature.
        return new SignatureField(reference);
      // Unknown.
      return null;
    }
    #endregion
    #endregion
    #endregion

    #region dynamic
    #region constructors
    /**
      <summary>Creates a new field within the given document context.</summary>
    */
    protected Field(
      PdfName fieldType,
      string name,
      Widget widget
      ) : this(widget.BaseObject)
    {
      PdfDictionary baseDataObject = BaseDataObject;
      baseDataObject[PdfName.FT] = fieldType;
      baseDataObject[PdfName.T] = new PdfTextString(name);
    }

    protected Field(
      PdfDirectObject baseObject
      ) : base(
        baseObject,
        null // NO container (baseObject MUST be an indirect reference).
        )
    {}
    #endregion

    #region interface
    #region public
    /**
      <summary>Gets/Sets the field's behavior in response to trigger events.</summary>
    */
    public FieldActions Actions
    {
      get
      {
        PdfDirectObject actionsObject = BaseDataObject[PdfName.AA];
        if(actionsObject == null)
          return null;

        return new FieldActions(actionsObject,Container);
      }
      set
      {BaseDataObject[PdfName.AA] = value.BaseObject;}
    }

    public override object Clone(
      Document context
      )
    {throw new NotImplementedException();}

    /**
      <summary>Gets the field default value.</summary>
    */
    public object DefaultValue
    {
      get
      {
        PdfDataObject defaultValueObject = File.Resolve(
          GetInheritableAttribute(PdfName.DV)
          );
        if(defaultValueObject == null)
          return null;

        return defaultValueObject.GetType().InvokeMember(
          "Value",
          BindingFlags.GetProperty,
          null,
          defaultValueObject,
          null
          );
      }
    }

    /**
      <summary>Gets/Sets whether the field is exported by a submit-form action.</summary>
    */
    public bool Exportable
    {
      get
      {return !((Flags & FlagsEnum.NoExport) == FlagsEnum.NoExport);}
      set
      {
        FlagsEnum flags = Flags;
        if(value)
        {flags ^= FlagsEnum.NoExport;}
        else
        {flags |= FlagsEnum.NoExport;}
        Flags = flags;
      }
    }

    /**
      <summary>Gets/Sets the field flags.</summary>
    */
    public FlagsEnum Flags
    {
      get
      {
        PdfInteger flagsObject = (PdfInteger)File.Resolve(
          GetInheritableAttribute(PdfName.Ff)
          );

        return (FlagsEnum)Enum.ToObject(
          typeof(FlagsEnum),
          (flagsObject == null ? 0 : flagsObject.RawValue)
          );
      }
      set
      {
        /*
          NOTE: As flags may be inherited from a parent field dictionary,
          we MUST ensure that the change will affect just this one;
          so, if such flags are implicit (inherited), they MUST be cloned
          and explicitly assigned to this field in order to apply changes.
        */
        PdfDictionary baseDataObject = BaseDataObject;
        PdfInteger entry = (PdfInteger)baseDataObject[PdfName.Ff];
        if(entry == null) // Implicit flags.
        {
          // Clone the inherited attribute in order to restrict its change to this field's scope only!
          entry = (PdfInteger)GetInheritableAttribute(PdfName.Ff).Clone(File);
          // Associate the cloned attribute to this field's dictionary!
          baseDataObject[PdfName.Ff] = entry;
        }

        entry.RawValue = (int)value;
      }
    }

    /**
      <summary>Gets the fully-qualified field name.</summary>
    */
    public string FullName
    {
      get
      {
        IList<string> partialNames = new List<string>();
        PdfDictionary parent = BaseDataObject;
        while(parent != null)
        {
          partialNames.Add((string)((PdfTextString)parent[PdfName.T]).Value);

          parent = (PdfDictionary)File.Resolve(parent[PdfName.Parent]);
        }

        StringBuilder buffer = new StringBuilder();
        for(
          int index = partialNames.Count - 1;
          index >= 0;
          index--
          )
        {
          buffer.Append(partialNames[index]);
          if(index > 0)
          {buffer.Append(".");}
        }

        return buffer.ToString();
      }
    }

    /**
      <summary>Gets/Sets the partial field name.</summary>
    */
    public string Name
    {
      get
      {return (string)((PdfTextString)BaseDataObject[PdfName.T]).Value;}
      set
      {BaseDataObject[PdfName.T] = new PdfTextString(value);}
    }

    /**
      <summary>Gets/Sets whether the user may not change the value of the field.</summary>
    */
    public bool ReadOnly
    {
      get
      {return ((Flags & FlagsEnum.ReadOnly) == FlagsEnum.ReadOnly);}
      set
      {
        FlagsEnum flags = Flags;
        if(value)
        {flags |= FlagsEnum.ReadOnly;}
        else
        {flags ^= FlagsEnum.ReadOnly;}
        Flags = flags;
      }
    }

    /**
      <summary>Gets/Sets whether the field must have a value at the time
      it is exported by a submit-form action.</summary>
    */
    public bool Required
    {
      get
      {return ((Flags & FlagsEnum.Required) == FlagsEnum.Required);}
      set
      {
        FlagsEnum flags = Flags;
        if(value)
        {flags |= FlagsEnum.Required;}
        else
        {flags ^= FlagsEnum.Required;}
        Flags = flags;
      }
    }

    /**
      <summary>Gets/Sets the field value.</summary>
    */
    public virtual object Value
    {
      get
      {
        PdfDataObject valueObject = File.Resolve(
          GetInheritableAttribute(PdfName.V)
          );
        if(valueObject == null)
          return null;

        return valueObject.GetType().InvokeMember(
          "Value",
          BindingFlags.GetProperty,
          null,
          valueObject,
          null
          );
      }
      set
      {BaseDataObject[PdfName.V] = new PdfString((string)value);}
    }

    public Widget Widget
    {
      get
      {
        /*
          NOTE: Terminal fields MUST be associated at least to one widget annotation.
          If there is only one associated widget annotation and its contents
          have been merged into the field dictionary, 'Kids' entry MUST be omitted.
        */
        return new Widget(BaseObject,null);
      }
    }

    /**
      <summary>Gets the widget annotations that are associated with this field.</summary>
    */
    public FieldWidgets Widgets
    {
      get
      {
        /*
          NOTE: Terminal fields MUST be associated at least to one widget annotation.
          If there is only one associated widget annotation and its contents
          have been merged into the field dictionary, 'Kids' entry MUST be omitted.
        */
        PdfDirectObject widgetsObject = BaseDataObject[PdfName.Kids];
        if(widgetsObject == null)
          return new FieldWidgets(BaseObject,null,this); // Merged annotation.

        return new FieldWidgets(widgetsObject,Container,this); // Annotation array.
      }
    }
    #endregion

    #region protected
    protected PdfDirectObject GetInheritableAttribute(
      PdfName key
      )
    {
      /*
        NOTE: It moves upward until it finds the inherited attribute.
      */
      PdfDictionary dictionary = BaseDataObject;
      while(true)
      {
        PdfDirectObject entry = dictionary[key];
        if(entry != null)
          return entry;

        dictionary = (PdfDictionary)File.Resolve(
          dictionary[PdfName.Parent]
          );
        if(dictionary == null)
        {
          if(key.Equals(PdfName.Ff))
            return new PdfInteger(0);

          return null;
        }
      }
    }
    #endregion
    #endregion
    #endregion
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.