1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: limitedformats.cxx,v $
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 //.........................................................................
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 //=====================================================================
57 //=====================================================================
58 //---------------------------------------------------------------------
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
);
86 OSL_ENSURE(sal_False
, "getLocale: invalid enum value!");
90 //---------------------------------------------------------------------
93 const sal_Char
* pDescription
;
98 //---------------------------------------------------------------------
99 static const FormatEntry
* lcl_getFormatTable(sal_Int16 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 ....
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
}
140 OSL_ENSURE(sal_False
, "lcl_getFormatTable: invalid id!");
144 //=====================================================================
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()
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
),
191 if (-1 == pLoopFormats
->nKey
)
193 pLoopFormats
->nKey
= xStandardFormats
->addNew(
194 ::rtl::OUString::createFromAscii(pLoopFormats
->pDescription
),
195 getLocale(pLoopFormats
->eLocale
)
200 xStandardFormats
->getByKey(pLoopFormats
->nKey
);
202 catch(const Exception
&)
204 OSL_ENSURE(sal_False
, "OLimitedFormats::ensureTableInitialized: adding the key to the formats collection failed!");
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;
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
;
240 if (m_xAggregate
.is())
244 m_xAggregate
->getFastPropertyValue(m_nFormatEnumPropertyHandle
);
246 catch(const Exception
&)
248 OSL_ENSURE(sal_False
, "OLimitedFormats::setAggregateSet: invalid handle!");
254 //---------------------------------------------------------------------
255 void OLimitedFormats::getFormatKeyPropertyValue( Any
& _rValue
) const
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;
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
);
306 _rConvertedValue
.clear();
308 // look for the entry with the given format key
309 sal_Int32 nTablePosition
= 0;
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
;
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
;
343 OSL_ENSURE(_rOldValue
.hasValue(), "OLimitedFormats::convertFormatKeyPropertyValue: did not find the old enum value in the table!");
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);
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 //.........................................................................
404 //.........................................................................