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