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