Kaydet (Commit) ddd94929 authored tarafından Armin Le Grand's avatar Armin Le Grand

#120498# fixed error with half text edit undone, extended as preparation for #120515#

üst 9cb69760
...@@ -37,6 +37,11 @@ private: ...@@ -37,6 +37,11 @@ private:
Link maEndTextEditHdl; Link maEndTextEditHdl;
SfxUndoAction* mpLastUndoActionBeforeTextEdit; SfxUndoAction* mpLastUndoActionBeforeTextEdit;
bool mbEndTextEditTriggeredFromUndo;
protected:
// call to check for TextEdit active
bool isTextEditActive() const;
public: public:
SdrUndoManager(sal_uInt16 nMaxUndoActionCount = 20); SdrUndoManager(sal_uInt16 nMaxUndoActionCount = 20);
...@@ -51,6 +56,11 @@ public: ...@@ -51,6 +56,11 @@ public:
// reset all text edit actions will be removed from this undo manager to // reset all text edit actions will be removed from this undo manager to
// restore the state before activation // restore the state before activation
void SetEndTextEditHdl(const Link& rLink); 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; }
}; };
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
......
...@@ -120,6 +120,12 @@ private: ...@@ -120,6 +120,12 @@ private:
SVX_DLLPRIVATE void ImpClearVars(); SVX_DLLPRIVATE void ImpClearVars();
protected: 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; OutlinerView* ImpFindOutlinerView(Window* pWin) const;
// Eine neue OutlinerView auf dem Heap anlegen und alle erforderlichen Parameter setzen. // Eine neue OutlinerView auf dem Heap anlegen und alle erforderlichen Parameter setzen.
......
...@@ -28,7 +28,8 @@ ...@@ -28,7 +28,8 @@
SdrUndoManager::SdrUndoManager(sal_uInt16 nMaxUndoActionCount) SdrUndoManager::SdrUndoManager(sal_uInt16 nMaxUndoActionCount)
: EditUndoManager(nMaxUndoActionCount), : EditUndoManager(nMaxUndoActionCount),
maEndTextEditHdl(), maEndTextEditHdl(),
mpLastUndoActionBeforeTextEdit(0) mpLastUndoActionBeforeTextEdit(0),
mbEndTextEditTriggeredFromUndo(false)
{ {
} }
...@@ -38,10 +39,10 @@ SdrUndoManager::~SdrUndoManager() ...@@ -38,10 +39,10 @@ SdrUndoManager::~SdrUndoManager()
sal_Bool SdrUndoManager::Undo() sal_Bool SdrUndoManager::Undo()
{ {
if(isTextEditActive())
{
sal_Bool bRetval(sal_False); sal_Bool bRetval(sal_False);
if(maEndTextEditHdl.IsSet())
{
// we are in text edit mode // we are in text edit mode
if(GetUndoActionCount() && mpLastUndoActionBeforeTextEdit != GetUndoAction(0)) if(GetUndoActionCount() && mpLastUndoActionBeforeTextEdit != GetUndoAction(0))
{ {
...@@ -51,24 +52,25 @@ sal_Bool SdrUndoManager::Undo() ...@@ -51,24 +52,25 @@ sal_Bool SdrUndoManager::Undo()
else else
{ {
// no more text edit undo, end text edit // no more text edit undo, end text edit
mbEndTextEditTriggeredFromUndo = true;
maEndTextEditHdl.Call(this); maEndTextEditHdl.Call(this);
} mbEndTextEditTriggeredFromUndo = false;
} }
if(!bRetval && GetUndoActionCount()) return bRetval;
}
else
{ {
// no undo triggered up to now, trigger local one // no undo triggered up to now, trigger local one
bRetval = SfxUndoManager::Undo(); return SfxUndoManager::Undo();
} }
return bRetval;
} }
sal_Bool SdrUndoManager::Redo() sal_Bool SdrUndoManager::Redo()
{ {
sal_Bool bRetval(sal_False); sal_Bool bRetval(sal_False);
if(maEndTextEditHdl.IsSet()) if(isTextEditActive())
{ {
// we are in text edit mode // we are in text edit mode
bRetval = EditUndoManager::Redo(); bRetval = EditUndoManager::Redo();
...@@ -87,7 +89,7 @@ void SdrUndoManager::SetEndTextEditHdl(const Link& rLink) ...@@ -87,7 +89,7 @@ void SdrUndoManager::SetEndTextEditHdl(const Link& rLink)
{ {
maEndTextEditHdl = rLink; maEndTextEditHdl = rLink;
if(maEndTextEditHdl.IsSet()) if(isTextEditActive())
{ {
// text edit start, remember last non-textedit action for later cleanup // text edit start, remember last non-textedit action for later cleanup
mpLastUndoActionBeforeTextEdit = GetUndoActionCount() ? GetUndoAction(0) : 0; mpLastUndoActionBeforeTextEdit = GetUndoActionCount() ? GetUndoAction(0) : 0;
...@@ -110,5 +112,10 @@ void SdrUndoManager::SetEndTextEditHdl(const Link& rLink) ...@@ -110,5 +112,10 @@ void SdrUndoManager::SetEndTextEditHdl(const Link& rLink)
} }
} }
bool SdrUndoManager::isTextEditActive() const
{
return maEndTextEditHdl.IsSet();
}
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// eof // eof
...@@ -550,6 +550,12 @@ IMPL_LINK(SdrObjEditView, EndTextEditHdl, SdrUndoManager*, /*pUndoManager*/) ...@@ -550,6 +550,12 @@ IMPL_LINK(SdrObjEditView, EndTextEditHdl, SdrUndoManager*, /*pUndoManager*/)
return 0; return 0;
} }
SdrUndoManager* SdrObjEditView::getSdrUndoManagerForEnhancedTextEdit() const
{
// default returns registered UndoManager
return GetModel() ? dynamic_cast< SdrUndoManager* >(GetModel()->GetSdrUndoManager()) : 0;
}
sal_Bool SdrObjEditView::SdrBeginTextEdit( sal_Bool SdrObjEditView::SdrBeginTextEdit(
SdrObject* pObj, SdrPageView* pPV, Window* pWin, SdrObject* pObj, SdrPageView* pPV, Window* pWin,
sal_Bool bIsNewObj, SdrOutliner* pGivenOutliner, sal_Bool bIsNewObj, SdrOutliner* pGivenOutliner,
...@@ -780,7 +786,7 @@ sal_Bool SdrObjEditView::SdrBeginTextEdit( ...@@ -780,7 +786,7 @@ sal_Bool SdrObjEditView::SdrBeginTextEdit(
if(IsUndoEnabled()) if(IsUndoEnabled())
{ {
SdrUndoManager* pSdrUndoManager = dynamic_cast< SdrUndoManager* >(GetModel()->GetSdrUndoManager()); SdrUndoManager* pSdrUndoManager = getSdrUndoManagerForEnhancedTextEdit();
if(pSdrUndoManager) if(pSdrUndoManager)
{ {
...@@ -789,7 +795,8 @@ sal_Bool SdrObjEditView::SdrBeginTextEdit( ...@@ -789,7 +795,8 @@ sal_Bool SdrObjEditView::SdrBeginTextEdit(
// it that text edit starts by setting a callback if it needs to end text edit mode. // it that text edit starts by setting a callback if it needs to end text edit mode.
if(mpOldTextEditUndoManager) 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; delete mpOldTextEditUndoManager;
mpOldTextEditUndoManager = 0; mpOldTextEditUndoManager = 0;
} }
...@@ -860,7 +867,8 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(sal_Bool bDontDeleteReally) ...@@ -860,7 +867,8 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(sal_Bool bDontDeleteReally)
SdrOutliner* pTEOutliner =pTextEditOutliner; SdrOutliner* pTEOutliner =pTextEditOutliner;
OutlinerView* pTEOutlinerView=pTextEditOutlinerView; OutlinerView* pTEOutlinerView=pTextEditOutlinerView;
Cursor* pTECursorMerker=pTextEditCursorMerker; Cursor* pTECursorMerker=pTextEditCursorMerker;
SdrUndoManager* pExtraUndoEditUndoManager = 0; SdrUndoManager* pUndoEditUndoManager = 0;
bool bNeedToUndoSavedRedoTextEdit(false);
if(IsUndoEnabled() && GetModel() && pTEObj && pTEOutliner) if(IsUndoEnabled() && GetModel() && pTEObj && pTEOutliner)
{ {
...@@ -871,19 +879,27 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(sal_Bool bDontDeleteReally) ...@@ -871,19 +879,27 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(sal_Bool bDontDeleteReally)
if(pOriginal) if(pOriginal)
{ {
// check if we got back our document undo manager // 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) if(pSdrUndoManager && dynamic_cast< SdrUndoManager* >(pOriginal) == pSdrUndoManager)
{ {
// We are ending text edit; execute all redos to create a complete text change if(pSdrUndoManager->isEndTextEditTriggeredFromUndo())
// 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 // remember the UndoManager where missing Undos have to be triggered after end
// outside the text edit changes // 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()) while(pSdrUndoManager->GetRedoActionCount())
{ {
pExtraUndoEditUndoManager = pSdrUndoManager; bNeedToUndoSavedRedoTextEdit = true;
pSdrUndoManager->Redo(); pSdrUndoManager->Redo();
} }
}
// reset the callback link and let the undo manager cleanup all text edit // reset the callback link and let the undo manager cleanup all text edit
// undo actions to get the stack back to the form before the text edit // undo actions to get the stack back to the form before the text edit
...@@ -1105,12 +1121,19 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(sal_Bool bDontDeleteReally) ...@@ -1105,12 +1121,19 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(sal_Bool bDontDeleteReally)
((SfxBroadcaster*)pTEObj->GetBroadcaster())->Broadcast(aHint); ((SfxBroadcaster*)pTEObj->GetBroadcaster())->Broadcast(aHint);
} }
if(pExtraUndoEditUndoManager) if(pUndoEditUndoManager)
{
if(bNeedToUndoSavedRedoTextEdit)
{ {
// undo the text edit action since it was created as part of a EndTextEdit // 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 // callback from undo itself. This needs to be done after the call to
// FmFormView::SdrEndTextEdit since it gets created there // FmFormView::SdrEndTextEdit since it gets created there
pExtraUndoEditUndoManager->Undo(); pUndoEditUndoManager->Undo();
}
// trigger the Undo which was not executed, but lead to this
// end text edit
pUndoEditUndoManager->Undo();
} }
return eRet; return eRet;
......
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