update dev300-m58
[ooovba.git] / forms / source / misc / limitedformats.cxx
blob8079dab0380227766a7ae7fdd4cf43d5d6756a43
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: limitedformats.cxx,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_forms.hxx"
33 #include "limitedformats.hxx"
34 #include "services.hxx"
35 #include <osl/diagnose.h>
36 #include <comphelper/types.hxx>
37 #include <comphelper/extract.hxx>
38 #include <com/sun/star/form/FormComponentType.hpp>
40 //.........................................................................
41 namespace frm
43 //.........................................................................
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::util;
47 using namespace ::com::sun::star::lang;
48 using namespace ::com::sun::star::form;
49 using namespace ::com::sun::star::beans;
51 sal_Int32 OLimitedFormats::s_nInstanceCount(0);
52 ::osl::Mutex OLimitedFormats::s_aMutex;
53 Reference< XNumberFormatsSupplier > OLimitedFormats::s_xStandardFormats;
55 //=====================================================================
56 //=
57 //=====================================================================
58 //---------------------------------------------------------------------
59 enum LocaleType
61 ltEnglishUS,
62 ltGerman,
63 ltSystem
66 //---------------------------------------------------------------------
67 static const Locale& getLocale(LocaleType _eType)
69 static const Locale s_aEnglishUS( ::rtl::OUString::createFromAscii("en"), ::rtl::OUString::createFromAscii("us"), ::rtl::OUString() );
70 static const Locale s_aGerman( ::rtl::OUString::createFromAscii("de"), ::rtl::OUString::createFromAscii("DE"), ::rtl::OUString() );
71 static const ::rtl::OUString s_sEmptyString;
72 static const Locale s_aSystem( s_sEmptyString, s_sEmptyString, s_sEmptyString );
74 switch (_eType)
76 case ltEnglishUS:
77 return s_aEnglishUS;
79 case ltGerman:
80 return s_aGerman;
82 case ltSystem:
83 return s_aSystem;
86 OSL_ENSURE(sal_False, "getLocale: invalid enum value!");
87 return s_aSystem;
90 //---------------------------------------------------------------------
91 struct FormatEntry
93 const sal_Char* pDescription;
94 sal_Int32 nKey;
95 LocaleType eLocale;
98 //---------------------------------------------------------------------
99 static const FormatEntry* lcl_getFormatTable(sal_Int16 nTableId)
101 switch (nTableId)
103 case FormComponentType::TIMEFIELD:
105 static FormatEntry s_aFormats[] = {
106 { "HH:MM", -1, ltEnglishUS },
107 { "HH:MM:SS", -1, ltEnglishUS },
108 { "HH:MM AM/PM", -1, ltEnglishUS },
109 { "HH:MM:SS AM/PM", -1, ltEnglishUS },
110 { NULL, -1, ltSystem }
112 // don't switch this table here to const. The compiler could be tempted to really place this
113 // in a non-writeable segment, but we want to fill in the format keys later ....
114 return s_aFormats;
116 case FormComponentType::DATEFIELD:
118 static FormatEntry s_aFormats[] = {
119 { "T-M-JJ", -1, ltGerman },
120 { "TT-MM-JJ", -1, ltGerman },
121 { "TT-MM-JJJJ", -1, ltGerman },
122 { "NNNNT. MMMM JJJJ", -1, ltGerman },
124 { "DD/MM/YY", -1, ltEnglishUS },
125 { "MM/DD/YY", -1, ltEnglishUS },
126 { "YY/MM/DD", -1, ltEnglishUS },
127 { "DD/MM/YYYY", -1, ltEnglishUS },
128 { "MM/DD/YYYY", -1, ltEnglishUS },
129 { "YYYY/MM/DD", -1, ltEnglishUS },
131 { "JJ-MM-TT", -1, ltGerman },
132 { "JJJJ-MM-TT", -1, ltGerman },
134 { NULL, -1, ltSystem }
136 return s_aFormats;
140 OSL_ENSURE(sal_False, "lcl_getFormatTable: invalid id!");
141 return NULL;
144 //=====================================================================
145 //= OLimitedFormats
146 //=====================================================================
147 //---------------------------------------------------------------------
148 OLimitedFormats::OLimitedFormats(const Reference< XMultiServiceFactory >& _rxORB, const sal_Int16 _nClassId)
149 :m_nFormatEnumPropertyHandle(-1)
150 ,m_nTableId(_nClassId)
152 OSL_ENSURE(_rxORB.is(), "OLimitedFormats::OLimitedFormats: invalid service factory!");
153 acquireSupplier(_rxORB);
154 ensureTableInitialized(m_nTableId);
157 //---------------------------------------------------------------------
158 OLimitedFormats::~OLimitedFormats()
160 releaseSupplier();
163 //---------------------------------------------------------------------
164 void OLimitedFormats::ensureTableInitialized(const sal_Int16 _nTableId)
166 const FormatEntry* pFormatTable = lcl_getFormatTable(_nTableId);
167 if (-1 == pFormatTable->nKey)
169 ::osl::MutexGuard aGuard(s_aMutex);
170 if (-1 == pFormatTable->nKey)
172 // initialize the keys
173 Reference<XNumberFormats> xStandardFormats;
174 if (s_xStandardFormats.is())
175 xStandardFormats = s_xStandardFormats->getNumberFormats();
176 OSL_ENSURE(xStandardFormats.is(), "OLimitedFormats::ensureTableInitialized: don't have a formats supplier!");
178 if (xStandardFormats.is())
180 // loop through the table
181 FormatEntry* pLoopFormats = const_cast<FormatEntry*>(pFormatTable);
182 while (pLoopFormats->pDescription)
184 // get the key for the description
185 pLoopFormats->nKey = xStandardFormats->queryKey(
186 ::rtl::OUString::createFromAscii(pLoopFormats->pDescription),
187 getLocale(pLoopFormats->eLocale),
188 sal_False
191 if (-1 == pLoopFormats->nKey)
193 pLoopFormats->nKey = xStandardFormats->addNew(
194 ::rtl::OUString::createFromAscii(pLoopFormats->pDescription),
195 getLocale(pLoopFormats->eLocale)
197 #ifdef DBG_UTIL
200 xStandardFormats->getByKey(pLoopFormats->nKey);
202 catch(const Exception&)
204 OSL_ENSURE(sal_False, "OLimitedFormats::ensureTableInitialized: adding the key to the formats collection failed!");
206 #endif
209 // next
210 ++pLoopFormats;
217 //---------------------------------------------------------------------
218 void OLimitedFormats::clearTable(const sal_Int16 _nTableId)
220 ::osl::MutexGuard aGuard(s_aMutex);
221 const FormatEntry* pFormats = lcl_getFormatTable(_nTableId);
222 FormatEntry* pResetLoop = const_cast<FormatEntry*>(pFormats);
223 while (pResetLoop->pDescription)
225 pResetLoop->nKey = -1;
226 ++pResetLoop;
230 //---------------------------------------------------------------------
231 void OLimitedFormats::setAggregateSet(const Reference< XFastPropertySet >& _rxAggregate, sal_Int32 _nOriginalPropertyHandle)
233 // changes (NULL -> not NULL) and (not NULL -> NULL) are allowed
234 OSL_ENSURE(!m_xAggregate.is() || !_rxAggregate.is(), "OLimitedFormats::setAggregateSet: already have an aggregate!");
235 OSL_ENSURE(_rxAggregate.is() || m_xAggregate.is(), "OLimitedFormats::setAggregateSet: invalid new aggregate!");
237 m_xAggregate = _rxAggregate;
238 m_nFormatEnumPropertyHandle = _nOriginalPropertyHandle;
239 #ifdef DBG_UTIL
240 if (m_xAggregate.is())
244 m_xAggregate->getFastPropertyValue(m_nFormatEnumPropertyHandle);
246 catch(const Exception&)
248 OSL_ENSURE(sal_False, "OLimitedFormats::setAggregateSet: invalid handle!");
251 #endif
254 //---------------------------------------------------------------------
255 void OLimitedFormats::getFormatKeyPropertyValue( Any& _rValue ) const
257 _rValue.clear();
259 OSL_ENSURE(m_xAggregate.is() && (-1 != m_nFormatEnumPropertyHandle), "OLimitedFormats::getFormatKeyPropertyValue: not initialized!");
260 if (m_xAggregate.is())
262 // get the aggregate's enum property value
263 Any aEnumPropertyValue = m_xAggregate->getFastPropertyValue(m_nFormatEnumPropertyHandle);
264 sal_Int32 nValue = -1;
265 ::cppu::enum2int(nValue, aEnumPropertyValue);
267 // get the translation table
268 const FormatEntry* pFormats = lcl_getFormatTable(m_nTableId);
270 // seek to the nValue'th entry
271 sal_Int32 nLookup = 0;
272 for ( ;
273 (NULL != pFormats->pDescription) && (nLookup < nValue);
274 ++pFormats, ++nLookup
277 OSL_ENSURE(NULL != pFormats->pDescription, "OLimitedFormats::getFormatKeyPropertyValue: did not find the value!");
278 if (pFormats->pDescription)
279 _rValue <<= pFormats->nKey;
282 // TODO: should use a standard format for the control type we're working for
285 //---------------------------------------------------------------------
286 sal_Bool OLimitedFormats::convertFormatKeyPropertyValue(Any& _rConvertedValue, Any& _rOldValue, const Any& _rNewValue)
288 OSL_ENSURE(m_xAggregate.is() && (-1 != m_nFormatEnumPropertyHandle), "OLimitedFormats::convertFormatKeyPropertyValue: not initialized!");
290 if (m_xAggregate.is())
292 // the new format key to set
293 sal_Int32 nNewFormat = 0;
294 if (!(_rNewValue >>= nNewFormat))
295 throw IllegalArgumentException();
297 // get the old (enum) value from the aggregate
298 Any aEnumPropertyValue = m_xAggregate->getFastPropertyValue(m_nFormatEnumPropertyHandle);
299 sal_Int32 nOldEnumValue = -1;
300 ::cppu::enum2int(nOldEnumValue, aEnumPropertyValue);
302 // get the translation table
303 const FormatEntry* pFormats = lcl_getFormatTable(m_nTableId);
305 _rOldValue.clear();
306 _rConvertedValue.clear();
308 // look for the entry with the given format key
309 sal_Int32 nTablePosition = 0;
310 for ( ;
311 (NULL != pFormats->pDescription) && (nNewFormat != pFormats->nKey);
312 ++pFormats, ++nTablePosition
315 if (nTablePosition == nOldEnumValue)
316 _rOldValue <<= pFormats->nKey;
319 sal_Bool bFoundIt = (NULL != pFormats->pDescription);
320 sal_Bool bModified = sal_False;
321 if (bFoundIt)
323 _rConvertedValue <<= (sal_Int16)nTablePosition;
324 bModified = nTablePosition != nOldEnumValue;
327 if (!_rOldValue.hasValue())
328 { // did not reach the end of the table (means we found nNewFormat)
329 // -> go to the end to ensure that _rOldValue is set
330 while (pFormats->pDescription)
332 if (nTablePosition == nOldEnumValue)
334 _rOldValue <<= pFormats->nKey;
335 break;
338 ++pFormats;
339 ++nTablePosition;
343 OSL_ENSURE(_rOldValue.hasValue(), "OLimitedFormats::convertFormatKeyPropertyValue: did not find the old enum value in the table!");
345 if (!bFoundIt)
346 { // somebody gave us an format which we can't translate
347 ::rtl::OUString sMessage = ::rtl::OUString::createFromAscii("This control supports only a very limited number of formats.");
348 throw IllegalArgumentException(sMessage, NULL, 2);
351 return bModified;
354 return sal_False;
357 //---------------------------------------------------------------------
358 void OLimitedFormats::setFormatKeyPropertyValue( const Any& _rNewValue )
360 OSL_ENSURE(m_xAggregate.is() && (-1 != m_nFormatEnumPropertyHandle), "OLimitedFormats::setFormatKeyPropertyValue: not initialized!");
362 if (m_xAggregate.is())
363 { // this is to be called after convertFormatKeyPropertyValue, where
364 // we translated the format key into a enum value.
365 // So now we can simply forward this enum value to our aggreate
366 m_xAggregate->setFastPropertyValue(m_nFormatEnumPropertyHandle, _rNewValue);
370 //---------------------------------------------------------------------
371 void OLimitedFormats::acquireSupplier(const Reference< XMultiServiceFactory >& _rxORB)
373 ::osl::MutexGuard aGuard(s_aMutex);
374 if ((1 == ++s_nInstanceCount) && _rxORB.is())
375 { // create the standard formatter
377 Sequence< Any > aInit(1);
378 aInit[0] <<= getLocale(ltEnglishUS);
380 Reference< XInterface > xSupplier = _rxORB->createInstanceWithArguments(FRM_NUMBER_FORMATS_SUPPLIER, aInit);
381 OSL_ENSURE(xSupplier.is(), "OLimitedFormats::OLimitedFormats: could not create a formats supplier!");
383 s_xStandardFormats = Reference< XNumberFormatsSupplier >(xSupplier, UNO_QUERY);
384 OSL_ENSURE(s_xStandardFormats.is() || !xSupplier.is(), "OLimitedFormats::OLimitedFormats: missing an interface!");
388 //---------------------------------------------------------------------
389 void OLimitedFormats::releaseSupplier()
391 ::osl::MutexGuard aGuard(s_aMutex);
392 if (0 == --s_nInstanceCount)
394 ::comphelper::disposeComponent(s_xStandardFormats);
395 s_xStandardFormats = NULL;
397 clearTable(FormComponentType::TIMEFIELD);
398 clearTable(FormComponentType::DATEFIELD);
402 //.........................................................................
403 } // namespace frm
404 //.........................................................................