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