1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_connectivity.hxx"
26
27 #include "MacabAddressBook.hxx"
28 #include "MacabRecords.hxx"
29 #include "MacabGroup.hxx"
30
31 #include <vector>
32
33 #include <premac.h>
34 #include <Carbon/Carbon.h>
35 #include <AddressBook/ABAddressBookC.h>
36 #include <postmac.h>
37 #include "connectivity/CommonTools.hxx"
38
39 using namespace connectivity::macab;
40 using namespace ::com::sun::star::uno;
41
42 // -----------------------------------------------------------------------------
MacabAddressBook()43 MacabAddressBook::MacabAddressBook( )
44 {
45 m_aAddressBook = ABGetSharedAddressBook();
46 m_xMacabRecords = NULL;
47 m_bRetrievedGroups = sal_False;
48 }
49
50 // -----------------------------------------------------------------------------
~MacabAddressBook()51 MacabAddressBook::~MacabAddressBook()
52 {
53 if(m_xMacabRecords != NULL)
54 {
55 delete m_xMacabRecords;
56 m_xMacabRecords = NULL;
57 }
58
59 if(!m_xMacabGroups.empty())
60 {
61 ::std::vector<MacabGroup *>::iterator iter, end;
62 iter = m_xMacabGroups.begin();
63 end = m_xMacabGroups.end();
64 for( ; iter != end; ++iter)
65 delete (*iter);
66 }
67
68 m_bRetrievedGroups = sal_False;
69 }
70
71 // -----------------------------------------------------------------------------
72 /* Get the address book's default table name. This is the table name that
73 * refers to the table containing _all_ records in the address book.
74 */
getDefaultTableName()75 const ::rtl::OUString & MacabAddressBook::getDefaultTableName()
76 {
77 /* This string probably needs to be localized. */
78 static const ::rtl::OUString aDefaultTableName
79 (::rtl::OUString::createFromAscii("Address Book"));
80
81 return aDefaultTableName;
82 }
83
84 // -----------------------------------------------------------------------------
getMacabRecords()85 MacabRecords *MacabAddressBook::getMacabRecords()
86 {
87 /* If the MacabRecords don't exist, create them. */
88 if(m_xMacabRecords == NULL)
89 {
90 m_xMacabRecords = new MacabRecords(m_aAddressBook);
91 m_xMacabRecords->setName(getDefaultTableName());
92 m_xMacabRecords->initialize();
93 }
94
95 return m_xMacabRecords;
96 }
97
98 // -----------------------------------------------------------------------------
99 /* Get the MacabRecords for a given name: either a group name or the
100 * default table name.
101 */
getMacabRecords(const::rtl::OUString _tableName)102 MacabRecords *MacabAddressBook::getMacabRecords(const ::rtl::OUString _tableName)
103 {
104 if(_tableName == getDefaultTableName())
105 {
106 return getMacabRecords();
107 }
108 else
109 {
110 return getMacabGroup(_tableName);
111 }
112 }
113
114 // -----------------------------------------------------------------------------
getMacabRecordsMatch(const::rtl::OUString _tableName)115 MacabRecords *MacabAddressBook::getMacabRecordsMatch(const ::rtl::OUString _tableName)
116 {
117 if(match(_tableName, getDefaultTableName(), '\0'))
118 {
119 return getMacabRecords();
120 }
121
122 return getMacabGroupMatch(_tableName);
123 }
124
125 // -----------------------------------------------------------------------------
getMacabGroups()126 ::std::vector<MacabGroup *> MacabAddressBook::getMacabGroups()
127 {
128 /* If the MacabGroups haven't been created yet, create them. */
129 if(m_bRetrievedGroups == sal_False)
130 {
131 /* If the MacabRecords haven't been created yet, create them. */
132 if(m_xMacabRecords == NULL)
133 {
134 m_xMacabRecords = new MacabRecords(m_aAddressBook);
135 m_xMacabRecords->setName(getDefaultTableName());
136 m_xMacabRecords->initialize();
137 }
138
139 CFArrayRef allGroups = ABCopyArrayOfAllGroups(m_aAddressBook);
140 sal_Int32 nGroups = CFArrayGetCount(allGroups);
141 m_xMacabGroups = ::std::vector<MacabGroup *>(nGroups);
142
143 sal_Int32 i;
144 ABGroupRef xGroup;
145
146 /* Go through each group and create a MacabGroup out of it. */
147 for(i = 0; i < nGroups; i++)
148 {
149 xGroup = (ABGroupRef) CFArrayGetValueAtIndex(allGroups, i);
150 m_xMacabGroups[i] = new MacabGroup(m_aAddressBook, m_xMacabRecords, xGroup);
151 }
152
153 CFRelease(allGroups);
154
155 /* Manage duplicates. */
156 manageDuplicateGroups(m_xMacabGroups);
157 m_bRetrievedGroups = sal_True;
158 }
159
160 return m_xMacabGroups;
161 }
162
163 // -----------------------------------------------------------------------------
getMacabGroup(::rtl::OUString _groupName)164 MacabGroup *MacabAddressBook::getMacabGroup(::rtl::OUString _groupName)
165 {
166 // initialize groups if not already initialized
167 if(m_bRetrievedGroups == sal_False)
168 getMacabGroups();
169
170 sal_Int32 nGroups = m_xMacabGroups.size();
171 sal_Int32 i;
172
173 for(i = 0; i < nGroups; i++)
174 {
175 if(m_xMacabGroups[i] != NULL)
176 {
177 if(m_xMacabGroups[i]->getName() == _groupName)
178 {
179 return m_xMacabGroups[i];
180 }
181 }
182 }
183
184 return NULL;
185 }
186
187 // -----------------------------------------------------------------------------
getMacabGroupMatch(::rtl::OUString _groupName)188 MacabGroup *MacabAddressBook::getMacabGroupMatch(::rtl::OUString _groupName)
189 {
190 // initialize groups if not already initialized
191 if(m_bRetrievedGroups == sal_False)
192 getMacabGroups();
193
194 sal_Int32 nGroups = m_xMacabGroups.size();
195 sal_Int32 i;
196
197 for(i = 0; i < nGroups; i++)
198 {
199 if(m_xMacabGroups[i] != NULL)
200 {
201 if(match(m_xMacabGroups[i]->getName(), _groupName, '\0'))
202 {
203 return m_xMacabGroups[i];
204 }
205 }
206 }
207
208 return NULL;
209 }
210
211 // -------------------------------------------------------------------------
manageDuplicateGroups(::std::vector<MacabGroup * > _xGroups) const212 void MacabAddressBook::manageDuplicateGroups(::std::vector<MacabGroup *> _xGroups) const
213 {
214 /* If we have two cases of groups, say, family, this makes it:
215 * family
216 * family (2)
217 */
218 ::std::vector<MacabGroup *>::reverse_iterator iter1, iter2;
219 sal_Int32 count;
220
221 for(iter1 = _xGroups.rbegin(); iter1 != _xGroups.rend(); ++iter1)
222 {
223 /* If the name matches the default table name, there is already
224 * (obviously) a conflict. So, start the count of groups with this
225 * name at 2 instead of 1.
226 */
227 if( (*iter1)->getName() == getDefaultTableName() )
228 count = 2;
229 else
230 count = 1;
231
232 iter2 = iter1;
233 for( ++iter2; iter2 != _xGroups.rend(); ++iter2)
234 {
235 if( (*iter1)->getName() == (*iter2)->getName() )
236 {
237 count++;
238 }
239 }
240
241 // duplicate!
242 if(count != 1)
243 {
244 ::rtl::OUString sName = (*iter1)->getName();
245 sName += ::rtl::OUString::createFromAscii(" (") +
246 ::rtl::OUString::valueOf(count) +
247 ::rtl::OUString::createFromAscii(")");
248 (*iter1)->setName(sName);
249 }
250 }
251 }
252
253