19b5730f6SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
39b5730f6SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
49b5730f6SAndrew Rist * or more contributor license agreements. See the NOTICE file
59b5730f6SAndrew Rist * distributed with this work for additional information
69b5730f6SAndrew Rist * regarding copyright ownership. The ASF licenses this file
79b5730f6SAndrew Rist * to you under the Apache License, Version 2.0 (the
89b5730f6SAndrew Rist * "License"); you may not use this file except in compliance
99b5730f6SAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
119b5730f6SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
139b5730f6SAndrew Rist * Unless required by applicable law or agreed to in writing,
149b5730f6SAndrew Rist * software distributed under the License is distributed on an
159b5730f6SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169b5730f6SAndrew Rist * KIND, either express or implied. See the License for the
179b5730f6SAndrew Rist * specific language governing permissions and limitations
189b5730f6SAndrew Rist * under the License.
19cdf0e10cSrcweir *
209b5730f6SAndrew Rist *************************************************************/
219b5730f6SAndrew Rist
229b5730f6SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_connectivity.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #include "MacabRecords.hxx"
28cdf0e10cSrcweir #include "MacabRecord.hxx"
29cdf0e10cSrcweir #include "MacabHeader.hxx"
30cdf0e10cSrcweir #include "macabutilities.hxx"
31cdf0e10cSrcweir
32cdf0e10cSrcweir #include <premac.h>
33cdf0e10cSrcweir #include <Carbon/Carbon.h>
34cdf0e10cSrcweir #include <AddressBook/ABAddressBookC.h>
35cdf0e10cSrcweir #include <postmac.h>
36cdf0e10cSrcweir #include <com/sun/star/util/DateTime.hpp>
37cdf0e10cSrcweir
38cdf0e10cSrcweir using namespace connectivity::macab;
39cdf0e10cSrcweir using namespace com::sun::star::util;
40cdf0e10cSrcweir
41cdf0e10cSrcweir // -------------------------------------------------------------------------
MacabRecords(const ABAddressBookRef _addressBook,MacabHeader * _header,MacabRecord ** _records,sal_Int32 _numRecords)42cdf0e10cSrcweir MacabRecords::MacabRecords(const ABAddressBookRef _addressBook, MacabHeader *_header, MacabRecord **_records, sal_Int32 _numRecords)
43cdf0e10cSrcweir {
44cdf0e10cSrcweir /* Variables passed in... */
45cdf0e10cSrcweir header = _header;
46cdf0e10cSrcweir recordsSize = _numRecords;
47cdf0e10cSrcweir currentRecord = _numRecords;
48cdf0e10cSrcweir records = _records;
49cdf0e10cSrcweir addressBook = _addressBook;
50cdf0e10cSrcweir
51cdf0e10cSrcweir /* Default variables... */
52cdf0e10cSrcweir recordType = kABPersonRecordType;
53cdf0e10cSrcweir
54cdf0e10cSrcweir /* Variables constructed... */
55cdf0e10cSrcweir bootstrap_CF_types();
56cdf0e10cSrcweir bootstrap_requiredProperties();
57cdf0e10cSrcweir }
58cdf0e10cSrcweir
59cdf0e10cSrcweir // -------------------------------------------------------------------------
60cdf0e10cSrcweir /* Creates a MacabRecords from another: copies the length, name, and
61cdf0e10cSrcweir * address book of the original, but the header or the records themselves.
62cdf0e10cSrcweir * The idea is that the only reason to copy a MacabRecords is to create
63cdf0e10cSrcweir * a filtered version of it, which can have the same length (to avoid
64cdf0e10cSrcweir * resizing) and will work from the same base addressbook, but might have
65cdf0e10cSrcweir * entirey different values and even (possibly in the future) a different
66cdf0e10cSrcweir * header.
67cdf0e10cSrcweir */
MacabRecords(const MacabRecords * _copy)68cdf0e10cSrcweir MacabRecords::MacabRecords(const MacabRecords *_copy)
69cdf0e10cSrcweir {
70cdf0e10cSrcweir /* Variables passed in... */
71cdf0e10cSrcweir recordsSize = _copy->recordsSize;
72cdf0e10cSrcweir addressBook = _copy->addressBook;
73cdf0e10cSrcweir m_sName = _copy->m_sName;
74cdf0e10cSrcweir
75cdf0e10cSrcweir /* Default variables... */
76cdf0e10cSrcweir currentRecord = 0;
77cdf0e10cSrcweir header = NULL;
78cdf0e10cSrcweir records = new MacabRecord *[recordsSize];
79cdf0e10cSrcweir recordType = kABPersonRecordType;
80cdf0e10cSrcweir
81cdf0e10cSrcweir /* Variables constructed... */
82cdf0e10cSrcweir bootstrap_CF_types();
83cdf0e10cSrcweir bootstrap_requiredProperties();
84cdf0e10cSrcweir }
85cdf0e10cSrcweir
86cdf0e10cSrcweir // -------------------------------------------------------------------------
MacabRecords(const ABAddressBookRef _addressBook)87cdf0e10cSrcweir MacabRecords::MacabRecords(const ABAddressBookRef _addressBook)
88cdf0e10cSrcweir {
89cdf0e10cSrcweir /* Variables passed in... */
90cdf0e10cSrcweir addressBook = _addressBook;
91cdf0e10cSrcweir
92cdf0e10cSrcweir /* Default variables... */
93cdf0e10cSrcweir recordsSize = 0;
94cdf0e10cSrcweir currentRecord = 0;
95cdf0e10cSrcweir records = NULL;
96cdf0e10cSrcweir header = NULL;
97cdf0e10cSrcweir recordType = kABPersonRecordType;
98cdf0e10cSrcweir
99cdf0e10cSrcweir /* Variables constructed... */
100cdf0e10cSrcweir bootstrap_CF_types();
101cdf0e10cSrcweir bootstrap_requiredProperties();
102cdf0e10cSrcweir }
103cdf0e10cSrcweir
104cdf0e10cSrcweir // -------------------------------------------------------------------------
initialize()105cdf0e10cSrcweir void MacabRecords::initialize()
106cdf0e10cSrcweir {
107cdf0e10cSrcweir
108cdf0e10cSrcweir /* Make sure everything is NULL before initializing. (We usually just
109cdf0e10cSrcweir * initialize after we use the constructor that takes only a
110cdf0e10cSrcweir * MacabAddressBook, so these variables will most likely already be
111cdf0e10cSrcweir * NULL.
112cdf0e10cSrcweir */
113cdf0e10cSrcweir if(records != NULL)
114cdf0e10cSrcweir {
115cdf0e10cSrcweir sal_Int32 i;
116cdf0e10cSrcweir
117cdf0e10cSrcweir for(i = 0; i < recordsSize; i++)
118cdf0e10cSrcweir delete records[i];
119cdf0e10cSrcweir
120cdf0e10cSrcweir delete [] records;
121cdf0e10cSrcweir }
122cdf0e10cSrcweir
123cdf0e10cSrcweir if(header != NULL)
124cdf0e10cSrcweir delete header;
125cdf0e10cSrcweir
126cdf0e10cSrcweir /* We can handle both default record Address Book record types in
127cdf0e10cSrcweir * this method, though only kABPersonRecordType is ever used.
128cdf0e10cSrcweir */
129cdf0e10cSrcweir CFArrayRef allRecords;
130cdf0e10cSrcweir if(CFStringCompare(recordType, kABPersonRecordType, 0) == kCFCompareEqualTo)
131cdf0e10cSrcweir allRecords = ABCopyArrayOfAllPeople(addressBook);
132cdf0e10cSrcweir else
133cdf0e10cSrcweir allRecords = ABCopyArrayOfAllGroups(addressBook);
134cdf0e10cSrcweir
135cdf0e10cSrcweir ABRecordRef record;
136cdf0e10cSrcweir sal_Int32 i;
137cdf0e10cSrcweir recordsSize = (sal_Int32) CFArrayGetCount(allRecords);
138cdf0e10cSrcweir records = new MacabRecord *[recordsSize];
139cdf0e10cSrcweir
140cdf0e10cSrcweir /* First, we create the header... */
141cdf0e10cSrcweir header = createHeaderForRecordType(allRecords, recordType);
142cdf0e10cSrcweir
143cdf0e10cSrcweir /* Then, we create each of the records... */
144cdf0e10cSrcweir for(i = 0; i < recordsSize; i++)
145cdf0e10cSrcweir {
146cdf0e10cSrcweir record = (ABRecordRef) CFArrayGetValueAtIndex(allRecords, i);
147cdf0e10cSrcweir records[i] = createMacabRecord(record, header, recordType);
148cdf0e10cSrcweir }
149cdf0e10cSrcweir currentRecord = recordsSize;
150cdf0e10cSrcweir
151cdf0e10cSrcweir CFRelease(allRecords);
152cdf0e10cSrcweir }
153cdf0e10cSrcweir
154cdf0e10cSrcweir // -------------------------------------------------------------------------
~MacabRecords()155cdf0e10cSrcweir MacabRecords::~MacabRecords()
156cdf0e10cSrcweir {
157cdf0e10cSrcweir }
158cdf0e10cSrcweir
159cdf0e10cSrcweir // -------------------------------------------------------------------------
setHeader(MacabHeader * _header)160cdf0e10cSrcweir void MacabRecords::setHeader(MacabHeader *_header)
161cdf0e10cSrcweir {
162cdf0e10cSrcweir if(header != NULL)
163cdf0e10cSrcweir delete header;
164cdf0e10cSrcweir header = _header;
165cdf0e10cSrcweir }
166cdf0e10cSrcweir
167cdf0e10cSrcweir // -------------------------------------------------------------------------
getHeader() const168cdf0e10cSrcweir MacabHeader *MacabRecords::getHeader() const
169cdf0e10cSrcweir {
170cdf0e10cSrcweir return header;
171cdf0e10cSrcweir }
172cdf0e10cSrcweir
173cdf0e10cSrcweir // -------------------------------------------------------------------------
174cdf0e10cSrcweir /* Inserts a MacabRecord at a given location. If there is already a
175cdf0e10cSrcweir * MacabRecord at that location, return it.
176cdf0e10cSrcweir */
insertRecord(MacabRecord * _newRecord,const sal_Int32 _location)177cdf0e10cSrcweir MacabRecord *MacabRecords::insertRecord(MacabRecord *_newRecord, const sal_Int32 _location)
178cdf0e10cSrcweir {
179cdf0e10cSrcweir MacabRecord *oldRecord;
180cdf0e10cSrcweir
181cdf0e10cSrcweir /* If the location is greater than the current allocated size of this
182cdf0e10cSrcweir * MacabRecords, allocate more space.
183cdf0e10cSrcweir */
184cdf0e10cSrcweir if(_location >= recordsSize)
185cdf0e10cSrcweir {
186cdf0e10cSrcweir sal_Int32 i;
187cdf0e10cSrcweir MacabRecord **newRecordsArray = new MacabRecord *[_location+1];
188cdf0e10cSrcweir for(i = 0; i < recordsSize; i++)
189cdf0e10cSrcweir {
190cdf0e10cSrcweir newRecordsArray[i] = records[i];
191cdf0e10cSrcweir }
192cdf0e10cSrcweir delete [] records;
193cdf0e10cSrcweir records = newRecordsArray;
194cdf0e10cSrcweir }
195cdf0e10cSrcweir
196cdf0e10cSrcweir /* Remember: currentRecord refers to one above the highest existing
197cdf0e10cSrcweir * record (i.e., it refers to where to place the next record if a
198cdf0e10cSrcweir * location is not given).
199cdf0e10cSrcweir */
200cdf0e10cSrcweir if(_location >= currentRecord)
201cdf0e10cSrcweir currentRecord = _location+1;
202cdf0e10cSrcweir
203cdf0e10cSrcweir oldRecord = records[_location];
204cdf0e10cSrcweir records[_location] = _newRecord;
205cdf0e10cSrcweir return oldRecord;
206cdf0e10cSrcweir }
207cdf0e10cSrcweir
208cdf0e10cSrcweir // -------------------------------------------------------------------------
209cdf0e10cSrcweir /* Insert a record at the next available place. */
insertRecord(MacabRecord * _newRecord)210cdf0e10cSrcweir void MacabRecords::insertRecord(MacabRecord *_newRecord)
211cdf0e10cSrcweir {
212cdf0e10cSrcweir insertRecord(_newRecord, currentRecord);
213cdf0e10cSrcweir }
214cdf0e10cSrcweir
215cdf0e10cSrcweir // -------------------------------------------------------------------------
getRecord(const sal_Int32 _location) const216cdf0e10cSrcweir MacabRecord *MacabRecords::getRecord(const sal_Int32 _location) const
217cdf0e10cSrcweir {
218cdf0e10cSrcweir if(_location >= recordsSize)
219cdf0e10cSrcweir return NULL;
220cdf0e10cSrcweir return records[_location];
221cdf0e10cSrcweir }
222cdf0e10cSrcweir
223cdf0e10cSrcweir // -------------------------------------------------------------------------
getField(const sal_Int32 _recordNumber,const sal_Int32 _columnNumber) const224cdf0e10cSrcweir macabfield *MacabRecords::getField(const sal_Int32 _recordNumber, const sal_Int32 _columnNumber) const
225cdf0e10cSrcweir {
226cdf0e10cSrcweir if(_recordNumber >= recordsSize)
227cdf0e10cSrcweir return NULL;
228cdf0e10cSrcweir
229cdf0e10cSrcweir MacabRecord *record = records[_recordNumber];
230cdf0e10cSrcweir
231cdf0e10cSrcweir if(_columnNumber < 0 || _columnNumber >= record->getSize())
232cdf0e10cSrcweir return NULL;
233cdf0e10cSrcweir
234cdf0e10cSrcweir return record->get(_columnNumber);
235cdf0e10cSrcweir }
236cdf0e10cSrcweir
237cdf0e10cSrcweir // -------------------------------------------------------------------------
getField(const sal_Int32 _recordNumber,const::rtl::OUString _columnName) const238cdf0e10cSrcweir macabfield *MacabRecords::getField(const sal_Int32 _recordNumber, const ::rtl::OUString _columnName) const
239cdf0e10cSrcweir {
240cdf0e10cSrcweir if(header != NULL)
241cdf0e10cSrcweir {
242cdf0e10cSrcweir sal_Int32 columnNumber = header->getColumnNumber(_columnName);
243cdf0e10cSrcweir if(columnNumber == -1)
244cdf0e10cSrcweir return NULL;
245cdf0e10cSrcweir
246cdf0e10cSrcweir return getField(_recordNumber, columnNumber);
247cdf0e10cSrcweir }
248cdf0e10cSrcweir else
249cdf0e10cSrcweir {
250cdf0e10cSrcweir // error: shouldn't access field with null header!
251cdf0e10cSrcweir return NULL;
252cdf0e10cSrcweir }
253cdf0e10cSrcweir }
254cdf0e10cSrcweir
255cdf0e10cSrcweir // -------------------------------------------------------------------------
getFieldNumber(const::rtl::OUString _columnName) const256cdf0e10cSrcweir sal_Int32 MacabRecords::getFieldNumber(const ::rtl::OUString _columnName) const
257cdf0e10cSrcweir {
258cdf0e10cSrcweir if(header != NULL)
259cdf0e10cSrcweir return header->getColumnNumber(_columnName);
260cdf0e10cSrcweir else
261cdf0e10cSrcweir // error: shouldn't access field with null header!
262cdf0e10cSrcweir return -1;
263cdf0e10cSrcweir }
264cdf0e10cSrcweir
265cdf0e10cSrcweir // -------------------------------------------------------------------------
266cdf0e10cSrcweir /* Create the lcl_CFTypes array -- we need this because there is no
267cdf0e10cSrcweir * way to get the ABType of an object from the object itself, and the
268cdf0e10cSrcweir * function ABTypeOfProperty can't handle multiple levels of data
269cdf0e10cSrcweir * (e.g., it can tell us that "address" is of type
270cdf0e10cSrcweir * kABDictionaryProperty, but it cannot tell us that all of the keys
271cdf0e10cSrcweir * and values in the dictionary have type kABStringProperty. On the
272cdf0e10cSrcweir * other hand, we _can_ get the CFType out of any object.
273cdf0e10cSrcweir * Unfortunately, all information about CFTypeIDs comes with the
274cdf0e10cSrcweir * warning that they change between releases, so we build them
275cdf0e10cSrcweir * ourselves here. (The one that we can't build is for multivalues,
276cdf0e10cSrcweir * e.g., kABMultiStringProperty. All of these appear to have the
277cdf0e10cSrcweir * same type: 1, but there is no function that I've found to give
278cdf0e10cSrcweir * us that dynamically in case that number ever changes.
279cdf0e10cSrcweir */
bootstrap_CF_types()280cdf0e10cSrcweir void MacabRecords::bootstrap_CF_types()
281cdf0e10cSrcweir {
282cdf0e10cSrcweir lcl_CFTypesLength = 6;
283cdf0e10cSrcweir lcl_CFTypes = new lcl_CFType[lcl_CFTypesLength];
284cdf0e10cSrcweir
285cdf0e10cSrcweir lcl_CFTypes[0].cf = CFNumberGetTypeID();
286cdf0e10cSrcweir lcl_CFTypes[0].ab = kABIntegerProperty;
287cdf0e10cSrcweir
288cdf0e10cSrcweir lcl_CFTypes[1].cf = CFStringGetTypeID();
289cdf0e10cSrcweir lcl_CFTypes[1].ab = kABStringProperty;
290cdf0e10cSrcweir
291cdf0e10cSrcweir lcl_CFTypes[2].cf = CFDateGetTypeID();
292cdf0e10cSrcweir lcl_CFTypes[2].ab = kABDateProperty;
293cdf0e10cSrcweir
294cdf0e10cSrcweir lcl_CFTypes[3].cf = CFArrayGetTypeID();
295cdf0e10cSrcweir lcl_CFTypes[3].ab = kABArrayProperty;
296cdf0e10cSrcweir
297cdf0e10cSrcweir lcl_CFTypes[4].cf = CFDictionaryGetTypeID();
298cdf0e10cSrcweir lcl_CFTypes[4].ab = kABDictionaryProperty;
299cdf0e10cSrcweir
300cdf0e10cSrcweir lcl_CFTypes[5].cf = CFDataGetTypeID();
301cdf0e10cSrcweir lcl_CFTypes[5].ab = kABDataProperty;
302cdf0e10cSrcweir }
303cdf0e10cSrcweir
304cdf0e10cSrcweir // -------------------------------------------------------------------------
305cdf0e10cSrcweir /* This is based on the possible fields required in the mail merge template
306cdf0e10cSrcweir * in sw. If the fields possible there change, it would be optimal to
307cdf0e10cSrcweir * change these fields as well.
308cdf0e10cSrcweir */
bootstrap_requiredProperties()309cdf0e10cSrcweir void MacabRecords::bootstrap_requiredProperties()
310cdf0e10cSrcweir {
311cdf0e10cSrcweir numRequiredProperties = 7;
312cdf0e10cSrcweir requiredProperties = new CFStringRef[numRequiredProperties];
313cdf0e10cSrcweir requiredProperties[0] = kABTitleProperty;
314cdf0e10cSrcweir requiredProperties[1] = kABFirstNameProperty;
315cdf0e10cSrcweir requiredProperties[2] = kABLastNameProperty;
316cdf0e10cSrcweir requiredProperties[3] = kABOrganizationProperty;
317cdf0e10cSrcweir requiredProperties[4] = kABAddressProperty;
318cdf0e10cSrcweir requiredProperties[5] = kABPhoneProperty;
319cdf0e10cSrcweir requiredProperties[6] = kABEmailProperty;
320cdf0e10cSrcweir }
321cdf0e10cSrcweir
322cdf0e10cSrcweir // -------------------------------------------------------------------------
323cdf0e10cSrcweir /* Create the header for a given record type and a given array of records.
324cdf0e10cSrcweir * Because the array of records and the record type are given, if you want
325cdf0e10cSrcweir * to, you can run this method on the members of a group, or on any other
326cdf0e10cSrcweir * filtered list of people and get a header relevant to them (e.g., if
327cdf0e10cSrcweir * they only have home addresses, the work address fields won't show up).
328cdf0e10cSrcweir */
createHeaderForRecordType(const CFArrayRef _records,const CFStringRef _recordType) const329cdf0e10cSrcweir MacabHeader *MacabRecords::createHeaderForRecordType(const CFArrayRef _records, const CFStringRef _recordType) const
330cdf0e10cSrcweir {
331cdf0e10cSrcweir /* We have two types of properties for a given record type, nonrequired
332cdf0e10cSrcweir * and required. Required properties are ones that will show up whether
333cdf0e10cSrcweir * or not they are empty. Nonrequired properties will only show up if
334cdf0e10cSrcweir * at least one record in the set has that property filled. The reason
335cdf0e10cSrcweir * is that some properties, like the kABTitleProperty are required by
336cdf0e10cSrcweir * the mail merge wizard (in module sw) but are by default not shown in
337cdf0e10cSrcweir * the Mac OS X address book, so they would be weeded out at this stage
338cdf0e10cSrcweir * and not shown if they were not required.
339cdf0e10cSrcweir *
340cdf0e10cSrcweir * Note: with the addition of required properties, I am not sure that
341cdf0e10cSrcweir * this method still works for kABGroupRecordType (since the required
342*152e651eSJohn Bampton * properties are all for kABPersonRecordType).
343cdf0e10cSrcweir *
344cdf0e10cSrcweir * Note: required properties are constructed in the method
345cdf0e10cSrcweir * bootstrap_requiredProperties() (above).
346cdf0e10cSrcweir */
347cdf0e10cSrcweir CFArrayRef allProperties = ABCopyArrayOfPropertiesForRecordType(addressBook, _recordType);
348cdf0e10cSrcweir CFStringRef *nonRequiredProperties;
349cdf0e10cSrcweir sal_Int32 numRecords = (sal_Int32) CFArrayGetCount(_records);
350cdf0e10cSrcweir sal_Int32 numProperties = (sal_Int32) CFArrayGetCount(allProperties);
351cdf0e10cSrcweir sal_Int32 numNonRequiredProperties = numProperties - numRequiredProperties;
352cdf0e10cSrcweir
353cdf0e10cSrcweir /* While searching through the properties for required properties, these
354cdf0e10cSrcweir * sal_Bools will keep track of what we have found.
355cdf0e10cSrcweir */
356cdf0e10cSrcweir sal_Bool bFoundProperty;
357cdf0e10cSrcweir sal_Bool bFoundRequiredProperties[numRequiredProperties];
358cdf0e10cSrcweir
359cdf0e10cSrcweir
360cdf0e10cSrcweir /* We have three MacabHeaders: headerDataForProperty is where we
361cdf0e10cSrcweir * store the result of createHeaderForProperty(), which return a
362cdf0e10cSrcweir * MacabHeader for a single property. lcl_header is where we store
363cdf0e10cSrcweir * the MacabHeader that we are constructing. And, nonRequiredHeader
364cdf0e10cSrcweir * is where we construct the MacabHeader for non-required properties,
365cdf0e10cSrcweir * so that we can sort them before adding them to lcl_header.
366cdf0e10cSrcweir */
367cdf0e10cSrcweir MacabHeader *headerDataForProperty;
368cdf0e10cSrcweir MacabHeader *lcl_header = new MacabHeader();
369cdf0e10cSrcweir MacabHeader *nonRequiredHeader = new MacabHeader();
370cdf0e10cSrcweir
371cdf0e10cSrcweir /* Other variables... */
372cdf0e10cSrcweir sal_Int32 i, j, k;
373cdf0e10cSrcweir ABRecordRef record;
374cdf0e10cSrcweir CFStringRef property;
375cdf0e10cSrcweir
376cdf0e10cSrcweir
377cdf0e10cSrcweir /* Allocate and initialize... */
378cdf0e10cSrcweir nonRequiredProperties = new CFStringRef[numNonRequiredProperties];
379cdf0e10cSrcweir k = 0;
380cdf0e10cSrcweir for(i = 0; i < numRequiredProperties; i++)
381cdf0e10cSrcweir bFoundRequiredProperties[i] = sal_False;
382cdf0e10cSrcweir
383cdf0e10cSrcweir /* Determine the non-required properties... */
384cdf0e10cSrcweir for(i = 0; i < numProperties; i++)
385cdf0e10cSrcweir {
386cdf0e10cSrcweir property = (CFStringRef) CFArrayGetValueAtIndex(allProperties, i);
387cdf0e10cSrcweir bFoundProperty = sal_False;
388cdf0e10cSrcweir for(j = 0; j < numRequiredProperties; j++)
389cdf0e10cSrcweir {
390cdf0e10cSrcweir if(CFEqual(property, requiredProperties[j]))
391cdf0e10cSrcweir {
392cdf0e10cSrcweir bFoundProperty = sal_True;
393cdf0e10cSrcweir bFoundRequiredProperties[j] = sal_True;
394cdf0e10cSrcweir break;
395cdf0e10cSrcweir }
396cdf0e10cSrcweir }
397cdf0e10cSrcweir
398cdf0e10cSrcweir if(bFoundProperty == sal_False)
399cdf0e10cSrcweir {
400cdf0e10cSrcweir /* If we have found too many non-required properties */
401cdf0e10cSrcweir if(k == numNonRequiredProperties)
402cdf0e10cSrcweir {
403cdf0e10cSrcweir k++; // so that the OSL_ENSURE below fails
404cdf0e10cSrcweir break;
405cdf0e10cSrcweir }
406cdf0e10cSrcweir nonRequiredProperties[k] = property;
407cdf0e10cSrcweir k++;
408cdf0e10cSrcweir }
409cdf0e10cSrcweir }
410cdf0e10cSrcweir
411cdf0e10cSrcweir // Somehow, we got too many or too few non-requird properties...
412cdf0e10cSrcweir // Most likely, one of the required properties no longer exists, which
413cdf0e10cSrcweir // we also test later.
414cdf0e10cSrcweir OSL_ENSURE(k == numNonRequiredProperties, "MacabRecords::createHeaderForRecordType: Found an unexpected number of non-required properties");
415cdf0e10cSrcweir
416cdf0e10cSrcweir /* Fill the header with required properties first... */
417cdf0e10cSrcweir for(i = 0; i < numRequiredProperties; i++)
418cdf0e10cSrcweir {
419cdf0e10cSrcweir if(bFoundRequiredProperties[i] == sal_True)
420cdf0e10cSrcweir {
421cdf0e10cSrcweir /* The order of these matters (we want all address properties
422cdf0e10cSrcweir * before any phone properties, or else things will look weird),
42351754c86SJohn Bampton * so we get all possibilities for each property, going through
424cdf0e10cSrcweir * each record, and then go onto the next property.
425cdf0e10cSrcweir * (Note: the reason that we have to go through all records
426cdf0e10cSrcweir * in the first place is that properties like address, phone, and
427cdf0e10cSrcweir * e-mail are multi-value properties with an unknown number of
428cdf0e10cSrcweir * values. A user could specify thirteen different kinds of
429cdf0e10cSrcweir * e-mail addresses for one of her or his contacts, and we need to
430cdf0e10cSrcweir * get all of them.
431cdf0e10cSrcweir */
432cdf0e10cSrcweir for(j = 0; j < numRecords; j++)
433cdf0e10cSrcweir {
434cdf0e10cSrcweir record = (ABRecordRef) CFArrayGetValueAtIndex(_records, j);
435cdf0e10cSrcweir headerDataForProperty = createHeaderForProperty(record,requiredProperties[i],_recordType,sal_True);
436cdf0e10cSrcweir if(headerDataForProperty != NULL)
437cdf0e10cSrcweir {
438cdf0e10cSrcweir (*lcl_header) += headerDataForProperty;
439cdf0e10cSrcweir delete headerDataForProperty;
440cdf0e10cSrcweir }
441cdf0e10cSrcweir }
442cdf0e10cSrcweir }
443cdf0e10cSrcweir else
444cdf0e10cSrcweir {
445cdf0e10cSrcweir // Couldn't find a required property...
446cdf0e10cSrcweir OSL_ENSURE(false, ::rtl::OString("MacabRecords::createHeaderForRecordType: could not find required property: ") +
447cdf0e10cSrcweir ::rtl::OUStringToOString(CFStringToOUString(requiredProperties[i]), RTL_TEXTENCODING_ASCII_US));
448cdf0e10cSrcweir }
449cdf0e10cSrcweir }
450cdf0e10cSrcweir
451cdf0e10cSrcweir /* And now, non-required properties... */
452cdf0e10cSrcweir for(i = 0; i < numRecords; i++)
453cdf0e10cSrcweir {
454cdf0e10cSrcweir record = (ABRecordRef) CFArrayGetValueAtIndex(_records, i);
455cdf0e10cSrcweir
456cdf0e10cSrcweir for(j = 0; j < numNonRequiredProperties; j++)
457cdf0e10cSrcweir {
458cdf0e10cSrcweir property = nonRequiredProperties[j];
459cdf0e10cSrcweir headerDataForProperty = createHeaderForProperty(record,property,_recordType,sal_False);
460cdf0e10cSrcweir if(headerDataForProperty != NULL)
461cdf0e10cSrcweir {
462cdf0e10cSrcweir (*nonRequiredHeader) += headerDataForProperty;
463cdf0e10cSrcweir delete headerDataForProperty;
464cdf0e10cSrcweir }
465cdf0e10cSrcweir }
466cdf0e10cSrcweir
467cdf0e10cSrcweir }
468cdf0e10cSrcweir nonRequiredHeader->sortRecord();
469cdf0e10cSrcweir
470cdf0e10cSrcweir (*lcl_header) += nonRequiredHeader;
471cdf0e10cSrcweir delete nonRequiredHeader;
472cdf0e10cSrcweir
473cdf0e10cSrcweir CFRelease(allProperties);
474cdf0e10cSrcweir delete [] nonRequiredProperties;
475cdf0e10cSrcweir
476cdf0e10cSrcweir return lcl_header;
477cdf0e10cSrcweir }
478cdf0e10cSrcweir
479cdf0e10cSrcweir // -------------------------------------------------------------------------
480cdf0e10cSrcweir /* Create a header for a single property. Basically, this method gets
481cdf0e10cSrcweir * the property's value and type and then calls another method of
482cdf0e10cSrcweir * the same name to do the dirty work.
483cdf0e10cSrcweir */
createHeaderForProperty(const ABRecordRef _record,const CFStringRef _propertyName,const CFStringRef _recordType,const sal_Bool _isPropertyRequired) const484cdf0e10cSrcweir MacabHeader *MacabRecords::createHeaderForProperty(const ABRecordRef _record, const CFStringRef _propertyName, const CFStringRef _recordType, const sal_Bool _isPropertyRequired) const
485cdf0e10cSrcweir {
486cdf0e10cSrcweir // local variables
487cdf0e10cSrcweir CFStringRef localizedPropertyName;
488cdf0e10cSrcweir CFTypeRef propertyValue;
489cdf0e10cSrcweir ABPropertyType propertyType;
490cdf0e10cSrcweir MacabHeader *result;
491cdf0e10cSrcweir
492cdf0e10cSrcweir /* Get the property's value */
493cdf0e10cSrcweir propertyValue = ABRecordCopyValue(_record,_propertyName);
494cdf0e10cSrcweir if(propertyValue == NULL && _isPropertyRequired == sal_False)
495cdf0e10cSrcweir return NULL;
496cdf0e10cSrcweir
497cdf0e10cSrcweir propertyType = ABTypeOfProperty(addressBook, _recordType, _propertyName);
498cdf0e10cSrcweir localizedPropertyName = ABCopyLocalizedPropertyOrLabel(_propertyName);
499cdf0e10cSrcweir
500cdf0e10cSrcweir result = createHeaderForProperty(propertyType, propertyValue, localizedPropertyName);
501cdf0e10cSrcweir
502cdf0e10cSrcweir if(propertyValue != NULL)
503cdf0e10cSrcweir CFRelease(propertyValue);
504cdf0e10cSrcweir
505cdf0e10cSrcweir return result;
506cdf0e10cSrcweir }
507cdf0e10cSrcweir
508cdf0e10cSrcweir // -------------------------------------------------------------------------
509cdf0e10cSrcweir /* Create a header for a single property. This method is recursive
510cdf0e10cSrcweir * because a single property might contain several sub-properties that
511cdf0e10cSrcweir * we also want to treat singly.
512cdf0e10cSrcweir */
createHeaderForProperty(const ABPropertyType _propertyType,const CFTypeRef _propertyValue,const CFStringRef _propertyName) const513cdf0e10cSrcweir MacabHeader *MacabRecords::createHeaderForProperty(const ABPropertyType _propertyType, const CFTypeRef _propertyValue, const CFStringRef _propertyName) const
514cdf0e10cSrcweir {
515cdf0e10cSrcweir macabfield **headerNames = NULL;
516cdf0e10cSrcweir sal_Int32 length = 0;
517cdf0e10cSrcweir
518cdf0e10cSrcweir switch(_propertyType)
519cdf0e10cSrcweir {
520cdf0e10cSrcweir /* Scalars */
521cdf0e10cSrcweir case kABStringProperty:
522cdf0e10cSrcweir case kABRealProperty:
523cdf0e10cSrcweir case kABIntegerProperty:
524cdf0e10cSrcweir case kABDateProperty:
525cdf0e10cSrcweir length = 1;
526cdf0e10cSrcweir headerNames = new macabfield *[1];
527cdf0e10cSrcweir headerNames[0] = new macabfield;
528cdf0e10cSrcweir headerNames[0]->value = _propertyName;
529cdf0e10cSrcweir headerNames[0]->type = _propertyType;
530cdf0e10cSrcweir break;
531cdf0e10cSrcweir
532cdf0e10cSrcweir /* Multi-scalars */
533cdf0e10cSrcweir case kABMultiIntegerProperty:
534cdf0e10cSrcweir case kABMultiDateProperty:
535cdf0e10cSrcweir case kABMultiStringProperty:
536cdf0e10cSrcweir case kABMultiRealProperty:
537cdf0e10cSrcweir case kABMultiDataProperty:
538cdf0e10cSrcweir /* For non-scalars, we can only get more information if the property
539cdf0e10cSrcweir * actually exists.
540cdf0e10cSrcweir */
541cdf0e10cSrcweir if(_propertyValue != NULL)
542cdf0e10cSrcweir {
543cdf0e10cSrcweir sal_Int32 i;
544cdf0e10cSrcweir
545cdf0e10cSrcweir sal_Int32 multiLength = ABMultiValueCount((ABMutableMultiValueRef) _propertyValue);
546cdf0e10cSrcweir CFStringRef multiLabel, localizedMultiLabel;
547cdf0e10cSrcweir ::rtl::OUString multiLabelString;
548cdf0e10cSrcweir ::rtl::OUString multiPropertyString;
549cdf0e10cSrcweir ::rtl::OUString headerNameString;
550cdf0e10cSrcweir ABPropertyType multiType = (ABPropertyType) (ABMultiValuePropertyType((ABMutableMultiValueRef) _propertyValue) - 0x100);
551cdf0e10cSrcweir
552cdf0e10cSrcweir length = multiLength;
553cdf0e10cSrcweir headerNames = new macabfield *[multiLength];
554cdf0e10cSrcweir multiPropertyString = CFStringToOUString(_propertyName);
555cdf0e10cSrcweir
556cdf0e10cSrcweir /* Go through each element, and - since each element is a scalar -
557cdf0e10cSrcweir * just create a new macabfield for it.
558cdf0e10cSrcweir */
559cdf0e10cSrcweir for(i = 0; i < multiLength; i++)
560cdf0e10cSrcweir {
561cdf0e10cSrcweir multiLabel = ABMultiValueCopyLabelAtIndex((ABMutableMultiValueRef) _propertyValue, i);
562cdf0e10cSrcweir localizedMultiLabel = ABCopyLocalizedPropertyOrLabel(multiLabel);
563cdf0e10cSrcweir multiLabelString = CFStringToOUString(localizedMultiLabel);
564cdf0e10cSrcweir CFRelease(multiLabel);
565cdf0e10cSrcweir CFRelease(localizedMultiLabel);
566cdf0e10cSrcweir headerNameString = multiPropertyString + ::rtl::OUString::createFromAscii(": ") + fixLabel(multiLabelString);
567cdf0e10cSrcweir headerNames[i] = new macabfield;
568cdf0e10cSrcweir headerNames[i]->value = OUStringToCFString(headerNameString);
569cdf0e10cSrcweir headerNames[i]->type = multiType;
570cdf0e10cSrcweir }
571cdf0e10cSrcweir }
572cdf0e10cSrcweir break;
573cdf0e10cSrcweir
574cdf0e10cSrcweir /* Multi-array or dictionary */
575cdf0e10cSrcweir case kABMultiArrayProperty:
576cdf0e10cSrcweir case kABMultiDictionaryProperty:
577cdf0e10cSrcweir /* For non-scalars, we can only get more information if the property
578cdf0e10cSrcweir * actually exists.
579cdf0e10cSrcweir */
580cdf0e10cSrcweir if(_propertyValue != NULL)
581cdf0e10cSrcweir {
582cdf0e10cSrcweir sal_Int32 i,j,k;
583cdf0e10cSrcweir
584cdf0e10cSrcweir // Total number of multi-array or multi-dictionary elements.
585cdf0e10cSrcweir sal_Int32 multiLengthFirstLevel = ABMultiValueCount((ABMutableMultiValueRef) _propertyValue);
586cdf0e10cSrcweir
587cdf0e10cSrcweir /* Total length, including the length of each element (e.g., if
588cdf0e10cSrcweir * this multi-dictionary contains three dictionaries, and each
589cdf0e10cSrcweir * dictionary has four elements, this variable will be twelve,
590cdf0e10cSrcweir * whereas multiLengthFirstLevel will be three.
591cdf0e10cSrcweir */
592cdf0e10cSrcweir sal_Int32 multiLengthSecondLevel = 0;
593cdf0e10cSrcweir
594cdf0e10cSrcweir CFStringRef multiLabel, localizedMultiLabel;
595cdf0e10cSrcweir CFTypeRef multiValue;
596cdf0e10cSrcweir ::rtl::OUString multiLabelString;
597cdf0e10cSrcweir ::rtl::OUString multiPropertyString;
598cdf0e10cSrcweir MacabHeader **multiHeaders = new MacabHeader *[multiLengthFirstLevel];
599cdf0e10cSrcweir ABPropertyType multiType = (ABPropertyType) (ABMultiValuePropertyType((ABMutableMultiValueRef) _propertyValue) - 0x100);
600cdf0e10cSrcweir
601cdf0e10cSrcweir multiPropertyString = CFStringToOUString(_propertyName);
602cdf0e10cSrcweir
603cdf0e10cSrcweir /* Go through each element - since each element can really
604cdf0e10cSrcweir * contain anything, we run this method again on each element
605cdf0e10cSrcweir * and store the resulting MacabHeader (in the multiHeaders
606cdf0e10cSrcweir * array). Then, all we'll have to do is combine the MacabHeaders
607cdf0e10cSrcweir * into a single one.
608cdf0e10cSrcweir */
609cdf0e10cSrcweir for(i = 0; i < multiLengthFirstLevel; i++)
610cdf0e10cSrcweir {
611cdf0e10cSrcweir /* label */
612cdf0e10cSrcweir multiLabel = ABMultiValueCopyLabelAtIndex((ABMutableMultiValueRef) _propertyValue, i);
613cdf0e10cSrcweir multiValue = ABMultiValueCopyValueAtIndex((ABMutableMultiValueRef) _propertyValue, i);
614cdf0e10cSrcweir if(multiValue && multiLabel)
615cdf0e10cSrcweir {
616cdf0e10cSrcweir localizedMultiLabel = ABCopyLocalizedPropertyOrLabel(multiLabel);
617cdf0e10cSrcweir multiLabelString = multiPropertyString + ::rtl::OUString::createFromAscii(": ") + fixLabel(CFStringToOUString(localizedMultiLabel));
618cdf0e10cSrcweir CFRelease(multiLabel);
619cdf0e10cSrcweir CFRelease(localizedMultiLabel);
620cdf0e10cSrcweir multiLabel = OUStringToCFString(multiLabelString);
621cdf0e10cSrcweir multiHeaders[i] = createHeaderForProperty(multiType, multiValue, multiLabel);
622cdf0e10cSrcweir if (!multiHeaders[i])
623cdf0e10cSrcweir multiHeaders[i] = new MacabHeader();
624cdf0e10cSrcweir multiLengthSecondLevel += multiHeaders[i]->getSize();
625cdf0e10cSrcweir }
626cdf0e10cSrcweir else
627cdf0e10cSrcweir {
628cdf0e10cSrcweir multiHeaders[i] = new MacabHeader();
629cdf0e10cSrcweir }
630cdf0e10cSrcweir if(multiValue)
631cdf0e10cSrcweir CFRelease(multiValue);
632cdf0e10cSrcweir }
633cdf0e10cSrcweir
634cdf0e10cSrcweir /* We now have enough information to create our final MacabHeader.
635cdf0e10cSrcweir * We go through each field of each header and add it to the
636cdf0e10cSrcweir * headerNames array (which is what is used below to construct
637cdf0e10cSrcweir * the MacabHeader we return).
638cdf0e10cSrcweir */
639cdf0e10cSrcweir length = multiLengthSecondLevel;
640cdf0e10cSrcweir headerNames = new macabfield *[multiLengthSecondLevel];
641cdf0e10cSrcweir
642cdf0e10cSrcweir for(i = 0, j = 0, k = 0; i < multiLengthSecondLevel; i++,k++)
643cdf0e10cSrcweir {
644cdf0e10cSrcweir while(multiHeaders[j]->getSize() == k)
645cdf0e10cSrcweir {
646cdf0e10cSrcweir j++;
647cdf0e10cSrcweir k = 0;
648cdf0e10cSrcweir }
649cdf0e10cSrcweir
650cdf0e10cSrcweir headerNames[i] = multiHeaders[j]->copy(k);
651cdf0e10cSrcweir }
652cdf0e10cSrcweir for(i = 0; i < multiLengthFirstLevel; i++)
653cdf0e10cSrcweir delete multiHeaders[i];
654cdf0e10cSrcweir
655cdf0e10cSrcweir delete [] multiHeaders;
656cdf0e10cSrcweir }
657cdf0e10cSrcweir break;
658cdf0e10cSrcweir
659cdf0e10cSrcweir /* Dictionary */
660cdf0e10cSrcweir case kABDictionaryProperty:
661cdf0e10cSrcweir /* For non-scalars, we can only get more information if the property
662cdf0e10cSrcweir * actually exists.
663cdf0e10cSrcweir */
664cdf0e10cSrcweir if(_propertyValue != NULL)
665cdf0e10cSrcweir {
666cdf0e10cSrcweir /* Assume all keys are strings */
667cdf0e10cSrcweir sal_Int32 numRecords = (sal_Int32) CFDictionaryGetCount((CFDictionaryRef) _propertyValue);
668cdf0e10cSrcweir
669cdf0e10cSrcweir /* The only method for getting info out of a CFDictionary, of both
670cdf0e10cSrcweir * keys and values, is to all of them all at once, so these
671cdf0e10cSrcweir * variables will hold them.
672cdf0e10cSrcweir */
673cdf0e10cSrcweir CFStringRef *dictKeys;
674cdf0e10cSrcweir CFTypeRef *dictValues;
675cdf0e10cSrcweir
676cdf0e10cSrcweir sal_Int32 i,j,k;
677cdf0e10cSrcweir ::rtl::OUString dictKeyString, propertyNameString;
678cdf0e10cSrcweir ABPropertyType dictType;
679cdf0e10cSrcweir MacabHeader **dictHeaders = new MacabHeader *[numRecords];
680cdf0e10cSrcweir ::rtl::OUString dictLabelString;
681cdf0e10cSrcweir CFStringRef dictLabel, localizedDictKey;
682cdf0e10cSrcweir
683cdf0e10cSrcweir /* Get the keys and values */
684cdf0e10cSrcweir dictKeys = (CFStringRef *) malloc(sizeof(CFStringRef)*numRecords);
685cdf0e10cSrcweir dictValues = (CFTypeRef *) malloc(sizeof(CFTypeRef)*numRecords);
686cdf0e10cSrcweir CFDictionaryGetKeysAndValues((CFDictionaryRef) _propertyValue, (const void **) dictKeys, (const void **) dictValues);
687cdf0e10cSrcweir
688cdf0e10cSrcweir propertyNameString = CFStringToOUString(_propertyName);
689cdf0e10cSrcweir
690cdf0e10cSrcweir length = 0;
691cdf0e10cSrcweir /* Go through each element - assuming that the key is a string but
692cdf0e10cSrcweir * that the value could be anything. Since the value could be
693cdf0e10cSrcweir * anything, we can't assume that it is scalar (it could even be
694cdf0e10cSrcweir * another dictionary), so we attempt to get its type using
695cdf0e10cSrcweir * the method getABTypeFromCFType and then run this method
696cdf0e10cSrcweir * recursively on that element, storing the MacabHeader that
697cdf0e10cSrcweir * results. Then, we just combine all of the MacabHeaders into
698cdf0e10cSrcweir * one.
699cdf0e10cSrcweir */
700cdf0e10cSrcweir for(i = 0; i < numRecords; i++)
701cdf0e10cSrcweir {
702cdf0e10cSrcweir dictType = (ABPropertyType) getABTypeFromCFType( CFGetTypeID(dictValues[i]) );
703cdf0e10cSrcweir localizedDictKey = ABCopyLocalizedPropertyOrLabel(dictKeys[i]);
704cdf0e10cSrcweir dictKeyString = CFStringToOUString(localizedDictKey);
705cdf0e10cSrcweir dictLabelString = propertyNameString + ::rtl::OUString::createFromAscii(": ") + fixLabel(dictKeyString);
706cdf0e10cSrcweir dictLabel = OUStringToCFString(dictLabelString);
707cdf0e10cSrcweir dictHeaders[i] = createHeaderForProperty(dictType, dictValues[i], dictLabel);
708cdf0e10cSrcweir if (!dictHeaders[i])
709cdf0e10cSrcweir dictHeaders[i] = new MacabHeader();
710cdf0e10cSrcweir length += dictHeaders[i]->getSize();
711cdf0e10cSrcweir CFRelease(dictLabel);
712cdf0e10cSrcweir CFRelease(localizedDictKey);
713cdf0e10cSrcweir }
714cdf0e10cSrcweir
715cdf0e10cSrcweir /* Combine all of the macabfields in each MacabHeader into the
716cdf0e10cSrcweir * headerNames array, which (at the end of this method) is used
717cdf0e10cSrcweir * to create the MacabHeader that is returned.
718cdf0e10cSrcweir */
719cdf0e10cSrcweir headerNames = new macabfield *[length];
720cdf0e10cSrcweir for(i = 0, j = 0, k = 0; i < length; i++,k++)
721cdf0e10cSrcweir {
722cdf0e10cSrcweir while(dictHeaders[j]->getSize() == k)
723cdf0e10cSrcweir {
724cdf0e10cSrcweir j++;
725cdf0e10cSrcweir k = 0;
726cdf0e10cSrcweir }
727cdf0e10cSrcweir
728cdf0e10cSrcweir headerNames[i] = dictHeaders[j]->copy(k);
729cdf0e10cSrcweir }
730cdf0e10cSrcweir
731cdf0e10cSrcweir for(i = 0; i < numRecords; i++)
732cdf0e10cSrcweir delete dictHeaders[i];
733cdf0e10cSrcweir
734cdf0e10cSrcweir delete [] dictHeaders;
735cdf0e10cSrcweir free(dictKeys);
736cdf0e10cSrcweir free(dictValues);
737cdf0e10cSrcweir }
738cdf0e10cSrcweir break;
739cdf0e10cSrcweir
740cdf0e10cSrcweir /* Array */
741cdf0e10cSrcweir case kABArrayProperty:
742cdf0e10cSrcweir /* For non-scalars, we can only get more information if the property
743cdf0e10cSrcweir * actually exists.
744cdf0e10cSrcweir */
745cdf0e10cSrcweir if(_propertyValue != NULL)
746cdf0e10cSrcweir {
747cdf0e10cSrcweir sal_Int32 arrLength = (sal_Int32) CFArrayGetCount( (CFArrayRef) _propertyValue);
748cdf0e10cSrcweir sal_Int32 i,j,k;
749cdf0e10cSrcweir CFTypeRef arrValue;
750cdf0e10cSrcweir ABPropertyType arrType;
751cdf0e10cSrcweir MacabHeader **arrHeaders = new MacabHeader *[arrLength];
752cdf0e10cSrcweir ::rtl::OUString propertyNameString = CFStringToOUString(_propertyName);
753cdf0e10cSrcweir ::rtl::OUString arrLabelString;
754cdf0e10cSrcweir CFStringRef arrLabel;
755cdf0e10cSrcweir
756cdf0e10cSrcweir length = 0;
757cdf0e10cSrcweir /* Go through each element - since the elements here do not have
758cdf0e10cSrcweir * unique keys like the ones in dictionaries, we create a unique
759cdf0e10cSrcweir * key out of the id of the element in the array (the first
760cdf0e10cSrcweir * element gets a 0 plopped onto the end of it, the second a 1...
761cdf0e10cSrcweir * As with dictionaries, the elements could be anything, including
762cdf0e10cSrcweir * another array, so we have to run this method recursively on
763cdf0e10cSrcweir * each element, storing the resulting MacabHeader into an array,
764cdf0e10cSrcweir * which we then combine into one MacabHeader that is returned.
765cdf0e10cSrcweir */
766cdf0e10cSrcweir for(i = 0; i < arrLength; i++)
767cdf0e10cSrcweir {
768cdf0e10cSrcweir arrValue = (CFTypeRef) CFArrayGetValueAtIndex( (CFArrayRef) _propertyValue, i);
769cdf0e10cSrcweir arrType = (ABPropertyType) getABTypeFromCFType( CFGetTypeID(arrValue) );
770cdf0e10cSrcweir arrLabelString = propertyNameString + ::rtl::OUString::valueOf(i);
771cdf0e10cSrcweir arrLabel = OUStringToCFString(arrLabelString);
772cdf0e10cSrcweir arrHeaders[i] = createHeaderForProperty(arrType, arrValue, arrLabel);
773cdf0e10cSrcweir if (!arrHeaders[i])
774cdf0e10cSrcweir arrHeaders[i] = new MacabHeader();
775cdf0e10cSrcweir length += arrHeaders[i]->getSize();
776cdf0e10cSrcweir CFRelease(arrLabel);
777cdf0e10cSrcweir }
778cdf0e10cSrcweir
779cdf0e10cSrcweir headerNames = new macabfield *[length];
780cdf0e10cSrcweir for(i = 0, j = 0, k = 0; i < length; i++,k++)
781cdf0e10cSrcweir {
782cdf0e10cSrcweir while(arrHeaders[j]->getSize() == k)
783cdf0e10cSrcweir {
784cdf0e10cSrcweir j++;
785cdf0e10cSrcweir k = 0;
786cdf0e10cSrcweir }
787cdf0e10cSrcweir
788cdf0e10cSrcweir headerNames[i] = arrHeaders[j]->copy(k);
789cdf0e10cSrcweir }
790cdf0e10cSrcweir for(i = 0; i < arrLength; i++)
791cdf0e10cSrcweir delete arrHeaders[i];
792cdf0e10cSrcweir
793cdf0e10cSrcweir delete [] arrHeaders;
794cdf0e10cSrcweir }
795cdf0e10cSrcweir break;
796cdf0e10cSrcweir
797cdf0e10cSrcweir default:
798cdf0e10cSrcweir break;
799cdf0e10cSrcweir
800cdf0e10cSrcweir }
801cdf0e10cSrcweir
802cdf0e10cSrcweir /* If we succeeded at adding elements to the headerNames array, then
803cdf0e10cSrcweir * length will no longer be 0. If it is, create a new MacabHeader
804cdf0e10cSrcweir * out of the headerNames (after weeding out duplicate headers), and
805cdf0e10cSrcweir * then return the result. If the length is still 0, return NULL: we
806cdf0e10cSrcweir * failed to create a MacabHeader out of this property.
807cdf0e10cSrcweir */
808cdf0e10cSrcweir if(length != 0)
809cdf0e10cSrcweir {
810cdf0e10cSrcweir manageDuplicateHeaders(headerNames, length);
811cdf0e10cSrcweir MacabHeader *headerResult = new MacabHeader(length, headerNames);
812cdf0e10cSrcweir delete [] headerNames;
813cdf0e10cSrcweir return headerResult;
814cdf0e10cSrcweir }
815cdf0e10cSrcweir else
816cdf0e10cSrcweir return NULL;
817cdf0e10cSrcweir }
818cdf0e10cSrcweir
819cdf0e10cSrcweir // -------------------------------------------------------------------------
manageDuplicateHeaders(macabfield ** _headerNames,const sal_Int32 _length) const820cdf0e10cSrcweir void MacabRecords::manageDuplicateHeaders(macabfield **_headerNames, const sal_Int32 _length) const
821cdf0e10cSrcweir {
822cdf0e10cSrcweir /* If we have two cases of, say, phone: home, this makes it:
823cdf0e10cSrcweir * phone: home (1)
824cdf0e10cSrcweir * phone: home (2)
825cdf0e10cSrcweir */
826cdf0e10cSrcweir sal_Int32 i, j;
827cdf0e10cSrcweir sal_Int32 count;
828cdf0e10cSrcweir for(i = _length-1; i >= 0; i--)
829cdf0e10cSrcweir {
830cdf0e10cSrcweir count = 1;
831cdf0e10cSrcweir for( j = i-1; j >= 0; j--)
832cdf0e10cSrcweir {
833cdf0e10cSrcweir if(CFEqual(_headerNames[i]->value, _headerNames[j]->value))
834cdf0e10cSrcweir {
835cdf0e10cSrcweir count++;
836cdf0e10cSrcweir }
837cdf0e10cSrcweir }
838cdf0e10cSrcweir
839cdf0e10cSrcweir // duplicate!
840cdf0e10cSrcweir if(count != 1)
841cdf0e10cSrcweir {
842cdf0e10cSrcweir // There is probably a better way to do this...
843cdf0e10cSrcweir ::rtl::OUString newName = CFStringToOUString((CFStringRef) _headerNames[i]->value);
844cdf0e10cSrcweir CFRelease(_headerNames[i]->value);
845cdf0e10cSrcweir newName += ::rtl::OUString::createFromAscii(" (") + ::rtl::OUString::valueOf(count) + ::rtl::OUString::createFromAscii(")");
846cdf0e10cSrcweir _headerNames[i]->value = OUStringToCFString(newName);
847cdf0e10cSrcweir }
848cdf0e10cSrcweir }
849cdf0e10cSrcweir }
850cdf0e10cSrcweir
851cdf0e10cSrcweir // -------------------------------------------------------------------------
852cdf0e10cSrcweir /* Create a MacabRecord out of an ABRecord, using a given MacabHeader and
853cdf0e10cSrcweir * the record's type. We go through each property for this record type
854cdf0e10cSrcweir * then process it much like we processed the header (above), with two
855cdf0e10cSrcweir * exceptions: if we come upon something not in the header, we ignore it
856cdf0e10cSrcweir * (it's something we don't want to add), and once we find a corresponding
857cdf0e10cSrcweir * location in the header, we store the property and the property type in
858cdf0e10cSrcweir * a macabfield. (For the header, we stored the property type and the name
859cdf0e10cSrcweir * of the property as a CFString.)
860cdf0e10cSrcweir */
createMacabRecord(const ABRecordRef _abrecord,const MacabHeader * _header,const CFStringRef _recordType) const861cdf0e10cSrcweir MacabRecord *MacabRecords::createMacabRecord(const ABRecordRef _abrecord, const MacabHeader *_header, const CFStringRef _recordType) const
862cdf0e10cSrcweir {
863cdf0e10cSrcweir /* The new record that we will create... */
864cdf0e10cSrcweir MacabRecord *macabRecord = new MacabRecord(_header->getSize());
865cdf0e10cSrcweir
866cdf0e10cSrcweir CFArrayRef recordProperties = ABCopyArrayOfPropertiesForRecordType(addressBook, _recordType);
867cdf0e10cSrcweir sal_Int32 numProperties = (sal_Int32) CFArrayGetCount(recordProperties);
868cdf0e10cSrcweir
869cdf0e10cSrcweir sal_Int32 i;
870cdf0e10cSrcweir
871cdf0e10cSrcweir CFTypeRef propertyValue;
872cdf0e10cSrcweir ABPropertyType propertyType;
873cdf0e10cSrcweir
874cdf0e10cSrcweir CFStringRef propertyName, localizedPropertyName;
875cdf0e10cSrcweir ::rtl::OUString propertyNameString;
876cdf0e10cSrcweir for(i = 0; i < numProperties; i++)
877cdf0e10cSrcweir {
878cdf0e10cSrcweir propertyName = (CFStringRef) CFArrayGetValueAtIndex(recordProperties, i);
879cdf0e10cSrcweir localizedPropertyName = ABCopyLocalizedPropertyOrLabel(propertyName);
880cdf0e10cSrcweir propertyNameString = CFStringToOUString(localizedPropertyName);
881cdf0e10cSrcweir CFRelease(localizedPropertyName);
882cdf0e10cSrcweir
883cdf0e10cSrcweir /* Get the property's value */
884cdf0e10cSrcweir propertyValue = ABRecordCopyValue(_abrecord,propertyName);
885cdf0e10cSrcweir if(propertyValue != NULL)
886cdf0e10cSrcweir {
887cdf0e10cSrcweir propertyType = ABTypeOfProperty(addressBook, _recordType, propertyName);
888cdf0e10cSrcweir if(propertyType != kABErrorInProperty)
889cdf0e10cSrcweir insertPropertyIntoMacabRecord(propertyType, macabRecord, _header, propertyNameString, propertyValue);
890cdf0e10cSrcweir
891cdf0e10cSrcweir CFRelease(propertyValue);
892cdf0e10cSrcweir }
893cdf0e10cSrcweir }
894cdf0e10cSrcweir CFRelease(recordProperties);
895cdf0e10cSrcweir return macabRecord;
896cdf0e10cSrcweir }
897cdf0e10cSrcweir
898cdf0e10cSrcweir // -------------------------------------------------------------------------
899cdf0e10cSrcweir /* Inserts a given property into a MacabRecord. This method calls another
900cdf0e10cSrcweir * method by the same name after getting the property type (it only
901cdf0e10cSrcweir * receives the property value). It is called when we aren't given the
902cdf0e10cSrcweir * property's type already.
903cdf0e10cSrcweir */
insertPropertyIntoMacabRecord(MacabRecord * _abrecord,const MacabHeader * _header,const::rtl::OUString _propertyName,const CFTypeRef _propertyValue) const904cdf0e10cSrcweir void MacabRecords::insertPropertyIntoMacabRecord(MacabRecord *_abrecord, const MacabHeader *_header, const ::rtl::OUString _propertyName, const CFTypeRef _propertyValue) const
905cdf0e10cSrcweir {
906cdf0e10cSrcweir CFTypeID cf_type = CFGetTypeID(_propertyValue);
907cdf0e10cSrcweir ABPropertyType ab_type = getABTypeFromCFType( cf_type );
908cdf0e10cSrcweir
909cdf0e10cSrcweir if(ab_type != kABErrorInProperty)
910cdf0e10cSrcweir insertPropertyIntoMacabRecord(ab_type, _abrecord, _header, _propertyName, _propertyValue);
911cdf0e10cSrcweir }
912cdf0e10cSrcweir
913cdf0e10cSrcweir // -------------------------------------------------------------------------
914cdf0e10cSrcweir /* Inserts a given property into a MacabRecord. This method is recursive
915cdf0e10cSrcweir * because properties can contain many sub-properties.
916cdf0e10cSrcweir */
insertPropertyIntoMacabRecord(const ABPropertyType _propertyType,MacabRecord * _abrecord,const MacabHeader * _header,const::rtl::OUString _propertyName,const CFTypeRef _propertyValue) const917cdf0e10cSrcweir void MacabRecords::insertPropertyIntoMacabRecord(const ABPropertyType _propertyType, MacabRecord *_abrecord, const MacabHeader *_header, const ::rtl::OUString _propertyName, const CFTypeRef _propertyValue) const
918cdf0e10cSrcweir {
919cdf0e10cSrcweir /* If there is no value, return */
920cdf0e10cSrcweir if(_propertyValue == NULL)
921cdf0e10cSrcweir return;
922cdf0e10cSrcweir
923cdf0e10cSrcweir /* The main switch statement */
924cdf0e10cSrcweir switch(_propertyType)
925cdf0e10cSrcweir {
926cdf0e10cSrcweir /* Scalars */
927cdf0e10cSrcweir case kABStringProperty:
928cdf0e10cSrcweir case kABRealProperty:
929cdf0e10cSrcweir case kABIntegerProperty:
930cdf0e10cSrcweir case kABDateProperty:
931cdf0e10cSrcweir {
932cdf0e10cSrcweir /* Only scalars actually insert a property into the MacabRecord.
933cdf0e10cSrcweir * In all other cases, this method is called recursively until a
934cdf0e10cSrcweir * scalar type, an error, or an unknown type are found.
935cdf0e10cSrcweir * Because of that, the following checks only occur for this type.
936cdf0e10cSrcweir * We store whether we have successfully placed this property
93707a3d7f1SPedro Giffuni * into the MacabRecord (or whether an unrecoverable error occurred).
938cdf0e10cSrcweir * Then, we try over and over again to place the property into the
939cdf0e10cSrcweir * record. There are three possible results:
940cdf0e10cSrcweir * 1) Success!
941cdf0e10cSrcweir * 2) There is already a property stored at the column of this name,
942cdf0e10cSrcweir * in which case we have a duplicate header (see the method
943cdf0e10cSrcweir * manageDuplicateHeaders()). If that is the case, we add an ID
944cdf0e10cSrcweir * to the end of the column name in the same format as we do in
945cdf0e10cSrcweir * manageDuplicateHeaders() and try again.
946cdf0e10cSrcweir * 3) No column of this name exists in the header. In this case,
947cdf0e10cSrcweir * there is nothing we can do: we have failed to place this
948cdf0e10cSrcweir * property into the record.
949cdf0e10cSrcweir */
950cdf0e10cSrcweir sal_Bool bPlaced = sal_False;
951cdf0e10cSrcweir ::rtl::OUString columnName = ::rtl::OUString(_propertyName);
952cdf0e10cSrcweir sal_Int32 i = 1;
953cdf0e10cSrcweir
954cdf0e10cSrcweir // A big safeguard to prevent two fields from having the same name.
955cdf0e10cSrcweir while(bPlaced != sal_True)
956cdf0e10cSrcweir {
957cdf0e10cSrcweir sal_Int32 columnNumber = _header->getColumnNumber(columnName);
958cdf0e10cSrcweir bPlaced = sal_True;
959cdf0e10cSrcweir if(columnNumber != -1)
960cdf0e10cSrcweir {
961cdf0e10cSrcweir // collision! A property already exists here!
962cdf0e10cSrcweir if(_abrecord->get(columnNumber) != NULL)
963cdf0e10cSrcweir {
964cdf0e10cSrcweir bPlaced = sal_False;
965cdf0e10cSrcweir i++;
966cdf0e10cSrcweir columnName = ::rtl::OUString(_propertyName) + ::rtl::OUString::createFromAscii(" (") + ::rtl::OUString::valueOf(i) + ::rtl::OUString::createFromAscii(")");
967cdf0e10cSrcweir }
968cdf0e10cSrcweir
969cdf0e10cSrcweir // success!
970cdf0e10cSrcweir else
971cdf0e10cSrcweir {
972cdf0e10cSrcweir _abrecord->insertAtColumn(_propertyValue, _propertyType, columnNumber);
973cdf0e10cSrcweir }
974cdf0e10cSrcweir }
975cdf0e10cSrcweir }
976cdf0e10cSrcweir }
977cdf0e10cSrcweir break;
978cdf0e10cSrcweir
979cdf0e10cSrcweir /* Array */
980cdf0e10cSrcweir case kABArrayProperty:
981cdf0e10cSrcweir {
982cdf0e10cSrcweir /* An array is basically just a list of anything, so all we do
983cdf0e10cSrcweir * is go through the array, and rerun this method recursively
984cdf0e10cSrcweir * on each element.
985cdf0e10cSrcweir */
986cdf0e10cSrcweir sal_Int32 arrLength = (sal_Int32) CFArrayGetCount( (CFArrayRef) _propertyValue);
987cdf0e10cSrcweir sal_Int32 i;
988cdf0e10cSrcweir const void *arrValue;
989cdf0e10cSrcweir ::rtl::OUString newPropertyName;
990cdf0e10cSrcweir
991cdf0e10cSrcweir /* Going through each element... */
992cdf0e10cSrcweir for(i = 0; i < arrLength; i++)
993cdf0e10cSrcweir {
994cdf0e10cSrcweir arrValue = CFArrayGetValueAtIndex( (CFArrayRef) _propertyValue, i);
995cdf0e10cSrcweir newPropertyName = _propertyName + ::rtl::OUString::valueOf(i);
996cdf0e10cSrcweir insertPropertyIntoMacabRecord(_abrecord, _header, newPropertyName, arrValue);
997cdf0e10cSrcweir CFRelease(arrValue);
998cdf0e10cSrcweir }
999cdf0e10cSrcweir
1000cdf0e10cSrcweir }
1001cdf0e10cSrcweir break;
1002cdf0e10cSrcweir
1003cdf0e10cSrcweir /* Dictionary */
1004cdf0e10cSrcweir case kABDictionaryProperty:
1005cdf0e10cSrcweir {
1006cdf0e10cSrcweir /* A dictionary is basically a hashmap. Technically, it can
1007cdf0e10cSrcweir * hold any object as a key and any object as a value.
1008cdf0e10cSrcweir * For our case, we assume that the key is a string (so that
1009cdf0e10cSrcweir * we can use the key to get the column name and match it against
1010cdf0e10cSrcweir * the header), but we don't assume anything about the value, so
1011cdf0e10cSrcweir * we run this method recursively (or, rather, we run the version
1012cdf0e10cSrcweir * of this method for when we don't know the object's type) until
1013cdf0e10cSrcweir * we hit a scalar value.
1014cdf0e10cSrcweir */
1015cdf0e10cSrcweir
1016cdf0e10cSrcweir sal_Int32 numRecords = (sal_Int32) CFDictionaryGetCount((CFDictionaryRef) _propertyValue);
1017cdf0e10cSrcweir ::rtl::OUString dictKeyString;
1018cdf0e10cSrcweir sal_Int32 i;
1019cdf0e10cSrcweir ::rtl::OUString newPropertyName;
1020cdf0e10cSrcweir
1021cdf0e10cSrcweir /* Unfortunately, the only way to get both keys and values out
1022cdf0e10cSrcweir * of a dictionary in Carbon is to get them all at once, so we
1023cdf0e10cSrcweir * do that.
1024cdf0e10cSrcweir */
1025cdf0e10cSrcweir CFStringRef *dictKeys;
1026cdf0e10cSrcweir CFStringRef localizedDictKey;
1027cdf0e10cSrcweir CFTypeRef *dictValues;
1028cdf0e10cSrcweir dictKeys = (CFStringRef *) malloc(sizeof(CFStringRef)*numRecords);
1029cdf0e10cSrcweir dictValues = (CFTypeRef *) malloc(sizeof(CFTypeRef)*numRecords);
1030cdf0e10cSrcweir CFDictionaryGetKeysAndValues((CFDictionaryRef) _propertyValue, (const void **) dictKeys, (const void **) dictValues);
1031cdf0e10cSrcweir
1032cdf0e10cSrcweir /* Going through each element... */
1033cdf0e10cSrcweir for(i = 0; i < numRecords; i++)
1034cdf0e10cSrcweir {
1035cdf0e10cSrcweir localizedDictKey = ABCopyLocalizedPropertyOrLabel(dictKeys[i]);
1036cdf0e10cSrcweir dictKeyString = CFStringToOUString(localizedDictKey);
1037cdf0e10cSrcweir CFRelease(localizedDictKey);
1038cdf0e10cSrcweir newPropertyName = _propertyName + ::rtl::OUString::createFromAscii(": ") + fixLabel(dictKeyString);
1039cdf0e10cSrcweir insertPropertyIntoMacabRecord(_abrecord, _header, newPropertyName, dictValues[i]);
1040cdf0e10cSrcweir }
1041cdf0e10cSrcweir
1042cdf0e10cSrcweir free(dictKeys);
1043cdf0e10cSrcweir free(dictValues);
1044cdf0e10cSrcweir }
1045cdf0e10cSrcweir break;
1046cdf0e10cSrcweir
1047cdf0e10cSrcweir /* Multivalue */
1048cdf0e10cSrcweir case kABMultiIntegerProperty:
1049cdf0e10cSrcweir case kABMultiDateProperty:
1050cdf0e10cSrcweir case kABMultiStringProperty:
1051cdf0e10cSrcweir case kABMultiRealProperty:
1052cdf0e10cSrcweir case kABMultiDataProperty:
1053cdf0e10cSrcweir case kABMultiDictionaryProperty:
1054cdf0e10cSrcweir case kABMultiArrayProperty:
1055cdf0e10cSrcweir {
1056cdf0e10cSrcweir /* All scalar multivalues are handled in the same way. Each element
1057cdf0e10cSrcweir * is a label and a value. All labels are strings
1058cdf0e10cSrcweir * (kABStringProperty), and all values have the same type
1059cdf0e10cSrcweir * (which is the type of the multivalue minus 255, or as
1060cdf0e10cSrcweir * Carbon's list of property types has it, minus 0x100.
1061cdf0e10cSrcweir * We just get the correct type, then go through each element
1062cdf0e10cSrcweir * and get the label and value and print them in a list.
1063cdf0e10cSrcweir */
1064cdf0e10cSrcweir
1065cdf0e10cSrcweir sal_Int32 i;
1066cdf0e10cSrcweir sal_Int32 multiLength = ABMultiValueCount((ABMutableMultiValueRef) _propertyValue);
1067cdf0e10cSrcweir CFStringRef multiLabel, localizedMultiLabel;
1068cdf0e10cSrcweir CFTypeRef multiValue;
1069cdf0e10cSrcweir ::rtl::OUString multiLabelString, newPropertyName;
1070cdf0e10cSrcweir ABPropertyType multiType = (ABPropertyType) (ABMultiValuePropertyType((ABMutableMultiValueRef) _propertyValue) - 0x100);
1071cdf0e10cSrcweir
1072cdf0e10cSrcweir /* Go through each element... */
1073cdf0e10cSrcweir for(i = 0; i < multiLength; i++)
1074cdf0e10cSrcweir {
1075cdf0e10cSrcweir /* Label and value */
1076cdf0e10cSrcweir multiLabel = ABMultiValueCopyLabelAtIndex((ABMutableMultiValueRef) _propertyValue, i);
1077cdf0e10cSrcweir multiValue = ABMultiValueCopyValueAtIndex((ABMutableMultiValueRef) _propertyValue, i);
1078cdf0e10cSrcweir
1079cdf0e10cSrcweir localizedMultiLabel = ABCopyLocalizedPropertyOrLabel(multiLabel);
1080cdf0e10cSrcweir multiLabelString = CFStringToOUString(localizedMultiLabel);
1081cdf0e10cSrcweir newPropertyName = _propertyName + ::rtl::OUString::createFromAscii(": ") + fixLabel(multiLabelString);
1082cdf0e10cSrcweir insertPropertyIntoMacabRecord(multiType, _abrecord, _header, newPropertyName, multiValue);
1083cdf0e10cSrcweir
1084cdf0e10cSrcweir /* free our variables */
1085cdf0e10cSrcweir CFRelease(multiLabel);
1086cdf0e10cSrcweir CFRelease(localizedMultiLabel);
1087cdf0e10cSrcweir CFRelease(multiValue);
1088cdf0e10cSrcweir }
1089cdf0e10cSrcweir }
1090cdf0e10cSrcweir break;
1091cdf0e10cSrcweir
1092cdf0e10cSrcweir /* Unhandled types */
1093cdf0e10cSrcweir case kABErrorInProperty:
1094cdf0e10cSrcweir case kABDataProperty:
1095cdf0e10cSrcweir default:
1096cdf0e10cSrcweir /* An error, as far as I have seen, only shows up as a type
1097cdf0e10cSrcweir * returned by a function for dictionaries when the dictionary
1098cdf0e10cSrcweir * holds many types of values. Since we do not use that function,
1099cdf0e10cSrcweir * it shouldn't come up. I have yet to see the kABDataProperty,
1100cdf0e10cSrcweir * and I am not sure how to represent it as a string anyway,
1101cdf0e10cSrcweir * since it appears to just be a bunch of bytes. Assumably, if
1102cdf0e10cSrcweir * these bytes made up a string, the type would be
1103cdf0e10cSrcweir * kABStringProperty. I think that this is used when we are not
1104cdf0e10cSrcweir * sure what the type is (e.g., it could be a string or a number).
1105cdf0e10cSrcweir * That being the case, I still don't know how to represent it.
1106cdf0e10cSrcweir * And, default should never come up, since we've exhausted all
1107cdf0e10cSrcweir * of the possible types for ABPropertyType, but... just in case.
1108cdf0e10cSrcweir */
1109cdf0e10cSrcweir break;
1110cdf0e10cSrcweir }
1111cdf0e10cSrcweir
1112cdf0e10cSrcweir }
1113cdf0e10cSrcweir
1114cdf0e10cSrcweir // -------------------------------------------------------------------------
getABTypeFromCFType(const CFTypeID cf_type) const1115cdf0e10cSrcweir ABPropertyType MacabRecords::getABTypeFromCFType(const CFTypeID cf_type ) const
1116cdf0e10cSrcweir {
1117cdf0e10cSrcweir sal_Int32 i;
1118cdf0e10cSrcweir for(i = 0; i < lcl_CFTypesLength; i++)
1119cdf0e10cSrcweir {
1120cdf0e10cSrcweir /* A match! */
1121cdf0e10cSrcweir if(lcl_CFTypes[i].cf == (sal_Int32) cf_type)
1122cdf0e10cSrcweir {
1123cdf0e10cSrcweir return (ABPropertyType) lcl_CFTypes[i].ab;
1124cdf0e10cSrcweir }
1125cdf0e10cSrcweir }
1126cdf0e10cSrcweir return kABErrorInProperty;
1127cdf0e10cSrcweir }
1128cdf0e10cSrcweir
1129cdf0e10cSrcweir // -------------------------------------------------------------------------
size() const1130cdf0e10cSrcweir sal_Int32 MacabRecords::size() const
1131cdf0e10cSrcweir {
1132cdf0e10cSrcweir return currentRecord;
1133cdf0e10cSrcweir }
1134cdf0e10cSrcweir
1135cdf0e10cSrcweir // -------------------------------------------------------------------------
begin()1136cdf0e10cSrcweir MacabRecords *MacabRecords::begin()
1137cdf0e10cSrcweir {
1138cdf0e10cSrcweir return this;
1139cdf0e10cSrcweir }
1140cdf0e10cSrcweir
1141cdf0e10cSrcweir // -------------------------------------------------------------------------
iterator()1142cdf0e10cSrcweir MacabRecords::iterator::iterator ()
1143cdf0e10cSrcweir {
1144cdf0e10cSrcweir }
1145cdf0e10cSrcweir
1146cdf0e10cSrcweir // -------------------------------------------------------------------------
~iterator()1147cdf0e10cSrcweir MacabRecords::iterator::~iterator ()
1148cdf0e10cSrcweir {
1149cdf0e10cSrcweir }
1150cdf0e10cSrcweir
1151cdf0e10cSrcweir // -------------------------------------------------------------------------
operator =(MacabRecords * _records)1152cdf0e10cSrcweir void MacabRecords::iterator::operator= (MacabRecords *_records)
1153cdf0e10cSrcweir {
1154cdf0e10cSrcweir id = 0;
1155cdf0e10cSrcweir records = _records;
1156cdf0e10cSrcweir }
1157cdf0e10cSrcweir
1158cdf0e10cSrcweir // -------------------------------------------------------------------------
operator ++()1159cdf0e10cSrcweir void MacabRecords::iterator::operator++ ()
1160cdf0e10cSrcweir {
1161cdf0e10cSrcweir id++;
1162cdf0e10cSrcweir }
1163cdf0e10cSrcweir
1164cdf0e10cSrcweir // -------------------------------------------------------------------------
operator !=(const sal_Int32 i) const1165cdf0e10cSrcweir sal_Bool MacabRecords::iterator::operator!= (const sal_Int32 i) const
1166cdf0e10cSrcweir {
1167cdf0e10cSrcweir return(id != i);
1168cdf0e10cSrcweir }
1169cdf0e10cSrcweir
1170cdf0e10cSrcweir // -------------------------------------------------------------------------
operator ==(const sal_Int32 i) const1171cdf0e10cSrcweir sal_Bool MacabRecords::iterator::operator== (const sal_Int32 i) const
1172cdf0e10cSrcweir {
1173cdf0e10cSrcweir return(id == i);
1174cdf0e10cSrcweir }
1175cdf0e10cSrcweir
1176cdf0e10cSrcweir // -------------------------------------------------------------------------
operator *() const1177cdf0e10cSrcweir MacabRecord *MacabRecords::iterator::operator* () const
1178cdf0e10cSrcweir {
1179cdf0e10cSrcweir return records->getRecord(id);
1180cdf0e10cSrcweir }
1181cdf0e10cSrcweir
1182cdf0e10cSrcweir // -------------------------------------------------------------------------
end() const1183cdf0e10cSrcweir sal_Int32 MacabRecords::end() const
1184cdf0e10cSrcweir {
1185cdf0e10cSrcweir return currentRecord;
1186cdf0e10cSrcweir }
1187cdf0e10cSrcweir
1188cdf0e10cSrcweir // -------------------------------------------------------------------------
swap(const sal_Int32 _id1,const sal_Int32 _id2)1189cdf0e10cSrcweir void MacabRecords::swap(const sal_Int32 _id1, const sal_Int32 _id2)
1190cdf0e10cSrcweir {
1191cdf0e10cSrcweir MacabRecord *swapRecord = records[_id1];
1192cdf0e10cSrcweir
1193cdf0e10cSrcweir records[_id1] = records[_id2];
1194cdf0e10cSrcweir records[_id2] = swapRecord;
1195cdf0e10cSrcweir }
1196cdf0e10cSrcweir
1197cdf0e10cSrcweir // -------------------------------------------------------------------------
setName(const::rtl::OUString _sName)1198cdf0e10cSrcweir void MacabRecords::setName(const ::rtl::OUString _sName)
1199cdf0e10cSrcweir {
1200cdf0e10cSrcweir m_sName = _sName;
1201cdf0e10cSrcweir }
1202cdf0e10cSrcweir
1203cdf0e10cSrcweir // -------------------------------------------------------------------------
getName() const1204cdf0e10cSrcweir ::rtl::OUString MacabRecords::getName() const
1205cdf0e10cSrcweir {
1206cdf0e10cSrcweir return m_sName;
1207cdf0e10cSrcweir }
1208