diff --git a/ChangeLog b/ChangeLog index 3aab9db17..cade4a6d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +1999-07-24 Michael Hanni + + * Headers/NSTextView.h: redid ivars. + * Source/NSTextView.m: complete rewrite. more methods written. + * Source/GSServicesManager.m: minor temp debug NSlog. + * Source/NSMenuView.m: debug logs. + * Source/NSText.m: debug logs. + + Look at core/Testing/gstextnetwork.app. That is the text + application for NSTextView/TextNetwork. Edit.app has been + modified to use NSText directly and not NSTextView. + 1999-07-23 Adam Fedor * Model/GMAppKit.m: Added ifndef's to comment out areas of code diff --git a/Headers/gnustep/gui/NSTextView.h b/Headers/gnustep/gui/NSTextView.h index 6e16c8aef..95f0f0270 100644 --- a/Headers/gnustep/gui/NSTextView.h +++ b/Headers/gnustep/gui/NSTextView.h @@ -2,7 +2,8 @@ * GNUTextView.h */ -// GNUTextView is a NSText subclass that displays the glyphs laid out in one NSTextContainer. +#ifndef _GNUstep_H_NSTextView +#define _GNUstep_H_NSTextView #import #import @@ -18,15 +19,32 @@ @interface NSTextView : NSText { - NSTextContainer *textContainer; - NSColor *insertionPointColor; - BOOL smartInsertDeleteEnabled; - NSSelectionAffinity selectionAffinity; - NSSelectionGranularity selectionGranularity; - NSSize textContainerInset; - NSPoint textContainerOrigin; - NSLayoutManager *layoutManager; - NSTextStorage *textStorage; + NSTextContainer *textContainer; + NSLayoutManager *layoutManager; + NSTextStorage *textStorage; + NSSize textContainerInset; + NSPoint textContainerOrigin; + BOOL tv_resetTextContainerOrigin; + NSColor *tv_backGroundColor; + BOOL tv_drawsBackground; + BOOL tv_shouldDrawInsertionPoint; + BOOL tv_selectable; + BOOL tv_editable; + BOOL tv_fieldEditor; + BOOL tv_acceptDraggedFiles; + BOOL tv_richText; + BOOL tv_usesFontPanel; + BOOL tv_usesRuler; + BOOL tv_rulerVisible; + BOOL tv_smartInsertDelete; + NSRange tv_selectedRange; + NSColor *tv_caretColor; + NSDictionary *tv_selectedTextAttributes; + NSDictionary *tv_markedTextAttributes; + NSDictionary *tv_typingAttributes; + int tv_spellTag; + NSSelectionAffinity tv_selectionAffinity; + NSSelectionGranularity tv_selectionGranularity; } /**************************** Initializing ****************************/ @@ -201,8 +219,10 @@ - (BOOL)smartInsertDeleteEnabled; - (void)setSmartInsertDeleteEnabled:(BOOL)flag; - (NSRange)smartDeleteRangeForProposedRange:(NSRange)proposedCharRange; -- (void)smartInsertForString:(NSString *)pasteString replacingRange:(NSRange)charRangeToReplace beforeString:(NSString **)beforeString afterString:(NSString **)afterString; - +- (void)smartInsertForString:(NSString *)aString + replacingRange:(NSRange)charRange + beforeString:(NSString *)beforeString + afterString:(NSString *)afterString; @end // Note that all delegation messages come from the first textView @@ -235,3 +255,4 @@ extern NSString *NSTextViewWillChangeNotifyingTextViewNotification; extern NSString *NSTextViewDidChangeSelectionNotification; // NSOldSelectedCharacterRange -> NSValue with old range. +#endif diff --git a/Source/GSServicesManager.m b/Source/GSServicesManager.m index 6dcfe7df3..7ff3ae350 100644 --- a/Source/GSServicesManager.m +++ b/Source/GSServicesManager.m @@ -403,6 +403,8 @@ static NSString *disabledName = @".GNUstepDisabled"; NSWindow *resp = [[application keyWindow] firstResponder]; id obj = nil; + NSLog(@"doService: called"); + for (i = 0; i <= es; i++) { NSString *sendType; diff --git a/Source/NSMenuView.m b/Source/NSMenuView.m index 28c61cf34..73925d301 100644 --- a/Source/NSMenuView.m +++ b/Source/NSMenuView.m @@ -663,14 +663,12 @@ cell do the following */ [self setHighlightedItemIndex: -1]; -// if ([selectedCell action] && ![selectedCell target]) if (menuv_menu) [menuv_menu performActionForItem: [menuv_items_link objectAtIndex: lastIndex]]; if (menuv_popb) [menuv_popb performSelector:[selectedCell action] withObject:selectedCell]; -// else if ([selectedCell action] && [selectedCell target]) /* If we are a menu */ diff --git a/Source/NSText.m b/Source/NSText.m index 12b20d88b..a6d90c662 100644 --- a/Source/NSText.m +++ b/Source/NSText.m @@ -1190,13 +1190,16 @@ currentCursorY=[self rectForCharacterIndex:NSMaxRange([self selectedRange])].ori // Handling Events // -(void) mouseDown:(NSEvent *)theEvent -{ NSSelectionGranularity granularity= NSSelectByCharacter; +{ + NSSelectionGranularity granularity= NSSelectByCharacter; NSRange chosenRange,prevChosenRange,proposedRange; NSPoint point,startPoint; NSEvent *currentEvent; unsigned startIndex; BOOL didDragging=NO; + NSLog(@"mouseDown:"); + if (!is_selectable) return; // If not selectable then don't recognize the mouse down [[self window] makeFirstResponder:self]; @@ -2058,6 +2061,8 @@ NSLog(@"opti hook 2"); redrawLineRange=[self lineRangeForRect:rect]; + NSLog(@"should be drawing text here. No big deal.\n"); + if([self drawsBackground]) // clear area under text { [[self backgroundColor] set]; NSRectFill(rect); } diff --git a/Source/NSTextView.m b/Source/NSTextView.m index f3c955dbe..0436bc94a 100644 --- a/Source/NSTextView.m +++ b/Source/NSTextView.m @@ -1,9 +1,16 @@ -/* - * NSTextView.h - */ - -// classes needed are: NSRulerView NSTextContainer NSLayoutManager - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -15,40 +22,41 @@ @implementation NSTextView -/**************************** Initializing ****************************/ +/* Class methods */ -+(void) initialize -{ [super initialize]; - - if([self class] == [NSTextView class]) [self registerForServices]; -} - - -//Registers send and return types for the Services facility. This method is invoked automatically; you should never need to invoke it directly. -+(void) registerForServices ++ (void)initialize { -// do we yet have services in gnustep? + [super initialize]; + + if([self class] == [NSTextView class]) + { + [self setVersion:1]; + [self registerForServices]; + } } - -// container may be nil -- initWithFrame:(NSRect)frameRect textContainer:(NSTextContainer *)container -{ if(container) [self setTextContainer: container]; - else // set up a new container - { - } - self=[super initWithFrame:frameRect]; - return self; ++ (void)registerForServices +{ + // Talk to Richard about how to do this properly. } -// This variant will create the text network (textStorage, layoutManager, and a container). -- initWithFrame:(NSRect)frameRect +/* Initializing Methods */ + +- (id)initWithFrame:(NSRect)frameRect + textContainer:(NSTextContainer *)aTextContainer +{ + self = [super initWithFrame:frameRect]; + + [self setTextContainer:aTextContainer]; + [self setEditable:YES]; + + return self; +} + +- (id)initWithFrame:(NSRect)frameRect { textStorage = [[NSTextStorage alloc] init]; - if (![textStorage delegate]) - NSLog(@"No delegate set."); - layoutManager = [[NSLayoutManager alloc] init]; [textStorage addLayoutManager:layoutManager]; [layoutManager release]; @@ -60,284 +68,827 @@ return [self initWithFrame:frameRect textContainer:textContainer]; } -/***************** Get/Set the container and other stuff *****************/ - --(NSTextContainer*) textContainer -{ return textContainer; -} - -// The set method should not be called directly, but you might want to override it. Gets or sets the text container for this view. Setting the text container marks the view as needing display. The text container calls the set method from its setTextView: method. - --(void) setTextContainer:(NSTextContainer *)container -{ if(textContainer) [textContainer autorelease]; - textContainer=[container retain]; -} - -// This method should be used instead of the primitive -setTextContainer: if you need to replace a view's text container with a new one leaving the rest of the web intact. This method deals with all the work of making sure the view doesn't get deallocated and removing the old container from the layoutManager and replacing it with the new one. - --(void) replaceTextContainer:(NSTextContainer *)newContainer -{ [self setTextContainer:newContainer]; - // now do something to retain the web -} - -// The textContianerInset determines the padding that the view provides around the container. The container's origin will be inset by this amount from the bounds point {0,0} and padding will be left to the right and below the container of the same amount. This inset affects the view sizing in response to new layout and is used by the rectangular text containers when they track the view's frame dimensions. - --(void)setTextContainerInset:(NSSize)inset +- (void)setTextContainer:(NSTextContainer *)aTextContainer { + ASSIGN(textContainer, aTextContainer); } --(NSSize) textContainerInset {return textContainerInset;} - --(NSPoint) textContainerOrigin {return textContainerOrigin;} - -// The container's origin in the view is determined from the current usage of the container, the container inset, and the view size. textContainerOrigin returns this point. invalidateTextContainerOrigin is sent automatically whenever something changes that causes the origin to possibly move. You usually do not need to call invalidate yourself. --(void)invalidateTextContainerOrigin +- (NSTextContainer *)textContainer { + return textContainer; } --(NSLayoutManager*) layoutManager {return layoutManager;} --(NSTextStorage*) textStorage {return textStorage;} - -/************************* Key binding entry-point *************************/ - -// This method is the funnel point for text insertion after keys pass through the key binder. -#ifdef DEBUGG --(void) insertText:(NSString*) insertString +- (void)replaceTextContainer:(NSTextContainer *)aTextContainer { + // Notify layoutManager of change? + + ASSIGN(textContainer, aTextContainer); } -#endif -/*************************** Sizing methods ***************************/ +- (void)setTextContainerInset:(NSSize)inset +{ + textContainerInset = inset; +} + +- (NSSize)textContainerInset +{ + return textContainerInset; +} + +- (NSPoint)textContainerOrigin +{ + // use bounds, inset, and used rect. + NSRect bRect = [self bounds]; + + return NSZeroPoint; +} + +- (void)invalidateTextContainerOrigin +{ + tv_resetTextContainerOrigin = YES; +} + +- (NSLayoutManager *)layoutManager +{ + return [textContainer layoutManager]; +} + +- (NSTextStorage *)textStorage +{ + return textStorage; +} + +- (void)setBackgroundColor:(NSColor *)aColor +{ + ASSIGN(tv_backGroundColor, aColor); +} + +- (NSColor *)backgroundColor +{ + return tv_backGroundColor; +} + +- (void)setDrawsBackground:(BOOL)flag +{ + tv_drawsBackground = flag; +} + +- (BOOL)drawsBackground +{ + return tv_drawsBackground; +} + +- (void)setNeedsDisplayInRect:(NSRect)aRect + avoidAdditionalLayout:(BOOL)flag +{ + // FIXME. +} + +/* We override NSView's setNeedsDisplayInRect: */ + +/* +- (void)setNeedsDisplayInRect:(NSRect)aRect +{ + [self setNeedsDisplayInRect:aRect avoidAdditionalLayout:NO]; +} +*/ + +- (BOOL)shouldDrawInsertionPoint +{ + return tv_shouldDrawInsertionPoint; +} + +- (void)drawInsertionPointInRect:(NSRect)aRect + color:(NSColor *)aColor + turnedOn:(BOOL)flag +{ + [self lockFocus]; + + NSLog(@"drawInsertionPointInRect: (%f, %f)", aRect.size.width, +aRect.size.height); + + aRect.size.width = 1; + + if (flag) + { + [aColor set]; + NSRectFill(aRect); + } + else + { + [[self backgroundColor] set]; + NSRectFill(aRect); + } + + [self unlockFocus]; + [[self window] flushWindow]; +} -// Sets the frame size of the view to desiredSize constrained within min and max size. - (void)setConstrainedFrameSize:(NSSize)desiredSize { + // some black magic here. + [self setFrameSize:desiredSize]; } -/***************** New miscellaneous API above and beyond NSText *****************/ +- (void)cleanUpAfterDragOperation +{ + // release drag information +} -- (void)setAlignment:(NSTextAlignment)alignment range:(NSRange)range +- (void)setEditable:(BOOL)flag +{ + if (flag) + tv_selectable = flag; + + tv_editable = flag; +} + +- (BOOL)isEditable +{ + return tv_editable; +} + +- (void)setSelectable:(BOOL)flag +{ + tv_selectable = flag; +} + +- (BOOL)isSelectable +{ + return tv_selectable; +} + +- (void)setFieldEditor:(BOOL)flag +{ + tv_fieldEditor = flag; +} + +- (BOOL)isFieldEditor +{ + return tv_fieldEditor; +} + +- (void)setRichText:(BOOL)flag +{ + if (!flag) + tv_acceptDraggedFiles = flag; + + tv_richText = flag; +} + +- (BOOL)isRichText +{ + return tv_richText; +} + +- (void)setImportsGraphics:(BOOL)flag +{ + if (flag) + tv_richText = flag; + + tv_acceptDraggedFiles = flag; +} + +- (BOOL)importsGraphics +{ + return tv_acceptDraggedFiles; +} + +- (void)setUsesFontPanel:(BOOL)flag +{ + tv_usesFontPanel = flag; +} + +- (BOOL)usesFontPanel +{ + return tv_usesFontPanel; +} + +- (void)setUsesRuler:(BOOL)flag +{ + tv_usesRuler = flag; +} + +- (BOOL)usesRuler +{ + return tv_usesRuler; +} + +- (void)setRulerVisible:(BOOL)flag +{ + tv_rulerVisible = flag; +} + +- (BOOL)isRulerVisible +{ + return tv_rulerVisible; +} + +- (void)setSelectedRange:(NSRange)charRange +{ + NSLog(@"setSelectedRange"); +/* + [[NSNotificationCenter defaultCenter] + postNotificationName:NSTextViewDidChangeSelectionNotification + object:self]; +*/ + tv_selectedRange = charRange; + [self setSelectionGranularity:NSSelectByCharacter]; + + // Also removes the marking from + // marked text if the new selection is greater than the marked region. +} + +- (NSRange)selectedRange +{ + return tv_selectedRange; +} + +- (void)setSelectedRange:(NSRange)charRange + affinity:(NSSelectionAffinity)affinity + stillSelecting:(BOOL)flag +{ + NSLog(@"setSelectedRange stillSelecting."); + + tv_selectedRange = charRange; + [self setSelectionGranularity:NSSelectByCharacter]; + + // FIXME, more. +} + +- (NSSelectionAffinity)selectionAffinity +{ + return tv_selectionAffinity; +} + +- (void)setSelectionGranularity:(NSSelectionGranularity)granularity +{ + tv_selectionGranularity = granularity; +} + +- (NSSelectionGranularity)selectionGranularity +{ + return tv_selectionGranularity; +} + +- (void)setInsertionPointColor:(NSColor *)aColor +{ + ASSIGN(tv_caretColor, aColor); +} + +- (NSColor *)insertionPointColor +{ + return tv_caretColor; +} + +- (void)updateInsertionPointStateAndRestartTimer:(BOOL)flag +{ + // tv_caretLocation = + + // restart blinking timer. +} + +- (void)setSelectedTextAttributes:(NSDictionary *)attributes +{ + ASSIGN(tv_selectedTextAttributes, attributes); +} + +- (NSDictionary *)selectedTextAttributes +{ + return tv_selectedTextAttributes; +} + +- (NSRange)markedRange +{ + // calculate + + return NSMakeRange(NSNotFound, 0); +} + +- (void)setMarkedTextAttributes:(NSDictionary *)attributes +{ + ASSIGN(tv_markedTextAttributes, attributes); +} + +- (NSDictionary *)markedTextAttributes +{ + return tv_markedTextAttributes; +} + +- (NSString *)preferredPasteboardTypeFromArray:(NSArray *)availableTypes + restrictedToTypesFromArray:(NSArray *)allowedTypes +{ + // No idea. +} + +- (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pboard +{ +/* +Reads the text view's preferred type of data from the pasteboard specified +by the pboard parameter. This method +invokes the preferredPasteboardTypeFromArray:restrictedToTypesFromArray: +method to determine the text view's +preferred type of data and then reads the data using the +readSelectionFromPasteboard:type: method. Returns YES if the +data was successfully read. +*/ + + return NO; +} + +- (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pboard + type:(NSString *)type +{ +/* +Reads data of the given type from pboard. The new data is placed at the +current insertion point, replacing the current selection if one exists. +Returns YES if the data was successfully read. + +You should override this method to read pasteboard types other than the +default types. Use the rangeForUserTextChange method to obtain the range +of characters (if any) to be replaced by the new data. +*/ + + return NO; +} + +- (NSArray *)readablePasteboardTypes +{ + // get default types, what are they? +} + +- (NSArray *)writablePasteboardTypes +{ + // the selected text can be written to the pasteboard with which types. +} + +- (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard + type:(NSString *)type +{ +/* +Writes the current selection to pboard using the given type. Returns YES +if the data was successfully written. You can override this method to add +support for writing new types of data to the pasteboard. You should invoke +super's implementation of the method to handle any types of data your +overridden version does not. +*/ + + return NO; +} + +- (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard + types:(NSArray *)types +{ + +/* Writes the current selection to pboard under each type in the types +array. Returns YES if the data for any single type was written +successfully. + +You should not need to override this method. You might need to invoke this +method if you are implementing a new type of pasteboard to handle services +other than copy/paste or dragging. */ + + return NO; +} + +- (void)alignJustified:(id)sender +{ +/* + if (!tv_richText) + // if plain all text is jsutified. + else + // selected range is fully justified. +*/ +} + +- (void)changeColor:(id)sender +{ +// NSColor *aColor = [sender color]; + + // sets the color for the selected range. +} + +- (void)setAlignment:(NSTextAlignment)alignment + range:(NSRange)aRange +{ +/* +Sets the alignment of the paragraphs containing characters in aRange to +alignment. alignment is one of: + + NSLeftTextAlignment + NSRightTextAlignment + NSCenterTextAlignment + NSJustifiedTextAlignment + NSNaturalTextAlignment +*/ +} + +- (void)setTypingAttributes:(NSDictionary *)attributes +{ + // more? + + ASSIGN(tv_typingAttributes, attributes); +} + +- (NSDictionary *)typingAttributes +{ + return tv_typingAttributes; +} + +- (void)useStandardKerning:(id)sender +{ + // rekern for selected range if rich text, else rekern entire document. +} + +- (void)lowerBaseline:(id)sender +{ +/* + if (tv_richText) + // lower baseline by one point for selected text + else + // lower baseline for entire document. +*/ +} + +- (void)raiseBaseline:(id)sender +{ +/* + if (tv_richText) + // raise baseline by one point for selected text + else + // raise baseline for entire document. +*/ +} + +- (void)turnOffKerning:(id)sender +{ +/* + if (tv_richText) + // turn off kerning in selection. + else + // turn off kerning document wide. +*/ +} + +- (void)loosenKerning:(id)sender +{ +/* + if (tv_richText) + // loosen kerning in selection. + else + // loosen kerning document wide. +*/ +} + +- (void)tightenKerning:(id)sender +{ +/* + if (tv_richText) + // tighten kerning in selection. + else + // tighten kerning document wide. +*/ +} + +- (void)useStandardLigatures:(id)sender +{ + // well. +} + +- (void)turnOffLigatures:(id)sender +{ + // sure. +} + +- (void)useAllLigatures:(id)sender +{ + // as you say. +} + +- (void)clickedOnLink:(id)link + atIndex:(unsigned int)charIndex +{ + +/* Notifies the delegate that the user clicked in a link at the specified +charIndex. The delegate may take any appropriate actions to handle the +click in its textView:clickedOnLink:atIndex: method.Notifies the delegate +that the user clicked in a link at the specified charIndex. The delegate +may take any appropriate actions to handle the click in its +textView:clickedOnLink:atIndex: method. */ + +} + +/* +The text is inserted at the insertion point if there is one, otherwise +replacing the selection. +*/ + +- (void)pasteAsPlainText:(id)sender +{ + [self insertText:[sender string]]; +} + +- (void)pasteAsRichText:(id)sender +{ + [self insertText:[sender string]]; +} + +- (void)updateFontPanel +{ + // [fontPanel setFont:[self fontFromRange]]; +} + +- (void)updateRuler +{ + // ruler! +} + +- (NSArray *)acceptableDragTypes { } --(void) pasteAsPlainText:sender -{ -} --(void) pasteAsRichText:sender -{ -} - -/*************************** New Font menu commands ***************************/ - --(void) turnOffKerning:(id)sender -{ -} --(void) tightenKerning:(id)sender -{ -} --(void) loosenKerning:(id)sender -{ -} --(void) useStandardKerning:(id)sender -{ -} --(void) turnOffLigatures:(id)sender -{ -} --(void) useStandardLigatures:(id)sender -{ -} --(void) useAllLigatures:(id)sender -{ -} --(void) raiseBaseline:(id)sender -{ -} --(void) lowerBaseline:(id)sender -{} - -/*************************** Ruler support ***************************/ - --(void) rulerView:(NSRulerView *)ruler didMoveMarker:(NSRulerMarker *)marker -{ -} --(void) rulerView:(NSRulerView *)ruler didRemoveMarker:(NSRulerMarker *)marker -{ -} --(void) rulerView:(NSRulerView *)ruler didAddMarker:(NSRulerMarker *)marker -{ -} --(BOOL) rulerView:(NSRulerView *)ruler shouldMoveMarker:(NSRulerMarker *)marker -{ -} --(BOOL) rulerView:(NSRulerView *)ruler shouldAddMarker:(NSRulerMarker *)marker -{ -} --(float) rulerView:(NSRulerView *)ruler willMoveMarker:(NSRulerMarker *)marker toLocation:(float)location -{ -} --(BOOL) rulerView:(NSRulerView *)ruler shouldRemoveMarker:(NSRulerMarker *)marker -{ -} --(float) rulerView:(NSRulerView *)ruler willAddMarker:(NSRulerMarker *)marker atLocation:(float)location -{ -} --(void) rulerView:(NSRulerView *)ruler handleMouseDown:(NSEvent *)event -{ -} -/*************************** Fine display control ***************************/ - --(void) setNeedsDisplayInRect:(NSRect)rect avoidAdditionalLayout:(BOOL)fla -{ -} -#ifdef DEBUGG --(BOOL)shouldDrawInsertionPoint -{ -} --(void) drawInsertionPointInRect:(NSRect)rect color:(NSColor *)color turnedOn:(BOOL)flag -{ -} -#endif -/*************************** Especially for subclassers ***************************/ - --(void) updateRuler -{ -} --(void) updateFontPanel -{ -} - --(NSArray*)acceptableDragTypes -{ NSMutableArray *ret=[NSMutableArray arrayWithObject:NSStringPboardType]; - - if([self isRichText]) [ret addObject:NSRTFPboardType]; - if([self importsGraphics]) [ret addObject:NSRTFDPboardType]; - return ret; -} -#ifdef DEBUGG - (void)updateDragTypeRegistration { } -- (NSRange)selectionRangeForProposedRange:(NSRange)proposedCharRange granularity:(NSSelectionGranularity)granularity -{} -#endif -@end - -@implementation NSTextView (NSSharing) - -// The methods in this category deal with settings that need to be shared by all the NSTextViews of a single NSLayoutManager. Many of these methods are overrides of NSText or NSResponder methods. - -/*************************** Selected/Marked range ***************************/ - --(void) setSelectedRange:(NSRange)charRange affinity:(NSSelectionAffinity)affinity stillSelecting:(BOOL)stillSelectingFlag +- (NSRange)selectionRangeForProposedRange:(NSRange)proposedSelRange + granularity:(NSSelectionGranularity)granularity { -} --(NSSelectionAffinity) selectionAffinity {return selectionAffinity;} --(NSSelectionGranularity) selectionGranularity {return selectionGranularity;} --(void) setSelectionGranularity:(NSSelectionGranularity)granularity -{ selectionGranularity= granularity; + NSRange retRange; + + switch (granularity) + { + case NSSelectByParagraph: + // we need to: 1, find how far to end of paragraph; 2, increase + // range. + case NSSelectByWord: + // we need to: 1, find how far to end of word; 2, increase range. + case NSSelectByCharacter: + default: + retRange = proposedSelRange; + } + + return retRange; } --(void) setSelectedTextAttributes:(NSDictionary *)attributeDictionary -{ -} --(NSDictionary*) selectedTextAttributes +- (NSRange)rangeForUserCharacterAttributeChange { + if (!tv_editable || !tv_usesFontPanel) + return NSMakeRange(NSNotFound, 0); + + if (tv_richText) + return tv_selectedRange; + else + return NSMakeRange(NSNotFound, 0); // should be entire contents. } --(void) setInsertionPointColor:(NSColor *)color -{ if(insertionPointColor) [insertionPointColor autorelease]; - insertionPointColor=[color retain]; -} -- (NSColor *)insertionPointColor {return insertionPointColor;} - --(void) updateInsertionPointStateAndRestartTimer:(BOOL)restartFlag +- (NSRange)rangeForUserParagraphAttributeChange { + if (!tv_editable) + return NSMakeRange(NSNotFound, 0); + + if (tv_richText) + return [self selectionRangeForProposedRange:tv_selectedRange + granularity:NSSelectByParagraph]; + else + return NSMakeRange(NSNotFound, 0); // should be entire contents. } --(NSRange)markedRange +- (NSRange)rangeForUserTextChange { + if (!tv_editable || !tv_usesRuler) + return NSMakeRange(NSNotFound, 0); + + return tv_selectedRange; } --(void) setMarkedTextAttributes:(NSDictionary*)attributeDictionary -{ -} --(NSDictionary*) markedTextAttributes +- (BOOL)shouldChangeTextInRange:(NSRange)affectedCharRange + replacementString:(NSString *)replacementString { +/* +This method checks with the delegate as needed using +textShouldBeginEditing: and +textView:shouldChangeTextInRange:replacementString:, returning YES to +allow the change, and NO to prohibit it. + +This method must be invoked at the start of any sequence of user-initiated +editing changes. If your subclass of NSTextView implements new methods +that modify the text, make sure to invoke this method to determine whether +the change should be made. If the change is allowed, complete the change +by invoking the didChangeText method. See Notifying About Changes to the +Text in the class description for more information. If you can't determine +the affected range or replacement string before beginning changes, pass +(NSNotFound, 0) and nil for these values. */ + + return NO; } -/*************************** Other GNUTextView methods ***************************/ - --(void) setRulerVisible:(BOOL)flag -{ -} --(BOOL) usesRuler +- (void)didChangeText { + [[NSNotificationCenter defaultCenter] + postNotificationName:NSTextDidChangeNotification object:self]; } --(void) setUsesRuler:(BOOL)flag +- (void)setSmartInsertDeleteEnabled:(BOOL)flag { + tv_smartInsertDelete = flag; } --(int) spellCheckerDocumentTag +- (BOOL)smartInsertDeleteEnabled { + return tv_smartInsertDelete; } --(NSDictionary*) typingAttributes -{ -} --(void) setTypingAttributes:(NSDictionary *)attrs +- (NSRange)smartDeleteRangeForProposedRange:(NSRange)proposedCharRange { +// FIXME. + return proposedCharRange; } -//Initiates a series of delegate messages (and general notifications) to determine whether modifications can be made to the receiver's text. If characters in the text string are being changed, replacementString contains the characters that will replace the characters in affectedCharRange. If only text attributes are being changed, replacementString is nil. This method checks with the delegate as needed using textShouldBeginEditing: and textView:shouldChangeTextInRange:replacementString:, returning YES to allow the change, and NO to prohibit it. +- (void)smartInsertForString:(NSString *)aString + replacingRange:(NSRange)charRange + beforeString:(NSString *)beforeString + afterString:(NSString *)afterString +{ -//This method must be invoked at the start of any sequence of user-initiated editing changes. If your subclass of NSTextView implements new methods that modify the text, make sure to invoke this method to determine whether the change should be made. If the change is allowed, complete the change by invoking the didChangeText method. See ªNotifying About Changes to the Textº in the class description for more information. If you can't determine the affected range or replacement string before beginning changes, pass (NSNotFound, 0) and nil for these values. +/* Determines whether whitespace needs to be added around aString to +preserve proper spacing and punctuation when it's inserted into the +receiver's text over charRange. Returns by reference in beforeString and +afterString any whitespace that should be added, unless either or both is +nil. Both are returned as nil if aString is nil or if smart insertion and +deletion is disabled. --(BOOL) shouldChangeTextInRange:(NSRange)affectedCharRange replacementString:(NSString *)replacementString -{ -} --(void)didChangeText -{} +As part of its implementation, this method calls +smartInsertAfterStringForString:replacingRange: and +smartInsertBeforeStringForString:replacingRange:.To change this method's +behavior, override those two methods instead of this one. + +NSTextView uses this method as necessary. You can also use it in +implementing your own methods that insert text. To do so, invoke this +method with the proper arguments, then insert beforeString, aString, and +afterString in order over charRange. */ --(NSRange)rangeForUserTextChange -{ -} --(NSRange) rangeForUserCharacterAttributeChange -{ -} --(NSRange) rangeForUserParagraphAttributeChange -{ } +- (BOOL)resignFirstResponder +{ +/* + if (nextRsponder == NSTextView_in_NSLayoutManager) + return YES; + else + { + if (![self textShouldEndEditing]) + return NO; + else + { + [[NSNotificationCenter defaultCenter] + postNotificationName:NSTextDidEndEditingNotification object:self]; + // [self hideSelection]; + return YES; + } + } +*/ + return YES; +} -/*************************** NSResponder methods ***************************/ -#ifdef DEBUGG --(BOOL) resignFirstResponder -{ return YES; +- (BOOL)becomeFirstResponder +{ +/* + if (!nextRsponder == NSTextView_in_NSLayoutManager) + { + //draw selection + //update the insertion point + } +*/ + return YES; } --(BOOL) becomeFirstResponder -{ return YES; -} -#endif -/*************************** Smart copy/paste/delete support ***************************/ --(BOOL)smartInsertDeleteEnabled {return smartInsertDeleteEnabled;} --(void) setSmartInsertDeleteEnabled:(BOOL)flag +- (id)validRequestorForSendType:(NSString *)sendType + returnType:(NSString *)returnType { +/* +Returns self if sendType specifies a type of data the text view can put on +the pasteboard and returnType contains a type of data the text view can +read from the pasteboard; otherwise returns nil. +*/ + + return nil; } --(NSRange) smartDeleteRangeForProposedRange:(NSRange)proposedCharRange + +- (int)spellCheckerDocumentTag { +/* + if (!tv_spellTag) + tv_spellTag = [[NSSpellingServer sharedServer] uniqueSpellDocumentTag]; +*/ + return tv_spellTag; } --(void) smartInsertForString:(NSString *)pasteString replacingRange:(NSRange)charRangeToReplace beforeString:(NSString **)beforeString afterString:(NSString **)afterString + +- (void)rulerView:(NSRulerView *)aRulerView + didMoveMarker:(NSRulerMarker *)aMarker { +/* +NSTextView checks for permission to make the change in its +rulerView:shouldMoveMarker: method, which invokes +shouldChangeTextInRange:replacementString: to send out the proper request +and notifications, and only invokes this +method if permission is granted. + + [self didChangeText]; +*/ +} + +- (void)rulerView:(NSRulerView *)aRulerView + didRemoveMarker:(NSRulerMarker *)aMarker +{ +/* +NSTextView checks for permission to move or remove a tab stop in its +rulerView:shouldMoveMarker: method, which invokes +shouldChangeTextInRange:replacementString: to send out the proper request +and notifications, and only invokes this method if permission is granted. +*/ +} + +- (void)rulerView:(NSRulerView *)aRulerView + handleMouseDown:(NSEvent *)theEvent +{ +/* +This NSRulerView client method adds a left tab marker to the ruler, but a +subclass can override this method to provide other behavior, such as +creating guidelines. This method is invoked once with theEvent when the +user first clicks in the aRulerView's ruler area, as described in the +NSRulerView class specification. +*/ +} + +- (BOOL)rulerView:(NSRulerView *)aRulerView + shouldAddMarker:(NSRulerMarker *)aMarker +{ + +/* This NSRulerView client method controls whether a new tab stop can be +added. The receiver checks for permission to make the change by invoking +shouldChangeTextInRange:replacementString: and returning the return value +of that message. If the change is allowed, the receiver is then sent a +rulerView:didAddMarker: message. */ + + return NO; +} + +- (BOOL)rulerView:(NSRulerView *)aRulerView + shouldMoveMarker:(NSRulerMarker *)aMarker +{ + +/* This NSRulerView client method controls whether an existing tab stop +can be moved. The receiver checks for permission to make the change by +invoking shouldChangeTextInRange:replacementString: and returning the +return value of that message. If the change is allowed, the receiver is +then sent a rulerView:didAddMarker: message. */ + + return NO; +} + +- (BOOL)rulerView:(NSRulerView *)aRulerView + shouldRemoveMarker:(NSRulerMarker *)aMarker +{ + +/* This NSRulerView client method controls whether an existing tab stop +can be removed. Returns YES if aMarker represents an NSTextTab, NO +otherwise. Because this method can be invoked repeatedly as the user drags +a ruler marker, it returns that value immediately. If the change is allows +and the user actually removes the marker, the receiver is also sent a +rulerView:didRemoveMarker: message. */ + + return NO; +} + +- (float)rulerView:(NSRulerView *)aRulerView + willAddMarker:(NSRulerMarker *)aMarker + atLocation:(float)location +{ + +/* This NSRulerView client method ensures that the proposed location of +aMarker lies within the appropriate bounds for the receiver's text +container, returning the modified location. */ + + return 0.0; +} + +- (float)rulerView:(NSRulerView *)aRulerView + willMoveMarker:(NSRulerMarker *)aMarker + toLocation:(float)location +{ + +/* This NSRulerView client method ensures that the proposed location of +aMarker lies within the appropriate bounds for the receiver's text +container, returning the modified location. */ + + return 0.0; } - (void) setDelegate: (id) anObject { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - + [super setDelegate: anObject]; #define SET_DELEGATE_NOTIFICATION(notif_name) \ @@ -350,4 +901,37 @@ SET_DELEGATE_NOTIFICATION(DidChangeSelection); SET_DELEGATE_NOTIFICATION(WillChangeNotifyingTextView); } + +-(void) setString:(NSString *)string +{ + NSAttributedString *aString = [[[NSAttributedString alloc] + initWithString: string + attributes: [self typingAttributes]] autorelease]; + + [textStorage insertAttributedString:aString atIndex:0]; +} + +-(void) setText:(NSString *)string {[self setString:string];} + +- (void)insertText:(NSString *)aString +{ + if (![aString isKindOfClass:[NSAttributedString class]]) + aString = [[[NSAttributedString alloc] initWithString:aString + attributes:[self typingAttributes]] autorelease]; + + [textStorage replaceCharactersInRange:[self selectedRange] + withAttributedString:(NSAttributedString *)aString]; +} + +- (void)drawRect:(NSRect)aRect +{ + [textStorage drawRange:[self selectedRange] atPoint:aRect.origin.x]; +} + +/* +- (void)mouseDown:(NSEvent *)aEvent +{ + NSLog(@"mouseDown:"); +} +*/ @end