/**************************************************************
 *
 * 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
//........................................................................
