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
10*f6e50924SAndrew Rist  *
11*f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*f6e50924SAndrew Rist  *
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.
19*f6e50924SAndrew Rist  *
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