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