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