LCOV - code coverage report
Current view: top level - svx/source/sdr/contact - viewobjectcontactofpageobj.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 25 110 22.7 %
Date: 2015-06-13 12:38:46 Functions: 7 21 33.3 %
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 <vcl/idle.hxx>
      21             : #include <svx/sdr/contact/viewobjectcontactofpageobj.hxx>
      22             : #include <svx/sdr/contact/viewcontactofpageobj.hxx>
      23             : #include <svx/svdopage.hxx>
      24             : #include <svx/sdr/contact/displayinfo.hxx>
      25             : #include <svtools/colorcfg.hxx>
      26             : #include <basegfx/polygon/b2dpolygontools.hxx>
      27             : #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
      28             : #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
      29             : #include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
      30             : #include <basegfx/matrix/b2dhommatrix.hxx>
      31             : #include <svx/svdpage.hxx>
      32             : #include <svx/unoapi.hxx>
      33             : #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx>
      34             : #include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx>
      35             : 
      36             : using namespace com::sun::star;
      37             : 
      38             : namespace sdr { namespace contact {
      39             : 
      40             : class PagePrimitiveExtractor : public ObjectContactOfPagePainter, public Idle
      41             : {
      42             : private:
      43             :     // the ViewObjectContactOfPageObj using this painter
      44             :     ViewObjectContactOfPageObj&         mrViewObjectContactOfPageObj;
      45             : 
      46             : public:
      47             :     // basic constructor/destructor
      48             :     explicit PagePrimitiveExtractor(ViewObjectContactOfPageObj& rVOC);
      49             :     virtual ~PagePrimitiveExtractor();
      50             : 
      51             :     // LazyInvalidate request. Supported here to not automatically
      52             :     // invalidate the second interaction state all the time at the
      53             :     // original OC
      54             :     virtual void setLazyInvalidate(ViewObjectContact& rVOC) SAL_OVERRIDE;
      55             : 
      56             :     // From baseclass Timer, the timeout call triggered by the LazyInvalidate mechanism
      57             :     virtual void Invoke() SAL_OVERRIDE;
      58             : 
      59             :     // get primitive visualization
      60             :     drawinglayer::primitive2d::Primitive2DSequence createPrimitive2DSequenceForPage(const DisplayInfo& rDisplayInfo);
      61             : 
      62             :     // Own reaction on changes which will be forwarded to the OC of the owner-VOC
      63             :     virtual void InvalidatePartOfView(const basegfx::B2DRange& rRange) const SAL_OVERRIDE;
      64             : 
      65             :     // forward access to SdrPageView of ViewObjectContactOfPageObj
      66             :     virtual bool isOutputToPrinter() const SAL_OVERRIDE;
      67             :     virtual bool isOutputToWindow() const SAL_OVERRIDE;
      68             :     virtual bool isOutputToVirtualDevice() const SAL_OVERRIDE;
      69             :     virtual bool isOutputToRecordingMetaFile() const SAL_OVERRIDE;
      70             :     virtual bool isOutputToPDFFile() const SAL_OVERRIDE;
      71             :     virtual bool isDrawModeGray() const SAL_OVERRIDE;
      72             :     virtual bool isDrawModeBlackWhite() const SAL_OVERRIDE;
      73             :     virtual bool isDrawModeHighContrast() const SAL_OVERRIDE;
      74             :     virtual SdrPageView* TryToGetSdrPageView() const SAL_OVERRIDE;
      75             :     virtual OutputDevice* TryToGetOutputDevice() const SAL_OVERRIDE;
      76             : };
      77             : 
      78           9 : PagePrimitiveExtractor::PagePrimitiveExtractor(
      79             :     ViewObjectContactOfPageObj& rVOC)
      80           9 : :   ObjectContactOfPagePainter(0, rVOC.GetObjectContact()),
      81           9 :     mrViewObjectContactOfPageObj(rVOC)
      82             : {
      83             :     // make this renderer a preview renderer
      84           9 :     setPreviewRenderer(true);
      85             : 
      86             :     // init timer
      87           9 :     SetPriority(SchedulerPriority::HIGH);
      88           9 :     Stop();
      89           9 : }
      90             : 
      91          27 : PagePrimitiveExtractor::~PagePrimitiveExtractor()
      92             : {
      93             :     // execute missing LazyInvalidates and stop timer
      94           9 :     Invoke();
      95          18 : }
      96             : 
      97           0 : void PagePrimitiveExtractor::setLazyInvalidate(ViewObjectContact& /*rVOC*/)
      98             : {
      99             :     // do NOT call parent, but remember that something is to do by
     100             :     // starting the LazyInvalidateTimer
     101           0 :     Start();
     102           0 : }
     103             : 
     104             : // From baseclass Timer, the timeout call triggered by the LazyInvalidate mechanism
     105           9 : void PagePrimitiveExtractor::Invoke()
     106             : {
     107             :     // stop the timer
     108           9 :     Stop();
     109             : 
     110             :     // invalidate all LazyInvalidate VOCs new situations
     111           9 :     const sal_uInt32 nVOCCount(getViewObjectContactCount());
     112             : 
     113           9 :     for(sal_uInt32 a(0); a < nVOCCount; a++)
     114             :     {
     115           0 :         ViewObjectContact* pCandidate = getViewObjectContact(a);
     116           0 :         pCandidate->triggerLazyInvalidate();
     117             :     }
     118           9 : }
     119             : 
     120           0 : drawinglayer::primitive2d::Primitive2DSequence PagePrimitiveExtractor::createPrimitive2DSequenceForPage(const DisplayInfo& /*rDisplayInfo*/)
     121             : {
     122           0 :     drawinglayer::primitive2d::Primitive2DSequence xRetval;
     123           0 :     const SdrPage* pStartPage = GetStartPage();
     124             : 
     125           0 :     if(pStartPage)
     126             :     {
     127             :         // update own ViewInformation2D for visualized page
     128           0 :         const drawinglayer::geometry::ViewInformation2D& rOriginalViewInformation = mrViewObjectContactOfPageObj.GetObjectContact().getViewInformation2D();
     129             :         const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D(
     130           0 :             rOriginalViewInformation.getObjectTransformation(),
     131           0 :             rOriginalViewInformation.getViewTransformation(),
     132             : 
     133             :             // #i101075# use empty range for page content here to force
     134             :             // the content not to be physically clipped in any way. This
     135             :             // would be possible, but would require the internal transformation
     136             :             // which maps between the page visualisation object and the page
     137             :             // content, including the aspect ratios (for details see in
     138             :             // PagePreviewPrimitive2D::create2DDecomposition)
     139             :             basegfx::B2DRange(),
     140             : 
     141             :             GetXDrawPageForSdrPage(const_cast< SdrPage* >(pStartPage)),
     142             :             0.0, // no time; page previews are not animated
     143           0 :             rOriginalViewInformation.getExtendedInformationSequence());
     144           0 :         updateViewInformation2D(aNewViewInformation2D);
     145             : 
     146             :         // create copy of DisplayInfo to set PagePainting
     147           0 :         DisplayInfo aDisplayInfo;
     148             : 
     149             :         // get page's VOC
     150           0 :         ViewObjectContact& rDrawPageVOContact = pStartPage->GetViewContact().GetViewObjectContact(*this);
     151             : 
     152             :         // get whole Primitive2DSequence
     153           0 :         xRetval = rDrawPageVOContact.getPrimitive2DSequenceHierarchy(aDisplayInfo);
     154             :     }
     155             : 
     156           0 :     return xRetval;
     157             : }
     158             : 
     159           0 : void PagePrimitiveExtractor::InvalidatePartOfView(const basegfx::B2DRange& rRange) const
     160             : {
     161             :     // an invalidate is called at this view, this needs to be translated to an invalidate
     162             :     // for the using VOC. Coordinates are in page coordinate system.
     163           0 :     const SdrPage* pStartPage = GetStartPage();
     164             : 
     165           0 :     if(pStartPage && !rRange.isEmpty())
     166             :     {
     167           0 :         const basegfx::B2DRange aPageRange(0.0, 0.0, (double)pStartPage->GetWdt(), (double)pStartPage->GetHgt());
     168             : 
     169           0 :         if(rRange.overlaps(aPageRange))
     170             :         {
     171             :             // if object on the page is inside or overlapping with page, create ActionChanged() for
     172             :             // involved VOC
     173           0 :             mrViewObjectContactOfPageObj.ActionChanged();
     174             :         }
     175             :     }
     176           0 : }
     177             : 
     178             : // forward access to SdrPageView to VOCOfPageObj
     179           0 : bool PagePrimitiveExtractor::isOutputToPrinter() const { return mrViewObjectContactOfPageObj.GetObjectContact().isOutputToPrinter(); }
     180           0 : bool PagePrimitiveExtractor::isOutputToWindow() const { return mrViewObjectContactOfPageObj.GetObjectContact().isOutputToWindow(); }
     181           0 : bool PagePrimitiveExtractor::isOutputToVirtualDevice() const { return mrViewObjectContactOfPageObj.GetObjectContact().isOutputToVirtualDevice(); }
     182           0 : bool PagePrimitiveExtractor::isOutputToRecordingMetaFile() const { return mrViewObjectContactOfPageObj.GetObjectContact().isOutputToRecordingMetaFile(); }
     183           0 : bool PagePrimitiveExtractor::isOutputToPDFFile() const { return mrViewObjectContactOfPageObj.GetObjectContact().isOutputToPDFFile(); }
     184           0 : bool PagePrimitiveExtractor::isDrawModeGray() const { return mrViewObjectContactOfPageObj.GetObjectContact().isDrawModeGray(); }
     185           0 : bool PagePrimitiveExtractor::isDrawModeBlackWhite() const { return mrViewObjectContactOfPageObj.GetObjectContact().isDrawModeBlackWhite(); }
     186           0 : bool PagePrimitiveExtractor::isDrawModeHighContrast() const { return mrViewObjectContactOfPageObj.GetObjectContact().isDrawModeHighContrast(); }
     187           0 : SdrPageView* PagePrimitiveExtractor::TryToGetSdrPageView() const { return mrViewObjectContactOfPageObj.GetObjectContact().TryToGetSdrPageView(); }
     188           0 : OutputDevice* PagePrimitiveExtractor::TryToGetOutputDevice() const { return mrViewObjectContactOfPageObj.GetObjectContact().TryToGetOutputDevice(); }
     189             : 
     190           0 : drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfPageObj::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const
     191             : {
     192           0 :     drawinglayer::primitive2d::Primitive2DSequence xRetval;
     193           0 :     const SdrPageObj& rPageObject((static_cast< ViewContactOfPageObj& >(GetViewContact())).GetPageObj());
     194           0 :     const SdrPage* pPage = rPageObject.GetReferencedPage();
     195           0 :     const svtools::ColorConfig aColorConfig;
     196             : 
     197             :     // get PageObject's geometry
     198           0 :     basegfx::B2DHomMatrix aPageObjectTransform;
     199             :     {
     200           0 :         const Rectangle aPageObjectModelData(rPageObject.GetLastBoundRect());
     201             :         const basegfx::B2DRange aPageObjectBound(
     202           0 :             aPageObjectModelData.Left(), aPageObjectModelData.Top(),
     203           0 :             aPageObjectModelData.Right(), aPageObjectModelData.Bottom());
     204             : 
     205           0 :         aPageObjectTransform.set(0, 0, aPageObjectBound.getWidth());
     206           0 :         aPageObjectTransform.set(1, 1, aPageObjectBound.getHeight());
     207           0 :         aPageObjectTransform.set(0, 2, aPageObjectBound.getMinX());
     208           0 :         aPageObjectTransform.set(1, 2, aPageObjectBound.getMinY());
     209             :     }
     210             : 
     211             :     // #i102637# add gray frame also when printing and page exists (handout pages)
     212           0 :     const bool bCreateGrayFrame(!GetObjectContact().isOutputToPrinter() || pPage);
     213             : 
     214             :     // get displayed page's content. This is the uscaled page content
     215           0 :     if(mpExtractor && pPage)
     216             :     {
     217             :         // get displayed page's geometry
     218           0 :            drawinglayer::primitive2d::Primitive2DSequence xPageContent;
     219           0 :         const Size aPageSize(pPage->GetSize());
     220           0 :         const double fPageWidth(aPageSize.getWidth());
     221           0 :         const double fPageHeight(aPageSize.getHeight());
     222             : 
     223             :         // The case that a PageObject contains another PageObject which visualizes the
     224             :         // same page again would lead to a recursion. Limit that recursion depth to one
     225             :         // by using a local static bool
     226             :         static bool bInCreatePrimitive2D(false);
     227             : 
     228           0 :         if(bInCreatePrimitive2D)
     229             :         {
     230             :             // Recursion is possible. Create a replacement primitive
     231           0 :             xPageContent.realloc(2);
     232           0 :             const Color aDocColor(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
     233           0 :             const Color aBorderColor(aColorConfig.GetColorValue(svtools::DOCBOUNDARIES).nColor);
     234           0 :             const basegfx::B2DRange aPageBound(0.0, 0.0, fPageWidth, fPageHeight);
     235           0 :             const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aPageBound));
     236             : 
     237             :             // add replacement fill
     238           0 :             xPageContent[0L] = drawinglayer::primitive2d::Primitive2DReference(
     239           0 :                 new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aOutline), aDocColor.getBColor()));
     240             : 
     241             :             // add replacement border
     242           0 :             xPageContent[1L] = drawinglayer::primitive2d::Primitive2DReference(
     243           0 :                 new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOutline, aBorderColor.getBColor()));
     244             :         }
     245             :         else
     246             :         {
     247             :             // set recursion flag
     248           0 :             bInCreatePrimitive2D = true;
     249             : 
     250             :             // init extractor, guarantee existence, set page there
     251           0 :             mpExtractor->SetStartPage(pPage);
     252             : 
     253             :             // #i105548# also need to copy the VOCRedirector for sub-content creation
     254           0 :             mpExtractor->SetViewObjectContactRedirector(GetObjectContact().GetViewObjectContactRedirector());
     255             : 
     256             :             // create page content
     257           0 :             xPageContent = mpExtractor->createPrimitive2DSequenceForPage(rDisplayInfo);
     258             : 
     259             :             // #i105548# reset VOCRedirector to not accidentially have a pointer to a
     260             :             // temporary class, so calls to it are avoided safely
     261           0 :             mpExtractor->SetViewObjectContactRedirector(0);
     262             : 
     263             :             // reset recursion flag
     264           0 :             bInCreatePrimitive2D = false;
     265             :         }
     266             : 
     267             :         // prepare retval
     268           0 :         if(xPageContent.hasElements())
     269             :         {
     270           0 :             const uno::Reference< drawing::XDrawPage > xDrawPage(GetXDrawPageForSdrPage(const_cast< SdrPage*>(pPage)));
     271             :             const drawinglayer::primitive2d::Primitive2DReference xPagePreview(new drawinglayer::primitive2d::PagePreviewPrimitive2D(
     272           0 :                 xDrawPage, aPageObjectTransform, fPageWidth, fPageHeight, xPageContent, true));
     273           0 :             xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xPagePreview, 1);
     274           0 :         }
     275             :     }
     276           0 :     else if(bCreateGrayFrame)
     277             :     {
     278             :         // #i105146# no content, but frame display. To make hitting the page preview objects
     279             :         // on the handout page more simple, add hidden fill geometry
     280             :         const drawinglayer::primitive2d::Primitive2DReference xFrameHit(
     281             :             drawinglayer::primitive2d::createHiddenGeometryPrimitives2D(
     282             :                 false,
     283           0 :                 aPageObjectTransform));
     284           0 :         xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xFrameHit, 1);
     285             :     }
     286             : 
     287             :     // add a gray outline frame, except not when printing
     288           0 :     if(bCreateGrayFrame)
     289             :     {
     290           0 :         const Color aFrameColor(aColorConfig.GetColorValue(svtools::OBJECTBOUNDARIES).nColor);
     291           0 :         basegfx::B2DPolygon aOwnOutline(basegfx::tools::createUnitPolygon());
     292           0 :         aOwnOutline.transform(aPageObjectTransform);
     293             : 
     294             :         const drawinglayer::primitive2d::Primitive2DReference xGrayFrame(
     295           0 :             new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOwnOutline, aFrameColor.getBColor()));
     296             : 
     297           0 :         drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xGrayFrame);
     298             :     }
     299             : 
     300           0 :     return xRetval;
     301             : }
     302             : 
     303           9 : ViewObjectContactOfPageObj::ViewObjectContactOfPageObj(ObjectContact& rObjectContact, ViewContact& rViewContact)
     304             : :   ViewObjectContactOfSdrObj(rObjectContact, rViewContact),
     305           9 :     mpExtractor(new PagePrimitiveExtractor(*this))
     306             : {
     307           9 : }
     308             : 
     309          27 : ViewObjectContactOfPageObj::~ViewObjectContactOfPageObj()
     310             : {
     311             :     // delete the helper OC
     312           9 :     if(mpExtractor)
     313             :     {
     314             :         // remember candidate and reset own pointer to avoid action when createPrimitive2DSequence()
     315             :         // would be called for any reason
     316           9 :         PagePrimitiveExtractor* pCandidate = mpExtractor;
     317           9 :         mpExtractor = 0;
     318             : 
     319             :         // also reset the StartPage to avoid ActionChanged() forwardings in the
     320             :         // PagePrimitiveExtractor::InvalidatePartOfView() implementation
     321           9 :         pCandidate->SetStartPage(0);
     322           9 :         delete pCandidate;
     323             :     }
     324          18 : }
     325             : 
     326             : }}
     327             : 
     328             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11