LCOV - code coverage report
Current view: top level - svx/source/sdr/contact - viewcontact.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 75 97 77.3 %
Date: 2015-06-13 12:38:46 Functions: 15 23 65.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/sdr/contact/viewcontact.hxx>
      21             : #include <svx/sdr/contact/viewobjectcontact.hxx>
      22             : #include <svx/sdr/contact/objectcontact.hxx>
      23             : #include <basegfx/polygon/b2dpolygon.hxx>
      24             : #include <basegfx/polygon/b2dpolygontools.hxx>
      25             : #include <basegfx/color/bcolor.hxx>
      26             : #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
      27             : #include <basegfx/matrix/b2dhommatrix.hxx>
      28             : #include <sdr/contact/objectcontactofpageview.hxx>
      29             : #include <tools/debug.hxx>
      30             : 
      31             : namespace sdr { namespace contact {
      32             : 
      33             : // Create a Object-Specific ViewObjectContact, set ViewContact and
      34             : // ObjectContact. Always needs to return something. Default is to create
      35             : // a standard ViewObjectContact containing the given ObjectContact and *this
      36           0 : ViewObjectContact& ViewContact::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact)
      37             : {
      38           0 :     return *(new ViewObjectContact(rObjectContact, *this));
      39             : }
      40             : 
      41      194387 : ViewContact::ViewContact()
      42             : :   maViewObjectContactVector(),
      43      194387 :     mxViewIndependentPrimitive2DSequence()
      44             : {
      45      194387 : }
      46             : 
      47      384648 : ViewContact::~ViewContact()
      48             : {
      49      192324 :     deleteAllVOCs();
      50      192324 : }
      51             : 
      52      624525 : void ViewContact::deleteAllVOCs()
      53             : {
      54             :     // get rid of all VOCs
      55             :     // #i84257# To avoid that each 'delete pCandidate' again uses
      56             :     // the local RemoveViewObjectContact with a search and removal in the
      57             :     // vector, simply copy and clear local vector.
      58      624525 :     std::vector< ViewObjectContact* > aLocalVOCList(maViewObjectContactVector);
      59      624525 :     maViewObjectContactVector.clear();
      60             : 
      61     1249305 :     while(!aLocalVOCList.empty())
      62             :     {
      63         255 :         ViewObjectContact* pCandidate = aLocalVOCList.back();
      64         255 :         aLocalVOCList.pop_back();
      65             :         DBG_ASSERT(pCandidate, "Corrupted ViewObjectContactList in VC (!)");
      66             : 
      67             :         // ViewObjectContacts only make sense with View and Object contacts.
      68             :         // When the contact to the SdrObject is deleted like in this case,
      69             :         // all ViewObjectContacts can be deleted, too.
      70         255 :         delete pCandidate;
      71             :     }
      72             : 
      73             :     // assert when there were new entries added during deletion
      74      624525 :     DBG_ASSERT(maViewObjectContactVector.empty(), "Corrupted ViewObjectContactList in VC (!)");
      75      624525 : }
      76             : 
      77             : // get a Object-specific ViewObjectContact for a specific
      78             : // ObjectContact (->View). Always needs to return something.
      79      596116 : ViewObjectContact& ViewContact::GetViewObjectContact(ObjectContact& rObjectContact)
      80             : {
      81      596116 :     ViewObjectContact* pRetval = 0L;
      82      596116 :     const sal_uInt32 nCount(maViewObjectContactVector.size());
      83             : 
      84             :     // first search if there exists a VOC for the given OC
      85     1112604 :     for(sal_uInt32 a(0); !pRetval && a < nCount; a++)
      86             :     {
      87      516488 :         ViewObjectContact* pCandidate = maViewObjectContactVector[a];
      88             :         DBG_ASSERT(pCandidate, "Corrupted ViewObjectContactList (!)");
      89             : 
      90      516488 :         if(&(pCandidate->GetObjectContact()) == &rObjectContact)
      91             :         {
      92      510791 :             pRetval = pCandidate;
      93             :         }
      94             :     }
      95             : 
      96      596116 :     if(!pRetval)
      97             :     {
      98             :         // create a new one. It's inserted to the local list from the
      99             :         // ViewObjectContact constructor via AddViewObjectContact()
     100       85325 :         pRetval = &CreateObjectSpecificViewObjectContact(rObjectContact);
     101             :     }
     102             : 
     103      596116 :     return *pRetval;
     104             : }
     105             : 
     106             : // A new ViewObjectContact was created and shall be remembered.
     107       85325 : void ViewContact::AddViewObjectContact(ViewObjectContact& rVOContact)
     108             : {
     109       85325 :     maViewObjectContactVector.push_back(&rVOContact);
     110       85325 : }
     111             : 
     112             : // A ViewObjectContact was deleted and shall be forgotten.
     113       84154 : void ViewContact::RemoveViewObjectContact(ViewObjectContact& rVOContact)
     114             : {
     115       84154 :     std::vector< ViewObjectContact* >::iterator aFindResult = std::find(maViewObjectContactVector.begin(), maViewObjectContactVector.end(), &rVOContact);
     116             : 
     117       84154 :     if(aFindResult != maViewObjectContactVector.end())
     118             :     {
     119       83899 :         maViewObjectContactVector.erase(aFindResult);
     120             :     }
     121       84154 : }
     122             : 
     123             : // Test if this ViewContact has ViewObjectContacts at all. This can
     124             : // be used to test if this ViewContact is visualized ATM or not
     125         112 : bool ViewContact::HasViewObjectContacts(bool bExcludePreviews) const
     126             : {
     127         112 :     const sal_uInt32 nCount(maViewObjectContactVector.size());
     128             : 
     129         112 :     if(bExcludePreviews)
     130             :     {
     131         112 :         for(sal_uInt32 a(0); a < nCount; a++)
     132             :         {
     133           1 :             if(!maViewObjectContactVector[a]->GetObjectContact().IsPreviewRenderer())
     134             :             {
     135           1 :                 return true;
     136             :             }
     137             :         }
     138             : 
     139         111 :         return false;
     140             :     }
     141             :     else
     142             :     {
     143           0 :         return (0L != nCount);
     144             :     }
     145             : }
     146             : 
     147             : // Test if this ViewContact has ViewObjectContacts at all. This can
     148             : // be used to test if this ViewContact is visualized ATM or not
     149           0 : bool ViewContact::isAnimatedInAnyViewObjectContact() const
     150             : {
     151           0 :     const sal_uInt32 nCount(maViewObjectContactVector.size());
     152             : 
     153           0 :     for(sal_uInt32 a(0); a < nCount; a++)
     154             :     {
     155           0 :         if(maViewObjectContactVector[a]->isAnimated())
     156             :         {
     157           0 :             return true;
     158             :         }
     159             :     }
     160             : 
     161           0 :     return false;
     162             : }
     163             : 
     164             : // Access to possible sub-hierarchy and parent. GetObjectCount() default is 0L
     165             : // and GetViewContact default pops up an assert since it's an error if
     166             : // GetObjectCount has a result != 0 and it's not overridden.
     167       19930 : sal_uInt32 ViewContact::GetObjectCount() const
     168             : {
     169             :     // no sub-objects
     170       19930 :     return 0;
     171             : }
     172             : 
     173           0 : ViewContact& ViewContact::GetViewContact(sal_uInt32 /*nIndex*/) const
     174             : {
     175             :     // This is the default implementation; call would be an error
     176             :     OSL_FAIL("ViewContact::GetViewContact: This call needs to be overridden when GetObjectCount() can return results != 0 (!)");
     177           0 :     return (ViewContact&)(*this);
     178             : }
     179             : 
     180           0 : ViewContact* ViewContact::GetParentContact() const
     181             : {
     182             :     // default has no parent
     183           0 :     return 0;
     184             : }
     185             : 
     186      111933 : void ViewContact::ActionChildInserted(ViewContact& rChild)
     187             : {
     188             :     // propagate change to all exsisting visualisations which
     189             :     // will force a VOC for the new child and invalidate its range
     190      111933 :     const sal_uInt32 nCount(maViewObjectContactVector.size());
     191             : 
     192      112673 :     for(sal_uInt32 a(0); a < nCount; a++)
     193             :     {
     194         740 :         ViewObjectContact* pCandidate = maViewObjectContactVector[a];
     195             :         DBG_ASSERT(pCandidate, "ViewContact::GetViewObjectContact() invalid ViewObjectContactList (!)");
     196             : 
     197             :         // take action at all VOCs. At the VOCs ObjectContact the initial
     198             :         // rectangle will be invalidated at the associated OutputDevice.
     199         740 :         pCandidate->ActionChildInserted(rChild);
     200             :     }
     201      111933 : }
     202             : 
     203             : // React on changes of the object of this ViewContact
     204     1623339 : void ViewContact::ActionChanged()
     205             : {
     206             :     // propagate change to all existing VOCs. This will invalidate
     207             :     // all drawn visualisations in all known views
     208     1623339 :     const sal_uInt32 nCount(maViewObjectContactVector.size());
     209             : 
     210     1634284 :     for(sal_uInt32 a(0); a < nCount; a++)
     211             :     {
     212       10945 :         ViewObjectContact* pCandidate = maViewObjectContactVector[a];
     213             :         DBG_ASSERT(pCandidate, "ViewContact::GetViewObjectContact() invalid ViewObjectContactList (!)");
     214             : 
     215       10945 :         pCandidate->ActionChanged();
     216             :     }
     217     1623339 : }
     218             : 
     219             : // access to SdrObject and/or SdrPage. May return 0L like the default
     220             : // implementations do. Override as needed.
     221        4243 : SdrObject* ViewContact::TryToGetSdrObject() const
     222             : {
     223        4243 :     return 0L;
     224             : }
     225             : 
     226           0 : SdrPage* ViewContact::TryToGetSdrPage() const
     227             : {
     228           0 :     return 0L;
     229             : }
     230             : 
     231             : 
     232             : // primitive stuff
     233             : 
     234           0 : drawinglayer::primitive2d::Primitive2DSequence ViewContact::createViewIndependentPrimitive2DSequence() const
     235             : {
     236             :     // This is the default implementation and should never be called (see header). If this is called,
     237             :     // someone implemented a ViewContact (VC) visualisation object without defining the visualisation by
     238             :     // providing a seqence of primitives -> which cannot be correct.
     239             :     // Since we have no access to any known model data here, the default implementation creates a yellow placeholder
     240             :     // hairline polygon with a default size of (1000, 1000, 5000, 3000)
     241             :     OSL_FAIL("ViewContact::createViewIndependentPrimitive2DSequence(): Never call the fallback base implementation, this is always an error (!)");
     242           0 :     const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(1000.0, 1000.0, 5000.0, 3000.0)));
     243           0 :     const basegfx::BColor aYellow(1.0, 1.0, 0.0);
     244             :     const drawinglayer::primitive2d::Primitive2DReference xReference(
     245           0 :         new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOutline, aYellow));
     246             : 
     247           0 :     return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
     248             : }
     249             : 
     250      115283 : drawinglayer::primitive2d::Primitive2DSequence ViewContact::getViewIndependentPrimitive2DSequence() const
     251             : {
     252             :     // local up-to-date checks. Create new list and compare.
     253      115283 :     drawinglayer::primitive2d::Primitive2DSequence xNew(createViewIndependentPrimitive2DSequence());
     254             : 
     255      115283 :     if(xNew.hasElements())
     256             :     {
     257             :         // allow evtl. embedding in object-specific infos, e.g. Name, Title, Description
     258      110147 :         xNew = embedToObjectSpecificInformation(xNew);
     259             :     }
     260             : 
     261      115283 :     if(!drawinglayer::primitive2d::arePrimitive2DSequencesEqual(mxViewIndependentPrimitive2DSequence, xNew))
     262             :     {
     263             :         // has changed, copy content
     264       62944 :         const_cast< ViewContact* >(this)->mxViewIndependentPrimitive2DSequence = xNew;
     265             :     }
     266             : 
     267             :     // return current Primitive2DSequence
     268      115283 :     return mxViewIndependentPrimitive2DSequence;
     269             : }
     270             : 
     271             : // add Gluepoints (if available)
     272           0 : drawinglayer::primitive2d::Primitive2DSequence ViewContact::createGluePointPrimitive2DSequence() const
     273             : {
     274             :     // default returns empty reference
     275           0 :     return drawinglayer::primitive2d::Primitive2DSequence();
     276             : }
     277             : 
     278        7244 : drawinglayer::primitive2d::Primitive2DSequence ViewContact::embedToObjectSpecificInformation(const drawinglayer::primitive2d::Primitive2DSequence& rSource) const
     279             : {
     280             :     // nothing to do for default
     281        7244 :     return rSource;
     282             : }
     283             : 
     284       76769 : basegfx::B2DRange ViewContact::getRange( const drawinglayer::geometry::ViewInformation2D& /*rViewInfo2D*/ ) const
     285             : {
     286             :     // Return empty range.
     287       76769 :     return basegfx::B2DRange();
     288             : }
     289             : 
     290      432201 : void ViewContact::flushViewObjectContacts(bool bWithHierarchy)
     291             : {
     292      432201 :     if(bWithHierarchy)
     293             :     {
     294             :         // flush DrawingLayer hierarchy
     295      432180 :         const sal_uInt32 nCount(GetObjectCount());
     296             : 
     297      749858 :         for(sal_uInt32 a(0); a < nCount; a++)
     298             :         {
     299      317678 :             ViewContact& rChild = GetViewContact(a);
     300      317678 :             rChild.flushViewObjectContacts(bWithHierarchy);
     301             :         }
     302             :     }
     303             : 
     304             :     // delete local VOCs
     305      432201 :     deleteAllVOCs();
     306      432201 : }
     307             : 
     308             : }}
     309             : 
     310             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11