Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
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.
15 : : *
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).
21 : : *
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.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "formatnormalizer.hxx"
30 : : #include "RptModel.hxx"
31 : :
32 : : #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
33 : : #include <com/sun/star/sdb/XParametersSupplier.hpp>
34 : : #include <com/sun/star/util/XNumberFormatTypes.hpp>
35 : :
36 : : #include <dbaccess/dbsubcomponentcontroller.hxx>
37 : : #include <unotools/syslocale.hxx>
38 : : #include <connectivity/statementcomposer.hxx>
39 : : #include <connectivity/dbtools.hxx>
40 : : #include <tools/diagnose_ex.h>
41 : :
42 : : //........................................................................
43 : : namespace rptui
44 : : {
45 : : //........................................................................
46 : :
47 : : /** === begin UNO using === **/
48 : : using ::com::sun::star::uno::Reference;
49 : : using ::com::sun::star::report::XReportDefinition;
50 : : using ::com::sun::star::report::XFormattedField;
51 : : using ::com::sun::star::uno::UNO_QUERY;
52 : : using ::com::sun::star::sdb::XSingleSelectQueryComposer;
53 : : using ::com::sun::star::sdbcx::XColumnsSupplier;
54 : : using ::com::sun::star::container::XIndexAccess;
55 : : using ::com::sun::star::beans::XPropertySet;
56 : : using ::com::sun::star::uno::UNO_QUERY_THROW;
57 : : using ::com::sun::star::uno::Exception;
58 : : using ::com::sun::star::sdb::XParametersSupplier;
59 : : using ::com::sun::star::sdbc::SQLException;
60 : : using ::com::sun::star::util::XNumberFormatsSupplier;
61 : : using ::com::sun::star::util::XNumberFormatTypes;
62 : : using ::com::sun::star::uno::makeAny;
63 : : /** === end UNO using === **/
64 : :
65 : : //====================================================================
66 : : //= FormatNormalizer
67 : : //====================================================================
68 : : DBG_NAME(rpt_FormatNormalizer)
69 : : //--------------------------------------------------------------------
70 : 0 : FormatNormalizer::FormatNormalizer( const OReportModel& _rModel )
71 : : :m_rModel( _rModel )
72 : : ,m_xReportDefinition( )
73 [ # # ]: 0 : ,m_bFieldListDirty( true )
74 : : {
75 : : DBG_CTOR(rpt_FormatNormalizer,NULL);
76 : 0 : }
77 : :
78 : : //--------------------------------------------------------------------
79 : 0 : FormatNormalizer::~FormatNormalizer()
80 : : {
81 : : DBG_DTOR(rpt_FormatNormalizer,NULL);
82 : 0 : }
83 : :
84 : : //--------------------------------------------------------------------
85 : 0 : void FormatNormalizer::notifyPropertyChange( const ::com::sun::star::beans::PropertyChangeEvent& _rEvent )
86 : : {
87 [ # # ][ # # ]: 0 : if ( !impl_lateInit() )
88 : : return;
89 : :
90 [ # # ][ # # ]: 0 : if ( ( _rEvent.Source == m_xReportDefinition ) && m_xReportDefinition.is() )
[ # # ][ # # ]
91 : : {
92 [ # # ]: 0 : impl_onDefinitionPropertyChange( _rEvent.PropertyName );
93 : : return;
94 : : }
95 : :
96 [ # # ]: 0 : Reference< XFormattedField > xFormatted( _rEvent.Source, UNO_QUERY );
97 [ # # ]: 0 : if ( xFormatted.is() )
98 [ # # ]: 0 : impl_onFormattedProperttyChange( xFormatted, _rEvent.PropertyName );
99 : : }
100 : :
101 : : //--------------------------------------------------------------------
102 : 0 : void FormatNormalizer::notifyElementInserted( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxElement )
103 : : {
104 [ # # ][ # # ]: 0 : if ( !impl_lateInit() )
105 : : return;
106 : :
107 [ # # ]: 0 : Reference< XFormattedField > xFormatted( _rxElement, UNO_QUERY );
108 [ # # ]: 0 : if ( !xFormatted.is() )
109 : : return;
110 : :
111 [ # # ][ # # ]: 0 : impl_adjustFormatToDataFieldType_nothrow( xFormatted );
112 : : }
113 : :
114 : : //--------------------------------------------------------------------
115 : 0 : bool FormatNormalizer::impl_lateInit()
116 : : {
117 [ # # ]: 0 : if ( m_xReportDefinition.is() )
118 : 0 : return true;
119 : :
120 [ # # ]: 0 : m_xReportDefinition = m_rModel.getReportDefinition();
121 : 0 : return m_xReportDefinition.is();
122 : : }
123 : :
124 : : //--------------------------------------------------------------------
125 : 0 : void FormatNormalizer::impl_onDefinitionPropertyChange( const ::rtl::OUString& _rChangedPropName )
126 : : {
127 [ # # ][ # # ]: 0 : if ( _rChangedPropName != "Command" && _rChangedPropName != "CommandType" && _rChangedPropName != "EscapeProcessing" )
[ # # ][ # # ]
128 : : // nothing we're interested in
129 : 0 : return;
130 : 0 : m_bFieldListDirty = true;
131 : : }
132 : :
133 : : //--------------------------------------------------------------------
134 : 0 : void FormatNormalizer::impl_onFormattedProperttyChange( const Reference< XFormattedField >& _rxFormatted, const ::rtl::OUString& _rChangedPropName )
135 : : {
136 [ # # ]: 0 : if ( _rChangedPropName != "DataField" )
137 : : // nothing we're interested in
138 : 0 : return;
139 : :
140 : 0 : impl_adjustFormatToDataFieldType_nothrow( _rxFormatted );
141 : : }
142 : :
143 : : //--------------------------------------------------------------------
144 : : namespace
145 : : {
146 : 0 : void lcl_collectFields_throw( const Reference< XIndexAccess >& _rxColumns, FormatNormalizer::FieldList& _inout_rFields )
147 : : {
148 : : try
149 : : {
150 [ # # ][ # # ]: 0 : sal_Int32 nCount( _rxColumns->getCount() );
151 [ # # ]: 0 : _inout_rFields.reserve( _inout_rFields.size() + (size_t)nCount );
152 : :
153 : 0 : Reference< XPropertySet > xColumn;
154 : 0 : FormatNormalizer::Field aField;
155 : :
156 [ # # ]: 0 : for ( sal_Int32 i=0; i<nCount; ++i )
157 : : {
158 [ # # ][ # # ]: 0 : xColumn.set( _rxColumns->getByIndex( i ), UNO_QUERY_THROW );
[ # # ]
159 [ # # ][ # # ]: 0 : OSL_VERIFY( xColumn->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Name" ) ) ) >>= aField.sName );
[ # # ]
160 [ # # ][ # # ]: 0 : OSL_VERIFY( xColumn->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ) ) >>= aField.nDataType );
[ # # ]
161 [ # # ][ # # ]: 0 : OSL_VERIFY( xColumn->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Scale" ) ) ) >>= aField.nScale );
[ # # ]
162 [ # # ][ # # ]: 0 : OSL_VERIFY( xColumn->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsCurrency" ) ) ) >>= aField.bIsCurrency );
[ # # ]
163 [ # # ]: 0 : _inout_rFields.push_back( aField );
164 [ # # ]: 0 : }
165 : : }
166 : 0 : catch( const Exception& )
167 : : {
168 : : DBG_UNHANDLED_EXCEPTION();
169 : : }
170 : 0 : }
171 : : }
172 : :
173 : : //--------------------------------------------------------------------
174 : 0 : bool FormatNormalizer::impl_ensureUpToDateFieldList_nothrow()
175 : : {
176 [ # # ]: 0 : if ( !m_bFieldListDirty )
177 : 0 : return true;
178 : 0 : m_aFields.resize( 0 );
179 : :
180 : : OSL_PRECOND( m_xReportDefinition.is(), "FormatNormalizer::impl_ensureUpToDateFieldList_nothrow: no report definition!" );
181 [ # # ]: 0 : if ( !m_xReportDefinition.is() )
182 : 0 : return false;
183 : :
184 : 0 : ::dbaui::DBSubComponentController* pController( m_rModel.getController() );
185 : : OSL_ENSURE( pController, "FormatNormalizer::impl_ensureUpToDateFieldList_nothrow: no controller? how can *this* happen?!" );
186 [ # # ]: 0 : if ( !pController )
187 : 0 : return false;
188 : :
189 : : try
190 : : {
191 [ # # ][ # # ]: 0 : ::dbtools::StatementComposer aComposer( pController->getConnection(), m_xReportDefinition->getCommand(),
192 [ # # ][ # # ]: 0 : m_xReportDefinition->getCommandType(), m_xReportDefinition->getEscapeProcessing() );
[ # # ][ # # ]
[ # # ][ # # ]
193 : :
194 [ # # ]: 0 : Reference< XSingleSelectQueryComposer > xComposer( aComposer.getComposer() );
195 [ # # ]: 0 : if ( !xComposer.is() )
196 : 0 : return false;
197 : :
198 : :
199 [ # # ]: 0 : Reference< XColumnsSupplier > xSuppCols( xComposer, UNO_QUERY_THROW );
200 [ # # ][ # # ]: 0 : Reference< XIndexAccess > xColumns( xSuppCols->getColumns(), UNO_QUERY_THROW );
[ # # ]
201 [ # # ]: 0 : lcl_collectFields_throw( xColumns, m_aFields );
202 : :
203 [ # # ]: 0 : Reference< XParametersSupplier > xSuppParams( xComposer, UNO_QUERY_THROW );
204 [ # # ][ # # ]: 0 : Reference< XIndexAccess > xParams( xSuppParams->getParameters(), UNO_QUERY_THROW );
[ # # ]
205 [ # # ][ # # ]: 0 : lcl_collectFields_throw( xParams, m_aFields );
[ # # ]
[ # # # ]
[ # # ]
206 : : }
207 : 0 : catch( const SQLException& )
208 : : {
209 : : // silence it. This might happen for instance when the user sets an non-existent table,
210 : : // or things like this
211 : : }
212 : 0 : catch( const Exception& )
213 : : {
214 : : DBG_UNHANDLED_EXCEPTION();
215 : : }
216 : :
217 : 0 : m_bFieldListDirty = false;
218 : 0 : return true;
219 : : }
220 : :
221 : : //--------------------------------------------------------------------
222 : 0 : void FormatNormalizer::impl_adjustFormatToDataFieldType_nothrow( const Reference< XFormattedField >& _rxFormatted )
223 : : {
224 [ # # ]: 0 : if ( !impl_ensureUpToDateFieldList_nothrow() )
225 : : // unable to obtain a recent field list
226 : 0 : return;
227 : :
228 : : try
229 : : {
230 [ # # ][ # # ]: 0 : sal_Int32 nFormatKey = _rxFormatted->getFormatKey();
231 [ # # ]: 0 : if ( nFormatKey != 0 )
232 : : // it's not the "standard numeric" format -> not interested in
233 : : return;
234 : :
235 [ # # ][ # # ]: 0 : ::rtl::OUString sDataField( _rxFormatted->getDataField() );
236 [ # # ]: 0 : const ::rtl::OUString sFieldPrefix( RTL_CONSTASCII_USTRINGPARAM( "field:[" ) );
237 [ # # ]: 0 : if ( sDataField.indexOf( sFieldPrefix ) != 0 )
238 : : // not bound to a table field
239 : : // TODO: we might also do this kind of thing for functions and expressions ...
240 : : return;
241 [ # # ]: 0 : if ( sDataField.getStr()[ sDataField.getLength() - 1 ] != ']' )
242 : : {
243 : : // last character is not the closing brace
244 : : OSL_FAIL( "FormatNormalizer::impl_adjustFormatToDataFieldType_nothrow: suspicious data field value!" );
245 : : return;
246 : : }
247 : 0 : sDataField = sDataField.copy( sFieldPrefix.getLength(), sDataField.getLength() - sFieldPrefix.getLength() - 1 );
248 : :
249 [ # # ]: 0 : FieldList::const_iterator field = m_aFields.begin();
250 [ # # ][ # # ]: 0 : for ( ; field != m_aFields.end(); ++field )
251 : : {
252 [ # # ]: 0 : if ( field->sName == sDataField )
253 : 0 : break;
254 : : }
255 [ # # ][ # # ]: 0 : if ( field == m_aFields.end() )
256 : : // unknown field
257 : : return;
258 : :
259 [ # # ][ # # ]: 0 : Reference< XNumberFormatsSupplier > xSuppNumFmts( _rxFormatted->getFormatsSupplier(), UNO_QUERY_THROW );
[ # # ]
260 [ # # ][ # # ]: 0 : Reference< XNumberFormatTypes > xNumFmtTypes( xSuppNumFmts->getNumberFormats(), UNO_QUERY_THROW );
[ # # ]
261 : :
262 : 0 : nFormatKey = ::dbtools::getDefaultNumberFormat( field->nDataType, field->nScale, field->bIsCurrency, xNumFmtTypes,
263 [ # # ]: 0 : SvtSysLocale().GetLocaleData().getLocale() );
[ # # # # ]
[ # # ][ # # ]
264 [ # # ][ # # ]: 0 : _rxFormatted->setFormatKey( nFormatKey );
[ # # ][ # # ]
[ # # ]
265 : : }
266 : 0 : catch( const Exception& )
267 : : {
268 : : DBG_UNHANDLED_EXCEPTION();
269 : : }
270 : : }
271 : :
272 : : //........................................................................
273 : : } // namespace rptui
274 : : //........................................................................
275 : :
276 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|