LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/svx/source/svdraw - sdrpagewindow.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 135 136 99.3 %
Date: 2013-07-09 Functions: 18 18 100.0 %
Legend: Lines: hit not hit

          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             : #include <svx/sdrpagewindow.hxx>
      21             : #include <com/sun/star/awt/XWindow.hpp>
      22             : #include <com/sun/star/beans/XPropertySet.hpp>
      23             : #include <com/sun/star/awt/PosSize.hpp>
      24             : #include <com/sun/star/util/XModeChangeBroadcaster.hpp>
      25             : #include <comphelper/processfactory.hxx>
      26             : #include <vcl/svapp.hxx>
      27             : #include <toolkit/helper/vclunohelper.hxx>
      28             : #include <svx/svdouno.hxx>
      29             : #include <svx/svdpage.hxx>
      30             : #include <svx/svdview.hxx>
      31             : #include <svx/svdpagv.hxx>
      32             : #include <svx/sdrpaintwindow.hxx>
      33             : #include <svx/sdr/contact/objectcontactofpageview.hxx>
      34             : #include <svx/sdr/contact/displayinfo.hxx>
      35             : #include <osl/mutex.hxx>
      36             : #include <svx/fmview.hxx>
      37             : #include <basegfx/matrix/b2dhommatrix.hxx>
      38             : 
      39             : ////////////////////////////////////////////////////////////////////////////////////////////////////
      40             : 
      41             : using namespace ::rtl;
      42             : using namespace ::com::sun::star;
      43             : 
      44             : ////////////////////////////////////////////////////////////////////////////////////////////////////
      45             : 
      46        1316 : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > SdrPageWindow::GetControlContainer( bool _bCreateIfNecessary ) const
      47             : {
      48        1316 :     if ( !mxControlContainer.is() && _bCreateIfNecessary )
      49             :     {
      50         480 :         SdrView& rView = GetPageView().GetView();
      51             : 
      52         480 :         const SdrPaintWindow& rPaintWindow( GetOriginalPaintWindow() ? *GetOriginalPaintWindow() : GetPaintWindow() );
      53         480 :         if ( rPaintWindow.OutputToWindow() && !rView.IsPrintPreview() )
      54             :         {
      55         471 :             Window& rWindow = dynamic_cast< Window& >( rPaintWindow.GetOutputDevice() );
      56         471 :             const_cast< SdrPageWindow* >( this )->mxControlContainer = VCLUnoHelper::CreateControlContainer( &rWindow );
      57             : 
      58             :             // #100394# xC->setVisible triggers window->Show() and this has
      59             :             // problems when the view is not completely constructed which may
      60             :             // happen when loading. This leads to accessibility broadcasts which
      61             :             // throw asserts due to the not finished view. All this chain can be avoided
      62             :             // since xC->setVisible is here called only for the side effect in
      63             :             // UnoControlContainer::setVisible(...) which calls createPeer(...).
      64             :             // This will now be called directly from here.
      65             : 
      66         471 :             uno::Reference< awt::XControl > xControl(mxControlContainer, uno::UNO_QUERY);
      67         471 :             if(xControl.is())
      68             :             {
      69         471 :                 uno::Reference< uno::XInterface > xContext = xControl->getContext();
      70         471 :                 if(!xContext.is())
      71             :                 {
      72         471 :                     xControl->createPeer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit > (),
      73         471 :                         ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > () );
      74         471 :                 }
      75         471 :             }
      76             :         }
      77             :         else
      78             :         {
      79             :             // Printer and VirtualDevice, or rather: no OutDev
      80           9 :             uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
      81           9 :             const_cast< SdrPageWindow* >( this )->mxControlContainer = uno::Reference< awt::XControlContainer >(xFactory->createInstance("com.sun.star.awt.UnoControlContainer"), uno::UNO_QUERY);
      82          18 :             uno::Reference< awt::XControlModel > xModel(xFactory->createInstance("com.sun.star.awt.UnoControlContainerModel"), uno::UNO_QUERY);
      83          18 :             uno::Reference< awt::XControl > xControl(mxControlContainer, uno::UNO_QUERY);
      84           9 :             if (xControl.is())
      85           9 :                 xControl->setModel(xModel);
      86             : 
      87           9 :             OutputDevice& rOutDev = rPaintWindow.GetOutputDevice();
      88           9 :             Point aPosPix = rOutDev.GetMapMode().GetOrigin();
      89           9 :             Size aSizePix = rOutDev.GetOutputSizePixel();
      90             : 
      91          18 :             uno::Reference< awt::XWindow > xContComp(mxControlContainer, uno::UNO_QUERY);
      92           9 :             if( xContComp.is() )
      93          18 :                 xContComp->setPosSize(aPosPix.X(), aPosPix.Y(), aSizePix.Width(), aSizePix.Height(), awt::PosSize::POSSIZE);
      94             :         }
      95             : 
      96         480 :         FmFormView* pViewAsFormView = dynamic_cast< FmFormView* >( &rView );
      97         480 :         if ( pViewAsFormView )
      98         480 :             pViewAsFormView->InsertControlContainer(mxControlContainer);
      99             :     }
     100        1316 :     return mxControlContainer;
     101             : }
     102             : 
     103        1913 : SdrPageWindow::SdrPageWindow(SdrPageView& rPageView, SdrPaintWindow& rPaintWindow)
     104             : :   mpObjectContact(0L),
     105             :     mrPageView(rPageView),
     106             :     mpPaintWindow(&rPaintWindow),
     107        1913 :     mpOriginalPaintWindow(NULL)
     108             : {
     109        1913 : }
     110             : 
     111        3820 : SdrPageWindow::~SdrPageWindow()
     112             : {
     113             :     // #i26631#
     114        1910 :     ResetObjectContact();
     115             : 
     116        1910 :     if (mxControlContainer.is())
     117             :     {
     118         479 :         SdrView& rView = GetPageView().GetView();
     119             : 
     120             :         // notify derived views
     121         479 :         FmFormView* pViewAsFormView = dynamic_cast< FmFormView* >( &rView );
     122         479 :         if ( pViewAsFormView )
     123         479 :             pViewAsFormView->RemoveControlContainer(mxControlContainer);
     124             : 
     125             :         // dispose the control container
     126         479 :         uno::Reference< lang::XComponent > xComponent(mxControlContainer, uno::UNO_QUERY);
     127         479 :         xComponent->dispose();
     128             :     }
     129        1910 : }
     130             : 
     131             : // ObjectContact section
     132        1214 : sdr::contact::ObjectContact* SdrPageWindow::CreateViewSpecificObjectContact()
     133             : {
     134        1214 :     return new sdr::contact::ObjectContactOfPageView(*this);
     135             : }
     136             : 
     137             : // OVERLAY MANAGER
     138        3855 : rtl::Reference< ::sdr::overlay::OverlayManager > SdrPageWindow::GetOverlayManager() const
     139             : {
     140        3855 :     return GetPaintWindow().GetOverlayManager();
     141             : }
     142             : 
     143       21811 : void SdrPageWindow::patchPaintWindow(SdrPaintWindow& rPaintWindow)
     144             : {
     145       21811 :     mpOriginalPaintWindow = mpPaintWindow;
     146       21811 :     mpPaintWindow = &rPaintWindow;
     147       21811 : }
     148             : 
     149       21811 : void SdrPageWindow::unpatchPaintWindow()
     150             : {
     151             :     DBG_ASSERT(mpOriginalPaintWindow, "SdrPageWindow::unpatchPaintWindow: paint window not patched!" );
     152       21811 :     if ( mpOriginalPaintWindow )
     153             :     {
     154       21811 :         mpPaintWindow = mpOriginalPaintWindow;
     155       21811 :         mpOriginalPaintWindow = NULL;
     156             :     }
     157       21811 : }
     158             : 
     159        7865 : void SdrPageWindow::PrePaint()
     160             : {
     161             :     // give OC the chance to do ProcessDisplay preparations
     162        7865 :     if(HasObjectContact())
     163             :     {
     164        6009 :         GetObjectContact().PrepareProcessDisplay();
     165             :     }
     166        7865 : }
     167             : 
     168        8019 : void SdrPageWindow::PrepareRedraw(const Region& rReg)
     169             : {
     170             :     // give OC the chance to do ProcessDisplay preparations
     171        8019 :     if(HasObjectContact())
     172             :     {
     173        6819 :         GetObjectContact().PrepareProcessDisplay();
     174             :     }
     175             : 
     176             :     // if necessary, remember changed RedrawArea at PaintWindow for usage with
     177             :     // overlay and PreRenderDevice stuff
     178        8019 :     GetPaintWindow().SetRedrawRegion(rReg);
     179        8019 : }
     180             : 
     181             : //////////////////////////////////////////////////////////////////////////////
     182             : // clip test
     183             : #ifdef CLIPPER_TEST
     184             : #include <svx/svdopath.hxx>
     185             : #include <basegfx/polygon/b2dpolygon.hxx>
     186             : #include <tools/helpers.hxx>
     187             : #include <basegfx/polygon/b2dpolygoncutandtouch.hxx>
     188             : #include <basegfx/polygon/b2dpolypolygontools.hxx>
     189             : #include <basegfx/polygon/b2dpolygontools.hxx>
     190             : #include <basegfx/polygon/b2dpolygonclipper.hxx>
     191             : 
     192             : // for ::std::sort
     193             : #include <algorithm>
     194             : 
     195             : namespace
     196             : {
     197             :     void impPaintStrokePolygon(const basegfx::B2DPolygon& rCandidate, OutputDevice& rOutDev, Color aColor)
     198             :     {
     199             :         basegfx::B2DPolygon aCandidate(rCandidate);
     200             : 
     201             :         if(aCandidate.areControlPointsUsed())
     202             :         {
     203             :             aCandidate = basegfx::tools::adaptiveSubdivideByAngle(rCandidate);
     204             :         }
     205             : 
     206             :         if(aCandidate.count())
     207             :         {
     208             :             const sal_uInt32 nLoopCount(aCandidate.isClosed() ? aCandidate.count() : aCandidate.count() - 1L);
     209             :             rOutDev.SetFillColor();
     210             :             rOutDev.SetLineColor(aColor);
     211             : 
     212             :             for(sal_uInt32 a(0L); a < nLoopCount; a++)
     213             :             {
     214             :                 const basegfx::B2DPoint aBStart(aCandidate.getB2DPoint(a));
     215             :                 const basegfx::B2DPoint aBEnd(aCandidate.getB2DPoint((a + 1) % aCandidate.count()));
     216             :                 const Point aStart(FRound(aBStart.getX()), FRound(aBStart.getY()));
     217             :                 const Point aEnd(FRound(aBEnd.getX()), FRound(aBEnd.getY()));
     218             :                 rOutDev.DrawLine(aStart, aEnd);
     219             :             }
     220             :         }
     221             :     }
     222             : 
     223             :     void impTryTest(const SdrPageView& rPageView, OutputDevice& rOutDev)
     224             :     {
     225             :         if(rPageView.GetPage() && rPageView.GetPage()->GetObjCount() >= 2L)
     226             :         {
     227             :             SdrPage* pPage = rPageView.GetPage();
     228             :             SdrObject* pObjA = pPage->GetObj(0L);
     229             : 
     230             :             if(pObjA && pObjA->ISA(SdrPathObj))
     231             :             {
     232             :                 basegfx::B2DPolyPolygon aPolyA(((SdrPathObj*)pObjA)->GetPathPoly());
     233             :                 aPolyA = basegfx::tools::correctOrientations(aPolyA);
     234             : 
     235             :                 basegfx::B2DPolyPolygon aPolyB;
     236             : 
     237             :                 for(sal_uInt32 a(1L); a < rPageView.GetPage()->GetObjCount(); a++)
     238             :                 {
     239             :                     SdrObject* pObjB = pPage->GetObj(a);
     240             : 
     241             :                     if(pObjB && pObjB->ISA(SdrPathObj))
     242             :                     {
     243             :                         basegfx::B2DPolyPolygon aCandidate(((SdrPathObj*)pObjB)->GetPathPoly());
     244             :                         aCandidate = basegfx::tools::correctOrientations(aCandidate);
     245             :                         aPolyB.append(aCandidate);
     246             :                     }
     247             :                 }
     248             : 
     249             :                 if(aPolyA.count() && aPolyA.isClosed() && aPolyB.count())
     250             :                 {
     251             :                     // poly A is the clipregion, clip poly b against it. Algo depends on
     252             :                     // poly b being closed.
     253             :                     basegfx::B2DPolyPolygon aResult(basegfx::tools::clipPolyPolygonOnPolyPolygon(aPolyB, aPolyA));
     254             : 
     255             :                     for(sal_uInt32 a(0L); a < aResult.count(); a++)
     256             :                     {
     257             :                         Color aColor(rand()%255, rand()%255, rand()%255);
     258             :                         impPaintStrokePolygon(aResult.getB2DPolygon(a), rOutDev, aColor);
     259             :                     }
     260             :                 }
     261             :             }
     262             :         }
     263             :     }
     264             : } // end of anonymous namespace
     265             : #endif // CLIPPER_TEST
     266             : 
     267             : //////////////////////////////////////////////////////////////////////////////
     268             : 
     269         969 : void SdrPageWindow::RedrawAll(sdr::contact::ViewObjectContactRedirector* pRedirector) const
     270             : {
     271             :     // set Redirector
     272         969 :     GetObjectContact().SetViewObjectContactRedirector(pRedirector);
     273             : 
     274             :     // set PaintingPageView
     275         969 :     const SdrView& rView = mrPageView.GetView();
     276         969 :     SdrModel& rModel = *((SdrModel*)rView.GetModel());
     277             : 
     278             :     // get to be processed layers
     279         969 :     const bool bPrinter(GetPaintWindow().OutputToPrinter());
     280         969 :     SetOfByte aProcessLayers = bPrinter ? mrPageView.GetPrintableLayers() : mrPageView.GetVisibleLayers();
     281             : 
     282             :     // create PaintInfoRec; use Rectangle only temporarily
     283         969 :     const Region& rRegion = GetPaintWindow().GetRedrawRegion();
     284             : 
     285             :     // create processing data
     286         969 :     sdr::contact::DisplayInfo aDisplayInfo;
     287             : 
     288             :     // Draw all layers. do NOT draw form layer from CompleteRedraw, this is done separately
     289             :     // as a single layer paint
     290         969 :     const SdrLayerAdmin& rLayerAdmin = rModel.GetLayerAdmin();
     291         969 :     const SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID(rLayerAdmin.GetControlLayerName(), sal_False);
     292         969 :     aProcessLayers.Clear(nControlLayerId);
     293             : 
     294             :     // still something to paint?
     295         969 :     if(!aProcessLayers.IsEmpty())
     296             :     {
     297         969 :         aDisplayInfo.SetProcessLayers(aProcessLayers);
     298             : 
     299             :         // Set region as redraw area
     300         969 :         aDisplayInfo.SetRedrawArea(rRegion);
     301             : 
     302             :         // Draw/Impress
     303         969 :         aDisplayInfo.SetPageProcessingActive(rView.IsPagePaintingAllowed()); // #i72889#
     304             : 
     305             :         // paint page
     306         969 :         GetObjectContact().ProcessDisplay(aDisplayInfo);
     307             :     }
     308             : 
     309             :     // reset redirector
     310         969 :     GetObjectContact().SetViewObjectContactRedirector(0L);
     311             : 
     312             :     // LineClip test
     313             : #ifdef CLIPPER_TEST
     314             :     if(true)
     315             :     {
     316             :         impTryTest(GetPageView(), GetPaintWindow().GetOutputDevice());
     317             :     }
     318             : #endif // CLIPPER_TEST
     319         969 : }
     320             : 
     321       22145 : void SdrPageWindow::RedrawLayer(const SdrLayerID* pId, sdr::contact::ViewObjectContactRedirector* pRedirector) const
     322             : {
     323             :     // set redirector
     324       22145 :     GetObjectContact().SetViewObjectContactRedirector(pRedirector);
     325             : 
     326             :     // set PaintingPageView
     327       22145 :     const SdrView& rView = mrPageView.GetView();
     328       22145 :     SdrModel& rModel = *((SdrModel*)rView.GetModel());
     329             : 
     330             :     // get the layers to process
     331       22145 :     const bool bPrinter(GetPaintWindow().OutputToPrinter());
     332       22145 :     SetOfByte aProcessLayers = bPrinter ? mrPageView.GetPrintableLayers() : mrPageView.GetVisibleLayers();
     333             : 
     334             :     // is the given layer visible at all?
     335       22145 :     if(aProcessLayers.IsSet(*pId))
     336             :     {
     337             :         // find out if we are painting the ControlLayer
     338       22145 :         const SdrLayerAdmin& rLayerAdmin = rModel.GetLayerAdmin();
     339       22145 :         const SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID(rLayerAdmin.GetControlLayerName(), sal_False);
     340       22145 :         const bool bControlLayerProcessingActive(pId && nControlLayerId == *pId);
     341             : 
     342             :         // create PaintInfoRec, use Rectangle only temporarily
     343       22145 :         const Region& rRegion = GetPaintWindow().GetRedrawRegion();
     344             : 
     345             :         // create processing data
     346       22145 :         sdr::contact::DisplayInfo aDisplayInfo;
     347             : 
     348             :         // is it the control layer? If Yes, set flag
     349       22145 :         aDisplayInfo.SetControlLayerProcessingActive(bControlLayerProcessingActive);
     350             : 
     351             :         // Draw just the one given layer
     352       22145 :         aProcessLayers.ClearAll();
     353       22145 :         aProcessLayers.Set(*pId);
     354             : 
     355       22145 :         aDisplayInfo.SetProcessLayers(aProcessLayers);
     356             : 
     357             :         // Set region as redraw area
     358       22145 :         aDisplayInfo.SetRedrawArea(rRegion);
     359             : 
     360             :         // Writer or calc, coming from original RedrawOneLayer.
     361             :         // #i72889# no page painting for layer painting
     362       22145 :         aDisplayInfo.SetPageProcessingActive(false);
     363             : 
     364             :         // paint page
     365       22145 :         GetObjectContact().ProcessDisplay(aDisplayInfo);
     366             :     }
     367             : 
     368             :     // reset redirector
     369       22145 :     GetObjectContact().SetViewObjectContactRedirector(0L);
     370       22145 : }
     371             : 
     372             : // Invalidate call, used from ObjectContact(OfPageView) in InvalidatePartOfView(...)
     373        9986 : void SdrPageWindow::InvalidatePageWindow(const basegfx::B2DRange& rRange)
     374             : {
     375        9986 :     if(GetPageView().IsVisible() && GetPaintWindow().OutputToWindow())
     376             :     {
     377        9901 :         const SvtOptionsDrawinglayer aDrawinglayerOpt;
     378        9901 :         Window& rWindow(static_cast< Window& >(GetPaintWindow().GetOutputDevice()));
     379        9901 :         basegfx::B2DRange aDiscreteRange(rRange);
     380        9901 :         aDiscreteRange.transform(rWindow.GetViewTransformation());
     381             : 
     382        9901 :         if(aDrawinglayerOpt.IsAntiAliasing())
     383             :         {
     384             :             // invalidate one discrete unit more under the assumption that AA
     385             :             // needs one pixel more
     386           0 :             aDiscreteRange.grow(1.0);
     387             :         }
     388             : 
     389             :         const Rectangle aVCLDiscreteRectangle(
     390       19802 :                 (sal_Int32)floor(aDiscreteRange.getMinX()), (sal_Int32)floor(aDiscreteRange.getMinY()),
     391       29703 :                 (sal_Int32)ceil(aDiscreteRange.getMaxX()), (sal_Int32)ceil(aDiscreteRange.getMaxY()));
     392        9901 :         const bool bWasMapModeEnabled(rWindow.IsMapModeEnabled());
     393             : 
     394        9901 :         rWindow.EnableMapMode(false);
     395        9901 :         rWindow.Invalidate(aVCLDiscreteRectangle, INVALIDATE_NOERASE);
     396        9901 :         rWindow.EnableMapMode(bWasMapModeEnabled);
     397             :     }
     398        9986 : }
     399             : 
     400             : // ObjectContact section
     401       82702 : sdr::contact::ObjectContact& SdrPageWindow::GetObjectContact() const
     402             : {
     403       82702 :     if(!mpObjectContact)
     404             :     {
     405        1214 :         ((SdrPageWindow*)this)->mpObjectContact = ((SdrPageWindow*)this)->CreateViewSpecificObjectContact();
     406             :     }
     407             : 
     408       82702 :     return *mpObjectContact;
     409             : }
     410             : 
     411       16344 : bool SdrPageWindow::HasObjectContact() const
     412             : {
     413       16344 :     return ( mpObjectContact != NULL );
     414             : }
     415             : 
     416             : // #i26631#
     417        1910 : void SdrPageWindow::ResetObjectContact()
     418             : {
     419        1910 :     if(mpObjectContact)
     420             :     {
     421        1214 :         delete mpObjectContact;
     422        1214 :         mpObjectContact = 0L;
     423             :     }
     424        1910 : }
     425             : 
     426           6 : void SdrPageWindow::SetDesignMode( bool _bDesignMode ) const
     427             : {
     428           6 :     const ::sdr::contact::ObjectContactOfPageView* pOC = dynamic_cast< const ::sdr::contact::ObjectContactOfPageView* >( &GetObjectContact() );
     429             :     DBG_ASSERT( pOC, "SdrPageWindow::SetDesignMode: invalid object contact!" );
     430           6 :     if ( pOC )
     431           6 :         pOC->SetUNOControlsDesignMode( _bDesignMode );
     432         264 : }
     433             : 
     434             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10