diff options
author | Armin Le Grand <alg@apache.org> | 2012-08-10 13:19:02 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2013-05-28 15:55:23 +0100 |
commit | 71e37a5c3886ff35d7240a9fb6b30aceec057782 (patch) | |
tree | fc4007d2288553c4823ffa9865593f28784103ce | |
parent | 12a4200e8ff7f045efcc7e9d15a24b15b248c437 (diff) |
Related: #i120498# fixed error with half text edit undone
extended as preparation for #i120515#
(cherry picked from commit ddd9492911585313faf1769f88323a8421bf93db)
Conflicts:
svx/inc/svx/sdrundomanager.hxx
svx/inc/svx/svdedxv.hxx
Change-Id: I50272a5719ee6e6a1a7fd1bafe9d94f480b1dbf5
-rw-r--r-- | include/svx/sdrundomanager.hxx | 10 | ||||
-rw-r--r-- | include/svx/svdedxv.hxx | 6 | ||||
-rw-r--r-- | svx/source/svdraw/sdrundomanager.cxx | 29 | ||||
-rw-r--r-- | svx/source/svdraw/svdedxv.cxx | 55 |
4 files changed, 73 insertions, 27 deletions
diff --git a/include/svx/sdrundomanager.hxx b/include/svx/sdrundomanager.hxx index 0d899f647aa9..860742f8bae7 100644 --- a/include/svx/sdrundomanager.hxx +++ b/include/svx/sdrundomanager.hxx @@ -33,6 +33,11 @@ private: Link maEndTextEditHdl; SfxUndoAction* mpLastUndoActionBeforeTextEdit; + bool mbEndTextEditTriggeredFromUndo; + +protected: + // call to check for TextEdit active + bool isTextEditActive() const; public: SdrUndoManager(sal_uInt16 nMaxUndoActionCount = 20); @@ -47,6 +52,11 @@ public: // reset all text edit actions will be removed from this undo manager to // restore the state before activation void SetEndTextEditHdl(const Link& rLink); + + // check from outside if we are inside a callback for ending text edit. This + // is needed to detect inside end text edit if it is a regular one or triggered + // by a last undo during text edit + bool isEndTextEditTriggeredFromUndo() { return mbEndTextEditTriggeredFromUndo; } }; ////////////////////////////////////////////////////////////////////////////// diff --git a/include/svx/svdedxv.hxx b/include/svx/svdedxv.hxx index c0d8a2a2eaac..0bdad27e229d 100644 --- a/include/svx/svdedxv.hxx +++ b/include/svx/svdedxv.hxx @@ -116,6 +116,12 @@ private: SVX_DLLPRIVATE void ImpClearVars(); protected: + // central method to get an SdrUndoManager for enhanced TextEdit. Default will + // try to return a dynamic_casted GetModel()->GetSdrUndoManager(). Applications + // which want to use this feature will need to overload this virtual method, + // provide their document UndoManager and derive it from SdrUndoManager. + virtual SdrUndoManager* getSdrUndoManagerForEnhancedTextEdit() const; + OutlinerView* ImpFindOutlinerView(Window* pWin) const; // Eine neue OutlinerView auf dem Heap anlegen und alle erforderlichen Parameter setzen. diff --git a/svx/source/svdraw/sdrundomanager.cxx b/svx/source/svdraw/sdrundomanager.cxx index 88e0c6c6c5d0..c28654cb924d 100644 --- a/svx/source/svdraw/sdrundomanager.cxx +++ b/svx/source/svdraw/sdrundomanager.cxx @@ -23,7 +23,8 @@ SdrUndoManager::SdrUndoManager(sal_uInt16 nMaxUndoActionCount) : EditUndoManager(nMaxUndoActionCount), maEndTextEditHdl(), - mpLastUndoActionBeforeTextEdit(0) + mpLastUndoActionBeforeTextEdit(0), + mbEndTextEditTriggeredFromUndo(false) { } @@ -33,10 +34,10 @@ SdrUndoManager::~SdrUndoManager() sal_Bool SdrUndoManager::Undo() { - sal_Bool bRetval(sal_False); - - if(maEndTextEditHdl.IsSet()) + if(isTextEditActive()) { + sal_Bool bRetval(sal_False); + // we are in text edit mode if(GetUndoActionCount() && mpLastUndoActionBeforeTextEdit != GetUndoAction(0)) { @@ -46,24 +47,25 @@ sal_Bool SdrUndoManager::Undo() else { // no more text edit undo, end text edit + mbEndTextEditTriggeredFromUndo = true; maEndTextEditHdl.Call(this); + mbEndTextEditTriggeredFromUndo = false; } - } - if(!bRetval && GetUndoActionCount()) + return bRetval; + } + else { // no undo triggered up to now, trigger local one - bRetval = SfxUndoManager::Undo(); + return SfxUndoManager::Undo(); } - - return bRetval; } sal_Bool SdrUndoManager::Redo() { sal_Bool bRetval(sal_False); - if(maEndTextEditHdl.IsSet()) + if(isTextEditActive()) { // we are in text edit mode bRetval = EditUndoManager::Redo(); @@ -82,7 +84,7 @@ void SdrUndoManager::SetEndTextEditHdl(const Link& rLink) { maEndTextEditHdl = rLink; - if(maEndTextEditHdl.IsSet()) + if(isTextEditActive()) { // text edit start, remember last non-textedit action for later cleanup mpLastUndoActionBeforeTextEdit = GetUndoActionCount() ? GetUndoAction(0) : 0; @@ -105,5 +107,10 @@ void SdrUndoManager::SetEndTextEditHdl(const Link& rLink) } } +bool SdrUndoManager::isTextEditActive() const +{ + return maEndTextEditHdl.IsSet(); +} + ////////////////////////////////////////////////////////////////////////////// // eof diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx index 6a5e571269bc..6d39a5b1d93f 100644 --- a/svx/source/svdraw/svdedxv.cxx +++ b/svx/source/svdraw/svdedxv.cxx @@ -526,6 +526,12 @@ IMPL_LINK(SdrObjEditView, EndTextEditHdl, SdrUndoManager*, /*pUndoManager*/) return 0; } +SdrUndoManager* SdrObjEditView::getSdrUndoManagerForEnhancedTextEdit() const +{ + // default returns registered UndoManager + return GetModel() ? dynamic_cast< SdrUndoManager* >(GetModel()->GetSdrUndoManager()) : 0; +} + sal_Bool SdrObjEditView::SdrBeginTextEdit( SdrObject* pObj, SdrPageView* pPV, Window* pWin, sal_Bool bIsNewObj, SdrOutliner* pGivenOutliner, @@ -754,7 +760,7 @@ sal_Bool SdrObjEditView::SdrBeginTextEdit( if(IsUndoEnabled()) { - SdrUndoManager* pSdrUndoManager = dynamic_cast< SdrUndoManager* >(GetModel()->GetSdrUndoManager()); + SdrUndoManager* pSdrUndoManager = getSdrUndoManagerForEnhancedTextEdit(); if(pSdrUndoManager) { @@ -763,7 +769,8 @@ sal_Bool SdrObjEditView::SdrBeginTextEdit( // it that text edit starts by setting a callback if it needs to end text edit mode. if(mpOldTextEditUndoManager) { - // should not happen, delete it + // should not happen, delete it since it was probably forgotten somewhere + OSL_ENSURE(false, "Deleting forgotten old TextEditUndoManager, should be checked (!)"); delete mpOldTextEditUndoManager; mpOldTextEditUndoManager = 0; } @@ -830,7 +837,8 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(sal_Bool bDontDeleteReally) SdrOutliner* pTEOutliner =pTextEditOutliner; OutlinerView* pTEOutlinerView=pTextEditOutlinerView; Cursor* pTECursorMerker=pTextEditCursorMerker; - SdrUndoManager* pExtraUndoEditUndoManager = 0; + SdrUndoManager* pUndoEditUndoManager = 0; + bool bNeedToUndoSavedRedoTextEdit(false); if(IsUndoEnabled() && GetModel() && pTEObj && pTEOutliner) { @@ -841,18 +849,26 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(sal_Bool bDontDeleteReally) if(pOriginal) { // check if we got back our document undo manager - SdrUndoManager* pSdrUndoManager = dynamic_cast< SdrUndoManager* >(GetModel()->GetSdrUndoManager()); + SdrUndoManager* pSdrUndoManager = getSdrUndoManagerForEnhancedTextEdit(); if(pSdrUndoManager && dynamic_cast< SdrUndoManager* >(pOriginal) == pSdrUndoManager) { - // We are ending text edit; execute all redos to create a complete text change - // undo action for the redo buffer. Also mark this state when at least one redo was - // executed; the created TextChange needs to be undone plus the first real undo - // outside the text edit changes - while(pSdrUndoManager->GetRedoActionCount()) + if(pSdrUndoManager->isEndTextEditTriggeredFromUndo()) { - pExtraUndoEditUndoManager = pSdrUndoManager; - pSdrUndoManager->Redo(); + // remember the UndoManager where missing Undos have to be triggered after end + // text edit. When the undo had triggered the end text edit, the original action + // which had to be undone originally is not yet undone. + pUndoEditUndoManager = pSdrUndoManager; + + // We are ending text edit; if text edit was triggered from undo, execute all redos + // to create a complete text change undo action for the redo buffer. Also mark this + // state when at least one redo was executed; the created extra TextChange needs to + // be undone in addition to the first real undo outside the text edit changes + while(pSdrUndoManager->GetRedoActionCount()) + { + bNeedToUndoSavedRedoTextEdit = true; + pSdrUndoManager->Redo(); + } } // reset the callback link and let the undo manager cleanup all text edit @@ -1059,12 +1075,19 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(sal_Bool bDontDeleteReally) ((SfxBroadcaster*)pTEObj->GetBroadcaster())->Broadcast(aHint); } - if(pExtraUndoEditUndoManager) + if(pUndoEditUndoManager) { - // undo the text edit action since it was created as part of a EndTextEdit - // callback from undo itself. This needs to be done after the call to - // FmFormView::SdrEndTextEdit since it gets created there - pExtraUndoEditUndoManager->Undo(); + if(bNeedToUndoSavedRedoTextEdit) + { + // undo the text edit action since it was created as part of an EndTextEdit + // callback from undo itself. This needs to be done after the call to + // FmFormView::SdrEndTextEdit since it gets created there + pUndoEditUndoManager->Undo(); + } + + // trigger the Undo which was not executed, but lead to this + // end text edit + pUndoEditUndoManager->Undo(); } return eRet; |