Kaydet (Commit) e012f326 authored tarafından Michael Stahl's avatar Michael Stahl

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
üst e3e2cf30
...@@ -866,7 +866,6 @@ public: ...@@ -866,7 +866,6 @@ public:
virtual bool Overwrite(const SwPaM &rRg, const String& rStr); virtual bool Overwrite(const SwPaM &rRg, const String& rStr);
virtual bool InsertString(const SwPaM &rRg, const String&, virtual bool InsertString(const SwPaM &rRg, const String&,
const enum InsertFlags nInsertMode = INS_EMPTYEXPAND ); 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 UpdateParRsid( SwTxtNode *pTxtNode, sal_uInt32 nVal = 0 );
virtual bool UpdateRsid( const SwPaM &rRg, xub_StrLen nLen ); virtual bool UpdateRsid( const SwPaM &rRg, xub_StrLen nLen );
virtual SwFlyFrmFmt* Insert(const SwPaM &rRg, const String& rGrfName, const String& rFltName, const Graphic* pGraphic, virtual SwFlyFrmFmt* Insert(const SwPaM &rRg, const String& rGrfName, const String& rFltName, const Graphic* pGraphic,
......
...@@ -52,7 +52,6 @@ ...@@ -52,7 +52,6 @@
#include <editeng/forbiddencharacterstable.hxx> #include <editeng/forbiddencharacterstable.hxx>
#include <svx/svdmodel.hxx> #include <svx/svdmodel.hxx>
#include <editeng/pbinitem.hxx> #include <editeng/pbinitem.hxx>
#include <editeng/rsiditem.hxx>
#include <unotools/charclass.hxx> #include <unotools/charclass.hxx>
#include <unotools/localedatawrapper.hxx> #include <unotools/localedatawrapper.hxx>
#include <vcl/timer.hxx> #include <vcl/timer.hxx>
...@@ -1111,40 +1110,6 @@ SwFieldType *SwDoc::GetSysFldType( const sal_uInt16 eWhich ) const ...@@ -1111,40 +1110,6 @@ SwFieldType *SwDoc::GetSysFldType( const sal_uInt16 eWhich ) const
return 0; 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 ) void SwDoc::SetDocStat( const SwDocStat& rStat )
{ {
*mpDocStat = rStat; *mpDocStat = rStat;
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <editeng/langitem.hxx> #include <editeng/langitem.hxx>
#include <editeng/lrspitem.hxx> #include <editeng/lrspitem.hxx>
#include <editeng/formatbreakitem.hxx> #include <editeng/formatbreakitem.hxx>
#include <editeng/rsiditem.hxx>
#include <svl/whiter.hxx> #include <svl/whiter.hxx>
#include <svl/zforlist.hxx> #include <svl/zforlist.hxx>
#include <comphelper/processfactory.hxx> #include <comphelper/processfactory.hxx>
...@@ -44,6 +45,7 @@ ...@@ -44,6 +45,7 @@
#include <pam.hxx> #include <pam.hxx>
#include <UndoCore.hxx> #include <UndoCore.hxx>
#include <UndoAttribute.hxx> #include <UndoAttribute.hxx>
#include <UndoInsert.hxx>
#include <ndgrf.hxx> #include <ndgrf.hxx>
#include <pagedesc.hxx> // For special treatment in InsFrmFmt #include <pagedesc.hxx> // For special treatment in InsFrmFmt
#include <rolbck.hxx> // Undo-Attr #include <rolbck.hxx> // Undo-Attr
...@@ -63,6 +65,7 @@ ...@@ -63,6 +65,7 @@
#include <fmtautofmt.hxx> #include <fmtautofmt.hxx>
#include <istyleaccess.hxx> #include <istyleaccess.hxx>
#include <SwUndoFmt.hxx> #include <SwUndoFmt.hxx>
#include <UndoManager.hxx>
#include <docsh.hxx> #include <docsh.hxx>
using namespace ::com::sun::star::i18n; using namespace ::com::sun::star::i18n;
...@@ -1098,6 +1101,47 @@ bool SwDoc::InsertItemSet ( const SwPaM &rRg, const SfxItemSet &rSet, ...@@ -1098,6 +1101,47 @@ bool SwDoc::InsertItemSet ( const SwPaM &rRg, const SfxItemSet &rSet,
return bRet; 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. /// Set the attribute according to the stated format.
/// If Undo is enabled, the old values is added to the Undo history. /// If Undo is enabled, the old values is added to the Undo history.
void SwDoc::SetAttr( const SfxPoolItem& rAttr, SwFmt& rFmt ) void SwDoc::SetAttr( const SfxPoolItem& rAttr, SwFmt& rFmt )
......
...@@ -95,14 +95,17 @@ void SwEditShell::Insert2(const String &rStr, const bool bForceExpandHints ) ...@@ -95,14 +95,17 @@ void SwEditShell::Insert2(const String &rStr, const bool bForceExpandHints )
const bool bSuccess = const bool bSuccess =
GetDoc()->InsertString(*_pStartCrsr, rStr, nInsertFlags); GetDoc()->InsertString(*_pStartCrsr, rStr, nInsertFlags);
OSL_ENSURE( bSuccess, "Doc->Insert() failed." ); 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 // Set paragraph rsid if beginning of paragraph
SwTxtNode *pTxtNode = _pStartCrsr->GetPoint()->nNode.GetNode().GetTxtNode(); SwTxtNode *const pTxtNode =
if( pTxtNode && pTxtNode->Len() == 1) _pStartCrsr->GetPoint()->nNode.GetNode().GetTxtNode();
GetDoc()->UpdateParRsid( pTxtNode ); if( pTxtNode && pTxtNode->Len() == 1)
GetDoc()->UpdateParRsid( pTxtNode );
}
SaveTblBoxCntnt( _pStartCrsr->GetPoint() ); SaveTblBoxCntnt( _pStartCrsr->GetPoint() );
......
...@@ -40,6 +40,7 @@ class SwUndoInsert: public SwUndo, private SwUndoSaveCntnt ...@@ -40,6 +40,7 @@ class SwUndoInsert: public SwUndo, private SwUndoSaveCntnt
xub_StrLen nCntnt, nLen; xub_StrLen nCntnt, nLen;
sal_Bool bIsWordDelim : 1; sal_Bool bIsWordDelim : 1;
sal_Bool bIsAppend : 1; sal_Bool bIsAppend : 1;
sal_Bool m_bWithRsid : 1;
const IDocumentContentOperations::InsertFlags m_nInsertFlags; const IDocumentContentOperations::InsertFlags m_nInsertFlags;
...@@ -76,6 +77,8 @@ public: ...@@ -76,6 +77,8 @@ public:
*/ */
virtual SwRewriter GetRewriter() const; virtual SwRewriter GetRewriter() const;
void SetWithRsid() { m_bWithRsid = true; }
DECL_FIXEDMEMPOOL_NEWDEL(SwUndoInsert) DECL_FIXEDMEMPOOL_NEWDEL(SwUndoInsert)
}; };
......
...@@ -115,6 +115,7 @@ SwUndoInsert::SwUndoInsert( const SwNodeIndex& rNd, xub_StrLen nCnt, ...@@ -115,6 +115,7 @@ SwUndoInsert::SwUndoInsert( const SwNodeIndex& rNd, xub_StrLen nCnt,
: SwUndo(UNDO_TYPING), pTxt( 0 ), pRedlData( 0 ), : SwUndo(UNDO_TYPING), pTxt( 0 ), pRedlData( 0 ),
nNode( rNd.GetIndex() ), nCntnt(nCnt), nLen(nL), nNode( rNd.GetIndex() ), nCntnt(nCnt), nLen(nL),
bIsWordDelim( bWDelim ), bIsAppend( sal_False ) bIsWordDelim( bWDelim ), bIsAppend( sal_False )
, m_bWithRsid(false)
, m_nInsertFlags(nInsertFlags) , m_nInsertFlags(nInsertFlags)
{ {
Init(rNd); Init(rNd);
...@@ -125,6 +126,7 @@ SwUndoInsert::SwUndoInsert( const SwNodeIndex& rNd ) ...@@ -125,6 +126,7 @@ SwUndoInsert::SwUndoInsert( const SwNodeIndex& rNd )
: SwUndo(UNDO_SPLITNODE), pTxt( 0 ), : SwUndo(UNDO_SPLITNODE), pTxt( 0 ),
pRedlData( 0 ), nNode( rNd.GetIndex() ), nCntnt(0), nLen(1), pRedlData( 0 ), nNode( rNd.GetIndex() ), nCntnt(0), nLen(1),
bIsWordDelim( sal_False ), bIsAppend( sal_True ) bIsWordDelim( sal_False ), bIsAppend( sal_True )
, m_bWithRsid(false)
, m_nInsertFlags(IDocumentContentOperations::INS_EMPTYEXPAND) , m_nInsertFlags(IDocumentContentOperations::INS_EMPTYEXPAND)
{ {
Init(rNd); Init(rNd);
...@@ -208,8 +210,6 @@ SwUndoInsert::~SwUndoInsert() ...@@ -208,8 +210,6 @@ SwUndoInsert::~SwUndoInsert()
delete pUndoTxt; delete pUndoTxt;
} }
void SwUndoInsert::UndoImpl(::sw::UndoRedoContext & rContext) void SwUndoInsert::UndoImpl(::sw::UndoRedoContext & rContext)
{ {
SwDoc *const pTmpDoc = & rContext.GetDoc(); SwDoc *const pTmpDoc = & rContext.GetDoc();
...@@ -249,6 +249,18 @@ void SwUndoInsert::UndoImpl(::sw::UndoRedoContext & rContext) ...@@ -249,6 +249,18 @@ void SwUndoInsert::UndoImpl(::sw::UndoRedoContext & rContext)
aPaM.GetPoint()->nContent -= nLen; aPaM.GetPoint()->nContent -= nLen;
if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() )) if( IDocumentRedlineAccess::IsRedlineOn( GetRedlineMode() ))
pTmpDoc->DeleteRedline( aPaM, true, USHRT_MAX ); 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 ); RemoveIdxFromRange( aPaM, sal_False );
pTxt = new String( pTxtNode->GetTxt().copy(nCntnt-nLen, nLen) ); pTxt = new String( pTxtNode->GetTxt().copy(nCntnt-nLen, nLen) );
pTxtNode->EraseText( aPaM.GetPoint()->nContent, nLen ); pTxtNode->EraseText( aPaM.GetPoint()->nContent, nLen );
...@@ -354,6 +366,11 @@ void SwUndoInsert::RedoImpl(::sw::UndoRedoContext & rContext) ...@@ -354,6 +366,11 @@ void SwUndoInsert::RedoImpl(::sw::UndoRedoContext & rContext)
m_nInsertFlags) ); m_nInsertFlags) );
assert(ins.getLength() == pTxt->Len()); // must succeed assert(ins.getLength() == pTxt->Len()); // must succeed
DELETEZ( pTxt ); DELETEZ( pTxt );
if (m_bWithRsid) // re-insert RSID
{
SwPaM pam(*pPam->GetMark(), 0); // mark -> point
pTmpDoc->UpdateRsid(pam, ins.getLength());
}
} }
else else
{ {
...@@ -384,7 +401,6 @@ void SwUndoInsert::RedoImpl(::sw::UndoRedoContext & rContext) ...@@ -384,7 +401,6 @@ void SwUndoInsert::RedoImpl(::sw::UndoRedoContext & rContext)
pUndoTxt = GetTxtFromDoc(); pUndoTxt = GetTxtFromDoc();
} }
void SwUndoInsert::RepeatImpl(::sw::RepeatContext & rContext) void SwUndoInsert::RepeatImpl(::sw::RepeatContext & rContext)
{ {
if( !nLen ) if( !nLen )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment