summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2013-06-19 20:52:11 +0200
committerMichael Stahl <mstahl@redhat.com>2013-06-20 00:34:38 +0200
commite012f326c1c32c053304998a6826cb322f2c7728 (patch)
tree6738393ea746d4407a013d4e4feebe7ca8346edc /sw
parente3e2cf30373446e5511b12467e3b8008311c81c2 (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.hxx1
-rw-r--r--sw/source/core/doc/doc.cxx35
-rw-r--r--sw/source/core/doc/docfmt.cxx44
-rw-r--r--sw/source/core/edit/editsh.cxx15
-rw-r--r--sw/source/core/inc/UndoInsert.hxx3
-rw-r--r--sw/source/core/undo/unins.cxx22
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 )