LibreOffice Module connectivity (master) 1
formattedcolumnvalue.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
24
25#include <com/sun/star/util/NumberFormatter.hpp>
26#include <com/sun/star/util/Date.hpp>
27#include <com/sun/star/sdbc/XConnection.hpp>
28#include <com/sun/star/util/XNumberFormatTypes.hpp>
29#include <com/sun/star/util/NumberFormat.hpp>
30#include <com/sun/star/sdbc/DataType.hpp>
31#include <com/sun/star/sdb/XColumn.hpp>
32#include <com/sun/star/sdb/XColumnUpdate.hpp>
33
38
39
40namespace dbtools
41{
42
43
44 using ::com::sun::star::uno::Reference;
45 using ::com::sun::star::uno::UNO_QUERY;
46 using ::com::sun::star::uno::UNO_QUERY_THROW;
47 using ::com::sun::star::uno::UNO_SET_THROW;
48 using ::com::sun::star::uno::Exception;
49 using ::com::sun::star::uno::XComponentContext;
50 using ::com::sun::star::sdbc::XRowSet;
51 using ::com::sun::star::beans::XPropertySet;
52 using ::com::sun::star::util::NumberFormatter;
53 using ::com::sun::star::util::XNumberFormatter;
54 using ::com::sun::star::util::Date;
55 using ::com::sun::star::sdbc::XConnection;
56 using ::com::sun::star::util::XNumberFormatsSupplier;
57 using ::com::sun::star::beans::XPropertySetInfo;
58 using ::com::sun::star::lang::Locale;
59 using ::com::sun::star::util::XNumberFormatTypes;
60 using ::com::sun::star::sdb::XColumn;
61 using ::com::sun::star::sdb::XColumnUpdate;
62
63 namespace DataType = ::com::sun::star::sdbc::DataType;
64 namespace NumberFormat = ::com::sun::star::util::NumberFormat;
65
67 {
68 Reference< XNumberFormatter > m_xFormatter;
70 sal_Int32 m_nFormatKey;
71 sal_Int32 m_nFieldType;
72 sal_Int16 m_nKeyType;
74
75 Reference< XColumn > m_xColumn;
76 Reference< XColumnUpdate > m_xColumnUpdate;
77
79 :m_aNullDate( DBTypeConversion::getStandardDate() )
80 ,m_nFormatKey( 0 )
82 ,m_nKeyType( NumberFormat::UNDEFINED )
83 ,m_bNumericField( false )
84 {
85 }
86 };
87
88
89 namespace
90 {
91
92 void lcl_clear_nothrow( FormattedColumnValue_Data& _rData )
93 {
94 _rData.m_xFormatter.clear();
95 _rData.m_nFormatKey = 0;
96 _rData.m_nFieldType = DataType::OTHER;
97 _rData.m_nKeyType = NumberFormat::UNDEFINED;
98 _rData.m_bNumericField = false;
99
100 _rData.m_xColumn.clear();
101 _rData.m_xColumnUpdate.clear();
102 }
103
104
105 void lcl_initColumnDataValue_nothrow( FormattedColumnValue_Data& _rData,
106 const Reference< XNumberFormatter >& i_rNumberFormatter, const Reference< XPropertySet >& _rxColumn )
107 {
108 lcl_clear_nothrow( _rData );
109
110 OSL_PRECOND( i_rNumberFormatter.is(), "lcl_initColumnDataValue_nothrow: no number formats -> no formatted values!" );
111 if ( !i_rNumberFormatter.is() )
112 return;
113
114 try
115 {
116 Reference< XNumberFormatsSupplier > xNumberFormatsSupp( i_rNumberFormatter->getNumberFormatsSupplier(), UNO_SET_THROW );
117
118 // remember the column
119 _rData.m_xColumn.set( _rxColumn, UNO_QUERY_THROW );
120 _rData.m_xColumnUpdate.set( _rxColumn, UNO_QUERY );
121
122 // determine the field type, and whether it's a numeric field
123 OSL_VERIFY( _rxColumn->getPropertyValue("Type") >>= _rData.m_nFieldType );
124
125 switch ( _rData.m_nFieldType )
126 {
127 case DataType::DATE:
128 case DataType::TIME:
129 case DataType::TIMESTAMP:
130 case DataType::BIT:
131 case DataType::BOOLEAN:
132 case DataType::TINYINT:
133 case DataType::SMALLINT:
134 case DataType::INTEGER:
135 case DataType::REAL:
136 case DataType::BIGINT:
137 case DataType::DOUBLE:
138 case DataType::NUMERIC:
139 case DataType::DECIMAL:
140 _rData.m_bNumericField = true;
141 break;
142 default:
143 _rData.m_bNumericField = false;
144 break;
145 }
146
147 // get the format key of our bound field
148 Reference< XPropertySetInfo > xPSI( _rxColumn->getPropertySetInfo(), UNO_SET_THROW );
149 bool bHaveFieldFormat = false;
150 static constexpr OUStringLiteral sFormatKeyProperty( u"FormatKey" );
151 if ( xPSI->hasPropertyByName( sFormatKeyProperty ) )
152 {
153 bHaveFieldFormat = ( _rxColumn->getPropertyValue( sFormatKeyProperty ) >>= _rData.m_nFormatKey );
154 }
155 if ( !bHaveFieldFormat )
156 {
157 // fall back to a format key as indicated by the field type
159 Reference< XNumberFormatTypes > xNumTypes( xNumberFormatsSupp->getNumberFormats(), UNO_QUERY_THROW );
160 _rData.m_nFormatKey = getDefaultNumberFormat( _rxColumn, xNumTypes, aSystemLocale );
161 }
162
163 // some more formatter settings
164 _rData.m_nKeyType = ::comphelper::getNumberFormatType( xNumberFormatsSupp->getNumberFormats(), _rData.m_nFormatKey );
165 Reference< XPropertySet > xFormatSettings( xNumberFormatsSupp->getNumberFormatSettings(), UNO_SET_THROW );
166 OSL_VERIFY( xFormatSettings->getPropertyValue("NullDate") >>= _rData.m_aNullDate );
167
168 // remember the formatter
169 _rData.m_xFormatter = i_rNumberFormatter;
170 }
171 catch( const Exception& )
172 {
173 DBG_UNHANDLED_EXCEPTION("connectivity.commontools");
174 }
175 }
176
177
178 void lcl_initColumnDataValue_nothrow( const Reference<XComponentContext>& i_rContext, FormattedColumnValue_Data& i_rData,
179 const Reference< XRowSet >& i_rRowSet, const Reference< XPropertySet >& i_rColumn )
180 {
181 OSL_PRECOND( i_rRowSet.is(), "lcl_initColumnDataValue_nothrow: no row set!" );
182 if ( !i_rRowSet.is() )
183 return;
184
185 Reference< XNumberFormatter > xNumberFormatter;
186 try
187 {
188 // get the number formats supplier of the connection of the form
189 Reference< XConnection > xConnection( getConnection( i_rRowSet ), UNO_SET_THROW );
190 Reference< XNumberFormatsSupplier > xSupplier( getNumberFormats( xConnection, true, i_rContext ), UNO_SET_THROW );
191
192 // create a number formatter for it
193 xNumberFormatter.set( NumberFormatter::create( i_rContext ), UNO_QUERY_THROW );
194 xNumberFormatter->attachNumberFormatsSupplier( xSupplier );
195 }
196 catch( const Exception& )
197 {
198 DBG_UNHANDLED_EXCEPTION("connectivity.commontools");
199 }
200
201 lcl_initColumnDataValue_nothrow( i_rData, xNumberFormatter, i_rColumn );
202 }
203 }
204
205 FormattedColumnValue::FormattedColumnValue( const Reference< XComponentContext >& _rxContext,
206 const Reference< XRowSet >& _rxRowSet, const Reference< XPropertySet >& i_rColumn )
207 :m_pData( new FormattedColumnValue_Data )
208 {
209 lcl_initColumnDataValue_nothrow( _rxContext, *m_pData, _rxRowSet, i_rColumn );
210 }
211
212
213 FormattedColumnValue::FormattedColumnValue( const Reference< XNumberFormatter >& i_rNumberFormatter,
214 const Reference< XPropertySet >& _rxColumn )
215 :m_pData( new FormattedColumnValue_Data )
216 {
217 lcl_initColumnDataValue_nothrow( *m_pData, i_rNumberFormatter, _rxColumn );
218 }
219
220
222 {
223 lcl_clear_nothrow( *m_pData );
224 }
225
227 {
228 return m_pData->m_nKeyType;
229 }
230
231
232 const Reference< XColumn >& FormattedColumnValue::getColumn() const
233 {
234 return m_pData->m_xColumn;
235 }
236
237 bool FormattedColumnValue::setFormattedValue( const OUString& _rFormattedStringValue ) const
238 {
239 OSL_PRECOND( m_pData->m_xColumnUpdate.is(), "FormattedColumnValue::setFormattedValue: no column!" );
240 if ( !m_pData->m_xColumnUpdate.is() )
241 return false;
242
243 try
244 {
245 if ( m_pData->m_bNumericField )
246 {
247 ::dbtools::DBTypeConversion::setValue( m_pData->m_xColumnUpdate, m_pData->m_xFormatter, m_pData->m_aNullDate,
248 _rFormattedStringValue, m_pData->m_nFormatKey, ::sal::static_int_cast< sal_Int16 >( m_pData->m_nFieldType ),
249 m_pData->m_nKeyType );
250 }
251 else
252 {
253 m_pData->m_xColumnUpdate->updateString( _rFormattedStringValue );
254 }
255 }
256 catch( const Exception& )
257 {
258 return false;
259 }
260 return true;
261 }
262
263
265 {
266 OSL_PRECOND( m_pData->m_xColumn.is(), "FormattedColumnValue::setFormattedValue: no column!" );
267
268 OUString sStringValue;
269 if ( m_pData->m_xColumn.is() )
270 {
271 if ( m_pData->m_bNumericField )
272 {
274 m_pData->m_xColumn, m_pData->m_xFormatter, m_pData->m_aNullDate, m_pData->m_nFormatKey, m_pData->m_nKeyType
275 );
276 }
277 else
278 {
279 sStringValue = m_pData->m_xColumn->getString();
280 }
281 }
282 return sStringValue;
283 }
284
285
286} // namespace dbtools
287
288
289/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static LanguageType getConfiguredSystemLanguage()
std::unique_ptr< FormattedColumnValue_Data > m_pData
FormattedColumnValue(const css::uno::Reference< css::uno::XComponentContext > &_rxContext, const css::uno::Reference< css::sdbc::XRowSet > &_rxRowSet, const css::uno::Reference< css::beans::XPropertySet > &_rxColumn)
constructs an instance
bool setFormattedValue(const OUString &_rFormattedStringValue) const
const css::uno::Reference< css::sdb::XColumn > & getColumn() const
#define DBG_UNHANDLED_EXCEPTION(...)
UNDEFINED
FmFilterData * m_pData
@ Exception
const LanguageTag & getLocale()
OOO_DLLPUBLIC_DBTOOLS OUString getFormattedValue(const css::uno::Reference< css::beans::XPropertySet > &_xColumn, const css::uno::Reference< css::util::XNumberFormatter > &xFormatter, const css::lang::Locale &_rLocale, const css::util::Date &rNullDate)
OOO_DLLPUBLIC_DBTOOLS css::util::Date const & getStandardDate()
OOO_DLLPUBLIC_DBTOOLS void setValue(const css::uno::Reference< css::sdb::XColumnUpdate > &xVariant, const css::uno::Reference< css::util::XNumberFormatter > &xFormatter, const css::util::Date &rNullDate, const OUString &rString, sal_Int32 nKey, sal_Int16 nFieldType, sal_Int16 nKeyType)
Reference< XConnection > getConnection(const Reference< XRowSet > &_rxRowSet)
Definition: dbtools.cxx:348
sal_Int32 getDefaultNumberFormat(const Reference< XPropertySet > &_xColumn, const Reference< XNumberFormatTypes > &_xTypes, const Locale &_rLocale)
Definition: dbtools.cxx:115
Reference< XNumberFormatsSupplier > getNumberFormats(const Reference< XConnection > &_rxConn, bool _bAlloweDefault, const Reference< XComponentContext > &_rxContext)
Definition: dbtools.cxx:908
DataType
Reference< XColumnUpdate > m_xColumnUpdate
Reference< XNumberFormatter > m_xFormatter