LCOV - code coverage report
Current view: top level - libreoffice/svx/source/svdraw - sdrpagewindow.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 98 138 71.0 %
Date: 2012-12-27 Functions: 13 16 81.2 %
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          38 : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > SdrPageWindow::GetControlContainer( bool _bCreateIfNecessary ) const
      47             : {
      48          38 :     if ( !mxControlContainer.is() && _bCreateIfNecessary )
      49             :     {
      50           9 :         SdrView& rView = GetPageView().GetView();
      51             : 
      52           9 :         const SdrPaintWindow& rPaintWindow( GetOriginalPaintWindow() ? *GetOriginalPaintWindow() : GetPaintWindow() );
      53           9 :         if ( rPaintWindow.OutputToWindow() && !rView.IsPrintPreview() )
      54             :         {
      55           9 :             Window& rWindow = dynamic_cast< Window& >( rPaintWindow.GetOutputDevice() );
      56          18 :             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           9 :             uno::Reference< awt::XControl > xControl(mxControlContainer, uno::UNO_QUERY);
      67           9 :             if(xControl.is())
      68             :             {
      69           9 :                 uno::Reference< uno::XInterface > xContext = xControl->getContext();
      70           9 :                 if(!xContext.is())
      71             :                 {
      72           9 :                     xControl->createPeer( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit > (),
      73           9 :                         ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > () );
      74           9 :                 }
      75           9 :             }
      76             :         }
      77             :         else
      78             :         {
      79             :             // Printer and VirtualDevice, or rather: no OutDev
      80           0 :             uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
      81           0 :             if( xFactory.is() )
      82             :             {
      83           0 :                 const_cast< SdrPageWindow* >( this )->mxControlContainer = uno::Reference< awt::XControlContainer >(xFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlContainer"))), uno::UNO_QUERY);
      84           0 :                 uno::Reference< awt::XControlModel > xModel(xFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlContainerModel"))), uno::UNO_QUERY);
      85           0 :                 uno::Reference< awt::XControl > xControl(mxControlContainer, uno::UNO_QUERY);
      86           0 :                 if (xControl.is())
      87           0 :                     xControl->setModel(xModel);
      88             : 
      89           0 :                 OutputDevice& rOutDev = rPaintWindow.GetOutputDevice();
      90           0 :                 Point aPosPix = rOutDev.GetMapMode().GetOrigin();
      91           0 :                 Size aSizePix = rOutDev.GetOutputSizePixel();
      92             : 
      93           0 :                 uno::Reference< awt::XWindow > xContComp(mxControlContainer, uno::UNO_QUERY);
      94           0 :                 if( xContComp.is() )
      95           0 :                     xContComp->setPosSize(aPosPix.X(), aPosPix.Y(), aSizePix.Width(), aSizePix.Height(), awt::PosSize::POSSIZE);
      96           0 :             }
      97             :         }
      98             : 
      99           9 :         FmFormView* pViewAsFormView = dynamic_cast< FmFormView* >( &rView );
     100           9 :         if ( pViewAsFormView )
     101           9 :             pViewAsFormView->InsertControlContainer(mxControlContainer);
     102             :     }
     103          38 :     return mxControlContainer;
     104             : }
     105             : 
     106         252 : SdrPageWindow::SdrPageWindow(SdrPageView& rPageView, SdrPaintWindow& rPaintWindow)
     107             : :   mpObjectContact(0L),
     108             :     mrPageView(rPageView),
     109             :     mpPaintWindow(&rPaintWindow),
     110         252 :     mpOriginalPaintWindow(NULL)
     111             : {
     112         252 : }
     113             : 
     114         158 : SdrPageWindow::~SdrPageWindow()
     115             : {
     116             :     // #i26631#
     117          79 :     ResetObjectContact();
     118             : 
     119          79 :     if (mxControlContainer.is())
     120             :     {
     121           2 :         SdrView& rView = GetPageView().GetView();
     122             : 
     123             :         // notify derived views
     124           2 :         FmFormView* pViewAsFormView = dynamic_cast< FmFormView* >( &rView );
     125           2 :         if ( pViewAsFormView )
     126           2 :             pViewAsFormView->RemoveControlContainer(mxControlContainer);
     127             : 
     128             :         // dispose the control container
     129           2 :         uno::Reference< lang::XComponent > xComponent(mxControlContainer, uno::UNO_QUERY);
     130           2 :         xComponent->dispose();
     131             :     }
     132          79 : }
     133             : 
     134             : // ObjectContact section
     135         134 : sdr::contact::ObjectContact* SdrPageWindow::CreateViewSpecificObjectContact()
     136             : {
     137         134 :     return new sdr::contact::ObjectContactOfPageView(*this);
     138             : }
     139             : 
     140             : // OVERLAY MANAGER
     141           0 : rtl::Reference< ::sdr::overlay::OverlayManager > SdrPageWindow::GetOverlayManager() const
     142             : {
     143           0 :     return GetPaintWindow().GetOverlayManager();
     144             : }
     145             : 
     146         806 : void SdrPageWindow::patchPaintWindow(SdrPaintWindow& rPaintWindow)
     147             : {
     148         806 :     mpOriginalPaintWindow = mpPaintWindow;
     149         806 :     mpPaintWindow = &rPaintWindow;
     150         806 : }
     151             : 
     152         806 : void SdrPageWindow::unpatchPaintWindow()
     153             : {
     154             :     DBG_ASSERT(mpOriginalPaintWindow, "SdrPageWindow::unpatchPaintWindow: paint window not patched!" );
     155         806 :     if ( mpOriginalPaintWindow )
     156             :     {
     157         806 :         mpPaintWindow = mpOriginalPaintWindow;
     158         806 :         mpOriginalPaintWindow = NULL;
     159             :     }
     160         806 : }
     161             : 
     162        1049 : void SdrPageWindow::PrePaint()
     163             : {
     164             :     // give OC the chance to do ProcessDisplay preparations
     165        1049 :     if(HasObjectContact())
     166             :     {
     167         287 :         GetObjectContact().PrepareProcessDisplay();
     168             :     }
     169        1049 : }
     170             : 
     171         265 : void SdrPageWindow::PrepareRedraw(const Region& rReg)
     172             : {
     173             :     // give OC the chance to do ProcessDisplay preparations
     174         265 :     if(HasObjectContact())
     175             :     {
     176         140 :         GetObjectContact().PrepareProcessDisplay();
     177             :     }
     178             : 
     179             :     // if necessary, remember changed RedrawArea at PaintWindow for usage with
     180             :     // overlay and PreRenderDevice stuff
     181         265 :     GetPaintWindow().SetRedrawRegion(rReg);
     182         265 : }
     183             : 
     184             : //////////////////////////////////////////////////////////////////////////////
     185             : // clip test
     186             : #ifdef CLIPPER_TEST
     187             : #include <svx/svdopath.hxx>
     188             : #include <basegfx/polygon/b2dpolygon.hxx>
     189             : #include <tools/helpers.hxx>
     190             : #include <basegfx/polygon/b2dpolygoncutandtouch.hxx>
     191             : #include <basegfx/polygon/b2dpolypolygontools.hxx>
     192             : #include <basegfx/polygon/b2dpolygontools.hxx>
     193             : #include <basegfx/polygon/b2dpolygonclipper.hxx>
     194             : 
     195             : // for ::std::sort
     196             : #include <algorithm>
     197             : 
     198             : namespace
     199             : {
     200             :     void impPaintStrokePolygon(const basegfx::B2DPolygon& rCandidate, OutputDevice& rOutDev, Color aColor)
     201             :     {
     202             :         basegfx::B2DPolygon aCandidate(rCandidate);
     203             : 
     204             :         if(aCandidate.areControlPointsUsed())
     205             :         {
     206             :             aCandidate = basegfx::tools::adaptiveSubdivideByAngle(rCandidate);
     207             :         }
     208             : 
     209             :         if(aCandidate.count())
     210             :         {
     211             :             const sal_uInt32 nLoopCount(aCandidate.isClosed() ? aCandidate.count() : aCandidate.count() - 1L);
     212             :             rOutDev.SetFillColor();
     213             :             rOutDev.SetLineColor(aColor);
     214             : 
     215             :             for(sal_uInt32 a(0L); a < nLoopCount; a++)
     216             :             {
     217             :                 const basegfx::B2DPoint aBStart(aCandidate.getB2DPoint(a));
     218             :                 const basegfx::B2DPoint aBEnd(aCandidate.getB2DPoint((a + 1) % aCandidate.count()));
     219             :                 const Point aStart(FRound(aBStart.getX()), FRound(aBStart.getY()));
     220             :                 const Point aEnd(FRound(aBEnd.getX()), FRound(aBEnd.getY()));
     221             :                 rOutDev.DrawLine(aStart, aEnd);
     222             :             }
     223             :         }
     224             :     }
     225             : 
     226             :     void impTryTest(const SdrPageView& rPageView, OutputDevice& rOutDev)
     227             :     {
     228             :         if(rPageView.GetPage() && rPageView.GetPage()->GetObjCount() >= 2L)
     229             :         {
     230             :             SdrPage* pPage = rPageView.GetPage();
     231             :             SdrObject* pObjA = pPage->GetObj(0L);
     232             : 
     233             :             if(pObjA && pObjA->ISA(SdrPathObj))
     234             :             {
     235             :                 basegfx::B2DPolyPolygon aPolyA(((SdrPathObj*)pObjA)->GetPathPoly());
     236             :                 aPolyA = basegfx::tools::correctOrientations(aPolyA);
     237             : 
     238             :                 basegfx::B2DPolyPolygon aPolyB;
     239             : 
     240             :                 for(sal_uInt32 a(1L); a < rPageView.GetPage()->GetObjCount(); a++)
     241             :                 {
     242             :                     SdrObject* pObjB = pPage->GetObj(a);
     243             : 
     244             :                     if(pObjB && pObjB->ISA(SdrPathObj))
     245             :                     {
     246             :                         basegfx::B2DPolyPolygon aCandidate(((SdrPathObj*)pObjB)->GetPathPoly());
     247             :                         aCandidate = basegfx::tools::correctOrientations(aCandidate);
     248             :                         aPolyB.append(aCandidate);
     249             :                     }
     250             :                 }
     251             : 
     252             :                 if(aPolyA.count() && aPolyA.isClosed() && aPolyB.count())
     253             :                 {
     254             :                     // poly A is the clipregion, clip poly b against it. Algo depends on
     255             :                     // poly b being closed.
     256             :                     basegfx::B2DPolyPolygon aResult(basegfx::tools::clipPolyPolygonOnPolyPolygon(aPolyB, aPolyA));
     257             : 
     258             :                     for(sal_uInt32 a(0L); a < aResult.count(); a++)
     259             :                     {
     260             :                         Color aColor(rand()%255, rand()%255, rand()%255);
     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           0 : void SdrPageWindow::RedrawAll(sdr::contact::ViewObjectContactRedirector* pRedirector) const
     273             : {
     274             :     // set Redirector
     275           0 :     GetObjectContact().SetViewObjectContactRedirector(pRedirector);
     276             : 
     277             :     // set PaintingPageView
     278           0 :     const SdrView& rView = mrPageView.GetView();
     279           0 :     SdrModel& rModel = *((SdrModel*)rView.GetModel());
     280             : 
     281             :     // get to be processed layers
     282           0 :     const sal_Bool bPrinter(GetPaintWindow().OutputToPrinter());
     283           0 :     SetOfByte aProcessLayers = bPrinter ? mrPageView.GetPrintableLayers() : mrPageView.GetVisibleLayers();
     284             : 
     285             :     // create PaintInfoRec; use Rectangle only temporarily
     286           0 :     const Region& rRegion = GetPaintWindow().GetRedrawRegion();
     287             : 
     288             :     // create processing data
     289           0 :     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           0 :     const SdrLayerAdmin& rLayerAdmin = rModel.GetLayerAdmin();
     294           0 :     const SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID(rLayerAdmin.GetControlLayerName(), sal_False);
     295           0 :     aProcessLayers.Clear(nControlLayerId);
     296             : 
     297             :     // still something to paint?
     298           0 :     if(!aProcessLayers.IsEmpty())
     299             :     {
     300           0 :         aDisplayInfo.SetProcessLayers(aProcessLayers);
     301             : 
     302             :         // Set region as redraw area
     303           0 :         aDisplayInfo.SetRedrawArea(rRegion);
     304             : 
     305             :         // Draw/Impress
     306           0 :         aDisplayInfo.SetPageProcessingActive(rView.IsPagePaintingAllowed()); // #i72889#
     307             : 
     308             :         // paint page
     309           0 :         GetObjectContact().ProcessDisplay(aDisplayInfo);
     310             :     }
     311             : 
     312             :     // reset redirector
     313           0 :     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           0 : }
     323             : 
     324         816 : void SdrPageWindow::RedrawLayer(const SdrLayerID* pId, sdr::contact::ViewObjectContactRedirector* pRedirector) const
     325             : {
     326             :     // set redirector
     327         816 :     GetObjectContact().SetViewObjectContactRedirector(pRedirector);
     328             : 
     329             :     // set PaintingPageView
     330         816 :     const SdrView& rView = mrPageView.GetView();
     331         816 :     SdrModel& rModel = *((SdrModel*)rView.GetModel());
     332             : 
     333             :     // get the layers to process
     334         816 :     const sal_Bool bPrinter(GetPaintWindow().OutputToPrinter());
     335         816 :     SetOfByte aProcessLayers = bPrinter ? mrPageView.GetPrintableLayers() : mrPageView.GetVisibleLayers();
     336             : 
     337             :     // is the given layer visible at all?
     338         816 :     if(aProcessLayers.IsSet(*pId))
     339             :     {
     340             :         // find out if we are painting the ControlLayer
     341         816 :         const SdrLayerAdmin& rLayerAdmin = rModel.GetLayerAdmin();
     342         816 :         const SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID(rLayerAdmin.GetControlLayerName(), sal_False);
     343         816 :         const sal_Bool bControlLayerProcessingActive(pId && nControlLayerId == *pId);
     344             : 
     345             :         // create PaintInfoRec, use Rectangle only temporarily
     346         816 :         const Region& rRegion = GetPaintWindow().GetRedrawRegion();
     347             : 
     348             :         // create processing data
     349         816 :         sdr::contact::DisplayInfo aDisplayInfo;
     350             : 
     351             :         // is it the control layer? If Yes, set flag
     352         816 :         aDisplayInfo.SetControlLayerProcessingActive(bControlLayerProcessingActive);
     353             : 
     354             :         // Draw just the one given layer
     355         816 :         aProcessLayers.ClearAll();
     356         816 :         aProcessLayers.Set(*pId);
     357             : 
     358         816 :         aDisplayInfo.SetProcessLayers(aProcessLayers);
     359             : 
     360             :         // Set region as redraw area
     361         816 :         aDisplayInfo.SetRedrawArea(rRegion);
     362             : 
     363             :         // Writer or calc, coming from original RedrawOneLayer.
     364             :         // #i72889# no page painting for layer painting
     365         816 :         aDisplayInfo.SetPageProcessingActive(false);
     366             : 
     367             :         // paint page
     368         816 :         GetObjectContact().ProcessDisplay(aDisplayInfo);
     369             :     }
     370             : 
     371             :     // reset redirector
     372         816 :     GetObjectContact().SetViewObjectContactRedirector(0L);
     373         816 : }
     374             : 
     375             : // Invalidate call, used from ObjectContact(OfPageView) in InvalidatePartOfView(...)
     376          18 : void SdrPageWindow::InvalidatePageWindow(const basegfx::B2DRange& rRange)
     377             : {
     378          18 :     if(GetPageView().IsVisible() && GetPaintWindow().OutputToWindow())
     379             :     {
     380          18 :         const SvtOptionsDrawinglayer aDrawinglayerOpt;
     381          18 :         Window& rWindow(static_cast< Window& >(GetPaintWindow().GetOutputDevice()));
     382          18 :         basegfx::B2DRange aDiscreteRange(rRange);
     383          18 :         aDiscreteRange.transform(rWindow.GetViewTransformation());
     384             : 
     385          18 :         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          36 :                 (sal_Int32)floor(aDiscreteRange.getMinX()), (sal_Int32)floor(aDiscreteRange.getMinY()),
     394          54 :                 (sal_Int32)ceil(aDiscreteRange.getMaxX()), (sal_Int32)ceil(aDiscreteRange.getMaxY()));
     395          18 :         const bool bWasMapModeEnabled(rWindow.IsMapModeEnabled());
     396             : 
     397          18 :         rWindow.EnableMapMode(false);
     398          18 :         rWindow.Invalidate(aVCLDiscreteRectangle, INVALIDATE_NOERASE);
     399          18 :         rWindow.EnableMapMode(bWasMapModeEnabled);
     400             :     }
     401          18 : }
     402             : 
     403             : // ObjectContact section
     404        2891 : sdr::contact::ObjectContact& SdrPageWindow::GetObjectContact() const
     405             : {
     406        2891 :     if(!mpObjectContact)
     407             :     {
     408         134 :         ((SdrPageWindow*)this)->mpObjectContact = ((SdrPageWindow*)this)->CreateViewSpecificObjectContact();
     409             :     }
     410             : 
     411        2891 :     return *mpObjectContact;
     412             : }
     413             : 
     414        1314 : bool SdrPageWindow::HasObjectContact() const
     415             : {
     416        1314 :     return ( mpObjectContact != NULL );
     417             : }
     418             : 
     419             : // #i26631#
     420          79 : void SdrPageWindow::ResetObjectContact()
     421             : {
     422          79 :     if(mpObjectContact)
     423             :     {
     424           9 :         delete mpObjectContact;
     425           9 :         mpObjectContact = 0L;
     426             :     }
     427          79 : }
     428             : 
     429           0 : void SdrPageWindow::SetDesignMode( bool _bDesignMode ) const
     430             : {
     431           0 :     const ::sdr::contact::ObjectContactOfPageView* pOC = dynamic_cast< const ::sdr::contact::ObjectContactOfPageView* >( &GetObjectContact() );
     432             :     DBG_ASSERT( pOC, "SdrPageWindow::SetDesignMode: invalid object contact!" );
     433           0 :     if ( pOC )
     434           0 :         pOC->SetUNOControlsDesignMode( _bDesignMode );
     435           0 : }
     436             : 
     437             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10