xref: /aoo42x/main/svx/source/fmcomp/gridcell.cxx (revision f6e50924)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 
27 
28 #include "fmprop.hrc"
29 #include "svx/fmresids.hrc"
30 #include "svx/fmtools.hxx"
31 #include "gridcell.hxx"
32 #include "gridcols.hxx"
33 #include "sdbdatacolumn.hxx"
34 
35 #include <com/sun/star/awt/LineEndFormat.hpp>
36 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
37 #include <com/sun/star/awt/VisualEffect.hpp>
38 #include <com/sun/star/container/XChild.hpp>
39 #include <com/sun/star/container/XNamed.hpp>
40 #include <com/sun/star/form/FormComponentType.hpp>
41 #include <com/sun/star/form/XBoundComponent.hpp>
42 #include <com/sun/star/script/XEventAttacherManager.hpp>
43 #include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
44 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
45 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
46 #include <com/sun/star/sdbc/ColumnValue.hpp>
47 #include <com/sun/star/sdbc/DataType.hpp>
48 #include <com/sun/star/sdbc/XStatement.hpp>
49 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
50 #include <com/sun/star/util/NumberFormat.hpp>
51 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
52 #include <com/sun/star/util/XNumberFormatter.hpp>
53 
54 #include <comphelper/extract.hxx>
55 #include <comphelper/numbers.hxx>
56 #include <comphelper/property.hxx>
57 #include <connectivity/formattedcolumnvalue.hxx>
58 #include <cppuhelper/typeprovider.hxx>
59 #include <i18npool/lang.h>
60 
61 #include <rtl/math.hxx>
62 #include <svtools/calendar.hxx>
63 #include <svtools/fmtfield.hxx>
64 #include <svl/numuno.hxx>
65 #include <svtools/svmedit.hxx>
66 #include <svx/dialmgr.hxx>
67 #include <toolkit/helper/vclunohelper.hxx>
68 #include <tools/diagnose_ex.h>
69 #include <tools/shl.hxx>
70 #include <vcl/longcurr.hxx>
71 
72 #include <math.h>
73 #include <stdio.h>
74 
75 using namespace ::connectivity;
76 using namespace ::connectivity::simple;
77 using namespace ::svxform;
78 using namespace ::comphelper;
79 using namespace ::svt;
80 using namespace ::com::sun::star;
81 using namespace ::com::sun::star::uno;
82 using namespace ::com::sun::star::sdbc;
83 using namespace ::com::sun::star::sdbcx;
84 using namespace ::com::sun::star::sdb;
85 using namespace ::com::sun::star::beans;
86 using namespace ::com::sun::star::form;
87 
88 using ::com::sun::star::util::XNumberFormatter;
89 namespace MouseWheelBehavior = ::com::sun::star::awt::MouseWheelBehavior;
90 
91 String INVALIDTEXT     = String::CreateFromAscii("###");
92 String OBJECTTEXT      = String::CreateFromAscii("<OBJECT>");
93     // TODO: resource
94 
95 //==================================================================
96 //= helper
97 //==================================================================
98 namespace
99 {
100     static LineEnd getModelLineEndSetting( const Reference< XPropertySet >& _rxModel )
101     {
102         LineEnd eFormat = LINEEND_LF;
103 
104         try
105         {
106             sal_Int16 nLineEndFormat = awt::LineEndFormat::LINE_FEED;
107 
108             Reference< XPropertySetInfo > xPSI;
109             if ( _rxModel.is() )
110                 xPSI = _rxModel->getPropertySetInfo();
111 
112             OSL_ENSURE( xPSI.is(), "getModelLineEndSetting: invalid column model!" );
113             if ( xPSI.is() && xPSI->hasPropertyByName( FM_PROP_LINEENDFORMAT ) )
114             {
115                 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_LINEENDFORMAT ) >>= nLineEndFormat );
116 
117                 switch ( nLineEndFormat )
118                 {
119                 case awt::LineEndFormat::CARRIAGE_RETURN:            eFormat = LINEEND_CR; break;
120                 case awt::LineEndFormat::LINE_FEED:                  eFormat = LINEEND_LF; break;
121                 case awt::LineEndFormat::CARRIAGE_RETURN_LINE_FEED:  eFormat = LINEEND_CRLF; break;
122                 default:
123                     OSL_ENSURE( sal_False, "getModelLineEndSetting: what's this?" );
124                 }
125             }
126         }
127         catch( const Exception& )
128         {
129     	    OSL_ENSURE( sal_False, "getModelLineEndSetting: caught an exception!" );
130         }
131         return eFormat;
132     }
133 }
134 
135 //==================================================================
136 //= DbGridColumn
137 //==================================================================
138 //------------------------------------------------------------------------------
139 CellControllerRef DbGridColumn::s_xEmptyController;
140 
141 //------------------------------------------------------------------------------
142 void DbGridColumn::CreateControl(sal_Int32 _nFieldPos, const Reference< ::com::sun::star::beans::XPropertySet >& xField, sal_Int32 nTypeId)
143 {
144     Clear();
145 
146     m_nTypeId = (sal_Int16)nTypeId;
147     if (xField != m_xField)
148     {
149         // Grundeinstellung
150         m_xField = xField;
151         xField->getPropertyValue(FM_PROP_FORMATKEY) >>= m_nFormatKey;
152         m_nFieldPos   = (sal_Int16)_nFieldPos;
153         m_bReadOnly   = ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_ISREADONLY));
154         m_bAutoValue  = ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_AUTOINCREMENT));
155         m_nFieldType  = (sal_Int16)::comphelper::getINT32(xField->getPropertyValue(FM_PROP_FIELDTYPE));
156 
157         switch (m_nFieldType)
158         {
159             case DataType::DATE:
160             case DataType::TIME:
161             case DataType::TIMESTAMP:
162                 m_bDateTime = sal_True;
163 
164             case DataType::BIT:
165             case DataType::BOOLEAN:
166             case DataType::TINYINT:
167             case DataType::SMALLINT:
168             case DataType::INTEGER:
169             case DataType::BIGINT:
170             case DataType::FLOAT:
171             case DataType::REAL:
172             case DataType::DOUBLE:
173             case DataType::NUMERIC:
174             case DataType::DECIMAL:
175                 m_nAlign = ::com::sun::star::awt::TextAlign::RIGHT;
176                 m_bNumeric = sal_True;
177                 break;
178             default:
179                 m_nAlign = ::com::sun::star::awt::TextAlign::LEFT;
180                 break;
181         }
182     }
183 
184     DbCellControl* pCellControl = NULL;
185     if (m_rParent.IsFilterMode())
186     {
187         pCellControl = new DbFilterField(m_rParent.getServiceManager(),*this);
188     }
189     else
190     {
191 
192         switch (nTypeId)
193         {
194             case TYPE_CHECKBOX: pCellControl = new DbCheckBox(*this);   break;
195             case TYPE_COMBOBOX: pCellControl = new DbComboBox(*this); break;
196             case TYPE_CURRENCYFIELD: pCellControl = new DbCurrencyField(*this); break;
197             case TYPE_DATEFIELD: pCellControl = new DbDateField(*this); break;
198             case TYPE_LISTBOX: pCellControl = new DbListBox(*this); break;
199             case TYPE_NUMERICFIELD: pCellControl = new DbNumericField(*this); break;
200             case TYPE_PATTERNFIELD: pCellControl = new DbPatternField( *this, ::comphelper::ComponentContext( m_rParent.getServiceManager() ) ); break;
201             case TYPE_TEXTFIELD: pCellControl = new DbTextField(*this); break;
202             case TYPE_TIMEFIELD: pCellControl = new DbTimeField(*this); break;
203             case TYPE_FORMATTEDFIELD: pCellControl = new DbFormattedField(*this); break;
204             default:
205                 DBG_ERROR("DbGridColumn::CreateControl: Unknown Column");
206                 return;
207         }
208 
209     }
210     Reference< XRowSet >  xCur;
211     if (m_rParent.getDataSource())
212         xCur = Reference< XRowSet > ((Reference< XInterface >)*m_rParent.getDataSource(), UNO_QUERY);
213         // TODO : the cursor wrapper should use an XRowSet interface, too
214 
215     pCellControl->Init( m_rParent.GetDataWindow(), xCur );
216 
217     // now create the control wrapper
218     if (m_rParent.IsFilterMode())
219         m_pCell = new FmXFilterCell(this, pCellControl);
220     else
221     {
222         switch (nTypeId)
223         {
224             case TYPE_CHECKBOX: m_pCell = new FmXCheckBoxCell( this, *pCellControl );  break;
225             case TYPE_LISTBOX: m_pCell = new FmXListBoxCell( this, *pCellControl );    break;
226             case TYPE_COMBOBOX: m_pCell = new FmXComboBoxCell( this, *pCellControl );    break;
227             default:
228                 m_pCell = new FmXEditCell( this, *pCellControl );
229         }
230     }
231     m_pCell->acquire();
232     m_pCell->init();
233 
234     impl_toggleScriptManager_nothrow( true );
235 
236     // only if we use have a bound field, we use a a controller for displaying the
237     // window in the grid
238     if (m_xField.is())
239         m_xController = pCellControl->CreateController();
240 }
241 
242 //------------------------------------------------------------------------------
243 void DbGridColumn::impl_toggleScriptManager_nothrow( bool _bAttach )
244 {
245     try
246     {
247         Reference< container::XChild > xChild( m_xModel, UNO_QUERY_THROW );
248         Reference< script::XEventAttacherManager > xManager( xChild->getParent(), UNO_QUERY_THROW );
249         Reference< container::XIndexAccess > xContainer( xChild->getParent(), UNO_QUERY_THROW );
250 
251         sal_Int32 nIndexInParent( getElementPos( xContainer, m_xModel ) );
252 
253         Reference< XInterface > xCellInterface( *m_pCell, UNO_QUERY );
254         if ( _bAttach )
255             xManager->attach( nIndexInParent, xCellInterface, makeAny( xCellInterface ) );
256         else
257             xManager->detach( nIndexInParent, xCellInterface );
258     }
259     catch( const Exception& )
260     {
261     	DBG_UNHANDLED_EXCEPTION();
262     }
263 }
264 
265 //------------------------------------------------------------------------------
266 void DbGridColumn::UpdateFromField(const DbGridRow* pRow, const Reference< XNumberFormatter >& xFormatter)
267 {
268     if (m_pCell && m_pCell->ISA(FmXFilterCell))
269         PTR_CAST(FmXFilterCell, m_pCell)->Update();
270     else if (pRow && pRow->IsValid() && m_nFieldPos >= 0 && m_pCell && pRow->HasField(m_nFieldPos))
271     {
272         PTR_CAST(FmXDataCell, m_pCell)->UpdateFromField( pRow->GetField( m_nFieldPos ).getColumn(), xFormatter );
273     }
274 }
275 
276 //------------------------------------------------------------------------------
277 sal_Bool DbGridColumn::Commit()
278 {
279     sal_Bool bResult = sal_True;
280     if (!m_bInSave && m_pCell)
281     {
282         m_bInSave = sal_True;
283         bResult = m_pCell->Commit();
284 
285         // store the data into the model
286         FmXDataCell* pDataCell = PTR_CAST(FmXDataCell, m_pCell);
287         if (bResult && pDataCell)
288         {
289             Reference< ::com::sun::star::form::XBoundComponent >  xComp(m_xModel, UNO_QUERY);
290             if (xComp.is())
291                 bResult = xComp->commit();
292         }
293         m_bInSave = sal_False;
294     }
295     return bResult;
296 }
297 
298 //------------------------------------------------------------------------------
299 DbGridColumn::~DbGridColumn()
300 {
301     Clear();
302 }
303 
304 //------------------------------------------------------------------------------
305 void DbGridColumn::setModel(::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >  _xModel)
306 {
307     if ( m_pCell )
308         impl_toggleScriptManager_nothrow( false );
309 
310     m_xModel = _xModel;
311 
312     if ( m_pCell )
313         impl_toggleScriptManager_nothrow( true );
314 }
315 
316 //------------------------------------------------------------------------------
317 void DbGridColumn::Clear()
318 {
319     if ( m_pCell )
320     {
321         impl_toggleScriptManager_nothrow( false );
322 
323         m_pCell->dispose();
324         m_pCell->release();
325         m_pCell = NULL;
326     }
327 
328     m_xController = NULL;
329     m_xField = NULL;
330 
331     m_nFormatKey = 0;
332     m_nFieldPos = -1;
333     m_bReadOnly = sal_True;
334     m_bAutoValue = sal_False;
335     m_nFieldType = DataType::OTHER;
336 }
337 
338 //------------------------------------------------------------------------------
339 sal_Int16 DbGridColumn::SetAlignment(sal_Int16 _nAlign)
340 {
341     if (_nAlign == -1)
342     {   // 'Standard'
343         if (m_xField.is())
344         {
345             sal_Int32 nType = 0;
346             m_xField->getPropertyValue(FM_PROP_FIELDTYPE) >>= nType;
347 
348             switch (nType)
349             {
350                 case DataType::NUMERIC:
351                 case DataType::DECIMAL:
352                 case DataType::DOUBLE:
353                 case DataType::REAL:
354                 case DataType::BIGINT:
355                 case DataType::INTEGER:
356                 case DataType::SMALLINT:
357                 case DataType::TINYINT:
358                 case DataType::DATE:
359                 case DataType::TIME:
360                 case DataType::TIMESTAMP:
361                     _nAlign = ::com::sun::star::awt::TextAlign::RIGHT;
362                     break;
363                 case DataType::BIT:
364                 case DataType::BOOLEAN:
365                     _nAlign = ::com::sun::star::awt::TextAlign::CENTER;
366                     break;
367                 default:
368                     _nAlign = ::com::sun::star::awt::TextAlign::LEFT;
369                     break;
370             }
371         }
372         else
373             _nAlign = ::com::sun::star::awt::TextAlign::LEFT;
374     }
375 
376     m_nAlign = _nAlign;
377     if (m_pCell && m_pCell->isAlignedController())
378         m_pCell->AlignControl(m_nAlign);
379 
380     return m_nAlign;
381 }
382 
383 //------------------------------------------------------------------------------
384 sal_Int16 DbGridColumn::SetAlignmentFromModel(sal_Int16 nStandardAlign)
385 {
386     Any aAlign( m_xModel->getPropertyValue(FM_PROP_ALIGN));
387     if (aAlign.hasValue())
388     {
389         sal_Int16 nTest = sal_Int16();
390         if (aAlign >>= nTest)
391             nStandardAlign = nTest;
392     }
393     return SetAlignment(nStandardAlign);
394 }
395 
396 //------------------------------------------------------------------------------
397 void DbGridColumn::setLock(sal_Bool _bLock)
398 {
399     if (m_bLocked == _bLock)
400         return;
401     m_bLocked = _bLock;
402 
403     // is the column we represent active ?
404     if (m_bHidden)
405         return;     // no, it isn't (or at least it shouldn't be ...)
406 
407     if (m_rParent.GetCurColumnId() == m_nId)
408     {
409         m_rParent.DeactivateCell();
410         m_rParent.ActivateCell(m_rParent.GetCurRow(), m_rParent.GetCurColumnId());
411     }
412 }
413 
414 //------------------------------------------------------------------------------
415 String DbGridColumn::GetCellText(const DbGridRow* pRow, const Reference< XNumberFormatter >& xFormatter) const
416 {
417     String aText;
418     if (m_pCell && m_pCell->ISA(FmXFilterCell))
419         return aText;
420 
421     if (!pRow || !pRow->IsValid())
422         aText  = INVALIDTEXT;
423     else if (pRow->HasField(m_nFieldPos))
424     {
425         aText = GetCellText( pRow->GetField( m_nFieldPos ).getColumn(), xFormatter );
426     }
427     return aText;
428 }
429 
430 //------------------------------------------------------------------------------
431 String DbGridColumn::GetCellText(const Reference< ::com::sun::star::sdb::XColumn >& xField, const Reference< XNumberFormatter >& xFormatter) const
432 {
433     String aText;
434     if (xField.is())
435     {
436         FmXTextCell* pTextCell = PTR_CAST(FmXTextCell, m_pCell);
437         if (pTextCell)
438             aText = pTextCell->GetText(xField, xFormatter);
439         else if (m_bObject)
440             aText = OBJECTTEXT;
441     }
442     return aText;
443 }
444 
445 //------------------------------------------------------------------------------
446 Reference< ::com::sun::star::sdb::XColumn >  DbGridColumn::GetCurrentFieldValue() const
447 {
448     Reference< ::com::sun::star::sdb::XColumn >  xField;
449     const DbGridRowRef xRow = m_rParent.GetCurrentRow();
450     if (xRow.Is() && xRow->HasField(m_nFieldPos))
451     {
452         xField = xRow->GetField(m_nFieldPos).getColumn();
453     }
454     return xField;
455 }
456 
457 //------------------------------------------------------------------------------
458 void DbGridColumn::Paint(OutputDevice& rDev,
459                          const Rectangle& rRect,
460                          const DbGridRow* pRow,
461                          const Reference< XNumberFormatter >& xFormatter)
462 {
463     bool bEnabled = ( rDev.GetOutDevType() != OUTDEV_WINDOW )
464                 ||  ( static_cast< Window& >( rDev ).IsEnabled() );
465 
466     FmXDataCell* pDataCell = PTR_CAST(FmXDataCell, m_pCell);
467     if (pDataCell)
468     {
469         if (!pRow || !pRow->IsValid())
470         {
471             sal_uInt16 nStyle = TEXT_DRAW_CLIP | TEXT_DRAW_CENTER;
472             if ( !bEnabled )
473                 nStyle |= TEXT_DRAW_DISABLE;
474 
475             rDev.DrawText(rRect, INVALIDTEXT, nStyle);
476         }
477         else if (m_bAutoValue && pRow->IsNew())
478         {
479             static String aAutoText(SVX_RES(RID_STR_AUTOFIELD));
480             sal_uInt16 nStyle = TEXT_DRAW_CLIP | TEXT_DRAW_VCENTER;
481             if ( !bEnabled )
482                 nStyle |= TEXT_DRAW_DISABLE;
483 
484             switch (GetAlignment())
485             {
486                 case ::com::sun::star::awt::TextAlign::RIGHT:
487                     nStyle |= TEXT_DRAW_RIGHT;
488                     break;
489                 case ::com::sun::star::awt::TextAlign::CENTER:
490                     nStyle |= TEXT_DRAW_CENTER;
491                     break;
492                 default:
493                     nStyle |= TEXT_DRAW_LEFT;
494             }
495 
496             rDev.DrawText(rRect, aAutoText , nStyle);
497         }
498         else if (pRow->HasField(m_nFieldPos))
499         {
500             pDataCell->PaintFieldToCell(rDev, rRect, pRow->GetField( m_nFieldPos ).getColumn(), xFormatter);
501         }
502     }
503     else if (!m_pCell)
504     {
505         if (!pRow || !pRow->IsValid())
506         {
507             sal_uInt16 nStyle = TEXT_DRAW_CLIP | TEXT_DRAW_CENTER;
508             if ( !bEnabled )
509                 nStyle |= TEXT_DRAW_DISABLE;
510 
511             rDev.DrawText(rRect, INVALIDTEXT, nStyle);
512         }
513         else if (pRow->HasField(m_nFieldPos) && m_bObject)
514         {
515             sal_uInt16 nStyle = TEXT_DRAW_CLIP | TEXT_DRAW_CENTER;
516             if ( !bEnabled )
517                 nStyle |= TEXT_DRAW_DISABLE;
518             rDev.DrawText(rRect, OBJECTTEXT, nStyle);
519         }
520     }
521     else if ( m_pCell->ISA( FmXFilterCell ) )
522         static_cast< FmXFilterCell* >( m_pCell )->PaintCell( rDev, rRect );
523 }
524 
525 //------------------------------------------------------------------------------
526 void DbGridColumn::ImplInitWindow( Window& rParent, const InitWindowFacet _eInitWhat )
527 {
528     if ( m_pCell )
529         m_pCell->ImplInitWindow( rParent, _eInitWhat );
530 }
531 
532 //==============================================================================
533 //= cell controls
534 //==============================================================================
535 TYPEINIT0( DbCellControl )
536 TYPEINIT1( DbLimitedLengthField, DbCellControl )
537 TYPEINIT1( DbTextField, DbLimitedLengthField )
538 TYPEINIT1( DbFormattedField, DbLimitedLengthField )
539 TYPEINIT1( DbCheckBox, DbCellControl )
540 TYPEINIT1( DbComboBox, DbCellControl )
541 TYPEINIT1( DbListBox, DbCellControl )
542 TYPEINIT1( DbPatternField, DbCellControl )
543 TYPEINIT1( DbSpinField, DbCellControl )
544 TYPEINIT1( DbDateField, DbSpinField )
545 TYPEINIT1( DbTimeField, DbSpinField )
546 TYPEINIT1( DbCurrencyField, DbSpinField )
547 TYPEINIT1( DbNumericField, DbSpinField )
548 TYPEINIT1( DbFilterField, DbCellControl )
549 
550 //------------------------------------------------------------------------------
551 DbCellControl::DbCellControl( DbGridColumn& _rColumn, sal_Bool /*_bText*/ )
552     :OPropertyChangeListener(m_aMutex)
553     ,m_pFieldChangeBroadcaster(NULL)
554     ,m_bTransparent( sal_False )
555     ,m_bAlignedController( sal_True )
556     ,m_bAccessingValueProperty( sal_False )
557     ,m_rColumn( _rColumn )
558     ,m_pPainter( NULL )
559     ,m_pWindow( NULL )
560 {
561     Reference< XPropertySet > xColModelProps( _rColumn.getModel(), UNO_QUERY );
562     if ( xColModelProps.is() )
563     {
564         // if our model's format key changes we want to propagate the new value to our windows
565         m_pModelChangeBroadcaster = new ::comphelper::OPropertyChangeMultiplexer(this, Reference< ::com::sun::star::beans::XPropertySet > (_rColumn.getModel(), UNO_QUERY));
566         m_pModelChangeBroadcaster->acquire();
567 
568         // be listener for some common properties
569         implDoPropertyListening( FM_PROP_READONLY, sal_False );
570         implDoPropertyListening( FM_PROP_ENABLED, sal_False );
571 
572         // add as listener for all know "value" properties
573         implDoPropertyListening( FM_PROP_VALUE, sal_False );
574         implDoPropertyListening( FM_PROP_STATE, sal_False );
575         implDoPropertyListening( FM_PROP_TEXT, sal_False );
576         implDoPropertyListening( FM_PROP_EFFECTIVE_VALUE, sal_False );
577 
578         // be listener at the bound field as well
579         try
580         {
581             Reference< XPropertySetInfo > xPSI( xColModelProps->getPropertySetInfo(), UNO_SET_THROW );
582             if ( xPSI->hasPropertyByName( FM_PROP_BOUNDFIELD ) )
583             {
584                 Reference< XPropertySet > xField;
585                 xColModelProps->getPropertyValue( FM_PROP_BOUNDFIELD ) >>= xField;
586                 if ( xField.is() )
587                 {
588                     m_pFieldChangeBroadcaster = new ::comphelper::OPropertyChangeMultiplexer(this, xField);
589                     m_pFieldChangeBroadcaster->acquire();
590                     m_pFieldChangeBroadcaster->addProperty( FM_PROP_ISREADONLY );
591                 }
592             }
593         }
594         catch( const Exception& )
595         {
596             DBG_ERROR( "DbCellControl::doPropertyListening: caught an exception!" );
597         }
598     }
599 }
600 
601 //------------------------------------------------------------------------------
602 void DbCellControl::implDoPropertyListening( const ::rtl::OUString& _rPropertyName, sal_Bool _bWarnIfNotExistent )
603 {
604     try
605     {
606         Reference< XPropertySet > xColModelProps( m_rColumn.getModel(), UNO_QUERY );
607         Reference< XPropertySetInfo > xPSI;
608         if ( xColModelProps.is() )
609             xPSI = xColModelProps->getPropertySetInfo();
610 
611         DBG_ASSERT( !_bWarnIfNotExistent || ( xPSI.is() && xPSI->hasPropertyByName( _rPropertyName ) ),
612             "DbCellControl::doPropertyListening: no property set info or non-existent property!" );
613         (void)_bWarnIfNotExistent;
614 
615         if ( xPSI.is() && xPSI->hasPropertyByName( _rPropertyName ) )
616             m_pModelChangeBroadcaster->addProperty( _rPropertyName );
617     }
618     catch( const Exception& )
619     {
620         DBG_ERROR( "DbCellControl::doPropertyListening: caught an exception!" );
621     }
622 }
623 
624 //------------------------------------------------------------------------------
625 void DbCellControl::doPropertyListening( const ::rtl::OUString& _rPropertyName )
626 {
627     implDoPropertyListening( _rPropertyName );
628 }
629 //------------------------------------------------------------------------------
630 void lcl_clearBroadCaster(::comphelper::OPropertyChangeMultiplexer*& _pBroadcaster)
631 {
632     if ( _pBroadcaster )
633     {
634         _pBroadcaster->dispose();
635         _pBroadcaster->release();
636         _pBroadcaster = NULL;
637         // no delete, this is done implicitly
638     }
639 }
640 //------------------------------------------------------------------------------
641 DbCellControl::~DbCellControl()
642 {
643     lcl_clearBroadCaster(m_pModelChangeBroadcaster);
644     lcl_clearBroadCaster(m_pFieldChangeBroadcaster);
645 
646     delete m_pWindow;
647     delete m_pPainter;
648 }
649 
650 //------------------------------------------------------------------------------
651 void DbCellControl::implValuePropertyChanged( )
652 {
653     OSL_ENSURE( !isValuePropertyLocked(),
654         "DbCellControl::implValuePropertyChanged: not to be called with the value property locked!" );
655 
656     if ( m_pWindow )
657     {
658         if ( m_rColumn.getModel().is() )
659             updateFromModel( m_rColumn.getModel() );
660     }
661 }
662 
663 //------------------------------------------------------------------------------
664 void DbCellControl::implAdjustGenericFieldSetting( const Reference< XPropertySet >& /*_rxModel*/ )
665 {
666     // nothing to to here
667 }
668 
669 //------------------------------------------------------------------------------
670 void DbCellControl::_propertyChanged(const PropertyChangeEvent& _rEvent) throw(RuntimeException)
671 {
672 	::vos::OGuard aGuard( Application::GetSolarMutex() );
673 
674     Reference< XPropertySet > xSourceProps( _rEvent.Source, UNO_QUERY );
675 
676     if  (   _rEvent.PropertyName.equals( FM_PROP_VALUE )
677         ||  _rEvent.PropertyName.equals( FM_PROP_STATE )
678         ||  _rEvent.PropertyName.equals( FM_PROP_TEXT )
679         ||  _rEvent.PropertyName.equals( FM_PROP_EFFECTIVE_VALUE )
680         )
681     {   // it was one of the known "value" properties
682         if ( !isValuePropertyLocked() )
683         {
684             implValuePropertyChanged( );
685         }
686     }
687     else if ( _rEvent.PropertyName.equals( FM_PROP_READONLY ) )
688     {
689         implAdjustReadOnly( xSourceProps, true);
690     }
691     else if ( _rEvent.PropertyName.equals( FM_PROP_ISREADONLY ) )
692     {
693         sal_Bool bReadOnly = sal_True;
694         _rEvent.NewValue >>= bReadOnly;
695         m_rColumn.SetReadOnly(bReadOnly);
696         implAdjustReadOnly( xSourceProps, false);
697     }
698     else if ( _rEvent.PropertyName.equals( FM_PROP_ENABLED ) )
699     {
700         implAdjustEnabled( xSourceProps );
701     }
702     else
703         implAdjustGenericFieldSetting( xSourceProps );
704 }
705 
706 //------------------------------------------------------------------------------
707 sal_Bool DbCellControl::Commit()
708 {
709     // lock the listening for value property changes
710     lockValueProperty();
711     // commit the content of the control into the model's value property
712     sal_Bool bReturn = sal_False;
713     try
714     {
715         bReturn = commitControl();
716     }
717     catch( const Exception& )
718     {
719     	DBG_UNHANDLED_EXCEPTION();
720     }
721     // unlock the listening for value property changes
722     unlockValueProperty();
723     // outta here
724     return bReturn;
725 }
726 
727 //------------------------------------------------------------------------------
728 void DbCellControl::ImplInitWindow( Window& rParent, const InitWindowFacet _eInitWhat )
729 {
730 	Window* pWindows[] = { m_pPainter, m_pWindow };
731 
732     if ( ( _eInitWhat & InitWritingMode ) != 0 )
733     {
734 		for ( size_t i=0; i < sizeof( pWindows ) / sizeof( pWindows[0] ); ++i )
735 		{
736 			if ( pWindows[i] )
737                 pWindows[i]->EnableRTL( rParent.IsRTLEnabled() );
738         }
739     }
740 
741     if ( ( _eInitWhat & InitFont ) != 0 )
742     {
743 		for (size_t i=0; i < sizeof(pWindows)/sizeof(pWindows[0]); ++i)
744 		{
745 			if ( !pWindows[i] )
746                 continue;
747 
748             pWindows[i]->SetZoom( rParent.GetZoom() );
749 
750             const StyleSettings& rStyleSettings = pWindows[i]->GetSettings().GetStyleSettings();
751 		    Font aFont = rStyleSettings.GetFieldFont();
752             aFont.SetTransparent( isTransparent() );
753 
754             if ( rParent.IsControlFont() )
755             {
756                 pWindows[i]->SetControlFont( rParent.GetControlFont() );
757 			    aFont.Merge( rParent.GetControlFont() );
758             }
759             else
760                 pWindows[i]->SetControlFont();
761 
762 		    pWindows[i]->SetZoomedPointFont( aFont );
763 		}
764     }
765 
766     if  (   ( ( _eInitWhat & InitFont ) != 0 )
767         ||  ( ( _eInitWhat & InitForeground ) != 0 )
768         )
769     {
770         Color aTextColor( rParent.IsControlForeground() ? rParent.GetControlForeground() : rParent.GetTextColor() );
771 
772         sal_Bool bTextLineColor = rParent.IsTextLineColor();
773         Color aTextLineColor( rParent.GetTextLineColor() );
774 
775 		for (size_t i=0; i < sizeof(pWindows)/sizeof(pWindows[0]); ++i)
776 		{
777 			if ( pWindows[i] )
778 			{
779 				pWindows[i]->SetTextColor(aTextColor);
780 				if (rParent.IsControlForeground())
781 					pWindows[i]->SetControlForeground(aTextColor);
782 
783 				if (bTextLineColor)
784 					pWindows[i]->SetTextLineColor();
785 				else
786 					pWindows[i]->SetTextLineColor(aTextLineColor);
787 			}
788 		}
789     }
790 
791     if ( ( _eInitWhat & InitBackground ) != 0 )
792     {
793         if (rParent.IsControlBackground())
794         {
795             Color aColor( rParent.GetControlBackground());
796 			for (size_t i=0; i < sizeof(pWindows)/sizeof(pWindows[0]); ++i)
797 			{
798 				if ( pWindows[i] )
799 				{
800 					if ( isTransparent() )
801 						pWindows[i]->SetBackground();
802 					else
803 					{
804 						pWindows[i]->SetBackground(aColor);
805 						pWindows[i]->SetControlBackground(aColor);
806 					}
807 					pWindows[i]->SetFillColor(aColor);
808 				}
809 			}
810         }
811         else
812         {
813             if (m_pPainter)
814             {
815                 if ( isTransparent() )
816                     m_pPainter->SetBackground();
817                 else
818                     m_pPainter->SetBackground(rParent.GetBackground());
819                 m_pPainter->SetFillColor(rParent.GetFillColor());
820             }
821 
822             if (m_pWindow)
823             {
824                 if ( isTransparent() )
825                     m_pWindow->SetBackground(rParent.GetBackground());
826                 else
827                     m_pWindow->SetFillColor(rParent.GetFillColor());
828             }
829         }
830     }
831 }
832 
833 //------------------------------------------------------------------------------
834 void DbCellControl::implAdjustReadOnly( const Reference< XPropertySet >& _rxModel,bool i_bReadOnly )
835 {
836     DBG_ASSERT( m_pWindow, "DbCellControl::implAdjustReadOnly: not to be called without window!" );
837     DBG_ASSERT( _rxModel.is(), "DbCellControl::implAdjustReadOnly: invalid model!" );
838     if ( m_pWindow && _rxModel.is() )
839     {
840         Edit* pEditWindow = dynamic_cast< Edit* >( m_pWindow );
841         if ( pEditWindow )
842         {
843             sal_Bool bReadOnly = m_rColumn.IsReadOnly();
844             if ( !bReadOnly )
845             {
846                 _rxModel->getPropertyValue( i_bReadOnly ? FM_PROP_READONLY : FM_PROP_ISREADONLY) >>= bReadOnly;
847             }
848             static_cast< Edit* >( m_pWindow )->SetReadOnly( bReadOnly );
849         }
850     }
851 }
852 
853 //------------------------------------------------------------------------------
854 void DbCellControl::implAdjustEnabled( const Reference< XPropertySet >& _rxModel )
855 {
856     DBG_ASSERT( m_pWindow, "DbCellControl::implAdjustEnabled: not to be called without window!" );
857     DBG_ASSERT( _rxModel.is(), "DbCellControl::implAdjustEnabled: invalid model!" );
858     if ( m_pWindow && _rxModel.is() )
859     {
860         sal_Bool bEnable = sal_True;
861         _rxModel->getPropertyValue( FM_PROP_ENABLED ) >>= bEnable;
862         m_pWindow->Enable( bEnable );
863     }
864 }
865 
866 //------------------------------------------------------------------------------
867 void DbCellControl::Init( Window& rParent, const Reference< XRowSet >& _rxCursor )
868 {
869     ImplInitWindow( rParent, InitAll );
870 
871     if ( m_pWindow )
872     {
873         // align the control
874         if ( isAlignedController() )
875             AlignControl( m_rColumn.GetAlignment() );
876 
877         try
878         {
879             // some other common properties
880             Reference< XPropertySet > xModel( m_rColumn.getModel(), UNO_SET_THROW );
881             Reference< XPropertySetInfo > xModelPSI( xModel->getPropertySetInfo(), UNO_SET_THROW );
882 
883             if ( xModelPSI->hasPropertyByName( FM_PROP_READONLY ) )
884             {
885                 implAdjustReadOnly( xModel,true );
886             }
887 
888             if ( xModelPSI->hasPropertyByName( FM_PROP_ENABLED ) )
889             {
890                 implAdjustEnabled( xModel );
891             }
892 
893             if ( xModelPSI->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) )
894             {
895                 sal_Int16 nWheelBehavior = MouseWheelBehavior::SCROLL_FOCUS_ONLY;
896                 OSL_VERIFY( xModel->getPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) >>= nWheelBehavior );
897                 sal_uInt16 nVclSetting = MOUSE_WHEEL_FOCUS_ONLY;
898                 switch ( nWheelBehavior )
899                 {
900                 case MouseWheelBehavior::SCROLL_DISABLED:   nVclSetting = MOUSE_WHEEL_DISABLE; break;
901                 case MouseWheelBehavior::SCROLL_FOCUS_ONLY: nVclSetting = MOUSE_WHEEL_FOCUS_ONLY; break;
902                 case MouseWheelBehavior::SCROLL_ALWAYS:     nVclSetting = MOUSE_WHEEL_ALWAYS; break;
903                 default:
904                     OSL_ENSURE( false, "DbCellControl::Init: invalid MouseWheelBehavior!" );
905                     break;
906                 }
907 
908                 AllSettings aSettings = m_pWindow->GetSettings();
909                 MouseSettings aMouseSettings = aSettings.GetMouseSettings();
910                 aMouseSettings.SetWheelBehavior( nVclSetting );
911                 aSettings.SetMouseSettings( aMouseSettings );
912                 m_pWindow->SetSettings( aSettings, sal_True );
913             }
914         }
915         catch( const Exception& )
916         {
917             DBG_UNHANDLED_EXCEPTION();
918         }
919     }
920     m_xCursor = _rxCursor;
921 }
922 
923 //------------------------------------------------------------------------------
924 void DbCellControl::SetTextLineColor()
925 {
926     if (m_pWindow)
927         m_pWindow->SetTextLineColor();
928     if (m_pPainter)
929         m_pPainter->SetTextLineColor();
930 }
931 
932 //------------------------------------------------------------------------------
933 void DbCellControl::SetTextLineColor(const Color& _rColor)
934 {
935     if (m_pWindow)
936         m_pWindow->SetTextLineColor(_rColor);
937     if (m_pPainter)
938         m_pPainter->SetTextLineColor(_rColor);
939 }
940 
941 namespace
942 {
943     static void lcl_implAlign( Window* _pWindow, WinBits _nAlignmentBit )
944     {
945         WinBits nStyle = _pWindow->GetStyle();
946         nStyle &= ~(WB_LEFT | WB_RIGHT | WB_CENTER);
947         _pWindow->SetStyle( nStyle | _nAlignmentBit );
948     }
949 }
950 
951 //------------------------------------------------------------------------------
952 void DbCellControl::AlignControl(sal_Int16 nAlignment)
953 {
954     WinBits nAlignmentBit = 0;
955     switch (nAlignment)
956     {
957         case ::com::sun::star::awt::TextAlign::RIGHT:
958             nAlignmentBit = WB_RIGHT;
959             break;
960         case ::com::sun::star::awt::TextAlign::CENTER:
961             nAlignmentBit = WB_CENTER;
962             break;
963         default:
964             nAlignmentBit = WB_LEFT;
965             break;
966     }
967     lcl_implAlign( m_pWindow, nAlignmentBit );
968     if ( m_pPainter )
969         lcl_implAlign( m_pPainter, nAlignmentBit );
970 }
971 
972 //------------------------------------------------------------------------------
973 void DbCellControl::PaintCell( OutputDevice& _rDev, const Rectangle& _rRect )
974 {
975     if ( m_pPainter->GetParent() == &_rDev )
976     {
977         m_pPainter->SetPaintTransparent( sal_True );
978         m_pPainter->SetBackground( );
979         m_pPainter->SetControlBackground( _rDev.GetFillColor() );
980         m_pPainter->SetControlForeground( _rDev.GetTextColor() );
981         m_pPainter->SetTextColor( _rDev.GetTextColor() );
982         m_pPainter->SetTextFillColor( _rDev.GetTextColor() );
983 
984         Font aFont( _rDev.GetFont() );
985         aFont.SetTransparent( sal_True );
986         m_pPainter->SetFont( aFont );
987 
988         m_pPainter->SetPosSizePixel( _rRect.TopLeft(), _rRect.GetSize() );
989 	    m_pPainter->Show();
990 	    m_pPainter->Update();
991 	    m_pPainter->SetParentUpdateMode( sal_False );
992 	    m_pPainter->Hide();
993 	    m_pPainter->SetParentUpdateMode( sal_True );
994     }
995 	else
996 		m_pPainter->Draw( &_rDev, _rRect.TopLeft(), _rRect.GetSize(), 0 );
997 }
998 
999 //------------------------------------------------------------------------------
1000 void DbCellControl::PaintFieldToCell( OutputDevice& _rDev, const Rectangle& _rRect, const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1001 {
1002     m_pPainter->SetText( GetFormatText( _rxField, _rxFormatter ) );
1003     PaintCell( _rDev, _rRect );
1004 }
1005 
1006 //------------------------------------------------------------------------------
1007 double DbCellControl::GetValue(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter) const
1008 {
1009     double fValue = 0;
1010     if (m_rColumn.IsNumeric())
1011     {
1012 		try
1013         {
1014 			fValue = _rxField->getDouble();
1015 		}
1016         catch(const Exception&) { }
1017     }
1018     else
1019     {
1020         sal_Bool bSuccess = sal_False;
1021         try
1022         {
1023             fValue = _rxField->getDouble();
1024             bSuccess = sal_True;
1025         }
1026         catch(const Exception&) { }
1027         if (!bSuccess)
1028         {
1029             try
1030             {
1031                 fValue = xFormatter->convertStringToNumber(m_rColumn.GetKey(), _rxField->getString());
1032             }
1033             catch(const Exception&) { }
1034         }
1035     }
1036     return fValue;
1037 }
1038 
1039 //------------------------------------------------------------------------------
1040 void DbCellControl::invalidatedController()
1041 {
1042     m_rColumn.GetParent().refreshController(m_rColumn.GetId(), DbGridControl::GrantControlAccess());
1043 }
1044 
1045 /*************************************************************************/
1046 // CellModels
1047 /*************************************************************************/
1048 
1049 //==============================================================================
1050 //= DbLimitedLengthField
1051 //==============================================================================
1052 //------------------------------------------------------------------------------
1053 DbLimitedLengthField::DbLimitedLengthField( DbGridColumn& _rColumn )
1054     :DbCellControl( _rColumn )
1055 {
1056     doPropertyListening( FM_PROP_MAXTEXTLEN );
1057 }
1058 
1059 //------------------------------------------------------------------------------
1060 void DbLimitedLengthField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1061 {
1062     DBG_ASSERT( m_pWindow, "DbLimitedLengthField::implAdjustGenericFieldSetting: not to be called without window!" );
1063     DBG_ASSERT( _rxModel.is(), "DbLimitedLengthField::implAdjustGenericFieldSetting: invalid model!" );
1064     if ( m_pWindow && _rxModel.is() )
1065     {
1066         sal_Int16 nMaxLen = 0;
1067         _rxModel->getPropertyValue( FM_PROP_MAXTEXTLEN ) >>= nMaxLen;
1068         implSetMaxTextLen( nMaxLen );
1069     }
1070 }
1071 
1072 //------------------------------------------------------------------------------
1073 void DbLimitedLengthField::implSetEffectiveMaxTextLen( sal_Int16 _nMaxLen )
1074 {
1075     dynamic_cast< Edit* >( m_pWindow )->SetMaxTextLen( _nMaxLen );
1076     if ( m_pPainter )
1077         dynamic_cast< Edit* >( m_pPainter )->SetMaxTextLen( _nMaxLen );
1078 }
1079 
1080 //==============================================================================
1081 //= DbTextField
1082 //==============================================================================
1083 //------------------------------------------------------------------------------
1084 DbTextField::DbTextField(DbGridColumn& _rColumn)
1085             :DbLimitedLengthField(_rColumn)
1086             ,m_pEdit( NULL )
1087             ,m_pPainterImplementation( NULL )
1088             ,m_nKeyType(::com::sun::star::util::NumberFormat::TEXT)
1089             ,m_bIsSimpleEdit( sal_True )
1090 {
1091 }
1092 
1093 //------------------------------------------------------------------------------
1094 DbTextField::~DbTextField( )
1095 {
1096     DELETEZ( m_pPainterImplementation );
1097     DELETEZ( m_pEdit );
1098 }
1099 
1100 //------------------------------------------------------------------------------
1101 void DbTextField::Init( Window& rParent, const Reference< XRowSet >& xCursor)
1102 {
1103     sal_Int16 nAlignment = m_rColumn.SetAlignmentFromModel(-1);
1104 
1105     Reference< XPropertySet > xModel( m_rColumn.getModel() );
1106 
1107     WinBits nStyle = WB_LEFT;
1108     switch (nAlignment)
1109     {
1110     case awt::TextAlign::RIGHT:
1111         nStyle = WB_RIGHT;
1112         break;
1113 
1114     case awt::TextAlign::CENTER:
1115         nStyle = WB_CENTER;
1116         break;
1117     }
1118 
1119     // is this a multi-line field?
1120     sal_Bool bIsMultiLine = sal_False;
1121     try
1122     {
1123         if ( xModel.is() )
1124         {
1125             OSL_VERIFY( xModel->getPropertyValue( FM_PROP_MULTILINE ) >>= bIsMultiLine );
1126         }
1127     }
1128     catch( const Exception& )
1129     {
1130     	OSL_ENSURE( sal_False, "DbTextField::Init: caught an exception while determining the multi-line capabilities!" );
1131     }
1132 
1133     m_bIsSimpleEdit = !bIsMultiLine;
1134     if ( bIsMultiLine )
1135     {
1136         m_pWindow = new MultiLineTextCell( &rParent, nStyle );
1137         m_pEdit = new MultiLineEditImplementation( *static_cast< MultiLineTextCell* >( m_pWindow ) );
1138 
1139         m_pPainter = new MultiLineTextCell( &rParent, nStyle );
1140         m_pPainterImplementation = new MultiLineEditImplementation( *static_cast< MultiLineTextCell* >( m_pPainter ) );
1141     }
1142     else
1143     {
1144         m_pWindow = new Edit( &rParent, nStyle );
1145         m_pEdit = new EditImplementation( *static_cast< Edit* >( m_pWindow ) );
1146 
1147         m_pPainter = new Edit( &rParent, nStyle );
1148         m_pPainterImplementation = new EditImplementation( *static_cast< Edit* >( m_pPainter ) );
1149     }
1150 
1151     if ( WB_LEFT == nStyle )
1152     {
1153         // this is so that when getting the focus, the selection is oriented left-to-right
1154         AllSettings aSettings = m_pWindow->GetSettings();
1155         StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1156         aStyleSettings.SetSelectionOptions(
1157             aStyleSettings.GetSelectionOptions() | SELECTION_OPTION_SHOWFIRST);
1158         aSettings.SetStyleSettings(aStyleSettings);
1159         m_pWindow->SetSettings(aSettings);
1160     }
1161 
1162     implAdjustGenericFieldSetting( xModel );
1163 
1164     if (m_rColumn.GetParent().getNumberFormatter().is() && m_rColumn.GetKey())
1165         m_nKeyType  = comphelper::getNumberFormatType(m_rColumn.GetParent().getNumberFormatter()->getNumberFormatsSupplier()->getNumberFormats(), m_rColumn.GetKey());
1166 
1167     DbLimitedLengthField::Init( rParent, xCursor );
1168 }
1169 
1170 //------------------------------------------------------------------------------
1171 CellControllerRef DbTextField::CreateController() const
1172 {
1173     return new EditCellController( m_pEdit );
1174 }
1175 
1176 //------------------------------------------------------------------------------
1177 void DbTextField::PaintFieldToCell( OutputDevice& _rDev, const Rectangle& _rRect, const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1178 {
1179     if ( m_pPainterImplementation )
1180         m_pPainterImplementation->SetText( GetFormatText( _rxField, _rxFormatter, NULL ) );
1181 
1182 	DbLimitedLengthField::PaintFieldToCell( _rDev, _rRect, _rxField, _rxFormatter );
1183 }
1184 
1185 //------------------------------------------------------------------------------
1186 String DbTextField::GetFormatText(const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter, Color** /*ppColor*/)
1187 {
1188     ::rtl::OUString aString;
1189     if ( _rxField.is() )
1190         try
1191         {
1192             aString = getFormattedValue( _rxField, xFormatter, m_rColumn.GetParent().getNullDate(), m_rColumn.GetKey(), m_nKeyType);
1193         }
1194         catch( const Exception& )
1195         {
1196         	DBG_UNHANDLED_EXCEPTION();
1197         }
1198 
1199     return aString;
1200 }
1201 
1202 //------------------------------------------------------------------------------
1203 void DbTextField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
1204 {
1205     m_pEdit->SetText( GetFormatText( _rxField, xFormatter ) );
1206     m_pEdit->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1207 }
1208 
1209 //------------------------------------------------------------------------------
1210 void DbTextField::updateFromModel( Reference< XPropertySet > _rxModel )
1211 {
1212     OSL_ENSURE( _rxModel.is() && m_pWindow, "DbTextField::updateFromModel: invalid call!" );
1213 
1214     ::rtl::OUString sText;
1215     _rxModel->getPropertyValue( FM_PROP_TEXT ) >>= sText;
1216 
1217 	xub_StrLen nMaxTextLen = m_pEdit->GetMaxTextLen();
1218 	if ( EDIT_NOLIMIT != nMaxTextLen && sText.getLength() > nMaxTextLen )
1219 	{
1220 		sal_Int32 nDiff = sText.getLength() - nMaxTextLen;
1221 		sText = sText.replaceAt(sText.getLength() - nDiff,nDiff,::rtl::OUString());
1222 	}
1223 
1224 
1225     m_pEdit->SetText( sText );
1226     m_pEdit->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1227 }
1228 
1229 //------------------------------------------------------------------------------
1230 sal_Bool DbTextField::commitControl()
1231 {
1232     ::rtl::OUString aText( m_pEdit->GetText( getModelLineEndSetting( m_rColumn.getModel() ) ) );
1233 	// we have to check if the length before we can decide if the value was modified
1234 	xub_StrLen nMaxTextLen = m_pEdit->GetMaxTextLen();
1235 	if ( EDIT_NOLIMIT != nMaxTextLen )
1236 	{
1237 		::rtl::OUString sOldValue;
1238 		m_rColumn.getModel()->getPropertyValue( FM_PROP_TEXT ) >>= sOldValue;
1239 		// if the new value didn't change we must set the old long value again
1240 		if ( sOldValue.getLength() > nMaxTextLen && sOldValue.compareTo(aText,nMaxTextLen) == 0 )
1241 			aText = sOldValue;
1242 	}
1243     m_rColumn.getModel()->setPropertyValue( FM_PROP_TEXT, makeAny( aText ) );
1244     return sal_True;
1245 }
1246 
1247 //------------------------------------------------------------------------------
1248 void DbTextField::implSetEffectiveMaxTextLen( sal_Int16 _nMaxLen )
1249 {
1250     if ( m_pEdit )
1251         m_pEdit->SetMaxTextLen( _nMaxLen );
1252     if ( m_pPainterImplementation )
1253         m_pPainterImplementation->SetMaxTextLen( _nMaxLen );
1254 }
1255 
1256 //==============================================================================
1257 //= DbFormattedField
1258 //==============================================================================
1259 DBG_NAME(DbFormattedField);
1260 //------------------------------------------------------------------------------
1261 DbFormattedField::DbFormattedField(DbGridColumn& _rColumn)
1262     :DbLimitedLengthField(_rColumn)
1263     ,m_nKeyType(::com::sun::star::util::NumberFormat::UNDEFINED)
1264 {
1265     DBG_CTOR(DbFormattedField,NULL);
1266 
1267     // if our model's format key changes we want to propagate the new value to our windows
1268     doPropertyListening( FM_PROP_FORMATKEY );
1269 }
1270 
1271 //------------------------------------------------------------------------------
1272 DbFormattedField::~DbFormattedField()
1273 {
1274     DBG_DTOR(DbFormattedField,NULL);
1275 }
1276 
1277 //------------------------------------------------------------------------------
1278 void DbFormattedField::Init( Window& rParent, const Reference< XRowSet >& xCursor)
1279 {
1280     sal_Int16 nAlignment = m_rColumn.SetAlignmentFromModel(-1);
1281 
1282     Reference< ::com::sun::star::beans::XPropertySet >  xUnoModel = m_rColumn.getModel();
1283 
1284     switch (nAlignment)
1285     {
1286         case ::com::sun::star::awt::TextAlign::RIGHT:
1287             m_pWindow  = new FormattedField( &rParent, WB_RIGHT );
1288             m_pPainter = new FormattedField( &rParent, WB_RIGHT );
1289             break;
1290 
1291         case ::com::sun::star::awt::TextAlign::CENTER:
1292             m_pWindow  = new FormattedField( &rParent, WB_CENTER );
1293             m_pPainter  = new FormattedField( &rParent, WB_CENTER );
1294             break;
1295         default:
1296             m_pWindow  = new FormattedField( &rParent, WB_LEFT );
1297             m_pPainter  = new FormattedField( &rParent, WB_LEFT );
1298 
1299             // Alles nur damit die Selektion bei Focuserhalt von rechts nach links geht
1300             AllSettings aSettings = m_pWindow->GetSettings();
1301             StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1302             aStyleSettings.SetSelectionOptions(
1303                 aStyleSettings.GetSelectionOptions() | SELECTION_OPTION_SHOWFIRST);
1304             aSettings.SetStyleSettings(aStyleSettings);
1305             m_pWindow->SetSettings(aSettings);
1306     }
1307 
1308     implAdjustGenericFieldSetting( xUnoModel );
1309 
1310     static_cast< FormattedField* >( m_pWindow )->SetStrictFormat( sal_False );
1311     static_cast< FormattedField* >( m_pPainter )->SetStrictFormat( sal_False );
1312         // wenn man _irgendeine_ Formatierung zulaesst, kann man da sowieso keine Eingabe-Ueberpruefung
1313         // machen (das FormattedField unterstuetzt das sowieso nicht, nur abgeleitete Klassen)
1314 
1315     // von dem Uno-Model den Formatter besorgen
1316     // (Ich koennte theoretisch auch ueber den ::com::sun::star::util::NumberFormatter gehen, den mir der Cursor bestimmt
1317     // liefern wuerde. Das Problem dabei ist, dass ich mich eigentlich nicht darauf verlassen
1318     // kann, dass die beiden Formatter die selben sind, sauber ist das Ganze, wenn ich ueber das
1319     // UNO-Model gehe.)
1320     sal_Int32 nFormatKey = -1;
1321 
1322     // mal sehen, ob das Model einen hat ...
1323     DBG_ASSERT(::comphelper::hasProperty(FM_PROP_FORMATSSUPPLIER, xUnoModel), "DbFormattedField::Init : invalid UNO model !");
1324     Any aSupplier( xUnoModel->getPropertyValue(FM_PROP_FORMATSSUPPLIER));
1325     if (aSupplier.hasValue())
1326     {
1327         ::cppu::extractInterface(m_xSupplier, aSupplier);
1328         if (m_xSupplier.is())
1329         {
1330             // wenn wir den Supplier vom Model nehmen, dann auch den Key
1331             Any aFmtKey( xUnoModel->getPropertyValue(FM_PROP_FORMATKEY));
1332             if (aFmtKey.hasValue())
1333             {
1334                 DBG_ASSERT(aFmtKey.getValueType().getTypeClass() == TypeClass_LONG, "DbFormattedField::Init : invalid format key property (no sal_Int32) !");
1335                 nFormatKey = ::comphelper::getINT32(aFmtKey);
1336             }
1337             else
1338             {
1339                 DBG_WARNING("DbFormattedField::Init : my uno-model has no format-key, but a formats supplier !");
1340                 // the OFormattedModel which we usually are working with ensures that the model has a format key
1341                 // as soon as the form is loaded. Unfortunally this method here is called from within loaded, too.
1342                 // So if our LoadListener is called before the LoadListener of the model, this "else case" is
1343                 // allowed.
1344                 // Of course our property listener for the FormatKey property will notify us if the prop is changed,
1345                 // so this here isn't really bad ....
1346                 nFormatKey = 0;
1347             }
1348         }
1349     }
1350 
1351     // nein ? vielleicht die ::com::sun::star::form::component::Form hinter dem Cursor ?
1352     if (!m_xSupplier.is())
1353     {
1354         Reference< XRowSet >  xCursorForm(xCursor, UNO_QUERY);
1355         if (xCursorForm.is())
1356         {   // wenn wir vom Cursor den Formatter nehmen, dann auch den Key vom Feld, an das wir gebunden sind
1357             m_xSupplier = getNumberFormats(getRowSetConnection(xCursorForm), sal_False);
1358 
1359             if (m_rColumn.GetField().is())
1360                 nFormatKey = ::comphelper::getINT32(m_rColumn.GetField()->getPropertyValue(FM_PROP_FORMATKEY));
1361         }
1362     }
1363 
1364     SvNumberFormatter* pFormatterUsed = NULL;
1365     if (m_xSupplier.is())
1366     {
1367         SvNumberFormatsSupplierObj* pImplmentation = SvNumberFormatsSupplierObj::getImplementation(m_xSupplier);
1368         if (pImplmentation)
1369             pFormatterUsed = pImplmentation->GetNumberFormatter();
1370         else
1371             // alles hingfaellig : der Supplier ist vom falschen Typ, dann koennen wir uns auch nicht darauf verlassen, dass
1372             // ein Standard-Formatter den (eventuell nicht-Standard-)Key kennt.
1373             nFormatKey = -1;
1374     }
1375 
1376     // einen Standard-Formatter ...
1377     if (pFormatterUsed == NULL)
1378     {
1379         pFormatterUsed = ((FormattedField*)m_pWindow)->StandardFormatter();
1380         DBG_ASSERT(pFormatterUsed != NULL, "DbFormattedField::Init : no standard formatter given by the numeric field !");
1381     }
1382     // ... und einen Standard-Key
1383     if (nFormatKey == -1)
1384         nFormatKey = 0;
1385 
1386     m_nKeyType  = comphelper::getNumberFormatType(m_xSupplier->getNumberFormats(), nFormatKey);
1387 
1388     ((FormattedField*)m_pWindow)->SetFormatter(pFormatterUsed);
1389     ((FormattedField*)m_pPainter)->SetFormatter(pFormatterUsed);
1390 
1391     ((FormattedField*)m_pWindow)->SetFormatKey(nFormatKey);
1392     ((FormattedField*)m_pPainter)->SetFormatKey(nFormatKey);
1393 
1394     ((FormattedField*)m_pWindow)->TreatAsNumber(m_rColumn.IsNumeric());
1395     ((FormattedField*)m_pPainter)->TreatAsNumber(m_rColumn.IsNumeric());
1396 
1397     // Min- und Max-Werte
1398     if (m_rColumn.IsNumeric())
1399     {
1400         sal_Bool bClearMin = sal_True;
1401         if (::comphelper::hasProperty(FM_PROP_EFFECTIVE_MIN, xUnoModel))
1402         {
1403             Any aMin( xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_MIN));
1404             if (aMin.getValueType().getTypeClass() != TypeClass_VOID)
1405             {
1406                 DBG_ASSERT(aMin.getValueType().getTypeClass() == TypeClass_DOUBLE, "DbFormattedField::Init : the model has an invalid min value !");
1407                 double dMin = ::comphelper::getDouble(aMin);
1408                 ((FormattedField*)m_pWindow)->SetMinValue(dMin);
1409                 ((FormattedField*)m_pPainter)->SetMinValue(dMin);
1410                 bClearMin = sal_False;
1411             }
1412         }
1413         if (bClearMin)
1414         {
1415             ((FormattedField*)m_pWindow)->ClearMinValue();
1416             ((FormattedField*)m_pPainter)->ClearMinValue();
1417         }
1418         sal_Bool bClearMax = sal_True;
1419         if (::comphelper::hasProperty(FM_PROP_EFFECTIVE_MAX, xUnoModel))
1420         {
1421             Any aMin( xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_MAX));
1422             if (aMin.getValueType().getTypeClass() != TypeClass_VOID)
1423             {
1424                 DBG_ASSERT(aMin.getValueType().getTypeClass() == TypeClass_DOUBLE, "DbFormattedField::Init : the model has an invalid max value !");
1425                 double dMin = ::comphelper::getDouble(aMin);
1426                 ((FormattedField*)m_pWindow)->SetMaxValue(dMin);
1427                 ((FormattedField*)m_pPainter)->SetMaxValue(dMin);
1428                 bClearMax = sal_False;
1429             }
1430         }
1431         if (bClearMax)
1432         {
1433             ((FormattedField*)m_pWindow)->ClearMaxValue();
1434             ((FormattedField*)m_pPainter)->ClearMaxValue();
1435         }
1436     }
1437 
1438     // den Default-Wert
1439     Any aDefault( xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_DEFAULT));
1440     if (aDefault.hasValue())
1441     {   // das Ding kann ein double oder ein String sein
1442         switch (aDefault.getValueType().getTypeClass())
1443         {
1444             case TypeClass_DOUBLE:
1445                 if (m_rColumn.IsNumeric())
1446                 {
1447                     ((FormattedField*)m_pWindow)->SetDefaultValue(::comphelper::getDouble(aDefault));
1448                     ((FormattedField*)m_pPainter)->SetDefaultValue(::comphelper::getDouble(aDefault));
1449                 }
1450                 else
1451                 {
1452                     String sConverted;
1453                     Color* pDummy;
1454                     pFormatterUsed->GetOutputString(::comphelper::getDouble(aDefault), 0, sConverted, &pDummy);
1455                     ((FormattedField*)m_pWindow)->SetDefaultText(sConverted);
1456                     ((FormattedField*)m_pPainter)->SetDefaultText(sConverted);
1457                 }
1458                 break;
1459             case TypeClass_STRING:
1460             {
1461                 String sDefault( ::comphelper::getString(aDefault) );
1462                 if (m_rColumn.IsNumeric())
1463                 {
1464                     double dVal;
1465                     sal_uInt32 nTestFormat(0);
1466                     if (pFormatterUsed->IsNumberFormat(sDefault, nTestFormat, dVal))
1467                     {
1468                         ((FormattedField*)m_pWindow)->SetDefaultValue(dVal);
1469                         ((FormattedField*)m_pPainter)->SetDefaultValue(dVal);
1470                     }
1471                 }
1472                 else
1473                 {
1474                     ((FormattedField*)m_pWindow)->SetDefaultText(sDefault);
1475                     ((FormattedField*)m_pPainter)->SetDefaultText(sDefault);
1476                 }
1477             }
1478             default:
1479                 DBG_ERROR( "DbFormattedField::Init: unexpected value type!" );
1480                 break;
1481         }
1482     }
1483     DbLimitedLengthField::Init( rParent, xCursor );
1484 }
1485 
1486 //------------------------------------------------------------------------------
1487 CellControllerRef DbFormattedField::CreateController() const
1488 {
1489 	return new ::svt::FormattedFieldCellController( static_cast< FormattedField* >( m_pWindow ) );
1490 }
1491 
1492 //------------------------------------------------------------------------------
1493 void DbFormattedField::_propertyChanged( const PropertyChangeEvent& _rEvent ) throw( RuntimeException )
1494 {
1495     if (_rEvent.PropertyName.compareTo(FM_PROP_FORMATKEY) == COMPARE_EQUAL)
1496     {
1497         sal_Int32 nNewKey = _rEvent.NewValue.hasValue() ? ::comphelper::getINT32(_rEvent.NewValue) : 0;
1498         m_nKeyType = comphelper::getNumberFormatType(m_xSupplier->getNumberFormats(), nNewKey);
1499 
1500         DBG_ASSERT(m_pWindow && m_pPainter, "DbFormattedField::_propertyChanged : where are my windows ?");
1501         if (m_pWindow)
1502             static_cast< FormattedField* >( m_pWindow )->SetFormatKey( nNewKey );
1503         if (m_pPainter)
1504             static_cast< FormattedField* >( m_pPainter )->SetFormatKey( nNewKey );
1505     }
1506     else
1507     {
1508         DbLimitedLengthField::_propertyChanged( _rEvent );
1509     }
1510 }
1511 
1512 //------------------------------------------------------------------------------
1513 String DbFormattedField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, Color** ppColor)
1514 {
1515     // defaultmaessig keine Farb-Angabe
1516     if (ppColor != NULL)
1517         *ppColor = NULL;
1518 
1519     // NULL-Wert -> leerer Text
1520     if (!_rxField.is())
1521         return String();
1522 
1523     String aText;
1524     try
1525     {
1526         if (m_rColumn.IsNumeric())
1527         {
1528             // das IsNumeric an der Column sagt nichts aus ueber die Klasse des benutzen Formates, sondern
1529             // ueber die des an die Column gebundenen Feldes. Wenn man also eine FormattedField-Spalte an
1530             // ein double-Feld bindet und als Text formatiert, liefert m_rColumn.IsNumeric() sal_True. Das heisst
1531             // also einfach, dass ich den Inhalt der Variant mittels getDouble abfragen kann, und dann kann
1532             // ich den Rest (die Formatierung) dem FormattedField ueberlassen.
1533             double dValue = getValue( _rxField, m_rColumn.GetParent().getNullDate() );
1534             if (_rxField->wasNull())
1535                 return aText;
1536             ((FormattedField*)m_pPainter)->SetValue(dValue);
1537         }
1538         else
1539         {
1540             // Hier kann ich nicht mit einem double arbeiten, da das Feld mir keines liefern kann.
1541             // Also einfach den Text vom ::com::sun::star::util::NumberFormatter in die richtige ::com::sun::star::form::component::Form brinden lassen.
1542             aText = (const sal_Unicode*)_rxField->getString();
1543             if (_rxField->wasNull())
1544                 return aText;
1545             ((FormattedField*)m_pPainter)->SetTextFormatted(aText);
1546         }
1547     }
1548     catch( const Exception& )
1549     {
1550         DBG_UNHANDLED_EXCEPTION();
1551     }
1552 
1553     aText = m_pPainter->GetText();
1554     if (ppColor != NULL)
1555         *ppColor = ((FormattedField*)m_pPainter)->GetLastOutputColor();
1556 
1557     return aText;
1558 }
1559 
1560 //------------------------------------------------------------------------------
1561 void DbFormattedField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
1562 {
1563     try
1564     {
1565         FormattedField* pFormattedWindow = static_cast<FormattedField*>(m_pWindow);
1566         if (!_rxField.is())
1567         {   // NULL-Wert -> leerer Text
1568             m_pWindow->SetText(String());
1569         }
1570         else if (m_rColumn.IsNumeric())
1571         {
1572             // das IsNumeric an der Column sagt nichts aus ueber die Klasse des benutzen Formates, sondern
1573             // ueber die des an die Column gebundenen Feldes. Wenn man also eine FormattedField-Spalte an
1574             // ein double-Feld bindet und als Text formatiert, liefert m_rColumn.IsNumeric() sal_True. Das heisst
1575             // also einfach, dass ich den Inhalt der Variant mittels getDouble abfragen kann, und dann kann
1576             // ich den Rest (die Formatierung) dem FormattedField ueberlassen.
1577             double dValue = getValue( _rxField, m_rColumn.GetParent().getNullDate() );
1578             if (_rxField->wasNull())
1579                 m_pWindow->SetText(String());
1580             else
1581                 pFormattedWindow->SetValue(dValue);
1582         }
1583         else
1584         {
1585             // Hier kann ich nicht mit einem double arbeiten, da das Feld mir keines liefern kann.
1586             // Also einfach den Text vom ::com::sun::star::util::NumberFormatter in die richtige ::com::sun::star::form::component::Form brinden lassen.
1587             String sText( _rxField->getString());
1588 
1589             pFormattedWindow->SetTextFormatted( sText );
1590             pFormattedWindow->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1591         }
1592     }
1593     catch( const Exception& )
1594     {
1595         DBG_UNHANDLED_EXCEPTION();
1596     }
1597 }
1598 
1599 //------------------------------------------------------------------------------
1600 void DbFormattedField::updateFromModel( Reference< XPropertySet > _rxModel )
1601 {
1602     OSL_ENSURE( _rxModel.is() && m_pWindow, "DbFormattedField::updateFromModel: invalid call!" );
1603 
1604     FormattedField* pFormattedWindow = static_cast< FormattedField* >( m_pWindow );
1605 
1606     ::rtl::OUString sText;
1607     Any aValue = _rxModel->getPropertyValue( FM_PROP_EFFECTIVE_VALUE );
1608     if ( aValue >>= sText )
1609     {   // our effective value is transfered as string
1610         pFormattedWindow->SetTextFormatted( sText );
1611         pFormattedWindow->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1612     }
1613     else
1614     {
1615         double dValue = 0;
1616         aValue >>= dValue;
1617         pFormattedWindow->SetValue(dValue);
1618     }
1619 }
1620 
1621 //------------------------------------------------------------------------------
1622 sal_Bool DbFormattedField::commitControl()
1623 {
1624     Any aNewVal;
1625     FormattedField& rField = *(FormattedField*)m_pWindow;
1626     DBG_ASSERT(&rField == m_pWindow, "DbFormattedField::commitControl : can't work with a window other than my own !");
1627     if (m_rColumn.IsNumeric())
1628     {
1629         if (rField.GetText().Len() != 0)
1630             aNewVal <<= rField.GetValue();
1631         // ein LeerString wird erst mal standardmaessig als void weitergereicht
1632     }
1633     else
1634         aNewVal <<= ::rtl::OUString(rField.GetTextValue());
1635 
1636     m_rColumn.getModel()->setPropertyValue(FM_PROP_EFFECTIVE_VALUE, aNewVal);
1637     return sal_True;
1638 }
1639 
1640 //==============================================================================
1641 //= DbCheckBox
1642 //==============================================================================
1643 //------------------------------------------------------------------------------
1644 DbCheckBox::DbCheckBox( DbGridColumn& _rColumn )
1645     :DbCellControl( _rColumn, sal_True )
1646 {
1647     setAlignedController( sal_False );
1648 }
1649 
1650 namespace
1651 {
1652     void setCheckBoxStyle( Window* _pWindow, bool bMono )
1653     {
1654         AllSettings aSettings = _pWindow->GetSettings();
1655 	    StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1656 	    if( bMono )
1657 	        aStyleSettings.SetOptions( aStyleSettings.GetOptions() | STYLE_OPTION_MONO );
1658 	    else
1659 	        aStyleSettings.SetOptions( aStyleSettings.GetOptions() & (~STYLE_OPTION_MONO) );
1660         aSettings.SetStyleSettings( aStyleSettings );
1661         _pWindow->SetSettings( aSettings );
1662     }
1663 }
1664 
1665 //------------------------------------------------------------------------------
1666 void DbCheckBox::Init( Window& rParent, const Reference< XRowSet >& xCursor )
1667 {
1668     setTransparent( sal_True );
1669 
1670     m_pWindow  = new CheckBoxControl( &rParent );
1671     m_pPainter = new CheckBoxControl( &rParent );
1672 
1673     m_pWindow->SetPaintTransparent( sal_True );
1674     m_pPainter->SetPaintTransparent( sal_True );
1675 
1676     m_pPainter->SetBackground();
1677 
1678     try
1679     {
1680         Reference< XPropertySet > xModel( m_rColumn.getModel(), UNO_SET_THROW );
1681 
1682         sal_Int16 nStyle = awt::VisualEffect::LOOK3D;
1683         OSL_VERIFY( xModel->getPropertyValue( FM_PROP_VISUALEFFECT ) >>= nStyle );
1684 
1685         setCheckBoxStyle( m_pWindow, nStyle == awt::VisualEffect::FLAT );
1686         setCheckBoxStyle( m_pPainter, nStyle == awt::VisualEffect::FLAT );
1687 
1688         sal_Bool bTristate = sal_True;
1689         OSL_VERIFY( xModel->getPropertyValue( FM_PROP_TRISTATE ) >>= bTristate );
1690         static_cast< CheckBoxControl* >( m_pWindow )->GetBox().EnableTriState( bTristate );
1691         static_cast< CheckBoxControl* >( m_pPainter )->GetBox().EnableTriState( bTristate );
1692     }
1693     catch( const Exception& )
1694     {
1695         DBG_UNHANDLED_EXCEPTION();
1696     }
1697 
1698     DbCellControl::Init( rParent, xCursor );
1699 }
1700 
1701 //------------------------------------------------------------------------------
1702 CellControllerRef DbCheckBox::CreateController() const
1703 {
1704     return new CheckBoxCellController((CheckBoxControl*)m_pWindow);
1705 }
1706 //------------------------------------------------------------------------------
1707 static void lcl_setCheckBoxState(	const Reference< ::com::sun::star::sdb::XColumn >& _rxField,
1708 						CheckBoxControl* _pCheckBoxControl )
1709 {
1710 	TriState eState = STATE_DONTKNOW;
1711 	if (_rxField.is())
1712 	{
1713         try
1714         {
1715 		    sal_Bool bValue = _rxField->getBoolean();
1716 		    if (!_rxField->wasNull())
1717 			    eState = bValue ? STATE_CHECK : STATE_NOCHECK;
1718         }
1719         catch( const Exception& )
1720         {
1721             DBG_UNHANDLED_EXCEPTION();
1722         }
1723 	}
1724 	_pCheckBoxControl->GetBox().SetState(eState);
1725 }
1726 
1727 //------------------------------------------------------------------------------
1728 void DbCheckBox::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
1729 {
1730 	lcl_setCheckBoxState( _rxField, static_cast<CheckBoxControl*>(m_pWindow) );
1731 }
1732 
1733 //------------------------------------------------------------------------------
1734 void DbCheckBox::PaintFieldToCell(OutputDevice& rDev, const Rectangle& rRect,
1735                           const Reference< ::com::sun::star::sdb::XColumn >& _rxField,
1736                           const Reference< XNumberFormatter >& xFormatter)
1737 {
1738 	lcl_setCheckBoxState( _rxField, static_cast<CheckBoxControl*>(m_pPainter) );
1739 	DbCellControl::PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
1740 }
1741 
1742 //------------------------------------------------------------------------------
1743 void DbCheckBox::updateFromModel( Reference< XPropertySet > _rxModel )
1744 {
1745     OSL_ENSURE( _rxModel.is() && m_pWindow, "DbCheckBox::updateFromModel: invalid call!" );
1746 
1747     sal_Int16 nState = STATE_DONTKNOW;
1748     _rxModel->getPropertyValue( FM_PROP_STATE ) >>= nState;
1749     static_cast< CheckBoxControl* >( m_pWindow )->GetBox().SetState( static_cast< TriState >( nState ) );
1750 }
1751 
1752 //------------------------------------------------------------------------------
1753 sal_Bool DbCheckBox::commitControl()
1754 {
1755 #if OSL_DEBUG_LEVEL > 0
1756     Any aVal = makeAny( (sal_Int16)( static_cast< CheckBoxControl* >( m_pWindow )->GetBox().GetState() ) );
1757 #endif
1758     m_rColumn.getModel()->setPropertyValue( FM_PROP_STATE,
1759 					makeAny( (sal_Int16)( static_cast< CheckBoxControl* >( m_pWindow )->GetBox().GetState() ) ) );
1760     return sal_True;
1761 }
1762 
1763 //------------------------------------------------------------------------------
1764 XubString DbCheckBox::GetFormatText(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
1765 {
1766     return XubString();
1767 }
1768 
1769 //==============================================================================
1770 //= DbPatternField
1771 //------------------------------------------------------------------------------
1772 DbPatternField::DbPatternField( DbGridColumn& _rColumn, const ::comphelper::ComponentContext& _rContext )
1773     :DbCellControl( _rColumn )
1774     ,m_aContext( _rContext )
1775 {
1776     doPropertyListening( FM_PROP_LITERALMASK );
1777     doPropertyListening( FM_PROP_EDITMASK );
1778     doPropertyListening( FM_PROP_STRICTFORMAT );
1779 }
1780 
1781 //------------------------------------------------------------------------------
1782 void DbPatternField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1783 {
1784     DBG_ASSERT( m_pWindow, "DbPatternField::implAdjustGenericFieldSetting: not to be called without window!" );
1785     DBG_ASSERT( _rxModel.is(), "DbPatternField::implAdjustGenericFieldSetting: invalid model!" );
1786     if ( m_pWindow && _rxModel.is() )
1787     {
1788         ::rtl::OUString aLitMask;
1789         ::rtl::OUString aEditMask;
1790         sal_Bool bStrict = sal_False;
1791 
1792         _rxModel->getPropertyValue( FM_PROP_LITERALMASK ) >>= aLitMask;
1793         _rxModel->getPropertyValue( FM_PROP_EDITMASK ) >>= aEditMask;
1794         _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) >>= bStrict;
1795 
1796         ByteString aAsciiEditMask( aEditMask.getStr(), RTL_TEXTENCODING_ASCII_US );
1797 
1798         static_cast< PatternField* >( m_pWindow )->SetMask( aAsciiEditMask, aLitMask );
1799         static_cast< PatternField* >( m_pPainter )->SetMask( aAsciiEditMask, aLitMask );
1800         static_cast< PatternField* >( m_pWindow )->SetStrictFormat( bStrict );
1801         static_cast< PatternField* >( m_pPainter )->SetStrictFormat( bStrict );
1802     }
1803 }
1804 
1805 //------------------------------------------------------------------------------
1806 void DbPatternField::Init( Window& rParent, const Reference< XRowSet >& xCursor)
1807 {
1808     m_rColumn.SetAlignmentFromModel(-1);
1809 
1810     m_pWindow = new PatternField( &rParent, 0 );
1811     m_pPainter= new PatternField( &rParent, 0 );
1812 
1813     Reference< XPropertySet >   xModel( m_rColumn.getModel() );
1814     implAdjustGenericFieldSetting( xModel );
1815 
1816     DbCellControl::Init( rParent, xCursor );
1817 }
1818 
1819 //------------------------------------------------------------------------------
1820 CellControllerRef DbPatternField::CreateController() const
1821 {
1822     return new SpinCellController( static_cast< PatternField* >( m_pWindow ) );
1823 }
1824 
1825 //------------------------------------------------------------------------------
1826 String DbPatternField::impl_formatText( const String& _rText )
1827 {
1828     m_pPainter->SetText( _rText );
1829     static_cast< PatternField* >( m_pPainter )->ReformatAll();
1830     return m_pPainter->GetText();
1831 }
1832 
1833 //------------------------------------------------------------------------------
1834 String DbPatternField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
1835 {
1836     bool bIsForPaint = _rxField != m_rColumn.GetField();
1837     ::std::auto_ptr< ::dbtools::FormattedColumnValue >& rpFormatter = bIsForPaint ? m_pPaintFormatter : m_pValueFormatter;
1838 
1839     if ( !rpFormatter.get() )
1840     {
1841         DBToolsObjectFactory aFactory;
1842         rpFormatter = aFactory.createFormattedColumnValue(
1843             m_aContext, getCursor(), Reference< XPropertySet >( _rxField, UNO_QUERY ) );
1844         OSL_ENSURE( rpFormatter.get(), "DbPatternField::Init: no value formatter!" );
1845     }
1846     else
1847         OSL_ENSURE( rpFormatter->getColumn() == _rxField, "DbPatternField::GetFormatText: my value formatter is working for another field ...!" );
1848         // re-creating the value formatter here everytime would be quite expensive ...
1849 
1850     String sText;
1851     if ( rpFormatter.get() )
1852         sText = rpFormatter->getFormattedValue();
1853 
1854     return impl_formatText( sText );
1855 }
1856 
1857 //------------------------------------------------------------------------------
1858 void DbPatternField::UpdateFromField( const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1859 {
1860     static_cast< Edit* >( m_pWindow )->SetText( GetFormatText( _rxField, _rxFormatter ) );
1861     static_cast< Edit* >( m_pWindow )->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1862 }
1863 
1864 //------------------------------------------------------------------------------
1865 void DbPatternField::updateFromModel( Reference< XPropertySet > _rxModel )
1866 {
1867     OSL_ENSURE( _rxModel.is() && m_pWindow, "DbPatternField::updateFromModel: invalid call!" );
1868 
1869     ::rtl::OUString sText;
1870     _rxModel->getPropertyValue( FM_PROP_TEXT ) >>= sText;
1871 
1872     static_cast< Edit* >( m_pWindow )->SetText( impl_formatText( sText ) );
1873     static_cast< Edit* >( m_pWindow )->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1874 }
1875 
1876 //------------------------------------------------------------------------------
1877 sal_Bool DbPatternField::commitControl()
1878 {
1879     String aText(m_pWindow->GetText());
1880     m_rColumn.getModel()->setPropertyValue(FM_PROP_TEXT, makeAny(::rtl::OUString(aText)));
1881     return sal_True;
1882 }
1883 
1884 //==============================================================================
1885 //= DbSpinField
1886 //==============================================================================
1887 //------------------------------------------------------------------------------
1888 DbSpinField::DbSpinField( DbGridColumn& _rColumn, sal_Int16 _nStandardAlign )
1889     :DbCellControl( _rColumn )
1890     ,m_nStandardAlign( _nStandardAlign )
1891 {
1892 }
1893 
1894 //------------------------------------------------------------------------------
1895 void DbSpinField::Init( Window& _rParent, const Reference< XRowSet >& _rxCursor )
1896 {
1897     m_rColumn.SetAlignmentFromModel( m_nStandardAlign );
1898 
1899     Reference< XPropertySet > xModel( m_rColumn.getModel() );
1900 
1901     // determine the WinBits for the field
1902     WinBits nFieldStyle = 0;
1903     if ( ::comphelper::getBOOL( xModel->getPropertyValue( FM_PROP_SPIN ) ) )
1904         nFieldStyle = WB_REPEAT | WB_SPIN;
1905     // create the fields
1906     m_pWindow = createField( &_rParent, nFieldStyle, xModel );
1907     m_pPainter = createField( &_rParent, nFieldStyle, xModel );
1908 
1909     // adjust all other settings which depend on the property values
1910     implAdjustGenericFieldSetting( xModel );
1911 
1912     // call the base class
1913     DbCellControl::Init( _rParent, _rxCursor );
1914 }
1915 
1916 //------------------------------------------------------------------------------
1917 CellControllerRef DbSpinField::CreateController() const
1918 {
1919     return new SpinCellController( static_cast< SpinField* >( m_pWindow ) );
1920 }
1921 
1922 //==============================================================================
1923 //= DbNumericField
1924 //==============================================================================
1925 //------------------------------------------------------------------------------
1926 DbNumericField::DbNumericField( DbGridColumn& _rColumn )
1927     :DbSpinField( _rColumn )
1928 {
1929     doPropertyListening( FM_PROP_DECIMAL_ACCURACY );
1930     doPropertyListening( FM_PROP_VALUEMIN );
1931     doPropertyListening( FM_PROP_VALUEMAX );
1932     doPropertyListening( FM_PROP_VALUESTEP );
1933     doPropertyListening( FM_PROP_STRICTFORMAT );
1934     doPropertyListening( FM_PROP_SHOWTHOUSANDSEP );
1935 }
1936 
1937 //------------------------------------------------------------------------------
1938 void DbNumericField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1939 {
1940     DBG_ASSERT( m_pWindow, "DbNumericField::implAdjustGenericFieldSetting: not to be called without window!" );
1941     DBG_ASSERT( _rxModel.is(), "DbNumericField::implAdjustGenericFieldSetting: invalid model!" );
1942     if ( m_pWindow && _rxModel.is() )
1943     {
1944         sal_Int32   nMin        = (sal_Int32)getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMIN ) );
1945         sal_Int32   nMax        = (sal_Int32)getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMAX ) );
1946         sal_Int32   nStep       = (sal_Int32)getDouble( _rxModel->getPropertyValue( FM_PROP_VALUESTEP ) );
1947         sal_Bool    bStrict     = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
1948         sal_Int16   nScale      = getINT16( _rxModel->getPropertyValue( FM_PROP_DECIMAL_ACCURACY ) );
1949         sal_Bool    bThousand   = getBOOL( _rxModel->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP ) );
1950 
1951         static_cast< DoubleNumericField* >( m_pWindow )->SetMinValue(nMin);
1952         static_cast< DoubleNumericField* >( m_pWindow )->SetMaxValue(nMax);
1953         static_cast< DoubleNumericField* >( m_pWindow )->SetSpinSize(nStep);
1954         static_cast< DoubleNumericField* >( m_pWindow )->SetStrictFormat(bStrict);
1955 
1956         static_cast< DoubleNumericField* >( m_pPainter )->SetMinValue(nMin);
1957         static_cast< DoubleNumericField* >( m_pPainter )->SetMaxValue(nMax);
1958         static_cast< DoubleNumericField* >( m_pPainter )->SetStrictFormat(bStrict);
1959 
1960 
1961         // dem Field und dem Painter einen Formatter spendieren
1962         // zuerst testen, ob ich von dem Service hinter einer Connection bekommen kann
1963         Reference< ::com::sun::star::util::XNumberFormatsSupplier >  xSupplier;
1964         Reference< XRowSet > xForm;
1965         if ( m_rColumn.GetParent().getDataSource() )
1966             xForm = Reference< XRowSet >( ( Reference< XInterface > )*m_rColumn.GetParent().getDataSource(), UNO_QUERY );
1967         if ( xForm.is() )
1968             xSupplier = getNumberFormats( getRowSetConnection( xForm ), sal_True );
1969         SvNumberFormatter* pFormatterUsed = NULL;
1970         if ( xSupplier.is() )
1971         {
1972             SvNumberFormatsSupplierObj* pImplmentation = SvNumberFormatsSupplierObj::getImplementation( xSupplier );
1973             pFormatterUsed = pImplmentation ? pImplmentation->GetNumberFormatter() : NULL;
1974         }
1975         if ( NULL == pFormatterUsed )
1976         {   // der Cursor fuehrte nicht zum Erfolg -> Standard
1977             pFormatterUsed = static_cast< DoubleNumericField* >( m_pWindow )->StandardFormatter();
1978             DBG_ASSERT( pFormatterUsed != NULL, "DbNumericField::implAdjustGenericFieldSetting: no standard formatter given by the numeric field !" );
1979         }
1980         static_cast< DoubleNumericField* >( m_pWindow )->SetFormatter( pFormatterUsed );
1981         static_cast< DoubleNumericField* >( m_pPainter )->SetFormatter( pFormatterUsed );
1982 
1983         // und dann ein Format generieren, dass die gewuenschten Nachkommastellen usw. hat
1984         String sFormatString;
1985         LanguageType aAppLanguage = Application::GetSettings().GetUILanguage();
1986         pFormatterUsed->GenerateFormat( sFormatString, 0, aAppLanguage, bThousand, sal_False, nScale );
1987 
1988         static_cast< DoubleNumericField* >( m_pWindow )->SetFormat( sFormatString, aAppLanguage );
1989         static_cast< DoubleNumericField* >( m_pPainter )->SetFormat( sFormatString, aAppLanguage );
1990     }
1991 }
1992 
1993 //------------------------------------------------------------------------------
1994 SpinField* DbNumericField::createField( Window* _pParent, WinBits _nFieldStyle, const Reference< XPropertySet >& /*_rxModel*/  )
1995 {
1996     return new DoubleNumericField( _pParent, _nFieldStyle );
1997 }
1998 
1999 namespace
2000 {
2001     //--------------------------------------------------------------------------
2002     static String lcl_setFormattedNumeric_nothrow( DoubleNumericField& _rField, const DbCellControl& _rControl,
2003         const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
2004     {
2005         String sValue;
2006         if ( _rxField.is() )
2007         {
2008             try
2009             {
2010                 double fValue = _rControl.GetValue( _rxField, _rxFormatter );
2011                 if ( !_rxField->wasNull() )
2012                 {
2013                     _rField.SetValue( fValue );
2014                     sValue = _rField.GetText();
2015                 }
2016             }
2017             catch( const Exception& )
2018             {
2019             	DBG_UNHANDLED_EXCEPTION();
2020             }
2021         }
2022         return sValue;
2023     }
2024 }
2025 
2026 //------------------------------------------------------------------------------
2027 String DbNumericField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& _rxFormatter, Color** /*ppColor*/)
2028 {
2029     return lcl_setFormattedNumeric_nothrow( *dynamic_cast< DoubleNumericField* >( m_pPainter ), *this, _rxField, _rxFormatter );
2030 }
2031 
2032 //------------------------------------------------------------------------------
2033 void DbNumericField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& _rxFormatter)
2034 {
2035     lcl_setFormattedNumeric_nothrow( *dynamic_cast< DoubleNumericField* >( m_pWindow ), *this, _rxField, _rxFormatter );
2036 }
2037 
2038 //------------------------------------------------------------------------------
2039 void DbNumericField::updateFromModel( Reference< XPropertySet > _rxModel )
2040 {
2041     OSL_ENSURE( _rxModel.is() && m_pWindow, "DbNumericField::updateFromModel: invalid call!" );
2042 
2043     double dValue = 0;
2044     if ( _rxModel->getPropertyValue( FM_PROP_VALUE ) >>= dValue )
2045         static_cast< DoubleNumericField* >( m_pWindow )->SetValue( dValue );
2046     else
2047         m_pWindow->SetText( String() );
2048 }
2049 
2050 //------------------------------------------------------------------------------
2051 sal_Bool DbNumericField::commitControl()
2052 {
2053     String aText( m_pWindow->GetText());
2054     Any aVal;
2055 
2056     if (aText.Len() != 0)   // nicht null
2057     {
2058         double fValue = ((DoubleNumericField*)m_pWindow)->GetValue();
2059         aVal <<= (double)fValue;
2060     }
2061     m_rColumn.getModel()->setPropertyValue(FM_PROP_VALUE, aVal);
2062     return sal_True;
2063 }
2064 
2065 //==============================================================================
2066 //= DbCurrencyField
2067 //==============================================================================
2068 //------------------------------------------------------------------------------
2069 DbCurrencyField::DbCurrencyField(DbGridColumn& _rColumn)
2070     :DbSpinField( _rColumn )
2071     ,m_nScale( 0 )
2072 {
2073     doPropertyListening( FM_PROP_DECIMAL_ACCURACY );
2074     doPropertyListening( FM_PROP_VALUEMIN );
2075     doPropertyListening( FM_PROP_VALUEMAX );
2076     doPropertyListening( FM_PROP_VALUESTEP );
2077     doPropertyListening( FM_PROP_STRICTFORMAT );
2078     doPropertyListening( FM_PROP_SHOWTHOUSANDSEP );
2079     doPropertyListening( FM_PROP_CURRENCYSYMBOL );
2080 }
2081 
2082 //------------------------------------------------------------------------------
2083 void DbCurrencyField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2084 {
2085     DBG_ASSERT( m_pWindow, "DbCurrencyField::implAdjustGenericFieldSetting: not to be called without window!" );
2086     DBG_ASSERT( _rxModel.is(), "DbCurrencyField::implAdjustGenericFieldSetting: invalid model!" );
2087     if ( m_pWindow && _rxModel.is() )
2088     {
2089         m_nScale                = getINT16( _rxModel->getPropertyValue( FM_PROP_DECIMAL_ACCURACY ) );
2090         double  nMin            = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMIN ) );
2091         double  nMax            = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMAX ) );
2092         double  nStep           = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUESTEP ) );
2093         sal_Bool    bStrict     = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2094         sal_Bool    bThousand   = getBOOL( _rxModel->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP ) );
2095         ::rtl::OUString aStr( getString( _rxModel->getPropertyValue(FM_PROP_CURRENCYSYMBOL ) ) );
2096 
2097         static_cast< LongCurrencyField* >( m_pWindow )->SetUseThousandSep( bThousand );
2098         static_cast< LongCurrencyField* >( m_pWindow )->SetDecimalDigits( m_nScale );
2099         static_cast< LongCurrencyField* >( m_pWindow )->SetCurrencySymbol( aStr );
2100         static_cast< LongCurrencyField* >( m_pWindow )->SetFirst( nMin );
2101         static_cast< LongCurrencyField* >( m_pWindow )->SetLast( nMax );
2102         static_cast< LongCurrencyField* >( m_pWindow )->SetMin( nMin );
2103         static_cast< LongCurrencyField* >( m_pWindow )->SetMax( nMax );
2104         static_cast< LongCurrencyField* >( m_pWindow )->SetSpinSize( nStep );
2105         static_cast< LongCurrencyField* >( m_pWindow )->SetStrictFormat( bStrict );
2106 
2107         static_cast< LongCurrencyField* >( m_pPainter )->SetUseThousandSep( bThousand );
2108         static_cast< LongCurrencyField* >( m_pPainter )->SetDecimalDigits( m_nScale );
2109         static_cast< LongCurrencyField* >( m_pPainter )->SetCurrencySymbol( aStr );
2110         static_cast< LongCurrencyField* >( m_pPainter )->SetFirst( nMin );
2111         static_cast< LongCurrencyField* >( m_pPainter )->SetLast( nMax );
2112         static_cast< LongCurrencyField* >( m_pPainter )->SetMin( nMin );
2113         static_cast< LongCurrencyField* >( m_pPainter )->SetMax( nMax );
2114         static_cast< LongCurrencyField* >( m_pPainter )->SetStrictFormat( bStrict );
2115     }
2116 }
2117 
2118 //------------------------------------------------------------------------------
2119 SpinField* DbCurrencyField::createField( Window* _pParent, WinBits _nFieldStyle, const Reference< XPropertySet >& /*_rxModel*/  )
2120 {
2121     return new LongCurrencyField( _pParent, _nFieldStyle );
2122 }
2123 
2124 //------------------------------------------------------------------------------
2125 double DbCurrencyField::GetCurrency(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter) const
2126 {
2127     double fValue = GetValue(_rxField, xFormatter);
2128     if (m_nScale)
2129     {
2130 		// OSL_TRACE("double = %.64f ",fValue);
2131         fValue = ::rtl::math::pow10Exp(fValue, m_nScale);
2132         fValue = ::rtl::math::round(fValue, 0);
2133     }
2134     return fValue;
2135 }
2136 
2137 namespace
2138 {
2139     //--------------------------------------------------------------------------
2140     static String lcl_setFormattedCurrency_nothrow( LongCurrencyField& _rField, const DbCurrencyField& _rControl,
2141         const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
2142     {
2143         String sValue;
2144         if ( _rxField.is() )
2145         {
2146             try
2147             {
2148                 double fValue = _rControl.GetCurrency( _rxField, _rxFormatter );
2149                 if ( !_rxField->wasNull() )
2150                 {
2151                     _rField.SetValue( fValue );
2152                     BigInt aValue = _rField.GetCorrectedValue();
2153                     sValue = aValue.GetString();
2154                     sValue = _rField.GetText();
2155                 }
2156             }
2157             catch( const Exception& )
2158             {
2159             	DBG_UNHANDLED_EXCEPTION();
2160             }
2161         }
2162         return sValue;
2163     }
2164 }
2165 
2166 //------------------------------------------------------------------------------
2167 String DbCurrencyField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& _rxFormatter, Color** /*ppColor*/)
2168 {
2169     return lcl_setFormattedCurrency_nothrow( *dynamic_cast< LongCurrencyField* >( m_pPainter ), *this, _rxField, _rxFormatter );
2170 }
2171 
2172 //------------------------------------------------------------------------------
2173 void DbCurrencyField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& _rxFormatter)
2174 {
2175     lcl_setFormattedCurrency_nothrow( *dynamic_cast< LongCurrencyField* >( m_pWindow ), *this, _rxField, _rxFormatter );
2176 }
2177 
2178 //------------------------------------------------------------------------------
2179 void DbCurrencyField::updateFromModel( Reference< XPropertySet > _rxModel )
2180 {
2181     OSL_ENSURE( _rxModel.is() && m_pWindow, "DbCurrencyField::updateFromModel: invalid call!" );
2182 
2183     double dValue = 0;
2184     if ( _rxModel->getPropertyValue( FM_PROP_VALUE ) >>= dValue )
2185     {
2186         if ( m_nScale )
2187         {
2188             dValue = ::rtl::math::pow10Exp( dValue, m_nScale );
2189             dValue = ::rtl::math::round(dValue, 0);
2190         }
2191 
2192         static_cast< LongCurrencyField* >( m_pWindow )->SetValue( dValue );
2193     }
2194     else
2195         m_pWindow->SetText( String() );
2196 }
2197 
2198 //------------------------------------------------------------------------------
2199 sal_Bool DbCurrencyField::commitControl()
2200 {
2201     String aText( m_pWindow->GetText());
2202     Any aVal;
2203     if (aText.Len() != 0)   // nicht null
2204     {
2205         double fValue = ((LongCurrencyField*)m_pWindow)->GetValue();
2206         if (m_nScale)
2207         {
2208             fValue /= ::rtl::math::pow10Exp(1.0, m_nScale);
2209             //fValue = ::rtl::math::round(fValue, m_nScale);
2210         }
2211         aVal <<= (double)fValue;
2212     }
2213     m_rColumn.getModel()->setPropertyValue(FM_PROP_VALUE, aVal);
2214     return sal_True;
2215 }
2216 
2217 //==============================================================================
2218 //= DbDateField
2219 //==============================================================================
2220 //------------------------------------------------------------------------------
2221 DbDateField::DbDateField( DbGridColumn& _rColumn )
2222     :DbSpinField( _rColumn )
2223 {
2224     doPropertyListening( FM_PROP_DATEFORMAT );
2225     doPropertyListening( FM_PROP_DATEMIN );
2226     doPropertyListening( FM_PROP_DATEMAX );
2227     doPropertyListening( FM_PROP_STRICTFORMAT );
2228     doPropertyListening( FM_PROP_DATE_SHOW_CENTURY );
2229 }
2230 
2231 //------------------------------------------------------------------------------
2232 SpinField* DbDateField::createField( Window* _pParent, WinBits _nFieldStyle, const Reference< XPropertySet >& _rxModel  )
2233 {
2234     // check if there is a DropDown property set to TRUE
2235     sal_Bool bDropDown =    !hasProperty( FM_PROP_DROPDOWN, _rxModel )
2236                         ||  getBOOL( _rxModel->getPropertyValue( FM_PROP_DROPDOWN ) );
2237     if ( bDropDown )
2238         _nFieldStyle |= WB_DROPDOWN;
2239 
2240     CalendarField* pField = new CalendarField( _pParent, _nFieldStyle );
2241 
2242     pField->EnableToday();
2243     pField->EnableNone();
2244 
2245     return pField;
2246 }
2247 
2248 //------------------------------------------------------------------------------
2249 void DbDateField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2250 {
2251     DBG_ASSERT( m_pWindow, "DbDateField::implAdjustGenericFieldSetting: not to be called without window!" );
2252     DBG_ASSERT( _rxModel.is(), "DbDateField::implAdjustGenericFieldSetting: invalid model!" );
2253     if ( m_pWindow && _rxModel.is() )
2254     {
2255         sal_Int16   nFormat     = getINT16( _rxModel->getPropertyValue( FM_PROP_DATEFORMAT ) );
2256         sal_Int32   nMin        = getINT32( _rxModel->getPropertyValue( FM_PROP_DATEMIN ) );
2257         sal_Int32   nMax        = getINT32( _rxModel->getPropertyValue( FM_PROP_DATEMAX ) );
2258         sal_Bool    bStrict     = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2259 
2260         Any  aCentury = _rxModel->getPropertyValue( FM_PROP_DATE_SHOW_CENTURY );
2261         if ( aCentury.getValueType().getTypeClass() != TypeClass_VOID )
2262         {
2263             sal_Bool bShowDateCentury = getBOOL( aCentury );
2264 
2265             static_cast<DateField*>( m_pWindow )->SetShowDateCentury( bShowDateCentury );
2266             static_cast<DateField*>( m_pPainter )->SetShowDateCentury( bShowDateCentury );
2267         }
2268 
2269         static_cast< DateField* >( m_pWindow )->SetExtDateFormat( (ExtDateFieldFormat)nFormat );
2270         static_cast< DateField* >( m_pWindow )->SetMin( nMin );
2271         static_cast< DateField* >( m_pWindow )->SetMax( nMax );
2272         static_cast< DateField* >( m_pWindow )->SetStrictFormat( bStrict );
2273         static_cast< DateField* >( m_pWindow )->EnableEmptyFieldValue( sal_True );
2274 
2275         static_cast< DateField* >( m_pPainter )->SetExtDateFormat( (ExtDateFieldFormat)nFormat );
2276         static_cast< DateField* >( m_pPainter )->SetMin( nMin );
2277         static_cast< DateField* >( m_pPainter )->SetMax( nMax );
2278         static_cast< DateField* >( m_pPainter )->SetStrictFormat( bStrict );
2279         static_cast< DateField* >( m_pPainter )->EnableEmptyFieldValue( sal_True );
2280     }
2281 }
2282 
2283 namespace
2284 {
2285     //--------------------------------------------------------------------------
2286     static String lcl_setFormattedDate_nothrow( DateField& _rField, const Reference< XColumn >& _rxField )
2287     {
2288         String sDate;
2289         if ( _rxField.is() )
2290         {
2291             try
2292             {
2293                 ::com::sun::star::util::Date aValue = _rxField->getDate();
2294                 if ( _rxField->wasNull() )
2295                     _rField.SetText( sDate );
2296                 else
2297                 {
2298                     _rField.SetDate( ::Date( aValue.Day, aValue.Month, aValue.Year ) );
2299                     sDate = _rField.GetText();
2300                 }
2301             }
2302             catch( const Exception& )
2303             {
2304         	    DBG_UNHANDLED_EXCEPTION();
2305             }
2306         }
2307         return sDate;
2308     }
2309 }
2310 //------------------------------------------------------------------------------
2311 String DbDateField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
2312 {
2313      return lcl_setFormattedDate_nothrow( *dynamic_cast< DateField* >( m_pPainter ), _rxField );
2314 }
2315 
2316 //------------------------------------------------------------------------------
2317 void DbDateField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
2318 {
2319     lcl_setFormattedDate_nothrow( *dynamic_cast< DateField* >( m_pWindow ), _rxField );
2320 }
2321 
2322 //------------------------------------------------------------------------------
2323 void DbDateField::updateFromModel( Reference< XPropertySet > _rxModel )
2324 {
2325     OSL_ENSURE( _rxModel.is() && m_pWindow, "DbDateField::updateFromModel: invalid call!" );
2326 
2327     sal_Int32 nDate = 0;
2328     if ( _rxModel->getPropertyValue( FM_PROP_DATE ) >>= nDate )
2329         static_cast< DateField* >( m_pWindow )->SetDate( ::Date( nDate ) );
2330     else
2331         static_cast< DateField* >( m_pWindow )->SetText( String() );
2332 }
2333 
2334 //------------------------------------------------------------------------------
2335 sal_Bool DbDateField::commitControl()
2336 {
2337     String aText( m_pWindow->GetText());
2338     Any aVal;
2339     if (aText.Len() != 0)
2340         aVal <<= (sal_Int32)static_cast<DateField*>(m_pWindow)->GetDate().GetDate();
2341     else
2342         aVal.clear();
2343 
2344     m_rColumn.getModel()->setPropertyValue(FM_PROP_DATE, aVal);
2345     return sal_True;
2346 }
2347 
2348 //==============================================================================
2349 //= DbTimeField
2350 //==============================================================================
2351 //------------------------------------------------------------------------------
2352 DbTimeField::DbTimeField( DbGridColumn& _rColumn )
2353     :DbSpinField( _rColumn, ::com::sun::star::awt::TextAlign::LEFT )
2354 {
2355     doPropertyListening( FM_PROP_TIMEFORMAT );
2356     doPropertyListening( FM_PROP_TIMEMIN );
2357     doPropertyListening( FM_PROP_TIMEMAX );
2358     doPropertyListening( FM_PROP_STRICTFORMAT );
2359 }
2360 
2361 //------------------------------------------------------------------------------
2362 SpinField* DbTimeField::createField( Window* _pParent, WinBits _nFieldStyle, const Reference< XPropertySet >& /*_rxModel*/ )
2363 {
2364     return new TimeField( _pParent, _nFieldStyle );
2365 }
2366 
2367 //------------------------------------------------------------------------------
2368 void DbTimeField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2369 {
2370     DBG_ASSERT( m_pWindow, "DbTimeField::implAdjustGenericFieldSetting: not to be called without window!" );
2371     DBG_ASSERT( _rxModel.is(), "DbTimeField::implAdjustGenericFieldSetting: invalid model!" );
2372     if ( m_pWindow && _rxModel.is() )
2373     {
2374         sal_Int16   nFormat     = getINT16( _rxModel->getPropertyValue( FM_PROP_TIMEFORMAT ) );
2375         sal_Int32   nMin        = getINT32( _rxModel->getPropertyValue( FM_PROP_TIMEMIN ) );
2376         sal_Int32   nMax        = getINT32( _rxModel->getPropertyValue( FM_PROP_TIMEMAX ) );
2377         sal_Bool    bStrict     = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2378 
2379         static_cast< TimeField* >( m_pWindow )->SetExtFormat( (ExtTimeFieldFormat)nFormat );
2380         static_cast< TimeField* >( m_pWindow )->SetMin( nMin );
2381         static_cast< TimeField* >( m_pWindow )->SetMax( nMax );
2382         static_cast< TimeField* >( m_pWindow )->SetStrictFormat( bStrict );
2383         static_cast< TimeField* >( m_pWindow )->EnableEmptyFieldValue( sal_True );
2384 
2385         static_cast< TimeField* >( m_pPainter )->SetExtFormat( (ExtTimeFieldFormat)nFormat );
2386         static_cast< TimeField* >( m_pPainter )->SetMin( nMin );
2387         static_cast< TimeField* >( m_pPainter )->SetMax( nMax );
2388         static_cast< TimeField* >( m_pPainter )->SetStrictFormat( bStrict );
2389         static_cast< TimeField* >( m_pPainter )->EnableEmptyFieldValue( sal_True );
2390     }
2391 }
2392 
2393 namespace
2394 {
2395     //--------------------------------------------------------------------------
2396     static String lcl_setFormattedTime_nothrow( TimeField& _rField, const Reference< XColumn >& _rxField )
2397     {
2398         String sTime;
2399         if ( _rxField.is() )
2400         {
2401             try
2402             {
2403                 ::com::sun::star::util::Time aValue = _rxField->getTime();
2404                 if ( _rxField->wasNull() )
2405                     _rField.SetText( sTime );
2406                 else
2407                 {
2408                     _rField.SetTime( ::Time( aValue.Hours, aValue.Minutes, aValue.Seconds, aValue.HundredthSeconds ) );
2409                     sTime = _rField.GetText();
2410                 }
2411             }
2412             catch( const Exception& )
2413             {
2414         	    DBG_UNHANDLED_EXCEPTION();
2415             }
2416         }
2417         return sTime;
2418     }
2419 }
2420 //------------------------------------------------------------------------------
2421 String DbTimeField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
2422 {
2423     return lcl_setFormattedTime_nothrow( *static_cast< TimeField* >( m_pPainter ), _rxField );
2424 }
2425 
2426 //------------------------------------------------------------------------------
2427 void DbTimeField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
2428 {
2429     lcl_setFormattedTime_nothrow( *static_cast< TimeField* >( m_pWindow ), _rxField );
2430 }
2431 
2432 //------------------------------------------------------------------------------
2433 void DbTimeField::updateFromModel( Reference< XPropertySet > _rxModel )
2434 {
2435     OSL_ENSURE( _rxModel.is() && m_pWindow, "DbTimeField::updateFromModel: invalid call!" );
2436 
2437     sal_Int32 nTime = 0;
2438     if ( _rxModel->getPropertyValue( FM_PROP_DATE ) >>= nTime )
2439         static_cast< TimeField* >( m_pWindow )->SetTime( ::Time( nTime ) );
2440     else
2441         static_cast< TimeField* >( m_pWindow )->SetText( String() );
2442 }
2443 
2444 //------------------------------------------------------------------------------
2445 sal_Bool DbTimeField::commitControl()
2446 {
2447     String aText( m_pWindow->GetText());
2448     Any aVal;
2449     if (aText.Len() != 0)
2450         aVal <<= (sal_Int32)static_cast<TimeField*>(m_pWindow)->GetTime().GetTime();
2451     else
2452         aVal.clear();
2453 
2454     m_rColumn.getModel()->setPropertyValue(FM_PROP_TIME, aVal);
2455     return sal_True;
2456 }
2457 
2458 //==============================================================================
2459 //= DbComboBox
2460 //==============================================================================
2461 //------------------------------------------------------------------------------
2462 DbComboBox::DbComboBox(DbGridColumn& _rColumn)
2463            :DbCellControl(_rColumn)
2464            ,m_nKeyType(::com::sun::star::util::NumberFormat::UNDEFINED)
2465 {
2466     setAlignedController( sal_False );
2467 
2468     doPropertyListening( FM_PROP_STRINGITEMLIST );
2469     doPropertyListening( FM_PROP_LINECOUNT );
2470 }
2471 
2472 //------------------------------------------------------------------------------
2473 void DbComboBox::_propertyChanged( const PropertyChangeEvent& _rEvent ) throw( RuntimeException )
2474 {
2475     if ( _rEvent.PropertyName.equals( FM_PROP_STRINGITEMLIST ) )
2476     {
2477         SetList(_rEvent.NewValue);
2478     }
2479     else
2480     {
2481         DbCellControl::_propertyChanged( _rEvent ) ;
2482     }
2483 }
2484 
2485 //------------------------------------------------------------------------------
2486 void DbComboBox::SetList(const Any& rItems)
2487 {
2488     ComboBoxControl* pField = (ComboBoxControl*)m_pWindow;
2489     pField->Clear();
2490 
2491     ::comphelper::StringSequence aTest;
2492     if (rItems >>= aTest)
2493     {
2494         const ::rtl::OUString* pStrings = aTest.getConstArray();
2495         sal_Int32 nItems = aTest.getLength();
2496         for (sal_Int32 i = 0; i < nItems; ++i, ++pStrings )
2497              pField->InsertEntry(*pStrings, LISTBOX_APPEND);
2498 
2499         // tell the grid control that this controller is invalid and has to be re-initialized
2500         invalidatedController();
2501     }
2502 }
2503 
2504 //------------------------------------------------------------------------------
2505 void DbComboBox::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2506 {
2507     DBG_ASSERT( m_pWindow, "DbComboBox::implAdjustGenericFieldSetting: not to be called without window!" );
2508     DBG_ASSERT( _rxModel.is(), "DbComboBox::implAdjustGenericFieldSetting: invalid model!" );
2509     if ( m_pWindow && _rxModel.is() )
2510     {
2511         sal_Int16  nLines = getINT16( _rxModel->getPropertyValue( FM_PROP_LINECOUNT ) );
2512         static_cast< ComboBoxControl* >( m_pWindow )->SetDropDownLineCount( nLines );
2513     }
2514 }
2515 
2516 //------------------------------------------------------------------------------
2517 void DbComboBox::Init( Window& rParent, const Reference< XRowSet >& xCursor )
2518 {
2519     m_rColumn.SetAlignmentFromModel(::com::sun::star::awt::TextAlign::LEFT);
2520 
2521     m_pWindow = new ComboBoxControl( &rParent );
2522 
2523     // selection von rechts nach links
2524     AllSettings     aSettings = m_pWindow->GetSettings();
2525     StyleSettings   aStyleSettings = aSettings.GetStyleSettings();
2526     aStyleSettings.SetSelectionOptions(
2527         aStyleSettings.GetSelectionOptions() | SELECTION_OPTION_SHOWFIRST);
2528     aSettings.SetStyleSettings(aStyleSettings);
2529     m_pWindow->SetSettings(aSettings, sal_True);
2530 
2531     // some initial properties
2532     Reference< XPropertySet >   xModel(m_rColumn.getModel());
2533     SetList( xModel->getPropertyValue( FM_PROP_STRINGITEMLIST ) );
2534     implAdjustGenericFieldSetting( xModel );
2535 
2536     if (m_rColumn.GetParent().getNumberFormatter().is())
2537         m_nKeyType  = comphelper::getNumberFormatType(m_rColumn.GetParent().getNumberFormatter()->getNumberFormatsSupplier()->getNumberFormats(), m_rColumn.GetKey());
2538 
2539     DbCellControl::Init( rParent, xCursor );
2540 }
2541 
2542 //------------------------------------------------------------------------------
2543 CellControllerRef DbComboBox::CreateController() const
2544 {
2545     return new ComboBoxCellController((ComboBoxControl*)m_pWindow);
2546 }
2547 
2548 //------------------------------------------------------------------------------
2549 String DbComboBox::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter, Color** /*ppColor*/)
2550 {
2551     ::rtl::OUString aString;
2552     if (_rxField.is())
2553         try
2554         {
2555             aString = getFormattedValue( _rxField, xFormatter, m_rColumn.GetParent().getNullDate(), m_rColumn.GetKey(), m_nKeyType );
2556         }
2557         catch( const Exception& )
2558         {
2559         	DBG_UNHANDLED_EXCEPTION();
2560         }
2561     return aString;
2562 }
2563 
2564 //------------------------------------------------------------------------------
2565 void DbComboBox::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
2566 {
2567     m_pWindow->SetText(GetFormatText(_rxField, xFormatter));
2568 }
2569 
2570 //------------------------------------------------------------------------------
2571 void DbComboBox::updateFromModel( Reference< XPropertySet > _rxModel )
2572 {
2573     OSL_ENSURE( _rxModel.is() && m_pWindow, "DbComboBox::updateFromModel: invalid call!" );
2574 
2575     ::rtl::OUString sText;
2576     _rxModel->getPropertyValue( FM_PROP_TEXT ) >>= sText;
2577 
2578     static_cast< ComboBox* >( m_pWindow )->SetText( sText );
2579     static_cast< ComboBox* >( m_pWindow )->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
2580 }
2581 
2582 //------------------------------------------------------------------------------
2583 sal_Bool DbComboBox::commitControl()
2584 {
2585     String aText( m_pWindow->GetText());
2586     m_rColumn.getModel()->setPropertyValue(FM_PROP_TEXT, makeAny(::rtl::OUString(aText)));
2587     return sal_True;
2588 }
2589 
2590 //------------------------------------------------------------------------------
2591 DbListBox::DbListBox(DbGridColumn& _rColumn)
2592           :DbCellControl(_rColumn)
2593           ,m_bBound(sal_False)
2594 {
2595     setAlignedController( sal_False );
2596 
2597     doPropertyListening( FM_PROP_STRINGITEMLIST );
2598     doPropertyListening( FM_PROP_LINECOUNT );
2599 }
2600 
2601 //------------------------------------------------------------------------------
2602 void DbListBox::_propertyChanged( const ::com::sun::star::beans::PropertyChangeEvent& _rEvent ) throw( RuntimeException )
2603 {
2604     if ( _rEvent.PropertyName.equals( FM_PROP_STRINGITEMLIST ) )
2605     {
2606         SetList(_rEvent.NewValue);
2607     }
2608     else
2609     {
2610         DbCellControl::_propertyChanged( _rEvent ) ;
2611     }
2612 }
2613 
2614 //------------------------------------------------------------------------------
2615 void DbListBox::SetList(const Any& rItems)
2616 {
2617     ListBoxControl* pField = (ListBoxControl*)m_pWindow;
2618 
2619     pField->Clear();
2620     m_bBound = sal_False;
2621 
2622     ::comphelper::StringSequence aTest;
2623     if (rItems >>= aTest)
2624     {
2625         const ::rtl::OUString* pStrings = aTest.getConstArray();
2626         sal_Int32 nItems = aTest.getLength();
2627         if (nItems)
2628         {
2629             for (sal_Int32 i = 0; i < nItems; ++i, ++pStrings )
2630                  pField->InsertEntry(*pStrings, LISTBOX_APPEND);
2631 
2632             m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ) >>= m_aValueList;
2633             m_bBound = m_aValueList.getLength() > 0;
2634 
2635             // tell the grid control that this controller is invalid and has to be re-initialized
2636             invalidatedController();
2637         }
2638     }
2639 }
2640 
2641 //------------------------------------------------------------------------------
2642 void DbListBox::Init( Window& rParent, const Reference< XRowSet >& xCursor)
2643 {
2644     m_rColumn.SetAlignment(::com::sun::star::awt::TextAlign::LEFT);
2645 
2646     m_pWindow = new ListBoxControl( &rParent );
2647 
2648     // some initial properties
2649     Reference< XPropertySet > xModel( m_rColumn.getModel() );
2650     SetList( xModel->getPropertyValue( FM_PROP_STRINGITEMLIST ) );
2651     implAdjustGenericFieldSetting( xModel );
2652 
2653     DbCellControl::Init( rParent, xCursor );
2654 }
2655 
2656 //------------------------------------------------------------------------------
2657 void DbListBox::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2658 {
2659     DBG_ASSERT( m_pWindow, "DbListBox::implAdjustGenericFieldSetting: not to be called without window!" );
2660     DBG_ASSERT( _rxModel.is(), "DbListBox::implAdjustGenericFieldSetting: invalid model!" );
2661     if ( m_pWindow && _rxModel.is() )
2662     {
2663         sal_Int16  nLines   = getINT16( _rxModel->getPropertyValue( FM_PROP_LINECOUNT ) );
2664         static_cast< ListBoxControl* >( m_pWindow )->SetDropDownLineCount( nLines );
2665     }
2666 }
2667 
2668 //------------------------------------------------------------------------------
2669 CellControllerRef DbListBox::CreateController() const
2670 {
2671     return new ListBoxCellController((ListBoxControl*)m_pWindow);
2672 }
2673 
2674 //------------------------------------------------------------------------------
2675 String DbListBox::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
2676 {
2677     String sText;
2678     if ( _rxField.is() )
2679     {
2680         try
2681         {
2682             sText = _rxField->getString();
2683             if ( m_bBound )
2684             {
2685                 Sequence< sal_Int16 > aPosSeq = ::comphelper::findValue( m_aValueList, sText, sal_True );
2686                 if ( aPosSeq.getLength() )
2687                     sText = static_cast<ListBox*>(m_pWindow)->GetEntry(aPosSeq.getConstArray()[0]);
2688                 else
2689                     sText = String();
2690             }
2691         }
2692         catch( const Exception& )
2693         {
2694         	DBG_UNHANDLED_EXCEPTION();
2695         }
2696     }
2697     return sText;
2698 }
2699 
2700 //------------------------------------------------------------------------------
2701 void DbListBox::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
2702 {
2703     String sFormattedText( GetFormatText( _rxField, xFormatter ) );
2704     if ( sFormattedText.Len() )
2705         static_cast< ListBox* >( m_pWindow )->SelectEntry( sFormattedText );
2706     else
2707         static_cast< ListBox* >( m_pWindow )->SetNoSelection();
2708 }
2709 
2710 //------------------------------------------------------------------------------
2711 void DbListBox::updateFromModel( Reference< XPropertySet > _rxModel )
2712 {
2713     OSL_ENSURE( _rxModel.is() && m_pWindow, "DbListBox::updateFromModel: invalid call!" );
2714 
2715     Sequence< sal_Int16 > aSelection;
2716     _rxModel->getPropertyValue( FM_PROP_SELECT_SEQ );
2717 
2718     sal_Int16 nSelection = -1;
2719     if ( aSelection.getLength() > 0 )
2720         nSelection = aSelection[ 0 ];
2721 
2722     ListBox* pListBox = static_cast< ListBox* >( m_pWindow );
2723 
2724     if ( ( nSelection >= 0 ) && ( nSelection < pListBox->GetEntryCount() ) )
2725         pListBox->SelectEntryPos( nSelection );
2726     else
2727         pListBox->SetNoSelection( );
2728 }
2729 
2730 //------------------------------------------------------------------------------
2731 sal_Bool DbListBox::commitControl()
2732 {
2733     Any aVal;
2734     Sequence<sal_Int16> aSelectSeq;
2735     if (static_cast<ListBox*>(m_pWindow)->GetSelectEntryCount())
2736     {
2737         aSelectSeq.realloc(1);
2738         *(sal_Int16 *)aSelectSeq.getArray() = (sal_Int16)static_cast<ListBox*>(m_pWindow)->GetSelectEntryPos();
2739     }
2740     aVal <<= aSelectSeq;
2741     m_rColumn.getModel()->setPropertyValue(FM_PROP_SELECT_SEQ, aVal);
2742     return sal_True;
2743 }
2744 
2745 
2746 DBG_NAME(DbFilterField);
2747 /*************************************************************************/
2748 DbFilterField::DbFilterField(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,DbGridColumn& _rColumn)
2749               :DbCellControl(_rColumn)
2750               ,OSQLParserClient(_rxORB)
2751               ,m_nControlClass(::com::sun::star::form::FormComponentType::TEXTFIELD)
2752               ,m_bFilterList(sal_False)
2753               ,m_bFilterListFilled(sal_False)
2754               ,m_bBound(sal_False)
2755 {
2756     DBG_CTOR(DbFilterField,NULL);
2757 
2758     setAlignedController( sal_False );
2759 }
2760 
2761 //------------------------------------------------------------------------------
2762 DbFilterField::~DbFilterField()
2763 {
2764     if (m_nControlClass == ::com::sun::star::form::FormComponentType::CHECKBOX)
2765         ((CheckBoxControl*)m_pWindow)->SetClickHdl( Link() );
2766 
2767     DBG_DTOR(DbFilterField,NULL);
2768 }
2769 
2770 //------------------------------------------------------------------------------
2771 void DbFilterField::PaintCell(OutputDevice& rDev, const Rectangle& rRect)
2772 {
2773     static sal_uInt16 nStyle = TEXT_DRAW_CLIP | TEXT_DRAW_VCENTER | TEXT_DRAW_LEFT;
2774     switch (m_nControlClass)
2775     {
2776         case FormComponentType::CHECKBOX:
2777             DbCellControl::PaintCell( rDev, rRect );
2778             break;
2779         case FormComponentType::LISTBOX:
2780             rDev.DrawText(rRect, static_cast<ListBox*>(m_pWindow)->GetSelectEntry(), nStyle);
2781             break;
2782         default:
2783             rDev.DrawText(rRect, m_aText, nStyle);
2784     }
2785 }
2786 
2787 //------------------------------------------------------------------------------
2788 void DbFilterField::SetList(const Any& rItems, sal_Bool bComboBox)
2789 {
2790     ::comphelper::StringSequence aTest;
2791     rItems >>= aTest;
2792     const ::rtl::OUString* pStrings = aTest.getConstArray();
2793     sal_Int32 nItems = aTest.getLength();
2794     if (nItems)
2795     {
2796         if (bComboBox)
2797         {
2798             ComboBox* pField = (ComboBox*)m_pWindow;
2799             for (sal_Int32 i = 0; i < nItems; ++i, ++pStrings )
2800                 pField->InsertEntry(*pStrings, LISTBOX_APPEND);
2801         }
2802         else
2803         {
2804             ListBox* pField = (ListBox*)m_pWindow;
2805             for (sal_Int32 i = 0; i < nItems; ++i, ++pStrings )
2806                 pField->InsertEntry(*pStrings, LISTBOX_APPEND);
2807 
2808             m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ) >>= m_aValueList;
2809             m_bBound = m_aValueList.getLength() > 0;
2810         }
2811     }
2812 }
2813 
2814 //------------------------------------------------------------------------------
2815 void DbFilterField::CreateControl(Window* pParent, const Reference< ::com::sun::star::beans::XPropertySet >& xModel)
2816 {
2817     switch (m_nControlClass)
2818     {
2819         case ::com::sun::star::form::FormComponentType::CHECKBOX:
2820             m_pWindow = new CheckBoxControl(pParent);
2821             m_pWindow->SetPaintTransparent( sal_True );
2822             ((CheckBoxControl*)m_pWindow)->SetClickHdl( LINK( this, DbFilterField, OnClick ) );
2823 
2824             m_pPainter = new CheckBoxControl(pParent);
2825             m_pPainter->SetPaintTransparent( sal_True );
2826             m_pPainter->SetBackground();
2827             break;
2828         case ::com::sun::star::form::FormComponentType::LISTBOX:
2829         {
2830             m_pWindow = new ListBoxControl(pParent);
2831             sal_Int16  nLines       = ::comphelper::getINT16(xModel->getPropertyValue(FM_PROP_LINECOUNT));
2832             Any  aItems      = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST);
2833             SetList(aItems, m_nControlClass == ::com::sun::star::form::FormComponentType::COMBOBOX);
2834             static_cast<ListBox*>(m_pWindow)->SetDropDownLineCount(nLines);
2835         }   break;
2836         case ::com::sun::star::form::FormComponentType::COMBOBOX:
2837         {
2838             m_pWindow = new ComboBoxControl(pParent);
2839 
2840             AllSettings     aSettings = m_pWindow->GetSettings();
2841             StyleSettings   aStyleSettings = aSettings.GetStyleSettings();
2842             aStyleSettings.SetSelectionOptions(
2843                            aStyleSettings.GetSelectionOptions() | SELECTION_OPTION_SHOWFIRST);
2844             aSettings.SetStyleSettings(aStyleSettings);
2845             m_pWindow->SetSettings(aSettings, sal_True);
2846 
2847             if (!m_bFilterList)
2848             {
2849                 sal_Int16  nLines       = ::comphelper::getINT16(xModel->getPropertyValue(FM_PROP_LINECOUNT));
2850                 Any  aItems      = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST);
2851                 SetList(aItems, m_nControlClass == ::com::sun::star::form::FormComponentType::COMBOBOX);
2852                 ((ComboBox*)m_pWindow)->SetDropDownLineCount(nLines);
2853             }
2854             else
2855                 ((ComboBox*)m_pWindow)->SetDropDownLineCount(5);
2856 
2857         }   break;
2858         default:
2859         {
2860             m_pWindow  = new Edit(pParent, WB_LEFT);
2861             AllSettings     aSettings = m_pWindow->GetSettings();
2862             StyleSettings   aStyleSettings = aSettings.GetStyleSettings();
2863             aStyleSettings.SetSelectionOptions(
2864                            aStyleSettings.GetSelectionOptions() | SELECTION_OPTION_SHOWFIRST);
2865             aSettings.SetStyleSettings(aStyleSettings);
2866             m_pWindow->SetSettings(aSettings, sal_True);
2867         }
2868     }
2869 }
2870 
2871 //------------------------------------------------------------------------------
2872 void DbFilterField::Init( Window& rParent, const Reference< XRowSet >& xCursor )
2873 {
2874     Reference< ::com::sun::star::beans::XPropertySet >  xModel(m_rColumn.getModel());
2875     m_rColumn.SetAlignment(::com::sun::star::awt::TextAlign::LEFT);
2876 
2877     if (xModel.is())
2878     {
2879         m_bFilterList = ::comphelper::hasProperty(FM_PROP_FILTERPROPOSAL, xModel) && ::comphelper::getBOOL(xModel->getPropertyValue(FM_PROP_FILTERPROPOSAL));
2880         if (m_bFilterList)
2881             m_nControlClass = ::com::sun::star::form::FormComponentType::COMBOBOX;
2882         else
2883         {
2884             sal_Int16 nClassId = ::comphelper::getINT16(xModel->getPropertyValue(FM_PROP_CLASSID));
2885             switch (nClassId)
2886             {
2887                 case FormComponentType::CHECKBOX:
2888                 case FormComponentType::LISTBOX:
2889                 case FormComponentType::COMBOBOX:
2890                     m_nControlClass = nClassId;
2891                     break;
2892                 default:
2893                     if (m_bFilterList)
2894                         m_nControlClass = FormComponentType::COMBOBOX;
2895                     else
2896                         m_nControlClass = FormComponentType::TEXTFIELD;
2897             }
2898         }
2899     }
2900 
2901     CreateControl( &rParent, xModel );
2902     DbCellControl::Init( rParent, xCursor );
2903 
2904 	// filter cells are never readonly
2905 	// 31.07.2002 - 101584 - fs@openoffice.org
2906     Edit* pAsEdit = dynamic_cast< Edit* >( m_pWindow );
2907     if ( pAsEdit )
2908 	    pAsEdit->SetReadOnly( sal_False );
2909 }
2910 
2911 //------------------------------------------------------------------------------
2912 CellControllerRef DbFilterField::CreateController() const
2913 {
2914     CellControllerRef xController;
2915     switch (m_nControlClass)
2916     {
2917         case ::com::sun::star::form::FormComponentType::CHECKBOX:
2918             xController = new CheckBoxCellController((CheckBoxControl*)m_pWindow);
2919             break;
2920         case ::com::sun::star::form::FormComponentType::LISTBOX:
2921             xController = new ListBoxCellController((ListBoxControl*)m_pWindow);
2922             break;
2923         case ::com::sun::star::form::FormComponentType::COMBOBOX:
2924             xController = new ComboBoxCellController((ComboBoxControl*)m_pWindow);
2925             break;
2926         default:
2927             if (m_bFilterList)
2928                 xController = new ComboBoxCellController((ComboBoxControl*)m_pWindow);
2929             else
2930                 xController = new EditCellController((Edit*)m_pWindow);
2931     }
2932     return xController;
2933 }
2934 
2935 //------------------------------------------------------------------------------
2936 void DbFilterField::updateFromModel( Reference< XPropertySet > _rxModel )
2937 {
2938     OSL_ENSURE( _rxModel.is() && m_pWindow, "DbFilterField::updateFromModel: invalid call!" );
2939     (void)_rxModel;
2940 
2941     OSL_ENSURE( sal_False, "DbListBox::updateFromModel: not implemented yet (how the hell did you reach this?)!" );
2942     // TODO: implement this.
2943     // remember: updateFromModel should be some kind of opposite of commitControl
2944 }
2945 
2946 //------------------------------------------------------------------------------
2947 sal_Bool DbFilterField::commitControl()
2948 {
2949     String aText(m_aText);
2950     switch (m_nControlClass)
2951     {
2952         case ::com::sun::star::form::FormComponentType::CHECKBOX:
2953             return sal_True;
2954         case ::com::sun::star::form::FormComponentType::LISTBOX:
2955             aText.Erase();
2956             if (static_cast<ListBox*>(m_pWindow)->GetSelectEntryCount())
2957             {
2958                 sal_Int16 nPos = (sal_Int16)static_cast<ListBox*>(m_pWindow)->GetSelectEntryPos();
2959                 if ( ( nPos >= 0 ) && ( nPos < m_aValueList.getLength() ) )
2960                     aText = (const sal_Unicode*)m_aValueList.getConstArray()[nPos];
2961             }
2962 
2963             if (m_aText != aText)
2964             {
2965                 m_aText = aText;
2966                 m_aCommitLink.Call(this);
2967             }
2968             return sal_True;
2969         default:
2970             aText = m_pWindow->GetText();
2971     }
2972 
2973     if (m_aText != aText)
2974     {
2975         // check the text with the SQL-Parser
2976         String aNewText(aText);
2977         aNewText.EraseTrailingChars();
2978         if (aNewText.Len() != 0)
2979         {
2980             ::rtl::OUString aErrorMsg;
2981             Reference< XNumberFormatter >  xNumberFormatter(m_rColumn.GetParent().getNumberFormatter());
2982 
2983             ::rtl::Reference< ISQLParseNode > xParseNode = predicateTree(aErrorMsg, aNewText,xNumberFormatter, m_rColumn.GetField());
2984             if (xParseNode.is())
2985             {
2986                 ::rtl::OUString aPreparedText;
2987 
2988                 ::com::sun::star::lang::Locale aAppLocale = Application::GetSettings().GetUILocale();
2989 
2990                 Reference< XRowSet > xDataSourceRowSet(
2991                     (Reference< XInterface >)*m_rColumn.GetParent().getDataSource(), UNO_QUERY);
2992                 Reference< XConnection >  xConnection(getRowSetConnection(xDataSourceRowSet));
2993 
2994                 xParseNode->parseNodeToPredicateStr(aPreparedText,
2995                                                     xConnection,
2996                                                     xNumberFormatter,
2997                                                     m_rColumn.GetField(),aAppLocale,'.',
2998 													getParseContext());
2999                 m_aText = aPreparedText;
3000             }
3001             else
3002             {
3003                 // display the error and return sal_False
3004                 String aTitle( SVX_RES(RID_STR_SYNTAXERROR) );
3005 
3006                 SQLException aError;
3007                 aError.Message = aErrorMsg;
3008                 displayException(aError, m_pWindow->GetParent());
3009                     // TODO: transport the title
3010 
3011                 return sal_False;
3012             }
3013         }
3014         else
3015             m_aText = aText;
3016 
3017         m_pWindow->SetText(m_aText);
3018         m_aCommitLink.Call(this);
3019     }
3020     return sal_True;
3021 }
3022 
3023 //------------------------------------------------------------------------------
3024 void DbFilterField::SetText(const String& rText)
3025 {
3026     m_aText = rText;
3027     switch (m_nControlClass)
3028     {
3029         case ::com::sun::star::form::FormComponentType::CHECKBOX:
3030         {
3031             TriState eState;
3032             if (rText.EqualsAscii("1"))
3033                 eState = STATE_CHECK;
3034             else if (rText.EqualsAscii("0"))
3035                 eState = STATE_NOCHECK;
3036             else
3037                 eState = STATE_DONTKNOW;
3038 
3039             ((CheckBoxControl*)m_pWindow)->GetBox().SetState(eState);
3040             ((CheckBoxControl*)m_pPainter)->GetBox().SetState(eState);
3041         }   break;
3042         case ::com::sun::star::form::FormComponentType::LISTBOX:
3043         {
3044             String aText;
3045             Sequence<sal_Int16> aPosSeq = ::comphelper::findValue(m_aValueList, m_aText, sal_True);
3046             if (aPosSeq.getLength())
3047                 static_cast<ListBox*>(m_pWindow)->SelectEntryPos(aPosSeq.getConstArray()[0], sal_True);
3048             else
3049                 static_cast<ListBox*>(m_pWindow)->SetNoSelection();
3050         }   break;
3051         default:
3052             m_pWindow->SetText(m_aText);
3053     }
3054 
3055     // now force a repaint on the window
3056     m_rColumn.GetParent().RowModified(0,m_rColumn.GetId());
3057 }
3058 
3059 //------------------------------------------------------------------------------
3060 void DbFilterField::Update()
3061 {
3062     // should we fill the combobox with a filter proposal?
3063     if (m_bFilterList && !m_bFilterListFilled)
3064     {
3065         m_bFilterListFilled = sal_True;
3066         Reference< ::com::sun::star::beans::XPropertySet >  xField = m_rColumn.GetField();
3067         if (!xField.is())
3068             return;
3069 
3070         ::rtl::OUString aName;
3071         xField->getPropertyValue(FM_PROP_NAME) >>= aName;
3072 
3073         // the columnmodel
3074         Reference< ::com::sun::star::container::XChild >  xModelAsChild(m_rColumn.getModel(), UNO_QUERY);
3075         // the grid model
3076         xModelAsChild = Reference< ::com::sun::star::container::XChild > (xModelAsChild->getParent(),UNO_QUERY);
3077         Reference< XRowSet >  xForm(xModelAsChild->getParent(), UNO_QUERY);
3078         if (!xForm.is())
3079             return;
3080 
3081         Reference<XPropertySet> xFormProp(xForm,UNO_QUERY);
3082         Reference< XTablesSupplier > xSupTab;
3083         xFormProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SingleSelectQueryComposer"))) >>= xSupTab;
3084 
3085         Reference< XConnection >  xConnection(getRowSetConnection(xForm));
3086         if (!xSupTab.is())
3087             return;
3088 
3089         // search the field
3090         Reference< XColumnsSupplier > xSupCol(xSupTab,UNO_QUERY);
3091         Reference< ::com::sun::star::container::XNameAccess >    xFieldNames = xSupCol->getColumns();
3092         if (!xFieldNames->hasByName(aName))
3093             return;
3094 
3095         Reference< ::com::sun::star::container::XNameAccess >    xTablesNames = xSupTab->getTables();
3096         Reference< ::com::sun::star::beans::XPropertySet >       xComposerFieldAsSet(xFieldNames->getByName(aName),UNO_QUERY);
3097 
3098         if (xComposerFieldAsSet.is() && ::comphelper::hasProperty(FM_PROP_TABLENAME, xComposerFieldAsSet) &&
3099             ::comphelper::hasProperty(FM_PROP_FIELDSOURCE, xComposerFieldAsSet))
3100         {
3101             ::rtl::OUString aFieldName;
3102             ::rtl::OUString aTableName;
3103             xComposerFieldAsSet->getPropertyValue(FM_PROP_FIELDSOURCE)  >>= aFieldName;
3104             xComposerFieldAsSet->getPropertyValue(FM_PROP_TABLENAME)    >>= aTableName;
3105 
3106             // no possibility to create a select statement
3107             // looking for the complete table name
3108             if (!xTablesNames->hasByName(aTableName))
3109                 return;
3110 
3111             // ein Statement aufbauen und abschicken als query
3112             // Access to the connection
3113             Reference< XStatement >  xStatement;
3114             Reference< XResultSet >  xListCursor;
3115             Reference< ::com::sun::star::sdb::XColumn >  xDataField;
3116 
3117             try
3118             {
3119                 Reference< XDatabaseMetaData >  xMeta = xConnection->getMetaData();
3120 
3121                 String aQuote( xMeta->getIdentifierQuoteString());
3122                 String aStatement;
3123                 aStatement.AssignAscii("SELECT DISTINCT ");
3124 
3125                 aStatement += String(quoteName(aQuote, aName));
3126                 if (aFieldName.getLength() && aName != aFieldName)
3127                 {
3128                     aStatement.AppendAscii(" AS ");
3129                     aStatement += quoteName(aQuote, aFieldName).getStr();
3130                 }
3131 
3132                 aStatement.AppendAscii(" FROM ");
3133 
3134                 Reference< XPropertySet > xTableNameAccess( xTablesNames->getByName(aTableName), UNO_QUERY_THROW );
3135                 aStatement += composeTableNameForSelect( xConnection, xTableNameAccess ).getStr();
3136 
3137                 xStatement = xConnection->createStatement();
3138                 Reference< ::com::sun::star::beans::XPropertySet >  xStatementProps(xStatement, UNO_QUERY);
3139                 xStatementProps->setPropertyValue(FM_PROP_ESCAPE_PROCESSING, makeAny((sal_Bool)sal_True));
3140 
3141                 xListCursor = xStatement->executeQuery(aStatement);
3142 
3143                 Reference< ::com::sun::star::sdbcx::XColumnsSupplier >  xSupplyCols(xListCursor, UNO_QUERY);
3144                 Reference< ::com::sun::star::container::XIndexAccess >  xFields(xSupplyCols->getColumns(), UNO_QUERY);
3145                 ::cppu::extractInterface(xDataField, xFields->getByIndex(0));
3146                 if (!xDataField.is())
3147                     return;
3148             }
3149             catch(const Exception&)
3150             {
3151                 ::comphelper::disposeComponent(xStatement);
3152                 return;
3153             }
3154 
3155             sal_Int16 i = 0;
3156             ::std::vector< ::rtl::OUString >   aStringList;
3157             aStringList.reserve(16);
3158             ::rtl::OUString aStr;
3159             com::sun::star::util::Date aNullDate = m_rColumn.GetParent().getNullDate();
3160             sal_Int32 nFormatKey = m_rColumn.GetKey();
3161             Reference< XNumberFormatter >  xFormatter = m_rColumn.GetParent().getNumberFormatter();
3162             sal_Int16 nKeyType = ::comphelper::getNumberFormatType(xFormatter->getNumberFormatsSupplier()->getNumberFormats(), nFormatKey);
3163 
3164             while (!xListCursor->isAfterLast() && i++ < SHRT_MAX) // max anzahl eintraege
3165             {
3166                 aStr = getFormattedValue(xDataField, xFormatter, aNullDate, nFormatKey, nKeyType);
3167                 aStringList.push_back(aStr);
3168                 xListCursor->next();
3169             }
3170 
3171             // filling the entries for the combobox
3172             for (::std::vector< ::rtl::OUString >::const_iterator iter = aStringList.begin();
3173                  iter != aStringList.end(); ++iter)
3174                 ((ComboBox*)m_pWindow)->InsertEntry(*iter, LISTBOX_APPEND);
3175         }
3176     }
3177 }
3178 
3179 //------------------------------------------------------------------------------
3180 XubString DbFilterField::GetFormatText(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
3181 {
3182     return XubString();
3183 }
3184 
3185 //------------------------------------------------------------------
3186 void DbFilterField::UpdateFromField(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/)
3187 {
3188     DBG_ERROR( "DbFilterField::UpdateFromField: cannot update a filter control from a field!" );
3189 }
3190 
3191 //------------------------------------------------------------------
3192 IMPL_LINK( DbFilterField, OnClick, void*, EMPTYARG )
3193 {
3194     TriState eState = ((CheckBoxControl*)m_pWindow)->GetBox().GetState();
3195     String aText;
3196 
3197     switch (eState)
3198     {
3199         case STATE_CHECK:
3200             aText.AssignAscii("1");
3201             break;
3202         case STATE_NOCHECK:
3203             aText.AssignAscii("0");
3204             break;
3205         case STATE_DONTKNOW:
3206             aText = String();
3207             break;
3208     }
3209 
3210     if (m_aText != aText)
3211     {
3212         m_aText = aText;
3213         m_aCommitLink.Call(this);
3214     }
3215     return 1;
3216 }
3217 
3218 /*************************************************************************/
3219 TYPEINIT0(FmXGridCell);
3220 
3221 
3222 DBG_NAME(FmXGridCell);
3223 //-----------------------------------------------------------------------------
3224 FmXGridCell::FmXGridCell( DbGridColumn* pColumn, DbCellControl* _pControl )
3225             :OComponentHelper(m_aMutex)
3226             ,m_pColumn(pColumn)
3227             ,m_pCellControl( _pControl )
3228             ,m_aWindowListeners( m_aMutex )
3229             ,m_aFocusListeners( m_aMutex )
3230             ,m_aKeyListeners( m_aMutex )
3231             ,m_aMouseListeners( m_aMutex )
3232             ,m_aMouseMotionListeners( m_aMutex )
3233 {
3234     DBG_CTOR(FmXGridCell,NULL);
3235 }
3236 
3237 //-----------------------------------------------------------------------------
3238 void FmXGridCell::init()
3239 {
3240     Window* pEventWindow( getEventWindow() );
3241     if ( pEventWindow )
3242         pEventWindow->AddEventListener( LINK( this, FmXGridCell, OnWindowEvent ) );
3243 }
3244 
3245 //-----------------------------------------------------------------------------
3246 Window* FmXGridCell::getEventWindow() const
3247 {
3248     if ( m_pCellControl )
3249         return &m_pCellControl->GetWindow();
3250     return NULL;
3251 }
3252 
3253 //-----------------------------------------------------------------------------
3254 FmXGridCell::~FmXGridCell()
3255 {
3256     if (!OComponentHelper::rBHelper.bDisposed)
3257     {
3258         acquire();
3259         dispose();
3260     }
3261 
3262     DBG_DTOR(FmXGridCell,NULL);
3263 }
3264 
3265 //------------------------------------------------------------------
3266 void FmXGridCell::SetTextLineColor()
3267 {
3268     if (m_pCellControl)
3269         m_pCellControl->SetTextLineColor();
3270 }
3271 
3272 //------------------------------------------------------------------
3273 void FmXGridCell::SetTextLineColor(const Color& _rColor)
3274 {
3275     if (m_pCellControl)
3276         m_pCellControl->SetTextLineColor(_rColor);
3277 }
3278 
3279 // XTypeProvider
3280 //------------------------------------------------------------------
3281 Sequence< Type > SAL_CALL FmXGridCell::getTypes( ) throw (RuntimeException)
3282 {
3283     Sequence< uno::Type > aTypes = ::comphelper::concatSequences(
3284         ::cppu::OComponentHelper::getTypes(),
3285         FmXGridCell_Base::getTypes()
3286     );
3287     if ( m_pCellControl )
3288         aTypes = ::comphelper::concatSequences(
3289             aTypes,
3290             FmXGridCell_WindowBase::getTypes()
3291         );
3292     return aTypes;
3293 }
3294 
3295 //------------------------------------------------------------------
3296 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXGridCell )
3297 
3298 // OComponentHelper
3299 //-----------------------------------------------------------------------------
3300 void FmXGridCell::disposing()
3301 {
3302     lang::EventObject aEvent( *this );
3303     m_aWindowListeners.disposeAndClear( aEvent );
3304     m_aFocusListeners.disposeAndClear( aEvent );
3305     m_aKeyListeners.disposeAndClear( aEvent );
3306     m_aMouseListeners.disposeAndClear( aEvent );
3307     m_aMouseMotionListeners.disposeAndClear( aEvent );
3308 
3309     OComponentHelper::disposing();
3310     m_pColumn = NULL;
3311     DELETEZ(m_pCellControl);
3312 }
3313 
3314 //------------------------------------------------------------------
3315 Any SAL_CALL FmXGridCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException)
3316 {
3317     Any aReturn = OComponentHelper::queryAggregation( _rType );
3318 
3319     if ( !aReturn.hasValue() )
3320         aReturn = FmXGridCell_Base::queryInterface( _rType );
3321 
3322     if ( !aReturn.hasValue() && ( m_pCellControl != NULL ) )
3323         aReturn = FmXGridCell_WindowBase::queryInterface( _rType );
3324 
3325     return aReturn;
3326 }
3327 
3328 // ::com::sun::star::awt::XControl
3329 //-----------------------------------------------------------------------------
3330 Reference< XInterface >  FmXGridCell::getContext() throw( RuntimeException )
3331 {
3332     return Reference< XInterface > ();
3333 }
3334 
3335 //-----------------------------------------------------------------------------
3336 Reference< ::com::sun::star::awt::XControlModel >  FmXGridCell::getModel() throw( ::com::sun::star::uno::RuntimeException )
3337 {
3338     return Reference< ::com::sun::star::awt::XControlModel > (m_pColumn->getModel(), UNO_QUERY);
3339 }
3340 
3341 // ::com::sun::star::form::XBoundControl
3342 //------------------------------------------------------------------
3343 sal_Bool FmXGridCell::getLock() throw( RuntimeException )
3344 {
3345     return m_pColumn->isLocked();
3346 }
3347 
3348 //------------------------------------------------------------------
3349 void FmXGridCell::setLock(sal_Bool _bLock) throw( RuntimeException )
3350 {
3351     if (getLock() == _bLock)
3352         return;
3353     else
3354     {
3355         ::osl::MutexGuard aGuard(m_aMutex);
3356         m_pColumn->setLock(_bLock);
3357     }
3358 }
3359 
3360 //------------------------------------------------------------------
3361 void SAL_CALL FmXGridCell::setPosSize( ::sal_Int32 _XX, ::sal_Int32 _Y, ::sal_Int32 _Width, ::sal_Int32 _Height, ::sal_Int16 _Flags ) throw (RuntimeException)
3362 {
3363     OSL_ENSURE( false, "FmXGridCell::setPosSize: not implemented" );
3364     (void)_XX;
3365     (void)_Y;
3366     (void)_Width;
3367     (void)_Height;
3368     (void)_Flags;
3369     // not allowed to tamper with this for a grid cell
3370 }
3371 
3372 //------------------------------------------------------------------
3373 awt::Rectangle SAL_CALL FmXGridCell::getPosSize(  ) throw (RuntimeException)
3374 {
3375     OSL_ENSURE( false, "FmXGridCell::getPosSize: not implemented" );
3376     return awt::Rectangle();
3377 }
3378 
3379 //------------------------------------------------------------------
3380 void SAL_CALL FmXGridCell::setVisible( ::sal_Bool _Visible ) throw (RuntimeException)
3381 {
3382     OSL_ENSURE( false, "FmXGridCell::setVisible: not implemented" );
3383     (void)_Visible;
3384     // not allowed to tamper with this for a grid cell
3385 }
3386 
3387 //------------------------------------------------------------------
3388 void SAL_CALL FmXGridCell::setEnable( ::sal_Bool _Enable ) throw (RuntimeException)
3389 {
3390     OSL_ENSURE( false, "FmXGridCell::setEnable: not implemented" );
3391     (void)_Enable;
3392     // not allowed to tamper with this for a grid cell
3393 }
3394 
3395 //------------------------------------------------------------------
3396 void SAL_CALL FmXGridCell::setFocus(  ) throw (RuntimeException)
3397 {
3398     OSL_ENSURE( false, "FmXGridCell::setFocus: not implemented" );
3399     // not allowed to tamper with this for a grid cell
3400 }
3401 
3402 //------------------------------------------------------------------
3403 void SAL_CALL FmXGridCell::addWindowListener( const Reference< awt::XWindowListener >& _rxListener ) throw (RuntimeException)
3404 {
3405     m_aWindowListeners.addInterface( _rxListener );
3406 }
3407 
3408 //------------------------------------------------------------------
3409 void SAL_CALL FmXGridCell::removeWindowListener( const Reference< awt::XWindowListener >& _rxListener ) throw (RuntimeException)
3410 {
3411     m_aWindowListeners.removeInterface( _rxListener );
3412 }
3413 
3414 //------------------------------------------------------------------
3415 void SAL_CALL FmXGridCell::addFocusListener( const Reference< awt::XFocusListener >& _rxListener ) throw (RuntimeException)
3416 {
3417     m_aFocusListeners.addInterface( _rxListener );
3418 }
3419 
3420 //------------------------------------------------------------------
3421 void SAL_CALL FmXGridCell::removeFocusListener( const Reference< awt::XFocusListener >& _rxListener ) throw (RuntimeException)
3422 {
3423     m_aFocusListeners.removeInterface( _rxListener );
3424 }
3425 
3426 //------------------------------------------------------------------
3427 void SAL_CALL FmXGridCell::addKeyListener( const Reference< awt::XKeyListener >& _rxListener ) throw (RuntimeException)
3428 {
3429     m_aKeyListeners.addInterface( _rxListener );
3430 }
3431 
3432 //------------------------------------------------------------------
3433 void SAL_CALL FmXGridCell::removeKeyListener( const Reference< awt::XKeyListener >& _rxListener ) throw (RuntimeException)
3434 {
3435     m_aKeyListeners.removeInterface( _rxListener );
3436 }
3437 
3438 //------------------------------------------------------------------
3439 void SAL_CALL FmXGridCell::addMouseListener( const Reference< awt::XMouseListener >& _rxListener ) throw (RuntimeException)
3440 {
3441     m_aMouseListeners.addInterface( _rxListener );
3442 }
3443 
3444 //------------------------------------------------------------------
3445 void SAL_CALL FmXGridCell::removeMouseListener( const Reference< awt::XMouseListener >& _rxListener ) throw (RuntimeException)
3446 {
3447     m_aMouseListeners.removeInterface( _rxListener );
3448 }
3449 
3450 //------------------------------------------------------------------
3451 void SAL_CALL FmXGridCell::addMouseMotionListener( const Reference< awt::XMouseMotionListener >& _rxListener ) throw (RuntimeException)
3452 {
3453     m_aMouseMotionListeners.addInterface( _rxListener );
3454 }
3455 
3456 //------------------------------------------------------------------
3457 void SAL_CALL FmXGridCell::removeMouseMotionListener( const Reference< awt::XMouseMotionListener >& _rxListener ) throw (RuntimeException)
3458 {
3459     m_aMouseMotionListeners.removeInterface( _rxListener );
3460 }
3461 
3462 //------------------------------------------------------------------
3463 void SAL_CALL FmXGridCell::addPaintListener( const Reference< awt::XPaintListener >& _rxListener ) throw (RuntimeException)
3464 {
3465     OSL_ENSURE( false, "FmXGridCell::addPaintListener: not implemented" );
3466     (void)_rxListener;
3467 }
3468 
3469 //------------------------------------------------------------------
3470 void SAL_CALL FmXGridCell::removePaintListener( const Reference< awt::XPaintListener >& _rxListener ) throw (RuntimeException)
3471 {
3472     OSL_ENSURE( false, "FmXGridCell::removePaintListener: not implemented" );
3473     (void)_rxListener;
3474 }
3475 
3476 //------------------------------------------------------------------
3477 IMPL_LINK( FmXGridCell, OnWindowEvent, VclWindowEvent*, _pEvent )
3478 {
3479     ENSURE_OR_THROW( _pEvent, "illegal event pointer" );
3480     ENSURE_OR_THROW( _pEvent->GetWindow(), "illegal window" );
3481     onWindowEvent( _pEvent->GetId(), *_pEvent->GetWindow(), _pEvent->GetData() );
3482     return 1L;
3483 }
3484 
3485 //------------------------------------------------------------------------------
3486 void FmXGridCell::onFocusGained( const awt::FocusEvent& _rEvent )
3487 {
3488     m_aFocusListeners.notifyEach( &awt::XFocusListener::focusGained, _rEvent );
3489 }
3490 
3491 //------------------------------------------------------------------------------
3492 void FmXGridCell::onFocusLost( const awt::FocusEvent& _rEvent )
3493 {
3494     m_aFocusListeners.notifyEach( &awt::XFocusListener::focusLost, _rEvent );
3495 }
3496 
3497 //------------------------------------------------------------------------------
3498 void FmXGridCell::onWindowEvent( const sal_uIntPtr _nEventId, const Window& _rWindow, const void* _pEventData )
3499 {
3500     switch ( _nEventId )
3501     {
3502 	case VCLEVENT_CONTROL_GETFOCUS:
3503     case VCLEVENT_WINDOW_GETFOCUS:
3504 	case VCLEVENT_CONTROL_LOSEFOCUS:
3505     case VCLEVENT_WINDOW_LOSEFOCUS:
3506     {
3507         if	(	(	_rWindow.IsCompoundControl()
3508 				&&	(   _nEventId == VCLEVENT_CONTROL_GETFOCUS
3509                     ||  _nEventId == VCLEVENT_CONTROL_LOSEFOCUS
3510                     )
3511 				)
3512 			||	(	!_rWindow.IsCompoundControl()
3513 				&&	(   _nEventId == VCLEVENT_WINDOW_GETFOCUS
3514                     ||  _nEventId == VCLEVENT_WINDOW_LOSEFOCUS
3515                     )
3516 				)
3517 			)
3518 		{
3519             if ( !m_aFocusListeners.getLength() )
3520                 break;
3521 
3522             bool bFocusGained = ( _nEventId == VCLEVENT_CONTROL_GETFOCUS ) || ( _nEventId == VCLEVENT_WINDOW_GETFOCUS );
3523 
3524             awt::FocusEvent aEvent;
3525             aEvent.Source = *this;
3526             aEvent.FocusFlags = _rWindow.GetGetFocusFlags();
3527             aEvent.Temporary = sal_False;
3528 
3529             if ( bFocusGained )
3530                 onFocusGained( aEvent );
3531             else
3532                 onFocusLost( aEvent );
3533 		}
3534     }
3535     break;
3536     case VCLEVENT_WINDOW_MOUSEBUTTONDOWN:
3537     case VCLEVENT_WINDOW_MOUSEBUTTONUP:
3538     {
3539         if ( !m_aMouseListeners.getLength() )
3540             break;
3541 
3542         const bool bButtonDown = ( _nEventId == VCLEVENT_WINDOW_MOUSEBUTTONDOWN );
3543 
3544         awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast< const ::MouseEvent* >( _pEventData ), *this ) );
3545         m_aMouseListeners.notifyEach( bButtonDown ? &awt::XMouseListener::mousePressed : &awt::XMouseListener::mouseReleased, aEvent );
3546     }
3547     break;
3548     case VCLEVENT_WINDOW_MOUSEMOVE:
3549     {
3550         const MouseEvent& rMouseEvent = *static_cast< const ::MouseEvent* >( _pEventData );
3551         if ( rMouseEvent.IsEnterWindow() || rMouseEvent.IsLeaveWindow() )
3552         {
3553             if ( m_aMouseListeners.getLength() != 0 )
3554             {
3555                 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
3556                 m_aMouseListeners.notifyEach( rMouseEvent.IsEnterWindow() ? &awt::XMouseListener::mouseEntered: &awt::XMouseListener::mouseExited, aEvent );
3557             }
3558         }
3559         else if ( !rMouseEvent.IsEnterWindow() && !rMouseEvent.IsLeaveWindow() )
3560         {
3561             if ( m_aMouseMotionListeners.getLength() != 0 )
3562             {
3563                 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
3564                 aEvent.ClickCount = 0;
3565                 const bool bSimpleMove = ( ( rMouseEvent.GetMode() & MOUSE_SIMPLEMOVE ) != 0 );
3566                 m_aMouseMotionListeners.notifyEach( bSimpleMove ? &awt::XMouseMotionListener::mouseMoved: &awt::XMouseMotionListener::mouseDragged, aEvent );
3567             }
3568         }
3569     }
3570     break;
3571     case VCLEVENT_WINDOW_KEYINPUT:
3572     case VCLEVENT_WINDOW_KEYUP:
3573     {
3574         if ( !m_aKeyListeners.getLength() )
3575             break;
3576 
3577         const bool bKeyPressed = ( _nEventId == VCLEVENT_WINDOW_KEYINPUT );
3578         awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent( *static_cast< const ::KeyEvent* >( _pEventData ), *this ) );
3579         m_aKeyListeners.notifyEach( bKeyPressed ? &awt::XKeyListener::keyPressed: &awt::XKeyListener::keyReleased, aEvent );
3580     }
3581     break;
3582     }
3583 }
3584 
3585 /*************************************************************************/
3586 TYPEINIT1(FmXDataCell, FmXGridCell);
3587 //------------------------------------------------------------------------------
3588 void FmXDataCell::PaintFieldToCell(OutputDevice& rDev, const Rectangle& rRect,
3589                         const Reference< ::com::sun::star::sdb::XColumn >& _rxField,
3590                         const Reference< XNumberFormatter >& xFormatter)
3591 {
3592     m_pCellControl->PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
3593 }
3594 
3595 //------------------------------------------------------------------------------
3596 void FmXDataCell::UpdateFromColumn()
3597 {
3598     Reference< ::com::sun::star::sdb::XColumn >  xField(m_pColumn->GetCurrentFieldValue());
3599     if (xField.is())
3600         m_pCellControl->UpdateFromField(xField, m_pColumn->GetParent().getNumberFormatter());
3601 }
3602 
3603 /*************************************************************************/
3604 TYPEINIT1(FmXTextCell, FmXDataCell);
3605 
3606 FmXTextCell::FmXTextCell( DbGridColumn* pColumn, DbCellControl& _rControl )
3607     :FmXDataCell( pColumn, _rControl )
3608     ,m_bFastPaint( sal_True )
3609 {
3610 }
3611 
3612 //------------------------------------------------------------------------------
3613 void FmXTextCell::PaintFieldToCell(OutputDevice& rDev,
3614                         const Rectangle& rRect,
3615                         const Reference< ::com::sun::star::sdb::XColumn >& _rxField,
3616                         const Reference< XNumberFormatter >& xFormatter)
3617 {
3618     if ( !m_bFastPaint )
3619     {
3620         FmXDataCell::PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
3621         return;
3622     }
3623 
3624     sal_uInt16 nStyle = TEXT_DRAW_CLIP | TEXT_DRAW_VCENTER;
3625     if ( ( rDev.GetOutDevType() == OUTDEV_WINDOW ) && !static_cast< Window& >( rDev ).IsEnabled() )
3626         nStyle |= TEXT_DRAW_DISABLE;
3627 
3628     switch (m_pColumn->GetAlignment())
3629     {
3630         case ::com::sun::star::awt::TextAlign::RIGHT:
3631             nStyle |= TEXT_DRAW_RIGHT;
3632             break;
3633         case ::com::sun::star::awt::TextAlign::CENTER:
3634             nStyle |= TEXT_DRAW_CENTER;
3635             break;
3636         default:
3637             nStyle |= TEXT_DRAW_LEFT;
3638     }
3639 
3640     Color* pColor = NULL;
3641     String aText = GetText(_rxField, xFormatter, &pColor);
3642     if (pColor != NULL)
3643     {
3644         Color aOldTextColor( rDev.GetTextColor() );
3645         rDev.SetTextColor( *pColor );
3646         rDev.DrawText(rRect, aText, nStyle);
3647         rDev.SetTextColor( aOldTextColor );
3648     }
3649     else
3650         rDev.DrawText(rRect, aText, nStyle);
3651 }
3652 
3653 
3654 /*************************************************************************/
3655 
3656 DBG_NAME(FmXEditCell);
3657 //------------------------------------------------------------------------------
3658 FmXEditCell::FmXEditCell( DbGridColumn* pColumn, DbCellControl& _rControl )
3659             :FmXTextCell( pColumn, _rControl )
3660             ,m_aTextListeners(m_aMutex)
3661             ,m_aChangeListeners( m_aMutex )
3662             ,m_pEditImplementation( NULL )
3663             ,m_bOwnEditImplementation( false )
3664 {
3665     DBG_CTOR(FmXEditCell,NULL);
3666 
3667     DbTextField* pTextField = PTR_CAST( DbTextField, &_rControl );
3668     if ( pTextField )
3669     {
3670 
3671         m_pEditImplementation = pTextField->GetEditImplementation();
3672         if ( !pTextField->IsSimpleEdit() )
3673             m_bFastPaint = sal_False;
3674     }
3675     else
3676     {
3677         m_pEditImplementation = new EditImplementation( static_cast< Edit& >( _rControl.GetWindow() ) );
3678         m_bOwnEditImplementation = true;
3679     }
3680 }
3681 
3682 //------------------------------------------------------------------
3683 FmXEditCell::~FmXEditCell()
3684 {
3685     if (!OComponentHelper::rBHelper.bDisposed)
3686     {
3687         acquire();
3688         dispose();
3689     }
3690 
3691 
3692     DBG_DTOR(FmXEditCell,NULL);
3693 }
3694 
3695 // OComponentHelper
3696 //-----------------------------------------------------------------------------
3697 void FmXEditCell::disposing()
3698 {
3699     ::com::sun::star::lang::EventObject aEvt(*this);
3700     m_aTextListeners.disposeAndClear(aEvt);
3701     m_aChangeListeners.disposeAndClear(aEvt);
3702 
3703     m_pEditImplementation->SetModifyHdl( Link() );
3704     if ( m_bOwnEditImplementation )
3705         delete m_pEditImplementation;
3706     m_pEditImplementation = NULL;
3707 
3708     FmXDataCell::disposing();
3709 }
3710 
3711 //------------------------------------------------------------------
3712 Any SAL_CALL FmXEditCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException)
3713 {
3714     Any aReturn = FmXTextCell::queryAggregation( _rType );
3715 
3716     if ( !aReturn.hasValue() )
3717         aReturn = FmXEditCell_Base::queryInterface( _rType );
3718 
3719     return aReturn;
3720 }
3721 
3722 //-------------------------------------------------------------------------
3723 Sequence< ::com::sun::star::uno::Type > SAL_CALL FmXEditCell::getTypes(  ) throw(RuntimeException)
3724 {
3725     return ::comphelper::concatSequences(
3726         FmXTextCell::getTypes(),
3727         FmXEditCell_Base::getTypes()
3728     );
3729 }
3730 
3731 //------------------------------------------------------------------------------
3732 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXEditCell )
3733 
3734 // ::com::sun::star::awt::XTextComponent
3735 //------------------------------------------------------------------------------
3736 void SAL_CALL FmXEditCell::addTextListener(const Reference< ::com::sun::star::awt::XTextListener >& l) throw( RuntimeException )
3737 {
3738     m_aTextListeners.addInterface( l );
3739 }
3740 
3741 //------------------------------------------------------------------------------
3742 void SAL_CALL FmXEditCell::removeTextListener(const Reference< ::com::sun::star::awt::XTextListener >& l) throw( RuntimeException )
3743 {
3744     m_aTextListeners.removeInterface( l );
3745 }
3746 
3747 //------------------------------------------------------------------------------
3748 void SAL_CALL FmXEditCell::setText( const ::rtl::OUString& aText ) throw( RuntimeException )
3749 {
3750     ::osl::MutexGuard aGuard( m_aMutex );
3751 
3752     if ( m_pEditImplementation )
3753     {
3754         m_pEditImplementation->SetText( aText );
3755 
3756         // In JAVA wird auch ein textChanged ausgeloest, in VCL nicht.
3757         // ::com::sun::star::awt::Toolkit soll JAVA-komform sein...
3758         onTextChanged();
3759     }
3760 }
3761 
3762 //------------------------------------------------------------------------------
3763 void SAL_CALL FmXEditCell::insertText(const ::com::sun::star::awt::Selection& rSel, const ::rtl::OUString& aText) throw(RuntimeException)
3764 {
3765     ::osl::MutexGuard aGuard( m_aMutex );
3766 
3767     if ( m_pEditImplementation )
3768     {
3769         m_pEditImplementation->SetSelection( Selection( rSel.Min, rSel.Max ) );
3770         m_pEditImplementation->ReplaceSelected( aText );
3771     }
3772 }
3773 
3774 //------------------------------------------------------------------------------
3775 ::rtl::OUString SAL_CALL FmXEditCell::getText() throw( RuntimeException )
3776 {
3777     ::osl::MutexGuard aGuard( m_aMutex );
3778 
3779     ::rtl::OUString aText;
3780     if ( m_pEditImplementation )
3781     {
3782         if ( m_pEditImplementation->GetControl().IsVisible() && m_pColumn->GetParent().getDisplaySynchron())
3783         {
3784             // if the display isn't sync with the cursor we can't ask the edit field
3785             LineEnd eLineEndFormat = m_pColumn ? getModelLineEndSetting( m_pColumn->getModel() ) : LINEEND_LF;
3786             aText = m_pEditImplementation->GetText( eLineEndFormat );
3787         }
3788         else
3789         {
3790             Reference< ::com::sun::star::sdb::XColumn >  xField(m_pColumn->GetCurrentFieldValue());
3791             if (xField.is())
3792                 aText = GetText(xField, m_pColumn->GetParent().getNumberFormatter());
3793         }
3794     }
3795     return aText;
3796 }
3797 
3798 //------------------------------------------------------------------------------
3799 ::rtl::OUString SAL_CALL FmXEditCell::getSelectedText( void ) throw( RuntimeException )
3800 {
3801     ::osl::MutexGuard aGuard( m_aMutex );
3802 
3803     ::rtl::OUString aText;
3804     if ( m_pEditImplementation )
3805     {
3806         LineEnd eLineEndFormat = m_pColumn ? getModelLineEndSetting( m_pColumn->getModel() ) : LINEEND_LF;
3807         aText = m_pEditImplementation->GetSelected( eLineEndFormat );
3808     }
3809     return aText;
3810 }
3811 
3812 //------------------------------------------------------------------------------
3813 void SAL_CALL FmXEditCell::setSelection( const ::com::sun::star::awt::Selection& aSelection ) throw( RuntimeException )
3814 {
3815     ::osl::MutexGuard aGuard( m_aMutex );
3816 
3817     if ( m_pEditImplementation )
3818         m_pEditImplementation->SetSelection( Selection( aSelection.Min, aSelection.Max ) );
3819 }
3820 
3821 //------------------------------------------------------------------------------
3822 ::com::sun::star::awt::Selection SAL_CALL FmXEditCell::getSelection( void ) throw( RuntimeException )
3823 {
3824     ::osl::MutexGuard aGuard( m_aMutex );
3825 
3826     Selection aSel;
3827     if ( m_pEditImplementation )
3828         aSel = m_pEditImplementation->GetSelection();
3829 
3830     return ::com::sun::star::awt::Selection(aSel.Min(), aSel.Max());
3831 }
3832 
3833 //------------------------------------------------------------------------------
3834 sal_Bool SAL_CALL FmXEditCell::isEditable( void ) throw( RuntimeException )
3835 {
3836     ::osl::MutexGuard aGuard( m_aMutex );
3837 
3838     return ( m_pEditImplementation && !m_pEditImplementation->IsReadOnly() && m_pEditImplementation->GetControl().IsEnabled() ) ? sal_True : sal_False;
3839 }
3840 
3841 //------------------------------------------------------------------------------
3842 void SAL_CALL FmXEditCell::setEditable( sal_Bool bEditable ) throw( RuntimeException )
3843 {
3844     ::osl::MutexGuard aGuard( m_aMutex );
3845 
3846     if ( m_pEditImplementation )
3847         m_pEditImplementation->SetReadOnly( !bEditable );
3848 }
3849 
3850 //------------------------------------------------------------------------------
3851 sal_Int16 SAL_CALL FmXEditCell::getMaxTextLen() throw( RuntimeException )
3852 {
3853     ::osl::MutexGuard aGuard( m_aMutex );
3854 
3855     return m_pEditImplementation ? m_pEditImplementation->GetMaxTextLen() : 0;
3856 }
3857 
3858 //------------------------------------------------------------------------------
3859 void SAL_CALL FmXEditCell::setMaxTextLen( sal_Int16 nLen ) throw( RuntimeException )
3860 {
3861     ::osl::MutexGuard aGuard( m_aMutex );
3862 
3863     if ( m_pEditImplementation )
3864         m_pEditImplementation->SetMaxTextLen( nLen );
3865 }
3866 
3867 //------------------------------------------------------------------------------
3868 void SAL_CALL FmXEditCell::addChangeListener( const Reference< form::XChangeListener >& _Listener ) throw (RuntimeException)
3869 {
3870     m_aChangeListeners.addInterface( _Listener );
3871 }
3872 
3873 //------------------------------------------------------------------------------
3874 void SAL_CALL FmXEditCell::removeChangeListener( const Reference< form::XChangeListener >& _Listener ) throw (RuntimeException)
3875 {
3876     m_aChangeListeners.removeInterface( _Listener );
3877 }
3878 
3879 //------------------------------------------------------------------------------
3880 void FmXEditCell::onTextChanged()
3881 {
3882     ::com::sun::star::awt::TextEvent aEvent;
3883     aEvent.Source = *this;
3884     m_aTextListeners.notifyEach( &awt::XTextListener::textChanged, aEvent );
3885 }
3886 
3887 //------------------------------------------------------------------------------
3888 void FmXEditCell::onFocusGained( const awt::FocusEvent& _rEvent )
3889 {
3890     FmXTextCell::onFocusGained( _rEvent );
3891     m_sValueOnEnter = getText();
3892 }
3893 
3894 //------------------------------------------------------------------------------
3895 void FmXEditCell::onFocusLost( const awt::FocusEvent& _rEvent )
3896 {
3897     FmXTextCell::onFocusLost( _rEvent );
3898 
3899     if ( getText() != m_sValueOnEnter )
3900     {
3901         lang::EventObject aEvent( *this );
3902         m_aChangeListeners.notifyEach( &XChangeListener::changed, aEvent );
3903     }
3904 }
3905 
3906 //------------------------------------------------------------------------------
3907 void FmXEditCell::onWindowEvent( const sal_uIntPtr _nEventId, const Window& _rWindow, const void* _pEventData )
3908 {
3909     switch ( _nEventId )
3910     {
3911     case VCLEVENT_EDIT_MODIFY:
3912     {
3913         if ( m_pEditImplementation && m_aTextListeners.getLength() )
3914             onTextChanged();
3915         return;
3916     }
3917     }
3918 
3919     FmXTextCell::onWindowEvent( _nEventId, _rWindow, _pEventData );
3920 }
3921 
3922 /*************************************************************************/
3923 DBG_NAME(FmXCheckBoxCell);
3924 //------------------------------------------------------------------------------
3925 FmXCheckBoxCell::FmXCheckBoxCell( DbGridColumn* pColumn, DbCellControl& _rControl )
3926                 :FmXDataCell( pColumn, _rControl )
3927                 ,m_aItemListeners(m_aMutex)
3928                 ,m_aActionListeners( m_aMutex )
3929                 ,m_pBox( & static_cast< CheckBoxControl& >( _rControl.GetWindow() ).GetBox() )
3930 {
3931     DBG_CTOR(FmXCheckBoxCell,NULL);
3932 }
3933 
3934 //------------------------------------------------------------------
3935 FmXCheckBoxCell::~FmXCheckBoxCell()
3936 {
3937     if (!OComponentHelper::rBHelper.bDisposed)
3938     {
3939         acquire();
3940         dispose();
3941     }
3942 
3943     DBG_DTOR(FmXCheckBoxCell,NULL);
3944 }
3945 
3946 // OComponentHelper
3947 //-----------------------------------------------------------------------------
3948 void FmXCheckBoxCell::disposing()
3949 {
3950     ::com::sun::star::lang::EventObject aEvt(*this);
3951     m_aItemListeners.disposeAndClear(aEvt);
3952     m_aActionListeners.disposeAndClear(aEvt);
3953 
3954     static_cast< CheckBoxControl& >( m_pCellControl->GetWindow() ).SetClickHdl(Link());
3955     m_pBox = NULL;
3956 
3957     FmXDataCell::disposing();
3958 }
3959 
3960 //------------------------------------------------------------------
3961 Any SAL_CALL FmXCheckBoxCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException)
3962 {
3963     Any aReturn = FmXDataCell::queryAggregation( _rType );
3964 
3965     if ( !aReturn.hasValue() )
3966         aReturn = FmXCheckBoxCell_Base::queryInterface( _rType );
3967 
3968     return aReturn;
3969 }
3970 
3971 //-------------------------------------------------------------------------
3972 Sequence< ::com::sun::star::uno::Type > SAL_CALL FmXCheckBoxCell::getTypes(  ) throw(RuntimeException)
3973 {
3974     return ::comphelper::concatSequences(
3975         FmXDataCell::getTypes(),
3976         FmXCheckBoxCell_Base::getTypes()
3977     );
3978 }
3979 
3980 //------------------------------------------------------------------------------
3981 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXCheckBoxCell )
3982 
3983 //------------------------------------------------------------------
3984 void SAL_CALL FmXCheckBoxCell::addItemListener( const Reference< ::com::sun::star::awt::XItemListener >& l ) throw( RuntimeException )
3985 {
3986     m_aItemListeners.addInterface( l );
3987 }
3988 
3989 //------------------------------------------------------------------
3990 void SAL_CALL FmXCheckBoxCell::removeItemListener( const Reference< ::com::sun::star::awt::XItemListener >& l ) throw( RuntimeException )
3991 {
3992     m_aItemListeners.removeInterface( l );
3993 }
3994 
3995 //------------------------------------------------------------------
3996 void SAL_CALL FmXCheckBoxCell::setState( short n ) throw( RuntimeException )
3997 {
3998     ::osl::MutexGuard aGuard( m_aMutex );
3999 
4000     if (m_pBox)
4001     {
4002         UpdateFromColumn();
4003         m_pBox->SetState( (TriState)n );
4004     }
4005 }
4006 
4007 //------------------------------------------------------------------
4008 short SAL_CALL FmXCheckBoxCell::getState() throw( RuntimeException )
4009 {
4010     ::osl::MutexGuard aGuard( m_aMutex );
4011 
4012     if (m_pBox)
4013     {
4014         UpdateFromColumn();
4015         return (short)m_pBox->GetState();
4016     }
4017     return STATE_DONTKNOW;
4018 }
4019 
4020 //------------------------------------------------------------------
4021 void SAL_CALL FmXCheckBoxCell::enableTriState( sal_Bool b ) throw( RuntimeException )
4022 {
4023     ::osl::MutexGuard aGuard( m_aMutex );
4024 
4025     if (m_pBox)
4026         m_pBox->EnableTriState( b );
4027 }
4028 
4029 //------------------------------------------------------------------
4030 void SAL_CALL FmXCheckBoxCell::addActionListener( const Reference< awt::XActionListener >& _Listener ) throw (RuntimeException)
4031 {
4032     m_aActionListeners.addInterface( _Listener );
4033 }
4034 
4035 //------------------------------------------------------------------
4036 void SAL_CALL FmXCheckBoxCell::removeActionListener( const Reference< awt::XActionListener >& _Listener ) throw (RuntimeException)
4037 {
4038     m_aActionListeners.removeInterface( _Listener );
4039 }
4040 
4041 //------------------------------------------------------------------
4042 void SAL_CALL FmXCheckBoxCell::setLabel( const ::rtl::OUString& _Label ) throw (RuntimeException)
4043 {
4044 	::vos::OGuard aGuard( Application::GetSolarMutex() );
4045     if ( m_pColumn )
4046     {
4047         DbGridControl& rGrid( m_pColumn->GetParent() );
4048         rGrid.SetColumnTitle( rGrid.GetColumnId( m_pColumn->GetFieldPos() ), _Label );
4049     }
4050 }
4051 
4052 //------------------------------------------------------------------
4053 void SAL_CALL FmXCheckBoxCell::setActionCommand( const ::rtl::OUString& _Command ) throw (RuntimeException)
4054 {
4055     m_aActionCommand = _Command;
4056 }
4057 
4058 //------------------------------------------------------------------
4059 Window* FmXCheckBoxCell::getEventWindow() const
4060 {
4061     return m_pBox;
4062 }
4063 
4064 //------------------------------------------------------------------
4065 void FmXCheckBoxCell::onWindowEvent( const sal_uIntPtr _nEventId, const Window& _rWindow, const void* _pEventData )
4066 {
4067     switch ( _nEventId )
4068     {
4069     case VCLEVENT_CHECKBOX_TOGGLE:
4070     {
4071         // check boxes are to be committed immediately (this holds for ordinary check box controls in
4072         // documents, and this must hold for check boxes in grid columns, too
4073         // 91210 - 22.08.2001 - frank.schoenheit@sun.com
4074         m_pCellControl->Commit();
4075 
4076         Reference< XWindow > xKeepAlive( this );
4077         if ( m_aItemListeners.getLength() && m_pBox )
4078         {
4079             awt::ItemEvent aEvent;
4080             aEvent.Source = *this;
4081             aEvent.Highlighted = sal_False;
4082             aEvent.Selected = m_pBox->GetState();
4083             m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4084         }
4085         if ( m_aActionListeners.getLength() )
4086         {
4087             awt::ActionEvent aEvent;
4088             aEvent.Source = *this;
4089             aEvent.ActionCommand = m_aActionCommand;
4090             m_aActionListeners.notifyEach( &awt::XActionListener::actionPerformed, aEvent );
4091         }
4092     }
4093     break;
4094 
4095     default:
4096         FmXDataCell::onWindowEvent( _nEventId, _rWindow, _pEventData );
4097         break;
4098     }
4099 }
4100 
4101 /*************************************************************************/
4102 
4103 DBG_NAME(FmXListBoxCell);
4104 //------------------------------------------------------------------------------
4105 FmXListBoxCell::FmXListBoxCell(DbGridColumn* pColumn, DbCellControl& _rControl)
4106                :FmXTextCell( pColumn, _rControl )
4107                ,m_aItemListeners(m_aMutex)
4108                ,m_aActionListeners(m_aMutex)
4109                ,m_pBox( &static_cast< ListBox& >( _rControl.GetWindow() ) )
4110 {
4111     DBG_CTOR(FmXListBoxCell,NULL);
4112 
4113     m_pBox->SetDoubleClickHdl( LINK( this, FmXListBoxCell, OnDoubleClick ) );
4114 }
4115 
4116 //------------------------------------------------------------------
4117 FmXListBoxCell::~FmXListBoxCell()
4118 {
4119     if (!OComponentHelper::rBHelper.bDisposed)
4120     {
4121         acquire();
4122         dispose();
4123     }
4124 
4125     DBG_DTOR(FmXListBoxCell,NULL);
4126 }
4127 
4128 // OComponentHelper
4129 //-----------------------------------------------------------------------------
4130 void FmXListBoxCell::disposing()
4131 {
4132     ::com::sun::star::lang::EventObject aEvt(*this);
4133     m_aItemListeners.disposeAndClear(aEvt);
4134     m_aActionListeners.disposeAndClear(aEvt);
4135 
4136     m_pBox->SetSelectHdl( Link() );
4137     m_pBox->SetDoubleClickHdl( Link() );
4138     m_pBox = NULL;
4139 
4140     FmXTextCell::disposing();
4141 }
4142 
4143 //------------------------------------------------------------------
4144 Any SAL_CALL FmXListBoxCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException)
4145 {
4146     Any aReturn = FmXTextCell::queryAggregation(_rType);
4147 
4148     if ( !aReturn.hasValue() )
4149         aReturn = FmXListBoxCell_Base::queryInterface( _rType );
4150 
4151     return aReturn;
4152 }
4153 
4154 //-------------------------------------------------------------------------
4155 Sequence< ::com::sun::star::uno::Type > SAL_CALL FmXListBoxCell::getTypes(  ) throw(RuntimeException)
4156 {
4157     return ::comphelper::concatSequences(
4158         FmXTextCell::getTypes(),
4159         FmXListBoxCell_Base::getTypes()
4160     );
4161 }
4162 
4163 //------------------------------------------------------------------------------
4164 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXListBoxCell )
4165 
4166 //------------------------------------------------------------------
4167 void SAL_CALL FmXListBoxCell::addItemListener(const Reference< ::com::sun::star::awt::XItemListener >& l) throw( RuntimeException )
4168 {
4169     m_aItemListeners.addInterface( l );
4170 }
4171 
4172 //------------------------------------------------------------------
4173 void SAL_CALL FmXListBoxCell::removeItemListener(const Reference< ::com::sun::star::awt::XItemListener >& l) throw( RuntimeException )
4174 {
4175     m_aItemListeners.removeInterface( l );
4176 }
4177 
4178 //------------------------------------------------------------------
4179 void SAL_CALL FmXListBoxCell::addActionListener(const Reference< ::com::sun::star::awt::XActionListener >& l) throw( RuntimeException )
4180 {
4181     m_aActionListeners.addInterface( l );
4182 }
4183 
4184 //------------------------------------------------------------------
4185 void SAL_CALL FmXListBoxCell::removeActionListener(const Reference< ::com::sun::star::awt::XActionListener >& l) throw( RuntimeException )
4186 {
4187     m_aActionListeners.removeInterface( l );
4188 }
4189 
4190 //------------------------------------------------------------------
4191 void SAL_CALL FmXListBoxCell::addItem(const ::rtl::OUString& aItem, sal_Int16 nPos) throw( RuntimeException )
4192 {
4193     ::osl::MutexGuard aGuard( m_aMutex );
4194     if (m_pBox)
4195         m_pBox->InsertEntry( aItem, nPos );
4196 }
4197 
4198 //------------------------------------------------------------------
4199 void SAL_CALL FmXListBoxCell::addItems(const ::comphelper::StringSequence& aItems, sal_Int16 nPos) throw( RuntimeException )
4200 {
4201     ::osl::MutexGuard aGuard( m_aMutex );
4202     if (m_pBox)
4203     {
4204         sal_uInt16 nP = nPos;
4205         for ( sal_uInt16 n = 0; n < aItems.getLength(); n++ )
4206         {
4207             m_pBox->InsertEntry( aItems.getConstArray()[n], nP );
4208             if ( nPos != -1 )    // Nicht wenn 0xFFFF, weil LIST_APPEND
4209                 nP++;
4210         }
4211     }
4212 }
4213 
4214 //------------------------------------------------------------------
4215 void SAL_CALL FmXListBoxCell::removeItems(sal_Int16 nPos, sal_Int16 nCount) throw( RuntimeException )
4216 {
4217     ::osl::MutexGuard aGuard( m_aMutex );
4218     if ( m_pBox )
4219     {
4220         for ( sal_uInt16 n = nCount; n; )
4221             m_pBox->RemoveEntry( nPos + (--n) );
4222     }
4223 }
4224 
4225 //------------------------------------------------------------------
4226 sal_Int16 SAL_CALL FmXListBoxCell::getItemCount() throw( RuntimeException )
4227 {
4228     ::osl::MutexGuard aGuard( m_aMutex );
4229     return m_pBox ? m_pBox->GetEntryCount() : 0;
4230 }
4231 
4232 //------------------------------------------------------------------
4233 ::rtl::OUString SAL_CALL FmXListBoxCell::getItem(sal_Int16 nPos) throw( RuntimeException )
4234 {
4235     ::osl::MutexGuard aGuard( m_aMutex );
4236     String aItem;
4237     if (m_pBox)
4238         aItem = m_pBox->GetEntry( nPos );
4239     return aItem;
4240 }
4241 //------------------------------------------------------------------
4242 ::comphelper::StringSequence SAL_CALL FmXListBoxCell::getItems() throw( RuntimeException )
4243 {
4244     ::osl::MutexGuard aGuard( m_aMutex );
4245 
4246     ::comphelper::StringSequence aSeq;
4247     if (m_pBox)
4248     {
4249         sal_uInt16 nEntries = m_pBox ->GetEntryCount();
4250         aSeq = ::comphelper::StringSequence( nEntries );
4251         for ( sal_uInt16 n = nEntries; n; )
4252         {
4253             --n;
4254             aSeq.getArray()[n] = m_pBox ->GetEntry( n );
4255         }
4256     }
4257     return aSeq;
4258 }
4259 
4260 //------------------------------------------------------------------
4261 sal_Int16 SAL_CALL FmXListBoxCell::getSelectedItemPos() throw( RuntimeException )
4262 {
4263     ::osl::MutexGuard aGuard( m_aMutex );
4264     if (m_pBox)
4265     {
4266         UpdateFromColumn();
4267         return m_pBox->GetSelectEntryPos();
4268     }
4269     return 0;
4270 }
4271 
4272 //------------------------------------------------------------------
4273 Sequence< sal_Int16 > SAL_CALL FmXListBoxCell::getSelectedItemsPos() throw( RuntimeException )
4274 {
4275     ::osl::MutexGuard aGuard( m_aMutex );
4276     Sequence<sal_Int16> aSeq;
4277 
4278     if (m_pBox)
4279     {
4280         UpdateFromColumn();
4281         sal_uInt16 nSelEntries = m_pBox->GetSelectEntryCount();
4282         aSeq = Sequence<sal_Int16>( nSelEntries );
4283         for ( sal_uInt16 n = 0; n < nSelEntries; n++ )
4284             aSeq.getArray()[n] = m_pBox->GetSelectEntryPos( n );
4285     }
4286     return aSeq;
4287 }
4288 //------------------------------------------------------------------
4289 ::rtl::OUString SAL_CALL FmXListBoxCell::getSelectedItem() throw( RuntimeException )
4290 {
4291     ::osl::MutexGuard aGuard( m_aMutex );
4292 
4293     String aItem;
4294     if (m_pBox)
4295     {
4296         UpdateFromColumn();
4297         aItem = m_pBox->GetSelectEntry();
4298     }
4299 
4300     return aItem;
4301 }
4302 
4303 //------------------------------------------------------------------
4304 ::comphelper::StringSequence SAL_CALL FmXListBoxCell::getSelectedItems() throw( RuntimeException )
4305 {
4306     ::osl::MutexGuard aGuard( m_aMutex );
4307 
4308     ::comphelper::StringSequence aSeq;
4309 
4310     if (m_pBox)
4311     {
4312         UpdateFromColumn();
4313         sal_uInt16 nSelEntries = m_pBox->GetSelectEntryCount();
4314         aSeq = ::comphelper::StringSequence( nSelEntries );
4315         for ( sal_uInt16 n = 0; n < nSelEntries; n++ )
4316             aSeq.getArray()[n] = m_pBox->GetSelectEntry( n );
4317     }
4318     return aSeq;
4319 }
4320 
4321 //------------------------------------------------------------------
4322 void SAL_CALL FmXListBoxCell::selectItemPos(sal_Int16 nPos, sal_Bool bSelect) throw( RuntimeException )
4323 {
4324     ::osl::MutexGuard aGuard( m_aMutex );
4325 
4326     if (m_pBox)
4327         m_pBox->SelectEntryPos( nPos, bSelect );
4328 }
4329 
4330 //------------------------------------------------------------------
4331 void SAL_CALL FmXListBoxCell::selectItemsPos(const Sequence< sal_Int16 >& aPositions, sal_Bool bSelect) throw( RuntimeException )
4332 {
4333     ::osl::MutexGuard aGuard( m_aMutex );
4334 
4335     if (m_pBox)
4336     {
4337         for ( sal_uInt16 n = (sal_uInt16)aPositions.getLength(); n; )
4338             m_pBox->SelectEntryPos( (sal_uInt16) aPositions.getConstArray()[--n], bSelect );
4339     }
4340 }
4341 
4342 //------------------------------------------------------------------
4343 void SAL_CALL FmXListBoxCell::selectItem(const ::rtl::OUString& aItem, sal_Bool bSelect) throw( RuntimeException )
4344 {
4345     ::osl::MutexGuard aGuard( m_aMutex );
4346 
4347     if (m_pBox)
4348         m_pBox->SelectEntry( aItem, bSelect );
4349 }
4350 
4351 //------------------------------------------------------------------
4352 sal_Bool SAL_CALL FmXListBoxCell::isMutipleMode() throw( RuntimeException )
4353 {
4354     ::osl::MutexGuard aGuard( m_aMutex );
4355 
4356     sal_Bool bMulti = sal_False;
4357     if (m_pBox)
4358         bMulti = m_pBox->IsMultiSelectionEnabled();
4359     return bMulti;
4360 }
4361 
4362 //------------------------------------------------------------------
4363 void SAL_CALL FmXListBoxCell::setMultipleMode(sal_Bool bMulti) throw( RuntimeException )
4364 {
4365     ::osl::MutexGuard aGuard( m_aMutex );
4366 
4367     if (m_pBox)
4368         m_pBox->EnableMultiSelection( bMulti );
4369 }
4370 
4371 //------------------------------------------------------------------
4372 sal_Int16 SAL_CALL FmXListBoxCell::getDropDownLineCount() throw( RuntimeException )
4373 {
4374     ::osl::MutexGuard aGuard( m_aMutex );
4375 
4376     sal_Int16 nLines = 0;
4377     if (m_pBox)
4378         nLines = m_pBox->GetDropDownLineCount();
4379 
4380     return nLines;
4381 }
4382 
4383 //------------------------------------------------------------------
4384 void SAL_CALL FmXListBoxCell::setDropDownLineCount(sal_Int16 nLines) throw( RuntimeException )
4385 {
4386     ::osl::MutexGuard aGuard( m_aMutex );
4387 
4388     if (m_pBox)
4389         m_pBox->SetDropDownLineCount( nLines );
4390 }
4391 
4392 //------------------------------------------------------------------
4393 void SAL_CALL FmXListBoxCell::makeVisible(sal_Int16 nEntry) throw( RuntimeException )
4394 {
4395     ::osl::MutexGuard aGuard( m_aMutex );
4396 
4397     if (m_pBox)
4398         m_pBox->SetTopEntry( nEntry );
4399 }
4400 
4401 //------------------------------------------------------------------
4402 void FmXListBoxCell::onWindowEvent( const sal_uIntPtr _nEventId, const Window& _rWindow, const void* _pEventData )
4403 {
4404     if  (   ( &_rWindow == m_pBox )
4405         &&  ( _nEventId == VCLEVENT_LISTBOX_SELECT )
4406         )
4407     {
4408         OnDoubleClick( NULL );
4409 
4410         ::com::sun::star::awt::ItemEvent aEvent;
4411         aEvent.Source = *this;
4412         aEvent.Highlighted = sal_False;
4413 
4414         // Bei Mehrfachselektion 0xFFFF, sonst die ID
4415         aEvent.Selected = (m_pBox->GetSelectEntryCount() == 1 )
4416             ? m_pBox->GetSelectEntryPos() : 0xFFFF;
4417 
4418         m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4419         return;
4420     }
4421 
4422     FmXTextCell::onWindowEvent( _nEventId, _rWindow, _pEventData );
4423 }
4424 
4425 
4426 //------------------------------------------------------------------
4427 IMPL_LINK( FmXListBoxCell, OnDoubleClick, void*, EMPTYARG )
4428 {
4429     if (m_pBox)
4430     {
4431         ::cppu::OInterfaceIteratorHelper aIt( m_aActionListeners );
4432 
4433         ::com::sun::star::awt::ActionEvent aEvent;
4434         aEvent.Source = *this;
4435         aEvent.ActionCommand = m_pBox->GetSelectEntry();
4436 
4437         while( aIt.hasMoreElements() )
4438             ((::com::sun::star::awt::XActionListener *)aIt.next())->actionPerformed( aEvent );
4439     }
4440     return 1;
4441 }
4442 
4443 
4444 /*************************************************************************/
4445 
4446 DBG_NAME( FmXComboBoxCell );
4447 
4448 //------------------------------------------------------------------------------
4449 FmXComboBoxCell::FmXComboBoxCell( DbGridColumn* pColumn, DbCellControl& _rControl )
4450     :FmXTextCell( pColumn, _rControl )
4451     ,m_aItemListeners( m_aMutex )
4452     ,m_aActionListeners( m_aMutex )
4453     ,m_pComboBox( &static_cast< ComboBox& >( _rControl.GetWindow() ) )
4454 {
4455     DBG_CTOR( FmXComboBoxCell, NULL );
4456 }
4457 
4458 //------------------------------------------------------------------------------
4459 FmXComboBoxCell::~FmXComboBoxCell()
4460 {
4461     if ( !OComponentHelper::rBHelper.bDisposed )
4462     {
4463         acquire();
4464         dispose();
4465     }
4466 
4467     DBG_DTOR( FmXComboBoxCell, NULL );
4468 }
4469 
4470 //-----------------------------------------------------------------------------
4471 void FmXComboBoxCell::disposing()
4472 {
4473     ::com::sun::star::lang::EventObject aEvt(*this);
4474     m_aItemListeners.disposeAndClear(aEvt);
4475     m_aActionListeners.disposeAndClear(aEvt);
4476 
4477     FmXTextCell::disposing();
4478 }
4479 
4480 //------------------------------------------------------------------
4481 Any SAL_CALL FmXComboBoxCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException)
4482 {
4483     Any aReturn = FmXTextCell::queryAggregation(_rType);
4484 
4485     if ( !aReturn.hasValue() )
4486         aReturn = FmXComboBoxCell_Base::queryInterface( _rType );
4487 
4488     return aReturn;
4489 }
4490 
4491 //-------------------------------------------------------------------------
4492 Sequence< Type > SAL_CALL FmXComboBoxCell::getTypes(  ) throw(RuntimeException)
4493 {
4494     return ::comphelper::concatSequences(
4495         FmXTextCell::getTypes(),
4496         FmXComboBoxCell_Base::getTypes()
4497     );
4498 }
4499 
4500 //------------------------------------------------------------------------------
4501 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXComboBoxCell )
4502 
4503 //------------------------------------------------------------------
4504 void SAL_CALL FmXComboBoxCell::addItemListener(const Reference< awt::XItemListener >& l) throw( RuntimeException )
4505 {
4506     m_aItemListeners.addInterface( l );
4507 }
4508 
4509 //------------------------------------------------------------------
4510 void SAL_CALL FmXComboBoxCell::removeItemListener(const Reference< awt::XItemListener >& l) throw( RuntimeException )
4511 {
4512     m_aItemListeners.removeInterface( l );
4513 }
4514 
4515 //------------------------------------------------------------------
4516 void SAL_CALL FmXComboBoxCell::addActionListener(const Reference< awt::XActionListener >& l) throw( RuntimeException )
4517 {
4518     m_aActionListeners.addInterface( l );
4519 }
4520 
4521 //------------------------------------------------------------------
4522 void SAL_CALL FmXComboBoxCell::removeActionListener(const Reference< awt::XActionListener >& l) throw( RuntimeException )
4523 {
4524     m_aActionListeners.removeInterface( l );
4525 }
4526 
4527 //------------------------------------------------------------------
4528 void SAL_CALL FmXComboBoxCell::addItem( const ::rtl::OUString& _Item, sal_Int16 _Pos ) throw( RuntimeException )
4529 {
4530     ::osl::MutexGuard aGuard( m_aMutex );
4531     if ( m_pComboBox )
4532         m_pComboBox->InsertEntry( _Item, _Pos );
4533 }
4534 
4535 //------------------------------------------------------------------
4536 void SAL_CALL FmXComboBoxCell::addItems( const Sequence< ::rtl::OUString >& _Items, sal_Int16 _Pos ) throw( RuntimeException )
4537 {
4538     ::osl::MutexGuard aGuard( m_aMutex );
4539     if ( m_pComboBox )
4540     {
4541         sal_uInt16 nP = _Pos;
4542         for ( sal_uInt16 n = 0; n < _Items.getLength(); n++ )
4543         {
4544             m_pComboBox->InsertEntry( _Items.getConstArray()[n], nP );
4545             if ( _Pos != -1 )
4546                 nP++;
4547         }
4548     }
4549 }
4550 
4551 //------------------------------------------------------------------
4552 void SAL_CALL FmXComboBoxCell::removeItems( sal_Int16 _Pos, sal_Int16 _Count ) throw( RuntimeException )
4553 {
4554     ::osl::MutexGuard aGuard( m_aMutex );
4555     if ( m_pComboBox )
4556     {
4557         for ( sal_uInt16 n = _Count; n; )
4558             m_pComboBox->RemoveEntry( _Pos + (--n) );
4559     }
4560 }
4561 
4562 //------------------------------------------------------------------
4563 sal_Int16 SAL_CALL FmXComboBoxCell::getItemCount() throw( RuntimeException )
4564 {
4565     ::osl::MutexGuard aGuard( m_aMutex );
4566     return m_pComboBox ? m_pComboBox->GetEntryCount() : 0;
4567 }
4568 
4569 //------------------------------------------------------------------
4570 ::rtl::OUString SAL_CALL FmXComboBoxCell::getItem( sal_Int16 _Pos ) throw( RuntimeException )
4571 {
4572     ::osl::MutexGuard aGuard( m_aMutex );
4573     String sItem;
4574     if ( m_pComboBox )
4575         sItem = m_pComboBox->GetEntry( _Pos );
4576     return sItem;
4577 }
4578 //------------------------------------------------------------------
4579 Sequence< ::rtl::OUString > SAL_CALL FmXComboBoxCell::getItems() throw( RuntimeException )
4580 {
4581     ::osl::MutexGuard aGuard( m_aMutex );
4582 
4583     Sequence< ::rtl::OUString > aItems;
4584     if ( m_pComboBox )
4585     {
4586         sal_uInt16 nEntries = m_pComboBox->GetEntryCount();
4587         aItems.realloc( nEntries );
4588         ::rtl::OUString* pItem = aItems.getArray();
4589         for ( sal_uInt16 n=0; n<nEntries; ++n, ++pItem )
4590             *pItem = m_pComboBox->GetEntry( n );
4591     }
4592     return aItems;
4593 }
4594 
4595 //------------------------------------------------------------------
4596 sal_Int16 SAL_CALL FmXComboBoxCell::getDropDownLineCount() throw( RuntimeException )
4597 {
4598     ::osl::MutexGuard aGuard( m_aMutex );
4599 
4600     sal_Int16 nLines = 0;
4601     if ( m_pComboBox )
4602         nLines = m_pComboBox->GetDropDownLineCount();
4603 
4604     return nLines;
4605 }
4606 
4607 //------------------------------------------------------------------
4608 void SAL_CALL FmXComboBoxCell::setDropDownLineCount(sal_Int16 nLines) throw( RuntimeException )
4609 {
4610     ::osl::MutexGuard aGuard( m_aMutex );
4611     if ( m_pComboBox )
4612         m_pComboBox->SetDropDownLineCount( nLines );
4613 }
4614 
4615 //------------------------------------------------------------------------------
4616 void FmXComboBoxCell::onWindowEvent( const sal_uIntPtr _nEventId, const Window& _rWindow, const void* _pEventData )
4617 {
4618 
4619     switch ( _nEventId )
4620     {
4621     case VCLEVENT_COMBOBOX_SELECT:
4622     {
4623         awt::ItemEvent aEvent;
4624         aEvent.Source = *this;
4625         aEvent.Highlighted = sal_False;
4626 
4627         // Bei Mehrfachselektion 0xFFFF, sonst die ID
4628         aEvent.Selected =   ( m_pComboBox->GetSelectEntryCount() == 1 )
4629                         ?   m_pComboBox->GetSelectEntryPos()
4630                         :   0xFFFF;
4631         m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4632     }
4633     break;
4634 
4635     default:
4636         FmXTextCell::onWindowEvent( _nEventId, _rWindow, _pEventData );
4637         break;
4638     }
4639 }
4640 
4641 /*************************************************************************/
4642 TYPEINIT1(FmXFilterCell, FmXGridCell);
4643 
4644 //------------------------------------------------------------------------------
4645 Reference< XInterface >  FmXFilterCell_CreateInstance(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& /*_rxFactory*/)
4646 {
4647     return *new FmXFilterCell();
4648 }
4649 
4650 DBG_NAME(FmXFilterCell);
4651 //------------------------------------------------------------------------------
4652 FmXFilterCell::FmXFilterCell(DbGridColumn* pColumn, DbCellControl* pControl )
4653               :FmXGridCell( pColumn, pControl )
4654               ,m_aTextListeners(m_aMutex)
4655 {
4656     DBG_CTOR(FmXFilterCell,NULL);
4657 
4658     DBG_ASSERT( m_pCellControl->ISA( DbFilterField ), "FmXFilterCell::FmXFilterCell: invalid cell control!" );
4659     static_cast< DbFilterField* >( m_pCellControl )->SetCommitHdl( LINK( this, FmXFilterCell, OnCommit ) );
4660 }
4661 
4662 //------------------------------------------------------------------
4663 FmXFilterCell::~FmXFilterCell()
4664 {
4665     if (!OComponentHelper::rBHelper.bDisposed)
4666     {
4667         acquire();
4668         dispose();
4669     }
4670 
4671     DBG_DTOR(FmXFilterCell,NULL);
4672 }
4673 
4674 // XUnoTunnel
4675 //------------------------------------------------------------------------------
4676 sal_Int64 SAL_CALL FmXFilterCell::getSomething( const Sequence< sal_Int8 >& _rIdentifier ) throw(RuntimeException)
4677 {
4678     sal_Int64 nReturn(0);
4679 
4680     if  (   (_rIdentifier.getLength() == 16)
4681         &&  (0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), _rIdentifier.getConstArray(), 16 ))
4682         )
4683     {
4684         nReturn = reinterpret_cast<sal_Int64>(this);
4685     }
4686 
4687     return nReturn;
4688 }
4689 
4690 //------------------------------------------------------------------------------
4691 const Sequence<sal_Int8>& FmXFilterCell::getUnoTunnelId()
4692 {
4693     static Sequence< sal_Int8 > * pSeq = 0;
4694     if( !pSeq )
4695     {
4696         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
4697         if( !pSeq )
4698         {
4699             static Sequence< sal_Int8 > aSeq( 16 );
4700             rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
4701             pSeq = &aSeq;
4702         }
4703     }
4704     return *pSeq;
4705 }
4706 
4707 //------------------------------------------------------------------------------
4708 FmXFilterCell* FmXFilterCell::getImplementation(const Reference< ::com::sun::star::awt::XControl >& _rxObject)
4709 {
4710     Reference< ::com::sun::star::lang::XUnoTunnel > xTunnel(
4711         _rxObject, UNO_QUERY);
4712     if (xTunnel.is())
4713         return reinterpret_cast<FmXFilterCell*>(xTunnel->getSomething(getUnoTunnelId()));
4714     return NULL;
4715 }
4716 
4717 //------------------------------------------------------------------------------
4718 void FmXFilterCell::PaintCell( OutputDevice& rDev, const Rectangle& rRect )
4719 {
4720     static_cast< DbFilterField* >( m_pCellControl )->PaintCell( rDev, rRect );
4721 }
4722 
4723 // OComponentHelper
4724 //-----------------------------------------------------------------------------
4725 void FmXFilterCell::disposing()
4726 {
4727     ::com::sun::star::lang::EventObject aEvt(*this);
4728     m_aTextListeners.disposeAndClear(aEvt);
4729 
4730     ((DbFilterField*)m_pCellControl)->SetCommitHdl(Link());
4731 
4732     FmXGridCell::disposing();
4733 }
4734 
4735 //------------------------------------------------------------------
4736 Any SAL_CALL FmXFilterCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException)
4737 {
4738     Any aReturn = FmXGridCell::queryAggregation(_rType);
4739 
4740     if ( !aReturn.hasValue() )
4741         aReturn = FmXFilterCell_Base::queryInterface( _rType );
4742 
4743     return aReturn;
4744 }
4745 
4746 //-------------------------------------------------------------------------
4747 Sequence< ::com::sun::star::uno::Type > SAL_CALL FmXFilterCell::getTypes(  ) throw(RuntimeException)
4748 {
4749     return ::comphelper::concatSequences(
4750         FmXGridCell::getTypes(),
4751         FmXFilterCell_Base::getTypes()
4752     );
4753 }
4754 
4755 //------------------------------------------------------------------------------
4756 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXFilterCell )
4757 
4758 // ::com::sun::star::awt::XTextComponent
4759 //------------------------------------------------------------------------------
4760 void SAL_CALL FmXFilterCell::addTextListener(const Reference< ::com::sun::star::awt::XTextListener >& l) throw( RuntimeException )
4761 {
4762     m_aTextListeners.addInterface( l );
4763 }
4764 
4765 //------------------------------------------------------------------------------
4766 void SAL_CALL FmXFilterCell::removeTextListener(const Reference< ::com::sun::star::awt::XTextListener >& l) throw( RuntimeException )
4767 {
4768     m_aTextListeners.removeInterface( l );
4769 }
4770 
4771 //------------------------------------------------------------------------------
4772 void SAL_CALL FmXFilterCell::setText( const ::rtl::OUString& aText ) throw( RuntimeException )
4773 {
4774     ::osl::MutexGuard aGuard( m_aMutex );
4775     ((DbFilterField*)m_pCellControl)->SetText(aText);
4776 }
4777 
4778 //------------------------------------------------------------------------------
4779 void SAL_CALL FmXFilterCell::insertText( const ::com::sun::star::awt::Selection& /*rSel*/, const ::rtl::OUString& /*aText*/ ) throw( RuntimeException )
4780 {
4781 }
4782 
4783 //------------------------------------------------------------------------------
4784 ::rtl::OUString SAL_CALL FmXFilterCell::getText() throw( RuntimeException )
4785 {
4786     ::osl::MutexGuard aGuard( m_aMutex );
4787     return ((DbFilterField*)m_pCellControl)->GetText();
4788 }
4789 
4790 //------------------------------------------------------------------------------
4791 ::rtl::OUString SAL_CALL FmXFilterCell::getSelectedText( void ) throw( RuntimeException )
4792 {
4793     return getText();
4794 }
4795 
4796 //------------------------------------------------------------------------------
4797 void SAL_CALL FmXFilterCell::setSelection( const ::com::sun::star::awt::Selection& /*aSelection*/ ) throw( RuntimeException )
4798 {
4799 }
4800 
4801 //------------------------------------------------------------------------------
4802 ::com::sun::star::awt::Selection SAL_CALL FmXFilterCell::getSelection( void ) throw( RuntimeException )
4803 {
4804     return ::com::sun::star::awt::Selection();
4805 }
4806 
4807 //------------------------------------------------------------------------------
4808 sal_Bool SAL_CALL FmXFilterCell::isEditable( void ) throw( RuntimeException )
4809 {
4810     return sal_True;
4811 }
4812 
4813 //------------------------------------------------------------------------------
4814 void SAL_CALL FmXFilterCell::setEditable( sal_Bool /*bEditable*/ ) throw( RuntimeException )
4815 {
4816 }
4817 
4818 //------------------------------------------------------------------------------
4819 sal_Int16 SAL_CALL FmXFilterCell::getMaxTextLen() throw( RuntimeException )
4820 {
4821     return 0;
4822 }
4823 
4824 //------------------------------------------------------------------------------
4825 void SAL_CALL FmXFilterCell::setMaxTextLen( sal_Int16 /*nLen*/ ) throw( RuntimeException )
4826 {
4827 }
4828 
4829 //------------------------------------------------------------------------------
4830 IMPL_LINK( FmXFilterCell, OnCommit, void*, EMPTYARG )
4831 {
4832     ::cppu::OInterfaceIteratorHelper aIt( m_aTextListeners );
4833     ::com::sun::star::awt::TextEvent aEvt;
4834     aEvt.Source = *this;
4835     while( aIt.hasMoreElements() )
4836         ((::com::sun::star::awt::XTextListener *)aIt.next())->textChanged( aEvt );
4837     return 1;
4838 }
4839 
4840