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