Added a basic implementation for undo in NSTextView.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@24232 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Fred Kiefer 2006-12-24 09:37:16 +00:00
parent 2eaf22ccb4
commit a24c80f048
5 changed files with 90 additions and 6 deletions

View file

@ -1,3 +1,15 @@
2006-12-21 Fred Kiefer <FredKiefer@gmx.de>
* Headers/AppKit/NSWindow.h
Added missing delegate methods.
* Source/NSResponder.m (-undoManager):
Forward method to next responder.
* Source/NSWindow.m (-undoManager):
Try to get an undo manager from delegate or document.
* Source/NSTextView.m
(-shouldChangeTextInRange:replacementString:): Added basic support
for undo.
2006-12-19 Fred Kiefer <FredKiefer@gmx.de>
* Headers/AppKit/NSObjectController.h

View file

@ -47,6 +47,7 @@
@class NSMutableArray;
@class NSNotification;
@class NSString;
@class NSUndoManager;
@class NSButtonCell;
@class NSColor;
@ -688,8 +689,15 @@ APPKIT_EXPORT NSSize NSTokenSize;
@interface NSObject (NSWindowDelegate)
- (BOOL) windowShouldClose: (id)sender;
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
- (NSRect) window: (NSWindow*)window
willPositionSheet: (NSWindow*)sheet
usingRect: (NSRect)rect;
- (void) windowDidChangeScreenProfile: (NSNotification*)aNotification;
- (void) windowDidEndSheet: (NSNotification*)aNotification;
- (BOOL) windowShouldZoom: (NSWindow*)sender
toFrame: (NSRect)aFrame;
- (void) windowWillBeginSheet: (NSNotification*)aNotification;
- (NSUndoManager*) windowWillReturnUndoManager: (NSWindow*)sender;
- (NSRect) windowWillUseStandardFrame: (NSWindow*)sender
defaultFrame: (NSRect)aFrame;
#endif

View file

@ -426,7 +426,10 @@
- (NSUndoManager*) undoManager
{
return nil;
if (_next_responder)
return [_next_responder undoManager];
else
return nil;
}
- (BOOL) shouldBeTreatedAsInkEvent: (NSEvent *)theEvent

View file

@ -56,6 +56,7 @@
#include <Foundation/NSRunLoop.h>
#include <Foundation/NSString.h>
#include <Foundation/NSTimer.h>
#include <Foundation/NSUndoManager.h>
#include <Foundation/NSValue.h>
#include "AppKit/NSApplication.h"
#include "AppKit/NSClipView.h"
@ -2336,10 +2337,11 @@ TextDidEndEditing notification _without_ asking the delegate
- (BOOL) shouldChangeTextInRange: (NSRange)affectedCharRange
replacementString: (NSString *)replacementString
{
BOOL result = YES;
if (_tf.is_editable == NO)
return NO;
/*
We need to send the textShouldBeginEditing: /
textDidBeginEditingNotification only once.
@ -2359,12 +2361,41 @@ TextDidEndEditing notification _without_ asking the delegate
if (_tf.delegate_responds_to_should_change)
{
return [_delegate textView: self
shouldChangeTextInRange: affectedCharRange
replacementString: replacementString];
result = [_delegate textView: self
shouldChangeTextInRange: affectedCharRange
replacementString: replacementString];
}
return YES;
if (result && [self allowsUndo])
{
NSUndoManager *undo;
NSRange undoRange;
NSAttributedString *undoString;
// FIXME: Not sure, if this rather belongs into a local implementation of
// the method undoManager.
if (![_delegate respondsToSelector: @selector(undoManagerForTextView:)]
|| ((undo = [_delegate undoManagerForTextView: self]) == nil))
{
undo = [self undoManager];
}
// The length of the undoRange is the length of the replacement, if any.
if (replacementString != nil)
{
undoRange = NSMakeRange(affectedCharRange.location,
[replacementString length]);
}
else
{
undoRange = affectedCharRange;
}
undoString = [self attributedSubstringFromRange: affectedCharRange];
[[undo prepareWithInvocationTarget: self] replaceCharactersInRange: undoRange
withAttributedString: undoString];
}
return result;
}
/*

View file

@ -2693,6 +2693,36 @@ resetCursorRectsForView(NSView *theView)
}
}
/**
Get a undo manager from the delegate or create one.
*/
- (NSUndoManager*) undoManager
{
NSUndoManager *undo;
if ([_delegate respondsToSelector: @selector(windowWillReturnUndoManager:)])
{
return [_delegate windowWillReturnUndoManager: self];
}
else
{
// FIXME: This is more a hack to get an undo manager.
if (_windowController)
{
NSDocument *document = [_windowController document];
if (document && (undo = [document undoManager]) != nil)
{
return undo;
}
}
// FIXME: We should reuse the same undo manager all the time!!!
//return AUTORELEASE([[NSUndoManager alloc] init]);
return nil;
}
}
/**
If YES, then the window is released when the close method is called.
*/