summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver-Rainer Wittmann <orw@apache.org>2013-06-26 12:15:55 +0000
committerCaolán McNamara <caolanm@redhat.com>2013-06-26 16:22:38 +0100
commit25d84e2826de81d1e7a55ff0fdab7845b7a78e74 (patch)
tree904e93931dd60504341c9a710aad5140784222da
parent19694e844942d44d2c2d5e1d1b95b49d03916573 (diff)
Resolves: #i121751# restore cursor/selection on Undo/Redo language...
change for all text - group intrinsic actions of language change for all text into one Undo action - secure <SwRootFrm::CalcRects(..)> - catch NULL pointer - correct <CursorGuard> - really restore the cursor (cherry picked from commit 4207db473430e02a65a5f4d57db6e46a8db29a19) Conflicts: svl/inc/svl/undo.hxx svl/source/undo/undo.cxx sw/inc/IDocumentUndoRedo.hxx sw/source/core/edit/edundo.cxx sw/source/core/inc/UndoManager.hxx sw/source/core/layout/trvlfrm.cxx sw/source/core/undo/docundo.cxx Change-Id: I972988bbc21a519e0956ff196aa93a46287b9a2e
-rw-r--r--include/svl/undo.hxx2
-rw-r--r--svl/source/undo/undo.cxx21
-rw-r--r--sw/inc/IDocumentUndoRedo.hxx6
-rw-r--r--sw/source/core/edit/edundo.cxx15
-rw-r--r--sw/source/core/inc/UndoManager.hxx6
-rw-r--r--sw/source/core/layout/trvlfrm.cxx61
-rw-r--r--sw/source/core/undo/docundo.cxx21
-rw-r--r--sw/source/ui/shells/textsh1.cxx5
8 files changed, 95 insertions, 42 deletions
diff --git a/include/svl/undo.hxx b/include/svl/undo.hxx
index c1054a6ac3bf..3e59baa693db 100644
--- a/include/svl/undo.hxx
+++ b/include/svl/undo.hxx
@@ -240,6 +240,7 @@ namespace svl
virtual size_t GetRedoActionCount( bool const i_currentLevel = CurrentLevel ) const = 0;
virtual OUString GetRedoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const = 0;
+ virtual SfxUndoAction* GetRedoAction( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const = 0;
virtual sal_Bool Undo() = 0;
virtual sal_Bool Redo() = 0;
@@ -358,6 +359,7 @@ public:
virtual SfxUndoAction* GetUndoAction( size_t nNo=0 ) const;
virtual size_t GetRedoActionCount( bool const i_currentLevel = CurrentLevel ) const;
virtual OUString GetRedoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const;
+ virtual SfxUndoAction* GetRedoAction( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const;
virtual sal_Bool Undo();
virtual sal_Bool Redo();
virtual void Clear();
diff --git a/svl/source/undo/undo.cxx b/svl/source/undo/undo.cxx
index dac5dc3d37dc..d27de22e266e 100644
--- a/svl/source/undo/undo.cxx
+++ b/svl/source/undo/undo.cxx
@@ -830,11 +830,30 @@ size_t SfxUndoManager::ImplGetRedoActionCount_Lock( bool const i_currentLevel )
//------------------------------------------------------------------------
+SfxUndoAction* SfxUndoManager::GetRedoAction( size_t nNo, bool const i_currentLevel ) const
+{
+ UndoManagerGuard aGuard( *m_pData );
+
+ const SfxUndoArray* pUndoArray = i_currentLevel ? m_pData->pActUndoArray : m_pData->pUndoArray;
+ if ( (pUndoArray->nCurUndoAction + nNo) > pUndoArray->aUndoActions.size() )
+ {
+ return NULL;
+ }
+ return pUndoArray->aUndoActions[ pUndoArray->nCurUndoAction + nNo ].pAction;
+}
+
+//------------------------------------------------------------------------
+
OUString SfxUndoManager::GetRedoActionComment( size_t nNo, bool const i_currentLevel ) const
{
+ String sComment;
UndoManagerGuard aGuard( *m_pData );
const SfxUndoArray* pUndoArray = i_currentLevel ? m_pData->pActUndoArray : m_pData->pUndoArray;
- return pUndoArray->aUndoActions[ pUndoArray->nCurUndoAction + nNo ].pAction->GetComment();
+ if ( (pUndoArray->nCurUndoAction + nNo) < pUndoArray->aUndoActions.size() )
+ {
+ sComment = pUndoArray->aUndoActions[ pUndoArray->nCurUndoAction + nNo ].pAction->GetComment();
+ }
+ return sComment;
}
//------------------------------------------------------------------------
diff --git a/sw/inc/IDocumentUndoRedo.hxx b/sw/inc/IDocumentUndoRedo.hxx
index 26e76f0b838f..a50a4f0dcbb4 100644
--- a/sw/inc/IDocumentUndoRedo.hxx
+++ b/sw/inc/IDocumentUndoRedo.hxx
@@ -156,11 +156,13 @@ public:
*/
virtual sal_Bool Redo() = 0;
- /** Get comment of first Redo action.
+ /** Get Id and comment of first Redo action.
@param o_pStr if not 0, receives comment of first Redo action.
+ @param o_pId if not 0, receives Id of first Redo action.
@return true if there is a Redo action, false if none
*/
- virtual bool GetFirstRedoInfo(OUString *const o_pStr) const = 0;
+ virtual bool GetFirstRedoInfo(OUString *const o_pStr,
+ SwUndoId *const o_pId = 0) const = 0;
/** Get comments of Redo actions.
@return comments of all top-level Redo actions.
diff --git a/sw/source/core/edit/edundo.cxx b/sw/source/core/edit/edundo.cxx
index bd27446a374f..4fa0ceef53be 100644
--- a/sw/source/core/edit/edundo.cxx
+++ b/sw/source/core/edit/edundo.cxx
@@ -111,9 +111,11 @@ bool SwEditShell::Undo(sal_uInt16 const nCount)
// Keep Cursor - so that we're able to set it at
// the same position for autoformat or autocorrection
SwUndoId nLastUndoId(UNDO_EMPTY);
- GetDoc()->GetIDocumentUndoRedo().GetLastUndoInfo(0, & nLastUndoId);
- bool bRestoreCrsr = 1 == nCount && (UNDO_AUTOFORMAT == nLastUndoId ||
- UNDO_AUTOCORRECT == nLastUndoId );
+ GetLastUndoInfo(0, & nLastUndoId);
+ const bool bRestoreCrsr = nCount == 1
+ && ( UNDO_AUTOFORMAT == nLastUndoId
+ || UNDO_AUTOCORRECT == nLastUndoId
+ || UNDO_SETDEFTATTR == nLastUndoId );
Push();
// Destroy stored TableBoxPtr. A dection is only permitted for the new "Box"!
@@ -168,6 +170,11 @@ bool SwEditShell::Redo(sal_uInt16 const nCount)
SetMark(); // Bound1 and Bound2 in the same Node
ClearMark();
+ SwUndoId nFirstRedoId(UNDO_EMPTY);
+ GetDoc()->GetIDocumentUndoRedo().GetFirstRedoInfo(0, & nFirstRedoId);
+ const bool bRestoreCrsr = nCount == 1 && UNDO_SETDEFTATTR == nFirstRedoId;
+ Push();
+
// Destroy stored TableBoxPtr. A dection is only permitted for the new "Box"!
ClearTblBoxCntnt();
@@ -185,6 +192,8 @@ bool SwEditShell::Redo(sal_uInt16 const nCount)
.getStr());
}
+ Pop( !bRestoreCrsr );
+
GetDoc()->SetRedlineMode( eOld );
GetDoc()->CompressRedlines();
diff --git a/sw/source/core/inc/UndoManager.hxx b/sw/source/core/inc/UndoManager.hxx
index 0db18261bf60..3b7d1136418d 100644
--- a/sw/source/core/inc/UndoManager.hxx
+++ b/sw/source/core/inc/UndoManager.hxx
@@ -59,10 +59,10 @@ public:
SwRewriter const*const pRewriter);
virtual void DelAllUndoObj();
virtual bool GetLastUndoInfo(OUString *const o_pStr,
- SwUndoId *const o_pId) const;
+ SwUndoId *const o_pId) const;
virtual SwUndoComments_t GetUndoComments() const;
-
- virtual bool GetFirstRedoInfo(OUString *const o_pStr) const;
+ virtual bool GetFirstRedoInfo(OUString *const o_pStr,
+ SwUndoId *const o_pId = 0) const;
virtual SwUndoComments_t GetRedoComments() const;
virtual bool Repeat(::sw::RepeatContext & rContext,
sal_uInt16 const nRepeatCnt);
diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx
index 1a2bb5c32228..e4318507167e 100644
--- a/sw/source/core/layout/trvlfrm.cxx
+++ b/sw/source/core/layout/trvlfrm.cxx
@@ -2097,8 +2097,7 @@ inline void Sub( SwRegionRects& rRegion, const SwRect& rRect )
void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
{
SwPosition *pStartPos = rCrsr.Start(),
- *pEndPos = rCrsr.GetPoint() == pStartPos ?
- rCrsr.GetMark() : rCrsr.GetPoint();
+ *pEndPos = rCrsr.GetPoint() == pStartPos ? rCrsr.GetMark() : rCrsr.GetPoint();
ViewShell *pSh = GetCurrShell();
@@ -2134,8 +2133,11 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
OSL_ENSURE( pObj, "No Start Object." );
if (pObj) aSortObjs.Insert( *(const_cast<SwAnchoredObject*>(pObj)) );
const SwAnchoredObject* pObj2 = pEndFrm->FindFlyFrm();
- OSL_ENSURE( pObj2, "No Start Object." );
- if (pObj2) aSortObjs.Insert( *(const_cast<SwAnchoredObject*>(pObj2)) );
+ OSL_ENSURE( pObj2, "SwRootFrm::CalcFrmRects(..) - FlyFrame missing - looks like an invalid selection" );
+ if ( pObj2 != NULL && pObj2 != pObj )
+ {
+ aSortObjs.Insert( *(const_cast<SwAnchoredObject*>(pObj2)) );
+ }
}
//Fall 4: Tabellenselection
@@ -2170,7 +2172,7 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
break;
OSL_ENSURE( pEndLFrm->GetType() == pSttLFrm->GetType(),
- "Selection ueber unterschiedliche Inhalte" );
+ "Selection ueber unterschiedliche Inhalte" );
switch( pSttLFrm->GetType() )
{
case FRM_HEADER:
@@ -2193,11 +2195,11 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
{
const SwTabFrm* pTabFrm = (SwTabFrm*)pSttLFrm;
if( ( pTabFrm->GetFollow() ||
- ((SwTabFrm*)pEndLFrm)->GetFollow() ) &&
+ ((SwTabFrm*)pEndLFrm)->GetFollow() ) &&
pTabFrm->GetTable()->GetRowsToRepeat() > 0 &&
pTabFrm->GetLower() != ((SwTabFrm*)pEndLFrm)->GetLower() &&
( lcl_IsInRepeatedHeadline( pStartFrm ) ||
- lcl_IsInRepeatedHeadline( pEndFrm ) ) )
+ lcl_IsInRepeatedHeadline( pEndFrm ) ) )
{
// End- auf den Start-CntntFrame setzen
if( pStartPos == rCrsr.GetPoint() )
@@ -2227,10 +2229,11 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
SwRect aStFrm ( pStartFrm->UnionFrm( sal_True ) );
aStFrm.Intersection( pStartFrm->PaintArea() );
- SwRect aEndFrm( pStartFrm == pEndFrm ? aStFrm :
- pEndFrm->UnionFrm( sal_True ) );
+ SwRect aEndFrm( pStartFrm == pEndFrm ? aStFrm : pEndFrm->UnionFrm( sal_True ) );
if( pStartFrm != pEndFrm )
+ {
aEndFrm.Intersection( pEndFrm->PaintArea() );
+ }
SWRECTFN( pStartFrm )
const sal_Bool bR2L = pStartFrm->IsRightToLeft();
const sal_Bool bEndR2L = pEndFrm->IsRightToLeft();
@@ -2251,8 +2254,8 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
// BiDi-Portions are swimming against the current.
const sal_Bool bPorR2L = ( MT_BIDI == pSt2Pos->nMultiType ) ?
- ! bR2L :
- bR2L;
+ ! bR2L :
+ bR2L;
if( MT_BIDI == pSt2Pos->nMultiType &&
(pSt2Pos->aPortion2.*fnRect->fnGetWidth)() )
@@ -2502,9 +2505,9 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
{
OutputDevice* pOut = pSh->GetOut();
long nCrsrWidth = pOut->GetSettings().GetStyleSettings().
- GetCursorSize();
+ GetCursorSize();
(aTmp.*fnRect->fnSetWidth)( pOut->PixelToLogic(
- Size( nCrsrWidth, 0 ) ).Width() );
+ Size( nCrsrWidth, 0 ) ).Width() );
}
aTmp.Intersection( aStFrm );
Sub( aRegion, aTmp );
@@ -2521,9 +2524,9 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
else
{
lLeft = (pStartFrm->Frm().*fnRect->fnGetLeft)() +
- (pStartFrm->Prt().*fnRect->fnGetLeft)();
+ (pStartFrm->Prt().*fnRect->fnGetLeft)();
lRight = (pStartFrm->Frm().*fnRect->fnGetLeft)() +
- (pStartFrm->Prt().*fnRect->fnGetRight)();
+ (pStartFrm->Prt().*fnRect->fnGetRight)();
}
if( lLeft < (aStFrm.*fnRect->fnGetLeft)() )
lLeft = (aStFrm.*fnRect->fnGetLeft)();
@@ -2579,15 +2582,12 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
//Now the frames between, if there are any
bool const bBody = pStartFrm->IsInDocBody();
const SwTableBox* pCellBox = pStartFrm->GetUpper()->IsCellFrm() ?
- ((SwCellFrm*)pStartFrm->GetUpper())->GetTabBox() : 0;
+ ((SwCellFrm*)pStartFrm->GetUpper())->GetTabBox() : 0;
const SwCntntFrm *pCntnt = pStartFrm->GetNextCntntFrm();
SwRect aPrvRect;
- // #123908# - introduce robust code
- // The stacktrace issue reveals that <pCntnt> could be NULL.
- // One root cause found by AMA - see #130650#
OSL_ENSURE( pCntnt,
- "<SwRootFrm::CalcFrmRects(..)> - no content frame. This is a serious defect -> please inform OD" );
+ "<SwRootFrm::CalcFrmRects(..)> - no content frame. This is a serious defect -> please inform OD" );
while ( pCntnt && pCntnt != pEndFrm )
{
if ( pCntnt->IsInFly() )
@@ -2600,7 +2600,7 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
// If pStartFrm is inside a SwCellFrm, consider only frames which are inside the
// same cell frame (or its follow cell)
const SwTableBox* pTmpCellBox = pCntnt->GetUpper()->IsCellFrm() ?
- ((SwCellFrm*)pCntnt->GetUpper())->GetTabBox() : 0;
+ ((SwCellFrm*)pCntnt->GetUpper())->GetTabBox() : 0;
if ( bBody == pCntnt->IsInDocBody() &&
( !pCellBox || pCellBox == pTmpCellBox ) )
{
@@ -2625,9 +2625,8 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
}
}
pCntnt = pCntnt->GetNextCntntFrm();
- // #123908#
OSL_ENSURE( pCntnt,
- "<SwRootFrm::CalcFrmRects(..)> - no content frame. This is a serious defect -> please inform OD" );
+ "<SwRootFrm::CalcFrmRects(..)> - no content frame. This is a serious defect -> please inform OD" );
}
if ( aPrvRect.HasArea() )
Sub( aRegion, aPrvRect );
@@ -2637,7 +2636,7 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
bRev = pEndFrm->IsReverse();
//Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
fnRect = bVert ? ( bRev ? fnRectVL2R : ( pEndFrm->IsVertLR() ? fnRectVertL2R : fnRectVert ) ) :
- ( bRev ? fnRectB2T : fnRectHori );
+ ( bRev ? fnRectB2T : fnRectHori );
nTmpTwips = (aEndRect.*fnRect->fnGetTop)();
if( (aEndFrm.*fnRect->fnGetTop)() != nTmpTwips )
{
@@ -2653,7 +2652,6 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
Sub( aRegion, aSubRect );
}
-// aRegion.Compress( sal_False );
aRegion.Invert();
delete pSt2Pos;
delete pEnd2Pos;
@@ -2681,8 +2679,8 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
const SwVirtFlyDrawObj* pObj = pFly->GetVirtDrawObj();
const SwFmtSurround &rSur = pFly->GetFmt()->GetSurround();
if ( !pFly->IsAnLower( pStartFrm ) &&
- (rSur.GetSurround() != SURROUND_THROUGHT &&
- !rSur.IsContour()) )
+ (rSur.GetSurround() != SURROUND_THROUGHT &&
+ !rSur.IsContour()) )
{
if ( aSortObjs.Contains( *pAnchoredObj ) )
continue;
@@ -2692,13 +2690,18 @@ void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode )
for ( sal_uInt16 k = 0; bSub && k < aSortObjs.Count(); ++k )
{
OSL_ENSURE( aSortObjs[k]->ISA(SwFlyFrm),
- "<SwRootFrm::CalcFrmRects(..)> - object in <aSortObjs> of unexcepted type" );
+ "<SwRootFrm::CalcFrmRects(..)> - object in <aSortObjs> of unexcepted type" );
const SwFlyFrm* pTmp = static_cast<SwFlyFrm*>(aSortObjs[k]);
do
- { if ( nPos < pTmp->GetVirtDrawObj()->GetOrdNumDirect() )
+ {
+ if ( nPos < pTmp->GetVirtDrawObj()->GetOrdNumDirect() )
+ {
bSub = sal_False;
+ }
else
+ {
pTmp = pTmp->GetAnchorFrm()->FindFlyFrm();
+ }
} while ( bSub && pTmp );
}
if ( bSub )
diff --git a/sw/source/core/undo/docundo.cxx b/sw/source/core/undo/docundo.cxx
index 79ad862c675f..fff78e4da186 100644
--- a/sw/source/core/undo/docundo.cxx
+++ b/sw/source/core/undo/docundo.cxx
@@ -332,16 +332,29 @@ SwUndoComments_t UndoManager::GetUndoComments() const
/**************** REDO ******************/
-bool UndoManager::GetFirstRedoInfo(OUString *const o_pStr) const
+
+bool UndoManager::GetFirstRedoInfo(OUString *const o_pStr,
+ SwUndoId *const o_pId) const
{
if (!SdrUndoManager::GetRedoActionCount(CurrentLevel))
{
return false;
}
+ SfxUndoAction *const pAction( SdrUndoManager::GetRedoAction(0, CurrentLevel) );
+ if ( pAction == NULL )
+ {
+ return false;
+ }
+
if (o_pStr)
{
- *o_pStr = SdrUndoManager::GetRedoActionComment(0, CurrentLevel);
+ *o_pStr = pAction->GetComment();
+ }
+ if (o_pId)
+ {
+ sal_uInt16 const nId(pAction->GetId());
+ *o_pId = static_cast<SwUndoId>(nId);
}
return true;
@@ -443,7 +456,7 @@ public:
{
if (m_bSaveCursor)
{
- m_rShell.Pop();
+ m_rShell.Pop( sal_False );
}
}
private:
@@ -468,7 +481,7 @@ bool UndoManager::impl_DoUndoRedo(UndoOrRedo_t const undoOrRedo)
// in case the model has controllers locked, the Undo should not
// change the view cursors!
bool const bSaveCursors(pEditShell->CursorsLocked());
- CursorGuard(*pEditShell, bSaveCursors);
+ CursorGuard aCursorGuard(*pEditShell, bSaveCursors);
if (!bSaveCursors)
{
// (in case Undo was called via API) clear the cursors:
diff --git a/sw/source/ui/shells/textsh1.cxx b/sw/source/ui/shells/textsh1.cxx
index 340e938ddac6..2ac65fd9f2a3 100644
--- a/sw/source/ui/shells/textsh1.cxx
+++ b/sw/source/ui/shells/textsh1.cxx
@@ -328,6 +328,7 @@ void SwTextShell::Execute(SfxRequest &rReq)
rWrtSh.StartAction();
// prevent view from jumping because of (temporary) selection changes
rWrtSh.LockView( sal_True );
+
// save selection for later restoration
rWrtSh.Push();
@@ -377,12 +378,16 @@ void SwTextShell::Execute(SfxRequest &rReq)
rWrtSh.SelAll();
rWrtSh.ExtendedSelectAll();
}
+
+ rWrtSh.StartUndo( ( !bForParagraph && !bForSelection ) ? UNDO_SETDEFTATTR : UNDO_EMPTY );
if (aNewLangTxt == aStrNone)
SwLangHelper::SetLanguage_None( rWrtSh, bForSelection, aCoreSet );
else if (aNewLangTxt == aStrResetLangs)
SwLangHelper::ResetLanguages( rWrtSh, bForSelection );
else
SwLangHelper::SetLanguage( rWrtSh, aNewLangTxt, bForSelection, aCoreSet );
+ rWrtSh.EndUndo();
+
}
// restore selection...