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 <svx/dialmgr.hxx> 31 #include <svx/fmshell.hxx> 32 #include <svx/fmmodel.hxx> 33 #include <svx/fmpage.hxx> 34 #include <svx/fmglob.hxx> 35 #include "svx/svditer.hxx" 36 #include <svx/svdogrp.hxx> 37 #include <svx/svdpagv.hxx> 38 39 #include "fmprop.hrc" 40 41 #include "fmundo.hxx" 42 #include "fmhelp.hrc" 43 #include "fmexpl.hrc" 44 #include "fmexpl.hxx" 45 #include "svx/fmresids.hrc" 46 #include "fmshimp.hxx" 47 #include "fmobj.hxx" 48 #include <sfx2/objsh.hxx> 49 #include <tools/diagnose_ex.h> 50 #include <rtl/logfile.hxx> 51 #include <com/sun/star/container/XContainer.hpp> 52 53 //............................................................................ 54 namespace svxform 55 { 56 //............................................................................ 57 58 using namespace ::com::sun::star::uno; 59 using namespace ::com::sun::star::lang; 60 using namespace ::com::sun::star::beans; 61 using namespace ::com::sun::star::form; 62 using namespace ::com::sun::star::awt; 63 using namespace ::com::sun::star::container; 64 using namespace ::com::sun::star::script; 65 using namespace ::com::sun::star::sdb; 66 67 //======================================================================== 68 // class OFormComponentObserver 69 //======================================================================== 70 //------------------------------------------------------------------------ 71 OFormComponentObserver::OFormComponentObserver(NavigatorTreeModel* _pModel) 72 :m_pNavModel(_pModel) 73 ,m_nLocks(0) 74 ,m_bCanUndo(sal_True) 75 { 76 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::OFormComponentObserver" ); 77 } 78 79 // XPropertyChangeListener 80 //------------------------------------------------------------------------ 81 void SAL_CALL OFormComponentObserver::disposing(const EventObject& Source) throw( RuntimeException ) 82 { 83 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::disposing" ); 84 Remove( Source.Source ); 85 } 86 87 //------------------------------------------------------------------------ 88 void SAL_CALL OFormComponentObserver::propertyChange(const PropertyChangeEvent& evt) throw(RuntimeException) 89 { 90 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::propertyChange" ); 91 if( !m_pNavModel ) return; 92 if( evt.PropertyName != FM_PROP_NAME ) return; 93 94 Reference< XFormComponent > xFormComponent(evt.Source, UNO_QUERY); 95 Reference< XForm > xForm(evt.Source, UNO_QUERY); 96 97 FmEntryData* pEntryData( NULL ); 98 if( xForm.is() ) 99 pEntryData = m_pNavModel->FindData( xForm, m_pNavModel->GetRootList() ); 100 else if( xFormComponent.is() ) 101 pEntryData = m_pNavModel->FindData( xFormComponent, m_pNavModel->GetRootList() ); 102 103 if( pEntryData ) 104 { 105 ::rtl::OUString aNewName = ::comphelper::getString(evt.NewValue); 106 pEntryData->SetText( aNewName ); 107 FmNavNameChangedHint aNameChangedHint( pEntryData, aNewName ); 108 m_pNavModel->Broadcast( aNameChangedHint ); 109 } 110 } 111 112 // XContainerListener 113 //------------------------------------------------------------------------------ 114 void SAL_CALL OFormComponentObserver::elementInserted(const ContainerEvent& evt) throw(RuntimeException) 115 { 116 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::elementInserted" ); 117 if (IsLocked() || !m_pNavModel) 118 return; 119 120 // keine Undoaction einfuegen 121 m_bCanUndo = sal_False; 122 123 Reference< XInterface > xTemp; 124 evt.Element >>= xTemp; 125 Insert(xTemp, ::comphelper::getINT32(evt.Accessor)); 126 127 m_bCanUndo = sal_True; 128 } 129 130 //------------------------------------------------------------------------------ 131 void OFormComponentObserver::Insert(const Reference< XInterface > & xIface, sal_Int32 nIndex) 132 { 133 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::Insert" ); 134 Reference< XForm > xForm(xIface, UNO_QUERY); 135 if (xForm.is()) 136 { 137 m_pNavModel->InsertForm(xForm, sal_uInt32(nIndex)); 138 Reference< XIndexContainer > xContainer(xForm, UNO_QUERY); 139 Reference< XInterface > xTemp; 140 for (sal_Int32 i = 0; i < xContainer->getCount(); i++) 141 { 142 xContainer->getByIndex(i) >>= xTemp; 143 Insert(xTemp, i); 144 } 145 } 146 else 147 { 148 Reference< XFormComponent > xFormComp(xIface, UNO_QUERY); 149 if (xFormComp.is()) 150 m_pNavModel->InsertFormComponent(xFormComp, sal_uInt32(nIndex)); 151 } 152 } 153 154 //------------------------------------------------------------------------------ 155 void SAL_CALL OFormComponentObserver::elementReplaced(const ContainerEvent& evt) throw(RuntimeException) 156 { 157 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::elementReplaced" ); 158 if (IsLocked() || !m_pNavModel) 159 return; 160 161 m_bCanUndo = sal_False; 162 163 // EntryData loeschen 164 Reference< XFormComponent > xReplaced; 165 evt.ReplacedElement >>= xReplaced; 166 FmEntryData* pEntryData = m_pNavModel->FindData(xReplaced, m_pNavModel->GetRootList(), sal_True); 167 if (pEntryData) 168 { 169 if (pEntryData->ISA(FmControlData)) 170 { 171 Reference< XFormComponent > xComp; 172 evt.Element >>= xComp; 173 DBG_ASSERT(xComp.is(), "OFormComponentObserver::elementReplaced : invalid argument !"); 174 // an einer FmControlData sollte eine XFormComponent haengen 175 m_pNavModel->ReplaceFormComponent(xReplaced, xComp); 176 } 177 else if (pEntryData->ISA(FmFormData)) 178 { 179 DBG_ERROR("replacing forms not implemented yet !"); 180 } 181 } 182 183 m_bCanUndo = sal_True; 184 } 185 186 //------------------------------------------------------------------------------ 187 void OFormComponentObserver::Remove( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxElement ) 188 { 189 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::Remove" ); 190 if (IsLocked() || !m_pNavModel) 191 return; 192 193 m_bCanUndo = sal_False; 194 195 ////////////////////////////////////////////////////////// 196 // EntryData loeschen 197 FmEntryData* pEntryData = m_pNavModel->FindData( _rxElement, m_pNavModel->GetRootList(), sal_True ); 198 if (pEntryData) 199 m_pNavModel->Remove(pEntryData); 200 201 m_bCanUndo = sal_True; 202 } 203 204 //------------------------------------------------------------------------------ 205 void SAL_CALL OFormComponentObserver::elementRemoved(const ContainerEvent& evt) throw(RuntimeException) 206 { 207 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "OFormComponentObserver::elementRemoved" ); 208 Reference< XInterface > xElement; 209 evt.Element >>= xElement; 210 Remove( xElement ); 211 } 212 213 //======================================================================== 214 // class NavigatorTreeModel 215 //======================================================================== 216 217 //------------------------------------------------------------------------ 218 NavigatorTreeModel::NavigatorTreeModel( const ImageList& _rNormalImages, const ImageList& _rHCImages ) 219 :m_pFormShell(NULL) 220 ,m_pFormPage(NULL) 221 ,m_pFormModel(NULL) 222 ,m_aNormalImages( _rNormalImages ) 223 ,m_aHCImages( _rHCImages ) 224 { 225 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::NavigatorTreeModel" ); 226 m_pPropChangeList = new OFormComponentObserver(this); 227 m_pPropChangeList->acquire(); 228 m_pRootList = new FmEntryDataList(); 229 } 230 231 //------------------------------------------------------------------------ 232 NavigatorTreeModel::~NavigatorTreeModel() 233 { 234 ////////////////////////////////////////////////////////////////////// 235 // Als Listener abmelden 236 if( m_pFormShell) 237 { 238 FmFormModel* pFormModel = m_pFormShell->GetFormModel(); 239 if( pFormModel && IsListening(*pFormModel)) 240 EndListening( *pFormModel ); 241 242 if (IsListening(*m_pFormShell)) 243 EndListening(*m_pFormShell); 244 } 245 246 Clear(); 247 delete m_pRootList; 248 m_pPropChangeList->ReleaseModel(); 249 m_pPropChangeList->release(); 250 } 251 252 253 //------------------------------------------------------------------------ 254 void NavigatorTreeModel::SetModified( sal_Bool bMod ) 255 { 256 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::SetModified" ); 257 if( !m_pFormShell ) return; 258 SfxObjectShell* pObjShell = m_pFormShell->GetFormModel()->GetObjectShell(); 259 if( !pObjShell ) return; 260 pObjShell->SetModified( bMod ); 261 } 262 263 //------------------------------------------------------------------------ 264 void NavigatorTreeModel::Clear() 265 { 266 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Clear" ); 267 Reference< XNameContainer > xForms( GetForms()); 268 Reference< XContainer > xContainer(xForms, UNO_QUERY); 269 if (xContainer.is()) 270 xContainer->removeContainerListener((XContainerListener*)m_pPropChangeList); 271 272 ////////////////////////////////////////////////////////////////////// 273 // RootList loeschen 274 FmEntryData* pChildData; 275 FmEntryDataList* pRootList = GetRootList(); 276 277 for( sal_uInt32 i=pRootList->Count(); i>0; i-- ) 278 { 279 pChildData = pRootList->GetObject(i-1); 280 pRootList->Remove( pChildData ); 281 delete pChildData; 282 } 283 284 ////////////////////////////////////////////////////////////////////// 285 // UI benachrichtigen 286 FmNavClearedHint aClearedHint; 287 Broadcast( aClearedHint ); 288 } 289 290 //------------------------------------------------------------------------ 291 Reference< XNameContainer > NavigatorTreeModel::GetForms() const 292 { 293 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::GetForms" ); 294 if( !m_pFormShell || !m_pFormShell->GetCurPage()) 295 return NULL; 296 else 297 return m_pFormShell->GetCurPage()->GetForms(); 298 } 299 300 //------------------------------------------------------------------------ 301 void NavigatorTreeModel::Insert(FmEntryData* pEntry, sal_uLong nRelPos, sal_Bool bAlterModel) 302 { 303 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Insert" ); 304 if (IsListening(*m_pFormModel)) 305 EndListening(*m_pFormModel); 306 307 m_pPropChangeList->Lock(); 308 FmFormData* pFolder = (FmFormData*) pEntry->GetParent(); 309 Reference< XChild > xElement( pEntry->GetChildIFace() ); 310 if (bAlterModel) 311 { 312 XubString aStr; 313 if (pEntry->ISA(FmFormData)) 314 aStr = SVX_RES(RID_STR_FORM); 315 else 316 aStr = SVX_RES(RID_STR_CONTROL); 317 318 Reference< XIndexContainer > xContainer; 319 if (pFolder) 320 xContainer = Reference< XIndexContainer > (pFolder->GetFormIface(), UNO_QUERY); 321 else 322 xContainer = Reference< XIndexContainer > (GetForms(), UNO_QUERY); 323 324 bool bUndo = m_pFormModel->IsUndoEnabled(); 325 326 if( bUndo ) 327 { 328 XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_INSERT)); 329 aUndoStr.SearchAndReplace('#', aStr); 330 m_pFormModel->BegUndo(aUndoStr); 331 } 332 333 if (nRelPos >= (sal_uInt32)xContainer->getCount()) 334 nRelPos = (sal_uInt32)xContainer->getCount(); 335 336 // UndoAction 337 if ( bUndo && m_pPropChangeList->CanUndo()) 338 { 339 m_pFormModel->AddUndo(new FmUndoContainerAction(*m_pFormModel, 340 FmUndoContainerAction::Inserted, 341 xContainer, 342 xElement, 343 nRelPos)); 344 } 345 346 // das Element muss den Typ haben, den der Container erwartet 347 if (xContainer->getElementType() == 348 ::getCppuType((const Reference< XForm>*)0)) 349 350 { 351 Reference< XForm > xElementAsForm(xElement, UNO_QUERY); 352 xContainer->insertByIndex(nRelPos, makeAny(xElementAsForm)); 353 } 354 else if (xContainer->getElementType() == 355 ::getCppuType((const Reference< XFormComponent>*)0)) 356 357 { 358 Reference< XFormComponent > xElementAsComponent(xElement, UNO_QUERY); 359 xContainer->insertByIndex(nRelPos, makeAny(xElementAsComponent)); 360 } 361 else 362 { 363 DBG_ERROR("NavigatorTreeModel::Insert : the parent container needs an elementtype I don't know !"); 364 } 365 366 if( bUndo ) 367 m_pFormModel->EndUndo(); 368 } 369 370 ////////////////////////////////////////////////////////////////////// 371 // Als PropertyChangeListener anmelden 372 Reference< XPropertySet > xSet(xElement, UNO_QUERY); 373 if( xSet.is() ) 374 xSet->addPropertyChangeListener( FM_PROP_NAME, m_pPropChangeList ); 375 376 ////////////////////////////////////////////////////////////////////// 377 // Daten aus Model entfernen 378 if (pEntry->ISA(FmFormData)) 379 { 380 Reference< XContainer > xContainer(xElement, UNO_QUERY); 381 if (xContainer.is()) 382 xContainer->addContainerListener((XContainerListener*)m_pPropChangeList); 383 } 384 385 if (pFolder) 386 pFolder->GetChildList()->Insert( pEntry, nRelPos ); 387 else 388 GetRootList()->Insert( pEntry, nRelPos ); 389 390 ////////////////////////////////////////////////////////////////////// 391 // UI benachrichtigen 392 FmNavInsertedHint aInsertedHint( pEntry, nRelPos ); 393 Broadcast( aInsertedHint ); 394 395 m_pPropChangeList->UnLock(); 396 if (IsListening(*m_pFormModel)) 397 StartListening(*m_pFormModel); 398 } 399 400 //------------------------------------------------------------------------ 401 void NavigatorTreeModel::Remove(FmEntryData* pEntry, sal_Bool bAlterModel) 402 { 403 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Remove" ); 404 ////////////////////////////////////////////////////////////////////// 405 // Form und Parent holen 406 if (!pEntry || !m_pFormModel) 407 return; 408 409 if (IsListening(*m_pFormModel)) 410 EndListening(*m_pFormModel); 411 412 const bool bUndo = m_pFormModel->IsUndoEnabled(); 413 414 m_pPropChangeList->Lock(); 415 FmFormData* pFolder = (FmFormData*) pEntry->GetParent(); 416 Reference< XChild > xElement ( pEntry->GetChildIFace() ); 417 if (bAlterModel) 418 { 419 XubString aStr; 420 if (pEntry->ISA(FmFormData)) 421 aStr = SVX_RES(RID_STR_FORM); 422 else 423 aStr = SVX_RES(RID_STR_CONTROL); 424 425 if( bUndo ) 426 { 427 XubString aUndoStr(SVX_RES(RID_STR_UNDO_CONTAINER_REMOVE)); 428 aUndoStr.SearchAndReplace('#', aStr); 429 m_pFormModel->BegUndo(aUndoStr); 430 } 431 } 432 433 // jetzt die eigentliche Entfernung der Daten aus dem Model 434 if (pEntry->ISA(FmFormData)) 435 RemoveForm((FmFormData*)pEntry); 436 else 437 RemoveFormComponent((FmControlData*)pEntry); 438 439 440 if (bAlterModel) 441 { 442 Reference< XIndexContainer > xContainer(xElement->getParent(), UNO_QUERY); 443 // aus dem Container entfernen 444 sal_Int32 nContainerIndex = getElementPos(xContainer.get(), xElement); 445 // UndoAction 446 if (nContainerIndex >= 0) 447 { 448 if ( bUndo && m_pPropChangeList->CanUndo()) 449 { 450 m_pFormModel->AddUndo(new FmUndoContainerAction(*m_pFormModel, 451 FmUndoContainerAction::Removed, 452 xContainer, 453 xElement, nContainerIndex )); 454 } 455 else if( !m_pPropChangeList->CanUndo() ) 456 { 457 FmUndoContainerAction::DisposeElement( xElement ); 458 } 459 460 xContainer->removeByIndex(nContainerIndex ); 461 } 462 463 if( bUndo ) 464 m_pFormModel->EndUndo(); 465 } 466 467 // beim Vater austragen 468 if (pFolder) 469 pFolder->GetChildList()->Remove(pEntry); 470 else 471 { 472 GetRootList()->Remove(pEntry); 473 ////////////////////////////////////////////////////////////////////// 474 // Wenn keine Form mehr in der Root, an der Shell CurForm zuruecksetzen 475 if (!GetRootList()->Count()) 476 m_pFormShell->GetImpl()->forgetCurrentForm(); 477 } 478 479 ////////////////////////////////////////////////////////////////////// 480 // UI benachrichtigen 481 FmNavRemovedHint aRemovedHint( pEntry ); 482 Broadcast( aRemovedHint ); 483 484 // Eintrag loeschen 485 delete pEntry; 486 487 m_pPropChangeList->UnLock(); 488 StartListening(*m_pFormModel); 489 } 490 491 //------------------------------------------------------------------------ 492 void NavigatorTreeModel::RemoveForm(FmFormData* pFormData) 493 { 494 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveForm" ); 495 ////////////////////////////////////////////////////////////////////// 496 // Form und Parent holen 497 if (!pFormData || !m_pFormModel) 498 return; 499 500 FmEntryDataList* pChildList = pFormData->GetChildList(); 501 sal_uInt32 nCount = pChildList->Count(); 502 for (sal_uInt32 i = nCount; i > 0; i--) 503 { 504 FmEntryData* pEntryData = pChildList->GetObject(i - 1); 505 506 ////////////////////////////////////////////////////////////////////// 507 // Child ist Form -> rekursiver Aufruf 508 if( pEntryData->ISA(FmFormData) ) 509 RemoveForm( (FmFormData*)pEntryData); 510 else if( pEntryData->ISA(FmControlData) ) 511 RemoveFormComponent((FmControlData*) pEntryData); 512 } 513 514 ////////////////////////////////////////////////////////////////////// 515 // Als PropertyChangeListener abmelden 516 Reference< XPropertySet > xSet( pFormData->GetPropertySet() ); 517 if ( xSet.is() ) 518 xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList ); 519 520 Reference< XContainer > xContainer( pFormData->GetContainer() ); 521 if (xContainer.is()) 522 xContainer->removeContainerListener((XContainerListener*)m_pPropChangeList); 523 } 524 525 //------------------------------------------------------------------------ 526 void NavigatorTreeModel::RemoveFormComponent(FmControlData* pControlData) 527 { 528 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveFormComponent" ); 529 ////////////////////////////////////////////////////////////////////// 530 // Control und Parent holen 531 if (!pControlData) 532 return; 533 534 ////////////////////////////////////////////////////////////////////// 535 // Als PropertyChangeListener abmelden 536 Reference< XPropertySet > xSet( pControlData->GetPropertySet() ); 537 if (xSet.is()) 538 xSet->removePropertyChangeListener( FM_PROP_NAME, m_pPropChangeList); 539 } 540 541 //------------------------------------------------------------------------ 542 void NavigatorTreeModel::ClearBranch( FmFormData* pParentData ) 543 { 544 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::ClearBranch" ); 545 ////////////////////////////////////////////////////////////////////// 546 // Alle Eintraege dieses Zweiges loeschen 547 FmEntryDataList* pChildList = pParentData->GetChildList(); 548 FmEntryData* pChildData; 549 550 for( sal_uInt32 i=pChildList->Count(); i>0; i-- ) 551 { 552 pChildData = pChildList->GetObject(i-1); 553 if( pChildData->ISA(FmFormData) ) 554 ClearBranch( (FmFormData*)pChildData ); 555 556 pChildList->Remove( pChildData ); 557 } 558 } 559 560 //------------------------------------------------------------------------ 561 void NavigatorTreeModel::FillBranch( FmFormData* pFormData ) 562 { 563 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FillBranch" ); 564 ////////////////////////////////////////////////////////////// 565 // Forms aus der Root einfuegen 566 if( pFormData == NULL ) 567 { 568 Reference< XIndexContainer > xForms(GetForms(), UNO_QUERY); 569 if (!xForms.is()) 570 return; 571 572 Reference< XForm > xSubForm; 573 FmFormData* pSubFormData; 574 for (sal_Int32 i=0; i<xForms->getCount(); ++i) 575 { 576 DBG_ASSERT( xForms->getByIndex(i).getValueType() == ::getCppuType((const Reference< XForm>*)NULL), 577 "NavigatorTreeModel::FillBranch : the root container should supply only elements of type XForm"); 578 579 xForms->getByIndex(i) >>= xSubForm; 580 pSubFormData = new FmFormData( xSubForm, m_aNormalImages, m_aHCImages, pFormData ); 581 Insert( pSubFormData, LIST_APPEND ); 582 583 ////////////////////////////////////////////////////////////// 584 // Neuer Branch, wenn SubForm wiederum Subforms enthaelt 585 FillBranch( pSubFormData ); 586 } 587 } 588 589 ////////////////////////////////////////////////////////////// 590 // Componenten einfuegen 591 else 592 { 593 Reference< XIndexContainer > xComponents( GetFormComponents(pFormData)); 594 if( !xComponents.is() ) return; 595 596 ::rtl::OUString aControlName; 597 Reference< XInterface > xInterface; 598 Reference< XPropertySet > xSet; 599 FmControlData* pNewControlData; 600 FmFormData* pSubFormData; 601 602 Reference< XFormComponent > xCurrentComponent; 603 for (sal_Int32 j=0; j<xComponents->getCount(); ++j) 604 { 605 xComponents->getByIndex(j) >>= xCurrentComponent; 606 Reference< XForm > xSubForm(xCurrentComponent, UNO_QUERY); 607 608 if (xSubForm.is()) 609 { // die aktuelle Component ist eine Form 610 pSubFormData = new FmFormData(xSubForm, m_aNormalImages, m_aHCImages, pFormData); 611 Insert(pSubFormData, LIST_APPEND); 612 613 ////////////////////////////////////////////////////////////// 614 // Neuer Branch, wenn SubForm wiederum Subforms enthaelt 615 FillBranch(pSubFormData); 616 } 617 else 618 { 619 pNewControlData = new FmControlData(xCurrentComponent, m_aNormalImages, m_aHCImages, pFormData); 620 Insert(pNewControlData, LIST_APPEND); 621 } 622 } 623 } 624 } 625 626 //------------------------------------------------------------------------ 627 void NavigatorTreeModel::InsertForm(const Reference< XForm > & xForm, sal_uInt32 nRelPos) 628 { 629 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertForm" ); 630 FmFormData* pFormData = (FmFormData*)FindData( xForm, GetRootList() ); 631 if (pFormData) 632 return; 633 634 ////////////////////////////////////////////////////////// 635 // ParentData setzen 636 Reference< XInterface > xIFace( xForm->getParent()); 637 Reference< XForm > xParentForm(xIFace, UNO_QUERY); 638 FmFormData* pParentData = NULL; 639 if (xParentForm.is()) 640 pParentData = (FmFormData*)FindData( xParentForm, GetRootList() ); 641 642 pFormData = new FmFormData( xForm, m_aNormalImages, m_aHCImages, pParentData ); 643 Insert( pFormData, nRelPos ); 644 } 645 646 //------------------------------------------------------------------------ 647 void NavigatorTreeModel::InsertFormComponent(const Reference< XFormComponent > & xComp, sal_uInt32 nRelPos) 648 { 649 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertFormComponent" ); 650 ////////////////////////////////////////////////////////// 651 // ParentData setzen 652 Reference< XInterface > xIFace( xComp->getParent()); 653 Reference< XForm > xForm(xIFace, UNO_QUERY); 654 if (!xForm.is()) 655 return; 656 657 FmFormData* pParentData = (FmFormData*)FindData( xForm, GetRootList() ); 658 if( !pParentData ) 659 { 660 pParentData = new FmFormData( xForm, m_aNormalImages, m_aHCImages, NULL ); 661 Insert( pParentData, LIST_APPEND ); 662 } 663 664 if (!FindData(xComp, pParentData->GetChildList(),sal_False)) 665 { 666 ////////////////////////////////////////////////////////// 667 // Neue EntryData setzen 668 FmEntryData* pNewEntryData = new FmControlData( xComp, m_aNormalImages, m_aHCImages, pParentData ); 669 670 ////////////////////////////////////////////////////////// 671 // Neue EntryData einfuegen 672 Insert( pNewEntryData, nRelPos ); 673 } 674 } 675 676 //------------------------------------------------------------------------ 677 void NavigatorTreeModel::ReplaceFormComponent(const Reference< XFormComponent > & xOld, const Reference< XFormComponent > & xNew) 678 { 679 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::ReplaceFormComponent" ); 680 FmEntryData* pData = FindData(xOld, GetRootList(), sal_True); 681 DBG_ASSERT(pData && pData->ISA(FmControlData), "NavigatorTreeModel::ReplaceFormComponent : invalid argument !"); 682 ((FmControlData*)pData)->ModelReplaced( xNew, m_aNormalImages, m_aHCImages ); 683 684 FmNavModelReplacedHint aReplacedHint( pData ); 685 Broadcast( aReplacedHint ); 686 } 687 688 //------------------------------------------------------------------------ 689 FmEntryData* NavigatorTreeModel::FindData(const Reference< XInterface > & xElement, FmEntryDataList* pDataList, sal_Bool bRecurs) 690 { 691 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FindData" ); 692 // normalize 693 Reference< XInterface > xIFace( xElement, UNO_QUERY ); 694 695 for (sal_uInt16 i=0; i < pDataList->Count(); i++) 696 { 697 FmEntryData* pEntryData = pDataList->GetObject(i); 698 if ( pEntryData->GetElement().get() == xIFace.get() ) 699 return pEntryData; 700 else if (bRecurs) 701 { 702 pEntryData = FindData( xElement, pEntryData->GetChildList() ); 703 if (pEntryData) 704 return pEntryData; 705 } 706 } 707 return NULL; 708 } 709 710 //------------------------------------------------------------------------ 711 FmEntryData* NavigatorTreeModel::FindData( const ::rtl::OUString& rText, FmFormData* pParentData, sal_Bool bRecurs ) 712 { 713 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::FindData" ); 714 FmEntryDataList* pDataList; 715 if( !pParentData ) 716 pDataList = GetRootList(); 717 else 718 pDataList = pParentData->GetChildList(); 719 720 ::rtl::OUString aEntryText; 721 FmEntryData* pEntryData; 722 FmEntryData* pChildData; 723 724 for( sal_uInt16 i=0; i<pDataList->Count(); i++ ) 725 { 726 pEntryData = pDataList->GetObject(i); 727 aEntryText = pEntryData->GetText(); 728 729 if (rText == aEntryText) 730 return pEntryData; 731 732 if( bRecurs && pEntryData->ISA(FmFormData) ) 733 { 734 pChildData = FindData( rText, (FmFormData*)pEntryData ); 735 if( pChildData ) 736 return pChildData; 737 } 738 } 739 740 return NULL; 741 } 742 743 //------------------------------------------------------------------------ 744 void NavigatorTreeModel::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint ) 745 { 746 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Notify" ); 747 if( rHint.ISA(SdrHint) ) 748 { 749 SdrHint* pSdrHint = (SdrHint*)&rHint; 750 switch( pSdrHint->GetKind() ) 751 { 752 case HINT_OBJINSERTED: 753 InsertSdrObj(pSdrHint->GetObject()); 754 break; 755 case HINT_OBJREMOVED: 756 RemoveSdrObj(pSdrHint->GetObject()); 757 break; 758 default: 759 break; 760 } 761 } 762 // hat sich die shell verabschiedet? 763 else if ( rHint.ISA(SfxSimpleHint) && ((SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING) 764 UpdateContent((FmFormShell*)NULL); 765 766 // hat sich die Markierung der Controls veraendert ? 767 else if (rHint.ISA(FmNavViewMarksChanged)) 768 { 769 FmNavViewMarksChanged* pvmcHint = (FmNavViewMarksChanged*)&rHint; 770 BroadcastMarkedObjects( pvmcHint->GetAffectedView()->GetMarkedObjectList() ); 771 } 772 } 773 774 //------------------------------------------------------------------------ 775 void NavigatorTreeModel::InsertSdrObj( const SdrObject* pObj ) 776 { 777 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertSdrObj" ); 778 const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj ); 779 if ( pFormObject ) 780 { 781 try 782 { 783 Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW ); 784 Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW ); 785 786 sal_Int32 nPos = getElementPos( xContainer, xFormComponent ); 787 InsertFormComponent( xFormComponent, nPos ); 788 } 789 catch( const Exception& ) 790 { 791 DBG_UNHANDLED_EXCEPTION(); 792 } 793 } 794 else if ( pObj->IsGroupObject() ) 795 { 796 SdrObjListIter aIter( *pObj->GetSubList() ); 797 while ( aIter.IsMore() ) 798 InsertSdrObj( aIter.Next() ); 799 } 800 } 801 802 //------------------------------------------------------------------------ 803 void NavigatorTreeModel::RemoveSdrObj( const SdrObject* pObj ) 804 { 805 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::RemoveSdrObj" ); 806 const FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj ); 807 if ( pFormObject ) 808 { 809 try 810 { 811 Reference< XFormComponent > xFormComponent( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW ); 812 FmEntryData* pEntryData = FindData( xFormComponent, GetRootList(), sal_True ); 813 if ( pEntryData ) 814 Remove( pEntryData ); 815 } 816 catch( const Exception& ) 817 { 818 DBG_UNHANDLED_EXCEPTION(); 819 } 820 } 821 else if ( pObj->IsGroupObject() ) 822 { 823 SdrObjListIter aIter( *pObj->GetSubList() ); 824 while ( aIter.IsMore() ) 825 RemoveSdrObj( aIter.Next() ); 826 } 827 } 828 829 sal_Bool NavigatorTreeModel::InsertFormComponent(FmNavRequestSelectHint& rHint, SdrObject* pObject) 830 { 831 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::InsertFormComponent" ); 832 if ( pObject->ISA(SdrObjGroup) ) 833 { // rekursiv absteigen 834 const SdrObjList *pChilds = ((SdrObjGroup*)pObject)->GetSubList(); 835 for ( sal_uInt16 i=0; i<pChilds->GetObjCount(); ++i ) 836 { 837 SdrObject* pCurrent = pChilds->GetObj(i); 838 if (!InsertFormComponent(rHint, pCurrent)) 839 return sal_False; 840 } 841 } 842 else 843 { 844 FmFormObj* pFormObject = FmFormObj::GetFormObject( pObject ); 845 if ( !pFormObject ) 846 return sal_False; 847 848 try 849 { 850 Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY_THROW ); 851 FmEntryData* pControlData = FindData( xFormViewControl, GetRootList() ); 852 if ( !pControlData ) 853 return sal_False; 854 855 rHint.AddItem( pControlData ); 856 return sal_True; 857 } 858 catch( const Exception& ) 859 { 860 DBG_UNHANDLED_EXCEPTION(); 861 return sal_False; 862 } 863 } 864 865 return sal_True; 866 } 867 868 void NavigatorTreeModel::BroadcastMarkedObjects(const SdrMarkList& mlMarked) 869 { 870 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::BroadcastMarkedObjects" ); 871 // gehen wir durch alle markierten Objekte und suchen wir die raus, mit denen ich was anfangen kann 872 FmNavRequestSelectHint rshRequestSelection; 873 sal_Bool bIsMixedSelection = sal_False; 874 875 for (sal_uLong i=0; (i<mlMarked.GetMarkCount()) && !bIsMixedSelection; i++) 876 { 877 SdrObject* pobjCurrent = mlMarked.GetMark(i)->GetMarkedSdrObj(); 878 bIsMixedSelection |= !InsertFormComponent(rshRequestSelection, pobjCurrent); 879 // bei einem Nicht-Form-Control liefert InsertFormComponent sal_False ! 880 } 881 882 rshRequestSelection.SetMixedSelection(bIsMixedSelection); 883 if (bIsMixedSelection) 884 rshRequestSelection.ClearItems(); 885 886 Broadcast(rshRequestSelection); 887 // eine leere Liste interpretiert der NavigatorTree so, dass er seine Selektion komplett rausnimmt 888 } 889 890 //------------------------------------------------------------------------ 891 void NavigatorTreeModel::UpdateContent( const Reference< XNameContainer > & xForms ) 892 { 893 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::UpdateContent" ); 894 ////////////////////////////////////////////////////////////////////// 895 // Model von der Root aufwaerts neu fuellen 896 Clear(); 897 if (xForms.is()) 898 { 899 Reference< XContainer > xFormContainer(xForms, UNO_QUERY); 900 if (xFormContainer.is()) 901 xFormContainer->addContainerListener((XContainerListener*)m_pPropChangeList); 902 903 FillBranch(NULL); 904 905 // jetzt in meinem Tree genau die das in meiner View markierte Control selektieren 906 // (bzw alle solchen), falls es eines gibt ... 907 if(!m_pFormShell) return; // keine Shell -> wech 908 909 FmFormView* pFormView = m_pFormShell->GetFormView(); 910 DBG_ASSERT(pFormView != NULL, "NavigatorTreeModel::UpdateContent : keine FormView"); 911 BroadcastMarkedObjects(pFormView->GetMarkedObjectList()); 912 } 913 } 914 915 //------------------------------------------------------------------------ 916 void NavigatorTreeModel::UpdateContent( FmFormShell* pShell ) 917 { 918 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::UpdateContent" ); 919 ////////////////////////////////////////////////////////////////////// 920 // Wenn Shell sich nicht veraendert hat, nichts machen 921 FmFormPage* pNewPage = pShell ? pShell->GetCurPage() : NULL; 922 if ((pShell == m_pFormShell) && (m_pFormPage == pNewPage)) 923 return; 924 925 ////////////////////////////////////////////////////////////////////// 926 // Als Listener abmelden 927 if( m_pFormShell ) 928 { 929 if (m_pFormModel) 930 EndListening( *m_pFormModel ); 931 m_pFormModel = NULL; 932 EndListening( *m_pFormShell ); 933 Clear(); 934 } 935 936 ////////////////////////////////////////////////////////////////////// 937 // Vollupdate 938 m_pFormShell = pShell; 939 if (m_pFormShell) 940 { 941 m_pFormPage = pNewPage; 942 UpdateContent(m_pFormPage->GetForms()); 943 } else 944 m_pFormPage = NULL; 945 946 ////////////////////////////////////////////////////////////////////// 947 // Als Listener neu anmelden 948 if( m_pFormShell ) 949 { 950 StartListening( *m_pFormShell ); 951 m_pFormModel = m_pFormShell->GetFormModel(); 952 if( m_pFormModel ) 953 StartListening( *m_pFormModel ); 954 } 955 } 956 957 //------------------------------------------------------------------------ 958 Reference< XIndexContainer > NavigatorTreeModel::GetFormComponents( FmFormData* pFormData ) 959 { 960 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::GetFormComponents" ); 961 ////////////////////////////////////////////////////////////////////// 962 // Von der Form Components holen 963 if (pFormData) 964 return Reference< XIndexContainer > (pFormData->GetFormIface(), UNO_QUERY); 965 966 return Reference< XIndexContainer > (); 967 } 968 969 //------------------------------------------------------------------------ 970 sal_Bool NavigatorTreeModel::CheckEntry( FmEntryData* pEntryData ) 971 { 972 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::CheckEntry" ); 973 ////////////////////////////////////////////////////////////////////// 974 // Nur Forms duerfen auf Doppeldeutigkeit untersucht werden 975 if( !pEntryData->ISA(FmFormData) ) return sal_True; 976 977 ////////////////////////////////////////////////////////////////////// 978 // ChildListe des Parents holen 979 FmFormData* pParentData = (FmFormData*)pEntryData->GetParent(); 980 FmEntryDataList* pChildList; 981 if( !pParentData ) 982 pChildList = GetRootList(); 983 else 984 pChildList = pParentData->GetChildList(); 985 986 ////////////////////////////////////////////////////////////////////// 987 // In ChildListe nach doppelten Namen suchen 988 ::rtl::OUString aChildText; 989 FmEntryData* pChildData; 990 991 for( sal_uInt16 i=0; i<pChildList->Count(); i++ ) 992 { 993 pChildData = pChildList->GetObject(i); 994 aChildText = pChildData->GetText(); 995 996 ////////////////////////////////////////////////////////////////////// 997 // Gleichen Eintrag gefunden 998 if ( (aChildText == pEntryData->GetText()) 999 && (pEntryData!=pChildData) 1000 ) 1001 { 1002 1003 1004 SQLContext aError; 1005 aError.Message = String(SVX_RES(RID_ERR_CONTEXT_ADDFORM)); 1006 aError.Details = String(SVX_RES(RID_ERR_DUPLICATE_NAME)); 1007 displayException(aError); 1008 1009 return sal_False; 1010 } 1011 } 1012 1013 return sal_True; 1014 } 1015 1016 //------------------------------------------------------------------------ 1017 sal_Bool NavigatorTreeModel::Rename( FmEntryData* pEntryData, const ::rtl::OUString& rNewText ) 1018 { 1019 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Rename" ); 1020 ////////////////////////////////////////////////////////////////////// 1021 // Wenn Name schon vorhanden, Fehlermeldung 1022 pEntryData->SetText( rNewText ); 1023 1024 ////////////////////////////////////////////////////////////////////// 1025 // PropertySet besorgen 1026 Reference< XFormComponent > xFormComponent; 1027 1028 if( pEntryData->ISA(FmFormData) ) 1029 { 1030 FmFormData* pFormData = (FmFormData*)pEntryData; 1031 Reference< XForm > xForm( pFormData->GetFormIface()); 1032 xFormComponent = Reference< XFormComponent > (xForm, UNO_QUERY); 1033 } 1034 1035 if( pEntryData->ISA(FmControlData) ) 1036 { 1037 FmControlData* pControlData = (FmControlData*)pEntryData; 1038 xFormComponent = pControlData->GetFormComponent(); 1039 } 1040 1041 if( !xFormComponent.is() ) return sal_False; 1042 Reference< XPropertySet > xSet(xFormComponent, UNO_QUERY); 1043 if( !xSet.is() ) return sal_False; 1044 1045 ////////////////////////////////////////////////////////////////////// 1046 // Namen setzen 1047 xSet->setPropertyValue( FM_PROP_NAME, makeAny(rNewText) ); 1048 1049 return sal_True; 1050 } 1051 1052 //------------------------------------------------------------------------ 1053 sal_Bool NavigatorTreeModel::IsNameAlreadyDefined( const ::rtl::OUString& rName, FmFormData* pParentData ) 1054 { 1055 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::IsNameAlreadyDefined" ); 1056 ////////////////////////////////////////////////////////////////////// 1057 // Form in der Root 1058 if( !pParentData ) 1059 { 1060 if (GetForms()->hasByName(rName)) 1061 return sal_True; 1062 } 1063 1064 ////////////////////////////////////////////////////////////////////// 1065 // Restliche Components 1066 else 1067 { 1068 Reference< XNameContainer > xFormComponents(GetFormComponents(pParentData), UNO_QUERY); 1069 if (xFormComponents.is() && xFormComponents->hasByName(rName)) 1070 return sal_True; 1071 } 1072 1073 return sal_False; 1074 } 1075 1076 //------------------------------------------------------------------------ 1077 SdrObject* NavigatorTreeModel::GetSdrObj( FmControlData* pControlData ) 1078 { 1079 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::GetSdrObj" ); 1080 if (!pControlData || !m_pFormShell) 1081 return NULL; 1082 1083 ////////////////////////////////////////////////////////////////////// 1084 // In der Page das entsprechende SdrObj finden und selektieren 1085 Reference< XFormComponent > xFormComponent( pControlData->GetFormComponent()); 1086 if (!xFormComponent.is()) 1087 return NULL; 1088 1089 FmFormView* pFormView = m_pFormShell->GetFormView(); 1090 SdrPageView* pPageView = pFormView->GetSdrPageView(); 1091 SdrPage* pPage = pPageView->GetPage(); 1092 1093 SdrObjListIter aIter( *pPage ); 1094 return Search(aIter, xFormComponent); 1095 } 1096 1097 //------------------------------------------------------------------ 1098 SdrObject* NavigatorTreeModel::Search(SdrObjListIter& rIter, const Reference< XFormComponent > & xComp) 1099 { 1100 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "NavigatorTreeModel::Search" ); 1101 while (rIter.IsMore()) 1102 { 1103 SdrObject* pObj = rIter.Next(); 1104 FmFormObj* pFormObject = FmFormObj::GetFormObject( pObj ); 1105 if ( pFormObject ) 1106 { 1107 Reference< XFormComponent > xFormViewControl( pFormObject->GetUnoControlModel(), UNO_QUERY ); 1108 if ( xFormViewControl == xComp ) 1109 return pObj; 1110 } 1111 else if ( pObj->IsGroupObject() ) 1112 { 1113 SdrObjListIter aIter( *pObj->GetSubList() ); 1114 pObj = Search( aIter, xComp ); 1115 if ( pObj ) 1116 return pObj; 1117 } 1118 } 1119 return NULL; 1120 } 1121 1122 //............................................................................ 1123 } // namespace svxform 1124 //............................................................................ 1125 1126 1127