1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <string.h>
21 
22 #include "Columns.hxx"
23 #include <property.hxx>
24 #include <componenttools.hxx>
25 #include "findpos.hxx"
26 #include <com/sun/star/io/XPersistObject.hpp>
27 #include <com/sun/star/io/XObjectOutputStream.hpp>
28 #include <com/sun/star/io/XObjectInputStream.hpp>
29 #include <com/sun/star/io/XMarkableStream.hpp>
30 #include <com/sun/star/form/XFormComponent.hpp>
31 #include <com/sun/star/lang/XServiceInfo.hpp>
32 #include <com/sun/star/form/binding/XBindableValue.hpp>
33 #include <com/sun/star/beans/XPropertyContainer.hpp>
34 #include <com/sun/star/text/XText.hpp>
35 #include <comphelper/property.hxx>
36 #include <comphelper/basicio.hxx>
37 #include <comphelper/servicehelper.hxx>
38 #include <comphelper/types.hxx>
39 #include <services.hxx>
40 #include <strings.hrc>
41 #include <tools/debug.hxx>
42 
43 
44 namespace frm
45 {
46 
47 using namespace ::com::sun::star::uno;
48 using namespace ::com::sun::star::beans;
49 using namespace ::com::sun::star::container;
50 using namespace ::com::sun::star::form;
51 using namespace ::com::sun::star::awt;
52 using namespace ::com::sun::star::io;
53 using namespace ::com::sun::star::lang;
54 using namespace ::com::sun::star::util;
55 using namespace ::com::sun::star::text;
56 using namespace ::com::sun::star::form::binding;
57 
58 const sal_uInt16 WIDTH              = 0x0001;
59 const sal_uInt16 ALIGN              = 0x0002;
60 const sal_uInt16 OLD_HIDDEN         = 0x0004;
61 const sal_uInt16 COMPATIBLE_HIDDEN  = 0x0008;
62 
63 
getColumnTypes()64 const css::uno::Sequence<OUString>& getColumnTypes()
65 {
66     static css::uno::Sequence<OUString> aColumnTypes = [&]()
67     {
68         css::uno::Sequence<OUString> tmp(10);
69         OUString* pNames = tmp.getArray();
70         pNames[TYPE_CHECKBOX]       = "CheckBox";
71         pNames[TYPE_COMBOBOX]       = "ComboBox";
72         pNames[TYPE_CURRENCYFIELD]  = "CurrencyField";
73         pNames[TYPE_DATEFIELD]      = "DateField";
74         pNames[TYPE_FORMATTEDFIELD] = "FormattedField";
75         pNames[TYPE_LISTBOX]        = "ListBox";
76         pNames[TYPE_NUMERICFIELD]   = "NumericField";
77         pNames[TYPE_PATTERNFIELD]   = "PatternField";
78         pNames[TYPE_TEXTFIELD]      = "TextField";
79         pNames[TYPE_TIMEFIELD]      = "TimeField";
80         return tmp;
81     }();
82     return aColumnTypes;
83 }
84 
85 
getColumnTypeByModelName(const OUString & aModelName)86 sal_Int32 getColumnTypeByModelName(const OUString& aModelName)
87 {
88     const OUString aModelPrefix ("com.sun.star.form.component.");
89     const OUString aCompatibleModelPrefix ("stardiv.one.form.component.");
90 
91     sal_Int32 nTypeId = -1;
92     if (aModelName == FRM_COMPONENT_EDIT)
93         nTypeId = TYPE_TEXTFIELD;
94     else
95     {
96         sal_Int32 nPrefixPos = aModelName.indexOf(aModelPrefix);
97 #ifdef DBG_UTIL
98         sal_Int32 nCompatiblePrefixPos = aModelName.indexOf(aCompatibleModelPrefix);
99         DBG_ASSERT( (nPrefixPos != -1) ||   (nCompatiblePrefixPos != -1),
100                 "::getColumnTypeByModelName() : wrong servivce !");
101 #endif
102 
103         OUString aColumnType = (nPrefixPos != -1)
104             ? aModelName.copy(aModelPrefix.getLength())
105             : aModelName.copy(aCompatibleModelPrefix.getLength());
106 
107         const css::uno::Sequence<OUString>& rColumnTypes = getColumnTypes();
108         nTypeId = ::detail::findPos(aColumnType, rColumnTypes);
109     }
110     return nTypeId;
111 }
112 
113 namespace
114 {
115     class theOGridColumnImplementationId : public rtl::Static< UnoTunnelIdInit, theOGridColumnImplementationId > {};
116 }
117 
getUnoTunnelId()118 const Sequence<sal_Int8>& OGridColumn::getUnoTunnelId()
119 {
120     return theOGridColumnImplementationId::get().getSeq();
121 }
122 
123 
getSomething(const Sequence<sal_Int8> & _rIdentifier)124 sal_Int64 SAL_CALL OGridColumn::getSomething( const Sequence<sal_Int8>& _rIdentifier)
125 {
126     sal_Int64 nReturn(0);
127 
128     if ( isUnoTunnelId<OGridColumn>(_rIdentifier) )
129     {
130         nReturn = reinterpret_cast<sal_Int64>(this);
131     }
132     else
133     {
134         Reference< XUnoTunnel > xAggTunnel;
135         if ( query_aggregation( m_xAggregate, xAggTunnel ) )
136             return xAggTunnel->getSomething( _rIdentifier );
137     }
138     return nReturn;
139 }
140 
141 
getImplementationId()142 Sequence<sal_Int8> SAL_CALL OGridColumn::getImplementationId()
143 {
144     return css::uno::Sequence<sal_Int8>();
145 }
146 
147 
getTypes()148 Sequence<Type> SAL_CALL OGridColumn::getTypes()
149 {
150     TypeBag aTypes( OGridColumn_BASE::getTypes() );
151     // erase the types which we do not support
152     aTypes.removeType( cppu::UnoType<XFormComponent>::get() );
153     aTypes.removeType( cppu::UnoType<XServiceInfo>::get() );
154     aTypes.removeType( cppu::UnoType<XBindableValue>::get() );
155     aTypes.removeType( cppu::UnoType<XPropertyContainer>::get() );
156 
157     // but re-add their base class(es)
158     aTypes.addType( cppu::UnoType<XChild>::get() );
159 
160     Reference< XTypeProvider > xProv;
161     if ( query_aggregation( m_xAggregate, xProv ))
162         aTypes.addTypes( xProv->getTypes() );
163 
164     aTypes.removeType( cppu::UnoType<XTextRange>::get() );
165     aTypes.removeType( cppu::UnoType<XSimpleText>::get() );
166     aTypes.removeType( cppu::UnoType<XText>::get() );
167 
168     return aTypes.getTypes();
169 }
170 
171 
queryAggregation(const Type & _rType)172 Any SAL_CALL OGridColumn::queryAggregation( const Type& _rType )
173 {
174     Any aReturn;
175     // some functionality at our aggregate cannot be reasonably fulfilled here.
176     if  (   _rType.equals(cppu::UnoType<XFormComponent>::get())
177         ||  _rType.equals(cppu::UnoType<XServiceInfo>::get())
178         ||  _rType.equals(cppu::UnoType<XBindableValue>::get())
179         ||  _rType.equals(cppu::UnoType<XPropertyContainer>::get())
180         ||  comphelper::isAssignableFrom(cppu::UnoType<XTextRange>::get(),_rType)
181         )
182         return aReturn;
183 
184     aReturn = OGridColumn_BASE::queryAggregation(_rType);
185     if (!aReturn.hasValue())
186     {
187         aReturn = OPropertySetAggregationHelper::queryInterface(_rType);
188         if (!aReturn.hasValue() && m_xAggregate.is())
189             aReturn = m_xAggregate->queryAggregation(_rType);
190     }
191 
192     return aReturn;
193 }
194 
195 
OGridColumn(const Reference<XComponentContext> & _rContext,const OUString & _sModelName)196 OGridColumn::OGridColumn( const Reference<XComponentContext>& _rContext, const OUString& _sModelName )
197     :OGridColumn_BASE(m_aMutex)
198     ,OPropertySetAggregationHelper(OGridColumn_BASE::rBHelper)
199     ,m_aHidden( makeAny( false ) )
200     ,m_aModelName(_sModelName)
201 {
202 
203     // Create the UnoControlModel
204     if ( !m_aModelName.isEmpty() ) // is there a to-be-aggregated model?
205     {
206         osl_atomic_increment( &m_refCount );
207 
208         {
209             m_xAggregate.set( _rContext->getServiceManager()->createInstanceWithContext( m_aModelName, _rContext ), UNO_QUERY );
210             setAggregation( m_xAggregate );
211         }
212 
213         if ( m_xAggregate.is() )
214         {   // don't omit those brackets - they ensure that the following temporary is properly deleted
215             m_xAggregate->setDelegator( static_cast< ::cppu::OWeakObject* >( this ) );
216         }
217 
218         // Set refcount back to zero
219         osl_atomic_decrement( &m_refCount );
220     }
221 }
222 
223 
OGridColumn(const OGridColumn * _pOriginal)224 OGridColumn::OGridColumn( const OGridColumn* _pOriginal )
225     :OGridColumn_BASE( m_aMutex )
226     ,OPropertySetAggregationHelper( OGridColumn_BASE::rBHelper )
227 {
228 
229     m_aWidth = _pOriginal->m_aWidth;
230     m_aAlign = _pOriginal->m_aAlign;
231     m_aHidden = _pOriginal->m_aHidden;
232     m_aModelName = _pOriginal->m_aModelName;
233     m_aLabel = _pOriginal->m_aLabel;
234 
235     osl_atomic_increment( &m_refCount );
236     {
237         {
238             m_xAggregate = createAggregateClone( _pOriginal );
239             setAggregation( m_xAggregate );
240         }
241 
242         if ( m_xAggregate.is() )
243         {   // don't omit this brackets - they ensure that the following temporary is properly deleted
244             m_xAggregate->setDelegator( static_cast< ::cppu::OWeakObject* >( this ) );
245         }
246     }
247     osl_atomic_decrement( &m_refCount );
248 }
249 
250 
~OGridColumn()251 OGridColumn::~OGridColumn()
252 {
253     if (!OGridColumn_BASE::rBHelper.bDisposed)
254     {
255         acquire();
256         dispose();
257     }
258 
259     // Free the aggregate
260     if (m_xAggregate.is())
261     {
262         css::uno::Reference<css::uno::XInterface>  xIface;
263         m_xAggregate->setDelegator(xIface);
264     }
265 
266 }
267 
268 // XEventListener
269 
disposing(const EventObject & _rSource)270 void SAL_CALL OGridColumn::disposing(const EventObject& _rSource)
271 {
272     OPropertySetAggregationHelper::disposing(_rSource);
273 
274     Reference<XEventListener>  xEvtLstner;
275     if (query_aggregation(m_xAggregate, xEvtLstner))
276         xEvtLstner->disposing(_rSource);
277 }
278 
279 // OGridColumn_BASE
280 
disposing()281 void OGridColumn::disposing()
282 {
283     OGridColumn_BASE::disposing();
284     OPropertySetAggregationHelper::disposing();
285 
286     Reference<XComponent>  xComp;
287     if (query_aggregation(m_xAggregate, xComp))
288         xComp->dispose();
289 }
290 
291 
clearAggregateProperties(Sequence<Property> & _rProps,bool bAllowDropDown)292 void OGridColumn::clearAggregateProperties( Sequence< Property >& _rProps, bool bAllowDropDown )
293 {
294     // some properties are not to be exposed to the outer world
295     ::std::set< OUString > aForbiddenProperties;
296     aForbiddenProperties.insert( PROPERTY_ALIGN );
297     aForbiddenProperties.insert( PROPERTY_AUTOCOMPLETE );
298     aForbiddenProperties.insert( PROPERTY_BACKGROUNDCOLOR );
299     aForbiddenProperties.insert( PROPERTY_BORDER );
300     aForbiddenProperties.insert( PROPERTY_BORDERCOLOR );
301     aForbiddenProperties.insert( PROPERTY_ECHO_CHAR );
302     aForbiddenProperties.insert( PROPERTY_FILLCOLOR );
303     aForbiddenProperties.insert( PROPERTY_FONT );
304     aForbiddenProperties.insert( PROPERTY_FONT_NAME );
305     aForbiddenProperties.insert( PROPERTY_FONT_STYLENAME );
306     aForbiddenProperties.insert( PROPERTY_FONT_FAMILY );
307     aForbiddenProperties.insert( PROPERTY_FONT_CHARSET );
308     aForbiddenProperties.insert( PROPERTY_FONT_HEIGHT );
309     aForbiddenProperties.insert( PROPERTY_FONT_WEIGHT );
310     aForbiddenProperties.insert( PROPERTY_FONT_SLANT );
311     aForbiddenProperties.insert( PROPERTY_FONT_UNDERLINE );
312     aForbiddenProperties.insert( PROPERTY_FONT_STRIKEOUT );
313     aForbiddenProperties.insert( PROPERTY_FONT_WORDLINEMODE );
314     aForbiddenProperties.insert( PROPERTY_TEXTLINECOLOR );
315     aForbiddenProperties.insert( PROPERTY_FONTEMPHASISMARK );
316     aForbiddenProperties.insert( PROPERTY_FONTRELIEF );
317     aForbiddenProperties.insert( PROPERTY_HARDLINEBREAKS );
318     aForbiddenProperties.insert( PROPERTY_HSCROLL );
319     aForbiddenProperties.insert( PROPERTY_LABEL );
320     aForbiddenProperties.insert( PROPERTY_LINECOLOR );
321     aForbiddenProperties.insert( PROPERTY_MULTISELECTION );
322     aForbiddenProperties.insert( PROPERTY_PRINTABLE );
323     aForbiddenProperties.insert( PROPERTY_TABINDEX );
324     aForbiddenProperties.insert( PROPERTY_TABSTOP );
325     aForbiddenProperties.insert( PROPERTY_TEXTCOLOR );
326     aForbiddenProperties.insert( PROPERTY_VSCROLL );
327     aForbiddenProperties.insert( PROPERTY_CONTROLLABEL );
328     aForbiddenProperties.insert( PROPERTY_RICH_TEXT );
329     aForbiddenProperties.insert( PROPERTY_VERTICAL_ALIGN );
330     aForbiddenProperties.insert( PROPERTY_IMAGE_URL );
331     aForbiddenProperties.insert( PROPERTY_IMAGE_POSITION );
332     aForbiddenProperties.insert( OUString( "EnableVisible" ) );
333     if ( !bAllowDropDown )
334         aForbiddenProperties.insert( PROPERTY_DROPDOWN );
335 
336     Sequence< Property > aNewProps( _rProps.getLength() );
337     Property* pNewProps = aNewProps.getArray();
338 
339     const Property* pProps = _rProps.getConstArray();
340     const Property* pPropsEnd = pProps + _rProps.getLength();
341     for ( ; pProps != pPropsEnd; ++pProps )
342     {
343         if ( aForbiddenProperties.find( pProps->Name ) == aForbiddenProperties.end() )
344             *pNewProps++ = *pProps;
345     }
346 
347     aNewProps.realloc( pNewProps - aNewProps.getArray() );
348     _rProps = aNewProps;
349 }
350 
351 
setOwnProperties(Sequence<Property> & aDescriptor)352 void OGridColumn::setOwnProperties(Sequence<Property>& aDescriptor)
353 {
354     aDescriptor.realloc(5);
355     Property* pProperties = aDescriptor.getArray();
356     DECL_PROP1(LABEL,               OUString,    BOUND);
357     DECL_PROP3(WIDTH,               sal_Int32,          BOUND, MAYBEVOID, MAYBEDEFAULT);
358     DECL_PROP3(ALIGN,               sal_Int16,          BOUND, MAYBEVOID, MAYBEDEFAULT);
359     DECL_BOOL_PROP2(HIDDEN,                             BOUND, MAYBEDEFAULT);
360     DECL_PROP1(COLUMNSERVICENAME,   OUString,    READONLY);
361 }
362 
363 // Reference<XPropertySet>
364 
getFastPropertyValue(Any & rValue,sal_Int32 nHandle) const365 void OGridColumn::getFastPropertyValue(Any& rValue, sal_Int32 nHandle ) const
366 {
367     switch (nHandle)
368     {
369         case PROPERTY_ID_COLUMNSERVICENAME:
370             rValue <<= m_aModelName;
371             break;
372         case PROPERTY_ID_LABEL:
373             rValue <<= m_aLabel;
374             break;
375         case PROPERTY_ID_WIDTH:
376             rValue = m_aWidth;
377             break;
378         case PROPERTY_ID_ALIGN:
379             rValue = m_aAlign;
380             break;
381         case PROPERTY_ID_HIDDEN:
382             rValue = m_aHidden;
383             break;
384         default:
385             OPropertySetAggregationHelper::getFastPropertyValue(rValue, nHandle);
386     }
387 }
388 
389 
convertFastPropertyValue(Any & rConvertedValue,Any & rOldValue,sal_Int32 nHandle,const Any & rValue)390 sal_Bool OGridColumn::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue,
391                                             sal_Int32 nHandle, const Any& rValue )
392 {
393     bool bModified(false);
394     switch (nHandle)
395     {
396         case PROPERTY_ID_LABEL:
397             bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aLabel);
398             break;
399         case PROPERTY_ID_WIDTH:
400             bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aWidth, cppu::UnoType<sal_Int32>::get());
401             break;
402         case PROPERTY_ID_ALIGN:
403             bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_aAlign, cppu::UnoType<sal_Int32>::get());
404             // strange enough, css.awt.TextAlign is a 32-bit integer, while the Align property (both here for grid controls
405             // and for ordinary toolkit controls) is a 16-bit integer. So, allow for 32 bit, but normalize it to 16 bit
406             if ( bModified )
407             {
408                 sal_Int32 nAlign( 0 );
409                 if ( rConvertedValue >>= nAlign )
410                     rConvertedValue <<= static_cast<sal_Int16>(nAlign);
411             }
412             break;
413         case PROPERTY_ID_HIDDEN:
414             bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, getBOOL(m_aHidden));
415             break;
416     }
417     return bModified;
418 }
419 
420 
setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any & rValue)421 void OGridColumn::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue )
422 {
423     switch (nHandle)
424     {
425         case PROPERTY_ID_LABEL:
426             DBG_ASSERT(rValue.getValueType().getTypeClass() == TypeClass_STRING, "invalid type" );
427             rValue >>= m_aLabel;
428             break;
429         case PROPERTY_ID_WIDTH:
430             m_aWidth = rValue;
431             break;
432         case PROPERTY_ID_ALIGN:
433             m_aAlign = rValue;
434             break;
435         case PROPERTY_ID_HIDDEN:
436             m_aHidden = rValue;
437             break;
438     }
439 }
440 
441 
442 // XPropertyState
443 
getPropertyDefaultByHandle(sal_Int32 nHandle) const444 Any OGridColumn::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
445 {
446     switch (nHandle)
447     {
448         case PROPERTY_ID_WIDTH:
449         case PROPERTY_ID_ALIGN:
450             return Any();
451         case PROPERTY_ID_HIDDEN:
452             return makeAny(false);
453         default:
454             return OPropertySetAggregationHelper::getPropertyDefaultByHandle(nHandle);
455     }
456 }
457 
458 // XCloneable
459 
createClone()460 Reference< XCloneable > SAL_CALL OGridColumn::createClone(  )
461 {
462     OGridColumn* pNewColumn = createCloneColumn();
463     return pNewColumn;
464 }
465 
466 // XPersistObject
467 
write(const Reference<XObjectOutputStream> & _rxOutStream)468 void OGridColumn::write(const Reference<XObjectOutputStream>& _rxOutStream)
469 {
470     // 1. Write the UnoControl
471     Reference<XMarkableStream>  xMark(_rxOutStream, UNO_QUERY);
472     sal_Int32 nMark = xMark->createMark();
473 
474     sal_Int32 nLen = 0;
475     _rxOutStream->writeLong(nLen);
476 
477     Reference<XPersistObject>  xPersist;
478     if (query_aggregation(m_xAggregate, xPersist))
479         xPersist->write(_rxOutStream);
480 
481     // Calculate the length
482     nLen = xMark->offsetToMark(nMark) - 4;
483     xMark->jumpToMark(nMark);
484     _rxOutStream->writeLong(nLen);
485     xMark->jumpToFurthest();
486     xMark->deleteMark(nMark);
487 
488     // 2. Write a version number
489     _rxOutStream->writeShort(0x0002);
490 
491     sal_uInt16 nAnyMask = 0;
492     if (m_aWidth.getValueType().getTypeClass() == TypeClass_LONG)
493         nAnyMask |= WIDTH;
494 
495     if (m_aAlign.getValueTypeClass() == TypeClass_SHORT)
496         nAnyMask |= ALIGN;
497 
498     nAnyMask |= COMPATIBLE_HIDDEN;
499 
500     _rxOutStream->writeShort(nAnyMask);
501 
502     if (nAnyMask & WIDTH)
503         _rxOutStream->writeLong(getINT32(m_aWidth));
504     if (nAnyMask & ALIGN)
505         _rxOutStream->writeShort(getINT16(m_aAlign));
506 
507     // Name
508     _rxOutStream << m_aLabel;
509 
510     // the new place for the hidden flag : after m_aLabel, so older office version read the correct label, too
511     if (nAnyMask & COMPATIBLE_HIDDEN)
512         _rxOutStream->writeBoolean(getBOOL(m_aHidden));
513 }
514 
515 
read(const Reference<XObjectInputStream> & _rxInStream)516 void OGridColumn::read(const Reference<XObjectInputStream>& _rxInStream)
517 {
518     // 1. Read the UnoControl
519     sal_Int32 nLen = _rxInStream->readLong();
520     if (nLen)
521     {
522         Reference<XMarkableStream>  xMark(_rxInStream, UNO_QUERY);
523         sal_Int32 nMark = xMark->createMark();
524         Reference<XPersistObject>  xPersist;
525         if (query_aggregation(m_xAggregate, xPersist))
526             xPersist->read(_rxInStream);
527 
528         xMark->jumpToMark(nMark);
529         _rxInStream->skipBytes(nLen);
530         xMark->deleteMark(nMark);
531     }
532 
533     // 2. Write a version number
534     _rxInStream->readShort(); // version;
535     sal_uInt16 nAnyMask = _rxInStream->readShort();
536 
537     if (nAnyMask & WIDTH)
538     {
539         sal_Int32 nValue = _rxInStream->readLong();
540         m_aWidth <<= nValue;
541     }
542 
543     if (nAnyMask & ALIGN)
544     {
545         sal_Int16 nValue = _rxInStream->readShort();
546         m_aAlign <<= nValue;
547     }
548     if (nAnyMask & OLD_HIDDEN)
549     {
550         bool bValue = _rxInStream->readBoolean();
551         m_aHidden <<= bValue;
552     }
553 
554     // Name
555     _rxInStream >> m_aLabel;
556 
557     if (nAnyMask & COMPATIBLE_HIDDEN)
558     {
559         bool bValue = _rxInStream->readBoolean();
560         m_aHidden <<= bValue;
561     }
562 }
563 
564 
565 IMPL_COLUMN(TextFieldColumn,        FRM_SUN_COMPONENT_TEXTFIELD,        false);
566 IMPL_COLUMN(PatternFieldColumn,     FRM_SUN_COMPONENT_PATTERNFIELD,     false);
567 IMPL_COLUMN(DateFieldColumn,        FRM_SUN_COMPONENT_DATEFIELD,        true);
568 IMPL_COLUMN(TimeFieldColumn,        FRM_SUN_COMPONENT_TIMEFIELD,        false);
569 IMPL_COLUMN(NumericFieldColumn,     FRM_SUN_COMPONENT_NUMERICFIELD,     false);
570 IMPL_COLUMN(CurrencyFieldColumn,    FRM_SUN_COMPONENT_CURRENCYFIELD,    false);
571 IMPL_COLUMN(CheckBoxColumn,         FRM_SUN_COMPONENT_CHECKBOX,         false);
572 IMPL_COLUMN(ComboBoxColumn,         FRM_SUN_COMPONENT_COMBOBOX,         false);
573 IMPL_COLUMN(ListBoxColumn,          FRM_SUN_COMPONENT_LISTBOX,          false);
574 IMPL_COLUMN(FormattedFieldColumn,   FRM_SUN_COMPONENT_FORMATTEDFIELD,   false);
575 
576 
577 }   // namespace frm
578 
579 
580 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
581