1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_i18npool.hxx"
30 
31 #include "calendarImpl.hxx"
32 #include "localedata.hxx"
33 #include <comphelper/processfactory.hxx>
34 
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::lang;
37 using namespace ::com::sun::star::i18n;
38 using namespace ::rtl;
39 
40 #define ERROR RuntimeException()
41 
42 CalendarImpl::CalendarImpl(const Reference< XMultiServiceFactory > &rxMSF) : xMSF(rxMSF)
43 {
44 }
45 
46 CalendarImpl::~CalendarImpl()
47 {
48     // Clear lookuptable
49     for (size_t l = 0; l < lookupTable.size(); l++)
50         delete lookupTable[l];
51     lookupTable.clear();
52 }
53 
54 
55 void SAL_CALL
56 CalendarImpl::loadDefaultCalendar( const Locale& rLocale ) throw(RuntimeException)
57 {
58     Sequence< Calendar> xC = LocaleData().getAllCalendars(rLocale);
59     for (sal_Int32 i = 0; i < xC.getLength(); i++) {
60         if (xC[i].Default) {
61             loadCalendar(xC[i].Name, rLocale);
62             return;
63         }
64     }
65     throw ERROR;
66 }
67 
68 void SAL_CALL
69 CalendarImpl::loadCalendar(const OUString& uniqueID, const Locale& rLocale ) throw (RuntimeException)
70 {
71     Reference < XExtendedCalendar > xOldCalendar( xCalendar );  // backup
72     sal_Int32 i;
73 
74     for (i = 0; i < sal::static_int_cast<sal_Int32>(lookupTable.size()); i++) {
75         lookupTableItem *listItem = lookupTable[i];
76         if (uniqueID == listItem->uniqueID) {
77             xCalendar = listItem->xCalendar;
78             break;
79         }
80     }
81 
82     if (i >= sal::static_int_cast<sal_Int32>(lookupTable.size())) {
83         Reference < XInterface > xI = xMSF->createInstance(
84                 OUString::createFromAscii("com.sun.star.i18n.Calendar_") + uniqueID);
85 
86         if ( ! xI.is() ) {
87             // check if the calendar is defined in localedata, load gregorian calendar service.
88             Sequence< Calendar> xC = LocaleData().getAllCalendars(rLocale);
89             for (i = 0; i < xC.getLength(); i++) {
90                 if (uniqueID == xC[i].Name) {
91                     xI = xMSF->createInstance(
92                         OUString::createFromAscii("com.sun.star.i18n.Calendar_gregorian"));
93                     break;
94                 }
95             }
96         }
97 
98         if ( xI.is() )
99             xI->queryInterface(::getCppuType((const Reference< XExtendedCalendar>*)0)) >>= xCalendar;
100         else
101             throw ERROR;
102 
103         lookupTable.push_back( new lookupTableItem(uniqueID, xCalendar) );
104     }
105 
106     if ( !xCalendar.is() )
107     {
108         xCalendar = xOldCalendar;
109         throw ERROR;
110     }
111 
112     try
113     {
114         xCalendar->loadCalendar(uniqueID, rLocale);
115     }
116     catch ( Exception& )
117     {   // restore previous calendar and re-throw
118         xCalendar = xOldCalendar;
119         throw;
120     }
121 }
122 
123 Calendar SAL_CALL
124 CalendarImpl::getLoadedCalendar() throw(RuntimeException)
125 {
126     if (xCalendar.is())
127         return xCalendar->getLoadedCalendar();
128     else
129         throw ERROR ;
130 }
131 
132 Sequence< OUString > SAL_CALL
133 CalendarImpl::getAllCalendars( const Locale& rLocale ) throw(RuntimeException)
134 {
135     Sequence< Calendar> xC = LocaleData().getAllCalendars(rLocale);
136     sal_Int32 nLen = xC.getLength();
137     Sequence< OUString > xSeq( nLen );
138     for (sal_Int32 i = 0; i < nLen; i++)
139         xSeq[i] = xC[i].Name;
140     return xSeq;
141 }
142 
143 void SAL_CALL
144 CalendarImpl::setDateTime( double timeInDays ) throw(RuntimeException)
145 {
146     if (xCalendar.is())
147         xCalendar->setDateTime( timeInDays );
148     else
149         throw ERROR ;
150 }
151 
152 double SAL_CALL
153 CalendarImpl::getDateTime() throw(RuntimeException)
154 {
155     if (xCalendar.is())
156         return xCalendar->getDateTime();
157     else
158         throw ERROR ;
159 }
160 
161 OUString SAL_CALL
162 CalendarImpl::getUniqueID() throw(RuntimeException)
163 {
164     if (xCalendar.is())
165         return xCalendar->getUniqueID();
166     else
167         throw ERROR ;
168 }
169 
170 void SAL_CALL
171 CalendarImpl::setValue( sal_Int16 fieldIndex, sal_Int16 value ) throw(RuntimeException)
172 {
173     if (xCalendar.is())
174         xCalendar->setValue( fieldIndex, value );
175     else
176         throw ERROR ;
177 }
178 
179 sal_Int16 SAL_CALL
180 CalendarImpl::getValue( sal_Int16 fieldIndex ) throw(RuntimeException)
181 {
182     if (xCalendar.is())
183         return xCalendar->getValue( fieldIndex );
184     else
185         throw ERROR ;
186 }
187 
188 void SAL_CALL
189 CalendarImpl::addValue( sal_Int16 fieldIndex, sal_Int32 amount ) throw(RuntimeException)
190 {
191     if (xCalendar.is())
192         xCalendar->addValue( fieldIndex, amount);
193     else
194         throw ERROR ;
195 }
196 
197 sal_Int16 SAL_CALL
198 CalendarImpl::getFirstDayOfWeek() throw(RuntimeException)
199 {
200     if (xCalendar.is())
201         return xCalendar->getFirstDayOfWeek();
202     else
203         throw ERROR ;
204 }
205 
206 void SAL_CALL
207 CalendarImpl::setFirstDayOfWeek( sal_Int16 day )
208 throw(RuntimeException)
209 {
210     if (xCalendar.is())
211         xCalendar->setFirstDayOfWeek(day);
212     else
213         throw ERROR ;
214 }
215 
216 void SAL_CALL
217 CalendarImpl::setMinimumNumberOfDaysForFirstWeek( sal_Int16 days ) throw(RuntimeException)
218 {
219     if (xCalendar.is())
220         xCalendar->setMinimumNumberOfDaysForFirstWeek(days);
221     else
222         throw ERROR ;
223 }
224 
225 sal_Int16 SAL_CALL
226 CalendarImpl::getMinimumNumberOfDaysForFirstWeek() throw(RuntimeException)
227 {
228     if (xCalendar.is())
229         return xCalendar->getMinimumNumberOfDaysForFirstWeek();
230     else
231         throw ERROR ;
232 }
233 
234 
235 OUString SAL_CALL
236 CalendarImpl::getDisplayName( sal_Int16 displayIndex, sal_Int16 idx, sal_Int16 nameType ) throw(RuntimeException)
237 {
238     if (xCalendar.is())
239         return xCalendar->getDisplayName( displayIndex, idx, nameType );
240     else
241         throw ERROR ;
242 }
243 
244 sal_Int16 SAL_CALL
245 CalendarImpl::getNumberOfMonthsInYear() throw(RuntimeException)
246 {
247     if (xCalendar.is())
248         return xCalendar->getNumberOfMonthsInYear();
249     else
250         throw ERROR ;
251 }
252 
253 
254 sal_Int16 SAL_CALL
255 CalendarImpl::getNumberOfDaysInWeek() throw(RuntimeException)
256 {
257     if (xCalendar.is())
258         return xCalendar->getNumberOfDaysInWeek();
259     else
260         throw ERROR ;
261 }
262 
263 
264 Sequence< CalendarItem > SAL_CALL
265 CalendarImpl::getMonths() throw(RuntimeException)
266 {
267     if (xCalendar.is())
268         return xCalendar->getMonths();
269     else
270         throw ERROR ;
271 }
272 
273 
274 Sequence< CalendarItem > SAL_CALL
275 CalendarImpl::getDays() throw(RuntimeException)
276 {
277     if (xCalendar.is())
278         return xCalendar->getDays();
279     else
280         throw ERROR ;
281 }
282 
283 
284 sal_Bool SAL_CALL
285 CalendarImpl::isValid() throw(RuntimeException)
286 {
287     if (xCalendar.is())
288         return xCalendar->isValid();
289     else
290         throw ERROR ;
291 }
292 
293 OUString SAL_CALL
294 CalendarImpl::getDisplayString( sal_Int32 nCalendarDisplayCode, sal_Int16 nNativeNumberMode )
295 	throw (RuntimeException)
296 {
297     if (xCalendar.is())
298         return xCalendar->getDisplayString(nCalendarDisplayCode, nNativeNumberMode);
299     else
300         throw ERROR ;
301 }
302 
303 OUString SAL_CALL
304 CalendarImpl::getImplementationName(void) throw( RuntimeException )
305 {
306     return OUString::createFromAscii("com.sun.star.i18n.CalendarImpl");
307 }
308 
309 const sal_Char cCalendar[] = "com.sun.star.i18n.LocaleCalendar";
310 
311 sal_Bool SAL_CALL
312 CalendarImpl::supportsService(const OUString& rServiceName) throw( RuntimeException )
313 {
314     return !rServiceName.compareToAscii(cCalendar);
315 }
316 
317 Sequence< OUString > SAL_CALL
318 CalendarImpl::getSupportedServiceNames(void) throw( RuntimeException )
319 {
320     Sequence< OUString > aRet(1);
321     aRet[0] = OUString::createFromAscii(cCalendar);
322     return aRet;
323 }
324 
325