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