Sorting NSTableView columns with digits as numbers [Was: Re: Sorting filenames the way the Finder does?]
Sorting NSTableView columns with digits as numbers [Was: Re: Sorting filenames the way the Finder does?]
- Subject: Sorting NSTableView columns with digits as numbers [Was: Re: Sorting filenames the way the Finder does?]
- From: António Nunes <email@hidden>
- Date: Fri, 8 Jun 2007 11:37:20 +0200
On 7 Jun 2007, at 23:44, Jim Correia wrote:
On Jun 7, 2007, at 5:39 PM, Jim Correia wrote:
On Jun 7, 2007, at 5:31 PM, James Bucanek wrote:
Is there a string comparison function (preferably Cocoa) that
will sort filenames in the same order the Finder does?
I've looked into lots of string comparison functions and options,
both Carbon and Cocoa, and I can't find any that say "this is the
way the Finder/NavServices orders items" or "this is the order
that filenames should be sorted when displaying them for the user."
http://developer.apple.com/qa/qa2004/qa1159.html
What perfect timing. I just started looking into this today, and
along comes this thread. :-D My need is to sort this way in two
columns of a table view (whose contents are bound to an array
controller). The contents of the columns are not necessarily file
names, but the desired behaviour is identical. So this is what I did:
Created a category on NSString integrating the code provided in the
technote (slightly modified to provide more ideal buffer sizes, and
more descriptive naming):
======================== .h file:
#import <Cocoa/Cocoa.h>
@interface NSString (NSStringAdditions)
- (CFComparisonResult)compareWithDigitsAsNumber:(NSString *)
comparisonString;
@end
static CFComparisonResult CompareWithDigitsAsNumber(const void *
val1,
const void * val2,
void * context);
======================== .m file:
#import "NSStringAdditions.h"
@implementation NSString (NSStringAdditions)
- (CFComparisonResult)compareWithDigitsAsNumber:(NSString *)
comparisonString
{
return CompareWithDigitsAsNumber(self, comparisonString, NULL);
}
@end
static CFComparisonResult CompareWithDigitsAsNumber(const void *
val1,
const void * val2,
void * context)
{
#pragma unused(context)
SInt32 compareResult;
CFStringRef lhsStr;
CFStringRef rhsStr;
CFIndex lhsLen;
CFIndex rhsLen;
// val1 is the left-hand side CFString.
lhsStr = (CFStringRef) val1;
lhsLen = CFStringGetLength(lhsStr);
// val2 is the right-hand side CFString.
rhsStr = (CFStringRef) val2;
rhsLen = CFStringGetLength(rhsStr);
// Size the buffers according to string length
UniChar lhsBuf[lhsLen];
UniChar rhsBuf[rhsLen];
// Get the actual Unicode characters (UTF-16) for each string.
CFStringGetCharacters( lhsStr, CFRangeMake(0, lhsLen), lhsBuf);
CFStringGetCharacters( rhsStr, CFRangeMake(0, rhsLen), rhsBuf);
// Do the comparison.
(void) UCCompareTextDefault(
kUCCollateComposeInsensitiveMask
| kUCCollateWidthInsensitiveMask
| kUCCollateCaseInsensitiveMask
| kUCCollateDigitsOverrideMask
| kUCCollateDigitsAsNumberMask
| kUCCollatePunctuationSignificantMask,
lhsBuf,
lhsLen,
rhsBuf,
rhsLen,
NULL,
&compareResult
);
// Return the result. Conveniently, UCCompareTextDefault
// returns -1, 0, or +1, which matches the values for
// CFComparisonResult exactly.
return (CFComparisonResult) compareResult;
}
========================
Then in the nib file I selected each relevant column in the table
view and in the NSTableColumnInspector set the "Source Key" field to
the identifier of the column and the "Sort Selector" field to
"CompareWithDigitsAsNumber:". Save, Build and Run, and voilá: instant
Finder like sorting.
Thanks quite a lot more than just a little bit James for starting the
thread, and Jim for pointing to the technote!
Cheers,
António
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden