summaryrefslogtreecommitdiff
path: root/sw/source/core/doc/docdraw.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/doc/docdraw.cxx')
-rw-r--r--sw/source/core/doc/docdraw.cxx1093
1 files changed, 1093 insertions, 0 deletions
diff --git a/sw/source/core/doc/docdraw.cxx b/sw/source/core/doc/docdraw.cxx
new file mode 100644
index 000000000000..91d99221e1fd
--- /dev/null
+++ b/sw/source/core/doc/docdraw.cxx
@@ -0,0 +1,1093 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+#include <hintids.hxx>
+#include <rtl/logfile.hxx>
+#include <vcl/outdev.hxx>
+#include <sfx2/printer.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/flditem.hxx>
+#include <editeng/editeng.hxx>
+#include <svx/svdoutl.hxx>
+#include <editeng/colritem.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdogrp.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/unolingu.hxx>
+#include <editeng/measfld.hxx>
+#include <svx/svdpool.hxx>
+#include <fmtanchr.hxx>
+#include <charatr.hxx>
+#include <frmfmt.hxx>
+#include <charfmt.hxx>
+#include <viewimp.hxx>
+#include <swhints.hxx>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <docsh.hxx>
+#include <rootfrm.hxx> //Damit der RootDtor gerufen wird.
+#include <poolfmt.hxx>
+#include <viewsh.hxx> // fuer MakeDrawView
+#include <drawdoc.hxx>
+#include <UndoDraw.hxx>
+#include <swundo.hxx> // fuer die UndoIds
+#include <dcontact.hxx>
+#include <dview.hxx>
+#include <mvsave.hxx>
+#include <flyfrm.hxx>
+#include <dflyobj.hxx>
+#include <svx/svdetc.hxx>
+#include <editeng/fhgtitem.hxx>
+
+// OD 26.06.2003 #108784#
+#include <svx/svdpagv.hxx>
+// OD 2004-04-01 #i26791#
+#include <dcontact.hxx>
+#include <txtfrm.hxx>
+#include <frmfmt.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <fmtornt.hxx>
+// --> OD 2006-03-14 #i62875#
+#include <svx/svditer.hxx>
+// <--
+// --> OD 2006-11-01 #130889#
+#include <vector>
+// <--
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::linguistic2;
+
+
+SV_IMPL_VARARR_SORT( _ZSortFlys, _ZSortFly )
+
+/*************************************************************************
+|*
+|* SwDoc::GroupSelection / SwDoc::UnGroupSelection
+|*
+|* Ersterstellung JP 21.08.95
+|* Letzte Aenderung JP 21.08.95
+|*
+|*************************************************************************/
+// OD 2004-04-01 #i26791# - local method to determine positioning and
+// alignment attributes for a drawing object, which is newly connected to
+// the layout. Used for a newly formed group object <SwDoc::GroupSelection(..)>
+// and the members of a destroyed group <SwDoc::UnGroupSelection(..)>
+void lcl_AdjustPositioningAttr( SwDrawFrmFmt* _pFrmFmt,
+ const SdrObject& _rSdrObj )
+{
+ const SwContact* pContact = GetUserCall( &_rSdrObj );
+ ASSERT( pContact, "<lcl_AdjustPositioningAttr(..)> - missing contact object." );
+
+ // determine position of new group object relative to its anchor frame position
+ SwTwips nHoriRelPos = 0;
+ SwTwips nVertRelPos = 0;
+ {
+ const SwFrm* pAnchorFrm = pContact->GetAnchoredObj( &_rSdrObj )->GetAnchorFrm();
+ ASSERT( !pAnchorFrm ||
+ !pAnchorFrm->IsTxtFrm() ||
+ !static_cast<const SwTxtFrm*>(pAnchorFrm)->IsFollow(),
+ "<lcl_AdjustPositioningAttr(..)> - anchor frame is a follow. Please inform OD." );
+ bool bVert = false;
+ bool bR2L = false;
+ // --> OD 2005-05-10 #i45952# - use anchor position of
+ // anchor frame, if it exist.
+ Point aAnchorPos;
+ if ( pAnchorFrm )
+ {
+ // --> OD 2005-05-10 #i45952#
+ aAnchorPos = pAnchorFrm->GetFrmAnchorPos( ::HasWrap( &_rSdrObj ) );
+ // <--
+ bVert = pAnchorFrm->IsVertical();
+ bR2L = pAnchorFrm->IsRightToLeft();
+ }
+ else
+ {
+ // --> OD 2005-05-10 #i45952#
+ aAnchorPos = _rSdrObj.GetAnchorPos();
+ // <--
+ // If no anchor frame exist - e.g. because no layout exists - the
+ // default layout direction is taken.
+ const SvxFrameDirectionItem* pDirItem =
+ static_cast<const SvxFrameDirectionItem*>(&(_pFrmFmt->GetAttrSet().GetPool()->GetDefaultItem( RES_FRAMEDIR )));
+ switch ( pDirItem->GetValue() )
+ {
+ case FRMDIR_VERT_TOP_LEFT:
+ {
+ // vertical from left-to-right - Badaa: supported now!
+ bVert = true;
+ bR2L = true;
+ //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
+ //ASSERT( false, "<lcl_AdjustPositioningAttr(..)> - vertical from left-to-right not supported." );
+ //End
+ }
+ break;
+ case FRMDIR_VERT_TOP_RIGHT:
+ {
+ // vertical from right-to-left
+ bVert = true;
+ bR2L = false;
+ }
+ break;
+ case FRMDIR_HORI_RIGHT_TOP:
+ {
+ // horizontal from right-to-left
+ bVert = false;
+ bR2L = true;
+ }
+ break;
+ case FRMDIR_HORI_LEFT_TOP:
+ {
+ // horizontal from left-to-right
+ bVert = false;
+ bR2L = false;
+ }
+ break;
+ }
+
+ }
+ // use geometry of drawing object
+ const SwRect aObjRect = _rSdrObj.GetSnapRect();
+
+ if ( bVert )
+ {
+ if ( bR2L ) {
+ //FRMDIR_VERT_TOP_LEFT
+ nHoriRelPos = aObjRect.Left() - aAnchorPos.X();
+ nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
+ } else {
+ //FRMDIR_VERT_TOP_RIGHT
+ nHoriRelPos = aObjRect.Top() - aAnchorPos.Y();
+ nVertRelPos = aAnchorPos.X() - aObjRect.Right();
+ }
+ }
+ else if ( bR2L )
+ {
+ nHoriRelPos = aAnchorPos.X() - aObjRect.Right();
+ nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
+ }
+ else
+ {
+ nHoriRelPos = aObjRect.Left() - aAnchorPos.X();
+ nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
+ }
+ //End of SCMS
+ }
+
+ _pFrmFmt->SetFmtAttr( SwFmtHoriOrient( nHoriRelPos, text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
+ _pFrmFmt->SetFmtAttr( SwFmtVertOrient( nVertRelPos, text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
+ // --> OD 2005-03-11 #i44334#, #i44681# - positioning attributes already set
+ _pFrmFmt->PosAttrSet();
+ // <--
+ // --> OD 2004-10-01 #i34750# - keep current object rectangle for drawing
+ // objects. The object rectangle is used on events from the drawing layer
+ // to adjust the positioning attributes - see <SwDrawContact::_Changed(..)>.
+ {
+ const SwAnchoredObject* pAnchoredObj = pContact->GetAnchoredObj( &_rSdrObj );
+ if ( pAnchoredObj->ISA(SwAnchoredDrawObject) )
+ {
+ const SwAnchoredDrawObject* pAnchoredDrawObj =
+ static_cast<const SwAnchoredDrawObject*>(pAnchoredObj);
+ const SwRect aObjRect = _rSdrObj.GetSnapRect();
+ const_cast<SwAnchoredDrawObject*>(pAnchoredDrawObj)
+ ->SetLastObjRect( aObjRect.SVRect() );
+ }
+ }
+ // <--
+}
+
+SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView )
+{
+ // OD 30.06.2003 #108784# - replace marked 'virtual' drawing objects by
+ // the corresponding 'master' drawing objects.
+ SwDrawView::ReplaceMarkedDrawVirtObjs( rDrawView );
+
+ const SdrMarkList &rMrkList = rDrawView.GetMarkedObjectList();
+ SwDrawFrmFmt *pFmt = 0L;
+ SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
+ sal_Bool bNoGroup = ( 0 == pObj->GetUpGroup() );
+ SwDrawContact* pNewContact = 0;
+ if( bNoGroup )
+ {
+ //Ankerattribut aufheben.
+ SwDrawContact *pMyContact = (SwDrawContact*)GetUserCall(pObj);
+ const SwFmtAnchor aAnch( pMyContact->GetFmt()->GetAnchor() );
+
+ SwUndoDrawGroup *const pUndo = (!GetIDocumentUndoRedo().DoesUndo())
+ ? 0
+ : new SwUndoDrawGroup( (sal_uInt16)rMrkList.GetMarkCount() );
+
+ // --> OD 2005-08-16 #i53320#
+ bool bGroupMembersNotPositioned( false );
+ {
+ SwAnchoredDrawObject* pAnchoredDrawObj =
+ static_cast<SwAnchoredDrawObject*>(pMyContact->GetAnchoredObj( pObj ));
+ bGroupMembersNotPositioned = pAnchoredDrawObj->NotYetPositioned();
+ }
+ // <--
+ //ContactObjekte und Formate vernichten.
+ for( sal_uInt16 i = 0; i < rMrkList.GetMarkCount(); ++i )
+ {
+ pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
+ SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
+
+ // --> OD 2005-08-16 #i53320#
+#ifdef DBG_UTIL
+ SwAnchoredDrawObject* pAnchoredDrawObj =
+ static_cast<SwAnchoredDrawObject*>(pContact->GetAnchoredObj( pObj ));
+ ASSERT( bGroupMembersNotPositioned == pAnchoredDrawObj->NotYetPositioned(),
+ "<SwDoc::GroupSelection(..)> - group members have different positioning status!" );
+#endif
+ // <--
+
+ pFmt = (SwDrawFrmFmt*)pContact->GetFmt();
+ //loescht sich selbst!
+ pContact->Changed(*pObj, SDRUSERCALL_DELETE, pObj->GetLastBoundRect() );
+ pObj->SetUserCall( 0 );
+
+ if( pUndo )
+ pUndo->AddObj( i, pFmt, pObj );
+ else
+ DelFrmFmt( pFmt );
+
+ // --> OD 2005-05-10 #i45952# - re-introduce position
+ // normalization of group member objects, because its anchor position
+ // is cleared, when they are grouped.
+ Point aAnchorPos( pObj->GetAnchorPos() );
+ pObj->NbcSetAnchorPos( Point( 0, 0 ) );
+ pObj->NbcMove( Size( aAnchorPos.X(), aAnchorPos.Y() ) );
+ // <--
+ }
+
+ pFmt = MakeDrawFrmFmt( String::CreateFromAscii(
+ RTL_CONSTASCII_STRINGPARAM( "DrawObject" )),
+ GetDfltFrmFmt() );
+ pFmt->SetFmtAttr( aAnch );
+ // --> OD 2004-10-25 #i36010# - set layout direction of the position
+ pFmt->SetPositionLayoutDir(
+ text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
+ // <--
+
+ rDrawView.GroupMarked();
+ ASSERT( rMrkList.GetMarkCount() == 1, "GroupMarked more or none groups." );
+
+ SdrObject* pNewGroupObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
+ pNewContact = new SwDrawContact( pFmt, pNewGroupObj );
+ // --> OD 2004-11-22 #i35635#
+ pNewContact->MoveObjToVisibleLayer( pNewGroupObj );
+ // <--
+ pNewContact->ConnectToLayout();
+ // --> OD 2005-08-16 #i53320# - No adjustment of the positioning and
+ // alignment attributes, if group members aren't positioned yet.
+ if ( !bGroupMembersNotPositioned )
+ {
+ // OD 2004-04-01 #i26791# - Adjust positioning and alignment attributes.
+ lcl_AdjustPositioningAttr( pFmt, *pNewGroupObj );
+ }
+ // <--
+
+ if( pUndo )
+ {
+ pUndo->SetGroupFmt( pFmt );
+ GetIDocumentUndoRedo().AppendUndo( pUndo );
+ }
+ }
+ else
+ {
+ if (GetIDocumentUndoRedo().DoesUndo())
+ {
+ GetIDocumentUndoRedo().ClearRedo();
+ }
+
+ rDrawView.GroupMarked();
+ ASSERT( rMrkList.GetMarkCount() == 1, "GroupMarked more or none groups." );
+ }
+
+ return pNewContact;
+}
+
+
+void SwDoc::UnGroupSelection( SdrView& rDrawView )
+{
+ bool const bUndo = GetIDocumentUndoRedo().DoesUndo();
+ if( bUndo )
+ {
+ GetIDocumentUndoRedo().ClearRedo();
+ }
+
+ // OD 30.06.2003 #108784# - replace marked 'virtual' drawing objects by
+ // the corresponding 'master' drawing objects.
+ SwDrawView::ReplaceMarkedDrawVirtObjs( rDrawView );
+
+ const SdrMarkList &rMrkList = rDrawView.GetMarkedObjectList();
+ // --> OD 2006-11-01 #130889#
+ std::vector< std::pair< SwDrawFrmFmt*, SdrObject* > >* pFmtsAndObjs( 0L );
+ const sal_uInt32 nMarkCount( rMrkList.GetMarkCount() );
+ // <--
+ if ( nMarkCount )
+ {
+ // --> OD 2006-11-01 #130889#
+ pFmtsAndObjs = new std::vector< std::pair< SwDrawFrmFmt*, SdrObject* > >[nMarkCount];
+ // <--
+ SdrObject *pMyObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
+ if( !pMyObj->GetUpGroup() )
+ {
+ String sDrwFmtNm( String::CreateFromAscii(
+ RTL_CONSTASCII_STRINGPARAM("DrawObject" )));
+ for ( sal_uInt16 i = 0; i < nMarkCount; ++i )
+ {
+ SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
+ if ( pObj->IsA( TYPE(SdrObjGroup) ) )
+ {
+ SwDrawContact *pContact = (SwDrawContact*)GetUserCall(pObj);
+ SwFmtAnchor aAnch( pContact->GetFmt()->GetAnchor() );
+ SdrObjList *pLst = ((SdrObjGroup*)pObj)->GetSubList();
+
+ SwUndoDrawUnGroup* pUndo = 0;
+ if( bUndo )
+ {
+ pUndo = new SwUndoDrawUnGroup( (SdrObjGroup*)pObj );
+ GetIDocumentUndoRedo().AppendUndo(pUndo);
+ }
+
+ for ( sal_uInt16 i2 = 0; i2 < pLst->GetObjCount(); ++i2 )
+ {
+ SdrObject* pSubObj = pLst->GetObj( i2 );
+ SwDrawFrmFmt *pFmt = MakeDrawFrmFmt( sDrwFmtNm,
+ GetDfltFrmFmt() );
+ pFmt->SetFmtAttr( aAnch );
+ // --> OD 2004-10-25 #i36010# - set layout direction of the position
+ pFmt->SetPositionLayoutDir(
+ text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
+ // <--
+ // --> OD 2006-11-01 #130889#
+ // creation of <SwDrawContact> instances for the group
+ // members and its connection to the Writer layout is
+ // done after intrinsic ungrouping.
+// SwDrawContact* pContact = new SwDrawContact( pFmt, pSubObj );
+// // --> OD 2004-11-22 #i35635#
+// pContact->MoveObjToVisibleLayer( pSubObj );
+// // <--
+// pContact->ConnectToLayout();
+// // OD 2004-04-07 #i26791# - Adjust positioning and
+// // alignment attributes.
+// lcl_AdjustPositioningAttr( pFmt, *pSubObj );
+ pFmtsAndObjs[i].push_back( std::pair< SwDrawFrmFmt*, SdrObject* >( pFmt, pSubObj ) );
+ // <--
+
+ if( bUndo )
+ pUndo->AddObj( i2, pFmt );
+ }
+ }
+ }
+ }
+ }
+ rDrawView.UnGroupMarked();
+ // --> OD 2006-11-01 #130889#
+ // creation of <SwDrawContact> instances for the former group members and
+ // its connection to the Writer layout.
+ for ( sal_uInt32 i = 0; i < nMarkCount; ++i )
+ {
+ SwUndoDrawUnGroupConnectToLayout* pUndo = 0;
+ if( bUndo )
+ {
+ pUndo = new SwUndoDrawUnGroupConnectToLayout();
+ GetIDocumentUndoRedo().AppendUndo(pUndo);
+ }
+
+ while ( pFmtsAndObjs[i].size() > 0 )
+ {
+ SwDrawFrmFmt* pFmt( pFmtsAndObjs[i].back().first );
+ SdrObject* pObj( pFmtsAndObjs[i].back().second );
+ pFmtsAndObjs[i].pop_back();
+
+ SwDrawContact* pContact = new SwDrawContact( pFmt, pObj );
+ pContact->MoveObjToVisibleLayer( pObj );
+ pContact->ConnectToLayout();
+ lcl_AdjustPositioningAttr( pFmt, *pObj );
+
+ if ( bUndo )
+ {
+ pUndo->AddFmtAndObj( pFmt, pObj );
+ }
+ }
+ }
+ delete [] pFmtsAndObjs;
+ // <--
+}
+
+/*************************************************************************
+|*
+|* SwDoc::DeleteSelection()
+|*
+|* Ersterstellung MA 14. Nov. 95
+|* Letzte Aenderung MA 14. Nov. 95
+|*
+|*************************************************************************/
+
+sal_Bool SwDoc::DeleteSelection( SwDrawView& rDrawView )
+{
+ sal_Bool bCallBase = sal_False;
+ const SdrMarkList &rMrkList = rDrawView.GetMarkedObjectList();
+ if( rMrkList.GetMarkCount() )
+ {
+ GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL);
+ sal_uInt16 i;
+ sal_Bool bDelMarked = sal_True;
+
+ if( 1 == rMrkList.GetMarkCount() )
+ {
+ SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
+ if( pObj->ISA(SwVirtFlyDrawObj) )
+ {
+ SwFlyFrmFmt* pFrmFmt = (SwFlyFrmFmt*)
+ ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm()->GetFmt();
+ if( pFrmFmt )
+ {
+ DelLayoutFmt( pFrmFmt );
+ bDelMarked = sal_False;
+ }
+ }
+ }
+
+ for( i = 0; i < rMrkList.GetMarkCount(); ++i )
+ {
+ SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
+ if( !pObj->ISA(SwVirtFlyDrawObj) )
+ {
+ SwDrawContact *pC = (SwDrawContact*)GetUserCall(pObj);
+ SwDrawFrmFmt *pFrmFmt = (SwDrawFrmFmt*)pC->GetFmt();
+ if( pFrmFmt &&
+ FLY_AS_CHAR == pFrmFmt->GetAnchor().GetAnchorId() )
+ {
+ rDrawView.MarkObj( pObj, rDrawView.Imp().GetPageView(), sal_True );
+ --i;
+ DelLayoutFmt( pFrmFmt );
+ }
+ }
+ }
+
+ if( rMrkList.GetMarkCount() && bDelMarked )
+ {
+ SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
+ if( !pObj->GetUpGroup() )
+ {
+ SwUndoDrawDelete *const pUndo =
+ (!GetIDocumentUndoRedo().DoesUndo())
+ ? 0
+ : new SwUndoDrawDelete( (sal_uInt16)rMrkList.GetMarkCount() );
+
+ //ContactObjekte vernichten, Formate sicherstellen.
+ for( i = 0; i < rMrkList.GetMarkCount(); ++i )
+ {
+ const SdrMark& rMark = *rMrkList.GetMark( i );
+ pObj = rMark.GetMarkedSdrObj();
+ SwDrawContact *pContact = (SwDrawContact*)pObj->GetUserCall();
+ if( pContact ) // natuerlich nicht bei gruppierten Objekten
+ {
+ SwDrawFrmFmt *pFmt = (SwDrawFrmFmt*)pContact->GetFmt();
+ // OD 18.06.2003 #108784# - before delete of selection
+ // is performed, marked <SwDrawVirtObj>-objects have to
+ // be replaced by its reference objects.
+ // Thus, assert, if a <SwDrawVirt>-object is found in the mark list.
+ if ( pObj->ISA(SwDrawVirtObj) )
+ {
+ ASSERT( false,
+ "<SwDrawVirtObj> is still marked for delete. application will crash!" );
+ }
+ //loescht sich selbst!
+ pContact->Changed(*pObj, SDRUSERCALL_DELETE, pObj->GetLastBoundRect() );
+ pObj->SetUserCall( 0 );
+
+ if( pUndo )
+ pUndo->AddObj( i, pFmt, rMark );
+ else
+ DelFrmFmt( pFmt );
+ }
+ }
+
+ if( pUndo )
+ {
+ GetIDocumentUndoRedo().AppendUndo( pUndo );
+ }
+ }
+ bCallBase = sal_True;
+ }
+ SetModified();
+
+ GetIDocumentUndoRedo().EndUndo(UNDO_EMPTY, NULL);
+ }
+
+ return bCallBase;
+}
+
+/*************************************************************************
+|*
+|* SwDoc::DeleteSelection()
+|*
+|* Ersterstellung JP 11.01.96
+|* Letzte Aenderung JP 11.01.96
+|*
+|*************************************************************************/
+
+_ZSortFly::_ZSortFly( const SwFrmFmt* pFrmFmt, const SwFmtAnchor* pFlyAn,
+ sal_uInt32 nArrOrdNum )
+ : pFmt( pFrmFmt ), pAnchor( pFlyAn ), nOrdNum( nArrOrdNum )
+{
+ // #i11176#
+ // This also needs to work when no layout exists. Thus, for
+ // FlyFrames an alternative method is used now in that case.
+ SwClientIter aIter( (SwFmt&)*pFmt );
+
+ if( RES_FLYFRMFMT == pFmt->Which() )
+ {
+ if( pFmt->getIDocumentLayoutAccess()->GetRootFrm() )
+ {
+ // Schauen, ob es ein SdrObject dafuer gibt
+ if( aIter.First( TYPE( SwFlyFrm) ) )
+ nOrdNum = ((SwFlyFrm*)aIter())->GetVirtDrawObj()->GetOrdNum();
+ }
+ else
+ {
+ // Schauen, ob es ein SdrObject dafuer gibt
+ if( aIter.First( TYPE(SwFlyDrawContact) ) )
+ nOrdNum = ((SwFlyDrawContact*)aIter())->GetMaster()->GetOrdNum();
+ }
+ }
+ else if( RES_DRAWFRMFMT == pFmt->Which() )
+ {
+ // Schauen, ob es ein SdrObject dafuer gibt
+ if( aIter.First( TYPE(SwDrawContact) ) )
+ nOrdNum = ((SwDrawContact*)aIter())->GetMaster()->GetOrdNum();
+ }
+ else {
+ ASSERT( !this, "was ist das fuer ein Format?" );
+ }
+}
+
+/*************************************************************************/
+// Wird auch vom Sw3-Reader gerufen, wenn ein Fehler beim Einlesen
+// des Drawing Layers auftrat. In diesem Fall wird der Layer komplett
+// neu aufgebaut.
+
+// #75371#
+#include <svx/sxenditm.hxx>
+
+void SwDoc::InitDrawModel()
+{
+ RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "SW", "JP93722", "SwDoc::InitDrawModel" );
+
+ //!!Achtung im sw3-Reader (sw3imp.cxx) gibt es aehnlichen Code, der
+ //mitgepfelgt werden muss.
+ if ( pDrawModel )
+ ReleaseDrawModel();
+
+ //DrawPool und EditEnginePool anlegen, diese gehoeren uns und werden
+ //dem Drawing nur mitgegeben. Im ReleaseDrawModel werden die Pools wieder
+ //zerstoert.
+ // 17.2.99: for Bug 73110 - for loading the drawing items. This must
+ // be loaded without RefCounts!
+ SfxItemPool *pSdrPool = new SdrItemPool( &GetAttrPool() );
+ // #75371# change DefaultItems for the SdrEdgeObj distance items
+ // to TWIPS.
+ if(pSdrPool)
+ {
+ const long nDefEdgeDist = ((500 * 72) / 127); // 1/100th mm in twips
+ pSdrPool->SetPoolDefaultItem(SdrEdgeNode1HorzDistItem(nDefEdgeDist));
+ pSdrPool->SetPoolDefaultItem(SdrEdgeNode1VertDistItem(nDefEdgeDist));
+ pSdrPool->SetPoolDefaultItem(SdrEdgeNode2HorzDistItem(nDefEdgeDist));
+ pSdrPool->SetPoolDefaultItem(SdrEdgeNode2VertDistItem(nDefEdgeDist));
+
+ // #i33700#
+ // Set shadow distance defaults as PoolDefaultItems. Details see bug.
+ pSdrPool->SetPoolDefaultItem(SdrShadowXDistItem((300 * 72) / 127));
+ pSdrPool->SetPoolDefaultItem(SdrShadowYDistItem((300 * 72) / 127));
+ }
+ SfxItemPool *pEEgPool = EditEngine::CreatePool( sal_False );
+ pSdrPool->SetSecondaryPool( pEEgPool );
+ if ( !GetAttrPool().GetFrozenIdRanges () )
+ GetAttrPool().FreezeIdRanges();
+ else
+ pSdrPool->FreezeIdRanges();
+
+ // SJ: #95129# set FontHeight pool defaults without changing static SdrEngineDefaults
+ GetAttrPool().SetPoolDefaultItem(SvxFontHeightItem( 240, 100, EE_CHAR_FONTHEIGHT ));
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "before create DrawDocument" );
+ //Das SdrModel gehoert dem Dokument, wir haben immer zwei Layer und eine
+ //Seite.
+ pDrawModel = new SwDrawDocument( this );
+
+ pDrawModel->EnableUndo( GetIDocumentUndoRedo().DoesUndo() );
+
+ String sLayerNm;
+ sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Hell" ));
+ nHell = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
+
+ sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Heaven" ));
+ nHeaven = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
+
+ sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Controls" ));
+ nControls = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
+
+ // OD 25.06.2003 #108784# - add invisible layers corresponding to the
+ // visible ones.
+ {
+ sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHell" ));
+ nInvisibleHell = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
+
+ sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHeaven" ));
+ nInvisibleHeaven = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
+
+ sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleControls" ));
+ nInvisibleControls = pDrawModel->GetLayerAdmin().NewLayer( sLayerNm )->GetID();
+ }
+
+ pDrawModel->InsertPage( pDrawModel->AllocPage( sal_False ) );
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "after create DrawDocument" );
+
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "before create Spellchecker/Hyphenator" );
+ SdrOutliner& rOutliner = pDrawModel->GetDrawOutliner();
+ uno::Reference< XSpellChecker1 > xSpell = ::GetSpellChecker();
+ rOutliner.SetSpeller( xSpell );
+ uno::Reference<XHyphenator> xHyphenator( ::GetHyphenator() );
+ rOutliner.SetHyphenator( xHyphenator );
+ RTL_LOGFILE_CONTEXT_TRACE( aLog, "after create Spellchecker/Hyphenator" );
+
+ SetCalcFieldValueHdl(&rOutliner);
+ SetCalcFieldValueHdl(&pDrawModel->GetHitTestOutliner());
+
+ //JP 16.07.98: Bug 50193 - Linkmanager am Model setzen, damit
+ // dort ggfs. verlinkte Grafiken eingefuegt werden koennen
+ //JP 28.01.99: der WinWord Import benoetigt ihn auch
+ pDrawModel->SetLinkManager( &GetLinkManager() );
+ pDrawModel->SetAddExtLeading( get(IDocumentSettingAccess::ADD_EXT_LEADING) );
+
+ OutputDevice* pRefDev = getReferenceDevice( false );
+ if ( pRefDev )
+ pDrawModel->SetRefDevice( pRefDev );
+
+ pDrawModel->SetNotifyUndoActionHdl( LINK( this, SwDoc, AddDrawUndo ));
+ if ( pLayout )
+ {
+ pLayout->SetDrawPage( pDrawModel->GetPage( 0 ) );
+ pLayout->GetDrawPage()->SetSize( pLayout->Frm().SSize() );
+ }
+}
+
+/** method to notify drawing page view about the invisible layers
+
+ OD 26.06.2003 #108784#
+
+ @author OD
+*/
+void SwDoc::NotifyInvisibleLayers( SdrPageView& _rSdrPageView )
+{
+ String sLayerNm;
+ sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHell" ));
+ _rSdrPageView.SetLayerVisible( sLayerNm, sal_False );
+
+ sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleHeaven" ));
+ _rSdrPageView.SetLayerVisible( sLayerNm, sal_False );
+
+ sLayerNm.AssignAscii(RTL_CONSTASCII_STRINGPARAM("InvisibleControls" ));
+ _rSdrPageView.SetLayerVisible( sLayerNm, sal_False );
+}
+
+/** method to determine, if a layer ID belongs to the visible ones.
+
+ OD 25.06.2003 #108784#
+ Note: If given layer ID is unknown, method asserts and returns <false>.
+
+ @author OD
+*/
+bool SwDoc::IsVisibleLayerId( const SdrLayerID& _nLayerId ) const
+{
+ bool bRetVal;
+
+ if ( _nLayerId == GetHeavenId() ||
+ _nLayerId == GetHellId() ||
+ _nLayerId == GetControlsId() )
+ {
+ bRetVal = true;
+ }
+ else if ( _nLayerId == GetInvisibleHeavenId() ||
+ _nLayerId == GetInvisibleHellId() ||
+ _nLayerId == GetInvisibleControlsId() )
+ {
+ bRetVal = false;
+ }
+ else
+ {
+ ASSERT( false, "<SwDoc::IsVisibleLayerId(..)> - unknown layer ID." );
+ bRetVal = false;
+ }
+
+ return bRetVal;
+}
+
+/** method to determine, if the corresponding visible layer ID for a invisible one.
+
+ OD 25.06.2003 #108784#
+ Note: If given layer ID is a visible one, method returns given layer ID.
+ Note: If given layer ID is unknown, method returns given layer ID.
+
+ @author OD
+*/
+SdrLayerID SwDoc::GetVisibleLayerIdByInvisibleOne( const SdrLayerID& _nInvisibleLayerId )
+{
+ SdrLayerID nVisibleLayerId;
+
+ if ( _nInvisibleLayerId == GetInvisibleHeavenId() )
+ {
+ nVisibleLayerId = GetHeavenId();
+ }
+ else if ( _nInvisibleLayerId == GetInvisibleHellId() )
+ {
+ nVisibleLayerId = GetHellId();
+ }
+ else if ( _nInvisibleLayerId == GetInvisibleControlsId() )
+ {
+ nVisibleLayerId = GetControlsId();
+ }
+ else if ( _nInvisibleLayerId == GetHeavenId() ||
+ _nInvisibleLayerId == GetHellId() ||
+ _nInvisibleLayerId == GetControlsId() )
+ {
+ ASSERT( false, "<SwDoc::GetVisibleLayerIdByInvisibleOne(..)> - given layer ID already an invisible one." );
+ nVisibleLayerId = _nInvisibleLayerId;
+ }
+ else
+ {
+ ASSERT( false, "<SwDoc::GetVisibleLayerIdByInvisibleOne(..)> - given layer ID is unknown." );
+ nVisibleLayerId = _nInvisibleLayerId;
+ }
+
+ return nVisibleLayerId;
+}
+
+/** method to determine, if the corresponding invisible layer ID for a visible one.
+
+ OD 25.06.2003 #108784#
+ Note: If given layer ID is a invisible one, method returns given layer ID.
+ Note: If given layer ID is unknown, method returns given layer ID.
+
+ @author OD
+*/
+SdrLayerID SwDoc::GetInvisibleLayerIdByVisibleOne( const SdrLayerID& _nVisibleLayerId )
+{
+ SdrLayerID nInvisibleLayerId;
+
+ if ( _nVisibleLayerId == GetHeavenId() )
+ {
+ nInvisibleLayerId = GetInvisibleHeavenId();
+ }
+ else if ( _nVisibleLayerId == GetHellId() )
+ {
+ nInvisibleLayerId = GetInvisibleHellId();
+ }
+ else if ( _nVisibleLayerId == GetControlsId() )
+ {
+ nInvisibleLayerId = GetInvisibleControlsId();
+ }
+ else if ( _nVisibleLayerId == GetInvisibleHeavenId() ||
+ _nVisibleLayerId == GetInvisibleHellId() ||
+ _nVisibleLayerId == GetInvisibleControlsId() )
+ {
+ ASSERT( false, "<SwDoc::GetInvisibleLayerIdByVisibleOne(..)> - given layer ID already an invisible one." );
+ nInvisibleLayerId = _nVisibleLayerId;
+ }
+ else
+ {
+ ASSERT( false, "<SwDoc::GetInvisibleLayerIdByVisibleOne(..)> - given layer ID is unknown." );
+ nInvisibleLayerId = _nVisibleLayerId;
+ }
+
+ return nInvisibleLayerId;
+}
+
+/*************************************************************************/
+
+
+void SwDoc::ReleaseDrawModel()
+{
+ if ( pDrawModel )
+ {
+ //!!Den code im sw3io fuer Einfuegen Dokument mitpflegen!!
+
+ delete pDrawModel; pDrawModel = 0;
+ SfxItemPool *pSdrPool = GetAttrPool().GetSecondaryPool();
+
+ ASSERT( pSdrPool, "missing Pool" );
+ SfxItemPool *pEEgPool = pSdrPool->GetSecondaryPool();
+ ASSERT( !pEEgPool->GetSecondaryPool(), "i don't accept additional pools");
+ pSdrPool->Delete(); //Erst die Items vernichten lassen,
+ //dann erst die Verkettung loesen
+ GetAttrPool().SetSecondaryPool( 0 ); //Der ist ein muss!
+ pSdrPool->SetSecondaryPool( 0 ); //Der ist sicherer
+ SfxItemPool::Free(pSdrPool);
+ SfxItemPool::Free(pEEgPool);
+ }
+}
+
+/*************************************************************************/
+
+
+SdrModel* SwDoc::_MakeDrawModel()
+{
+ ASSERT( !pDrawModel, "_MakeDrawModel: Why?" );
+ InitDrawModel();
+ if ( pLayout && pLayout->GetCurrShell() )
+ {
+ ViewShell* pTmp = pLayout->GetCurrShell();
+ do
+ {
+ pTmp->MakeDrawView();
+ pTmp = (ViewShell*) pTmp->GetNext();
+ } while ( pTmp != pLayout->GetCurrShell() );
+
+ //Broadcast, damit die FormShell mit der DrawView verbunden werden kann
+ if( GetDocShell() )
+ {
+ SfxSimpleHint aHnt( SW_BROADCAST_DRAWVIEWS_CREATED );
+ GetDocShell()->Broadcast( aHnt );
+ }
+ }
+ return pDrawModel;
+}
+
+/*************************************************************************/
+
+void SwDoc::DrawNotifyUndoHdl()
+{
+ pDrawModel->SetNotifyUndoActionHdl( Link() );
+}
+
+/*************************************************************************
+*
+* Am Outliner Link auf Methode fuer Felddarstellung in Editobjekten setzen
+*
+*************************************************************************/
+
+void SwDoc::SetCalcFieldValueHdl(Outliner* pOutliner)
+{
+ pOutliner->SetCalcFieldValueHdl(LINK(this, SwDoc, CalcFieldValueHdl));
+}
+
+/*************************************************************************
+|*
+|* Felder bzw URLs im Outliner erkennen und Darstellung festlegen
+|*
+\************************************************************************/
+
+IMPL_LINK(SwDoc, CalcFieldValueHdl, EditFieldInfo*, pInfo)
+{
+ if (pInfo)
+ {
+ const SvxFieldItem& rField = pInfo->GetField();
+ const SvxFieldData* pField = rField.GetField();
+
+ if (pField && pField->ISA(SvxDateField))
+ {
+ /******************************************************************
+ * Date-Field
+ ******************************************************************/
+ pInfo->SetRepresentation(
+ ((const SvxDateField*) pField)->GetFormatted(
+ *GetNumberFormatter( sal_True ), LANGUAGE_SYSTEM) );
+ }
+ else if (pField && pField->ISA(SvxURLField))
+ {
+ /******************************************************************
+ * URL-Field
+ ******************************************************************/
+
+ switch ( ((const SvxURLField*) pField)->GetFormat() )
+ {
+ case SVXURLFORMAT_APPDEFAULT: //!!! einstellbar an App???
+ case SVXURLFORMAT_REPR:
+ {
+ pInfo->SetRepresentation(
+ ((const SvxURLField*)pField)->GetRepresentation());
+ }
+ break;
+
+ case SVXURLFORMAT_URL:
+ {
+ pInfo->SetRepresentation(
+ ((const SvxURLField*)pField)->GetURL());
+ }
+ break;
+ }
+
+ sal_uInt16 nChrFmt;
+
+ if (IsVisitedURL(((const SvxURLField*)pField)->GetURL()))
+ nChrFmt = RES_POOLCHR_INET_VISIT;
+ else
+ nChrFmt = RES_POOLCHR_INET_NORMAL;
+
+ SwFmt *pFmt = GetCharFmtFromPool(nChrFmt);
+
+ Color aColor(COL_LIGHTBLUE);
+ if (pFmt)
+ aColor = pFmt->GetColor().GetValue();
+
+ pInfo->SetTxtColor(aColor);
+ }
+ else if (pField && pField->ISA(SdrMeasureField))
+ {
+ /******************************************************************
+ * Measure-Field
+ ******************************************************************/
+ pInfo->ClearFldColor();
+ }
+ else if ( pField && pField->ISA(SvxExtTimeField))
+ {
+ /******************************************************************
+ * Time-Field
+ ******************************************************************/
+ pInfo->SetRepresentation(
+ ((const SvxExtTimeField*) pField)->GetFormatted(
+ *GetNumberFormatter( sal_True ), LANGUAGE_SYSTEM) );
+ }
+ else
+ {
+ DBG_ERROR("unbekannter Feldbefehl");
+ pInfo->SetRepresentation( String( '?' ) );
+ }
+ }
+
+ return(0);
+}
+
+/* TFFDI: The functions formerly declared 'inline'
+ */
+const SdrModel* SwDoc::GetDrawModel() const { return pDrawModel; }
+SdrModel* SwDoc::GetDrawModel() { return pDrawModel; }
+SdrLayerID SwDoc::GetHeavenId() const { return nHeaven; }
+SdrLayerID SwDoc::GetHellId() const { return nHell; }
+SdrLayerID SwDoc::GetControlsId() const { return nControls; }
+SdrLayerID SwDoc::GetInvisibleHeavenId() const { return nInvisibleHeaven; }
+SdrLayerID SwDoc::GetInvisibleHellId() const { return nInvisibleHell; }
+SdrLayerID SwDoc::GetInvisibleControlsId() const { return nInvisibleControls; }
+SdrModel* SwDoc::GetOrCreateDrawModel() { return GetDrawModel() ? GetDrawModel() : _MakeDrawModel(); }
+
+// --> OD 2006-03-14 #i62875#
+namespace docfunc
+{
+ bool ExistsDrawObjs( SwDoc& p_rDoc )
+ {
+ bool bExistsDrawObjs( false );
+
+ if ( p_rDoc.GetDrawModel() &&
+ p_rDoc.GetDrawModel()->GetPage( 0 ) )
+ {
+ const SdrPage& rSdrPage( *(p_rDoc.GetDrawModel()->GetPage( 0 )) );
+
+ SdrObjListIter aIter( rSdrPage, IM_FLAT );
+ while( aIter.IsMore() )
+ {
+ SdrObject* pObj( aIter.Next() );
+ if ( !dynamic_cast<SwVirtFlyDrawObj*>(pObj) &&
+ !dynamic_cast<SwFlyDrawObj*>(pObj) )
+ {
+ bExistsDrawObjs = true;
+ break;
+ }
+ }
+ }
+
+ return bExistsDrawObjs;
+ }
+
+ bool AllDrawObjsOnPage( SwDoc& p_rDoc )
+ {
+ bool bAllDrawObjsOnPage( true );
+
+ if ( p_rDoc.GetDrawModel() &&
+ p_rDoc.GetDrawModel()->GetPage( 0 ) )
+ {
+ const SdrPage& rSdrPage( *(p_rDoc.GetDrawModel()->GetPage( 0 )) );
+
+ SdrObjListIter aIter( rSdrPage, IM_FLAT );
+ while( aIter.IsMore() )
+ {
+ SdrObject* pObj( aIter.Next() );
+ if ( !dynamic_cast<SwVirtFlyDrawObj*>(pObj) &&
+ !dynamic_cast<SwFlyDrawObj*>(pObj) )
+ {
+ SwDrawContact* pDrawContact =
+ dynamic_cast<SwDrawContact*>(::GetUserCall( pObj ));
+ if ( pDrawContact )
+ {
+ SwAnchoredDrawObject* pAnchoredDrawObj =
+ dynamic_cast<SwAnchoredDrawObject*>(pDrawContact->GetAnchoredObj( pObj ));
+
+ // error handling
+ {
+ if ( !pAnchoredDrawObj )
+ {
+ ASSERT( false,
+ "<docfunc::AllDrawObjsOnPage() - missing anchored draw object" );
+ bAllDrawObjsOnPage = false;
+ break;
+ }
+ }
+
+ if ( pAnchoredDrawObj->NotYetPositioned() )
+ {
+ // The drawing object isn't yet layouted.
+ // Thus, it isn't known, if all drawing objects are on page.
+ bAllDrawObjsOnPage = false;
+ break;
+ }
+ else if ( pAnchoredDrawObj->IsOutsidePage() )
+ {
+ bAllDrawObjsOnPage = false;
+ break;
+ }
+ }
+ else
+ {
+ // contact object of drawing object doesn't exists.
+ // Thus, the drawing object isn't yet positioned.
+ // Thus, it isn't known, if all drawing objects are on page.
+ bAllDrawObjsOnPage = false;
+ break;
+ }
+ }
+ }
+ }
+
+ return bAllDrawObjsOnPage;
+ }
+}
+// <--
+