Update ooo320-m1
[ooovba.git] / reportdesign / source / core / sdr / formatnormalizer.cxx
blobf58b698197415e84408ba233a4206e660107223e
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: formatnormalizer.cxx,v $
10 * $Revision: 1.4 $
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 ************************************************************************/
30 #include "precompiled_reportdesign.hxx"
32 #include "formatnormalizer.hxx"
33 #include "RptModel.hxx"
35 /** === begin UNO includes === **/
36 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
37 #include <com/sun/star/sdb/XParametersSupplier.hpp>
38 #include <com/sun/star/util/XNumberFormatTypes.hpp>
39 /** === end UNO includes === **/
41 #include <dbaccess/singledoccontroller.hxx>
42 #include <svtools/syslocale.hxx>
43 #include <connectivity/statementcomposer.hxx>
44 #include <connectivity/dbtools.hxx>
45 #include <tools/diagnose_ex.h>
47 //........................................................................
48 namespace rptui
50 //........................................................................
52 /** === begin UNO using === **/
53 using ::com::sun::star::uno::Reference;
54 using ::com::sun::star::report::XReportDefinition;
55 using ::com::sun::star::report::XFormattedField;
56 using ::com::sun::star::uno::UNO_QUERY;
57 using ::com::sun::star::sdb::XSingleSelectQueryComposer;
58 using ::com::sun::star::sdbcx::XColumnsSupplier;
59 using ::com::sun::star::container::XIndexAccess;
60 using ::com::sun::star::beans::XPropertySet;
61 using ::com::sun::star::uno::UNO_QUERY_THROW;
62 using ::com::sun::star::uno::Exception;
63 using ::com::sun::star::sdb::XParametersSupplier;
64 using ::com::sun::star::sdbc::SQLException;
65 using ::com::sun::star::util::XNumberFormatsSupplier;
66 using ::com::sun::star::util::XNumberFormatTypes;
67 using ::com::sun::star::uno::makeAny;
68 /** === end UNO using === **/
70 //====================================================================
71 //= FormatNormalizer
72 //====================================================================
73 DBG_NAME(rpt_FormatNormalizer)
74 //--------------------------------------------------------------------
75 FormatNormalizer::FormatNormalizer( const OReportModel& _rModel )
76 :m_rModel( _rModel )
77 ,m_xReportDefinition( )
78 ,m_bFieldListDirty( true )
80 DBG_CTOR(rpt_FormatNormalizer,NULL);
83 //--------------------------------------------------------------------
84 FormatNormalizer::~FormatNormalizer()
86 DBG_DTOR(rpt_FormatNormalizer,NULL);
89 //--------------------------------------------------------------------
90 void FormatNormalizer::notifyPropertyChange( const ::com::sun::star::beans::PropertyChangeEvent& _rEvent )
92 if ( !impl_lateInit() )
93 return;
95 if ( ( _rEvent.Source == m_xReportDefinition ) && m_xReportDefinition.is() )
97 impl_onDefinitionPropertyChange( _rEvent.PropertyName );
98 return;
101 Reference< XFormattedField > xFormatted( _rEvent.Source, UNO_QUERY );
102 if ( xFormatted.is() )
103 impl_onFormattedProperttyChange( xFormatted, _rEvent.PropertyName );
106 //--------------------------------------------------------------------
107 void FormatNormalizer::notifyElementInserted( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxElement )
109 if ( !impl_lateInit() )
110 return;
112 Reference< XFormattedField > xFormatted( _rxElement, UNO_QUERY );
113 if ( !xFormatted.is() )
114 return;
116 impl_adjustFormatToDataFieldType_nothrow( xFormatted );
119 //--------------------------------------------------------------------
120 bool FormatNormalizer::impl_lateInit()
122 if ( m_xReportDefinition.is() )
123 return true;
125 m_xReportDefinition = m_rModel.getReportDefinition();
126 return m_xReportDefinition.is();
129 //--------------------------------------------------------------------
130 void FormatNormalizer::impl_onDefinitionPropertyChange( const ::rtl::OUString& _rChangedPropName )
132 if ( !_rChangedPropName.equalsAscii( "Command" )
133 && !_rChangedPropName.equalsAscii( "CommandType" )
134 && !_rChangedPropName.equalsAscii( "EscapeProcessing" )
136 // nothing we're interested in
137 return;
138 m_bFieldListDirty = true;
141 //--------------------------------------------------------------------
142 void FormatNormalizer::impl_onFormattedProperttyChange( const Reference< XFormattedField >& _rxFormatted, const ::rtl::OUString& _rChangedPropName )
144 if ( !_rChangedPropName.equalsAscii( "DataField" ) )
145 // nothing we're interested in
146 return;
148 impl_adjustFormatToDataFieldType_nothrow( _rxFormatted );
151 //--------------------------------------------------------------------
152 namespace
154 void lcl_collectFields_throw( const Reference< XIndexAccess >& _rxColumns, FormatNormalizer::FieldList& _inout_rFields )
158 sal_Int32 nCount( _rxColumns->getCount() );
159 _inout_rFields.reserve( _inout_rFields.size() + (size_t)nCount );
161 Reference< XPropertySet > xColumn;
162 FormatNormalizer::Field aField;
164 for ( sal_Int32 i=0; i<nCount; ++i )
166 xColumn.set( _rxColumns->getByIndex( i ), UNO_QUERY_THROW );
167 OSL_VERIFY( xColumn->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Name" ) ) ) >>= aField.sName );
168 OSL_VERIFY( xColumn->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ) ) >>= aField.nDataType );
169 OSL_VERIFY( xColumn->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Scale" ) ) ) >>= aField.nScale );
170 OSL_VERIFY( xColumn->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsCurrency" ) ) ) >>= aField.bIsCurrency );
171 _inout_rFields.push_back( aField );
174 catch( const Exception& )
176 DBG_UNHANDLED_EXCEPTION();
181 //--------------------------------------------------------------------
182 bool FormatNormalizer::impl_ensureUpToDateFieldList_nothrow()
184 if ( !m_bFieldListDirty )
185 return true;
186 m_aFields.resize( 0 );
188 OSL_PRECOND( m_xReportDefinition.is(), "FormatNormalizer::impl_ensureUpToDateFieldList_nothrow: no report definition!" );
189 if ( !m_xReportDefinition.is() )
190 return false;
192 ::dbaui::OSingleDocumentController* pController( m_rModel.getController() );
193 OSL_ENSURE( pController, "FormatNormalizer::impl_ensureUpToDateFieldList_nothrow: no controller? how can *this* happen?!" );
194 if ( !pController )
195 return false;
199 ::dbtools::StatementComposer aComposer( pController->getConnection(), m_xReportDefinition->getCommand(),
200 m_xReportDefinition->getCommandType(), m_xReportDefinition->getEscapeProcessing() );
202 Reference< XSingleSelectQueryComposer > xComposer( aComposer.getComposer() );
203 if ( !xComposer.is() )
204 return false;
207 Reference< XColumnsSupplier > xSuppCols( xComposer, UNO_QUERY_THROW );
208 Reference< XIndexAccess > xColumns( xSuppCols->getColumns(), UNO_QUERY_THROW );
209 lcl_collectFields_throw( xColumns, m_aFields );
211 Reference< XParametersSupplier > xSuppParams( xComposer, UNO_QUERY_THROW );
212 Reference< XIndexAccess > xParams( xSuppParams->getParameters(), UNO_QUERY_THROW );
213 lcl_collectFields_throw( xParams, m_aFields );
215 catch( const SQLException& )
217 // silence it. This might happen for instance when the user sets an non-existent table,
218 // or things like this
220 catch( const Exception& )
222 DBG_UNHANDLED_EXCEPTION();
225 m_bFieldListDirty = false;
226 return true;
229 //--------------------------------------------------------------------
230 void FormatNormalizer::impl_adjustFormatToDataFieldType_nothrow( const Reference< XFormattedField >& _rxFormatted )
232 if ( !impl_ensureUpToDateFieldList_nothrow() )
233 // unable to obtain a recent field list
234 return;
238 sal_Int32 nFormatKey = _rxFormatted->getFormatKey();
239 if ( nFormatKey != 0 )
240 // it's not the "standard numeric" format -> not interested in
241 return;
243 ::rtl::OUString sDataField( _rxFormatted->getDataField() );
244 const ::rtl::OUString sFieldPrefix( RTL_CONSTASCII_USTRINGPARAM( "field:[" ) );
245 if ( sDataField.indexOf( sFieldPrefix ) != 0 )
246 // not bound to a table field
247 // TODO: we might also do this kind of thing for functions and expressions ...
248 return;
249 if ( sDataField.getStr()[ sDataField.getLength() - 1 ] != ']' )
251 // last character is not the closing brace
252 OSL_ENSURE( false, "FormatNormalizer::impl_adjustFormatToDataFieldType_nothrow: suspicious data field value!" );
253 return;
255 sDataField = sDataField.copy( sFieldPrefix.getLength(), sDataField.getLength() - sFieldPrefix.getLength() - 1 );
257 FieldList::const_iterator field = m_aFields.begin();
258 for ( ; field != m_aFields.end(); ++field )
260 if ( field->sName == sDataField )
261 break;
263 if ( field == m_aFields.end() )
264 // unknown field
265 return;
267 Reference< XNumberFormatsSupplier > xSuppNumFmts( _rxFormatted->getFormatsSupplier(), UNO_QUERY_THROW );
268 Reference< XNumberFormatTypes > xNumFmtTypes( xSuppNumFmts->getNumberFormats(), UNO_QUERY_THROW );
270 nFormatKey = ::dbtools::getDefaultNumberFormat( field->nDataType, field->nScale, field->bIsCurrency, xNumFmtTypes,
271 SvtSysLocale().GetLocaleData().getLocale() );
272 _rxFormatted->setFormatKey( nFormatKey );
274 catch( const Exception& )
276 DBG_UNHANDLED_EXCEPTION();
280 //........................................................................
281 } // namespace rptui
282 //........................................................................