Re: Advice on restricting/monitoring character input in NSTextView
Re: Advice on restricting/monitoring character input in NSTextView
- Subject: Re: Advice on restricting/monitoring character input in NSTextView
- From: Scott Lehman <email@hidden>
- Date: Tue, 7 Feb 2006 15:37:40 -0800 (PST)
Thanks. I'll give an NSTextView subclass a try next.
I was hoping to be able to have all the filtering in
just one function, but I think I see how to have it
all in the subclass at least, which is good enough.
Is it theoretically possible to completely override
NSTextView's
shouldChangeTextInRange(s):replacementString(s): to
catch both typing and pastes? I'm guessing there's
stuff in there I don't want to try duplicating - just
trying to confirm my understanding of where text is
flowing.
Thanks for the heads up about pasting and
lists/tables. That is something I hope to work with.
Scott
--- Keith Blount <email@hidden> wrote:
> Hmm, the more I think about, the more I think you're
> right - a subclass might be the best way after all.
> I
> have subclassed NSTextView quite extensively for my
> own app, and I do in fact modify text as it is
> pasted
> in by overriding the pasteboard methods. What you
> will
> need to do is override
> -readSelectionFromPasteboard:type: and handle all
> the
> types your app reads yourself. Read them from the
> pasteboard, modify the strings, then insert the
> modified text into the text view's text storage
> yourself. Once you've modified the (attributed)
> string, make sure you insert it along these lines:
>
> if ([self shouldChangeTextInRange:[self
> rangeForUserTextChange]
> replacementString:[modifiedAttributedStr string]])
> {
> [[self textStorage] replaceCharactersInRange:[self
> rangeForUserTextChange]
> withAttributedString:modifiedAttributedString];
> [self didChangeText];
> return YES;
> }
> else
> return NO;
>
> This will ensure that undo still works as usual and
> your user can undo/redo the paste - all your changes
> will be transparent (sorry if this is obvious
> already).
>
> (Be aware that overriding the pasteboard methods can
> result in slightly different behaviour than the
> default when pasting into tables and lists, because
> of
> some private stuff that NSTextView does - search the
> forums for a recent post by myself on this, in which
> Douglas Davidson, one of the Apple text gurus,
> explained the reasons why.)
>
> All the stuff discussed about restricting user input
> through typing would still apply, only instead of
> using the delegate method, you would override the
> text
> view's -shouldChangeTextInRanges:replacementStrings:
> method directly (making sure you return super's
> method
> if you allow the change).
>
> That way you should be able to handle both user
> input
> and pasting. The only tricky part left will be
> parsing
> through your string and modifying it within the
> pasteboard method, but like I say, using
> -rangeOfString:... should do for that, so it
> shouldn't
> be too hard.
>
> Hope that helps.
> Cheers,
> Keith
>
> P.S. If you are implementing smart quotes, let me
> know
> - I modified Andrew Stone's code and put it in my
> subclass, and made some improvements to it. I'd be
> more than happy to share that code with you to save
> you time.
>
> --- Scott Lehman <email@hidden> wrote:
>
> > It was the need to process strings longer than one
> > character from the pasteboard that led me to look
> > beyond the delegate methods - I want to modify
> > rather
> > than disallow input. I've been trying what you
> > outlined below (I am doing rich text), but am
> > failing
> > to get it to play nicely with undo. I can get the
> > appearance of proper functionality by querying the
> > state of the undo manager, but still raise out of
> > bounds exceptions.
> >
> > It looks like modifying the string that late in
> the
> > game poses issues when dealing with undo since the
> > original string is already registered. I bet it's
> > still possible, but at this point, I'm thinking
> > there
> > has to be a better solution.
> >
> > I want undo, so is there an easy way to modify
> text
> > input before the actions that are registered with
> > the
> > undo manager?
> >
> > That makes me think an NSTextView subclass might
> be
> > best, but I haven't pieced together precisely how
> > the
> > input flows thru it yet, or if there are new
> issues
> > when subclassing it.
> >
> > Thanks,
> >
> > Scott
> >
> > PS - Thanks for the tip on the Smart Quotes
> article.
> >
> > That is something I will deal with, and
> > indidentally,
> > his method for inserting processed strings goes
> > direct
> > to the text storage, bypassing undo .
> >
> > --- Keith Blount <email@hidden> wrote:
> >
> > > You shouldn't need to subclass for this - you
> were
> > > on
> > > the right track in the first place.
> > >
> > > The delegate method
> > >
> >
>
-textView:shouldChangeTextInRanges:replacementStrings:
> > > (or you can use the singular version for
> pre-Tiger
> > > or
> > > text views that don't allow multiple selection)
> > will
> > > get called before undo gets set up. So if you
> > > restrict
> > > input there, all that will happen is that
> whenever
> > > the
> > > user tries to type something restricted, you
> have
> > > this
> > > method return NO and nothing will happen when
> the
> > > user
> > > types (or you can provide an NSBeep() or a
> message
> > > or
> > > whatever you want within that method.
> > >
> > > This method will also get called whenever you
> try
> > to
> > > paste anything into your text view. This is
> > probably
> > > the sort of thing you want (note that I haven't
> > > tested
> > > this code so there may be errors in it - it was
> > just
> > > a
> > > quick effort and can definitely be improved):
> > >
> > > -- code snipped for message size --
> > >
> > > That should deal with preventing the user from
> > > typing
> > > consecutive spaces or tabs. Dealing with a paste
> > of
> > > multiple characters is more difficult. In that
> > case,
> > > you will need to parse through the string being
> > > pasted, looking for restricted characters.
> > > NSString's
> > > -rangeOfString:options:range: would probably be
> > best
> > > for this, although you could also look at
> > NSScanner.
> > > The trouble is, what to do if there is a
> > restricted
> > > character? You could return NO and disallow the
> > > paste
> > > entirely, which would be by far the simplest
> > > solution.
> > > Otherwise, things get tricky. If your text view
> is
> > > plain text only, it's not too difficult. You
> would
> > > just modify the new string and place it in the
> > text
> > > view yourself, still returning NO to the method.
> > > (This
> > > is because, unfortunately, the above method
> allows
> > > you
> > > to stop the new string getting entered, but it
> > > doesn't
>
=== message truncated ===
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden