* Source/NSLayoutManager.m: Clear temporary attributes

on the modified range when informed of a change in the text
storage
* Source/NSTextView.m: Add a context menu with spelling
suggestions and cut/copy/paste


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@32561 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Eric Wasylishen 2011-03-14 04:19:32 +00:00
parent c598c7fb4d
commit 2d713e6cca
3 changed files with 118 additions and 0 deletions

View file

@ -1,3 +1,11 @@
2011-03-13 Eric Wasylishen <ewasylishen@gmail.com>
* Source/NSLayoutManager.m: Clear temporary attributes
on the modified range when informed of a change in the text
storage
* Source/NSTextView.m: Add a context menu with spelling
suggestions and cut/copy/paste
2011-03-13 Eric Wasylishen <ewasylishen@gmail.com>
* Source/NSSavePanel.m:

View file

@ -2294,12 +2294,28 @@ this file describes this.
if (_temporaryAttributes != nil && (mask & NSTextStorageEditedCharacters) != 0)
{
int i;
NSArray *attrs;
NSRange oldRange = NSMakeRange(range.location, range.length - lengthChange);
NSString *replacementString = [[GSDummyMutableString alloc] initWithLength: range.length];
[_temporaryAttributes replaceCharactersInRange: oldRange
withString: replacementString];
[replacementString release];
// In addition, clear any temporary attributes that may have been extended
// over the affected range
if (range.length > 0)
{
attrs = [[self temporaryAttributesAtCharacterIndex: range.location
effectiveRange: NULL] allKeys];
for (i=0; i<[attrs count]; i++)
{
[self removeTemporaryAttribute: [attrs objectAtIndex: i]
forCharacterRange: range];
}
}
}
[self invalidateGlyphsForCharacterRange: invalidatedRange

View file

@ -73,6 +73,7 @@
#import "AppKit/NSGraphics.h"
#import "AppKit/NSImage.h"
#import "AppKit/NSLayoutManager.h"
#import "AppKit/NSMenu.h"
#import "AppKit/NSMenuItem.h"
#import "AppKit/NSParagraphStyle.h"
#import "AppKit/NSPasteboard.h"
@ -576,6 +577,8 @@ static NSCharacterSet *smartRightChars;
text on the pasteboard. */
static NSString *NSSmartPastePboardType = @"NSSmartPastePboardType";
static NSMenu *textViewMenu;
/**** Misc. class methods ****/
+(void) initialize
@ -629,6 +632,17 @@ static NSDictionary *defaultTypingAttributes;
return defaultTypingAttributes;
}
+ (NSMenu *) defaultMenu
{
if (!textViewMenu)
{
textViewMenu = [[NSMenu alloc] initWithTitle: @""];
[textViewMenu insertItemWithTitle: _(@"Cut") action:@selector(cut:) keyEquivalent:@"x" atIndex:0];
[textViewMenu insertItemWithTitle: _(@"Copy") action:@selector(copy:) keyEquivalent:@"c" atIndex:1];
[textViewMenu insertItemWithTitle: _(@"Paste") action:@selector(paste:) keyEquivalent:@"v" atIndex:2];
}
return textViewMenu;
}
/**** Initialization ****/
@ -5487,6 +5501,86 @@ other than copy/paste or dragging. */
[self setSelectionGranularity: granularity];
}
static const NSInteger GSSpellingSuggestionMenuItemTag = 1;
- (void) _acceptGuess: (id)sender
{
NSString *guess = [(NSMenuItem*)sender title];
[[self textStorage] replaceCharactersInRange: [self selectedRange]
withString: guess];
}
- (void) rightMouseDown: (NSEvent *)theEvent
{
int i;
NSMenu *menu = [[self class] defaultMenu];
NSPoint point = [self convertPoint: [theEvent locationInWindow] fromView: nil];
NSUInteger index = [self _characterIndexForPoint: point
respectFraction: NO];
if (_tf.is_selectable == NO)
return;
if (!_layoutManager)
return;
for (i=[[menu itemArray] count]-1; i>=0; --i)
{
NSMenuItem *item = [menu itemAtIndex: i];
if ([item tag] == GSSpellingSuggestionMenuItemTag)
{
[menu removeItemAtIndex: i];
}
}
if (!(index >= [self selectedRange].location &&
index <= NSMaxRange([self selectedRange])))
{
NSRange wordRange = [self selectionRangeForProposedRange: NSMakeRange(index, 0)
granularity: NSSelectByWord];
[self setSelectedRange: wordRange
affinity: [self selectionAffinity]
stillSelecting: NO];
}
if (NSEqualRanges([self selectedRange],
[self selectionRangeForProposedRange: NSMakeRange([self selectedRange].location, 0)
granularity: NSSelectByWord]))
{
// Possibly show spelling suggestions
NSSpellChecker *sp = [NSSpellChecker sharedSpellChecker];
NSString *word = [[self string] substringWithRange: [self selectedRange]];
if ([sp checkSpellingOfString: word startingAt: 0].location != NSNotFound)
{
/*NSArray *guesses = [sp guessesForWordRange: wordRange
inString: [self string]
language: [sp language]
inSpellDocumentWithTag: [self spellCheckerDocumentTag]];*/
NSArray *guesses = [sp guessesForWord: word];
if ([guesses count] > 0)
{
for (i=0; i < [guesses count] && i < 5; i++)
{
NSString *guess = [guesses objectAtIndex: i];
[menu insertItemWithTitle: guess action:@selector(_acceptGuess:) keyEquivalent:@"" atIndex:i];
[[menu itemAtIndex: i] setTarget: self];
[[menu itemAtIndex: i] setTag: GSSpellingSuggestionMenuItemTag];
}
[menu insertItem: [NSMenuItem separatorItem] atIndex: i];
[[menu itemAtIndex: i] setTag: GSSpellingSuggestionMenuItemTag];
}
}
}
[NSMenu popUpContextMenu: menu
withEvent: theEvent
forView: self];
}
- (void) keyDown: (NSEvent *)theEvent
{
// If not editable, don't recognize the key down