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