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 :
31 : namespace {
32 :
33 : class FindByName : public ::std::unary_function<ScUserListData::SubStr, bool>
34 : {
35 : const OUString& mrName;
36 : bool mbUpper;
37 : public:
38 0 : FindByName(const OUString& rName, bool bUpper) : mrName(rName), mbUpper(bUpper) {}
39 0 : bool operator() (const ScUserListData::SubStr& r) const
40 : {
41 0 : return mbUpper ? r.maUpper.equals(mrName) : r.maReal.equals(mrName);
42 : }
43 : };
44 :
45 : }
46 :
47 0 : ScUserListData::SubStr::SubStr(const OUString& rReal, const OUString& rUpper) :
48 0 : maReal(rReal), maUpper(rUpper) {}
49 :
50 0 : void ScUserListData::InitTokens()
51 : {
52 0 : sal_Unicode cSep = ScGlobal::cListDelimiter;
53 0 : maSubStrings.clear();
54 0 : const sal_Unicode* p = aStr.getStr();
55 0 : const sal_Unicode* p0 = p;
56 0 : sal_Int32 nLen = 0;
57 0 : bool bFirst = true;
58 0 : for (sal_Int32 i = 0, n = aStr.getLength(); i < n; ++i, ++p, ++nLen)
59 : {
60 0 : if (bFirst)
61 : {
62 : // very first character, or the first character after a separator.
63 0 : p0 = p;
64 0 : nLen = 0;
65 0 : bFirst = false;
66 : }
67 0 : if (*p == cSep)
68 : {
69 0 : if (nLen)
70 : {
71 0 : OUString aSub(p0, nLen);
72 0 : OUString aUpStr = ScGlobal::pCharClass->uppercase(aSub);
73 0 : maSubStrings.push_back(new SubStr(aSub, aUpStr));
74 : }
75 0 : bFirst = true;
76 : }
77 : }
78 :
79 0 : if (nLen)
80 : {
81 0 : OUString aSub(p0, nLen);
82 0 : OUString aUpStr = ScGlobal::pCharClass->uppercase(aSub);
83 0 : maSubStrings.push_back(new SubStr(aSub, aUpStr));
84 : }
85 0 : }
86 :
87 0 : ScUserListData::ScUserListData(const OUString& rStr) :
88 0 : aStr(rStr)
89 : {
90 0 : InitTokens();
91 0 : }
92 :
93 0 : ScUserListData::ScUserListData(const ScUserListData& rData) :
94 0 : aStr(rData.aStr)
95 : {
96 0 : InitTokens();
97 0 : }
98 :
99 0 : ScUserListData::~ScUserListData()
100 : {
101 0 : }
102 :
103 0 : void ScUserListData::SetString( const OUString& rStr )
104 : {
105 0 : aStr = rStr;
106 0 : InitTokens();
107 0 : }
108 :
109 0 : size_t ScUserListData::GetSubCount() const
110 : {
111 0 : return maSubStrings.size();
112 : }
113 :
114 0 : 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 0 : maSubStrings.begin(), maSubStrings.end(), FindByName(rSubStr, false));
119 0 : if (itr != maSubStrings.end())
120 : {
121 0 : rIndex = ::std::distance(maSubStrings.begin(), itr);
122 0 : return true;
123 : }
124 :
125 : // When that fails, do a case insensitive search.
126 0 : OUString aTmp = ScGlobal::pCharClass->uppercase(rSubStr);
127 0 : OUString aUpStr = aTmp;
128 : itr = ::std::find_if(
129 0 : maSubStrings.begin(), maSubStrings.end(), FindByName(aUpStr, true));
130 0 : if (itr != maSubStrings.end())
131 : {
132 0 : rIndex = ::std::distance(maSubStrings.begin(), itr);
133 0 : return true;
134 : }
135 0 : return false;
136 : }
137 :
138 0 : OUString ScUserListData::GetSubStr(sal_uInt16 nIndex) const
139 : {
140 0 : if (nIndex < maSubStrings.size())
141 0 : 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 0 : ScUserList::ScUserList()
197 : {
198 : using namespace ::com::sun::star;
199 :
200 0 : sal_Unicode cDelimiter = ScGlobal::cListDelimiter;
201 0 : uno::Sequence< i18n::CalendarItem2 > xCal;
202 :
203 : uno::Sequence< i18n::Calendar2 > xCalendars(
204 0 : ScGlobal::pLocaleData->getAllCalendars() );
205 :
206 0 : for ( sal_Int32 j = 0; j < xCalendars.getLength(); ++j )
207 : {
208 0 : xCal = xCalendars[j].Days;
209 0 : if ( xCal.getLength() )
210 : {
211 0 : OUStringBuffer aDayShortBuf, aDayLongBuf;
212 : sal_Int32 i;
213 0 : sal_Int32 nLen = xCal.getLength();
214 0 : sal_Int16 nStart = sal::static_int_cast<sal_Int16>(nLen);
215 0 : while (nStart > 0)
216 : {
217 0 : if (xCal[--nStart].ID == xCalendars[j].StartOfWeek)
218 0 : break;
219 : }
220 0 : sal_Int16 nLast = sal::static_int_cast<sal_Int16>( (nStart + nLen - 1) % nLen );
221 0 : for (i = nStart; i != nLast; i = (i+1) % nLen)
222 : {
223 0 : aDayShortBuf.append(xCal[i].AbbrevName);
224 0 : aDayShortBuf.append(cDelimiter);
225 0 : aDayLongBuf.append(xCal[i].FullName);
226 0 : aDayLongBuf.append(cDelimiter);
227 : }
228 0 : aDayShortBuf.append(xCal[i].AbbrevName);
229 0 : aDayLongBuf.append(xCal[i].FullName);
230 :
231 0 : OUString aDayShort = aDayShortBuf.makeStringAndClear();
232 0 : OUString aDayLong = aDayLongBuf.makeStringAndClear();
233 :
234 0 : if ( !HasEntry( aDayShort ) )
235 0 : maData.push_back( new ScUserListData( aDayShort ));
236 0 : if ( !HasEntry( aDayLong ) )
237 0 : maData.push_back( new ScUserListData( aDayLong ));
238 : }
239 :
240 0 : xCal = xCalendars[j].Months;
241 0 : if ( xCal.getLength() )
242 : {
243 0 : OUStringBuffer aMonthShortBuf, aMonthLongBuf;
244 : sal_Int32 i;
245 0 : sal_Int32 nLen = xCal.getLength() - 1;
246 0 : for (i = 0; i < nLen; i++)
247 : {
248 0 : aMonthShortBuf.append(xCal[i].AbbrevName);
249 0 : aMonthShortBuf.append(cDelimiter);
250 0 : aMonthLongBuf.append(xCal[i].FullName);
251 0 : aMonthLongBuf.append(cDelimiter);
252 : }
253 0 : aMonthShortBuf.append(xCal[i].AbbrevName);
254 0 : aMonthLongBuf.append(xCal[i].FullName);
255 :
256 0 : OUString aMonthShort = aMonthShortBuf.makeStringAndClear();
257 0 : OUString aMonthLong = aMonthLongBuf.makeStringAndClear();
258 :
259 0 : if ( !HasEntry( aMonthShort ) )
260 0 : maData.push_back( new ScUserListData( aMonthShort ));
261 0 : if ( !HasEntry( aMonthLong ) )
262 0 : maData.push_back( new ScUserListData( aMonthLong ));
263 : }
264 0 : }
265 0 : }
266 :
267 0 : ScUserList::ScUserList(const ScUserList& r) :
268 0 : maData(r.maData) {}
269 :
270 0 : const ScUserListData* ScUserList::GetData(const OUString& rSubStr) const
271 : {
272 0 : DataType::const_iterator itr = maData.begin(), itrEnd = maData.end();
273 0 : for (; itr != itrEnd; ++itr)
274 : {
275 : sal_uInt16 nIndex;
276 0 : if (itr->GetSubIndex(rSubStr, nIndex))
277 0 : return &(*itr);
278 : }
279 0 : return NULL;
280 : }
281 :
282 0 : const ScUserListData* ScUserList::operator[](size_t nIndex) const
283 : {
284 0 : return &maData[nIndex];
285 : }
286 :
287 0 : ScUserListData* ScUserList::operator[](size_t nIndex)
288 : {
289 0 : 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 :
320 0 : bool ScUserList::HasEntry( const OUString& rStr ) const
321 : {
322 : DataType::const_iterator itr = ::std::find_if(
323 0 : maData.begin(), maData.end(), ::boost::bind(&ScUserListData::GetString, _1) == rStr);
324 0 : return itr != maData.end();
325 : }
326 :
327 0 : ScUserList::iterator ScUserList::begin()
328 : {
329 0 : return maData.begin();
330 : }
331 :
332 0 : ScUserList::const_iterator ScUserList::begin() const
333 : {
334 0 : return maData.begin();
335 : }
336 :
337 0 : void ScUserList::clear()
338 : {
339 0 : maData.clear();
340 0 : }
341 :
342 0 : size_t ScUserList::size() const
343 : {
344 0 : return maData.size();
345 : }
346 :
347 0 : void ScUserList::push_back(ScUserListData* p)
348 : {
349 0 : maData.push_back(p);
350 0 : }
351 :
352 0 : void ScUserList::erase(iterator itr)
353 : {
354 0 : maData.erase(itr);
355 0 : }
356 :
357 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|