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:
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,
......
......@@ -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;
......
......@@ -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 )
......
......@@ -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() );
......
......@@ -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)
};
......
......@@ -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 )
......
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