1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #ifndef INCLUDED_SLIDESHOW_DRAWSHAPESUBSETTING_HXX 29*cdf0e10cSrcweir #define INCLUDED_SLIDESHOW_DRAWSHAPESUBSETTING_HXX 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <boost/shared_ptr.hpp> 32*cdf0e10cSrcweir #include <boost/noncopyable.hpp> 33*cdf0e10cSrcweir 34*cdf0e10cSrcweir #include "doctreenode.hxx" 35*cdf0e10cSrcweir #include "attributableshape.hxx" 36*cdf0e10cSrcweir 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir class GDIMetaFile; 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir namespace slideshow 41*cdf0e10cSrcweir { 42*cdf0e10cSrcweir namespace internal 43*cdf0e10cSrcweir { 44*cdf0e10cSrcweir /** This class encapsulates the subsetting aspects of a 45*cdf0e10cSrcweir DrawShape. 46*cdf0e10cSrcweir */ 47*cdf0e10cSrcweir class DrawShapeSubsetting : private boost::noncopyable 48*cdf0e10cSrcweir { 49*cdf0e10cSrcweir public: 50*cdf0e10cSrcweir /** Create empty shape subset handling. 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir This method creates a subset handler which contains no 53*cdf0e10cSrcweir subset information. All methods will return default 54*cdf0e10cSrcweir values. 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir @param rMtf 57*cdf0e10cSrcweir Metafile to retrieve subset info from (must have been 58*cdf0e10cSrcweir generated with verbose text comments switched on). 59*cdf0e10cSrcweir */ 60*cdf0e10cSrcweir DrawShapeSubsetting(); 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir /** Create new shape subset handling. 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir This method creates a subset handler which initially 65*cdf0e10cSrcweir displays the whole shape. 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir @param rMtf 68*cdf0e10cSrcweir Metafile to retrieve subset info from (must have been 69*cdf0e10cSrcweir generated with verbose text comments switched on). 70*cdf0e10cSrcweir */ 71*cdf0e10cSrcweir explicit DrawShapeSubsetting( const ::boost::shared_ptr< GDIMetaFile >& rMtf ); 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir /** Create new shape subset handling. 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir @param rShapeSubset 76*cdf0e10cSrcweir The subset this object represents (can be empty, then 77*cdf0e10cSrcweir denoting 'represents a whole shape') 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir @param rMtf 80*cdf0e10cSrcweir Metafile to retrieve subset info from (must have been 81*cdf0e10cSrcweir generated with verbose text comments switched on). 82*cdf0e10cSrcweir */ 83*cdf0e10cSrcweir DrawShapeSubsetting( const DocTreeNode& rShapeSubset, 84*cdf0e10cSrcweir const ::boost::shared_ptr< GDIMetaFile >& rMtf ); 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir /** Reset metafile. 87*cdf0e10cSrcweir 88*cdf0e10cSrcweir Use this method to completely reset the 89*cdf0e10cSrcweir ShapeSubsetting, with a new metafile. Note that any 90*cdf0e10cSrcweir information previously set will be lost, including 91*cdf0e10cSrcweir added subset shapes! 92*cdf0e10cSrcweir 93*cdf0e10cSrcweir @param rMtf 94*cdf0e10cSrcweir Metafile to retrieve subset info from (must have been 95*cdf0e10cSrcweir generated with verbose text comments switched on). 96*cdf0e10cSrcweir */ 97*cdf0e10cSrcweir void reset( const ::boost::shared_ptr< GDIMetaFile >& rMtf ); 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir /** Reset metafile and subset. 100*cdf0e10cSrcweir 101*cdf0e10cSrcweir Use this method to completely reset the 102*cdf0e10cSrcweir ShapeSubsetting, with a new metafile and subset 103*cdf0e10cSrcweir range. Note that any information previously set will 104*cdf0e10cSrcweir be lost, including added subset shapes! 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir @param rShapeSubset 107*cdf0e10cSrcweir The subset this object represents (can be empty, then 108*cdf0e10cSrcweir denoting 'represents a whole shape') 109*cdf0e10cSrcweir 110*cdf0e10cSrcweir @param rMtf 111*cdf0e10cSrcweir Metafile to retrieve subset info from (must have been 112*cdf0e10cSrcweir generated with verbose text comments switched on). 113*cdf0e10cSrcweir */ 114*cdf0e10cSrcweir void reset( const DocTreeNode& rShapeSubset, 115*cdf0e10cSrcweir const ::boost::shared_ptr< GDIMetaFile >& rMtf ); 116*cdf0e10cSrcweir 117*cdf0e10cSrcweir 118*cdf0e10cSrcweir // Shape subsetting methods 119*cdf0e10cSrcweir // ======================================================== 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir /// Return subset node for this shape 122*cdf0e10cSrcweir DocTreeNode getSubsetNode () const; 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir /// Return true, if any child subset shapes exist 125*cdf0e10cSrcweir bool hasSubsetShapes () const; 126*cdf0e10cSrcweir 127*cdf0e10cSrcweir /// Get subset shape for given node, if any 128*cdf0e10cSrcweir AttributableShapeSharedPtr getSubsetShape ( const DocTreeNode& rTreeNode ) const; 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir /// Add child subset shape (or increase use count, if already existent) 131*cdf0e10cSrcweir void addSubsetShape ( const AttributableShapeSharedPtr& rShape ); 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir /** Revoke subset shape 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir This method revokes a subset shape, decrementing the 136*cdf0e10cSrcweir use count for this subset by one. If the use count 137*cdf0e10cSrcweir reaches zero (i.e. when the number of addSubsetShape() 138*cdf0e10cSrcweir matches the number of revokeSubsetShape() calls for 139*cdf0e10cSrcweir the same subset), the subset entry is removed from the 140*cdf0e10cSrcweir internal list, and subsequent getSubsetShape() calls 141*cdf0e10cSrcweir will return the empty pointer for this subset. 142*cdf0e10cSrcweir 143*cdf0e10cSrcweir @return true, if the subset shape was physically 144*cdf0e10cSrcweir removed from the list (false is returned, when nothing 145*cdf0e10cSrcweir was removed, either because only the use count was 146*cdf0e10cSrcweir decremented, or there was no such subset found, in the 147*cdf0e10cSrcweir first place). 148*cdf0e10cSrcweir */ 149*cdf0e10cSrcweir bool revokeSubsetShape ( const AttributableShapeSharedPtr& rShape ); 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir // Doc tree methods 153*cdf0e10cSrcweir // ======================================================== 154*cdf0e10cSrcweir 155*cdf0e10cSrcweir /// Return overall number of nodes for given type 156*cdf0e10cSrcweir sal_Int32 getNumberOfTreeNodes ( DocTreeNode::NodeType eNodeType ) const; 157*cdf0e10cSrcweir 158*cdf0e10cSrcweir /// Return tree node of given index and given type 159*cdf0e10cSrcweir DocTreeNode getTreeNode ( sal_Int32 nNodeIndex, 160*cdf0e10cSrcweir DocTreeNode::NodeType eNodeType ) const; 161*cdf0e10cSrcweir 162*cdf0e10cSrcweir /// Return number of nodes of given type, below parent node 163*cdf0e10cSrcweir sal_Int32 getNumberOfSubsetTreeNodes ( const DocTreeNode& rParentNode, 164*cdf0e10cSrcweir DocTreeNode::NodeType eNodeType ) const; 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir /// Return tree node of given index and given type, relative to parent node 167*cdf0e10cSrcweir DocTreeNode getSubsetTreeNode ( const DocTreeNode& rParentNode, 168*cdf0e10cSrcweir sal_Int32 nNodeIndex, 169*cdf0e10cSrcweir DocTreeNode::NodeType eNodeType ) const; 170*cdf0e10cSrcweir 171*cdf0e10cSrcweir // Helper 172*cdf0e10cSrcweir // ======================================================== 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir /** Return a vector of currently active subsets. 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir Needed when rendering a shape, this method provides a 177*cdf0e10cSrcweir vector of subsets currently visible (the range as 178*cdf0e10cSrcweir returned by getEffectiveSubset(), minus the parts that 179*cdf0e10cSrcweir are currently hidden, because displayed by child 180*cdf0e10cSrcweir shapes). 181*cdf0e10cSrcweir */ 182*cdf0e10cSrcweir const VectorOfDocTreeNodes& getActiveSubsets() const; 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir /** This enum classifies each action index in the 185*cdf0e10cSrcweir metafile. 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir Of interest are, of course, the places where 188*cdf0e10cSrcweir structural shape and/or text elements end. The 189*cdf0e10cSrcweir remainder of the action gets classified as 'noop' 190*cdf0e10cSrcweir */ 191*cdf0e10cSrcweir enum IndexClassificator 192*cdf0e10cSrcweir { 193*cdf0e10cSrcweir CLASS_NOOP, 194*cdf0e10cSrcweir CLASS_SHAPE_START, 195*cdf0e10cSrcweir CLASS_SHAPE_END, 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir CLASS_LINE_END, 198*cdf0e10cSrcweir CLASS_PARAGRAPH_END, 199*cdf0e10cSrcweir CLASS_SENTENCE_END, 200*cdf0e10cSrcweir CLASS_WORD_END, 201*cdf0e10cSrcweir CLASS_CHARACTER_CELL_END 202*cdf0e10cSrcweir }; 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir typedef ::std::vector< IndexClassificator > IndexClassificatorVector; 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir private: 207*cdf0e10cSrcweir /** Entry for subset shape 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir This struct contains data for every subset shape 210*cdf0e10cSrcweir generated. Note that for a given start/end action 211*cdf0e10cSrcweir index combination, only one subset instance is 212*cdf0e10cSrcweir generated (and reused for subsequent queries). 213*cdf0e10cSrcweir */ 214*cdf0e10cSrcweir struct SubsetEntry 215*cdf0e10cSrcweir { 216*cdf0e10cSrcweir AttributableShapeSharedPtr mpShape; 217*cdf0e10cSrcweir sal_Int32 mnStartActionIndex; 218*cdf0e10cSrcweir sal_Int32 mnEndActionIndex; 219*cdf0e10cSrcweir 220*cdf0e10cSrcweir /// Number of times this subset was queried, and not yet revoked 221*cdf0e10cSrcweir int mnSubsetQueriedCount; 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir sal_Int32 getHashValue() const 224*cdf0e10cSrcweir { 225*cdf0e10cSrcweir // TODO(Q3): That's a hack. We assume that start 226*cdf0e10cSrcweir // index will always be less than 65535 (if this 227*cdf0e10cSrcweir // assumption is violated, hash map performance 228*cdf0e10cSrcweir // will degrade severely) 229*cdf0e10cSrcweir return mnStartActionIndex*SAL_MAX_INT16 + mnEndActionIndex; 230*cdf0e10cSrcweir } 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir /// The shape set is ordered according to this method 233*cdf0e10cSrcweir bool operator<(const SubsetEntry& rOther) const 234*cdf0e10cSrcweir { 235*cdf0e10cSrcweir return getHashValue() < rOther.getHashValue(); 236*cdf0e10cSrcweir } 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir }; 239*cdf0e10cSrcweir 240*cdf0e10cSrcweir typedef ::std::set< SubsetEntry > ShapeSet; 241*cdf0e10cSrcweir 242*cdf0e10cSrcweir void ensureInitializedNodeTree() const; 243*cdf0e10cSrcweir void updateSubsetBounds( const SubsetEntry& rSubsetEntry ); 244*cdf0e10cSrcweir void updateSubsets(); 245*cdf0e10cSrcweir void initCurrentSubsets(); 246*cdf0e10cSrcweir void reset(); 247*cdf0e10cSrcweir 248*cdf0e10cSrcweir sal_Int32 implGetNumberOfTreeNodes( const IndexClassificatorVector::const_iterator& rBegin, 249*cdf0e10cSrcweir const IndexClassificatorVector::const_iterator& rEnd, 250*cdf0e10cSrcweir DocTreeNode::NodeType eNodeType ) const; 251*cdf0e10cSrcweir DocTreeNode implGetTreeNode( const IndexClassificatorVector::const_iterator& rBegin, 252*cdf0e10cSrcweir const IndexClassificatorVector::const_iterator& rEnd, 253*cdf0e10cSrcweir sal_Int32 nNodeIndex, 254*cdf0e10cSrcweir DocTreeNode::NodeType eNodeType ) const; 255*cdf0e10cSrcweir 256*cdf0e10cSrcweir mutable IndexClassificatorVector maActionClassVector; 257*cdf0e10cSrcweir 258*cdf0e10cSrcweir /// Metafile to retrieve subset info from 259*cdf0e10cSrcweir ::boost::shared_ptr< GDIMetaFile > mpMtf; 260*cdf0e10cSrcweir 261*cdf0e10cSrcweir /// Subset of the metafile represented by this object 262*cdf0e10cSrcweir DocTreeNode maSubset; 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir /// the list of subset shapes spawned from this one. 265*cdf0e10cSrcweir ShapeSet maSubsetShapes; 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir /// caches minimal subset index from maSubsetShapes 268*cdf0e10cSrcweir sal_Int32 mnMinSubsetActionIndex; 269*cdf0e10cSrcweir 270*cdf0e10cSrcweir /// caches maximal subset index from maSubsetShapes 271*cdf0e10cSrcweir sal_Int32 mnMaxSubsetActionIndex; 272*cdf0e10cSrcweir 273*cdf0e10cSrcweir /** Current number of subsets to render (calculated from 274*cdf0e10cSrcweir maSubset and mnMin/MaxSubsetActionIndex). 275*cdf0e10cSrcweir 276*cdf0e10cSrcweir Note that this is generally _not_ equivalent to 277*cdf0e10cSrcweir maSubset, as it excludes all active subset children! 278*cdf0e10cSrcweir */ 279*cdf0e10cSrcweir mutable VectorOfDocTreeNodes maCurrentSubsets; 280*cdf0e10cSrcweir 281*cdf0e10cSrcweir /// Whether the shape's doc tree has been initialized successfully, or not 282*cdf0e10cSrcweir mutable bool mbNodeTreeInitialized; 283*cdf0e10cSrcweir }; 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir } 286*cdf0e10cSrcweir } 287*cdf0e10cSrcweir 288*cdf0e10cSrcweir #endif /* INCLUDED_SLIDESHOW_DRAWSHAPESUBSETTING_HXX */ 289