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