diff options
author | Michael Stahl <mstahl@redhat.com> | 2013-06-19 20:52:11 +0200 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2013-06-20 00:34:38 +0200 |
commit | e012f326c1c32c053304998a6826cb322f2c7728 (patch) | |
tree | 6738393ea746d4407a013d4e4feebe7ca8346edc /sw | |
parent | e3e2cf30373446e5511b12467e3b8008311c81c2 (diff) |
sw: implement proper Undo for SwDoc::UpdateRsid
This is annoying because it's not possible to use StartUndo/EndUndo
because that would break grouping via SwUndoInsert::CanGrouping();
also SwUndoAttr is somehow incapable of removing the inserted hints of a
grouped insert (it seems to leave no-length hints behind); so add an
explicit call to DeleteAttributes which should avoid the no-length
hints.
Change-Id: I1533daed9b2cf59886f380141b4eace4b22c15e0
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/doc.hxx | 1 | ||||
-rw-r--r-- | sw/source/core/doc/doc.cxx | 35 | ||||
-rw-r--r-- | sw/source/core/doc/docfmt.cxx | 44 | ||||
-rw-r--r-- | sw/source/core/edit/editsh.cxx | 15 | ||||
-rw-r--r-- | sw/source/core/inc/UndoInsert.hxx | 3 | ||||
-rw-r--r-- | sw/source/core/undo/unins.cxx | 22 |
6 files changed, 75 insertions, 45 deletions
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index ee667453cabe..e3eeb61f9f5a 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -866,7 +866,6 @@ public: virtual bool Overwrite(const SwPaM &rRg, const String& rStr); virtual bool InsertString(const SwPaM &rRg, const String&, const enum InsertFlags nInsertMode = INS_EMPTYEXPAND ); - virtual bool UpdateRsid( SwTxtNode *pTxtNode, xub_StrLen nStt, xub_StrLen nEnd ); virtual bool UpdateParRsid( SwTxtNode *pTxtNode, sal_uInt32 nVal = 0 ); virtual bool UpdateRsid( const SwPaM &rRg, xub_StrLen nLen ); virtual SwFlyFrmFmt* Insert(const SwPaM &rRg, const String& rGrfName, const String& rFltName, const Graphic* pGraphic, diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx index 42aa6df15098..139735dac7bc 100644 --- a/sw/source/core/doc/doc.cxx +++ b/sw/source/core/doc/doc.cxx @@ -52,7 +52,6 @@ #include <editeng/forbiddencharacterstable.hxx> #include <svx/svdmodel.hxx> #include <editeng/pbinitem.hxx> -#include <editeng/rsiditem.hxx> #include <unotools/charclass.hxx> #include <unotools/localedatawrapper.hxx> #include <vcl/timer.hxx> @@ -1111,40 +1110,6 @@ SwFieldType *SwDoc::GetSysFldType( const sal_uInt16 eWhich ) const return 0; } -/// Set the rsid from nStt to nEnd of pTxtNode to the current session number -bool SwDoc::UpdateRsid( SwTxtNode *pTxtNode, xub_StrLen nStt, xub_StrLen nEnd ) -{ - if ( !pTxtNode ) - { - return false; - } - - SvxRsidItem aRsid( mnRsid, RES_CHRATR_RSID ); - SwTxtAttr* pAttr = MakeTxtAttr( *this, aRsid, nStt, nEnd ); - return pTxtNode->InsertHint( pAttr, INS_DEFAULT ); -} - -/// Set the rsid of the next nLen symbols of rRg to the current session number -bool SwDoc::UpdateRsid( const SwPaM &rRg, const xub_StrLen nLen ) -{ - const SwPosition* pPos = rRg.GetPoint(); - SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode(); - xub_StrLen nInsPos = pPos->nContent.GetIndex(); - - return UpdateRsid( pTxtNode, nInsPos - nLen, nInsPos ); -} - -bool SwDoc::UpdateParRsid( SwTxtNode *pTxtNode, sal_uInt32 nVal ) -{ - if ( !pTxtNode ) - { - return false; - } - - SvxRsidItem aRsid( nVal ? nVal : mnRsid, RES_PARATR_RSID ); - return pTxtNode->SetAttr( aRsid ); -} - void SwDoc::SetDocStat( const SwDocStat& rStat ) { *mpDocStat = rStat; diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx index 49a36da82d3b..748b5b28ca5b 100644 --- a/sw/source/core/doc/docfmt.cxx +++ b/sw/source/core/doc/docfmt.cxx @@ -26,6 +26,7 @@ #include <editeng/langitem.hxx> #include <editeng/lrspitem.hxx> #include <editeng/formatbreakitem.hxx> +#include <editeng/rsiditem.hxx> #include <svl/whiter.hxx> #include <svl/zforlist.hxx> #include <comphelper/processfactory.hxx> @@ -44,6 +45,7 @@ #include <pam.hxx> #include <UndoCore.hxx> #include <UndoAttribute.hxx> +#include <UndoInsert.hxx> #include <ndgrf.hxx> #include <pagedesc.hxx> // For special treatment in InsFrmFmt #include <rolbck.hxx> // Undo-Attr @@ -63,6 +65,7 @@ #include <fmtautofmt.hxx> #include <istyleaccess.hxx> #include <SwUndoFmt.hxx> +#include <UndoManager.hxx> #include <docsh.hxx> using namespace ::com::sun::star::i18n; @@ -1098,6 +1101,47 @@ bool SwDoc::InsertItemSet ( const SwPaM &rRg, const SfxItemSet &rSet, return bRet; } +/// Set the rsid of the next nLen symbols of rRg to the current session number +bool SwDoc::UpdateRsid( const SwPaM &rRg, const xub_StrLen nLen ) +{ + SwTxtNode *pTxtNode = rRg.GetPoint()->nNode.GetNode().GetTxtNode(); + if (!pTxtNode) + { + return false; + } + xub_StrLen const nStart(rRg.GetPoint()->nContent.GetIndex() - nLen); + SvxRsidItem aRsid( mnRsid, RES_CHRATR_RSID ); + + SfxItemSet aSet(GetAttrPool(), RES_CHRATR_RSID, RES_CHRATR_RSID); + aSet.Put(aRsid); + bool const bRet(pTxtNode->SetAttr(aSet, nStart, + rRg.GetPoint()->nContent.GetIndex(), nsSetAttrMode::SETATTR_DEFAULT)); + + if (bRet && GetIDocumentUndoRedo().DoesUndo()) + { + SwUndo *const pLastUndo = GetUndoManager().GetLastUndo(); + SwUndoInsert *const pUndoInsert(dynamic_cast<SwUndoInsert*>(pLastUndo)); + // this function is called after Insert so expects to find SwUndoInsert + assert(pUndoInsert); + if (pUndoInsert) + { + pUndoInsert->SetWithRsid(); + } + } + return bRet; +} + +bool SwDoc::UpdateParRsid( SwTxtNode *pTxtNode, sal_uInt32 nVal ) +{ + if (!pTxtNode) + { + return false; + } + + SvxRsidItem aRsid( nVal ? nVal : mnRsid, RES_PARATR_RSID ); + return pTxtNode->SetAttr( aRsid ); +} + /// Set the attribute according to the stated format. /// If Undo is enabled, the old values is added to the Undo history. void SwDoc::SetAttr( const SfxPoolItem& rAttr, SwFmt& rFmt ) diff --git a/sw/source/core/edit/editsh.cxx b/sw/source/core/edit/editsh.cxx index a13598aa0203..c49cb15fd4e3 100644 --- a/sw/source/core/edit/editsh.cxx +++ b/sw/source/core/edit/editsh.cxx @@ -95,14 +95,17 @@ void SwEditShell::Insert2(const String &rStr, const bool bForceExpandHints ) const bool bSuccess = GetDoc()->InsertString(*_pStartCrsr, rStr, nInsertFlags); OSL_ENSURE( bSuccess, "Doc->Insert() failed." ); - (void) bSuccess; - GetDoc()->UpdateRsid( *_pStartCrsr, rStr.Len() ); + if (bSuccess) + { + GetDoc()->UpdateRsid( *_pStartCrsr, rStr.Len() ); - // Set paragraph rsid if beginning of paragraph - SwTxtNode *pTxtNode = _pStartCrsr->GetPoint()->nNode.GetNode().GetTxtNode(); - if( pTxtNode && pTxtNode->Len() == 1) - GetDoc()->UpdateParRsid( pTxtNode ); + // Set paragraph rsid if beginning of paragraph + SwTxtNode *const pTxtNode = + _pStartCrsr->GetPoint()->nNode.GetNode().GetTxtNode(); + if( pTxtNode && pTxtNode->Len() == 1) + GetDoc()->UpdateParRsid( pTxtNode ); + } SaveTblBoxCntnt( _pStartCrsr->GetPoint() ); diff --git a/sw/source/core/inc/UndoInsert.hxx b/sw/source/core/inc/UndoInsert.hxx index e16644ce5811..b4689d3c7737 100644 --- a/sw/source/core/inc/UndoInsert.hxx +++ b/sw/source/core/inc/UndoInsert.hxx @@ -40,6 +40,7 @@ class SwUndoInsert: public SwUndo, private SwUndoSaveCntnt xub_StrLen nCntnt, nLen; sal_Bool bIsWordDelim : 1; sal_Bool bIsAppend : 1; + sal_Bool m_bWithRsid : 1; const IDocumentContentOperations::InsertFlags m_nInsertFlags; @@ -76,6 +77,8 @@ public: */ virtual SwRewriter GetRewriter() const; + void SetWithRsid() { m_bWithRsid = true; } + DECL_FIXEDMEMPOOL_NEWDEL(SwUndoInsert) }; diff --git a/sw/source/core/undo/unins.cxx b/sw/source/core/undo/unins.cxx index eafb7f4adcf1..cbacd830e7aa 100644 --- a/sw/source/core/undo/unins.cxx +++ b/sw/source/core/undo/unins.cxx @@ -115,6 +115,7 @@ SwUndoInsert::SwUndoInsert( const SwNodeIndex& rNd, xub_StrLen nCnt, : SwUndo(UNDO_TYPING), pTxt( 0 ), pRedlData( 0 ), nNode( rNd.GetIndex() ), nCntnt(nCnt), nLen(nL), bIsWordDelim( bWDelim ), bIsAppend( sal_False ) + , m_bWithRsid(false) , m_nInsertFlags(nInsertFlags) { Init(rNd); @@ -125,6 +126,7 @@ SwUndoInsert::SwUndoInsert( const SwNodeIndex& rNd ) : SwUndo(UNDO_SPLITNODE), pTxt( 0 ), pRedlData( 0 ), nNode( rNd.GetIndex() ), nCntnt(0), nLen(1), bIsWordDelim( sal_False ), bIsAppend( sal_True ) + , m_bWithRsid(false) , m_nInsertFlags(IDocumentContentOperations::INS_EMPTYEXPAND) { Init(rNd); @@ -208,8 +210,6 @@ SwUndoInsert::~SwUndoInsert() delete pUndoTxt; } - - void SwUndoInsert::UndoImpl(::sw::UndoRedoContext & rContext) { SwDoc *const pTmpDoc = & rContext.GetDoc(); @@ -249,6 +249,18 @@ void SwUndoInsert::UndoImpl(::sw::UndoRedoContext & rContext) aPaM.GetPoint()->nContent -= nLen; if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() )) pTmpDoc->DeleteRedline( aPaM, true, USHRT_MAX ); + if (m_bWithRsid) + { + // RSID was added: remove any CHARFMT/AUTOFMT that may be + // set on the deleted text; EraseText will leave empty + // ones behind otherwise + pTxtNode->DeleteAttributes(RES_TXTATR_AUTOFMT, + aPaM.GetPoint()->nContent.GetIndex(), + aPaM.GetMark()->nContent.GetIndex()); + pTxtNode->DeleteAttributes(RES_TXTATR_CHARFMT, + aPaM.GetPoint()->nContent.GetIndex(), + aPaM.GetMark()->nContent.GetIndex()); + } RemoveIdxFromRange( aPaM, sal_False ); pTxt = new String( pTxtNode->GetTxt().copy(nCntnt-nLen, nLen) ); pTxtNode->EraseText( aPaM.GetPoint()->nContent, nLen ); @@ -354,6 +366,11 @@ void SwUndoInsert::RedoImpl(::sw::UndoRedoContext & rContext) m_nInsertFlags) ); assert(ins.getLength() == pTxt->Len()); // must succeed DELETEZ( pTxt ); + if (m_bWithRsid) // re-insert RSID + { + SwPaM pam(*pPam->GetMark(), 0); // mark -> point + pTmpDoc->UpdateRsid(pam, ins.getLength()); + } } else { @@ -384,7 +401,6 @@ void SwUndoInsert::RedoImpl(::sw::UndoRedoContext & rContext) pUndoTxt = GetTxtFromDoc(); } - void SwUndoInsert::RepeatImpl(::sw::RepeatContext & rContext) { if( !nLen ) |