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 //UUUU 603 // //DrawPool und EditEnginePool anlegen, diese gehoeren uns und werden 604 // //dem Drawing nur mitgegeben. Im ReleaseDrawModel werden die Pools wieder 605 // //zerstoert. 606 // // 17.2.99: for Bug 73110 - for loading the drawing items. This must 607 // // be loaded without RefCounts! 608 // SfxItemPool *pSdrPool = new SdrItemPool( &GetAttrPool() ); 609 // // #75371# change DefaultItems for the SdrEdgeObj distance items 610 // // to TWIPS. 611 // if(pSdrPool) 612 // { 613 // const long nDefEdgeDist = ((500 * 72) / 127); // 1/100th mm in twips 614 // pSdrPool->SetPoolDefaultItem(SdrEdgeNode1HorzDistItem(nDefEdgeDist)); 615 // pSdrPool->SetPoolDefaultItem(SdrEdgeNode1VertDistItem(nDefEdgeDist)); 616 // pSdrPool->SetPoolDefaultItem(SdrEdgeNode2HorzDistItem(nDefEdgeDist)); 617 // pSdrPool->SetPoolDefaultItem(SdrEdgeNode2VertDistItem(nDefEdgeDist)); 618 // 619 // // #i33700# 620 // // Set shadow distance defaults as PoolDefaultItems. Details see bug. 621 // pSdrPool->SetPoolDefaultItem(SdrShadowXDistItem((300 * 72) / 127)); 622 // pSdrPool->SetPoolDefaultItem(SdrShadowYDistItem((300 * 72) / 127)); 623 // } 624 // SfxItemPool *pEEgPool = EditEngine::CreatePool( sal_False ); 625 // pSdrPool->SetSecondaryPool( pEEgPool ); 626 // if ( !GetAttrPool().GetFrozenIdRanges () ) 627 // GetAttrPool().FreezeIdRanges(); 628 // else 629 // pSdrPool->FreezeIdRanges(); 630 631 // SJ: #95129# set FontHeight pool defaults without changing static SdrEngineDefaults 632 GetAttrPool().SetPoolDefaultItem(SvxFontHeightItem( 240, 100, EE_CHAR_FONTHEIGHT )); 633 634 RTL_LOGFILE_CONTEXT_TRACE( aLog, "before create DrawDocument" ); 635 //Das SdrModel gehoert dem Dokument, wir haben immer zwei Layer und eine 636 //Seite. 637 pDrawModel = new SwDrawDocument( this ); 638 639 pDrawModel->EnableUndo( GetIDocumentUndoRedo().DoesUndo() ); 640 641 String sLayerNm; 642 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Hell" )); 643 nHell = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID(); 644 645 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Heaven" )); 646 nHeaven = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID(); 647 648 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Controls" )); 649 nControls = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID(); 650 651 // OD 25.06.2003 #108784# - add invisible layers corresponding to the 652 // visible ones. 653 { 654 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHell" )); 655 nInvisibleHell = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID(); 656 657 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHeaven" )); 658 nInvisibleHeaven = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID(); 659 660 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleControls" )); 661 nInvisibleControls = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID(); 662 } 663 664 SdrPage* pMasterPage = pDrawModel->AllocPage( sal_False ); 665 pDrawModel->InsertPage( pMasterPage ); 666 RTL_LOGFILE_CONTEXT_TRACE( aLog, "after create DrawDocument" ); 667 668 RTL_LOGFILE_CONTEXT_TRACE( aLog, "before create Spellchecker/Hyphenator" ); 669 SdrOutliner& rOutliner = pDrawModel->GetDrawOutliner(); 670 uno::Reference< XSpellChecker1 > xSpell = ::GetSpellChecker(); 671 rOutliner.SetSpeller( xSpell ); 672 uno::Reference<XHyphenator> xHyphenator( ::GetHyphenator() ); 673 rOutliner.SetHyphenator( xHyphenator ); 674 RTL_LOGFILE_CONTEXT_TRACE( aLog, "after create Spellchecker/Hyphenator" ); 675 676 SetCalcFieldValueHdl(&rOutliner); 677 SetCalcFieldValueHdl(&pDrawModel->GetHitTestOutliner()); 678 679 //JP 16.07.98: Bug 50193 - Linkmanager am Model setzen, damit 680 // dort ggfs. verlinkte Grafiken eingefuegt werden koennen 681 //JP 28.01.99: der WinWord Import benoetigt ihn auch 682 pDrawModel->SetLinkManager( &GetLinkManager() ); 683 pDrawModel->SetAddExtLeading( get(IDocumentSettingAccess::ADD_EXT_LEADING) ); 684 685 OutputDevice* pRefDev = getReferenceDevice( false ); 686 if ( pRefDev ) 687 pDrawModel->SetRefDevice( pRefDev ); 688 689 pDrawModel->SetNotifyUndoActionHdl( LINK( this, SwDoc, AddDrawUndo )); 690 if ( pCurrentView ) 691 { 692 ViewShell* pViewSh = pCurrentView; 693 do 694 { 695 SwRootFrm* pRoot = pViewSh->GetLayout(); 696 if( pRoot && !pRoot->GetDrawPage() ) 697 { 698 // Disable "multiple layout" for the moment: 699 // use pMasterPage instead of a new created SdrPage 700 // pDrawModel->AllocPage( FALSE ); 701 // pDrawModel->InsertPage( pDrawPage ); 702 SdrPage* pDrawPage = pMasterPage; 703 pRoot->SetDrawPage( pDrawPage ); 704 pDrawPage->SetSize( pRoot->Frm().SSize() ); 705 } 706 pViewSh = (ViewShell*)pViewSh->GetNext(); 707 }while( pViewSh != pCurrentView ); 708 } 709 } 710 711 /** method to notify drawing page view about the invisible layers 712 713 OD 26.06.2003 #108784# 714 715 @author OD 716 */ 717 void SwDoc::NotifyInvisibleLayers( SdrPageView& _rSdrPageView ) 718 { 719 String sLayerNm; 720 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHell" )); 721 _rSdrPageView.SetLayerVisible( sLayerNm, sal_False ); 722 723 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHeaven" )); 724 _rSdrPageView.SetLayerVisible( sLayerNm, sal_False ); 725 726 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleControls" )); 727 _rSdrPageView.SetLayerVisible( sLayerNm, sal_False ); 728 } 729 730 /** method to determine, if a layer ID belongs to the visible ones. 731 732 OD 25.06.2003 #108784# 733 Note: If given layer ID is unknown, method asserts and returns <false>. 734 735 @author OD 736 */ 737 bool SwDoc::IsVisibleLayerId( const SdrLayerID& _nLayerId ) const 738 { 739 bool bRetVal; 740 741 if ( _nLayerId == GetHeavenId() || 742 _nLayerId == GetHellId() || 743 _nLayerId == GetControlsId() ) 744 { 745 bRetVal = true; 746 } 747 else if ( _nLayerId == GetInvisibleHeavenId() || 748 _nLayerId == GetInvisibleHellId() || 749 _nLayerId == GetInvisibleControlsId() ) 750 { 751 bRetVal = false; 752 } 753 else 754 { 755 ASSERT( false, "<SwDoc::IsVisibleLayerId(..)> - unknown layer ID." ); 756 bRetVal = false; 757 } 758 759 return bRetVal; 760 } 761 762 /** method to determine, if the corresponding visible layer ID for a invisible one. 763 764 OD 25.06.2003 #108784# 765 Note: If given layer ID is a visible one, method returns given layer ID. 766 Note: If given layer ID is unknown, method returns given layer ID. 767 768 @author OD 769 */ 770 SdrLayerID SwDoc::GetVisibleLayerIdByInvisibleOne( const SdrLayerID& _nInvisibleLayerId ) 771 { 772 SdrLayerID nVisibleLayerId; 773 774 if ( _nInvisibleLayerId == GetInvisibleHeavenId() ) 775 { 776 nVisibleLayerId = GetHeavenId(); 777 } 778 else if ( _nInvisibleLayerId == GetInvisibleHellId() ) 779 { 780 nVisibleLayerId = GetHellId(); 781 } 782 else if ( _nInvisibleLayerId == GetInvisibleControlsId() ) 783 { 784 nVisibleLayerId = GetControlsId(); 785 } 786 else if ( _nInvisibleLayerId == GetHeavenId() || 787 _nInvisibleLayerId == GetHellId() || 788 _nInvisibleLayerId == GetControlsId() ) 789 { 790 ASSERT( false, "<SwDoc::GetVisibleLayerIdByInvisibleOne(..)> - given layer ID already an invisible one." ); 791 nVisibleLayerId = _nInvisibleLayerId; 792 } 793 else 794 { 795 ASSERT( false, "<SwDoc::GetVisibleLayerIdByInvisibleOne(..)> - given layer ID is unknown." ); 796 nVisibleLayerId = _nInvisibleLayerId; 797 } 798 799 return nVisibleLayerId; 800 } 801 802 /** method to determine, if the corresponding invisible layer ID for a visible one. 803 804 OD 25.06.2003 #108784# 805 Note: If given layer ID is a invisible one, method returns given layer ID. 806 Note: If given layer ID is unknown, method returns given layer ID. 807 808 @author OD 809 */ 810 SdrLayerID SwDoc::GetInvisibleLayerIdByVisibleOne( const SdrLayerID& _nVisibleLayerId ) 811 { 812 SdrLayerID nInvisibleLayerId; 813 814 if ( _nVisibleLayerId == GetHeavenId() ) 815 { 816 nInvisibleLayerId = GetInvisibleHeavenId(); 817 } 818 else if ( _nVisibleLayerId == GetHellId() ) 819 { 820 nInvisibleLayerId = GetInvisibleHellId(); 821 } 822 else if ( _nVisibleLayerId == GetControlsId() ) 823 { 824 nInvisibleLayerId = GetInvisibleControlsId(); 825 } 826 else if ( _nVisibleLayerId == GetInvisibleHeavenId() || 827 _nVisibleLayerId == GetInvisibleHellId() || 828 _nVisibleLayerId == GetInvisibleControlsId() ) 829 { 830 ASSERT( false, "<SwDoc::GetInvisibleLayerIdByVisibleOne(..)> - given layer ID already an invisible one." ); 831 nInvisibleLayerId = _nVisibleLayerId; 832 } 833 else 834 { 835 ASSERT( false, "<SwDoc::GetInvisibleLayerIdByVisibleOne(..)> - given layer ID is unknown." ); 836 nInvisibleLayerId = _nVisibleLayerId; 837 } 838 839 return nInvisibleLayerId; 840 } 841 842 /*************************************************************************/ 843 844 845 void SwDoc::ReleaseDrawModel() 846 { 847 if ( pDrawModel ) 848 { 849 //!!Den code im sw3io fuer Einfuegen Dokument mitpflegen!! 850 851 delete pDrawModel; pDrawModel = 0; 852 //UUUU 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 // eof 1103