1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <svx/sdr/contact/viewobjectcontactofgraphic.hxx>
22 #include <svx/sdr/contact/viewcontactofgraphic.hxx>
23 #include <svx/sdr/event/eventhandler.hxx>
24 #include <svx/svdograf.hxx>
25 #include <svx/sdr/contact/objectcontact.hxx>
26 #include <svx/svdmodel.hxx>
27 #include <svx/svdpage.hxx>
29 //////////////////////////////////////////////////////////////////////////////
35 class AsynchGraphicLoadingEvent
: public BaseEvent
37 // the ViewContactOfGraphic to work with
38 sdr::contact::ViewObjectContactOfGraphic
& mrVOCOfGraphic
;
42 AsynchGraphicLoadingEvent(EventHandler
& rEventHandler
, sdr::contact::ViewObjectContactOfGraphic
& rVOCOfGraphic
);
45 virtual ~AsynchGraphicLoadingEvent();
47 // the called method if the event is triggered
48 virtual void ExecuteEvent();
51 AsynchGraphicLoadingEvent::AsynchGraphicLoadingEvent(
52 EventHandler
& rEventHandler
, sdr::contact::ViewObjectContactOfGraphic
& rVOCOfGraphic
)
53 : BaseEvent(rEventHandler
),
54 mrVOCOfGraphic(rVOCOfGraphic
)
58 AsynchGraphicLoadingEvent::~AsynchGraphicLoadingEvent()
60 mrVOCOfGraphic
.forgetAsynchGraphicLoadingEvent(this);
63 void AsynchGraphicLoadingEvent::ExecuteEvent()
65 mrVOCOfGraphic
.doAsynchGraphicLoading();
67 } // end of namespace event
68 } // end of namespace sdr
70 //////////////////////////////////////////////////////////////////////////////
76 // Test graphics state and eventually trigger a SwapIn event or an Asynchronous
77 // load event. Return value gives info if SwapIn was triggered or not
78 bool ViewObjectContactOfGraphic::impPrepareGraphicWithAsynchroniousLoading()
81 SdrGrafObj
& rGrafObj
= getSdrGrafObj();
83 if(rGrafObj
.IsSwappedOut())
85 if(rGrafObj
.IsLinkedGraphic())
87 // update graphic link
88 rGrafObj
.ImpUpdateGraphicLink();
92 // SwapIn needs to be done. Decide if it can be done asynchronious.
93 bool bSwapInAsynchronious(false);
94 ObjectContact
& rObjectContact
= GetObjectContact();
96 // only when allowed from configuration
97 if(rObjectContact
.IsAsynchronGraphicsLoadingAllowed())
99 // direct output or vdev output (PageView buffering)
100 if(rObjectContact
.isOutputToWindow() || rObjectContact
.isOutputToVirtualDevice())
102 // only when no metafile recording
103 if(!rObjectContact
.isOutputToRecordingMetaFile())
105 // allow asynchronious loading
106 bSwapInAsynchronious
= true;
111 if(bSwapInAsynchronious
)
113 // maybe it's on the way, then do nothing
114 if(!mpAsynchLoadEvent
)
116 // Trigger asynchronious SwapIn.
117 sdr::event::TimerEventHandler
& rEventHandler
= rObjectContact
.GetEventHandler();
119 mpAsynchLoadEvent
= new sdr::event::AsynchGraphicLoadingEvent(rEventHandler
, *this);
124 if(rObjectContact
.isOutputToPrinter() || rObjectContact
.isOutputToPDFFile())
126 // #i76395# preview mechanism is only active if
127 // swapin is called from inside paint preparation, so mbInsidePaint
128 // has to be false to be able to print with high resolution
129 rGrafObj
.ForceSwapIn();
134 rGrafObj
.mbInsidePaint
= true;
135 rGrafObj
.ForceSwapIn();
136 rGrafObj
.mbInsidePaint
= false;
145 // it is not swapped out, somehow it was loaded. In that case, forget
146 // about an existing triggered event
147 if(mpAsynchLoadEvent
)
149 // just delete it, this will remove it from the EventHandler and
150 // will trigger forgetAsynchGraphicLoadingEvent from the destructor
151 delete mpAsynchLoadEvent
;
158 // Test graphics state and eventually trigger a SwapIn event. Return value
159 // gives info if SwapIn was triggered or not
160 bool ViewObjectContactOfGraphic::impPrepareGraphicWithSynchroniousLoading()
163 SdrGrafObj
& rGrafObj
= getSdrGrafObj();
165 if(rGrafObj
.IsSwappedOut())
167 if(rGrafObj
.IsLinkedGraphic())
169 // update graphic link
170 rGrafObj
.ImpUpdateGraphicLink( sal_False
);
174 ObjectContact
& rObjectContact
= GetObjectContact();
176 if(rObjectContact
.isOutputToPrinter() || rObjectContact
.isOutputToPDFFile())
178 // #i76395# preview mechanism is only active if
179 // swapin is called from inside paint preparation, so mbInsidePaint
180 // has to be false to be able to print with high resolution
181 rGrafObj
.ForceSwapIn();
186 rGrafObj
.mbInsidePaint
= true;
187 rGrafObj
.ForceSwapIn();
188 rGrafObj
.mbInsidePaint
= false;
198 // This is the call from the asynch graphic loading. This may only be called from
199 // AsynchGraphicLoadingEvent::ExecuteEvent(). Do load the graphics. The event will
200 // be deleted (consumed) and forgetAsynchGraphicLoadingEvent will be called.
201 void ViewObjectContactOfGraphic::doAsynchGraphicLoading()
203 DBG_ASSERT(mpAsynchLoadEvent
, "ViewObjectContactOfGraphic::doAsynchGraphicLoading: I did not trigger a event, why am i called (?)");
206 SdrGrafObj
& rGrafObj
= getSdrGrafObj();
207 rGrafObj
.ForceSwapIn();
209 // #i103720# forget event to avoid possible deletion by the following ActionChanged call
210 // which may use createPrimitive2DSequence/impPrepareGraphicWithAsynchroniousLoading again.
211 // Deletion is actally done by the scheduler who leaded to coming here
212 mpAsynchLoadEvent
= 0;
214 // Invalidate all paint areas and check existing animation (which may have changed).
215 GetViewContact().ActionChanged();
218 // This is the call from the destructor of the asynch graphic loading event.
219 // No one else has to call this. It is needed to let this object forget about
220 // the event. The parameter allows checking for the correct event.
221 void ViewObjectContactOfGraphic::forgetAsynchGraphicLoadingEvent(sdr::event::AsynchGraphicLoadingEvent
* pEvent
)
223 (void) pEvent
; // suppress warning
225 if(mpAsynchLoadEvent
)
227 OSL_ENSURE(!pEvent
|| mpAsynchLoadEvent
== pEvent
,
228 "ViewObjectContactOfGraphic::forgetAsynchGraphicLoadingEvent: Forced to forget another event then i have scheduled (?)");
231 mpAsynchLoadEvent
= 0;
235 SdrGrafObj
& ViewObjectContactOfGraphic::getSdrGrafObj()
237 return static_cast< ViewContactOfGraphic
& >(GetViewContact()).GetGrafObject();
240 drawinglayer::primitive2d::Primitive2DSequence
ViewObjectContactOfGraphic::createPrimitive2DSequence(const DisplayInfo
& rDisplayInfo
) const
242 // prepare primitive generation with evtl. loading the graphic when it's swapped out
243 SdrGrafObj
& rGrafObj
= const_cast< ViewObjectContactOfGraphic
* >(this)->getSdrGrafObj();
244 bool bDoAsynchronGraphicLoading(rGrafObj
.GetModel() && rGrafObj
.GetModel()->IsSwapGraphics());
245 bool bSwapInDone(false);
246 bool bSwapInExclusive(false);
248 if( bDoAsynchronGraphicLoading
&& rGrafObj
.IsSwappedOut() )
250 // sometimes it is needed that each graphic is completely available and swapped in
251 // for these cases a ForceSwapIn is called later at the graphic object
252 if ( rGrafObj
.GetPage() && rGrafObj
.GetPage()->IsMasterPage() )
254 // #i102380# force Swap-In for GraphicObjects on MasterPage to have a nicer visualisation
255 bDoAsynchronGraphicLoading
= false;
257 else if ( GetObjectContact().isOutputToPrinter()
258 || GetObjectContact().isOutputToRecordingMetaFile()
259 || GetObjectContact().isOutputToPDFFile() )
261 bDoAsynchronGraphicLoading
= false;
262 bSwapInExclusive
= true;
265 if( bDoAsynchronGraphicLoading
)
267 bSwapInDone
= const_cast< ViewObjectContactOfGraphic
* >(this)->impPrepareGraphicWithAsynchroniousLoading();
271 bSwapInDone
= const_cast< ViewObjectContactOfGraphic
* >(this)->impPrepareGraphicWithSynchroniousLoading();
274 // get return value by calling parent
275 drawinglayer::primitive2d::Primitive2DSequence xRetval
= ViewObjectContactOfSdrObj::createPrimitive2DSequence(rDisplayInfo
);
277 if(xRetval
.hasElements())
279 // #i103255# suppress when graphic needs draft visualisation and output
280 // is for PDF export/Printer
281 const ViewContactOfGraphic
& rVCOfGraphic
= static_cast< const ViewContactOfGraphic
& >(GetViewContact());
283 if(rVCOfGraphic
.visualisationUsesDraft())
285 const ObjectContact
& rObjectContact
= GetObjectContact();
287 if(rObjectContact
.isOutputToPDFFile() || rObjectContact
.isOutputToPrinter())
289 xRetval
= drawinglayer::primitive2d::Primitive2DSequence();
294 // if swap in was forced only for printing metafile and pdf, swap out again
295 if( bSwapInDone
&& bSwapInExclusive
)
297 rGrafObj
.ForceSwapOut();
303 ViewObjectContactOfGraphic::ViewObjectContactOfGraphic(ObjectContact
& rObjectContact
, ViewContact
& rViewContact
)
304 : ViewObjectContactOfSdrObj(rObjectContact
, rViewContact
),
309 ViewObjectContactOfGraphic::~ViewObjectContactOfGraphic()
311 // evtl. delete the asynch loading event
312 if(mpAsynchLoadEvent
)
314 // just delete it, this will remove it from the EventHandler and
315 // will trigger forgetAsynchGraphicLoadingEvent from the destructor
316 delete mpAsynchLoadEvent
;
319 } // end of namespace contact
320 } // end of namespace sdr
322 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */