开发者

Controlling what gets pasted into NSTableView

A user selects a song in my mp3 player. He proceeds to rename a song (thus highlighting the "name" column of that given song).

Let's say he pastes in "The\nGreat\nSong". By default, if the string formatter doesn't allow newlines (which is what I want), the app will produce a beep.

How can I process the string before it is pasted? This is what I want: If the string is less than 200 characters long, and if it contains newlines, replace the newlines with spaces before the string actually gets pasted. If it is longer than 200 characters, just do what it would do by default (because I don't want the user accidentally pasting his PhD thesis in there).

How can one do something like th开发者_开发技巧at?


If you want to validate the user input, then use some of the delegate methods. I never did this on my own, it's just what I know from the header and the documentation. But this might already help you:

Have a look at textShouldEndEditing: method of NSTableView. This method is being called when the user want to finish editing data, just as in your case. You can override this method to do your changes. However, from the documentation it read like you don't even need to override, just to implement a delegate method, control:textShouldEndEditing:, that is being called on that occasion.

I'd go for the latter. Implement control:textShouldEndEditing: and see how it's being called. The first argument should actually be the table view, the second an NSTextView used for editing. Using editedRow and editedColumn you can get the cell being edited for the table view. Make your validation and simply change the text of the field editor being passed.


Turns out it was probably easiest to just edit my NSFormatter subclass itself. Here is my NSFormatter method, in case anyone is interested:

- (BOOL)isPartialStringValid:(NSString *)partial
            newEditingString:(NSString **)newString
            errorDescription:(NSString **)errorString
{
  *errorString = nil;
  *newString = nil;

  if ([partial containsIllegal])
  {
    NSBeep();
    return NO;
  }
  else if ([partial containsNewline])
  {
    if ([partial length] > 200)
    {
      NSBeep();
      return NO;
    }
    else
    {
      *newString = [partial stringByReplacingOccurrencesOfString:@"\n" withString:@" "];
      return NO;
    }
  }
  else
    return YES;
}

Those two NSString category methods there are simply as follows:

- (BOOL)containsIllegal
{
  for (int i=0; i<[self length]; i++)
  {
    unichar currentChar = [self characterAtIndex:i];

    BOOL charIsIllegal = [[NSCharacterSet illegalCharacterSet] characterIsMember:currentChar];

    if (charIsIllegal)
      return YES;
  }
  return NO;
}

- (BOOL)containsNewline
{
  for (int i=0; i<[self length]; i++)
  {
    unichar currentChar = [self characterAtIndex:i];

    BOOL charIsNewLine = [[NSCharacterSet newlineCharacterSet] characterIsMember:currentChar];

    if (charIsNewLine)
      return YES;
  }
  return NO;
}


- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex

You can check anObject (usually it is NSString) value and decide should you agree with new value or not.


Look up NSPasteBoard for getting what is copied. From there, do the string checking and decide if they can paste or not.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜