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 #ifndef INCLUDED_SW_INC_NDHINTS_HXX 20 #define INCLUDED_SW_INC_NDHINTS_HXX 21 22 #include "swtypes.hxx" 23 24 class SwTextNode; 25 class SwRegHistory; // Is in RolBck.hxx. 26 class SwTextAttr; 27 class SwTextAttrNesting; 28 29 class SfxPoolItem; 30 class SfxItemSet; 31 class SwDoc; 32 33 enum class CopyOrNewType { Copy, New }; 34 35 /// if COPY then pTextNode must be given! 36 SwTextAttr * MakeTextAttr( 37 SwDoc & rDoc, 38 SfxPoolItem & rNew, 39 sal_Int32 const nStt, 40 sal_Int32 const nEnd, 41 CopyOrNewType const bIsCopy = CopyOrNewType::New, 42 SwTextNode *const pTextNode = nullptr ); 43 44 SwTextAttr * MakeTextAttr( 45 SwDoc & rDoc, 46 const SfxItemSet & rSet, 47 sal_Int32 nStt, 48 sal_Int32 nEnd ); 49 50 /// create redline dummy text hint that must not be inserted into hints array 51 SwTextAttr* MakeRedlineTextAttr( 52 SwDoc & rDoc, 53 SfxPoolItem const & rAttr ); 54 55 struct CompareSwpHtEnd 56 { 57 bool operator()( sal_Int32 nEndPos, const SwTextAttr* rhs ) const; 58 bool operator()( const SwTextAttr* lhs, const SwTextAttr* rhs ) const; 59 }; 60 struct CompareSwpHtWhichStart 61 { 62 bool operator()( const SwTextAttr* lhs, const sal_uInt16 nWhich ) const; 63 bool operator()( const SwTextAttr* lhs, const SwTextAttr* rhs ) const; 64 }; 65 66 /// An SwTextAttr container, stores all directly formatted text portions for a text node. 67 class SwpHints 68 { 69 private: 70 const SwTextNode& m_rParent; 71 72 // SAL_MAX_SIZE is used by GetStartOf to return 73 // failure, so just allow SAL_MAX_SIZE-1 hints 74 static const size_t MAX_HINTS = SAL_MAX_SIZE-1; 75 76 std::vector<SwTextAttr*> m_HintsByStart; 77 std::vector<SwTextAttr*> m_HintsByEnd; 78 std::vector<SwTextAttr*> m_HintsByWhichAndStart; 79 80 SwRegHistory* m_pHistory; ///< for Undo 81 82 /// true: the Node is in Split and Frames are moved 83 bool m_bInSplitNode : 1; 84 // m_bHiddenByParaField is invalid, call CalcHiddenParaField() 85 mutable bool m_bCalcHiddenParaField : 1; 86 // if all fields controlling visibility of the paragraph require to hide it 87 // (if there's no such fields, or if any field requires to show, then this is false) 88 mutable bool m_bHiddenByParaField : 1; 89 bool m_bFootnote : 1; ///< footnotes 90 bool m_bDDEFields : 1; ///< the TextNode has DDE fields 91 // Sort on demand to avoid O(n^2) behaviour 92 mutable bool m_bStartMapNeedsSorting : 1; 93 mutable bool m_bEndMapNeedsSorting : 1; 94 mutable bool m_bWhichMapNeedsSorting : 1; 95 96 /// records a new attribute in m_pHistory. 97 void NoteInHistory( SwTextAttr *pAttr, const bool bNew = false ); 98 99 void CalcFlags( ); 100 101 /** Delete methods may only be called by the TextNode! 102 Because the TextNode also guarantees removal of the Character for 103 attributes without an end. */ 104 friend class SwTextNode; 105 void DeleteAtPos( size_t nPos ); 106 /// Delete the given Hint. The Hint must actually be in the array! 107 void Delete( SwTextAttr const * pTextHt ); 108 SetInSplitNode(bool bInSplit)109 void SetInSplitNode(bool bInSplit) { m_bInSplitNode = bInSplit; } SetCalcHiddenParaField() const110 void SetCalcHiddenParaField() const { m_bCalcHiddenParaField = true; } SetHiddenByParaField(const bool bNew) const111 void SetHiddenByParaField( const bool bNew ) const { m_bHiddenByParaField = bNew; } IsHiddenByParaField() const112 bool IsHiddenByParaField() const 113 { 114 if ( m_bCalcHiddenParaField ) 115 { 116 CalcHiddenParaField(); 117 } 118 return m_bHiddenByParaField; 119 } 120 121 void InsertNesting(SwTextAttrNesting & rNewHint); 122 bool TryInsertNesting(SwTextNode & rNode, SwTextAttrNesting & rNewHint); 123 void BuildPortions( SwTextNode& rNode, SwTextAttr& rNewHint, 124 const SetAttrMode nMode ); 125 bool MergePortions( SwTextNode& rNode ); 126 127 void Insert(SwTextAttr* pHt); 128 SW_DLLPUBLIC void Resort() const; 129 SW_DLLPUBLIC void ResortStartMap() const; 130 SW_DLLPUBLIC void ResortEndMap() const; 131 SW_DLLPUBLIC void ResortWhichMap() const; 132 133 size_t GetIndexOf( const SwTextAttr *pHt ) const; 134 135 #ifdef DBG_UTIL 136 bool Check(bool) const; 137 #endif 138 139 public: 140 SwpHints(const SwTextNode& rParent); 141 Count() const142 size_t Count() const { return m_HintsByStart.size(); } 143 bool Contains( const SwTextAttr *pHt ) const; Get(size_t nPos) const144 SwTextAttr * Get( size_t nPos ) const 145 { 146 assert( !(nPos != 0 && m_bStartMapNeedsSorting) && "going to trigger a resort in the middle of an iteration, that's bad" ); 147 if (m_bStartMapNeedsSorting) 148 ResortStartMap(); 149 return m_HintsByStart[nPos]; 150 } 151 // Get without triggering resorting - useful if we are modifying start/end pos while iterating GetWithoutResorting(size_t nPos) const152 SwTextAttr * GetWithoutResorting( size_t nPos ) const 153 { 154 return m_HintsByStart[nPos]; 155 } 156 157 int GetLastPosSortedByEnd(sal_Int32 nEndPos) const; GetSortedByEnd(size_t nPos) const158 SwTextAttr * GetSortedByEnd( size_t nPos ) const 159 { 160 assert( !(nPos != 0 && m_bEndMapNeedsSorting) && "going to trigger a resort in the middle of an iteration, that's bad" ); 161 if (m_bEndMapNeedsSorting) 162 ResortEndMap(); 163 return m_HintsByEnd[nPos]; 164 } 165 166 size_t GetFirstPosSortedByWhichAndStart(sal_uInt16 nWhich) const; GetSortedByWhichAndStart(size_t nPos) const167 SwTextAttr * GetSortedByWhichAndStart( size_t nPos ) const 168 { 169 assert( !(nPos != 0 && m_bWhichMapNeedsSorting) && "going to trigger a resort in the middle of an iteration, that's bad" ); 170 if (m_bWhichMapNeedsSorting) 171 ResortWhichMap(); 172 return m_HintsByWhichAndStart[nPos]; 173 } 174 175 /// Trigger the sorting if necessary SortIfNeedBe() const176 void SortIfNeedBe() const 177 { 178 if (m_bStartMapNeedsSorting) 179 ResortStartMap(); 180 if (m_bEndMapNeedsSorting) 181 ResortEndMap(); 182 if (m_bWhichMapNeedsSorting) 183 ResortWhichMap(); 184 } Cut(const size_t nPosInStart)185 SwTextAttr * Cut( const size_t nPosInStart ) 186 { 187 SwTextAttr *pHt = m_HintsByStart[nPosInStart]; 188 DeleteAtPos( nPosInStart ); 189 return pHt; 190 } 191 CanBeDeleted() const192 bool CanBeDeleted() const { return m_HintsByStart.empty(); } 193 194 /// register a History, which receives all attribute changes (for Undo) Register(SwRegHistory * pHist)195 void Register( SwRegHistory* pHist ) { m_pHistory = pHist; } 196 /// deregister the currently registered History DeRegister()197 void DeRegister() { Register(nullptr); } GetHistory() const198 SwRegHistory* GetHistory() const { return m_pHistory; } 199 200 /// try to insert the hint 201 /// @return true iff hint successfully inserted 202 bool TryInsertHint( SwTextAttr * const pHint, SwTextNode & rNode, 203 const SetAttrMode nMode = SetAttrMode::DEFAULT ); 204 HasFootnote() const205 bool HasFootnote() const { return m_bFootnote; } IsInSplitNode() const206 bool IsInSplitNode() const { return m_bInSplitNode; } 207 208 // calc current value of m_bHiddenByParaField, returns true iff changed 209 bool CalcHiddenParaField() const; // changes mutable state 210 211 // Marks the hint-maps as needing sorting because the position of something has changed StartPosChanged() const212 void StartPosChanged() const { m_bStartMapNeedsSorting = true; m_bEndMapNeedsSorting = true; m_bWhichMapNeedsSorting = true; } EndPosChanged() const213 void EndPosChanged() const { m_bStartMapNeedsSorting = true; m_bEndMapNeedsSorting = true; m_bWhichMapNeedsSorting = true; } 214 }; 215 216 #endif 217 218 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 219