Revision: 29071 http://sourceforge.net/p/bibdesk/svn/29071 Author: hofman Date: 2025-02-26 15:50:10 +0000 (Wed, 26 Feb 2025) Log Message: ----------- Override scriptingValueForSpecifier: instead of implementing indicesOfObjectsByEvaluatingSpecifier:, as the latter does not work when a range specifier happens to return a single object.
Modified Paths: -------------- trunk/bibdesk/BibDocument+Scripting.m Modified: trunk/bibdesk/BibDocument+Scripting.m =================================================================== --- trunk/bibdesk/BibDocument+Scripting.m 2025-02-26 09:58:36 UTC (rev 29070) +++ trunk/bibdesk/BibDocument+Scripting.m 2025-02-26 15:50:10 UTC (rev 29071) @@ -710,10 +710,10 @@ return groupKeys; } -// The following "indicesOf..." methods are in support of scripting. They allow more flexible range and relative specifiers to be used with the different group keys of a SKTDrawDocument. +// The following "scriptingValueFor...Specifiers:" methods are in support of scripting. They allow more flexible range and relative specifiers to be used with the different group keys of a BibDesk. // The scripting engine does not know about the fact that the "static groups" key is really just a subset of the "groups" key, so script code like "groups from static group 1 to field group 4" don't make sense to it. But BibDesk does know and can answer such questions itself, with a little work. -// This is copied from Apple's Sketch sample code -- (NSArray *)indicesOfObjectsByEvaluatingRangeSpecifier:(NSRangeSpecifier *)rangeSpec { +// This is copied and modified from Apple's Sketch sample code +- (id)scriptingValueForRangeSpecifier:(NSRangeSpecifier *)rangeSpec { NSString *key = [rangeSpec key]; if ([groupKeys() containsObject:key]) { @@ -752,45 +752,37 @@ // The strategy here is going to be to find the index of the start and stop object in the full groups array, regardless of what its key is. Then we can find what we're looking for in that range of the groups key (weeding out objects we don't want, if necessary). // First find the index of the first start object in the groups array - if (startSpec == nil && keyIsGroups) { - startIndex = 0; - } else { - if (startSpec) { - object = [startSpec objectsByEvaluatingWithContainers:self]; - if ([object isKindOfClass:[NSArray class]]) - object = [object firstObject]; - if (object == nil) - // Oops. We could not find the start object. - return nil; - } else { - object = [rangeKeyObjects firstObject]; - } + if (startSpec) { + object = [startSpec objectsByEvaluatingWithContainers:self]; + if ([object isKindOfClass:[NSArray class]]) + object = [object firstObject]; + if (object == nil) + // Oops. We could not find the start object. + return nil; startIndex = [allGroups indexOfObjectIdenticalTo:object]; if (startIndex == NSNotFound) // Oops. We couldn't find the start object in the groups array. This should not happen. return nil; + } else { + startIndex = 0; } // Now find the index of the last end object in the groups array - if (endSpec == nil && keyIsGroups) { - endIndex = [allGroups count] - 1; - } else { - if (endSpec) { - object = [endSpec objectsByEvaluatingWithContainers:self]; - if ([object isKindOfClass:[NSArray class]]) - object = [object lastObject]; - if (object == nil) - // Oops. We could not find the end object. - return nil; - } else { - object = [rangeKeyObjects lastObject]; - } + if (endSpec) { + object = [endSpec objectsByEvaluatingWithContainers:self]; + if ([object isKindOfClass:[NSArray class]]) + object = [object lastObject]; + if (object == nil) + // Oops. We could not find the end object. + return nil; endIndex = [allGroups indexOfObjectIdenticalTo:object]; if (endIndex == NSNotFound) // Oops. We couldn't find the end object in the groups array. This should not happen. return nil; + } else { + endIndex = [allGroups count] - 1; } if (endIndex < startIndex) { @@ -801,27 +793,27 @@ } // Now startIndex and endIndex specify the end points of the range we want within the groups array. - // We will traverse the range and pick the objects we want. - // We do this by getting each object and seeing if it actually appears in the real key that we are trying to evaluate in. - NSMutableArray *result = [NSMutableArray array]; + if (keyIsGroups == NO) { + // Restrict to the requested group range + NSUInteger rangeStartIndex = [allGroups indexOfObjectIdenticalTo:[rangeKeyObjects firstObject]]; + NSUInteger rangeEndIndex = [allGroups indexOfObjectIdenticalTo:[rangeKeyObjects lastObject]]; + if (rangeStartIndex == NSNotFound || rangeEndIndex == NSNotFound) + // Oops. We couldn't find the range objects in the groups array. This should not happen. + return nil; + startIndex = MAX(startIndex, rangeStartIndex); + endIndex = MIN(endIndex, rangeEndIndex); + if (endIndex < startIndex) + // The requested range does not include any of the requested type of groups. + return @[]; + } - for (NSUInteger i = startIndex; i <= endIndex; i++) { - if (keyIsGroups) { - [result addObject:[NSNumber numberWithInteger:i]]; - } else { - object = [allGroups objectAtIndex:i]; - NSUInteger curKeyIndex = [rangeKeyObjects indexOfObjectIdenticalTo:object]; - if (curKeyIndex != NSNotFound) - [result addObject:[NSNumber numberWithInteger:curKeyIndex]]; - } - } - return result; + return [allGroups subarrayWithRange:NSMakeRange(startIndex, endIndex + 1 - startIndex)]; } } return nil; } -- (NSArray *)indicesOfObjectsByEvaluatingRelativeSpecifier:(NSRelativeSpecifier *)relSpec { +- (id)scriptingValueForRelativeSpecifier:(NSRelativeSpecifier *)relSpec { NSString *key = [relSpec key]; if ([groupKeys() containsObject:key]) { @@ -878,16 +870,10 @@ baseIndex++; while ((baseIndex >= 0) && (baseIndex < groupCount)) { - if (keyIsGroups) { - [result addObject:[NSNumber numberWithInteger:baseIndex]]; + curObj = [allGroups objectAtIndex:baseIndex]; + if (keyIsGroups || [relKeyObjects containsObject:curObj]) { + [result addObject:curObj]; break; - } else { - curObj = [allGroups objectAtIndex:baseIndex]; - curKeyIndex = [relKeyObjects indexOfObjectIdenticalTo:curObj]; - if (curKeyIndex != NSNotFound) { - [result addObject:[NSNumber numberWithInteger:curKeyIndex]]; - break; - } } if (relPos == NSRelativeBefore) baseIndex--; @@ -900,18 +886,18 @@ } return nil; } - -- (NSArray *)indicesOfObjectsByEvaluatingObjectSpecifier:(NSScriptObjectSpecifier *)specifier { + +- (id)scriptingValueForSpecifier:(NSScriptObjectSpecifier *)specifier { // We want to handle some range and relative specifiers ourselves in order to support such things as "groups from static group 3 to static group 5" or "static groups from groups 7 to groups 10" or "static group before smart group 1". // Returning nil from this method will cause the specifier to try to evaluate itself using its default evaluation strategy. - + + id result = nil; if ([specifier isKindOfClass:[NSRangeSpecifier class]]) - return [self indicesOfObjectsByEvaluatingRangeSpecifier:(NSRangeSpecifier *)specifier]; + result = [self scriptingValueForRangeSpecifier:(NSRangeSpecifier *)specifier]; else if ([specifier isKindOfClass:[NSRelativeSpecifier class]]) - return [self indicesOfObjectsByEvaluatingRelativeSpecifier:(NSRelativeSpecifier *)specifier]; - - // If we didn't handle it, return nil so that the default object specifier evaluation will do it. - return nil; + result = [self scriptingValueForRelativeSpecifier:(NSRelativeSpecifier *)specifier]; + + return result ?: [super scriptingValueForSpecifier:specifier]; } #pragma mark Commands This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. _______________________________________________ Bibdesk-commit mailing list Bibdesk-commit@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bibdesk-commit