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:
Marcian Lytwyn 2013-09-09 01:54:02 +00:00
parent 2929f8aed8
commit a9e4f72f54
3 changed files with 99 additions and 83 deletions

View file

@ -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;

View file

@ -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 [_textView insertCompletion: word
forPartialWordRange: _range forPartialWordRange: _range
movement: movement movement: movement
isFinal: flag]; 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);

View file

@ -2723,24 +2723,31 @@ TextDidEndEditing notification _without_ asking the delegate
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)
{
if ([undo _canCoalesceUndoWithTarget: _textStorage
selector: @selector(_undoTextChange:)
object: _undoObject])
{ {
undoRange = [_undoObject range]; undoRange = [_undoObject range];
if (isTyping && if (isTyping &&
NSMaxRange(undoRange) == affectedCharRange.location && NSMaxRange(undoRange) == affectedCharRange.location &&
affectedCharRange.length == 0 && affectedCharRange.length == 0)
[undo _canCoalesceUndoWithTarget: _textStorage
selector: @selector(_undoTextChange:)
object: _undoObject])
{ {
undoRange.length += [replacementString length]; undoRange.length += [replacementString length];
[_undoObject setRange: undoRange]; [_undoObject setRange: undoRange];
return result; return result;
} }
else if (_tf.isAutoCompleting == 2)
{
[_undoObject setRange: affectedCharRange];
return result;
}
DESTROY(_undoObject); 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.
if (replacementString != nil) if (replacementString != nil)
@ -2760,10 +2767,12 @@ TextDidEndEditing notification _without_ asking the delegate
[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;
} }
} }