summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand <alg@apache.org>2012-08-10 13:19:02 +0000
committerCaolán McNamara <caolanm@redhat.com>2013-05-28 15:55:23 +0100
commit71e37a5c3886ff35d7240a9fb6b30aceec057782 (patch)
treefc4007d2288553c4823ffa9865593f28784103ce
parent12a4200e8ff7f045efcc7e9d15a24b15b248c437 (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.hxx10
-rw-r--r--include/svx/svdedxv.hxx6
-rw-r--r--svx/source/svdraw/sdrundomanager.cxx29
-rw-r--r--svx/source/svdraw/svdedxv.cxx55
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;