xref: /trunk/main/connectivity/source/drivers/macab/MacabAddressBook.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_connectivity.hxx"
30 
31 #include "MacabAddressBook.hxx"
32 #include "MacabRecords.hxx"
33 #include "MacabGroup.hxx"
34 
35 #include <vector>
36 
37 #include <premac.h>
38 #include <Carbon/Carbon.h>
39 #include <AddressBook/ABAddressBookC.h>
40 #include <postmac.h>
41 #include "connectivity/CommonTools.hxx"
42 
43 using namespace connectivity::macab;
44 using namespace ::com::sun::star::uno;
45 
46 // -----------------------------------------------------------------------------
47 MacabAddressBook::MacabAddressBook( )
48 {
49     m_aAddressBook = ABGetSharedAddressBook();
50     m_xMacabRecords = NULL;
51     m_bRetrievedGroups = sal_False;
52 }
53 
54 // -----------------------------------------------------------------------------
55 MacabAddressBook::~MacabAddressBook()
56 {
57     if(m_xMacabRecords != NULL)
58     {
59         delete m_xMacabRecords;
60         m_xMacabRecords = NULL;
61     }
62 
63     if(!m_xMacabGroups.empty())
64     {
65         ::std::vector<MacabGroup *>::iterator iter, end;
66         iter = m_xMacabGroups.begin();
67         end = m_xMacabGroups.end();
68         for( ; iter != end; ++iter)
69             delete (*iter);
70     }
71 
72     m_bRetrievedGroups = sal_False;
73 }
74 
75 // -----------------------------------------------------------------------------
76 /* Get the address book's default table name. This is the table name that
77  * refers to the table containing _all_ records in the address book.
78  */
79 const ::rtl::OUString & MacabAddressBook::getDefaultTableName()
80 {
81     /* This string probably needs to be localized. */
82     static const ::rtl::OUString aDefaultTableName
83         (::rtl::OUString::createFromAscii("Address Book"));
84 
85     return aDefaultTableName;
86 }
87 
88 // -----------------------------------------------------------------------------
89 MacabRecords *MacabAddressBook::getMacabRecords()
90 {
91     /* If the MacabRecords don't exist, create them. */
92     if(m_xMacabRecords == NULL)
93     {
94         m_xMacabRecords = new MacabRecords(m_aAddressBook);
95         m_xMacabRecords->setName(getDefaultTableName());
96         m_xMacabRecords->initialize();
97     }
98 
99     return m_xMacabRecords;
100 }
101 
102 // -----------------------------------------------------------------------------
103 /* Get the MacabRecords for a given name: either a group name or the
104  * default table name.
105  */
106 MacabRecords *MacabAddressBook::getMacabRecords(const ::rtl::OUString _tableName)
107 {
108     if(_tableName == getDefaultTableName())
109     {
110         return getMacabRecords();
111     }
112     else
113     {
114         return getMacabGroup(_tableName);
115     }
116 }
117 
118 // -----------------------------------------------------------------------------
119 MacabRecords *MacabAddressBook::getMacabRecordsMatch(const ::rtl::OUString _tableName)
120 {
121     if(match(_tableName, getDefaultTableName(), '\0'))
122     {
123         return getMacabRecords();
124     }
125 
126     return getMacabGroupMatch(_tableName);
127 }
128 
129 // -----------------------------------------------------------------------------
130 ::std::vector<MacabGroup *> MacabAddressBook::getMacabGroups()
131 {
132     /* If the MacabGroups haven't been created yet, create them. */
133     if(m_bRetrievedGroups == sal_False)
134     {
135         /* If the MacabRecords haven't been created yet, create them. */
136         if(m_xMacabRecords == NULL)
137         {
138             m_xMacabRecords = new MacabRecords(m_aAddressBook);
139             m_xMacabRecords->setName(getDefaultTableName());
140             m_xMacabRecords->initialize();
141         }
142 
143         CFArrayRef allGroups = ABCopyArrayOfAllGroups(m_aAddressBook);
144         sal_Int32 nGroups = CFArrayGetCount(allGroups);
145         m_xMacabGroups = ::std::vector<MacabGroup *>(nGroups);
146 
147         sal_Int32 i;
148         ABGroupRef xGroup;
149 
150         /* Go through each group and create a MacabGroup out of it. */
151         for(i = 0; i < nGroups; i++)
152         {
153             xGroup = (ABGroupRef) CFArrayGetValueAtIndex(allGroups, i);
154             m_xMacabGroups[i] = new MacabGroup(m_aAddressBook, m_xMacabRecords, xGroup);
155         }
156 
157         CFRelease(allGroups);
158 
159         /* Manage duplicates. */
160         manageDuplicateGroups(m_xMacabGroups);
161         m_bRetrievedGroups = sal_True;
162     }
163 
164     return m_xMacabGroups;
165 }
166 
167 // -----------------------------------------------------------------------------
168 MacabGroup *MacabAddressBook::getMacabGroup(::rtl::OUString _groupName)
169 {
170     // initialize groups if not already initialized
171     if(m_bRetrievedGroups == sal_False)
172         getMacabGroups();
173 
174     sal_Int32 nGroups = m_xMacabGroups.size();
175     sal_Int32 i;
176 
177     for(i = 0; i < nGroups; i++)
178     {
179         if(m_xMacabGroups[i] != NULL)
180         {
181             if(m_xMacabGroups[i]->getName() == _groupName)
182             {
183                 return m_xMacabGroups[i];
184             }
185         }
186     }
187 
188     return NULL;
189 }
190 
191 // -----------------------------------------------------------------------------
192 MacabGroup *MacabAddressBook::getMacabGroupMatch(::rtl::OUString _groupName)
193 {
194     // initialize groups if not already initialized
195     if(m_bRetrievedGroups == sal_False)
196         getMacabGroups();
197 
198     sal_Int32 nGroups = m_xMacabGroups.size();
199     sal_Int32 i;
200 
201     for(i = 0; i < nGroups; i++)
202     {
203         if(m_xMacabGroups[i] != NULL)
204         {
205             if(match(m_xMacabGroups[i]->getName(), _groupName, '\0'))
206             {
207                 return m_xMacabGroups[i];
208             }
209         }
210     }
211 
212     return NULL;
213 }
214 
215 // -------------------------------------------------------------------------
216 void MacabAddressBook::manageDuplicateGroups(::std::vector<MacabGroup *> _xGroups) const
217 {
218     /* If we have two cases of groups, say, family, this makes it:
219      * family
220      * family (2)
221      */
222     ::std::vector<MacabGroup *>::reverse_iterator iter1, iter2;
223     sal_Int32 count;
224 
225     for(iter1 = _xGroups.rbegin(); iter1 != _xGroups.rend(); ++iter1)
226     {
227         /* If the name matches the default table name, there is already
228          * (obviously) a conflict. So, start the count of groups with this
229          * name at 2 instead of 1.
230          */
231         if( (*iter1)->getName() == getDefaultTableName() )
232             count = 2;
233         else
234             count = 1;
235 
236         iter2 = iter1;
237         for( ++iter2; iter2 != _xGroups.rend(); ++iter2)
238         {
239             if( (*iter1)->getName() == (*iter2)->getName() )
240             {
241                 count++;
242             }
243         }
244 
245         // duplicate!
246         if(count != 1)
247         {
248             ::rtl::OUString sName = (*iter1)->getName();
249             sName += ::rtl::OUString::createFromAscii(" (") +
250                 ::rtl::OUString::valueOf(count) +
251                 ::rtl::OUString::createFromAscii(")");
252             (*iter1)->setName(sName);
253         }
254     }
255 }
256 
257