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_UNDOBJ_HXX 20 #define INCLUDED_SW_INC_UNDOBJ_HXX 21 22 #include <vector> 23 #include <memory> 24 25 #include <svl/undo.hxx> 26 #include <tools/solar.h> 27 #include "SwRewriter.hxx" 28 #include "swundo.hxx" 29 #include <o3tl/typed_flags_set.hxx> 30 #include <boost/optional.hpp> 31 32 class SwHistory; 33 class SwPaM; 34 struct SwPosition; 35 class SwDoc; 36 class SwTextFormatColl; 37 class SwFrameFormat; 38 class SwFormatAnchor; 39 class SwNodeIndex; 40 class SwNodeRange; 41 class SwRedlineData; 42 class SwRedlineSaveDatas; 43 enum class RedlineFlags; 44 enum class RndStdIds; 45 46 namespace sw { 47 class UndoRedoContext; 48 class RepeatContext; 49 } 50 51 class SwUndo 52 : public SfxUndoAction 53 { 54 SwUndoId const m_nId; 55 RedlineFlags m_nOrigRedlineFlags; 56 ViewShellId const m_nViewShellId; 57 bool m_isRepeatIgnored; ///< for multi-selection, only repeat 1st selection 58 59 protected: 60 bool m_bCacheComment; 61 mutable boost::optional<OUString> maComment; 62 63 static void RemoveIdxFromSection( SwDoc&, sal_uLong nSttIdx, const sal_uLong* pEndIdx = nullptr ); 64 static void RemoveIdxFromRange( SwPaM& rPam, bool bMoveNext ); 65 static void RemoveIdxRel( sal_uLong, const SwPosition& ); 66 67 static bool CanRedlineGroup( SwRedlineSaveDatas& rCurr, 68 const SwRedlineSaveDatas& rCheck, 69 bool bCurrIsEnd ); 70 71 /** 72 Returns the rewriter for this object. 73 74 @return the rewriter for this object 75 */ 76 virtual SwRewriter GetRewriter() const; 77 78 // the 4 methods that derived classes have to override 79 // base implementation does nothing 80 virtual void RepeatImpl( ::sw::RepeatContext & ); 81 public: // should not be public, but ran into trouble in untbl.cxx 82 virtual void UndoImpl( ::sw::UndoRedoContext & ) = 0; 83 virtual void RedoImpl( ::sw::UndoRedoContext & ) = 0; 84 85 private: 86 /// Try to obtain the view shell ID of the current view. 87 static ViewShellId CreateViewShellId(const SwDoc* pDoc); 88 // SfxUndoAction 89 virtual void Undo() override; 90 virtual void Redo() override; 91 virtual void UndoWithContext(SfxUndoContext &) override; 92 virtual void RedoWithContext(SfxUndoContext &) override; 93 virtual void Repeat(SfxRepeatTarget &) override; 94 virtual bool CanRepeat(SfxRepeatTarget &) const override; 95 96 public: 97 SwUndo(SwUndoId const nId, const SwDoc* pDoc); 98 virtual ~SwUndo() override; 99 GetId() const100 SwUndoId GetId() const { return m_nId; } 101 102 /** 103 Returns textual comment for this undo object. 104 105 The textual comment is created from the resource string 106 corresponding to this object's ID. The rewriter of this object 107 is applied to the resource string to get the final comment. 108 109 @return textual comment for this undo object 110 */ 111 virtual OUString GetComment() const override; 112 113 /// See SfxUndoAction::GetViewShellId(). 114 ViewShellId GetViewShellId() const override; 115 116 // UndoObject remembers which mode was turned on. 117 // In Undo/Redo/Repeat this remembered mode is switched on. GetRedlineFlags() const118 RedlineFlags GetRedlineFlags() const { return m_nOrigRedlineFlags; } SetRedlineFlags(RedlineFlags eMode)119 void SetRedlineFlags( RedlineFlags eMode ) { m_nOrigRedlineFlags = eMode; } 120 121 bool IsDelBox() const; 122 123 // Save and set Redline data. 124 static bool FillSaveData( const SwPaM& rRange, SwRedlineSaveDatas& rSData, 125 bool bDelRange = true, bool bCopyNext = true ); 126 static bool FillSaveDataForFormat( const SwPaM& , SwRedlineSaveDatas& ); 127 static void SetSaveData( SwDoc& rDoc, SwRedlineSaveDatas& rSData ); 128 static bool HasHiddenRedlines( const SwRedlineSaveDatas& rSData ); IgnoreRepeat()129 void IgnoreRepeat() { m_isRepeatIgnored = true; } 130 }; 131 132 enum class DelContentType : sal_uInt16 133 { 134 Ftn = 0x01, 135 Fly = 0x02, 136 Bkm = 0x08, 137 AllMask = 0x0b, 138 Replace = 0x10, 139 WriterfilterHack = 0x20, 140 ExcludeFlyAtStartEnd = 0x40, 141 CheckNoCntnt = 0x80, 142 }; 143 namespace o3tl { 144 template<> struct typed_flags<DelContentType> : is_typed_flags<DelContentType, 0xfb> {}; 145 } 146 147 /// will DelContentIndex destroy a frame anchored at character at rAnchorPos? 148 bool IsDestroyFrameAnchoredAtChar(SwPosition const & rAnchorPos, 149 SwPosition const & rStart, SwPosition const & rEnd, 150 DelContentType const nDelContentType = DelContentType::AllMask); 151 /// is a fly anchored at paragraph at rAnchorPos selected? 152 bool IsSelectFrameAnchoredAtPara(SwPosition const & rAnchorPos, 153 SwPosition const & rStart, SwPosition const & rEnd, 154 DelContentType const nDelContentType = DelContentType::AllMask); 155 /// check at-char and at-para flys in rDoc 156 bool IsFlySelectedByCursor(SwDoc const & rDoc, 157 SwPosition const & rStart, SwPosition const & rEnd); 158 159 // This class has to be inherited into an Undo-object if it saves content 160 // for Redo/Undo... 161 class SwUndoSaveContent 162 { 163 protected: 164 165 std::unique_ptr<SwHistory> m_pHistory; 166 167 // Needed for deletion of content. For Redo content is moved into the 168 // UndoNodesArray. These methods always create a new node to insert 169 // content. So the attributes do not get expanded. 170 // MoveTo: moves from the NodesArray into the UndoNodesArray. 171 // MoveFrom: moves from the UndoNodesArray into the NodesArray. 172 static void MoveToUndoNds( SwPaM& rPam, 173 SwNodeIndex* pNodeIdx, 174 sal_uLong* pEndNdIdx = nullptr ); 175 static void MoveFromUndoNds( SwDoc& rDoc, sal_uLong nNodeIdx, 176 SwPosition& rInsPos, 177 const sal_uLong* pEndNdIdx = nullptr, 178 bool bForceCreateFrames = false); 179 180 // These two methods move the SPoint back/forth from PaM. With it 181 // a range can be spanned for Undo/Redo. (In this case the SPoint 182 // is before the manipulated range!!) 183 // The flag indicates if there is content before the SPoint. 184 static bool MovePtBackward( SwPaM& rPam ); 185 static void MovePtForward( SwPaM& rPam, bool bMvBkwrd ); 186 187 // Before moving stuff into UndoNodes-Array care has to be taken that 188 // the content-bearing attributes are removed from the nodes-array. 189 void DelContentIndex( const SwPosition& pMark, const SwPosition& pPoint, 190 DelContentType nDelContentType = DelContentType::AllMask ); 191 192 public: 193 SwUndoSaveContent(); 194 ~SwUndoSaveContent() COVERITY_NOEXCEPT_FALSE; 195 }; 196 197 // Save a complete section in nodes-array. 198 class SwUndoSaveSection : private SwUndoSaveContent 199 { 200 std::unique_ptr<SwNodeIndex> m_pMovedStart; 201 std::unique_ptr<SwRedlineSaveDatas> m_pRedlineSaveData; 202 sal_uLong m_nMoveLen; // Index into UndoNodes-Array. 203 sal_uLong m_nStartPos; 204 205 protected: GetMvSttIdx() const206 SwNodeIndex* GetMvSttIdx() const { return m_pMovedStart.get(); } GetMvNodeCnt() const207 sal_uLong GetMvNodeCnt() const { return m_nMoveLen; } 208 209 public: 210 SwUndoSaveSection(); 211 ~SwUndoSaveSection(); 212 213 void SaveSection( const SwNodeIndex& rSttIdx ); 214 void SaveSection(const SwNodeRange& rRange, bool bExpandNodes = true); 215 void RestoreSection( SwDoc* pDoc, SwNodeIndex* pIdx, sal_uInt16 nSectType ); 216 void RestoreSection(SwDoc* pDoc, const SwNodeIndex& rInsPos, bool bForceCreateFrames = false); 217 GetHistory() const218 const SwHistory* GetHistory() const { return m_pHistory.get(); } GetHistory()219 SwHistory* GetHistory() { return m_pHistory.get(); } 220 }; 221 222 // This class saves the PaM as sal_uInt16's and is able to restore it 223 // into a PaM. 224 class SwUndRng 225 { 226 public: 227 sal_uLong m_nSttNode, m_nEndNode; 228 sal_Int32 m_nSttContent, m_nEndContent; 229 230 SwUndRng(); 231 SwUndRng( const SwPaM& ); 232 233 void SetValues( const SwPaM& rPam ); 234 void SetPaM( SwPaM&, bool bCorrToContent = false ) const; 235 SwPaM & AddUndoRedoPaM( 236 ::sw::UndoRedoContext &, bool const bCorrToContent = false) const; 237 }; 238 239 class SwUndoInsLayFormat; 240 241 namespace sw { 242 243 std::unique_ptr<std::vector<SwFrameFormat*>> 244 GetFlysAnchoredAt(SwDoc & rDoc, sal_uLong nSttNode); 245 246 } 247 248 // base class for insertion of Document, Glossaries and Copy 249 class SwUndoInserts : public SwUndo, public SwUndRng, private SwUndoSaveContent 250 { 251 SwTextFormatColl *m_pTextFormatColl, *m_pLastNodeColl; 252 std::unique_ptr<std::vector<SwFrameFormat*>> m_pFrameFormats; 253 std::vector< std::shared_ptr<SwUndoInsLayFormat> > m_FlyUndos; 254 std::unique_ptr<SwRedlineData> m_pRedlineData; 255 int m_nDeleteTextNodes; 256 257 protected: 258 sal_uLong m_nNodeDiff; 259 /// start of Content in UndoNodes for Redo 260 std::unique_ptr<SwNodeIndex> m_pUndoNodeIndex; 261 sal_uInt16 m_nSetPos; // Start in the history list. 262 263 SwUndoInserts( SwUndoId nUndoId, const SwPaM& ); 264 public: 265 virtual ~SwUndoInserts() override; 266 267 virtual void UndoImpl( ::sw::UndoRedoContext & ) override; 268 virtual void RedoImpl( ::sw::UndoRedoContext & ) override; 269 virtual void RepeatImpl( ::sw::RepeatContext & ) override; 270 271 // Set destination range after reading. 272 void SetInsertRange( const SwPaM&, bool bScanFlys = true, 273 int nDeleteTextNodes = 1); 274 275 static bool IsCreateUndoForNewFly(SwFormatAnchor const& rAnchor, 276 sal_uLong const nStartNode, sal_uLong const nEndNode); GetFlysAnchoredAt()277 std::vector<SwFrameFormat*> * GetFlysAnchoredAt() { return m_pFrameFormats.get(); } 278 }; 279 280 class SwUndoInsDoc final : public SwUndoInserts 281 { 282 public: 283 SwUndoInsDoc( const SwPaM& ); 284 }; 285 286 class SwUndoCpyDoc final : public SwUndoInserts 287 { 288 public: 289 SwUndoCpyDoc( const SwPaM& ); 290 }; 291 292 class SwUndoFlyBase : public SwUndo, private SwUndoSaveSection 293 { 294 protected: 295 SwFrameFormat* m_pFrameFormat; // The saved FlyFormat. 296 sal_uLong m_nNodePagePos; 297 sal_Int32 m_nContentPos; // Page at/in paragraph. 298 RndStdIds m_nRndId; 299 bool m_bDelFormat; // Delete saved format. 300 301 void InsFly(::sw::UndoRedoContext & rContext, bool bShowSel = true); 302 void DelFly( SwDoc* ); 303 304 SwUndoFlyBase( SwFrameFormat* pFormat, SwUndoId nUndoId ); 305 GetMvSttIdx() const306 SwNodeIndex* GetMvSttIdx() const { return SwUndoSaveSection::GetMvSttIdx(); } GetMvNodeCnt() const307 sal_uLong GetMvNodeCnt() const { return SwUndoSaveSection::GetMvNodeCnt(); } 308 309 public: 310 virtual ~SwUndoFlyBase() override; 311 312 }; 313 314 class SwUndoInsLayFormat : public SwUndoFlyBase 315 { 316 sal_uLong mnCursorSaveIndexPara; // Cursor position 317 sal_Int32 const mnCursorSaveIndexPos; // for undo 318 public: 319 SwUndoInsLayFormat( SwFrameFormat* pFormat, sal_uLong nNodeIdx, sal_Int32 nCntIdx ); 320 321 virtual ~SwUndoInsLayFormat() override; 322 323 virtual void UndoImpl( ::sw::UndoRedoContext & ) override; 324 virtual void RedoImpl( ::sw::UndoRedoContext & ) override; 325 virtual void RepeatImpl( ::sw::RepeatContext & ) override; 326 327 virtual OUString GetComment() const override; 328 329 }; 330 331 class SwUndoDelLayFormat final : public SwUndoFlyBase 332 { 333 bool m_bShowSelFrame; 334 public: 335 SwUndoDelLayFormat( SwFrameFormat* pFormat ); 336 337 virtual void UndoImpl( ::sw::UndoRedoContext & ) override; 338 virtual void RedoImpl( ::sw::UndoRedoContext & ) override; 339 340 void RedoForRollback(); 341 ChgShowSel(bool bNew)342 void ChgShowSel( bool bNew ) { m_bShowSelFrame = bNew; } 343 344 virtual SwRewriter GetRewriter() const override; 345 346 }; 347 348 #endif 349 350 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 351