update dev300-m58
[ooovba.git] / sw / source / core / graphic / ndgrf.cxx
blob242469f0ca59819b08a8207e5496d4f3ef6dc063
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 $
10 * $Revision: 1.48 $
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>
39 #endif
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>
48 #include <fmturl.hxx>
49 #include <frmfmt.hxx>
50 #include <doc.hxx>
51 #include <frmatr.hxx>
52 #include <grfatr.hxx>
53 #include <swtypes.hxx>
54 #include <ndgrf.hxx>
55 #include <fmtcol.hxx>
56 #include <hints.hxx>
57 #include <swbaslnk.hxx>
58 #include <pagefrm.hxx>
59 #include <editsh.hxx>
60 #include <pam.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>
70 // <--
72 using namespace com::sun::star;
74 // --------------------
75 // SwGrfNode
76 // --------------------
77 SwGrfNode::SwGrfNode(
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 )
87 // <--
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 )
104 // <--
106 aGrfObj = rGrfObj;
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 )
127 // <--
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 );
139 if( IsLinkedFile() )
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,
154 BOOL bNewGrf )
156 BOOL bReadGrf = FALSE, bSetTwipSize = TRUE;
158 ASSERT( pGraphic || pGrfObj || rGrfName.Len(),
159 "GraphicNode without a name, Graphic or GraphicObject" );
161 // ReadRead mit Namen
162 if( refLink.Is() )
164 ASSERT( !bInSwapIn, "ReRead: stehe noch im SwapIn" );
166 if( rGrfName.Len() )
168 // Besonderheit: steht im FltNamen DDE, handelt es sich um eine
169 // DDE-gelinkte Grafik
170 String sCmd( rGrfName );
171 if( rFltName.Len() )
173 USHORT nNewType;
174 if( rFltName.EqualsAscii( "DDE" ))
175 nNewType = OBJECT_CLIENT_DDE;
176 else
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 );
194 refLink.Clear();
197 if( pGraphic )
199 aGrfObj.SetGraphic( *pGraphic, rGrfName );
200 bReadGrf = TRUE;
202 else if( pGrfObj )
204 aGrfObj = *pGrfObj;
205 if( pGrfObj->HasUserData() && pGrfObj->IsSwappedOut() )
206 aGrfObj.SetSwapState();
207 aGrfObj.SetLink( rGrfName );
208 bReadGrf = TRUE;
210 else
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 );
218 if( refLink.Is() )
220 if( GetFrm() )
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.
227 // else {
228 else if ( bNewGrf )
229 // <--
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() )
242 DelStreamName();
244 aGrfObj.SetGraphic( *pGraphic );
245 bReadGrf = TRUE;
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() )
251 DelStreamName();
253 aGrfObj = *pGrfObj;
254 if( pGrfObj->HasUserData() && pGrfObj->IsSwappedOut() )
255 aGrfObj.SetSwapState();
256 bReadGrf = TRUE;
258 // Import einer Grafik:
259 // Ist die Grafik bereits geladen?
260 else if( !bNewGrf && GRAPHIC_NONE != aGrfObj.GetType() )
261 return TRUE;
263 else
265 if( HasStreamName() )
266 DelStreamName();
268 // einen neuen Grafik-Link anlegen
269 InsertLink( rGrfName, rFltName );
271 if( GetNodes().IsDocNodes() )
273 if( pGraphic )
275 aGrfObj.SetGraphic( *pGraphic, rGrfName );
276 bReadGrf = TRUE;
277 // Verbindung herstellen ohne ein Update; Grafik haben wir!
278 ((SwBaseLink*)&refLink)->Connect();
280 else if( pGrfObj )
282 aGrfObj = *pGrfObj;
283 aGrfObj.SetLink( rGrfName );
284 bReadGrf = TRUE;
285 // Verbindung herstellen ohne ein Update; Grafik haben wir!
286 ((SwBaseLink*)&refLink)->Connect();
288 else
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();
299 if ( bNewGrf )
301 ((SwBaseLink*)&refLink)->SwapIn();
303 // <--
308 // Bug 39281: Size nicht sofort loeschen - Events auf ImageMaps
309 // sollten nicht beim Austauschen nicht ins "leere greifen"
310 if( bSetTwipSize )
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 );
320 return bReadGrf;
324 SwGrfNode::~SwGrfNode()
326 // --> OD 2007-03-30 #i73788#
327 mpThreadConsumer.reset();
328 // <--
330 SwDoc* pDoc = GetDoc();
331 if( refLink.Is() )
333 ASSERT( !bInSwapIn, "DTOR: stehe noch im SwapIn" );
334 pDoc->GetLinkManager().Remove( refLink );
335 refLink->Disconnect();
337 else
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() )
349 // DelStreamName();
350 // <--
352 //#39289# Die Frames muessen hier bereits geloescht weil der DTor der
353 //Frms die Grafik noch fuer StopAnimation braucht.
354 if( GetDepends() )
355 DelFrms();
359 SwCntntNode *SwGrfNode::SplitCntntNode( const SwPosition & )
361 return this;
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,
371 BOOL bDelayed )
373 ASSERT( pGrfColl, "MakeGrfNode: Formatpointer ist 0." );
374 SwGrfNode *pNode;
375 // Delayed erzeugen nur aus dem SW/G-Reader
376 if( bDelayed )
377 pNode = new SwGrfNode( rWhere, rGrfName,
378 rFltName, pGrfColl, pAutoAttr );
379 else
380 pNode = new SwGrfNode( rWhere, rGrfName,
381 rFltName, pGraphic, pGrfColl, pAutoAttr );
382 return pNode;
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
397 return nGrfSize;
402 BOOL SwGrfNode::ImportGraphic( SvStream& rStrm )
404 Graphic aGraphic;
405 if( !GetGrfFilter()->ImportGraphic( aGraphic, String(), rStrm ) )
407 const String aUserData( aGrfObj.GetUserData() );
409 aGrfObj.SetGraphic( aGraphic );
410 aGrfObj.SetUserData( aUserData );
411 return TRUE;
414 return FALSE;
417 // Returnwert:
418 // -1 : ReRead erfolgreich
419 // 0 : nicht geladen
420 // 1 : Einlesen erfolgreich
422 short SwGrfNode::SwapIn( BOOL bWaitForData )
424 if( bInSwapIn ) // nicht rekuriv!!
425 return !aGrfObj.IsSwappedOut();
427 short nRet = 0;
428 bInSwapIn = TRUE;
429 SwBaseLink* pLink = (SwBaseLink*)(::sfx2::SvBaseLink*) refLink;
431 if( pLink )
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 ) )
439 nRet = -1;
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;
453 else
454 nRet = 1;
456 else if( aGrfObj.IsSwappedOut() )
458 // Die Grafik ist im Storage oder im TempFile drin
459 if( !HasStreamName() )
460 nRet = (short)aGrfObj.SwapIn();
461 else
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 );
475 if ( pStrm )
477 if ( ImportGraphic( *pStrm ) )
478 nRet = 1;
479 delete pStrm;
481 // <--
483 catch ( uno::Exception& )
485 // --> OD 2005-04-25 #i48434#
486 ASSERT( false, "<SwGrfNode::SwapIn(..)> - unhandled exception!" );
487 // <--
489 // <--
492 if( 1 == nRet )
494 SwMsgPoolItem aMsg( RES_GRAPHIC_SWAPIN );
495 Modify( &aMsg, &aMsg );
498 else
499 nRet = 1;
500 DBG_ASSERTWARNING( nRet, "Grafik kann nicht eingeswapt werden" );
502 if( nRet )
504 if( !nGrfSize.Width() && !nGrfSize.Height() )
505 SetTwipSize( ::GetGraphicSizeTwip( aGrfObj.GetGraphic(), 0 ) );
507 bInSwapIn = FALSE;
508 return nRet;
512 short SwGrfNode::SwapOut()
514 if( aGrfObj.GetType() != GRAPHIC_DEFAULT &&
515 aGrfObj.GetType() != GRAPHIC_NONE &&
516 !aGrfObj.IsSwappedOut() && !bInSwapIn )
518 if( !refLink.Is() )
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() )
526 return 0;
528 // Geschriebene Grafiken oder Links werden jetzt weggeschmissen
529 return (short) aGrfObj.SwapOut( NULL );
531 return 1;
535 BOOL SwGrfNode::GetFileFilterNms( String* pFileNm, String* pFilterNm ) const
537 BOOL bRet = FALSE;
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;
552 *pFileNm += sItem;
553 pFilterNm->AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDE" ));
554 bRet = TRUE;
558 return bRet;
562 // Eine Grafik Undo-faehig machen. Falls sie sich bereits in
563 // einem Storage befindet, muss sie geladen werden.
565 BOOL SwGrfNode::SavePersistentData()
567 if( refLink.Is() )
569 ASSERT( !bInSwapIn, "SavePersistentData: stehe noch im SwapIn" );
570 GetDoc()->GetLinkManager().Remove( refLink );
571 return TRUE;
574 // Erst mal reinswappen, falls sie im Storage ist
575 if( HasStreamName() && !SwapIn() )
576 return FALSE;
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() )
589 // DelStreamName();
590 // <--
592 // Und in TempFile rausswappen
593 return (BOOL) SwapOut();
597 BOOL SwGrfNode::RestorePersistentData()
599 if( refLink.Is() )
601 IDocumentLinksAdministration* pIDLA = getIDocumentLinksAdministration();
602 refLink->SetVisible( pIDLA->IsVisibleLinks() );
603 pIDLA->GetLinkManager().InsertDDELink( refLink );
604 if( getIDocumentLayoutAccess()->GetRootFrm() )
605 refLink->Update();
607 return TRUE;
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" ))
621 USHORT nTmp = 0;
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 );
629 else
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()
646 if( refLink.Is() )
648 // erst die Grafik reinswappen!
649 // if( aGraphic.IsSwapOut() || !refLink->IsSynchron() )
651 bInSwapIn = TRUE;
652 SwBaseLink* pLink = (SwBaseLink*)(::sfx2::SvBaseLink*) refLink;
653 //TODO pLink->setInputStream(getInputStream());
654 pLink->SwapIn( TRUE, TRUE );
655 bInSwapIn = FALSE;
657 getIDocumentLinksAdministration()->GetLinkManager().Remove( refLink );
658 refLink.Clear();
659 aGrfObj.SetLink();
664 void SwGrfNode::SetTwipSize( const Size& rSz )
666 nGrfSize = rSz;
667 if( IsScaleImageMap() && nGrfSize.Width() && nGrfSize.Height() )
669 // Image-Map an Grafik-Groesse anpassen
670 ScaleImageMap();
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() )
689 return;
691 // dann die Image-Map skalieren
692 SwFrmFmt* pFmt = GetFlyFmt();
694 if( !pFmt )
695 return;
697 SwFmtURL aURL( pFmt->GetURL() );
698 if ( !aURL.GetMap() )
699 return;
701 BOOL bScale = FALSE;
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 );
720 bScale = TRUE;
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 );
735 bScale = TRUE;
739 if( bScale )
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();
753 if( xDocStg.is() )
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 );
764 if ( xTrans.is() )
765 xTrans->commit();
767 catch ( uno::Exception& )
769 // --> OD 2005-04-25 #i48434#
770 ASSERT( false, "<SwGrfNode::DelStreamName()> - unhandled exception!" );
771 // <--
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() )
793 if( refStor.is() )
794 return refStor->openStorageElement( aStgName, embed::ElementModes::READ );
797 return refStor;
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.
810 @author OD
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;
843 // <--
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 );
852 else
854 ASSERT( false, "<SwGrfNode::_GetStreamForEmbedGrf(..)> - embedded graphic file not found!" );
858 return pStrm;
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
867 rStorName.Erase();
868 rStrmName.Erase();
870 String aUserData( aGrfObj.GetUserData() );
871 if( !aUserData.Len() )
872 return;
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() ) )
881 // 6.0 (XML) Package
882 xub_StrLen nPos = aUserData.Search( '/' );
883 if( STRING_NOTFOUND == nPos )
885 rStrmName = aUserData.Copy( aProt.Len() );
887 else
889 xub_StrLen nPathStart = aProt.Len();
890 if( 0 == aUserData.CompareToAscii( "./", 2 ) )
891 nPathStart += 2;
892 rStorName = aUserData.Copy( nPathStart, nPos-nPathStart );
893 rStrmName = aUserData.Copy( nPos+1 );
896 else
898 ASSERT( false,
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" );
904 // <--
906 SwCntntNode* SwGrfNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
908 // kopiere die Formate in das andere Dokument:
909 SwGrfFmtColl* pColl = pDoc->CopyGrfColl( *GetGrfColl() );
911 Graphic aTmpGrf;
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 );
926 if ( pStrm )
928 GetGrfFilter()->ImportGraphic( aTmpGrf, String(), *pStrm );
929 delete pStrm;
931 // <--
933 catch ( uno::Exception& )
935 // --> OD 2005-04-25 #i48434#
936 ASSERT( false, "<SwGrfNode::MakeCopy(..)> - unhandled exception!" );
937 // <--
939 // <--
941 else
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;
950 if( IsLinkedFile() )
951 rMgr.GetDisplayNames( refLink, 0, &sFile, 0, &sFilter );
952 else if( IsLinkedDDE() )
954 String sTmp1, sTmp2;
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,
961 &aTmpGrf, pColl,
962 (SwAttrSet*)GetpSwAttrSet() );
963 pGrfNd->SetTitle( GetTitle() );
964 pGrfNd->SetDescription( GetDescription() );
965 pGrfNd->SetContour( HasContour(), HasAutomaticContour() );
966 return pGrfNd;
969 IMPL_LINK( SwGrfNode, SwapGraphic, GraphicObject*, pGrfObj )
971 SvStream* pRet;
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
983 if( !bInSwapIn )
985 BOOL bIsModifyLocked = IsModifyLocked();
986 LockModify();
987 SwapIn( FALSE );
988 if( !bIsModifyLocked )
989 UnlockModify();
991 pRet = GRFMGR_AUTOSWAPSTREAM_NONE;
993 else
994 pRet = GRFMGR_AUTOSWAPSTREAM_LINK;
996 else
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 );
1013 if ( pStrm )
1015 if( pGrfObj->IsInSwapOut() )
1017 pRet = GRFMGR_AUTOSWAPSTREAM_LINK;
1019 else
1021 ImportGraphic( *pStrm );
1022 pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
1024 delete pStrm;
1026 // <--
1028 catch ( uno::Exception& )
1030 // --> OD 2005-04-25 #i48434#
1031 ASSERT( false, "<SwapGraphic> - unhandled exception!" );
1032 // <--
1034 // <--
1038 return (long)pRet;
1042 // alle QuickDraw-Bitmaps eines speziellen Docs loeschen
1043 void DelAllGrfCacheEntries( SwDoc* pDoc )
1045 if( 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();
1050 SwGrfNode* pGrfNd;
1051 String sFileNm;
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;
1083 break;
1084 default: nMirror = BMP_MIRROR_VERT; break;
1087 else
1088 switch( rMirror.GetValue() )
1090 case RES_MIRROR_GRAPH_BOTH: nMirror = BMP_MIRROR_HORZ|BMP_MIRROR_VERT;
1091 break;
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 ) );
1119 return rGA;
1122 BOOL SwGrfNode::IsTransparent() const
1124 BOOL bRet = aGrfObj.IsTransparent();
1125 if( !bRet ) // ask the attribut
1126 bRet = 0 != GetSwAttrSet().GetTransparencyGrf().GetValue();
1128 return bRet;
1132 BOOL SwGrfNode::IsSelected() const
1134 BOOL bRet = FALSE;
1135 const SwEditShell* pESh = GetDoc()->GetEditShell();
1136 if( pESh )
1138 const SwNode* pN = this;
1139 const ViewShell* pV = pESh;
1140 do {
1141 if( pV->ISA( SwEditShell ) && pN == &((SwCrsrShell*)pV)
1142 ->GetCrsr()->GetPoint()->nNode.GetNode() )
1144 bRet = TRUE;
1145 break;
1148 while( pESh != ( pV = (ViewShell*)pV->GetNext() ));
1150 return bRet;
1153 // --> OD 2006-12-22 #i73788#
1154 boost::weak_ptr< SwAsyncRetrieveInputStreamThreadConsumer > SwGrfNode::GetThreadConsumer()
1156 return mpThreadConsumer;
1159 void SwGrfNode::TriggerAsyncRetrieveInputStream()
1161 if ( !IsLinkedFile() )
1163 ASSERT( false,
1164 "<SwGrfNode::TriggerAsyncLoad()> - Method is misused. Method call is only valid for graphic nodes, which refer a linked graphic file" );
1165 return;
1168 if ( mpThreadConsumer.get() == 0 )
1170 mpThreadConsumer.reset( new SwAsyncRetrieveInputStreamThreadConsumer( *this ) );
1172 String sGrfNm;
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();
1213 // <--
1214 mbLinkedInputStreamReady = false;
1215 mpThreadConsumer.reset();
1218 // <--
1220 // --> OD 2008-07-21 #i90395#
1221 bool SwGrfNode::IsAsyncRetrieveInputStreamPossible() const
1223 bool bRet = false;
1225 if ( IsLinkedFile() )
1227 String sGrfNm;
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 )
1232 bRet = true;
1236 return bRet;
1238 // <--