blob: b08889fa1c5ea16e5b451f914acc959b75b0d1be [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the 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>
#include <svx/svdpagv.hxx>
#include <dcontact.hxx>
#include <txtfrm.hxx>
#include <frmfmt.hxx>
#include <editeng/frmdiritem.hxx>
#include <fmtornt.hxx>
#include <svx/svditer.hxx>
#include <vector>
#include <switerator.hxx>
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.
if( RES_FLYFRMFMT == pFmt->Which() )
{
if( pFmt->getIDocumentLayoutAccess()->GetCurrentViewShell() ) //swmod 071107//swmod 071225
{
// Schauen, ob es ein SdrObject dafuer gibt
SwFlyFrm* pFly = SwIterator<SwFlyFrm,SwFmt>::FirstElement( *pFrmFmt );
if( pFly )
nOrdNum = pFly->GetVirtDrawObj()->GetOrdNum();
}
else
{
// Schauen, ob es ein SdrObject dafuer gibt
SwFlyDrawContact* pContact = SwIterator<SwFlyDrawContact,SwFmt>::FirstElement( *pFrmFmt );
if( pContact )
nOrdNum = pContact->GetMaster()->GetOrdNum();
}
}
else if( RES_DRAWFRMFMT == pFmt->Which() )
{
// Schauen, ob es ein SdrObject dafuer gibt
SwDrawContact* pContact = SwIterator<SwDrawContact,SwFmt>::FirstElement( *pFrmFmt );
if( pContact )
nOrdNum = pContact->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();
}
SdrPage* pMasterPage = pDrawModel->AllocPage( sal_False );
pDrawModel->InsertPage( pMasterPage );
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 ( pCurrentView )
{
ViewShell* pViewSh = pCurrentView;
do
{
SwRootFrm* pRoot = pViewSh->GetLayout();
if( pRoot && !pRoot->GetDrawPage() )
{
// Disable "multiple layout" for the moment:
// use pMasterPage instead of a new created SdrPage
// pDrawModel->AllocPage( FALSE );
// pDrawModel->InsertPage( pDrawPage );
SdrPage* pDrawPage = pMasterPage;
pRoot->SetDrawPage( pDrawPage );
pDrawPage->SetSize( pRoot->Frm().SSize() );
}
pViewSh = (ViewShell*)pViewSh->GetNext();
}while( pViewSh != pCurrentView );
}
}
/** 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 ( pCurrentView )
{
ViewShell* pTmp = pCurrentView;
do
{
pTmp->MakeDrawView();
pTmp = (ViewShell*) pTmp->GetNext();
} while ( pTmp != pCurrentView );
//Broadcast, damit die FormShell mit der DrawView verbunden werden kann
if( GetDocShell() )
{
SfxSimpleHint aHnt( SW_BROADCAST_DRAWVIEWS_CREATED );
GetDocShell()->Broadcast( aHnt );
}
} //swmod 071029//swmod 071225
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;
}
}
// <--
// eof