Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <unotools/charclass.hxx>
30 : :
31 : : #include "global.hxx"
32 : : #include "userlist.hxx"
33 : : #include <unotools/localedatawrapper.hxx>
34 : : #include <unotools/calendarwrapper.hxx>
35 : : #include <unotools/transliterationwrapper.hxx>
36 : :
37 : : #include <boost/bind.hpp>
38 : :
39 : : using ::rtl::OUString;
40 : : using ::rtl::OUStringBuffer;
41 : :
42 : : namespace {
43 : :
44 : : class FindByName : public ::std::unary_function<ScUserListData::SubStr, bool>
45 : : {
46 : : const OUString& mrName;
47 : : bool mbUpper;
48 : : public:
49 : 24 : FindByName(const OUString& rName, bool bUpper) : mrName(rName), mbUpper(bUpper) {}
50 : 162 : bool operator() (const ScUserListData::SubStr& r) const
51 : : {
52 [ + + ]: 162 : return mbUpper ? r.maUpper.equals(mrName) : r.maReal.equals(mrName);
53 : : }
54 : : };
55 : :
56 : : }
57 : :
58 : 6096 : ScUserListData::SubStr::SubStr(const OUString& rReal, const OUString& rUpper) :
59 : 6096 : maReal(rReal), maUpper(rUpper) {}
60 : :
61 : 636 : void ScUserListData::InitTokens()
62 : : {
63 : 636 : sal_Unicode cSep = ScGlobal::cListDelimiter;
64 : 636 : maSubStrings.clear();
65 : 636 : const sal_Unicode* p = aStr.getStr();
66 : 636 : const sal_Unicode* p0 = p;
67 : 636 : sal_Int32 nLen = 0;
68 : 636 : bool bFirst = true;
69 [ + + ]: 37357 : for (sal_Int32 i = 0, n = aStr.getLength(); i < n; ++i, ++p, ++nLen)
70 : : {
71 [ + + ]: 36721 : if (bFirst)
72 : : {
73 : : // very first character, or the first character after a separator.
74 : 6096 : p0 = p;
75 : 6096 : nLen = 0;
76 : 6096 : bFirst = false;
77 : : }
78 [ + + ]: 36721 : if (*p == cSep)
79 : : {
80 [ + - ]: 5460 : if (nLen)
81 : : {
82 : 5460 : OUString aSub(p0, nLen);
83 [ + - ][ + - ]: 5460 : String aUpStr = ScGlobal::pCharClass->uppercase(aSub);
84 [ + - ][ + - ]: 5460 : maSubStrings.push_back(new SubStr(aSub, aUpStr));
[ + - ][ + - ]
[ + - ]
85 : : }
86 : 5460 : bFirst = true;
87 : : }
88 : : }
89 : :
90 [ + - ]: 636 : if (nLen)
91 : : {
92 : 636 : OUString aSub(p0, nLen);
93 [ + - ][ + - ]: 636 : String aUpStr = ScGlobal::pCharClass->uppercase(aSub);
94 [ + - ][ + - ]: 636 : maSubStrings.push_back(new SubStr(aSub, aUpStr));
[ + - ][ + - ]
[ + - ]
95 : : }
96 : 636 : }
97 : :
98 : 330 : ScUserListData::ScUserListData(const OUString& rStr) :
99 : 330 : aStr(rStr)
100 : : {
101 [ + - ]: 330 : InitTokens();
102 : 330 : }
103 : :
104 : 306 : ScUserListData::ScUserListData(const ScUserListData& rData) :
105 : 306 : aStr(rData.aStr)
106 : : {
107 [ + - ]: 306 : InitTokens();
108 : 306 : }
109 : :
110 : 438 : ScUserListData::~ScUserListData()
111 : : {
112 : 438 : }
113 : :
114 : 0 : void ScUserListData::SetString( const OUString& rStr )
115 : : {
116 : 0 : aStr = rStr;
117 : 0 : InitTokens();
118 : 0 : }
119 : :
120 : 3 : size_t ScUserListData::GetSubCount() const
121 : : {
122 : 3 : return maSubStrings.size();
123 : : }
124 : :
125 : 15 : bool ScUserListData::GetSubIndex(const OUString& rSubStr, sal_uInt16& rIndex) const
126 : : {
127 : : // First, case sensitive search.
128 : : SubStringsType::const_iterator itr = ::std::find_if(
129 [ + - ][ + - ]: 15 : maSubStrings.begin(), maSubStrings.end(), FindByName(rSubStr, false));
[ + - ]
130 [ + - ][ + - ]: 15 : if (itr != maSubStrings.end())
[ + + ]
131 : : {
132 [ + - ][ + - ]: 6 : rIndex = ::std::distance(maSubStrings.begin(), itr);
133 : 6 : return true;
134 : : }
135 : :
136 : : // When that fails, do a case insensitive search.
137 [ + - ][ + - ]: 9 : String aTmp = ScGlobal::pCharClass->uppercase(rSubStr);
138 [ + - ]: 9 : OUString aUpStr = aTmp;
139 : : itr = ::std::find_if(
140 [ + - ][ + - ]: 9 : maSubStrings.begin(), maSubStrings.end(), FindByName(aUpStr, true));
[ + - ]
141 [ + - ][ + - ]: 9 : if (itr != maSubStrings.end())
[ - + ]
142 : : {
143 [ # # ][ # # ]: 0 : rIndex = ::std::distance(maSubStrings.begin(), itr);
144 : 0 : return true;
145 : : }
146 [ + - ]: 15 : return false;
147 : : }
148 : :
149 : 6 : OUString ScUserListData::GetSubStr(sal_uInt16 nIndex) const
150 : : {
151 [ + - ]: 6 : if (nIndex < maSubStrings.size())
152 : 6 : return maSubStrings[nIndex].maReal;
153 : : else
154 : 6 : return OUString();
155 : : }
156 : :
157 : 0 : StringCompare ScUserListData::Compare(const OUString& rSubStr1, const OUString& rSubStr2) const
158 : : {
159 : : sal_uInt16 nIndex1, nIndex2;
160 [ # # ]: 0 : bool bFound1 = GetSubIndex(rSubStr1, nIndex1);
161 [ # # ]: 0 : bool bFound2 = GetSubIndex(rSubStr2, nIndex2);
162 [ # # ]: 0 : if (bFound1)
163 : : {
164 [ # # ]: 0 : if (bFound2)
165 : : {
166 [ # # ]: 0 : if (nIndex1 < nIndex2)
167 : 0 : return COMPARE_LESS;
168 [ # # ]: 0 : else if (nIndex1 > nIndex2)
169 : 0 : return COMPARE_GREATER;
170 : : else
171 : 0 : return COMPARE_EQUAL;
172 : : }
173 : : else
174 : 0 : return COMPARE_LESS;
175 : : }
176 [ # # ]: 0 : else if (bFound2)
177 : 0 : return COMPARE_GREATER;
178 : : else
179 [ # # ][ # # ]: 0 : return (StringCompare) ScGlobal::GetCaseTransliteration()->compareString( rSubStr1, rSubStr2 );
[ # # ][ # # ]
[ # # ][ # # ]
180 : : }
181 : :
182 : 0 : StringCompare ScUserListData::ICompare(const OUString& rSubStr1, const OUString& rSubStr2) const
183 : : {
184 : : sal_uInt16 nIndex1, nIndex2;
185 [ # # ]: 0 : bool bFound1 = GetSubIndex(rSubStr1, nIndex1);
186 [ # # ]: 0 : bool bFound2 = GetSubIndex(rSubStr2, nIndex2);
187 [ # # ]: 0 : if (bFound1)
188 : : {
189 [ # # ]: 0 : if (bFound2)
190 : : {
191 [ # # ]: 0 : if (nIndex1 < nIndex2)
192 : 0 : return COMPARE_LESS;
193 [ # # ]: 0 : else if (nIndex1 > nIndex2)
194 : 0 : return COMPARE_GREATER;
195 : : else
196 : 0 : return COMPARE_EQUAL;
197 : : }
198 : : else
199 : 0 : return COMPARE_LESS;
200 : : }
201 [ # # ]: 0 : else if (bFound2)
202 : 0 : return COMPARE_GREATER;
203 : : else
204 [ # # ][ # # ]: 0 : return (StringCompare) ScGlobal::GetpTransliteration()->compareString( rSubStr1, rSubStr2 );
[ # # ][ # # ]
[ # # ][ # # ]
205 : : }
206 : :
207 : 51 : ScUserList::ScUserList()
208 : : {
209 : : using namespace ::com::sun::star;
210 : :
211 : 51 : sal_Unicode cDelimiter = ScGlobal::cListDelimiter;
212 [ + - ]: 51 : uno::Sequence< i18n::CalendarItem2 > xCal;
213 : :
214 : : uno::Sequence< i18n::Calendar2 > xCalendars(
215 [ + - ]: 51 : ScGlobal::pLocaleData->getAllCalendars() );
216 : :
217 [ + + ]: 153 : for ( sal_Int32 j = 0; j < xCalendars.getLength(); ++j )
218 : : {
219 [ + - ][ + - ]: 102 : xCal = xCalendars[j].Days;
220 [ + - ]: 102 : if ( xCal.getLength() )
221 : : {
222 : 102 : OUStringBuffer aDayShortBuf, aDayLongBuf;
223 : : sal_Int32 i;
224 : 102 : sal_Int32 nLen = xCal.getLength();
225 : 102 : sal_Int16 nStart = sal::static_int_cast<sal_Int16>(nLen);
226 [ + - ]: 714 : while (nStart > 0)
227 : : {
228 [ + - ][ + - ]: 714 : if (xCal[--nStart].ID == xCalendars[j].StartOfWeek)
[ + + ]
229 : 102 : break;
230 : : }
231 : 102 : sal_Int16 nLast = sal::static_int_cast<sal_Int16>( (nStart + nLen - 1) % nLen );
232 [ + + ]: 714 : for (i = nStart; i != nLast; i = (i+1) % nLen)
233 : : {
234 [ + - ][ + - ]: 612 : aDayShortBuf.append(xCal[i].AbbrevName);
235 [ + - ]: 612 : aDayShortBuf.append(cDelimiter);
236 [ + - ][ + - ]: 612 : aDayLongBuf.append(xCal[i].FullName);
237 [ + - ]: 612 : aDayLongBuf.append(cDelimiter);
238 : : }
239 [ + - ][ + - ]: 102 : aDayShortBuf.append(xCal[i].AbbrevName);
240 [ + - ][ + - ]: 102 : aDayLongBuf.append(xCal[i].FullName);
241 : :
242 [ + - ]: 102 : OUString aDayShort = aDayShortBuf.makeStringAndClear();
243 [ + - ]: 102 : OUString aDayLong = aDayLongBuf.makeStringAndClear();
244 : :
245 [ + - ][ + + ]: 102 : if ( !HasEntry( aDayShort ) )
246 [ + - ][ + - ]: 51 : maData.push_back( new ScUserListData( aDayShort ));
[ + - ]
247 [ + - ][ + - ]: 102 : if ( !HasEntry( aDayLong ) )
248 [ + - ][ + - ]: 102 : maData.push_back( new ScUserListData( aDayLong ));
[ + - ]
249 : : }
250 : :
251 [ + - ][ + - ]: 102 : xCal = xCalendars[j].Months;
252 [ + - ]: 102 : if ( xCal.getLength() )
253 : : {
254 : 102 : OUStringBuffer aMonthShortBuf, aMonthLongBuf;
255 : : sal_Int32 i;
256 : 102 : sal_Int32 nLen = xCal.getLength() - 1;
257 [ + + ]: 1275 : for (i = 0; i < nLen; i++)
258 : : {
259 [ + - ][ + - ]: 1173 : aMonthShortBuf.append(xCal[i].AbbrevName);
260 [ + - ]: 1173 : aMonthShortBuf.append(cDelimiter);
261 [ + - ][ + - ]: 1173 : aMonthLongBuf.append(xCal[i].FullName);
262 [ + - ]: 1173 : aMonthLongBuf.append(cDelimiter);
263 : : }
264 [ + - ][ + - ]: 102 : aMonthShortBuf.append(xCal[i].AbbrevName);
265 [ + - ][ + - ]: 102 : aMonthLongBuf.append(xCal[i].FullName);
266 : :
267 [ + - ]: 102 : OUString aMonthShort = aMonthShortBuf.makeStringAndClear();
268 [ + - ]: 102 : OUString aMonthLong = aMonthLongBuf.makeStringAndClear();
269 : :
270 [ + - ][ + - ]: 102 : if ( !HasEntry( aMonthShort ) )
271 [ + - ][ + - ]: 102 : maData.push_back( new ScUserListData( aMonthShort ));
[ + - ]
272 [ + - ][ + + ]: 102 : if ( !HasEntry( aMonthLong ) )
273 [ + - ][ + - ]: 102 : maData.push_back( new ScUserListData( aMonthLong ));
[ + - ]
274 : : }
275 [ + - ][ + - ]: 51 : }
276 : 51 : }
277 : :
278 : 51 : ScUserList::ScUserList(const ScUserList& r) :
279 : 51 : maData(r.maData) {}
280 : :
281 : 3 : const ScUserListData* ScUserList::GetData(const OUString& rSubStr) const
282 : : {
283 [ + - ][ + - ]: 3 : DataType::const_iterator itr = maData.begin(), itrEnd = maData.end();
284 [ + - ][ + - ]: 12 : for (; itr != itrEnd; ++itr)
[ + - ]
285 : : {
286 : : sal_uInt16 nIndex;
287 [ + - ][ + - ]: 12 : if (itr->GetSubIndex(rSubStr, nIndex))
[ + + ]
288 [ + - ]: 3 : return &(*itr);
289 : : }
290 : 3 : return NULL;
291 : : }
292 : :
293 : 9 : const ScUserListData* ScUserList::operator[](size_t nIndex) const
294 : : {
295 : 9 : return &maData[nIndex];
296 : : }
297 : :
298 : 53 : ScUserListData* ScUserList::operator[](size_t nIndex)
299 : : {
300 : 53 : return &maData[nIndex];
301 : : }
302 : :
303 : 0 : ScUserList& ScUserList::operator=( const ScUserList& r )
304 : : {
305 [ # # ]: 0 : maData = r.maData;
306 : 0 : return *this;
307 : : }
308 : :
309 : 0 : bool ScUserList::operator==( const ScUserList& r ) const
310 : : {
311 [ # # ][ # # ]: 0 : if (size() != r.size())
[ # # ]
312 : 0 : return false;
313 : :
314 [ # # ][ # # ]: 0 : DataType::const_iterator itr1 = maData.begin(), itr2 = r.maData.begin(), itrEnd = maData.end();
[ # # ]
315 [ # # ][ # # ]: 0 : for (; itr1 != itrEnd; ++itr1, ++itr2)
[ # # ][ # # ]
316 : : {
317 [ # # ]: 0 : const ScUserListData& v1 = *itr1;
318 [ # # ]: 0 : const ScUserListData& v2 = *itr2;
319 [ # # ][ # # ]: 0 : if (v1.GetString() != v2.GetString() || v1.GetSubCount() != v2.GetSubCount())
[ # # ][ # # ]
[ # # ]
320 : 0 : return false;
321 : : }
322 : 0 : return true;
323 : : }
324 : :
325 : 0 : bool ScUserList::operator!=( const ScUserList& r ) const
326 : : {
327 : 0 : return !operator==( r );
328 : : }
329 : :
330 : :
331 : 408 : bool ScUserList::HasEntry( const OUString& rStr ) const
332 : : {
333 : : DataType::const_iterator itr = ::std::find_if(
334 [ + - ][ + - ]: 408 : maData.begin(), maData.end(), ::boost::bind(&ScUserListData::GetString, _1) == rStr);
[ + - ][ + - ]
[ + - ]
335 [ + - ][ + - ]: 408 : return itr != maData.end();
336 : : }
337 : :
338 : 0 : ScUserList::iterator ScUserList::begin()
339 : : {
340 : 0 : return maData.begin();
341 : : }
342 : :
343 : 0 : ScUserList::const_iterator ScUserList::begin() const
344 : : {
345 : 0 : return maData.begin();
346 : : }
347 : :
348 : 3 : void ScUserList::clear()
349 : : {
350 : 3 : maData.clear();
351 : 3 : }
352 : :
353 : 8 : size_t ScUserList::size() const
354 : : {
355 : 8 : return maData.size();
356 : : }
357 : :
358 : 24 : void ScUserList::push_back(ScUserListData* p)
359 : : {
360 : 24 : maData.push_back(p);
361 : 24 : }
362 : :
363 : 0 : void ScUserList::erase(iterator itr)
364 : : {
365 : 0 : maData.erase(itr);
366 [ + - ][ + - ]: 153 : }
367 : :
368 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|