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