[Libreoffice-commits] core.git: 2 commits - extensions/source forms/source include/toolkit offapi/com offapi/UnoApi_offapi.mk qadevOOo/runner sc/source toolkit/source

Eike Rathke erack at redhat.com
Tue Feb 14 10:49:56 UTC 2017


 extensions/source/propctrlr/cellbindinghandler.cxx         |    3 
 extensions/source/propctrlr/formcomponenthandler.cxx       |   10 +
 extensions/source/propctrlr/formmetadata.hxx               |    1 
 extensions/source/propctrlr/formstrings.hxx                |    1 
 forms/source/component/ComboBox.cxx                        |   17 ++
 forms/source/component/ListBox.cxx                         |   39 +++++-
 forms/source/component/entrylisthelper.cxx                 |   54 +++++++-
 forms/source/component/entrylisthelper.hxx                 |   13 ++
 forms/source/inc/frm_strings.hxx                           |    1 
 forms/source/inc/property.hrc                              |    2 
 include/toolkit/helper/property.hxx                        |    1 
 offapi/UnoApi_offapi.mk                                    |    1 
 offapi/com/sun/star/awt/UnoControlComboBoxModel.idl        |   13 ++
 offapi/com/sun/star/awt/UnoControlListBoxModel.idl         |   10 +
 offapi/com/sun/star/form/binding/XListEntryTypedSource.idl |   47 +++++++
 qadevOOo/runner/util/ValueChanger.java                     |   69 ++++++----
 sc/source/ui/unoobj/celllistsource.cxx                     |   83 +++++++++++--
 sc/source/ui/unoobj/celllistsource.hxx                     |   12 +
 toolkit/source/awt/vclxwindows.cxx                         |    2 
 toolkit/source/controls/unocontrolmodel.cxx                |    7 +
 toolkit/source/controls/unocontrols.cxx                    |    2 
 toolkit/source/helper/property.cxx                         |    1 
 22 files changed, 341 insertions(+), 48 deletions(-)

New commits:
commit 838fab822c8052dd9471e28a70b1907dfde111af
Author: Eike Rathke <erack at redhat.com>
Date:   Fri Feb 10 18:27:14 2017 +0100

    Resolves: tdf#79250 add typed list to form control listbox
    
    ... so numeric and text data can be distinguished input.
    
    Change-Id: I63280a93c272ccc6f5e7ca06a1a1fcbfb3db8455

diff --git a/extensions/source/propctrlr/cellbindinghandler.cxx b/extensions/source/propctrlr/cellbindinghandler.cxx
index 578339a..3ac0591 100644
--- a/extensions/source/propctrlr/cellbindinghandler.cxx
+++ b/extensions/source/propctrlr/cellbindinghandler.cxx
@@ -162,7 +162,10 @@ namespace pcr
                 try
                 {
                     if ( !xSource.is() )
+                    {
                         setPropertyValue( PROPERTY_STRINGITEMLIST, makeAny( Sequence< OUString >() ) );
+                        setPropertyValue( PROPERTY_TYPEDITEMLIST, makeAny( Sequence< Any >() ) );
+                    }
                 }
                 catch( const Exception& )
                 {
diff --git a/extensions/source/propctrlr/formcomponenthandler.cxx b/extensions/source/propctrlr/formcomponenthandler.cxx
index 9159e45..0bd51e8 100644
--- a/extensions/source/propctrlr/formcomponenthandler.cxx
+++ b/extensions/source/propctrlr/formcomponenthandler.cxx
@@ -1547,11 +1547,13 @@ namespace pcr
                 // available list source values (tables or queries) might have changed
                 _rxInspectorUI->rebuildPropertyUI( PROPERTY_LISTSOURCE );
             aDependentProperties.push_back( PROPERTY_ID_STRINGITEMLIST );
+            aDependentProperties.push_back( PROPERTY_ID_TYPEDITEMLIST );
             aDependentProperties.push_back( PROPERTY_ID_BOUNDCOLUMN );
             SAL_FALLTHROUGH;
 
         // ----- StringItemList -----
         case PROPERTY_ID_STRINGITEMLIST:
+            aDependentProperties.push_back( PROPERTY_ID_TYPEDITEMLIST );
             aDependentProperties.push_back( PROPERTY_ID_SELECTEDITEMS );
             aDependentProperties.push_back( PROPERTY_ID_DEFAULT_SELECT_SEQ );
             break;
@@ -1559,6 +1561,7 @@ namespace pcr
         // ----- ListSource -----
         case PROPERTY_ID_LISTSOURCE:
             aDependentProperties.push_back( PROPERTY_ID_STRINGITEMLIST );
+            aDependentProperties.push_back( PROPERTY_ID_TYPEDITEMLIST );
             break;
 
         // ----- DataField -----
@@ -1808,6 +1811,13 @@ namespace pcr
             }
             break;  // case PROPERTY_ID_STRINGITEMLIST
 
+            // ----- TypedItemList -----
+            case PROPERTY_ID_TYPEDITEMLIST:
+            {
+                /* TODO: anything? */
+            }
+            break;  // case PROPERTY_ID_TYPEDITEMLIST
+
             // ----- BoundColumn -----
             case PROPERTY_ID_BOUNDCOLUMN:
             {
diff --git a/extensions/source/propctrlr/formmetadata.hxx b/extensions/source/propctrlr/formmetadata.hxx
index 7208a00..0c9f369 100644
--- a/extensions/source/propctrlr/formmetadata.hxx
+++ b/extensions/source/propctrlr/formmetadata.hxx
@@ -326,6 +326,7 @@ namespace pcr
     #define PROPERTY_ID_SCROLL_HEIGHT               204
     #define PROPERTY_ID_SCROLL_TOP                  205
     #define PROPERTY_ID_SCROLL_LEFT                 206
+    #define PROPERTY_ID_TYPEDITEMLIST               207
 
 
 } // namespace pcr
diff --git a/extensions/source/propctrlr/formstrings.hxx b/extensions/source/propctrlr/formstrings.hxx
index c5e8145..a4d8955 100644
--- a/extensions/source/propctrlr/formstrings.hxx
+++ b/extensions/source/propctrlr/formstrings.hxx
@@ -63,6 +63,7 @@ namespace pcr
     #define PROPERTY_BUTTONTYPE             "ButtonType"
     #define PROPERTY_XFORMS_BUTTONTYPE      "XFormsButtonType"
     #define PROPERTY_STRINGITEMLIST         "StringItemList"
+    #define PROPERTY_TYPEDITEMLIST          "TypedItemList"
     #define PROPERTY_DEFAULT_TEXT           "DefaultText"
     #define PROPERTY_DEFAULT_STATE          "DefaultState"
     #define PROPERTY_FORMATKEY              "FormatKey"
diff --git a/forms/source/component/ComboBox.cxx b/forms/source/component/ComboBox.cxx
index 57ff1e6..dd419a1 100644
--- a/forms/source/component/ComboBox.cxx
+++ b/forms/source/component/ComboBox.cxx
@@ -193,6 +193,10 @@ void OComboBoxModel::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) cons
             _rValue <<= comphelper::containerToSequence(getStringItemList());
             break;
 
+        case PROPERTY_ID_TYPEDITEMLIST:
+            _rValue <<= getTypedItemList();
+            break;
+
         default:
             OBoundControlModel::getFastPropertyValue(_rValue, _nHandle);
     }
@@ -247,6 +251,11 @@ void OComboBoxModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const
         }
         break;
 
+        // XXX NOTE: PROPERTY_ID_TYPEDITEMLIST not handled here because only
+        // set for external sources in which case not even
+        // setNewStringItemList() for PROPERTY_ID_STRINGITEMLIST above should
+        // had been called ...
+
         default:
             OBoundControlModel::setFastPropertyValue_NoBroadcast(_nHandle, _rValue);
     }
@@ -304,6 +313,7 @@ void OComboBoxModel::describeAggregateProperties( Sequence< Property >& _rAggreg
 
     // superseded properties:
     RemoveProperty( _rAggregateProps, PROPERTY_STRINGITEMLIST );
+    RemoveProperty( _rAggregateProps, PROPERTY_TYPEDITEMLIST );
 }
 
 
@@ -432,6 +442,7 @@ void SAL_CALL OComboBoxModel::read(const Reference<css::io::XObjectInputStream>&
         )
     {
         setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( css::uno::Sequence<OUString>() ) );
+        setFastPropertyValue( PROPERTY_ID_TYPEDITEMLIST, makeAny( css::uno::Sequence<css::uno::Any>() ) );
     }
 
     if (nVersion > 0x0004)
@@ -655,6 +666,8 @@ void OComboBoxModel::loadData( bool _bForce )
 
     // Set String-Sequence at ListBox
     setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( comphelper::containerToSequence(aStringList) ) );
+    // Reset TypedItemList, no matching data.
+    setFastPropertyValue( PROPERTY_ID_TYPEDITEMLIST, makeAny( css::uno::Sequence<css::uno::Any>() ) );
 }
 
 
@@ -765,6 +778,7 @@ bool OComboBoxModel::commitControlValueToDbColumn( bool _bPostReset )
                 aStringItemList.getArray()[ nOldLen ] = sNewValue;
 
                 setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( aStringItemList ) );
+                setFastPropertyValue( PROPERTY_ID_TYPEDITEMLIST, makeAny( css::uno::Sequence<css::uno::Any>() ) );
             }
         }
     }
@@ -810,7 +824,10 @@ Any OComboBoxModel::getDefaultForReset() const
 void OComboBoxModel::stringItemListChanged( ControlModelLock& /*_rInstanceLock*/ )
 {
     if ( m_xAggregateSet.is() )
+    {
         m_xAggregateSet->setPropertyValue( PROPERTY_STRINGITEMLIST, makeAny( comphelper::containerToSequence(getStringItemList()) ) );
+        m_xAggregateSet->setPropertyValue( PROPERTY_TYPEDITEMLIST, makeAny( getTypedItemList()) ) ;
+    }
 }
 
 
diff --git a/forms/source/component/ListBox.cxx b/forms/source/component/ListBox.cxx
index 2b5426f..2e1d52c 100644
--- a/forms/source/component/ListBox.cxx
+++ b/forms/source/component/ListBox.cxx
@@ -147,6 +147,7 @@ namespace frm
     void OListBoxModel::init()
     {
         startAggregatePropertyListening( PROPERTY_STRINGITEMLIST );
+        startAggregatePropertyListening( PROPERTY_TYPEDITEMLIST );
     }
 
 
@@ -286,6 +287,10 @@ namespace frm
             _rValue <<= comphelper::containerToSequence(getStringItemList());
             break;
 
+        case PROPERTY_ID_TYPEDITEMLIST:
+            _rValue <<= getTypedItemList();
+            break;
+
         default:
             OBoundControlModel::getFastPropertyValue(_rValue, _nHandle);
         }
@@ -505,6 +510,7 @@ namespace frm
             // <----- SYNCHRONIZED
             return;
         }
+        // XXX NOTE: PROPERTY_TYPEDITEMLIST not handled, used only with external list source.
         OBoundControlModel::_propertyChanged( i_rEvent );
     }
 
@@ -515,6 +521,7 @@ namespace frm
 
         // superseded properties:
         RemoveProperty( _rAggregateProps, PROPERTY_STRINGITEMLIST );
+        RemoveProperty( _rAggregateProps, PROPERTY_TYPEDITEMLIST );
     }
 
 
@@ -669,6 +676,7 @@ namespace frm
             )
         {
             setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( css::uno::Sequence<OUString>() ) );
+            setFastPropertyValue( PROPERTY_ID_TYPEDITEMLIST, makeAny( css::uno::Sequence<css::uno::Any>() ) );
         }
 
         if (nVersion > 3)
@@ -991,6 +999,7 @@ namespace frm
         setBoundValues(aValueList);
 
         setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( lcl_convertToStringSequence( aDisplayList ) ) );
+        setFastPropertyValue( PROPERTY_ID_TYPEDITEMLIST, makeAny( css::uno::Sequence<css::uno::Any>() ) );
     }
 
 
@@ -1456,6 +1465,26 @@ namespace frm
         };
 
 
+        Any lcl_getSingleSelectedEntryTyped( const Sequence< sal_Int16 >& _rSelectSequence, const Sequence<Any>& _rTypedList )
+        {
+            Any aReturn;
+
+            // by definition, multiple selected entries are transferred as NULL if the
+            // binding does not support lists
+            if ( _rSelectSequence.getLength() <= 1 )
+            {
+                if ( _rSelectSequence.getLength() == 1 )
+                {
+                    sal_Int32 nIndex = _rSelectSequence[0];
+                    if (0 <= nIndex && nIndex < _rTypedList.getLength())
+                        aReturn = _rTypedList[nIndex];
+                }
+            }
+
+            return aReturn;
+        }
+
+
         Any lcl_getSingleSelectedEntry( const Sequence< sal_Int16 >& _rSelectSequence, const std::vector< OUString >& _rStringList )
         {
             Any aReturn;
@@ -1586,7 +1615,14 @@ namespace frm
             break;
 
         case eEntry:
-            aReturn = lcl_getSingleSelectedEntry( aSelectSequence, getStringItemList() );
+            {
+                const std::vector<OUString>& rStrings = getStringItemList();
+                const Sequence<Any>& rValues = getTypedItemList();
+                if (rStrings.size() == static_cast<size_t>(rValues.getLength()))
+                    aReturn = lcl_getSingleSelectedEntryTyped( aSelectSequence, rValues );
+                else
+                    aReturn = lcl_getSingleSelectedEntry( aSelectSequence, rStrings );
+            }
             break;
         }
 
@@ -1689,6 +1725,7 @@ namespace frm
         try
         {
             m_xAggregateSet->setPropertyValue( PROPERTY_STRINGITEMLIST, makeAny( comphelper::containerToSequence(getStringItemList()) ) );
+            m_xAggregateSet->setPropertyValue( PROPERTY_TYPEDITEMLIST, makeAny( getTypedItemList() ) );
         }
         catch( const Exception& )
         {
diff --git a/forms/source/component/entrylisthelper.cxx b/forms/source/component/entrylisthelper.cxx
index b306256..4e9202be 100644
--- a/forms/source/component/entrylisthelper.cxx
+++ b/forms/source/component/entrylisthelper.cxx
@@ -23,6 +23,7 @@
 #include <osl/diagnose.h>
 #include <comphelper/sequence.hxx>
 #include <comphelper/property.hxx>
+#include <com/sun/star/form/binding/XListEntryTypedSource.hpp>
 #include <algorithm>
 
 
@@ -92,6 +93,8 @@ namespace frm
             )
         {
             m_aStringItems[ _rEvent.Position ] = _rEvent.Entries[ 0 ];
+            if (m_aTypedItems.getLength())
+                m_aTypedItems = Sequence<Any>();    // doesn't match anymore
             stringItemListChanged( aLock );
         }
     }
@@ -112,7 +115,8 @@ namespace frm
             )
         {
             m_aStringItems.insert(m_aStringItems.begin() + _rEvent.Position, _rEvent.Entries.begin(), _rEvent.Entries.end());
-
+            if (m_aTypedItems.getLength())
+                m_aTypedItems = Sequence<Any>();    // doesn't match anymore
             stringItemListChanged( aLock );
         }
     }
@@ -134,6 +138,26 @@ namespace frm
         {
             m_aStringItems.erase(m_aStringItems.begin() + _rEvent.Position,
                                  m_aStringItems.begin() + _rEvent.Position + _rEvent.Count );
+            if (_rEvent.Position + _rEvent.Count <= m_aTypedItems.getLength())
+            {
+                Sequence<Any> aTmp( m_aTypedItems.getLength() - _rEvent.Count );
+                sal_Int32 nStop = _rEvent.Position;
+                sal_Int32 i = 0;
+                for ( ; i < nStop; ++i)
+                {
+                    aTmp[i] = m_aTypedItems[i];
+                }
+                nStop = aTmp.getLength();
+                for (sal_Int32 j = _rEvent.Position + _rEvent.Count; i < nStop; ++i, ++j)
+                {
+                    aTmp[i] = m_aTypedItems[j];
+                }
+                m_aTypedItems = aTmp;
+            }
+            else if (m_aTypedItems.getLength())
+            {
+                m_aTypedItems = Sequence<Any>();    // doesn't match anymore
+            }
             stringItemListChanged( aLock );
         }
     }
@@ -184,10 +208,7 @@ namespace frm
     void OEntryListHelper::impl_lock_refreshList( ControlModelLock& _rInstanceLock )
     {
         if ( hasExternalListSource() )
-        {
-            comphelper::sequenceToContainer(m_aStringItems, m_xListSource->getAllListEntries());
-            stringItemListChanged( _rInstanceLock );
-        }
+            obtainListSourceEntries( _rInstanceLock );
         else
             refreshInternalEntryList();
     }
@@ -251,8 +272,7 @@ namespace frm
             // be notified when the list changes ...
             m_xListSource->addListEntryListener( this );
 
-            comphelper::sequenceToContainer( m_aStringItems, m_xListSource->getAllListEntries() );
-            stringItemListChanged( _rInstanceLock );
+            obtainListSourceEntries( _rInstanceLock );
 
             // let derivees react on the new list source
             connectedExternalListSource();
@@ -260,6 +280,24 @@ namespace frm
     }
 
 
+    void OEntryListHelper::obtainListSourceEntries( ControlModelLock& _rInstanceLock )
+    {
+        Reference< XListEntryTypedSource > xTyped;
+        xTyped.set( m_xListSource, UNO_QUERY);
+        if (xTyped.is())
+        {
+            comphelper::sequenceToContainer( m_aStringItems, xTyped->getAllListEntriesTyped( m_aTypedItems));
+        }
+        else
+        {
+            comphelper::sequenceToContainer( m_aStringItems, m_xListSource->getAllListEntries());
+            if (m_aTypedItems.getLength())
+                m_aTypedItems = Sequence<Any>();
+        }
+        stringItemListChanged( _rInstanceLock );
+    }
+
+
     bool OEntryListHelper::convertNewListSourceProperty( Any& _rConvertedValue,
         Any& _rOldValue, const Any& _rValue )
     {
@@ -277,6 +315,8 @@ namespace frm
         css::uno::Sequence<OUString> aTmp;
         OSL_VERIFY( _rValue >>= aTmp );
         comphelper::sequenceToContainer(m_aStringItems, aTmp);
+        if (m_aTypedItems.getLength())
+            m_aTypedItems = Sequence<Any>();    // doesn't match anymore
         stringItemListChanged( _rInstanceLock );
     }
 
diff --git a/forms/source/component/entrylisthelper.hxx b/forms/source/component/entrylisthelper.hxx
index 3ae722c..3ad407c 100644
--- a/forms/source/component/entrylisthelper.hxx
+++ b/forms/source/component/entrylisthelper.hxx
@@ -53,6 +53,8 @@ namespace frm
                         m_xListSource;      /// our external list source
         std::vector< OUString >
                         m_aStringItems;     /// "overridden" StringItemList property value
+        css::uno::Sequence< css::uno::Any >
+                        m_aTypedItems;      /// "overridden" TypedItemList property value
         ::comphelper::OInterfaceContainerHelper2
                         m_aRefreshListeners;
 
@@ -66,6 +68,10 @@ namespace frm
         inline const std::vector< OUString >&
                     getStringItemList() const { return m_aStringItems; }
 
+        /// returns the current typed item list
+        inline const css::uno::Sequence< css::uno::Any >&
+                    getTypedItemList() const { return m_aTypedItems; }
+
         /// determines whether we actually have an external list source
         inline bool hasExternalListSource( ) const { return m_xListSource.is(); }
 
@@ -161,6 +167,13 @@ namespace frm
                         ControlModelLock& _rInstanceLock
                     );
 
+        /** obtains list entries and possibly data values from list source
+
+            @precond
+                m_xListSource has to hold an external list source
+        */
+        void        obtainListSourceEntries( ControlModelLock& _rInstanceLock );
+
         /** refreshes our list entries
 
             In case we have an external list source, its used to obtain the new entries, and then
diff --git a/forms/source/inc/frm_strings.hxx b/forms/source/inc/frm_strings.hxx
index 7415ebe..868772a 100644
--- a/forms/source/inc/frm_strings.hxx
+++ b/forms/source/inc/frm_strings.hxx
@@ -70,6 +70,7 @@ namespace frm
     #define PROPERTY_HIDDEN_VALUE             "HiddenValue"
     #define PROPERTY_BUTTONTYPE               "ButtonType"
     #define PROPERTY_STRINGITEMLIST           "StringItemList"
+    #define PROPERTY_TYPEDITEMLIST            "TypedItemList"
     #define PROPERTY_DEFAULT_TEXT             "DefaultText"
     #define PROPERTY_DEFAULT_STATE             "DefaultState"
     #define PROPERTY_FORMATKEY                "FormatKey"
diff --git a/forms/source/inc/property.hrc b/forms/source/inc/property.hrc
index 2086db0..57b6202 100644
--- a/forms/source/inc/property.hrc
+++ b/forms/source/inc/property.hrc
@@ -292,6 +292,8 @@ namespace frm
 #define PROPERTY_ID_CONTROL_TYPE_IN_MSO         ( PROPERTY_ID_START + 261 )
 #define PROPERTY_ID_OBJ_ID_IN_MSO           ( PROPERTY_ID_START + 262 )
 
+#define PROPERTY_ID_TYPEDITEMLIST               ( PROPERTY_ID_START + 263 ) // Sequence<Any>
+
 // start ID fuer aggregierte Properties
 #define PROPERTY_ID_AGGREGATE_ID        (PROPERTY_ID_START + 10000)
 
diff --git a/include/toolkit/helper/property.hxx b/include/toolkit/helper/property.hxx
index d3a637d..34d8918 100644
--- a/include/toolkit/helper/property.hxx
+++ b/include/toolkit/helper/property.hxx
@@ -207,6 +207,7 @@ namespace uno {
 #define BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR  166
 #define BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR          167
 #define BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR        168
+#define BASEPROPERTY_TYPEDITEMLIST                  169 // AnySequence
 
 
 // These properties are not bound, they are always extracted from the BASEPROPERTY_FONTDESCRIPTOR property
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index 064a847..49602b9 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -2526,6 +2526,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/form/binding,\
 	XListEntryListener \
 	XListEntrySink \
 	XListEntrySource \
+	XListEntryTypedSource \
 	XValueBinding \
 ))
 $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/form/runtime,\
diff --git a/offapi/com/sun/star/awt/UnoControlComboBoxModel.idl b/offapi/com/sun/star/awt/UnoControlComboBoxModel.idl
index 2ee9d69..3a359eb 100644
--- a/offapi/com/sun/star/awt/UnoControlComboBoxModel.idl
+++ b/offapi/com/sun/star/awt/UnoControlComboBoxModel.idl
@@ -192,6 +192,19 @@ published service UnoControlComboBoxModel
         #StringItemList property.
     */
     [optional] interface XItemList;
+
+    /** specifies the list of raw typed (not stringized) items.
+
+        <p>This list corresponds with the StringItemList and if given
+        has to be of the same length, the elements' positions matching
+        those of their string representation in StringItemList.</p>
+
+        <p>If a new value is entered via the ComboBox edit then this
+        list will be invalidated.</p>
+
+        @since LibreOffice 5.4
+     */
+    [optional, property] sequence<any> TypedItemList;
 };
 
 
diff --git a/offapi/com/sun/star/awt/UnoControlListBoxModel.idl b/offapi/com/sun/star/awt/UnoControlListBoxModel.idl
index 8e577f8..05a102b 100644
--- a/offapi/com/sun/star/awt/UnoControlListBoxModel.idl
+++ b/offapi/com/sun/star/awt/UnoControlListBoxModel.idl
@@ -186,6 +186,16 @@ published service UnoControlListBoxModel
         @since OOo 3.3
     */
     [optional, property, maybevoid] short ItemSeparatorPos;
+
+    /** specifies the list of raw typed (not stringized) items.
+
+        <p>This list corresponds with the StringItemList and if given
+        has to be of the same length, the elements' positions matching
+        those of their string representation in StringItemList.</p>
+
+        @since LibreOffice 5.4
+     */
+    [optional, property] sequence<any> TypedItemList;
 };
 
 
diff --git a/offapi/com/sun/star/form/binding/XListEntryTypedSource.idl b/offapi/com/sun/star/form/binding/XListEntryTypedSource.idl
new file mode 100644
index 0000000..8f8003d
--- /dev/null
+++ b/offapi/com/sun/star/form/binding/XListEntryTypedSource.idl
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef __com_sun_star_form_binding_XListEntryTypedSource_idl__
+#define __com_sun_star_form_binding_XListEntryTypedSource_idl__
+
+#include <com/sun/star/form/binding/XListEntrySource.idl>
+
+
+module com {  module sun {  module star {  module form { module binding {
+
+
+/** specifies a source of string list entries with corresponding underlying data values
+
+    @see XListEntrySource
+
+    @since LibreOffice 5.4
+*/
+interface XListEntryTypedSource : com::sun::star::form::binding::XListEntrySource
+{
+    /** provides access to the entirety of all list entries, along with
+        the corresponding underlying data values.
+
+        @param  DataValues
+                The sequence is used by
+                com::sun::star::form::component::ListBox for external
+                sources such as spreadsheets to return the resulting
+                data value if a listbox entry was selected, e.g. set it
+                at the specified bound cell using
+                com::sun::star::form::binding::XValueBinding::setValue().
+     */
+    sequence< string > getAllListEntriesTyped( [out] sequence< any > DataValues );
+
+};
+
+
+}; }; }; }; };
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/unoobj/celllistsource.cxx b/sc/source/ui/unoobj/celllistsource.cxx
index b2dec38..c78b862 100644
--- a/sc/source/ui/unoobj/celllistsource.cxx
+++ b/sc/source/ui/unoobj/celllistsource.cxx
@@ -161,16 +161,64 @@ namespace calc
         return aAddress;
     }
 
-    OUString OCellListSource::getCellTextContent_noCheck( sal_Int32 _nRangeRelativeRow )
+    OUString OCellListSource::getCellTextContent_noCheck( sal_Int32 _nRangeRelativeRow, css::uno::Any* pAny )
     {
+        OUString sText;
+
         OSL_PRECOND( m_xRange.is(), "OCellListSource::getRangeAddress: invalid range!" );
+
+        if (!m_xRange.is())
+            return sText;
+
+        Reference< XCell > xCell( m_xRange->getCellByPosition( 0, _nRangeRelativeRow ));
+        if (!xCell.is())
+        {
+            if (pAny)
+                *pAny <<= sText;
+            return sText;
+        }
+
         Reference< XTextRange > xCellText;
-        if ( m_xRange.is() )
-            xCellText.set(m_xRange->getCellByPosition( 0, _nRangeRelativeRow ), css::uno::UNO_QUERY);
+        xCellText.set( xCell, UNO_QUERY);
+
+        if (xCellText.is())
+            sText = xCellText->getString();     // formatted output string
+
+        if (pAny)
+        {
+            switch (xCell->getType())
+            {
+                case CellContentType_VALUE:
+                    *pAny <<= xCell->getValue();
+                break;
+                case CellContentType_TEXT:
+                    *pAny <<= sText;
+                break;
+                case CellContentType_FORMULA:
+                    if (xCell->getError())
+                        *pAny <<= sText;    // Err:... or #...!
+                    else
+                    {
+                        Reference< XPropertySet > xProp( xCell, UNO_QUERY);
+                        if (xProp.is())
+                        {
+                            CellContentType eResultType;
+                            if ((xProp->getPropertyValue("FormulaResultType") >>= eResultType) &&
+                                    eResultType == CellContentType_VALUE)
+                                *pAny <<= xCell->getValue();
+                            else
+                                *pAny <<= sText;
+                        }
+                    }
+                break;
+                case CellContentType_EMPTY:
+                    *pAny <<= OUString();
+                break;
+                default:
+                    ;   // nothing, if actually occurred it would result in #N/A being displayed if selected
+            }
+        }
 
-        OUString sText;
-        if ( xCellText.is() )
-            sText = xCellText->getString();
         return sText;
     }
 
@@ -193,7 +241,7 @@ namespace calc
         if ( _nPosition >= getListEntryCount() )
             throw IndexOutOfBoundsException();
 
-        return getCellTextContent_noCheck( _nPosition );
+        return getCellTextContent_noCheck( _nPosition, nullptr );
     }
 
     Sequence< OUString > SAL_CALL OCellListSource::getAllListEntries(  )
@@ -206,7 +254,26 @@ namespace calc
         OUString* pAllEntries = aAllEntries.getArray();
         for ( sal_Int32 i = 0; i < aAllEntries.getLength(); ++i )
         {
-            *pAllEntries++ = getCellTextContent_noCheck( i );
+            *pAllEntries++ = getCellTextContent_noCheck( i, nullptr );
+        }
+
+        return aAllEntries;
+    }
+
+    Sequence< OUString > SAL_CALL OCellListSource::getAllListEntriesTyped( Sequence< Any >& rDataValues )
+    {
+        ::osl::MutexGuard aGuard( m_aMutex );
+        checkDisposed();
+        checkInitialized();
+
+        const sal_Int32 nCount = getListEntryCount();
+        Sequence< OUString > aAllEntries( nCount );
+        rDataValues = Sequence< Any >( nCount );
+        OUString* pAllEntries = aAllEntries.getArray();
+        Any* pDataValues = rDataValues.getArray();
+        for ( sal_Int32 i = 0; i < nCount; ++i )
+        {
+            *pAllEntries++ = getCellTextContent_noCheck( i, pDataValues++ );
         }
 
         return aAllEntries;
diff --git a/sc/source/ui/unoobj/celllistsource.hxx b/sc/source/ui/unoobj/celllistsource.hxx
index 2763c76..5444dfe 100644
--- a/sc/source/ui/unoobj/celllistsource.hxx
+++ b/sc/source/ui/unoobj/celllistsource.hxx
@@ -20,7 +20,7 @@
 #ifndef INCLUDED_SC_SOURCE_UI_UNOOBJ_CELLLISTSOURCE_HXX
 #define INCLUDED_SC_SOURCE_UI_UNOOBJ_CELLLISTSOURCE_HXX
 
-#include <com/sun/star/form/binding/XListEntrySource.hpp>
+#include <com/sun/star/form/binding/XListEntryTypedSource.hpp>
 #include <cppuhelper/compbase4.hxx>
 #include <cppuhelper/basemutex.hxx>
 #include <comphelper/interfacecontainer2.hxx>
@@ -42,7 +42,7 @@ namespace calc
 
     class OCellListSource;
     // the base for our interfaces
-    typedef ::cppu::WeakAggComponentImplHelper4 <   css::form::binding::XListEntrySource
+    typedef ::cppu::WeakAggComponentImplHelper4 <   css::form::binding::XListEntryTypedSource
                                                 ,   css::util::XModifyListener
                                                 ,   css::lang::XServiceInfo
                                                 ,   css::lang::XInitialization
@@ -91,6 +91,9 @@ namespace calc
         virtual void SAL_CALL addListEntryListener( const css::uno::Reference< css::form::binding::XListEntryListener >& Listener ) override;
         virtual void SAL_CALL removeListEntryListener( const css::uno::Reference< css::form::binding::XListEntryListener >& Listener ) override;
 
+        // XListEntryTypedSource
+        virtual css::uno::Sequence< OUString > SAL_CALL getAllListEntriesTyped( css::uno::Sequence< css::uno::Any >& rDataValues ) override;
+
         // OComponentHelper/XComponent
         virtual void SAL_CALL disposing() override;
 
@@ -130,12 +133,15 @@ namespace calc
         /** retrievs the text of a cell within our range
             @param _nRangeRelativeRow
                 the relative row index of the cell within our range
+            @param pAny
+                if not <NULL/> then the underlying data value is returned in the Any
             @precond
                 our m_xRange is not <NULL/>
         */
         OUString
                 getCellTextContent_noCheck(
-                    sal_Int32 _nRangeRelativeRow
+                    sal_Int32 _nRangeRelativeRow,
+                    css::uno::Any* pAny
                 );
 
         void    notifyModified();
diff --git a/toolkit/source/awt/vclxwindows.cxx b/toolkit/source/awt/vclxwindows.cxx
index af6d16f..e5c6fc8 100644
--- a/toolkit/source/awt/vclxwindows.cxx
+++ b/toolkit/source/awt/vclxwindows.cxx
@@ -1487,6 +1487,7 @@ void VCLXListBox::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
                      BASEPROPERTY_PRINTABLE,
                      BASEPROPERTY_SELECTEDITEMS,
                      BASEPROPERTY_STRINGITEMLIST,
+                     BASEPROPERTY_TYPEDITEMLIST,
                      BASEPROPERTY_TABSTOP,
                      BASEPROPERTY_READONLY,
                      BASEPROPERTY_ALIGN,
@@ -4121,6 +4122,7 @@ void VCLXComboBox::ImplGetPropertyIds( std::vector< sal_uInt16 > &rIds )
                      BASEPROPERTY_PRINTABLE,
                      BASEPROPERTY_READONLY,
                      BASEPROPERTY_STRINGITEMLIST,
+                     BASEPROPERTY_TYPEDITEMLIST,
                      BASEPROPERTY_TABSTOP,
                      BASEPROPERTY_TEXT,
                      BASEPROPERTY_HIDEINACTIVESELECTION,
diff --git a/toolkit/source/controls/unocontrolmodel.cxx b/toolkit/source/controls/unocontrolmodel.cxx
index 3a2cf61..876cb9e 100644
--- a/toolkit/source/controls/unocontrolmodel.cxx
+++ b/toolkit/source/controls/unocontrolmodel.cxx
@@ -309,6 +309,13 @@ css::uno::Any UnoControlModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
 
             }
             break;
+            case BASEPROPERTY_TYPEDITEMLIST:
+            {
+                css::uno::Sequence< css::uno::Any > aAnySeq;
+                aDefault <<= aAnySeq;
+
+            }
+            break;
             case BASEPROPERTY_SELECTEDITEMS:
             {
                 css::uno::Sequence<sal_Int16> aINT16Seq;
diff --git a/toolkit/source/controls/unocontrols.cxx b/toolkit/source/controls/unocontrols.cxx
index 9a1e5cb..a529d33 100644
--- a/toolkit/source/controls/unocontrols.cxx
+++ b/toolkit/source/controls/unocontrols.cxx
@@ -2277,6 +2277,8 @@ void UnoControlListBoxModel::ImplNormalizePropertySequence( const sal_Int32 _nCo
     // dependencies we know:
     // BASEPROPERTY_STRINGITEMLIST->BASEPROPERTY_SELECTEDITEMS
     ImplEnsureHandleOrder( _nCount, _pHandles, _pValues, BASEPROPERTY_STRINGITEMLIST, BASEPROPERTY_SELECTEDITEMS );
+    // BASEPROPERTY_STRINGITEMLIST->BASEPROPERTY_TYPEDITEMLIST
+    ImplEnsureHandleOrder( _nCount, _pHandles, _pValues, BASEPROPERTY_STRINGITEMLIST, BASEPROPERTY_TYPEDITEMLIST );
 
     UnoControlModel::ImplNormalizePropertySequence( _nCount, _pHandles, _pValues, _pValidHandles );
 }
diff --git a/toolkit/source/helper/property.cxx b/toolkit/source/helper/property.cxx
index 9e8b544..2ea27d5 100644
--- a/toolkit/source/helper/property.cxx
+++ b/toolkit/source/helper/property.cxx
@@ -221,6 +221,7 @@ ImplPropertyInfo* ImplGetPropertyInfos( sal_uInt16& rElementCount )
             DECL_DEP_PROP_2 ( "State",                  STATE,                  sal_Int16,      BOUND, MAYBEDEFAULT ),
             DECL_PROP_2     ( "StrictFormat",           STRICTFORMAT,           bool,           BOUND, MAYBEDEFAULT ),
             DECL_PROP_2     ( "StringItemList",         STRINGITEMLIST,         Sequence< OUString >, BOUND, MAYBEDEFAULT ),
+            DECL_PROP_2     ( "TypedItemList",          TYPEDITEMLIST,          Sequence< Any >, BOUND, MAYBEDEFAULT ),
             DECL_PROP_2     ( "VisualEffect",           VISUALEFFECT,           sal_Int16,      BOUND, MAYBEDEFAULT ),
             DECL_PROP_3     ( "SymbolColor",            SYMBOL_COLOR,           sal_Int32,      BOUND, MAYBEDEFAULT, MAYBEVOID ),
             DECL_PROP_3     ( "Tabstop",                TABSTOP,                bool,           BOUND, MAYBEDEFAULT, MAYBEVOID ),
commit cdbec91da4931be72ed4f1b28f78d83a9a0d616f
Author: Eike Rathke <erack at redhat.com>
Date:   Tue Feb 14 11:48:22 2017 +0100

    special case TypedItemList in preparation for tdf#79250
    
    Seems a Sequence<Any> property was never supported in the
    qadevOOo/tests/java/ifc/beans/_XPropertySet.java addPropertyChangeListener()
    tests, where the property has to be changed in ValueChanger to pass the test.
    However, simply generally adding a value to an empty sequence does not work as
    it would break other tests in turn, so special-case it to the TypedItemList
    property. This is all fubar.
    
    Change-Id: If6d0f45c7440e3553dc8bd293dadb21c5fb09bb5

diff --git a/qadevOOo/runner/util/ValueChanger.java b/qadevOOo/runner/util/ValueChanger.java
index ec796ae..3905b44 100644
--- a/qadevOOo/runner/util/ValueChanger.java
+++ b/qadevOOo/runner/util/ValueChanger.java
@@ -28,6 +28,7 @@ import java.lang.reflect.Modifier;
 import java.lang.reflect.Array;
 import com.sun.star.uno.Any;
 import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.Type;
 
 public class ValueChanger {
 
@@ -938,35 +939,45 @@ public class ValueChanger {
         } else if (oldValue.getClass().isArray()) {
             // changer for arrays : changes all elements
             Class<?> arrType = oldValue.getClass().getComponentType();
-            newValue = Array.newInstance(arrType, Array.getLength(oldValue));
-            for (int i = 0; i < Array.getLength(newValue); i++) {
-                if (!arrType.isPrimitive()) {
-                    Object elem = changePValue(Array.get(oldValue, i));
-                    Array.set(newValue, i, elem);
-                } else {
-                    if (Boolean.TYPE.equals(arrType)) {
-                        Array.setBoolean(newValue, i,
-                                !Array.getBoolean(oldValue, i));
-                    } else if (Byte.TYPE.equals(arrType)) {
-                        Array.setByte(newValue, i,
-                                (byte) (Array.getByte(oldValue, i) + 1));
-                    } else if (Character.TYPE.equals(arrType)) {
-                        Array.setChar(newValue, i,
-                                (char) (Array.getChar(oldValue, i) + 1));
-                    } else if (Double.TYPE.equals(arrType)) {
-                        Array.setDouble(newValue, i,
-                                Array.getDouble(oldValue, i) + 1);
-                    } else if (Float.TYPE.equals(arrType)) {
-                        Array.setFloat(newValue, i,
-                                Array.getFloat(oldValue, i) + 1);
-                    } else if (Integer.TYPE.equals(arrType)) {
-                        Array.setInt(newValue, i, Array.getInt(oldValue, i) + 1);
-                    } else if (Long.TYPE.equals(arrType)) {
-                        Array.setLong(newValue, i,
-                                Array.getLong(oldValue, i) + 1);
-                    } else if (Short.TYPE.equals(arrType)) {
-                        Array.setShort(newValue, i,
-                                (short) (Array.getShort(oldValue, i) + 1));
+            int oldLen = Array.getLength(oldValue);
+            if (oldLen == 0 && "TypedItemList".equals(name) && !arrType.isPrimitive()) {
+                // This case is needed to make the Sequence<Any> property pass
+                // the addPropertyChangeListener tests, where the property has
+                // to be changed (and not stay empty ...)
+                newValue = Array.newInstance(arrType, 1);
+                Object elem = new Any(new Type(String.class), "_Any");
+                Array.set(newValue, 0, elem);
+            } else {
+                newValue = Array.newInstance(arrType, oldLen);
+                for (int i = 0; i < Array.getLength(newValue); i++) {
+                    if (!arrType.isPrimitive()) {
+                        Object elem = changePValue(Array.get(oldValue, i));
+                        Array.set(newValue, i, elem);
+                    } else {
+                        if (Boolean.TYPE.equals(arrType)) {
+                            Array.setBoolean(newValue, i,
+                                    !Array.getBoolean(oldValue, i));
+                        } else if (Byte.TYPE.equals(arrType)) {
+                            Array.setByte(newValue, i,
+                                    (byte) (Array.getByte(oldValue, i) + 1));
+                        } else if (Character.TYPE.equals(arrType)) {
+                            Array.setChar(newValue, i,
+                                    (char) (Array.getChar(oldValue, i) + 1));
+                        } else if (Double.TYPE.equals(arrType)) {
+                            Array.setDouble(newValue, i,
+                                    Array.getDouble(oldValue, i) + 1);
+                        } else if (Float.TYPE.equals(arrType)) {
+                            Array.setFloat(newValue, i,
+                                    Array.getFloat(oldValue, i) + 1);
+                        } else if (Integer.TYPE.equals(arrType)) {
+                            Array.setInt(newValue, i, Array.getInt(oldValue, i) + 1);
+                        } else if (Long.TYPE.equals(arrType)) {
+                            Array.setLong(newValue, i,
+                                    Array.getLong(oldValue, i) + 1);
+                        } else if (Short.TYPE.equals(arrType)) {
+                            Array.setShort(newValue, i,
+                                    (short) (Array.getShort(oldValue, i) + 1));
+                        }
                     }
                 }
             }


More information about the Libreoffice-commits mailing list