|
Q: My application displays a list of files to the user. How can I sort this list like the Finder?A: There is no specific system routine to sort a list of strings as the Finder does. However, the Finder uses a standard system routine, Listing 1: Comparison function to sort like the Finder
#include <CoreServices/CoreServices.h>
#include <sys/param.h>
static CFComparisonResult CompareLikeTheFinder(
const void * val1,
const void * val2,
void * context
)
{
#pragma unused(context)
SInt32 compareResult;
CFStringRef lhsStr;
CFStringRef rhsStr;
CFIndex lhsLen;
CFIndex rhsLen;
UniChar lhsBuf[MAXPATHLEN];
UniChar rhsBuf[MAXPATHLEN];
// 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);
// 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;
}
static void SortCFMutableArrayOfCFStringsLikeTheFinder(
CFMutableArrayRef strArray
)
{
CFArraySortValues(
strArray,
CFRangeMake(0, CFArrayGetCount(strArray)),
CompareLikeTheFinder,
NULL
);
}
Note: The code in Listing 1 is sample code that is not optimized for speed. There are a number of steps that you can take to make this code run faster.
Note: The use of I could, and in production quality code I would, get the length of the string and allocate an appropriately sized buffer. However, that would be overkill for a sample whose focus is on how to sort file names. Moreover, in production code I would prefer to preconvert all of the strings to UTF-16 rather than converting them for each string comparison. Document Revision History
Posted: 2004-10-27 |
|