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