[Tcladdressbook-commits] Source TclAddressBook.c,1.10,1.11
Status: Alpha
Brought to you by:
bdesgraupes
|
From: <bde...@us...> - 2003-12-07 16:04:09
|
Update of /cvsroot/tcladdressbook/Source
In directory sc8-pr-cvs1:/tmp/cvs-serv26913/Source
Modified Files:
TclAddressBook.c
Log Message:
Implemented [search]
Index: TclAddressBook.c
===================================================================
RCS file: /cvsroot/tcladdressbook/Source/TclAddressBook.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- TclAddressBook.c 6 Dec 2003 15:37:16 -0000 1.10
+++ TclAddressBook.c 7 Dec 2003 16:04:06 -0000 1.11
@@ -1,7 +1,7 @@
/*
* File : "TclAddressBook.c"
* Created: 2003-11-26 12:54:15
- * Last modification: 2003-12-06 16:29:57
+ * Last modification: 2003-12-07 02:00:17
* Author: Bernard Desgraupes
* e-mail: <bde...@ea...>
*
@@ -786,7 +786,7 @@
* See the user documentation for details on what it does.
*
* Syntax:
- * addressbook parents recordID ?-ids?
+ * addressbook parents ?-ids? recordID
*
* Results:
* A standard Tcl result.
@@ -807,7 +807,7 @@
{
CFArrayRef allParents;
ABRecordRef theRecord;
- CONST84 char * groupUID;
+ CONST84 char * theUID;
CFStringRef uidRef;
int index, kind, length;
ABAddressBookRef ab;
@@ -822,12 +822,12 @@
};
if (objc != 3 && objc != 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "recordID ?-ids?");
+ Tcl_WrongNumArgs(interp, 2, objv, "?-ids? recordID");
return TCL_ERROR;
}
if (objc == 4) {
- if (Tcl_GetIndexFromObj(interp, objv[3], parentsSwitches, "option", 0, &index) != TCL_OK) {
+ if (Tcl_GetIndexFromObj(interp, objv[2], parentsSwitches, "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
} else {
onlyID = true;
@@ -837,8 +837,8 @@
// Get the address book
ab = ABGetSharedAddressBook();
- groupUID = Tcl_GetStringFromObj(objv[2], &length);
- uidRef = CFStringCreateWithCString(NULL, groupUID, GetApplicationTextEncoding());
+ theUID = Tcl_GetStringFromObj(objv[objc-1], &length);
+ uidRef = CFStringCreateWithCString(NULL, theUID, GetApplicationTextEncoding());
// Find the record corresponding to the UID
theRecord = ABCopyRecordForUniqueId(ab, uidRef);
@@ -1184,8 +1184,9 @@
* See the user documentation for details on what it does.
*
* Syntax:
- * addressbook search property value ?property value ...?
+ * addressbook search ?(-groups|-persons)? ?-ids? ?-nocase? property op value
*
+ * The op argument can be: "==", "!=", "<", "<=", ">", or ">="
* Results:
* A standard Tcl result.
*
@@ -1203,6 +1204,176 @@
Tcl_Obj *CONST objv[], /* Argument values. */
Tcl_Obj *resultPtr) /* Pointer to store the result. */
{
+ ABAddressBookRef ab;
+ ABSearchElementRef theSearchElement;
+ ABSearchComparison comparison;
+ ABPropertyType thePropType;
+ CONST84 char * theProperty;
+ CONST84 char * theOp;
+ CONST84 char * theValue;
+ CFStringRef propertyRef, valueRef;
+ CFArrayRef foundItemsRef;
+ SInt32 theSInt32;
+ double theDouble;
+ int i, index, opIndex, kind = rec_person, length;
+ TextEncoding theEncoding = GetApplicationTextEncoding();
+ Boolean onlyID = false;
+ Boolean noCase = false;
+ Boolean isNumeric = false;
+
+ static CONST char *searchSwitches[] = {
+ "-groups", "-persons", "-ids", "-nocase", (char *) NULL
+ };
+
+ enum {
+ TCLAB_SEARCH_GROUPS, TCLAB_SEARCH_PERSONS,
+ TCLAB_SEARCH_IDS, TCLAB_SEARCH_NOCASE
+ };
+
+ static CONST char *searchOpSwitches[] = {
+ "==", "!=", "<", "<=", ">", ">=", (char *) NULL
+ };
+
+ // Same order as in the ABSearchComparison enum. DON'T CHANGE IT!
+ enum {
+ TCLAB_SEARCHOP_EQUAL, TCLAB_SEARCHOP_NOTEQUAL, TCLAB_SEARCHOP_LESSTHAN,
+ TCLAB_SEARCHOP_LESSTHANOREQUAL, TCLAB_SEARCHOP_GREATERTHAN,
+ TCLAB_SEARCHOP_GREATERTHANOREQUAL,
+ };
+
+ if (objc < 5 || objc > 8) {
+ Tcl_WrongNumArgs(interp, 2, objv, "?(-groups|-persons)? ?-ids? ?-nocase? property op value");
+ return TCL_ERROR;
+ }
+ if (objc > 6) {
+ for (i = objc-4; i > 1; i--) {
+ if (Tcl_GetIndexFromObj(interp, objv[i], searchSwitches, "option", 0, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch (index) {
+ case TCLAB_SEARCH_GROUPS:
+ case TCLAB_SEARCH_PERSONS:
+ kind = index;
+ break;
+
+ case TCLAB_SEARCH_IDS:
+ onlyID = true;
+ break;
+
+ case TCLAB_SEARCH_NOCASE:
+ noCase = true;
+ break;
+ }
+ }
+ }
+
+ if (Tcl_GetIndexFromObj(interp, objv[objc-2], searchOpSwitches, "operator", 0, &opIndex) != TCL_OK) {
+ return TCL_ERROR;
+ }
+
+ theProperty = Tcl_GetStringFromObj(objv[objc-3], &length);
+ theValue = Tcl_GetStringFromObj(objv[objc-1], &length);
+
+ // Make CF objects. The kind of CF object for value depends on the type of
+ // the property (string, integer, date etc.)
+ propertyRef = CFStringCreateWithCString(NULL, theProperty, theEncoding);
+ if (!propertyRef) {
+ Tcl_AppendStringsToObj(resultPtr, "Couldn't create property reference", (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ // Get the address book
+ ab = ABGetSharedAddressBook();
+
+ thePropType = ABTypeOfProperty(ab, kind ? kABPersonRecordType : kABGroupRecordType, theProperty);
+ switch (thePropType) {
+ case kABArrayProperty:
+ case kABDictionaryProperty:
+ case kABStringProperty:
+ case kABMultiArrayProperty:
+ case kABMultiDictionaryProperty:
+ case kABMultiStringProperty:
+ valueRef = CFStringCreateWithCString(NULL, theValue, theEncoding);
+ break;
+
+ case kABDateProperty:
+ case kABMultiDateProperty:
+ theDouble = atof(theValue);
+ theDouble -= kCFAbsoluteTimeIntervalSince1970;
+ valueRef = CFDateCreate(NULL, theDouble);
+ isNumeric = true;
+ break;
+
+ case kABIntegerProperty:
+ case kABRealProperty:
+ case kABMultiIntegerProperty:
+ case kABMultiRealProperty:
+ theSInt32 = atoi(theValue);
+ valueRef = CFNumberCreate(NULL, kCFNumberSInt32Type, &theSInt32);
+ isNumeric = true;
+ break;
+
+ case kABDataProperty:
+ case kABMultiDataProperty:
+ valueRef = NULL;
+ default:
+ break;
+ }
+ if (!valueRef) {
+ Tcl_AppendStringsToObj(resultPtr, "Invalid value", (char *) NULL);
+ CFRelease(propertyRef);
+ return TCL_ERROR;
+ }
+
+ switch (opIndex) {
+ case TCLAB_SEARCHOP_EQUAL:
+ if (!isNumeric && noCase) {
+ comparison = kABEqualCaseInsensitive;
+ } else {
+ comparison = opIndex;
+ }
+ break;
+
+ case TCLAB_SEARCHOP_GREATERTHAN:
+ case TCLAB_SEARCHOP_GREATERTHANOREQUAL:
+ if (isNumeric) {
+ comparison = opIndex;
+ } else if (noCase) {
+ comparison = kABContainsSubStringCaseInsensitive;
+ } else {
+ comparison = kABContainsSubString;
+ }
+ break;
+
+ case TCLAB_SEARCHOP_NOTEQUAL:
+ case TCLAB_SEARCHOP_LESSTHAN:
+ case TCLAB_SEARCHOP_LESSTHANOREQUAL:
+ comparison = opIndex;
+ break;
+ }
+
+ switch (kind) {
+ case rec_person:
+ theSearchElement = ABPersonCreateSearchElement(propertyRef, NULL, NULL, valueRef, comparison);
+ break;
+
+ case rec_group:
+ theSearchElement = ABGroupCreateSearchElement(propertyRef, NULL, NULL, valueRef, comparison);
+ break;
+ }
+ CFRelease(propertyRef);
+ CFRelease(valueRef);
+
+ if (theSearchElement) {
+ foundItemsRef = ABCopyArrayOfMatchingRecords(ab, theSearchElement);
+ CFRelease(theSearchElement);
+ TclAB_ResultListFromCFArray(interp, resultPtr, foundItemsRef, onlyID, kind);
+ CFRelease(foundItemsRef);
+ } else {
+ Tcl_AppendStringsToObj(resultPtr, "Couldn't build search element", (char *) NULL);
+ return TCL_ERROR;
+ }
+
return TCL_OK;
}
|