update dev300-m58
[ooovba.git] / svx / source / svdraw / sdrpagewindow.cxx
blobd1e2f13403d3ee62c0843c938e3d39d20b7758a7
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: sdrpagewindow.cxx,v $
10 * $Revision: 1.11 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include <svx/sdrpagewindow.hxx>
34 #include <com/sun/star/awt/XWindow.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/awt/PosSize.hpp>
37 #include <com/sun/star/util/XModeChangeBroadcaster.hpp>
38 #include <comphelper/processfactory.hxx>
39 #include <vcl/svapp.hxx>
40 #include <toolkit/helper/vclunohelper.hxx>
41 #include <svx/svdouno.hxx>
42 #include <svx/svdpage.hxx>
43 #include <svx/svdview.hxx>
44 #include <svx/svdpagv.hxx>
45 #include <sdrpaintwindow.hxx>
46 #include <svx/sdr/contact/objectcontactofpageview.hxx>
47 #include <svx/sdr/contact/displayinfo.hxx>
48 #include <vos/mutex.hxx>
49 #include <svx/fmview.hxx>
50 #include <basegfx/matrix/b2dhommatrix.hxx>
52 ////////////////////////////////////////////////////////////////////////////////////////////////////
54 using namespace ::rtl;
55 using namespace ::com::sun::star;
57 ////////////////////////////////////////////////////////////////////////////////////////////////////
59 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > SdrPageWindow::GetControlContainer( bool _bCreateIfNecessary ) const
61 if ( !mxControlContainer.is() && _bCreateIfNecessary )
63 SdrView& rView = GetPageView().GetView();
65 const SdrPaintWindow& rPaintWindow( GetOriginalPaintWindow() ? *GetOriginalPaintWindow() : GetPaintWindow() );
66 if ( rPaintWindow.OutputToWindow() && !rView.IsPrintPreview() )
68 Window& rWindow = dynamic_cast< Window& >( rPaintWindow.GetOutputDevice() );
69 const_cast< SdrPageWindow* >( this )->mxControlContainer = VCLUnoHelper::CreateControlContainer( &rWindow );
71 // #100394# xC->setVisible triggers window->Show() and this has
72 // problems when the view is not completely constructed which may
73 // happen when loading. This leads to accessibility broadcasts which
74 // throw asserts due to the not finished view. All this chan be avoided
75 // since xC->setVisible is here called only for the side effect in
76 // UnoControlContainer::setVisible(...) which calls createPeer(...).
77 // This will now be called directly from here.
79 // UnoContainerModel erzeugen
80 // uno::Reference< awt::XWindow > xC(mxControlContainer, uno::UNO_QUERY);
81 // CreateControlContainer() is only used from
82 // , thus it seems not necessary to make
83 // it visible her at all.
84 // #58917# Das Show darf nicht am VCL-Fenster landen, weil dann Assertion vom SFX
85 // BOOL bVis = pWindow->IsVisible();
86 // xC->setVisible(TRUE);
87 // if ( !bVis )
88 // pWindow->Hide();
89 // if( !mxContext.is() && bVisible )
90 // // Es ist ein TopWindow, also automatisch anzeigen
91 // createPeer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit > (), ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > () );
93 uno::Reference< awt::XControl > xControl(mxControlContainer, uno::UNO_QUERY);
94 if(xControl.is())
96 uno::Reference< uno::XInterface > xContext = xControl->getContext();
97 if(!xContext.is())
99 xControl->createPeer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit > (),
100 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > () );
104 else
106 // Printer und VirtualDevice, bzw. kein OutDev
107 uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
108 if( xFactory.is() )
110 const_cast< SdrPageWindow* >( this )->mxControlContainer = uno::Reference< awt::XControlContainer >(xFactory->createInstance(rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlContainer")), uno::UNO_QUERY);
111 uno::Reference< awt::XControlModel > xModel(xFactory->createInstance(rtl::OUString::createFromAscii("com.sun.star.awt.UnoControlContainerModel")), uno::UNO_QUERY);
112 uno::Reference< awt::XControl > xControl(mxControlContainer, uno::UNO_QUERY);
113 if (xControl.is())
114 xControl->setModel(xModel);
116 OutputDevice& rOutDev = rPaintWindow.GetOutputDevice();
117 Point aPosPix = rOutDev.GetMapMode().GetOrigin();
118 Size aSizePix = rOutDev.GetOutputSizePixel();
120 uno::Reference< awt::XWindow > xContComp(mxControlContainer, uno::UNO_QUERY);
121 if( xContComp.is() )
122 xContComp->setPosSize(aPosPix.X(), aPosPix.Y(), aSizePix.Width(), aSizePix.Height(), awt::PosSize::POSSIZE);
126 FmFormView* pViewAsFormView = dynamic_cast< FmFormView* >( &rView );
127 if ( pViewAsFormView )
128 pViewAsFormView->InsertControlContainer(mxControlContainer);
130 return mxControlContainer;
133 SdrPageWindow::SdrPageWindow(SdrPageView& rPageView, SdrPaintWindow& rPaintWindow)
134 : mpObjectContact(0L),
135 mrPageView(rPageView),
136 mpPaintWindow(&rPaintWindow),
137 mpOriginalPaintWindow(NULL)
141 SdrPageWindow::~SdrPageWindow()
143 // #110094#, #i26631#
144 ResetObjectContact();
146 if (mxControlContainer.is())
148 SdrView& rView = GetPageView().GetView();
150 // notify derived views
151 FmFormView* pViewAsFormView = dynamic_cast< FmFormView* >( &rView );
152 if ( pViewAsFormView )
153 pViewAsFormView->RemoveControlContainer(mxControlContainer);
155 // dispose the control container
156 uno::Reference< lang::XComponent > xComponent(mxControlContainer, uno::UNO_QUERY);
157 xComponent->dispose();
161 // #110094# ObjectContact section
162 sdr::contact::ObjectContact* SdrPageWindow::CreateViewSpecificObjectContact()
164 return new sdr::contact::ObjectContactOfPageView(*this);
167 // OVERLAYMANAGER
168 ::sdr::overlay::OverlayManager* SdrPageWindow::GetOverlayManager() const
170 return GetPaintWindow().GetOverlayManager();
173 void SdrPageWindow::patchPaintWindow(SdrPaintWindow& rPaintWindow)
175 mpOriginalPaintWindow = mpPaintWindow;
176 mpPaintWindow = &rPaintWindow;
179 void SdrPageWindow::unpatchPaintWindow()
181 DBG_ASSERT(mpOriginalPaintWindow, "SdrPageWindow::unpatchPaintWindow: paint window not patched!" );
182 if ( mpOriginalPaintWindow )
184 mpPaintWindow = mpOriginalPaintWindow;
185 mpOriginalPaintWindow = NULL;
189 void SdrPageWindow::PrePaint()
191 // give OC the chance to do ProcessDisplay preparations
192 if(HasObjectContact())
194 GetObjectContact().PrepareProcessDisplay();
198 void SdrPageWindow::PrepareRedraw(const Region& rReg)
200 // evtl. give OC the chance to do ProcessDisplay preparations
201 if(HasObjectContact())
203 GetObjectContact().PrepareProcessDisplay();
206 // remember eventually changed RedrawArea at PaintWindow for usage with
207 // overlay and PreRenderDevice stuff
208 GetPaintWindow().SetRedrawRegion(rReg);
211 //////////////////////////////////////////////////////////////////////////////
212 // clip test
213 #ifdef CLIPPER_TEST
214 #include <svx/svdopath.hxx>
215 #include <basegfx/polygon/b2dpolygon.hxx>
216 #include <vcl/salbtype.hxx> // FRound
217 #include <basegfx/polygon/b2dpolygoncutandtouch.hxx>
218 #include <basegfx/polygon/b2dpolypolygontools.hxx>
219 #include <basegfx/polygon/b2dpolygontools.hxx>
220 #include <basegfx/polygon/b2dpolygonclipper.hxx>
222 // for ::std::sort
223 #include <algorithm>
225 namespace
227 void impPaintStrokePolygon(const basegfx::B2DPolygon& rCandidate, OutputDevice& rOutDev, Color aColor)
229 basegfx::B2DPolygon aCandidate(rCandidate);
231 if(aCandidate.areControlPointsUsed())
233 aCandidate = basegfx::tools::adaptiveSubdivideByAngle(rCandidate);
236 if(aCandidate.count())
238 const sal_uInt32 nLoopCount(aCandidate.isClosed() ? aCandidate.count() : aCandidate.count() - 1L);
239 rOutDev.SetFillColor();
240 rOutDev.SetLineColor(aColor);
242 for(sal_uInt32 a(0L); a < nLoopCount; a++)
244 const basegfx::B2DPoint aBStart(aCandidate.getB2DPoint(a));
245 const basegfx::B2DPoint aBEnd(aCandidate.getB2DPoint((a + 1) % aCandidate.count()));
246 const Point aStart(FRound(aBStart.getX()), FRound(aBStart.getY()));
247 const Point aEnd(FRound(aBEnd.getX()), FRound(aBEnd.getY()));
248 rOutDev.DrawLine(aStart, aEnd);
253 void impTryTest(const SdrPageView& rPageView, OutputDevice& rOutDev)
255 if(rPageView.GetPage() && rPageView.GetPage()->GetObjCount() >= 2L)
257 SdrPage* pPage = rPageView.GetPage();
258 SdrObject* pObjA = pPage->GetObj(0L);
260 if(pObjA && pObjA->ISA(SdrPathObj))
262 basegfx::B2DPolyPolygon aPolyA(((SdrPathObj*)pObjA)->GetPathPoly());
263 aPolyA = basegfx::tools::correctOrientations(aPolyA);
265 basegfx::B2DPolyPolygon aPolyB;
267 for(sal_uInt32 a(1L); a < rPageView.GetPage()->GetObjCount(); a++)
269 SdrObject* pObjB = pPage->GetObj(a);
271 if(pObjB && pObjB->ISA(SdrPathObj))
273 basegfx::B2DPolyPolygon aCandidate(((SdrPathObj*)pObjB)->GetPathPoly());
274 aCandidate = basegfx::tools::correctOrientations(aCandidate);
275 aPolyB.append(aCandidate);
279 if(aPolyA.count() && aPolyA.isClosed() && aPolyB.count())
281 // poly A is the clipregion, clip poly b against it. Algo depends on
282 // poly b being closed.
283 basegfx::B2DPolyPolygon aResult(basegfx::tools::clipPolyPolygonOnPolyPolygon(aPolyB, aPolyA));
285 for(sal_uInt32 a(0L); a < aResult.count(); a++)
287 Color aColor(rand()%255, rand()%255, rand()%255);
288 impPaintStrokePolygon(aResult.getB2DPolygon(a), rOutDev, aColor);
291 bool bBla = true;
296 } // end of anonymous namespace
297 #endif // CLIPPER_TEST
299 //////////////////////////////////////////////////////////////////////////////
301 void SdrPageWindow::RedrawAll(sdr::contact::ViewObjectContactRedirector* pRedirector) const
303 // set Redirector
304 GetObjectContact().SetViewObjectContactRedirector(pRedirector);
306 // set PaintingPageView
307 const SdrView& rView = mrPageView.GetView();
308 SdrModel& rModel = *((SdrModel*)rView.GetModel());
310 // get to be processed layers
311 const sal_Bool bPrinter(GetPaintWindow().OutputToPrinter());
312 SetOfByte aProcessLayers = bPrinter ? mrPageView.GetPrintableLayers() : mrPageView.GetVisibleLayers();
314 // create PaintInfoRec, #114359# use Rectangle only temporarily
315 const Region& rRegion = GetPaintWindow().GetRedrawRegion();
317 // create processing data
318 sdr::contact::DisplayInfo aDisplayInfo;
320 // Draw all layers. do NOT draw form layer from CompleteRedraw, this is done separate
321 // as a single layer paint
322 const SdrLayerAdmin& rLayerAdmin = rModel.GetLayerAdmin();
323 const SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID(rLayerAdmin.GetControlLayerName(), sal_False);
324 aProcessLayers.Clear(nControlLayerId);
326 // still something to paint?
327 if(!aProcessLayers.IsEmpty())
329 aDisplayInfo.SetProcessLayers(aProcessLayers);
331 // Set region as redraw area
332 aDisplayInfo.SetRedrawArea(rRegion);
334 // Draw/Impress
335 aDisplayInfo.SetPageProcessingActive(rView.IsPagePaintingAllowed()); // #i72889#
337 // paint page
338 GetObjectContact().ProcessDisplay(aDisplayInfo);
341 // reset redirector
342 GetObjectContact().SetViewObjectContactRedirector(0L);
344 // LineClip test
345 #ifdef CLIPPER_TEST
346 if(true)
348 impTryTest(GetPageView(), GetPaintWindow().GetOutputDevice());
350 #endif // CLIPPER_TEST
353 void SdrPageWindow::RedrawLayer(const SdrLayerID* pId, sdr::contact::ViewObjectContactRedirector* pRedirector) const
355 // set redirector
356 GetObjectContact().SetViewObjectContactRedirector(pRedirector);
358 // set PaintingPageView
359 const SdrView& rView = mrPageView.GetView();
360 SdrModel& rModel = *((SdrModel*)rView.GetModel());
362 // get the layers to process
363 const sal_Bool bPrinter(GetPaintWindow().OutputToPrinter());
364 SetOfByte aProcessLayers = bPrinter ? mrPageView.GetPrintableLayers() : mrPageView.GetVisibleLayers();
366 // is the given layer visible at all?
367 if(aProcessLayers.IsSet(*pId))
369 // find out if we are painting the ControlLayer
370 const SdrLayerAdmin& rLayerAdmin = rModel.GetLayerAdmin();
371 const SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID(rLayerAdmin.GetControlLayerName(), sal_False);
372 const sal_Bool bControlLayerProcessingActive(pId && nControlLayerId == *pId);
374 // create PaintInfoRec, use Rectangle only temporarily
375 const Region& rRegion = GetPaintWindow().GetRedrawRegion();
377 // create processing data
378 sdr::contact::DisplayInfo aDisplayInfo;
380 // is it the control layer? If Yes, set flag
381 aDisplayInfo.SetControlLayerProcessingActive(bControlLayerProcessingActive);
383 // Draw just the one given layer
384 aProcessLayers.ClearAll();
385 aProcessLayers.Set(*pId);
387 aDisplayInfo.SetProcessLayers(aProcessLayers);
389 // Set region as redraw area
390 aDisplayInfo.SetRedrawArea(rRegion);
392 // Writer or calc, coming from original RedrawOneLayer.
393 // #i72889# no page painting for layer painting
394 aDisplayInfo.SetPageProcessingActive(false);
396 // paint page
397 GetObjectContact().ProcessDisplay(aDisplayInfo);
400 // reset redirector
401 GetObjectContact().SetViewObjectContactRedirector(0L);
404 // Invalidate call, used from ObjectContact(OfPageView) in InvalidatePartOfView(...)
405 void SdrPageWindow::InvalidatePageWindow(const basegfx::B2DRange& rRange)
407 if(GetPageView().IsVisible() && GetPaintWindow().OutputToWindow())
409 const SvtOptionsDrawinglayer aDrawinglayerOpt;
410 Window& rWindow(static_cast< Window& >(GetPaintWindow().GetOutputDevice()));
411 basegfx::B2DRange aDiscreteRange(rRange);
412 aDiscreteRange.transform(rWindow.GetViewTransformation());
414 if(aDrawinglayerOpt.IsAntiAliasing())
416 // invalidate one discrete unit more under the assumption that AA
417 // needs one pixel more
418 aDiscreteRange.grow(1.0);
421 const Rectangle aVCLDiscreteRectangle(
422 (sal_Int32)floor(aDiscreteRange.getMinX()), (sal_Int32)floor(aDiscreteRange.getMinY()),
423 (sal_Int32)ceil(aDiscreteRange.getMaxX()), (sal_Int32)ceil(aDiscreteRange.getMaxY()));
424 const bool bWasMapModeEnabled(rWindow.IsMapModeEnabled());
426 rWindow.EnableMapMode(false);
427 rWindow.Invalidate(aVCLDiscreteRectangle, INVALIDATE_NOERASE);
428 rWindow.EnableMapMode(bWasMapModeEnabled);
432 // #110094# ObjectContact section
433 sdr::contact::ObjectContact& SdrPageWindow::GetObjectContact() const
435 if(!mpObjectContact)
437 ((SdrPageWindow*)this)->mpObjectContact = ((SdrPageWindow*)this)->CreateViewSpecificObjectContact();
440 return *mpObjectContact;
443 bool SdrPageWindow::HasObjectContact() const
445 return ( mpObjectContact != NULL );
448 // #i26631#
449 void SdrPageWindow::ResetObjectContact()
451 if(mpObjectContact)
453 delete mpObjectContact;
454 mpObjectContact = 0L;
458 void SdrPageWindow::SetDesignMode( bool _bDesignMode ) const
460 const ::sdr::contact::ObjectContactOfPageView* pOC = dynamic_cast< const ::sdr::contact::ObjectContactOfPageView* >( &GetObjectContact() );
461 DBG_ASSERT( pOC, "SdrPageWindow::SetDesignMode: invalid object contact!" );
462 if ( pOC )
463 pOC->SetUNOControlsDesignMode( _bDesignMode );
466 ////////////////////////////////////////////////////////////////////////////////////////////////////
467 // eof