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