xref: /AOO41X/main/svx/source/sdr/contact/viewobjectcontactofgraphic.cxx (revision f6e50924346d0b8c0b07c91832a97665dd718b0c)
1*f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*f6e50924SAndrew Rist  * distributed with this work for additional information
6*f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9*f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15*f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17*f6e50924SAndrew Rist  * specific language governing permissions and limitations
18*f6e50924SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*f6e50924SAndrew Rist  *************************************************************/
21*f6e50924SAndrew Rist 
22*f6e50924SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svx.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <svx/sdr/contact/viewobjectcontactofgraphic.hxx>
28cdf0e10cSrcweir #include <svx/sdr/contact/viewcontactofgraphic.hxx>
29cdf0e10cSrcweir #include <svx/sdr/event/eventhandler.hxx>
30cdf0e10cSrcweir #include <svx/svdograf.hxx>
31cdf0e10cSrcweir #include <svx/sdr/contact/objectcontact.hxx>
32cdf0e10cSrcweir #include <svx/svdmodel.hxx>
33cdf0e10cSrcweir #include <svx/svdpage.hxx>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
36cdf0e10cSrcweir 
37cdf0e10cSrcweir namespace sdr
38cdf0e10cSrcweir {
39cdf0e10cSrcweir     namespace event
40cdf0e10cSrcweir     {
41cdf0e10cSrcweir         class AsynchGraphicLoadingEvent : public BaseEvent
42cdf0e10cSrcweir         {
43cdf0e10cSrcweir             // the ViewContactOfGraphic to work with
44cdf0e10cSrcweir             sdr::contact::ViewObjectContactOfGraphic&       mrVOCOfGraphic;
45cdf0e10cSrcweir 
46cdf0e10cSrcweir         public:
47cdf0e10cSrcweir             // basic constructor.
48cdf0e10cSrcweir             AsynchGraphicLoadingEvent(EventHandler& rEventHandler, sdr::contact::ViewObjectContactOfGraphic& rVOCOfGraphic);
49cdf0e10cSrcweir 
50cdf0e10cSrcweir             // destructor
51cdf0e10cSrcweir             virtual ~AsynchGraphicLoadingEvent();
52cdf0e10cSrcweir 
53cdf0e10cSrcweir             // the called method if the event is triggered
54cdf0e10cSrcweir             virtual void ExecuteEvent();
55cdf0e10cSrcweir         };
56cdf0e10cSrcweir 
AsynchGraphicLoadingEvent(EventHandler & rEventHandler,sdr::contact::ViewObjectContactOfGraphic & rVOCOfGraphic)57cdf0e10cSrcweir         AsynchGraphicLoadingEvent::AsynchGraphicLoadingEvent(
58cdf0e10cSrcweir             EventHandler& rEventHandler, sdr::contact::ViewObjectContactOfGraphic& rVOCOfGraphic)
59cdf0e10cSrcweir         :   BaseEvent(rEventHandler),
60cdf0e10cSrcweir             mrVOCOfGraphic(rVOCOfGraphic)
61cdf0e10cSrcweir         {
62cdf0e10cSrcweir         }
63cdf0e10cSrcweir 
~AsynchGraphicLoadingEvent()64cdf0e10cSrcweir         AsynchGraphicLoadingEvent::~AsynchGraphicLoadingEvent()
65cdf0e10cSrcweir         {
66cdf0e10cSrcweir             mrVOCOfGraphic.forgetAsynchGraphicLoadingEvent(this);
67cdf0e10cSrcweir         }
68cdf0e10cSrcweir 
ExecuteEvent()69cdf0e10cSrcweir         void AsynchGraphicLoadingEvent::ExecuteEvent()
70cdf0e10cSrcweir         {
71cdf0e10cSrcweir             mrVOCOfGraphic.doAsynchGraphicLoading();
72cdf0e10cSrcweir         }
73cdf0e10cSrcweir     } // end of namespace event
74cdf0e10cSrcweir } // end of namespace sdr
75cdf0e10cSrcweir 
76cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
77cdf0e10cSrcweir 
78cdf0e10cSrcweir namespace sdr
79cdf0e10cSrcweir {
80cdf0e10cSrcweir     namespace contact
81cdf0e10cSrcweir     {
82cdf0e10cSrcweir         // Test graphics state and eventually trigger a SwapIn event or an Asynchronous
83cdf0e10cSrcweir         // load event. Return value gives info if SwapIn was triggered or not
impPrepareGraphicWithAsynchroniousLoading()84cdf0e10cSrcweir         bool ViewObjectContactOfGraphic::impPrepareGraphicWithAsynchroniousLoading()
85cdf0e10cSrcweir         {
86cdf0e10cSrcweir             bool bRetval(false);
87cdf0e10cSrcweir             SdrGrafObj& rGrafObj = getSdrGrafObj();
88cdf0e10cSrcweir 
89cdf0e10cSrcweir             if(rGrafObj.IsSwappedOut())
90cdf0e10cSrcweir             {
91cdf0e10cSrcweir                 if(rGrafObj.IsLinkedGraphic())
92cdf0e10cSrcweir                 {
93cdf0e10cSrcweir                     // update graphic link
94cdf0e10cSrcweir                     rGrafObj.ImpUpdateGraphicLink();
95cdf0e10cSrcweir                 }
96cdf0e10cSrcweir                 else
97cdf0e10cSrcweir                 {
98cdf0e10cSrcweir                     // SwapIn needs to be done. Decide if it can be done asynchronious.
99cdf0e10cSrcweir                     bool bSwapInAsynchronious(false);
100cdf0e10cSrcweir                     ObjectContact& rObjectContact = GetObjectContact();
101cdf0e10cSrcweir 
102cdf0e10cSrcweir                     // only when allowed from configuration
103cdf0e10cSrcweir                     if(rObjectContact.IsAsynchronGraphicsLoadingAllowed())
104cdf0e10cSrcweir                     {
105cdf0e10cSrcweir                         // direct output or vdev output (PageView buffering)
106cdf0e10cSrcweir                         if(rObjectContact.isOutputToWindow() || rObjectContact.isOutputToVirtualDevice())
107cdf0e10cSrcweir                         {
108cdf0e10cSrcweir                             // only when no metafile recording
109cdf0e10cSrcweir                             if(!rObjectContact.isOutputToRecordingMetaFile())
110cdf0e10cSrcweir                             {
111cdf0e10cSrcweir                                 // allow asynchronious loading
112cdf0e10cSrcweir                                 bSwapInAsynchronious = true;
113cdf0e10cSrcweir                             }
114cdf0e10cSrcweir                         }
115cdf0e10cSrcweir                     }
116cdf0e10cSrcweir 
117cdf0e10cSrcweir                     if(bSwapInAsynchronious)
118cdf0e10cSrcweir                     {
119cdf0e10cSrcweir                         // maybe it's on the way, then do nothing
120cdf0e10cSrcweir                         if(!mpAsynchLoadEvent)
121cdf0e10cSrcweir                         {
122cdf0e10cSrcweir                             // Trigger asynchronious SwapIn.
123cdf0e10cSrcweir                             sdr::event::TimerEventHandler& rEventHandler = rObjectContact.GetEventHandler();
124cdf0e10cSrcweir 
125cdf0e10cSrcweir                             mpAsynchLoadEvent = new sdr::event::AsynchGraphicLoadingEvent(rEventHandler, *this);
126cdf0e10cSrcweir                         }
127cdf0e10cSrcweir                     }
128cdf0e10cSrcweir                     else
129cdf0e10cSrcweir                     {
130cdf0e10cSrcweir                         if(rObjectContact.isOutputToPrinter())
131cdf0e10cSrcweir                         {
132cdf0e10cSrcweir                             // #i76395# preview mechanism is only active if
133cdf0e10cSrcweir                             // swapin is called from inside paint preparation, so mbInsidePaint
134cdf0e10cSrcweir                             // has to be false to be able to print with high resolution
135cdf0e10cSrcweir                             rGrafObj.ForceSwapIn();
136cdf0e10cSrcweir                         }
137cdf0e10cSrcweir                         else
138cdf0e10cSrcweir                         {
139cdf0e10cSrcweir                             // SwapIn direct
140cdf0e10cSrcweir                             rGrafObj.mbInsidePaint = sal_True;
141cdf0e10cSrcweir                             rGrafObj.ForceSwapIn();
142cdf0e10cSrcweir                             rGrafObj.mbInsidePaint = sal_False;
143cdf0e10cSrcweir                         }
144cdf0e10cSrcweir 
145cdf0e10cSrcweir                         bRetval = true;
146cdf0e10cSrcweir                     }
147cdf0e10cSrcweir                 }
148cdf0e10cSrcweir             }
149cdf0e10cSrcweir             else
150cdf0e10cSrcweir             {
151cdf0e10cSrcweir                 // it is not swapped out, somehow it was loaded. In that case, forget
152cdf0e10cSrcweir                 // about an existing triggered event
153cdf0e10cSrcweir                 if(mpAsynchLoadEvent)
154cdf0e10cSrcweir                 {
155cdf0e10cSrcweir                     // just delete it, this will remove it from the EventHandler and
156cdf0e10cSrcweir                     // will trigger forgetAsynchGraphicLoadingEvent from the destructor
157cdf0e10cSrcweir                     delete mpAsynchLoadEvent;
158cdf0e10cSrcweir                 }
159cdf0e10cSrcweir             }
160cdf0e10cSrcweir 
161cdf0e10cSrcweir             return bRetval;
162cdf0e10cSrcweir         }
163cdf0e10cSrcweir 
164cdf0e10cSrcweir         // Test graphics state and eventually trigger a SwapIn event. Return value
165cdf0e10cSrcweir         // gives info if SwapIn was triggered or not
impPrepareGraphicWithSynchroniousLoading()166cdf0e10cSrcweir         bool ViewObjectContactOfGraphic::impPrepareGraphicWithSynchroniousLoading()
167cdf0e10cSrcweir         {
168cdf0e10cSrcweir             bool bRetval(false);
169cdf0e10cSrcweir             SdrGrafObj& rGrafObj = getSdrGrafObj();
170cdf0e10cSrcweir 
171cdf0e10cSrcweir             if(rGrafObj.IsSwappedOut())
172cdf0e10cSrcweir             {
173cdf0e10cSrcweir                 if(rGrafObj.IsLinkedGraphic())
174cdf0e10cSrcweir                 {
175cdf0e10cSrcweir                     // update graphic link
176cdf0e10cSrcweir                     rGrafObj.ImpUpdateGraphicLink( sal_False );
177cdf0e10cSrcweir                 }
178cdf0e10cSrcweir                 else
179cdf0e10cSrcweir                 {
180cdf0e10cSrcweir                     ObjectContact& rObjectContact = GetObjectContact();
181cdf0e10cSrcweir 
182cdf0e10cSrcweir                     if(rObjectContact.isOutputToPrinter())
183cdf0e10cSrcweir                     {
184cdf0e10cSrcweir                         // #i76395# preview mechanism is only active if
185cdf0e10cSrcweir                         // swapin is called from inside paint preparation, so mbInsidePaint
186cdf0e10cSrcweir                         // has to be false to be able to print with high resolution
187cdf0e10cSrcweir                         rGrafObj.ForceSwapIn();
188cdf0e10cSrcweir                     }
189cdf0e10cSrcweir                     else
190cdf0e10cSrcweir                     {
191cdf0e10cSrcweir                         // SwapIn direct
192cdf0e10cSrcweir                         rGrafObj.mbInsidePaint = sal_True;
193cdf0e10cSrcweir                         rGrafObj.ForceSwapIn();
194cdf0e10cSrcweir                         rGrafObj.mbInsidePaint = sal_False;
195cdf0e10cSrcweir                         }
196cdf0e10cSrcweir 
197cdf0e10cSrcweir                     bRetval = true;
198cdf0e10cSrcweir                 }
199cdf0e10cSrcweir             }
200cdf0e10cSrcweir 
201cdf0e10cSrcweir             return bRetval;
202cdf0e10cSrcweir         }
203cdf0e10cSrcweir 
204cdf0e10cSrcweir         // This is the call from the asynch graphic loading. This may only be called from
205cdf0e10cSrcweir         // AsynchGraphicLoadingEvent::ExecuteEvent(). Do load the graphics. The event will
206cdf0e10cSrcweir         // be deleted (consumed) and forgetAsynchGraphicLoadingEvent will be called.
doAsynchGraphicLoading()207cdf0e10cSrcweir         void ViewObjectContactOfGraphic::doAsynchGraphicLoading()
208cdf0e10cSrcweir         {
209cdf0e10cSrcweir             DBG_ASSERT(mpAsynchLoadEvent, "ViewObjectContactOfGraphic::doAsynchGraphicLoading: I did not trigger a event, why am i called (?)");
210cdf0e10cSrcweir 
211cdf0e10cSrcweir             // swap it in
212cdf0e10cSrcweir             SdrGrafObj& rGrafObj = getSdrGrafObj();
213cdf0e10cSrcweir             rGrafObj.ForceSwapIn();
214cdf0e10cSrcweir 
215cdf0e10cSrcweir             // #i103720# forget event to avoid possible deletion by the following ActionChanged call
216cdf0e10cSrcweir             // which may use createPrimitive2DSequence/impPrepareGraphicWithAsynchroniousLoading again.
217cdf0e10cSrcweir             // Deletion is actally done by the scheduler who leaded to coming here
218cdf0e10cSrcweir             mpAsynchLoadEvent = 0;
219cdf0e10cSrcweir 
220cdf0e10cSrcweir             // Invalidate all paint areas and check existing animation (which may have changed).
221cdf0e10cSrcweir             GetViewContact().ActionChanged();
222cdf0e10cSrcweir         }
223cdf0e10cSrcweir 
224cdf0e10cSrcweir         // This is the call from the destructor of the asynch graphic loading event.
225cdf0e10cSrcweir         // No one else has to call this. It is needed to let this object forget about
226cdf0e10cSrcweir         // the event. The parameter allows checking for the correct event.
forgetAsynchGraphicLoadingEvent(sdr::event::AsynchGraphicLoadingEvent * pEvent)227cdf0e10cSrcweir         void ViewObjectContactOfGraphic::forgetAsynchGraphicLoadingEvent(sdr::event::AsynchGraphicLoadingEvent* pEvent)
228cdf0e10cSrcweir         {
229cdf0e10cSrcweir             (void) pEvent; // suppress warning
230cdf0e10cSrcweir 
231cdf0e10cSrcweir             if(mpAsynchLoadEvent)
232cdf0e10cSrcweir             {
233cdf0e10cSrcweir                 OSL_ENSURE(!pEvent || mpAsynchLoadEvent == pEvent,
234cdf0e10cSrcweir                     "ViewObjectContactOfGraphic::forgetAsynchGraphicLoadingEvent: Forced to forget another event then i have scheduled (?)");
235cdf0e10cSrcweir 
236cdf0e10cSrcweir                 // forget event
237cdf0e10cSrcweir                 mpAsynchLoadEvent = 0;
238cdf0e10cSrcweir             }
239cdf0e10cSrcweir         }
240cdf0e10cSrcweir 
getSdrGrafObj()241cdf0e10cSrcweir         SdrGrafObj& ViewObjectContactOfGraphic::getSdrGrafObj()
242cdf0e10cSrcweir         {
243cdf0e10cSrcweir             return static_cast< ViewContactOfGraphic& >(GetViewContact()).GetGrafObject();
244cdf0e10cSrcweir         }
245cdf0e10cSrcweir 
createPrimitive2DSequence(const DisplayInfo & rDisplayInfo) const246cdf0e10cSrcweir         drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfGraphic::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const
247cdf0e10cSrcweir         {
248cdf0e10cSrcweir             // prepare primitive generation with evtl. loading the graphic when it's swapped out
249cdf0e10cSrcweir             SdrGrafObj& rGrafObj = const_cast< ViewObjectContactOfGraphic* >(this)->getSdrGrafObj();
250cdf0e10cSrcweir             bool bDoAsynchronGraphicLoading(rGrafObj.GetModel() && rGrafObj.GetModel()->IsSwapGraphics());
251cdf0e10cSrcweir             bool bSwapInDone(false);
252cdf0e10cSrcweir             bool bSwapInExclusive(false);
253cdf0e10cSrcweir 
254cdf0e10cSrcweir             if( bDoAsynchronGraphicLoading && rGrafObj.IsSwappedOut() )
255cdf0e10cSrcweir             {
256cdf0e10cSrcweir                 // sometimes it is needed that each graphic is completely available and swapped in
257cdf0e10cSrcweir                 // for these cases a ForceSwapIn is called later at the graphic object
258cdf0e10cSrcweir                 if ( rGrafObj.GetPage() && rGrafObj.GetPage()->IsMasterPage() )
259cdf0e10cSrcweir                 {
260cdf0e10cSrcweir                     // #i102380# force Swap-In for GraphicObjects on MasterPage to have a nicer visualisation
261cdf0e10cSrcweir                     bDoAsynchronGraphicLoading = false;
262cdf0e10cSrcweir                 }
263cdf0e10cSrcweir                 else if ( GetObjectContact().isOutputToPrinter()
264cdf0e10cSrcweir                     || GetObjectContact().isOutputToRecordingMetaFile()
265cdf0e10cSrcweir                     || GetObjectContact().isOutputToPDFFile() )
266cdf0e10cSrcweir                 {
267cdf0e10cSrcweir                     bDoAsynchronGraphicLoading = false;
268cdf0e10cSrcweir                     bSwapInExclusive = true;
269cdf0e10cSrcweir                 }
270cdf0e10cSrcweir             }
271cdf0e10cSrcweir             if( bDoAsynchronGraphicLoading )
272cdf0e10cSrcweir             {
273cdf0e10cSrcweir                 bSwapInDone = const_cast< ViewObjectContactOfGraphic* >(this)->impPrepareGraphicWithAsynchroniousLoading();
274cdf0e10cSrcweir             }
275cdf0e10cSrcweir             else
276cdf0e10cSrcweir             {
277cdf0e10cSrcweir                 bSwapInDone = const_cast< ViewObjectContactOfGraphic* >(this)->impPrepareGraphicWithSynchroniousLoading();
278cdf0e10cSrcweir             }
279cdf0e10cSrcweir 
280cdf0e10cSrcweir             // get return value by calling parent
281cdf0e10cSrcweir             drawinglayer::primitive2d::Primitive2DSequence xRetval = ViewObjectContactOfSdrObj::createPrimitive2DSequence(rDisplayInfo);
282cdf0e10cSrcweir 
283cdf0e10cSrcweir             if(xRetval.hasElements())
284cdf0e10cSrcweir             {
285cdf0e10cSrcweir                 // #i103255# suppress when graphic needs draft visualisation and output
286cdf0e10cSrcweir                 // is for PDF export/Printer
287cdf0e10cSrcweir                 const ViewContactOfGraphic& rVCOfGraphic = static_cast< const ViewContactOfGraphic& >(GetViewContact());
288cdf0e10cSrcweir 
289cdf0e10cSrcweir                 if(rVCOfGraphic.visualisationUsesDraft())
290cdf0e10cSrcweir                 {
291cdf0e10cSrcweir                     const ObjectContact& rObjectContact = GetObjectContact();
292cdf0e10cSrcweir 
293cdf0e10cSrcweir                     if(rObjectContact.isOutputToPDFFile() || rObjectContact.isOutputToPrinter())
294cdf0e10cSrcweir                     {
295cdf0e10cSrcweir                         xRetval = drawinglayer::primitive2d::Primitive2DSequence();
296cdf0e10cSrcweir                     }
297cdf0e10cSrcweir                 }
298cdf0e10cSrcweir             }
299cdf0e10cSrcweir 
300cdf0e10cSrcweir             // if swap in was forced only for printing metafile and pdf, swap out again
301cdf0e10cSrcweir             if( bSwapInDone && bSwapInExclusive )
302cdf0e10cSrcweir             {
303cdf0e10cSrcweir                 rGrafObj.ForceSwapOut();
304cdf0e10cSrcweir             }
305cdf0e10cSrcweir 
306cdf0e10cSrcweir             return xRetval;
307cdf0e10cSrcweir         }
308cdf0e10cSrcweir 
ViewObjectContactOfGraphic(ObjectContact & rObjectContact,ViewContact & rViewContact)309cdf0e10cSrcweir         ViewObjectContactOfGraphic::ViewObjectContactOfGraphic(ObjectContact& rObjectContact, ViewContact& rViewContact)
310cdf0e10cSrcweir         :   ViewObjectContactOfSdrObj(rObjectContact, rViewContact),
311cdf0e10cSrcweir             mpAsynchLoadEvent(0)
312cdf0e10cSrcweir         {
313cdf0e10cSrcweir         }
314cdf0e10cSrcweir 
~ViewObjectContactOfGraphic()315cdf0e10cSrcweir         ViewObjectContactOfGraphic::~ViewObjectContactOfGraphic()
316cdf0e10cSrcweir         {
317cdf0e10cSrcweir             // evtl. delete the asynch loading event
318cdf0e10cSrcweir             if(mpAsynchLoadEvent)
319cdf0e10cSrcweir             {
320cdf0e10cSrcweir                 // just delete it, this will remove it from the EventHandler and
321cdf0e10cSrcweir                 // will trigger forgetAsynchGraphicLoadingEvent from the destructor
322cdf0e10cSrcweir                 delete mpAsynchLoadEvent;
323cdf0e10cSrcweir             }
324cdf0e10cSrcweir         }
325cdf0e10cSrcweir     } // end of namespace contact
326cdf0e10cSrcweir } // end of namespace sdr
327cdf0e10cSrcweir 
328cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
329cdf0e10cSrcweir // eof
330