1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "connectivity/formattedcolumnvalue.hxx"
31 #include "connectivity/dbtools.hxx"
32 #include "connectivity/dbconversion.hxx"
34 /** === begin UNO includes === **/
35 #include <com/sun/star/util/XNumberFormatter.hpp>
36 #include <com/sun/star/util/Date.hpp>
37 #include <com/sun/star/sdbc/XConnection.hpp>
38 #include <com/sun/star/util/XNumberFormatTypes.hpp>
39 #include <com/sun/star/util/NumberFormat.hpp>
40 #include <com/sun/star/sdbc/DataType.hpp>
41 /** === end UNO includes === **/
43 #include <tools/diagnose_ex.h>
44 #include <i18npool/mslangid.hxx>
45 #include <comphelper/numbers.hxx>
46 #include <comphelper/componentcontext.hxx>
47 #include <unotools/sharedunocomponent.hxx>
49 //........................................................................
52 //........................................................................
54 /** === begin UNO using === **/
55 using ::com::sun::star::uno::Reference
;
56 using ::com::sun::star::uno::UNO_QUERY
;
57 using ::com::sun::star::uno::UNO_QUERY_THROW
;
58 using ::com::sun::star::uno::UNO_SET_THROW
;
59 using ::com::sun::star::uno::Exception
;
60 using ::com::sun::star::uno::RuntimeException
;
61 using ::com::sun::star::uno::Any
;
62 using ::com::sun::star::uno::makeAny
;
63 using ::com::sun::star::sdbc::XRowSet
;
64 using ::com::sun::star::beans::XPropertySet
;
65 using ::com::sun::star::util::XNumberFormatter
;
66 using ::com::sun::star::util::Date
;
67 using ::com::sun::star::sdbc::XConnection
;
68 using ::com::sun::star::util::XNumberFormatsSupplier
;
69 using ::com::sun::star::beans::XPropertySetInfo
;
70 using ::com::sun::star::lang::Locale
;
71 using ::com::sun::star::util::XNumberFormatTypes
;
72 using ::com::sun::star::sdb::XColumn
;
73 using ::com::sun::star::sdb::XColumnUpdate
;
74 using ::com::sun::star::lang::XComponent
;
75 /** === end UNO using === **/
76 namespace DataType
= ::com::sun::star::sdbc::DataType
;
77 namespace NumberFormat
= ::com::sun::star::util::NumberFormat
;
79 //====================================================================
80 //= FormattedColumnValue_Data
81 //====================================================================
82 struct FormattedColumnValue_Data
84 Reference
< XNumberFormatter
> m_xFormatter
;
86 sal_Int32 m_nFormatKey
;
87 sal_Int32 m_nFieldType
;
91 Reference
< XColumn
> m_xColumn
;
92 Reference
< XColumnUpdate
> m_xColumnUpdate
;
94 FormattedColumnValue_Data()
96 ,m_aNullDate( DBTypeConversion::getStandardDate() )
98 ,m_nFieldType( DataType::OTHER
)
99 ,m_nKeyType( NumberFormat::UNDEFINED
)
100 ,m_bNumericField( false )
107 //--------------------------------------------------------------------
110 //................................................................
111 void lcl_clear_nothrow( FormattedColumnValue_Data
& _rData
)
113 _rData
.m_xFormatter
.clear();
114 _rData
.m_nFormatKey
= 0;
115 _rData
.m_nFieldType
= DataType::OTHER
;
116 _rData
.m_nKeyType
= NumberFormat::UNDEFINED
;
117 _rData
.m_bNumericField
= false;
119 _rData
.m_xColumn
.clear();
120 _rData
.m_xColumnUpdate
.clear();
123 //................................................................
124 void lcl_initColumnDataValue_nothrow( FormattedColumnValue_Data
& _rData
,
125 const Reference
< XNumberFormatter
>& i_rNumberFormatter
, const Reference
< XPropertySet
>& _rxColumn
)
127 lcl_clear_nothrow( _rData
);
129 OSL_PRECOND( i_rNumberFormatter
.is(), "lcl_initColumnDataValue_nothrow: no number formats -> no formatted values!" );
130 if ( !i_rNumberFormatter
.is() )
135 Reference
< XNumberFormatsSupplier
> xNumberFormatsSupp( i_rNumberFormatter
->getNumberFormatsSupplier(), UNO_SET_THROW
);
137 // remember the column
138 _rData
.m_xColumn
.set( _rxColumn
, UNO_QUERY_THROW
);
139 _rData
.m_xColumnUpdate
.set( _rxColumn
, UNO_QUERY
);
141 // determine the field type, and whether it's a numeric field
142 OSL_VERIFY( _rxColumn
->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ) ) >>= _rData
.m_nFieldType
);
144 switch ( _rData
.m_nFieldType
)
148 case DataType::TIMESTAMP
:
150 case DataType::BOOLEAN
:
151 case DataType::TINYINT
:
152 case DataType::SMALLINT
:
153 case DataType::INTEGER
:
155 case DataType::BIGINT
:
156 case DataType::DOUBLE
:
157 case DataType::NUMERIC
:
158 case DataType::DECIMAL
:
159 _rData
.m_bNumericField
= true;
162 _rData
.m_bNumericField
= false;
166 // get the format key of our bound field
167 Reference
< XPropertySetInfo
> xPSI( _rxColumn
->getPropertySetInfo(), UNO_QUERY_THROW
);
168 bool bHaveFieldFormat
= false;
169 const ::rtl::OUString
sFormatKeyProperty( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FormatKey" ) ) );
170 if ( xPSI
->hasPropertyByName( sFormatKeyProperty
) )
172 bHaveFieldFormat
= ( _rxColumn
->getPropertyValue( sFormatKeyProperty
) >>= _rData
.m_nFormatKey
);
174 if ( !bHaveFieldFormat
)
176 // fall back to a format key as indicated by the field type
177 Locale aSystemLocale
;
178 MsLangId::convertLanguageToLocale( MsLangId::getSystemLanguage(), aSystemLocale
);
179 Reference
< XNumberFormatTypes
> xNumTypes( xNumberFormatsSupp
->getNumberFormats(), UNO_QUERY_THROW
);
180 _rData
.m_nFormatKey
= getDefaultNumberFormat( _rxColumn
, xNumTypes
, aSystemLocale
);
183 // some more formatter settings
184 _rData
.m_nKeyType
= ::comphelper::getNumberFormatType( xNumberFormatsSupp
->getNumberFormats(), _rData
.m_nFormatKey
);
185 Reference
< XPropertySet
> xFormatSettings( xNumberFormatsSupp
->getNumberFormatSettings(), UNO_QUERY_THROW
);
186 OSL_VERIFY( xFormatSettings
->getPropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "NullDate" )) ) >>= _rData
.m_aNullDate
);
188 // remember the formatter
189 _rData
.m_xFormatter
= i_rNumberFormatter
;
191 catch( const Exception
& )
193 DBG_UNHANDLED_EXCEPTION();
197 //................................................................
198 void lcl_initColumnDataValue_nothrow( const ::comphelper::ComponentContext
& i_rContext
, FormattedColumnValue_Data
& i_rData
,
199 const Reference
< XRowSet
>& i_rRowSet
, const Reference
< XPropertySet
>& i_rColumn
)
201 OSL_PRECOND( i_rRowSet
.is(), "lcl_initColumnDataValue_nothrow: no row set!" );
202 if ( !i_rRowSet
.is() )
205 Reference
< XNumberFormatter
> xNumberFormatter
;
208 // get the number formats supplier of the connection of the form
209 Reference
< XConnection
> xConnection( getConnection( i_rRowSet
), UNO_QUERY_THROW
);
210 Reference
< XNumberFormatsSupplier
> xSupplier( getNumberFormats( xConnection
, sal_True
, i_rContext
.getLegacyServiceFactory() ), UNO_SET_THROW
);
212 // create a number formatter for it
213 xNumberFormatter
.set( i_rContext
.createComponent( "com.sun.star.util.NumberFormatter" ), UNO_QUERY_THROW
);
214 xNumberFormatter
->attachNumberFormatsSupplier( xSupplier
);
216 catch( const Exception
& )
218 DBG_UNHANDLED_EXCEPTION();
221 lcl_initColumnDataValue_nothrow( i_rData
, xNumberFormatter
, i_rColumn
);
225 //====================================================================
226 //= FormattedColumnValue
227 //====================================================================
228 //--------------------------------------------------------------------
229 FormattedColumnValue::FormattedColumnValue( const ::comphelper::ComponentContext
& i_rContext
,
230 const Reference
< XRowSet
>& _rxRowSet
, const Reference
< XPropertySet
>& i_rColumn
)
231 :m_pData( new FormattedColumnValue_Data
)
233 lcl_initColumnDataValue_nothrow( i_rContext
, *m_pData
, _rxRowSet
, i_rColumn
);
236 //--------------------------------------------------------------------
237 FormattedColumnValue::FormattedColumnValue( const Reference
< XNumberFormatter
>& i_rNumberFormatter
,
238 const Reference
< XPropertySet
>& _rxColumn
)
239 :m_pData( new FormattedColumnValue_Data
)
241 lcl_initColumnDataValue_nothrow( *m_pData
, i_rNumberFormatter
, _rxColumn
);
244 //--------------------------------------------------------------------
245 void FormattedColumnValue::clear()
247 lcl_clear_nothrow( *m_pData
);
250 //--------------------------------------------------------------------
251 FormattedColumnValue::~FormattedColumnValue()
256 //--------------------------------------------------------------------
257 sal_Int32
FormattedColumnValue::getFormatKey() const
259 return m_pData
->m_nFormatKey
;
262 //--------------------------------------------------------------------
263 sal_Int32
FormattedColumnValue::getFieldType() const
265 return m_pData
->m_nFieldType
;
268 //--------------------------------------------------------------------
269 sal_Int16
FormattedColumnValue::getKeyType() const
271 return m_pData
->m_nKeyType
;
274 //--------------------------------------------------------------------
275 bool FormattedColumnValue::isNumericField() const
277 return m_pData
->m_bNumericField
;
280 //--------------------------------------------------------------------
281 const Reference
< XColumn
>& FormattedColumnValue::getColumn() const
283 return m_pData
->m_xColumn
;
286 //--------------------------------------------------------------------
287 const Reference
< XColumnUpdate
>& FormattedColumnValue::getColumnUpdate() const
289 return m_pData
->m_xColumnUpdate
;
292 //--------------------------------------------------------------------
293 bool FormattedColumnValue::setFormattedValue( const ::rtl::OUString
& _rFormattedStringValue
) const
295 OSL_PRECOND( m_pData
->m_xColumnUpdate
.is(), "FormattedColumnValue::setFormattedValue: no column!" );
296 if ( !m_pData
->m_xColumnUpdate
.is() )
301 if ( m_pData
->m_bNumericField
)
303 ::dbtools::DBTypeConversion::setValue( m_pData
->m_xColumnUpdate
, m_pData
->m_xFormatter
, m_pData
->m_aNullDate
,
304 _rFormattedStringValue
, m_pData
->m_nFormatKey
, ::sal::static_int_cast
< sal_Int16
>( m_pData
->m_nFieldType
),
305 m_pData
->m_nKeyType
);
309 m_pData
->m_xColumnUpdate
->updateString( _rFormattedStringValue
);
312 catch( const Exception
& )
319 //--------------------------------------------------------------------
320 ::rtl::OUString
FormattedColumnValue::getFormattedValue() const
322 OSL_PRECOND( m_pData
->m_xColumn
.is(), "FormattedColumnValue::setFormattedValue: no column!" );
324 ::rtl::OUString sStringValue
;
325 if ( m_pData
->m_xColumn
.is() )
327 if ( m_pData
->m_bNumericField
)
329 sStringValue
= DBTypeConversion::getFormattedValue(
330 m_pData
->m_xColumn
, m_pData
->m_xFormatter
, m_pData
->m_aNullDate
, m_pData
->m_nFormatKey
, m_pData
->m_nKeyType
335 sStringValue
= m_pData
->m_xColumn
->getString();
341 //........................................................................
342 } // namespace dbtools
343 //........................................................................
345 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */