merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / doc / docdraw.cxx
blob3befc37ff3d1d973558968626df6d2a2a1d9b2e6
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: docdraw.cxx,v $
10 * $Revision: 1.45 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include <hintids.hxx>
34 #include <rtl/logfile.hxx>
35 #ifndef _OUTDEV_HXX //autogen
36 #include <vcl/outdev.hxx>
37 #endif
38 #include <sfx2/printer.hxx>
39 #include <svx/eeitem.hxx>
40 #include <svx/flditem.hxx>
41 #include <svx/editeng.hxx>
42 #include <svx/svdoutl.hxx>
43 #include <svx/colritem.hxx>
44 #include <svx/svdpage.hxx>
45 #include <svx/svdogrp.hxx>
46 #include <svx/langitem.hxx>
47 #include <svx/unolingu.hxx>
49 #ifndef _SVDOMEAS_HXX
50 #include <svx/svdfield.hxx>
51 #endif
52 #include <svx/svdpool.hxx>
53 #include <fmtanchr.hxx>
54 #include <charatr.hxx>
55 #include <frmfmt.hxx>
56 #include <charfmt.hxx>
57 #include <viewimp.hxx>
58 #ifndef _SWHINTS_HXX
59 #include <swhints.hxx>
60 #endif
61 #include <doc.hxx>
62 #ifndef _DOCSH_HXX
63 #include <docsh.hxx>
64 #endif
65 #include <rootfrm.hxx> //Damit der RootDtor gerufen wird.
66 #include <poolfmt.hxx>
67 #include <viewsh.hxx> // fuer MakeDrawView
68 #include <drawdoc.hxx>
69 #include <undobj.hxx>
70 #include <swundo.hxx> // fuer die UndoIds
71 #include <dcontact.hxx>
72 #include <dview.hxx>
73 #include <mvsave.hxx>
74 #include <flyfrm.hxx>
75 #include <dflyobj.hxx>
76 #include <svx/svdetc.hxx>
77 #include <svx/fhgtitem.hxx>
79 // OD 26.06.2003 #108784#
80 #include <svx/svdpagv.hxx>
81 // OD 2004-04-01 #i26791#
82 #include <dcontact.hxx>
83 #include <txtfrm.hxx>
84 #include <frmfmt.hxx>
85 #include <svx/frmdiritem.hxx>
86 #include <fmtornt.hxx>
87 // --> OD 2006-03-14 #i62875#
88 #include <svx/svditer.hxx>
89 // <--
90 // --> OD 2006-11-01 #130889#
91 #include <vector>
92 // <--
94 using namespace ::com::sun::star;
95 using namespace ::com::sun::star::linguistic2;
98 SV_IMPL_VARARR_SORT( _ZSortFlys, _ZSortFly )
100 /*************************************************************************
102 |* SwDoc::GroupSelection / SwDoc::UnGroupSelection
104 |* Ersterstellung JP 21.08.95
105 |* Letzte Aenderung JP 21.08.95
107 |*************************************************************************/
108 // OD 2004-04-01 #i26791# - local method to determine positioning and
109 // alignment attributes for a drawing object, which is newly connected to
110 // the layout. Used for a newly formed group object <SwDoc::GroupSelection(..)>
111 // and the members of a destroyed group <SwDoc::UnGroupSelection(..)>
112 void lcl_AdjustPositioningAttr( SwDrawFrmFmt* _pFrmFmt,
113 const SdrObject& _rSdrObj )
115 const SwContact* pContact = GetUserCall( &_rSdrObj );
116 ASSERT( pContact, "<lcl_AdjustPositioningAttr(..)> - missing contact object." );
118 // determine position of new group object relative to its anchor frame position
119 SwTwips nHoriRelPos = 0;
120 SwTwips nVertRelPos = 0;
122 const SwFrm* pAnchorFrm = pContact->GetAnchoredObj( &_rSdrObj )->GetAnchorFrm();
123 ASSERT( !pAnchorFrm ||
124 !pAnchorFrm->IsTxtFrm() ||
125 !static_cast<const SwTxtFrm*>(pAnchorFrm)->IsFollow(),
126 "<lcl_AdjustPositioningAttr(..)> - anchor frame is a follow. Please inform OD." );
127 bool bVert = false;
128 bool bR2L = false;
129 // --> OD 2005-05-10 #i45952# - use anchor position of
130 // anchor frame, if it exist.
131 Point aAnchorPos;
132 if ( pAnchorFrm )
134 // --> OD 2005-05-10 #i45952#
135 aAnchorPos = pAnchorFrm->GetFrmAnchorPos( ::HasWrap( &_rSdrObj ) );
136 // <--
137 bVert = pAnchorFrm->IsVertical();
138 bR2L = pAnchorFrm->IsRightToLeft();
140 else
142 // --> OD 2005-05-10 #i45952#
143 aAnchorPos = _rSdrObj.GetAnchorPos();
144 // <--
145 // If no anchor frame exist - e.g. because no layout exists - the
146 // default layout direction is taken.
147 const SvxFrameDirectionItem* pDirItem =
148 static_cast<const SvxFrameDirectionItem*>(&(_pFrmFmt->GetAttrSet().GetPool()->GetDefaultItem( RES_FRAMEDIR )));
149 switch ( pDirItem->GetValue() )
151 case FRMDIR_VERT_TOP_LEFT:
153 // vertical from left-to-right - not supported yet
154 bVert = true;
155 bR2L = true;
156 ASSERT( false,
157 "<lcl_AdjustPositioningAttr(..)> - vertical from left-to-right not supported." );
159 break;
160 case FRMDIR_VERT_TOP_RIGHT:
162 // vertical from right-to-left
163 bVert = true;
164 bR2L = false;
166 break;
167 case FRMDIR_HORI_RIGHT_TOP:
169 // horizontal from right-to-left
170 bVert = false;
171 bR2L = true;
173 break;
174 case FRMDIR_HORI_LEFT_TOP:
176 // horizontal from left-to-right
177 bVert = false;
178 bR2L = false;
180 break;
184 // use geometry of drawing object
185 const SwRect aObjRect = _rSdrObj.GetSnapRect();
186 if ( bVert )
188 nHoriRelPos = aObjRect.Top() - aAnchorPos.Y();
189 nVertRelPos = aAnchorPos.X() - aObjRect.Right();
191 else if ( bR2L )
193 nHoriRelPos = aAnchorPos.X() - aObjRect.Right();
194 nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
196 else
198 nHoriRelPos = aObjRect.Left() - aAnchorPos.X();
199 nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
203 _pFrmFmt->SetFmtAttr( SwFmtHoriOrient( nHoriRelPos, text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
204 _pFrmFmt->SetFmtAttr( SwFmtVertOrient( nVertRelPos, text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
205 // --> OD 2005-03-11 #i44334#, #i44681# - positioning attributes already set
206 _pFrmFmt->PosAttrSet();
207 // <--
208 // --> OD 2004-10-01 #i34750# - keep current object rectangle for drawing
209 // objects. The object rectangle is used on events from the drawing layer
210 // to adjust the positioning attributes - see <SwDrawContact::_Changed(..)>.
212 const SwAnchoredObject* pAnchoredObj = pContact->GetAnchoredObj( &_rSdrObj );
213 if ( pAnchoredObj->ISA(SwAnchoredDrawObject) )
215 const SwAnchoredDrawObject* pAnchoredDrawObj =
216 static_cast<const SwAnchoredDrawObject*>(pAnchoredObj);
217 const SwRect aObjRect = _rSdrObj.GetSnapRect();
218 const_cast<SwAnchoredDrawObject*>(pAnchoredDrawObj)
219 ->SetLastObjRect( aObjRect.SVRect() );
222 // <--
225 SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView )
227 // OD 30.06.2003 #108784# - replace marked 'virtual' drawing objects by
228 // the corresponding 'master' drawing objects.
229 SwDrawView::ReplaceMarkedDrawVirtObjs( rDrawView );
231 const SdrMarkList &rMrkList = rDrawView.GetMarkedObjectList();
232 SwDrawFrmFmt *pFmt = 0L;
233 SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
234 BOOL bNoGroup = ( 0 == pObj->GetUpGroup() );
235 SwDrawContact* pNewContact = 0;
236 if( bNoGroup )
238 //Ankerattribut aufheben.
239 SwDrawContact *pMyContact = (SwDrawContact*)GetUserCall(pObj);
240 const SwFmtAnchor aAnch( pMyContact->GetFmt()->GetAnchor() );
242 SwUndoDrawGroup* pUndo = !DoesUndo()
244 : new SwUndoDrawGroup( (USHORT)rMrkList.GetMarkCount() );
246 // --> OD 2005-08-16 #i53320#
247 bool bGroupMembersNotPositioned( false );
249 SwAnchoredDrawObject* pAnchoredDrawObj =
250 static_cast<SwAnchoredDrawObject*>(pMyContact->GetAnchoredObj( pObj ));
251 bGroupMembersNotPositioned = pAnchoredDrawObj->NotYetPositioned();
253 // <--
254 //ContactObjekte und Formate vernichten.
255 for( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
257 pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
258 SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
260 // --> OD 2005-08-16 #i53320#
261 #ifndef PRODUCT
262 SwAnchoredDrawObject* pAnchoredDrawObj =
263 static_cast<SwAnchoredDrawObject*>(pContact->GetAnchoredObj( pObj ));
264 ASSERT( bGroupMembersNotPositioned == pAnchoredDrawObj->NotYetPositioned(),
265 "<SwDoc::GroupSelection(..)> - group members have different positioning status!" );
266 #endif
267 // <--
269 pFmt = (SwDrawFrmFmt*)pContact->GetFmt();
270 //loescht sich selbst!
271 pContact->Changed(*pObj, SDRUSERCALL_DELETE, pObj->GetLastBoundRect() );
272 pObj->SetUserCall( 0 );
274 if( pUndo )
275 pUndo->AddObj( i, pFmt, pObj );
276 else
277 DelFrmFmt( pFmt );
279 // --> OD 2005-05-10 #i45952# - re-introduce position
280 // normalization of group member objects, because its anchor position
281 // is cleared, when they are grouped.
282 Point aAnchorPos( pObj->GetAnchorPos() );
283 pObj->NbcSetAnchorPos( Point( 0, 0 ) );
284 pObj->NbcMove( Size( aAnchorPos.X(), aAnchorPos.Y() ) );
285 // <--
288 pFmt = MakeDrawFrmFmt( String::CreateFromAscii(
289 RTL_CONSTASCII_STRINGPARAM( "DrawObject" )),
290 GetDfltFrmFmt() );
291 pFmt->SetFmtAttr( aAnch );
292 // --> OD 2004-10-25 #i36010# - set layout direction of the position
293 pFmt->SetPositionLayoutDir(
294 text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
295 // <--
297 rDrawView.GroupMarked();
298 ASSERT( rMrkList.GetMarkCount() == 1, "GroupMarked more or none groups." );
300 SdrObject* pNewGroupObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
301 pNewContact = new SwDrawContact( pFmt, pNewGroupObj );
302 // --> OD 2004-11-22 #i35635#
303 pNewContact->MoveObjToVisibleLayer( pNewGroupObj );
304 // <--
305 pNewContact->ConnectToLayout();
306 // --> OD 2005-08-16 #i53320# - No adjustment of the positioning and
307 // alignment attributes, if group members aren't positioned yet.
308 if ( !bGroupMembersNotPositioned )
310 // OD 2004-04-01 #i26791# - Adjust positioning and alignment attributes.
311 lcl_AdjustPositioningAttr( pFmt, *pNewGroupObj );
313 // <--
315 if( pUndo )
317 pUndo->SetGroupFmt( pFmt );
318 ClearRedo();
319 AppendUndo( pUndo );
322 else
324 if ( DoesUndo() )
325 ClearRedo();
327 rDrawView.GroupMarked();
328 ASSERT( rMrkList.GetMarkCount() == 1, "GroupMarked more or none groups." );
331 return pNewContact;
335 void SwDoc::UnGroupSelection( SdrView& rDrawView )
337 const int bUndo = DoesUndo();
338 if( bUndo )
339 ClearRedo();
341 // OD 30.06.2003 #108784# - replace marked 'virtual' drawing objects by
342 // the corresponding 'master' drawing objects.
343 SwDrawView::ReplaceMarkedDrawVirtObjs( rDrawView );
345 const SdrMarkList &rMrkList = rDrawView.GetMarkedObjectList();
346 // --> OD 2006-11-01 #130889#
347 std::vector< std::pair< SwDrawFrmFmt*, SdrObject* > >* pFmtsAndObjs( 0L );
348 const sal_uInt32 nMarkCount( rMrkList.GetMarkCount() );
349 // <--
350 if ( nMarkCount )
352 // --> OD 2006-11-01 #130889#
353 pFmtsAndObjs = new std::vector< std::pair< SwDrawFrmFmt*, SdrObject* > >[nMarkCount];
354 // <--
355 SdrObject *pMyObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
356 if( !pMyObj->GetUpGroup() )
358 String sDrwFmtNm( String::CreateFromAscii(
359 RTL_CONSTASCII_STRINGPARAM("DrawObject" )));
360 for ( USHORT i = 0; i < nMarkCount; ++i )
362 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
363 if ( pObj->IsA( TYPE(SdrObjGroup) ) )
365 SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
366 SwFmtAnchor aAnch( pContact->GetFmt()->GetAnchor() );
367 SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList();
369 SwUndoDrawUnGroup* pUndo = 0;
370 if( bUndo )
372 pUndo = new SwUndoDrawUnGroup( (SdrObjGroup*)pObj );
373 AppendUndo( pUndo );
376 for ( USHORT i2 = 0; i2 < pLst->GetObjCount(); ++i2 )
378 SdrObject* pSubObj = pLst->GetObj( i2 );
379 SwDrawFrmFmt *pFmt = MakeDrawFrmFmt( sDrwFmtNm,
380 GetDfltFrmFmt() );
381 pFmt->SetFmtAttr( aAnch );
382 // --> OD 2004-10-25 #i36010# - set layout direction of the position
383 pFmt->SetPositionLayoutDir(
384 text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
385 // <--
386 // --> OD 2006-11-01 #130889#
387 // creation of <SwDrawContact> instances for the group
388 // members and its connection to the Writer layout is
389 // done after intrinsic ungrouping.
390 // SwDrawContact* pContact = new SwDrawContact( pFmt, pSubObj );
391 // // --> OD 2004-11-22 #i35635#
392 // pContact->MoveObjToVisibleLayer( pSubObj );
393 // // <--
394 // pContact->ConnectToLayout();
395 // // OD 2004-04-07 #i26791# - Adjust positioning and
396 // // alignment attributes.
397 // lcl_AdjustPositioningAttr( pFmt, *pSubObj );
398 pFmtsAndObjs[i].push_back( std::pair< SwDrawFrmFmt*, SdrObject* >( pFmt, pSubObj ) );
399 // <--
401 if( bUndo )
402 pUndo->AddObj( i2, pFmt );
408 rDrawView.UnGroupMarked();
409 // --> OD 2006-11-01 #130889#
410 // creation of <SwDrawContact> instances for the former group members and
411 // its connection to the Writer layout.
412 for ( sal_uInt32 i = 0; i < nMarkCount; ++i )
414 SwUndoDrawUnGroupConnectToLayout* pUndo = 0;
415 if( bUndo )
417 pUndo = new SwUndoDrawUnGroupConnectToLayout();
418 AppendUndo( pUndo );
421 while ( pFmtsAndObjs[i].size() > 0 )
423 SwDrawFrmFmt* pFmt( pFmtsAndObjs[i].back().first );
424 SdrObject* pObj( pFmtsAndObjs[i].back().second );
425 pFmtsAndObjs[i].pop_back();
427 SwDrawContact* pContact = new SwDrawContact( pFmt, pObj );
428 pContact->MoveObjToVisibleLayer( pObj );
429 pContact->ConnectToLayout();
430 lcl_AdjustPositioningAttr( pFmt, *pObj );
432 if ( bUndo )
434 pUndo->AddFmtAndObj( pFmt, pObj );
438 delete [] pFmtsAndObjs;
439 // <--
442 /*************************************************************************
444 |* SwDoc::DeleteSelection()
446 |* Ersterstellung MA 14. Nov. 95
447 |* Letzte Aenderung MA 14. Nov. 95
449 |*************************************************************************/
451 BOOL SwDoc::DeleteSelection( SwDrawView& rDrawView )
453 BOOL bCallBase = FALSE;
454 const SdrMarkList &rMrkList = rDrawView.GetMarkedObjectList();
455 if( rMrkList.GetMarkCount() )
457 StartUndo(UNDO_EMPTY, NULL);
458 USHORT i;
459 BOOL bDelMarked = TRUE;
461 if( 1 == rMrkList.GetMarkCount() )
463 SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
464 if( pObj->ISA(SwVirtFlyDrawObj) )
466 SwFlyFrmFmt* pFrmFmt = (SwFlyFrmFmt*)
467 ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetFmt();
468 if( pFrmFmt )
470 DelLayoutFmt( pFrmFmt );
471 bDelMarked = FALSE;
476 for( i = 0; i < rMrkList.GetMarkCount(); ++i )
478 SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
479 if( !pObj->ISA(SwVirtFlyDrawObj) )
481 SwDrawContact *pC = (SwDrawContact*)GetUserCall(pObj);
482 SwDrawFrmFmt *pFrmFmt = (SwDrawFrmFmt*)pC->GetFmt();
483 if( pFrmFmt &&
484 FLY_IN_CNTNT == pFrmFmt->GetAnchor().GetAnchorId() )
486 rDrawView.MarkObj( pObj, rDrawView.Imp().GetPageView(), TRUE );
487 --i;
488 DelLayoutFmt( pFrmFmt );
493 if( rMrkList.GetMarkCount() && bDelMarked )
495 SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
496 if( !pObj->GetUpGroup() )
498 SwUndoDrawDelete* pUndo = !DoesUndo() ? 0
499 : new SwUndoDrawDelete( (USHORT)rMrkList.GetMarkCount() );
501 //ContactObjekte vernichten, Formate sicherstellen.
502 for( i = 0; i < rMrkList.GetMarkCount(); ++i )
504 const SdrMark& rMark = *rMrkList.GetMark( i );
505 pObj = rMark.GetMarkedSdrObj();
506 SwDrawContact *pContact = (SwDrawContact*)pObj->GetUserCall();
507 if( pContact ) // natuerlich nicht bei gruppierten Objekten
509 SwDrawFrmFmt *pFmt = (SwDrawFrmFmt*)pContact->GetFmt();
510 // OD 18.06.2003 #108784# - before delete of selection
511 // is performed, marked <SwDrawVirtObj>-objects have to
512 // be replaced by its reference objects.
513 // Thus, assert, if a <SwDrawVirt>-object is found in the mark list.
514 if ( pObj->ISA(SwDrawVirtObj) )
516 ASSERT( false,
517 "<SwDrawVirtObj> is still marked for delete. application will crash!" );
519 //loescht sich selbst!
520 pContact->Changed(*pObj, SDRUSERCALL_DELETE, pObj->GetLastBoundRect() );
521 pObj->SetUserCall( 0 );
523 if( pUndo )
524 pUndo->AddObj( i, pFmt, rMark );
525 else
526 DelFrmFmt( pFmt );
530 if( pUndo )
531 AppendUndo( pUndo );
533 bCallBase = TRUE;
535 SetModified();
537 EndUndo(UNDO_EMPTY, NULL);
540 return bCallBase;
543 /*************************************************************************
545 |* SwDoc::DeleteSelection()
547 |* Ersterstellung JP 11.01.96
548 |* Letzte Aenderung JP 11.01.96
550 |*************************************************************************/
552 _ZSortFly::_ZSortFly( const SwFrmFmt* pFrmFmt, const SwFmtAnchor* pFlyAn,
553 UINT32 nArrOrdNum )
554 : pFmt( pFrmFmt ), pAnchor( pFlyAn ), nOrdNum( nArrOrdNum )
556 // #i11176#
557 // This also needs to work when no layout exists. Thus, for
558 // FlyFrames an alternative method is used now in that case.
559 SwClientIter aIter( (SwFmt&)*pFmt );
561 if( RES_FLYFRMFMT == pFmt->Which() )
563 if( pFmt->getIDocumentLayoutAccess()->GetRootFrm() )
565 // Schauen, ob es ein SdrObject dafuer gibt
566 if( aIter.First( TYPE( SwFlyFrm) ) )
567 nOrdNum = ((SwFlyFrm*)aIter())->GetVirtDrawObj()->GetOrdNum();
569 else
571 // Schauen, ob es ein SdrObject dafuer gibt
572 if( aIter.First( TYPE(SwFlyDrawContact) ) )
573 nOrdNum = ((SwFlyDrawContact*)aIter())->GetMaster()->GetOrdNum();
576 else if( RES_DRAWFRMFMT == pFmt->Which() )
578 // Schauen, ob es ein SdrObject dafuer gibt
579 if( aIter.First( TYPE(SwDrawContact) ) )
580 nOrdNum = ((SwDrawContact*)aIter())->GetMaster()->GetOrdNum();
582 else {
583 ASSERT( !this, "was ist das fuer ein Format?" );
587 /*************************************************************************/
588 // Wird auch vom Sw3-Reader gerufen, wenn ein Fehler beim Einlesen
589 // des Drawing Layers auftrat. In diesem Fall wird der Layer komplett
590 // neu aufgebaut.
592 // #75371#
593 #include <svx/sxenditm.hxx>
595 void SwDoc::InitDrawModel()
597 RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "SW", "JP93722", "SwDoc::InitDrawModel" );
599 //!!Achtung im sw3-Reader (sw3imp.cxx) gibt es aehnlichen Code, der
600 //mitgepfelgt werden muss.
601 if ( pDrawModel )
602 ReleaseDrawModel();
604 //DrawPool und EditEnginePool anlegen, diese gehoeren uns und werden
605 //dem Drawing nur mitgegeben. Im ReleaseDrawModel werden die Pools wieder
606 //zerstoert.
607 // 17.2.99: for Bug 73110 - for loading the drawing items. This must
608 // be loaded without RefCounts!
609 SfxItemPool *pSdrPool = new SdrItemPool( &GetAttrPool() );
610 // #75371# change DefaultItems for the SdrEdgeObj distance items
611 // to TWIPS.
612 if(pSdrPool)
614 const long nDefEdgeDist = ((500 * 72) / 127); // 1/100th mm in twips
615 pSdrPool->SetPoolDefaultItem(SdrEdgeNode1HorzDistItem(nDefEdgeDist));
616 pSdrPool->SetPoolDefaultItem(SdrEdgeNode1VertDistItem(nDefEdgeDist));
617 pSdrPool->SetPoolDefaultItem(SdrEdgeNode2HorzDistItem(nDefEdgeDist));
618 pSdrPool->SetPoolDefaultItem(SdrEdgeNode2VertDistItem(nDefEdgeDist));
620 // #i33700#
621 // Set shadow distance defaults as PoolDefaultItems. Details see bug.
622 pSdrPool->SetPoolDefaultItem(SdrShadowXDistItem((300 * 72) / 127));
623 pSdrPool->SetPoolDefaultItem(SdrShadowYDistItem((300 * 72) / 127));
625 SfxItemPool *pEEgPool = EditEngine::CreatePool( FALSE );
626 pSdrPool->SetSecondaryPool( pEEgPool );
627 if ( !GetAttrPool().GetFrozenIdRanges () )
628 GetAttrPool().FreezeIdRanges();
629 else
630 pSdrPool->FreezeIdRanges();
632 // SJ: #95129# set FontHeight pool defaults without changing static SdrEngineDefaults
633 GetAttrPool().SetPoolDefaultItem(SvxFontHeightItem( 240, 100, EE_CHAR_FONTHEIGHT ));
635 RTL_LOGFILE_CONTEXT_TRACE( aLog, "before create DrawDocument" );
636 //Das SdrModel gehoert dem Dokument, wir haben immer zwei Layer und eine
637 //Seite.
638 pDrawModel = new SwDrawDocument( this );
640 pDrawModel->EnableUndo( DoesUndo() );
642 String sLayerNm;
643 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Hell" ));
644 nHell = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
646 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Heaven" ));
647 nHeaven = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
649 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Controls" ));
650 nControls = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
652 // OD 25.06.2003 #108784# - add invisible layers corresponding to the
653 // visible ones.
655 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHell" ));
656 nInvisibleHell = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
658 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHeaven" ));
659 nInvisibleHeaven = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
661 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleControls" ));
662 nInvisibleControls = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
665 pDrawModel->InsertPage( pDrawModel->AllocPage( FALSE ) );
666 RTL_LOGFILE_CONTEXT_TRACE( aLog, "after create DrawDocument" );
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" );
676 SetCalcFieldValueHdl(&rOutliner);
677 SetCalcFieldValueHdl(&pDrawModel->GetHitTestOutliner());
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) );
685 OutputDevice* pRefDev = getReferenceDevice( false );
686 if ( pRefDev )
687 pDrawModel->SetRefDevice( pRefDev );
689 pDrawModel->SetNotifyUndoActionHdl( LINK( this, SwDoc, AddDrawUndo ));
690 if ( pLayout )
692 pLayout->SetDrawPage( pDrawModel->GetPage( 0 ) );
693 pLayout->GetDrawPage()->SetSize( pLayout->Frm().SSize() );
697 /** method to notify drawing page view about the invisible layers
699 OD 26.06.2003 #108784#
701 @author OD
703 void SwDoc::NotifyInvisibleLayers( SdrPageView& _rSdrPageView )
705 String sLayerNm;
706 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHell" ));
707 _rSdrPageView.SetLayerVisible( sLayerNm, FALSE );
709 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHeaven" ));
710 _rSdrPageView.SetLayerVisible( sLayerNm, FALSE );
712 sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleControls" ));
713 _rSdrPageView.SetLayerVisible( sLayerNm, FALSE );
716 /** method to determine, if a layer ID belongs to the visible ones.
718 OD 25.06.2003 #108784#
719 Note: If given layer ID is unknown, method asserts and returns <false>.
721 @author OD
723 bool SwDoc::IsVisibleLayerId( const SdrLayerID& _nLayerId ) const
725 bool bRetVal;
727 if ( _nLayerId == GetHeavenId() ||
728 _nLayerId == GetHellId() ||
729 _nLayerId == GetControlsId() )
731 bRetVal = true;
733 else if ( _nLayerId == GetInvisibleHeavenId() ||
734 _nLayerId == GetInvisibleHellId() ||
735 _nLayerId == GetInvisibleControlsId() )
737 bRetVal = false;
739 else
741 ASSERT( false, "<SwDoc::IsVisibleLayerId(..)> - unknown layer ID." );
742 bRetVal = false;
745 return bRetVal;
748 /** method to determine, if the corresponding visible layer ID for a invisible one.
750 OD 25.06.2003 #108784#
751 Note: If given layer ID is a visible one, method returns given layer ID.
752 Note: If given layer ID is unknown, method returns given layer ID.
754 @author OD
756 SdrLayerID SwDoc::GetVisibleLayerIdByInvisibleOne( const SdrLayerID& _nInvisibleLayerId )
758 SdrLayerID nVisibleLayerId;
760 if ( _nInvisibleLayerId == GetInvisibleHeavenId() )
762 nVisibleLayerId = GetHeavenId();
764 else if ( _nInvisibleLayerId == GetInvisibleHellId() )
766 nVisibleLayerId = GetHellId();
768 else if ( _nInvisibleLayerId == GetInvisibleControlsId() )
770 nVisibleLayerId = GetControlsId();
772 else if ( _nInvisibleLayerId == GetHeavenId() ||
773 _nInvisibleLayerId == GetHellId() ||
774 _nInvisibleLayerId == GetControlsId() )
776 ASSERT( false, "<SwDoc::GetVisibleLayerIdByInvisibleOne(..)> - given layer ID already an invisible one." );
777 nVisibleLayerId = _nInvisibleLayerId;
779 else
781 ASSERT( false, "<SwDoc::GetVisibleLayerIdByInvisibleOne(..)> - given layer ID is unknown." );
782 nVisibleLayerId = _nInvisibleLayerId;
785 return nVisibleLayerId;
788 /** method to determine, if the corresponding invisible layer ID for a visible one.
790 OD 25.06.2003 #108784#
791 Note: If given layer ID is a invisible one, method returns given layer ID.
792 Note: If given layer ID is unknown, method returns given layer ID.
794 @author OD
796 SdrLayerID SwDoc::GetInvisibleLayerIdByVisibleOne( const SdrLayerID& _nVisibleLayerId )
798 SdrLayerID nInvisibleLayerId;
800 if ( _nVisibleLayerId == GetHeavenId() )
802 nInvisibleLayerId = GetInvisibleHeavenId();
804 else if ( _nVisibleLayerId == GetHellId() )
806 nInvisibleLayerId = GetInvisibleHellId();
808 else if ( _nVisibleLayerId == GetControlsId() )
810 nInvisibleLayerId = GetInvisibleControlsId();
812 else if ( _nVisibleLayerId == GetInvisibleHeavenId() ||
813 _nVisibleLayerId == GetInvisibleHellId() ||
814 _nVisibleLayerId == GetInvisibleControlsId() )
816 ASSERT( false, "<SwDoc::GetInvisibleLayerIdByVisibleOne(..)> - given layer ID already an invisible one." );
817 nInvisibleLayerId = _nVisibleLayerId;
819 else
821 ASSERT( false, "<SwDoc::GetInvisibleLayerIdByVisibleOne(..)> - given layer ID is unknown." );
822 nInvisibleLayerId = _nVisibleLayerId;
825 return nInvisibleLayerId;
828 /*************************************************************************/
831 void SwDoc::ReleaseDrawModel()
833 if ( pDrawModel )
835 //!!Den code im sw3io fuer Einfuegen Dokument mitpflegen!!
837 delete pDrawModel; pDrawModel = 0;
838 SfxItemPool *pSdrPool = GetAttrPool().GetSecondaryPool();
840 ASSERT( pSdrPool, "missing Pool" );
841 SfxItemPool *pEEgPool = pSdrPool->GetSecondaryPool();
842 ASSERT( !pEEgPool->GetSecondaryPool(), "i don't accept additional pools");
843 pSdrPool->Delete(); //Erst die Items vernichten lassen,
844 //dann erst die Verkettung loesen
845 GetAttrPool().SetSecondaryPool( 0 ); //Der ist ein muss!
846 pSdrPool->SetSecondaryPool( 0 ); //Der ist sicherer
847 SfxItemPool::Free(pSdrPool);
848 SfxItemPool::Free(pEEgPool);
852 /*************************************************************************/
855 SdrModel* SwDoc::_MakeDrawModel()
857 ASSERT( !pDrawModel, "_MakeDrawModel: Why?" );
858 InitDrawModel();
859 if ( pLayout && pLayout->GetCurrShell() )
861 ViewShell* pTmp = pLayout->GetCurrShell();
864 pTmp->MakeDrawView();
865 pTmp = (ViewShell*) pTmp->GetNext();
866 } while ( pTmp != pLayout->GetCurrShell() );
868 //Broadcast, damit die FormShell mit der DrawView verbunden werden kann
869 if( GetDocShell() )
871 SfxSimpleHint aHnt( SW_BROADCAST_DRAWVIEWS_CREATED );
872 GetDocShell()->Broadcast( aHnt );
875 return pDrawModel;
878 /*************************************************************************/
880 void SwDoc::DrawNotifyUndoHdl()
882 pDrawModel->SetNotifyUndoActionHdl( Link() );
885 /*************************************************************************
887 * Am Outliner Link auf Methode fuer Felddarstellung in Editobjekten setzen
889 *************************************************************************/
891 void SwDoc::SetCalcFieldValueHdl(Outliner* pOutliner)
893 pOutliner->SetCalcFieldValueHdl(LINK(this, SwDoc, CalcFieldValueHdl));
896 /*************************************************************************
898 |* Felder bzw URLs im Outliner erkennen und Darstellung festlegen
900 \************************************************************************/
902 IMPL_LINK(SwDoc, CalcFieldValueHdl, EditFieldInfo*, pInfo)
904 if (pInfo)
906 const SvxFieldItem& rField = pInfo->GetField();
907 const SvxFieldData* pField = rField.GetField();
909 if (pField && pField->ISA(SvxDateField))
911 /******************************************************************
912 * Date-Field
913 ******************************************************************/
914 pInfo->SetRepresentation(
915 ((const SvxDateField*) pField)->GetFormatted(
916 *GetNumberFormatter( TRUE ), LANGUAGE_SYSTEM) );
918 else if (pField && pField->ISA(SvxURLField))
920 /******************************************************************
921 * URL-Field
922 ******************************************************************/
924 switch ( ((const SvxURLField*) pField)->GetFormat() )
926 case SVXURLFORMAT_APPDEFAULT: //!!! einstellbar an App???
927 case SVXURLFORMAT_REPR:
929 pInfo->SetRepresentation(
930 ((const SvxURLField*)pField)->GetRepresentation());
932 break;
934 case SVXURLFORMAT_URL:
936 pInfo->SetRepresentation(
937 ((const SvxURLField*)pField)->GetURL());
939 break;
942 USHORT nChrFmt;
944 if (IsVisitedURL(((const SvxURLField*)pField)->GetURL()))
945 nChrFmt = RES_POOLCHR_INET_VISIT;
946 else
947 nChrFmt = RES_POOLCHR_INET_NORMAL;
949 SwFmt *pFmt = GetCharFmtFromPool(nChrFmt);
951 Color aColor(COL_LIGHTBLUE);
952 if (pFmt)
953 aColor = pFmt->GetColor().GetValue();
955 pInfo->SetTxtColor(aColor);
957 else if (pField && pField->ISA(SdrMeasureField))
959 /******************************************************************
960 * Measure-Field
961 ******************************************************************/
962 pInfo->ClearFldColor();
964 else if ( pField && pField->ISA(SvxExtTimeField))
966 /******************************************************************
967 * Time-Field
968 ******************************************************************/
969 pInfo->SetRepresentation(
970 ((const SvxExtTimeField*) pField)->GetFormatted(
971 *GetNumberFormatter( TRUE ), LANGUAGE_SYSTEM) );
973 else
975 DBG_ERROR("unbekannter Feldbefehl");
976 pInfo->SetRepresentation( String( '?' ) );
980 return(0);
983 /* TFFDI: The functions formerly declared 'inline'
985 const SdrModel* SwDoc::GetDrawModel() const { return pDrawModel; }
986 SdrModel* SwDoc::GetDrawModel() { return pDrawModel; }
987 SdrLayerID SwDoc::GetHeavenId() const { return nHeaven; }
988 SdrLayerID SwDoc::GetHellId() const { return nHell; }
989 SdrLayerID SwDoc::GetControlsId() const { return nControls; }
990 SdrLayerID SwDoc::GetInvisibleHeavenId() const { return nInvisibleHeaven; }
991 SdrLayerID SwDoc::GetInvisibleHellId() const { return nInvisibleHell; }
992 SdrLayerID SwDoc::GetInvisibleControlsId() const { return nInvisibleControls; }
993 SdrModel* SwDoc::GetOrCreateDrawModel() { return GetDrawModel() ? GetDrawModel() : _MakeDrawModel(); }
995 // --> OD 2006-03-14 #i62875#
996 namespace docfunc
998 bool ExistsDrawObjs( SwDoc& p_rDoc )
1000 bool bExistsDrawObjs( false );
1002 if ( p_rDoc.GetDrawModel() &&
1003 p_rDoc.GetDrawModel()->GetPage( 0 ) )
1005 const SdrPage& rSdrPage( *(p_rDoc.GetDrawModel()->GetPage( 0 )) );
1007 SdrObjListIter aIter( rSdrPage, IM_FLAT );
1008 while( aIter.IsMore() )
1010 SdrObject* pObj( aIter.Next() );
1011 if ( !dynamic_cast<SwVirtFlyDrawObj*>(pObj) &&
1012 !dynamic_cast<SwFlyDrawObj*>(pObj) )
1014 bExistsDrawObjs = true;
1015 break;
1020 return bExistsDrawObjs;
1023 bool AllDrawObjsOnPage( SwDoc& p_rDoc )
1025 bool bAllDrawObjsOnPage( true );
1027 if ( p_rDoc.GetDrawModel() &&
1028 p_rDoc.GetDrawModel()->GetPage( 0 ) )
1030 const SdrPage& rSdrPage( *(p_rDoc.GetDrawModel()->GetPage( 0 )) );
1032 SdrObjListIter aIter( rSdrPage, IM_FLAT );
1033 while( aIter.IsMore() )
1035 SdrObject* pObj( aIter.Next() );
1036 if ( !dynamic_cast<SwVirtFlyDrawObj*>(pObj) &&
1037 !dynamic_cast<SwFlyDrawObj*>(pObj) )
1039 SwDrawContact* pDrawContact =
1040 dynamic_cast<SwDrawContact*>(::GetUserCall( pObj ));
1041 if ( pDrawContact )
1043 SwAnchoredDrawObject* pAnchoredDrawObj =
1044 dynamic_cast<SwAnchoredDrawObject*>(pDrawContact->GetAnchoredObj( pObj ));
1046 // error handling
1048 if ( !pAnchoredDrawObj )
1050 ASSERT( false,
1051 "<docfunc::AllDrawObjsOnPage() - missing anchored draw object" );
1052 bAllDrawObjsOnPage = false;
1053 break;
1057 if ( pAnchoredDrawObj->NotYetPositioned() )
1059 // The drawing object isn't yet layouted.
1060 // Thus, it isn't known, if all drawing objects are on page.
1061 bAllDrawObjsOnPage = false;
1062 break;
1064 else if ( pAnchoredDrawObj->IsOutsidePage() )
1066 bAllDrawObjsOnPage = false;
1067 break;
1070 else
1072 // contact object of drawing object doesn't exists.
1073 // Thus, the drawing object isn't yet positioned.
1074 // Thus, it isn't known, if all drawing objects are on page.
1075 bAllDrawObjsOnPage = false;
1076 break;
1082 return bAllDrawObjsOnPage;
1085 // <--