LibreOffice Module connectivity (master) 1
MacabAddressBook.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
21#include "MacabAddressBook.hxx"
22#include "MacabRecords.hxx"
23#include "MacabGroup.hxx"
24
25#include <vector>
26
27#include <premac.h>
28#include <Carbon/Carbon.h>
29#include <AddressBook/ABAddressBookC.h>
30#include <postmac.h>
32
33using namespace connectivity::macab;
34using namespace ::com::sun::star::uno;
35
36namespace {
37
38void manageDuplicateGroups(std::vector<MacabGroup *> _xGroups)
39{
40 /* If we have two cases of groups, say, family, this makes it:
41 * family
42 * family (2)
43 */
44 std::vector<MacabGroup *>::reverse_iterator iter1, iter2;
45 sal_Int32 count;
46
47 for(iter1 = _xGroups.rbegin(); iter1 != _xGroups.rend(); ++iter1)
48 {
49 /* If the name matches the default table name, there is already
50 * (obviously) a conflict. So, start the count of groups with this
51 * name at 2 instead of 1.
52 */
53 if( (*iter1)->getName() == MacabAddressBook::getDefaultTableName() )
54 count = 2;
55 else
56 count = 1;
57
58 iter2 = iter1;
59 for( ++iter2; iter2 != _xGroups.rend(); ++iter2)
60 {
61 if( (*iter1)->getName() == (*iter2)->getName() )
62 {
63 count++;
64 }
65 }
66
67 // duplicate!
68 if(count != 1)
69 {
70 OUString sName = (*iter1)->getName() + " (" +
71 OUString::number(count) +
72 ")";
73 (*iter1)->setName(sName);
74 }
75 }
76}
77
78}
79
80MacabAddressBook::MacabAddressBook( )
81 : m_aAddressBook(ABGetSharedAddressBook()),
82 m_xMacabRecords(nullptr),
83 m_bRetrievedGroups(false)
84{
85 if(m_aAddressBook == nullptr)
86 {
87 // TODO: tell the user to reset the permission via "tccutil reset AddressBook"
88 // or the system preferences and try again, this time granting the access
89 throw RuntimeException(
90 "failed to access the macOS address book - permission not granted?" );
91 }
92}
93
94
96{
97 if(m_xMacabRecords != nullptr)
98 {
99 delete m_xMacabRecords;
100 m_xMacabRecords = nullptr;
101 }
102
103 for(MacabGroup* pMacabGroup : m_xMacabGroups)
104 delete pMacabGroup;
105
106 m_bRetrievedGroups = false;
107}
108
109
110/* Get the address book's default table name. This is the table name that
111 * refers to the table containing _all_ records in the address book.
112 */
114{
115 /* This string probably needs to be localized. */
116 static const OUString aDefaultTableName
117 (OUString("Address Book"));
118
119 return aDefaultTableName;
120}
121
122
124{
125 /* If the MacabRecords don't exist, create them. */
126 if(m_xMacabRecords == nullptr)
127 {
131 }
132
133 return m_xMacabRecords;
134}
135
136
137/* Get the MacabRecords for a given name: either a group name or the
138 * default table name.
139 */
140MacabRecords *MacabAddressBook::getMacabRecords(std::u16string_view _tableName)
141{
142 if(_tableName == getDefaultTableName())
143 {
144 return getMacabRecords();
145 }
146 else
147 {
148 return getMacabGroup(_tableName);
149 }
150}
151
152
154{
155 if(match(_tableName, getDefaultTableName(), '\0'))
156 {
157 return getMacabRecords();
158 }
159
160 return getMacabGroupMatch(_tableName);
161}
162
163
164std::vector<MacabGroup *> MacabAddressBook::getMacabGroups()
165{
166 /* If the MacabGroups haven't been created yet, create them. */
168 {
169 /* If the MacabRecords haven't been created yet, create them. */
170 if(m_xMacabRecords == nullptr)
171 {
175 }
176
177 CFArrayRef allGroups = ABCopyArrayOfAllGroups(m_aAddressBook);
178 sal_Int32 nGroups = CFArrayGetCount(allGroups);
179 m_xMacabGroups = std::vector<MacabGroup *>(nGroups);
180
181 sal_Int32 i;
182 ABGroupRef xGroup;
183
184 /* Go through each group and create a MacabGroup out of it. */
185 for(i = 0; i < nGroups; i++)
186 {
187 xGroup = static_cast<ABGroupRef>(const_cast<void *>(CFArrayGetValueAtIndex(allGroups, i)));
189 }
190
191 CFRelease(allGroups);
192
193 /* Manage duplicates. */
194 manageDuplicateGroups(m_xMacabGroups);
195 m_bRetrievedGroups = true;
196 }
197
198 return m_xMacabGroups;
199}
200
201
202MacabGroup *MacabAddressBook::getMacabGroup(std::u16string_view _groupName)
203{
204 // initialize groups if not already initialized
207
208 sal_Int32 nGroups = m_xMacabGroups.size();
209 sal_Int32 i;
210
211 for(i = 0; i < nGroups; i++)
212 {
213 if(m_xMacabGroups[i] != nullptr)
214 {
215 if(m_xMacabGroups[i]->getName() == _groupName)
216 {
217 return m_xMacabGroups[i];
218 }
219 }
220 }
221
222 return nullptr;
223}
224
225
227{
228 // initialize groups if not already initialized
231
232 sal_Int32 nGroups = m_xMacabGroups.size();
233 sal_Int32 i;
234
235 for(i = 0; i < nGroups; i++)
236 {
237 if(m_xMacabGroups[i] != nullptr)
238 {
239 if(match(m_xMacabGroups[i]->getName(), _groupName, '\0'))
240 {
241 return m_xMacabGroups[i];
242 }
243 }
244 }
245
246 return nullptr;
247}
248
249/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static const OUString & getDefaultTableName()
MacabGroup * getMacabGroup(std::u16string_view _groupName)
MacabRecords * getMacabRecordsMatch(const OUString &_tableName)
MacabGroup * getMacabGroupMatch(const OUString &_groupName)
std::vector< MacabGroup * > m_xMacabGroups
std::vector< MacabGroup * > getMacabGroups()
void setName(const OUString &_sName)
OUString sName
bool match(const sal_Unicode *pWild, const sal_Unicode *pStr, const sal_Unicode cEscape)
Definition: CommonTools.cxx:51
int i