Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / core / tool / userlist.cxx
bloba379e2288d13bdbcbd050894c4b05102f12779c7
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
22 #include "global.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>
31 namespace {
33 class FindByName : public ::std::unary_function<ScUserListData::SubStr, bool>
35 const OUString& mrName;
36 bool mbUpper;
37 public:
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;
53 maSubStrings.clear();
54 const sal_Unicode* p = aStr.getStr();
55 const sal_Unicode* p0 = p;
56 sal_Int32 nLen = 0;
57 bool bFirst = true;
58 for (sal_Int32 i = 0, n = aStr.getLength(); i < n; ++i, ++p, ++nLen)
60 if (bFirst)
62 // very first character, or the first character after a separator.
63 p0 = p;
64 nLen = 0;
65 bFirst = false;
67 if (*p == cSep)
69 if (nLen)
71 OUString aSub(p0, nLen);
72 OUString aUpStr = ScGlobal::pCharClass->uppercase(aSub);
73 maSubStrings.push_back(new SubStr(aSub, aUpStr));
75 bFirst = true;
79 if (nLen)
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) :
88 aStr(rStr)
90 InitTokens();
93 ScUserListData::ScUserListData(const ScUserListData& rData) :
94 aStr(rData.aStr)
96 InitTokens();
99 ScUserListData::~ScUserListData()
103 void ScUserListData::SetString( const OUString& rStr )
105 aStr = rStr;
106 InitTokens();
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);
122 return true;
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);
133 return true;
135 return false;
138 OUString ScUserListData::GetSubStr(sal_uInt16 nIndex) const
140 if (nIndex < maSubStrings.size())
141 return maSubStrings[nIndex].maReal;
142 else
143 return OUString();
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);
151 if (bFound1)
153 if (bFound2)
155 if (nIndex1 < nIndex2)
156 return -1;
157 else if (nIndex1 > nIndex2)
158 return 1;
159 else
160 return 0;
162 else
163 return -1;
165 else if (bFound2)
166 return 1;
167 else
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);
176 if (bFound1)
178 if (bFound2)
180 if (nIndex1 < nIndex2)
181 return -1;
182 else if (nIndex1 > nIndex2)
183 return 1;
184 else
185 return 0;
187 else
188 return -1;
190 else if (bFound2)
191 return 1;
192 else
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;
212 sal_Int32 i;
213 sal_Int32 nLen = xCal.getLength();
214 sal_Int16 nStart = sal::static_int_cast<sal_Int16>(nLen);
215 while (nStart > 0)
217 if (xCal[--nStart].ID == xCalendars[j].StartOfWeek)
218 break;
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;
244 sal_Int32 i;
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) :
268 maData(r.maData) {}
270 const ScUserListData* ScUserList::GetData(const OUString& rSubStr) const
272 DataType::const_iterator itr = maData.begin(), itrEnd = maData.end();
273 for (; itr != itrEnd; ++itr)
275 sal_uInt16 nIndex;
276 if (itr->GetSubIndex(rSubStr, nIndex))
277 return &(*itr);
279 return NULL;
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 )
294 maData = r.maData;
295 return *this;
298 bool ScUserList::operator==( const ScUserList& r ) const
300 if (size() != r.size())
301 return false;
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())
309 return false;
311 return true;
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()
339 maData.clear();
342 size_t ScUserList::size() const
344 return maData.size();
347 void ScUserList::push_back(ScUserListData* p)
349 maData.push_back(p);
352 void ScUserList::erase(iterator itr)
354 maData.erase(itr);
357 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */