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: FormattedFieldWrapper.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 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_forms.hxx"
33 #include "FormattedFieldWrapper.hxx"
35 #include "FormattedField.hxx"
36 #include <tools/debug.hxx>
37 #include "EditBase.hxx"
38 #include "services.hxx"
39 #include <connectivity/dbtools.hxx>
40 #include <vcl/svapp.hxx>
42 //.........................................................................
45 using namespace ::com::sun::star::uno
;
46 using namespace ::com::sun::star::sdb
;
47 using namespace ::com::sun::star::sdbc
;
48 using namespace ::com::sun::star::sdbcx
;
49 using namespace ::com::sun::star::beans
;
50 using namespace ::com::sun::star::container
;
51 using namespace ::com::sun::star::form
;
52 using namespace ::com::sun::star::awt
;
53 using namespace ::com::sun::star::io
;
54 using namespace ::com::sun::star::lang
;
55 using namespace ::com::sun::star::util
;
57 //==================================================================
58 // OFormattedFieldWrapper
59 //==================================================================
60 DBG_NAME(OFormattedFieldWrapper
)
61 //------------------------------------------------------------------
62 InterfaceRef SAL_CALL
OFormattedFieldWrapper_CreateInstance_ForceFormatted(const Reference
<XMultiServiceFactory
>& _rxFactory
)
64 return *(new OFormattedFieldWrapper(_rxFactory
, sal_True
));
67 //------------------------------------------------------------------
68 InterfaceRef SAL_CALL
OFormattedFieldWrapper_CreateInstance(const Reference
<XMultiServiceFactory
>& _rxFactory
)
70 return *(new OFormattedFieldWrapper(_rxFactory
, sal_False
));
73 //------------------------------------------------------------------
74 OFormattedFieldWrapper::OFormattedFieldWrapper(const Reference
<XMultiServiceFactory
>& _rxFactory
, sal_Bool _bActAsFormatted
)
75 :m_xServiceFactory(_rxFactory
)
78 DBG_CTOR(OFormattedFieldWrapper
, NULL
);
82 increment(m_refCount
);
84 // instantiate an FormattedModel
85 InterfaceRef xFormattedModel
;
86 // (instantiate it directly ..., as the OFormattedModel isn't registered for any service names anymore)
87 OFormattedModel
* pModel
= new OFormattedModel(m_xServiceFactory
);
88 query_interface(static_cast<XWeak
*>(pModel
), xFormattedModel
);
90 m_xAggregate
= Reference
<XAggregation
> (xFormattedModel
, UNO_QUERY
);
91 DBG_ASSERT(m_xAggregate
.is(), "OFormattedFieldWrapper::OFormattedFieldWrapper : the OFormattedModel didn't have an XAggregation interface !");
93 // _before_ setting the delegator, give it to the member references
94 query_interface(xFormattedModel
, m_xFormattedPart
);
95 m_pEditPart
= new OEditModel(m_xServiceFactory
);
96 m_pEditPart
->acquire();
98 if (m_xAggregate
.is())
99 { // has to be in it's own block because of the temporary variable created by *this
100 m_xAggregate
->setDelegator(static_cast<XWeak
*>(this));
102 decrement(m_refCount
);
106 //------------------------------------------------------------------
107 OFormattedFieldWrapper::OFormattedFieldWrapper( const OFormattedFieldWrapper
* _pCloneSource
)
108 :m_xServiceFactory( _pCloneSource
->m_xServiceFactory
)
111 Reference
< XCloneable
> xCloneAccess
;
112 query_aggregation( _pCloneSource
->m_xAggregate
, xCloneAccess
);
114 // clone the aggregate
115 if ( xCloneAccess
.is() )
117 increment( m_refCount
);
119 Reference
< XCloneable
> xClone
= xCloneAccess
->createClone();
120 m_xAggregate
= Reference
< XAggregation
>( xClone
, UNO_QUERY
);
121 DBG_ASSERT(m_xAggregate
.is(), "OFormattedFieldWrapper::OFormattedFieldWrapper : invalid aggregate clone!");
123 query_interface( Reference
< XInterface
>( xClone
.get() ), m_xFormattedPart
);
125 if ( _pCloneSource
->m_pEditPart
)
127 m_pEditPart
= new OEditModel( _pCloneSource
->m_pEditPart
, _pCloneSource
->m_xServiceFactory
);
128 m_pEditPart
->acquire();
131 if ( m_xAggregate
.is() )
132 { // has to be in it's own block because of the temporary variable created by *this
133 m_xAggregate
->setDelegator( static_cast< XWeak
* >( this ) );
135 decrement( m_refCount
);
138 { // the clone source does not yet have an aggregate -> we don't yet need one, too
142 //------------------------------------------------------------------
143 OFormattedFieldWrapper::~OFormattedFieldWrapper()
145 // release the aggregated object (if any)
146 if (m_xAggregate
.is())
147 m_xAggregate
->setDelegator(InterfaceRef ());
150 m_pEditPart
->release();
152 DBG_DTOR(OFormattedFieldWrapper
, NULL
);
155 //------------------------------------------------------------------
156 Any SAL_CALL
OFormattedFieldWrapper::queryAggregation(const Type
& _rType
) throw (RuntimeException
)
160 if (_rType
.equals( ::getCppuType( static_cast< Reference
< XTypeProvider
>* >(NULL
) ) ) )
161 { // a XTypeProvider interface needs a working aggregate - we don't want to give the type provider
162 // of our base class (OFormattedFieldWrapper_Base) to the caller as it supplies nearly nothing
164 if (m_xAggregate
.is())
165 aReturn
= m_xAggregate
->queryAggregation(_rType
);
168 if (!aReturn
.hasValue())
170 aReturn
= OFormattedFieldWrapper_Base::queryAggregation(_rType
);
172 if ((_rType
.equals( ::getCppuType( static_cast< Reference
< XServiceInfo
>* >(NULL
) ) ) ) && aReturn
.hasValue())
173 { // somebody requested an XServiceInfo interface and our base class provided it
174 // check our aggregate if it has one, too
178 if (!aReturn
.hasValue())
180 aReturn
= ::cppu::queryInterface( _rType
,
181 static_cast< XPersistObject
* >( this ),
182 static_cast< XCloneable
* >( this )
185 if (!aReturn
.hasValue())
187 // somebody requests an interface other than the basics (XInterface) and other than
188 // the two we can supply without an aggregate. So ensure
189 // the aggregate exists.
191 if (m_xAggregate
.is())
192 aReturn
= m_xAggregate
->queryAggregation(_rType
);
200 //------------------------------------------------------------------
201 ::rtl::OUString SAL_CALL
OFormattedFieldWrapper::getServiceName() throw(RuntimeException
)
203 // return the old compatibility name for an EditModel
204 return FRM_COMPONENT_EDIT
;
207 //------------------------------------------------------------------
208 ::rtl::OUString SAL_CALL
OFormattedFieldWrapper::getImplementationName( ) throw (RuntimeException
)
210 return ::rtl::OUString::createFromAscii("com.sun.star.comp.forms.OFormattedFieldWrapper");
213 //------------------------------------------------------------------
214 sal_Bool SAL_CALL
OFormattedFieldWrapper::supportsService( const ::rtl::OUString
& _rServiceName
) throw (RuntimeException
)
216 DBG_ASSERT(m_xAggregate
.is(), "OFormattedFieldWrapper::supportsService: should never have made it 'til here without an aggregate!");
217 Reference
< XServiceInfo
> xSI
;
218 m_xAggregate
->queryAggregation(::getCppuType(static_cast< Reference
< XServiceInfo
>* >(NULL
))) >>= xSI
;
219 return xSI
->supportsService(_rServiceName
);
222 //------------------------------------------------------------------
223 Sequence
< ::rtl::OUString
> SAL_CALL
OFormattedFieldWrapper::getSupportedServiceNames( ) throw (RuntimeException
)
225 DBG_ASSERT(m_xAggregate
.is(), "OFormattedFieldWrapper::getSupportedServiceNames: should never have made it 'til here without an aggregate!");
226 Reference
< XServiceInfo
> xSI
;
227 m_xAggregate
->queryAggregation(::getCppuType(static_cast< Reference
< XServiceInfo
>* >(NULL
))) >>= xSI
;
228 return xSI
->getSupportedServiceNames();
231 //------------------------------------------------------------------
232 void SAL_CALL
OFormattedFieldWrapper::write(const Reference
<XObjectOutputStream
>& _rxOutStream
) throw( IOException
, RuntimeException
)
234 // can't write myself
237 // if we act as real edit field, we can simple forward this write request
238 if (!m_xFormattedPart
.is())
240 Reference
<XPersistObject
> xAggregatePersistence
;
241 query_aggregation(m_xAggregate
, xAggregatePersistence
);
242 DBG_ASSERT(xAggregatePersistence
.is(), "OFormattedFieldWrapper::write : don't know how to handle this : can't write !");
243 // oops ... We gave an XPersistObject interface to the caller but now we aren't an XPersistObject ...
244 if (xAggregatePersistence
.is())
245 xAggregatePersistence
->write(_rxOutStream
);
249 // else we have to write an edit part first
250 DBG_ASSERT(m_pEditPart
, "OFormattedFieldWrapper::write : formatted part without edit part ?");
252 throw RuntimeException( ::rtl::OUString(), *this );
254 // for this we transfer the current props of the formatted part to the edit part
255 Reference
<XPropertySet
> xFormatProps(m_xFormattedPart
, UNO_QUERY
);
256 Reference
<XPropertySet
> xEditProps
;
257 query_interface(static_cast<XWeak
*>(m_pEditPart
), xEditProps
);
259 Locale aAppLanguage
= Application::GetSettings().GetUILocale();
260 dbtools::TransferFormComponentProperties(xFormatProps
, xEditProps
, aAppLanguage
);
262 // then write the edit part, after switching to "fake mode"
263 m_pEditPart
->enableFormattedWriteFake();
264 m_pEditPart
->write(_rxOutStream
);
265 m_pEditPart
->disableFormattedWriteFake();
267 // and finally write the formatted part we're really interested in
268 m_xFormattedPart
->write(_rxOutStream
);
271 //------------------------------------------------------------------
272 void SAL_CALL
OFormattedFieldWrapper::read(const Reference
<XObjectInputStream
>& _rxInStream
) throw( IOException
, RuntimeException
)
274 if (m_xAggregate
.is())
275 { // we alread did a decision if we're an EditModel or a FormattedModel
277 // if we act as formatted, we have to read the edit part first
278 if (m_xFormattedPart
.is())
280 // two possible cases:
281 // a) the stuff was written by a version which didn't work with an Edit header (all intermediate
282 // versions >5.1 && <=568)
283 // b) it was written by a version using edit headers
284 // as we can distinguish a) from b) only after we have read the edit part, we need to remember the
286 Reference
<XMarkableStream
> xInMarkable(_rxInStream
, UNO_QUERY
);
287 DBG_ASSERT(xInMarkable
.is(), "OFormattedFieldWrapper::read : can only work with markable streams !");
288 sal_Int32 nBeforeEditPart
= xInMarkable
->createMark();
290 m_pEditPart
->read(_rxInStream
);
291 // this only works because an edit model can read the stuff written by a formatted model (maybe with
292 // some assertions) , but not vice versa
293 if (!m_pEditPart
->lastReadWasFormattedFake())
294 { // case a), written with a version without the edit part fake, so seek to the start position, again
295 xInMarkable
->jumpToMark(nBeforeEditPart
);
297 xInMarkable
->deleteMark(nBeforeEditPart
);
300 Reference
<XPersistObject
> xAggregatePersistence
;
301 query_aggregation(m_xAggregate
, xAggregatePersistence
);
302 DBG_ASSERT(xAggregatePersistence
.is(), "OFormattedFieldWrapper::read : don't know how to handle this : can't read !");
303 // oops ... We gave an XPersistObject interface to the caller but now we aren't an XPersistObject ...
305 if (xAggregatePersistence
.is())
306 xAggregatePersistence
->read(_rxInStream
);
310 // we have to decide from the data within the stream whether we should be an EditModel or a FormattedModel
311 OEditBaseModel
* pNewAggregate
= NULL
;
313 // let an OEditModel do the reading
314 OEditModel
* pBasicReader
= new OEditModel(m_xServiceFactory
);
315 Reference
< XInterface
> xHoldBasicReaderAlive( *pBasicReader
);
316 pBasicReader
->read(_rxInStream
);
318 // was it really an edit model ?
319 if (!pBasicReader
->lastReadWasFormattedFake())
321 pNewAggregate
= pBasicReader
;
323 { // no -> substitute it with a formatted model
325 // let the formmatted model do the reading
326 OFormattedModel
* pFormattedReader
= new OFormattedModel(m_xServiceFactory
);
327 Reference
< XInterface
> xHoldAliveWhileRead( *pFormattedReader
);
328 pFormattedReader
->read(_rxInStream
);
330 // for the next write (if any) : the FormattedModel and the EditModel parts
331 query_interface(static_cast<XWeak
*>(pFormattedReader
), m_xFormattedPart
);
332 m_pEditPart
= pBasicReader
;
333 m_pEditPart
->acquire();
335 // aggregate the formatted part below
336 pNewAggregate
= pFormattedReader
;
339 // do the aggregation
340 increment(m_refCount
);
342 query_interface(static_cast<XWeak
*>(pNewAggregate
), m_xAggregate
);
343 DBG_ASSERT(m_xAggregate
.is(), "OFormattedFieldWrapper::read : the OEditModel didn't have an XAggregation interface !");
345 if (m_xAggregate
.is())
346 { // has to be in it's own block because of the temporary variable created by *this
347 m_xAggregate
->setDelegator(static_cast<XWeak
*>(this));
349 decrement(m_refCount
);
352 //------------------------------------------------------------------
353 Reference
< XCloneable
> SAL_CALL
OFormattedFieldWrapper::createClone( ) throw (RuntimeException
)
357 return new OFormattedFieldWrapper( this );
360 //------------------------------------------------------------------
361 void OFormattedFieldWrapper::ensureAggregate()
363 if (m_xAggregate
.is())
366 increment(m_refCount
);
368 // instantiate an EditModel (the only place where we are allowed to decide that we're an FormattedModel
370 InterfaceRef xEditModel
= m_xServiceFactory
->createInstance(FRM_SUN_COMPONENT_TEXTFIELD
);
371 if (!xEditModel
.is())
373 // arghhh ... instantiate it directly ... it's dirty, but we really need this aggregate
374 OEditModel
* pModel
= new OEditModel(m_xServiceFactory
);
375 query_interface(static_cast<XWeak
*>(pModel
), xEditModel
);
378 m_xAggregate
= Reference
<XAggregation
> (xEditModel
, UNO_QUERY
);
379 DBG_ASSERT(m_xAggregate
.is(), "OFormattedFieldWrapper::ensureAggregate : the OEditModel didn't have an XAggregation interface !");
382 Reference
< XServiceInfo
> xSI(m_xAggregate
, UNO_QUERY
);
385 DBG_ERROR("OFormattedFieldWrapper::ensureAggregate: the aggregate has no XServiceInfo!");
386 m_xAggregate
.clear();
390 if (m_xAggregate
.is())
391 { // has to be in it's own block because of the temporary variable created by *this
392 m_xAggregate
->setDelegator(static_cast<XWeak
*>(this));
394 decrement(m_refCount
);
397 //.........................................................................
399 //.........................................................................