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_svx.hxx" 30 #include "fmobj.hxx" 31 #include "fmprop.hrc" 32 #include "fmvwimp.hxx" 33 #include "fmpgeimp.hxx" 34 #include "svx/fmresids.hrc" 35 #include "svx/fmview.hxx" 36 #include "svx/fmglob.hxx" 37 #include "svx/fmpage.hxx" 38 #include "editeng/editeng.hxx" 39 #include "svx/svdovirt.hxx" 40 #include "svx/fmmodel.hxx" 41 #include "svx/dialmgr.hxx" 42 43 /** === begin UNO includes === **/ 44 #include <com/sun/star/awt/XDevice.hpp> 45 #include <com/sun/star/script/XEventAttacherManager.hpp> 46 #include <com/sun/star/io/XPersistObject.hpp> 47 #include <com/sun/star/awt/XControlContainer.hpp> 48 #include <com/sun/star/util/XCloneable.hpp> 49 /** === end UNO includes === **/ 50 #include "svx/fmtools.hxx" 51 52 #include <tools/shl.hxx> 53 #include <comphelper/property.hxx> 54 #include <comphelper/processfactory.hxx> 55 #include <toolkit/awt/vclxdevice.hxx> 56 #include <vcl/svapp.hxx> 57 #include <tools/resmgr.hxx> 58 #include <tools/diagnose_ex.h> 59 60 using namespace ::com::sun::star::io; 61 using namespace ::com::sun::star::uno; 62 using namespace ::com::sun::star::awt; 63 using namespace ::com::sun::star::lang; 64 using namespace ::com::sun::star::util; 65 using namespace ::com::sun::star::form; 66 using namespace ::com::sun::star::beans; 67 using namespace ::com::sun::star::script; 68 using namespace ::com::sun::star::container; 69 using namespace ::svxform; 70 71 TYPEINIT1(FmFormObj, SdrUnoObj); 72 DBG_NAME(FmFormObj); 73 //------------------------------------------------------------------ 74 FmFormObj::FmFormObj(const ::rtl::OUString& rModelName,sal_Int32 _nType) 75 :SdrUnoObj ( rModelName ) 76 ,m_nPos ( -1 ) 77 ,m_nType ( _nType ) 78 ,m_pLastKnownRefDevice ( NULL ) 79 { 80 DBG_CTOR(FmFormObj, NULL); 81 82 // normally, this is done in SetUnoControlModel, but if the call happened in the base class ctor, 83 // then our incarnation of it was not called (since we were not constructed at this time). 84 impl_checkRefDevice_nothrow( true ); 85 } 86 87 //------------------------------------------------------------------ 88 FmFormObj::FmFormObj( sal_Int32 _nType ) 89 :SdrUnoObj ( String() ) 90 ,m_nPos ( -1 ) 91 ,m_nType ( _nType ) 92 ,m_pLastKnownRefDevice ( NULL ) 93 { 94 DBG_CTOR(FmFormObj, NULL); 95 } 96 97 //------------------------------------------------------------------ 98 FmFormObj::~FmFormObj() 99 { 100 DBG_DTOR(FmFormObj, NULL); 101 102 Reference< XComponent> xHistory(m_xEnvironmentHistory, UNO_QUERY); 103 if (xHistory.is()) 104 xHistory->dispose(); 105 106 m_xEnvironmentHistory = NULL; 107 m_aEventsHistory.realloc(0); 108 } 109 110 //------------------------------------------------------------------ 111 void FmFormObj::SetObjEnv(const Reference< XIndexContainer > & xForm, const sal_Int32 nIdx, 112 const Sequence< ScriptEventDescriptor >& rEvts) 113 { 114 m_xParent = xForm; 115 aEvts = rEvts; 116 m_nPos = nIdx; 117 } 118 119 //------------------------------------------------------------------ 120 void FmFormObj::ClearObjEnv() 121 { 122 m_xParent.clear(); 123 aEvts.realloc( 0 ); 124 m_nPos = -1; 125 } 126 127 //------------------------------------------------------------------ 128 void FmFormObj::impl_checkRefDevice_nothrow( bool _force ) 129 { 130 const FmFormModel* pFormModel = PTR_CAST( FmFormModel, GetModel() ); 131 if ( !pFormModel || !pFormModel->ControlsUseRefDevice() ) 132 return; 133 134 OutputDevice* pCurrentRefDevice = pFormModel ? pFormModel->GetRefDevice() : NULL; 135 if ( ( m_pLastKnownRefDevice == pCurrentRefDevice ) && !_force ) 136 return; 137 138 Reference< XControlModel > xControlModel( GetUnoControlModel() ); 139 if ( !xControlModel.is() ) 140 return; 141 142 m_pLastKnownRefDevice = pCurrentRefDevice; 143 if ( m_pLastKnownRefDevice == NULL ) 144 return; 145 146 try 147 { 148 Reference< XPropertySet > xModelProps( GetUnoControlModel(), UNO_QUERY_THROW ); 149 Reference< XPropertySetInfo > xPropertyInfo( xModelProps->getPropertySetInfo(), UNO_SET_THROW ); 150 151 static const ::rtl::OUString sRefDevicePropName( RTL_CONSTASCII_USTRINGPARAM( "ReferenceDevice" ) ); 152 if ( xPropertyInfo->hasPropertyByName( sRefDevicePropName ) ) 153 { 154 VCLXDevice* pUnoRefDevice = new VCLXDevice; 155 pUnoRefDevice->SetOutputDevice( m_pLastKnownRefDevice ); 156 Reference< XDevice > xRefDevice( pUnoRefDevice ); 157 xModelProps->setPropertyValue( sRefDevicePropName, makeAny( xRefDevice ) ); 158 } 159 } 160 catch( const Exception& ) 161 { 162 DBG_UNHANDLED_EXCEPTION(); 163 } 164 } 165 166 //------------------------------------------------------------------ 167 void FmFormObj::impl_isolateControlModel_nothrow() 168 { 169 try 170 { 171 Reference< XChild > xControlModel( GetUnoControlModel(), UNO_QUERY ); 172 if ( xControlModel.is() ) 173 { 174 Reference< XIndexContainer> xParent( xControlModel->getParent(), UNO_QUERY ); 175 if ( xParent.is() ) 176 { 177 sal_Int32 nPos = getElementPos( xParent.get(), xControlModel ); 178 xParent->removeByIndex( nPos ); 179 } 180 } 181 } 182 catch( const Exception& ) 183 { 184 DBG_UNHANDLED_EXCEPTION(); 185 } 186 } 187 188 //------------------------------------------------------------------ 189 void FmFormObj::SetPage(SdrPage* _pNewPage) 190 { 191 if ( GetPage() == _pNewPage ) 192 { 193 SdrUnoObj::SetPage(_pNewPage); 194 return; 195 } 196 197 FmFormPage* pOldFormPage = PTR_CAST( FmFormPage, GetPage() ); 198 if ( pOldFormPage ) 199 pOldFormPage->GetImpl().formObjectRemoved( *this ); 200 201 FmFormPage* pNewFormPage = PTR_CAST( FmFormPage, _pNewPage ); 202 if ( !pNewFormPage ) 203 { // Maybe it makes sense to create an environment history here : if somebody set's our page to NULL, and we have a valid page before, 204 // me may want to remember our place within the old page. For this we could create a new m_xEnvironmentHistory to store it. 205 // So the next SetPage with a valid new page would restore that environment within the new page. 206 // But for the original Bug (#57300#) we don't need that, so I omit it here. Maybe this will be implemented later. 207 impl_isolateControlModel_nothrow(); 208 SdrUnoObj::SetPage(_pNewPage); 209 return; 210 } 211 212 Reference< XIndexContainer > xNewPageForms( pNewFormPage->GetForms( true ), UNO_QUERY ); 213 Reference< XIndexContainer > xNewParent; 214 Sequence< ScriptEventDescriptor> aNewEvents; 215 216 // calc the new parent for my model (within the new page's forms hierarchy) 217 // do we have a history ? (from :Clone) 218 if ( m_xEnvironmentHistory.is() ) 219 { 220 // the element in m_xEnvironmentHistory which is equivalent to my new parent (which (perhaps) has to be created within _pNewPage->GetForms) 221 // is the right-most element in the tree. 222 Reference< XIndexContainer > xRightMostLeaf = m_xEnvironmentHistory; 223 try 224 { 225 while ( xRightMostLeaf->getCount() ) 226 { 227 xRightMostLeaf.set( 228 xRightMostLeaf->getByIndex( xRightMostLeaf->getCount() - 1 ), 229 UNO_QUERY_THROW 230 ); 231 } 232 233 xNewParent.set( ensureModelEnv( xRightMostLeaf, xNewPageForms ), UNO_QUERY_THROW ); 234 235 // we successfully cloned the environment in m_xEnvironmentHistory, so we can use m_aEventsHistory 236 // (which describes the events of our model at the moment m_xEnvironmentHistory was created) 237 aNewEvents = m_aEventsHistory; 238 } 239 catch( const Exception& ) 240 { 241 DBG_UNHANDLED_EXCEPTION(); 242 } 243 } 244 245 if ( !xNewParent.is() ) 246 { 247 // are we a valid part of our current page forms ? 248 Reference< XIndexContainer > xOldForms; 249 if ( pOldFormPage ) 250 xOldForms.set( pOldFormPage->GetForms(), UNO_QUERY_THROW ); 251 252 if ( xOldForms.is() ) 253 { 254 // search (upward from our model) for xOldForms 255 Reference< XChild > xSearch( GetUnoControlModel(), UNO_QUERY ); 256 while (xSearch.is()) 257 { 258 if ( xSearch == xOldForms ) 259 break; 260 xSearch = Reference< XChild >( xSearch->getParent(), UNO_QUERY ); 261 } 262 if ( xSearch.is() ) // implies xSearch == xOldForms, which means we're a valid part of our current page forms hierarchy 263 { 264 Reference< XChild > xMeAsChild( GetUnoControlModel(), UNO_QUERY ); 265 xNewParent.set( ensureModelEnv( xMeAsChild->getParent(), xNewPageForms ), UNO_QUERY ); 266 267 if ( xNewParent.is() ) 268 { 269 try 270 { 271 // transfer the events from our (model's) parent to the new (model's) parent, too 272 Reference< XEventAttacherManager > xEventManager(xMeAsChild->getParent(), UNO_QUERY); 273 Reference< XIndexAccess > xManagerAsIndex(xEventManager, UNO_QUERY); 274 if (xManagerAsIndex.is()) 275 { 276 sal_Int32 nPos = getElementPos(xManagerAsIndex, xMeAsChild); 277 if (nPos >= 0) 278 aNewEvents = xEventManager->getScriptEvents(nPos); 279 } 280 else 281 aNewEvents = aEvts; 282 } 283 catch( const Exception& ) 284 { 285 DBG_UNHANDLED_EXCEPTION(); 286 } 287 } 288 } 289 } 290 } 291 292 // now set the page 293 SdrUnoObj::SetPage(_pNewPage); 294 295 // place my model within the new parent container 296 if (xNewParent.is()) 297 { 298 Reference< XFormComponent > xMeAsFormComp(GetUnoControlModel(), UNO_QUERY); 299 if (xMeAsFormComp.is()) 300 { 301 // check if I have another parent (and remove me, if neccessary) 302 Reference< XIndexContainer > xOldParent(xMeAsFormComp->getParent(), UNO_QUERY); 303 if (xOldParent.is()) 304 { 305 sal_Int32 nPos = getElementPos(Reference< XIndexAccess > (xOldParent, UNO_QUERY), xMeAsFormComp); 306 if (nPos > -1) 307 xOldParent->removeByIndex(nPos); 308 } 309 // and insert into the new container 310 xNewParent->insertByIndex(xNewParent->getCount(), makeAny(xMeAsFormComp)); 311 312 // transfer the events 313 if (aNewEvents.getLength()) 314 { 315 try 316 { 317 Reference< XEventAttacherManager > xEventManager(xNewParent, UNO_QUERY); 318 Reference< XIndexAccess > xManagerAsIndex(xEventManager, UNO_QUERY); 319 if (xManagerAsIndex.is()) 320 { 321 sal_Int32 nPos = getElementPos(xManagerAsIndex, xMeAsFormComp); 322 DBG_ASSERT(nPos >= 0, "FmFormObj::SetPage : inserted but not present ?"); 323 xEventManager->registerScriptEvents(nPos, aNewEvents); 324 } 325 } 326 catch( const Exception& ) 327 { 328 DBG_UNHANDLED_EXCEPTION(); 329 } 330 331 } 332 } 333 } 334 335 // delete my history 336 Reference< XComponent> xHistory(m_xEnvironmentHistory, UNO_QUERY); 337 if (xHistory.is()) 338 xHistory->dispose(); 339 340 m_xEnvironmentHistory = NULL; 341 m_aEventsHistory.realloc(0); 342 343 if ( pNewFormPage ) 344 pNewFormPage->GetImpl().formObjectInserted( *this ); 345 } 346 347 //------------------------------------------------------------------ 348 sal_uInt32 FmFormObj::GetObjInventor() const 349 { 350 return FmFormInventor; 351 } 352 353 //------------------------------------------------------------------ 354 sal_uInt16 FmFormObj::GetObjIdentifier() const 355 { 356 return OBJ_UNO; 357 } 358 359 //------------------------------------------------------------------ 360 void FmFormObj::clonedFrom(const FmFormObj* _pSource) 361 { 362 DBG_ASSERT(_pSource != NULL, "FmFormObj::clonedFrom : invalid source !"); 363 Reference< XComponent> xHistory(m_xEnvironmentHistory, UNO_QUERY); 364 if (xHistory.is()) 365 xHistory->dispose(); 366 367 m_xEnvironmentHistory = NULL; 368 m_aEventsHistory.realloc(0); 369 370 Reference< XChild > xSourceAsChild(_pSource->GetUnoControlModel(), UNO_QUERY); 371 if (!xSourceAsChild.is()) 372 return; 373 374 Reference< XInterface > xSourceContainer = xSourceAsChild->getParent(); 375 376 m_xEnvironmentHistory = Reference< XIndexContainer >( 377 ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.form.Forms")), 378 UNO_QUERY); 379 DBG_ASSERT(m_xEnvironmentHistory.is(), "FmFormObj::clonedFrom : could not create a forms collection !"); 380 381 if (m_xEnvironmentHistory.is()) 382 { 383 ensureModelEnv(xSourceContainer, m_xEnvironmentHistory); 384 m_aEventsHistory = aEvts; 385 // if we we're clone there was a call to operator=, so aEvts are excatly the events we need here ... 386 } 387 } 388 389 //------------------------------------------------------------------ 390 SdrObject* FmFormObj::Clone() const 391 { 392 SdrObject* pReturn = SdrUnoObj::Clone(); 393 394 FmFormObj* pFormObject = PTR_CAST(FmFormObj, pReturn); 395 DBG_ASSERT(pFormObject != NULL, "FmFormObj::Clone : invalid clone !"); 396 if (pFormObject) 397 pFormObject->clonedFrom(this); 398 399 return pReturn; 400 } 401 402 //------------------------------------------------------------------ 403 void FmFormObj::NbcReformatText() 404 { 405 impl_checkRefDevice_nothrow( false ); 406 SdrUnoObj::NbcReformatText(); 407 } 408 409 //------------------------------------------------------------------ 410 void FmFormObj::operator= (const SdrObject& rObj) 411 { 412 SdrUnoObj::operator= (rObj); 413 414 FmFormObj* pFormObj = PTR_CAST(FmFormObj, &rObj); 415 if (pFormObj) 416 { 417 // liegt das UnoControlModel in einer Eventumgebung, 418 // dann koennen noch Events zugeordnet sein 419 Reference< XFormComponent > xContent(pFormObj->xUnoControlModel, UNO_QUERY); 420 if (xContent.is()) 421 { 422 Reference< XEventAttacherManager > xManager(xContent->getParent(), UNO_QUERY); 423 Reference< XIndexAccess > xManagerAsIndex(xManager, UNO_QUERY); 424 if (xManagerAsIndex.is()) 425 { 426 sal_Int32 nPos = getElementPos( xManagerAsIndex, xContent ); 427 if ( nPos >= 0 ) 428 aEvts = xManager->getScriptEvents( nPos ); 429 } 430 } 431 else 432 aEvts = pFormObj->aEvts; 433 } 434 } 435 436 //------------------------------------------------------------------ 437 namespace 438 { 439 String lcl_getFormComponentAccessPath(const Reference< XInterface >& _xElement, Reference< XInterface >& _rTopLevelElement) 440 { 441 Reference< ::com::sun::star::form::XFormComponent> xChild(_xElement, UNO_QUERY); 442 Reference< ::com::sun::star::container::XIndexAccess> xParent; 443 if (xChild.is()) 444 xParent = Reference< ::com::sun::star::container::XIndexAccess>(xChild->getParent(), UNO_QUERY); 445 446 // while the current content is a form 447 String sReturn; 448 String sCurrentIndex; 449 while (xChild.is()) 450 { 451 // get the content's relative pos within it's parent container 452 sal_Int32 nPos = getElementPos(xParent, xChild); 453 454 // prepend this current relaive pos 455 sCurrentIndex = String::CreateFromInt32(nPos); 456 if (sReturn.Len() != 0) 457 { 458 sCurrentIndex += '\\'; 459 sCurrentIndex += sReturn; 460 } 461 462 sReturn = sCurrentIndex; 463 464 // travel up 465 if (::comphelper::query_interface((Reference< XInterface >)xParent,xChild)) 466 xParent = Reference< ::com::sun::star::container::XIndexAccess>(xChild->getParent(), UNO_QUERY); 467 } 468 469 _rTopLevelElement = xParent; 470 return sReturn; 471 } 472 } 473 474 //------------------------------------------------------------------ 475 Reference< XInterface > FmFormObj::ensureModelEnv(const Reference< XInterface > & _rSourceContainer, const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer > _rTopLevelDestContainer) 476 { 477 Reference< XInterface > xTopLevelSouce; 478 String sAccessPath = lcl_getFormComponentAccessPath(_rSourceContainer, xTopLevelSouce); 479 if (!xTopLevelSouce.is()) 480 // somthing went wrong, maybe _rSourceContainer isn't part of a valid forms hierarchy 481 return Reference< XInterface > (); 482 483 Reference< XIndexContainer > xDestContainer(_rTopLevelDestContainer); 484 Reference< XIndexContainer > xSourceContainer(xTopLevelSouce, UNO_QUERY); 485 DBG_ASSERT(xSourceContainer.is(), "FmFormObj::ensureModelEnv : the top level source is invalid !"); 486 487 for (xub_StrLen i=0; i<sAccessPath.GetTokenCount('\\'); ++i) 488 { 489 sal_uInt16 nIndex = (sal_uInt16)sAccessPath.GetToken(i, '\\').ToInt32(); 490 491 // get the DSS of the source form (we have to find an aquivalent for) 492 DBG_ASSERT(nIndex<xSourceContainer->getCount(), "FmFormObj::ensureModelEnv : invalid access path !"); 493 Reference< XPropertySet > xSourceForm; 494 xSourceContainer->getByIndex(nIndex) >>= xSourceForm; 495 DBG_ASSERT(xSourceForm.is(), "FmFormObj::ensureModelEnv : invalid source form !"); 496 497 Any aSrcCursorSource, aSrcCursorSourceType, aSrcDataSource; 498 DBG_ASSERT(::comphelper::hasProperty(FM_PROP_COMMAND, xSourceForm) && ::comphelper::hasProperty(FM_PROP_COMMANDTYPE, xSourceForm) 499 && ::comphelper::hasProperty(FM_PROP_DATASOURCE, xSourceForm), "FmFormObj::ensureModelEnv : invalid access path or invalid form (missing props) !"); 500 // the parent access path should refer to a row set 501 try 502 { 503 aSrcCursorSource = xSourceForm->getPropertyValue(FM_PROP_COMMAND); 504 aSrcCursorSourceType = xSourceForm->getPropertyValue(FM_PROP_COMMANDTYPE); 505 aSrcDataSource = xSourceForm->getPropertyValue(FM_PROP_DATASOURCE); 506 } 507 catch(Exception&) 508 { 509 DBG_ERROR("FmFormObj::ensureModelEnv : could not retrieve a source DSS !"); 510 } 511 512 513 // calc the number of (source) form siblings with the same DSS 514 Reference< XPropertySet > xCurrentSourceForm, xCurrentDestForm; 515 sal_Int16 nCurrentSourceIndex = 0, nCurrentDestIndex = 0; 516 while (nCurrentSourceIndex <= nIndex) 517 { 518 sal_Bool bEqualDSS = sal_False; 519 while (!bEqualDSS) // (we don't have to check nCurrentSourceIndex here : it's bound by nIndex) 520 { 521 xSourceContainer->getByIndex(nCurrentSourceIndex) >>= xCurrentSourceForm; 522 DBG_ASSERT(xCurrentSourceForm.is(), "FmFormObj::ensureModelEnv : invalid form ancestor (2) !"); 523 bEqualDSS = sal_False; 524 if (::comphelper::hasProperty(FM_PROP_DATASOURCE, xCurrentSourceForm)) 525 { // it is a form 526 try 527 { 528 if ( ::comphelper::compare(xCurrentSourceForm->getPropertyValue(FM_PROP_COMMAND), aSrcCursorSource) 529 && ::comphelper::compare(xCurrentSourceForm->getPropertyValue(FM_PROP_COMMANDTYPE), aSrcCursorSourceType) 530 && ::comphelper::compare(xCurrentSourceForm->getPropertyValue(FM_PROP_DATASOURCE), aSrcDataSource) 531 ) 532 { 533 bEqualDSS = sal_True; 534 } 535 } 536 catch(Exception&) 537 { 538 DBG_ERROR("FmFormObj::ensureModelEnv : exception while getting a sibling's DSS !"); 539 } 540 541 } 542 ++nCurrentSourceIndex; 543 } 544 545 DBG_ASSERT(bEqualDSS, "FmFormObj::ensureModelEnv : found no source form !"); 546 // ??? at least the nIndex-th one should have been found ??? 547 548 // now search the next one with the given DSS (within the destination container) 549 bEqualDSS = sal_False; 550 while (!bEqualDSS && (nCurrentDestIndex < xDestContainer->getCount())) 551 { 552 xDestContainer->getByIndex(nCurrentDestIndex) >>= xCurrentDestForm; 553 DBG_ASSERT(xCurrentDestForm.is(), "FmFormObj::ensureModelEnv : invalid destination form !"); 554 bEqualDSS = sal_False; 555 if (::comphelper::hasProperty(FM_PROP_DATASOURCE, xCurrentDestForm)) 556 { // it is a form 557 try 558 { 559 if ( ::comphelper::compare(xCurrentDestForm->getPropertyValue(FM_PROP_COMMAND), aSrcCursorSource) 560 && ::comphelper::compare(xCurrentDestForm->getPropertyValue(FM_PROP_COMMANDTYPE), aSrcCursorSourceType) 561 && ::comphelper::compare(xCurrentDestForm->getPropertyValue(FM_PROP_DATASOURCE), aSrcDataSource) 562 ) 563 { 564 bEqualDSS = sal_True; 565 } 566 } 567 catch(Exception&) 568 { 569 DBG_ERROR("FmFormObj::ensureModelEnv : exception while getting a destination DSS !"); 570 } 571 572 } 573 ++nCurrentDestIndex; 574 } 575 576 if (!bEqualDSS) 577 { // There is at least one more source form with the given DSS than destination forms are. 578 // correct this ... 579 try 580 { 581 // create and insert (into the destination) a copy of the form 582 xCurrentDestForm.set( 583 ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii( "com.sun.star.form.component.DataForm" ) ), 584 UNO_QUERY_THROW ); 585 ::comphelper::copyProperties( xCurrentSourceForm, xCurrentDestForm ); 586 587 DBG_ASSERT(nCurrentDestIndex == xDestContainer->getCount(), "FmFormObj::ensureModelEnv : something went wrong with the numbers !"); 588 xDestContainer->insertByIndex(nCurrentDestIndex, makeAny(xCurrentDestForm)); 589 590 ++nCurrentDestIndex; 591 // like nCurrentSourceIndex, nCurrentDestIndex now points 'behind' the form it actally means 592 } 593 catch(Exception&) 594 { 595 DBG_ERROR("FmFormObj::ensureModelEnv : something went seriously wrong while creating a new form !"); 596 // no more options anymore ... 597 return Reference< XInterface > (); 598 } 599 600 } 601 } 602 603 // now xCurrentDestForm is a form equivalent to xSourceForm (which means they have the same DSS and the same number 604 // of left siblings with the same DSS, which counts for all their ancestors, too) 605 606 // go down 607 xDestContainer = Reference< XIndexContainer > (xCurrentDestForm, UNO_QUERY); 608 xSourceContainer = Reference< XIndexContainer > (xSourceForm, UNO_QUERY); 609 DBG_ASSERT(xDestContainer.is() && xSourceContainer.is(), "FmFormObj::ensureModelEnv : invalid container !"); 610 } 611 612 return Reference< XInterface > (xDestContainer, UNO_QUERY); 613 } 614 615 //------------------------------------------------------------------ 616 void FmFormObj::SetModel( SdrModel* _pNewModel ) 617 { 618 SdrUnoObj::SetModel( _pNewModel ); 619 impl_checkRefDevice_nothrow(); 620 } 621 622 //------------------------------------------------------------------ 623 FmFormObj* FmFormObj::GetFormObject( SdrObject* _pSdrObject ) 624 { 625 FmFormObj* pFormObject = dynamic_cast< FmFormObj* >( _pSdrObject ); 626 if ( !pFormObject ) 627 { 628 SdrVirtObj* pVirtualObject = dynamic_cast< SdrVirtObj* >( _pSdrObject ); 629 if ( pVirtualObject ) 630 pFormObject = dynamic_cast< FmFormObj* >( &pVirtualObject->ReferencedObj() ); 631 } 632 return pFormObject; 633 } 634 635 //------------------------------------------------------------------ 636 const FmFormObj* FmFormObj::GetFormObject( const SdrObject* _pSdrObject ) 637 { 638 const FmFormObj* pFormObject = dynamic_cast< const FmFormObj* >( _pSdrObject ); 639 if ( !pFormObject ) 640 { 641 const SdrVirtObj* pVirtualObject = dynamic_cast< const SdrVirtObj* >( _pSdrObject ); 642 if ( pVirtualObject ) 643 pFormObject = dynamic_cast< const FmFormObj* >( &pVirtualObject->GetReferencedObj() ); 644 } 645 return pFormObject; 646 } 647 648 //------------------------------------------------------------------ 649 void FmFormObj::SetUnoControlModel( const Reference< com::sun::star::awt::XControlModel >& _rxModel ) 650 { 651 SdrUnoObj::SetUnoControlModel( _rxModel ); 652 653 FmFormPage* pFormPage = PTR_CAST( FmFormPage, GetPage() ); 654 if ( pFormPage ) 655 pFormPage->GetImpl().formModelAssigned( *this ); 656 657 impl_checkRefDevice_nothrow( true ); 658 } 659 660 //------------------------------------------------------------------ 661 FASTBOOL FmFormObj::EndCreate( SdrDragStat& rStat, SdrCreateCmd eCmd ) 662 { 663 bool bResult = SdrUnoObj::EndCreate(rStat, eCmd); 664 if ( bResult && SDRCREATE_FORCEEND == eCmd && rStat.GetView() ) 665 { 666 if ( pPage ) 667 { 668 FmFormPage& rPage = dynamic_cast< FmFormPage& >( *pPage ); 669 670 try 671 { 672 Reference< XFormComponent > xContent( xUnoControlModel, UNO_QUERY_THROW ); 673 Reference< XForm > xParentForm( xContent->getParent(), UNO_QUERY ); 674 675 Reference< XIndexContainer > xFormToInsertInto; 676 677 if ( !xParentForm.is() ) 678 { // model is not yet part of a form component hierachy 679 xParentForm.set( rPage.GetImpl().findPlaceInFormComponentHierarchy( xContent ), UNO_SET_THROW ); 680 xFormToInsertInto.set( xParentForm, UNO_QUERY_THROW ); 681 } 682 683 rPage.GetImpl().setUniqueName( xContent, xParentForm ); 684 685 if ( xFormToInsertInto.is() ) 686 xFormToInsertInto->insertByIndex( xFormToInsertInto->getCount(), makeAny( xContent ) ); 687 } 688 catch( const Exception& ) 689 { 690 DBG_UNHANDLED_EXCEPTION(); 691 } 692 } 693 694 FmFormView* pView( dynamic_cast< FmFormView* >( rStat.GetView() ) ); 695 FmXFormView* pViewImpl = pView ? pView->GetImpl() : NULL; 696 OSL_ENSURE( pViewImpl, "FmFormObj::EndCreate: no view!?" ); 697 if ( pViewImpl ) 698 pViewImpl->onCreatedFormObject( *this ); 699 } 700 return bResult; 701 } 702 703 //------------------------------------------------------------------------------ 704 void FmFormObj::BrkCreate( SdrDragStat& rStat ) 705 { 706 SdrUnoObj::BrkCreate( rStat ); 707 impl_isolateControlModel_nothrow(); 708 } 709 710 // ----------------------------------------------------------------------------- 711 sal_Int32 FmFormObj::getType() const 712 { 713 return m_nType; 714 } 715 716 // ----------------------------------------------------------------------------- 717 // #i70852# overload Layer interface to force to FormColtrol layer 718 719 SdrLayerID FmFormObj::GetLayer() const 720 { 721 // #i72535# 722 // i70852 was too radical, in SW obects (and thus, FormControls, too) 723 // get moved to invisible layers to hide them (e.g. in hidden sections). 724 // This means that form controls ARE allowed to be on other layers than 725 // the form control layer ATM and that being member of form control layer 726 // is no criteria to find all FormControls of a document. 727 // To fix, use parent functionality 728 return SdrUnoObj::GetLayer(); 729 } 730 731 void FmFormObj::NbcSetLayer(SdrLayerID nLayer) 732 { 733 // #i72535# 734 // See above. To fix, use parent functionality 735 return SdrUnoObj::NbcSetLayer(nLayer); 736 } 737 738 // eof 739