1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <unotools/charclass.hxx>
23 #include "userlist.hxx"
24 #include <unotools/localedatawrapper.hxx>
25 #include <unotools/calendarwrapper.hxx>
26 #include <unotools/transliterationwrapper.hxx>
28 #include <boost/bind.hpp>
33 class FindByName
: public ::std::unary_function
<ScUserListData::SubStr
, bool>
35 const OUString
& mrName
;
38 FindByName(const OUString
& rName
, bool bUpper
) : mrName(rName
), mbUpper(bUpper
) {}
39 bool operator() (const ScUserListData::SubStr
& r
) const
41 return mbUpper
? r
.maUpper
.equals(mrName
) : r
.maReal
.equals(mrName
);
47 ScUserListData::SubStr::SubStr(const OUString
& rReal
, const OUString
& rUpper
) :
48 maReal(rReal
), maUpper(rUpper
) {}
50 void ScUserListData::InitTokens()
52 sal_Unicode cSep
= ScGlobal::cListDelimiter
;
54 const sal_Unicode
* p
= aStr
.getStr();
55 const sal_Unicode
* p0
= p
;
58 for (sal_Int32 i
= 0, n
= aStr
.getLength(); i
< n
; ++i
, ++p
, ++nLen
)
62 // very first character, or the first character after a separator.
71 OUString
aSub(p0
, nLen
);
72 OUString aUpStr
= ScGlobal::pCharClass
->uppercase(aSub
);
73 maSubStrings
.push_back(new SubStr(aSub
, aUpStr
));
81 OUString
aSub(p0
, nLen
);
82 OUString aUpStr
= ScGlobal::pCharClass
->uppercase(aSub
);
83 maSubStrings
.push_back(new SubStr(aSub
, aUpStr
));
87 ScUserListData::ScUserListData(const OUString
& rStr
) :
93 ScUserListData::ScUserListData(const ScUserListData
& rData
) :
99 ScUserListData::~ScUserListData()
103 void ScUserListData::SetString( const OUString
& rStr
)
109 size_t ScUserListData::GetSubCount() const
111 return maSubStrings
.size();
114 bool ScUserListData::GetSubIndex(const OUString
& rSubStr
, sal_uInt16
& rIndex
) const
116 // First, case sensitive search.
117 SubStringsType::const_iterator itr
= ::std::find_if(
118 maSubStrings
.begin(), maSubStrings
.end(), FindByName(rSubStr
, false));
119 if (itr
!= maSubStrings
.end())
121 rIndex
= ::std::distance(maSubStrings
.begin(), itr
);
125 // When that fails, do a case insensitive search.
126 OUString aTmp
= ScGlobal::pCharClass
->uppercase(rSubStr
);
127 OUString aUpStr
= aTmp
;
128 itr
= ::std::find_if(
129 maSubStrings
.begin(), maSubStrings
.end(), FindByName(aUpStr
, true));
130 if (itr
!= maSubStrings
.end())
132 rIndex
= ::std::distance(maSubStrings
.begin(), itr
);
138 OUString
ScUserListData::GetSubStr(sal_uInt16 nIndex
) const
140 if (nIndex
< maSubStrings
.size())
141 return maSubStrings
[nIndex
].maReal
;
146 sal_Int32
ScUserListData::Compare(const OUString
& rSubStr1
, const OUString
& rSubStr2
) const
148 sal_uInt16 nIndex1
, nIndex2
;
149 bool bFound1
= GetSubIndex(rSubStr1
, nIndex1
);
150 bool bFound2
= GetSubIndex(rSubStr2
, nIndex2
);
155 if (nIndex1
< nIndex2
)
157 else if (nIndex1
> nIndex2
)
168 return ScGlobal::GetCaseTransliteration()->compareString( rSubStr1
, rSubStr2
);
171 sal_Int32
ScUserListData::ICompare(const OUString
& rSubStr1
, const OUString
& rSubStr2
) const
173 sal_uInt16 nIndex1
, nIndex2
;
174 bool bFound1
= GetSubIndex(rSubStr1
, nIndex1
);
175 bool bFound2
= GetSubIndex(rSubStr2
, nIndex2
);
180 if (nIndex1
< nIndex2
)
182 else if (nIndex1
> nIndex2
)
193 return ScGlobal::GetpTransliteration()->compareString( rSubStr1
, rSubStr2
);
196 ScUserList::ScUserList()
198 using namespace ::com::sun::star
;
200 sal_Unicode cDelimiter
= ScGlobal::cListDelimiter
;
201 uno::Sequence
< i18n::CalendarItem2
> xCal
;
203 uno::Sequence
< i18n::Calendar2
> xCalendars(
204 ScGlobal::pLocaleData
->getAllCalendars() );
206 for ( sal_Int32 j
= 0; j
< xCalendars
.getLength(); ++j
)
208 xCal
= xCalendars
[j
].Days
;
209 if ( xCal
.getLength() )
211 OUStringBuffer aDayShortBuf
, aDayLongBuf
;
213 sal_Int32 nLen
= xCal
.getLength();
214 sal_Int16 nStart
= sal::static_int_cast
<sal_Int16
>(nLen
);
217 if (xCal
[--nStart
].ID
== xCalendars
[j
].StartOfWeek
)
220 sal_Int16 nLast
= sal::static_int_cast
<sal_Int16
>( (nStart
+ nLen
- 1) % nLen
);
221 for (i
= nStart
; i
!= nLast
; i
= (i
+1) % nLen
)
223 aDayShortBuf
.append(xCal
[i
].AbbrevName
);
224 aDayShortBuf
.append(cDelimiter
);
225 aDayLongBuf
.append(xCal
[i
].FullName
);
226 aDayLongBuf
.append(cDelimiter
);
228 aDayShortBuf
.append(xCal
[i
].AbbrevName
);
229 aDayLongBuf
.append(xCal
[i
].FullName
);
231 OUString aDayShort
= aDayShortBuf
.makeStringAndClear();
232 OUString aDayLong
= aDayLongBuf
.makeStringAndClear();
234 if ( !HasEntry( aDayShort
) )
235 maData
.push_back( new ScUserListData( aDayShort
));
236 if ( !HasEntry( aDayLong
) )
237 maData
.push_back( new ScUserListData( aDayLong
));
240 xCal
= xCalendars
[j
].Months
;
241 if ( xCal
.getLength() )
243 OUStringBuffer aMonthShortBuf
, aMonthLongBuf
;
245 sal_Int32 nLen
= xCal
.getLength() - 1;
246 for (i
= 0; i
< nLen
; i
++)
248 aMonthShortBuf
.append(xCal
[i
].AbbrevName
);
249 aMonthShortBuf
.append(cDelimiter
);
250 aMonthLongBuf
.append(xCal
[i
].FullName
);
251 aMonthLongBuf
.append(cDelimiter
);
253 aMonthShortBuf
.append(xCal
[i
].AbbrevName
);
254 aMonthLongBuf
.append(xCal
[i
].FullName
);
256 OUString aMonthShort
= aMonthShortBuf
.makeStringAndClear();
257 OUString aMonthLong
= aMonthLongBuf
.makeStringAndClear();
259 if ( !HasEntry( aMonthShort
) )
260 maData
.push_back( new ScUserListData( aMonthShort
));
261 if ( !HasEntry( aMonthLong
) )
262 maData
.push_back( new ScUserListData( aMonthLong
));
267 ScUserList::ScUserList(const ScUserList
& r
) :
270 const ScUserListData
* ScUserList::GetData(const OUString
& rSubStr
) const
272 DataType::const_iterator itr
= maData
.begin(), itrEnd
= maData
.end();
273 for (; itr
!= itrEnd
; ++itr
)
276 if (itr
->GetSubIndex(rSubStr
, nIndex
))
282 const ScUserListData
* ScUserList::operator[](size_t nIndex
) const
284 return &maData
[nIndex
];
287 ScUserListData
* ScUserList::operator[](size_t nIndex
)
289 return &maData
[nIndex
];
292 ScUserList
& ScUserList::operator=( const ScUserList
& r
)
298 bool ScUserList::operator==( const ScUserList
& r
) const
300 if (size() != r
.size())
303 DataType::const_iterator itr1
= maData
.begin(), itr2
= r
.maData
.begin(), itrEnd
= maData
.end();
304 for (; itr1
!= itrEnd
; ++itr1
, ++itr2
)
306 const ScUserListData
& v1
= *itr1
;
307 const ScUserListData
& v2
= *itr2
;
308 if (v1
.GetString() != v2
.GetString() || v1
.GetSubCount() != v2
.GetSubCount())
314 bool ScUserList::operator!=( const ScUserList
& r
) const
316 return !operator==( r
);
320 bool ScUserList::HasEntry( const OUString
& rStr
) const
322 DataType::const_iterator itr
= ::std::find_if(
323 maData
.begin(), maData
.end(), ::boost::bind(&ScUserListData::GetString
, _1
) == rStr
);
324 return itr
!= maData
.end();
327 ScUserList::iterator
ScUserList::begin()
329 return maData
.begin();
332 ScUserList::const_iterator
ScUserList::begin() const
334 return maData
.begin();
337 void ScUserList::clear()
342 size_t ScUserList::size() const
344 return maData
.size();
347 void ScUserList::push_back(ScUserListData
* p
)
352 void ScUserList::erase(iterator itr
)
357 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */