21#include <rtl/math.hxx>
22#include <com/sun/star/form/binding/IncompatibleTypesException.hpp>
23#include <com/sun/star/lang/NotInitializedException.hpp>
24#include <com/sun/star/text/XTextRange.hpp>
25#include <com/sun/star/table/XCellRange.hpp>
26#include <com/sun/star/sheet/FormulaResult.hpp>
27#include <com/sun/star/sheet/XCellAddressable.hpp>
28#include <com/sun/star/sheet/XCellRangeData.hpp>
29#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
30#include <com/sun/star/container/XIndexAccess.hpp>
31#include <com/sun/star/beans/PropertyAttribute.hpp>
32#include <com/sun/star/beans/NamedValue.hpp>
33#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
34#include <com/sun/star/util/XNumberFormatTypes.hpp>
35#include <com/sun/star/util/NumberFormat.hpp>
43#define PROP_HANDLE_BOUND_CELL 1
45 namespace lang = ::com::sun::star::lang;
54 using namespace ::com::sun::star::form::binding;
61 ,m_bInitialized( false )
62 ,m_bListPos( _bListPos )
65 registerPropertyNoMember(
68 PropertyAttribute::BOUND | PropertyAttribute::READONLY,
70 css::uno::Any(CellAddress())
77 OCellValueBinding::~OCellValueBinding( )
79 if ( !OCellValueBinding_Base::rBHelper.bDisposed )
92 Reference<XModifyBroadcaster> xBroadcaster( m_xCell, UNO_QUERY );
93 if ( xBroadcaster.is() )
95 xBroadcaster->removeModifyListener(
this );
98 WeakComponentImplHelperBase::disposing();
104 Reference< XPropertySetInfo > SAL_CALL OCellValueBinding::getPropertySetInfo( )
106 return createPropertySetInfo( getInfoHelper() ) ;
111 return *OCellValueBinding_PABase::getArrayHelper();
116 Sequence< Property > aProps;
117 describeProperties( aProps );
118 return new ::cppu::OPropertyArrayHelper(aProps);
121 void SAL_CALL OCellValueBinding::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle )
const
123 OSL_ENSURE( _nHandle ==
PROP_HANDLE_BOUND_CELL,
"OCellValueBinding::getFastPropertyValue: invalid handle!" );
127 Reference< XCellAddressable > xCellAddress( m_xCell, UNO_QUERY );
128 if ( xCellAddress.is() )
129 _rValue <<= xCellAddress->getCellAddress( );
132 Sequence< Type > SAL_CALL OCellValueBinding::getSupportedValueTypes( )
137 sal_Int32
nCount = m_xCellText.is() ? 3 : m_xCell.is() ? 1 : 0;
144 auto pTypes =
aTypes.getArray();
148 if ( m_xCellText.is() )
178 Any SAL_CALL OCellValueBinding::getValue(
const Type& aType )
182 checkValueType( aType );
185 switch ( aType.getTypeClass() )
187 case TypeClass_STRING:
188 OSL_ENSURE( m_xCellText.is(),
"OCellValueBinding::getValue: don't have a text!" );
189 if ( m_xCellText.is() )
190 aReturn <<= m_xCellText->getString();
192 aReturn <<= OUString();
195 case TypeClass_BOOLEAN:
196 OSL_ENSURE( m_xCell.is(),
"OCellValueBinding::getValue: don't have a double value supplier!" );
201 bool bHasValue =
false;
202 CellContentType eCellType = m_xCell->getType();
203 if ( eCellType == CellContentType_VALUE )
205 else if ( eCellType == CellContentType_FORMULA )
208 if ( m_xCell->getError() == 0 )
210 Reference<XPropertySet> xProp( m_xCell, UNO_QUERY );
213 sal_Int32 nResultType;
214 if ( (xProp->getPropertyValue(
"FormulaResultType2") >>= nResultType)
215 && nResultType == FormulaResult::VALUE )
224 double nCellValue = m_xCell->getValue();
225 bool bBoolValue = ( nCellValue != 0.0 );
226 aReturn <<= bBoolValue;
232 case TypeClass_DOUBLE:
233 OSL_ENSURE( m_xCell.is(),
"OCellValueBinding::getValue: don't have a double value supplier!" );
235 aReturn <<= m_xCell->getValue();
237 aReturn <<= double(0);
241 OSL_ENSURE( m_xCell.is(),
"OCellValueBinding::getValue: don't have a double value supplier!" );
247 sal_Int32
nValue =
static_cast<sal_Int32
>(rtl::math::approxFloor( m_xCell->getValue() ));
253 aReturn <<= sal_Int32(0);
257 OSL_FAIL(
"OCellValueBinding::getValue: unreachable code!" );
264 void SAL_CALL OCellValueBinding::setValue(
const Any& aValue )
268 if ( aValue.hasValue() )
269 checkValueType( aValue.getValueType() );
271 switch ( aValue.getValueType().getTypeClass() )
273 case TypeClass_STRING:
275 OSL_ENSURE( m_xCellText.is(),
"OCellValueBinding::setValue: don't have a text!" );
279 if ( m_xCellText.is() )
280 m_xCellText->setString( sText );
284 case TypeClass_BOOLEAN:
286 OSL_ENSURE( m_xCell.is(),
"OCellValueBinding::setValue: don't have a double value supplier!" );
291 bool bValue(
false );
293 double nCellValue = bValue ? 1.0 : 0.0;
296 m_xCell->setValue( nCellValue );
302 case TypeClass_DOUBLE:
304 OSL_ENSURE( m_xCell.is(),
"OCellValueBinding::setValue: don't have a double value supplier!" );
309 m_xCell->setValue(
nValue );
315 OSL_ENSURE( m_xCell.is(),
"OCellValueBinding::setValue: don't have a double value supplier!" );
321 m_xCell->setValue(
nValue );
329 Reference<XCellRangeData> xData( m_xCell, UNO_QUERY );
330 OSL_ENSURE( xData.is(),
"OCellValueBinding::setValue: don't have XCellRangeData!" );
333 Sequence<Any> aInner(1);
334 Sequence< Sequence<Any> > aOuter( &aInner, 1 );
335 xData->setDataArray( aOuter );
341 OSL_FAIL(
"OCellValueBinding::setValue: unreachable code!" );
347 void OCellValueBinding::setBooleanFormat()
351 OUString sPropName(
"NumberFormat" );
352 Reference<XPropertySet> xCellProp( m_xCell, UNO_QUERY );
353 Reference<XNumberFormatsSupplier> xSupplier(
m_xDocument, UNO_QUERY );
354 if ( !(xSupplier.is() && xCellProp.is()) )
357 Reference<XNumberFormats> xFormats(xSupplier->getNumberFormats());
358 Reference<XNumberFormatTypes> xTypes( xFormats, UNO_QUERY );
362 lang::Locale aLocale;
363 bool bWasBoolean =
false;
365 sal_Int32 nOldIndex = ::comphelper::getINT32( xCellProp->getPropertyValue( sPropName ) );
366 Reference<XPropertySet> xOldFormat;
369 xOldFormat.set(xFormats->getByKey( nOldIndex ));
375 if ( xOldFormat.is() )
378 xOldFormat->getPropertyValue(
"Locale") >>= aLocale;
380 sal_Int16 nOldType = ::comphelper::getINT16(
381 xOldFormat->getPropertyValue(
"Type") );
382 if ( nOldType & NumberFormat::LOGICAL )
388 sal_Int32 nNewIndex = xTypes->getStandardFormat( NumberFormat::LOGICAL, aLocale );
389 xCellProp->setPropertyValue( sPropName,
Any( nNewIndex ) );
393 void OCellValueBinding::checkDisposed( )
const
395 if ( OCellValueBinding_Base::rBHelper.bInDispose || OCellValueBinding_Base::rBHelper.bDisposed )
396 throw DisposedException();
400 void OCellValueBinding::checkInitialized()
402 if ( !m_bInitialized )
403 throw NotInitializedException(
"CellValueBinding is not initialized", getXWeak());
406 void OCellValueBinding::checkValueType(
const Type& _rType )
const
411 OUString
sMessage =
"The given type (" +
412 _rType.getTypeName() +
413 ") is not supported by this binding.";
416 throw IncompatibleTypesException(
sMessage, *pNonConstThis );
421 OUString SAL_CALL OCellValueBinding::getImplementationName( )
423 return "com.sun.star.comp.sheet.OCellValueBinding";
426 sal_Bool SAL_CALL OCellValueBinding::supportsService(
const OUString& _rServiceName )
431 Sequence< OUString > SAL_CALL OCellValueBinding::getSupportedServiceNames( )
433 Sequence< OUString > aServices( m_bListPos ? 3 : 2 );
434 auto pServices = aServices.getArray();
435 pServices[ 0 ] =
"com.sun.star.table.CellValueBinding";
436 pServices[ 1 ] =
"com.sun.star.form.binding.ValueBinding";
438 pServices[ 2 ] =
"com.sun.star.table.ListPositionCellBinding";
442 void SAL_CALL OCellValueBinding::addModifyListener(
const Reference< XModifyListener >& _rxListener )
444 if ( _rxListener.is() )
445 m_aModifyListeners.addInterface( _rxListener );
448 void SAL_CALL OCellValueBinding::removeModifyListener(
const Reference< XModifyListener >& _rxListener )
450 if ( _rxListener.is() )
451 m_aModifyListeners.removeInterface( _rxListener );
454 void OCellValueBinding::notifyModified()
472 TOOLS_WARN_EXCEPTION(
"sc",
"OCellValueBinding::notifyModified: caught a (non-runtime) exception!" );
477 void SAL_CALL OCellValueBinding::modified(
const EventObject& )
482 void SAL_CALL OCellValueBinding::disposing(
const EventObject& aEvent )
484 Reference<XInterface> xCellInt( m_xCell, UNO_QUERY );
485 if ( xCellInt ==
aEvent.Source )
493 void SAL_CALL OCellValueBinding::initialize(
const Sequence< Any >& _rArguments )
495 if ( m_bInitialized )
496 throw RuntimeException(
"CellValueBinding is already initialized", getXWeak());
499 CellAddress aAddress;
500 bool bFoundAddress =
false;
502 for (
const Any& rArg : _rArguments )
505 if ( rArg >>= aValue )
507 if ( aValue.Name ==
"BoundCell" )
509 if ( aValue.Value >>= aAddress )
511 bFoundAddress =
true;
518 if ( !bFoundAddress )
525 Reference< XIndexAccess > xSheets;
527 xSheets.set(
m_xDocument->getSheets( ), css::uno::UNO_QUERY);
528 OSL_ENSURE( xSheets.is(),
"OCellValueBinding::initialize: could not retrieve the sheets!" );
533 Reference< XCellRange > xSheet(xSheets->getByIndex( aAddress.Sheet ), UNO_QUERY);
534 OSL_ENSURE( xSheet.is(),
"OCellValueBinding::initialize: NULL sheet, but no exception!" );
539 m_xCell.set(xSheet->getCellByPosition( aAddress.Column, aAddress.Row ));
540 Reference< XCellAddressable > xAddressAccess( m_xCell, UNO_QUERY );
541 OSL_ENSURE( xAddressAccess.is(),
"OCellValueBinding::initialize: either NULL cell, or cell without address access!" );
547 TOOLS_WARN_EXCEPTION(
"sc",
"OCellValueBinding::initialize: caught an exception while retrieving the cell object!" );
553 m_xCellText.set(m_xCell, css::uno::UNO_QUERY);
555 Reference<XModifyBroadcaster> xBroadcaster( m_xCell, UNO_QUERY );
556 if ( xBroadcaster.is() )
558 xBroadcaster->addModifyListener(
this );
570 m_bInitialized =
true;
#define PROP_HANDLE_BOUND_CELL
virtual sal_Bool SAL_CALL supportsType(const css::uno::Type &aType) override
OCellValueBinding(const css::uno::Reference< css::sheet::XSpreadsheetDocument > &_rxDocument, bool _bListPos)
constructed as ListPositionCellBinding?
bool hasMoreElements() const
css::uno::Reference< ListenerT > const & next()
css::uno::Type const & get()
Reference< XOfficeDatabaseDocument > m_xDocument
#define TOOLS_WARN_EXCEPTION(area, stream)
::cppu::WeakComponentImplHelper< css::form::binding::XValueBinding, css::lang::XServiceInfo, css::util::XModifyBroadcaster, css::util::XModifyListener, css::lang::XInitialization > OCellValueBinding_Base
::comphelper::OPropertyContainer OCellValueBinding_PBase
void checkDisposed(bool _bThrow)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
const Supported_NumberingType aSupportedTypes[]
IMPLEMENT_FORWARD_XTYPEPROVIDER2(ChildWindowPane, ChildWindowPaneInterfaceBase, Pane)
IMPLEMENT_FORWARD_XINTERFACE2(ChildWindowPane, ChildWindowPaneInterfaceBase, Pane)