mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-06-02 22:21:00 +00:00
Save undo sequences for only LAST auto-completion selected or UNDO on cancelled auto-completion
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/branches/gnustep_testplant_branch@37051 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
2929f8aed8
commit
a9e4f72f54
3 changed files with 99 additions and 83 deletions
|
@ -153,6 +153,7 @@ therefore be stored in the NSLayoutManager to avoid problems.
|
||||||
unsigned uses_find_panel:1;
|
unsigned uses_find_panel:1;
|
||||||
unsigned accepts_glyph_info:1;
|
unsigned accepts_glyph_info:1;
|
||||||
unsigned allows_document_background_color_change:1;
|
unsigned allows_document_background_color_change:1;
|
||||||
|
unsigned isAutoCompleting:2;
|
||||||
} _tf;
|
} _tf;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#import <Foundation/NSAutoreleasePool.h>
|
#import <Foundation/NSAutoreleasePool.h>
|
||||||
#import <Foundation/NSRunLoop.h>
|
#import <Foundation/NSRunLoop.h>
|
||||||
#import <Foundation/NSNotification.h>
|
#import <Foundation/NSNotification.h>
|
||||||
|
#import "Foundation/NSUndoManager.h"
|
||||||
#import "AppKit/NSApplication.h"
|
#import "AppKit/NSApplication.h"
|
||||||
#import "AppKit/NSBox.h"
|
#import "AppKit/NSBox.h"
|
||||||
#import "AppKit/NSEvent.h"
|
#import "AppKit/NSEvent.h"
|
||||||
|
@ -316,7 +317,7 @@ static GSAutocompleteWindow *gsWindow = nil;
|
||||||
if ([event window] != self)
|
if ([event window] != self)
|
||||||
{
|
{
|
||||||
[self updateTextViewWithMovement: NSCancelTextMovement
|
[self updateTextViewWithMovement: NSCancelTextMovement
|
||||||
isFinal: NO];
|
isFinal: YES];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -352,7 +353,7 @@ static GSAutocompleteWindow *gsWindow = nil;
|
||||||
key == NSLeftArrowFunctionKey)
|
key == NSLeftArrowFunctionKey)
|
||||||
{
|
{
|
||||||
[self updateTextViewWithMovement: NSCancelTextMovement
|
[self updateTextViewWithMovement: NSCancelTextMovement
|
||||||
isFinal: NO];
|
isFinal: YES];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -382,7 +383,7 @@ static GSAutocompleteWindow *gsWindow = nil;
|
||||||
{
|
{
|
||||||
_stopped = YES;
|
_stopped = YES;
|
||||||
[self updateTextViewWithMovement: NSCancelTextMovement
|
[self updateTextViewWithMovement: NSCancelTextMovement
|
||||||
isFinal: NO];
|
isFinal: YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) reloadData
|
- (void) reloadData
|
||||||
|
@ -431,25 +432,28 @@ static GSAutocompleteWindow *gsWindow = nil;
|
||||||
{
|
{
|
||||||
NSString *word;
|
NSString *word;
|
||||||
|
|
||||||
if (movement != NSCancelTextMovement)
|
// If this is a cancelling request...
|
||||||
|
if (movement == NSCancelTextMovement)
|
||||||
{
|
{
|
||||||
NSInteger rowIndex = [_tableView selectedRow];
|
// Invocation with flag==YES indicates we've inserted at least once
|
||||||
word = [[_words objectAtIndex: rowIndex] description];
|
// causing text view to push an undo sequence that we need to undo
|
||||||
|
// here...
|
||||||
|
if (flag)
|
||||||
|
[[_textView undoManager] undo];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
word = _originalWord;
|
NSInteger rowIndex = [_tableView selectedRow];
|
||||||
|
word = [[_words objectAtIndex: rowIndex] description];
|
||||||
|
[_textView insertCompletion: word
|
||||||
|
forPartialWordRange: _range
|
||||||
|
movement: movement
|
||||||
|
isFinal: flag];
|
||||||
}
|
}
|
||||||
|
|
||||||
[_textView insertCompletion: word
|
|
||||||
forPartialWordRange: _range
|
|
||||||
movement: movement
|
|
||||||
isFinal: flag];
|
|
||||||
|
|
||||||
// Release _words and _originalWords if
|
// Release _words and _originalWords if
|
||||||
// autocomplete is final or canceled.
|
// autocomplete is final or canceled.
|
||||||
if ( (flag) ||
|
if ((flag) || (movement == NSCancelTextMovement) )
|
||||||
(movement == NSCancelTextMovement) )
|
|
||||||
{
|
{
|
||||||
ASSIGN(_originalWord, nil);
|
ASSIGN(_originalWord, nil);
|
||||||
ASSIGN(_words, nil);
|
ASSIGN(_words, nil);
|
||||||
|
|
|
@ -2658,27 +2658,27 @@ TextDidEndEditing notification _without_ asking the delegate
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We need to send the textShouldBeginEditing: /
|
We need to send the textShouldBeginEditing: /
|
||||||
textDidBeginEditingNotification only once.
|
textDidBeginEditingNotification only once.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (BEGAN_EDITING == NO)
|
if (BEGAN_EDITING == NO)
|
||||||
{
|
{
|
||||||
if (([_delegate respondsToSelector: @selector(textShouldBeginEditing:)])
|
if (([_delegate respondsToSelector: @selector(textShouldBeginEditing:)])
|
||||||
&& ([_delegate textShouldBeginEditing: _notifObject] == NO))
|
&& ([_delegate textShouldBeginEditing: _notifObject] == NO))
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
SET_BEGAN_EDITING(YES);
|
SET_BEGAN_EDITING(YES);
|
||||||
|
|
||||||
[notificationCenter postNotificationName: NSTextDidBeginEditingNotification
|
[notificationCenter postNotificationName: NSTextDidBeginEditingNotification
|
||||||
object: _notifObject];
|
object: _notifObject];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_tf.delegate_responds_to_should_change)
|
if (_tf.delegate_responds_to_should_change)
|
||||||
{
|
{
|
||||||
result = [_delegate textView: self
|
result = [_delegate textView: self
|
||||||
shouldChangeTextInRange: affectedCharRange
|
shouldChangeTextInRange: affectedCharRange
|
||||||
replacementString: replacementString];
|
replacementString: replacementString];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result && [self allowsUndo])
|
if (result && [self allowsUndo])
|
||||||
|
@ -2692,54 +2692,61 @@ TextDidEndEditing notification _without_ asking the delegate
|
||||||
static BOOL undoManagerCanCoalesce = NO;
|
static BOOL undoManagerCanCoalesce = NO;
|
||||||
|
|
||||||
{
|
{
|
||||||
// FIXME This code (together with undoManagerCanCoalesce) is a
|
// FIXME This code (together with undoManagerCanCoalesce) is a
|
||||||
// temporary workaround to allow using an out of date version of
|
// temporary workaround to allow using an out of date version of
|
||||||
// base. Removed this upon the next release of base.
|
// base. Removed this upon the next release of base.
|
||||||
static BOOL didCheck = NO;
|
static BOOL didCheck = NO;
|
||||||
if (!didCheck)
|
if (!didCheck)
|
||||||
{
|
{
|
||||||
undoManagerCanCoalesce =
|
undoManagerCanCoalesce =
|
||||||
[NSUndoManager instancesRespondToSelector:
|
[NSUndoManager instancesRespondToSelector:
|
||||||
@selector(_canCoalesceUndoWithTarget:selector:object:)];
|
@selector(_canCoalesceUndoWithTarget:selector:object:)];
|
||||||
if (!undoManagerCanCoalesce)
|
if (!undoManagerCanCoalesce)
|
||||||
{
|
{
|
||||||
NSLog(@"This version of NSUndoManager does not\n"
|
NSLog(@"This version of NSUndoManager does not\n"
|
||||||
@"support coalescing undo operations. "
|
@"support coalescing undo operations. "
|
||||||
@"Upgrade gnustep-base to r29163 or newer to\n"
|
@"Upgrade gnustep-base to r29163 or newer to\n"
|
||||||
@"get rid of this one-time warning.");
|
@"get rid of this one-time warning.");
|
||||||
}
|
}
|
||||||
didCheck = YES;
|
didCheck = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
undo = [self undoManager];
|
undo = [self undoManager];
|
||||||
|
|
||||||
/* Coalesce consecutive typing events into a single undo action using
|
/* Coalesce consecutive typing events into a single undo action using
|
||||||
currently private undo manager functionality. An event is considered
|
currently private undo manager functionality. An event is considered
|
||||||
a typing event if it is a keyboard event and the event's characters
|
a typing event if it is a keyboard event and the event's characters
|
||||||
match our replacement string.
|
match our replacement string.
|
||||||
Note: Typing events are coalesced only when the previous action was
|
Note: Typing events are coalesced only when the previous action was
|
||||||
a typing event too and the current character follows the previous one
|
a typing event too and the current character follows the previous one
|
||||||
immediately. We never coalesce actions when the current selection is
|
immediately. We never coalesce actions when the current selection is
|
||||||
not empty. */
|
not empty. */
|
||||||
event = [NSApp currentEvent];
|
event = [NSApp currentEvent];
|
||||||
isTyping = [event type] == NSKeyDown
|
isTyping = (([event type] == NSKeyDown) &&
|
||||||
&& [[event characters] isEqualToString: replacementString];
|
([[event characters] isEqualToString: replacementString]));
|
||||||
if (undoManagerCanCoalesce && _undoObject)
|
if (undoManagerCanCoalesce && _undoObject)
|
||||||
{
|
{
|
||||||
undoRange = [_undoObject range];
|
if ([undo _canCoalesceUndoWithTarget: _textStorage
|
||||||
if (isTyping &&
|
selector: @selector(_undoTextChange:)
|
||||||
NSMaxRange(undoRange) == affectedCharRange.location &&
|
object: _undoObject])
|
||||||
affectedCharRange.length == 0 &&
|
{
|
||||||
[undo _canCoalesceUndoWithTarget: _textStorage
|
undoRange = [_undoObject range];
|
||||||
selector: @selector(_undoTextChange:)
|
if (isTyping &&
|
||||||
object: _undoObject])
|
NSMaxRange(undoRange) == affectedCharRange.location &&
|
||||||
{
|
affectedCharRange.length == 0)
|
||||||
undoRange.length += [replacementString length];
|
{
|
||||||
[_undoObject setRange: undoRange];
|
undoRange.length += [replacementString length];
|
||||||
return result;
|
[_undoObject setRange: undoRange];
|
||||||
}
|
return result;
|
||||||
DESTROY(_undoObject);
|
}
|
||||||
|
else if (_tf.isAutoCompleting == 2)
|
||||||
|
{
|
||||||
|
[_undoObject setRange: affectedCharRange];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
DESTROY(_undoObject);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The length of the undoRange is the length of the replacement, if any.
|
// The length of the undoRange is the length of the replacement, if any.
|
||||||
|
@ -2755,15 +2762,17 @@ TextDidEndEditing notification _without_ asking the delegate
|
||||||
undoString = [self attributedSubstringFromRange: affectedCharRange];
|
undoString = [self attributedSubstringFromRange: affectedCharRange];
|
||||||
|
|
||||||
undoObject =
|
undoObject =
|
||||||
[[NSTextViewUndoObject alloc] initWithRange: undoRange
|
[[NSTextViewUndoObject alloc] initWithRange: undoRange
|
||||||
attributedString: undoString];
|
attributedString: undoString];
|
||||||
[undo registerUndoWithTarget: _textStorage
|
[undo registerUndoWithTarget: _textStorage
|
||||||
selector: @selector(_undoTextChange:)
|
selector: @selector(_undoTextChange:)
|
||||||
object: undoObject];
|
object: undoObject];
|
||||||
if (isTyping)
|
if (isTyping || _tf.isAutoCompleting)
|
||||||
_undoObject = undoObject;
|
_undoObject = undoObject;
|
||||||
else
|
else
|
||||||
RELEASE(undoObject);
|
RELEASE(undoObject);
|
||||||
|
if (_tf.isAutoCompleting == 1)
|
||||||
|
_tf.isAutoCompleting = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -6022,7 +6031,9 @@ configuation! */
|
||||||
range.location != NSNotFound && range.length != 0)
|
range.location != NSNotFound && range.length != 0)
|
||||||
{
|
{
|
||||||
GSAutocompleteWindow *window = [GSAutocompleteWindow defaultWindow];
|
GSAutocompleteWindow *window = [GSAutocompleteWindow defaultWindow];
|
||||||
|
_tf.isAutoCompleting = 1;
|
||||||
[window displayForTextView: self];
|
[window displayForTextView: self];
|
||||||
|
_tf.isAutoCompleting = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue