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 <sal/config.h>
22 #include <unotools/charclass.hxx>
25 #include <userlist.hxx>
26 #include <unotools/localedatawrapper.hxx>
27 #include <unotools/transliterationwrapper.hxx>
28 #include <com/sun/star/i18n/Calendar2.hpp>
33 ScUserListData::SubStr::SubStr(OUString
&& aReal
) :
34 maReal(std::move(aReal
)), maUpper(ScGlobal::getCharClass().uppercase(maReal
)) {}
36 void ScUserListData::InitTokens()
42 OUString aSub
= aStr
.getToken(0, ScGlobal::cListDelimiter
, nIndex
);
44 maSubStrings
.emplace_back(std::move(aSub
));
45 } while (nIndex
>= 0);
48 ScUserListData::ScUserListData(OUString _aStr
) :
49 aStr(std::move(_aStr
))
54 void ScUserListData::SetString( const OUString
& rStr
)
60 bool ScUserListData::GetSubIndex(const OUString
& rSubStr
, sal_uInt16
& rIndex
, bool& bMatchCase
) const
62 // First, case sensitive search.
63 auto itr
= ::std::find_if(maSubStrings
.begin(), maSubStrings
.end(),
64 [&rSubStr
](const SubStr
& item
) { return item
.maReal
== rSubStr
; });
65 if (itr
!= maSubStrings
.end())
67 rIndex
= ::std::distance(maSubStrings
.begin(), itr
);
72 // When that fails, do a case insensitive search.
74 OUString aUpStr
= ScGlobal::getCharClass().uppercase(rSubStr
);
75 itr
= ::std::find_if(maSubStrings
.begin(), maSubStrings
.end(),
76 [&aUpStr
](const SubStr
& item
) { return item
.maUpper
== aUpStr
; });
77 if (itr
!= maSubStrings
.end())
79 rIndex
= ::std::distance(maSubStrings
.begin(), itr
);
85 OUString
ScUserListData::GetSubStr(sal_uInt16 nIndex
) const
87 if (nIndex
< maSubStrings
.size())
88 return maSubStrings
[nIndex
].maReal
;
93 sal_Int32
ScUserListData::Compare(const OUString
& rSubStr1
, const OUString
& rSubStr2
) const
95 sal_uInt16 nIndex1
, nIndex2
;
97 bool bFound1
= GetSubIndex(rSubStr1
, nIndex1
, bMatchCase
);
98 bool bFound2
= GetSubIndex(rSubStr2
, nIndex2
, bMatchCase
);
103 if (nIndex1
< nIndex2
)
105 else if (nIndex1
> nIndex2
)
116 return ScGlobal::GetCaseTransliteration().compareString( rSubStr1
, rSubStr2
);
119 sal_Int32
ScUserListData::ICompare(const OUString
& rSubStr1
, const OUString
& rSubStr2
) const
121 sal_uInt16 nIndex1
, nIndex2
;
123 bool bFound1
= GetSubIndex(rSubStr1
, nIndex1
, bMatchCase
);
124 bool bFound2
= GetSubIndex(rSubStr2
, nIndex2
, bMatchCase
);
129 if (nIndex1
< nIndex2
)
131 else if (nIndex1
> nIndex2
)
142 return ScGlobal::GetTransliteration().compareString( rSubStr1
, rSubStr2
);
145 ScUserList::ScUserList(bool initDefault
)
151 void ScUserList::AddDefaults()
153 sal_Unicode cDelimiter
= ScGlobal::cListDelimiter
;
154 for (const auto& rCalendar
: ScGlobal::getLocaleData().getAllCalendars())
156 if (const auto& xCal
= rCalendar
.Days
; xCal
.hasElements())
158 OUStringBuffer
aDayShortBuf(32), aDayLongBuf(64);
160 sal_Int32 nLen
= xCal
.getLength();
161 sal_Int16 nStart
= sal::static_int_cast
<sal_Int16
>(nLen
);
164 if (xCal
[--nStart
].ID
== rCalendar
.StartOfWeek
)
167 sal_Int16 nLast
= sal::static_int_cast
<sal_Int16
>( (nStart
+ nLen
- 1) % nLen
);
168 for (i
= nStart
; i
!= nLast
; i
= (i
+1) % nLen
)
170 aDayShortBuf
.append(xCal
[i
].AbbrevName
);
171 aDayShortBuf
.append(cDelimiter
);
172 aDayLongBuf
.append(xCal
[i
].FullName
);
173 aDayLongBuf
.append(cDelimiter
);
175 aDayShortBuf
.append(xCal
[i
].AbbrevName
);
176 aDayLongBuf
.append(xCal
[i
].FullName
);
178 OUString aDayShort
= aDayShortBuf
.makeStringAndClear();
179 OUString aDayLong
= aDayLongBuf
.makeStringAndClear();
181 if ( !HasEntry( aDayShort
) )
182 emplace_back(aDayShort
);
183 if ( !HasEntry( aDayLong
) )
184 emplace_back(aDayLong
);
187 if (const auto& xCal
= rCalendar
.Months
; xCal
.hasElements())
189 OUStringBuffer
aMonthShortBuf(128), aMonthLongBuf(128);
191 sal_Int32 nLen
= xCal
.getLength() - 1;
192 for (i
= 0; i
< nLen
; i
++)
194 aMonthShortBuf
.append(xCal
[i
].AbbrevName
);
195 aMonthShortBuf
.append(cDelimiter
);
196 aMonthLongBuf
.append(xCal
[i
].FullName
);
197 aMonthLongBuf
.append(cDelimiter
);
199 aMonthShortBuf
.append(xCal
[i
].AbbrevName
);
200 aMonthLongBuf
.append(xCal
[i
].FullName
);
202 OUString aMonthShort
= aMonthShortBuf
.makeStringAndClear();
203 OUString aMonthLong
= aMonthLongBuf
.makeStringAndClear();
205 if ( !HasEntry( aMonthShort
) )
206 emplace_back(aMonthShort
);
207 if ( !HasEntry( aMonthLong
) )
208 emplace_back(aMonthLong
);
213 const ScUserListData
* ScUserList::GetData(const OUString
& rSubStr
) const
215 const ScUserListData
* pFirstCaseInsensitive
= nullptr;
217 bool bMatchCase
= false;
219 for (const auto& rxItem
: maData
)
221 if (rxItem
.GetSubIndex(rSubStr
, nIndex
, bMatchCase
))
225 if (!pFirstCaseInsensitive
)
226 pFirstCaseInsensitive
= &rxItem
;
230 return pFirstCaseInsensitive
;
233 bool ScUserList::operator==( const ScUserList
& r
) const
235 return std::equal(maData
.begin(), maData
.end(), r
.maData
.begin(), r
.maData
.end(),
236 [](const ScUserListData
& lhs
, const ScUserListData
& rhs
) {
237 return lhs
.GetString() == rhs
.GetString();
241 bool ScUserList::HasEntry( std::u16string_view rStr
) const
243 return ::std::any_of(maData
.begin(), maData
.end(),
244 [&] (ScUserListData
const& pData
)
245 { return pData
.GetString() == rStr
; } );
248 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */