summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Schoenheit [fs] <frank.schoenheit@oracle.com>2010-12-01 15:30:01 +0100
committerFrank Schoenheit [fs] <frank.schoenheit@oracle.com>2010-12-01 15:30:01 +0100
commitd5a671a4b0a5fd7c33f7faf77c30790777ccf800 (patch)
treed6d5f3a14ac7df147b8687ad9c4b054608ba0fd4
parent06d2c4e3e229b7cd409e20fa36968efe7d3986cd (diff)
undoapi: clear the redo stack when leaving an Undo context resp. list action, not when entering it. This is a pre-requisite for Writer's upcoming migratin to SfxUndoManager
-rwxr-xr-xframework/source/helper/undomanagerhelper.cxx13
-rwxr-xr-xsfx2/qa/complex/sfx2/UndoManager.java19
2 files changed, 23 insertions, 9 deletions
diff --git a/framework/source/helper/undomanagerhelper.cxx b/framework/source/helper/undomanagerhelper.cxx
index e2cfd13c5bb7..d0ece6131841 100755
--- a/framework/source/helper/undomanagerhelper.cxx
+++ b/framework/source/helper/undomanagerhelper.cxx
@@ -595,6 +595,7 @@ namespace framework
const bool isHiddenContext = m_aContextVisibilities.top();;
m_aContextVisibilities.pop();
+ const bool bHadRedoActions = ( rUndoManager.GetRedoActionCount( IUndoManager::TopLevel ) > 0 );
{
::comphelper::FlagGuard aNotificationGuard( m_bAPIActionRunning );
if ( isHiddenContext )
@@ -602,11 +603,13 @@ namespace framework
else
nContextElements = rUndoManager.LeaveListAction();
}
+ const bool bHasRedoActions = ( rUndoManager.GetRedoActionCount( IUndoManager::TopLevel ) > 0 );
// prepare notification
void ( SAL_CALL XUndoManagerListener::*notificationMethod )( const UndoManagerEvent& ) = NULL;
- UndoManagerEvent aEvent( buildEvent( ::rtl::OUString() ) );
+ UndoManagerEvent aContextEvent( buildEvent( ::rtl::OUString() ) );
+ const EventObject aClearedEvent( getXUndoManager() );
if ( nContextElements == 0 )
{
notificationMethod = &XUndoManagerListener::cancelledContext;
@@ -617,14 +620,16 @@ namespace framework
}
else
{
- aEvent.UndoActionTitle = rUndoManager.GetUndoActionComment( 0, IUndoManager::CurrentLevel );
+ aContextEvent.UndoActionTitle = rUndoManager.GetUndoActionComment( 0, IUndoManager::CurrentLevel );
notificationMethod = &XUndoManagerListener::leftContext;
}
aGuard.clear();
// <--- SYNCHRONIZED
- m_aUndoListeners.notifyEach( notificationMethod, aEvent );
+ if ( bHadRedoActions && !bHasRedoActions )
+ m_aUndoListeners.notifyEach( &XUndoManagerListener::redoActionsCleared, aClearedEvent );
+ m_aUndoListeners.notifyEach( notificationMethod, aContextEvent );
impl_notifyModified();
}
@@ -702,7 +707,7 @@ namespace framework
m_aUndoListeners.notifyEach( &XUndoManagerListener::undoActionAdded, aEventAdd );
if ( bHadRedoActions && !bHasRedoActions )
- m_aUndoListeners.notifyEach( &XUndoManagerListener::redoActionsCleared , aEventClear );
+ m_aUndoListeners.notifyEach( &XUndoManagerListener::redoActionsCleared, aEventClear );
impl_notifyModified();
}
diff --git a/sfx2/qa/complex/sfx2/UndoManager.java b/sfx2/qa/complex/sfx2/UndoManager.java
index 2e4c5abe2903..42461c9365bb 100755
--- a/sfx2/qa/complex/sfx2/UndoManager.java
+++ b/sfx2/qa/complex/sfx2/UndoManager.java
@@ -833,9 +833,9 @@ public class UndoManager
m_undoListener.reset();
// put one action on the undo and one on the redo stack, as precondition for the following tests
- XUndoAction undoAction1 = new CustomUndoAction( "Undo Action 1" );
+ final XUndoAction undoAction1 = new CustomUndoAction( "Undo Action 1" );
i_undoManager.addUndoAction( undoAction1 );
- XUndoAction undoAction2 = new CustomUndoAction( "Undo Action 2" );
+ final XUndoAction undoAction2 = new CustomUndoAction( "Undo Action 2" );
i_undoManager.addUndoAction( undoAction2 );
i_undoManager.undo();
assertTrue( "precondition for context handling tests not met (1)", i_undoManager.isUndoPossible() );
@@ -843,11 +843,19 @@ public class UndoManager
assertArrayEquals( new String[] { undoAction1.getTitle() }, i_undoManager.getAllUndoActionTitles() );
assertArrayEquals( new String[] { undoAction2.getTitle() }, i_undoManager.getAllRedoActionTitles() );
- // enter a context, add a single action
+ final String[] expectedRedoActionComments = new String[] { undoAction2.getTitle() };
+ assertArrayEquals( expectedRedoActionComments, i_undoManager.getAllRedoActionTitles() );
+
+ // enter a context
i_undoManager.enterUndoContext( "Undo Context" );
+ // this should not (yet) touch the redo stack
+ assertArrayEquals( expectedRedoActionComments, i_undoManager.getAllRedoActionTitles() );
assertEquals( "unexpected undo context depth after entering a context", 1, m_undoListener.getCurrentUndoContextDepth() );
+ // add a single action
XUndoAction undoAction3 = new CustomUndoAction( "Undo Action 3" );
i_undoManager.addUndoAction( undoAction3 );
+ // still, the redo stack should be untouched - added at a lower level does not affect it at all
+ assertArrayEquals( expectedRedoActionComments, i_undoManager.getAllRedoActionTitles() );
// while the context is open, its title should already contribute to the stack, ...
assertEquals( "Undo Context", i_undoManager.getCurrentUndoActionTitle() );
@@ -855,8 +863,6 @@ public class UndoManager
// context, ...
assertArrayEquals( new String[] { "Undo Context", undoAction1.getTitle() },
i_undoManager.getAllUndoActionTitles() );
- assertArrayEquals( new String[] {}, i_undoManager.getAllRedoActionTitles() );
- // (the redo stack has been cleared when a new context was entered)
// ... but Undo and Redo should be impossible as long as the context is open
assertFalse( i_undoManager.isUndoPossible() );
assertFalse( i_undoManager.isRedoPossible() );
@@ -867,6 +873,9 @@ public class UndoManager
assertFalse( m_undoListener.wasHiddenContextLeft() );
assertFalse( m_undoListener.hasContextBeenCancelled() );
assertEquals( "unexpected undo context depth leaving a non-empty context", 0, m_undoListener.getCurrentUndoContextDepth() );
+ // leaving a non-empty context should have cleare the redo stack
+ assertArrayEquals( new String[0], i_undoManager.getAllRedoActionTitles() );
+ assertTrue( m_undoListener.wasRedoStackCleared() );
// .............................................................................................................
// part II: empty contexts