From f2545c5e4fc4414d4ee448de4a5f399d6cf58ad2 Mon Sep 17 00:00:00 2001 From: rowanbeentje Date: Mon, 4 Mar 2013 00:02:33 +0000 Subject: - Add support for export path tokens containing non-alphanumeric characters, automatically grouping and tokenising as required for both dragged and typed tokens. This addresses Issue #1567. --- Source/SPExportControllerDelegate.m | 27 ++++++++++++++++++ Source/SPExportFilenameUtilities.m | 55 +++++++++++++++++++++++++++---------- 2 files changed, 68 insertions(+), 14 deletions(-) diff --git a/Source/SPExportControllerDelegate.m b/Source/SPExportControllerDelegate.m index ef084283..8c273813 100644 --- a/Source/SPExportControllerDelegate.m +++ b/Source/SPExportControllerDelegate.m @@ -112,8 +112,10 @@ - (NSArray *)tokenField:(NSTokenField *)tokenField shouldAddObjects:(NSArray *)tokens atIndex:(NSUInteger)index { NSUInteger i, j; + NSInteger k; NSMutableArray *processedTokens = [NSMutableArray array]; NSCharacterSet *alphanumericSet = [NSCharacterSet alphanumericCharacterSet]; + id groupToken; for (NSString *inputToken in tokens) { @@ -137,6 +139,31 @@ } } + // Check to see whether unprocessed strings can be combined to form tokens + for (i = 1; i < [processedTokens count]; i++) { + + // If this is a token object, skip + if ([[processedTokens objectAtIndex:i] isKindOfClass:[SPExportFileNameTokenObject class]]) { + continue; + } + + for (k = i - 1; k >= 0; k--) { + + // If this is a token object, stop processing + if ([[processedTokens objectAtIndex:k] isKindOfClass:[SPExportFileNameTokenObject class]]) { + break; + } + + // Check whether the group of items make up a token + groupToken = [self tokenObjectForString:[[processedTokens subarrayWithRange:NSMakeRange(k, 1 + i - k)] componentsJoinedByString:@""]]; + if ([groupToken isKindOfClass:[SPExportFileNameTokenObject class]]) { + [processedTokens replaceObjectsInRange:NSMakeRange(k, 1 + i - k) withObjectsFromArray:[NSArray arrayWithObject:groupToken]]; + i = k + 1; + break; + } + } + } + return processedTokens; } diff --git a/Source/SPExportFilenameUtilities.m b/Source/SPExportFilenameUtilities.m index 1a14ef6c..5ea5bb44 100644 --- a/Source/SPExportFilenameUtilities.m +++ b/Source/SPExportFilenameUtilities.m @@ -150,8 +150,7 @@ */ - (void)tokenizeCustomFilenameTokenField { - NSCharacterSet *nonAlphanumericSet = [[NSCharacterSet alphanumericCharacterSet] invertedSet]; - NSArray *validTokens = [exportCustomFilenameTokensField objectValue]; + NSCharacterSet *alphanumericSet = [NSCharacterSet alphanumericCharacterSet]; if ([exportCustomFilenameTokenField currentEditor] == nil) return; @@ -163,21 +162,49 @@ // Retrieve the object value of the token field. This consists of plain text and recognised tokens interspersed. NSArray *representedObjects = [exportCustomFilenameTokenField objectValue]; - // Walk through the strings - not the tokens - and determine whether any need tokenizing + // Walk through the strings - not the tokens - and determine whether any need tokenizing, + // including scanning for groups of strings which make up a single token BOOL tokenizingRequired = NO; - - for (id representedObject in representedObjects) - { - if ([representedObject isKindOfClass:[SPExportFileNameTokenObject class]]) continue; - - NSArray *tokenParts = [representedObject componentsSeparatedByCharactersInSet:nonAlphanumericSet]; - - for (NSString *tokenPart in tokenParts) - { - if ([validTokens containsObject:tokenPart]) { - tokenizingRequired = YES; + NSUInteger i, j; + NSInteger k; + id tokenCheck; + NSMutableArray *tokenParts = [NSMutableArray array]; + + // Add all tokens, words, and separators to the array to process + for (id eachObject in representedObjects) { + if ([eachObject isKindOfClass:[SPExportFileNameTokenObject class]]) { + [tokenParts addObject:eachObject]; + } else { + for (i = 0, j = 0; i < [(NSString *)eachObject length]; i++) { + if ([alphanumericSet characterIsMember:[eachObject characterAtIndex:i]]) { + continue; + } + if (i > j) { + [tokenParts addObject:[eachObject substringWithRange:NSMakeRange(j, i - j)]]; + } + [tokenParts addObject:[eachObject substringWithRange:NSMakeRange(i, 1)]]; + j = i + 1; + } + if (j < i) { + [tokenParts addObject:[eachObject substringWithRange:NSMakeRange(j, i - j)]]; + } + } + } + + // Walk through the array to process, scanning it for words or groups which are tokens + for (i = 0; i < [tokenParts count]; i++) { + for (k = i; k >= 0; k--) { + + // Don't process existing token objects + if ([[tokenParts objectAtIndex:k] isKindOfClass:[SPExportFileNameTokenObject class]]) { break; } + + // Check whether this item, or group of adjacent items, make up a token + tokenCheck = [self tokenObjectForString:[[tokenParts subarrayWithRange:NSMakeRange(k, 1 + i - k)] componentsJoinedByString:@""]]; + if ([tokenCheck isKindOfClass:[SPExportFileNameTokenObject class]]) { + tokenizingRequired = YES; + } } } -- cgit v1.2.3