1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ndgrf.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include <hintids.hxx>
34 #include <vcl/salbtype.hxx> // FRound
35 #include <tools/urlobj.hxx>
36 #include <svtools/undo.hxx>
37 #ifndef SVTOOLS_FSTATHELPER_HXX
38 #include <svtools/fstathelper.hxx>
40 #include <svtools/imap.hxx>
41 #include <svtools/filter.hxx>
42 #include <sot/storage.hxx>
43 #include <svx/linkmgr.hxx>
44 #include <svx/boxitem.hxx>
45 #include <svx/impgrf.hxx>
46 #include <sot/formats.hxx>
47 #include <fmtfsize.hxx>
53 #include <swtypes.hxx>
57 #include <swbaslnk.hxx>
58 #include <pagefrm.hxx>
62 #include <unotools/ucbstreamhelper.hxx>
63 #include <com/sun/star/embed/ElementModes.hpp>
64 #include <com/sun/star/embed/XTransactedObject.hpp>
65 #include <tools/link.hxx>
66 #include <vcl/svapp.hxx>
67 #include <com/sun/star/io/XSeekable.hpp>
68 // --> OD 2007-03-28 #i73788#
69 #include <retrieveinputstreamconsumer.hxx>
72 using namespace com::sun::star
;
74 // --------------------
76 // --------------------
78 const SwNodeIndex
& rWhere
,
79 const String
& rGrfName
, const String
& rFltName
,
80 const Graphic
* pGraphic
,
81 SwGrfFmtColl
*pGrfColl
,
82 SwAttrSet
* pAutoAttr
) :
83 SwNoTxtNode( rWhere
, ND_GRFNODE
, pGrfColl
, pAutoAttr
),
84 // --> OD 2007-01-23 #i73788#
85 mbLinkedInputStreamReady( false ),
86 mbIsStreamReadOnly( sal_False
)
89 aGrfObj
.SetSwapStreamHdl( LINK( this, SwGrfNode
, SwapGraphic
) );
90 bInSwapIn
= bChgTwipSize
= bChgTwipSizeFromPixel
= bLoadLowResGrf
=
91 bFrameInPaint
= bScaleImageMap
= FALSE
;
93 bGrafikArrived
= TRUE
;
94 ReRead(rGrfName
,rFltName
, pGraphic
, 0, FALSE
);
97 SwGrfNode::SwGrfNode( const SwNodeIndex
& rWhere
,
98 const GraphicObject
& rGrfObj
,
99 SwGrfFmtColl
*pGrfColl
, SwAttrSet
* pAutoAttr
) :
100 SwNoTxtNode( rWhere
, ND_GRFNODE
, pGrfColl
, pAutoAttr
),
101 // --> OD 2007-01-23 #i73788#
102 mbLinkedInputStreamReady( false ),
103 mbIsStreamReadOnly( sal_False
)
107 aGrfObj
.SetSwapStreamHdl( LINK( this, SwGrfNode
, SwapGraphic
) );
108 if( rGrfObj
.HasUserData() && rGrfObj
.IsSwappedOut() )
109 aGrfObj
.SetSwapState();
110 bInSwapIn
= bChgTwipSize
= bChgTwipSizeFromPixel
= bLoadLowResGrf
=
111 bFrameInPaint
= bScaleImageMap
= FALSE
;
112 bGrafikArrived
= TRUE
;
115 // Konstruktor fuer den SW/G-Reader. Dieser ctor wird verwendet,
116 // wenn eine gelinkte Grafik gelesen wird. Sie liest diese NICHT ein.
119 SwGrfNode::SwGrfNode( const SwNodeIndex
& rWhere
,
120 const String
& rGrfName
, const String
& rFltName
,
121 SwGrfFmtColl
*pGrfColl
,
122 SwAttrSet
* pAutoAttr
) :
123 SwNoTxtNode( rWhere
, ND_GRFNODE
, pGrfColl
, pAutoAttr
),
124 // --> OD 2007-01-23 #i73788#
125 mbLinkedInputStreamReady( false ),
126 mbIsStreamReadOnly( sal_False
)
129 aGrfObj
.SetSwapStreamHdl( LINK( this, SwGrfNode
, SwapGraphic
) );
131 Graphic aGrf
; aGrf
.SetDefaultType();
132 aGrfObj
.SetGraphic( aGrf
, rGrfName
);
134 bInSwapIn
= bChgTwipSize
= bChgTwipSizeFromPixel
= bLoadLowResGrf
=
135 bFrameInPaint
= bScaleImageMap
= FALSE
;
136 bGrafikArrived
= TRUE
;
138 InsertLink( rGrfName
, rFltName
);
141 INetURLObject
aUrl( rGrfName
);
142 if( INET_PROT_FILE
== aUrl
.GetProtocol() &&
143 FStatHelper::IsDocument( aUrl
.GetMainURL( INetURLObject::NO_DECODE
) ))
145 // File vorhanden, Verbindung herstellen ohne ein Update
146 ((SwBaseLink
*)&refLink
)->Connect();
151 BOOL
SwGrfNode::ReRead(
152 const String
& rGrfName
, const String
& rFltName
,
153 const Graphic
* pGraphic
, const GraphicObject
* pGrfObj
,
156 BOOL bReadGrf
= FALSE
, bSetTwipSize
= TRUE
;
158 ASSERT( pGraphic
|| pGrfObj
|| rGrfName
.Len(),
159 "GraphicNode without a name, Graphic or GraphicObject" );
161 // ReadRead mit Namen
164 ASSERT( !bInSwapIn
, "ReRead: stehe noch im SwapIn" );
168 // Besonderheit: steht im FltNamen DDE, handelt es sich um eine
169 // DDE-gelinkte Grafik
170 String
sCmd( rGrfName
);
174 if( rFltName
.EqualsAscii( "DDE" ))
175 nNewType
= OBJECT_CLIENT_DDE
;
178 sfx2::MakeLnkName( sCmd
, 0, rGrfName
, aEmptyStr
, &rFltName
);
179 nNewType
= OBJECT_CLIENT_GRF
;
182 if( nNewType
!= refLink
->GetObjType() )
184 refLink
->Disconnect();
185 ((SwBaseLink
*)&refLink
)->SetObjType( nNewType
);
189 refLink
->SetLinkSourceName( sCmd
);
191 else // kein Name mehr, Link aufheben
193 GetDoc()->GetLinkManager().Remove( refLink
);
199 aGrfObj
.SetGraphic( *pGraphic
, rGrfName
);
205 if( pGrfObj
->HasUserData() && pGrfObj
->IsSwappedOut() )
206 aGrfObj
.SetSwapState();
207 aGrfObj
.SetLink( rGrfName
);
212 // MIB 25.02.97: Daten der alten Grafik zuruecksetzen, damit
213 // die korrekte Ersatz-Darstellung erscheint, wenn die
214 // der neue Link nicht geladen werden konnte.
215 Graphic aGrf
; aGrf
.SetDefaultType();
216 aGrfObj
.SetGraphic( aGrf
, rGrfName
);
222 SwMsgPoolItem
aMsgHint( RES_GRF_REREAD_AND_INCACHE
);
223 Modify( &aMsgHint
, &aMsgHint
);
225 // --> OD 2006-11-03 #i59688#
226 // do not load linked graphic, if it isn't a new linked graphic.
231 //TODO refLink->setInputStream(getInputStream());
232 ((SwBaseLink
*)&refLink
)->SwapIn();
235 bSetTwipSize
= FALSE
;
238 else if( pGraphic
&& !rGrfName
.Len() )
240 // MIB 27.02.2001: Old stream must be deleted before the new one is set.
241 if( HasStreamName() )
244 aGrfObj
.SetGraphic( *pGraphic
);
247 else if( pGrfObj
&& !rGrfName
.Len() )
249 // MIB 27.02.2001: Old stream must be deleted before the new one is set.
250 if( HasStreamName() )
254 if( pGrfObj
->HasUserData() && pGrfObj
->IsSwappedOut() )
255 aGrfObj
.SetSwapState();
258 // Import einer Grafik:
259 // Ist die Grafik bereits geladen?
260 else if( !bNewGrf
&& GRAPHIC_NONE
!= aGrfObj
.GetType() )
265 if( HasStreamName() )
268 // einen neuen Grafik-Link anlegen
269 InsertLink( rGrfName
, rFltName
);
271 if( GetNodes().IsDocNodes() )
275 aGrfObj
.SetGraphic( *pGraphic
, rGrfName
);
277 // Verbindung herstellen ohne ein Update; Grafik haben wir!
278 ((SwBaseLink
*)&refLink
)->Connect();
283 aGrfObj
.SetLink( rGrfName
);
285 // Verbindung herstellen ohne ein Update; Grafik haben wir!
286 ((SwBaseLink
*)&refLink
)->Connect();
290 // MIB 25.02.97: Daten der alten Grafik zuruecksetzen, damit
291 // die korrekte Ersatz-Darstellung erscheint, wenn die
292 // der neue Kink nicht geladen werden konnte.
293 Graphic aGrf
; aGrf
.SetDefaultType();
294 aGrfObj
.SetGraphic( aGrf
, rGrfName
);
295 // --> OD 2006-11-03 #i59688#
296 // do not load linked graphic, if it isn't a new linked graphic.
297 // //TODO refLink->setInputStream(getInputStream());
298 // ((SwBaseLink*)&refLink)->SwapIn();
301 ((SwBaseLink
*)&refLink
)->SwapIn();
308 // Bug 39281: Size nicht sofort loeschen - Events auf ImageMaps
309 // sollten nicht beim Austauschen nicht ins "leere greifen"
311 SetTwipSize( ::GetGraphicSizeTwip( aGrfObj
.GetGraphic(), 0 ) );
313 // erzeuge noch einen Update auf die Frames
314 if( bReadGrf
&& bNewGrf
)
316 SwMsgPoolItem
aMsgHint( RES_UPDATE_ATTR
);
317 Modify( &aMsgHint
, &aMsgHint
);
324 SwGrfNode::~SwGrfNode()
326 // --> OD 2007-03-30 #i73788#
327 mpThreadConsumer
.reset();
330 SwDoc
* pDoc
= GetDoc();
333 ASSERT( !bInSwapIn
, "DTOR: stehe noch im SwapIn" );
334 pDoc
->GetLinkManager().Remove( refLink
);
335 refLink
->Disconnect();
339 // --> OD 2005-01-19 #i40014# - A graphic node, which are in linked
340 // section, whose link is another section is the document, doesn't
341 // have to remove the stream from the storage.
342 // Because it's hard to detect this case here and it would only fix
343 // one problem with shared graphic files - there are also problems,
344 // a certain graphic file is referenced by two independent graphic nodes,
345 // brush item or drawing objects, the stream isn't no longer removed here.
346 // To do this stuff correct, a reference counting on shared streams
347 // inside one document have to be implemented.
348 // if( !pDoc->IsInDtor() && HasStreamName() )
352 //#39289# Die Frames muessen hier bereits geloescht weil der DTor der
353 //Frms die Grafik noch fuer StopAnimation braucht.
359 SwCntntNode
*SwGrfNode::SplitCntntNode( const SwPosition
& )
365 SwGrfNode
* SwNodes::MakeGrfNode( const SwNodeIndex
& rWhere
,
366 const String
& rGrfName
,
367 const String
& rFltName
,
368 const Graphic
* pGraphic
,
369 SwGrfFmtColl
* pGrfColl
,
370 SwAttrSet
* pAutoAttr
,
373 ASSERT( pGrfColl
, "MakeGrfNode: Formatpointer ist 0." );
375 // Delayed erzeugen nur aus dem SW/G-Reader
377 pNode
= new SwGrfNode( rWhere
, rGrfName
,
378 rFltName
, pGrfColl
, pAutoAttr
);
380 pNode
= new SwGrfNode( rWhere
, rGrfName
,
381 rFltName
, pGraphic
, pGrfColl
, pAutoAttr
);
385 SwGrfNode
* SwNodes::MakeGrfNode( const SwNodeIndex
& rWhere
,
386 const GraphicObject
& rGrfObj
,
387 SwGrfFmtColl
* pGrfColl
,
388 SwAttrSet
* pAutoAttr
)
390 ASSERT( pGrfColl
, "MakeGrfNode: Formatpointer ist 0." );
391 return new SwGrfNode( rWhere
, rGrfObj
, pGrfColl
, pAutoAttr
);
395 Size
SwGrfNode::GetTwipSize() const
402 BOOL
SwGrfNode::ImportGraphic( SvStream
& rStrm
)
405 if( !GetGrfFilter()->ImportGraphic( aGraphic
, String(), rStrm
) )
407 const String
aUserData( aGrfObj
.GetUserData() );
409 aGrfObj
.SetGraphic( aGraphic
);
410 aGrfObj
.SetUserData( aUserData
);
418 // -1 : ReRead erfolgreich
420 // 1 : Einlesen erfolgreich
422 short SwGrfNode::SwapIn( BOOL bWaitForData
)
424 if( bInSwapIn
) // nicht rekuriv!!
425 return !aGrfObj
.IsSwappedOut();
429 SwBaseLink
* pLink
= (SwBaseLink
*)(::sfx2::SvBaseLink
*) refLink
;
433 if( GRAPHIC_NONE
== aGrfObj
.GetType() ||
434 GRAPHIC_DEFAULT
== aGrfObj
.GetType() )
436 // noch nicht geladener Link
437 //TODO pLink->setInputStream(getInputStream());
438 if( pLink
->SwapIn( bWaitForData
) )
440 else if( GRAPHIC_DEFAULT
== aGrfObj
.GetType() )
442 // keine default Bitmap mehr, also neu Painten!
443 aGrfObj
.SetGraphic( Graphic() );
444 SwMsgPoolItem
aMsgHint( RES_GRAPHIC_PIECE_ARRIVED
);
445 Modify( &aMsgHint
, &aMsgHint
);
448 else if( aGrfObj
.IsSwappedOut() ) {
449 // nachzuladender Link
450 //TODO pLink->setInputStream(getInputStream());
451 nRet
= pLink
->SwapIn( bWaitForData
) ? 1 : 0;
456 else if( aGrfObj
.IsSwappedOut() )
458 // Die Grafik ist im Storage oder im TempFile drin
459 if( !HasStreamName() )
460 nRet
= (short)aGrfObj
.SwapIn();
464 // --> OD 2005-05-04 #i48434# - usage of new method <_GetStreamForEmbedGrf(..)>
467 // --> OD, MAV 2005-08-17 #i53025# - needed correction of new
468 // method <_GetStreamForEmbedGrf(..)>
469 // bool bGraphic(false);
470 // SvStream* pStrm = _GetStreamForEmbedGrf( bGraphic );
471 String aStrmName
, aPicStgName
;
472 _GetStreamStorageNames( aStrmName
, aPicStgName
);
473 uno::Reference
< embed::XStorage
> refPics
= _GetDocSubstorageOrRoot( aPicStgName
);
474 SvStream
* pStrm
= _GetStreamForEmbedGrf( refPics
, aStrmName
);
477 if ( ImportGraphic( *pStrm
) )
483 catch ( uno::Exception
& )
485 // --> OD 2005-04-25 #i48434#
486 ASSERT( false, "<SwGrfNode::SwapIn(..)> - unhandled exception!" );
494 SwMsgPoolItem
aMsg( RES_GRAPHIC_SWAPIN
);
495 Modify( &aMsg
, &aMsg
);
500 DBG_ASSERTWARNING( nRet
, "Grafik kann nicht eingeswapt werden" );
504 if( !nGrfSize
.Width() && !nGrfSize
.Height() )
505 SetTwipSize( ::GetGraphicSizeTwip( aGrfObj
.GetGraphic(), 0 ) );
512 short SwGrfNode::SwapOut()
514 if( aGrfObj
.GetType() != GRAPHIC_DEFAULT
&&
515 aGrfObj
.GetType() != GRAPHIC_NONE
&&
516 !aGrfObj
.IsSwappedOut() && !bInSwapIn
)
520 // Das Swapping brauchen wir nur fuer Embedded Pictures
521 // Die Grafik wird in eine TempFile geschrieben, wenn
522 // sie frisch eingefuegt war, d.h. wenn es noch keinen
523 // Streamnamen im Storage gibt.
524 if( !HasStreamName() )
525 if( !aGrfObj
.SwapOut() )
528 // Geschriebene Grafiken oder Links werden jetzt weggeschmissen
529 return (short) aGrfObj
.SwapOut( NULL
);
535 BOOL
SwGrfNode::GetFileFilterNms( String
* pFileNm
, String
* pFilterNm
) const
538 if( refLink
.Is() && refLink
->GetLinkManager() )
540 USHORT nType
= refLink
->GetObjType();
541 if( OBJECT_CLIENT_GRF
== nType
)
542 bRet
= refLink
->GetLinkManager()->GetDisplayNames(
543 refLink
, 0, pFileNm
, 0, pFilterNm
);
544 else if( OBJECT_CLIENT_DDE
== nType
&& pFileNm
&& pFilterNm
)
546 String sApp
, sTopic
, sItem
;
547 if( refLink
->GetLinkManager()->GetDisplayNames(
548 refLink
, &sApp
, &sTopic
, &sItem
) )
550 ( *pFileNm
= sApp
) += sfx2::cTokenSeperator
;
551 ( *pFileNm
+= sTopic
) += sfx2::cTokenSeperator
;
553 pFilterNm
->AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDE" ));
562 // Eine Grafik Undo-faehig machen. Falls sie sich bereits in
563 // einem Storage befindet, muss sie geladen werden.
565 BOOL
SwGrfNode::SavePersistentData()
569 ASSERT( !bInSwapIn
, "SavePersistentData: stehe noch im SwapIn" );
570 GetDoc()->GetLinkManager().Remove( refLink
);
574 // Erst mal reinswappen, falls sie im Storage ist
575 if( HasStreamName() && !SwapIn() )
578 // --> OD 2005-04-19 #i44367#
579 // Do not delete graphic file in storage, because the graphic file could
580 // be referenced by other graphic nodes.
581 // Because it's hard to detect this case here and it would only fix
582 // one problem with shared graphic files - there are also problems,
583 // a certain graphic file is referenced by two independent graphic nodes,
584 // brush item or drawing objects, the stream isn't no longer removed here.
585 // To do this stuff correct, a reference counting on shared streams
586 // inside one document have to be implemented.
587 // Important note: see also fix for #i40014#
588 // if( HasStreamName() )
592 // Und in TempFile rausswappen
593 return (BOOL
) SwapOut();
597 BOOL
SwGrfNode::RestorePersistentData()
601 IDocumentLinksAdministration
* pIDLA
= getIDocumentLinksAdministration();
602 refLink
->SetVisible( pIDLA
->IsVisibleLinks() );
603 pIDLA
->GetLinkManager().InsertDDELink( refLink
);
604 if( getIDocumentLayoutAccess()->GetRootFrm() )
611 void SwGrfNode::InsertLink( const String
& rGrfName
, const String
& rFltName
)
613 refLink
= new SwBaseLink( sfx2::LINKUPDATE_ONCALL
, FORMAT_GDIMETAFILE
, this );
615 IDocumentLinksAdministration
* pIDLA
= getIDocumentLinksAdministration();
616 if( GetNodes().IsDocNodes() )
618 refLink
->SetVisible( pIDLA
->IsVisibleLinks() );
619 if( rFltName
.EqualsAscii( "DDE" ))
622 String sApp
, sTopic
, sItem
;
623 sApp
= rGrfName
.GetToken( 0, sfx2::cTokenSeperator
, nTmp
);
624 sTopic
= rGrfName
.GetToken( 0, sfx2::cTokenSeperator
, nTmp
);
625 sItem
= rGrfName
.Copy( nTmp
);
626 pIDLA
->GetLinkManager().InsertDDELink( refLink
,
627 sApp
, sTopic
, sItem
);
631 BOOL bSync
= rFltName
.EqualsAscii( "SYNCHRON" );
632 refLink
->SetSynchron( bSync
);
633 refLink
->SetContentType( SOT_FORMATSTR_ID_SVXB
);
635 pIDLA
->GetLinkManager().InsertFileLink( *refLink
,
636 OBJECT_CLIENT_GRF
, rGrfName
,
637 (!bSync
&& rFltName
.Len() ? &rFltName
: 0) );
640 aGrfObj
.SetLink( rGrfName
);
644 void SwGrfNode::ReleaseLink()
648 // erst die Grafik reinswappen!
649 // if( aGraphic.IsSwapOut() || !refLink->IsSynchron() )
652 SwBaseLink
* pLink
= (SwBaseLink
*)(::sfx2::SvBaseLink
*) refLink
;
653 //TODO pLink->setInputStream(getInputStream());
654 pLink
->SwapIn( TRUE
, TRUE
);
657 getIDocumentLinksAdministration()->GetLinkManager().Remove( refLink
);
664 void SwGrfNode::SetTwipSize( const Size
& rSz
)
667 if( IsScaleImageMap() && nGrfSize
.Width() && nGrfSize
.Height() )
669 // Image-Map an Grafik-Groesse anpassen
672 // Image-Map nicht noch einmal skalieren
673 SetScaleImageMap( FALSE
);
677 // Prioritaet beim Laden der Grafik setzen. Geht nur, wenn der Link
678 // ein FileObject gesetzt hat
679 void SwGrfNode::SetTransferPriority( USHORT nPrio
)
681 if( refLink
.Is() && refLink
->GetObj() )
682 SvxLinkManager::SetTransferPriority( *refLink
, nPrio
);
686 void SwGrfNode::ScaleImageMap()
688 if( !nGrfSize
.Width() || !nGrfSize
.Height() )
691 // dann die Image-Map skalieren
692 SwFrmFmt
* pFmt
= GetFlyFmt();
697 SwFmtURL
aURL( pFmt
->GetURL() );
698 if ( !aURL
.GetMap() )
702 Fraction
aScaleX( 1, 1 );
703 Fraction
aScaleY( 1, 1 );
705 const SwFmtFrmSize
& rFrmSize
= pFmt
->GetFrmSize();
706 const SvxBoxItem
& rBox
= pFmt
->GetBox();
708 if( !rFrmSize
.GetWidthPercent() )
710 SwTwips nWidth
= rFrmSize
.GetWidth();
712 nWidth
-= rBox
.CalcLineSpace(BOX_LINE_LEFT
) +
713 rBox
.CalcLineSpace(BOX_LINE_RIGHT
);
715 ASSERT( nWidth
>0, "Gibt es 0 twip breite Grafiken!?" );
717 if( nGrfSize
.Width() != nWidth
)
719 aScaleX
= Fraction( nGrfSize
.Width(), nWidth
);
723 if( !rFrmSize
.GetHeightPercent() )
725 SwTwips nHeight
= rFrmSize
.GetHeight();
727 nHeight
-= rBox
.CalcLineSpace(BOX_LINE_TOP
) +
728 rBox
.CalcLineSpace(BOX_LINE_BOTTOM
);
730 ASSERT( nHeight
>0, "Gibt es 0 twip hohe Grafiken!?" );
732 if( nGrfSize
.Height() != nHeight
)
734 aScaleY
= Fraction( nGrfSize
.Height(), nHeight
);
741 aURL
.GetMap()->Scale( aScaleX
, aScaleY
);
742 pFmt
->SetFmtAttr( aURL
);
747 void SwGrfNode::DelStreamName()
749 if( HasStreamName() )
751 // Dann die Grafik im Storage loeschen
752 uno::Reference
< embed::XStorage
> xDocStg
= GetDoc()->GetDocStorage();
757 String aPicStgName
, aStrmName
;
758 _GetStreamStorageNames( aStrmName
, aPicStgName
);
759 uno::Reference
< embed::XStorage
> refPics
= xDocStg
;
760 if ( aPicStgName
.Len() )
761 refPics
= xDocStg
->openStorageElement( aPicStgName
, embed::ElementModes::READWRITE
);
762 refPics
->removeElement( aStrmName
);
763 uno::Reference
< embed::XTransactedObject
> xTrans( refPics
, uno::UNO_QUERY
);
767 catch ( uno::Exception
& )
769 // --> OD 2005-04-25 #i48434#
770 ASSERT( false, "<SwGrfNode::DelStreamName()> - unhandled exception!" );
775 aGrfObj
.SetUserData();
779 /** helper method to get a substorage of the document storage for readonly access.
781 OD, MAV 2005-08-17 #i53025#
782 A substorage with the specified name will be opened readonly. If the provided
783 name is empty the root storage will be returned.
785 uno::Reference
< embed::XStorage
> SwGrfNode::_GetDocSubstorageOrRoot( const String
& aStgName
) const
787 uno::Reference
< embed::XStorage
> refStor
=
788 const_cast<SwGrfNode
*>(this)->GetDoc()->GetDocStorage();
789 ASSERT( refStor
.is(), "Kein Storage am Doc" );
791 if ( aStgName
.Len() )
794 return refStor
->openStorageElement( aStgName
, embed::ElementModes::READ
);
800 /** helper method to determine stream for the embedded graphic.
802 OD 2005-05-04 #i48434#
803 Important note: caller of this method has to handle the thrown exceptions
804 OD, MAV 2005-08-17 #i53025#
805 Storage, which should contain the stream of the embedded graphic, is
806 provided via parameter. Otherwise the returned stream will be closed
807 after the the method returns, because its parent stream is closed and deleted.
808 Proposed name of embedded graphic stream is also provided by parameter.
812 SvStream
* SwGrfNode::_GetStreamForEmbedGrf(
813 const uno::Reference
< embed::XStorage
>& _refPics
,
814 String
& _aStrmName
) const
816 SvStream
* pStrm( 0L );
818 if( _refPics
.is() && _aStrmName
.Len() )
820 // If stream doesn't exist in the storage, try access the graphic file by
821 // re-generating its name.
822 // A save action can have changed the filename of the embedded graphic,
823 // because a changed unique ID of the graphic is calculated.
824 // --> OD 2006-01-30 #b6364738#
825 // recursive calls of <GetUniqueID()> have to be avoided.
826 // Thus, use local static boolean to assure this.
827 static bool bInRegenerateStrmName( false );
828 if ( !bInRegenerateStrmName
&&
829 ( !_refPics
->hasByName( _aStrmName
) ||
830 !_refPics
->isStreamElement( _aStrmName
) ) )
832 bInRegenerateStrmName
= true;
833 xub_StrLen nExtPos
= _aStrmName
.Search( '.' );
834 String aExtStr
= _aStrmName
.Copy( nExtPos
);
835 Graphic
aGraphic( GetGrfObj().GetGraphic() );
836 if ( aGraphic
.GetType() != GRAPHIC_NONE
)
838 _aStrmName
= String( GetGrfObj().GetUniqueID(), RTL_TEXTENCODING_ASCII_US
);
839 _aStrmName
+= aExtStr
;
841 bInRegenerateStrmName
= false;
845 // assure that graphic file exist in the storage.
846 if ( _refPics
->hasByName( _aStrmName
) &&
847 _refPics
->isStreamElement( _aStrmName
) )
849 uno::Reference
< io::XStream
> refStrm
= _refPics
->openStreamElement( _aStrmName
, embed::ElementModes::READ
);
850 pStrm
= utl::UcbStreamHelper::CreateStream( refStrm
);
854 ASSERT( false, "<SwGrfNode::_GetStreamForEmbedGrf(..)> - embedded graphic file not found!" );
862 // --> OD 2005-08-17 #i53025# - stream couldn't be in a 3.1 - 5.2 storage any more.
863 // Thus, removing corresponding code.
864 void SwGrfNode::_GetStreamStorageNames( String
& rStrmName
,
865 String
& rStorName
) const
870 String
aUserData( aGrfObj
.GetUserData() );
871 if( !aUserData
.Len() )
874 if (aNewStrmName
.Len()>0) {
875 aUserData
=aNewStrmName
;
878 String
aProt( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.Package:" ) );
879 if( 0 == aUserData
.CompareTo( aProt
, aProt
.Len() ) )
882 xub_StrLen nPos
= aUserData
.Search( '/' );
883 if( STRING_NOTFOUND
== nPos
)
885 rStrmName
= aUserData
.Copy( aProt
.Len() );
889 xub_StrLen nPathStart
= aProt
.Len();
890 if( 0 == aUserData
.CompareToAscii( "./", 2 ) )
892 rStorName
= aUserData
.Copy( nPathStart
, nPos
-nPathStart
);
893 rStrmName
= aUserData
.Copy( nPos
+1 );
899 "<SwGrfNode::_GetStreamStorageNames(..)> - unknown graphic URL type. Code for handling 3.1 - 5.2 storages has been deleted by issue i53025." );
901 ASSERT( STRING_NOTFOUND
== rStrmName
.Search( '/' ),
902 "invalid graphic stream name" );
906 SwCntntNode
* SwGrfNode::MakeCopy( SwDoc
* pDoc
, const SwNodeIndex
& rIdx
) const
908 // kopiere die Formate in das andere Dokument:
909 SwGrfFmtColl
* pColl
= pDoc
->CopyGrfColl( *GetGrfColl() );
912 SwBaseLink
* pLink
= (SwBaseLink
*)(::sfx2::SvBaseLink
*) refLink
;
913 if( !pLink
&& HasStreamName() )
915 // --> OD 2005-05-04 #i48434# - usage of new method <_GetStreamForEmbedGrf(..)>
918 // --> OD, MAV 2005-08-17 #i53025# - needed correction of new
919 // method <_GetStreamForEmbedGrf(..)>
920 // bool bGraphic(false);
921 // SvStream* pStrm = _GetStreamForEmbedGrf( bGraphic );
922 String aStrmName
, aPicStgName
;
923 _GetStreamStorageNames( aStrmName
, aPicStgName
);
924 uno::Reference
< embed::XStorage
> refPics
= _GetDocSubstorageOrRoot( aPicStgName
);
925 SvStream
* pStrm
= _GetStreamForEmbedGrf( refPics
, aStrmName
);
928 GetGrfFilter()->ImportGraphic( aTmpGrf
, String(), *pStrm
);
933 catch ( uno::Exception
& )
935 // --> OD 2005-04-25 #i48434#
936 ASSERT( false, "<SwGrfNode::MakeCopy(..)> - unhandled exception!" );
943 if( aGrfObj
.IsSwappedOut() )
944 const_cast<SwGrfNode
*>(this)->SwapIn();
945 aTmpGrf
= aGrfObj
.GetGraphic();
948 const sfx2::SvLinkManager
& rMgr
= getIDocumentLinksAdministration()->GetLinkManager();
949 String sFile
, sFilter
;
951 rMgr
.GetDisplayNames( refLink
, 0, &sFile
, 0, &sFilter
);
952 else if( IsLinkedDDE() )
955 rMgr
.GetDisplayNames( refLink
, &sTmp1
, &sTmp2
, &sFilter
);
956 sfx2::MakeLnkName( sFile
, &sTmp1
, sTmp2
, sFilter
);
957 sFilter
.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDE" ));
960 SwGrfNode
* pGrfNd
= pDoc
->GetNodes().MakeGrfNode( rIdx
, sFile
, sFilter
,
962 (SwAttrSet
*)GetpSwAttrSet() );
963 pGrfNd
->SetTitle( GetTitle() );
964 pGrfNd
->SetDescription( GetDescription() );
965 pGrfNd
->SetContour( HasContour(), HasAutomaticContour() );
969 IMPL_LINK( SwGrfNode
, SwapGraphic
, GraphicObject
*, pGrfObj
)
973 // #101174#: Keep graphic while in swap in. That's at least important
974 // when breaking links, because in this situation a reschedule call and
975 // a DataChanged call lead to a paint of the graphic.
976 if( pGrfObj
->IsInSwapOut() && (IsSelected() || bInSwapIn
) )
977 pRet
= GRFMGR_AUTOSWAPSTREAM_NONE
;
978 else if( refLink
.Is() )
980 if( pGrfObj
->IsInSwapIn() )
982 // then make it by your self
985 BOOL bIsModifyLocked
= IsModifyLocked();
988 if( !bIsModifyLocked
)
991 pRet
= GRFMGR_AUTOSWAPSTREAM_NONE
;
994 pRet
= GRFMGR_AUTOSWAPSTREAM_LINK
;
998 pRet
= GRFMGR_AUTOSWAPSTREAM_TEMP
;
1000 if( HasStreamName() )
1002 // --> OD 2005-05-04 #i48434# - usage of new method <_GetStreamForEmbedGrf(..)>
1005 // --> OD, MAV 2005-08-17 #i53025# - needed correction of new
1006 // method <_GetStreamForEmbedGrf(..)>
1007 // bool bGraphic(false);
1008 // SvStream* pStrm = _GetStreamForEmbedGrf( bGraphic );
1009 String aStrmName
, aPicStgName
;
1010 _GetStreamStorageNames( aStrmName
, aPicStgName
);
1011 uno::Reference
< embed::XStorage
> refPics
= _GetDocSubstorageOrRoot( aPicStgName
);
1012 SvStream
* pStrm
= _GetStreamForEmbedGrf( refPics
, aStrmName
);
1015 if( pGrfObj
->IsInSwapOut() )
1017 pRet
= GRFMGR_AUTOSWAPSTREAM_LINK
;
1021 ImportGraphic( *pStrm
);
1022 pRet
= GRFMGR_AUTOSWAPSTREAM_LOADED
;
1028 catch ( uno::Exception
& )
1030 // --> OD 2005-04-25 #i48434#
1031 ASSERT( false, "<SwapGraphic> - unhandled exception!" );
1042 // alle QuickDraw-Bitmaps eines speziellen Docs loeschen
1043 void DelAllGrfCacheEntries( SwDoc
* pDoc
)
1047 // alle Graphic-Links mit dem Namen aus dem Cache loeschen
1048 const SvxLinkManager
& rLnkMgr
= pDoc
->GetLinkManager();
1049 const ::sfx2::SvBaseLinks
& rLnks
= rLnkMgr
.GetLinks();
1052 for( USHORT n
= rLnks
.Count(); n
; )
1054 ::sfx2::SvBaseLink
* pLnk
= &(*rLnks
[ --n
]);
1055 if( pLnk
&& OBJECT_CLIENT_GRF
== pLnk
->GetObjType() &&
1056 rLnkMgr
.GetDisplayNames( pLnk
, 0, &sFileNm
) &&
1057 pLnk
->ISA( SwBaseLink
) && 0 != ( pGrfNd
=
1058 ((SwBaseLink
*)pLnk
)->GetCntntNode()->GetGrfNode()) )
1060 pGrfNd
->GetGrfObj().ReleaseFromCache();
1066 // returns the with our graphic attributes filled Graphic-Attr-Structure
1067 GraphicAttr
& SwGrfNode::GetGraphicAttr( GraphicAttr
& rGA
,
1068 const SwFrm
* pFrm
) const
1070 const SwAttrSet
& rSet
= GetSwAttrSet();
1072 rGA
.SetDrawMode( (GraphicDrawMode
)rSet
.GetDrawModeGrf().GetValue() );
1074 const SwMirrorGrf
& rMirror
= rSet
.GetMirrorGrf();
1075 ULONG nMirror
= BMP_MIRROR_NONE
;
1076 if( rMirror
.IsGrfToggle() && pFrm
&& !pFrm
->FindPageFrm()->OnRightPage() )
1078 switch( rMirror
.GetValue() )
1080 case RES_MIRROR_GRAPH_DONT
: nMirror
= BMP_MIRROR_HORZ
; break;
1081 case RES_MIRROR_GRAPH_VERT
: nMirror
= BMP_MIRROR_NONE
; break;
1082 case RES_MIRROR_GRAPH_HOR
: nMirror
= BMP_MIRROR_HORZ
|BMP_MIRROR_VERT
;
1084 default: nMirror
= BMP_MIRROR_VERT
; break;
1088 switch( rMirror
.GetValue() )
1090 case RES_MIRROR_GRAPH_BOTH
: nMirror
= BMP_MIRROR_HORZ
|BMP_MIRROR_VERT
;
1092 case RES_MIRROR_GRAPH_VERT
: nMirror
= BMP_MIRROR_HORZ
; break;
1093 case RES_MIRROR_GRAPH_HOR
: nMirror
= BMP_MIRROR_VERT
; break;
1096 rGA
.SetMirrorFlags( nMirror
);
1098 const SwCropGrf
& rCrop
= rSet
.GetCropGrf();
1099 rGA
.SetCrop( TWIP_TO_MM100( rCrop
.GetLeft() ),
1100 TWIP_TO_MM100( rCrop
.GetTop() ),
1101 TWIP_TO_MM100( rCrop
.GetRight() ),
1102 TWIP_TO_MM100( rCrop
.GetBottom() ));
1104 const SwRotationGrf
& rRotation
= rSet
.GetRotationGrf();
1105 rGA
.SetRotation( rRotation
.GetValue() );
1107 rGA
.SetLuminance( rSet
.GetLuminanceGrf().GetValue() );
1108 rGA
.SetContrast( rSet
.GetContrastGrf().GetValue() );
1109 rGA
.SetChannelR( rSet
.GetChannelRGrf().GetValue() );
1110 rGA
.SetChannelG( rSet
.GetChannelGGrf().GetValue() );
1111 rGA
.SetChannelB( rSet
.GetChannelBGrf().GetValue() );
1112 rGA
.SetGamma( rSet
.GetGammaGrf().GetValue() );
1113 rGA
.SetInvert( rSet
.GetInvertGrf().GetValue() );
1115 const sal_uInt16 nTrans
= rSet
.GetTransparencyGrf().GetValue();
1116 rGA
.SetTransparency( (BYTE
) FRound(
1117 Min( nTrans
, (USHORT
) 100 ) * 2.55 ) );
1122 BOOL
SwGrfNode::IsTransparent() const
1124 BOOL bRet
= aGrfObj
.IsTransparent();
1125 if( !bRet
) // ask the attribut
1126 bRet
= 0 != GetSwAttrSet().GetTransparencyGrf().GetValue();
1132 BOOL
SwGrfNode::IsSelected() const
1135 const SwEditShell
* pESh
= GetDoc()->GetEditShell();
1138 const SwNode
* pN
= this;
1139 const ViewShell
* pV
= pESh
;
1141 if( pV
->ISA( SwEditShell
) && pN
== &((SwCrsrShell
*)pV
)
1142 ->GetCrsr()->GetPoint()->nNode
.GetNode() )
1148 while( pESh
!= ( pV
= (ViewShell
*)pV
->GetNext() ));
1153 // --> OD 2006-12-22 #i73788#
1154 boost::weak_ptr
< SwAsyncRetrieveInputStreamThreadConsumer
> SwGrfNode::GetThreadConsumer()
1156 return mpThreadConsumer
;
1159 void SwGrfNode::TriggerAsyncRetrieveInputStream()
1161 if ( !IsLinkedFile() )
1164 "<SwGrfNode::TriggerAsyncLoad()> - Method is misused. Method call is only valid for graphic nodes, which refer a linked graphic file" );
1168 if ( mpThreadConsumer
.get() == 0 )
1170 mpThreadConsumer
.reset( new SwAsyncRetrieveInputStreamThreadConsumer( *this ) );
1173 refLink
->GetLinkManager()->GetDisplayNames( refLink
, 0, &sGrfNm
, 0, 0 );
1175 mpThreadConsumer
->CreateThread( sGrfNm
);
1179 bool SwGrfNode::IsLinkedInputStreamReady() const
1181 return mbLinkedInputStreamReady
;
1184 void SwGrfNode::ApplyInputStream(
1185 com::sun::star::uno::Reference
<com::sun::star::io::XInputStream
> xInputStream
,
1186 const sal_Bool bIsStreamReadOnly
)
1188 if ( IsLinkedFile() )
1190 if ( xInputStream
.is() )
1192 mxInputStream
= xInputStream
;
1193 mbIsStreamReadOnly
= bIsStreamReadOnly
;
1194 mbLinkedInputStreamReady
= true;
1195 SwMsgPoolItem
aMsgHint( RES_LINKED_GRAPHIC_STREAM_ARRIVED
);
1196 Modify( &aMsgHint
, &aMsgHint
);
1201 void SwGrfNode::UpdateLinkWithInputStream()
1203 if ( IsLinkedFile() )
1205 GetLink()->setStreamToLoadFrom( mxInputStream
, mbIsStreamReadOnly
);
1206 GetLink()->Update();
1207 SwMsgPoolItem
aMsgHint( RES_GRAPHIC_ARRIVED
);
1208 Modify( &aMsgHint
, &aMsgHint
);
1210 // --> OD 2008-06-18 #i88291#
1211 mxInputStream
.clear();
1212 GetLink()->clearStreamToLoadFrom();
1214 mbLinkedInputStreamReady
= false;
1215 mpThreadConsumer
.reset();
1220 // --> OD 2008-07-21 #i90395#
1221 bool SwGrfNode::IsAsyncRetrieveInputStreamPossible() const
1225 if ( IsLinkedFile() )
1228 refLink
->GetLinkManager()->GetDisplayNames( refLink
, 0, &sGrfNm
, 0, 0 );
1229 String
sProtocol( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.pkg:" ) );
1230 if ( sGrfNm
.CompareTo( sProtocol
, sProtocol
.Len() ) != 0 )