LCOV - code coverage report
Current view: top level - svx/source/svdraw - sdrpagewindow.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 137 138 99.3 %
Date: 2014-11-03 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 <comphelper/random.hxx>
      27             : #include <vcl/svapp.hxx>
      28             : #include <toolkit/helper/vclunohelper.hxx>
      29             : #include <svx/svdouno.hxx>
      30             : #include <svx/svdpage.hxx>
      31             : #include <svx/svdview.hxx>
      32             : #include <svx/svdpagv.hxx>
      33             : #include <svx/sdrpaintwindow.hxx>
      34             : #include <sdr/contact/objectcontactofpageview.hxx>
      35             : #include <svx/sdr/contact/displayinfo.hxx>
      36             : #include <osl/mutex.hxx>
      37             : #include <svx/fmview.hxx>
      38             : #include <basegfx/matrix/b2dhommatrix.hxx>
      39             : 
      40             : 
      41             : 
      42             : using namespace ::com::sun::star;
      43             : 
      44             : 
      45             : 
      46        4086 : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > SdrPageWindow::GetControlContainer( bool _bCreateIfNecessary ) const
      47             : {
      48        4086 :     if ( !mxControlContainer.is() && _bCreateIfNecessary )
      49             :     {
      50        1503 :         SdrView& rView = GetPageView().GetView();
      51             : 
      52        1503 :         const SdrPaintWindow& rPaintWindow( GetOriginalPaintWindow() ? *GetOriginalPaintWindow() : GetPaintWindow() );
      53        1503 :         if ( rPaintWindow.OutputToWindow() && !rView.IsPrintPreview() )
      54             :         {
      55        1368 :             vcl::Window& rWindow = dynamic_cast< vcl::Window& >( rPaintWindow.GetOutputDevice() );
      56        1368 :             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        1368 :             uno::Reference< awt::XControl > xControl(mxControlContainer, uno::UNO_QUERY);
      67        1368 :             if(xControl.is())
      68             :             {
      69        1368 :                 uno::Reference< uno::XInterface > xContext = xControl->getContext();
      70        1368 :                 if(!xContext.is())
      71             :                 {
      72        1368 :                     xControl->createPeer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit > (),
      73        1368 :                         ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > () );
      74        1368 :                 }
      75        1368 :             }
      76             :         }
      77             :         else
      78             :         {
      79             :             // Printer and VirtualDevice, or rather: no OutDev
      80         135 :             uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
      81         135 :             const_cast< SdrPageWindow* >( this )->mxControlContainer = uno::Reference< awt::XControlContainer >(xFactory->createInstance("com.sun.star.awt.UnoControlContainer"), uno::UNO_QUERY);
      82         270 :             uno::Reference< awt::XControlModel > xModel(xFactory->createInstance("com.sun.star.awt.UnoControlContainerModel"), uno::UNO_QUERY);
      83         270 :             uno::Reference< awt::XControl > xControl(mxControlContainer, uno::UNO_QUERY);
      84         135 :             if (xControl.is())
      85         135 :                 xControl->setModel(xModel);
      86             : 
      87         135 :             OutputDevice& rOutDev = rPaintWindow.GetOutputDevice();
      88         135 :             Point aPosPix = rOutDev.GetMapMode().GetOrigin();
      89         135 :             Size aSizePix = rOutDev.GetOutputSizePixel();
      90             : 
      91         270 :             uno::Reference< awt::XWindow > xContComp(mxControlContainer, uno::UNO_QUERY);
      92         135 :             if( xContComp.is() )
      93         270 :                 xContComp->setPosSize(aPosPix.X(), aPosPix.Y(), aSizePix.Width(), aSizePix.Height(), awt::PosSize::POSSIZE);
      94             :         }
      95             : 
      96        1503 :         FmFormView* pViewAsFormView = dynamic_cast< FmFormView* >( &rView );
      97        1503 :         if ( pViewAsFormView )
      98        1503 :             pViewAsFormView->InsertControlContainer(mxControlContainer);
      99             :     }
     100        4086 :     return mxControlContainer;
     101             : }
     102             : 
     103        7947 : SdrPageWindow::SdrPageWindow(SdrPageView& rPageView, SdrPaintWindow& rPaintWindow)
     104             : :   mpObjectContact(0L),
     105             :     mrPageView(rPageView),
     106             :     mpPaintWindow(&rPaintWindow),
     107        7947 :     mpOriginalPaintWindow(NULL)
     108             : {
     109        7947 : }
     110             : 
     111       15834 : SdrPageWindow::~SdrPageWindow()
     112             : {
     113             :     // #i26631#
     114        7917 :     ResetObjectContact();
     115             : 
     116        7917 :     if (mxControlContainer.is())
     117             :     {
     118        1503 :         SdrView& rView = GetPageView().GetView();
     119             : 
     120             :         // notify derived views
     121        1503 :         FmFormView* pViewAsFormView = dynamic_cast< FmFormView* >( &rView );
     122        1503 :         if ( pViewAsFormView )
     123        1503 :             pViewAsFormView->RemoveControlContainer(mxControlContainer);
     124             : 
     125             :         // dispose the control container
     126        1503 :         uno::Reference< lang::XComponent > xComponent(mxControlContainer, uno::UNO_QUERY);
     127        1503 :         xComponent->dispose();
     128             :     }
     129        7917 : }
     130             : 
     131             : // ObjectContact section
     132        3197 : sdr::contact::ObjectContact* SdrPageWindow::CreateViewSpecificObjectContact()
     133             : {
     134        3197 :     return new sdr::contact::ObjectContactOfPageView(*this);
     135             : }
     136             : 
     137             : // OVERLAY MANAGER
     138        8188 : rtl::Reference< ::sdr::overlay::OverlayManager > SdrPageWindow::GetOverlayManager() const
     139             : {
     140        8188 :     return GetPaintWindow().GetOverlayManager();
     141             : }
     142             : 
     143       41659 : void SdrPageWindow::patchPaintWindow(SdrPaintWindow& rPaintWindow)
     144             : {
     145       41659 :     mpOriginalPaintWindow = mpPaintWindow;
     146       41659 :     mpPaintWindow = &rPaintWindow;
     147       41659 : }
     148             : 
     149       41659 : void SdrPageWindow::unpatchPaintWindow()
     150             : {
     151             :     DBG_ASSERT(mpOriginalPaintWindow, "SdrPageWindow::unpatchPaintWindow: paint window not patched!" );
     152       41659 :     if ( mpOriginalPaintWindow )
     153             :     {
     154       41659 :         mpPaintWindow = mpOriginalPaintWindow;
     155       41659 :         mpOriginalPaintWindow = NULL;
     156             :     }
     157       41659 : }
     158             : 
     159       43601 : void SdrPageWindow::PrePaint()
     160             : {
     161             :     // give OC the chance to do ProcessDisplay preparations
     162       43601 :     if(HasObjectContact())
     163             :     {
     164        9997 :         GetObjectContact().PrepareProcessDisplay();
     165             :     }
     166       43601 : }
     167             : 
     168       15382 : void SdrPageWindow::PrepareRedraw(const vcl::Region& rReg)
     169             : {
     170             :     // give OC the chance to do ProcessDisplay preparations
     171       15382 :     if(HasObjectContact())
     172             :     {
     173       12301 :         GetObjectContact().PrepareProcessDisplay();
     174             :     }
     175             : 
     176             :     // if necessary, remember changed RedrawArea at PaintWindow for usage with
     177             :     // overlay and PreRenderDevice stuff
     178       15382 :     GetPaintWindow().SetRedrawRegion(rReg);
     179       15382 : }
     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             :                         int nR = comphelper::rng::uniform_int_distribution(0, 254);
     258             :                         int nG = comphelper::rng::uniform_int_distribution(0, 254);
     259             :                         int nB = comphelper::rng::uniform_int_distribution(0, 254);
     260             :                         Color aColor(nR, nG, nB);
     261             :                         impPaintStrokePolygon(aResult.getB2DPolygon(a), rOutDev, aColor);
     262             :                     }
     263             :                 }
     264             :             }
     265             :         }
     266             :     }
     267             : } // end of anonymous namespace
     268             : #endif // CLIPPER_TEST
     269             : 
     270             : 
     271             : 
     272        1019 : void SdrPageWindow::RedrawAll(sdr::contact::ViewObjectContactRedirector* pRedirector) const
     273             : {
     274             :     // set Redirector
     275        1019 :     GetObjectContact().SetViewObjectContactRedirector(pRedirector);
     276             : 
     277             :     // set PaintingPageView
     278        1019 :     const SdrView& rView = mrPageView.GetView();
     279        1019 :     SdrModel& rModel = *((SdrModel*)rView.GetModel());
     280             : 
     281             :     // get to be processed layers
     282        1019 :     const bool bPrinter(GetPaintWindow().OutputToPrinter());
     283        1019 :     SetOfByte aProcessLayers = bPrinter ? mrPageView.GetPrintableLayers() : mrPageView.GetVisibleLayers();
     284             : 
     285             :     // create PaintInfoRec; use Rectangle only temporarily
     286        1019 :     const vcl::Region& rRegion = GetPaintWindow().GetRedrawRegion();
     287             : 
     288             :     // create processing data
     289        1019 :     sdr::contact::DisplayInfo aDisplayInfo;
     290             : 
     291             :     // Draw all layers. do NOT draw form layer from CompleteRedraw, this is done separately
     292             :     // as a single layer paint
     293        1019 :     const SdrLayerAdmin& rLayerAdmin = rModel.GetLayerAdmin();
     294        1019 :     const SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID(rLayerAdmin.GetControlLayerName(), false);
     295        1019 :     aProcessLayers.Clear(nControlLayerId);
     296             : 
     297             :     // still something to paint?
     298        1019 :     if(!aProcessLayers.IsEmpty())
     299             :     {
     300        1019 :         aDisplayInfo.SetProcessLayers(aProcessLayers);
     301             : 
     302             :         // Set region as redraw area
     303        1019 :         aDisplayInfo.SetRedrawArea(rRegion);
     304             : 
     305             :         // Draw/Impress
     306        1019 :         aDisplayInfo.SetPageProcessingActive(rView.IsPagePaintingAllowed()); // #i72889#
     307             : 
     308             :         // paint page
     309        1019 :         GetObjectContact().ProcessDisplay(aDisplayInfo);
     310             :     }
     311             : 
     312             :     // reset redirector
     313        1019 :     GetObjectContact().SetViewObjectContactRedirector(0L);
     314             : 
     315             :     // LineClip test
     316             : #ifdef CLIPPER_TEST
     317             :     if(true)
     318             :     {
     319             :         impTryTest(GetPageView(), GetPaintWindow().GetOutputDevice());
     320             :     }
     321             : #endif // CLIPPER_TEST
     322        1019 : }
     323             : 
     324       44116 : void SdrPageWindow::RedrawLayer(const SdrLayerID* pId, sdr::contact::ViewObjectContactRedirector* pRedirector) const
     325             : {
     326             :     // set redirector
     327       44116 :     GetObjectContact().SetViewObjectContactRedirector(pRedirector);
     328             : 
     329             :     // set PaintingPageView
     330       44116 :     const SdrView& rView = mrPageView.GetView();
     331       44116 :     SdrModel& rModel = *((SdrModel*)rView.GetModel());
     332             : 
     333             :     // get the layers to process
     334       44116 :     const bool bPrinter(GetPaintWindow().OutputToPrinter());
     335       44116 :     SetOfByte aProcessLayers = bPrinter ? mrPageView.GetPrintableLayers() : mrPageView.GetVisibleLayers();
     336             : 
     337             :     // is the given layer visible at all?
     338       44116 :     if(aProcessLayers.IsSet(*pId))
     339             :     {
     340             :         // find out if we are painting the ControlLayer
     341       44116 :         const SdrLayerAdmin& rLayerAdmin = rModel.GetLayerAdmin();
     342       44116 :         const SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID(rLayerAdmin.GetControlLayerName(), false);
     343       44116 :         const bool bControlLayerProcessingActive(nControlLayerId == *pId);
     344             : 
     345             :         // create PaintInfoRec, use Rectangle only temporarily
     346       44116 :         const vcl::Region& rRegion = GetPaintWindow().GetRedrawRegion();
     347             : 
     348             :         // create processing data
     349       44116 :         sdr::contact::DisplayInfo aDisplayInfo;
     350             : 
     351             :         // is it the control layer? If Yes, set flag
     352       44116 :         aDisplayInfo.SetControlLayerProcessingActive(bControlLayerProcessingActive);
     353             : 
     354             :         // Draw just the one given layer
     355       44116 :         aProcessLayers.ClearAll();
     356       44116 :         aProcessLayers.Set(*pId);
     357             : 
     358       44116 :         aDisplayInfo.SetProcessLayers(aProcessLayers);
     359             : 
     360             :         // Set region as redraw area
     361       44116 :         aDisplayInfo.SetRedrawArea(rRegion);
     362             : 
     363             :         // Writer or calc, coming from original RedrawOneLayer.
     364             :         // #i72889# no page painting for layer painting
     365       44116 :         aDisplayInfo.SetPageProcessingActive(false);
     366             : 
     367             :         // paint page
     368       44116 :         GetObjectContact().ProcessDisplay(aDisplayInfo);
     369             :     }
     370             : 
     371             :     // reset redirector
     372       44116 :     GetObjectContact().SetViewObjectContactRedirector(0L);
     373       44116 : }
     374             : 
     375             : // Invalidate call, used from ObjectContact(OfPageView) in InvalidatePartOfView(...)
     376       24000 : void SdrPageWindow::InvalidatePageWindow(const basegfx::B2DRange& rRange)
     377             : {
     378       24000 :     if(GetPageView().IsVisible() && GetPaintWindow().OutputToWindow())
     379             :     {
     380       23917 :         const SvtOptionsDrawinglayer aDrawinglayerOpt;
     381       23917 :         vcl::Window& rWindow(static_cast< vcl::Window& >(GetPaintWindow().GetOutputDevice()));
     382       23917 :         basegfx::B2DRange aDiscreteRange(rRange);
     383       23917 :         aDiscreteRange.transform(rWindow.GetViewTransformation());
     384             : 
     385       23917 :         if(aDrawinglayerOpt.IsAntiAliasing())
     386             :         {
     387             :             // invalidate one discrete unit more under the assumption that AA
     388             :             // needs one pixel more
     389           0 :             aDiscreteRange.grow(1.0);
     390             :         }
     391             : 
     392             :         const Rectangle aVCLDiscreteRectangle(
     393       23917 :             static_cast<long>(floor(aDiscreteRange.getMinX())),
     394       23917 :             static_cast<long>(floor(aDiscreteRange.getMinY())),
     395       23917 :             static_cast<long>(ceil(aDiscreteRange.getMaxX())),
     396       95668 :             static_cast<long>(ceil(aDiscreteRange.getMaxY())));
     397       23917 :         const bool bWasMapModeEnabled(rWindow.IsMapModeEnabled());
     398             : 
     399       23917 :         rWindow.EnableMapMode(false);
     400       23917 :         rWindow.Invalidate(aVCLDiscreteRectangle, INVALIDATE_NOERASE);
     401       23917 :         rWindow.EnableMapMode(bWasMapModeEnabled);
     402             :     }
     403       24000 : }
     404             : 
     405             : // ObjectContact section
     406      158523 : sdr::contact::ObjectContact& SdrPageWindow::GetObjectContact() const
     407             : {
     408      158523 :     if(!mpObjectContact)
     409             :     {
     410        3197 :         ((SdrPageWindow*)this)->mpObjectContact = ((SdrPageWindow*)this)->CreateViewSpecificObjectContact();
     411             :     }
     412             : 
     413      158523 :     return *mpObjectContact;
     414             : }
     415             : 
     416       59975 : bool SdrPageWindow::HasObjectContact() const
     417             : {
     418       59975 :     return ( mpObjectContact != NULL );
     419             : }
     420             : 
     421             : // #i26631#
     422        7917 : void SdrPageWindow::ResetObjectContact()
     423             : {
     424        7917 :     if(mpObjectContact)
     425             :     {
     426        3174 :         delete mpObjectContact;
     427        3174 :         mpObjectContact = 0L;
     428             :     }
     429        7917 : }
     430             : 
     431          46 : void SdrPageWindow::SetDesignMode( bool _bDesignMode ) const
     432             : {
     433          46 :     const ::sdr::contact::ObjectContactOfPageView* pOC = dynamic_cast< const ::sdr::contact::ObjectContactOfPageView* >( &GetObjectContact() );
     434             :     DBG_ASSERT( pOC, "SdrPageWindow::SetDesignMode: invalid object contact!" );
     435          46 :     if ( pOC )
     436          46 :         pOC->SetUNOControlsDesignMode( _bDesignMode );
     437         697 : }
     438             : 
     439             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10