xref: /trunk/main/sw/source/core/graphic/ndgrf.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 #include <hintids.hxx>
31 #include <vcl/salbtype.hxx>             // FRound
32 #include <tools/urlobj.hxx>
33 #include <svl/undo.hxx>
34 #ifndef SVTOOLS_FSTATHELPER_HXX
35 #include <svl/fstathelper.hxx>
36 #endif
37 #include <svtools/imap.hxx>
38 #include <svtools/filter.hxx>
39 #include <sot/storage.hxx>
40 #include <sfx2/linkmgr.hxx>
41 #include <editeng/boxitem.hxx>
42 #include <sot/formats.hxx>
43 #include <fmtfsize.hxx>
44 #include <fmturl.hxx>
45 #include <frmfmt.hxx>
46 #include <doc.hxx>
47 #include <frmatr.hxx>
48 #include <grfatr.hxx>
49 #include <swtypes.hxx>
50 #include <ndgrf.hxx>
51 #include <fmtcol.hxx>
52 #include <hints.hxx>
53 #include <swbaslnk.hxx>
54 #include <pagefrm.hxx>
55 #include <editsh.hxx>
56 #include <pam.hxx>
57 
58 #include <unotools/ucbstreamhelper.hxx>
59 #include <com/sun/star/embed/ElementModes.hpp>
60 #include <com/sun/star/embed/XTransactedObject.hpp>
61 #include <tools/link.hxx>
62 #include <vcl/svapp.hxx>
63 #include <com/sun/star/io/XSeekable.hpp>
64 // --> OD 2007-03-28 #i73788#
65 #include <retrieveinputstreamconsumer.hxx>
66 // <--
67 
68 using namespace com::sun::star;
69 
70 // --------------------
71 // SwGrfNode
72 // --------------------
73 SwGrfNode::SwGrfNode(
74         const SwNodeIndex & rWhere,
75         const String& rGrfName, const String& rFltName,
76         const Graphic* pGraphic,
77         SwGrfFmtColl *pGrfColl,
78         SwAttrSet* pAutoAttr ) :
79     SwNoTxtNode( rWhere, ND_GRFNODE, pGrfColl, pAutoAttr ),
80     // --> OD 2007-01-23 #i73788#
81     mbLinkedInputStreamReady( false ),
82     mbIsStreamReadOnly( sal_False )
83     // <--
84 {
85     aGrfObj.SetSwapStreamHdl( LINK( this, SwGrfNode, SwapGraphic ) );
86     bInSwapIn = bChgTwipSize = bChgTwipSizeFromPixel = bLoadLowResGrf =
87         bFrameInPaint = bScaleImageMap = sal_False;
88 
89     bGrafikArrived = sal_True;
90     ReRead(rGrfName,rFltName, pGraphic, 0, sal_False);
91 }
92 
93 SwGrfNode::SwGrfNode( const SwNodeIndex & rWhere,
94                         const GraphicObject& rGrfObj,
95                       SwGrfFmtColl *pGrfColl, SwAttrSet* pAutoAttr ) :
96     SwNoTxtNode( rWhere, ND_GRFNODE, pGrfColl, pAutoAttr ),
97     // --> OD 2007-01-23 #i73788#
98     mbLinkedInputStreamReady( false ),
99     mbIsStreamReadOnly( sal_False )
100     // <--
101 {
102     aGrfObj = rGrfObj;
103     aGrfObj.SetSwapStreamHdl( LINK( this, SwGrfNode, SwapGraphic ) );
104     if( rGrfObj.HasUserData() && rGrfObj.IsSwappedOut() )
105         aGrfObj.SetSwapState();
106     bInSwapIn = bChgTwipSize = bChgTwipSizeFromPixel= bLoadLowResGrf =
107         bFrameInPaint = bScaleImageMap = sal_False;
108     bGrafikArrived = sal_True;
109 }
110 
111 // Konstruktor fuer den SW/G-Reader. Dieser ctor wird verwendet,
112 // wenn eine gelinkte Grafik gelesen wird. Sie liest diese NICHT ein.
113 
114 
115 SwGrfNode::SwGrfNode( const SwNodeIndex & rWhere,
116                       const String& rGrfName, const String& rFltName,
117                       SwGrfFmtColl *pGrfColl,
118                       SwAttrSet* pAutoAttr ) :
119     SwNoTxtNode( rWhere, ND_GRFNODE, pGrfColl, pAutoAttr ),
120     // --> OD 2007-01-23 #i73788#
121     mbLinkedInputStreamReady( false ),
122     mbIsStreamReadOnly( sal_False )
123     // <--
124 {
125     aGrfObj.SetSwapStreamHdl( LINK( this, SwGrfNode, SwapGraphic ) );
126 
127     Graphic aGrf; aGrf.SetDefaultType();
128     aGrfObj.SetGraphic( aGrf, rGrfName );
129 
130     bInSwapIn = bChgTwipSize = bChgTwipSizeFromPixel = bLoadLowResGrf =
131         bFrameInPaint = bScaleImageMap = sal_False;
132     bGrafikArrived = sal_True;
133 
134     InsertLink( rGrfName, rFltName );
135     if( IsLinkedFile() )
136     {
137         INetURLObject aUrl( rGrfName );
138         if( INET_PROT_FILE == aUrl.GetProtocol() &&
139             FStatHelper::IsDocument( aUrl.GetMainURL( INetURLObject::NO_DECODE ) ))
140         {
141             // File vorhanden, Verbindung herstellen ohne ein Update
142             ((SwBaseLink*)&refLink)->Connect();
143         }
144     }
145 }
146 
147 sal_Bool SwGrfNode::ReRead(
148     const String& rGrfName, const String& rFltName,
149     const Graphic* pGraphic, const GraphicObject* pGrfObj,
150     sal_Bool bNewGrf )
151 {
152     sal_Bool bReadGrf = sal_False, bSetTwipSize = sal_True;
153 
154     ASSERT( pGraphic || pGrfObj || rGrfName.Len(),
155             "GraphicNode without a name, Graphic or GraphicObject" );
156 
157     // ReadRead mit Namen
158     if( refLink.Is() )
159     {
160         ASSERT( !bInSwapIn, "ReRead: stehe noch im SwapIn" );
161 
162         if( rGrfName.Len() )
163         {
164             // Besonderheit: steht im FltNamen DDE, handelt es sich um eine
165             //                  DDE-gelinkte Grafik
166             String sCmd( rGrfName );
167             if( rFltName.Len() )
168             {
169                 sal_uInt16 nNewType;
170                 if( rFltName.EqualsAscii( "DDE" ))
171                     nNewType = OBJECT_CLIENT_DDE;
172                 else
173                 {
174                     sfx2::MakeLnkName( sCmd, 0, rGrfName, aEmptyStr, &rFltName );
175                     nNewType = OBJECT_CLIENT_GRF;
176                 }
177 
178                 if( nNewType != refLink->GetObjType() )
179                 {
180                     refLink->Disconnect();
181                     ((SwBaseLink*)&refLink)->SetObjType( nNewType );
182                 }
183             }
184 
185             refLink->SetLinkSourceName( sCmd );
186         }
187         else        // kein Name mehr, Link aufheben
188         {
189             GetDoc()->GetLinkManager().Remove( refLink );
190             refLink.Clear();
191         }
192 
193         if( pGraphic )
194         {
195             aGrfObj.SetGraphic( *pGraphic, rGrfName );
196             bReadGrf = sal_True;
197         }
198         else if( pGrfObj )
199         {
200             aGrfObj = *pGrfObj;
201             if( pGrfObj->HasUserData() && pGrfObj->IsSwappedOut() )
202                 aGrfObj.SetSwapState();
203             aGrfObj.SetLink( rGrfName );
204             bReadGrf = sal_True;
205         }
206         else
207         {
208             // MIB 25.02.97: Daten der alten Grafik zuruecksetzen, damit
209             // die korrekte Ersatz-Darstellung erscheint, wenn die
210             // der neue Link nicht geladen werden konnte.
211             Graphic aGrf; aGrf.SetDefaultType();
212             aGrfObj.SetGraphic( aGrf, rGrfName );
213 
214             if( refLink.Is() )
215             {
216                 if( getLayoutFrm( GetDoc()->GetCurrentLayout() ) )
217                 {
218                     SwMsgPoolItem aMsgHint( RES_GRF_REREAD_AND_INCACHE );
219                     ModifyNotification( &aMsgHint, &aMsgHint );
220                 }
221                 // --> OD 2006-11-03 #i59688#
222                 // do not load linked graphic, if it isn't a new linked graphic.
223 //                else {
224                 else if ( bNewGrf )
225                 // <--
226                 {
227                     //TODO refLink->setInputStream(getInputStream());
228                     ((SwBaseLink*)&refLink)->SwapIn();
229                 }
230             }
231             bSetTwipSize = sal_False;
232         }
233     }
234     else if( pGraphic && !rGrfName.Len() )
235     {
236         // MIB 27.02.2001: Old stream must be deleted before the new one is set.
237         if( HasStreamName() )
238             DelStreamName();
239 
240         aGrfObj.SetGraphic( *pGraphic );
241         bReadGrf = sal_True;
242     }
243     else if( pGrfObj && !rGrfName.Len() )
244     {
245         // MIB 27.02.2001: Old stream must be deleted before the new one is set.
246         if( HasStreamName() )
247             DelStreamName();
248 
249         aGrfObj = *pGrfObj;
250         if( pGrfObj->HasUserData() && pGrfObj->IsSwappedOut() )
251             aGrfObj.SetSwapState();
252         bReadGrf = sal_True;
253     }
254         // Import einer Grafik:
255         // Ist die Grafik bereits geladen?
256     else if( !bNewGrf && GRAPHIC_NONE != aGrfObj.GetType() )
257         return sal_True;
258 
259     else
260     {
261         if( HasStreamName() )
262             DelStreamName();
263 
264         // einen neuen Grafik-Link anlegen
265         InsertLink( rGrfName, rFltName );
266 
267         if( GetNodes().IsDocNodes() )
268         {
269             if( pGraphic )
270             {
271                 aGrfObj.SetGraphic( *pGraphic, rGrfName );
272                 bReadGrf = sal_True;
273                 // Verbindung herstellen ohne ein Update; Grafik haben wir!
274                 ((SwBaseLink*)&refLink)->Connect();
275             }
276             else if( pGrfObj )
277             {
278                 aGrfObj = *pGrfObj;
279                 aGrfObj.SetLink( rGrfName );
280                 bReadGrf = sal_True;
281                 // Verbindung herstellen ohne ein Update; Grafik haben wir!
282                 ((SwBaseLink*)&refLink)->Connect();
283             }
284             else
285             {
286                 // MIB 25.02.97: Daten der alten Grafik zuruecksetzen, damit
287                 // die korrekte Ersatz-Darstellung erscheint, wenn die
288                 // der neue Kink nicht geladen werden konnte.
289                 Graphic aGrf; aGrf.SetDefaultType();
290                 aGrfObj.SetGraphic( aGrf, rGrfName );
291                 // --> OD 2006-11-03 #i59688#
292                 // do not load linked graphic, if it isn't a new linked graphic.
293 //                //TODO refLink->setInputStream(getInputStream());
294 //                ((SwBaseLink*)&refLink)->SwapIn();
295                 if ( bNewGrf )
296                 {
297                     ((SwBaseLink*)&refLink)->SwapIn();
298                 }
299                 // <--
300             }
301         }
302     }
303 
304     // Bug 39281: Size nicht sofort loeschen - Events auf ImageMaps
305     //            sollten nicht beim Austauschen nicht ins "leere greifen"
306     if( bSetTwipSize )
307         SetTwipSize( ::GetGraphicSizeTwip( aGrfObj.GetGraphic(), 0 ) );
308 
309     // erzeuge noch einen Update auf die Frames
310     if( bReadGrf && bNewGrf )
311     {
312         SwMsgPoolItem aMsgHint( RES_UPDATE_ATTR );
313         ModifyNotification( &aMsgHint, &aMsgHint );
314     }
315 
316     return bReadGrf;
317 }
318 
319 
320 SwGrfNode::~SwGrfNode()
321 {
322     // --> OD 2007-03-30 #i73788#
323     mpThreadConsumer.reset();
324     // <--
325 
326     SwDoc* pDoc = GetDoc();
327     if( refLink.Is() )
328     {
329         ASSERT( !bInSwapIn, "DTOR: stehe noch im SwapIn" );
330         pDoc->GetLinkManager().Remove( refLink );
331         refLink->Disconnect();
332     }
333     else
334     {
335         // --> OD 2005-01-19 #i40014# - A graphic node, which are in linked
336         // section, whose link is another section is the document, doesn't
337         // have to remove the stream from the storage.
338         // Because it's hard to detect this case here and it would only fix
339         // one problem with shared graphic files - there are also problems,
340         // a certain graphic file is referenced by two independent graphic nodes,
341         // brush item or drawing objects, the stream isn't no longer removed here.
342         // To do this stuff correct, a reference counting on shared streams
343         // inside one document have to be implemented.
344 //        if( !pDoc->IsInDtor() && HasStreamName() )
345 //          DelStreamName();
346         // <--
347     }
348     //#39289# Die Frames muessen hier bereits geloescht weil der DTor der
349     //Frms die Grafik noch fuer StopAnimation braucht.
350     if( GetDepends() )
351         DelFrms();
352 }
353 
354 
355 SwCntntNode *SwGrfNode::SplitCntntNode( const SwPosition & )
356 {
357     return this;
358 }
359 
360 
361 SwGrfNode * SwNodes::MakeGrfNode( const SwNodeIndex & rWhere,
362                                 const String& rGrfName,
363                                 const String& rFltName,
364                                 const Graphic* pGraphic,
365                                 SwGrfFmtColl* pGrfColl,
366                                 SwAttrSet* pAutoAttr,
367                                 sal_Bool bDelayed )
368 {
369     ASSERT( pGrfColl, "MakeGrfNode: Formatpointer ist 0." );
370     SwGrfNode *pNode;
371     // Delayed erzeugen nur aus dem SW/G-Reader
372     if( bDelayed )
373         pNode = new SwGrfNode( rWhere, rGrfName,
374                                 rFltName, pGrfColl, pAutoAttr );
375     else
376         pNode = new SwGrfNode( rWhere, rGrfName,
377                                 rFltName, pGraphic, pGrfColl, pAutoAttr );
378     return pNode;
379 }
380 
381 SwGrfNode * SwNodes::MakeGrfNode( const SwNodeIndex & rWhere,
382                                 const GraphicObject& rGrfObj,
383                                 SwGrfFmtColl* pGrfColl,
384                                 SwAttrSet* pAutoAttr )
385 {
386     ASSERT( pGrfColl, "MakeGrfNode: Formatpointer ist 0." );
387     return new SwGrfNode( rWhere, rGrfObj, pGrfColl, pAutoAttr );
388 }
389 
390 
391 Size SwGrfNode::GetTwipSize() const
392 {
393     return nGrfSize;
394 }
395 
396 
397 
398 sal_Bool SwGrfNode::ImportGraphic( SvStream& rStrm )
399 {
400     Graphic aGraphic;
401     if( !GraphicFilter::GetGraphicFilter()->ImportGraphic( aGraphic, String(), rStrm ) )
402     {
403         const String aUserData( aGrfObj.GetUserData() );
404 
405         aGrfObj.SetGraphic( aGraphic );
406         aGrfObj.SetUserData( aUserData );
407         return sal_True;
408     }
409 
410     return sal_False;
411 }
412 
413 // Returnwert:
414 // -1 : ReRead erfolgreich
415 //  0 : nicht geladen
416 //  1 : Einlesen erfolgreich
417 
418 short SwGrfNode::SwapIn( sal_Bool bWaitForData )
419 {
420     if( bInSwapIn )                 // nicht rekuriv!!
421         return !aGrfObj.IsSwappedOut();
422 
423     short nRet = 0;
424     bInSwapIn = sal_True;
425     SwBaseLink* pLink = (SwBaseLink*)(::sfx2::SvBaseLink*) refLink;
426 
427     if( pLink )
428     {
429         if( GRAPHIC_NONE == aGrfObj.GetType() ||
430             GRAPHIC_DEFAULT == aGrfObj.GetType() )
431         {
432             // noch nicht geladener Link
433             //TODO pLink->setInputStream(getInputStream());
434             if( pLink->SwapIn( bWaitForData ) )
435                 nRet = -1;
436             else if( GRAPHIC_DEFAULT == aGrfObj.GetType() )
437             {
438                 // keine default Bitmap mehr, also neu Painten!
439                 aGrfObj.SetGraphic( Graphic() );
440                 SwMsgPoolItem aMsgHint( RES_GRAPHIC_PIECE_ARRIVED );
441                 ModifyNotification( &aMsgHint, &aMsgHint );
442             }
443         }
444         else if( aGrfObj.IsSwappedOut() ) {
445             // nachzuladender Link
446             //TODO pLink->setInputStream(getInputStream());
447             nRet = pLink->SwapIn( bWaitForData ) ? 1 : 0;
448         }
449         else
450             nRet = 1;
451     }
452     else if( aGrfObj.IsSwappedOut() )
453     {
454         // Die Grafik ist im Storage oder im TempFile drin
455         if( !HasStreamName() )
456             nRet = (short)aGrfObj.SwapIn();
457         else
458         {
459 
460             // --> OD 2005-05-04 #i48434# - usage of new method <_GetStreamForEmbedGrf(..)>
461             try
462             {
463                 // --> OD, MAV 2005-08-17 #i53025# - needed correction of new
464                 // method <_GetStreamForEmbedGrf(..)>
465 //                bool bGraphic(false);
466 //                SvStream* pStrm = _GetStreamForEmbedGrf( bGraphic );
467                 String aStrmName, aPicStgName;
468                 _GetStreamStorageNames( aStrmName, aPicStgName );
469                 uno::Reference < embed::XStorage > refPics = _GetDocSubstorageOrRoot( aPicStgName );
470                 SvStream* pStrm = _GetStreamForEmbedGrf( refPics, aStrmName );
471                 if ( pStrm )
472                 {
473                     if ( ImportGraphic( *pStrm ) )
474                         nRet = 1;
475                     delete pStrm;
476                 }
477                 // <--
478             }
479             catch ( uno::Exception& )
480             {
481                 // --> OD 2005-04-25 #i48434#
482                 ASSERT( false, "<SwGrfNode::SwapIn(..)> - unhandled exception!" );
483                 // <--
484             }
485             // <--
486         }
487 
488         if( 1 == nRet )
489         {
490             SwMsgPoolItem aMsg( RES_GRAPHIC_SWAPIN );
491             ModifyNotification( &aMsg, &aMsg );
492         }
493     }
494     else
495         nRet = 1;
496     DBG_ASSERTWARNING( nRet, "Grafik kann nicht eingeswapt werden" );
497 
498     if( nRet )
499     {
500         if( !nGrfSize.Width() && !nGrfSize.Height() )
501             SetTwipSize( ::GetGraphicSizeTwip( aGrfObj.GetGraphic(), 0 ) );
502     }
503     bInSwapIn = sal_False;
504     return nRet;
505 }
506 
507 
508 short SwGrfNode::SwapOut()
509 {
510     if( aGrfObj.GetType() != GRAPHIC_DEFAULT &&
511         aGrfObj.GetType() != GRAPHIC_NONE &&
512         !aGrfObj.IsSwappedOut() && !bInSwapIn )
513     {
514         if( !refLink.Is() )
515         {
516             // Das Swapping brauchen wir nur fuer Embedded Pictures
517             // Die Grafik wird in eine TempFile geschrieben, wenn
518             // sie frisch eingefuegt war, d.h. wenn es noch keinen
519             // Streamnamen im Storage gibt.
520             if( !HasStreamName() )
521                 if( !aGrfObj.SwapOut() )
522                     return 0;
523         }
524         // Geschriebene Grafiken oder Links werden jetzt weggeschmissen
525         return (short) aGrfObj.SwapOut( NULL );
526     }
527     return 1;
528 }
529 
530 
531 sal_Bool SwGrfNode::GetFileFilterNms( String* pFileNm, String* pFilterNm ) const
532 {
533     sal_Bool bRet = sal_False;
534     if( refLink.Is() && refLink->GetLinkManager() )
535     {
536         sal_uInt16 nType = refLink->GetObjType();
537         if( OBJECT_CLIENT_GRF == nType )
538             bRet = refLink->GetLinkManager()->GetDisplayNames(
539                     refLink, 0, pFileNm, 0, pFilterNm );
540         else if( OBJECT_CLIENT_DDE == nType && pFileNm && pFilterNm )
541         {
542             String sApp, sTopic, sItem;
543             if( refLink->GetLinkManager()->GetDisplayNames(
544                     refLink, &sApp, &sTopic, &sItem ) )
545             {
546                 ( *pFileNm = sApp ) += sfx2::cTokenSeperator;
547                 ( *pFileNm += sTopic ) += sfx2::cTokenSeperator;
548                 *pFileNm += sItem;
549                 pFilterNm->AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDE" ));
550                 bRet = sal_True;
551             }
552         }
553     }
554     return bRet;
555 }
556 
557 
558 // Eine Grafik Undo-faehig machen. Falls sie sich bereits in
559 // einem Storage befindet, muss sie geladen werden.
560 
561 sal_Bool SwGrfNode::SavePersistentData()
562 {
563     if( refLink.Is() )
564     {
565         ASSERT( !bInSwapIn, "SavePersistentData: stehe noch im SwapIn" );
566         GetDoc()->GetLinkManager().Remove( refLink );
567         return sal_True;
568     }
569 
570     // Erst mal reinswappen, falls sie im Storage ist
571     if( HasStreamName() && !SwapIn() )
572         return sal_False;
573 
574     // --> OD 2005-04-19 #i44367#
575     // Do not delete graphic file in storage, because the graphic file could
576     // be referenced by other graphic nodes.
577     // Because it's hard to detect this case here and it would only fix
578     // one problem with shared graphic files - there are also problems,
579     // a certain graphic file is referenced by two independent graphic nodes,
580     // brush item or drawing objects, the stream isn't no longer removed here.
581     // To do this stuff correct, a reference counting on shared streams
582     // inside one document have to be implemented.
583     // Important note: see also fix for #i40014#
584 //    if( HasStreamName() )
585 //        DelStreamName();
586     // <--
587 
588     // Und in TempFile rausswappen
589     return (sal_Bool) SwapOut();
590 }
591 
592 
593 sal_Bool SwGrfNode::RestorePersistentData()
594 {
595     if( refLink.Is() )
596     {
597         IDocumentLinksAdministration* pIDLA = getIDocumentLinksAdministration();
598         refLink->SetVisible( pIDLA->IsVisibleLinks() );
599         pIDLA->GetLinkManager().InsertDDELink( refLink );
600         if( getIDocumentLayoutAccess()->GetCurrentLayout() )    //swmod 080218
601             refLink->Update();
602     }
603     return sal_True;
604 }
605 
606 
607 void SwGrfNode::InsertLink( const String& rGrfName, const String& rFltName )
608 {
609     refLink = new SwBaseLink( sfx2::LINKUPDATE_ONCALL, FORMAT_GDIMETAFILE, this );
610 
611     IDocumentLinksAdministration* pIDLA = getIDocumentLinksAdministration();
612     if( GetNodes().IsDocNodes() )
613     {
614         refLink->SetVisible( pIDLA->IsVisibleLinks() );
615         if( rFltName.EqualsAscii( "DDE" ))
616         {
617             sal_uInt16 nTmp = 0;
618             String sApp, sTopic, sItem;
619             sApp = rGrfName.GetToken( 0, sfx2::cTokenSeperator, nTmp );
620             sTopic = rGrfName.GetToken( 0, sfx2::cTokenSeperator, nTmp );
621             sItem = rGrfName.Copy( nTmp );
622             pIDLA->GetLinkManager().InsertDDELink( refLink,
623                                             sApp, sTopic, sItem );
624         }
625         else
626         {
627             sal_Bool bSync = rFltName.EqualsAscii( "SYNCHRON" );
628             refLink->SetSynchron( bSync );
629             refLink->SetContentType( SOT_FORMATSTR_ID_SVXB );
630 
631             pIDLA->GetLinkManager().InsertFileLink( *refLink,
632                                             OBJECT_CLIENT_GRF, rGrfName,
633                                 (!bSync && rFltName.Len() ? &rFltName : 0) );
634         }
635     }
636     aGrfObj.SetLink( rGrfName );
637 }
638 
639 
640 void SwGrfNode::ReleaseLink()
641 {
642     if( refLink.Is() )
643     {
644         // erst die Grafik reinswappen!
645 //      if( aGraphic.IsSwapOut() || !refLink->IsSynchron() )
646         {
647             bInSwapIn = sal_True;
648             SwBaseLink* pLink = (SwBaseLink*)(::sfx2::SvBaseLink*) refLink;
649             //TODO pLink->setInputStream(getInputStream());
650             pLink->SwapIn( sal_True, sal_True );
651             bInSwapIn = sal_False;
652         }
653         getIDocumentLinksAdministration()->GetLinkManager().Remove( refLink );
654         refLink.Clear();
655         aGrfObj.SetLink();
656     }
657 }
658 
659 
660 void SwGrfNode::SetTwipSize( const Size& rSz )
661 {
662     nGrfSize = rSz;
663     if( IsScaleImageMap() && nGrfSize.Width() && nGrfSize.Height() )
664     {
665         // Image-Map an Grafik-Groesse anpassen
666         ScaleImageMap();
667 
668         // Image-Map nicht noch einmal skalieren
669         SetScaleImageMap( sal_False );
670     }
671 }
672 
673 void SwGrfNode::ScaleImageMap()
674 {
675     if( !nGrfSize.Width() || !nGrfSize.Height() )
676         return;
677 
678     // dann die Image-Map skalieren
679     SwFrmFmt* pFmt = GetFlyFmt();
680 
681     if( !pFmt )
682         return;
683 
684     SwFmtURL aURL( pFmt->GetURL() );
685     if ( !aURL.GetMap() )
686         return;
687 
688     sal_Bool bScale = sal_False;
689     Fraction aScaleX( 1, 1 );
690     Fraction aScaleY( 1, 1 );
691 
692     const SwFmtFrmSize& rFrmSize = pFmt->GetFrmSize();
693     const SvxBoxItem& rBox = pFmt->GetBox();
694 
695     if( !rFrmSize.GetWidthPercent() )
696     {
697         SwTwips nWidth = rFrmSize.GetWidth();
698 
699         nWidth -= rBox.CalcLineSpace(BOX_LINE_LEFT) +
700                   rBox.CalcLineSpace(BOX_LINE_RIGHT);
701 
702         ASSERT( nWidth>0, "Gibt es 0 twip breite Grafiken!?" );
703 
704         if( nGrfSize.Width() != nWidth )
705         {
706             aScaleX = Fraction( nGrfSize.Width(), nWidth );
707             bScale = sal_True;
708         }
709     }
710     if( !rFrmSize.GetHeightPercent() )
711     {
712         SwTwips nHeight = rFrmSize.GetHeight();
713 
714         nHeight -= rBox.CalcLineSpace(BOX_LINE_TOP) +
715                    rBox.CalcLineSpace(BOX_LINE_BOTTOM);
716 
717         ASSERT( nHeight>0, "Gibt es 0 twip hohe Grafiken!?" );
718 
719         if( nGrfSize.Height() != nHeight )
720         {
721             aScaleY = Fraction( nGrfSize.Height(), nHeight );
722             bScale = sal_True;
723         }
724     }
725 
726     if( bScale )
727     {
728         aURL.GetMap()->Scale( aScaleX, aScaleY );
729         pFmt->SetFmtAttr( aURL );
730     }
731 }
732 
733 
734 void SwGrfNode::DelStreamName()
735 {
736     if( HasStreamName() )
737     {
738         // Dann die Grafik im Storage loeschen
739         uno::Reference < embed::XStorage > xDocStg = GetDoc()->GetDocStorage();
740         if( xDocStg.is() )
741         {
742             try
743             {
744                 String aPicStgName, aStrmName;
745                 _GetStreamStorageNames( aStrmName, aPicStgName );
746                 uno::Reference < embed::XStorage > refPics = xDocStg;
747                 if ( aPicStgName.Len() )
748                     refPics = xDocStg->openStorageElement( aPicStgName, embed::ElementModes::READWRITE );
749                 refPics->removeElement( aStrmName );
750                 uno::Reference < embed::XTransactedObject > xTrans( refPics, uno::UNO_QUERY );
751                 if ( xTrans.is() )
752                     xTrans->commit();
753             }
754             catch ( uno::Exception& )
755             {
756                 // --> OD 2005-04-25 #i48434#
757                 ASSERT( false, "<SwGrfNode::DelStreamName()> - unhandled exception!" );
758                 // <--
759             }
760         }
761 
762         aGrfObj.SetUserData();
763     }
764 }
765 
766 /** helper method to get a substorage of the document storage for readonly access.
767 
768     OD, MAV 2005-08-17 #i53025#
769     A substorage with the specified name will be opened readonly. If the provided
770     name is empty the root storage will be returned.
771 */
772 uno::Reference< embed::XStorage > SwGrfNode::_GetDocSubstorageOrRoot( const String& aStgName ) const
773 {
774     uno::Reference < embed::XStorage > refStor =
775         const_cast<SwGrfNode*>(this)->GetDoc()->GetDocStorage();
776     ASSERT( refStor.is(), "Kein Storage am Doc" );
777 
778     if ( aStgName.Len() )
779     {
780         if( refStor.is() )
781             return refStor->openStorageElement( aStgName, embed::ElementModes::READ );
782     }
783 
784     return refStor;
785 }
786 
787 /** helper method to determine stream for the embedded graphic.
788 
789     OD 2005-05-04 #i48434#
790     Important note: caller of this method has to handle the thrown exceptions
791     OD, MAV 2005-08-17 #i53025#
792     Storage, which should contain the stream of the embedded graphic, is
793     provided via parameter. Otherwise the returned stream will be closed
794     after the the method returns, because its parent stream is closed and deleted.
795     Proposed name of embedded graphic stream is also provided by parameter.
796 
797     @author OD
798 */
799 SvStream* SwGrfNode::_GetStreamForEmbedGrf(
800             const uno::Reference< embed::XStorage >& _refPics,
801             String& _aStrmName ) const
802 {
803     SvStream* pStrm( 0L );
804 
805     if( _refPics.is() && _aStrmName.Len() )
806     {
807         // If stream doesn't exist in the storage, try access the graphic file by
808         // re-generating its name.
809         // A save action can have changed the filename of the embedded graphic,
810         // because a changed unique ID of the graphic is calculated.
811         // --> OD 2006-01-30 #b6364738#
812         // recursive calls of <GetUniqueID()> have to be avoided.
813         // Thus, use local static boolean to assure this.
814         static bool bInRegenerateStrmName( false );
815         if ( !bInRegenerateStrmName &&
816              ( !_refPics->hasByName( _aStrmName ) ||
817                !_refPics->isStreamElement( _aStrmName ) ) )
818         {
819             bInRegenerateStrmName = true;
820             xub_StrLen nExtPos = _aStrmName.Search( '.' );
821             String aExtStr = _aStrmName.Copy( nExtPos );
822             Graphic aGraphic( GetGrfObj().GetGraphic() );
823             if ( aGraphic.GetType() != GRAPHIC_NONE )
824             {
825                 _aStrmName = String( GetGrfObj().GetUniqueID(), RTL_TEXTENCODING_ASCII_US );
826                 _aStrmName += aExtStr;
827             }
828             bInRegenerateStrmName = false;
829         }
830         // <--
831 
832         // assure that graphic file exist in the storage.
833         if ( _refPics->hasByName( _aStrmName ) &&
834              _refPics->isStreamElement( _aStrmName ) )
835         {
836             uno::Reference < io::XStream > refStrm = _refPics->openStreamElement( _aStrmName, embed::ElementModes::READ );
837             pStrm = utl::UcbStreamHelper::CreateStream( refStrm );
838         }
839         else
840         {
841             ASSERT( false, "<SwGrfNode::_GetStreamForEmbedGrf(..)> - embedded graphic file not found!" );
842         }
843     }
844 
845     return pStrm;
846 }
847 
848 
849 // --> OD 2005-08-17 #i53025# - stream couldn't be in a 3.1 - 5.2 storage any more.
850 // Thus, removing corresponding code.
851 void SwGrfNode::_GetStreamStorageNames( String& rStrmName,
852                                         String& rStorName ) const
853 {
854     rStorName.Erase();
855     rStrmName.Erase();
856 
857     String aUserData( aGrfObj.GetUserData() );
858     if( !aUserData.Len() )
859         return;
860 
861     String aProt( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.Package:" ) );
862     if( 0 == aUserData.CompareTo( aProt, aProt.Len() ) )
863     {
864         // 6.0 (XML) Package
865         xub_StrLen nPos = aUserData.Search( '/' );
866         if( STRING_NOTFOUND == nPos )
867         {
868             rStrmName = aUserData.Copy( aProt.Len() );
869         }
870         else
871         {
872             xub_StrLen nPathStart = aProt.Len();
873             if( 0 == aUserData.CompareToAscii( "./", 2 ) )
874                 nPathStart += 2;
875             rStorName = aUserData.Copy( nPathStart, nPos-nPathStart );
876             rStrmName = aUserData.Copy( nPos+1 );
877         }
878     }
879     else
880     {
881         ASSERT( false,
882                 "<SwGrfNode::_GetStreamStorageNames(..)> - unknown graphic URL type. Code for handling 3.1 - 5.2 storages has been deleted by issue i53025." );
883     }
884     ASSERT( STRING_NOTFOUND == rStrmName.Search( '/' ),
885             "invalid graphic stream name" );
886 }
887 // <--
888 
889 SwCntntNode* SwGrfNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
890 {
891     // kopiere die Formate in das andere Dokument:
892     SwGrfFmtColl* pColl = pDoc->CopyGrfColl( *GetGrfColl() );
893 
894     Graphic aTmpGrf;
895     SwBaseLink* pLink = (SwBaseLink*)(::sfx2::SvBaseLink*) refLink;
896     if( !pLink && HasStreamName() )
897     {
898         // --> OD 2005-05-04 #i48434# - usage of new method <_GetStreamForEmbedGrf(..)>
899         try
900         {
901             // --> OD, MAV 2005-08-17 #i53025# - needed correction of new
902             // method <_GetStreamForEmbedGrf(..)>
903 //            bool bGraphic(false);
904 //            SvStream* pStrm = _GetStreamForEmbedGrf( bGraphic );
905             String aStrmName, aPicStgName;
906             _GetStreamStorageNames( aStrmName, aPicStgName );
907             uno::Reference < embed::XStorage > refPics = _GetDocSubstorageOrRoot( aPicStgName );
908             SvStream* pStrm = _GetStreamForEmbedGrf( refPics, aStrmName );
909             if ( pStrm )
910             {
911                 GraphicFilter::GetGraphicFilter()->ImportGraphic( aTmpGrf, String(), *pStrm );
912                 delete pStrm;
913             }
914             // <--
915         }
916         catch ( uno::Exception& )
917         {
918             // --> OD 2005-04-25 #i48434#
919             ASSERT( false, "<SwGrfNode::MakeCopy(..)> - unhandled exception!" );
920             // <--
921         }
922         // <--
923     }
924     else
925     {
926         if( aGrfObj.IsSwappedOut() )
927             const_cast<SwGrfNode*>(this)->SwapIn();
928         aTmpGrf = aGrfObj.GetGraphic();
929     }
930 
931     const sfx2::LinkManager& rMgr = getIDocumentLinksAdministration()->GetLinkManager();
932     String sFile, sFilter;
933     if( IsLinkedFile() )
934         rMgr.GetDisplayNames( refLink, 0, &sFile, 0, &sFilter );
935     else if( IsLinkedDDE() )
936     {
937         String sTmp1, sTmp2;
938         rMgr.GetDisplayNames( refLink, &sTmp1, &sTmp2, &sFilter );
939         sfx2::MakeLnkName( sFile, &sTmp1, sTmp2, sFilter );
940         sFilter.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDE" ));
941     }
942 
943     SwGrfNode* pGrfNd = pDoc->GetNodes().MakeGrfNode( rIdx, sFile, sFilter,
944                                                     &aTmpGrf, pColl,
945                                             (SwAttrSet*)GetpSwAttrSet() );
946     pGrfNd->SetTitle( GetTitle() );
947     pGrfNd->SetDescription( GetDescription() );
948     pGrfNd->SetContour( HasContour(), HasAutomaticContour() );
949     return pGrfNd;
950 }
951 
952 IMPL_LINK( SwGrfNode, SwapGraphic, GraphicObject*, pGrfObj )
953 {
954     SvStream* pRet;
955 
956     // #101174#: Keep graphic while in swap in. That's at least important
957     // when breaking links, because in this situation a reschedule call and
958     // a DataChanged call lead to a paint of the graphic.
959     if( pGrfObj->IsInSwapOut() && (IsSelected() || bInSwapIn) )
960         pRet = GRFMGR_AUTOSWAPSTREAM_NONE;
961     else if( refLink.Is() )
962     {
963         if( pGrfObj->IsInSwapIn() )
964         {
965             // then make it by your self
966             if( !bInSwapIn )
967             {
968                 sal_Bool bIsModifyLocked = IsModifyLocked();
969                 LockModify();
970                 SwapIn( sal_False );
971                 if( !bIsModifyLocked )
972                     UnlockModify();
973             }
974             pRet = GRFMGR_AUTOSWAPSTREAM_NONE;
975         }
976         else
977             pRet = GRFMGR_AUTOSWAPSTREAM_LINK;
978     }
979     else
980     {
981         pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
982 
983         if( HasStreamName() )
984         {
985             // --> OD 2005-05-04 #i48434# - usage of new method <_GetStreamForEmbedGrf(..)>
986             try
987             {
988                 // --> OD, MAV 2005-08-17 #i53025# - needed correction of new
989                 // method <_GetStreamForEmbedGrf(..)>
990 //                bool bGraphic(false);
991 //                SvStream* pStrm = _GetStreamForEmbedGrf( bGraphic );
992                 String aStrmName, aPicStgName;
993                 _GetStreamStorageNames( aStrmName, aPicStgName );
994                 uno::Reference < embed::XStorage > refPics = _GetDocSubstorageOrRoot( aPicStgName );
995                 SvStream* pStrm = _GetStreamForEmbedGrf( refPics, aStrmName );
996                 if ( pStrm )
997                 {
998                     if( pGrfObj->IsInSwapOut() )
999                     {
1000                         pRet = GRFMGR_AUTOSWAPSTREAM_LINK;
1001                     }
1002                     else
1003                     {
1004                         ImportGraphic( *pStrm );
1005                         pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
1006                     }
1007                     delete pStrm;
1008                 }
1009                 // <--
1010             }
1011             catch ( uno::Exception& )
1012             {
1013                 // --> OD 2005-04-25 #i48434#
1014                 ASSERT( false, "<SwapGraphic> - unhandled exception!" );
1015                 // <--
1016             }
1017             // <--
1018         }
1019     }
1020 
1021     return (long)pRet;
1022 }
1023 
1024 
1025 // alle QuickDraw-Bitmaps eines speziellen Docs loeschen
1026 void DelAllGrfCacheEntries( SwDoc* pDoc )
1027 {
1028     if( pDoc )
1029     {
1030         // alle Graphic-Links mit dem Namen aus dem Cache loeschen
1031         const sfx2::LinkManager& rLnkMgr = pDoc->GetLinkManager();
1032         const ::sfx2::SvBaseLinks& rLnks = rLnkMgr.GetLinks();
1033         SwGrfNode* pGrfNd;
1034         String sFileNm;
1035         for( sal_uInt16 n = rLnks.Count(); n; )
1036         {
1037             ::sfx2::SvBaseLink* pLnk = &(*rLnks[ --n ]);
1038             if( pLnk && OBJECT_CLIENT_GRF == pLnk->GetObjType() &&
1039                 rLnkMgr.GetDisplayNames( pLnk, 0, &sFileNm ) &&
1040                 pLnk->ISA( SwBaseLink ) && 0 != ( pGrfNd =
1041                 ((SwBaseLink*)pLnk)->GetCntntNode()->GetGrfNode()) )
1042             {
1043                 pGrfNd->GetGrfObj().ReleaseFromCache();
1044             }
1045         }
1046     }
1047 }
1048 
1049 // returns the with our graphic attributes filled Graphic-Attr-Structure
1050 GraphicAttr& SwGrfNode::GetGraphicAttr( GraphicAttr& rGA,
1051                                         const SwFrm* pFrm ) const
1052 {
1053     const SwAttrSet& rSet = GetSwAttrSet();
1054 
1055     rGA.SetDrawMode( (GraphicDrawMode)rSet.GetDrawModeGrf().GetValue() );
1056 
1057     const SwMirrorGrf & rMirror = rSet.GetMirrorGrf();
1058     sal_uLong nMirror = BMP_MIRROR_NONE;
1059     if( rMirror.IsGrfToggle() && pFrm && !pFrm->FindPageFrm()->OnRightPage() )
1060     {
1061         switch( rMirror.GetValue() )
1062         {
1063         case RES_MIRROR_GRAPH_DONT:     nMirror = BMP_MIRROR_HORZ; break;
1064         case RES_MIRROR_GRAPH_VERT:     nMirror = BMP_MIRROR_NONE; break;
1065         case RES_MIRROR_GRAPH_HOR:  nMirror = BMP_MIRROR_HORZ|BMP_MIRROR_VERT;
1066                                     break;
1067         default:                    nMirror = BMP_MIRROR_VERT; break;
1068         }
1069     }
1070     else
1071         switch( rMirror.GetValue() )
1072         {
1073         case RES_MIRROR_GRAPH_BOTH:     nMirror = BMP_MIRROR_HORZ|BMP_MIRROR_VERT;
1074                                     break;
1075         case RES_MIRROR_GRAPH_VERT: nMirror = BMP_MIRROR_HORZ; break;
1076         case RES_MIRROR_GRAPH_HOR:  nMirror = BMP_MIRROR_VERT; break;
1077         }
1078 
1079     rGA.SetMirrorFlags( nMirror );
1080 
1081     const SwCropGrf& rCrop = rSet.GetCropGrf();
1082     rGA.SetCrop( TWIP_TO_MM100( rCrop.GetLeft() ),
1083                  TWIP_TO_MM100( rCrop.GetTop() ),
1084                  TWIP_TO_MM100( rCrop.GetRight() ),
1085                  TWIP_TO_MM100( rCrop.GetBottom() ));
1086 
1087     const SwRotationGrf& rRotation = rSet.GetRotationGrf();
1088     rGA.SetRotation( rRotation.GetValue() );
1089 
1090     rGA.SetLuminance( rSet.GetLuminanceGrf().GetValue() );
1091     rGA.SetContrast( rSet.GetContrastGrf().GetValue() );
1092     rGA.SetChannelR( rSet.GetChannelRGrf().GetValue() );
1093     rGA.SetChannelG( rSet.GetChannelGGrf().GetValue() );
1094     rGA.SetChannelB( rSet.GetChannelBGrf().GetValue() );
1095     rGA.SetGamma( rSet.GetGammaGrf().GetValue() );
1096     rGA.SetInvert( rSet.GetInvertGrf().GetValue() );
1097 
1098     const sal_uInt16 nTrans = rSet.GetTransparencyGrf().GetValue();
1099     rGA.SetTransparency( (sal_uInt8) FRound(
1100                                 Min( nTrans, (sal_uInt16) 100 )  * 2.55 ) );
1101 
1102     return rGA;
1103 }
1104 
1105 sal_Bool SwGrfNode::IsTransparent() const
1106 {
1107     sal_Bool bRet = aGrfObj.IsTransparent();
1108     if( !bRet ) // ask the attribut
1109         bRet = 0 != GetSwAttrSet().GetTransparencyGrf().GetValue();
1110 
1111     return bRet;
1112 }
1113 
1114 
1115 sal_Bool SwGrfNode::IsSelected() const
1116 {
1117     sal_Bool bRet = sal_False;
1118     const SwEditShell* pESh = GetDoc()->GetEditShell();
1119     if( pESh )
1120     {
1121         const SwNode* pN = this;
1122         const ViewShell* pV = pESh;
1123         do {
1124             if( pV->ISA( SwEditShell ) && pN == &((SwCrsrShell*)pV)
1125                                 ->GetCrsr()->GetPoint()->nNode.GetNode() )
1126             {
1127                 bRet = sal_True;
1128                 break;
1129             }
1130         }
1131         while( pESh != ( pV = (ViewShell*)pV->GetNext() ));
1132     }
1133     return bRet;
1134 }
1135 
1136 // --> OD 2006-12-22 #i73788#
1137 boost::weak_ptr< SwAsyncRetrieveInputStreamThreadConsumer > SwGrfNode::GetThreadConsumer()
1138 {
1139     return mpThreadConsumer;
1140 }
1141 
1142 void SwGrfNode::TriggerAsyncRetrieveInputStream()
1143 {
1144     if ( !IsLinkedFile() )
1145     {
1146         ASSERT( false,
1147                 "<SwGrfNode::TriggerAsyncLoad()> - Method is misused. Method call is only valid for graphic nodes, which refer a linked graphic file" );
1148         return;
1149     }
1150 
1151     if ( mpThreadConsumer.get() == 0 )
1152     {
1153         mpThreadConsumer.reset( new SwAsyncRetrieveInputStreamThreadConsumer( *this ) );
1154 
1155         String sGrfNm;
1156         refLink->GetLinkManager()->GetDisplayNames( refLink, 0, &sGrfNm, 0, 0 );
1157 
1158         mpThreadConsumer->CreateThread( sGrfNm );
1159     }
1160 }
1161 
1162 bool SwGrfNode::IsLinkedInputStreamReady() const
1163 {
1164     return mbLinkedInputStreamReady;
1165 }
1166 
1167 void SwGrfNode::ApplyInputStream(
1168     com::sun::star::uno::Reference<com::sun::star::io::XInputStream> xInputStream,
1169     const sal_Bool bIsStreamReadOnly )
1170 {
1171     if ( IsLinkedFile() )
1172     {
1173         if ( xInputStream.is() )
1174         {
1175             mxInputStream = xInputStream;
1176             mbIsStreamReadOnly = bIsStreamReadOnly;
1177             mbLinkedInputStreamReady = true;
1178             SwMsgPoolItem aMsgHint( RES_LINKED_GRAPHIC_STREAM_ARRIVED );
1179             ModifyNotification( &aMsgHint, &aMsgHint );
1180         }
1181     }
1182 }
1183 
1184 void SwGrfNode::UpdateLinkWithInputStream()
1185 {
1186     // --> OD #i85105#
1187     // do not work on link, if a <SwapIn> has been triggered.
1188     if ( !bInSwapIn && IsLinkedFile() )
1189     // <--
1190     {
1191         GetLink()->setStreamToLoadFrom( mxInputStream, mbIsStreamReadOnly );
1192         GetLink()->Update();
1193         SwMsgPoolItem aMsgHint( RES_GRAPHIC_ARRIVED );
1194         ModifyNotification( &aMsgHint, &aMsgHint );
1195 
1196         // --> OD 2008-06-18 #i88291#
1197         mxInputStream.clear();
1198         GetLink()->clearStreamToLoadFrom();
1199         // <--
1200         mbLinkedInputStreamReady = false;
1201         mpThreadConsumer.reset();
1202     }
1203 }
1204 // <--
1205 
1206 // --> OD 2008-07-21 #i90395#
1207 bool SwGrfNode::IsAsyncRetrieveInputStreamPossible() const
1208 {
1209     bool bRet = false;
1210 
1211     if ( IsLinkedFile() )
1212     {
1213         String sGrfNm;
1214         refLink->GetLinkManager()->GetDisplayNames( refLink, 0, &sGrfNm, 0, 0 );
1215         String sProtocol( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.pkg:" ) );
1216         if ( sGrfNm.CompareTo( sProtocol, sProtocol.Len() ) != 0 )
1217         {
1218             bRet = true;
1219         }
1220     }
1221 
1222     return bRet;
1223 }
1224 // <--
1225