diff options
Diffstat (limited to 'binfilter/bf_sw/source/core/ole/sw_ndole.cxx')
-rw-r--r-- | binfilter/bf_sw/source/core/ole/sw_ndole.cxx | 536 |
1 files changed, 536 insertions, 0 deletions
diff --git a/binfilter/bf_sw/source/core/ole/sw_ndole.cxx b/binfilter/bf_sw/source/core/ole/sw_ndole.cxx new file mode 100644 index 000000000000..e435257a6322 --- /dev/null +++ b/binfilter/bf_sw/source/core/ole/sw_ndole.cxx @@ -0,0 +1,536 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + + +#ifdef _MSC_VER +#pragma hdrstop +#endif + + +#include <tools/urlobj.hxx> +#include <bf_sfx2/docfile.hxx> +#include <unotools/configitem.hxx> +#include <vcl/outdev.hxx> + +#include <fmtanchr.hxx> + +#include <horiornt.hxx> +#include <errhdl.hxx> + +#include <doc.hxx> +#include <pam.hxx> +#include <section.hxx> +#include <cntfrm.hxx> +#include <docsh.hxx> +#include <ndole.hxx> +#include <sw3io.hxx> +#include "bf_so3/staticbaseurl.hxx" +namespace binfilter { + +using namespace ::utl; +using namespace ::rtl; +using namespace ::com::sun::star::uno; + + +class SwOLELRUCache : private SvPtrarr, private ::utl::ConfigItem +{ + sal_uInt16 nLRU_InitSize; + sal_Bool bInUnload; + ::com::sun::star::uno::Sequence< ::rtl::OUString > GetPropertyNames(); + +public: + SwOLELRUCache(); + + void Load(); + + SvPtrarr::Count; + + virtual void Commit(); + virtual void Notify( const ::com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames ); + + void Insert( SwOLEObj& rObj ); + void Remove( SwOLEObj& rObj ); + + void RemovePtr( SwOLEObj* pObj ) + { + USHORT nPos = SvPtrarr::GetPos( pObj ); + if( USHRT_MAX != nPos ) + SvPtrarr::Remove( nPos ); + } +}; + +void SwOLELRUCache::Commit() {} +void SwOLELRUCache::Notify( const ::com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames ) {} + +SwOLELRUCache* SwOLEObj::pOLELRU_Cache = 0; + +// -------------------- +// SwOLENode +// -------------------- + +/*N*/ SwOLENode::SwOLENode( const SwNodeIndex &rWhere, +/*N*/ SvInPlaceObject *pObj, +/*N*/ SwGrfFmtColl *pGrfColl, +/*N*/ SwAttrSet* pAutoAttr ) : +/*N*/ SwNoTxtNode( rWhere, ND_OLENODE, pGrfColl, pAutoAttr ), +/*N*/ aOLEObj( pObj ), +/*N*/ bOLESizeInvalid( FALSE ) +/*N*/ { +/*N*/ aOLEObj.SetNode( this ); +/*N*/ } + +/*N*/ SwOLENode::SwOLENode( const SwNodeIndex &rWhere, +/*N*/ const String &rString, +/*N*/ SwGrfFmtColl *pGrfColl, +/*N*/ SwAttrSet* pAutoAttr ) : +/*N*/ SwNoTxtNode( rWhere, ND_OLENODE, pGrfColl, pAutoAttr ), +/*N*/ aOLEObj( rString ), +/*N*/ bOLESizeInvalid( FALSE ) +/*N*/ { +/*N*/ aOLEObj.SetNode( this ); +/*N*/ } + +/*N*/ SwCntntNode *SwOLENode::SplitNode( const SwPosition & ) +/*N*/ { +/*N*/ // OLE-Objecte vervielfaeltigen ?? +/*N*/ ASSERT( FALSE, "OleNode: can't split." ); +/*N*/ return this; +/*N*/ } + +// Laden eines in den Undo-Bereich verschobenen OLE-Objekts + + +// Sichern eines in den Undo-Bereich zu verschiebenden OLE-Objekts + + + +/*N*/ SwOLENode * SwNodes::MakeOLENode( const SwNodeIndex & rWhere, +/*N*/ SvInPlaceObject *pObj, +/*N*/ SwGrfFmtColl* pGrfColl, +/*N*/ SwAttrSet* pAutoAttr ) +/*N*/ { +/*N*/ ASSERT( pGrfColl,"SwNodes::MakeOLENode: Formatpointer ist 0." ); +/*N*/ +/*N*/ SwOLENode *pNode = +/*N*/ new SwOLENode( rWhere, pObj, pGrfColl, pAutoAttr ); +/*N*/ +/*N*/ #if 0 +/*N*/ JP 02.10.97 - OLE Objecte stehen immer alleine im Rahmen, also hat es +/*N*/ keinen Sinn, nach einem vorherigen/nachfolgenden +/*N*/ ContentNode zu suchen! +/*N*/ +/*N*/ SwCntntNode *pCntntNd; +/*N*/ SwIndex aIdx( rWhere, -1 ); +/*N*/ if ( (pCntntNd=(*this)[ rWhere ]->GetCntntNode()) != 0 ) +/*N*/ pCntntNd->MakeFrms( rWhere, aIdx ); +/*N*/ else +/*N*/ { +/*N*/ aIdx--; +/*N*/ if ( (pCntntNd=(*this)[aIdx]->GetCntntNode()) != 0 ) +/*N*/ { +/*N*/ SwIndex aTmp( aIdx ); +/*N*/ aIdx++; +/*N*/ pCntntNd->MakeFrms( aTmp, aIdx ); +/*N*/ } +/*N*/ } +/*N*/ #endif +/*N*/ return pNode; +/*N*/ } + + +/*N*/ SwOLENode * SwNodes::MakeOLENode( const SwNodeIndex & rWhere, +/*N*/ String &rName, +/*N*/ SwGrfFmtColl* pGrfColl, +/*N*/ SwAttrSet* pAutoAttr ) +/*N*/ { +/*N*/ ASSERT( pGrfColl,"SwNodes::MakeOLENode: Formatpointer ist 0." ); +/*N*/ +/*N*/ SwOLENode *pNode = +/*N*/ new SwOLENode( rWhere, rName, pGrfColl, pAutoAttr ); +/*N*/ +/*N*/ #if 0 +/*N*/ JP 02.10.97 - OLE Objecte stehen immer alleine im Rahmen, also hat es +/*N*/ keinen Sinn, nach einem vorherigen/nachfolgenden +/*N*/ ContentNode zu suchen! +/*N*/ SwCntntNode *pCntntNd; +/*N*/ SwIndex aIdx( rWhere, -1 ); +/*N*/ if ( (pCntntNd=(*this)[ rWhere ]->GetCntntNode()) != 0 ) +/*N*/ pCntntNd->MakeFrms( rWhere, aIdx ); +/*N*/ else +/*N*/ { +/*N*/ aIdx--; +/*N*/ if ( (pCntntNd=(*this)[aIdx]->GetCntntNode()) != 0 ) +/*N*/ { +/*N*/ SwIndex aTmp( aIdx ); +/*N*/ aIdx++; +/*N*/ pCntntNd->MakeFrms( aTmp, aIdx ); +/*N*/ } +/*N*/ } +/*N*/ #endif +/*N*/ return pNode; +/*N*/ } + + +/*N*/ Size SwOLENode::GetTwipSize() const +/*N*/ { +/*N*/ SvInPlaceObjectRef xRef( ((SwOLENode*)this)->aOLEObj.GetOleRef() ); +/*N*/ Size aSz( xRef->GetVisArea().GetSize() ); +/*N*/ const MapMode aDest( MAP_TWIP ); +/*N*/ const MapMode aSrc ( xRef->GetMapUnit() ); +/*N*/ return OutputDevice::LogicToLogic( aSz, aSrc, aDest ); +/*N*/ } + + +/*N*/ SwCntntNode* SwOLENode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const +/*N*/ { +/*N*/ // Falls bereits eine SvPersist-Instanz existiert, nehmen wir diese +/*N*/ SvPersist* p = pDoc->GetPersist(); +/*N*/ if( !p ) +/*N*/ { +/*?*/ ASSERT( pDoc->GetRefForDocShell(), +/*?*/ "wo ist die Ref-Klasse fuer die DocShell?") +/*?*/ p = new SwDocShell( pDoc, SFX_CREATE_MODE_INTERNAL ); +/*?*/ *pDoc->GetRefForDocShell() = p; +/*?*/ p->DoInitNew( NULL ); +/*N*/ } +/*N*/ +/*N*/ // Wir hauen das Ding auf SvPersist-Ebene rein +/*N*/ String aNewName( Sw3Io::UniqueName( p->GetStorage(), "Obj" ) ); +/*N*/ SvPersist* pSrc = GetDoc()->GetPersist(); +/*N*/ +/*N*/ p->CopyObject( aOLEObj.aName, aNewName, pSrc ); +/*N*/ SwOLENode* pOLENd = pDoc->GetNodes().MakeOLENode( rIdx, aNewName, +/*N*/ (SwGrfFmtColl*)pDoc->GetDfltGrfFmtColl(), +/*N*/ (SwAttrSet*)GetpSwAttrSet() ); +/*N*/ +/*N*/ pOLENd->SetChartTblName( GetChartTblName() ); +/*N*/ pOLENd->SetAlternateText( GetAlternateText() ); +/*N*/ pOLENd->SetContour( HasContour(), HasAutomaticContour() ); +/*N*/ +/*N*/ pOLENd->SetOLESizeInvalid( TRUE ); +/*N*/ pDoc->SetOLEPrtNotifyPending(); +/*N*/ +/*N*/ return pOLENd; +/*N*/ } + + +/*N*/ BOOL SwOLENode::IsInGlobalDocSection() const +/*N*/ { +/*N*/ // suche den "Body Anchor" +/*N*/ ULONG nEndExtraIdx = GetNodes().GetEndOfExtras().GetIndex(); +/*N*/ const SwNode* pAnchorNd = this; +/*N*/ do { +/*N*/ SwFrmFmt* pFlyFmt = pAnchorNd->GetFlyFmt(); +/*N*/ if( !pFlyFmt ) +/*N*/ return FALSE; +/*N*/ +/*N*/ const SwFmtAnchor& rAnchor = pFlyFmt->GetAnchor(); +/*N*/ if( !rAnchor.GetCntntAnchor() ) +/*N*/ return FALSE; +/*N*/ +/*N*/ pAnchorNd = &rAnchor.GetCntntAnchor()->nNode.GetNode(); +/*N*/ } while( pAnchorNd->GetIndex() < nEndExtraIdx ); +/*N*/ +/*N*/ const SwSectionNode* pSectNd = pAnchorNd->FindSectionNode(); +/*N*/ if( !pSectNd ) +/*N*/ return FALSE; +/*N*/ +/*N*/ while( pSectNd ) +/*N*/ { +/*N*/ pAnchorNd = pSectNd; +/*N*/ pSectNd = pAnchorNd->FindStartNode()->FindSectionNode(); +/*N*/ } +/*N*/ +/*N*/ // in pAnchorNd steht der zuletzt gefundene Section Node. Der muss +/*N*/ // jetzt die Bedingung fuers GlobalDoc erfuellen. +/*N*/ pSectNd = (SwSectionNode*)pAnchorNd; +/*N*/ return FILE_LINK_SECTION == pSectNd->GetSection().GetType() && +/*N*/ pSectNd->GetIndex() > nEndExtraIdx; +/*N*/ } + + +/*N*/ BOOL SwOLENode::IsOLEObjectDeleted() const +/*N*/ { +/*N*/ BOOL bRet = FALSE; +/*N*/ if( aOLEObj.pOLERef && aOLEObj.pOLERef->Is() ) +/*N*/ { +/*N*/ SvPersist* p = GetDoc()->GetPersist(); +/*N*/ if( p ) // muss da sein +/*N*/ { +/*N*/ SvInfoObjectRef aRef( p->Find( aOLEObj.aName ) ); +/*N*/ if( aRef.Is() ) +/*N*/ bRet = aRef->IsDeleted(); +/*N*/ } +/*N*/ } +/*N*/ return bRet; +/*N*/ } + + +/*N*/ SwOLEObj::SwOLEObj( SvInPlaceObject *pObj ) : +/*N*/ pOLERef( new SvInPlaceObjectRef( pObj ) ), +/*N*/ pOLENd( 0 ) +/*N*/ { +/*N*/ } + + +/*N*/ SwOLEObj::SwOLEObj( const String &rString ) : +/*N*/ pOLERef( 0 ), +/*N*/ pOLENd( 0 ), +/*N*/ aName( rString ) +/*N*/ { +/*N*/ } + + +/*N*/ SwOLEObj::~SwOLEObj() +/*N*/ { +/*N*/ if( pOLERef && pOLERef->Is() ) +/*N*/ //#41499# Kein DoClose(). Beim Beenden ruft der Sfx ein DoClose auf +/*N*/ //die offenen Objekte. Dadurch wird ggf. eine temp. OLE-Grafik wieder +/*N*/ //in eine Grafik gewandelt. Der OLE-Node wird zerstoert. Das DoClose +/*N*/ //wueder in das leere laufen, weil das Objekt bereits im DoClose steht. +/*N*/ //Durch das remove unten waere das DoClose aber nicht vollstaendig. +/*N*/ (*pOLERef)->GetProtocol().Reset(); +/*N*/ delete pOLERef; +/*N*/ // Object aus dem Storage removen!! +/*N*/ if( pOLENd && !pOLENd->GetDoc()->IsInDtor() ) //NIcht notwendig im DTor (MM) +/*N*/ { +/*N*/ SvPersist* p = pOLENd->GetDoc()->GetPersist(); +/*N*/ if( p ) // muss er existieren ? +/*N*/ p->Remove( aName ); +/*N*/ } +/*N*/ +/*N*/ if( pOLELRU_Cache ) +/*N*/ { +/*N*/ pOLELRU_Cache->RemovePtr( this ); +/*N*/ if( !pOLELRU_Cache->Count() ) +/*N*/ // der letzte macht die Tuer zu +/*N*/ delete pOLELRU_Cache, pOLELRU_Cache = 0; +/*N*/ } +/*N*/ } + + +/*N*/ void SwOLEObj::SetNode( SwOLENode* pNode ) +/*N*/ { +/*N*/ pOLENd = pNode; +/*N*/ if ( pOLERef && !aName.Len() ) +/*N*/ { +/*N*/ SwDoc* pDoc = pNode->GetDoc(); +/*N*/ +/*N*/ // Falls bereits eine SvPersist-Instanz existiert, nehmen wir diese +/*N*/ SvPersist* p = pDoc->GetPersist(); +/*N*/ if( !p ) +/*N*/ { +/*?*/ ASSERT( !this, "warum wird hier eine DocShell angelegt?" ); +/*?*/ p = new SwDocShell( pDoc, SFX_CREATE_MODE_INTERNAL ); +/*?*/ p->DoInitNew( NULL ); +/*N*/ } +/*N*/ // Wir hauen das Ding auf SvPersist-Ebene rein +/*N*/ aName = Sw3Io::UniqueName( p->GetStorage(), "Obj" ); +/*N*/ SvInfoObjectRef refObj = new SvEmbeddedInfoObject( *pOLERef, aName ); +/*N*/ +/*N*/ ULONG nLstLen = p->GetObjectList() ? p->GetObjectList()->Count() : 0; +/*N*/ if ( !p->Move( refObj, aName ) ) // Eigentuemer Uebergang! +/*?*/ refObj.Clear(); +/*N*/ else if( nLstLen == p->GetObjectList()->Count() ) +/*N*/ { +/*N*/ // Task 91051: Info-Object not insertet, so it exist another +/*N*/ // InfoObject to the same Object and the Objects +/*N*/ // is stored in the persist. This InfoObject we must +/*N*/ // found. +/*?*/ p->Insert( refObj ); +/*N*/ } +/*N*/ ASSERT( refObj.Is(), "InsertObject failed" ); +/*N*/ } +/*N*/ } + +/*N*/ BOOL SwOLEObj::IsOleRef() const +/*N*/ { +/*N*/ return pOLERef && pOLERef->Is(); +/*N*/ } + +/*N*/ SvInPlaceObjectRef SwOLEObj::GetOleRef() +/*N*/ { +/*N*/ if( !pOLERef || !pOLERef->Is() ) +/*N*/ { +/*N*/ SvPersist* p = pOLENd->GetDoc()->GetPersist(); +/*N*/ ASSERT( p, "kein SvPersist vorhanden" ); +/*N*/ +/*N*/ // MIB 18.5.97: DIe Base-URL wird jetzt gesetzt, damit Plugins +/*N*/ // nach dem Laden und vor dem Aktivieren des Frames korrekt +/*N*/ // geladen werden koennen +/*N*/ String sBaseURL( ::binfilter::StaticBaseUrl::GetBaseURL() ); +/*N*/ const SwDocShell *pDocSh = pOLENd->GetDoc()->GetDocShell(); +/*N*/ const SfxMedium *pMedium; +/*N*/ if( pDocSh && 0 != (pMedium = pDocSh->GetMedium()) && +/*N*/ pMedium->GetName() != sBaseURL ) +/*N*/ ::binfilter::StaticBaseUrl::SetBaseURL( pMedium->GetName() ); +/*N*/ +/*N*/ SvPersistRef xObj = p->GetObject( aName ); +/*N*/ ASSERT( !pOLERef || !pOLERef->Is(), +/*N*/ "rekursiver Aufruf von GetOleRef() ist nicht erlaubt" ) +/*N*/ +/*N*/ ::binfilter::StaticBaseUrl::SetBaseURL( sBaseURL ); +/*N*/ +/*N*/ if ( !xObj.Is() ) +/*N*/ { +/*?*/ //Das Teil konnte nicht geladen werden (wahrsch. Kaputt). +/*?*/ Rectangle aArea; +/*?*/ SwFrm *pFrm = pOLENd->GetFrm(); +/*?*/ if ( pFrm ) +/*?*/ { +/*?*/ Size aSz( pFrm->Frm().SSize() ); +/*?*/ const MapMode aSrc ( MAP_TWIP ); +/*?*/ const MapMode aDest( MAP_100TH_MM ); +/*?*/ aSz = OutputDevice::LogicToLogic( aSz, aSrc, aDest ); +/*?*/ aArea.SetSize( aSz ); +/*?*/ } +/*?*/ else +/*?*/ aArea.SetSize( Size( 5000, 5000 ) ); +/*?*/ xObj = new SvDeathObject( aArea ); +/*N*/ } +/*N*/ +/*N*/ if( pOLERef ) +/*?*/ *pOLERef = &xObj; +/*N*/ else +/*N*/ pOLERef = new SvInPlaceObjectRef( xObj ); +/*N*/ } +/*N*/ +/*N*/ if( !pOLELRU_Cache ) +/*N*/ pOLELRU_Cache = new SwOLELRUCache; +/*N*/ +/*N*/ pOLELRU_Cache->Insert( *this ); +/*N*/ +/*N*/ return *pOLERef; +/*N*/ } + + +/*N*/ BOOL SwOLEObj::RemovedFromLRU() +/*N*/ { +/*N*/ BOOL bRet = TRUE; +/*N*/ return bRet; +/*N*/ } + +/*N*/ SwOLELRUCache::SwOLELRUCache() +/*N*/ : SvPtrarr( 64, 16 ), +/*N*/ ::utl::ConfigItem( OUString::createFromAscii( "Office.Common/Cache" )), +/*N*/ bInUnload( sal_False ), +/*N*/ nLRU_InitSize( 20 ) +/*N*/ { +/*N*/ EnableNotification( GetPropertyNames() ); +/*N*/ Load(); +/*N*/ } + +/*N*/ ::com::sun::star::uno::Sequence< ::rtl::OUString > SwOLELRUCache::GetPropertyNames() +/*N*/ { +/*N*/ Sequence< OUString > aNames( 1 ); +/*N*/ OUString* pNames = aNames.getArray(); +/*N*/ pNames[0] = OUString::createFromAscii( "Writer/OLE_Objects" ); +/*N*/ return aNames; +/*N*/ } + + + +/*N*/ void SwOLELRUCache::Load() +/*N*/ { +/*N*/ Sequence< OUString > aNames( GetPropertyNames() ); +/*N*/ Sequence< Any > aValues = GetProperties( aNames ); +/*N*/ const Any* pValues = aValues.getConstArray(); +/*N*/ DBG_ASSERT( aValues.getLength() == aNames.getLength(), "GetProperties failed" ); +/*N*/ if( aValues.getLength() == aNames.getLength() && +/*N*/ pValues->hasValue() ) +/*N*/ { +/*N*/ sal_Int32 nVal; +/*N*/ *pValues >>= nVal; +/*N*/ if( 20 > nVal ) +/*N*/ nVal = 20; +/*N*/ +/*N*/ if( !bInUnload ) +/*N*/ { +/*N*/ USHORT nPos = SvPtrarr::Count(); +/*N*/ if( nVal < nLRU_InitSize && nPos > nVal ) +/*N*/ { +/*N*/ // remove the last entries +/*N*/ while( nPos > nVal ) +/*N*/ { +/*?*/ SwOLEObj* pObj = (SwOLEObj*) SvPtrarr::GetObject( --nPos ); +/*?*/ if( pObj->RemovedFromLRU() ) +/*?*/ SvPtrarr::Remove( nPos ); +/*?*/ } +/*N*/ } +/*N*/ } +/*N*/ nLRU_InitSize = (USHORT)nVal; +/*N*/ } +/*N*/ } + +/*N*/ void SwOLELRUCache::Insert( SwOLEObj& rObj ) +/*N*/ { +/*N*/ if( !bInUnload ) +/*N*/ { +/*N*/ SwOLEObj* pObj = &rObj; +/*N*/ USHORT nPos = SvPtrarr::GetPos( pObj ); +/*N*/ if( nPos ) // der auf der 0. Pos muss nicht verschoben werden! +/*N*/ { +/*N*/ if( USHRT_MAX != nPos ) +/*?*/ SvPtrarr::Remove( nPos ); +/*N*/ +/*N*/ SvPtrarr::Insert( pObj, 0 ); +/*N*/ +/*N*/ nPos = SvPtrarr::Count(); +/*N*/ while( nPos > nLRU_InitSize ) +/*N*/ { +/*?*/ pObj = (SwOLEObj*) SvPtrarr::GetObject( --nPos ); +/*?*/ if( pObj->RemovedFromLRU() ) +/*?*/ SvPtrarr::Remove( nPos ); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ #ifdef DBG_UTIL +/*N*/ else +/*N*/ { +/*?*/ SwOLEObj* pObj = &rObj; +/*?*/ USHORT nPos = SvPtrarr::GetPos( pObj ); +/*?*/ ASSERT( USHRT_MAX != nPos, "Insert a new OLE object into a looked cache" ); +/*?*/ } +/*N*/ #endif +/*N*/ } + +/*N*/ void SwOLELRUCache::Remove( SwOLEObj& rObj ) +/*N*/ { +/*N*/ if( !bInUnload ) +/*N*/ { +/*N*/ USHORT nPos = SvPtrarr::GetPos( &rObj ); +/*N*/ if( USHRT_MAX != nPos && rObj.RemovedFromLRU() ) +/*N*/ SvPtrarr::Remove( nPos ); +/*N*/ } +/*N*/ } + + + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |