1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_forms.hxx"
26*b1cdbd2cSJim Jagielski #include "FormattedFieldWrapper.hxx"
27*b1cdbd2cSJim Jagielski #include "Edit.hxx"
28*b1cdbd2cSJim Jagielski #include "FormattedField.hxx"
29*b1cdbd2cSJim Jagielski #include <tools/debug.hxx>
30*b1cdbd2cSJim Jagielski #include "EditBase.hxx"
31*b1cdbd2cSJim Jagielski #include "services.hxx"
32*b1cdbd2cSJim Jagielski #include <connectivity/dbtools.hxx>
33*b1cdbd2cSJim Jagielski #include <vcl/svapp.hxx>
34*b1cdbd2cSJim Jagielski 
35*b1cdbd2cSJim Jagielski //.........................................................................
36*b1cdbd2cSJim Jagielski namespace frm
37*b1cdbd2cSJim Jagielski {
38*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::uno;
39*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::sdb;
40*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::sdbc;
41*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::sdbcx;
42*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::beans;
43*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::container;
44*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::form;
45*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::awt;
46*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::io;
47*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::lang;
48*b1cdbd2cSJim Jagielski using namespace ::com::sun::star::util;
49*b1cdbd2cSJim Jagielski 
50*b1cdbd2cSJim Jagielski //==================================================================
51*b1cdbd2cSJim Jagielski // OFormattedFieldWrapper
52*b1cdbd2cSJim Jagielski //==================================================================
DBG_NAME(OFormattedFieldWrapper)53*b1cdbd2cSJim Jagielski DBG_NAME(OFormattedFieldWrapper)
54*b1cdbd2cSJim Jagielski //------------------------------------------------------------------
55*b1cdbd2cSJim Jagielski InterfaceRef SAL_CALL OFormattedFieldWrapper_CreateInstance_ForceFormatted(const Reference<XMultiServiceFactory>& _rxFactory)
56*b1cdbd2cSJim Jagielski {
57*b1cdbd2cSJim Jagielski 	return *(new OFormattedFieldWrapper(_rxFactory, sal_True));
58*b1cdbd2cSJim Jagielski }
59*b1cdbd2cSJim Jagielski 
60*b1cdbd2cSJim Jagielski //------------------------------------------------------------------
OFormattedFieldWrapper_CreateInstance(const Reference<XMultiServiceFactory> & _rxFactory)61*b1cdbd2cSJim Jagielski InterfaceRef SAL_CALL OFormattedFieldWrapper_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
62*b1cdbd2cSJim Jagielski {
63*b1cdbd2cSJim Jagielski 	return *(new OFormattedFieldWrapper(_rxFactory, sal_False));
64*b1cdbd2cSJim Jagielski }
65*b1cdbd2cSJim Jagielski 
66*b1cdbd2cSJim Jagielski //------------------------------------------------------------------
OFormattedFieldWrapper(const Reference<XMultiServiceFactory> & _rxFactory,sal_Bool _bActAsFormatted)67*b1cdbd2cSJim Jagielski OFormattedFieldWrapper::OFormattedFieldWrapper(const Reference<XMultiServiceFactory>& _rxFactory, sal_Bool _bActAsFormatted)
68*b1cdbd2cSJim Jagielski     :m_xServiceFactory(_rxFactory)
69*b1cdbd2cSJim Jagielski 	,m_pEditPart(NULL)
70*b1cdbd2cSJim Jagielski {
71*b1cdbd2cSJim Jagielski 	DBG_CTOR(OFormattedFieldWrapper, NULL);
72*b1cdbd2cSJim Jagielski 
73*b1cdbd2cSJim Jagielski 	if (_bActAsFormatted)
74*b1cdbd2cSJim Jagielski 	{
75*b1cdbd2cSJim Jagielski 		increment(m_refCount);
76*b1cdbd2cSJim Jagielski 		{
77*b1cdbd2cSJim Jagielski 			// instantiate an FormattedModel
78*b1cdbd2cSJim Jagielski 			InterfaceRef  xFormattedModel;
79*b1cdbd2cSJim Jagielski 			// (instantiate it directly ..., as the OFormattedModel isn't registered for any service names anymore)
80*b1cdbd2cSJim Jagielski 			OFormattedModel* pModel = new OFormattedModel(m_xServiceFactory);
81*b1cdbd2cSJim Jagielski 			query_interface(static_cast<XWeak*>(pModel), xFormattedModel);
82*b1cdbd2cSJim Jagielski 
83*b1cdbd2cSJim Jagielski 			m_xAggregate = Reference<XAggregation> (xFormattedModel, UNO_QUERY);
84*b1cdbd2cSJim Jagielski 			DBG_ASSERT(m_xAggregate.is(), "OFormattedFieldWrapper::OFormattedFieldWrapper : the OFormattedModel didn't have an XAggregation interface !");
85*b1cdbd2cSJim Jagielski 
86*b1cdbd2cSJim Jagielski 			// _before_ setting the delegator, give it to the member references
87*b1cdbd2cSJim Jagielski 			query_interface(xFormattedModel, m_xFormattedPart);
88*b1cdbd2cSJim Jagielski 			m_pEditPart = new OEditModel(m_xServiceFactory);
89*b1cdbd2cSJim Jagielski 			m_pEditPart->acquire();
90*b1cdbd2cSJim Jagielski 		}
91*b1cdbd2cSJim Jagielski 		if (m_xAggregate.is())
92*b1cdbd2cSJim Jagielski 		{	// has to be in it's own block because of the temporary variable created by *this
93*b1cdbd2cSJim Jagielski 			m_xAggregate->setDelegator(static_cast<XWeak*>(this));
94*b1cdbd2cSJim Jagielski 		}
95*b1cdbd2cSJim Jagielski 		decrement(m_refCount);
96*b1cdbd2cSJim Jagielski 	}
97*b1cdbd2cSJim Jagielski }
98*b1cdbd2cSJim Jagielski 
99*b1cdbd2cSJim Jagielski //------------------------------------------------------------------
OFormattedFieldWrapper(const OFormattedFieldWrapper * _pCloneSource)100*b1cdbd2cSJim Jagielski OFormattedFieldWrapper::OFormattedFieldWrapper( const OFormattedFieldWrapper* _pCloneSource )
101*b1cdbd2cSJim Jagielski 	:m_xServiceFactory( _pCloneSource->m_xServiceFactory )
102*b1cdbd2cSJim Jagielski 	,m_pEditPart( NULL )
103*b1cdbd2cSJim Jagielski {
104*b1cdbd2cSJim Jagielski 	Reference< XCloneable > xCloneAccess;
105*b1cdbd2cSJim Jagielski 	query_aggregation( _pCloneSource->m_xAggregate, xCloneAccess );
106*b1cdbd2cSJim Jagielski 
107*b1cdbd2cSJim Jagielski 	// clone the aggregate
108*b1cdbd2cSJim Jagielski 	if ( xCloneAccess.is() )
109*b1cdbd2cSJim Jagielski 	{
110*b1cdbd2cSJim Jagielski 		increment( m_refCount );
111*b1cdbd2cSJim Jagielski 		{
112*b1cdbd2cSJim Jagielski 			Reference< XCloneable > xClone = xCloneAccess->createClone();
113*b1cdbd2cSJim Jagielski 			m_xAggregate = Reference< XAggregation >( xClone, UNO_QUERY );
114*b1cdbd2cSJim Jagielski 			DBG_ASSERT(m_xAggregate.is(), "OFormattedFieldWrapper::OFormattedFieldWrapper : invalid aggregate clone!");
115*b1cdbd2cSJim Jagielski 
116*b1cdbd2cSJim Jagielski 			query_interface( Reference< XInterface >( xClone.get() ), m_xFormattedPart );
117*b1cdbd2cSJim Jagielski 
118*b1cdbd2cSJim Jagielski 			if ( _pCloneSource->m_pEditPart )
119*b1cdbd2cSJim Jagielski             {
120*b1cdbd2cSJim Jagielski 				m_pEditPart = new OEditModel( _pCloneSource->m_pEditPart, _pCloneSource->m_xServiceFactory );
121*b1cdbd2cSJim Jagielski                 m_pEditPart->acquire();
122*b1cdbd2cSJim Jagielski             }
123*b1cdbd2cSJim Jagielski 		}
124*b1cdbd2cSJim Jagielski 		if ( m_xAggregate.is() )
125*b1cdbd2cSJim Jagielski 		{	// has to be in it's own block because of the temporary variable created by *this
126*b1cdbd2cSJim Jagielski 			m_xAggregate->setDelegator( static_cast< XWeak* >( this ) );
127*b1cdbd2cSJim Jagielski 		}
128*b1cdbd2cSJim Jagielski 		decrement( m_refCount );
129*b1cdbd2cSJim Jagielski 	}
130*b1cdbd2cSJim Jagielski 	else
131*b1cdbd2cSJim Jagielski 	{	// the clone source does not yet have an aggregate -> we don't yet need one, too
132*b1cdbd2cSJim Jagielski 	}
133*b1cdbd2cSJim Jagielski }
134*b1cdbd2cSJim Jagielski 
135*b1cdbd2cSJim Jagielski //------------------------------------------------------------------
~OFormattedFieldWrapper()136*b1cdbd2cSJim Jagielski OFormattedFieldWrapper::~OFormattedFieldWrapper()
137*b1cdbd2cSJim Jagielski {
138*b1cdbd2cSJim Jagielski 	// release the aggregated object (if any)
139*b1cdbd2cSJim Jagielski 	if (m_xAggregate.is())
140*b1cdbd2cSJim Jagielski 		m_xAggregate->setDelegator(InterfaceRef ());
141*b1cdbd2cSJim Jagielski 
142*b1cdbd2cSJim Jagielski 	if (m_pEditPart)
143*b1cdbd2cSJim Jagielski 		m_pEditPart->release();
144*b1cdbd2cSJim Jagielski 
145*b1cdbd2cSJim Jagielski 	DBG_DTOR(OFormattedFieldWrapper, NULL);
146*b1cdbd2cSJim Jagielski }
147*b1cdbd2cSJim Jagielski 
148*b1cdbd2cSJim Jagielski //------------------------------------------------------------------
queryAggregation(const Type & _rType)149*b1cdbd2cSJim Jagielski Any SAL_CALL OFormattedFieldWrapper::queryAggregation(const Type& _rType) throw (RuntimeException)
150*b1cdbd2cSJim Jagielski {
151*b1cdbd2cSJim Jagielski 	Any aReturn;
152*b1cdbd2cSJim Jagielski 
153*b1cdbd2cSJim Jagielski 	if (_rType.equals( ::getCppuType( static_cast< Reference< XTypeProvider >* >(NULL) ) ) )
154*b1cdbd2cSJim Jagielski 	{	// a XTypeProvider interface needs a working aggregate - we don't want to give the type provider
155*b1cdbd2cSJim Jagielski 		// of our base class (OFormattedFieldWrapper_Base) to the caller as it supplies nearly nothing
156*b1cdbd2cSJim Jagielski 		ensureAggregate();
157*b1cdbd2cSJim Jagielski 		if (m_xAggregate.is())
158*b1cdbd2cSJim Jagielski 			aReturn = m_xAggregate->queryAggregation(_rType);
159*b1cdbd2cSJim Jagielski 	}
160*b1cdbd2cSJim Jagielski 
161*b1cdbd2cSJim Jagielski 	if (!aReturn.hasValue())
162*b1cdbd2cSJim Jagielski 	{
163*b1cdbd2cSJim Jagielski 		aReturn = OFormattedFieldWrapper_Base::queryAggregation(_rType);
164*b1cdbd2cSJim Jagielski 
165*b1cdbd2cSJim Jagielski 		if ((_rType.equals( ::getCppuType( static_cast< Reference< XServiceInfo >* >(NULL) ) ) ) && aReturn.hasValue())
166*b1cdbd2cSJim Jagielski 		{	// somebody requested an XServiceInfo interface and our base class provided it
167*b1cdbd2cSJim Jagielski 			// check our aggregate if it has one, too
168*b1cdbd2cSJim Jagielski 			ensureAggregate();
169*b1cdbd2cSJim Jagielski 		}
170*b1cdbd2cSJim Jagielski 
171*b1cdbd2cSJim Jagielski 		if (!aReturn.hasValue())
172*b1cdbd2cSJim Jagielski 		{
173*b1cdbd2cSJim Jagielski 			aReturn = ::cppu::queryInterface( _rType,
174*b1cdbd2cSJim Jagielski 				static_cast< XPersistObject* >( this ),
175*b1cdbd2cSJim Jagielski 				static_cast< XCloneable* >( this )
176*b1cdbd2cSJim Jagielski 			);
177*b1cdbd2cSJim Jagielski 
178*b1cdbd2cSJim Jagielski 			if (!aReturn.hasValue())
179*b1cdbd2cSJim Jagielski 			{
180*b1cdbd2cSJim Jagielski 				// somebody requests an interface other than the basics (XInterface) and other than
181*b1cdbd2cSJim Jagielski 				// the two we can supply without an aggregate. So ensure
182*b1cdbd2cSJim Jagielski 				// the aggregate exists.
183*b1cdbd2cSJim Jagielski 				ensureAggregate();
184*b1cdbd2cSJim Jagielski 				if (m_xAggregate.is())
185*b1cdbd2cSJim Jagielski 					aReturn = m_xAggregate->queryAggregation(_rType);
186*b1cdbd2cSJim Jagielski 			}
187*b1cdbd2cSJim Jagielski 		}
188*b1cdbd2cSJim Jagielski 	}
189*b1cdbd2cSJim Jagielski 
190*b1cdbd2cSJim Jagielski 	return aReturn;
191*b1cdbd2cSJim Jagielski }
192*b1cdbd2cSJim Jagielski 
193*b1cdbd2cSJim Jagielski //------------------------------------------------------------------
getServiceName()194*b1cdbd2cSJim Jagielski ::rtl::OUString SAL_CALL OFormattedFieldWrapper::getServiceName() throw(RuntimeException)
195*b1cdbd2cSJim Jagielski {
196*b1cdbd2cSJim Jagielski 	// return the old compatibility name for an EditModel
197*b1cdbd2cSJim Jagielski 	return FRM_COMPONENT_EDIT;
198*b1cdbd2cSJim Jagielski }
199*b1cdbd2cSJim Jagielski 
200*b1cdbd2cSJim Jagielski //------------------------------------------------------------------
getImplementationName()201*b1cdbd2cSJim Jagielski ::rtl::OUString SAL_CALL OFormattedFieldWrapper::getImplementationName(  ) throw (RuntimeException)
202*b1cdbd2cSJim Jagielski {
203*b1cdbd2cSJim Jagielski 	return ::rtl::OUString::createFromAscii("com.sun.star.comp.forms.OFormattedFieldWrapper");
204*b1cdbd2cSJim Jagielski }
205*b1cdbd2cSJim Jagielski 
206*b1cdbd2cSJim Jagielski //------------------------------------------------------------------
supportsService(const::rtl::OUString & _rServiceName)207*b1cdbd2cSJim Jagielski sal_Bool SAL_CALL OFormattedFieldWrapper::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
208*b1cdbd2cSJim Jagielski {
209*b1cdbd2cSJim Jagielski 	DBG_ASSERT(m_xAggregate.is(), "OFormattedFieldWrapper::supportsService: should never have made it 'til here without an aggregate!");
210*b1cdbd2cSJim Jagielski 	Reference< XServiceInfo > xSI;
211*b1cdbd2cSJim Jagielski 	m_xAggregate->queryAggregation(::getCppuType(static_cast< Reference< XServiceInfo >* >(NULL))) >>= xSI;
212*b1cdbd2cSJim Jagielski 	return xSI->supportsService(_rServiceName);
213*b1cdbd2cSJim Jagielski }
214*b1cdbd2cSJim Jagielski 
215*b1cdbd2cSJim Jagielski //------------------------------------------------------------------
getSupportedServiceNames()216*b1cdbd2cSJim Jagielski Sequence< ::rtl::OUString > SAL_CALL OFormattedFieldWrapper::getSupportedServiceNames(  ) throw (RuntimeException)
217*b1cdbd2cSJim Jagielski {
218*b1cdbd2cSJim Jagielski 	DBG_ASSERT(m_xAggregate.is(), "OFormattedFieldWrapper::getSupportedServiceNames: should never have made it 'til here without an aggregate!");
219*b1cdbd2cSJim Jagielski 	Reference< XServiceInfo > xSI;
220*b1cdbd2cSJim Jagielski 	m_xAggregate->queryAggregation(::getCppuType(static_cast< Reference< XServiceInfo >* >(NULL))) >>= xSI;
221*b1cdbd2cSJim Jagielski 	return xSI->getSupportedServiceNames();
222*b1cdbd2cSJim Jagielski }
223*b1cdbd2cSJim Jagielski 
224*b1cdbd2cSJim Jagielski //------------------------------------------------------------------
write(const Reference<XObjectOutputStream> & _rxOutStream)225*b1cdbd2cSJim Jagielski void SAL_CALL OFormattedFieldWrapper::write(const Reference<XObjectOutputStream>& _rxOutStream) throw( IOException, RuntimeException )
226*b1cdbd2cSJim Jagielski {
227*b1cdbd2cSJim Jagielski 	// can't write myself
228*b1cdbd2cSJim Jagielski 	ensureAggregate();
229*b1cdbd2cSJim Jagielski 
230*b1cdbd2cSJim Jagielski 	// if we act as real edit field, we can simple forward this write request
231*b1cdbd2cSJim Jagielski 	if (!m_xFormattedPart.is())
232*b1cdbd2cSJim Jagielski 	{
233*b1cdbd2cSJim Jagielski 		Reference<XPersistObject>  xAggregatePersistence;
234*b1cdbd2cSJim Jagielski 		query_aggregation(m_xAggregate, xAggregatePersistence);
235*b1cdbd2cSJim Jagielski 		DBG_ASSERT(xAggregatePersistence.is(), "OFormattedFieldWrapper::write : don't know how to handle this : can't write !");
236*b1cdbd2cSJim Jagielski 			// oops ... We gave an XPersistObject interface to the caller but now we aren't an XPersistObject ...
237*b1cdbd2cSJim Jagielski 		if (xAggregatePersistence.is())
238*b1cdbd2cSJim Jagielski 			xAggregatePersistence->write(_rxOutStream);
239*b1cdbd2cSJim Jagielski 		return;
240*b1cdbd2cSJim Jagielski 	}
241*b1cdbd2cSJim Jagielski 
242*b1cdbd2cSJim Jagielski 	// else we have to write an edit part first
243*b1cdbd2cSJim Jagielski 	DBG_ASSERT(m_pEditPart, "OFormattedFieldWrapper::write : formatted part without edit part ?");
244*b1cdbd2cSJim Jagielski     if ( !m_pEditPart )
245*b1cdbd2cSJim Jagielski         throw RuntimeException( ::rtl::OUString(), *this );
246*b1cdbd2cSJim Jagielski 
247*b1cdbd2cSJim Jagielski 	// for this we transfer the current props of the formatted part to the edit part
248*b1cdbd2cSJim Jagielski 	Reference<XPropertySet>  xFormatProps(m_xFormattedPart, UNO_QUERY);
249*b1cdbd2cSJim Jagielski 	Reference<XPropertySet>  xEditProps;
250*b1cdbd2cSJim Jagielski 	query_interface(static_cast<XWeak*>(m_pEditPart), xEditProps);
251*b1cdbd2cSJim Jagielski 
252*b1cdbd2cSJim Jagielski 	Locale aAppLanguage = Application::GetSettings().GetUILocale();
253*b1cdbd2cSJim Jagielski 	dbtools::TransferFormComponentProperties(xFormatProps, xEditProps, aAppLanguage);
254*b1cdbd2cSJim Jagielski 
255*b1cdbd2cSJim Jagielski 	// then write the edit part, after switching to "fake mode"
256*b1cdbd2cSJim Jagielski 	m_pEditPart->enableFormattedWriteFake();
257*b1cdbd2cSJim Jagielski 	m_pEditPart->write(_rxOutStream);
258*b1cdbd2cSJim Jagielski 	m_pEditPart->disableFormattedWriteFake();
259*b1cdbd2cSJim Jagielski 
260*b1cdbd2cSJim Jagielski 	// and finally write the formatted part we're really interested in
261*b1cdbd2cSJim Jagielski 	m_xFormattedPart->write(_rxOutStream);
262*b1cdbd2cSJim Jagielski }
263*b1cdbd2cSJim Jagielski 
264*b1cdbd2cSJim Jagielski //------------------------------------------------------------------
read(const Reference<XObjectInputStream> & _rxInStream)265*b1cdbd2cSJim Jagielski void SAL_CALL OFormattedFieldWrapper::read(const Reference<XObjectInputStream>& _rxInStream) throw( IOException, RuntimeException )
266*b1cdbd2cSJim Jagielski {
267*b1cdbd2cSJim Jagielski 	if (m_xAggregate.is())
268*b1cdbd2cSJim Jagielski 	{	//  we alread did a decision if we're an EditModel or a FormattedModel
269*b1cdbd2cSJim Jagielski 
270*b1cdbd2cSJim Jagielski 		// if we act as formatted, we have to read the edit part first
271*b1cdbd2cSJim Jagielski 		if (m_xFormattedPart.is())
272*b1cdbd2cSJim Jagielski 		{
273*b1cdbd2cSJim Jagielski 			// two possible cases:
274*b1cdbd2cSJim Jagielski 			// a) the stuff was written by a version which didn't work with an Edit header (all intermediate
275*b1cdbd2cSJim Jagielski 			//		versions >5.1 && <=568)
276*b1cdbd2cSJim Jagielski 			// b) it was written by a version using edit headers
277*b1cdbd2cSJim Jagielski 			// as we can distinguish a) from b) only after we have read the edit part, we need to remember the
278*b1cdbd2cSJim Jagielski 			// position
279*b1cdbd2cSJim Jagielski 			Reference<XMarkableStream>  xInMarkable(_rxInStream, UNO_QUERY);
280*b1cdbd2cSJim Jagielski 			DBG_ASSERT(xInMarkable.is(), "OFormattedFieldWrapper::read : can only work with markable streams !");
281*b1cdbd2cSJim Jagielski 			sal_Int32 nBeforeEditPart = xInMarkable->createMark();
282*b1cdbd2cSJim Jagielski 
283*b1cdbd2cSJim Jagielski 			m_pEditPart->read(_rxInStream);
284*b1cdbd2cSJim Jagielski 				// this only works because an edit model can read the stuff written by a formatted model (maybe with
285*b1cdbd2cSJim Jagielski 				// some assertions) , but not vice versa
286*b1cdbd2cSJim Jagielski 			if (!m_pEditPart->lastReadWasFormattedFake())
287*b1cdbd2cSJim Jagielski 			{	// case a), written with a version without the edit part fake, so seek to the start position, again
288*b1cdbd2cSJim Jagielski 				xInMarkable->jumpToMark(nBeforeEditPart);
289*b1cdbd2cSJim Jagielski 			}
290*b1cdbd2cSJim Jagielski 			xInMarkable->deleteMark(nBeforeEditPart);
291*b1cdbd2cSJim Jagielski 		}
292*b1cdbd2cSJim Jagielski 
293*b1cdbd2cSJim Jagielski 		Reference<XPersistObject>  xAggregatePersistence;
294*b1cdbd2cSJim Jagielski 		query_aggregation(m_xAggregate, xAggregatePersistence);
295*b1cdbd2cSJim Jagielski 		DBG_ASSERT(xAggregatePersistence.is(), "OFormattedFieldWrapper::read : don't know how to handle this : can't read !");
296*b1cdbd2cSJim Jagielski 			// oops ... We gave an XPersistObject interface to the caller but now we aren't an XPersistObject ...
297*b1cdbd2cSJim Jagielski 
298*b1cdbd2cSJim Jagielski 		if (xAggregatePersistence.is())
299*b1cdbd2cSJim Jagielski 			xAggregatePersistence->read(_rxInStream);
300*b1cdbd2cSJim Jagielski 		return;
301*b1cdbd2cSJim Jagielski 	}
302*b1cdbd2cSJim Jagielski 
303*b1cdbd2cSJim Jagielski 	// we have to decide from the data within the stream whether we should be an EditModel or a FormattedModel
304*b1cdbd2cSJim Jagielski 	OEditBaseModel* pNewAggregate = NULL;
305*b1cdbd2cSJim Jagielski 
306*b1cdbd2cSJim Jagielski 	// let an OEditModel do the reading
307*b1cdbd2cSJim Jagielski 	OEditModel* pBasicReader = new OEditModel(m_xServiceFactory);
308*b1cdbd2cSJim Jagielski     Reference< XInterface > xHoldBasicReaderAlive( *pBasicReader );
309*b1cdbd2cSJim Jagielski 	pBasicReader->read(_rxInStream);
310*b1cdbd2cSJim Jagielski 
311*b1cdbd2cSJim Jagielski 	// was it really an edit model ?
312*b1cdbd2cSJim Jagielski 	if (!pBasicReader->lastReadWasFormattedFake())
313*b1cdbd2cSJim Jagielski 		// yes -> all fine
314*b1cdbd2cSJim Jagielski 		pNewAggregate = pBasicReader;
315*b1cdbd2cSJim Jagielski 	else
316*b1cdbd2cSJim Jagielski 	{	// no -> substitute it with a formatted model
317*b1cdbd2cSJim Jagielski 
318*b1cdbd2cSJim Jagielski 		// let the formmatted model do the reading
319*b1cdbd2cSJim Jagielski 		OFormattedModel* pFormattedReader = new OFormattedModel(m_xServiceFactory);
320*b1cdbd2cSJim Jagielski         Reference< XInterface > xHoldAliveWhileRead( *pFormattedReader );
321*b1cdbd2cSJim Jagielski 		pFormattedReader->read(_rxInStream);
322*b1cdbd2cSJim Jagielski 
323*b1cdbd2cSJim Jagielski 		// for the next write (if any) : the FormattedModel and the EditModel parts
324*b1cdbd2cSJim Jagielski 		query_interface(static_cast<XWeak*>(pFormattedReader), m_xFormattedPart);
325*b1cdbd2cSJim Jagielski 		m_pEditPart = pBasicReader;
326*b1cdbd2cSJim Jagielski 		m_pEditPart->acquire();
327*b1cdbd2cSJim Jagielski 
328*b1cdbd2cSJim Jagielski 		// aggregate the formatted part below
329*b1cdbd2cSJim Jagielski 		pNewAggregate = pFormattedReader;
330*b1cdbd2cSJim Jagielski 	}
331*b1cdbd2cSJim Jagielski 
332*b1cdbd2cSJim Jagielski 	// do the aggregation
333*b1cdbd2cSJim Jagielski 	increment(m_refCount);
334*b1cdbd2cSJim Jagielski 	{
335*b1cdbd2cSJim Jagielski 		query_interface(static_cast<XWeak*>(pNewAggregate), m_xAggregate);
336*b1cdbd2cSJim Jagielski 		DBG_ASSERT(m_xAggregate.is(), "OFormattedFieldWrapper::read : the OEditModel didn't have an XAggregation interface !");
337*b1cdbd2cSJim Jagielski 	}
338*b1cdbd2cSJim Jagielski 	if (m_xAggregate.is())
339*b1cdbd2cSJim Jagielski 	{	// has to be in it's own block because of the temporary variable created by *this
340*b1cdbd2cSJim Jagielski 		m_xAggregate->setDelegator(static_cast<XWeak*>(this));
341*b1cdbd2cSJim Jagielski 	}
342*b1cdbd2cSJim Jagielski 	decrement(m_refCount);
343*b1cdbd2cSJim Jagielski }
344*b1cdbd2cSJim Jagielski 
345*b1cdbd2cSJim Jagielski //------------------------------------------------------------------
createClone()346*b1cdbd2cSJim Jagielski Reference< XCloneable > SAL_CALL OFormattedFieldWrapper::createClone(  ) throw (RuntimeException)
347*b1cdbd2cSJim Jagielski {
348*b1cdbd2cSJim Jagielski 	ensureAggregate();
349*b1cdbd2cSJim Jagielski 
350*b1cdbd2cSJim Jagielski 	return new OFormattedFieldWrapper( this );
351*b1cdbd2cSJim Jagielski }
352*b1cdbd2cSJim Jagielski 
353*b1cdbd2cSJim Jagielski //------------------------------------------------------------------
ensureAggregate()354*b1cdbd2cSJim Jagielski void OFormattedFieldWrapper::ensureAggregate()
355*b1cdbd2cSJim Jagielski {
356*b1cdbd2cSJim Jagielski 	if (m_xAggregate.is())
357*b1cdbd2cSJim Jagielski 		return;
358*b1cdbd2cSJim Jagielski 
359*b1cdbd2cSJim Jagielski 	increment(m_refCount);
360*b1cdbd2cSJim Jagielski 	{
361*b1cdbd2cSJim Jagielski 		// instantiate an EditModel (the only place where we are allowed to decide that we're an FormattedModel
362*b1cdbd2cSJim Jagielski 		// is in ::read)
363*b1cdbd2cSJim Jagielski 		InterfaceRef  xEditModel = m_xServiceFactory->createInstance(FRM_SUN_COMPONENT_TEXTFIELD);
364*b1cdbd2cSJim Jagielski 		if (!xEditModel.is())
365*b1cdbd2cSJim Jagielski 		{
366*b1cdbd2cSJim Jagielski 			// arghhh ... instantiate it directly ... it's dirty, but we really need this aggregate
367*b1cdbd2cSJim Jagielski 			OEditModel* pModel = new OEditModel(m_xServiceFactory);
368*b1cdbd2cSJim Jagielski 			query_interface(static_cast<XWeak*>(pModel), xEditModel);
369*b1cdbd2cSJim Jagielski 		}
370*b1cdbd2cSJim Jagielski 
371*b1cdbd2cSJim Jagielski 		m_xAggregate = Reference<XAggregation> (xEditModel, UNO_QUERY);
372*b1cdbd2cSJim Jagielski 		DBG_ASSERT(m_xAggregate.is(), "OFormattedFieldWrapper::ensureAggregate : the OEditModel didn't have an XAggregation interface !");
373*b1cdbd2cSJim Jagielski 
374*b1cdbd2cSJim Jagielski 		{
375*b1cdbd2cSJim Jagielski 			Reference< XServiceInfo > xSI(m_xAggregate, UNO_QUERY);
376*b1cdbd2cSJim Jagielski 			if (!xSI.is())
377*b1cdbd2cSJim Jagielski 			{
378*b1cdbd2cSJim Jagielski 				DBG_ERROR("OFormattedFieldWrapper::ensureAggregate: the aggregate has no XServiceInfo!");
379*b1cdbd2cSJim Jagielski 				m_xAggregate.clear();
380*b1cdbd2cSJim Jagielski 			}
381*b1cdbd2cSJim Jagielski 		}
382*b1cdbd2cSJim Jagielski 	}
383*b1cdbd2cSJim Jagielski 	if (m_xAggregate.is())
384*b1cdbd2cSJim Jagielski 	{	// has to be in it's own block because of the temporary variable created by *this
385*b1cdbd2cSJim Jagielski 		m_xAggregate->setDelegator(static_cast<XWeak*>(this));
386*b1cdbd2cSJim Jagielski 	}
387*b1cdbd2cSJim Jagielski 	decrement(m_refCount);
388*b1cdbd2cSJim Jagielski }
389*b1cdbd2cSJim Jagielski 
390*b1cdbd2cSJim Jagielski //.........................................................................
391*b1cdbd2cSJim Jagielski }
392*b1cdbd2cSJim Jagielski //.........................................................................
393*b1cdbd2cSJim Jagielski 
394*b1cdbd2cSJim Jagielski 
395