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