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