mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-10-24 17:18:54 +00:00
AppKit: Disable Undo and Redo when a text view does not allow undo
A text view handled undo: and redo: and registered its changes even when allowsUndo was NO, so Edit > Undo stayed enabled and did nothing. Behaviour now follows canonical Cocoa: a text view that does not allow undo registers nothing and passes undo: and redo: on to the window, and Undo and Redo are enabled only when there is a change to undo or redo. * CPTextView/CPTextView.j: Register changes only when undo is allowed, stop responding to undo: and redo: when it is not, and validate the Undo and Redo items against the undo manager. * CPWindow/CPWindow.j: Validate the Undo and Redo items against the window's undo manager. * Tests/AppKit/CPTextViewTest.j: Add tests for responding to undo:, registering changes and validating the Undo item. * Tests/Manual/TextEditor/DocumentWindowController.j: Add toggleAllowsUndo: and validateMenuItem:, so that undo can be turned on and off for the active document. * Tests/Manual/TextEditor/Resources/MainMenu.xib, Resources/MainMenu.cib: Add Edit > Allow Undo. * Tests/Manual/TextEditor/WORKLIST.md: Remove the entry for this gap, record Allow Undo as tested, and add the key equivalent behaviour of disabled menu items for discussion.
This commit is contained in:
1 parent
92b8039c71
commit
66ea130c8d
7 files changed
+171
-14
No files matched your search
@@ -688,6 +688,47 @@ var kDelegateRespondsTo_textShouldBeginEditing
|
||||
[[[self window] undoManager] redo];
|
||||
}
|
||||
|
||||
/*
|
||||
@ignore
|
||||
Returns the undo manager that records the text view's changes, or nil when allowsUndo is NO,
|
||||
so that a text view that does not allow undo registers nothing.
|
||||
*/
|
||||
- (CPUndoManager)_registeringUndoManager
|
||||
{
|
||||
return _allowsUndo ? [[self window] undoManager] : nil;
|
||||
}
|
||||
|
||||
/*!
|
||||
A text view that does not allow undo does not respond to \c -undo: or \c -redo:, so those
|
||||
actions continue along the responder chain to the window, as in Cocoa.
|
||||
*/
|
||||
- (BOOL)respondsToSelector:(SEL)aSelector
|
||||
{
|
||||
if (!_allowsUndo && (aSelector === @selector(undo:) || aSelector === @selector(redo:)))
|
||||
return NO;
|
||||
|
||||
return [super respondsToSelector:aSelector];
|
||||
}
|
||||
|
||||
/*!
|
||||
Enables the Undo and Redo items only when the undo manager has a change to undo or redo.
|
||||
Every other item is enabled.
|
||||
@param anItem the item to validate
|
||||
@return \c YES if the item should be enabled
|
||||
*/
|
||||
- (BOOL)validateUserInterfaceItem:(id /*<CPValidatedUserInterfaceItem>*/)anItem
|
||||
{
|
||||
var action = [anItem action];
|
||||
|
||||
if (action === @selector(undo:))
|
||||
return [[[self window] undoManager] canUndo];
|
||||
|
||||
if (action === @selector(redo:))
|
||||
return [[[self window] undoManager] canRedo];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
// MARK: -
|
||||
// MARK: Accessors
|
||||
@@ -818,7 +859,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
|
||||
|
||||
- (void)_replaceCharactersInRange:(CPRange)aRange withAttributedString:(CPString)aString selectionRange:(CPRange)selectionRange
|
||||
{
|
||||
[[[[self window] undoManager] prepareWithInvocationTarget:self]
|
||||
[[[self _registeringUndoManager] prepareWithInvocationTarget:self]
|
||||
_replaceCharactersInRange:CPMakeRange(aRange.location, [aString length])
|
||||
withAttributedString:[_textStorage attributedSubstringFromRange:CPMakeRangeCopy(aRange)]
|
||||
selectionRange:CPMakeRangeCopy(_selectionRange)];
|
||||
@@ -840,7 +881,7 @@ var kDelegateRespondsTo_textShouldBeginEditing
|
||||
else if (![self isRichText])
|
||||
aString = [[CPAttributedString alloc] initWithString:string attributes:_typingAttributes];
|
||||
|
||||
var undoManager = [[self window] undoManager];
|
||||
var undoManager = [self _registeringUndoManager];
|
||||
[undoManager setActionName:@"Replace/insert text"];
|
||||
|
||||
[[undoManager prepareWithInvocationTarget:self]
|
||||
@@ -1692,7 +1733,7 @@ Sets the selection to a range of characters in response to user action.
|
||||
|
||||
changedRange = CPIntersectionRange(CPMakeRange(0, [_layoutManager numberOfCharacters]), changedRange);
|
||||
|
||||
[[[_window undoManager] prepareWithInvocationTarget:self] _replaceCharactersInRange:CPMakeRange(changedRange.location, 0)
|
||||
[[[self _registeringUndoManager] prepareWithInvocationTarget:self] _replaceCharactersInRange:CPMakeRange(changedRange.location, 0)
|
||||
withAttributedString:[_textStorage attributedSubstringFromRange:CPMakeRangeCopy(changedRange)]
|
||||
selectionRange:CPMakeRangeCopy(_selectionRange)];
|
||||
[self willChangeValueForKey:@"objectValue"];
|
||||
@@ -1879,7 +1920,7 @@ Sets the selection to a range of characters in response to user action.
|
||||
|
||||
var currentAttributes = [_textStorage attributesAtIndex:range.location effectiveRange:nil] || _typingAttributes;
|
||||
|
||||
[[[[self window] undoManager] prepareWithInvocationTarget:self]
|
||||
[[[self _registeringUndoManager] prepareWithInvocationTarget:self]
|
||||
setFont:[currentAttributes objectForKey:CPFontAttributeName] || [self font]
|
||||
range:CPMakeRangeCopy(range)];
|
||||
|
||||
@@ -1893,7 +1934,7 @@ Sets the selection to a range of characters in response to user action.
|
||||
oldFont,
|
||||
attributes,
|
||||
scrollRange = CPMakeRange(CPMaxRange(_selectionRange), 0),
|
||||
undoManager = [[self window] undoManager];
|
||||
undoManager = [self _registeringUndoManager];
|
||||
|
||||
[undoManager beginUndoGrouping];
|
||||
|
||||
@@ -1957,7 +1998,7 @@ Sets the selection to a range of characters in response to user action.
|
||||
{
|
||||
var currentAttributes = [_textStorage attributesAtIndex:range.location effectiveRange:nil] || _typingAttributes;
|
||||
|
||||
[[[[self window] undoManager] prepareWithInvocationTarget:self]
|
||||
[[[self _registeringUndoManager] prepareWithInvocationTarget:self]
|
||||
setTextColor:[currentAttributes objectForKey:CPForegroundColorAttributeName] || _textColor
|
||||
range:CPMakeRangeCopy(range)];
|
||||
|
||||
@@ -2031,7 +2072,7 @@ Sets the selection to a range of characters in response to user action.
|
||||
if (_selectionRange.length > 0)
|
||||
{
|
||||
// Add rudimentary undo support
|
||||
var undoManager = [[self window] undoManager];
|
||||
var undoManager = [self _registeringUndoManager];
|
||||
if (undoManager)
|
||||
{
|
||||
[[undoManager prepareWithInvocationTarget:self]
|
||||
|
||||
@@ -2830,13 +2830,22 @@ CPTexturedBackgroundWindowMask
|
||||
|
||||
For \c -toggleToolbarShown:, the item's title becomes "Hide Toolbar" or "Show Toolbar"
|
||||
to reflect the toolbar's visibility, and the item is enabled only when the window has
|
||||
a toolbar. Every other item is enabled.
|
||||
a toolbar. \c -undo: and \c -redo: are enabled only when the window's undo manager has a
|
||||
change to undo or redo. Every other item is enabled.
|
||||
@param anItem the item to validate
|
||||
@return \c YES if the item should be enabled
|
||||
*/
|
||||
- (BOOL)validateUserInterfaceItem:(id /*<CPValidatedUserInterfaceItem>*/)anItem
|
||||
{
|
||||
if ([anItem action] !== @selector(toggleToolbarShown:))
|
||||
var action = [anItem action];
|
||||
|
||||
if (action === @selector(undo:))
|
||||
return [[self undoManager] canUndo];
|
||||
|
||||
if (action === @selector(redo:))
|
||||
return [[self undoManager] canRedo];
|
||||
|
||||
if (action !== @selector(toggleToolbarShown:))
|
||||
return YES;
|
||||
|
||||
var toolbar = [self toolbar];
|
||||
|
||||
Reference in new issue
Block a user