Commits

Anonymous committed 13baab1

container_controls: add support for data-aware controls

  • Participants
  • Parent commits 18731d6

Comments (0)

Files changed (16)

extensions/source/propctrlr/defaultforminspection.cxx

             { "com.sun.star.form.inspection.EventHandler", false },
 
             // a handler which introduces virtual properties for binding controls to spreadsheet cells
-            { "com.sun.star.form.inspection.CellBindingPropertyHandler", true },
+            { "com.sun.star.form.inspection.CellBindingPropertyHandler", false },
 
             // properties related to binding to an XForms DOM node
             { "com.sun.star.form.inspection.XMLFormsPropertyHandler", true },

oox/inc/oox/helper/propertyset.hxx

 
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/frame/XModel.hpp>
 
 namespace oox {
 
     setAnyProperty( nPropId, ::com::sun::star::uno::Any( rValue ) );
 }
 
+class FormPropertySet : public PropertySet
+{
+public:
+    inline explicit     FormPropertySet() : PropertySet() {}
+
+    /** Constructs a property set wrapper with the passed UNO property set. */
+    inline explicit     FormPropertySet(
+                            const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rxPropSet ) : PropertySet( rxPropSet ) {}
+
+    /** Constructs a property set wrapper after querying the XPropertySet interface. */
+    template< typename Type >
+    inline explicit     FormPropertySet( const Type& rObject ) : PropertySet( rObject ) {}
+    void setDataAwareProperties(  const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxDocModel, const PropertyMap& );
+};
 // ============================================================================
 
 } // namespace oox

oox/inc/oox/ole/vbacontrol.hxx

                             ApiControlType eCtrlType,
                             sal_Int32 nCtrlIndex ) const;
 
+    void                convertDataAwareProperties( PropertyMap& rPropMap );
+
 protected:
     ::rtl::OUString     maName;             /// Name of the control.
     ::rtl::OUString     maTag;              /// User defined tag.
     ::rtl::OUString     maToolTip;          /// Tool tip for the control.
-    ::rtl::OUString     maLinkedCell;       /// Linked cell for the control value in a spreadsheet.
-    ::rtl::OUString     maSourceRange;      /// Source data for the control in a spreadsheet.
+    ::rtl::OUString     maControlSource;    /// Linked cell for the control value in a spreadsheet.
+    ::rtl::OUString     maRowSource;        /// Source data for the control in a spreadsheet.
     AxPairData          maPos;              /// Position in parent container.
     sal_Int32           mnId;               /// Control identifier.
     sal_Int32           mnHelpContextId;    /// Help context identifier.
         and converts all control properties. */
     void                createAndConvert(
                             sal_Int32 nCtrlIndex,
+                            const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxDocModel,
                             const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxParentNC,
                             const ControlConverter& rConv ) const;
 
 
     /** Converts all control properties, and inserts and converts embedded controls. */
     bool                convertProperties(
+                            const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxDocModel,
                             const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& rxCtrlModel,
                             const ControlConverter& rConv,
                             sal_Int32 nCtrlIndex ) const;

oox/source/helper/propertyset.cxx

 #include <osl/diagnose.h>
 #include "oox/helper/propertymap.hxx"
 
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/form/binding/XBindableValue.hpp>
+#include <com/sun/star/form/binding/XListEntrySink.hpp>
+#include <com/sun/star/form/binding/XListEntrySource.hpp>
+#include <com/sun/star/form/binding/XValueBinding.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/sheet/XCellRangeReferrer.hpp>
+#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <oox/helper/helper.hxx>
+
+#include "properties.hxx"
+
 using ::rtl::OUString;
 using ::rtl::OStringBuffer;
 using ::rtl::OUStringToOString;
 using ::com::sun::star::uno::Reference;
 using ::com::sun::star::uno::Sequence;
 using ::com::sun::star::uno::Exception;
+using ::com::sun::star::uno::makeAny;
 using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::uno::UNO_QUERY_THROW;
+using ::com::sun::star::lang::XMultiServiceFactory;
 using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::beans::NamedValue;
+using ::com::sun::star::frame::XModel;
+using ::com::sun::star::container::XNameAccess;
+using ::com::sun::star::form::binding::XBindableValue;
+using ::com::sun::star::form::binding::XListEntrySink;
+using ::com::sun::star::form::binding::XListEntrySource;
+using ::com::sun::star::form::binding::XValueBinding;
+using ::com::sun::star::table::CellRangeAddress;
+using ::com::sun::star::table::CellAddress;
+using ::com::sun::star::sheet::XCellRangeReferrer;
+using ::com::sun::star::sheet::XCellRangeAddressable;
 
 namespace oox {
 
     PropertyMap::dump( Reference< XPropertySet >( getXPropertySet(), UNO_QUERY ) );
 }
 #endif
+bool lcl_isNamedRange( const rtl::OUString& sAddress, const Reference< XModel >& xModel, CellRangeAddress& aAddress )
+{
+    bool bRes = false;
+    const static OUString sNamedRanges( RTL_CONSTASCII_USTRINGPARAM("NamedRanges"));
+    Reference< XCellRangeReferrer > xReferrer;
+    try
+    {
+        Reference< XPropertySet > xPropSet( xModel, UNO_QUERY_THROW );
+        Reference< XNameAccess > xNamed( xPropSet->getPropertyValue( sNamedRanges ), UNO_QUERY_THROW );
+        xReferrer.set ( xNamed->getByName( sAddress ), UNO_QUERY );
+    }
+    catch( Exception& /*e*/ )
+    {
+        // do nothing
+    }
+    if ( xReferrer.is() )
+    {
+        Reference< XCellRangeAddressable > xRangeAddressable( xReferrer->getReferredCells(), UNO_QUERY );
+        if ( xRangeAddressable.is() )
+        {
+            aAddress = xRangeAddressable->getRangeAddress();
+            bRes = true;
+        }
+    }
+    return bRes;
+}
+
+void lcl_ApplyListSourceAndBindableStuff( const Reference< XModel >& xModel, const Reference< XPropertySet >& rPropSet, const OUString& rsCtrlSource, const OUString& rsRowSource )
+{
+// XBindable etc.
+    Reference< XMultiServiceFactory > xFac;
+    if ( xModel.is() )
+        xFac.set( xModel, UNO_QUERY );
+    Reference< XBindableValue > xBindable( rPropSet, UNO_QUERY );
+    if (  xFac.is() && rsCtrlSource.getLength() && xBindable.is() )
+    {
+         
+         // OOo address structures
+         // RefCell - convert from XL
+         // pretend we converted the imported string address into the
+         // appropriate address structure
+         Reference< XPropertySet > xConvertor( xFac->createInstance( CREATE_OUSTRING( "com.sun.star.table.CellAddressConversion" )), UNO_QUERY );
+         CellAddress aAddress;
+         if ( xConvertor.is() )
+         {
+             // we need this service to properly convert XL notation also
+             // Should be easy to extend
+             xConvertor->setPropertyValue( CREATE_OUSTRING( "XL_A1_Representation" ), makeAny( rsCtrlSource ) );
+             xConvertor->getPropertyValue( CREATE_OUSTRING( "Address" ) ) >>= aAddress;    
+         }
+        
+         NamedValue aArg1;
+         aArg1.Name = CREATE_OUSTRING("BoundCell");
+         aArg1.Value <<= aAddress;
+
+         Sequence< Any > aArgs(1);
+         aArgs[ 0 ]  <<= aArg1;
+
+         Reference< XValueBinding > xBinding( xFac->createInstanceWithArguments( CREATE_OUSTRING("com.sun.star.table.CellValueBinding" ), aArgs ), UNO_QUERY );
+         xBindable->setValueBinding( xBinding );
+    }
+    Reference< XListEntrySink > xListEntrySink( rPropSet, UNO_QUERY );
+    if (  xFac.is() && rsRowSource.getLength() && xListEntrySink.is() )
+    {
+         
+         // OOo address structures
+         // RefCell - convert from XL
+         // pretend we converted the imported string address into the
+         // appropriate address structure
+         Reference< XPropertySet > xConvertor( xFac->createInstance( CREATE_OUSTRING( "com.sun.star.table.CellRangeAddressConversion" )), UNO_QUERY );
+         CellRangeAddress aAddress;
+         if ( xConvertor.is() )
+         {
+             if ( !lcl_isNamedRange( rsRowSource, xModel, aAddress ) )
+             {
+                 // we need this service to properly convert XL notation also
+                 // Should be easy to extend
+                 xConvertor->setPropertyValue( CREATE_OUSTRING( "XL_A1_Representation" ), makeAny( rsRowSource ) );
+                 xConvertor->getPropertyValue( CREATE_OUSTRING( "Address" ) ) >>= aAddress;
+             }
+         }
+        
+         NamedValue aArg1;
+         aArg1.Name = CREATE_OUSTRING("CellRange");
+         aArg1.Value <<= aAddress;
+
+         Sequence< Any > aArgs(1);
+         aArgs[ 0 ]  <<= aArg1;
+
+         Reference< XListEntrySource > xSource( xFac->createInstanceWithArguments( CREATE_OUSTRING("com.sun.star.table.CellRangeListSource" ), aArgs ), UNO_QUERY );
+         xListEntrySink->setListEntrySource( xSource );
+    }
+}
+void FormPropertySet::setDataAwareProperties( const Reference< XModel >& rxDocModel, const PropertyMap& rMap )
+{
+    OUString sRowSource;
+    OUString sControlSource;
+    if ( rMap.hasProperty( PROP_ControlSource ) )
+        *(rMap.getProperty( PROP_ControlSource )) >>= sControlSource;
+    if ( rMap.hasProperty( PROP_RowSource ) )
+        *(rMap.getProperty( PROP_RowSource )) >>= sRowSource;
+    lcl_ApplyListSourceAndBindableStuff( rxDocModel, getXPropertySet(), sControlSource, sRowSource );
+}
 
 // ============================================================================
 

oox/source/ole/axcontrol.cxx

         case API_CONTROL_FIXEDTEXT:     return CREATE_OUSTRING( "com.sun.star.awt.UnoControlFixedTextModel" );
         case API_CONTROL_IMAGE:         return CREATE_OUSTRING( "com.sun.star.awt.UnoControlImageControlModel" );
         case API_CONTROL_CHECKBOX:      return CREATE_OUSTRING( "com.sun.star.awt.UnoControlCheckBoxModel" );
-        case API_CONTROL_RADIOBUTTON:   return CREATE_OUSTRING( "com.sun.star.awt.UnoControlRadioButtonModel" );
+        case API_CONTROL_RADIOBUTTON:   return CREATE_OUSTRING( "com.sun.star.form.component.RadioButton" );
         case API_CONTROL_EDIT:          return CREATE_OUSTRING( "com.sun.star.awt.UnoControlEditModel" );
-        case API_CONTROL_LISTBOX:       return CREATE_OUSTRING( "com.sun.star.awt.UnoControlListBoxModel" );
-        case API_CONTROL_COMBOBOX:      return CREATE_OUSTRING( "com.sun.star.awt.UnoControlComboBoxModel" );
-        case API_CONTROL_SPINBUTTON:    return CREATE_OUSTRING( "com.sun.star.awt.UnoControlSpinButtonModel" );
-        case API_CONTROL_SCROLLBAR:     return CREATE_OUSTRING( "com.sun.star.awt.UnoControlScrollBarModel" );
+        case API_CONTROL_LISTBOX:       return CREATE_OUSTRING( "com.sun.star.form.component.ListBox" );
+        case API_CONTROL_COMBOBOX:      return CREATE_OUSTRING( "com.sun.star.form.component.ComboBox" );
+        case API_CONTROL_SPINBUTTON:    return CREATE_OUSTRING( "com.sun.star.form.component.SpinButton" );
+        case API_CONTROL_SCROLLBAR:     return CREATE_OUSTRING( "com.sun.star.form.component.ScrollBar" );
         case API_CONTROL_PROGRESSBAR:   return CREATE_OUSTRING( "com.sun.star.awt.UnoControlProgressBarModel" );
         case API_CONTROL_FRAME:         return CREATE_OUSTRING( "com.sun.star.awt.UnoFrameModel" );
         case API_CONTROL_PAGE:          return CREATE_OUSTRING( "com.sun.star.awt.UnoPageModel" );

oox/source/ole/vbacontrol.cxx

     aReader.skipUndefinedProperty();
     aReader.readStringProperty( maToolTip );
     aReader.skipStringProperty();   // license key
-    aReader.readStringProperty( maLinkedCell );
-    aReader.readStringProperty( maSourceRange );
+    aReader.readStringProperty( maControlSource );
+    aReader.readStringProperty( maRowSource );
     return aReader.finalizeImport();
 }
 
     return xCtrlModel;
 }
 
+void VbaSiteModel::convertDataAwareProperties( PropertyMap& rPropMap )
+{
+    rPropMap.setProperty( PROP_ControlSource, maControlSource );
+    rPropMap.setProperty( PROP_RowSource, maRowSource );
+}
+
 void VbaSiteModel::convertProperties( PropertyMap& rPropMap,
         const ControlConverter& rConv, ApiControlType eCtrlType, sal_Int32 nCtrlIndex ) const
 {
 }
 
 void VbaFormControl::createAndConvert( sal_Int32 nCtrlIndex,
+         const Reference< XModel >& rxDocModel,
         const Reference< XNameContainer >& rxParentNC, const ControlConverter& rConv ) const
 {
     if( rxParentNC.is() && mxSiteModel.get() && mxCtrlModel.get() ) try
         Reference< XControlModel > xCtrlModel( xModelFactory->createInstance( aServiceName ), UNO_QUERY_THROW );
 
         // convert all properties and embedded controls
-        if( convertProperties( xCtrlModel, rConv, nCtrlIndex ) )
+        if( convertProperties( rxDocModel, xCtrlModel, rConv, nCtrlIndex ) )
         {
             // insert into parent container
             const OUString& rCtrlName = mxSiteModel->getName();
     }
 }
 
-bool VbaFormControl::convertProperties( const Reference< XControlModel >& rxCtrlModel,
+bool VbaFormControl::convertProperties( const Reference< XModel >& rxDocModel, const Reference< XControlModel >& rxCtrlModel,
         const ControlConverter& rConv, sal_Int32 nCtrlIndex ) const
 {
     if( rxCtrlModel.is() && mxSiteModel.get() && mxCtrlModel.get() )
             // convert all properties
             PropertyMap aPropMap;
             mxSiteModel->convertProperties( aPropMap, rConv, mxCtrlModel->getControlType(), nCtrlIndex );
+            PropertyMap aDataPropMap;
+            mxSiteModel->convertDataAwareProperties( aDataPropMap );
             mxCtrlModel->convertProperties( aPropMap, rConv );
             mxCtrlModel->convertSize( aPropMap, rConv );
-            PropertySet aPropSet( rxCtrlModel );
+            FormPropertySet aPropSet( rxCtrlModel );
             aPropSet.setProperties( aPropMap );
+            aPropSet.setDataAwareProperties( rxDocModel, aDataPropMap );
 
             // create and convert all embedded controls
             if( !maControls.empty() ) try
                 /*  Call conversion for all controls. Pass vector index as new
                     tab order to make option button groups work correctly. */
                 maControls.forEachMemWithIndex( &VbaFormControl::createAndConvert,
-                    ::boost::cref( xCtrlModelNC ), ::boost::cref( rConv ) );
+                    ::boost::cref( rxDocModel ), ::boost::cref( xCtrlModelNC ), ::boost::cref( rConv ) );
             }
             catch( Exception& )
             {
         Reference< XNameContainer > xDialogNC( xDialogModel, UNO_QUERY_THROW );
 
         // convert properties and embedded controls
-        if( convertProperties( xDialogModel, *this, 0 ) )
+        if( convertProperties( rxDocModel, xDialogModel, *this, 0 ) )
         {
             // export the dialog to XML and insert it into the dialog library
             PropertySet aFactoryProps( mxGlobalFactory );

oox/source/token/properties.txt

 ConditionalFormat
 ConnectBars
 ContainsHeader
+ControlSource
 Coordinates
 CopyBack
 CopyFormulas
 RotationVertical
 RowGrand
 RowLabelRanges
+RowSource
 ScaleMode
 ScaleToPages
 ScaleToPagesX

sc/inc/addruno.hxx

     sal_Int32               nRefSheet;
     sal_Bool                bIsRange;
 
-    sal_Bool                ParseUIString( const String& rUIString );
+    sal_Bool                ParseUIString( const String& rUIString, ::formula::FormulaGrammar::AddressConvention eConv = ::formula::FormulaGrammar::CONV_OOO );
 
 public:
 

sc/inc/unonames.hxx

 #define SC_UNONAME_ADDRESS          "Address"
 #define SC_UNONAME_UIREPR           "UserInterfaceRepresentation"
 #define SC_UNONAME_PERSREPR         "PersistentRepresentation"
+#define SC_UNONAME_XL_A1_REPR       "XL_A1_Representation"
 #define SC_UNONAME_REFSHEET         "ReferenceSheet"
 
 // --> PB 2004-08-23 #i33095# Security Options

sc/source/ui/unoobj/addruno.cxx

     }
 }
 
-sal_Bool ScAddressConversionObj::ParseUIString( const String& rUIString )
+sal_Bool ScAddressConversionObj::ParseUIString( const String& rUIString, ::formula::FormulaGrammar::AddressConvention eConv )
 {
     if (!pDocShell)
         return sal_False;
     sal_Bool bSuccess = sal_False;
     if ( bIsRange )
     {
-        USHORT nResult = aRange.ParseAny( rUIString, pDoc );
+        USHORT nResult = aRange.ParseAny( rUIString, pDoc, eConv );
         if ( nResult & SCA_VALID )
         {
             if ( ( nResult & SCA_TAB_3D ) == 0 )
     }
     else
     {
-        USHORT nResult = aRange.aStart.Parse( rUIString, pDoc );
+        USHORT nResult = aRange.aStart.Parse( rUIString, pDoc, eConv );
         if ( nResult & SCA_VALID )
         {
             if ( ( nResult & SCA_TAB_3D ) == 0 )
         {
             {MAP_CHAR_LEN(SC_UNONAME_ADDRESS),  0,  &getCppuType((table::CellRangeAddress*)0), 0, 0 },
             {MAP_CHAR_LEN(SC_UNONAME_PERSREPR), 0,  &getCppuType((rtl::OUString*)0),    0, 0 },
+            {MAP_CHAR_LEN(SC_UNONAME_XL_A1_REPR), 0,  &getCppuType((rtl::OUString*)0),    0, 0 },
             {MAP_CHAR_LEN(SC_UNONAME_REFSHEET), 0,  &getCppuType((sal_Int32*)0),        0, 0 },
             {MAP_CHAR_LEN(SC_UNONAME_UIREPR),   0,  &getCppuType((rtl::OUString*)0),    0, 0 },
             {0,0,0,0,0,0}
         {
             {MAP_CHAR_LEN(SC_UNONAME_ADDRESS),  0,  &getCppuType((table::CellAddress*)0), 0, 0 },
             {MAP_CHAR_LEN(SC_UNONAME_PERSREPR), 0,  &getCppuType((rtl::OUString*)0),    0, 0 },
+            {MAP_CHAR_LEN(SC_UNONAME_XL_A1_REPR), 0,  &getCppuType((rtl::OUString*)0),    0, 0 },
             {MAP_CHAR_LEN(SC_UNONAME_REFSHEET), 0,  &getCppuType((sal_Int32*)0),        0, 0 },
             {MAP_CHAR_LEN(SC_UNONAME_UIREPR),   0,  &getCppuType((rtl::OUString*)0),    0, 0 },
             {0,0,0,0,0,0}
             bSuccess = ParseUIString( aUIString );
         }
     }
-    else if ( aNameStr.EqualsAscii( SC_UNONAME_PERSREPR ) )
+    else if ( aNameStr.EqualsAscii( SC_UNONAME_PERSREPR ) || aNameStr.EqualsAscii( SC_UNONAME_XL_A1_REPR ) )
     {
+        ::formula::FormulaGrammar::AddressConvention aConv = ::formula::FormulaGrammar::CONV_OOO; 
+        if ( aNameStr.EqualsAscii( SC_UNONAME_XL_A1_REPR ) )
+            aConv = ::formula::FormulaGrammar::CONV_XL_A1; 
         //  parse the file format string
         rtl::OUString sRepresentation;
         if (aValue >>= sRepresentation)
             }
 
             //  parse the rest like a UI string
-            bSuccess = ParseUIString( aUIString );
+            bSuccess = ParseUIString( aUIString, aConv );
         }
     }
     else
             aRange.aStart.Format( aFormatStr, nFlags, pDoc );
         aRet <<= rtl::OUString( aFormatStr );
     }
-    else if ( aNameStr.EqualsAscii( SC_UNONAME_PERSREPR ) )
+    else if ( aNameStr.EqualsAscii( SC_UNONAME_PERSREPR ) || aNameStr.EqualsAscii( SC_UNONAME_XL_A1_REPR ) )
     {
+        ::formula::FormulaGrammar::AddressConvention aConv = ::formula::FormulaGrammar::CONV_OOO; 
+        if ( aNameStr.EqualsAscii( SC_UNONAME_XL_A1_REPR ) )
+            aConv = ::formula::FormulaGrammar::CONV_XL_A1; 
+
         //  generate file format string - always include sheet
         String aFormatStr;
-        aRange.aStart.Format( aFormatStr, SCA_VALID | SCA_TAB_3D, pDoc );
+        aRange.aStart.Format( aFormatStr, SCA_VALID | SCA_TAB_3D, pDoc, aConv );
         if ( bIsRange )
         {
             //  manually concatenate range so both parts always have the sheet name
             aFormatStr.Append( (sal_Unicode) ':' );
             String aSecond;
-            aRange.aEnd.Format( aSecond, SCA_VALID | SCA_TAB_3D, pDoc );
+            USHORT nFlags = SCA_VALID;
+            if( aConv != ::formula::FormulaGrammar::CONV_XL_A1 )
+		nFlags |= SCA_TAB_3D;
+            aRange.aEnd.Format( aSecond, SCA_VALID | SCA_TAB_3D, pDoc, aConv );
             aFormatStr.Append( aSecond );
         }
         aRet <<= rtl::OUString( aFormatStr );

xmlscript/source/xmldlg_imexp/exp_share.hxx

 	void readSelectionTypeAttr(
         ::rtl::OUString const & rPropName, ::rtl::OUString const & rAttrName );
 	//
+    void readDataAwareAttr(
+        ::rtl::OUString const & rAttrName );
     inline void addBoolAttr(
         ::rtl::OUString const & rAttrName, sal_Bool bValue )
         { addAttribute( rAttrName, ::rtl::OUString::valueOf(bValue) ); }

xmlscript/source/xmldlg_imexp/imp_share.hxx

     
     ::rtl::OUString getControlId(
         css::uno::Reference<css::xml::input::XAttributes> const & xAttributes );
+    ::rtl::OUString getControlModelName(
+        rtl::OUString const& rDefaultModel,
+        css::uno::Reference<css::xml::input::XAttributes> const & xAttributes );
     css::uno::Reference< css::xml::input::XElement > getStyle(
         css::uno::Reference<css::xml::input::XAttributes> const & xAttributes );
 public:
 	bool importSelectionTypeProperty(
         ::rtl::OUString const & rPropName, ::rtl::OUString const & rAttrName,
         css::uno::Reference<css::xml::input::XAttributes> const & xAttributes );
+    bool importDataAwareProperty( 
+        ::rtl::OUString const & rPropName,
+        css::uno::Reference<css::xml::input::XAttributes> const & xAttributes );
 };
 
 //==============================================================================

xmlscript/source/xmldlg_imexp/xmldlg_expmodels.cxx

     readShortAttr( OUString( RTL_CONSTASCII_USTRINGPARAM("LineCount") ),
                    OUString( RTL_CONSTASCII_USTRINGPARAM(XMLNS_DIALOGS_PREFIX ":linecount") ) );
 
+    readDataAwareAttr( OUSTR(XMLNS_DIALOGS_PREFIX ":linked-cell") );
+    readDataAwareAttr( OUSTR( XMLNS_DIALOGS_PREFIX ":source-cell-range") );
+
     // string item list
     Sequence< OUString > itemValues;
     if ((readProp( OUString( RTL_CONSTASCII_USTRINGPARAM("StringItemList") ) ) >>= itemValues) &&
                    OUString( RTL_CONSTASCII_USTRINGPARAM(XMLNS_DIALOGS_PREFIX ":linecount") ) );
     readAlignAttr( OUString( RTL_CONSTASCII_USTRINGPARAM("Align") ),
                    OUString( RTL_CONSTASCII_USTRINGPARAM(XMLNS_DIALOGS_PREFIX ":align") ) );
-
+    readDataAwareAttr( OUSTR(XMLNS_DIALOGS_PREFIX ":linked-cell") );
+    readDataAwareAttr( OUSTR( XMLNS_DIALOGS_PREFIX ":source-cell-range") );
     // string item list
     Sequence< OUString > itemValues;
     if ((readProp( OUString( RTL_CONSTASCII_USTRINGPARAM("StringItemList") ) ) >>= itemValues) &&
             break;
         }
     }
+    readDataAwareAttr( OUSTR(XMLNS_DIALOGS_PREFIX ":linked-cell") );
     readEvents();
 }
 //__________________________________________________________________________________________________
                   OUString( RTL_CONSTASCII_USTRINGPARAM(XMLNS_DIALOGS_PREFIX ":tabstop") ) );
     readHexLongAttr( OUString( RTL_CONSTASCII_USTRINGPARAM("SymbolColor") ),
                      OUString( RTL_CONSTASCII_USTRINGPARAM(XMLNS_DIALOGS_PREFIX ":symbol-color") ) );
+    readDataAwareAttr( OUSTR(XMLNS_DIALOGS_PREFIX ":linked-cell") );
     readEvents();
 }
 
                   OUString( RTL_CONSTASCII_USTRINGPARAM(XMLNS_DIALOGS_PREFIX ":live-scroll") ) );
     readHexLongAttr( OUString( RTL_CONSTASCII_USTRINGPARAM("SymbolColor") ),
                      OUString( RTL_CONSTASCII_USTRINGPARAM(XMLNS_DIALOGS_PREFIX ":symbol-color") ) );
+    readDataAwareAttr( OUSTR(XMLNS_DIALOGS_PREFIX ":linked-cell") );
     readEvents();
 }
 //__________________________________________________________________________________________________

xmlscript/source/xmldlg_imexp/xmldlg_export.cxx

 #include <com/sun/star/awt/PushButtonType.hpp>
 #include <com/sun/star/awt/VisualEffect.hpp>
 
+#include <com/sun/star/io/XPersistObject.hpp>
+
 #include <com/sun/star/script/XScriptEventsSupplier.hpp>
 #include <com/sun/star/script/ScriptEventDescriptor.hpp>
 
 
 #include <com/sun/star/view/SelectionType.hpp>
 
+#include <com/sun/star/form/binding/XListEntrySink.hpp>
+#include <com/sun/star/form/binding/XBindableValue.hpp>
+#include <com/sun/star/form/binding/XValueBinding.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
 #include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/document/XStorageBasedDocument.hpp>
 #include <com/sun/star/document/XGraphicObjectResolver.hpp>
     }
 }
 //__________________________________________________________________________________________________
+void ElementDescriptor::readDataAwareAttr( OUString const & rAttrName )
+{
+    Reference< lang::XMultiServiceFactory > xFac;
+    if ( _xDocument.is() )
+        xFac.set( _xDocument, uno::UNO_QUERY );
+
+    Reference< form::binding::XBindableValue > xBinding( _xProps, UNO_QUERY );
+
+    if ( xFac.is() && xBinding.is() && rAttrName.equals( OUSTR(XMLNS_DIALOGS_PREFIX ":linked-cell") ) )
+    {
+        try
+        {
+            Reference< beans::XPropertySet > xConvertor( xFac->createInstance( OUSTR( "com.sun.star.table.CellAddressConversion" )), uno::UNO_QUERY );  
+        Reference< beans::XPropertySet > xBindable( xBinding->getValueBinding(), UNO_QUERY );
+            if ( xBindable.is() )
+            {
+                table::CellAddress aAddress; 
+                xBindable->getPropertyValue( OUSTR("BoundCell") ) >>= aAddress; 
+                xConvertor->setPropertyValue( OUSTR("Address"), makeAny( aAddress ) );
+                rtl::OUString sAddress;
+                xConvertor->getPropertyValue( OUSTR("PersistentRepresentation") ) >>= sAddress;
+                if ( sAddress.getLength() > 0 )
+                    addAttribute( rAttrName, sAddress );
+                
+                OSL_TRACE( "*** Bindable value %s", rtl::OUStringToOString( sAddress, RTL_TEXTENCODING_UTF8 ).getStr() ); 
+               
+            }
+        }
+        catch( uno::Exception& )
+        {
+        }
+    }
+    Reference< form::binding::XListEntrySink > xEntrySink( _xProps, UNO_QUERY );
+    if ( xEntrySink.is() && rAttrName.equals( OUSTR( XMLNS_DIALOGS_PREFIX ":source-cell-range") ) )
+    {
+        Reference< beans::XPropertySet > xListSource( xEntrySink->getListEntrySource(), UNO_QUERY );
+        if ( xListSource.is() )
+        {
+            try
+            {
+                Reference< beans::XPropertySet > xConvertor( xFac->createInstance( OUSTR( "com.sun.star.table.CellRangeAddressConversion" )), uno::UNO_QUERY );  
+
+                table::CellRangeAddress aAddress; 
+                xListSource->getPropertyValue( OUSTR( "CellRange" ) ) >>= aAddress;
+
+                rtl::OUString sAddress;
+                xConvertor->setPropertyValue( OUSTR("Address"), makeAny( aAddress ) );
+                xConvertor->getPropertyValue( OUSTR("PersistentRepresentation") ) >>= sAddress;
+                OSL_TRACE("**** cell range source list %s",
+                    rtl::OUStringToOString( sAddress, RTL_TEXTENCODING_UTF8 ).getStr() ); 
+                if ( sAddress.getLength() > 0 )
+                    addAttribute( rAttrName, sAddress );
+            }
+            catch( uno::Exception& )
+            {
+            }
+        }
+    }
+}
+//__________________________________________________________________________________________________
 void ElementDescriptor::readSelectionTypeAttr( OUString const & rPropName, OUString const & rAttrName )
 {
     if (beans::PropertyState_DEFAULT_VALUE != _xPropState->getPropertyState( rPropName ))
 void ElementDescriptor::readDefaults( bool supportPrintable, bool supportVisible )
 {
     Any a( _xProps->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("Name") ) ) );
+    OUString sName;
+    a >>= sName;
+
+    // The following is a hack to allow 'form' controls to override the default
+    // control supported by dialogs. This should work well for both vba support and 
+    // normal openoffice ( when normal 'Dialogs' decide to support form control models )
+    // In the future VBA support might require custom models ( and not the just the form
+    // variant of a control that we currently use ) In this case the door is still open,
+    // we just need to define a new way for the 'ServiceName' to be extracted from the
+    // incomming model. E.g. the use of supporting service 
+    // "com.sun.star.form.FormComponent", 'ServiceName' and XPersistObject 
+    // is only an implementation detail here, in the future some other 
+    // method ( perhaps a custom prop ) could be used instead.
+    Reference< lang::XServiceInfo > xSrvInfo( _xProps, UNO_QUERY );
+    if ( xSrvInfo.is() && xSrvInfo->supportsService( OUSTR("com.sun.star.form.FormComponent" ) ) )
+    {
+        Reference< io::XPersistObject > xPersist( _xProps, UNO_QUERY );
+        if ( xPersist.is() )
+        {
+            OUString sCtrlName = xPersist->getServiceName();
+            if ( sCtrlName.getLength() )
+                    addAttribute( OUString( RTL_CONSTASCII_USTRINGPARAM(XMLNS_DIALOGS_PREFIX ":control-implementation") ), sCtrlName ); 
+        }
+    }
     addAttribute( OUString( RTL_CONSTASCII_USTRINGPARAM(XMLNS_DIALOGS_PREFIX ":id") ),
              * reinterpret_cast< const OUString * >( a.getValue() ) );
     readShortAttr( OUString( RTL_CONSTASCII_USTRINGPARAM("TabIndex") ),

xmlscript/source/xmldlg_imexp/xmldlg_impmodels.cxx

 {
 	ControlImportContext ctx(
 		_pImport, getControlId( _xAttributes ),
-		OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlScrollBarModel") ) );
+		getControlModelName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlScrollBarModel") ), _xAttributes ) );
 	
 	Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) );
 	if (xStyle.is())
                                OUString( RTL_CONSTASCII_USTRINGPARAM("symbol-color") ),
                                _xAttributes );
     
+    ctx.importDataAwareProperty( OUSTR("linked-cell" ), _xAttributes );
 	ctx.importEvents( _events );
     // avoid ring-reference:
     // vector< event elements > holding event elements holding this (via _pParent)
 {
 	ControlImportContext ctx(
 		_pImport, getControlId( _xAttributes ),
-		OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.form.component.SpinButton") ) );
+		getControlModelName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlSpinButtonModel") ), _xAttributes ) );
 	
 	Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) );
 	if (xStyle.is())
     ctx.importHexLongProperty( OUString( RTL_CONSTASCII_USTRINGPARAM("SymbolColor") ),
                                OUString( RTL_CONSTASCII_USTRINGPARAM("symbol-color") ),
                                _xAttributes );
+    ctx.importDataAwareProperty( OUSTR("linked-cell" ), _xAttributes );
     ctx.importEvents( _events );
     // avoid ring-reference:
     // vector< event elements > holding event elements holding this (via _pParent)
 		
 		ControlImportContext ctx(
 			_pImport, getControlId( xAttributes ),
-			OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlRadioButtonModel") ) );
+			getControlModelName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlRadioButtonModel") ), xAttributes ) );
 		Reference< beans::XPropertySet > xControlModel( ctx.getControlModel() );
 		
 		Reference< xml::input::XElement > xStyle( getStyle( xAttributes ) );
         ctx.importBooleanProperty( OUString( RTL_CONSTASCII_USTRINGPARAM("MultiLine") ),
                                    OUString( RTL_CONSTASCII_USTRINGPARAM("multiline") ),
                                    xAttributes );
-		
 		sal_Int16 nVal = 0;
 		sal_Bool bChecked = sal_False;
 		if (getBoolAttr( &bChecked,
 		xControlModel->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("State") ),
 										 makeAny( nVal ) );
         
+	ctx.importDataAwareProperty( OUSTR("linked-cell" ), xAttributes );	
+
         ::std::vector< Reference< xml::input::XElement > > * radioEvents =
             static_cast< RadioElement * >( xRadio.get() )->getEvents();
 		ctx.importEvents( *radioEvents );
 		
 		ControlImportContext ctx(
 			_pImport, getControlId( xAttributes ),
-			OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlRadioButtonModel") ) );
+			getControlModelName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlRadioButtonModel") ), xAttributes ) );
 		Reference< beans::XPropertySet > xControlModel( ctx.getControlModel() );
 		
 		Reference< xml::input::XElement > xStyle( getStyle( xAttributes ) );
 		}
 		xControlModel->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("State") ),
 										 makeAny( nVal ) );
+
+	ctx.importDataAwareProperty( OUSTR("linked-cell" ), xAttributes );	
 		
         ::std::vector< Reference< xml::input::XElement > > * radioEvents =
             static_cast< RadioElement * >( xRadio.get() )->getEvents();
 {
 	ControlImportContext ctx(
 		_pImport, getControlId( _xAttributes ),
-		OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlListBoxModel") ) );
+		getControlModelName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlListBoxModel") ), _xAttributes  ) );
+
 	Reference< beans::XPropertySet > xControlModel( ctx.getControlModel() );
 	
 	Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) );
 	ctx.importAlignProperty( OUString( RTL_CONSTASCII_USTRINGPARAM("Align") ),
                              OUString( RTL_CONSTASCII_USTRINGPARAM("align") ),
                              _xAttributes );
+        
+        bool bHasLinkedCell = ctx.importDataAwareProperty( OUSTR("linked-cell" ), _xAttributes );
+        bool bHasSrcRange = ctx.importDataAwareProperty( OUSTR("source-cell-range" ), _xAttributes );
 	
 	if (_popup.is())
 	{
 		MenuPopupElement * p = static_cast< MenuPopupElement * >( _popup.get() );
-		xControlModel->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("StringItemList") ),
+                if ( !bHasSrcRange )
+		    xControlModel->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("StringItemList") ),
 										 makeAny( p->getItemValues() ) );
-		xControlModel->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("SelectedItems") ),
+                if ( !bHasLinkedCell )
+		    xControlModel->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("SelectedItems") ),
 										 makeAny( p->getSelectedItems() ) );
 	}
 	ctx.importEvents( _events );
 {
 	ControlImportContext ctx(
 		_pImport, getControlId( _xAttributes ),
-		OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlComboBoxModel") ) );
+		getControlModelName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlComboBoxModel") ), _xAttributes ) );
 	Reference< beans::XPropertySet > xControlModel( ctx.getControlModel() );
 	
 	Reference< xml::input::XElement > xStyle( getStyle( _xAttributes ) );
 	ctx.importAlignProperty( OUString( RTL_CONSTASCII_USTRINGPARAM("Align") ),
                              OUString( RTL_CONSTASCII_USTRINGPARAM("align") ),
                              _xAttributes );
-	
-	if (_popup.is())
+	ctx.importDataAwareProperty( OUSTR("linked-cell" ), _xAttributes );
+        bool bHasSrcRange = ctx.importDataAwareProperty( OUSTR("source-cell-range" ), _xAttributes );
+
+	if (_popup.is() && !bHasSrcRange )
 	{
 		MenuPopupElement * p = static_cast< MenuPopupElement * >( _popup.get() );
 		xControlModel->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("StringItemList") ),

xmlscript/source/xmldlg_imexp/xmldlg_import.cxx

 
 #include <com/sun/star/view/SelectionType.hpp>
 #include <com/sun/star/lang/XServiceInfo.hpp>
-
+#include <com/sun/star/form/binding/XBindableValue.hpp>
+#include <com/sun/star/form/binding/XValueBinding.hpp>
+#include <com/sun/star/form/binding/XListEntrySink.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/table/CellAddress.hpp>
+#include <com/sun/star/table/CellRangeAddress.hpp>
 #include <com/sun/star/document/XGraphicObjectResolver.hpp>
 #include <com/sun/star/document/XStorageBasedDocument.hpp>
 
     return aId;
 }
 
+OUString ControlElement::getControlModelName(
+    OUString const& rDefaultModel,
+    Reference< xml::input::XAttributes > const & xAttributes )
+{
+    OUString aModel;
+    aModel = xAttributes->getValueByUidName(
+        _pImport->XMLNS_DIALOGS_UID,
+        OUString( RTL_CONSTASCII_USTRINGPARAM("control-implementation") ) );
+    if (! aModel.getLength())
+        aModel = rDefaultModel;
+    return aModel;
+}
+
+
 //##################################################################################################
 
 //__________________________________________________________________________________________________
     return false;
 }
 //__________________________________________________________________________________________________
+ bool ImportContext::importDataAwareProperty( 
+        ::rtl::OUString const & rPropName,
+        Reference<xml::input::XAttributes> const & xAttributes )
+{
+    OUString sLinkedCell;
+    OUString sCellRange;
+    if ( rPropName.equals( OUSTR("linked-cell" ) ) )
+       sLinkedCell = xAttributes->getValueByUidName( _pImport->XMLNS_DIALOGS_UID, rPropName );
+    if ( rPropName.equals( OUSTR(  "source-cell-range" ) ) )
+    	sCellRange = xAttributes->getValueByUidName( _pImport->XMLNS_DIALOGS_UID, rPropName );    
+    bool bRes = false;
+    Reference< lang::XMultiServiceFactory > xFac( _pImport->getDocOwner(), UNO_QUERY );
+    if ( xFac.is() && ( sLinkedCell.getLength() ||  sCellRange.getLength() ) )
+    {
+        // Set up Celllink
+        if ( sLinkedCell.getLength() )
+        {
+            Reference< form::binding::XBindableValue > xBindable( getControlModel(), uno::UNO_QUERY );
+            Reference< beans::XPropertySet > xConvertor( xFac->createInstance( OUSTR( "com.sun.star.table.CellAddressConversion" )), uno::UNO_QUERY );
+            if ( xBindable.is() && xConvertor.is() )
+            {
+                table::CellAddress aAddress;
+                xConvertor->setPropertyValue( OUSTR( "PersistentRepresentation" ), uno::makeAny( sLinkedCell ) );
+                xConvertor->getPropertyValue( OUSTR( "Address" ) ) >>= aAddress;     
+                beans::NamedValue aArg1;
+                aArg1.Name = OUSTR("BoundCell");
+                aArg1.Value <<= aAddress;
+                
+                uno::Sequence< uno::Any > aArgs(1);
+                aArgs[ 0 ]  <<= aArg1;
+            
+                uno::Reference< form::binding::XValueBinding > xBinding( xFac->createInstanceWithArguments( OUSTR("com.sun.star.table.CellValueBinding" ), aArgs ), uno::UNO_QUERY );
+                xBindable->setValueBinding( xBinding );
+                bRes = true; 
+            }
+        }
+        // Set up CelllRange
+        if ( sCellRange.getLength() )
+        {
+            Reference< form::binding::XListEntrySink  > xListEntrySink( getControlModel(), uno::UNO_QUERY );
+            Reference< beans::XPropertySet > xConvertor( xFac->createInstance( OUSTR( "com.sun.star.table.CellRangeAddressConversion" )), uno::UNO_QUERY );
+            if ( xListEntrySink.is() && xConvertor.is() )
+            {
+                table::CellRangeAddress aAddress;
+                xConvertor->setPropertyValue( OUSTR( "PersistentRepresentation" ), uno::makeAny( sCellRange ) );
+                xConvertor->getPropertyValue( OUSTR( "Address" ) ) >>= aAddress;     
+                beans::NamedValue aArg1;
+                aArg1.Name = OUSTR("CellRange");
+                aArg1.Value <<= aAddress;
+        
+                uno::Sequence< uno::Any > aArgs(1);
+                aArgs[ 0 ]  <<= aArg1;
+    
+                uno::Reference< form::binding::XListEntrySource > xSource( xFac->createInstanceWithArguments( OUSTR("com.sun.star.table.CellRangeListSource" ), aArgs ), uno::UNO_QUERY );
+                xListEntrySink->setListEntrySource( xSource );
+                bRes = true; 
+            }
+        }
+    }
+    return bRes;
+}
+//__________________________________________________________________________________________________
 bool ImportContext::importImageAlignProperty(
     OUString const & rPropName, OUString const & rAttrName,
     Reference< xml::input::XAttributes > const & xAttributes )