24#include <com/sun/star/lang/IllegalArgumentException.hpp>
25#include <com/sun/star/lang/XServiceInfo.hpp>
26#include <com/sun/star/inspection/XStringRepresentation.hpp>
27#include <com/sun/star/lang/XInitialization.hpp>
28#include <com/sun/star/script/CannotConvertException.hpp>
29#include <com/sun/star/script/XTypeConverter.hpp>
30#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
31#include <com/sun/star/reflection/XConstantsTypeDescription.hpp>
32#include <com/sun/star/util/DateTime.hpp>
33#include <com/sun/star/util/Date.hpp>
34#include <com/sun/star/util/Time.hpp>
35#include <com/sun/star/uno/XComponentContext.hpp>
37#include <osl/diagnose.h>
38#include <rtl/ustrbuf.hxx>
55class StringRepresentation:
56 public ::cppu::WeakImplHelper<
58 inspection::XStringRepresentation,
59 lang::XInitialization>
62 explicit StringRepresentation(uno::Reference< uno::XComponentContext > context);
63 StringRepresentation (
const StringRepresentation&) =
delete;
64 StringRepresentation& operator=(
const StringRepresentation&) =
delete;
72 virtual OUString SAL_CALL convertToControlValue(
const uno::Any & PropertyValue)
override;
73 virtual uno::Any SAL_CALL convertToPropertyValue(
const OUString & ControlValue,
const uno::Type & ControlValueType)
override;
76 virtual void SAL_CALL initialize(
const uno::Sequence< uno::Any > & aArguments)
override;
79 virtual ~StringRepresentation()
override {}
89 static bool convertGenericValueToString(
102 static bool convertStringToGenericValue(
103 const OUString& _rStringRep,
113 OUString convertSimpleToString(
const uno::Any& _rValue );
120 uno::Any convertStringToSimple(
const OUString& _rValue,
const uno::TypeClass& _ePropertyType );
122 uno::Reference< uno::XComponentContext >
m_xContext;
123 uno::Reference< script::XTypeConverter > m_xTypeConverter;
124 uno::Reference< reflection::XConstantsTypeDescription > m_xTypeDescription;
126 uno::Sequence< uno::Reference< reflection::XConstantTypeDescription> > m_aConstants;
132StringRepresentation::StringRepresentation(uno::Reference< uno::XComponentContext > context) :
137OUString SAL_CALL StringRepresentation::getImplementationName()
139 return "StringRepresentation";
142sal_Bool SAL_CALL StringRepresentation::supportsService(OUString
const & serviceName)
147uno::Sequence< OUString > SAL_CALL StringRepresentation::getSupportedServiceNames()
149 return {
"com.sun.star.inspection.StringRepresentation" };
153OUString SAL_CALL StringRepresentation::convertToControlValue(
const uno::Any & PropertyValue)
156 if ( !convertGenericValueToString( PropertyValue, sReturn ) )
158 sReturn = convertSimpleToString( PropertyValue );
160 if ( sReturn.isEmpty() && PropertyValue.
hasValue() )
162 SAL_WARN(
"extensions.propctrlr",
"StringRepresentation::convertPropertyValueToStringRepresentation: cannot convert values of type '"
163 << PropertyValue.getValueType().getTypeName()
172uno::Any SAL_CALL StringRepresentation::convertToPropertyValue(
const OUString & ControlValue,
const uno::Type & ControlValueType)
176 uno::TypeClass ePropertyType = ControlValueType.getTypeClass();
177 switch ( ePropertyType )
179 case uno::TypeClass_FLOAT:
180 case uno::TypeClass_DOUBLE:
181 case uno::TypeClass_BYTE:
182 case uno::TypeClass_SHORT:
183 case uno::TypeClass_LONG:
184 case uno::TypeClass_HYPER:
185 case uno::TypeClass_UNSIGNED_SHORT:
186 case uno::TypeClass_UNSIGNED_LONG:
187 case uno::TypeClass_UNSIGNED_HYPER:
190 aReturn = convertStringToSimple(ControlValue, ePropertyType);
192 catch(
const script::CannotConvertException& ) { }
193 catch(
const lang::IllegalArgumentException& ) { }
197 #if OSL_DEBUG_LEVEL > 0
200 convertStringToGenericValue( ControlValue, aReturn, ControlValueType );
202 #if OSL_DEBUG_LEVEL > 0
204 if ( !bCanConvert && !ControlValue.isEmpty() )
206 SAL_WARN(
"extensions.propctrlr",
"StringRepresentation::convertStringRepresentationToPropertyValue: cannot convert into values of type '"
207 << ControlValueType.getTypeName() <<
"'!" );
219struct CompareConstants {
221 css::uno::Reference< css::reflection::XConstantTypeDescription >
const &
223 css::uno::Reference< css::reflection::XConstantTypeDescription >
const &
226 return c1->getConstantValue().get<sal_Int32>()
227 < c2->getConstantValue().get<sal_Int32>();
234void SAL_CALL StringRepresentation::initialize(
const uno::Sequence< uno::Any > & aArguments)
241 m_xTypeConverter.set(*pIter++,uno::UNO_QUERY);
245 OUString sConstantName;
246 *pIter++ >>= sConstantName;
252 uno::Reference< container::XHierarchicalNameAccess > xTypeDescProv(
253 m_xContext->getValueByName(
"/singletons/com.sun.star.reflection.theTypeDescriptionManager"),
254 uno::UNO_QUERY_THROW );
256 m_xTypeDescription.set( xTypeDescProv->getByHierarchicalName( sConstantName ), uno::UNO_QUERY_THROW );
258 uno::Reference< reflection::XConstantTypeDescription > >
259 cs(m_xTypeDescription->getConstants());
260 auto [
begin,
end] = asNonConstRange(cs);
261 std::sort(begin, end, CompareConstants());
265OUString StringRepresentation::convertSimpleToString(
const uno::Any& _rValue )
268 if ( m_xTypeConverter.is() && _rValue.
hasValue() )
272 if ( m_aConstants.hasElements() )
274 sal_Int16 nConstantValue = 0;
275 if ( _rValue >>= nConstantValue )
277 const uno::Reference< reflection::XConstantTypeDescription>* pIter = m_aConstants.getConstArray();
278 const uno::Reference< reflection::XConstantTypeDescription>* pEnd = pIter + m_aConstants.getLength();
279 for(sal_Int32 i = 0;pIter != pEnd;++pIter,++
i)
281 if ( (*pIter)->getConstantValue() == _rValue )
283 OSL_ENSURE(i <
m_aValues.getLength() ,
"StringRepresentation::convertSimpleToString: Index is not in range of m_aValues");
291 if ( sReturn.isEmpty() )
292 m_xTypeConverter->convertToSimpleType( _rValue, uno::TypeClass_STRING ) >>= sReturn;
294 catch(
const script::CannotConvertException& ) { }
295 catch(
const lang::IllegalArgumentException& ) { }
303 struct ConvertIntegerFromAndToString
305 OUString operator()( sal_Int32 _rIntValue )
const
307 return OUString::number( _rIntValue );
309 sal_Int32 operator()( std::u16string_view _rStringValue )
const
315 struct StringIdentity
317 OUString operator()(
const OUString& _rValue )
const
323 template <
class ElementType,
class Transformer >
324 OUString composeSequenceElements(
const Sequence< ElementType >& _rElements,
const Transformer& _rTransformer )
326 OUStringBuffer sCompose;
330 for (
const auto& rElement : _rElements)
332 sCompose.append(OUString(_rTransformer(rElement)) +
"\n");
334 sCompose.stripEnd(
'\n');
336 return sCompose.makeStringAndClear();
339 template <
class ElementType,
class Transformer >
340 void splitComposedStringToSequence( std::u16string_view _rComposed, Sequence< ElementType >& _out_SplitUp,
const Transformer& _rTransformer )
342 _out_SplitUp.realloc( 0 );
343 if ( _rComposed.empty() )
345 sal_Int32 tokenPos = 0;
348 _out_SplitUp.realloc( _out_SplitUp.getLength() + 1 );
349 _out_SplitUp.getArray()[ _out_SplitUp.getLength() - 1 ] =
static_cast<ElementType>(_rTransformer( OUString(
o3tl::getToken(_rComposed, 0,
'\n', tokenPos )) ));
351 while ( tokenPos != -1 );
356bool StringRepresentation::convertGenericValueToString(
const uno::Any& _rValue, OUString& _rStringRep )
358 bool bCanConvert =
true;
360 switch ( _rValue.getValueTypeClass() )
362 case uno::TypeClass_STRING:
363 _rValue >>= _rStringRep;
366 case uno::TypeClass_BOOLEAN:
370 _rStringRep = bValue ?
PcrRes(RID_RSC_ENUM_YESNO[1])
371 :
PcrRes(RID_RSC_ENUM_YESNO[0]);
376 case uno::TypeClass_SEQUENCE:
378 Sequence< OUString > aStringValues;
380 Sequence< sal_uInt16 > aUInt16Values;
381 Sequence< sal_Int16 > aInt16Values;
382 Sequence< sal_uInt32 > aUInt32Values;
383 Sequence< sal_Int32 > aInt32Values;
386 if ( _rValue >>= aStringValues )
388 _rStringRep = composeSequenceElements( aStringValues, StringIdentity() );
391 else if ( _rValue >>= aInt8Values )
393 _rStringRep = composeSequenceElements( aInt8Values, ConvertIntegerFromAndToString() );
396 else if ( _rValue >>= aUInt16Values )
398 _rStringRep = composeSequenceElements( aUInt16Values, ConvertIntegerFromAndToString() );
401 else if ( _rValue >>= aInt16Values )
403 _rStringRep = composeSequenceElements( aInt16Values, ConvertIntegerFromAndToString() );
406 else if ( _rValue >>= aUInt32Values )
408 _rStringRep = composeSequenceElements( aUInt32Values, ConvertIntegerFromAndToString() );
411 else if ( _rValue >>= aInt32Values )
413 _rStringRep = composeSequenceElements( aInt32Values, ConvertIntegerFromAndToString() );
419 case uno::TypeClass_CONSTANT:
423 case uno::TypeClass_STRUCT:
424 OSL_FAIL(
"StringRepresentation::convertGenericValueToString(STRUCT): this is dead code - isn't it?" );
431 _rValue >>= aUnoDate;
432 _rStringRep = ::dbtools::DBTypeConversion::toDateString(aUnoDate);
438 _rValue >>= aUnoTime;
439 _rStringRep = ::dbtools::DBTypeConversion::toTimeString(aUnoTime);
443 util::DateTime aUnoDateTime;
444 _rValue >>= aUnoDateTime;
445 _rStringRep = ::dbtools::DBTypeConversion::toDateTimeString(aUnoDateTime);
459uno::Any StringRepresentation::convertStringToSimple(
const OUString& _rValue,
const uno::TypeClass& _ePropertyType )
462 if ( m_xTypeConverter.is() && !_rValue.isEmpty() )
466 if ( m_aConstants.hasElements() &&
m_aValues.hasElements() )
468 const OUString* pIter =
m_aValues.getConstArray();
469 const OUString* pEnd = pIter +
m_aValues.getLength();
470 for(sal_Int32 i = 0;pIter != pEnd;++pIter,++
i)
472 if ( *pIter == _rValue )
474 OSL_ENSURE(i < m_aConstants.getLength() ,
"StringRepresentation::convertSimpleToString: Index is not in range of m_aValues");
475 aReturn = m_aConstants[
i]->getConstantValue();
482 aReturn = m_xTypeConverter->convertToSimpleType(
Any( _rValue ), _ePropertyType );
484 catch(
const script::CannotConvertException& ) { }
485 catch(
const lang::IllegalArgumentException& ) { }
490bool StringRepresentation::convertStringToGenericValue(
const OUString& _rStringRep,
uno::Any& _rValue,
const uno::Type& _rTargetType )
492 bool bCanConvert =
true;
494 switch ( _rTargetType.getTypeClass() )
496 case uno::TypeClass_STRING:
497 _rValue <<= _rStringRep;
500 case uno::TypeClass_BOOLEAN:
502 _rValue <<=
PcrRes(RID_RSC_ENUM_YESNO[0]) != _rStringRep;
506 case uno::TypeClass_SEQUENCE:
508 uno::Type aElementType = ::comphelper::getSequenceElementType( _rTargetType );
510 switch ( aElementType.getTypeClass() )
512 case uno::TypeClass_STRING:
514 Sequence< OUString > aElements;
515 splitComposedStringToSequence( _rStringRep, aElements, StringIdentity() );
516 _rValue <<= aElements;
519 case uno::TypeClass_SHORT:
521 Sequence< sal_Int16 > aElements;
522 splitComposedStringToSequence( _rStringRep, aElements, ConvertIntegerFromAndToString() );
523 _rValue <<= aElements;
526 case uno::TypeClass_UNSIGNED_SHORT:
528 Sequence< sal_uInt16 > aElements;
529 splitComposedStringToSequence( _rStringRep, aElements, ConvertIntegerFromAndToString() );
530 _rValue <<= aElements;
533 case uno::TypeClass_LONG:
535 Sequence< sal_Int32 > aElements;
536 splitComposedStringToSequence( _rStringRep, aElements, ConvertIntegerFromAndToString() );
537 _rValue <<= aElements;
540 case uno::TypeClass_UNSIGNED_LONG:
542 Sequence< sal_uInt32 > aElements;
543 splitComposedStringToSequence( _rStringRep, aElements, ConvertIntegerFromAndToString() );
544 _rValue <<= aElements;
547 case uno::TypeClass_BYTE:
550 splitComposedStringToSequence( _rStringRep, aElements, ConvertIntegerFromAndToString() );
551 _rValue <<= aElements;
561 case uno::TypeClass_STRUCT:
562 OSL_FAIL(
"StringRepresentation::convertStringToGenericValue(STRUCT): this is dead code - isn't it?" );
569 _rValue <<= ::dbtools::DBTypeConversion::toDate(_rStringRep);
574 _rValue <<= ::dbtools::DBTypeConversion::toTime(_rStringRep);
578 _rValue <<= ::dbtools::DBTypeConversion::toDateTime(_rStringRep);
596extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
598 css::uno::XComponentContext* context , css::uno::Sequence<css::uno::Any>
const&)
600 return cppu::acquire(
new pcr::StringRepresentation(context));
Reference< XComponentContext > m_xContext
Sequence< PropertyValue > aArguments
#define SAL_WARN(area, stream)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
enumrange< T >::Iterator begin(enumrange< T >)
a property handler for any virtual string properties
OUString PcrRes(TranslateId aId)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * extensions_propctrlr_StringRepresentation_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)