Implemented notifications to the delegate about changes in the selection

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@8412 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
nico 2000-12-22 19:08:29 +00:00
parent f3e5387500
commit d20f647768

View file

@ -222,6 +222,7 @@ static NSNotificationCenter *nc;
_tf.uses_font_panel = YES; _tf.uses_font_panel = YES;
_tf.uses_ruler = YES; _tf.uses_ruler = YES;
_tf.is_ruler_visible = NO; _tf.is_ruler_visible = NO;
_original_selected_range.location = NSNotFound;
ASSIGN (_caret_color, [NSColor blackColor]); ASSIGN (_caret_color, [NSColor blackColor]);
[self setTypingAttributes: [isa defaultTypingAttributes]]; [self setTypingAttributes: [isa defaultTypingAttributes]];
@ -1267,35 +1268,56 @@ static NSNotificationCenter *nc;
{ {
/* TODO: Use affinity to determine the insertion point */ /* TODO: Use affinity to determine the insertion point */
/* The `official' (the last one the delegate approved of) selected
range before this one. */
NSRange oldRange;
/* If the user was interactively changing the selection, the last
displayed selection could have been a temporary selection,
different from the last official one: */
NSRange oldDisplayedRange = _selected_range;
if (flag == YES) if (flag == YES)
{ {
_selected_range = range; /* Store the original range before the interactive selection
[self setSelectionGranularity: NSSelectByCharacter]; process begin. That's because we will need to ask the delegate
return; if it's all right for him to do the change, and then notify
him we did. In both cases, we need to post the original selection
together with the new one. */
if (_original_selected_range.location == NSNotFound)
{
_original_selected_range = _selected_range;
}
} }
else else
{ {
NSRange oldRange = _selected_range; /* Retrieve the original range */
NSRange overlap; if (_original_selected_range.location != NSNotFound)
{
oldRange = _original_selected_range;
_original_selected_range.location = NSNotFound;
}
else
{
oldRange = _selected_range;
}
/* Ask delegate to modify the range */
if (_tvf.delegate_responds_to_will_change_sel)
{
range = [_delegate textView: _notifObject
willChangeSelectionFromCharacterRange: oldRange
toCharacterRange: range];
}
}
// Nothing to do, if the range is still the same /* Set the new selected range */
if (NSEqualRanges(range, oldRange)) _selected_range = range;
return;
if (flag == NO)
//<!> ask delegate for selection validation {
_selected_range = range;
[self updateFontPanel]; [self updateFontPanel];
#if 0 /* Insertion Point */
[nc postNotificationName: NSTextViewDidChangeSelectionNotification
object: self
userInfo: [NSDictionary dictionaryWithObjectsAndKeys:
NSStringFromRange (_selected_range),
NSOldSelectedCharacterRange, nil]];
#endif
// display
if (range.length) if (range.length)
{ {
/* <!>disable caret timed entry */ /* <!>disable caret timed entry */
@ -1312,44 +1334,70 @@ static NSNotificationCenter *nc;
} }
/* <!>enable caret timed entry */ /* <!>enable caret timed entry */
} }
}
if (!_window)
return; if (_window != nil)
{
// Make the selected range visible NSRange overlap;
[self scrollRangeToVisible: range];
if (flag == NO)
// Redisplay what has changed {
// This does an unhighlight of the old selected region /* Make the selected range visible */
[self scrollRangeToVisible: range];
}
/* Try to optimize for overlapping ranges */
overlap = NSIntersectionRange (oldRange, range); overlap = NSIntersectionRange (oldRange, range);
if (overlap.length) if (overlap.length)
{ {
// Try to optimize for overlapping ranges if (range.location != oldDisplayedRange.location)
if (range.location != oldRange.location)
{ {
NSRange r; NSRange r;
r = MakeRangeFromAbs (MIN (range.location, oldRange.location), r = MakeRangeFromAbs (MIN (range.location,
MAX (range.location, oldRange.location)); oldDisplayedRange.location),
[self setNeedsDisplayInRect: [self rectForCharacterRange: r]]; MAX (range.location,
oldDisplayedRange.location));
[self setNeedsDisplayInRect: [self rectForCharacterRange: r]
avoidAdditionalLayout: YES];
} }
if (NSMaxRange (range) != NSMaxRange (oldRange)) if (NSMaxRange (range) != NSMaxRange (oldDisplayedRange))
{ {
NSRange r = MakeRangeFromAbs (MIN (NSMaxRange (range), NSRange r;
NSMaxRange (oldRange)),
MAX (NSMaxRange (range), r = MakeRangeFromAbs (MIN (NSMaxRange (range),
NSMaxRange (oldRange))); NSMaxRange (oldDisplayedRange)),
[self setNeedsDisplayInRect: [self rectForCharacterRange: r]]; MAX (NSMaxRange (range),
NSMaxRange (oldDisplayedRange)));
[self setNeedsDisplayInRect: [self rectForCharacterRange: r]
avoidAdditionalLayout: YES];
} }
} }
else else
{ {
[self setNeedsDisplayInRect: [self rectForCharacterRange: range]]; [self setNeedsDisplayInRect: [self rectForCharacterRange: range]
[self setNeedsDisplayInRect: [self rectForCharacterRange: oldRange]]; avoidAdditionalLayout: YES];
[self setNeedsDisplayInRect: [self rectForCharacterRange:
oldDisplayedRange]
avoidAdditionalLayout: YES];
} }
}
[self setSelectionGranularity: NSSelectByCharacter];
// Also removes the marking from [self setSelectionGranularity: NSSelectByCharacter];
// marked text if the new selection is greater than the marked region.
/* TODO: Remove the marking from marked text if the new selection is
greater than the marked region. */
if (flag == NO)
{
NSDictionary *userInfo;
userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
[NSValue valueWithBytes: &oldRange
objCType: @encode(NSRange)],
NSOldSelectedCharacterRange, nil];
[nc postNotificationName: NSTextViewDidChangeSelectionNotification
object: _notifObject userInfo: userInfo];
} }
} }
@ -1919,8 +1967,9 @@ afterString in order over charRange. */
chosenRange = [self selectionRangeForProposedRange: proposedRange chosenRange = [self selectionRangeForProposedRange: proposedRange
granularity: granularity]; granularity: granularity];
[self setSelectedRange: chosenRange affinity: affinity
stillSelecting: YES];
[self setSelectedRange: chosenRange];
/* Do an immediate redisplay for visual feedback */ /* Do an immediate redisplay for visual feedback */
[_window flushWindow]; /* FIXME: This doesn't work while it should ! */ [_window flushWindow]; /* FIXME: This doesn't work while it should ! */
@ -1940,8 +1989,8 @@ afterString in order over charRange. */
startIndex); startIndex);
chosenRange = [self selectionRangeForProposedRange: proposedRange chosenRange = [self selectionRangeForProposedRange: proposedRange
granularity: granularity]; granularity: granularity];
[self setSelectedRange: chosenRange affinity: affinity
[self setSelectedRange: chosenRange]; stillSelecting: YES];
if (didScroll) if (didScroll)
{ {
@ -1956,6 +2005,12 @@ afterString in order over charRange. */
NSDebugLog(@"chosenRange. location = %d, length = %d\n", NSDebugLog(@"chosenRange. location = %d, length = %d\n",
(int)chosenRange.location, (int)chosenRange.length); (int)chosenRange.location, (int)chosenRange.length);
[self setSelectedRange: chosenRange affinity: affinity
stillSelecting: NO];
/* Ahm - this shouldn't really be needed but... */
[_window flushWindow];
/* Remember granularity till a new selection destroys the memory */ /* Remember granularity till a new selection destroys the memory */
[self setSelectionGranularity: granularity]; [self setSelectionGranularity: granularity];
@ -2392,6 +2447,8 @@ container, returning the modified location. */
- (void) setDelegate: (id)anObject - (void) setDelegate: (id)anObject
{ {
SEL selector;
/* Code to allow sharing the delegate */ /* Code to allow sharing the delegate */
if (_tvf.multiple_textviews && (IS_SYNCHRONIZING_DELEGATES == NO)) if (_tvf.multiple_textviews && (IS_SYNCHRONIZING_DELEGATES == NO))
{ {
@ -2425,8 +2482,8 @@ container, returning the modified location. */
[super setDelegate: anObject]; [super setDelegate: anObject];
if ([_delegate respondsToSelector: selector = @selector(shouldChangeTextInRange:replacementString:);
@selector(shouldChangeTextInRange:replacementString:)]) if ([_delegate respondsToSelector: selector])
{ {
_tvf.delegate_responds_to_should_change = YES; _tvf.delegate_responds_to_should_change = YES;
} }
@ -2435,6 +2492,16 @@ container, returning the modified location. */
_tvf.delegate_responds_to_should_change = NO; _tvf.delegate_responds_to_should_change = NO;
} }
selector = @selector(textView:willChangeSelectionFromCharacterRange:toCharacterRange:);
if ([_delegate respondsToSelector: selector])
{
_tvf.delegate_responds_to_will_change_sel = YES;
}
else
{
_tvf.delegate_responds_to_will_change_sel = NO;
}
/* SET_DELEGATE_NOTIFICATION defined at the beginning of file */ /* SET_DELEGATE_NOTIFICATION defined at the beginning of file */
/* NSText notifications */ /* NSText notifications */