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