1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: formatnormalizer.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "formatnormalizer.hxx"
32 #include "RptModel.hxx"
34 /** === begin UNO includes === **/
35 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
36 #include <com/sun/star/sdb/XParametersSupplier.hpp>
37 #include <com/sun/star/util/XNumberFormatTypes.hpp>
38 /** === end UNO includes === **/
40 #include <dbaccess/singledoccontroller.hxx>
41 #include <svtools/syslocale.hxx>
42 #include <connectivity/statementcomposer.hxx>
43 #include <connectivity/dbtools.hxx>
44 #include <tools/diagnose_ex.h>
46 //........................................................................
49 //........................................................................
51 /** === begin UNO using === **/
52 using ::com::sun::star::uno::Reference
;
53 using ::com::sun::star::report::XReportDefinition
;
54 using ::com::sun::star::report::XFormattedField
;
55 using ::com::sun::star::uno::UNO_QUERY
;
56 using ::com::sun::star::sdb::XSingleSelectQueryComposer
;
57 using ::com::sun::star::sdbcx::XColumnsSupplier
;
58 using ::com::sun::star::container::XIndexAccess
;
59 using ::com::sun::star::beans::XPropertySet
;
60 using ::com::sun::star::uno::UNO_QUERY_THROW
;
61 using ::com::sun::star::uno::Exception
;
62 using ::com::sun::star::sdb::XParametersSupplier
;
63 using ::com::sun::star::sdbc::SQLException
;
64 using ::com::sun::star::util::XNumberFormatsSupplier
;
65 using ::com::sun::star::util::XNumberFormatTypes
;
66 /** === end UNO using === **/
68 //====================================================================
70 //====================================================================
71 DBG_NAME(rpt_FormatNormalizer
)
72 //--------------------------------------------------------------------
73 FormatNormalizer::FormatNormalizer( const OReportModel
& _rModel
)
75 ,m_xReportDefinition( )
76 ,m_bFieldListDirty( true )
78 DBG_CTOR(rpt_FormatNormalizer
,NULL
);
81 //--------------------------------------------------------------------
82 FormatNormalizer::~FormatNormalizer()
84 DBG_DTOR(rpt_FormatNormalizer
,NULL
);
87 //--------------------------------------------------------------------
88 void FormatNormalizer::notifyPropertyChange( const ::com::sun::star::beans::PropertyChangeEvent
& _rEvent
)
90 if ( !impl_lateInit() )
93 if ( ( _rEvent
.Source
== m_xReportDefinition
) && m_xReportDefinition
.is() )
95 impl_onDefinitionPropertyChange( _rEvent
.PropertyName
);
99 Reference
< XFormattedField
> xFormatted( _rEvent
.Source
, UNO_QUERY
);
100 if ( xFormatted
.is() )
101 impl_onFormattedProperttyChange( xFormatted
, _rEvent
.PropertyName
);
104 //--------------------------------------------------------------------
105 void FormatNormalizer::notifyElementInserted( const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& _rxElement
)
107 if ( !impl_lateInit() )
110 Reference
< XFormattedField
> xFormatted( _rxElement
, UNO_QUERY
);
111 if ( !xFormatted
.is() )
114 impl_adjustFormatToDataFieldType_nothrow( xFormatted
);
117 //--------------------------------------------------------------------
118 bool FormatNormalizer::impl_lateInit()
120 if ( m_xReportDefinition
.is() )
123 m_xReportDefinition
= m_rModel
.getReportDefinition();
124 return m_xReportDefinition
.is();
127 //--------------------------------------------------------------------
128 void FormatNormalizer::impl_onDefinitionPropertyChange( const ::rtl::OUString
& _rChangedPropName
)
130 if ( !_rChangedPropName
.equalsAscii( "Command" )
131 && !_rChangedPropName
.equalsAscii( "CommandType" )
132 && !_rChangedPropName
.equalsAscii( "EscapeProcessing" )
134 // nothing we're interested in
136 m_bFieldListDirty
= true;
139 //--------------------------------------------------------------------
140 void FormatNormalizer::impl_onFormattedProperttyChange( const Reference
< XFormattedField
>& _rxFormatted
, const ::rtl::OUString
& _rChangedPropName
)
142 if ( !_rChangedPropName
.equalsAscii( "DataField" ) )
143 // nothing we're interested in
146 impl_adjustFormatToDataFieldType_nothrow( _rxFormatted
);
149 //--------------------------------------------------------------------
152 void lcl_collectFields_throw( const Reference
< XIndexAccess
>& _rxColumns
, FormatNormalizer::FieldList
& _inout_rFields
)
156 sal_Int32
nCount( _rxColumns
->getCount() );
157 _inout_rFields
.reserve( _inout_rFields
.size() + (size_t)nCount
);
159 Reference
< XPropertySet
> xColumn
;
160 FormatNormalizer::Field aField
;
162 for ( sal_Int32 i
=0; i
<nCount
; ++i
)
164 xColumn
.set( _rxColumns
->getByIndex( i
), UNO_QUERY_THROW
);
165 OSL_VERIFY( xColumn
->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Name" ) ) ) >>= aField
.sName
);
166 OSL_VERIFY( xColumn
->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ) ) >>= aField
.nDataType
);
167 OSL_VERIFY( xColumn
->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Scale" ) ) ) >>= aField
.nScale
);
168 OSL_VERIFY( xColumn
->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsCurrency" ) ) ) >>= aField
.bIsCurrency
);
169 _inout_rFields
.push_back( aField
);
172 catch( const Exception
& )
174 DBG_UNHANDLED_EXCEPTION();
179 //--------------------------------------------------------------------
180 bool FormatNormalizer::impl_ensureUpToDateFieldList_nothrow()
182 if ( !m_bFieldListDirty
)
184 m_aFields
.resize( 0 );
186 OSL_PRECOND( m_xReportDefinition
.is(), "FormatNormalizer::impl_ensureUpToDateFieldList_nothrow: no report definition!" );
187 if ( !m_xReportDefinition
.is() )
190 ::dbaui::OSingleDocumentController
* pController( m_rModel
.getController() );
191 OSL_ENSURE( pController
, "FormatNormalizer::impl_ensureUpToDateFieldList_nothrow: no controller? how can *this* happen?!" );
197 ::dbtools::StatementComposer
aComposer( pController
->getConnection(), m_xReportDefinition
->getCommand(),
198 m_xReportDefinition
->getCommandType(), m_xReportDefinition
->getEscapeProcessing() );
200 Reference
< XSingleSelectQueryComposer
> xComposer( aComposer
.getComposer() );
201 if ( !xComposer
.is() )
205 Reference
< XColumnsSupplier
> xSuppCols( xComposer
, UNO_QUERY_THROW
);
206 Reference
< XIndexAccess
> xColumns( xSuppCols
->getColumns(), UNO_QUERY_THROW
);
207 lcl_collectFields_throw( xColumns
, m_aFields
);
209 Reference
< XParametersSupplier
> xSuppParams( xComposer
, UNO_QUERY_THROW
);
210 Reference
< XIndexAccess
> xParams( xSuppParams
->getParameters(), UNO_QUERY_THROW
);
211 lcl_collectFields_throw( xParams
, m_aFields
);
213 catch( const SQLException
& )
215 // silence it. This might happen for instance when the user sets an non-existent table,
216 // or things like this
218 catch( const Exception
& )
220 DBG_UNHANDLED_EXCEPTION();
223 m_bFieldListDirty
= false;
227 //--------------------------------------------------------------------
228 void FormatNormalizer::impl_adjustFormatToDataFieldType_nothrow( const Reference
< XFormattedField
>& _rxFormatted
)
230 if ( !impl_ensureUpToDateFieldList_nothrow() )
231 // unable to obtain a recent field list
236 sal_Int32 nFormatKey
= _rxFormatted
->getFormatKey();
237 if ( nFormatKey
!= 0 )
238 // it's not the "standard numeric" format -> not interested in
241 ::rtl::OUString
sDataField( _rxFormatted
->getDataField() );
242 const ::rtl::OUString
sFieldPrefix( RTL_CONSTASCII_USTRINGPARAM( "field:[" ) );
243 if ( sDataField
.indexOf( sFieldPrefix
) != 0 )
244 // not bound to a table field
245 // TODO: we might also do this kind of thing for functions and expressions ...
247 if ( sDataField
.getStr()[ sDataField
.getLength() - 1 ] != ']' )
249 // last character is not the closing brace
250 OSL_ENSURE( false, "FormatNormalizer::impl_adjustFormatToDataFieldType_nothrow: suspicious data field value!" );
253 sDataField
= sDataField
.copy( sFieldPrefix
.getLength(), sDataField
.getLength() - sFieldPrefix
.getLength() - 1 );
255 FieldList::const_iterator field
= m_aFields
.begin();
256 for ( ; field
!= m_aFields
.end(); ++field
)
258 if ( field
->sName
== sDataField
)
261 if ( field
== m_aFields
.end() )
265 Reference
< XNumberFormatsSupplier
> xSuppNumFmts( _rxFormatted
->getFormatsSupplier(), UNO_QUERY_THROW
);
266 Reference
< XNumberFormatTypes
> xNumFmtTypes( xSuppNumFmts
->getNumberFormats(), UNO_QUERY_THROW
);
268 nFormatKey
= ::dbtools::getDefaultNumberFormat( field
->nDataType
, field
->nScale
, field
->bIsCurrency
, xNumFmtTypes
,
269 SvtSysLocale().GetLocaleData().getLocale() );
270 _rxFormatted
->setFormatKey( nFormatKey
);
272 catch( const Exception
& )
274 DBG_UNHANDLED_EXCEPTION();
278 //........................................................................
280 //........................................................................