Author: orw Date: Wed Jun 26 12:15:55 2013 New Revision: 1496901 URL: http://svn.apache.org/r1496901 Log: 121751: - 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
Modified: openoffice/trunk/main/svl/inc/svl/undo.hxx openoffice/trunk/main/svl/source/undo/undo.cxx openoffice/trunk/main/sw/inc/IDocumentUndoRedo.hxx openoffice/trunk/main/sw/source/core/edit/edundo.cxx openoffice/trunk/main/sw/source/core/inc/UndoManager.hxx openoffice/trunk/main/sw/source/core/layout/trvlfrm.cxx openoffice/trunk/main/sw/source/core/undo/docundo.cxx openoffice/trunk/main/sw/source/ui/shells/textsh1.cxx Modified: openoffice/trunk/main/svl/inc/svl/undo.hxx URL: http://svn.apache.org/viewvc/openoffice/trunk/main/svl/inc/svl/undo.hxx?rev=1496901&r1=1496900&r2=1496901&view=diff ============================================================================== --- openoffice/trunk/main/svl/inc/svl/undo.hxx (original) +++ openoffice/trunk/main/svl/inc/svl/undo.hxx Wed Jun 26 12:15:55 2013 @@ -242,6 +242,7 @@ namespace svl virtual size_t GetRedoActionCount( bool const i_currentLevel = CurrentLevel ) const = 0; virtual UniString 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; @@ -360,6 +361,7 @@ public: virtual SfxUndoAction* GetUndoAction( size_t nNo=0 ) const; virtual size_t GetRedoActionCount( bool const i_currentLevel = CurrentLevel ) const; virtual UniString 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(); Modified: openoffice/trunk/main/svl/source/undo/undo.cxx URL: http://svn.apache.org/viewvc/openoffice/trunk/main/svl/source/undo/undo.cxx?rev=1496901&r1=1496900&r2=1496901&view=diff ============================================================================== --- openoffice/trunk/main/svl/source/undo/undo.cxx (original) +++ openoffice/trunk/main/svl/source/undo/undo.cxx Wed Jun 26 12:15:55 2013 @@ -831,11 +831,30 @@ size_t SfxUndoManager::ImplGetRedoAction //------------------------------------------------------------------------ +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; +} + +//------------------------------------------------------------------------ + XubString 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; } //------------------------------------------------------------------------ Modified: openoffice/trunk/main/sw/inc/IDocumentUndoRedo.hxx URL: http://svn.apache.org/viewvc/openoffice/trunk/main/sw/inc/IDocumentUndoRedo.hxx?rev=1496901&r1=1496900&r2=1496901&view=diff ============================================================================== --- openoffice/trunk/main/sw/inc/IDocumentUndoRedo.hxx (original) +++ openoffice/trunk/main/sw/inc/IDocumentUndoRedo.hxx Wed Jun 26 12:15:55 2013 @@ -160,11 +160,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(::rtl::OUString *const o_pStr) const = 0; + virtual bool GetFirstRedoInfo(::rtl::OUString *const o_pStr, + SwUndoId *const o_pId = 0) const = 0; /** Get comments of Redo actions. @return comments of all top-level Redo actions. Modified: openoffice/trunk/main/sw/source/core/edit/edundo.cxx URL: http://svn.apache.org/viewvc/openoffice/trunk/main/sw/source/core/edit/edundo.cxx?rev=1496901&r1=1496900&r2=1496901&view=diff ============================================================================== --- openoffice/trunk/main/sw/source/core/edit/edundo.cxx (original) +++ openoffice/trunk/main/sw/source/core/edit/edundo.cxx Wed Jun 26 12:15:55 2013 @@ -97,35 +97,35 @@ SwEditShell::HandleUndoRedoContext(::sw: bool SwEditShell::Undo(sal_uInt16 const nCount) { - SET_CURR_SHELL( this ); + SET_CURR_SHELL( this ); // #105332# current undo state was not saved ::sw::UndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo()); - sal_Bool bRet = sal_False; + sal_Bool bRet = sal_False; - StartAllAction(); - { - // eigentlich muesste ja nur der aktuelle Cursor berarbeitet - // werden, d.H. falls ein Ring besteht, diesen temporaer aufheben, - // damit nicht bei Einfuge-Operationen innerhalb von Undo - // an allen Bereichen eingefuegt wird. - KillPams(); - SetMark(); // Bound1 und Bound2 in den gleichen Node - ClearMark(); + StartAllAction(); + { + // eigentlich muesste ja nur der aktuelle Cursor berarbeitet + // werden, d.H. falls ein Ring besteht, diesen temporaer aufheben, + // damit nicht bei Einfuge-Operationen innerhalb von Undo + // an allen Bereichen eingefuegt wird. + KillPams(); + SetMark(); // Bound1 und Bound2 in den gleichen Node + ClearMark(); - // JP 02.04.98: Cursor merken - beim Auto-Format/-Korrektur - // soll dieser wieder an die Position SwUndoId nLastUndoId(UNDO_EMPTY); - GetDoc()->GetIDocumentUndoRedo().GetLastUndoInfo(0, & nLastUndoId); - bool bRestoreCrsr = 1 == nCount && (UNDO_AUTOFORMAT == nLastUndoId || - UNDO_AUTOCORRECT == nLastUndoId ); - Push(); - - //JP 18.09.97: gesicherten TabellenBoxPtr zerstoeren, eine autom. - // Erkennung darf nur noch fuer die neue "Box" erfolgen! - ClearTblBoxCntnt(); + GetLastUndoInfo(0, & nLastUndoId); + const bool bRestoreCrsr = nCount == 1 + && ( UNDO_AUTOFORMAT == nLastUndoId + || UNDO_AUTOCORRECT == nLastUndoId + || UNDO_SETDEFTATTR == nLastUndoId ); + Push(); + + //JP 18.09.97: gesicherten TabellenBoxPtr zerstoeren, eine autom. + // Erkennung darf nur noch fuer die neue "Box" erfolgen! + ClearTblBoxCntnt(); - RedlineMode_t eOld = GetDoc()->GetRedlineMode(); + RedlineMode_t eOld = GetDoc()->GetRedlineMode(); try { for (sal_uInt16 i = 0; i < nCount; ++i) @@ -139,44 +139,49 @@ bool SwEditShell::Undo(sal_uInt16 const .getStr()); } - Pop( !bRestoreCrsr ); + Pop( !bRestoreCrsr ); - GetDoc()->SetRedlineMode( eOld ); - GetDoc()->CompressRedlines(); + GetDoc()->SetRedlineMode( eOld ); + GetDoc()->CompressRedlines(); - //JP 18.09.97: autom. Erkennung fuer die neue "Box" - SaveTblBoxCntnt(); - } - EndAllAction(); + //JP 18.09.97: autom. Erkennung fuer die neue "Box" + SaveTblBoxCntnt(); + } + EndAllAction(); - return bRet; + return bRet; } bool SwEditShell::Redo(sal_uInt16 const nCount) { - SET_CURR_SHELL( this ); + SET_CURR_SHELL( this ); - sal_Bool bRet = sal_False; + sal_Bool bRet = sal_False; // #105332# undo state was not saved ::sw::UndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo()); - StartAllAction(); + StartAllAction(); - { - // eigentlich muesste ja nur der aktuelle Cursor berarbeitet - // werden, d.H. falls ein Ring besteht, diesen temporaer aufheben, - // damit nicht bei Einfuge-Operationen innerhalb von Undo - // an allen Bereichen eingefuegt wird. - KillPams(); - SetMark(); // Bound1 und Bound2 in den gleichen Node - ClearMark(); - - //JP 18.09.97: gesicherten TabellenBoxPtr zerstoeren, eine autom. - // Erkennung darf nur noch fuer die neue "Box" erfolgen! - ClearTblBoxCntnt(); + { + // eigentlich muesste ja nur der aktuelle Cursor berarbeitet + // werden, d.H. falls ein Ring besteht, diesen temporaer aufheben, + // damit nicht bei Einfuge-Operationen innerhalb von Undo + // an allen Bereichen eingefuegt wird. + KillPams(); + SetMark(); // Bound1 und Bound2 in den gleichen Node + ClearMark(); + + SwUndoId nFirstRedoId(UNDO_EMPTY); + GetDoc()->GetIDocumentUndoRedo().GetFirstRedoInfo(0, & nFirstRedoId); + const bool bRestoreCrsr = nCount == 1 && UNDO_SETDEFTATTR == nFirstRedoId; + Push(); + + //JP 18.09.97: gesicherten TabellenBoxPtr zerstoeren, eine autom. + // Erkennung darf nur noch fuer die neue "Box" erfolgen! + ClearTblBoxCntnt(); - RedlineMode_t eOld = GetDoc()->GetRedlineMode(); + RedlineMode_t eOld = GetDoc()->GetRedlineMode(); try { for (sal_uInt16 i = 0; i < nCount; ++i) @@ -190,16 +195,18 @@ bool SwEditShell::Redo(sal_uInt16 const .getStr()); } - GetDoc()->SetRedlineMode( eOld ); - GetDoc()->CompressRedlines(); + Pop( !bRestoreCrsr ); - //JP 18.09.97: autom. Erkennung fuer die neue "Box" - SaveTblBoxCntnt(); - } + GetDoc()->SetRedlineMode( eOld ); + GetDoc()->CompressRedlines(); - EndAllAction(); + //JP 18.09.97: autom. Erkennung fuer die neue "Box" + SaveTblBoxCntnt(); + } - return bRet; + EndAllAction(); + + return bRet; } Modified: openoffice/trunk/main/sw/source/core/inc/UndoManager.hxx URL: http://svn.apache.org/viewvc/openoffice/trunk/main/sw/source/core/inc/UndoManager.hxx?rev=1496901&r1=1496900&r2=1496901&view=diff ============================================================================== --- openoffice/trunk/main/sw/source/core/inc/UndoManager.hxx (original) +++ openoffice/trunk/main/sw/source/core/inc/UndoManager.hxx Wed Jun 26 12:15:55 2013 @@ -57,17 +57,16 @@ public: virtual void UnLockUndoNoModifiedPosition(); virtual void SetUndoNoResetModified(); virtual bool IsUndoNoResetModified() const; -// virtual bool Undo(); virtual SwUndoId StartUndo(SwUndoId const eUndoId, SwRewriter const*const pRewriter); virtual SwUndoId EndUndo(SwUndoId const eUndoId, SwRewriter const*const pRewriter); virtual void DelAllUndoObj(); virtual bool GetLastUndoInfo(::rtl::OUString *const o_pStr, - SwUndoId *const o_pId) const; + SwUndoId *const o_pId) const; virtual SwUndoComments_t GetUndoComments() const; -// virtual bool Redo(); - virtual bool GetFirstRedoInfo(::rtl::OUString *const o_pStr) const; + virtual bool GetFirstRedoInfo(::rtl::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); Modified: openoffice/trunk/main/sw/source/core/layout/trvlfrm.cxx URL: http://svn.apache.org/viewvc/openoffice/trunk/main/sw/source/core/layout/trvlfrm.cxx?rev=1496901&r1=1496900&r2=1496901&view=diff ============================================================================== --- openoffice/trunk/main/sw/source/core/layout/trvlfrm.cxx (original) +++ openoffice/trunk/main/sw/source/core/layout/trvlfrm.cxx Wed Jun 26 12:15:55 2013 @@ -2007,175 +2007,164 @@ inline void Sub( SwRegionRects& rRegion, void SwRootFrm::CalcFrmRects( SwShellCrsr &rCrsr, sal_Bool bIsTblMode ) { - SwPosition *pStartPos = rCrsr.Start(), - *pEndPos = rCrsr.GetPoint() == pStartPos ? - rCrsr.GetMark() : rCrsr.GetPoint(); + SwPosition *pStartPos = rCrsr.Start(), + *pEndPos = rCrsr.GetPoint() == pStartPos ? rCrsr.GetMark() : rCrsr.GetPoint(); - ViewShell *pSh = GetCurrShell(); + ViewShell *pSh = GetCurrShell(); -// --> FME 2004-06-08 #i12836# enhanced pdf - SwRegionRects aRegion( pSh && !pSh->GetViewOptions()->IsPDFExport() ? + SwRegionRects aRegion( pSh && !pSh->GetViewOptions()->IsPDFExport() ? pSh->VisArea() : Frm() ); -// <-- if( !pStartPos->nNode.GetNode().IsCntntNode() || !pStartPos->nNode.GetNode().GetCntntNode()->getLayoutFrm(this) || ( pStartPos->nNode != pEndPos->nNode && ( !pEndPos->nNode.GetNode().IsCntntNode() || !pEndPos->nNode.GetNode().GetCntntNode()->getLayoutFrm(this) ) ) ) { - /* For SelectAll we will need something like this later on... - const SwFrm* pPageFrm = GetLower(); - while( pPageFrm ) - { - SwRect aTmp( pPageFrm->Prt() ); - aTmp.Pos() += pPageFrm->Frm().Pos(); - Sub( aRegion, aTmp ); - pPageFrm = pPageFrm->GetNext(); - } - aRegion.Invert(); - rCrsr.Remove( 0, rCrsr.Count() ); - rCrsr.Insert( &aRegion, 0 ); - */ return; } - //Erstmal die CntntFrms zum Start und End besorgen, die brauch ich auf - //jedenfall. + //Erstmal die CntntFrms zum Start und End besorgen, die brauch ich auf + //jedenfall. SwCntntFrm const* pStartFrm = pStartPos->nNode.GetNode(). - GetCntntNode()->getLayoutFrm( this, &rCrsr.GetSttPos(), pStartPos ); + GetCntntNode()->getLayoutFrm( this, &rCrsr.GetSttPos(), pStartPos ); SwCntntFrm const* pEndFrm = pEndPos->nNode.GetNode(). - GetCntntNode()->getLayoutFrm( this, &rCrsr.GetEndPos(), pEndPos ); + GetCntntNode()->getLayoutFrm( this, &rCrsr.GetEndPos(), pEndPos ); - ASSERT( (pStartFrm && pEndFrm), "Keine CntntFrms gefunden." ); + ASSERT( (pStartFrm && pEndFrm), "Keine CntntFrms gefunden." ); - //Damit die FlyFrms, in denen selektierte Frames stecken, nicht - //abgezogen werden + //Damit die FlyFrms, in denen selektierte Frames stecken, nicht + //abgezogen werden SwSortedObjs aSortObjs; - if ( pStartFrm->IsInFly() ) - { + if ( pStartFrm->IsInFly() ) + { const SwAnchoredObject* pObj = pStartFrm->FindFlyFrm(); aSortObjs.Insert( *(const_cast<SwAnchoredObject*>(pObj)) ); const SwAnchoredObject* pObj2 = pEndFrm->FindFlyFrm(); - aSortObjs.Insert( *(const_cast<SwAnchoredObject*>(pObj2)) ); - } + ASSERT( pObj2 != NULL, "SwRootFrm::CalcFrmRects(..) - FlyFrame missing - looks like an invalid selection" ); + if ( pObj2 != NULL && pObj2 != pObj ) + { + aSortObjs.Insert( *(const_cast<SwAnchoredObject*>(pObj2)) ); + } + } - //Fall 4: Tabellenselection - if( bIsTblMode ) - { - const SwFrm *pCell = pStartFrm->GetUpper(); - while ( !pCell->IsCellFrm() ) - pCell = pCell->GetUpper(); - SwRect aTmp( pCell->Prt() ); - aTmp.Pos() += pCell->Frm().Pos(); - aRegion.ChangeOrigin( aTmp ); - aRegion.Remove( 0, aRegion.Count() ); - aRegion.Insert( aTmp, 0 ); - } - else - { - // falls eine nicht erlaubte Selection besteht, dann korrigiere das - // nicht erlaubt ist Header/Footer/TableHeadline ueber 2 Seiten - do { // middle check loop - const SwLayoutFrm* pSttLFrm = pStartFrm->GetUpper(); - const sal_uInt16 cHdFtTblHd = FRM_HEADER | FRM_FOOTER | FRM_TAB; - while( pSttLFrm && - ! (cHdFtTblHd & pSttLFrm->GetType() )) - pSttLFrm = pSttLFrm->GetUpper(); - if( !pSttLFrm ) - break; - const SwLayoutFrm* pEndLFrm = pEndFrm->GetUpper(); - while( pEndLFrm && - ! (cHdFtTblHd & pEndLFrm->GetType() )) - pEndLFrm = pEndLFrm->GetUpper(); - if( !pEndLFrm ) - break; - - ASSERT( pEndLFrm->GetType() == pSttLFrm->GetType(), - "Selection ueber unterschiedliche Inhalte" ); - switch( pSttLFrm->GetType() ) - { - case FRM_HEADER: - case FRM_FOOTER: - // auf unterschiedlichen Seiten ?? - // dann immer auf die Start-Seite - if( pEndLFrm->FindPageFrm() != pSttLFrm->FindPageFrm() ) - { - // End- auf den Start-CntntFrame setzen - if( pStartPos == rCrsr.GetPoint() ) - pEndFrm = pStartFrm; - else - pStartFrm = pEndFrm; - } - break; - case FRM_TAB: - // auf unterschiedlichen Seiten ?? - // existiert - // dann teste auf Tabelle-Headline - { - const SwTabFrm* pTabFrm = (SwTabFrm*)pSttLFrm; - if( ( pTabFrm->GetFollow() || - ((SwTabFrm*)pEndLFrm)->GetFollow() ) && + //Fall 4: Tabellenselection + if( bIsTblMode ) + { + const SwFrm *pCell = pStartFrm->GetUpper(); + while ( !pCell->IsCellFrm() ) + pCell = pCell->GetUpper(); + SwRect aTmp( pCell->Prt() ); + aTmp.Pos() += pCell->Frm().Pos(); + aRegion.ChangeOrigin( aTmp ); + aRegion.Remove( 0, aRegion.Count() ); + aRegion.Insert( aTmp, 0 ); + } + else + { + // falls eine nicht erlaubte Selection besteht, dann korrigiere das + // nicht erlaubt ist Header/Footer/TableHeadline ueber 2 Seiten + do { // middle check loop + const SwLayoutFrm* pSttLFrm = pStartFrm->GetUpper(); + const sal_uInt16 cHdFtTblHd = FRM_HEADER | FRM_FOOTER | FRM_TAB; + while( pSttLFrm && + ! (cHdFtTblHd & pSttLFrm->GetType() )) + pSttLFrm = pSttLFrm->GetUpper(); + if( !pSttLFrm ) + break; + const SwLayoutFrm* pEndLFrm = pEndFrm->GetUpper(); + while( pEndLFrm && + ! (cHdFtTblHd & pEndLFrm->GetType() )) + pEndLFrm = pEndLFrm->GetUpper(); + if( !pEndLFrm ) + break; + + ASSERT( pEndLFrm->GetType() == pSttLFrm->GetType(), + "Selection ueber unterschiedliche Inhalte" ); + switch( pSttLFrm->GetType() ) + { + case FRM_HEADER: + case FRM_FOOTER: + // auf unterschiedlichen Seiten ?? + // dann immer auf die Start-Seite + if( pEndLFrm->FindPageFrm() != pSttLFrm->FindPageFrm() ) + { + // End- auf den Start-CntntFrame setzen + if( pStartPos == rCrsr.GetPoint() ) + pEndFrm = pStartFrm; + else + pStartFrm = pEndFrm; + } + break; + case FRM_TAB: + // auf unterschiedlichen Seiten ?? + // existiert + // dann teste auf Tabelle-Headline + { + const SwTabFrm* pTabFrm = (SwTabFrm*)pSttLFrm; + if( ( pTabFrm->GetFollow() || + ((SwTabFrm*)pEndLFrm)->GetFollow() ) && pTabFrm->GetTable()->GetRowsToRepeat() > 0 && - pTabFrm->GetLower() != ((SwTabFrm*)pEndLFrm)->GetLower() && + pTabFrm->GetLower() != ((SwTabFrm*)pEndLFrm)->GetLower() && ( lcl_IsInRepeatedHeadline( pStartFrm ) || - lcl_IsInRepeatedHeadline( pEndFrm ) ) ) - { - // End- auf den Start-CntntFrame setzen - if( pStartPos == rCrsr.GetPoint() ) - pEndFrm = pStartFrm; - else - pStartFrm = pEndFrm; - } - } - break; - } - } while( sal_False ); + lcl_IsInRepeatedHeadline( pEndFrm ) ) ) + { + // End- auf den Start-CntntFrame setzen + if( pStartPos == rCrsr.GetPoint() ) + pEndFrm = pStartFrm; + else + pStartFrm = pEndFrm; + } + } + break; + } + } while( sal_False ); - SwCrsrMoveState aTmpState( MV_NONE ); - aTmpState.b2Lines = sal_True; + SwCrsrMoveState aTmpState( MV_NONE ); + aTmpState.b2Lines = sal_True; aTmpState.bNoScroll = sal_True; aTmpState.nCursorBidiLevel = pStartFrm->IsRightToLeft() ? 1 : 0; //CntntRects zu Start- und EndFrms. - SwRect aStRect, aEndRect; - pStartFrm->GetCharRect( aStRect, *pStartPos, &aTmpState ); - Sw2LinesPos *pSt2Pos = aTmpState.p2Lines; - aTmpState.p2Lines = NULL; + SwRect aStRect, aEndRect; + pStartFrm->GetCharRect( aStRect, *pStartPos, &aTmpState ); + Sw2LinesPos *pSt2Pos = aTmpState.p2Lines; + aTmpState.p2Lines = NULL; aTmpState.nCursorBidiLevel = pEndFrm->IsRightToLeft() ? 1 : 0; pEndFrm->GetCharRect ( aEndRect, *pEndPos, &aTmpState ); - Sw2LinesPos *pEnd2Pos = aTmpState.p2Lines; + Sw2LinesPos *pEnd2Pos = aTmpState.p2Lines; - SwRect aStFrm ( pStartFrm->UnionFrm( sal_True ) ); - aStFrm.Intersection( pStartFrm->PaintArea() ); - SwRect aEndFrm( pStartFrm == pEndFrm ? aStFrm : - pEndFrm->UnionFrm( sal_True ) ); - if( pStartFrm != pEndFrm ) - aEndFrm.Intersection( pEndFrm->PaintArea() ); + SwRect aStFrm ( pStartFrm->UnionFrm( sal_True ) ); + aStFrm.Intersection( pStartFrm->PaintArea() ); + 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(); // If there's no doubleline portion involved or start and end are both - // in the same doubleline portion, all works fine, but otherwise - // we need the following... - if( pSt2Pos != pEnd2Pos && ( !pSt2Pos || !pEnd2Pos || + // in the same doubleline portion, all works fine, but otherwise + // we need the following... + if( pSt2Pos != pEnd2Pos && ( !pSt2Pos || !pEnd2Pos || pSt2Pos->aPortion != pEnd2Pos->aPortion ) ) - { - // If we have a start(end) position inside a doubleline portion - // the surrounded part of the doubleline portion is subtracted - // from the region and the aStRect(aEndRect) is set to the - // end(start) of the doubleline portion. + { + // If we have a start(end) position inside a doubleline portion + // the surrounded part of the doubleline portion is subtracted + // from the region and the aStRect(aEndRect) is set to the + // end(start) of the doubleline portion. if( pSt2Pos ) - { + { SwRect aTmp( aStRect ); // 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)() ) @@ -2214,7 +2203,7 @@ void SwRootFrm::CalcFrmRects( SwShellCrs } aTmp.Intersection( aStFrm ); - Sub( aRegion, aTmp ); + Sub( aRegion, aTmp ); SwTwips nTmp = (pSt2Pos->aLine.*fnRect->fnGetBottom)(); if( MT_ROT_90 != pSt2Pos->nMultiType && @@ -2241,10 +2230,10 @@ void SwRootFrm::CalcFrmRects( SwShellCrs (pSt2Pos->aPortion.*fnRect->fnGetLeft)() : (pSt2Pos->aPortion.*fnRect->fnGetRight)() ); (aStRect.*fnRect->fnSetWidth)( 1 ); - } + } if( pEnd2Pos ) - { + { SWRECTFNX( pEndFrm ) SwRect aTmp( aEndRect ); @@ -2290,7 +2279,7 @@ void SwRootFrm::CalcFrmRects( SwShellCrs } aTmp.Intersection( aEndFrm ); - Sub( aRegion, aTmp ); + Sub( aRegion, aTmp ); // The next statement means neither ruby nor rotate(90): if( !( MT_RUBY & pEnd2Pos->nMultiType ) ) @@ -2321,8 +2310,8 @@ void SwRootFrm::CalcFrmRects( SwShellCrs (pEnd2Pos->aPortion.*fnRectX->fnGetRight)() : (pEnd2Pos->aPortion.*fnRectX->fnGetLeft)() ); (aEndRect.*fnRectX->fnSetWidth)( 1 ); - } - } + } + } else if( pSt2Pos && pEnd2Pos && MT_BIDI == pSt2Pos->nMultiType && MT_BIDI == pEnd2Pos->nMultiType && @@ -2367,38 +2356,38 @@ void SwRootFrm::CalcFrmRects( SwShellCrs } } - // The charrect may be outside the paintarea (for cursortravelling) - // but the selection has to be restricted to the paintarea - if( aStRect.Left() < aStFrm.Left() ) - aStRect.Left( aStFrm.Left() ); - else if( aStRect.Left() > aStFrm.Right() ) - aStRect.Left( aStFrm.Right() ); - SwTwips nTmp = aStRect.Right(); - if( nTmp < aStFrm.Left() ) - aStRect.Right( aStFrm.Left() ); - else if( nTmp > aStFrm.Right() ) - aStRect.Right( aStFrm.Right() ); - if( aEndRect.Left() < aEndFrm.Left() ) - aEndRect.Left( aEndFrm.Left() ); - else if( aEndRect.Left() > aEndFrm.Right() ) - aEndRect.Left( aEndFrm.Right() ); - nTmp = aEndRect.Right(); - if( nTmp < aEndFrm.Left() ) - aEndRect.Right( aEndFrm.Left() ); - else if( nTmp > aEndFrm.Right() ) - aEndRect.Right( aEndFrm.Right() ); + // The charrect may be outside the paintarea (for cursortravelling) + // but the selection has to be restricted to the paintarea + if( aStRect.Left() < aStFrm.Left() ) + aStRect.Left( aStFrm.Left() ); + else if( aStRect.Left() > aStFrm.Right() ) + aStRect.Left( aStFrm.Right() ); + SwTwips nTmp = aStRect.Right(); + if( nTmp < aStFrm.Left() ) + aStRect.Right( aStFrm.Left() ); + else if( nTmp > aStFrm.Right() ) + aStRect.Right( aStFrm.Right() ); + if( aEndRect.Left() < aEndFrm.Left() ) + aEndRect.Left( aEndFrm.Left() ); + else if( aEndRect.Left() > aEndFrm.Right() ) + aEndRect.Left( aEndFrm.Right() ); + nTmp = aEndRect.Right(); + if( nTmp < aEndFrm.Left() ) + aEndRect.Right( aEndFrm.Left() ); + else if( nTmp > aEndFrm.Right() ) + aEndRect.Right( aEndFrm.Right() ); - if( pStartFrm == pEndFrm ) - { + if( pStartFrm == pEndFrm ) + { sal_Bool bSameRotatedOrBidi = pSt2Pos && pEnd2Pos && ( MT_BIDI & pSt2Pos->nMultiType ) && pSt2Pos->aPortion == pEnd2Pos->aPortion; //case 1: (Same frame and same row) if( bSameRotatedOrBidi || (aStRect.*fnRect->fnGetTop)() == (aEndRect.*fnRect->fnGetTop)() ) - { - Point aTmpSt( aStRect.Pos() ); - Point aTmpEnd( aEndRect.Right(), aEndRect.Bottom() ); + { + Point aTmpSt( aStRect.Pos() ); + Point aTmpEnd( aEndRect.Right(), aEndRect.Bottom() ); if( bSameRotatedOrBidi || bR2L ) { if( aTmpSt.Y() > aTmpEnd.Y() ) @@ -2415,39 +2404,39 @@ void SwRootFrm::CalcFrmRects( SwShellCrs } } - SwRect aTmp = SwRect( aTmpSt, aTmpEnd ); - // Bug 34888: falls Inhalt selektiert ist, der keinen Platz - // einnimmt (z.B. PostIts,RefMarks, TOXMarks), - // dann mindestens die Breite des Crsr setzen. + SwRect aTmp = SwRect( aTmpSt, aTmpEnd ); + // Bug 34888: falls Inhalt selektiert ist, der keinen Platz + // einnimmt (z.B. PostIts,RefMarks, TOXMarks), + // dann mindestens die Breite des Crsr setzen. if( 1 == (aTmp.*fnRect->fnGetWidth)() && pStartPos->nContent.GetIndex() != pEndPos->nContent.GetIndex() ) - { - OutputDevice* pOut = pSh->GetOut(); - long nCrsrWidth = pOut->GetSettings().GetStyleSettings(). - GetCursorSize(); + { + OutputDevice* pOut = pSh->GetOut(); + long nCrsrWidth = pOut->GetSettings().GetStyleSettings(). + GetCursorSize(); (aTmp.*fnRect->fnSetWidth)( pOut->PixelToLogic( - Size( nCrsrWidth, 0 ) ).Width() ); - } - aTmp.Intersection( aStFrm ); - Sub( aRegion, aTmp ); - } + Size( nCrsrWidth, 0 ) ).Width() ); + } + aTmp.Intersection( aStFrm ); + Sub( aRegion, aTmp ); + } //case 2: (Same frame, but not the same line) - else - { - SwTwips lLeft, lRight; - if( pSt2Pos && pEnd2Pos && pSt2Pos->aPortion == pEnd2Pos->aPortion ) - { + else + { + SwTwips lLeft, lRight; + if( pSt2Pos && pEnd2Pos && pSt2Pos->aPortion == pEnd2Pos->aPortion ) + { lLeft = (pSt2Pos->aPortion.*fnRect->fnGetLeft)(); lRight = (pSt2Pos->aPortion.*fnRect->fnGetRight)(); - } - else - { + } + 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)(); if( lRight > (aStFrm.*fnRect->fnGetRight)() ) @@ -2479,11 +2468,11 @@ void SwRootFrm::CalcFrmRects( SwShellCrs else (aSubRect.*fnRect->fnSetLeft)( lLeft ); Sub( aRegion, aSubRect ); - } - } + } + } //case 3: (Different frames, maybe with ohther frames between - else - { + else + { //The startframe first... SwRect aSubRect( aStRect ); if( bR2L ) @@ -2500,69 +2489,63 @@ void SwRootFrm::CalcFrmRects( SwShellCrs } //Now the frames between, if there are any - sal_Bool bBody = pStartFrm->IsInDocBody(); + sal_Bool 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; + SwRect aPrvRect; - // --> OD 2006-01-24 #123908# - introduce robust code: - // The stacktrace issue reveals that <pCntnt> could be NULL. - // One root cause found by AMA - see #130650# ASSERT( 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() ) - { + if ( pCntnt->IsInFly() ) + { const SwAnchoredObject* pObj = pCntnt->FindFlyFrm(); aSortObjs.Insert( *(const_cast<SwAnchoredObject*>(pObj)) ); - } + } - // Consider only frames which have the same IsInDocBody value like pStartFrm + // Consider only frames which have the same IsInDocBody value like pStartFrm // 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 ) ) { - SwRect aCRect( pCntnt->UnionFrm( sal_True ) ); - aCRect.Intersection( pCntnt->PaintArea() ); - if( aCRect.IsOver( aRegion.GetOrigin() )) - { - SwRect aTmp( aPrvRect ); - aTmp.Union( aCRect ); - if ( (aPrvRect.Height() * aPrvRect.Width() + - aCRect.Height() * aCRect.Width()) == - (aTmp.Height() * aTmp.Width()) ) - { - aPrvRect.Union( aCRect ); - } - else - { - if ( aPrvRect.HasArea() ) - Sub( aRegion, aPrvRect ); - aPrvRect = aCRect; - } - } - } - pCntnt = pCntnt->GetNextCntntFrm(); - // --> OD 2006-01-24 #123908# + SwRect aCRect( pCntnt->UnionFrm( sal_True ) ); + aCRect.Intersection( pCntnt->PaintArea() ); + if( aCRect.IsOver( aRegion.GetOrigin() )) + { + SwRect aTmp( aPrvRect ); + aTmp.Union( aCRect ); + if ( (aPrvRect.Height() * aPrvRect.Width() + + aCRect.Height() * aCRect.Width()) == + (aTmp.Height() * aTmp.Width()) ) + { + aPrvRect.Union( aCRect ); + } + else + { + if ( aPrvRect.HasArea() ) + Sub( aRegion, aPrvRect ); + aPrvRect = aCRect; + } + } + } + pCntnt = pCntnt->GetNextCntntFrm(); ASSERT( pCntnt, - "<SwRootFrm::CalcFrmRects(..)> - no content frame. This is a serious defect -> please inform OD" ); - // <-- - } - if ( aPrvRect.HasArea() ) - Sub( aRegion, aPrvRect ); + "<SwRootFrm::CalcFrmRects(..)> - no content frame. This is a serious defect -> please inform OD" ); + } + if ( aPrvRect.HasArea() ) + Sub( aRegion, aPrvRect ); //At least the endframe... bVert = pEndFrm->IsVertical(); 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 ) { @@ -2576,82 +2559,86 @@ void SwRootFrm::CalcFrmRects( SwShellCrs else (aSubRect.*fnRect->fnSetLeft)( (aEndFrm.*fnRect->fnGetLeft)() ); Sub( aRegion, aSubRect ); - } + } -// aRegion.Compress( sal_False ); - aRegion.Invert(); - delete pSt2Pos; - delete pEnd2Pos; - } - - //Flys mit Durchlauf ausstanzen. Nicht ausgestanzt werden Flys: - //- die Lower des StartFrm/EndFrm sind (FlyInCnt und alle Flys die wiederum - // darin sitzen) - //- in der Z-Order ueber denjenigen Flys stehen in denen sich der StartFrm - // befindet. - const SwPageFrm *pPage = pStartFrm->FindPageFrm(); - const SwPageFrm *pEndPage = pEndFrm->FindPageFrm(); + aRegion.Invert(); + delete pSt2Pos; + delete pEnd2Pos; + } + + //Flys mit Durchlauf ausstanzen. Nicht ausgestanzt werden Flys: + //- die Lower des StartFrm/EndFrm sind (FlyInCnt und alle Flys die wiederum + // darin sitzen) + //- in der Z-Order ueber denjenigen Flys stehen in denen sich der StartFrm + // befindet. + const SwPageFrm *pPage = pStartFrm->FindPageFrm(); + const SwPageFrm *pEndPage = pEndFrm->FindPageFrm(); while ( pPage ) - { - if ( pPage->GetSortedObjs() ) - { + { + if ( pPage->GetSortedObjs() ) + { const SwSortedObjs &rObjs = *pPage->GetSortedObjs(); - for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i ) - { + for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i ) + { SwAnchoredObject* pAnchoredObj = rObjs[i]; if ( !pAnchoredObj->ISA(SwFlyFrm) ) - continue; + continue; const SwFlyFrm* pFly = static_cast<const SwFlyFrm*>(pAnchoredObj); const SwVirtFlyDrawObj* pObj = pFly->GetVirtDrawObj(); - const SwFmtSurround &rSur = pFly->GetFmt()->GetSurround(); - if ( !pFly->IsAnLower( pStartFrm ) && - (rSur.GetSurround() != SURROUND_THROUGHT && - !rSur.IsContour()) ) - { + const SwFmtSurround &rSur = pFly->GetFmt()->GetSurround(); + if ( !pFly->IsAnLower( pStartFrm ) && + (rSur.GetSurround() != SURROUND_THROUGHT && + !rSur.IsContour()) ) + { if ( aSortObjs.Contains( *pAnchoredObj ) ) - continue; + continue; - sal_Bool bSub = sal_True; - const sal_uInt32 nPos = pObj->GetOrdNum(); - for ( sal_uInt16 k = 0; bSub && k < aSortObjs.Count(); ++k ) - { + sal_Bool bSub = sal_True; + const sal_uInt32 nPos = pObj->GetOrdNum(); + for ( sal_uInt16 k = 0; bSub && k < aSortObjs.Count(); ++k ) + { ASSERT( 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() ) - bSub = sal_False; - else + do + { + if ( nPos < pTmp->GetVirtDrawObj()->GetOrdNumDirect() ) + { + bSub = sal_False; + } + else + { pTmp = pTmp->GetAnchorFrm()->FindFlyFrm(); - } while ( bSub && pTmp ); - } - if ( bSub ) - Sub( aRegion, pFly->Frm() ); - } - } - } - if ( pPage == pEndPage ) - break; - else - pPage = (SwPageFrm*)pPage->GetNext(); - } - - //Weil's besser aussieht noch die DropCaps ausschliessen. - SwRect aDropRect; - if ( pStartFrm->IsTxtFrm() ) - { - if ( ((SwTxtFrm*)pStartFrm)->GetDropRect( aDropRect ) ) - Sub( aRegion, aDropRect ); - } - if ( pEndFrm != pStartFrm && pEndFrm->IsTxtFrm() ) - { - if ( ((SwTxtFrm*)pEndFrm)->GetDropRect( aDropRect ) ) - Sub( aRegion, aDropRect ); - } + } + } while ( bSub && pTmp ); + } + if ( bSub ) + Sub( aRegion, pFly->Frm() ); + } + } + } + if ( pPage == pEndPage ) + break; + else + pPage = (SwPageFrm*)pPage->GetNext(); + } + + //Weil's besser aussieht noch die DropCaps ausschliessen. + SwRect aDropRect; + if ( pStartFrm->IsTxtFrm() ) + { + if ( ((SwTxtFrm*)pStartFrm)->GetDropRect( aDropRect ) ) + Sub( aRegion, aDropRect ); + } + if ( pEndFrm != pStartFrm && pEndFrm->IsTxtFrm() ) + { + if ( ((SwTxtFrm*)pEndFrm)->GetDropRect( aDropRect ) ) + Sub( aRegion, aDropRect ); + } - rCrsr.Remove( 0, rCrsr.Count() ); - rCrsr.Insert( &aRegion, 0 ); + rCrsr.Remove( 0, rCrsr.Count() ); + rCrsr.Insert( &aRegion, 0 ); } Modified: openoffice/trunk/main/sw/source/core/undo/docundo.cxx URL: http://svn.apache.org/viewvc/openoffice/trunk/main/sw/source/core/undo/docundo.cxx?rev=1496901&r1=1496900&r2=1496901&view=diff ============================================================================== --- openoffice/trunk/main/sw/source/core/undo/docundo.cxx (original) +++ openoffice/trunk/main/sw/source/core/undo/docundo.cxx Wed Jun 26 12:15:55 2013 @@ -341,16 +341,28 @@ SwUndoComments_t UndoManager::GetUndoCom /**************** REDO ******************/ -bool UndoManager::GetFirstRedoInfo(::rtl::OUString *const o_pStr) const +bool UndoManager::GetFirstRedoInfo(::rtl::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; @@ -452,7 +464,7 @@ public: { if (m_bSaveCursor) { - m_rShell.Pop(); + m_rShell.Pop( sal_False ); } } private: @@ -477,7 +489,7 @@ bool UndoManager::impl_DoUndoRedo(UndoOr // 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: Modified: openoffice/trunk/main/sw/source/ui/shells/textsh1.cxx URL: http://svn.apache.org/viewvc/openoffice/trunk/main/sw/source/ui/shells/textsh1.cxx?rev=1496901&r1=1496900&r2=1496901&view=diff ============================================================================== --- openoffice/trunk/main/sw/source/ui/shells/textsh1.cxx (original) +++ openoffice/trunk/main/sw/source/ui/shells/textsh1.cxx Wed Jun 26 12:15:55 2013 @@ -302,14 +302,14 @@ short lcl_AskRedlineMode(Window *pWin) void SwTextShell::Execute(SfxRequest &rReq) { sal_Bool bUseDialog = sal_True; - const SfxItemSet *pArgs = rReq.GetArgs(); - SwWrtShell& rWrtSh = GetShell(); - const SfxPoolItem* pItem = 0; - sal_uInt16 nSlot = rReq.GetSlot(); - if(pArgs) - pArgs->GetItemState(GetPool().GetWhich(nSlot), sal_False, &pItem); - switch( nSlot ) - { + const SfxItemSet *pArgs = rReq.GetArgs(); + SwWrtShell& rWrtSh = GetShell(); + const SfxPoolItem* pItem = 0; + sal_uInt16 nSlot = rReq.GetSlot(); + if(pArgs) + pArgs->GetItemState(GetPool().GetWhich(nSlot), sal_False, &pItem); + switch( nSlot ) + { case SID_LANGUAGE_STATUS: { // get the language @@ -318,44 +318,45 @@ void SwTextShell::Execute(SfxRequest &rR if (pItem2) aNewLangTxt = pItem2->GetValue(); - //!! Remember the view frame right now... - //!! (call to GetView().GetViewFrame() will break if the - //!! SwTextShell got destroyed meanwhile.) - SfxViewFrame *pViewFrame = GetView().GetViewFrame(); + //!! Remember the view frame right now... + //!! (call to GetView().GetViewFrame() will break if the + //!! SwTextShell got destroyed meanwhile.) + SfxViewFrame *pViewFrame = GetView().GetViewFrame(); if (aNewLangTxt.EqualsAscii( "*" )) - { + { // open the dialog "Tools/Options/Language Settings - Language" - // to set the documents default language - SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); - if (pFact) - { + // to set the documents default language + SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create(); + if (pFact) + { VclAbstractDialog* pDlg = pFact->CreateVclDialog( GetView().GetWindow(), SID_LANGUAGE_OPTIONS ); - pDlg->Execute(); - delete pDlg; - } - } - else - { - //!! We have to use StartAction / EndAction bracketing in - //!! order to prevent possible destruction of the SwTextShell - //!! due to the selection changes coming below. - rWrtSh.StartAction(); - // prevent view from jumping because of (temporary) selection changes - rWrtSh.LockView( sal_True ); - // save selection for later restoration - rWrtSh.Push(); + pDlg->Execute(); + delete pDlg; + } + } + else + { + //!! We have to use StartAction / EndAction bracketing in + //!! order to prevent possible destruction of the SwTextShell + //!! due to the selection changes coming below. + rWrtSh.StartAction(); + // prevent view from jumping because of (temporary) selection changes + rWrtSh.LockView( sal_True ); + + // save selection for later restoration + rWrtSh.Push(); // setting the new language... if (aNewLangTxt.Len() > 0) - { + { const String aSelectionLangPrefix( String::CreateFromAscii("Current_") ); const String aParagraphLangPrefix( String::CreateFromAscii("Paragraph_") ); const String aDocumentLangPrefix( String::CreateFromAscii("Default_") ); - const String aStrNone( String::CreateFromAscii("LANGUAGE_NONE") ); - const String aStrResetLangs( String::CreateFromAscii("RESET_LANGUAGES") ); + const String aStrNone( String::CreateFromAscii("LANGUAGE_NONE") ); + const String aStrResetLangs( String::CreateFromAscii("RESET_LANGUAGES") ); - SfxItemSet aCoreSet( GetPool(), + SfxItemSet aCoreSet( GetPool(), RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CTL_LANGUAGE, RES_CHRATR_CTL_LANGUAGE, @@ -365,11 +366,11 @@ void SwTextShell::Execute(SfxRequest &rR bool bForSelection = true; bool bForParagraph = false; if (STRING_NOTFOUND != (nPos = aNewLangTxt.Search( aSelectionLangPrefix, 0 ))) - { + { // ... for the current selection aNewLangTxt = aNewLangTxt.Erase( nPos, aSelectionLangPrefix.Len() ); bForSelection = true; - } + } else if (STRING_NOTFOUND != (nPos = aNewLangTxt.Search( aParagraphLangPrefix , 0 ))) { // ... for the current paragraph language @@ -378,40 +379,44 @@ void SwTextShell::Execute(SfxRequest &rR bForParagraph = true; } else if (STRING_NOTFOUND != (nPos = aNewLangTxt.Search( aDocumentLangPrefix , 0 ))) - { + { // ... as default document language aNewLangTxt = aNewLangTxt.Erase( nPos, aDocumentLangPrefix.Len() ); bForSelection = false; - } + } if (bForParagraph) SwLangHelper::SelectCurrentPara( rWrtSh ); - if (!bForSelection) // document language to be changed... + if (!bForSelection) // document language to be changed... { - rWrtSh.SelAll(); + 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... - rWrtSh.Pop( sal_False ); + // restore selection... + rWrtSh.Pop( sal_False ); - rWrtSh.LockView( sal_False ); - rWrtSh.EndAction(); - } + rWrtSh.LockView( sal_False ); + rWrtSh.EndAction(); + } // invalidate slot to get the new language displayed - pViewFrame->GetBindings().Invalidate( nSlot ); + pViewFrame->GetBindings().Invalidate( nSlot ); rReq.Done(); - break; + break; } case SID_THES: