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_sw.hxx" 30 31 #include <hintids.hxx> 32 #include <rtl/logfile.hxx> 33 #include <vcl/outdev.hxx> 34 #include <sfx2/printer.hxx> 35 #include <editeng/eeitem.hxx> 36 #include <editeng/flditem.hxx> 37 #include <editeng/editeng.hxx> 38 #include <svx/svdoutl.hxx> 39 #include <editeng/colritem.hxx> 40 #include <svx/svdpage.hxx> 41 #include <svx/svdogrp.hxx> 42 #include <editeng/langitem.hxx> 43 #include <editeng/unolingu.hxx> 44 #include <editeng/measfld.hxx> 45 #include <svx/svdpool.hxx> 46 #include <fmtanchr.hxx> 47 #include <charatr.hxx> 48 #include <frmfmt.hxx> 49 #include <charfmt.hxx> 50 #include <viewimp.hxx> 51 #include <swhints.hxx> 52 #include <doc.hxx> 53 #include <IDocumentUndoRedo.hxx> 54 #include <docsh.hxx> 55 #include <rootfrm.hxx> //Damit der RootDtor gerufen wird. 56 #include <poolfmt.hxx> 57 #include <viewsh.hxx> // fuer MakeDrawView 58 #include <drawdoc.hxx> 59 #include <UndoDraw.hxx> 60 #include <swundo.hxx> // fuer die UndoIds 61 #include <dcontact.hxx> 62 #include <dview.hxx> 63 #include <mvsave.hxx> 64 #include <flyfrm.hxx> 65 #include <dflyobj.hxx> 66 #include <svx/svdetc.hxx> 67 #include <editeng/fhgtitem.hxx> 68 #include <svx/svdpagv.hxx> 69 #include <dcontact.hxx> 70 #include <txtfrm.hxx> 71 #include <frmfmt.hxx> 72 #include <editeng/frmdiritem.hxx> 73 #include <fmtornt.hxx> 74 #include <svx/svditer.hxx> 75 #include <vector> 76 #include <switerator.hxx> 77 78 using namespace ::com::sun::star; 79 using namespace ::com::sun::star::linguistic2; 80 81 82 SV_IMPL_VARARR_SORT( _ZSortFlys, _ZSortFly ) 83 84 /************************************************************************* 85 |* 86 |* SwDoc::GroupSelection / SwDoc::UnGroupSelection 87 |* 88 |* Ersterstellung JP 21.08.95 89 |* Letzte Aenderung JP 21.08.95 90 |* 91 |*************************************************************************/ 92 // OD 2004-04-01 #i26791# - local method to determine positioning and 93 // alignment attributes for a drawing object, which is newly connected to 94 // the layout. Used for a newly formed group object <SwDoc::GroupSelection(..)> 95 // and the members of a destroyed group <SwDoc::UnGroupSelection(..)> 96 void lcl_AdjustPositioningAttr( SwDrawFrmFmt* _pFrmFmt, 97 const SdrObject& _rSdrObj ) 98 { 99 const SwContact* pContact = GetUserCall( &_rSdrObj ); 100 ASSERT( pContact, "<lcl_AdjustPositioningAttr(..)> - missing contact object." ); 101 102 // determine position of new group object relative to its anchor frame position 103 SwTwips nHoriRelPos = 0; 104 SwTwips nVertRelPos = 0; 105 { 106 const SwFrm* pAnchorFrm = pContact->GetAnchoredObj( &_rSdrObj )->GetAnchorFrm(); 107 ASSERT( !pAnchorFrm || 108 !pAnchorFrm->IsTxtFrm() || 109 !static_cast<const SwTxtFrm*>(pAnchorFrm)->IsFollow(), 110 "<lcl_AdjustPositioningAttr(..)> - anchor frame is a follow. Please inform OD." ); 111 bool bVert = false; 112 bool bR2L = false; 113 // --> OD 2005-05-10 #i45952# - use anchor position of 114 // anchor frame, if it exist. 115 Point aAnchorPos; 116 if ( pAnchorFrm ) 117 { 118 // --> OD 2005-05-10 #i45952# 119 aAnchorPos = pAnchorFrm->GetFrmAnchorPos( ::HasWrap( &_rSdrObj ) ); 120 // <-- 121 bVert = pAnchorFrm->IsVertical(); 122 bR2L = pAnchorFrm->IsRightToLeft(); 123 } 124 else 125 { 126 // --> OD 2005-05-10 #i45952# 127 aAnchorPos = _rSdrObj.GetAnchorPos(); 128 // <-- 129 // If no anchor frame exist - e.g. because no layout exists - the 130 // default layout direction is taken. 131 const SvxFrameDirectionItem* pDirItem = 132 static_cast<const SvxFrameDirectionItem*>(&(_pFrmFmt->GetAttrSet().GetPool()->GetDefaultItem( RES_FRAMEDIR ))); 133 switch ( pDirItem->GetValue() ) 134 { 135 case FRMDIR_VERT_TOP_LEFT: 136 { 137 // vertical from left-to-right - Badaa: supported now! 138 bVert = true; 139 bR2L = true; 140 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 141 //ASSERT( false, "<lcl_AdjustPositioningAttr(..)> - vertical from left-to-right not supported." ); 142 //End 143 } 144 break; 145 case FRMDIR_VERT_TOP_RIGHT: 146 { 147 // vertical from right-to-left 148 bVert = true; 149 bR2L = false; 150 } 151 break; 152 case FRMDIR_HORI_RIGHT_TOP: 153 { 154 // horizontal from right-to-left 155 bVert = false; 156 bR2L = true; 157 } 158 break; 159 case FRMDIR_HORI_LEFT_TOP: 160 { 161 // horizontal from left-to-right 162 bVert = false; 163 bR2L = false; 164 } 165 break; 166 } 167 168 } 169 // use geometry of drawing object 170 const SwRect aObjRect = _rSdrObj.GetSnapRect(); 171 172 if ( bVert ) 173 { 174 if ( bR2L ) { 175 //FRMDIR_VERT_TOP_LEFT 176 nHoriRelPos = aObjRect.Left() - aAnchorPos.X(); 177 nVertRelPos = aObjRect.Top() - aAnchorPos.Y(); 178 } else { 179 //FRMDIR_VERT_TOP_RIGHT 180 nHoriRelPos = aObjRect.Top() - aAnchorPos.Y(); 181 nVertRelPos = aAnchorPos.X() - aObjRect.Right(); 182 } 183 } 184 else if ( bR2L ) 185 { 186 nHoriRelPos = aAnchorPos.X() - aObjRect.Right(); 187 nVertRelPos = aObjRect.Top() - aAnchorPos.Y(); 188 } 189 else 190 { 191 nHoriRelPos = aObjRect.Left() - aAnchorPos.X(); 192 nVertRelPos = aObjRect.Top() - aAnchorPos.Y(); 193 } 194 //End of SCMS 195 } 196 197 _pFrmFmt->SetFmtAttr( SwFmtHoriOrient( nHoriRelPos, text::HoriOrientation::NONE, text::RelOrientation::FRAME ) ); 198 _pFrmFmt->SetFmtAttr( SwFmtVertOrient( nVertRelPos, text::VertOrientation::NONE, text::RelOrientation::FRAME ) ); 199 // --> OD 2005-03-11 #i44334#, #i44681# - positioning attributes already set 200 _pFrmFmt->PosAttrSet(); 201 // <-- 202 // --> OD 2004-10-01 #i34750# - keep current object rectangle for drawing 203 // objects. The object rectangle is used on events from the drawing layer 204 // to adjust the positioning attributes - see <SwDrawContact::_Changed(..)>. 205 { 206 const SwAnchoredObject* pAnchoredObj = pContact->GetAnchoredObj( &_rSdrObj ); 207 if ( pAnchoredObj->ISA(SwAnchoredDrawObject) ) 208 { 209 const SwAnchoredDrawObject* pAnchoredDrawObj = 210 static_cast<const SwAnchoredDrawObject*>(pAnchoredObj); 211 const SwRect aObjRect = _rSdrObj.GetSnapRect(); 212 const_cast<SwAnchoredDrawObject*>(pAnchoredDrawObj) 213 ->SetLastObjRect( aObjRect.SVRect() ); 214 } 215 } 216 // <-- 217 } 218 219 SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView ) 220 { 221 // OD 30.06.2003 #108784# - replace marked 'virtual' drawing objects by 222 // the corresponding 'master' drawing objects. 223 SwDrawView::ReplaceMarkedDrawVirtObjs( rDrawView ); 224 225 const SdrMarkList &rMrkList = rDrawView.GetMarkedObjectList(); 226 SwDrawFrmFmt *pFmt = 0L; 227 SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj(); 228 sal_Bool bNoGroup = ( 0 == pObj->GetUpGroup() ); 229 SwDrawContact* pNewContact = 0; 230 if( bNoGroup ) 231 { 232 //Ankerattribut aufheben. 233 SwDrawContact *pMyContact = (SwDrawContact*)GetUserCall(pObj); 234 const SwFmtAnchor aAnch( pMyContact->GetFmt()->GetAnchor() ); 235 236 SwUndoDrawGroup *const pUndo = (!GetIDocumentUndoRedo().DoesUndo()) 237 ? 0 238 : new SwUndoDrawGroup( (sal_uInt16)rMrkList.GetMarkCount() ); 239 240 // --> OD 2005-08-16 #i53320# 241 bool bGroupMembersNotPositioned( false ); 242 { 243 SwAnchoredDrawObject* pAnchoredDrawObj = 244 static_cast<SwAnchoredDrawObject*>(pMyContact->GetAnchoredObj( pObj )); 245 bGroupMembersNotPositioned = pAnchoredDrawObj->NotYetPositioned(); 246 } 247 // <-- 248 //ContactObjekte und Formate vernichten. 249 for( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i ) 250 { 251 pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 252 SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj); 253 254 // --> OD 2005-08-16 #i53320# 255 #ifdef DBG_UTIL 256 SwAnchoredDrawObject* pAnchoredDrawObj = 257 static_cast<SwAnchoredDrawObject*>(pContact->GetAnchoredObj( pObj )); 258 ASSERT( bGroupMembersNotPositioned == pAnchoredDrawObj->NotYetPositioned(), 259 "<SwDoc::GroupSelection(..)> - group members have different positioning status!" ); 260 #endif 261 // <-- 262 263 pFmt = (SwDrawFrmFmt*)pContact->GetFmt(); 264 //loescht sich selbst! 265 pContact->Changed(*pObj, SDRUSERCALL_DELETE, pObj->GetLastBoundRect() ); 266 pObj->SetUserCall( 0 ); 267 268 if( pUndo ) 269 pUndo->AddObj( i, pFmt, pObj ); 270 else 271 DelFrmFmt( pFmt ); 272 273 // --> OD 2005-05-10 #i45952# - re-introduce position 274 // normalization of group member objects, because its anchor position 275 // is cleared, when they are grouped. 276 Point aAnchorPos( pObj->GetAnchorPos() ); 277 pObj->NbcSetAnchorPos( Point( 0, 0 ) ); 278 pObj->NbcMove( Size( aAnchorPos.X(), aAnchorPos.Y() ) ); 279 // <-- 280 } 281 282 pFmt = MakeDrawFrmFmt( String::CreateFromAscii( 283 RTL_CONSTASCII_STRINGPARAM( "DrawObject" )), 284 GetDfltFrmFmt() ); 285 pFmt->SetFmtAttr( aAnch ); 286 // --> OD 2004-10-25 #i36010# - set layout direction of the position 287 pFmt->SetPositionLayoutDir( 288 text::PositionLayoutDir::PositionInLayoutDirOfAnchor ); 289 // <-- 290 291 rDrawView.GroupMarked(); 292 ASSERT( rMrkList.GetMarkCount() == 1, "GroupMarked more or none groups." ); 293 294 SdrObject* pNewGroupObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj(); 295 pNewContact = new SwDrawContact( pFmt, pNewGroupObj ); 296 // --> OD 2004-11-22 #i35635# 297 pNewContact->MoveObjToVisibleLayer( pNewGroupObj ); 298 // <-- 299 pNewContact->ConnectToLayout(); 300 // --> OD 2005-08-16 #i53320# - No adjustment of the positioning and 301 // alignment attributes, if group members aren't positioned yet. 302 if ( !bGroupMembersNotPositioned ) 303 { 304 // OD 2004-04-01 #i26791# - Adjust positioning and alignment attributes. 305 lcl_AdjustPositioningAttr( pFmt, *pNewGroupObj ); 306 } 307 // <-- 308 309 if( pUndo ) 310 { 311 pUndo->SetGroupFmt( pFmt ); 312 GetIDocumentUndoRedo().AppendUndo( pUndo ); 313 } 314 } 315 else 316 { 317 if (GetIDocumentUndoRedo().DoesUndo()) 318 { 319 GetIDocumentUndoRedo().ClearRedo(); 320 } 321 322 rDrawView.GroupMarked(); 323 ASSERT( rMrkList.GetMarkCount() == 1, "GroupMarked more or none groups." ); 324 } 325 326 return pNewContact; 327 } 328 329 330 void SwDoc::UnGroupSelection( SdrView& rDrawView ) 331 { 332 bool const bUndo = GetIDocumentUndoRedo().DoesUndo(); 333 if( bUndo ) 334 { 335 GetIDocumentUndoRedo().ClearRedo(); 336 } 337 338 // OD 30.06.2003 #108784# - replace marked 'virtual' drawing objects by 339 // the corresponding 'master' drawing objects. 340 SwDrawView::ReplaceMarkedDrawVirtObjs( rDrawView ); 341 342 const SdrMarkList &rMrkList = rDrawView.GetMarkedObjectList(); 343 // --> OD 2006-11-01 #130889# 344 std::vector< std::pair< SwDrawFrmFmt*, SdrObject* > >* pFmtsAndObjs( 0L ); 345 const sal_uInt32 nMarkCount( rMrkList.GetMarkCount() ); 346 // <-- 347 if ( nMarkCount ) 348 { 349 // --> OD 2006-11-01 #130889# 350 pFmtsAndObjs = new std::vector< std::pair< SwDrawFrmFmt*, SdrObject* > >[nMarkCount]; 351 // <-- 352 SdrObject *pMyObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj(); 353 if( !pMyObj->GetUpGroup() ) 354 { 355 String sDrwFmtNm( String::CreateFromAscii( 356 RTL_CONSTASCII_STRINGPARAM("DrawObject" ))); 357 for ( sal_uInt16 i = 0; i < nMarkCount; ++i ) 358 { 359 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 360 if ( pObj->IsA( TYPE(SdrObjGroup) ) ) 361 { 362 SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj); 363 SwFmtAnchor aAnch( pContact->GetFmt()->GetAnchor() ); 364 SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList(); 365 366 SwUndoDrawUnGroup* pUndo = 0; 367 if( bUndo ) 368 { 369 pUndo = new SwUndoDrawUnGroup( (SdrObjGroup*)pObj ); 370 GetIDocumentUndoRedo().AppendUndo(pUndo); 371 } 372 373 for ( sal_uInt16 i2 = 0; i2 < pLst->GetObjCount(); ++i2 ) 374 { 375 SdrObject* pSubObj = pLst->GetObj( i2 ); 376 SwDrawFrmFmt *pFmt = MakeDrawFrmFmt( sDrwFmtNm, 377 GetDfltFrmFmt() ); 378 pFmt->SetFmtAttr( aAnch ); 379 // --> OD 2004-10-25 #i36010# - set layout direction of the position 380 pFmt->SetPositionLayoutDir( 381 text::PositionLayoutDir::PositionInLayoutDirOfAnchor ); 382 // <-- 383 // --> OD 2006-11-01 #130889# 384 // creation of <SwDrawContact> instances for the group 385 // members and its connection to the Writer layout is 386 // done after intrinsic ungrouping. 387 // SwDrawContact* pContact = new SwDrawContact( pFmt, pSubObj ); 388 // // --> OD 2004-11-22 #i35635# 389 // pContact->MoveObjToVisibleLayer( pSubObj ); 390 // // <-- 391 // pContact->ConnectToLayout(); 392 // // OD 2004-04-07 #i26791# - Adjust positioning and 393 // // alignment attributes. 394 // lcl_AdjustPositioningAttr( pFmt, *pSubObj ); 395 pFmtsAndObjs[i].push_back( std::pair< SwDrawFrmFmt*, SdrObject* >( pFmt, pSubObj ) ); 396 // <-- 397 398 if( bUndo ) 399 pUndo->AddObj( i2, pFmt ); 400 } 401 } 402 } 403 } 404 } 405 rDrawView.UnGroupMarked(); 406 // --> OD 2006-11-01 #130889# 407 // creation of <SwDrawContact> instances for the former group members and 408 // its connection to the Writer layout. 409 for ( sal_uInt32 i = 0; i < nMarkCount; ++i ) 410 { 411 SwUndoDrawUnGroupConnectToLayout* pUndo = 0; 412 if( bUndo ) 413 { 414 pUndo = new SwUndoDrawUnGroupConnectToLayout(); 415 GetIDocumentUndoRedo().AppendUndo(pUndo); 416 } 417 418 while ( pFmtsAndObjs[i].size() > 0 ) 419 { 420 SwDrawFrmFmt* pFmt( pFmtsAndObjs[i].back().first ); 421 SdrObject* pObj( pFmtsAndObjs[i].back().second ); 422 pFmtsAndObjs[i].pop_back(); 423 424 SwDrawContact* pContact = new SwDrawContact( pFmt, pObj ); 425 pContact->MoveObjToVisibleLayer( pObj ); 426 pContact->ConnectToLayout(); 427 lcl_AdjustPositioningAttr( pFmt, *pObj ); 428 429 if ( bUndo ) 430 { 431 pUndo->AddFmtAndObj( pFmt, pObj ); 432 } 433 } 434 } 435 delete [] pFmtsAndObjs; 436 // <-- 437 } 438 439 /************************************************************************* 440 |* 441 |* SwDoc::DeleteSelection() 442 |* 443 |* Ersterstellung MA 14. Nov. 95 444 |* Letzte Aenderung MA 14. Nov. 95 445 |* 446 |*************************************************************************/ 447 448 sal_Bool SwDoc::DeleteSelection( SwDrawView& rDrawView ) 449 { 450 sal_Bool bCallBase = sal_False; 451 const SdrMarkList &rMrkList = rDrawView.GetMarkedObjectList(); 452 if( rMrkList.GetMarkCount() ) 453 { 454 GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL); 455 sal_uInt16 i; 456 sal_Bool bDelMarked = sal_True; 457 458 if( 1 == rMrkList.GetMarkCount() ) 459 { 460 SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj(); 461 if( pObj->ISA(SwVirtFlyDrawObj) ) 462 { 463 SwFlyFrmFmt* pFrmFmt = (SwFlyFrmFmt*) 464 ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetFmt(); 465 if( pFrmFmt ) 466 { 467 DelLayoutFmt( pFrmFmt ); 468 bDelMarked = sal_False; 469 } 470 } 471 } 472 473 for( i = 0; i < rMrkList.GetMarkCount(); ++i ) 474 { 475 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); 476 if( !pObj->ISA(SwVirtFlyDrawObj) ) 477 { 478 SwDrawContact *pC = (SwDrawContact*)GetUserCall(pObj); 479 SwDrawFrmFmt *pFrmFmt = (SwDrawFrmFmt*)pC->GetFmt(); 480 if( pFrmFmt && 481 FLY_AS_CHAR == pFrmFmt->GetAnchor().GetAnchorId() ) 482 { 483 rDrawView.MarkObj( pObj, rDrawView.Imp().GetPageView(), sal_True ); 484 --i; 485 DelLayoutFmt( pFrmFmt ); 486 } 487 } 488 } 489 490 if( rMrkList.GetMarkCount() && bDelMarked ) 491 { 492 SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj(); 493 if( !pObj->GetUpGroup() ) 494 { 495 SwUndoDrawDelete *const pUndo = 496 (!GetIDocumentUndoRedo().DoesUndo()) 497 ? 0 498 : new SwUndoDrawDelete( (sal_uInt16)rMrkList.GetMarkCount() ); 499 500 //ContactObjekte vernichten, Formate sicherstellen. 501 for( i = 0; i < rMrkList.GetMarkCount(); ++i ) 502 { 503 const SdrMark& rMark = *rMrkList.GetMark( i ); 504 pObj = rMark.GetMarkedSdrObj(); 505 SwDrawContact *pContact = (SwDrawContact*)pObj->GetUserCall(); 506 if( pContact ) // natuerlich nicht bei gruppierten Objekten 507 { 508 SwDrawFrmFmt *pFmt = (SwDrawFrmFmt*)pContact->GetFmt(); 509 // OD 18.06.2003 #108784# - before delete of selection 510 // is performed, marked <SwDrawVirtObj>-objects have to 511 // be replaced by its reference objects. 512 // Thus, assert, if a <SwDrawVirt>-object is found in the mark list. 513 if ( pObj->ISA(SwDrawVirtObj) ) 514 { 515 ASSERT( false, 516 "<SwDrawVirtObj> is still marked for delete. application will crash!" ); 517 } 518 //loescht sich selbst! 519 pContact->Changed(*pObj, SDRUSERCALL_DELETE, pObj->GetLastBoundRect() ); 520 pObj->SetUserCall( 0 ); 521 522 if( pUndo ) 523 pUndo->AddObj( i, pFmt, rMark ); 524 else 525 DelFrmFmt( pFmt ); 526 } 527 } 528 529 if( pUndo ) 530 { 531 GetIDocumentUndoRedo().AppendUndo( pUndo ); 532 } 533 } 534 bCallBase = sal_True; 535 } 536 SetModified(); 537 538 GetIDocumentUndoRedo().EndUndo(UNDO_EMPTY, NULL); 539 } 540 541 return bCallBase; 542 } 543 544 /************************************************************************* 545 |* 546 |* SwDoc::DeleteSelection() 547 |* 548 |* Ersterstellung JP 11.01.96 549 |* Letzte Aenderung JP 11.01.96 550 |* 551 |*************************************************************************/ 552 553 _ZSortFly::_ZSortFly( const SwFrmFmt* pFrmFmt, const SwFmtAnchor* pFlyAn, 554 sal_uInt32 nArrOrdNum ) 555 : pFmt( pFrmFmt ), pAnchor( pFlyAn ), nOrdNum( nArrOrdNum ) 556 { 557 // #i11176# 558 // This also needs to work when no layout exists. Thus, for 559 // FlyFrames an alternative method is used now in that case. 560 if( RES_FLYFRMFMT == pFmt->Which() ) 561 { 562 if( pFmt->getIDocumentLayoutAccess()->GetCurrentViewShell() ) //swmod 071107//swmod 071225 563 { 564 // Schauen, ob es ein SdrObject dafuer gibt 565 SwFlyFrm* pFly = SwIterator<SwFlyFrm,SwFmt>::FirstElement( *pFrmFmt ); 566 if( pFly ) 567 nOrdNum = pFly->GetVirtDrawObj()->GetOrdNum(); 568 } 569 else 570 { 571 // Schauen, ob es ein SdrObject dafuer gibt 572 SwFlyDrawContact* pContact = SwIterator<SwFlyDrawContact,SwFmt>::FirstElement( *pFrmFmt ); 573 if( pContact ) 574 nOrdNum = pContact->GetMaster()->GetOrdNum(); 575 } 576 } 577 else if( RES_DRAWFRMFMT == pFmt->Which() ) 578 { 579 // Schauen, ob es ein SdrObject dafuer gibt 580 SwDrawContact* pContact = SwIterator<SwDrawContact,SwFmt>::FirstElement( *pFrmFmt ); 581 if( pContact ) 582 nOrdNum = pContact->GetMaster()->GetOrdNum(); 583 } 584 else { 585 ASSERT( !this, "was ist das fuer ein Format?" ); 586 } 587 } 588 589 /*************************************************************************/ 590 // Wird auch vom Sw3-Reader gerufen, wenn ein Fehler beim Einlesen 591 // des Drawing Layers auftrat. In diesem Fall wird der Layer komplett 592 // neu aufgebaut. 593 594 // #75371# 595 #include <svx/sxenditm.hxx> 596 597 void SwDoc::InitDrawModel() 598 { 599 RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "SW", "JP93722", "SwDoc::InitDrawModel" ); 600 601 //!!Achtung im sw3-Reader (sw3imp.cxx) gibt es aehnlichen Code, der 602 //mitgepfelgt werden muss. 603 if ( pDrawModel ) 604 ReleaseDrawModel(); 605 606 //DrawPool und EditEnginePool anlegen, diese gehoeren uns und werden 607 //dem Drawing nur mitgegeben. Im ReleaseDrawModel werden die Pools wieder 608 //zerstoert. 609 // 17.2.99: for Bug 73110 - for loading the drawing items. This must 610 // be loaded without RefCounts! 611 SfxItemPool *pSdrPool = new SdrItemPool( &GetAttrPool() ); 612 // #75371# change DefaultItems for the SdrEdgeObj distance items 613 // to TWIPS. 614 if(pSdrPool) 615 { 616 const long nDefEdgeDist = ((500 * 72) / 127); // 1/100th mm in twips 617 pSdrPool->SetPoolDefaultItem(SdrEdgeNode1HorzDistItem(nDefEdgeDist)); 618 pSdrPool->SetPoolDefaultItem(SdrEdgeNode1VertDistItem(nDefEdgeDist)); 619 pSdrPool->SetPoolDefaultItem(SdrEdgeNode2HorzDistItem(nDefEdgeDist)); 620 pSdrPool->SetPoolDefaultItem(SdrEdgeNode2VertDistItem(nDefEdgeDist)); 621 622 // #i33700# 623 // Set shadow distance defaults as PoolDefaultItems. Details see bug. 624 pSdrPool->SetPoolDefaultItem(SdrShadowXDistItem((300 * 72) / 127)); 625 pSdrPool->SetPoolDefaultItem(SdrShadowYDistItem((300 * 72) / 127)); 626 } 627 SfxItemPool *pEEgPool = EditEngine::CreatePool( sal_False ); 628 pSdrPool->SetSecondaryPool( pEEgPool ); 629 if ( !GetAttrPool().GetFrozenIdRanges () ) 630 GetAttrPool().FreezeIdRanges(); 631 else 632 pSdrPool->FreezeIdRanges(); 633 634 // SJ: #95129# set FontHeight pool defaults without changing static SdrEngineDefaults 635 GetAttrPool().SetPoolDefaultItem(SvxFontHeightItem( 240, 100, EE_CHAR_FONTHEIGHT )); 636 637 RTL_LOGFILE_CONTEXT_TRACE( aLog, "before create DrawDocument" ); 638 //Das SdrModel gehoert dem Dokument, wir haben immer zwei Layer und eine 639 //Seite. 640 pDrawModel = new SwDrawDocument( this ); 641 642 pDrawModel->EnableUndo( GetIDocumentUndoRedo().DoesUndo() ); 643 644 String sLayerNm; 645 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Hell" )); 646 nHell = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID(); 647 648 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Heaven" )); 649 nHeaven = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID(); 650 651 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Controls" )); 652 nControls = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID(); 653 654 // OD 25.06.2003 #108784# - add invisible layers corresponding to the 655 // visible ones. 656 { 657 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHell" )); 658 nInvisibleHell = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID(); 659 660 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHeaven" )); 661 nInvisibleHeaven = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID(); 662 663 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleControls" )); 664 nInvisibleControls = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID(); 665 } 666 667 SdrPage* pMasterPage = pDrawModel->AllocPage( sal_False ); 668 pDrawModel->InsertPage( pMasterPage ); 669 RTL_LOGFILE_CONTEXT_TRACE( aLog, "after create DrawDocument" ); 670 671 RTL_LOGFILE_CONTEXT_TRACE( aLog, "before create Spellchecker/Hyphenator" ); 672 SdrOutliner& rOutliner = pDrawModel->GetDrawOutliner(); 673 uno::Reference< XSpellChecker1 > xSpell = ::GetSpellChecker(); 674 rOutliner.SetSpeller( xSpell ); 675 uno::Reference<XHyphenator> xHyphenator( ::GetHyphenator() ); 676 rOutliner.SetHyphenator( xHyphenator ); 677 RTL_LOGFILE_CONTEXT_TRACE( aLog, "after create Spellchecker/Hyphenator" ); 678 679 SetCalcFieldValueHdl(&rOutliner); 680 SetCalcFieldValueHdl(&pDrawModel->GetHitTestOutliner()); 681 682 //JP 16.07.98: Bug 50193 - Linkmanager am Model setzen, damit 683 // dort ggfs. verlinkte Grafiken eingefuegt werden koennen 684 //JP 28.01.99: der WinWord Import benoetigt ihn auch 685 pDrawModel->SetLinkManager( &GetLinkManager() ); 686 pDrawModel->SetAddExtLeading( get(IDocumentSettingAccess::ADD_EXT_LEADING) ); 687 688 OutputDevice* pRefDev = getReferenceDevice( false ); 689 if ( pRefDev ) 690 pDrawModel->SetRefDevice( pRefDev ); 691 692 pDrawModel->SetNotifyUndoActionHdl( LINK( this, SwDoc, AddDrawUndo )); 693 if ( pCurrentView ) 694 { 695 ViewShell* pViewSh = pCurrentView; 696 do 697 { 698 SwRootFrm* pRoot = pViewSh->GetLayout(); 699 if( pRoot && !pRoot->GetDrawPage() ) 700 { 701 // Disable "multiple layout" for the moment: 702 // use pMasterPage instead of a new created SdrPage 703 // pDrawModel->AllocPage( FALSE ); 704 // pDrawModel->InsertPage( pDrawPage ); 705 SdrPage* pDrawPage = pMasterPage; 706 pRoot->SetDrawPage( pDrawPage ); 707 pDrawPage->SetSize( pRoot->Frm().SSize() ); 708 } 709 pViewSh = (ViewShell*)pViewSh->GetNext(); 710 }while( pViewSh != pCurrentView ); 711 } 712 713 UpdateDrawDefaults(); 714 } 715 716 /** method to notify drawing page view about the invisible layers 717 718 OD 26.06.2003 #108784# 719 720 @author OD 721 */ 722 void SwDoc::NotifyInvisibleLayers( SdrPageView& _rSdrPageView ) 723 { 724 String sLayerNm; 725 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHell" )); 726 _rSdrPageView.SetLayerVisible( sLayerNm, sal_False ); 727 728 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHeaven" )); 729 _rSdrPageView.SetLayerVisible( sLayerNm, sal_False ); 730 731 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleControls" )); 732 _rSdrPageView.SetLayerVisible( sLayerNm, sal_False ); 733 } 734 735 /** method to determine, if a layer ID belongs to the visible ones. 736 737 OD 25.06.2003 #108784# 738 Note: If given layer ID is unknown, method asserts and returns <false>. 739 740 @author OD 741 */ 742 bool SwDoc::IsVisibleLayerId( const SdrLayerID& _nLayerId ) const 743 { 744 bool bRetVal; 745 746 if ( _nLayerId == GetHeavenId() || 747 _nLayerId == GetHellId() || 748 _nLayerId == GetControlsId() ) 749 { 750 bRetVal = true; 751 } 752 else if ( _nLayerId == GetInvisibleHeavenId() || 753 _nLayerId == GetInvisibleHellId() || 754 _nLayerId == GetInvisibleControlsId() ) 755 { 756 bRetVal = false; 757 } 758 else 759 { 760 ASSERT( false, "<SwDoc::IsVisibleLayerId(..)> - unknown layer ID." ); 761 bRetVal = false; 762 } 763 764 return bRetVal; 765 } 766 767 /** method to determine, if the corresponding visible layer ID for a invisible one. 768 769 OD 25.06.2003 #108784# 770 Note: If given layer ID is a visible one, method returns given layer ID. 771 Note: If given layer ID is unknown, method returns given layer ID. 772 773 @author OD 774 */ 775 SdrLayerID SwDoc::GetVisibleLayerIdByInvisibleOne( const SdrLayerID& _nInvisibleLayerId ) 776 { 777 SdrLayerID nVisibleLayerId; 778 779 if ( _nInvisibleLayerId == GetInvisibleHeavenId() ) 780 { 781 nVisibleLayerId = GetHeavenId(); 782 } 783 else if ( _nInvisibleLayerId == GetInvisibleHellId() ) 784 { 785 nVisibleLayerId = GetHellId(); 786 } 787 else if ( _nInvisibleLayerId == GetInvisibleControlsId() ) 788 { 789 nVisibleLayerId = GetControlsId(); 790 } 791 else if ( _nInvisibleLayerId == GetHeavenId() || 792 _nInvisibleLayerId == GetHellId() || 793 _nInvisibleLayerId == GetControlsId() ) 794 { 795 ASSERT( false, "<SwDoc::GetVisibleLayerIdByInvisibleOne(..)> - given layer ID already an invisible one." ); 796 nVisibleLayerId = _nInvisibleLayerId; 797 } 798 else 799 { 800 ASSERT( false, "<SwDoc::GetVisibleLayerIdByInvisibleOne(..)> - given layer ID is unknown." ); 801 nVisibleLayerId = _nInvisibleLayerId; 802 } 803 804 return nVisibleLayerId; 805 } 806 807 /** method to determine, if the corresponding invisible layer ID for a visible one. 808 809 OD 25.06.2003 #108784# 810 Note: If given layer ID is a invisible one, method returns given layer ID. 811 Note: If given layer ID is unknown, method returns given layer ID. 812 813 @author OD 814 */ 815 SdrLayerID SwDoc::GetInvisibleLayerIdByVisibleOne( const SdrLayerID& _nVisibleLayerId ) 816 { 817 SdrLayerID nInvisibleLayerId; 818 819 if ( _nVisibleLayerId == GetHeavenId() ) 820 { 821 nInvisibleLayerId = GetInvisibleHeavenId(); 822 } 823 else if ( _nVisibleLayerId == GetHellId() ) 824 { 825 nInvisibleLayerId = GetInvisibleHellId(); 826 } 827 else if ( _nVisibleLayerId == GetControlsId() ) 828 { 829 nInvisibleLayerId = GetInvisibleControlsId(); 830 } 831 else if ( _nVisibleLayerId == GetInvisibleHeavenId() || 832 _nVisibleLayerId == GetInvisibleHellId() || 833 _nVisibleLayerId == GetInvisibleControlsId() ) 834 { 835 ASSERT( false, "<SwDoc::GetInvisibleLayerIdByVisibleOne(..)> - given layer ID already an invisible one." ); 836 nInvisibleLayerId = _nVisibleLayerId; 837 } 838 else 839 { 840 ASSERT( false, "<SwDoc::GetInvisibleLayerIdByVisibleOne(..)> - given layer ID is unknown." ); 841 nInvisibleLayerId = _nVisibleLayerId; 842 } 843 844 return nInvisibleLayerId; 845 } 846 847 /*************************************************************************/ 848 849 850 void SwDoc::ReleaseDrawModel() 851 { 852 if ( pDrawModel ) 853 { 854 //!!Den code im sw3io fuer Einfuegen Dokument mitpflegen!! 855 856 delete pDrawModel; pDrawModel = 0; 857 SfxItemPool *pSdrPool = GetAttrPool().GetSecondaryPool(); 858 859 ASSERT( pSdrPool, "missing Pool" ); 860 SfxItemPool *pEEgPool = pSdrPool->GetSecondaryPool(); 861 ASSERT( !pEEgPool->GetSecondaryPool(), "i don't accept additional pools"); 862 pSdrPool->Delete(); //Erst die Items vernichten lassen, 863 //dann erst die Verkettung loesen 864 GetAttrPool().SetSecondaryPool( 0 ); //Der ist ein muss! 865 pSdrPool->SetSecondaryPool( 0 ); //Der ist sicherer 866 SfxItemPool::Free(pSdrPool); 867 SfxItemPool::Free(pEEgPool); 868 } 869 } 870 871 /*************************************************************************/ 872 873 874 SdrModel* SwDoc::_MakeDrawModel() 875 { 876 ASSERT( !pDrawModel, "_MakeDrawModel: Why?" ); 877 InitDrawModel(); 878 if ( pCurrentView ) 879 { 880 ViewShell* pTmp = pCurrentView; 881 do 882 { 883 pTmp->MakeDrawView(); 884 pTmp = (ViewShell*) pTmp->GetNext(); 885 } while ( pTmp != pCurrentView ); 886 887 //Broadcast, damit die FormShell mit der DrawView verbunden werden kann 888 if( GetDocShell() ) 889 { 890 SfxSimpleHint aHnt( SW_BROADCAST_DRAWVIEWS_CREATED ); 891 GetDocShell()->Broadcast( aHnt ); 892 } 893 } //swmod 071029//swmod 071225 894 return pDrawModel; 895 } 896 897 /*************************************************************************/ 898 899 void SwDoc::DrawNotifyUndoHdl() 900 { 901 pDrawModel->SetNotifyUndoActionHdl( Link() ); 902 } 903 904 /************************************************************************* 905 * 906 * Am Outliner Link auf Methode fuer Felddarstellung in Editobjekten setzen 907 * 908 *************************************************************************/ 909 910 void SwDoc::SetCalcFieldValueHdl(Outliner* pOutliner) 911 { 912 pOutliner->SetCalcFieldValueHdl(LINK(this, SwDoc, CalcFieldValueHdl)); 913 } 914 915 /************************************************************************* 916 |* 917 |* Felder bzw URLs im Outliner erkennen und Darstellung festlegen 918 |* 919 \************************************************************************/ 920 921 IMPL_LINK(SwDoc, CalcFieldValueHdl, EditFieldInfo*, pInfo) 922 { 923 if (pInfo) 924 { 925 const SvxFieldItem& rField = pInfo->GetField(); 926 const SvxFieldData* pField = rField.GetField(); 927 928 if (pField && pField->ISA(SvxDateField)) 929 { 930 /****************************************************************** 931 * Date-Field 932 ******************************************************************/ 933 pInfo->SetRepresentation( 934 ((const SvxDateField*) pField)->GetFormatted( 935 *GetNumberFormatter( sal_True ), LANGUAGE_SYSTEM) ); 936 } 937 else if (pField && pField->ISA(SvxURLField)) 938 { 939 /****************************************************************** 940 * URL-Field 941 ******************************************************************/ 942 943 switch ( ((const SvxURLField*) pField)->GetFormat() ) 944 { 945 case SVXURLFORMAT_APPDEFAULT: //!!! einstellbar an App??? 946 case SVXURLFORMAT_REPR: 947 { 948 pInfo->SetRepresentation( 949 ((const SvxURLField*)pField)->GetRepresentation()); 950 } 951 break; 952 953 case SVXURLFORMAT_URL: 954 { 955 pInfo->SetRepresentation( 956 ((const SvxURLField*)pField)->GetURL()); 957 } 958 break; 959 } 960 961 sal_uInt16 nChrFmt; 962 963 if (IsVisitedURL(((const SvxURLField*)pField)->GetURL())) 964 nChrFmt = RES_POOLCHR_INET_VISIT; 965 else 966 nChrFmt = RES_POOLCHR_INET_NORMAL; 967 968 SwFmt *pFmt = GetCharFmtFromPool(nChrFmt); 969 970 Color aColor(COL_LIGHTBLUE); 971 if (pFmt) 972 aColor = pFmt->GetColor().GetValue(); 973 974 pInfo->SetTxtColor(aColor); 975 } 976 else if (pField && pField->ISA(SdrMeasureField)) 977 { 978 /****************************************************************** 979 * Measure-Field 980 ******************************************************************/ 981 pInfo->ClearFldColor(); 982 } 983 else if ( pField && pField->ISA(SvxExtTimeField)) 984 { 985 /****************************************************************** 986 * Time-Field 987 ******************************************************************/ 988 pInfo->SetRepresentation( 989 ((const SvxExtTimeField*) pField)->GetFormatted( 990 *GetNumberFormatter( sal_True ), LANGUAGE_SYSTEM) ); 991 } 992 else 993 { 994 DBG_ERROR("unbekannter Feldbefehl"); 995 pInfo->SetRepresentation( String( '?' ) ); 996 } 997 } 998 999 return(0); 1000 } 1001 1002 /* TFFDI: The functions formerly declared 'inline' 1003 */ 1004 const SdrModel* SwDoc::GetDrawModel() const { return pDrawModel; } 1005 SdrModel* SwDoc::GetDrawModel() { return pDrawModel; } 1006 SdrLayerID SwDoc::GetHeavenId() const { return nHeaven; } 1007 SdrLayerID SwDoc::GetHellId() const { return nHell; } 1008 SdrLayerID SwDoc::GetControlsId() const { return nControls; } 1009 SdrLayerID SwDoc::GetInvisibleHeavenId() const { return nInvisibleHeaven; } 1010 SdrLayerID SwDoc::GetInvisibleHellId() const { return nInvisibleHell; } 1011 SdrLayerID SwDoc::GetInvisibleControlsId() const { return nInvisibleControls; } 1012 SdrModel* SwDoc::GetOrCreateDrawModel() { return GetDrawModel() ? GetDrawModel() : _MakeDrawModel(); } 1013 1014 // --> OD 2006-03-14 #i62875# 1015 namespace docfunc 1016 { 1017 bool ExistsDrawObjs( SwDoc& p_rDoc ) 1018 { 1019 bool bExistsDrawObjs( false ); 1020 1021 if ( p_rDoc.GetDrawModel() && 1022 p_rDoc.GetDrawModel()->GetPage( 0 ) ) 1023 { 1024 const SdrPage& rSdrPage( *(p_rDoc.GetDrawModel()->GetPage( 0 )) ); 1025 1026 SdrObjListIter aIter( rSdrPage, IM_FLAT ); 1027 while( aIter.IsMore() ) 1028 { 1029 SdrObject* pObj( aIter.Next() ); 1030 if ( !dynamic_cast<SwVirtFlyDrawObj*>(pObj) && 1031 !dynamic_cast<SwFlyDrawObj*>(pObj) ) 1032 { 1033 bExistsDrawObjs = true; 1034 break; 1035 } 1036 } 1037 } 1038 1039 return bExistsDrawObjs; 1040 } 1041 1042 bool AllDrawObjsOnPage( SwDoc& p_rDoc ) 1043 { 1044 bool bAllDrawObjsOnPage( true ); 1045 1046 if ( p_rDoc.GetDrawModel() && 1047 p_rDoc.GetDrawModel()->GetPage( 0 ) ) 1048 { 1049 const SdrPage& rSdrPage( *(p_rDoc.GetDrawModel()->GetPage( 0 )) ); 1050 1051 SdrObjListIter aIter( rSdrPage, IM_FLAT ); 1052 while( aIter.IsMore() ) 1053 { 1054 SdrObject* pObj( aIter.Next() ); 1055 if ( !dynamic_cast<SwVirtFlyDrawObj*>(pObj) && 1056 !dynamic_cast<SwFlyDrawObj*>(pObj) ) 1057 { 1058 SwDrawContact* pDrawContact = 1059 dynamic_cast<SwDrawContact*>(::GetUserCall( pObj )); 1060 if ( pDrawContact ) 1061 { 1062 SwAnchoredDrawObject* pAnchoredDrawObj = 1063 dynamic_cast<SwAnchoredDrawObject*>(pDrawContact->GetAnchoredObj( pObj )); 1064 1065 // error handling 1066 { 1067 if ( !pAnchoredDrawObj ) 1068 { 1069 ASSERT( false, 1070 "<docfunc::AllDrawObjsOnPage() - missing anchored draw object" ); 1071 bAllDrawObjsOnPage = false; 1072 break; 1073 } 1074 } 1075 1076 if ( pAnchoredDrawObj->NotYetPositioned() ) 1077 { 1078 // The drawing object isn't yet layouted. 1079 // Thus, it isn't known, if all drawing objects are on page. 1080 bAllDrawObjsOnPage = false; 1081 break; 1082 } 1083 else if ( pAnchoredDrawObj->IsOutsidePage() ) 1084 { 1085 bAllDrawObjsOnPage = false; 1086 break; 1087 } 1088 } 1089 else 1090 { 1091 // contact object of drawing object doesn't exists. 1092 // Thus, the drawing object isn't yet positioned. 1093 // Thus, it isn't known, if all drawing objects are on page. 1094 bAllDrawObjsOnPage = false; 1095 break; 1096 } 1097 } 1098 } 1099 } 1100 1101 return bAllDrawObjsOnPage; 1102 } 1103 } 1104 // <-- 1105 1106 void SwDoc::SetDrawDefaults() 1107 { 1108 mbSetDrawDefaults = true; 1109 UpdateDrawDefaults(); 1110 } 1111 1112 void SwDoc::UpdateDrawDefaults() 1113 { 1114 // drawing layer defaults that are set for new documents (if InitNew was called) 1115 if ( pDrawModel && mbSetDrawDefaults ) 1116 pDrawModel->SetDrawingLayerPoolDefaults(); 1117 } 1118 1119