Line data Source code
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 : #include <unotools/charclass.hxx>
21 :
22 : #include "global.hxx"
23 : #include "userlist.hxx"
24 : #include <unotools/localedatawrapper.hxx>
25 : #include <unotools/calendarwrapper.hxx>
26 : #include <unotools/transliterationwrapper.hxx>
27 :
28 : #include <boost/bind.hpp>
29 :
30 : using ::rtl::OUString;
31 : using ::rtl::OUStringBuffer;
32 :
33 : namespace {
34 :
35 : class FindByName : public ::std::unary_function<ScUserListData::SubStr, bool>
36 : {
37 : const OUString& mrName;
38 : bool mbUpper;
39 : public:
40 8 : FindByName(const OUString& rName, bool bUpper) : mrName(rName), mbUpper(bUpper) {}
41 54 : bool operator() (const ScUserListData::SubStr& r) const
42 : {
43 54 : return mbUpper ? r.maUpper.equals(mrName) : r.maReal.equals(mrName);
44 : }
45 : };
46 :
47 : }
48 :
49 580 : ScUserListData::SubStr::SubStr(const OUString& rReal, const OUString& rUpper) :
50 580 : maReal(rReal), maUpper(rUpper) {}
51 :
52 60 : void ScUserListData::InitTokens()
53 : {
54 60 : sal_Unicode cSep = ScGlobal::cListDelimiter;
55 60 : maSubStrings.clear();
56 60 : const sal_Unicode* p = aStr.getStr();
57 60 : const sal_Unicode* p0 = p;
58 60 : sal_Int32 nLen = 0;
59 60 : bool bFirst = true;
60 3550 : for (sal_Int32 i = 0, n = aStr.getLength(); i < n; ++i, ++p, ++nLen)
61 : {
62 3490 : if (bFirst)
63 : {
64 : // very first character, or the first character after a separator.
65 580 : p0 = p;
66 580 : nLen = 0;
67 580 : bFirst = false;
68 : }
69 3490 : if (*p == cSep)
70 : {
71 520 : if (nLen)
72 : {
73 520 : OUString aSub(p0, nLen);
74 520 : String aUpStr = ScGlobal::pCharClass->uppercase(aSub);
75 520 : maSubStrings.push_back(new SubStr(aSub, aUpStr));
76 : }
77 520 : bFirst = true;
78 : }
79 : }
80 :
81 60 : if (nLen)
82 : {
83 60 : OUString aSub(p0, nLen);
84 60 : String aUpStr = ScGlobal::pCharClass->uppercase(aSub);
85 60 : maSubStrings.push_back(new SubStr(aSub, aUpStr));
86 : }
87 60 : }
88 :
89 30 : ScUserListData::ScUserListData(const OUString& rStr) :
90 30 : aStr(rStr)
91 : {
92 30 : InitTokens();
93 30 : }
94 :
95 30 : ScUserListData::ScUserListData(const ScUserListData& rData) :
96 30 : aStr(rData.aStr)
97 : {
98 30 : InitTokens();
99 30 : }
100 :
101 30 : ScUserListData::~ScUserListData()
102 : {
103 30 : }
104 :
105 0 : void ScUserListData::SetString( const OUString& rStr )
106 : {
107 0 : aStr = rStr;
108 0 : InitTokens();
109 0 : }
110 :
111 1 : size_t ScUserListData::GetSubCount() const
112 : {
113 1 : return maSubStrings.size();
114 : }
115 :
116 5 : bool ScUserListData::GetSubIndex(const OUString& rSubStr, sal_uInt16& rIndex) const
117 : {
118 : // First, case sensitive search.
119 : SubStringsType::const_iterator itr = ::std::find_if(
120 5 : maSubStrings.begin(), maSubStrings.end(), FindByName(rSubStr, false));
121 5 : if (itr != maSubStrings.end())
122 : {
123 2 : rIndex = ::std::distance(maSubStrings.begin(), itr);
124 2 : return true;
125 : }
126 :
127 : // When that fails, do a case insensitive search.
128 3 : String aTmp = ScGlobal::pCharClass->uppercase(rSubStr);
129 3 : OUString aUpStr = aTmp;
130 : itr = ::std::find_if(
131 3 : maSubStrings.begin(), maSubStrings.end(), FindByName(aUpStr, true));
132 3 : if (itr != maSubStrings.end())
133 : {
134 0 : rIndex = ::std::distance(maSubStrings.begin(), itr);
135 0 : return true;
136 : }
137 3 : return false;
138 : }
139 :
140 2 : OUString ScUserListData::GetSubStr(sal_uInt16 nIndex) const
141 : {
142 2 : if (nIndex < maSubStrings.size())
143 2 : return maSubStrings[nIndex].maReal;
144 : else
145 0 : return OUString();
146 : }
147 :
148 0 : StringCompare ScUserListData::Compare(const OUString& rSubStr1, const OUString& rSubStr2) const
149 : {
150 : sal_uInt16 nIndex1, nIndex2;
151 0 : bool bFound1 = GetSubIndex(rSubStr1, nIndex1);
152 0 : bool bFound2 = GetSubIndex(rSubStr2, nIndex2);
153 0 : if (bFound1)
154 : {
155 0 : if (bFound2)
156 : {
157 0 : if (nIndex1 < nIndex2)
158 0 : return COMPARE_LESS;
159 0 : else if (nIndex1 > nIndex2)
160 0 : return COMPARE_GREATER;
161 : else
162 0 : return COMPARE_EQUAL;
163 : }
164 : else
165 0 : return COMPARE_LESS;
166 : }
167 0 : else if (bFound2)
168 0 : return COMPARE_GREATER;
169 : else
170 0 : return (StringCompare) ScGlobal::GetCaseTransliteration()->compareString( rSubStr1, rSubStr2 );
171 : }
172 :
173 0 : StringCompare ScUserListData::ICompare(const OUString& rSubStr1, const OUString& rSubStr2) const
174 : {
175 : sal_uInt16 nIndex1, nIndex2;
176 0 : bool bFound1 = GetSubIndex(rSubStr1, nIndex1);
177 0 : bool bFound2 = GetSubIndex(rSubStr2, nIndex2);
178 0 : if (bFound1)
179 : {
180 0 : if (bFound2)
181 : {
182 0 : if (nIndex1 < nIndex2)
183 0 : return COMPARE_LESS;
184 0 : else if (nIndex1 > nIndex2)
185 0 : return COMPARE_GREATER;
186 : else
187 0 : return COMPARE_EQUAL;
188 : }
189 : else
190 0 : return COMPARE_LESS;
191 : }
192 0 : else if (bFound2)
193 0 : return COMPARE_GREATER;
194 : else
195 0 : return (StringCompare) ScGlobal::GetpTransliteration()->compareString( rSubStr1, rSubStr2 );
196 : }
197 :
198 5 : ScUserList::ScUserList()
199 : {
200 : using namespace ::com::sun::star;
201 :
202 5 : sal_Unicode cDelimiter = ScGlobal::cListDelimiter;
203 5 : uno::Sequence< i18n::CalendarItem2 > xCal;
204 :
205 : uno::Sequence< i18n::Calendar2 > xCalendars(
206 5 : ScGlobal::pLocaleData->getAllCalendars() );
207 :
208 15 : for ( sal_Int32 j = 0; j < xCalendars.getLength(); ++j )
209 : {
210 10 : xCal = xCalendars[j].Days;
211 10 : if ( xCal.getLength() )
212 : {
213 10 : OUStringBuffer aDayShortBuf, aDayLongBuf;
214 : sal_Int32 i;
215 10 : sal_Int32 nLen = xCal.getLength();
216 10 : sal_Int16 nStart = sal::static_int_cast<sal_Int16>(nLen);
217 10 : while (nStart > 0)
218 : {
219 70 : if (xCal[--nStart].ID == xCalendars[j].StartOfWeek)
220 10 : break;
221 : }
222 10 : sal_Int16 nLast = sal::static_int_cast<sal_Int16>( (nStart + nLen - 1) % nLen );
223 70 : for (i = nStart; i != nLast; i = (i+1) % nLen)
224 : {
225 60 : aDayShortBuf.append(xCal[i].AbbrevName);
226 60 : aDayShortBuf.append(cDelimiter);
227 60 : aDayLongBuf.append(xCal[i].FullName);
228 60 : aDayLongBuf.append(cDelimiter);
229 : }
230 10 : aDayShortBuf.append(xCal[i].AbbrevName);
231 10 : aDayLongBuf.append(xCal[i].FullName);
232 :
233 10 : OUString aDayShort = aDayShortBuf.makeStringAndClear();
234 10 : OUString aDayLong = aDayLongBuf.makeStringAndClear();
235 :
236 10 : if ( !HasEntry( aDayShort ) )
237 5 : maData.push_back( new ScUserListData( aDayShort ));
238 10 : if ( !HasEntry( aDayLong ) )
239 10 : maData.push_back( new ScUserListData( aDayLong ));
240 : }
241 :
242 10 : xCal = xCalendars[j].Months;
243 10 : if ( xCal.getLength() )
244 : {
245 10 : OUStringBuffer aMonthShortBuf, aMonthLongBuf;
246 : sal_Int32 i;
247 10 : sal_Int32 nLen = xCal.getLength() - 1;
248 125 : for (i = 0; i < nLen; i++)
249 : {
250 115 : aMonthShortBuf.append(xCal[i].AbbrevName);
251 115 : aMonthShortBuf.append(cDelimiter);
252 115 : aMonthLongBuf.append(xCal[i].FullName);
253 115 : aMonthLongBuf.append(cDelimiter);
254 : }
255 10 : aMonthShortBuf.append(xCal[i].AbbrevName);
256 10 : aMonthLongBuf.append(xCal[i].FullName);
257 :
258 10 : OUString aMonthShort = aMonthShortBuf.makeStringAndClear();
259 10 : OUString aMonthLong = aMonthLongBuf.makeStringAndClear();
260 :
261 10 : if ( !HasEntry( aMonthShort ) )
262 10 : maData.push_back( new ScUserListData( aMonthShort ));
263 10 : if ( !HasEntry( aMonthLong ) )
264 5 : maData.push_back( new ScUserListData( aMonthLong ));
265 : }
266 5 : }
267 5 : }
268 :
269 5 : ScUserList::ScUserList(const ScUserList& r) :
270 5 : maData(r.maData) {}
271 :
272 1 : const ScUserListData* ScUserList::GetData(const OUString& rSubStr) const
273 : {
274 1 : DataType::const_iterator itr = maData.begin(), itrEnd = maData.end();
275 4 : for (; itr != itrEnd; ++itr)
276 : {
277 : sal_uInt16 nIndex;
278 4 : if (itr->GetSubIndex(rSubStr, nIndex))
279 1 : return &(*itr);
280 : }
281 0 : return NULL;
282 : }
283 :
284 0 : const ScUserListData* ScUserList::operator[](size_t nIndex) const
285 : {
286 0 : return &maData[nIndex];
287 : }
288 :
289 0 : ScUserListData* ScUserList::operator[](size_t nIndex)
290 : {
291 0 : return &maData[nIndex];
292 : }
293 :
294 0 : ScUserList& ScUserList::operator=( const ScUserList& r )
295 : {
296 0 : maData = r.maData;
297 0 : return *this;
298 : }
299 :
300 0 : bool ScUserList::operator==( const ScUserList& r ) const
301 : {
302 0 : if (size() != r.size())
303 0 : return false;
304 :
305 0 : DataType::const_iterator itr1 = maData.begin(), itr2 = r.maData.begin(), itrEnd = maData.end();
306 0 : for (; itr1 != itrEnd; ++itr1, ++itr2)
307 : {
308 0 : const ScUserListData& v1 = *itr1;
309 0 : const ScUserListData& v2 = *itr2;
310 0 : if (v1.GetString() != v2.GetString() || v1.GetSubCount() != v2.GetSubCount())
311 0 : return false;
312 : }
313 0 : return true;
314 : }
315 :
316 0 : bool ScUserList::operator!=( const ScUserList& r ) const
317 : {
318 0 : return !operator==( r );
319 : }
320 :
321 :
322 40 : bool ScUserList::HasEntry( const OUString& rStr ) const
323 : {
324 : DataType::const_iterator itr = ::std::find_if(
325 40 : maData.begin(), maData.end(), ::boost::bind(&ScUserListData::GetString, _1) == rStr);
326 40 : return itr != maData.end();
327 : }
328 :
329 0 : ScUserList::iterator ScUserList::begin()
330 : {
331 0 : return maData.begin();
332 : }
333 :
334 0 : ScUserList::const_iterator ScUserList::begin() const
335 : {
336 0 : return maData.begin();
337 : }
338 :
339 0 : void ScUserList::clear()
340 : {
341 0 : maData.clear();
342 0 : }
343 :
344 0 : size_t ScUserList::size() const
345 : {
346 0 : return maData.size();
347 : }
348 :
349 0 : void ScUserList::push_back(ScUserListData* p)
350 : {
351 0 : maData.push_back(p);
352 0 : }
353 :
354 0 : void ScUserList::erase(iterator itr)
355 : {
356 0 : maData.erase(itr);
357 15 : }
358 :
359 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|