/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_toolkit.hxx"

#include <toolkit/helper/formpdfexport.hxx>

/** === begin UNO includes === **/
#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/form/XForm.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/form/FormComponentType.hpp>
#include <com/sun/star/awt/TextAlign.hpp>
#include <com/sun/star/style/VerticalAlignment.hpp>
#include <com/sun/star/form/FormButtonType.hpp>
#include <com/sun/star/form/FormSubmitMethod.hpp>
/** === end UNO includes === **/

#include <toolkit/helper/vclunohelper.hxx>
#include <tools/diagnose_ex.h>
#include <vcl/pdfextoutdevdata.hxx>
#include <vcl/outdev.hxx>

#include <functional>
#include <algorithm>

//........................................................................
namespace toolkitform
{
//........................................................................

    using namespace ::com::sun::star;
    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::awt;
    using namespace ::com::sun::star::style;
    using namespace ::com::sun::star::beans;
    using namespace ::com::sun::star::form;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::container;

    // used strings
    static const ::rtl::OUString FM_PROP_CLASSID(RTL_CONSTASCII_USTRINGPARAM("ClassId"));
    static const ::rtl::OUString FM_PROP_NAME(RTL_CONSTASCII_USTRINGPARAM("Name"));
    static const ::rtl::OUString FM_PROP_STRINGITEMLIST(RTL_CONSTASCII_USTRINGPARAM("StringItemList"));
    static const ::rtl::OUString FM_PROP_HELPTEXT(RTL_CONSTASCII_USTRINGPARAM("HelpText"));
    static const ::rtl::OUString FM_PROP_TEXT(RTL_CONSTASCII_USTRINGPARAM("Text"));
    static const ::rtl::OUString FM_PROP_LABEL(RTL_CONSTASCII_USTRINGPARAM("Label"));
    static const ::rtl::OUString FM_PROP_READONLY(RTL_CONSTASCII_USTRINGPARAM("ReadOnly"));
    static const ::rtl::OUString FM_PROP_BORDER(RTL_CONSTASCII_USTRINGPARAM("Border"));
    static const ::rtl::OUString FM_PROP_BACKGROUNDCOLOR(RTL_CONSTASCII_USTRINGPARAM("BackgroundColor"));
    static const ::rtl::OUString FM_PROP_TEXTCOLOR(RTL_CONSTASCII_USTRINGPARAM("TextColor"));
    static const ::rtl::OUString FM_PROP_MULTILINE(RTL_CONSTASCII_USTRINGPARAM("MultiLine"));
    static const ::rtl::OUString FM_PROP_ALIGN(RTL_CONSTASCII_USTRINGPARAM("Align"));
    static const ::rtl::OUString FM_PROP_FONT(RTL_CONSTASCII_USTRINGPARAM("FontDescriptor"));
    static const ::rtl::OUString FM_PROP_MAXTEXTLEN(RTL_CONSTASCII_USTRINGPARAM("MaxTextLen"));
    static const ::rtl::OUString FM_PROP_TARGET_URL(RTL_CONSTASCII_USTRINGPARAM("TargetURL"));
    static const ::rtl::OUString FM_PROP_STATE(RTL_CONSTASCII_USTRINGPARAM("State"));
    static const ::rtl::OUString FM_PROP_REFVALUE(RTL_CONSTASCII_USTRINGPARAM("RefValue"));
    static const ::rtl::OUString FM_PROP_DROPDOWN(RTL_CONSTASCII_USTRINGPARAM("Dropdown"));
    static const ::rtl::OUString FM_SUN_COMPONENT_FILECONTROL(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.form.component.FileControl"));

    namespace
    {
        //--------------------------------------------------------------------
        /** determines the FormComponentType of a form control
        */
        sal_Int16 classifyFormControl( const Reference< XPropertySet >& _rxModel ) SAL_THROW(( Exception ))
        {
            sal_Int16 nControlType = FormComponentType::CONTROL;

            Reference< XPropertySetInfo > xPSI;
            if ( _rxModel.is() )
                xPSI = _rxModel->getPropertySetInfo();
            if ( xPSI.is() && xPSI->hasPropertyByName( FM_PROP_CLASSID ) )
            {
                OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_CLASSID ) >>= nControlType );
            }

            return nControlType;
        }

	    //--------------------------------------------------------------------
        /** (default-)creates a PDF widget according to a given FormComponentType
        */
        ::vcl::PDFWriter::AnyWidget* createDefaultWidget( sal_Int16 _nFormComponentType )
        {
            switch ( _nFormComponentType )
            {
            case FormComponentType::COMMANDBUTTON:
                return new ::vcl::PDFWriter::PushButtonWidget;
            case FormComponentType::CHECKBOX:
                return new ::vcl::PDFWriter::CheckBoxWidget;
            case FormComponentType::RADIOBUTTON:
                return new ::vcl::PDFWriter::RadioButtonWidget;
            case FormComponentType::LISTBOX:
                return new ::vcl::PDFWriter::ListBoxWidget;
            case FormComponentType::COMBOBOX:
                return new ::vcl::PDFWriter::ComboBoxWidget;

            case FormComponentType::TEXTFIELD:
            case FormComponentType::FILECONTROL:
            case FormComponentType::DATEFIELD:
            case FormComponentType::TIMEFIELD:
            case FormComponentType::NUMERICFIELD:
            case FormComponentType::CURRENCYFIELD:
            case FormComponentType::PATTERNFIELD:
                return new ::vcl::PDFWriter::EditWidget;
            }
            return NULL;
        }

	    //--------------------------------------------------------------------
        /** determines a unique number for the radio group which the given radio
            button model belongs to

            The number is guaranteed to be
            <ul><li>unique within the document in which the button lives</li>
                <li>the same for subsequent calls with other radio button models,
                    which live in the same document, and belong to the same group</li>
            </ul>

            @precond
                the model must be part of the form component hierarchy in a document
        */
        sal_Int32 determineRadioGroupId( const Reference< XPropertySet >& _rxRadioModel ) SAL_THROW((Exception))
        {
            OSL_ENSURE( classifyFormControl( _rxRadioModel ) == FormComponentType::RADIOBUTTON,
                "determineRadioGroupId: this *is* no radio button model!" );
            // The fact that radio button groups need to be unique within the complete
            // host document makes it somewhat difficult ...
            // Problem is that two form radio buttons belong to the same group if
            // - they have the same parent
            // - AND they have the same name
            // This implies that we need some knowledge about (potentially) *all* radio button
            // groups in the document.

            // get the root-level container
            Reference< XChild > xChild( _rxRadioModel, UNO_QUERY );
            Reference< XForm > xParentForm( xChild.is() ? xChild->getParent() : Reference< XInterface >(), UNO_QUERY );
            OSL_ENSURE( xParentForm.is(), "determineRadioGroupId: no parent form -> group id!" );
            if ( !xParentForm.is() )
                return -1;

            while ( xParentForm.is() )
            {
                xChild = xParentForm.get();
                xParentForm = xParentForm.query( xChild->getParent() );
            }
            Reference< XIndexAccess > xRoot( xChild->getParent(), UNO_QUERY );
            OSL_ENSURE( xRoot.is(), "determineRadioGroupId: unable to determine the root of the form component hierarchy!" );
            if ( !xRoot.is() )
                return -1;

            // count the leafs in the hierarchy, until we encounter radio button
            ::std::vector< Reference< XIndexAccess > > aAncestors;
            ::std::vector< sal_Int32 >                 aPath;

            Reference< XInterface > xNormalizedLookup( _rxRadioModel, UNO_QUERY );
            ::rtl::OUString sRadioGroupName;
            OSL_VERIFY( _rxRadioModel->getPropertyValue( FM_PROP_NAME ) >>= sRadioGroupName );

            Reference< XIndexAccess > xCurrentContainer( xRoot );
            sal_Int32 nStartWithChild = 0;
            sal_Int32 nGroupsEncountered = 0;
            do
            {
                Reference< XNameAccess > xElementNameAccess( xCurrentContainer, UNO_QUERY );
                OSL_ENSURE( xElementNameAccess.is(), "determineRadioGroupId: no name container?" );
                if ( !xElementNameAccess.is() )
                    return -1;

                if ( nStartWithChild == 0 )
                {   // we encounter this container the first time. In particular, we did not
                    // just step up
                    nGroupsEncountered += xElementNameAccess->getElementNames().getLength();
                        // this is way too much: Not all of the elements in the current container
                        // may form groups, especially if they're forms. But anyway, this number is
                        // sufficient for our purpose. Finally, the container contains *at most*
                        // that much groups
                }

                sal_Int32 nCount = xCurrentContainer->getCount();
                sal_Int32 i;
                for ( i = nStartWithChild; i < nCount; ++i )
                {
                    Reference< XInterface > xElement( xCurrentContainer->getByIndex( i ), UNO_QUERY );
                    if ( !xElement.is() )
                    {
                        OSL_ENSURE( sal_False, "determineRadioGroupId: very suspicious!" );
                        continue;
                    }

                    Reference< XIndexAccess > xNewContainer( xElement, UNO_QUERY );
                    if ( xNewContainer.is() )
                    {
                        // step down the hierarchy
                        aAncestors.push_back( xCurrentContainer );
                        xCurrentContainer = xNewContainer;
                        aPath.push_back( i );
                        nStartWithChild = 0;
                        break;
                            // out of the inner loop, but continue with the outer loop
                    }

                    if ( xElement.get() == xNormalizedLookup.get() )
                    {
                        // look up the name of the radio group in the list of all element names
                        Sequence< ::rtl::OUString > aElementNames( xElementNameAccess->getElementNames() );
                        const ::rtl::OUString* pElementNames = aElementNames.getConstArray();
                        const ::rtl::OUString* pElementNamesEnd = pElementNames + aElementNames.getLength();
                        while ( pElementNames != pElementNamesEnd )
                        {
                            if ( *pElementNames == sRadioGroupName )
                            {
                                sal_Int32 nLocalGroupIndex = pElementNames - aElementNames.getConstArray();
                                OSL_ENSURE( nLocalGroupIndex < xElementNameAccess->getElementNames().getLength(),
                                    "determineRadioGroupId: inconsistency!" );

                                sal_Int32 nGlobalGroupId = nGroupsEncountered - xElementNameAccess->getElementNames().getLength() + nLocalGroupIndex;
                                return nGlobalGroupId;
                            }
                            ++pElementNames;
                        }
                        OSL_ENSURE( sal_False, "determineRadioGroupId: did not find the radios element name!" );
                    }
                }

                if ( !( i < nCount ) )
                {
                    // the loop terminated because there were no more elements
                    // -> step up, if possible
                    if ( aAncestors.empty() )
                        break;

                    xCurrentContainer = aAncestors.back(); aAncestors.pop_back();
                    nStartWithChild = aPath.back() + 1; aPath.pop_back();
                }
            }
            while ( true );
            return -1;
        }

        //--------------------------------------------------------------------
        /** copies a StringItemList to a PDF widget's list
        */
        void getStringItemVector( const Reference< XPropertySet >& _rxModel, ::std::vector< ::rtl::OUString >& _rVector )
        {
            Sequence< ::rtl::OUString > aListEntries;
            OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_STRINGITEMLIST ) >>= aListEntries );
            ::std::copy( aListEntries.getConstArray(), aListEntries.getConstArray() + aListEntries.getLength(),
                ::std::back_insert_iterator< ::std::vector< ::rtl::OUString > >( _rVector ) );
        }
    }

	//--------------------------------------------------------------------
    /** creates a PDF compatible control descriptor for the given control
    */
    void TOOLKIT_DLLPUBLIC describePDFControl( const Reference< XControl >& _rxControl,
        ::std::auto_ptr< ::vcl::PDFWriter::AnyWidget >& _rpDescriptor, ::vcl::PDFExtOutDevData& i_pdfExportData ) SAL_THROW(())
    {
        _rpDescriptor.reset();
        OSL_ENSURE( _rxControl.is(), "describePDFControl: invalid (NULL) control!" );
        if ( !_rxControl.is() )
            return;

        try
        {
            Reference< XPropertySet > xModelProps( _rxControl->getModel(), UNO_QUERY );
            sal_Int16 nControlType = classifyFormControl( xModelProps );
            _rpDescriptor.reset( createDefaultWidget( nControlType ) );
            if ( !_rpDescriptor.get() )
                // no PDF widget available for this
                return;

            Reference< XPropertySetInfo > xPSI( xModelProps->getPropertySetInfo() );
            Reference< XServiceInfo > xSI( xModelProps, UNO_QUERY );
            OSL_ENSURE( xSI.is(), "describePDFControl: no service info!" );
                // if we survived classifyFormControl, then it's a real form control, and they all have
                // service infos

            // ================================
            // set the common widget properties

            // --------------------------------
            // Name, Description, Text
            OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_NAME ) >>= _rpDescriptor->Name );
            OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_HELPTEXT ) >>= _rpDescriptor->Description );
            Any aText;
            if ( xPSI->hasPropertyByName( FM_PROP_TEXT ) )
                aText = xModelProps->getPropertyValue( FM_PROP_TEXT );
            else if ( xPSI->hasPropertyByName( FM_PROP_LABEL ) )
                aText = xModelProps->getPropertyValue( FM_PROP_LABEL );
            if ( aText.hasValue() )
                OSL_VERIFY( aText >>= _rpDescriptor->Text );

            // --------------------------------
            // readonly
            if ( xPSI->hasPropertyByName( FM_PROP_READONLY ) )
                OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_READONLY ) >>= _rpDescriptor->ReadOnly );

            // --------------------------------
            // border
            {
                if ( xPSI->hasPropertyByName( FM_PROP_BORDER ) )
                {
                    sal_Int16 nBorderType = 0;
                    OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_BORDER ) >>= nBorderType );
                    _rpDescriptor->Border = ( nBorderType != 0 );

                    ::rtl::OUString sBorderColorPropertyName( RTL_CONSTASCII_USTRINGPARAM( "BorderColor" ) );
                    if ( xPSI->hasPropertyByName( sBorderColorPropertyName ) )
                    {
                        sal_Int32 nBoderColor = COL_TRANSPARENT;
                        if ( xModelProps->getPropertyValue( sBorderColorPropertyName ) >>= nBoderColor )
                            _rpDescriptor->BorderColor = Color( nBoderColor );
                        else
                            _rpDescriptor->BorderColor = Color( COL_BLACK );
                    }
                }
            }

            // --------------------------------
            // background color
            if ( xPSI->hasPropertyByName( FM_PROP_BACKGROUNDCOLOR ) )
            {
                sal_Int32 nBackColor = COL_TRANSPARENT;
                xModelProps->getPropertyValue( FM_PROP_BACKGROUNDCOLOR ) >>= nBackColor;
                _rpDescriptor->Background = true;
                _rpDescriptor->BackgroundColor = Color( nBackColor );
            }

            // --------------------------------
            // text color
            if ( xPSI->hasPropertyByName( FM_PROP_TEXTCOLOR ) )
            {
                sal_Int32 nTextColor = COL_TRANSPARENT;
                xModelProps->getPropertyValue( FM_PROP_TEXTCOLOR ) >>= nTextColor;
                _rpDescriptor->TextColor = Color( nTextColor );
            }

            // --------------------------------
            // text style
            _rpDescriptor->TextStyle = 0;
            // ............................
            // multi line and word break
            // The MultiLine property of the control is mapped to both the "MULTILINE" and
            // "WORDBREAK" style flags
            if ( xPSI->hasPropertyByName( FM_PROP_MULTILINE ) )
            {
                sal_Bool bMultiLine = sal_False;
                OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_MULTILINE ) >>= bMultiLine );
                if ( bMultiLine )
                    _rpDescriptor->TextStyle |= TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK;
            }
            // ............................
            // horizontal alignment
            if ( xPSI->hasPropertyByName( FM_PROP_ALIGN ) )
            {
                sal_Int16 nAlign = awt::TextAlign::LEFT;
                xModelProps->getPropertyValue( FM_PROP_ALIGN ) >>= nAlign;
                // TODO: when the property is VOID - are there situations/UIs where this
                // means something else than LEFT?
                switch ( nAlign )
                {
                case awt::TextAlign::LEFT:  _rpDescriptor->TextStyle |= TEXT_DRAW_LEFT; break;
                case awt::TextAlign::CENTER:  _rpDescriptor->TextStyle |= TEXT_DRAW_CENTER; break;
                case awt::TextAlign::RIGHT:  _rpDescriptor->TextStyle |= TEXT_DRAW_RIGHT; break;
                default:
                    OSL_ENSURE( sal_False, "describePDFControl: invalid text align!" );
                }
            }
            // ............................
            // vertical alignment
            {
                ::rtl::OUString sVertAlignPropertyName( RTL_CONSTASCII_USTRINGPARAM( "VerticalAlign" ) );
                if ( xPSI->hasPropertyByName( sVertAlignPropertyName ) )
                {
                    sal_Int16 nAlign = VerticalAlignment_MIDDLE;
                    xModelProps->getPropertyValue( sVertAlignPropertyName ) >>= nAlign;
                    switch ( nAlign )
                    {
                    case VerticalAlignment_TOP:  _rpDescriptor->TextStyle |= TEXT_DRAW_TOP; break;
                    case VerticalAlignment_MIDDLE:  _rpDescriptor->TextStyle |= TEXT_DRAW_VCENTER; break;
                    case VerticalAlignment_BOTTOM:  _rpDescriptor->TextStyle |= TEXT_DRAW_BOTTOM; break;
                    default:
                        OSL_ENSURE( sal_False, "describePDFControl: invalid vertical text align!" );
                    }
                }
            }

            // font
            if ( xPSI->hasPropertyByName( FM_PROP_FONT ) )
            {
                FontDescriptor aUNOFont;
                OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_FONT ) >>= aUNOFont );
                _rpDescriptor->TextFont = VCLUnoHelper::CreateFont( aUNOFont, Font() );
            }
            
            // tab order
            rtl::OUString aTabIndexString( RTL_CONSTASCII_USTRINGPARAM( "TabIndex" ) );
            if ( xPSI->hasPropertyByName( aTabIndexString ) )
            {
                sal_Int16 nIndex = -1;
                OSL_VERIFY( xModelProps->getPropertyValue( aTabIndexString ) >>= nIndex );
                _rpDescriptor->TabOrder = nIndex;
            }

            // ================================
            // special widget properties
            // --------------------------------
            // edits
            if ( _rpDescriptor->getType() == ::vcl::PDFWriter::Edit )
            {
                ::vcl::PDFWriter::EditWidget* pEditWidget = static_cast< ::vcl::PDFWriter::EditWidget* >( _rpDescriptor.get() );
                // ............................
                // multiline (already flagged in the TextStyle)
                pEditWidget->MultiLine = ( _rpDescriptor->TextStyle & TEXT_DRAW_MULTILINE ) != 0;
                // ............................
                // password input
                ::rtl::OUString sEchoCharPropName( RTL_CONSTASCII_USTRINGPARAM( "EchoChar" ) );
                if ( xPSI->hasPropertyByName( sEchoCharPropName ) )
                {
                    sal_Int16 nEchoChar = 0;
                    if ( ( xModelProps->getPropertyValue( sEchoCharPropName ) >>= nEchoChar ) && ( nEchoChar != 0 ) )
                        pEditWidget->Password = true;
                }
                // ............................
                // file select
                if ( xSI->supportsService( FM_SUN_COMPONENT_FILECONTROL ) )
                    pEditWidget->FileSelect = true;
                // ............................
                // maximum text length
                if ( xPSI->hasPropertyByName( FM_PROP_MAXTEXTLEN ) )
                {
                    sal_Int16 nMaxTextLength = 0;
                    OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_MAXTEXTLEN ) >>= nMaxTextLength );
                    if ( nMaxTextLength <= 0 )
                        // "-1" has a special meaning for database-bound controls
                        nMaxTextLength = 0;
                    pEditWidget->MaxLen = nMaxTextLength;
                }
            }

            // --------------------------------
            // buttons
            if ( _rpDescriptor->getType() == ::vcl::PDFWriter::PushButton )
            {
                ::vcl::PDFWriter::PushButtonWidget* pButtonWidget = static_cast< ::vcl::PDFWriter::PushButtonWidget* >( _rpDescriptor.get() );
                FormButtonType eButtonType = FormButtonType_PUSH;
                OSL_VERIFY( xModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ButtonType" ) ) ) >>= eButtonType );
                if ( eButtonType == FormButtonType_SUBMIT )
                {
                    // if a button is a submit button, then it uses the URL at it's parent form
                    Reference< XChild > xChild( xModelProps, UNO_QUERY );
                    Reference < XPropertySet > xParentProps;
                    if ( xChild.is() )
                        xParentProps = xParentProps.query( xChild->getParent() );
                    if ( xParentProps.is() )
                    {
                        Reference< XServiceInfo > xParentSI( xParentProps, UNO_QUERY );
                        if ( xParentSI.is() && xParentSI->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.component.HTMLForm" ) ) ) )
                        {
                            OSL_VERIFY( xParentProps->getPropertyValue( FM_PROP_TARGET_URL ) >>= pButtonWidget->URL );
                            pButtonWidget->Submit = true;
                            FormSubmitMethod eMethod = FormSubmitMethod_POST;
                            OSL_VERIFY( xParentProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SubmitMethod" ) ) ) >>= eMethod );
                            pButtonWidget->SubmitGet = (eMethod == FormSubmitMethod_GET);
                        }
                    }
                }
                else if ( eButtonType == FormButtonType_URL )
                {
                    ::rtl::OUString sURL;
                    OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_TARGET_URL ) >>= sURL );
                    const bool bDocumentLocalTarget = ( sURL.getLength() > 0 ) && ( sURL.getStr()[0] == '#' );
                    if ( bDocumentLocalTarget )
                    {
                        const ::rtl::OUString sDestinationName( sURL.copy(1) );
                        // Register the destination for for future handling ...
                        pButtonWidget->Dest = i_pdfExportData.RegisterDest();

                        // and put it into the bookmarks, to ensure the future handling really happens
                        ::std::vector< ::vcl::PDFExtOutDevBookmarkEntry >& rBookmarks( i_pdfExportData.GetBookmarks() );
                        ::vcl::PDFExtOutDevBookmarkEntry aBookmark;
                        aBookmark.nDestId = pButtonWidget->Dest;
                        aBookmark.aBookmark = sURL;
                        rBookmarks.push_back( aBookmark );
                    }
                    else
                        pButtonWidget->URL = sURL;

                    pButtonWidget->Submit = false;
                }

               // TODO:
                // In PDF files, buttons are either reset, url or submit buttons. So if we have a simple PUSH button
                // in a document, then this means that we do not export a SubmitToURL, which means that in PDF,
                // the button is used as reset button.
                // Is this desired? If no, we would have to reset _rpDescriptor to NULL here, in case eButtonType
                // != FormButtonType_SUBMIT && != FormButtonType_RESET

                // the PDF exporter defaults the text style, if 0. To prevent this, we have to transfer the UNO
                // defaults to the PDF widget
                if ( !pButtonWidget->TextStyle )
                    pButtonWidget->TextStyle = TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER;
            }

            // --------------------------------
            // check boxes
            if ( _rpDescriptor->getType() == ::vcl::PDFWriter::CheckBox )
            {
                ::vcl::PDFWriter::CheckBoxWidget* pCheckBoxWidget = static_cast< ::vcl::PDFWriter::CheckBoxWidget* >( _rpDescriptor.get() );
                sal_Int16 nState = 0;
                OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_STATE ) >>= nState );
                pCheckBoxWidget->Checked = ( nState != 0 );
            }

            // --------------------------------
            // radio buttons
            if ( _rpDescriptor->getType() == ::vcl::PDFWriter::RadioButton )
            {
                ::vcl::PDFWriter::RadioButtonWidget* pRadioWidget = static_cast< ::vcl::PDFWriter::RadioButtonWidget* >( _rpDescriptor.get() );
                sal_Int16 nState = 0;
                OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_STATE ) >>= nState );
                pRadioWidget->Selected = ( nState != 0 );
                pRadioWidget->RadioGroup = determineRadioGroupId( xModelProps );
                try
                {
                    xModelProps->getPropertyValue( FM_PROP_REFVALUE ) >>= pRadioWidget->OnValue;
                }
                catch(...)
                {
                    pRadioWidget->OnValue = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "On" ) );
                }
            }

            // --------------------------------
            // list boxes
            if ( _rpDescriptor->getType() == ::vcl::PDFWriter::ListBox )
            {
                ::vcl::PDFWriter::ListBoxWidget* pListWidget = static_cast< ::vcl::PDFWriter::ListBoxWidget* >( _rpDescriptor.get() );
                // ............................
                // drop down
                OSL_VERIFY( xModelProps->getPropertyValue( FM_PROP_DROPDOWN ) >>= pListWidget->DropDown );
                // ............................
                // multi selection
                OSL_VERIFY( xModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MultiSelection" ) ) ) >>= pListWidget->MultiSelect );
                // ............................
                // entries
                getStringItemVector( xModelProps, pListWidget->Entries );
                // since we explicitly list the entries in the order in which they appear, they should not be
                // resorted by the PDF viewer
                pListWidget->Sort = false;
                
                // get selected items
                Sequence< sal_Int16 > aSelectIndices;
                OSL_VERIFY( xModelProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SelectedItems" ) ) ) >>= aSelectIndices );
                if( aSelectIndices.getLength() > 0 )
                {
                    pListWidget->SelectedEntries.resize( 0 );
                    for( sal_Int32 i = 0; i < aSelectIndices.getLength(); i++ )
                    {
                        sal_Int16 nIndex = aSelectIndices.getConstArray()[i];
                        if( nIndex >= 0 && nIndex < (sal_Int16)pListWidget->Entries.size() )
                            pListWidget->SelectedEntries.push_back( nIndex );
                    }
                }
            }

            // --------------------------------
            // combo boxes
            if ( _rpDescriptor->getType() == ::vcl::PDFWriter::ComboBox )
            {
                ::vcl::PDFWriter::ComboBoxWidget* pComboWidget = static_cast< ::vcl::PDFWriter::ComboBoxWidget* >( _rpDescriptor.get() );
                // ............................
                // entries
                getStringItemVector( xModelProps, pComboWidget->Entries );
                // same reasoning as above
                pComboWidget->Sort = false;
            }

            // ================================
            // some post-processing
            // --------------------------------
            // text line ends
            // some controls may (always or dependent on other settings) return UNIX line ends
            String aConverter( _rpDescriptor->Text );
            _rpDescriptor->Text = aConverter.ConvertLineEnd( LINEEND_CRLF );
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }

//........................................................................
} // namespace toolkitform
//........................................................................
