xref: /AOO41X/main/sw/source/core/graphic/ndgrf.cxx (revision e1390266ac3390ed01f5e7bc5d6890c477f08573)
1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5efeef26fSAndrew Rist  * distributed with this work for additional information
6efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17efeef26fSAndrew Rist  * specific language governing permissions and limitations
18efeef26fSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20efeef26fSAndrew Rist  *************************************************************/
21efeef26fSAndrew Rist 
22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
23cdf0e10cSrcweir #include "precompiled_sw.hxx"
24cdf0e10cSrcweir #include <hintids.hxx>
25cdf0e10cSrcweir #include <vcl/salbtype.hxx>             // FRound
26cdf0e10cSrcweir #include <tools/urlobj.hxx>
27cdf0e10cSrcweir #include <svl/undo.hxx>
28cdf0e10cSrcweir #ifndef SVTOOLS_FSTATHELPER_HXX
29cdf0e10cSrcweir #include <svl/fstathelper.hxx>
30cdf0e10cSrcweir #endif
31cdf0e10cSrcweir #include <svtools/imap.hxx>
32cdf0e10cSrcweir #include <svtools/filter.hxx>
33cdf0e10cSrcweir #include <sot/storage.hxx>
34cdf0e10cSrcweir #include <sfx2/linkmgr.hxx>
35cdf0e10cSrcweir #include <editeng/boxitem.hxx>
36cdf0e10cSrcweir #include <sot/formats.hxx>
37cdf0e10cSrcweir #include <fmtfsize.hxx>
38cdf0e10cSrcweir #include <fmturl.hxx>
39cdf0e10cSrcweir #include <frmfmt.hxx>
40cdf0e10cSrcweir #include <doc.hxx>
41cdf0e10cSrcweir #include <frmatr.hxx>
42cdf0e10cSrcweir #include <grfatr.hxx>
43cdf0e10cSrcweir #include <swtypes.hxx>
44cdf0e10cSrcweir #include <ndgrf.hxx>
45cdf0e10cSrcweir #include <fmtcol.hxx>
46cdf0e10cSrcweir #include <hints.hxx>
47cdf0e10cSrcweir #include <swbaslnk.hxx>
48cdf0e10cSrcweir #include <pagefrm.hxx>
49cdf0e10cSrcweir #include <editsh.hxx>
50cdf0e10cSrcweir #include <pam.hxx>
51cdf0e10cSrcweir 
52cdf0e10cSrcweir #include <unotools/ucbstreamhelper.hxx>
53cdf0e10cSrcweir #include <com/sun/star/embed/ElementModes.hpp>
54cdf0e10cSrcweir #include <com/sun/star/embed/XTransactedObject.hpp>
55cdf0e10cSrcweir #include <tools/link.hxx>
56cdf0e10cSrcweir #include <vcl/svapp.hxx>
57cdf0e10cSrcweir #include <com/sun/star/io/XSeekable.hpp>
58cdf0e10cSrcweir #include <retrieveinputstreamconsumer.hxx>
59172c67b2SArmin Le Grand #include <drawinglayer/processor2d/objectinfoextractor2d.hxx>
60172c67b2SArmin Le Grand #include <drawinglayer/primitive2d/objectinfoprimitive2d.hxx>
61d327e58aSArmin Le Grand #include <unotools/cacheoptions.hxx>
62172c67b2SArmin Le Grand 
63cdf0e10cSrcweir using namespace com::sun::star;
64cdf0e10cSrcweir 
65d327e58aSArmin Le Grand #define SWAPGRAPHIC_TIMEOUT     5000
668a2cae91SOliver-Rainer Wittmann 
67d327e58aSArmin Le Grand // For comments see same method used in svx
getCacheTimeInMs()68d327e58aSArmin Le Grand sal_uInt32 getCacheTimeInMs()
69d327e58aSArmin Le Grand {
70d327e58aSArmin Le Grand     static bool bSetAtAll(true);
71d327e58aSArmin Le Grand 
72d327e58aSArmin Le Grand     if(bSetAtAll)
73d327e58aSArmin Le Grand     {
74d327e58aSArmin Le Grand         static bool bSetToPreferenceTime(true);
75d327e58aSArmin Le Grand 
76d327e58aSArmin Le Grand         if(bSetToPreferenceTime)
77d327e58aSArmin Le Grand         {
78d327e58aSArmin Le Grand             const SvtCacheOptions aCacheOptions;
79d327e58aSArmin Le Grand             const sal_Int32 nSeconds(aCacheOptions.GetGraphicManagerObjectReleaseTime());
80d327e58aSArmin Le Grand 
81d327e58aSArmin Le Grand             return nSeconds * 1000 / 12;
82d327e58aSArmin Le Grand         }
83d327e58aSArmin Le Grand         else
84d327e58aSArmin Le Grand         {
85d327e58aSArmin Le Grand             return SWAPGRAPHIC_TIMEOUT;
86d327e58aSArmin Le Grand         }
87d327e58aSArmin Le Grand     }
88d327e58aSArmin Le Grand 
89d327e58aSArmin Le Grand     return 0;
90d327e58aSArmin Le Grand }
913b5ba58cSOliver-Rainer Wittmann 
92cdf0e10cSrcweir // --------------------
93cdf0e10cSrcweir // SwGrfNode
94cdf0e10cSrcweir // --------------------
SwGrfNode(const SwNodeIndex & rWhere,const String & rGrfName,const String & rFltName,const Graphic * pGraphic,SwGrfFmtColl * pGrfColl,SwAttrSet * pAutoAttr)95cdf0e10cSrcweir SwGrfNode::SwGrfNode(
96cdf0e10cSrcweir     const SwNodeIndex & rWhere,
9757326f99SOliver-Rainer Wittmann     const String& rGrfName,
9857326f99SOliver-Rainer Wittmann     const String& rFltName,
99cdf0e10cSrcweir     const Graphic* pGraphic,
100cdf0e10cSrcweir     SwGrfFmtColl *pGrfColl,
10157326f99SOliver-Rainer Wittmann     SwAttrSet* pAutoAttr )
10257326f99SOliver-Rainer Wittmann         : SwNoTxtNode( rWhere, ND_GRFNODE, pGrfColl, pAutoAttr ),
103172c67b2SArmin Le Grand           maGrfObj(),
104ddde725dSArmin Le Grand           mpReplacementGraphic( 0 ),
105cdf0e10cSrcweir           mbLinkedInputStreamReady( false ),
106cdf0e10cSrcweir           mbIsStreamReadOnly( sal_False )
107cdf0e10cSrcweir {
108d327e58aSArmin Le Grand     maGrfObj.SetSwapStreamHdl( LINK( this, SwGrfNode, SwapGraphic ), getCacheTimeInMs() );
10957326f99SOliver-Rainer Wittmann     bInSwapIn = bChgTwipSize = bChgTwipSizeFromPixel = bLoadLowResGrf = bFrameInPaint = bScaleImageMap = sal_False;
110cdf0e10cSrcweir 
111cdf0e10cSrcweir     bGrafikArrived = sal_True;
112cdf0e10cSrcweir     ReRead( rGrfName, rFltName, pGraphic, 0, sal_False );
113cdf0e10cSrcweir }
114cdf0e10cSrcweir 
SwGrfNode(const SwNodeIndex & rWhere,const GraphicObject & rGrfObj,SwGrfFmtColl * pGrfColl,SwAttrSet * pAutoAttr)11557326f99SOliver-Rainer Wittmann SwGrfNode::SwGrfNode(
11657326f99SOliver-Rainer Wittmann     const SwNodeIndex & rWhere,
117cdf0e10cSrcweir     const GraphicObject& rGrfObj,
11857326f99SOliver-Rainer Wittmann     SwGrfFmtColl *pGrfColl,
11957326f99SOliver-Rainer Wittmann     SwAttrSet* pAutoAttr )
12057326f99SOliver-Rainer Wittmann         : SwNoTxtNode( rWhere, ND_GRFNODE, pGrfColl, pAutoAttr ),
121172c67b2SArmin Le Grand           maGrfObj( rGrfObj ),
122ddde725dSArmin Le Grand           mpReplacementGraphic( 0 ),
123cdf0e10cSrcweir           mbLinkedInputStreamReady( false ),
124cdf0e10cSrcweir           mbIsStreamReadOnly( sal_False )
125cdf0e10cSrcweir {
126172c67b2SArmin Le Grand     maGrfObj = rGrfObj;
127d327e58aSArmin Le Grand     maGrfObj.SetSwapStreamHdl( LINK( this, SwGrfNode, SwapGraphic ), getCacheTimeInMs() );
128cdf0e10cSrcweir     if ( rGrfObj.HasUserData() && rGrfObj.IsSwappedOut() )
129172c67b2SArmin Le Grand         maGrfObj.SetSwapState();
13057326f99SOliver-Rainer Wittmann     bInSwapIn = bChgTwipSize = bChgTwipSizeFromPixel = bLoadLowResGrf = bFrameInPaint = bScaleImageMap = sal_False;
131cdf0e10cSrcweir     bGrafikArrived = sal_True;
132cdf0e10cSrcweir }
133cdf0e10cSrcweir 
134cdf0e10cSrcweir // Konstruktor fuer den SW/G-Reader. Dieser ctor wird verwendet,
135cdf0e10cSrcweir // wenn eine gelinkte Grafik gelesen wird. Sie liest diese NICHT ein.
136cdf0e10cSrcweir 
SwGrfNode(const SwNodeIndex & rWhere,const String & rGrfName,const String & rFltName,SwGrfFmtColl * pGrfColl,SwAttrSet * pAutoAttr)1378a2cae91SOliver-Rainer Wittmann SwGrfNode::SwGrfNode(
1388a2cae91SOliver-Rainer Wittmann     const SwNodeIndex & rWhere,
1398a2cae91SOliver-Rainer Wittmann     const String& rGrfName,
1408a2cae91SOliver-Rainer Wittmann     const String& rFltName,
141cdf0e10cSrcweir     SwGrfFmtColl *pGrfColl,
1428a2cae91SOliver-Rainer Wittmann     SwAttrSet* pAutoAttr )
1438a2cae91SOliver-Rainer Wittmann         :
144cdf0e10cSrcweir           SwNoTxtNode( rWhere, ND_GRFNODE, pGrfColl, pAutoAttr ),
145172c67b2SArmin Le Grand           maGrfObj(),
146ddde725dSArmin Le Grand           mpReplacementGraphic( 0 ),
147cdf0e10cSrcweir           mbLinkedInputStreamReady( false ),
148cdf0e10cSrcweir           mbIsStreamReadOnly( sal_False )
149cdf0e10cSrcweir {
150d327e58aSArmin Le Grand     maGrfObj.SetSwapStreamHdl( LINK( this, SwGrfNode, SwapGraphic ), getCacheTimeInMs() );
151cdf0e10cSrcweir 
1528a2cae91SOliver-Rainer Wittmann     Graphic aGrf;
1538a2cae91SOliver-Rainer Wittmann     aGrf.SetDefaultType();
154172c67b2SArmin Le Grand     maGrfObj.SetGraphic( aGrf, rGrfName );
155cdf0e10cSrcweir 
156cdf0e10cSrcweir     bInSwapIn = bChgTwipSize = bChgTwipSizeFromPixel = bLoadLowResGrf =
157cdf0e10cSrcweir             bFrameInPaint = bScaleImageMap = sal_False;
158cdf0e10cSrcweir     bGrafikArrived = sal_True;
159cdf0e10cSrcweir 
160cdf0e10cSrcweir     InsertLink( rGrfName, rFltName );
161cdf0e10cSrcweir     if ( IsLinkedFile() )
162cdf0e10cSrcweir     {
163cdf0e10cSrcweir         INetURLObject aUrl( rGrfName );
164cdf0e10cSrcweir         if ( INET_PROT_FILE == aUrl.GetProtocol() &&
165cdf0e10cSrcweir              FStatHelper::IsDocument( aUrl.GetMainURL( INetURLObject::NO_DECODE ) ) )
166cdf0e10cSrcweir         {
167cdf0e10cSrcweir             // File vorhanden, Verbindung herstellen ohne ein Update
168cdf0e10cSrcweir             ( (SwBaseLink*) &refLink )->Connect();
169cdf0e10cSrcweir         }
170cdf0e10cSrcweir     }
171cdf0e10cSrcweir }
172cdf0e10cSrcweir 
ReRead(const String & rGrfName,const String & rFltName,const Graphic * pGraphic,const GraphicObject * pGrfObj,sal_Bool bNewGrf)173cdf0e10cSrcweir sal_Bool SwGrfNode::ReRead(
1748a2cae91SOliver-Rainer Wittmann     const String& rGrfName,
1758a2cae91SOliver-Rainer Wittmann     const String& rFltName,
1768a2cae91SOliver-Rainer Wittmann     const Graphic* pGraphic,
1778a2cae91SOliver-Rainer Wittmann     const GraphicObject* pGrfObj,
178cdf0e10cSrcweir     sal_Bool bNewGrf )
179cdf0e10cSrcweir {
180cdf0e10cSrcweir     sal_Bool bReadGrf = sal_False, bSetTwipSize = sal_True;
181ddde725dSArmin Le Grand     delete mpReplacementGraphic;
182ddde725dSArmin Le Grand     mpReplacementGraphic = 0;
183cdf0e10cSrcweir 
184cdf0e10cSrcweir     ASSERT( pGraphic || pGrfObj || rGrfName.Len(),
185cdf0e10cSrcweir         "GraphicNode without a name, Graphic or GraphicObject" );
186cdf0e10cSrcweir 
187*e1390266SArrigo Marchiori     if ( GetDoc()->GetLinkManager().urlIsVendor( rGrfName ) )
188*e1390266SArrigo Marchiori         return sal_False;
189*e1390266SArrigo Marchiori 
190cdf0e10cSrcweir     // ReadRead mit Namen
191cdf0e10cSrcweir     if ( refLink.Is() )
192cdf0e10cSrcweir     {
193cdf0e10cSrcweir         ASSERT( !bInSwapIn, "ReRead: stehe noch im SwapIn" );
194cdf0e10cSrcweir 
195cdf0e10cSrcweir         if ( rGrfName.Len() )
196cdf0e10cSrcweir         {
197cdf0e10cSrcweir             // Besonderheit: steht im FltNamen DDE, handelt es sich um eine
198cdf0e10cSrcweir             //					DDE-gelinkte Grafik
199cdf0e10cSrcweir             String sCmd( rGrfName );
200cdf0e10cSrcweir             if ( rFltName.Len() )
201cdf0e10cSrcweir             {
202cdf0e10cSrcweir                 sal_uInt16 nNewType;
203cdf0e10cSrcweir                 if ( rFltName.EqualsAscii( "DDE" ) )
204cdf0e10cSrcweir                     nNewType = OBJECT_CLIENT_DDE;
205cdf0e10cSrcweir                 else
206cdf0e10cSrcweir                 {
207cdf0e10cSrcweir                     sfx2::MakeLnkName( sCmd, 0, rGrfName, aEmptyStr, &rFltName );
208cdf0e10cSrcweir                     nNewType = OBJECT_CLIENT_GRF;
209cdf0e10cSrcweir                 }
210cdf0e10cSrcweir 
211cdf0e10cSrcweir                 if ( nNewType != refLink->GetObjType() )
212cdf0e10cSrcweir                 {
213cdf0e10cSrcweir                     refLink->Disconnect();
214cdf0e10cSrcweir                     ( (SwBaseLink*) &refLink )->SetObjType( nNewType );
215cdf0e10cSrcweir                 }
216cdf0e10cSrcweir             }
217cdf0e10cSrcweir 
218cdf0e10cSrcweir             refLink->SetLinkSourceName( sCmd );
219cdf0e10cSrcweir         }
220cdf0e10cSrcweir         else		// kein Name mehr, Link aufheben
221cdf0e10cSrcweir         {
222cdf0e10cSrcweir             GetDoc()->GetLinkManager().Remove( refLink );
223cdf0e10cSrcweir             refLink.Clear();
224cdf0e10cSrcweir         }
225cdf0e10cSrcweir 
226cdf0e10cSrcweir         if ( pGraphic )
227cdf0e10cSrcweir         {
228172c67b2SArmin Le Grand             maGrfObj.SetGraphic( *pGraphic, rGrfName );
229172c67b2SArmin Le Grand             onGraphicChanged();
230cdf0e10cSrcweir             bReadGrf = sal_True;
231cdf0e10cSrcweir         }
232cdf0e10cSrcweir         else if ( pGrfObj )
233cdf0e10cSrcweir         {
234172c67b2SArmin Le Grand             maGrfObj = *pGrfObj;
235cdf0e10cSrcweir             if ( pGrfObj->HasUserData() && pGrfObj->IsSwappedOut() )
236172c67b2SArmin Le Grand                 maGrfObj.SetSwapState();
237172c67b2SArmin Le Grand             maGrfObj.SetLink( rGrfName );
238172c67b2SArmin Le Grand             onGraphicChanged();
239cdf0e10cSrcweir             bReadGrf = sal_True;
240cdf0e10cSrcweir         }
241cdf0e10cSrcweir         else
242cdf0e10cSrcweir         {
243cdf0e10cSrcweir             // MIB 25.02.97: Daten der alten Grafik zuruecksetzen, damit
244cdf0e10cSrcweir             // die korrekte Ersatz-Darstellung erscheint, wenn die
245cdf0e10cSrcweir             // der neue Link nicht geladen werden konnte.
2468a2cae91SOliver-Rainer Wittmann             Graphic aGrf;
2478a2cae91SOliver-Rainer Wittmann             aGrf.SetDefaultType();
248172c67b2SArmin Le Grand             maGrfObj.SetGraphic( aGrf, rGrfName );
249cdf0e10cSrcweir 
250cdf0e10cSrcweir             if ( refLink.Is() )
251cdf0e10cSrcweir             {
252cdf0e10cSrcweir                 if ( getLayoutFrm( GetDoc()->GetCurrentLayout() ) )
253cdf0e10cSrcweir                 {
254cdf0e10cSrcweir                     SwMsgPoolItem aMsgHint( RES_GRF_REREAD_AND_INCACHE );
255cdf0e10cSrcweir                     ModifyNotification( &aMsgHint, &aMsgHint );
256cdf0e10cSrcweir                 }
257cdf0e10cSrcweir                 else if ( bNewGrf )
258cdf0e10cSrcweir                 {
259cdf0e10cSrcweir                     //TODO refLink->setInputStream(getInputStream());
260cdf0e10cSrcweir                     ( (SwBaseLink*) &refLink )->SwapIn();
261cdf0e10cSrcweir                 }
262cdf0e10cSrcweir             }
263172c67b2SArmin Le Grand             onGraphicChanged();
264cdf0e10cSrcweir             bSetTwipSize = sal_False;
265cdf0e10cSrcweir         }
266cdf0e10cSrcweir     }
267cdf0e10cSrcweir     else if ( pGraphic && !rGrfName.Len() )
268cdf0e10cSrcweir     {
269cdf0e10cSrcweir         // MIB 27.02.2001: Old stream must be deleted before the new one is set.
2700b19465bSOliver-Rainer Wittmann         if ( HasEmbeddedStreamName() )
271cdf0e10cSrcweir             DelStreamName();
272cdf0e10cSrcweir 
273172c67b2SArmin Le Grand         maGrfObj.SetGraphic( *pGraphic );
274172c67b2SArmin Le Grand         onGraphicChanged();
275cdf0e10cSrcweir         bReadGrf = sal_True;
276cdf0e10cSrcweir     }
277cdf0e10cSrcweir     else if ( pGrfObj && !rGrfName.Len() )
278cdf0e10cSrcweir     {
279cdf0e10cSrcweir         // MIB 27.02.2001: Old stream must be deleted before the new one is set.
2800b19465bSOliver-Rainer Wittmann         if ( HasEmbeddedStreamName() )
281cdf0e10cSrcweir             DelStreamName();
282cdf0e10cSrcweir 
283172c67b2SArmin Le Grand         maGrfObj = *pGrfObj;
284172c67b2SArmin Le Grand         onGraphicChanged();
285cdf0e10cSrcweir         if ( pGrfObj->HasUserData() && pGrfObj->IsSwappedOut() )
286172c67b2SArmin Le Grand             maGrfObj.SetSwapState();
287cdf0e10cSrcweir         bReadGrf = sal_True;
288cdf0e10cSrcweir     }
289172c67b2SArmin Le Grand     else if ( !bNewGrf && GRAPHIC_NONE != maGrfObj.GetType() )
290cdf0e10cSrcweir         return sal_True;
291cdf0e10cSrcweir 
292cdf0e10cSrcweir     else
293cdf0e10cSrcweir     {
2940b19465bSOliver-Rainer Wittmann         if ( HasEmbeddedStreamName() )
295cdf0e10cSrcweir             DelStreamName();
296cdf0e10cSrcweir 
297cdf0e10cSrcweir         // einen neuen Grafik-Link anlegen
298cdf0e10cSrcweir         InsertLink( rGrfName, rFltName );
299cdf0e10cSrcweir 
300cdf0e10cSrcweir         if ( GetNodes().IsDocNodes() )
301cdf0e10cSrcweir         {
302cdf0e10cSrcweir             if ( pGraphic )
303cdf0e10cSrcweir             {
304172c67b2SArmin Le Grand                 maGrfObj.SetGraphic( *pGraphic, rGrfName );
305172c67b2SArmin Le Grand                 onGraphicChanged();
306cdf0e10cSrcweir                 bReadGrf = sal_True;
307cdf0e10cSrcweir                 // Verbindung herstellen ohne ein Update; Grafik haben wir!
308cdf0e10cSrcweir                 ( (SwBaseLink*) &refLink )->Connect();
309cdf0e10cSrcweir             }
310cdf0e10cSrcweir             else if ( pGrfObj )
311cdf0e10cSrcweir             {
312172c67b2SArmin Le Grand                 maGrfObj = *pGrfObj;
313172c67b2SArmin Le Grand                 maGrfObj.SetLink( rGrfName );
314172c67b2SArmin Le Grand                 onGraphicChanged();
315cdf0e10cSrcweir                 bReadGrf = sal_True;
316cdf0e10cSrcweir                 // Verbindung herstellen ohne ein Update; Grafik haben wir!
317cdf0e10cSrcweir                 ( (SwBaseLink*) &refLink )->Connect();
318cdf0e10cSrcweir             }
319cdf0e10cSrcweir             else
320cdf0e10cSrcweir             {
3218a2cae91SOliver-Rainer Wittmann                 Graphic aGrf;
3228a2cae91SOliver-Rainer Wittmann                 aGrf.SetDefaultType();
323172c67b2SArmin Le Grand                 maGrfObj.SetGraphic( aGrf, rGrfName );
324172c67b2SArmin Le Grand                 onGraphicChanged();
325cdf0e10cSrcweir                 if ( bNewGrf )
326cdf0e10cSrcweir                 {
327cdf0e10cSrcweir                     ( (SwBaseLink*) &refLink )->SwapIn();
328cdf0e10cSrcweir                 }
329cdf0e10cSrcweir             }
330cdf0e10cSrcweir         }
331cdf0e10cSrcweir     }
332cdf0e10cSrcweir 
333cdf0e10cSrcweir     // Bug 39281: Size nicht sofort loeschen - Events auf ImageMaps
334cdf0e10cSrcweir     //			  sollten nicht beim Austauschen nicht ins "leere greifen"
335cdf0e10cSrcweir     if ( bSetTwipSize )
336172c67b2SArmin Le Grand         SetTwipSize( ::GetGraphicSizeTwip( maGrfObj.GetGraphic(), 0 ) );
337cdf0e10cSrcweir 
338cdf0e10cSrcweir     // erzeuge noch einen Update auf die Frames
339cdf0e10cSrcweir     if ( bReadGrf && bNewGrf )
340cdf0e10cSrcweir     {
341cdf0e10cSrcweir         SwMsgPoolItem aMsgHint( RES_UPDATE_ATTR );
342cdf0e10cSrcweir         ModifyNotification( &aMsgHint, &aMsgHint );
343cdf0e10cSrcweir     }
344cdf0e10cSrcweir 
345cdf0e10cSrcweir     return bReadGrf;
346cdf0e10cSrcweir }
347cdf0e10cSrcweir 
~SwGrfNode()348cdf0e10cSrcweir SwGrfNode::~SwGrfNode()
349cdf0e10cSrcweir {
350ddde725dSArmin Le Grand     delete mpReplacementGraphic;
351ddde725dSArmin Le Grand     mpReplacementGraphic = 0;
352ddde725dSArmin Le Grand 
353cdf0e10cSrcweir     mpThreadConsumer.reset();
354cdf0e10cSrcweir 
355cdf0e10cSrcweir     SwDoc* pDoc = GetDoc();
356cdf0e10cSrcweir     if ( refLink.Is() )
357cdf0e10cSrcweir     {
358cdf0e10cSrcweir         ASSERT( !bInSwapIn, "DTOR: stehe noch im SwapIn" );
359cdf0e10cSrcweir         pDoc->GetLinkManager().Remove( refLink );
360cdf0e10cSrcweir         refLink->Disconnect();
361cdf0e10cSrcweir     }
362cdf0e10cSrcweir     else
363cdf0e10cSrcweir     {
3648a2cae91SOliver-Rainer Wittmann         // #i40014# - A graphic node, which are in linked
365cdf0e10cSrcweir         // section, whose link is another section is the document, doesn't
366cdf0e10cSrcweir         // have to remove the stream from the storage.
367cdf0e10cSrcweir         // Because it's hard to detect this case here and it would only fix
368cdf0e10cSrcweir         // one problem with shared graphic files - there are also problems,
369cdf0e10cSrcweir         // a certain graphic file is referenced by two independent graphic nodes,
370cdf0e10cSrcweir         // brush item or drawing objects, the stream isn't no longer removed here.
371cdf0e10cSrcweir         // To do this stuff correct, a reference counting on shared streams
372cdf0e10cSrcweir         // inside one document have to be implemented.
373cdf0e10cSrcweir //        if( !pDoc->IsInDtor() && HasStreamName() )
374cdf0e10cSrcweir //          DelStreamName();
375cdf0e10cSrcweir     }
376cdf0e10cSrcweir     //#39289# Die Frames muessen hier bereits geloescht weil der DTor der
377cdf0e10cSrcweir     //Frms die Grafik noch fuer StopAnimation braucht.
378cdf0e10cSrcweir     if ( GetDepends() )
379cdf0e10cSrcweir         DelFrms();
380cdf0e10cSrcweir }
381cdf0e10cSrcweir 
382172c67b2SArmin Le Grand /// allow reaction on change of content of GraphicObject
onGraphicChanged()383172c67b2SArmin Le Grand void SwGrfNode::onGraphicChanged()
384172c67b2SArmin Le Grand {
385172c67b2SArmin Le Grand     // try to access SwFlyFrmFmt; since title/desc/name are set there, there is no
386172c67b2SArmin Le Grand     // use to continue if it is not yet set. If not yet set, call onGraphicChanged()
387172c67b2SArmin Le Grand     // when it is set.
388172c67b2SArmin Le Grand     SwFlyFrmFmt* pFlyFmt = dynamic_cast< SwFlyFrmFmt* >( GetFlyFmt() );
389172c67b2SArmin Le Grand 
3908a2cae91SOliver-Rainer Wittmann     if ( pFlyFmt != NULL )
391172c67b2SArmin Le Grand     {
3928a2cae91SOliver-Rainer Wittmann         const bool bWasSwappedOut = ( GetGrfObj().IsSwappedOut() == sal_True );
3938a2cae91SOliver-Rainer Wittmann 
394172c67b2SArmin Le Grand         String aName;
395172c67b2SArmin Le Grand         String aTitle;
396172c67b2SArmin Le Grand         String aDesc;
397172c67b2SArmin Le Grand         const SvgDataPtr& rSvgDataPtr = GetGrf().getSvgData();
398172c67b2SArmin Le Grand 
399172c67b2SArmin Le Grand         if ( rSvgDataPtr.get() )
400172c67b2SArmin Le Grand         {
401172c67b2SArmin Le Grand             const drawinglayer::primitive2d::Primitive2DSequence aSequence( rSvgDataPtr->getPrimitive2DSequence() );
402172c67b2SArmin Le Grand 
403172c67b2SArmin Le Grand             if ( aSequence.hasElements() )
404172c67b2SArmin Le Grand             {
405172c67b2SArmin Le Grand                 drawinglayer::geometry::ViewInformation2D aViewInformation2D;
406172c67b2SArmin Le Grand                 drawinglayer::processor2d::ObjectInfoPrimitiveExtractor2D aProcessor( aViewInformation2D );
407172c67b2SArmin Le Grand 
408172c67b2SArmin Le Grand                 aProcessor.process( aSequence );
409172c67b2SArmin Le Grand 
410172c67b2SArmin Le Grand                 const drawinglayer::primitive2d::ObjectInfoPrimitive2D* pResult = aProcessor.getResult();
411172c67b2SArmin Le Grand 
412172c67b2SArmin Le Grand                 if ( pResult )
413172c67b2SArmin Le Grand                 {
414172c67b2SArmin Le Grand                     aName = pResult->getName();
415172c67b2SArmin Le Grand                     aTitle = pResult->getTitle();
416172c67b2SArmin Le Grand                     aDesc = pResult->getDesc();
417172c67b2SArmin Le Grand                 }
418172c67b2SArmin Le Grand             }
419172c67b2SArmin Le Grand         }
420172c67b2SArmin Le Grand 
4218a2cae91SOliver-Rainer Wittmann         if ( aTitle.Len() > 0 )
422172c67b2SArmin Le Grand         {
423172c67b2SArmin Le Grand             SetTitle( aTitle );
424172c67b2SArmin Le Grand         }
4258a2cae91SOliver-Rainer Wittmann         else if ( aName.Len() > 0 )
4268a2cae91SOliver-Rainer Wittmann         {
4278a2cae91SOliver-Rainer Wittmann             SetTitle( aName );
4288a2cae91SOliver-Rainer Wittmann         }
429172c67b2SArmin Le Grand 
4308a2cae91SOliver-Rainer Wittmann         if ( aDesc.Len() > 0 )
431172c67b2SArmin Le Grand         {
432172c67b2SArmin Le Grand             SetDescription( aDesc );
433172c67b2SArmin Le Grand         }
4348a2cae91SOliver-Rainer Wittmann 
4358a2cae91SOliver-Rainer Wittmann         if ( bWasSwappedOut )
4368a2cae91SOliver-Rainer Wittmann         {
4378a2cae91SOliver-Rainer Wittmann             SwapOut();
4388a2cae91SOliver-Rainer Wittmann         }
439172c67b2SArmin Le Grand     }
440172c67b2SArmin Le Grand }
441172c67b2SArmin Le Grand 
SetGraphic(const Graphic & rGraphic,const String & rLink)4428a2cae91SOliver-Rainer Wittmann void SwGrfNode::SetGraphic(
4438a2cae91SOliver-Rainer Wittmann     const Graphic& rGraphic,
4448a2cae91SOliver-Rainer Wittmann     const String& rLink )
445172c67b2SArmin Le Grand {
446172c67b2SArmin Le Grand     maGrfObj.SetGraphic( rGraphic, rLink );
447172c67b2SArmin Le Grand     onGraphicChanged();
448172c67b2SArmin Le Grand }
449cdf0e10cSrcweir 
GetReplacementGrfObj() const450ddde725dSArmin Le Grand const GraphicObject* SwGrfNode::GetReplacementGrfObj() const
451ddde725dSArmin Le Grand {
452ddde725dSArmin Le Grand     if ( !mpReplacementGraphic )
453ddde725dSArmin Le Grand     {
454ddde725dSArmin Le Grand         const SvgDataPtr& rSvgDataPtr = GetGrfObj().GetGraphic().getSvgData();
455ddde725dSArmin Le Grand 
456ddde725dSArmin Le Grand         if ( rSvgDataPtr.get() )
457ddde725dSArmin Le Grand         {
458ddde725dSArmin Le Grand             const_cast< SwGrfNode* >( this )->mpReplacementGraphic = new GraphicObject( rSvgDataPtr->getReplacement() );
459ddde725dSArmin Le Grand         }
460ddde725dSArmin Le Grand     }
461ddde725dSArmin Le Grand 
462ddde725dSArmin Le Grand     return mpReplacementGraphic;
463ddde725dSArmin Le Grand }
464ddde725dSArmin Le Grand 
SplitCntntNode(const SwPosition &)4658a2cae91SOliver-Rainer Wittmann SwCntntNode *SwGrfNode::SplitCntntNode(
4668a2cae91SOliver-Rainer Wittmann     const SwPosition & )
467cdf0e10cSrcweir {
468cdf0e10cSrcweir     return this;
469cdf0e10cSrcweir }
470cdf0e10cSrcweir 
MakeGrfNode(const SwNodeIndex & rWhere,const String & rGrfName,const String & rFltName,const Graphic * pGraphic,SwGrfFmtColl * pGrfColl,SwAttrSet * pAutoAttr,sal_Bool bDelayed)4718a2cae91SOliver-Rainer Wittmann SwGrfNode * SwNodes::MakeGrfNode(
4728a2cae91SOliver-Rainer Wittmann     const SwNodeIndex & rWhere,
473cdf0e10cSrcweir     const String& rGrfName,
474cdf0e10cSrcweir     const String& rFltName,
475cdf0e10cSrcweir     const Graphic* pGraphic,
476cdf0e10cSrcweir     SwGrfFmtColl* pGrfColl,
477cdf0e10cSrcweir     SwAttrSet* pAutoAttr,
478cdf0e10cSrcweir     sal_Bool bDelayed )
479cdf0e10cSrcweir {
480cdf0e10cSrcweir     ASSERT( pGrfColl, "MakeGrfNode: Formatpointer ist 0." );
481cdf0e10cSrcweir     SwGrfNode *pNode;
482cdf0e10cSrcweir     // Delayed erzeugen nur aus dem SW/G-Reader
483cdf0e10cSrcweir     if ( bDelayed )
484cdf0e10cSrcweir         pNode = new SwGrfNode( rWhere, rGrfName,
485cdf0e10cSrcweir             rFltName, pGrfColl, pAutoAttr );
486cdf0e10cSrcweir     else
487cdf0e10cSrcweir         pNode = new SwGrfNode( rWhere, rGrfName,
488cdf0e10cSrcweir             rFltName, pGraphic, pGrfColl, pAutoAttr );
489cdf0e10cSrcweir     return pNode;
490cdf0e10cSrcweir }
491cdf0e10cSrcweir 
MakeGrfNode(const SwNodeIndex & rWhere,const GraphicObject & rGrfObj,SwGrfFmtColl * pGrfColl,SwAttrSet * pAutoAttr)4928a2cae91SOliver-Rainer Wittmann SwGrfNode * SwNodes::MakeGrfNode(
4938a2cae91SOliver-Rainer Wittmann     const SwNodeIndex & rWhere,
494cdf0e10cSrcweir     const GraphicObject& rGrfObj,
495cdf0e10cSrcweir     SwGrfFmtColl* pGrfColl,
496cdf0e10cSrcweir     SwAttrSet* pAutoAttr )
497cdf0e10cSrcweir {
498cdf0e10cSrcweir     ASSERT( pGrfColl, "MakeGrfNode: Formatpointer ist 0." );
499cdf0e10cSrcweir     return new SwGrfNode( rWhere, rGrfObj, pGrfColl, pAutoAttr );
500cdf0e10cSrcweir }
501cdf0e10cSrcweir 
GetTwipSize() const502cdf0e10cSrcweir Size SwGrfNode::GetTwipSize() const
503cdf0e10cSrcweir {
504cdf0e10cSrcweir     return nGrfSize;
505cdf0e10cSrcweir }
506cdf0e10cSrcweir 
ImportGraphic(SvStream & rStrm)5078a2cae91SOliver-Rainer Wittmann sal_Bool SwGrfNode::ImportGraphic(
5088a2cae91SOliver-Rainer Wittmann     SvStream& rStrm )
509cdf0e10cSrcweir {
510cdf0e10cSrcweir     Graphic aGraphic;
511172c67b2SArmin Le Grand     const String aURL( maGrfObj.GetUserData() );
512ddde725dSArmin Le Grand 
513ddde725dSArmin Le Grand     if ( !GraphicFilter::GetGraphicFilter()->ImportGraphic( aGraphic, aURL, rStrm ) )
514cdf0e10cSrcweir     {
515ddde725dSArmin Le Grand         delete mpReplacementGraphic;
516ddde725dSArmin Le Grand         mpReplacementGraphic = 0;
517cdf0e10cSrcweir 
518172c67b2SArmin Le Grand         maGrfObj.SetGraphic( aGraphic );
519172c67b2SArmin Le Grand         maGrfObj.SetUserData( aURL );
520172c67b2SArmin Le Grand         onGraphicChanged();
521cdf0e10cSrcweir         return sal_True;
522cdf0e10cSrcweir     }
523cdf0e10cSrcweir 
524cdf0e10cSrcweir     return sal_False;
525cdf0e10cSrcweir }
526cdf0e10cSrcweir 
527cdf0e10cSrcweir // Returnwert:
528cdf0e10cSrcweir // -1 : ReRead erfolgreich
529cdf0e10cSrcweir //  0 : nicht geladen
530cdf0e10cSrcweir //  1 : Einlesen erfolgreich
531cdf0e10cSrcweir 
SwapIn(sal_Bool bWaitForData)5328a2cae91SOliver-Rainer Wittmann short SwGrfNode::SwapIn(
5338a2cae91SOliver-Rainer Wittmann     sal_Bool bWaitForData )
534cdf0e10cSrcweir {
535cdf0e10cSrcweir     if ( bInSwapIn )					// nicht rekuriv!!
536172c67b2SArmin Le Grand         return !maGrfObj.IsSwappedOut();
537cdf0e10cSrcweir 
538cdf0e10cSrcweir     short nRet = 0;
539cdf0e10cSrcweir     bInSwapIn = sal_True;
540cdf0e10cSrcweir     SwBaseLink* pLink = (SwBaseLink*) (::sfx2::SvBaseLink*) refLink;
541cdf0e10cSrcweir 
542cdf0e10cSrcweir     if ( pLink )
543cdf0e10cSrcweir     {
544172c67b2SArmin Le Grand         if ( GRAPHIC_NONE == maGrfObj.GetType() ||
545172c67b2SArmin Le Grand              GRAPHIC_DEFAULT == maGrfObj.GetType() )
546cdf0e10cSrcweir         {
547cdf0e10cSrcweir             // noch nicht geladener Link
548cdf0e10cSrcweir             //TODO pLink->setInputStream(getInputStream());
549cdf0e10cSrcweir             if ( pLink->SwapIn( bWaitForData ) )
550cdf0e10cSrcweir                 nRet = -1;
551172c67b2SArmin Le Grand             else if ( GRAPHIC_DEFAULT == maGrfObj.GetType() )
552cdf0e10cSrcweir             {
553cdf0e10cSrcweir                 // keine default Bitmap mehr, also neu Painten!
554ddde725dSArmin Le Grand                 delete mpReplacementGraphic;
555ddde725dSArmin Le Grand                 mpReplacementGraphic = 0;
556ddde725dSArmin Le Grand 
557172c67b2SArmin Le Grand                 maGrfObj.SetGraphic( Graphic() );
558172c67b2SArmin Le Grand                 onGraphicChanged();
559cdf0e10cSrcweir                 SwMsgPoolItem aMsgHint( RES_GRAPHIC_PIECE_ARRIVED );
560cdf0e10cSrcweir                 ModifyNotification( &aMsgHint, &aMsgHint );
561cdf0e10cSrcweir             }
562cdf0e10cSrcweir         }
5638a2cae91SOliver-Rainer Wittmann         else if ( maGrfObj.IsSwappedOut() )
5648a2cae91SOliver-Rainer Wittmann         {
565cdf0e10cSrcweir             // nachzuladender Link
566cdf0e10cSrcweir             //TODO pLink->setInputStream(getInputStream());
567cdf0e10cSrcweir             nRet = pLink->SwapIn( bWaitForData ) ? 1 : 0;
568cdf0e10cSrcweir         }
569cdf0e10cSrcweir         else
570cdf0e10cSrcweir             nRet = 1;
571cdf0e10cSrcweir     }
572172c67b2SArmin Le Grand     else if ( maGrfObj.IsSwappedOut() )
573cdf0e10cSrcweir     {
574cdf0e10cSrcweir         // Die Grafik ist im Storage oder im TempFile drin
5750b19465bSOliver-Rainer Wittmann         if ( !HasEmbeddedStreamName() )
576172c67b2SArmin Le Grand             nRet = (short) maGrfObj.SwapIn();
577cdf0e10cSrcweir         else
578cdf0e10cSrcweir         {
579cdf0e10cSrcweir 
580cdf0e10cSrcweir             try
581cdf0e10cSrcweir             {
582cdf0e10cSrcweir                 String aStrmName, aPicStgName;
583cdf0e10cSrcweir                 _GetStreamStorageNames( aStrmName, aPicStgName );
584cdf0e10cSrcweir                 uno::Reference< embed::XStorage > refPics = _GetDocSubstorageOrRoot( aPicStgName );
585cdf0e10cSrcweir                 SvStream* pStrm = _GetStreamForEmbedGrf( refPics, aStrmName );
586cdf0e10cSrcweir                 if ( pStrm )
587cdf0e10cSrcweir                 {
588cdf0e10cSrcweir                     if ( ImportGraphic( *pStrm ) )
589cdf0e10cSrcweir                         nRet = 1;
590cdf0e10cSrcweir                     delete pStrm;
591cdf0e10cSrcweir                 }
592cdf0e10cSrcweir             }
593cdf0e10cSrcweir             catch ( uno::Exception& )
594cdf0e10cSrcweir             {
595cdf0e10cSrcweir                 ASSERT( false, "<SwGrfNode::SwapIn(..)> - unhandled exception!" );
596cdf0e10cSrcweir             }
597cdf0e10cSrcweir         }
598cdf0e10cSrcweir 
599cdf0e10cSrcweir         if ( 1 == nRet )
600cdf0e10cSrcweir         {
601cdf0e10cSrcweir             SwMsgPoolItem aMsg( RES_GRAPHIC_SWAPIN );
602cdf0e10cSrcweir             ModifyNotification( &aMsg, &aMsg );
603cdf0e10cSrcweir         }
604cdf0e10cSrcweir     }
605cdf0e10cSrcweir     else
606cdf0e10cSrcweir         nRet = 1;
607cdf0e10cSrcweir     DBG_ASSERTWARNING( nRet, "Grafik kann nicht eingeswapt werden" );
608cdf0e10cSrcweir 
609cdf0e10cSrcweir     if ( nRet )
610cdf0e10cSrcweir     {
611cdf0e10cSrcweir         if ( !nGrfSize.Width() && !nGrfSize.Height() )
612172c67b2SArmin Le Grand             SetTwipSize( ::GetGraphicSizeTwip( maGrfObj.GetGraphic(), 0 ) );
613cdf0e10cSrcweir     }
614cdf0e10cSrcweir     bInSwapIn = sal_False;
615cdf0e10cSrcweir     return nRet;
616cdf0e10cSrcweir }
617cdf0e10cSrcweir 
SwapOut()618cdf0e10cSrcweir short SwGrfNode::SwapOut()
619cdf0e10cSrcweir {
6208a2cae91SOliver-Rainer Wittmann     if ( maGrfObj.GetType() != GRAPHIC_DEFAULT
6218a2cae91SOliver-Rainer Wittmann          && maGrfObj.GetType() != GRAPHIC_NONE
6228a2cae91SOliver-Rainer Wittmann          && !maGrfObj.IsSwappedOut()
6238a2cae91SOliver-Rainer Wittmann          && !bInSwapIn )
624cdf0e10cSrcweir     {
625cdf0e10cSrcweir         if ( !refLink.Is() )
626cdf0e10cSrcweir         {
627cdf0e10cSrcweir             // Das Swapping brauchen wir nur fuer Embedded Pictures
628cdf0e10cSrcweir             // Die Grafik wird in eine TempFile geschrieben, wenn
629cdf0e10cSrcweir             // sie frisch eingefuegt war, d.h. wenn es noch keinen
630cdf0e10cSrcweir             // Streamnamen im Storage gibt.
6310b19465bSOliver-Rainer Wittmann             if ( !HasEmbeddedStreamName() )
632172c67b2SArmin Le Grand                 if ( !maGrfObj.SwapOut() )
633cdf0e10cSrcweir                     return 0;
634cdf0e10cSrcweir         }
635cdf0e10cSrcweir         // Geschriebene Grafiken oder Links werden jetzt weggeschmissen
636172c67b2SArmin Le Grand         return (short) maGrfObj.SwapOut( NULL );
637cdf0e10cSrcweir     }
638cdf0e10cSrcweir     return 1;
639cdf0e10cSrcweir }
640cdf0e10cSrcweir 
GetFileFilterNms(String * pFileNm,String * pFilterNm) const6418a2cae91SOliver-Rainer Wittmann sal_Bool SwGrfNode::GetFileFilterNms(
6428a2cae91SOliver-Rainer Wittmann     String* pFileNm,
6438a2cae91SOliver-Rainer Wittmann     String* pFilterNm ) const
644cdf0e10cSrcweir     {
645cdf0e10cSrcweir     sal_Bool bRet = sal_False;
646cdf0e10cSrcweir     if ( refLink.Is() && refLink->GetLinkManager() )
647cdf0e10cSrcweir     {
648cdf0e10cSrcweir         sal_uInt16 nType = refLink->GetObjType();
649cdf0e10cSrcweir         if ( OBJECT_CLIENT_GRF == nType )
650cdf0e10cSrcweir             bRet = refLink->GetLinkManager()->GetDisplayNames(
651cdf0e10cSrcweir                 refLink, 0, pFileNm, 0, pFilterNm );
652cdf0e10cSrcweir         else if ( OBJECT_CLIENT_DDE == nType && pFileNm && pFilterNm )
653cdf0e10cSrcweir         {
654cdf0e10cSrcweir             String sApp, sTopic, sItem;
655cdf0e10cSrcweir             if ( refLink->GetLinkManager()->GetDisplayNames(
656cdf0e10cSrcweir                 refLink, &sApp, &sTopic, &sItem ) )
657cdf0e10cSrcweir             {
658cdf0e10cSrcweir                 ( *pFileNm = sApp ) += sfx2::cTokenSeperator;
659cdf0e10cSrcweir                 ( *pFileNm += sTopic ) += sfx2::cTokenSeperator;
660cdf0e10cSrcweir                 *pFileNm += sItem;
661cdf0e10cSrcweir                 pFilterNm->AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDE" ) );
662cdf0e10cSrcweir                 bRet = sal_True;
663cdf0e10cSrcweir             }
664cdf0e10cSrcweir         }
665cdf0e10cSrcweir     }
666cdf0e10cSrcweir     return bRet;
667cdf0e10cSrcweir }
668cdf0e10cSrcweir 
669cdf0e10cSrcweir // Eine Grafik Undo-faehig machen. Falls sie sich bereits in
670cdf0e10cSrcweir // einem Storage befindet, muss sie geladen werden.
671cdf0e10cSrcweir 
SavePersistentData()672cdf0e10cSrcweir sal_Bool SwGrfNode::SavePersistentData()
673cdf0e10cSrcweir {
674cdf0e10cSrcweir     if ( refLink.Is() )
675cdf0e10cSrcweir     {
676cdf0e10cSrcweir         ASSERT( !bInSwapIn, "SavePersistentData: stehe noch im SwapIn" );
677cdf0e10cSrcweir         GetDoc()->GetLinkManager().Remove( refLink );
678cdf0e10cSrcweir         return sal_True;
679cdf0e10cSrcweir     }
680cdf0e10cSrcweir 
681cdf0e10cSrcweir     // Erst mal reinswappen, falls sie im Storage ist
6820b19465bSOliver-Rainer Wittmann     if ( HasEmbeddedStreamName() && !SwapIn() )
683cdf0e10cSrcweir         return sal_False;
684cdf0e10cSrcweir 
6858a2cae91SOliver-Rainer Wittmann     // #i44367#
686cdf0e10cSrcweir     // Do not delete graphic file in storage, because the graphic file could
687cdf0e10cSrcweir     // be referenced by other graphic nodes.
688cdf0e10cSrcweir     // Because it's hard to detect this case here and it would only fix
689cdf0e10cSrcweir     // one problem with shared graphic files - there are also problems,
690cdf0e10cSrcweir     // a certain graphic file is referenced by two independent graphic nodes,
691cdf0e10cSrcweir     // brush item or drawing objects, the stream isn't no longer removed here.
692cdf0e10cSrcweir     // To do this stuff correct, a reference counting on shared streams
693cdf0e10cSrcweir     // inside one document have to be implemented.
694cdf0e10cSrcweir     // Important note: see also fix for #i40014#
695cdf0e10cSrcweir //    if( HasStreamName() )
696cdf0e10cSrcweir //        DelStreamName();
697cdf0e10cSrcweir 
698cdf0e10cSrcweir     // Und in TempFile rausswappen
699cdf0e10cSrcweir     return (sal_Bool) SwapOut();
700cdf0e10cSrcweir }
701cdf0e10cSrcweir 
RestorePersistentData()702cdf0e10cSrcweir sal_Bool SwGrfNode::RestorePersistentData()
703cdf0e10cSrcweir {
704cdf0e10cSrcweir     if ( refLink.Is() )
705cdf0e10cSrcweir     {
706cdf0e10cSrcweir         IDocumentLinksAdministration* pIDLA = getIDocumentLinksAdministration();
707cdf0e10cSrcweir         refLink->SetVisible( pIDLA->IsVisibleLinks() );
708cdf0e10cSrcweir         pIDLA->GetLinkManager().InsertDDELink( refLink );
7098a2cae91SOliver-Rainer Wittmann         if ( getIDocumentLayoutAccess()->GetCurrentLayout() )
710cdf0e10cSrcweir             refLink->Update();
711cdf0e10cSrcweir     }
712cdf0e10cSrcweir     return sal_True;
713cdf0e10cSrcweir }
714cdf0e10cSrcweir 
InsertLink(const String & rGrfName,const String & rFltName)7158a2cae91SOliver-Rainer Wittmann void SwGrfNode::InsertLink(
7168a2cae91SOliver-Rainer Wittmann     const String& rGrfName,
7178a2cae91SOliver-Rainer Wittmann     const String& rFltName )
718cdf0e10cSrcweir {
719cdf0e10cSrcweir     refLink = new SwBaseLink( sfx2::LINKUPDATE_ONCALL, FORMAT_GDIMETAFILE, this );
720cdf0e10cSrcweir 
721cdf0e10cSrcweir     IDocumentLinksAdministration* pIDLA = getIDocumentLinksAdministration();
722cdf0e10cSrcweir     if ( GetNodes().IsDocNodes() )
723cdf0e10cSrcweir     {
724cdf0e10cSrcweir         refLink->SetVisible( pIDLA->IsVisibleLinks() );
725cdf0e10cSrcweir         if ( rFltName.EqualsAscii( "DDE" ) )
726cdf0e10cSrcweir         {
727cdf0e10cSrcweir             sal_uInt16 nTmp = 0;
728cdf0e10cSrcweir             String sApp, sTopic, sItem;
729cdf0e10cSrcweir             sApp = rGrfName.GetToken( 0, sfx2::cTokenSeperator, nTmp );
730cdf0e10cSrcweir             sTopic = rGrfName.GetToken( 0, sfx2::cTokenSeperator, nTmp );
731cdf0e10cSrcweir             sItem = rGrfName.Copy( nTmp );
732cdf0e10cSrcweir             pIDLA->GetLinkManager().InsertDDELink( refLink,
733cdf0e10cSrcweir                 sApp, sTopic, sItem );
734cdf0e10cSrcweir         }
735cdf0e10cSrcweir         else
736cdf0e10cSrcweir         {
737cdf0e10cSrcweir             sal_Bool bSync = rFltName.EqualsAscii( "SYNCHRON" );
738cdf0e10cSrcweir             refLink->SetSynchron( bSync );
739cdf0e10cSrcweir             refLink->SetContentType( SOT_FORMATSTR_ID_SVXB );
740cdf0e10cSrcweir 
741cdf0e10cSrcweir             pIDLA->GetLinkManager().InsertFileLink( *refLink,
742cdf0e10cSrcweir             OBJECT_CLIENT_GRF, rGrfName,
743cdf0e10cSrcweir                 ( !bSync && rFltName.Len() ? &rFltName : 0 ) );
744cdf0e10cSrcweir         }
745cdf0e10cSrcweir     }
746172c67b2SArmin Le Grand     maGrfObj.SetLink( rGrfName );
747cdf0e10cSrcweir }
748cdf0e10cSrcweir 
ReleaseLink()749cdf0e10cSrcweir void SwGrfNode::ReleaseLink()
750cdf0e10cSrcweir {
751cdf0e10cSrcweir     if ( refLink.Is() )
752cdf0e10cSrcweir     {
753c37c1899SArmin Le Grand         const String aFileName( maGrfObj.GetLink() );
754c37c1899SArmin Le Grand         const Graphic aLocalGraphic( maGrfObj.GetGraphic() );
755c37c1899SArmin Le Grand         const bool bHasOriginalData( aLocalGraphic.IsLink() );
756c37c1899SArmin Le Grand 
757cdf0e10cSrcweir         {
758cdf0e10cSrcweir             bInSwapIn = sal_True;
759cdf0e10cSrcweir             SwBaseLink* pLink = (SwBaseLink*) (::sfx2::SvBaseLink*) refLink;
760cdf0e10cSrcweir             //TODO pLink->setInputStream(getInputStream());
761cdf0e10cSrcweir             pLink->SwapIn( sal_True, sal_True );
762cdf0e10cSrcweir             bInSwapIn = sal_False;
763cdf0e10cSrcweir         }
764c37c1899SArmin Le Grand 
765cdf0e10cSrcweir         getIDocumentLinksAdministration()->GetLinkManager().Remove( refLink );
766cdf0e10cSrcweir         refLink.Clear();
767172c67b2SArmin Le Grand         maGrfObj.SetLink();
768c37c1899SArmin Le Grand 
769c37c1899SArmin Le Grand         // #15508# added extra processing after getting rid of the link. Use whatever is
770c37c1899SArmin Le Grand         // known from the formally linked graphic to get to a state as close to a directly
771c37c1899SArmin Le Grand         // unlinked insterted graphic as possible. Goal is to have a valid GfxLink at the
772c37c1899SArmin Le Grand         // ImplGraphic (see there) that holds temporary data to the original data and type
773c37c1899SArmin Le Grand         // information about the original data. Only when this is given will
774c37c1899SArmin Le Grand         // SvXMLGraphicHelper::ImplInsertGraphicURL which is used at export use that type
775c37c1899SArmin Le Grand         // and use the original graphic at export for the ODF, without evtl. recoding
776c37c1899SArmin Le Grand         // of trhe bitmap graphic data to something without loss (e.g. PNG) but bigger
777c37c1899SArmin Le Grand         if ( bHasOriginalData )
778c37c1899SArmin Le Grand         {
779c37c1899SArmin Le Grand             // #15508# if we have the original data at the Graphic, let it survive
780c37c1899SArmin Le Grand             // by using that Graphic again, this time at a GraphicObject without link.
781c37c1899SArmin Le Grand             // This happens e.g. when inserting a linked graphic and breaking the link
782c37c1899SArmin Le Grand             maGrfObj.SetGraphic( aLocalGraphic );
783c37c1899SArmin Le Grand         }
784c37c1899SArmin Le Grand         else if ( aFileName.Len() )
785c37c1899SArmin Le Grand         {
786c37c1899SArmin Le Grand             // #15508# we have no original data, but a file name. This happens e.g.
787c37c1899SArmin Le Grand             // when inserting a linked graphic and save, reload document. Try to access
788c37c1899SArmin Le Grand             // that data from the original file; if this works, use it. Else use the
789c37c1899SArmin Le Grand             // data we have (but without knowing the original format)
790c37c1899SArmin Le Grand             int nRes = GRFILTER_OK;
791c37c1899SArmin Le Grand             GraphicFilter* pFlt = GraphicFilter::GetGraphicFilter();
792c37c1899SArmin Le Grand             Graphic aNew;
793c37c1899SArmin Le Grand             nRes = GraphicFilter::LoadGraphic( aFileName, String(), aNew, pFlt );
794c37c1899SArmin Le Grand 
795c37c1899SArmin Le Grand             if ( GRFILTER_OK == nRes )
796c37c1899SArmin Le Grand             {
797c37c1899SArmin Le Grand                 maGrfObj.SetGraphic( aNew );
798c37c1899SArmin Le Grand             }
799c37c1899SArmin Le Grand         }
800cdf0e10cSrcweir     }
801cdf0e10cSrcweir }
802cdf0e10cSrcweir 
SetTwipSize(const Size & rSz)8038a2cae91SOliver-Rainer Wittmann void SwGrfNode::SetTwipSize(
8048a2cae91SOliver-Rainer Wittmann     const Size& rSz )
805cdf0e10cSrcweir {
806cdf0e10cSrcweir     nGrfSize = rSz;
807cdf0e10cSrcweir     if ( IsScaleImageMap() && nGrfSize.Width() && nGrfSize.Height() )
808cdf0e10cSrcweir     {
809cdf0e10cSrcweir         // Image-Map an Grafik-Groesse anpassen
810cdf0e10cSrcweir         ScaleImageMap();
811cdf0e10cSrcweir 
812cdf0e10cSrcweir         // Image-Map nicht noch einmal skalieren
813cdf0e10cSrcweir         SetScaleImageMap( sal_False );
814cdf0e10cSrcweir     }
815cdf0e10cSrcweir }
816cdf0e10cSrcweir 
ScaleImageMap()817cdf0e10cSrcweir void SwGrfNode::ScaleImageMap()
818cdf0e10cSrcweir {
819cdf0e10cSrcweir     if ( !nGrfSize.Width() || !nGrfSize.Height() )
820cdf0e10cSrcweir         return;
821cdf0e10cSrcweir 
822cdf0e10cSrcweir     // dann die Image-Map skalieren
823cdf0e10cSrcweir     SwFrmFmt* pFmt = GetFlyFmt();
824cdf0e10cSrcweir 
825cdf0e10cSrcweir     if ( !pFmt )
826cdf0e10cSrcweir         return;
827cdf0e10cSrcweir 
828cdf0e10cSrcweir     SwFmtURL aURL( pFmt->GetURL() );
829cdf0e10cSrcweir     if ( !aURL.GetMap() )
830cdf0e10cSrcweir         return;
831cdf0e10cSrcweir 
832cdf0e10cSrcweir     sal_Bool bScale = sal_False;
833cdf0e10cSrcweir     Fraction aScaleX( 1, 1 );
834cdf0e10cSrcweir     Fraction aScaleY( 1, 1 );
835cdf0e10cSrcweir 
836cdf0e10cSrcweir     const SwFmtFrmSize& rFrmSize = pFmt->GetFrmSize();
837cdf0e10cSrcweir     const SvxBoxItem& rBox = pFmt->GetBox();
838cdf0e10cSrcweir 
839cdf0e10cSrcweir     if ( !rFrmSize.GetWidthPercent() )
840cdf0e10cSrcweir     {
841cdf0e10cSrcweir         SwTwips nWidth = rFrmSize.GetWidth();
842cdf0e10cSrcweir 
843cdf0e10cSrcweir         nWidth -= rBox.CalcLineSpace( BOX_LINE_LEFT ) +
844cdf0e10cSrcweir                   rBox.CalcLineSpace( BOX_LINE_RIGHT );
845cdf0e10cSrcweir 
846cdf0e10cSrcweir         ASSERT( nWidth>0, "Gibt es 0 twip breite Grafiken!?" );
847cdf0e10cSrcweir 
848cdf0e10cSrcweir         if ( nGrfSize.Width() != nWidth )
849cdf0e10cSrcweir         {
850cdf0e10cSrcweir             aScaleX = Fraction( nGrfSize.Width(), nWidth );
851cdf0e10cSrcweir             bScale = sal_True;
852cdf0e10cSrcweir         }
853cdf0e10cSrcweir     }
854cdf0e10cSrcweir     if ( !rFrmSize.GetHeightPercent() )
855cdf0e10cSrcweir     {
856cdf0e10cSrcweir         SwTwips nHeight = rFrmSize.GetHeight();
857cdf0e10cSrcweir 
858cdf0e10cSrcweir         nHeight -= rBox.CalcLineSpace( BOX_LINE_TOP ) +
859cdf0e10cSrcweir                    rBox.CalcLineSpace( BOX_LINE_BOTTOM );
860cdf0e10cSrcweir 
861cdf0e10cSrcweir         ASSERT( nHeight>0, "Gibt es 0 twip hohe Grafiken!?" );
862cdf0e10cSrcweir 
863cdf0e10cSrcweir         if ( nGrfSize.Height() != nHeight )
864cdf0e10cSrcweir         {
865cdf0e10cSrcweir             aScaleY = Fraction( nGrfSize.Height(), nHeight );
866cdf0e10cSrcweir             bScale = sal_True;
867cdf0e10cSrcweir         }
868cdf0e10cSrcweir     }
869cdf0e10cSrcweir 
870cdf0e10cSrcweir     if ( bScale )
871cdf0e10cSrcweir     {
872cdf0e10cSrcweir         aURL.GetMap()->Scale( aScaleX, aScaleY );
873cdf0e10cSrcweir         pFmt->SetFmtAttr( aURL );
874cdf0e10cSrcweir     }
875cdf0e10cSrcweir }
876cdf0e10cSrcweir 
DelStreamName()877cdf0e10cSrcweir void SwGrfNode::DelStreamName()
878cdf0e10cSrcweir {
8790b19465bSOliver-Rainer Wittmann     if ( HasEmbeddedStreamName() )
880cdf0e10cSrcweir     {
881cdf0e10cSrcweir         // Dann die Grafik im Storage loeschen
882cdf0e10cSrcweir         uno::Reference< embed::XStorage > xDocStg = GetDoc()->GetDocStorage();
883cdf0e10cSrcweir         if ( xDocStg.is() )
884cdf0e10cSrcweir         {
885cdf0e10cSrcweir             try
886cdf0e10cSrcweir             {
887cdf0e10cSrcweir                 String aPicStgName, aStrmName;
888cdf0e10cSrcweir                 _GetStreamStorageNames( aStrmName, aPicStgName );
889cdf0e10cSrcweir                 uno::Reference< embed::XStorage > refPics = xDocStg;
890cdf0e10cSrcweir                 if ( aPicStgName.Len() )
891cdf0e10cSrcweir                     refPics = xDocStg->openStorageElement( aPicStgName, embed::ElementModes::READWRITE );
892cdf0e10cSrcweir                 refPics->removeElement( aStrmName );
893cdf0e10cSrcweir                 uno::Reference< embed::XTransactedObject > xTrans( refPics, uno::UNO_QUERY );
894cdf0e10cSrcweir                 if ( xTrans.is() )
895cdf0e10cSrcweir                     xTrans->commit();
896cdf0e10cSrcweir             }
897cdf0e10cSrcweir             catch ( uno::Exception& )
898cdf0e10cSrcweir             {
899cdf0e10cSrcweir                 // --> OD 2005-04-25 #i48434#
900cdf0e10cSrcweir                 ASSERT( false, "<SwGrfNode::DelStreamName()> - unhandled exception!" );
901cdf0e10cSrcweir                 // <--
902cdf0e10cSrcweir             }
903cdf0e10cSrcweir         }
904cdf0e10cSrcweir 
905172c67b2SArmin Le Grand         maGrfObj.SetUserData();
906cdf0e10cSrcweir     }
907cdf0e10cSrcweir }
908cdf0e10cSrcweir 
909cdf0e10cSrcweir /** helper method to get a substorage of the document storage for readonly access.
910cdf0e10cSrcweir 
9118a2cae91SOliver-Rainer Wittmann  #i53025#
912cdf0e10cSrcweir  A substorage with the specified name will be opened readonly. If the provided
913cdf0e10cSrcweir  name is empty the root storage will be returned.
914cdf0e10cSrcweir  */
_GetDocSubstorageOrRoot(const String & aStgName) const9158a2cae91SOliver-Rainer Wittmann uno::Reference< embed::XStorage > SwGrfNode::_GetDocSubstorageOrRoot(
9168a2cae91SOliver-Rainer Wittmann     const String& aStgName ) const
917cdf0e10cSrcweir     {
918cdf0e10cSrcweir     uno::Reference< embed::XStorage > refStor =
919cdf0e10cSrcweir             const_cast< SwGrfNode* >( this )->GetDoc()->GetDocStorage();
920cdf0e10cSrcweir     ASSERT( refStor.is(), "Kein Storage am Doc" );
921cdf0e10cSrcweir 
922cdf0e10cSrcweir     if ( aStgName.Len() )
923cdf0e10cSrcweir     {
924cdf0e10cSrcweir         if ( refStor.is() )
925cdf0e10cSrcweir             return refStor->openStorageElement( aStgName, embed::ElementModes::READ );
926cdf0e10cSrcweir     }
927cdf0e10cSrcweir 
928cdf0e10cSrcweir     return refStor;
929cdf0e10cSrcweir }
930cdf0e10cSrcweir 
931cdf0e10cSrcweir /** helper method to determine stream for the embedded graphic.
932cdf0e10cSrcweir 
9338a2cae91SOliver-Rainer Wittmann  #i48434#
934cdf0e10cSrcweir  Important note: caller of this method has to handle the thrown exceptions
9358a2cae91SOliver-Rainer Wittmann  #i53025#
936cdf0e10cSrcweir  Storage, which should contain the stream of the embedded graphic, is
937cdf0e10cSrcweir  provided via parameter. Otherwise the returned stream will be closed
938cdf0e10cSrcweir  after the the method returns, because its parent stream is closed and deleted.
939cdf0e10cSrcweir  Proposed name of embedded graphic stream is also provided by parameter.
940cdf0e10cSrcweir 
941cdf0e10cSrcweir  @author OD
942cdf0e10cSrcweir  */
_GetStreamForEmbedGrf(const uno::Reference<embed::XStorage> & _refPics,String & _aStrmName) const943cdf0e10cSrcweir SvStream* SwGrfNode::_GetStreamForEmbedGrf(
944cdf0e10cSrcweir     const uno::Reference< embed::XStorage >& _refPics,
945cdf0e10cSrcweir     String& _aStrmName ) const
946cdf0e10cSrcweir     {
947cdf0e10cSrcweir     SvStream* pStrm( 0L );
948cdf0e10cSrcweir 
949cdf0e10cSrcweir     if ( _refPics.is() && _aStrmName.Len() )
950cdf0e10cSrcweir     {
951cdf0e10cSrcweir         // If stream doesn't exist in the storage, try access the graphic file by
952cdf0e10cSrcweir         // re-generating its name.
953cdf0e10cSrcweir         // A save action can have changed the filename of the embedded graphic,
954cdf0e10cSrcweir         // because a changed unique ID of the graphic is calculated.
9558a2cae91SOliver-Rainer Wittmann         // #b6364738#
956cdf0e10cSrcweir         // recursive calls of <GetUniqueID()> have to be avoided.
957cdf0e10cSrcweir         // Thus, use local static boolean to assure this.
958cdf0e10cSrcweir         static bool bInRegenerateStrmName( false );
959cdf0e10cSrcweir         if ( !bInRegenerateStrmName &&
960cdf0e10cSrcweir              ( !_refPics->hasByName( _aStrmName ) ||
961cdf0e10cSrcweir                !_refPics->isStreamElement( _aStrmName ) ) )
962cdf0e10cSrcweir         {
963cdf0e10cSrcweir             bInRegenerateStrmName = true;
964cdf0e10cSrcweir             xub_StrLen nExtPos = _aStrmName.Search( '.' );
965cdf0e10cSrcweir             String aExtStr = _aStrmName.Copy( nExtPos );
966cdf0e10cSrcweir             Graphic aGraphic( GetGrfObj().GetGraphic() );
967cdf0e10cSrcweir             if ( aGraphic.GetType() != GRAPHIC_NONE )
968cdf0e10cSrcweir             {
969cdf0e10cSrcweir                 _aStrmName = String( GetGrfObj().GetUniqueID(), RTL_TEXTENCODING_ASCII_US );
970cdf0e10cSrcweir                 _aStrmName += aExtStr;
971cdf0e10cSrcweir             }
972cdf0e10cSrcweir             bInRegenerateStrmName = false;
973cdf0e10cSrcweir         }
974cdf0e10cSrcweir 
975cdf0e10cSrcweir         // assure that graphic file exist in the storage.
976cdf0e10cSrcweir         if ( _refPics->hasByName( _aStrmName ) &&
977cdf0e10cSrcweir              _refPics->isStreamElement( _aStrmName ) )
978cdf0e10cSrcweir         {
979cdf0e10cSrcweir             uno::Reference< io::XStream > refStrm = _refPics->openStreamElement( _aStrmName, embed::ElementModes::READ );
980cdf0e10cSrcweir             pStrm = utl::UcbStreamHelper::CreateStream( refStrm );
981cdf0e10cSrcweir         }
982cdf0e10cSrcweir         else
983cdf0e10cSrcweir         {
984cdf0e10cSrcweir             ASSERT( false, "<SwGrfNode::_GetStreamForEmbedGrf(..)> - embedded graphic file not found!" );
985cdf0e10cSrcweir         }
986cdf0e10cSrcweir     }
987cdf0e10cSrcweir 
988cdf0e10cSrcweir     return pStrm;
989cdf0e10cSrcweir }
990cdf0e10cSrcweir 
991cdf0e10cSrcweir 
_GetStreamStorageNames(String & rStrmName,String & rStorName) const9928a2cae91SOliver-Rainer Wittmann void SwGrfNode::_GetStreamStorageNames(
9938a2cae91SOliver-Rainer Wittmann     String& rStrmName,
994cdf0e10cSrcweir     String& rStorName ) const
995cdf0e10cSrcweir     {
996cdf0e10cSrcweir     rStorName.Erase();
997cdf0e10cSrcweir     rStrmName.Erase();
998cdf0e10cSrcweir 
999172c67b2SArmin Le Grand     String aUserData( maGrfObj.GetUserData() );
1000cdf0e10cSrcweir     if ( !aUserData.Len() )
1001cdf0e10cSrcweir         return;
1002cdf0e10cSrcweir 
1003cdf0e10cSrcweir     String aProt( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.Package:" ) );
1004cdf0e10cSrcweir     if ( 0 == aUserData.CompareTo( aProt, aProt.Len() ) )
1005cdf0e10cSrcweir     {
1006cdf0e10cSrcweir         // 6.0 (XML) Package
1007cdf0e10cSrcweir         xub_StrLen nPos = aUserData.Search( '/' );
1008cdf0e10cSrcweir         if ( STRING_NOTFOUND == nPos )
1009cdf0e10cSrcweir         {
1010cdf0e10cSrcweir             rStrmName = aUserData.Copy( aProt.Len() );
1011cdf0e10cSrcweir         }
1012cdf0e10cSrcweir         else
1013cdf0e10cSrcweir         {
1014cdf0e10cSrcweir             xub_StrLen nPathStart = aProt.Len();
1015cdf0e10cSrcweir             if ( 0 == aUserData.CompareToAscii( "./", 2 ) )
1016cdf0e10cSrcweir                 nPathStart += 2;
1017cdf0e10cSrcweir             rStorName = aUserData.Copy( nPathStart, nPos - nPathStart );
1018cdf0e10cSrcweir             rStrmName = aUserData.Copy( nPos + 1 );
1019cdf0e10cSrcweir         }
1020cdf0e10cSrcweir     }
1021cdf0e10cSrcweir     else
1022cdf0e10cSrcweir     {
1023cdf0e10cSrcweir         ASSERT( false,
1024cdf0e10cSrcweir             "<SwGrfNode::_GetStreamStorageNames(..)> - unknown graphic URL type. Code for handling 3.1 - 5.2 storages has been deleted by issue i53025." );
1025cdf0e10cSrcweir     }
1026cdf0e10cSrcweir     ASSERT( STRING_NOTFOUND == rStrmName.Search( '/' ),
1027cdf0e10cSrcweir         "invalid graphic stream name" );
1028cdf0e10cSrcweir }
1029cdf0e10cSrcweir 
10308a2cae91SOliver-Rainer Wittmann 
MakeCopy(SwDoc * pDoc,const SwNodeIndex & rIdx) const10318a2cae91SOliver-Rainer Wittmann SwCntntNode* SwGrfNode::MakeCopy(
10328a2cae91SOliver-Rainer Wittmann     SwDoc* pDoc,
10338a2cae91SOliver-Rainer Wittmann     const SwNodeIndex& rIdx ) const
1034cdf0e10cSrcweir     {
1035cdf0e10cSrcweir     // kopiere die Formate in das andere Dokument:
1036cdf0e10cSrcweir     SwGrfFmtColl* pColl = pDoc->CopyGrfColl( *GetGrfColl() );
1037cdf0e10cSrcweir 
1038cdf0e10cSrcweir     Graphic aTmpGrf;
1039cdf0e10cSrcweir     SwBaseLink* pLink = (SwBaseLink*) (::sfx2::SvBaseLink*) refLink;
10400b19465bSOliver-Rainer Wittmann     if ( !pLink && HasEmbeddedStreamName() )
1041cdf0e10cSrcweir     {
1042cdf0e10cSrcweir         try
1043cdf0e10cSrcweir         {
1044cdf0e10cSrcweir             String aStrmName, aPicStgName;
1045cdf0e10cSrcweir             _GetStreamStorageNames( aStrmName, aPicStgName );
1046cdf0e10cSrcweir             uno::Reference< embed::XStorage > refPics = _GetDocSubstorageOrRoot( aPicStgName );
1047cdf0e10cSrcweir             SvStream* pStrm = _GetStreamForEmbedGrf( refPics, aStrmName );
1048cdf0e10cSrcweir             if ( pStrm )
1049cdf0e10cSrcweir             {
1050172c67b2SArmin Le Grand                 const String aURL( maGrfObj.GetUserData() );
1051ddde725dSArmin Le Grand                 GraphicFilter::GetGraphicFilter()->ImportGraphic( aTmpGrf, aURL, *pStrm );
1052cdf0e10cSrcweir                 delete pStrm;
1053cdf0e10cSrcweir             }
1054cdf0e10cSrcweir         }
1055cdf0e10cSrcweir         catch ( uno::Exception& )
1056cdf0e10cSrcweir         {
1057cdf0e10cSrcweir             ASSERT( false, "<SwGrfNode::MakeCopy(..)> - unhandled exception!" );
1058cdf0e10cSrcweir         }
1059cdf0e10cSrcweir     }
1060cdf0e10cSrcweir     else
1061cdf0e10cSrcweir     {
1062172c67b2SArmin Le Grand         if ( maGrfObj.IsSwappedOut() )
1063cdf0e10cSrcweir             const_cast< SwGrfNode* >( this )->SwapIn();
1064172c67b2SArmin Le Grand         aTmpGrf = maGrfObj.GetGraphic();
1065cdf0e10cSrcweir     }
1066cdf0e10cSrcweir 
1067cdf0e10cSrcweir     const sfx2::LinkManager& rMgr = getIDocumentLinksAdministration()->GetLinkManager();
1068cdf0e10cSrcweir     String sFile, sFilter;
1069cdf0e10cSrcweir     if ( IsLinkedFile() )
1070cdf0e10cSrcweir         rMgr.GetDisplayNames( refLink, 0, &sFile, 0, &sFilter );
1071cdf0e10cSrcweir     else if ( IsLinkedDDE() )
1072cdf0e10cSrcweir     {
1073cdf0e10cSrcweir         String sTmp1, sTmp2;
1074cdf0e10cSrcweir         rMgr.GetDisplayNames( refLink, &sTmp1, &sTmp2, &sFilter );
1075cdf0e10cSrcweir         sfx2::MakeLnkName( sFile, &sTmp1, sTmp2, sFilter );
1076cdf0e10cSrcweir         sFilter.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDE" ) );
1077cdf0e10cSrcweir     }
1078cdf0e10cSrcweir 
1079cdf0e10cSrcweir     SwGrfNode* pGrfNd = pDoc->GetNodes().MakeGrfNode( rIdx, sFile, sFilter,
1080cdf0e10cSrcweir         &aTmpGrf, pColl,
1081cdf0e10cSrcweir         (SwAttrSet*) GetpSwAttrSet() );
1082cdf0e10cSrcweir     pGrfNd->SetTitle( GetTitle() );
1083cdf0e10cSrcweir     pGrfNd->SetDescription( GetDescription() );
1084cdf0e10cSrcweir     pGrfNd->SetContour( HasContour(), HasAutomaticContour() );
1085cdf0e10cSrcweir     return pGrfNd;
1086cdf0e10cSrcweir }
1087cdf0e10cSrcweir 
IMPL_LINK(SwGrfNode,SwapGraphic,GraphicObject *,pGrfObj)1088cdf0e10cSrcweir IMPL_LINK( SwGrfNode, SwapGraphic, GraphicObject*, pGrfObj )
1089cdf0e10cSrcweir {
1090cdf0e10cSrcweir     SvStream* pRet;
1091cdf0e10cSrcweir 
1092cdf0e10cSrcweir     // #101174#: Keep graphic while in swap in. That's at least important
1093cdf0e10cSrcweir     // when breaking links, because in this situation a reschedule call and
1094cdf0e10cSrcweir     // a DataChanged call lead to a paint of the graphic.
1095cdf0e10cSrcweir     if ( pGrfObj->IsInSwapOut() && ( IsSelected() || bInSwapIn ) )
1096cdf0e10cSrcweir         pRet = GRFMGR_AUTOSWAPSTREAM_NONE;
1097cdf0e10cSrcweir     else if ( refLink.Is() )
1098cdf0e10cSrcweir     {
1099cdf0e10cSrcweir         if ( pGrfObj->IsInSwapIn() )
1100cdf0e10cSrcweir         {
1101cdf0e10cSrcweir             // then make it by your self
1102cdf0e10cSrcweir             if ( !bInSwapIn )
1103cdf0e10cSrcweir             {
1104cdf0e10cSrcweir                 sal_Bool bIsModifyLocked = IsModifyLocked();
1105cdf0e10cSrcweir                 LockModify();
1106cdf0e10cSrcweir                 SwapIn( sal_False );
1107cdf0e10cSrcweir                 if ( !bIsModifyLocked )
1108cdf0e10cSrcweir                     UnlockModify();
1109cdf0e10cSrcweir             }
1110cdf0e10cSrcweir             pRet = GRFMGR_AUTOSWAPSTREAM_NONE;
1111cdf0e10cSrcweir         }
1112cdf0e10cSrcweir         else
1113cdf0e10cSrcweir             pRet = GRFMGR_AUTOSWAPSTREAM_LINK;
1114cdf0e10cSrcweir     }
1115cdf0e10cSrcweir     else
1116cdf0e10cSrcweir     {
1117cdf0e10cSrcweir         pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1118cdf0e10cSrcweir 
11190b19465bSOliver-Rainer Wittmann         if ( HasEmbeddedStreamName() )
1120cdf0e10cSrcweir         {
1121cdf0e10cSrcweir             try
1122cdf0e10cSrcweir             {
1123cdf0e10cSrcweir                 String aStrmName, aPicStgName;
1124cdf0e10cSrcweir                 _GetStreamStorageNames( aStrmName, aPicStgName );
1125cdf0e10cSrcweir                 uno::Reference< embed::XStorage > refPics = _GetDocSubstorageOrRoot( aPicStgName );
1126cdf0e10cSrcweir                 SvStream* pStrm = _GetStreamForEmbedGrf( refPics, aStrmName );
1127cdf0e10cSrcweir                 if ( pStrm )
1128cdf0e10cSrcweir                 {
1129cdf0e10cSrcweir                     if ( pGrfObj->IsInSwapOut() )
1130cdf0e10cSrcweir                     {
1131cdf0e10cSrcweir                         pRet = GRFMGR_AUTOSWAPSTREAM_LINK;
1132cdf0e10cSrcweir                     }
1133cdf0e10cSrcweir                     else
1134cdf0e10cSrcweir                     {
1135cdf0e10cSrcweir                         ImportGraphic( *pStrm );
1136cdf0e10cSrcweir                         pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
1137cdf0e10cSrcweir                     }
1138cdf0e10cSrcweir                     delete pStrm;
1139cdf0e10cSrcweir                 }
1140cdf0e10cSrcweir             }
1141cdf0e10cSrcweir             catch ( uno::Exception& )
1142cdf0e10cSrcweir             {
1143cdf0e10cSrcweir                 ASSERT( false, "<SwapGraphic> - unhandled exception!" );
1144cdf0e10cSrcweir             }
1145cdf0e10cSrcweir         }
1146cdf0e10cSrcweir     }
1147cdf0e10cSrcweir 
1148cdf0e10cSrcweir     return (long) pRet;
1149cdf0e10cSrcweir }
1150cdf0e10cSrcweir 
1151cdf0e10cSrcweir // alle QuickDraw-Bitmaps eines speziellen Docs loeschen
DelAllGrfCacheEntries(SwDoc * pDoc)11528a2cae91SOliver-Rainer Wittmann void DelAllGrfCacheEntries(
11538a2cae91SOliver-Rainer Wittmann     SwDoc* pDoc )
1154cdf0e10cSrcweir {
1155cdf0e10cSrcweir     if ( pDoc )
1156cdf0e10cSrcweir     {
1157cdf0e10cSrcweir         // alle Graphic-Links mit dem Namen aus dem Cache loeschen
1158cdf0e10cSrcweir         const sfx2::LinkManager& rLnkMgr = pDoc->GetLinkManager();
1159cdf0e10cSrcweir         const ::sfx2::SvBaseLinks& rLnks = rLnkMgr.GetLinks();
1160cdf0e10cSrcweir         SwGrfNode* pGrfNd;
1161cdf0e10cSrcweir         String sFileNm;
1162cdf0e10cSrcweir         for ( sal_uInt16 n = rLnks.Count(); n; )
1163cdf0e10cSrcweir         {
1164cdf0e10cSrcweir             ::sfx2::SvBaseLink* pLnk = &( *rLnks[--n] );
11658a2cae91SOliver-Rainer Wittmann             if ( pLnk && OBJECT_CLIENT_GRF == pLnk->GetObjType()
11668a2cae91SOliver-Rainer Wittmann                  && rLnkMgr.GetDisplayNames( pLnk, 0, &sFileNm )
11678a2cae91SOliver-Rainer Wittmann                  && pLnk->ISA( SwBaseLink )
11688a2cae91SOliver-Rainer Wittmann                  && 0 != ( pGrfNd = ( (SwBaseLink*) pLnk )->GetCntntNode()->GetGrfNode() ) )
1169cdf0e10cSrcweir             {
1170172c67b2SArmin Le Grand                 pGrfNd->ReleaseGraphicFromCache();
1171cdf0e10cSrcweir             }
1172cdf0e10cSrcweir         }
1173cdf0e10cSrcweir     }
1174cdf0e10cSrcweir }
1175cdf0e10cSrcweir 
1176cdf0e10cSrcweir // returns the with our graphic attributes filled Graphic-Attr-Structure
GetGraphicAttr(GraphicAttr & rGA,const SwFrm * pFrm) const11778a2cae91SOliver-Rainer Wittmann GraphicAttr& SwGrfNode::GetGraphicAttr(
11788a2cae91SOliver-Rainer Wittmann     GraphicAttr& rGA,
1179cdf0e10cSrcweir     const SwFrm* pFrm ) const
1180cdf0e10cSrcweir     {
1181cdf0e10cSrcweir     const SwAttrSet& rSet = GetSwAttrSet();
1182cdf0e10cSrcweir 
1183cdf0e10cSrcweir     rGA.SetDrawMode( (GraphicDrawMode) rSet.GetDrawModeGrf().GetValue() );
1184cdf0e10cSrcweir 
1185cdf0e10cSrcweir     const SwMirrorGrf & rMirror = rSet.GetMirrorGrf();
1186cdf0e10cSrcweir     sal_uLong nMirror = BMP_MIRROR_NONE;
1187cdf0e10cSrcweir     if ( rMirror.IsGrfToggle() && pFrm && !pFrm->FindPageFrm()->OnRightPage() )
1188cdf0e10cSrcweir     {
1189cdf0e10cSrcweir         switch (rMirror.GetValue())
1190cdf0e10cSrcweir         {
11918a2cae91SOliver-Rainer Wittmann         case RES_MIRROR_GRAPH_DONT:
11928a2cae91SOliver-Rainer Wittmann             nMirror = BMP_MIRROR_HORZ;
1193cdf0e10cSrcweir             break;
11948a2cae91SOliver-Rainer Wittmann         case RES_MIRROR_GRAPH_VERT:
11958a2cae91SOliver-Rainer Wittmann             nMirror = BMP_MIRROR_NONE;
11968a2cae91SOliver-Rainer Wittmann             break;
11978a2cae91SOliver-Rainer Wittmann         case RES_MIRROR_GRAPH_HOR:
11988a2cae91SOliver-Rainer Wittmann             nMirror = BMP_MIRROR_HORZ | BMP_MIRROR_VERT;
11998a2cae91SOliver-Rainer Wittmann             break;
12008a2cae91SOliver-Rainer Wittmann         default:
12018a2cae91SOliver-Rainer Wittmann             nMirror = BMP_MIRROR_VERT;
12028a2cae91SOliver-Rainer Wittmann             break;
1203cdf0e10cSrcweir         }
1204cdf0e10cSrcweir     }
1205cdf0e10cSrcweir     else
1206cdf0e10cSrcweir         switch (rMirror.GetValue())
1207cdf0e10cSrcweir         {
12088a2cae91SOliver-Rainer Wittmann         case RES_MIRROR_GRAPH_BOTH:
12098a2cae91SOliver-Rainer Wittmann             nMirror = BMP_MIRROR_HORZ | BMP_MIRROR_VERT;
1210cdf0e10cSrcweir             break;
12118a2cae91SOliver-Rainer Wittmann         case RES_MIRROR_GRAPH_VERT:
12128a2cae91SOliver-Rainer Wittmann             nMirror = BMP_MIRROR_HORZ;
12138a2cae91SOliver-Rainer Wittmann             break;
12148a2cae91SOliver-Rainer Wittmann         case RES_MIRROR_GRAPH_HOR:
12158a2cae91SOliver-Rainer Wittmann             nMirror = BMP_MIRROR_VERT;
12168a2cae91SOliver-Rainer Wittmann             break;
1217cdf0e10cSrcweir         }
1218cdf0e10cSrcweir 
1219cdf0e10cSrcweir     rGA.SetMirrorFlags( nMirror );
1220cdf0e10cSrcweir 
1221cdf0e10cSrcweir     const SwCropGrf& rCrop = rSet.GetCropGrf();
1222cdf0e10cSrcweir     rGA.SetCrop( TWIP_TO_MM100( rCrop.GetLeft() ),
1223cdf0e10cSrcweir         TWIP_TO_MM100( rCrop.GetTop() ),
1224cdf0e10cSrcweir         TWIP_TO_MM100( rCrop.GetRight() ),
1225cdf0e10cSrcweir         TWIP_TO_MM100( rCrop.GetBottom() ) );
1226cdf0e10cSrcweir 
1227cdf0e10cSrcweir     const SwRotationGrf& rRotation = rSet.GetRotationGrf();
1228cdf0e10cSrcweir     rGA.SetRotation( rRotation.GetValue() );
1229cdf0e10cSrcweir 
1230cdf0e10cSrcweir     rGA.SetLuminance( rSet.GetLuminanceGrf().GetValue() );
1231cdf0e10cSrcweir     rGA.SetContrast( rSet.GetContrastGrf().GetValue() );
1232cdf0e10cSrcweir     rGA.SetChannelR( rSet.GetChannelRGrf().GetValue() );
1233cdf0e10cSrcweir     rGA.SetChannelG( rSet.GetChannelGGrf().GetValue() );
1234cdf0e10cSrcweir     rGA.SetChannelB( rSet.GetChannelBGrf().GetValue() );
1235cdf0e10cSrcweir     rGA.SetGamma( rSet.GetGammaGrf().GetValue() );
1236cdf0e10cSrcweir     rGA.SetInvert( rSet.GetInvertGrf().GetValue() );
1237cdf0e10cSrcweir 
1238cdf0e10cSrcweir     const sal_uInt16 nTrans = rSet.GetTransparencyGrf().GetValue();
1239cdf0e10cSrcweir     rGA.SetTransparency( (sal_uInt8) FRound(
1240cdf0e10cSrcweir         Min( nTrans, (sal_uInt16) 100 ) * 2.55 ) );
1241cdf0e10cSrcweir 
1242cdf0e10cSrcweir     return rGA;
1243cdf0e10cSrcweir }
1244cdf0e10cSrcweir 
IsTransparent() const1245cdf0e10cSrcweir sal_Bool SwGrfNode::IsTransparent() const
1246cdf0e10cSrcweir {
1247172c67b2SArmin Le Grand     sal_Bool bRet = maGrfObj.IsTransparent();
1248cdf0e10cSrcweir     if ( !bRet )	// ask the attribut
1249cdf0e10cSrcweir         bRet = 0 != GetSwAttrSet().GetTransparencyGrf().GetValue();
1250cdf0e10cSrcweir 
1251cdf0e10cSrcweir     return bRet;
1252cdf0e10cSrcweir }
1253cdf0e10cSrcweir 
IsSelected() const1254cdf0e10cSrcweir sal_Bool SwGrfNode::IsSelected() const
1255cdf0e10cSrcweir {
1256cdf0e10cSrcweir     sal_Bool bRet = sal_False;
1257cdf0e10cSrcweir     const SwEditShell* pESh = GetDoc()->GetEditShell();
1258cdf0e10cSrcweir     if ( pESh )
1259cdf0e10cSrcweir     {
1260cdf0e10cSrcweir         const SwNode* pN = this;
1261cdf0e10cSrcweir         const ViewShell* pV = pESh;
12628a2cae91SOliver-Rainer Wittmann         do
12638a2cae91SOliver-Rainer Wittmann         {
1264cdf0e10cSrcweir             if ( pV->ISA( SwEditShell ) && pN == &( (SwCrsrShell*) pV )
1265cdf0e10cSrcweir                                                    ->GetCrsr()->GetPoint()->nNode.GetNode() )
1266cdf0e10cSrcweir             {
1267cdf0e10cSrcweir                 bRet = sal_True;
1268cdf0e10cSrcweir                 break;
1269cdf0e10cSrcweir             }
1270cdf0e10cSrcweir         }
1271cdf0e10cSrcweir         while (pESh != ( pV = (ViewShell*) pV->GetNext() ));
1272cdf0e10cSrcweir     }
1273cdf0e10cSrcweir     return bRet;
1274cdf0e10cSrcweir }
1275cdf0e10cSrcweir 
GetThreadConsumer()1276cdf0e10cSrcweir boost::weak_ptr< SwAsyncRetrieveInputStreamThreadConsumer > SwGrfNode::GetThreadConsumer()
1277cdf0e10cSrcweir {
1278cdf0e10cSrcweir     return mpThreadConsumer;
1279cdf0e10cSrcweir }
1280cdf0e10cSrcweir 
TriggerAsyncRetrieveInputStream()1281cdf0e10cSrcweir void SwGrfNode::TriggerAsyncRetrieveInputStream()
1282cdf0e10cSrcweir {
1283cdf0e10cSrcweir     if ( !IsLinkedFile() )
1284cdf0e10cSrcweir     {
1285cdf0e10cSrcweir         ASSERT( false,
1286cdf0e10cSrcweir             "<SwGrfNode::TriggerAsyncLoad()> - Method is misused. Method call is only valid for graphic nodes, which refer a linked graphic file" );
1287cdf0e10cSrcweir         return;
1288cdf0e10cSrcweir     }
1289cdf0e10cSrcweir 
1290cdf0e10cSrcweir     if ( mpThreadConsumer.get() == 0 )
1291cdf0e10cSrcweir     {
1292cdf0e10cSrcweir         mpThreadConsumer.reset( new SwAsyncRetrieveInputStreamThreadConsumer( *this ) );
1293cdf0e10cSrcweir 
1294cdf0e10cSrcweir         String sGrfNm;
1295cdf0e10cSrcweir         refLink->GetLinkManager()->GetDisplayNames( refLink, 0, &sGrfNm, 0, 0 );
1296cdf0e10cSrcweir 
1297cdf0e10cSrcweir         mpThreadConsumer->CreateThread( sGrfNm );
1298cdf0e10cSrcweir     }
1299cdf0e10cSrcweir }
1300cdf0e10cSrcweir 
IsLinkedInputStreamReady() const1301cdf0e10cSrcweir bool SwGrfNode::IsLinkedInputStreamReady() const
1302cdf0e10cSrcweir {
1303cdf0e10cSrcweir     return mbLinkedInputStreamReady;
1304cdf0e10cSrcweir }
1305cdf0e10cSrcweir 
ApplyInputStream(com::sun::star::uno::Reference<com::sun::star::io::XInputStream> xInputStream,const sal_Bool bIsStreamReadOnly)1306cdf0e10cSrcweir void SwGrfNode::ApplyInputStream(
1307cdf0e10cSrcweir     com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream,
1308cdf0e10cSrcweir     const sal_Bool bIsStreamReadOnly )
1309cdf0e10cSrcweir {
1310cdf0e10cSrcweir     if ( IsLinkedFile() )
1311cdf0e10cSrcweir     {
1312cdf0e10cSrcweir         if ( xInputStream.is() )
1313cdf0e10cSrcweir         {
1314cdf0e10cSrcweir             mxInputStream = xInputStream;
1315cdf0e10cSrcweir             mbIsStreamReadOnly = bIsStreamReadOnly;
1316cdf0e10cSrcweir             mbLinkedInputStreamReady = true;
1317cdf0e10cSrcweir             SwMsgPoolItem aMsgHint( RES_LINKED_GRAPHIC_STREAM_ARRIVED );
1318cdf0e10cSrcweir             ModifyNotification( &aMsgHint, &aMsgHint );
1319cdf0e10cSrcweir         }
1320cdf0e10cSrcweir     }
1321cdf0e10cSrcweir }
1322cdf0e10cSrcweir 
UpdateLinkWithInputStream()1323cdf0e10cSrcweir void SwGrfNode::UpdateLinkWithInputStream()
1324cdf0e10cSrcweir {
1325cdf0e10cSrcweir     // do not work on link, if a <SwapIn> has been triggered.
1326cdf0e10cSrcweir     if ( !bInSwapIn && IsLinkedFile() )
1327cdf0e10cSrcweir     {
1328cdf0e10cSrcweir         GetLink()->setStreamToLoadFrom( mxInputStream, mbIsStreamReadOnly );
1329cdf0e10cSrcweir         GetLink()->Update();
1330cdf0e10cSrcweir         SwMsgPoolItem aMsgHint( RES_GRAPHIC_ARRIVED );
1331cdf0e10cSrcweir         ModifyNotification( &aMsgHint, &aMsgHint );
1332cdf0e10cSrcweir 
1333cdf0e10cSrcweir         mxInputStream.clear();
1334cdf0e10cSrcweir         GetLink()->clearStreamToLoadFrom();
1335cdf0e10cSrcweir         mbLinkedInputStreamReady = false;
1336cdf0e10cSrcweir         mpThreadConsumer.reset();
1337cdf0e10cSrcweir     }
1338cdf0e10cSrcweir }
1339cdf0e10cSrcweir 
13408a2cae91SOliver-Rainer Wittmann 
IsAsyncRetrieveInputStreamPossible() const1341cdf0e10cSrcweir bool SwGrfNode::IsAsyncRetrieveInputStreamPossible() const
1342cdf0e10cSrcweir {
1343cdf0e10cSrcweir     bool bRet = false;
1344cdf0e10cSrcweir 
1345cdf0e10cSrcweir     if ( IsLinkedFile() )
1346cdf0e10cSrcweir     {
1347cdf0e10cSrcweir         String sGrfNm;
1348cdf0e10cSrcweir         refLink->GetLinkManager()->GetDisplayNames( refLink, 0, &sGrfNm, 0, 0 );
1349cdf0e10cSrcweir         String sProtocol( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.pkg:" ) );
1350cdf0e10cSrcweir         if ( sGrfNm.CompareTo( sProtocol, sProtocol.Len() ) != 0 )
1351cdf0e10cSrcweir         {
1352cdf0e10cSrcweir             bRet = true;
1353cdf0e10cSrcweir         }
1354cdf0e10cSrcweir     }
1355cdf0e10cSrcweir 
1356cdf0e10cSrcweir     return bRet;
1357cdf0e10cSrcweir }
1358