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