lok: Don't attempt to select the exact text after a failed search.
[LibreOffice.git] / svx / source / fmcomp / gridcell.cxx
blob52b828926c1682c70ff86d9de96a8a6f1d9cad87
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <sal/macros.h>
22 #include "fmprop.hrc"
23 #include "svx/fmresids.hrc"
24 #include "svx/fmtools.hxx"
25 #include "gridcell.hxx"
26 #include "gridcols.hxx"
27 #include "sdbdatacolumn.hxx"
29 #include <com/sun/star/awt/LineEndFormat.hpp>
30 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
31 #include <com/sun/star/awt/VisualEffect.hpp>
32 #include <com/sun/star/container/XChild.hpp>
33 #include <com/sun/star/container/XNamed.hpp>
34 #include <com/sun/star/form/FormComponentType.hpp>
35 #include <com/sun/star/form/XBoundComponent.hpp>
36 #include <com/sun/star/script/XEventAttacherManager.hpp>
37 #include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
38 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
39 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
40 #include <com/sun/star/sdbc/ColumnValue.hpp>
41 #include <com/sun/star/sdbc/DataType.hpp>
42 #include <com/sun/star/sdbc/XStatement.hpp>
43 #include <com/sun/star/util/NumberFormat.hpp>
44 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
45 #include <com/sun/star/util/Time.hpp>
46 #include <com/sun/star/util/Date.hpp>
48 #include <comphelper/numbers.hxx>
49 #include <comphelper/property.hxx>
50 #include <comphelper/servicehelper.hxx>
51 #include <comphelper/string.hxx>
52 #include <connectivity/formattedcolumnvalue.hxx>
53 #include <cppuhelper/typeprovider.hxx>
54 #include <i18nlangtag/lang.h>
56 #include <rtl/math.hxx>
57 #include <svtools/calendar.hxx>
58 #include <svtools/fmtfield.hxx>
59 #include <svl/numuno.hxx>
60 #include <svtools/svmedit.hxx>
61 #include <svx/dialmgr.hxx>
62 #include <toolkit/helper/vclunohelper.hxx>
63 #include <tools/diagnose_ex.h>
64 #include <vcl/longcurr.hxx>
65 #include <vcl/settings.hxx>
66 #include <connectivity/dbtools.hxx>
67 #include <connectivity/dbconversion.hxx>
68 #include <connectivity/sqlnode.hxx>
70 #include <math.h>
71 #include <stdio.h>
73 using namespace ::connectivity;
74 using namespace ::svxform;
75 using namespace ::comphelper;
76 using namespace ::svt;
77 using namespace ::com::sun::star;
78 using namespace ::com::sun::star::uno;
79 using namespace ::com::sun::star::sdbc;
80 using namespace ::com::sun::star::sdbcx;
81 using namespace ::com::sun::star::sdb;
82 using namespace ::com::sun::star::beans;
83 using namespace ::com::sun::star::form;
84 using namespace ::dbtools::DBTypeConversion;
85 using namespace ::dbtools;
87 using ::com::sun::star::util::XNumberFormatter;
89 const char INVALIDTEXT[] = "###";
90 const char OBJECTTEXT[] = "<OBJECT>";
93 //= helper
95 namespace
97 static LineEnd getModelLineEndSetting( const Reference< XPropertySet >& _rxModel )
99 LineEnd eFormat = LINEEND_LF;
103 sal_Int16 nLineEndFormat = awt::LineEndFormat::LINE_FEED;
105 Reference< XPropertySetInfo > xPSI;
106 if ( _rxModel.is() )
107 xPSI = _rxModel->getPropertySetInfo();
109 OSL_ENSURE( xPSI.is(), "getModelLineEndSetting: invalid column model!" );
110 if ( xPSI.is() && xPSI->hasPropertyByName( FM_PROP_LINEENDFORMAT ) )
112 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_LINEENDFORMAT ) >>= nLineEndFormat );
114 switch ( nLineEndFormat )
116 case awt::LineEndFormat::CARRIAGE_RETURN: eFormat = LINEEND_CR; break;
117 case awt::LineEndFormat::LINE_FEED: eFormat = LINEEND_LF; break;
118 case awt::LineEndFormat::CARRIAGE_RETURN_LINE_FEED: eFormat = LINEEND_CRLF; break;
119 default:
120 OSL_FAIL( "getModelLineEndSetting: what's this?" );
124 catch( const Exception& )
126 OSL_FAIL( "getModelLineEndSetting: caught an exception!" );
127 DBG_UNHANDLED_EXCEPTION();
129 return eFormat;
134 //= DbGridColumn
137 CellControllerRef DbGridColumn::s_xEmptyController;
140 void DbGridColumn::CreateControl(sal_Int32 _nFieldPos, const Reference< ::com::sun::star::beans::XPropertySet >& xField, sal_Int32 nTypeId)
142 Clear();
144 m_nTypeId = (sal_Int16)nTypeId;
145 if (xField != m_xField)
147 // Grundeinstellung
148 m_xField = xField;
149 xField->getPropertyValue(FM_PROP_FORMATKEY) >>= m_nFormatKey;
150 m_nFieldPos = (sal_Int16)_nFieldPos;
151 m_bReadOnly = ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_ISREADONLY));
152 m_bAutoValue = ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_AUTOINCREMENT));
153 m_nFieldType = (sal_Int16)::comphelper::getINT32(xField->getPropertyValue(FM_PROP_FIELDTYPE));
155 switch (m_nFieldType)
157 case DataType::DATE:
158 case DataType::TIME:
159 case DataType::TIMESTAMP:
160 m_bDateTime = true;
161 //fall-through
162 case DataType::BIT:
163 case DataType::BOOLEAN:
164 case DataType::TINYINT:
165 case DataType::SMALLINT:
166 case DataType::INTEGER:
167 case DataType::BIGINT:
168 case DataType::FLOAT:
169 case DataType::REAL:
170 case DataType::DOUBLE:
171 case DataType::NUMERIC:
172 case DataType::DECIMAL:
173 m_nAlign = ::com::sun::star::awt::TextAlign::RIGHT;
174 m_bNumeric = true;
175 break;
176 default:
177 m_nAlign = ::com::sun::star::awt::TextAlign::LEFT;
178 break;
182 DbCellControl* pCellControl = NULL;
183 if (m_rParent.IsFilterMode())
185 pCellControl = new DbFilterField(m_rParent.getContext(),*this);
187 else
190 switch (nTypeId)
192 case TYPE_CHECKBOX: pCellControl = new DbCheckBox(*this); break;
193 case TYPE_COMBOBOX: pCellControl = new DbComboBox(*this); break;
194 case TYPE_CURRENCYFIELD: pCellControl = new DbCurrencyField(*this); break;
195 case TYPE_DATEFIELD: pCellControl = new DbDateField(*this); break;
196 case TYPE_LISTBOX: pCellControl = new DbListBox(*this); break;
197 case TYPE_NUMERICFIELD: pCellControl = new DbNumericField(*this); break;
198 case TYPE_PATTERNFIELD: pCellControl = new DbPatternField( *this, m_rParent.getContext() ); break;
199 case TYPE_TEXTFIELD: pCellControl = new DbTextField(*this); break;
200 case TYPE_TIMEFIELD: pCellControl = new DbTimeField(*this); break;
201 case TYPE_FORMATTEDFIELD: pCellControl = new DbFormattedField(*this); break;
202 default:
203 OSL_FAIL("DbGridColumn::CreateControl: Unknown Column");
204 return;
208 Reference< XRowSet > xCur;
209 if (m_rParent.getDataSource())
210 xCur = Reference< XRowSet > (Reference< XInterface >(*m_rParent.getDataSource()), UNO_QUERY);
211 // TODO : the cursor wrapper should use an XRowSet interface, too
213 pCellControl->Init( m_rParent.GetDataWindow(), xCur );
215 // now create the control wrapper
216 if (m_rParent.IsFilterMode())
217 m_pCell = new FmXFilterCell(this, pCellControl);
218 else
220 switch (nTypeId)
222 case TYPE_CHECKBOX: m_pCell = new FmXCheckBoxCell( this, *pCellControl ); break;
223 case TYPE_LISTBOX: m_pCell = new FmXListBoxCell( this, *pCellControl ); break;
224 case TYPE_COMBOBOX: m_pCell = new FmXComboBoxCell( this, *pCellControl ); break;
225 default:
226 m_pCell = new FmXEditCell( this, *pCellControl );
229 m_pCell->acquire();
230 m_pCell->init();
232 impl_toggleScriptManager_nothrow( true );
234 // only if we use have a bound field, we use a controller for displaying the
235 // window in the grid
236 if (m_xField.is())
237 m_xController = pCellControl->CreateController();
241 void DbGridColumn::impl_toggleScriptManager_nothrow( bool _bAttach )
245 Reference< container::XChild > xChild( m_xModel, UNO_QUERY_THROW );
246 Reference< script::XEventAttacherManager > xManager( xChild->getParent(), UNO_QUERY_THROW );
247 Reference< container::XIndexAccess > xContainer( xChild->getParent(), UNO_QUERY_THROW );
249 sal_Int32 nIndexInParent( getElementPos( xContainer, m_xModel ) );
251 Reference< XInterface > xCellInterface( *m_pCell, UNO_QUERY );
252 if ( _bAttach )
253 xManager->attach( nIndexInParent, xCellInterface, makeAny( xCellInterface ) );
254 else
255 xManager->detach( nIndexInParent, xCellInterface );
257 catch( const Exception& )
259 DBG_UNHANDLED_EXCEPTION();
264 void DbGridColumn::UpdateFromField(const DbGridRow* pRow, const Reference< XNumberFormatter >& xFormatter)
266 if (m_pCell && m_pCell->ISA(FmXFilterCell))
267 PTR_CAST(FmXFilterCell, m_pCell)->Update();
268 else if (pRow && pRow->IsValid() && m_nFieldPos >= 0 && m_pCell && pRow->HasField(m_nFieldPos))
270 PTR_CAST(FmXDataCell, m_pCell)->UpdateFromField( pRow->GetField( m_nFieldPos ).getColumn(), xFormatter );
275 bool DbGridColumn::Commit()
277 bool bResult = true;
278 if (!m_bInSave && m_pCell)
280 m_bInSave = true;
281 bResult = m_pCell->Commit();
283 // store the data into the model
284 FmXDataCell* pDataCell = PTR_CAST(FmXDataCell, m_pCell);
285 if (bResult && pDataCell)
287 Reference< ::com::sun::star::form::XBoundComponent > xComp(m_xModel, UNO_QUERY);
288 if (xComp.is())
289 bResult = xComp->commit();
291 m_bInSave = false;
293 return bResult;
297 DbGridColumn::~DbGridColumn()
299 Clear();
303 void DbGridColumn::setModel(::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > _xModel)
305 if ( m_pCell )
306 impl_toggleScriptManager_nothrow( false );
308 m_xModel = _xModel;
310 if ( m_pCell )
311 impl_toggleScriptManager_nothrow( true );
315 void DbGridColumn::Clear()
317 if ( m_pCell )
319 impl_toggleScriptManager_nothrow( false );
321 m_pCell->dispose();
322 m_pCell->release();
323 m_pCell = NULL;
326 m_xController = NULL;
327 m_xField = NULL;
329 m_nFormatKey = 0;
330 m_nFieldPos = -1;
331 m_bReadOnly = true;
332 m_bAutoValue = false;
333 m_nFieldType = DataType::OTHER;
337 sal_Int16 DbGridColumn::SetAlignment(sal_Int16 _nAlign)
339 if (_nAlign == -1)
340 { // 'Standard'
341 if (m_xField.is())
343 sal_Int32 nType = 0;
344 m_xField->getPropertyValue(FM_PROP_FIELDTYPE) >>= nType;
346 switch (nType)
348 case DataType::NUMERIC:
349 case DataType::DECIMAL:
350 case DataType::DOUBLE:
351 case DataType::REAL:
352 case DataType::BIGINT:
353 case DataType::INTEGER:
354 case DataType::SMALLINT:
355 case DataType::TINYINT:
356 case DataType::DATE:
357 case DataType::TIME:
358 case DataType::TIMESTAMP:
359 _nAlign = ::com::sun::star::awt::TextAlign::RIGHT;
360 break;
361 case DataType::BIT:
362 case DataType::BOOLEAN:
363 _nAlign = ::com::sun::star::awt::TextAlign::CENTER;
364 break;
365 default:
366 _nAlign = ::com::sun::star::awt::TextAlign::LEFT;
367 break;
370 else
371 _nAlign = ::com::sun::star::awt::TextAlign::LEFT;
374 m_nAlign = _nAlign;
375 if (m_pCell && m_pCell->isAlignedController())
376 m_pCell->AlignControl(m_nAlign);
378 return m_nAlign;
382 sal_Int16 DbGridColumn::SetAlignmentFromModel(sal_Int16 nStandardAlign)
384 Any aAlign( m_xModel->getPropertyValue(FM_PROP_ALIGN));
385 if (aAlign.hasValue())
387 sal_Int16 nTest = sal_Int16();
388 if (aAlign >>= nTest)
389 nStandardAlign = nTest;
391 return SetAlignment(nStandardAlign);
395 void DbGridColumn::setLock(bool _bLock)
397 if (m_bLocked == _bLock)
398 return;
399 m_bLocked = _bLock;
401 // is the column we represent active ?
402 if (m_bHidden)
403 return; // no, it isn't (or at least it shouldn't be ...)
405 if (m_rParent.GetCurColumnId() == m_nId)
407 m_rParent.DeactivateCell();
408 m_rParent.ActivateCell(m_rParent.GetCurRow(), m_rParent.GetCurColumnId());
413 OUString DbGridColumn::GetCellText(const DbGridRow* pRow, const Reference< XNumberFormatter >& xFormatter) const
415 OUString aText;
416 if (m_pCell && m_pCell->ISA(FmXFilterCell))
417 return aText;
419 if (!pRow || !pRow->IsValid())
420 aText = INVALIDTEXT;
421 else if (pRow->HasField(m_nFieldPos))
423 aText = GetCellText( pRow->GetField( m_nFieldPos ).getColumn(), xFormatter );
425 return aText;
429 OUString DbGridColumn::GetCellText(const Reference< ::com::sun::star::sdb::XColumn >& xField, const Reference< XNumberFormatter >& xFormatter) const
431 OUString aText;
432 if (xField.is())
434 FmXTextCell* pTextCell = PTR_CAST(FmXTextCell, m_pCell);
435 if (pTextCell)
436 aText = pTextCell->GetText(xField, xFormatter);
437 else if (m_bObject)
438 aText = OBJECTTEXT;
440 return aText;
444 Reference< ::com::sun::star::sdb::XColumn > DbGridColumn::GetCurrentFieldValue() const
446 Reference< ::com::sun::star::sdb::XColumn > xField;
447 const DbGridRowRef xRow = m_rParent.GetCurrentRow();
448 if (xRow.Is() && xRow->HasField(m_nFieldPos))
450 xField = xRow->GetField(m_nFieldPos).getColumn();
452 return xField;
456 void DbGridColumn::Paint(OutputDevice& rDev,
457 const Rectangle& rRect,
458 const DbGridRow* pRow,
459 const Reference< XNumberFormatter >& xFormatter)
461 bool bEnabled = ( rDev.GetOutDevType() != OUTDEV_WINDOW )
462 || ( static_cast< vcl::Window& >( rDev ).IsEnabled() );
464 FmXDataCell* pDataCell = PTR_CAST(FmXDataCell, m_pCell);
465 if (pDataCell)
467 if (!pRow || !pRow->IsValid())
469 DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::Center;
470 if ( !bEnabled )
471 nStyle |= DrawTextFlags::Disable;
473 rDev.DrawText(rRect, OUString(INVALIDTEXT), nStyle);
475 else if (m_bAutoValue && pRow->IsNew())
477 DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::VCenter;
478 if ( !bEnabled )
479 nStyle |= DrawTextFlags::Disable;
481 switch (GetAlignment())
483 case ::com::sun::star::awt::TextAlign::RIGHT:
484 nStyle |= DrawTextFlags::Right;
485 break;
486 case ::com::sun::star::awt::TextAlign::CENTER:
487 nStyle |= DrawTextFlags::Center;
488 break;
489 default:
490 nStyle |= DrawTextFlags::Left;
493 rDev.DrawText(rRect, SVX_RESSTR(RID_STR_AUTOFIELD), nStyle);
495 else if (pRow->HasField(m_nFieldPos))
497 pDataCell->PaintFieldToCell(rDev, rRect, pRow->GetField( m_nFieldPos ).getColumn(), xFormatter);
500 else if (!m_pCell)
502 if (!pRow || !pRow->IsValid())
504 DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::Center;
505 if ( !bEnabled )
506 nStyle |= DrawTextFlags::Disable;
508 rDev.DrawText(rRect, OUString(INVALIDTEXT), nStyle);
510 else if (pRow->HasField(m_nFieldPos) && m_bObject)
512 DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::Center;
513 if ( !bEnabled )
514 nStyle |= DrawTextFlags::Disable;
515 rDev.DrawText(rRect, OUString(OBJECTTEXT), nStyle);
518 else if ( m_pCell->ISA( FmXFilterCell ) )
519 static_cast< FmXFilterCell* >( m_pCell )->PaintCell( rDev, rRect );
523 void DbGridColumn::ImplInitWindow( vcl::Window& rParent, const InitWindowFacet _eInitWhat )
525 if ( m_pCell )
526 m_pCell->ImplInitWindow( rParent, _eInitWhat );
530 //= cell controls
532 TYPEINIT0( DbCellControl )
533 TYPEINIT1( DbLimitedLengthField, DbCellControl )
534 TYPEINIT1( DbTextField, DbLimitedLengthField )
535 TYPEINIT1( DbFormattedField, DbLimitedLengthField )
536 TYPEINIT1( DbCheckBox, DbCellControl )
537 TYPEINIT1( DbComboBox, DbCellControl )
538 TYPEINIT1( DbListBox, DbCellControl )
539 TYPEINIT1( DbPatternField, DbCellControl )
540 TYPEINIT1( DbSpinField, DbCellControl )
541 TYPEINIT1( DbDateField, DbSpinField )
542 TYPEINIT1( DbTimeField, DbSpinField )
543 TYPEINIT1( DbCurrencyField, DbSpinField )
544 TYPEINIT1( DbNumericField, DbSpinField )
545 TYPEINIT1( DbFilterField, DbCellControl )
548 DbCellControl::DbCellControl( DbGridColumn& _rColumn, bool /*_bText*/ )
549 :OPropertyChangeListener(m_aMutex)
550 ,m_pModelChangeBroadcaster(NULL)
551 ,m_pFieldChangeBroadcaster(NULL)
552 ,m_bTransparent( false )
553 ,m_bAlignedController( true )
554 ,m_bAccessingValueProperty( false )
555 ,m_rColumn( _rColumn )
556 ,m_pPainter( NULL )
557 ,m_pWindow( NULL )
559 Reference< XPropertySet > xColModelProps( _rColumn.getModel(), UNO_QUERY );
560 if ( xColModelProps.is() )
562 // if our model's format key changes we want to propagate the new value to our windows
563 m_pModelChangeBroadcaster = new ::comphelper::OPropertyChangeMultiplexer(this, Reference< ::com::sun::star::beans::XPropertySet > (_rColumn.getModel(), UNO_QUERY));
564 m_pModelChangeBroadcaster->acquire();
566 // be listener for some common properties
567 implDoPropertyListening( FM_PROP_READONLY, false );
568 implDoPropertyListening( FM_PROP_ENABLED, false );
570 // add as listener for all know "value" properties
571 implDoPropertyListening( FM_PROP_VALUE, false );
572 implDoPropertyListening( FM_PROP_STATE, false );
573 implDoPropertyListening( FM_PROP_TEXT, false );
574 implDoPropertyListening( FM_PROP_EFFECTIVE_VALUE, false );
576 // be listener at the bound field as well
579 Reference< XPropertySetInfo > xPSI( xColModelProps->getPropertySetInfo(), UNO_SET_THROW );
580 if ( xPSI->hasPropertyByName( FM_PROP_BOUNDFIELD ) )
582 Reference< XPropertySet > xField;
583 xColModelProps->getPropertyValue( FM_PROP_BOUNDFIELD ) >>= xField;
584 if ( xField.is() )
586 m_pFieldChangeBroadcaster = new ::comphelper::OPropertyChangeMultiplexer(this, xField);
587 m_pFieldChangeBroadcaster->acquire();
588 m_pFieldChangeBroadcaster->addProperty( FM_PROP_ISREADONLY );
592 catch( const Exception& )
594 OSL_FAIL( "DbCellControl::doPropertyListening: caught an exception!" );
595 DBG_UNHANDLED_EXCEPTION();
601 void DbCellControl::implDoPropertyListening(const OUString& _rPropertyName, bool _bWarnIfNotExistent)
605 Reference< XPropertySet > xColModelProps( m_rColumn.getModel(), UNO_QUERY );
606 Reference< XPropertySetInfo > xPSI;
607 if ( xColModelProps.is() )
608 xPSI = xColModelProps->getPropertySetInfo();
610 DBG_ASSERT( !_bWarnIfNotExistent || ( xPSI.is() && xPSI->hasPropertyByName( _rPropertyName ) ),
611 "DbCellControl::doPropertyListening: no property set info or non-existent property!" );
612 (void)_bWarnIfNotExistent;
614 if ( xPSI.is() && xPSI->hasPropertyByName( _rPropertyName ) )
615 m_pModelChangeBroadcaster->addProperty( _rPropertyName );
617 catch( const Exception& )
619 OSL_FAIL( "DbCellControl::doPropertyListening: caught an exception!" );
620 DBG_UNHANDLED_EXCEPTION();
625 void DbCellControl::doPropertyListening(const OUString& _rPropertyName)
627 implDoPropertyListening( _rPropertyName );
630 static void lcl_clearBroadCaster(::comphelper::OPropertyChangeMultiplexer*& _pBroadcaster)
632 if ( _pBroadcaster )
634 _pBroadcaster->dispose();
635 _pBroadcaster->release();
636 _pBroadcaster = NULL;
637 // no delete, this is done implicitly
641 DbCellControl::~DbCellControl()
643 lcl_clearBroadCaster(m_pModelChangeBroadcaster);
644 lcl_clearBroadCaster(m_pFieldChangeBroadcaster);
646 m_pWindow.disposeAndClear();
647 m_pPainter.disposeAndClear();
650 void DbCellControl::implValuePropertyChanged( )
652 OSL_ENSURE( !isValuePropertyLocked(),
653 "DbCellControl::implValuePropertyChanged: not to be called with the value property locked!" );
655 if ( m_pWindow )
657 if ( m_rColumn.getModel().is() )
658 updateFromModel( m_rColumn.getModel() );
663 void DbCellControl::implAdjustGenericFieldSetting( const Reference< XPropertySet >& /*_rxModel*/ )
665 // nothing to do here
669 void DbCellControl::_propertyChanged(const PropertyChangeEvent& _rEvent) throw(RuntimeException)
671 SolarMutexGuard aGuard;
673 Reference< XPropertySet > xSourceProps( _rEvent.Source, UNO_QUERY );
675 if ( _rEvent.PropertyName == FM_PROP_VALUE
676 || _rEvent.PropertyName == FM_PROP_STATE
677 || _rEvent.PropertyName == FM_PROP_TEXT
678 || _rEvent.PropertyName == FM_PROP_EFFECTIVE_VALUE
680 { // it was one of the known "value" properties
681 if ( !isValuePropertyLocked() )
683 implValuePropertyChanged( );
686 else if ( _rEvent.PropertyName == FM_PROP_READONLY )
688 implAdjustReadOnly( xSourceProps, true);
690 else if ( _rEvent.PropertyName == FM_PROP_ISREADONLY )
692 bool bReadOnly = true;
693 _rEvent.NewValue >>= bReadOnly;
694 m_rColumn.SetReadOnly(bReadOnly);
695 implAdjustReadOnly( xSourceProps, false);
697 else if ( _rEvent.PropertyName == FM_PROP_ENABLED )
699 implAdjustEnabled( xSourceProps );
701 else
702 implAdjustGenericFieldSetting( xSourceProps );
706 bool DbCellControl::Commit()
708 // lock the listening for value property changes
709 lockValueProperty();
710 // commit the content of the control into the model's value property
711 bool bReturn = false;
714 bReturn = commitControl();
716 catch( const Exception& )
718 DBG_UNHANDLED_EXCEPTION();
720 // unlock the listening for value property changes
721 unlockValueProperty();
722 // outta here
723 return bReturn;
727 void DbCellControl::ImplInitWindow( vcl::Window& rParent, const InitWindowFacet _eInitWhat )
729 vcl::Window* pWindows[] = { m_pPainter, m_pWindow };
731 if ((_eInitWhat & InitWritingMode) != 0)
733 for (size_t i = 0; i < sizeof(pWindows) / sizeof(pWindows[0]); ++i)
735 if (pWindows[i])
736 pWindows[i]->EnableRTL(rParent.IsRTLEnabled());
740 if ((_eInitWhat & InitFontFacet) != 0)
742 for (size_t i = 0; i < sizeof(pWindows) / sizeof(pWindows[0]); ++i)
744 if (!pWindows[i])
745 continue;
747 pWindows[i]->SetZoom(rParent.GetZoom());
749 const StyleSettings& rStyleSettings = pWindows[i]->GetSettings().GetStyleSettings();
750 vcl::Font aFont = rStyleSettings.GetFieldFont();
751 aFont.SetTransparent(isTransparent());
753 if (rParent.IsControlFont())
755 pWindows[i]->SetControlFont(rParent.GetControlFont());
756 aFont.Merge(rParent.GetControlFont());
758 else
759 pWindows[i]->SetControlFont();
761 pWindows[i]->SetZoomedPointFont(*pWindows[i], aFont); // FIXME RenderContext
765 if (((_eInitWhat & InitFontFacet) != 0) || ((_eInitWhat & InitForeground) != 0))
767 Color aTextColor(rParent.IsControlForeground() ? rParent.GetControlForeground() : rParent.GetTextColor());
769 bool bTextLineColor = rParent.IsTextLineColor();
770 Color aTextLineColor(rParent.GetTextLineColor());
772 for (size_t i=0; i < sizeof(pWindows) / sizeof(pWindows[0]); ++i)
774 if (pWindows[i])
776 pWindows[i]->SetTextColor(aTextColor);
777 if (rParent.IsControlForeground())
778 pWindows[i]->SetControlForeground(aTextColor);
780 if (bTextLineColor)
781 pWindows[i]->SetTextLineColor();
782 else
783 pWindows[i]->SetTextLineColor(aTextLineColor);
788 if ((_eInitWhat & InitBackground) != 0)
790 if (rParent.IsControlBackground())
792 Color aColor(rParent.GetControlBackground());
793 for (size_t i=0; i < sizeof(pWindows) / sizeof(pWindows[0]); ++i)
795 if (pWindows[i])
797 if (isTransparent())
798 pWindows[i]->SetBackground();
799 else
801 pWindows[i]->SetBackground(aColor);
802 pWindows[i]->SetControlBackground(aColor);
804 pWindows[i]->SetFillColor(aColor);
808 else
810 if (m_pPainter)
812 if (isTransparent())
813 m_pPainter->SetBackground();
814 else
815 m_pPainter->SetBackground(rParent.GetBackground());
816 m_pPainter->SetFillColor(rParent.GetFillColor());
819 if (m_pWindow)
821 if (isTransparent())
822 m_pWindow->SetBackground(rParent.GetBackground());
823 else
824 m_pWindow->SetFillColor(rParent.GetFillColor());
831 void DbCellControl::implAdjustReadOnly( const Reference< XPropertySet >& _rxModel,bool i_bReadOnly )
833 DBG_ASSERT( m_pWindow, "DbCellControl::implAdjustReadOnly: not to be called without window!" );
834 DBG_ASSERT( _rxModel.is(), "DbCellControl::implAdjustReadOnly: invalid model!" );
835 if ( m_pWindow && _rxModel.is() )
837 Edit* pEditWindow = dynamic_cast< Edit* >( m_pWindow.get() );
838 if ( pEditWindow )
840 bool bReadOnly = m_rColumn.IsReadOnly();
841 if ( !bReadOnly )
843 _rxModel->getPropertyValue( i_bReadOnly ? OUString(FM_PROP_READONLY) : OUString(FM_PROP_ISREADONLY)) >>= bReadOnly;
845 static_cast< Edit* >( m_pWindow.get() )->SetReadOnly( bReadOnly );
851 void DbCellControl::implAdjustEnabled( const Reference< XPropertySet >& _rxModel )
853 DBG_ASSERT( m_pWindow, "DbCellControl::implAdjustEnabled: not to be called without window!" );
854 DBG_ASSERT( _rxModel.is(), "DbCellControl::implAdjustEnabled: invalid model!" );
855 if ( m_pWindow && _rxModel.is() )
857 bool bEnable = true;
858 _rxModel->getPropertyValue( FM_PROP_ENABLED ) >>= bEnable;
859 m_pWindow->Enable( bEnable );
864 void DbCellControl::Init( vcl::Window& rParent, const Reference< XRowSet >& _rxCursor )
866 ImplInitWindow( rParent, InitAll );
868 if ( m_pWindow )
870 // align the control
871 if ( isAlignedController() )
872 AlignControl( m_rColumn.GetAlignment() );
876 // some other common properties
877 Reference< XPropertySet > xModel( m_rColumn.getModel(), UNO_SET_THROW );
878 Reference< XPropertySetInfo > xModelPSI( xModel->getPropertySetInfo(), UNO_SET_THROW );
880 if ( xModelPSI->hasPropertyByName( FM_PROP_READONLY ) )
882 implAdjustReadOnly( xModel,true );
885 if ( xModelPSI->hasPropertyByName( FM_PROP_ENABLED ) )
887 implAdjustEnabled( xModel );
890 if ( xModelPSI->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) )
892 sal_Int16 nWheelBehavior = css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY;
893 OSL_VERIFY( xModel->getPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) >>= nWheelBehavior );
894 MouseWheelBehaviour nVclSetting = MouseWheelBehaviour::FocusOnly;
895 switch ( nWheelBehavior )
897 case css::awt::MouseWheelBehavior::SCROLL_DISABLED: nVclSetting = MouseWheelBehaviour::Disable; break;
898 case css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY: nVclSetting = MouseWheelBehaviour::FocusOnly; break;
899 case css::awt::MouseWheelBehavior::SCROLL_ALWAYS: nVclSetting = MouseWheelBehaviour::ALWAYS; break;
900 default:
901 OSL_FAIL( "DbCellControl::Init: invalid MouseWheelBehavior!" );
902 break;
905 AllSettings aSettings = m_pWindow->GetSettings();
906 MouseSettings aMouseSettings = aSettings.GetMouseSettings();
907 aMouseSettings.SetWheelBehavior( nVclSetting );
908 aSettings.SetMouseSettings( aMouseSettings );
909 m_pWindow->SetSettings( aSettings, true );
912 catch( const Exception& )
914 DBG_UNHANDLED_EXCEPTION();
917 m_xCursor = _rxCursor;
918 if ( m_rColumn.getModel().is() )
919 updateFromModel( m_rColumn.getModel() );
923 void DbCellControl::SetTextLineColor()
925 if (m_pWindow)
926 m_pWindow->SetTextLineColor();
927 if (m_pPainter)
928 m_pPainter->SetTextLineColor();
932 void DbCellControl::SetTextLineColor(const Color& _rColor)
934 if (m_pWindow)
935 m_pWindow->SetTextLineColor(_rColor);
936 if (m_pPainter)
937 m_pPainter->SetTextLineColor(_rColor);
940 namespace
942 static void lcl_implAlign( vcl::Window* _pWindow, WinBits _nAlignmentBit )
944 WinBits nStyle = _pWindow->GetStyle();
945 nStyle &= ~(WB_LEFT | WB_RIGHT | WB_CENTER);
946 _pWindow->SetStyle( nStyle | _nAlignmentBit );
951 void DbCellControl::AlignControl(sal_Int16 nAlignment)
953 WinBits nAlignmentBit = 0;
954 switch (nAlignment)
956 case ::com::sun::star::awt::TextAlign::RIGHT:
957 nAlignmentBit = WB_RIGHT;
958 break;
959 case ::com::sun::star::awt::TextAlign::CENTER:
960 nAlignmentBit = WB_CENTER;
961 break;
962 default:
963 nAlignmentBit = WB_LEFT;
964 break;
966 lcl_implAlign( m_pWindow, nAlignmentBit );
967 if ( m_pPainter )
968 lcl_implAlign( m_pPainter, nAlignmentBit );
972 void DbCellControl::PaintCell( OutputDevice& _rDev, const Rectangle& _rRect )
974 if ( m_pPainter->GetParent() == &_rDev )
976 m_pPainter->SetPaintTransparent( true );
977 m_pPainter->SetBackground( );
978 m_pPainter->SetControlBackground( _rDev.GetFillColor() );
979 m_pPainter->SetControlForeground( _rDev.GetTextColor() );
980 m_pPainter->SetTextColor( _rDev.GetTextColor() );
981 m_pPainter->SetTextFillColor( _rDev.GetTextColor() );
983 vcl::Font aFont( _rDev.GetFont() );
984 aFont.SetTransparent( true );
985 m_pPainter->SetFont( aFont );
987 m_pPainter->SetPosSizePixel( _rRect.TopLeft(), _rRect.GetSize() );
988 m_pPainter->Show();
989 m_pPainter->Update();
990 m_pPainter->SetParentUpdateMode( false );
991 m_pPainter->Hide();
992 m_pPainter->SetParentUpdateMode( true );
994 else
995 m_pPainter->Draw( &_rDev, _rRect.TopLeft(), _rRect.GetSize(), 0 );
999 void DbCellControl::PaintFieldToCell( OutputDevice& _rDev, const Rectangle& _rRect, const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1001 m_pPainter->SetText( GetFormatText( _rxField, _rxFormatter ) );
1002 PaintCell( _rDev, _rRect );
1006 double DbCellControl::GetValue(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter) const
1008 double fValue = 0;
1009 if (m_rColumn.IsNumeric())
1013 fValue = _rxField->getDouble();
1015 catch(const Exception&) { }
1017 else
1019 bool bSuccess = false;
1022 fValue = _rxField->getDouble();
1023 bSuccess = true;
1025 catch(const Exception&) { }
1026 if (!bSuccess)
1030 fValue = xFormatter->convertStringToNumber(m_rColumn.GetKey(), _rxField->getString());
1032 catch(const Exception&) { }
1035 return fValue;
1039 void DbCellControl::invalidatedController()
1041 m_rColumn.GetParent().refreshController(m_rColumn.GetId(), DbGridControl::GrantControlAccess());
1044 // CellModels
1046 DbLimitedLengthField::DbLimitedLengthField( DbGridColumn& _rColumn )
1047 :DbCellControl( _rColumn )
1049 doPropertyListening( FM_PROP_MAXTEXTLEN );
1053 void DbLimitedLengthField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1055 DBG_ASSERT( m_pWindow, "DbLimitedLengthField::implAdjustGenericFieldSetting: not to be called without window!" );
1056 DBG_ASSERT( _rxModel.is(), "DbLimitedLengthField::implAdjustGenericFieldSetting: invalid model!" );
1057 if ( m_pWindow && _rxModel.is() )
1059 sal_Int16 nMaxLen = 0;
1060 _rxModel->getPropertyValue( FM_PROP_MAXTEXTLEN ) >>= nMaxLen;
1061 implSetMaxTextLen( nMaxLen );
1065 void DbLimitedLengthField::implSetEffectiveMaxTextLen( sal_Int32 _nMaxLen )
1067 dynamic_cast<Edit&>(*m_pWindow).SetMaxTextLen(_nMaxLen);
1068 if (m_pPainter)
1069 dynamic_cast<Edit&>(*m_pPainter).SetMaxTextLen(_nMaxLen);
1072 DbTextField::DbTextField(DbGridColumn& _rColumn)
1073 :DbLimitedLengthField(_rColumn)
1074 ,m_pEdit( NULL )
1075 ,m_pPainterImplementation( NULL )
1076 ,m_bIsSimpleEdit( true )
1081 DbTextField::~DbTextField( )
1083 DELETEZ( m_pPainterImplementation );
1084 DELETEZ( m_pEdit );
1088 void DbTextField::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor)
1090 sal_Int16 nAlignment = m_rColumn.SetAlignmentFromModel(-1);
1092 Reference< XPropertySet > xModel( m_rColumn.getModel() );
1094 WinBits nStyle = WB_LEFT;
1095 switch (nAlignment)
1097 case awt::TextAlign::RIGHT:
1098 nStyle = WB_RIGHT;
1099 break;
1101 case awt::TextAlign::CENTER:
1102 nStyle = WB_CENTER;
1103 break;
1106 // is this a multi-line field?
1107 bool bIsMultiLine = false;
1110 if ( xModel.is() )
1112 OSL_VERIFY( xModel->getPropertyValue( FM_PROP_MULTILINE ) >>= bIsMultiLine );
1115 catch( const Exception& )
1117 OSL_FAIL( "DbTextField::Init: caught an exception while determining the multi-line capabilities!" );
1118 DBG_UNHANDLED_EXCEPTION();
1121 m_bIsSimpleEdit = !bIsMultiLine;
1122 if ( bIsMultiLine )
1124 m_pWindow = VclPtr<MultiLineTextCell>::Create( &rParent, nStyle );
1125 m_pEdit = new MultiLineEditImplementation( *static_cast< MultiLineTextCell* >( m_pWindow.get() ) );
1127 m_pPainter = VclPtr<MultiLineTextCell>::Create( &rParent, nStyle );
1128 m_pPainterImplementation = new MultiLineEditImplementation( *static_cast< MultiLineTextCell* >( m_pPainter.get() ) );
1130 else
1132 m_pWindow = VclPtr<Edit>::Create( &rParent, nStyle );
1133 m_pEdit = new EditImplementation( *static_cast< Edit* >( m_pWindow.get() ) );
1135 m_pPainter = VclPtr<Edit>::Create( &rParent, nStyle );
1136 m_pPainterImplementation = new EditImplementation( *static_cast< Edit* >( m_pPainter.get() ) );
1139 if ( WB_LEFT == nStyle )
1141 // this is so that when getting the focus, the selection is oriented left-to-right
1142 AllSettings aSettings = m_pWindow->GetSettings();
1143 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1144 aStyleSettings.SetSelectionOptions(
1145 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
1146 aSettings.SetStyleSettings(aStyleSettings);
1147 m_pWindow->SetSettings(aSettings);
1150 implAdjustGenericFieldSetting( xModel );
1152 DbLimitedLengthField::Init( rParent, xCursor );
1156 CellControllerRef DbTextField::CreateController() const
1158 return new EditCellController( m_pEdit );
1162 void DbTextField::PaintFieldToCell( OutputDevice& _rDev, const Rectangle& _rRect, const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1164 if ( m_pPainterImplementation )
1165 m_pPainterImplementation->SetText( GetFormatText( _rxField, _rxFormatter, NULL ) );
1167 DbLimitedLengthField::PaintFieldToCell( _rDev, _rRect, _rxField, _rxFormatter );
1171 OUString DbTextField::GetFormatText(const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter, Color** /*ppColor*/)
1173 const com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> xPS(_rxField, UNO_QUERY);
1174 FormattedColumnValue fmter( xFormatter, xPS );
1176 return fmter.getFormattedValue();
1180 void DbTextField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
1182 m_pEdit->SetText( GetFormatText( _rxField, xFormatter ) );
1183 m_pEdit->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1187 void DbTextField::updateFromModel( Reference< XPropertySet > _rxModel )
1189 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbTextField::updateFromModel: invalid call!" );
1191 OUString sText;
1192 _rxModel->getPropertyValue( FM_PROP_TEXT ) >>= sText;
1194 sal_Int32 nMaxTextLen = m_pEdit->GetMaxTextLen();
1195 if ( EDIT_NOLIMIT != nMaxTextLen && sText.getLength() > nMaxTextLen )
1197 sal_Int32 nDiff = sText.getLength() - nMaxTextLen;
1198 sText = sText.replaceAt(sText.getLength() - nDiff,nDiff, OUString());
1202 m_pEdit->SetText( sText );
1203 m_pEdit->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1207 bool DbTextField::commitControl()
1209 OUString aText( m_pEdit->GetText( getModelLineEndSetting( m_rColumn.getModel() ) ) );
1210 // we have to check if the length before we can decide if the value was modified
1211 sal_Int32 nMaxTextLen = m_pEdit->GetMaxTextLen();
1212 if ( EDIT_NOLIMIT != nMaxTextLen )
1214 OUString sOldValue;
1215 m_rColumn.getModel()->getPropertyValue( FM_PROP_TEXT ) >>= sOldValue;
1216 // if the new value didn't change we must set the old long value again
1217 if ( sOldValue.getLength() > nMaxTextLen && sOldValue.compareTo(aText,nMaxTextLen) == 0 )
1218 aText = sOldValue;
1220 m_rColumn.getModel()->setPropertyValue( FM_PROP_TEXT, makeAny( aText ) );
1221 return true;
1225 void DbTextField::implSetEffectiveMaxTextLen( sal_Int32 _nMaxLen )
1227 if ( m_pEdit )
1228 m_pEdit->SetMaxTextLen( _nMaxLen );
1229 if ( m_pPainterImplementation )
1230 m_pPainterImplementation->SetMaxTextLen( _nMaxLen );
1233 DbFormattedField::DbFormattedField(DbGridColumn& _rColumn)
1234 :DbLimitedLengthField(_rColumn)
1235 ,m_nKeyType(::com::sun::star::util::NumberFormat::UNDEFINED)
1238 // if our model's format key changes we want to propagate the new value to our windows
1239 doPropertyListening( FM_PROP_FORMATKEY );
1243 DbFormattedField::~DbFormattedField()
1248 void DbFormattedField::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor)
1250 sal_Int16 nAlignment = m_rColumn.SetAlignmentFromModel(-1);
1252 Reference< ::com::sun::star::beans::XPropertySet > xUnoModel = m_rColumn.getModel();
1254 switch (nAlignment)
1256 case ::com::sun::star::awt::TextAlign::RIGHT:
1257 m_pWindow = VclPtr<FormattedField>::Create( &rParent, WB_RIGHT );
1258 m_pPainter = VclPtr<FormattedField>::Create( &rParent, WB_RIGHT );
1259 break;
1261 case ::com::sun::star::awt::TextAlign::CENTER:
1262 m_pWindow = VclPtr<FormattedField>::Create( &rParent, WB_CENTER );
1263 m_pPainter = VclPtr<FormattedField>::Create( &rParent, WB_CENTER );
1264 break;
1265 default:
1266 m_pWindow = VclPtr<FormattedField>::Create( &rParent, WB_LEFT );
1267 m_pPainter = VclPtr<FormattedField>::Create( &rParent, WB_LEFT );
1269 // Alles nur damit die Selektion bei Focuserhalt von rechts nach links geht
1270 AllSettings aSettings = m_pWindow->GetSettings();
1271 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1272 aStyleSettings.SetSelectionOptions(
1273 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
1274 aSettings.SetStyleSettings(aStyleSettings);
1275 m_pWindow->SetSettings(aSettings);
1278 implAdjustGenericFieldSetting( xUnoModel );
1280 static_cast< FormattedField* >( m_pWindow.get() )->SetStrictFormat( false );
1281 static_cast< FormattedField* >( m_pPainter.get() )->SetStrictFormat( false );
1282 // wenn man _irgendeine_ Formatierung zulaesst, kann man da sowieso keine Eingabe-Ueberpruefung
1283 // machen (das FormattedField unterstuetzt das sowieso nicht, nur abgeleitete Klassen)
1285 // von dem Uno-Model den Formatter besorgen
1286 // (Ich koennte theoretisch auch ueber den ::com::sun::star::util::NumberFormatter gehen, den mir der Cursor bestimmt
1287 // liefern wuerde. Das Problem dabei ist, dass ich mich eigentlich nicht darauf verlassen
1288 // kann, dass die beiden Formatter die selben sind, sauber ist das Ganze, wenn ich ueber das
1289 // UNO-Model gehe.)
1290 sal_Int32 nFormatKey = -1;
1292 // mal sehen, ob das Model einen hat ...
1293 DBG_ASSERT(::comphelper::hasProperty(FM_PROP_FORMATSSUPPLIER, xUnoModel), "DbFormattedField::Init : invalid UNO model !");
1294 Any aSupplier( xUnoModel->getPropertyValue(FM_PROP_FORMATSSUPPLIER));
1295 if (aSupplier.hasValue())
1297 m_xSupplier.set(aSupplier, css::uno::UNO_QUERY);
1298 if (m_xSupplier.is())
1300 // wenn wir den Supplier vom Model nehmen, dann auch den Key
1301 Any aFmtKey( xUnoModel->getPropertyValue(FM_PROP_FORMATKEY));
1302 if (aFmtKey.hasValue())
1304 DBG_ASSERT(aFmtKey.getValueType().getTypeClass() == TypeClass_LONG, "DbFormattedField::Init : invalid format key property (no sal_Int32) !");
1305 nFormatKey = ::comphelper::getINT32(aFmtKey);
1307 else
1309 DBG_WARNING("DbFormattedField::Init : my uno-model has no format-key, but a formats supplier !");
1310 // the OFormattedModel which we usually are working with ensures that the model has a format key
1311 // as soon as the form is loaded. Unfortunally this method here is called from within loaded, too.
1312 // So if our LoadListener is called before the LoadListener of the model, this "else case" is
1313 // allowed.
1314 // Of course our property listener for the FormatKey property will notify us if the prop is changed,
1315 // so this here isn't really bad ....
1316 nFormatKey = 0;
1321 // nein ? vielleicht die ::com::sun::star::form::component::Form hinter dem Cursor ?
1322 if (!m_xSupplier.is())
1324 Reference< XRowSet > xCursorForm(xCursor, UNO_QUERY);
1325 if (xCursorForm.is())
1326 { // wenn wir vom Cursor den Formatter nehmen, dann auch den Key vom Feld, an das wir gebunden sind
1327 m_xSupplier = getNumberFormats(getConnection(xCursorForm), false);
1329 if (m_rColumn.GetField().is())
1330 nFormatKey = ::comphelper::getINT32(m_rColumn.GetField()->getPropertyValue(FM_PROP_FORMATKEY));
1334 SvNumberFormatter* pFormatterUsed = NULL;
1335 if (m_xSupplier.is())
1337 SvNumberFormatsSupplierObj* pImplmentation = SvNumberFormatsSupplierObj::getImplementation(m_xSupplier);
1338 if (pImplmentation)
1339 pFormatterUsed = pImplmentation->GetNumberFormatter();
1340 else
1341 // alles hingfaellig : der Supplier ist vom falschen Typ, dann koennen wir uns auch nicht darauf verlassen, dass
1342 // ein Standard-Formatter den (eventuell nicht-Standard-)Key kennt.
1343 nFormatKey = -1;
1346 // einen Standard-Formatter ...
1347 if (pFormatterUsed == NULL)
1349 pFormatterUsed = static_cast<FormattedField*>(m_pWindow.get())->StandardFormatter();
1350 DBG_ASSERT(pFormatterUsed != NULL, "DbFormattedField::Init : no standard formatter given by the numeric field !");
1352 // ... und einen Standard-Key
1353 if (nFormatKey == -1)
1354 nFormatKey = 0;
1356 m_nKeyType = comphelper::getNumberFormatType(m_xSupplier->getNumberFormats(), nFormatKey);
1358 static_cast<FormattedField*>(m_pWindow.get())->SetFormatter(pFormatterUsed);
1359 static_cast<FormattedField*>(m_pPainter.get())->SetFormatter(pFormatterUsed);
1361 static_cast<FormattedField*>(m_pWindow.get())->SetFormatKey(nFormatKey);
1362 static_cast<FormattedField*>(m_pPainter.get())->SetFormatKey(nFormatKey);
1364 static_cast<FormattedField*>(m_pWindow.get())->TreatAsNumber(m_rColumn.IsNumeric());
1365 static_cast<FormattedField*>(m_pPainter.get())->TreatAsNumber(m_rColumn.IsNumeric());
1367 // Min- und Max-Werte
1368 if (m_rColumn.IsNumeric())
1370 bool bClearMin = true;
1371 if (::comphelper::hasProperty(FM_PROP_EFFECTIVE_MIN, xUnoModel))
1373 Any aMin( xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_MIN));
1374 if (aMin.getValueType().getTypeClass() != TypeClass_VOID)
1376 DBG_ASSERT(aMin.getValueType().getTypeClass() == TypeClass_DOUBLE, "DbFormattedField::Init : the model has an invalid min value !");
1377 double dMin = ::comphelper::getDouble(aMin);
1378 static_cast<FormattedField*>(m_pWindow.get())->SetMinValue(dMin);
1379 static_cast<FormattedField*>(m_pPainter.get())->SetMinValue(dMin);
1380 bClearMin = false;
1383 if (bClearMin)
1385 static_cast<FormattedField*>(m_pWindow.get())->ClearMinValue();
1386 static_cast<FormattedField*>(m_pPainter.get())->ClearMinValue();
1388 bool bClearMax = true;
1389 if (::comphelper::hasProperty(FM_PROP_EFFECTIVE_MAX, xUnoModel))
1391 Any aMin( xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_MAX));
1392 if (aMin.getValueType().getTypeClass() != TypeClass_VOID)
1394 DBG_ASSERT(aMin.getValueType().getTypeClass() == TypeClass_DOUBLE, "DbFormattedField::Init : the model has an invalid max value !");
1395 double dMin = ::comphelper::getDouble(aMin);
1396 static_cast<FormattedField*>(m_pWindow.get())->SetMaxValue(dMin);
1397 static_cast<FormattedField*>(m_pPainter.get())->SetMaxValue(dMin);
1398 bClearMax = false;
1401 if (bClearMax)
1403 static_cast<FormattedField*>(m_pWindow.get())->ClearMaxValue();
1404 static_cast<FormattedField*>(m_pPainter.get())->ClearMaxValue();
1408 // den Default-Wert
1409 Any aDefault( xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_DEFAULT));
1410 if (aDefault.hasValue())
1411 { // das Ding kann ein double oder ein String sein
1412 switch (aDefault.getValueType().getTypeClass())
1414 case TypeClass_DOUBLE:
1415 if (m_rColumn.IsNumeric())
1417 static_cast<FormattedField*>(m_pWindow.get())->SetDefaultValue(::comphelper::getDouble(aDefault));
1418 static_cast<FormattedField*>(m_pPainter.get())->SetDefaultValue(::comphelper::getDouble(aDefault));
1420 else
1422 OUString sConverted;
1423 Color* pDummy;
1424 pFormatterUsed->GetOutputString(::comphelper::getDouble(aDefault), 0, sConverted, &pDummy);
1425 static_cast<FormattedField*>(m_pWindow.get())->SetDefaultText(sConverted);
1426 static_cast<FormattedField*>(m_pPainter.get())->SetDefaultText(sConverted);
1428 break;
1429 case TypeClass_STRING:
1431 OUString sDefault( ::comphelper::getString(aDefault) );
1432 if (m_rColumn.IsNumeric())
1434 double dVal;
1435 sal_uInt32 nTestFormat(0);
1436 if (pFormatterUsed->IsNumberFormat(sDefault, nTestFormat, dVal))
1438 static_cast<FormattedField*>(m_pWindow.get())->SetDefaultValue(dVal);
1439 static_cast<FormattedField*>(m_pPainter.get())->SetDefaultValue(dVal);
1442 else
1444 static_cast<FormattedField*>(m_pWindow.get())->SetDefaultText(sDefault);
1445 static_cast<FormattedField*>(m_pPainter.get())->SetDefaultText(sDefault);
1448 break;
1449 default:
1450 OSL_FAIL( "DbFormattedField::Init: unexpected value type!" );
1451 break;
1454 DbLimitedLengthField::Init( rParent, xCursor );
1458 CellControllerRef DbFormattedField::CreateController() const
1460 return new ::svt::FormattedFieldCellController( static_cast< FormattedField* >( m_pWindow.get() ) );
1464 void DbFormattedField::_propertyChanged( const PropertyChangeEvent& _rEvent ) throw( RuntimeException )
1466 if (_rEvent.PropertyName == FM_PROP_FORMATKEY )
1468 sal_Int32 nNewKey = _rEvent.NewValue.hasValue() ? ::comphelper::getINT32(_rEvent.NewValue) : 0;
1469 m_nKeyType = comphelper::getNumberFormatType(m_xSupplier->getNumberFormats(), nNewKey);
1471 DBG_ASSERT(m_pWindow && m_pPainter, "DbFormattedField::_propertyChanged : where are my windows ?");
1472 if (m_pWindow)
1473 static_cast< FormattedField* >( m_pWindow.get() )->SetFormatKey( nNewKey );
1474 if (m_pPainter)
1475 static_cast< FormattedField* >( m_pPainter.get() )->SetFormatKey( nNewKey );
1477 else
1479 DbLimitedLengthField::_propertyChanged( _rEvent );
1484 OUString DbFormattedField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, Color** ppColor)
1486 // defaultmaessig keine Farb-Angabe
1487 if (ppColor != NULL)
1488 *ppColor = NULL;
1490 // NULL-Wert -> leerer Text
1491 if (!_rxField.is())
1492 return OUString();
1494 OUString aText;
1497 if (m_rColumn.IsNumeric())
1499 // das IsNumeric an der Column sagt nichts aus ueber die Klasse des benutzen Formates, sondern
1500 // ueber die des an die Column gebundenen Feldes. Wenn man also eine FormattedField-Spalte an
1501 // ein double-Feld bindet und als Text formatiert, liefert m_rColumn.IsNumeric() sal_True. Das heisst
1502 // also einfach, dass ich den Inhalt der Variant mittels getDouble abfragen kann, und dann kann
1503 // ich den Rest (die Formatierung) dem FormattedField ueberlassen.
1504 double dValue = getValue( _rxField, m_rColumn.GetParent().getNullDate() );
1505 if (_rxField->wasNull())
1506 return aText;
1507 static_cast<FormattedField*>(m_pPainter.get())->SetValue(dValue);
1509 else
1511 // Hier kann ich nicht mit einem double arbeiten, da das Feld mir keines liefern kann.
1512 // Also einfach den Text vom ::com::sun::star::util::NumberFormatter in die richtige ::com::sun::star::form::component::Form brinden lassen.
1513 aText = _rxField->getString();
1514 if (_rxField->wasNull())
1515 return aText;
1516 static_cast<FormattedField*>(m_pPainter.get())->SetTextFormatted(aText);
1519 catch( const Exception& )
1521 DBG_UNHANDLED_EXCEPTION();
1524 aText = m_pPainter->GetText();
1525 if (ppColor != NULL)
1526 *ppColor = static_cast<FormattedField*>(m_pPainter.get())->GetLastOutputColor();
1528 return aText;
1532 void DbFormattedField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
1536 FormattedField* pFormattedWindow = static_cast<FormattedField*>(m_pWindow.get());
1537 if (!_rxField.is())
1538 { // NULL-Wert -> leerer Text
1539 m_pWindow->SetText(OUString());
1541 else if (m_rColumn.IsNumeric())
1543 // das IsNumeric an der Column sagt nichts aus ueber die Klasse des benutzen Formates, sondern
1544 // ueber die des an die Column gebundenen Feldes. Wenn man also eine FormattedField-Spalte an
1545 // ein double-Feld bindet und als Text formatiert, liefert m_rColumn.IsNumeric() sal_True. Das heisst
1546 // also einfach, dass ich den Inhalt der Variant mittels getDouble abfragen kann, und dann kann
1547 // ich den Rest (die Formatierung) dem FormattedField ueberlassen.
1548 double dValue = getValue( _rxField, m_rColumn.GetParent().getNullDate() );
1549 if (_rxField->wasNull())
1550 m_pWindow->SetText(OUString());
1551 else
1552 pFormattedWindow->SetValue(dValue);
1554 else
1556 // Hier kann ich nicht mit einem double arbeiten, da das Feld mir keines liefern kann.
1557 // Also einfach den Text vom ::com::sun::star::util::NumberFormatter in die richtige ::com::sun::star::form::component::Form brinden lassen.
1558 OUString sText( _rxField->getString());
1560 pFormattedWindow->SetTextFormatted( sText );
1561 pFormattedWindow->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1564 catch( const Exception& )
1566 DBG_UNHANDLED_EXCEPTION();
1571 void DbFormattedField::updateFromModel( Reference< XPropertySet > _rxModel )
1573 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbFormattedField::updateFromModel: invalid call!" );
1575 FormattedField* pFormattedWindow = static_cast< FormattedField* >( m_pWindow.get() );
1577 OUString sText;
1578 Any aValue = _rxModel->getPropertyValue( FM_PROP_EFFECTIVE_VALUE );
1579 if ( aValue >>= sText )
1580 { // our effective value is transferred as string
1581 pFormattedWindow->SetTextFormatted( sText );
1582 pFormattedWindow->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1584 else
1586 double dValue = 0;
1587 aValue >>= dValue;
1588 pFormattedWindow->SetValue(dValue);
1593 bool DbFormattedField::commitControl()
1595 Any aNewVal;
1596 FormattedField& rField = *static_cast<FormattedField*>(m_pWindow.get());
1597 DBG_ASSERT(&rField == m_pWindow, "DbFormattedField::commitControl : can't work with a window other than my own !");
1598 if (m_rColumn.IsNumeric())
1600 if (!rField.GetText().isEmpty())
1601 aNewVal <<= rField.GetValue();
1602 // ein LeerString wird erst mal standardmaessig als void weitergereicht
1604 else
1605 aNewVal <<= OUString(rField.GetTextValue());
1607 m_rColumn.getModel()->setPropertyValue(FM_PROP_EFFECTIVE_VALUE, aNewVal);
1608 return true;
1611 DbCheckBox::DbCheckBox( DbGridColumn& _rColumn )
1612 :DbCellControl( _rColumn, true )
1614 setAlignedController( false );
1617 namespace
1619 void setCheckBoxStyle( vcl::Window* _pWindow, bool bMono )
1621 AllSettings aSettings = _pWindow->GetSettings();
1622 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1623 if( bMono )
1624 aStyleSettings.SetOptions( aStyleSettings.GetOptions() | StyleSettingsOptions::Mono );
1625 else
1626 aStyleSettings.SetOptions( aStyleSettings.GetOptions() & (~StyleSettingsOptions::Mono) );
1627 aSettings.SetStyleSettings( aStyleSettings );
1628 _pWindow->SetSettings( aSettings );
1633 void DbCheckBox::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor )
1635 setTransparent( true );
1637 m_pWindow = VclPtr<CheckBoxControl>::Create( &rParent );
1638 m_pPainter = VclPtr<CheckBoxControl>::Create( &rParent );
1640 m_pWindow->SetPaintTransparent( true );
1641 m_pPainter->SetPaintTransparent( true );
1643 m_pPainter->SetBackground();
1647 Reference< XPropertySet > xModel( m_rColumn.getModel(), UNO_SET_THROW );
1649 sal_Int16 nStyle = awt::VisualEffect::LOOK3D;
1650 OSL_VERIFY( xModel->getPropertyValue( FM_PROP_VISUALEFFECT ) >>= nStyle );
1652 setCheckBoxStyle( m_pWindow, nStyle == awt::VisualEffect::FLAT );
1653 setCheckBoxStyle( m_pPainter, nStyle == awt::VisualEffect::FLAT );
1655 bool bTristate = true;
1656 OSL_VERIFY( xModel->getPropertyValue( FM_PROP_TRISTATE ) >>= bTristate );
1657 static_cast< CheckBoxControl* >( m_pWindow.get() )->GetBox().EnableTriState( bTristate );
1658 static_cast< CheckBoxControl* >( m_pPainter.get() )->GetBox().EnableTriState( bTristate );
1660 catch( const Exception& )
1662 DBG_UNHANDLED_EXCEPTION();
1665 DbCellControl::Init( rParent, xCursor );
1669 CellControllerRef DbCheckBox::CreateController() const
1671 return new CheckBoxCellController(static_cast<CheckBoxControl*>(m_pWindow.get()));
1674 static void lcl_setCheckBoxState( const Reference< ::com::sun::star::sdb::XColumn >& _rxField,
1675 CheckBoxControl* _pCheckBoxControl )
1677 TriState eState = TRISTATE_INDET;
1678 if (_rxField.is())
1682 bool bValue = _rxField->getBoolean();
1683 if (!_rxField->wasNull())
1684 eState = bValue ? TRISTATE_TRUE : TRISTATE_FALSE;
1686 catch( const Exception& )
1688 DBG_UNHANDLED_EXCEPTION();
1691 _pCheckBoxControl->GetBox().SetState(eState);
1695 void DbCheckBox::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
1697 lcl_setCheckBoxState( _rxField, static_cast<CheckBoxControl*>(m_pWindow.get()) );
1701 void DbCheckBox::PaintFieldToCell(OutputDevice& rDev, const Rectangle& rRect,
1702 const Reference< ::com::sun::star::sdb::XColumn >& _rxField,
1703 const Reference< XNumberFormatter >& xFormatter)
1705 lcl_setCheckBoxState( _rxField, static_cast<CheckBoxControl*>(m_pPainter.get()) );
1706 DbCellControl::PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
1710 void DbCheckBox::updateFromModel( Reference< XPropertySet > _rxModel )
1712 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbCheckBox::updateFromModel: invalid call!" );
1714 sal_Int16 nState = TRISTATE_INDET;
1715 _rxModel->getPropertyValue( FM_PROP_STATE ) >>= nState;
1716 static_cast< CheckBoxControl* >( m_pWindow.get() )->GetBox().SetState( static_cast< TriState >( nState ) );
1720 bool DbCheckBox::commitControl()
1722 m_rColumn.getModel()->setPropertyValue( FM_PROP_STATE,
1723 makeAny( (sal_Int16)( static_cast< CheckBoxControl* >( m_pWindow.get() )->GetBox().GetState() ) ) );
1724 return true;
1728 OUString DbCheckBox::GetFormatText(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
1730 return OUString();
1733 DbPatternField::DbPatternField( DbGridColumn& _rColumn, const Reference<XComponentContext>& _rContext )
1734 :DbCellControl( _rColumn )
1735 ,m_xContext( _rContext )
1737 doPropertyListening( FM_PROP_LITERALMASK );
1738 doPropertyListening( FM_PROP_EDITMASK );
1739 doPropertyListening( FM_PROP_STRICTFORMAT );
1743 void DbPatternField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1745 DBG_ASSERT( m_pWindow, "DbPatternField::implAdjustGenericFieldSetting: not to be called without window!" );
1746 DBG_ASSERT( _rxModel.is(), "DbPatternField::implAdjustGenericFieldSetting: invalid model!" );
1747 if ( m_pWindow && _rxModel.is() )
1749 OUString aLitMask;
1750 OUString aEditMask;
1751 bool bStrict = false;
1753 _rxModel->getPropertyValue( FM_PROP_LITERALMASK ) >>= aLitMask;
1754 _rxModel->getPropertyValue( FM_PROP_EDITMASK ) >>= aEditMask;
1755 _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) >>= bStrict;
1757 OString aAsciiEditMask(OUStringToOString(aEditMask, RTL_TEXTENCODING_ASCII_US));
1759 static_cast< PatternField* >( m_pWindow.get() )->SetMask( aAsciiEditMask, aLitMask );
1760 static_cast< PatternField* >( m_pPainter.get() )->SetMask( aAsciiEditMask, aLitMask );
1761 static_cast< PatternField* >( m_pWindow.get() )->SetStrictFormat( bStrict );
1762 static_cast< PatternField* >( m_pPainter.get() )->SetStrictFormat( bStrict );
1767 void DbPatternField::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor)
1769 m_rColumn.SetAlignmentFromModel(-1);
1771 m_pWindow = VclPtr<PatternField>::Create( &rParent, 0 );
1772 m_pPainter= VclPtr<PatternField>::Create( &rParent, 0 );
1774 Reference< XPropertySet > xModel( m_rColumn.getModel() );
1775 implAdjustGenericFieldSetting( xModel );
1777 DbCellControl::Init( rParent, xCursor );
1781 CellControllerRef DbPatternField::CreateController() const
1783 return new SpinCellController( static_cast< PatternField* >( m_pWindow.get() ) );
1787 OUString DbPatternField::impl_formatText( const OUString& _rText )
1789 m_pPainter->SetText( _rText );
1790 static_cast< PatternField* >( m_pPainter.get() )->ReformatAll();
1791 return m_pPainter->GetText();
1795 OUString DbPatternField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
1797 bool bIsForPaint = _rxField != m_rColumn.GetField();
1798 ::std::unique_ptr< FormattedColumnValue >& rpFormatter = bIsForPaint ? m_pPaintFormatter : m_pValueFormatter;
1800 if ( !rpFormatter.get() )
1802 rpFormatter = ::std::unique_ptr< FormattedColumnValue> (
1803 new FormattedColumnValue(m_xContext, getCursor(), Reference< XPropertySet >( _rxField, UNO_QUERY ) ) );
1804 OSL_ENSURE( rpFormatter.get(), "DbPatternField::Init: no value formatter!" );
1806 else
1807 OSL_ENSURE( rpFormatter->getColumn() == _rxField, "DbPatternField::GetFormatText: my value formatter is working for another field ...!" );
1808 // re-creating the value formatter here every time would be quite expensive ...
1810 OUString sText;
1811 if ( rpFormatter.get() )
1812 sText = rpFormatter->getFormattedValue();
1814 return impl_formatText( sText );
1818 void DbPatternField::UpdateFromField( const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1820 static_cast< Edit* >( m_pWindow.get() )->SetText( GetFormatText( _rxField, _rxFormatter ) );
1821 static_cast< Edit* >( m_pWindow.get() )->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1825 void DbPatternField::updateFromModel( Reference< XPropertySet > _rxModel )
1827 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbPatternField::updateFromModel: invalid call!" );
1829 OUString sText;
1830 _rxModel->getPropertyValue( FM_PROP_TEXT ) >>= sText;
1832 static_cast< Edit* >( m_pWindow.get() )->SetText( impl_formatText( sText ) );
1833 static_cast< Edit* >( m_pWindow.get() )->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1837 bool DbPatternField::commitControl()
1839 OUString aText(m_pWindow->GetText());
1840 m_rColumn.getModel()->setPropertyValue(FM_PROP_TEXT, makeAny(aText));
1841 return true;
1844 DbSpinField::DbSpinField( DbGridColumn& _rColumn, sal_Int16 _nStandardAlign )
1845 :DbCellControl( _rColumn )
1846 ,m_nStandardAlign( _nStandardAlign )
1851 void DbSpinField::Init( vcl::Window& _rParent, const Reference< XRowSet >& _rxCursor )
1853 m_rColumn.SetAlignmentFromModel( m_nStandardAlign );
1855 Reference< XPropertySet > xModel( m_rColumn.getModel() );
1857 // determine the WinBits for the field
1858 WinBits nFieldStyle = 0;
1859 if ( ::comphelper::getBOOL( xModel->getPropertyValue( FM_PROP_SPIN ) ) )
1860 nFieldStyle = WB_REPEAT | WB_SPIN;
1861 // create the fields
1862 m_pWindow = createField( &_rParent, nFieldStyle, xModel );
1863 m_pPainter = createField( &_rParent, nFieldStyle, xModel );
1865 // adjust all other settings which depend on the property values
1866 implAdjustGenericFieldSetting( xModel );
1868 // call the base class
1869 DbCellControl::Init( _rParent, _rxCursor );
1873 CellControllerRef DbSpinField::CreateController() const
1875 return new SpinCellController( static_cast< SpinField* >( m_pWindow.get() ) );
1878 DbNumericField::DbNumericField( DbGridColumn& _rColumn )
1879 :DbSpinField( _rColumn )
1881 doPropertyListening( FM_PROP_DECIMAL_ACCURACY );
1882 doPropertyListening( FM_PROP_VALUEMIN );
1883 doPropertyListening( FM_PROP_VALUEMAX );
1884 doPropertyListening( FM_PROP_VALUESTEP );
1885 doPropertyListening( FM_PROP_STRICTFORMAT );
1886 doPropertyListening( FM_PROP_SHOWTHOUSANDSEP );
1890 void DbNumericField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1892 DBG_ASSERT( m_pWindow, "DbNumericField::implAdjustGenericFieldSetting: not to be called without window!" );
1893 DBG_ASSERT( _rxModel.is(), "DbNumericField::implAdjustGenericFieldSetting: invalid model!" );
1894 if ( m_pWindow && _rxModel.is() )
1896 sal_Int32 nMin = (sal_Int32)getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMIN ) );
1897 sal_Int32 nMax = (sal_Int32)getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMAX ) );
1898 sal_Int32 nStep = (sal_Int32)getDouble( _rxModel->getPropertyValue( FM_PROP_VALUESTEP ) );
1899 bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
1900 sal_Int16 nScale = getINT16( _rxModel->getPropertyValue( FM_PROP_DECIMAL_ACCURACY ) );
1901 bool bThousand = getBOOL( _rxModel->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP ) );
1903 static_cast< DoubleNumericField* >( m_pWindow.get() )->SetMinValue(nMin);
1904 static_cast< DoubleNumericField* >( m_pWindow.get() )->SetMaxValue(nMax);
1905 static_cast< DoubleNumericField* >( m_pWindow.get() )->SetSpinSize(nStep);
1906 static_cast< DoubleNumericField* >( m_pWindow.get() )->SetStrictFormat(bStrict);
1908 static_cast< DoubleNumericField* >( m_pPainter.get() )->SetMinValue(nMin);
1909 static_cast< DoubleNumericField* >( m_pPainter.get() )->SetMaxValue(nMax);
1910 static_cast< DoubleNumericField* >( m_pPainter.get() )->SetStrictFormat(bStrict);
1913 // dem Field und dem Painter einen Formatter spendieren
1914 // zuerst testen, ob ich von dem Service hinter einer Connection bekommen kann
1915 Reference< ::com::sun::star::util::XNumberFormatsSupplier > xSupplier;
1916 Reference< XRowSet > xForm;
1917 if ( m_rColumn.GetParent().getDataSource() )
1918 xForm = Reference< XRowSet >( Reference< XInterface >(*m_rColumn.GetParent().getDataSource()), UNO_QUERY );
1919 if ( xForm.is() )
1920 xSupplier = getNumberFormats( getConnection( xForm ), true );
1921 SvNumberFormatter* pFormatterUsed = NULL;
1922 if ( xSupplier.is() )
1924 SvNumberFormatsSupplierObj* pImplmentation = SvNumberFormatsSupplierObj::getImplementation( xSupplier );
1925 pFormatterUsed = pImplmentation ? pImplmentation->GetNumberFormatter() : NULL;
1927 if ( NULL == pFormatterUsed )
1928 { // der Cursor fuehrte nicht zum Erfolg -> Standard
1929 pFormatterUsed = static_cast< DoubleNumericField* >( m_pWindow.get() )->StandardFormatter();
1930 DBG_ASSERT( pFormatterUsed != NULL, "DbNumericField::implAdjustGenericFieldSetting: no standard formatter given by the numeric field !" );
1932 static_cast< DoubleNumericField* >( m_pWindow.get() )->SetFormatter( pFormatterUsed );
1933 static_cast< DoubleNumericField* >( m_pPainter.get() )->SetFormatter( pFormatterUsed );
1935 // und dann ein Format generieren, dass die gewuenschten Nachkommastellen usw. hat
1936 LanguageType aAppLanguage = Application::GetSettings().GetUILanguageTag().getLanguageType();
1937 OUString sFormatString = pFormatterUsed->GenerateFormat(0, aAppLanguage, bThousand, false, nScale);
1939 static_cast< DoubleNumericField* >( m_pWindow.get() )->SetFormat( sFormatString, aAppLanguage );
1940 static_cast< DoubleNumericField* >( m_pPainter.get() )->SetFormat( sFormatString, aAppLanguage );
1945 VclPtr<SpinField> DbNumericField::createField( vcl::Window* _pParent, WinBits _nFieldStyle, const Reference< XPropertySet >& /*_rxModel*/ )
1947 return VclPtr<DoubleNumericField>::Create( _pParent, _nFieldStyle );
1950 namespace
1953 static OUString lcl_setFormattedNumeric_nothrow( DoubleNumericField& _rField, const DbCellControl& _rControl,
1954 const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1956 OUString sValue;
1957 if ( _rxField.is() )
1961 double fValue = _rControl.GetValue( _rxField, _rxFormatter );
1962 if ( !_rxField->wasNull() )
1964 _rField.SetValue( fValue );
1965 sValue = _rField.GetText();
1968 catch( const Exception& )
1970 DBG_UNHANDLED_EXCEPTION();
1973 return sValue;
1978 OUString DbNumericField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& _rxFormatter, Color** /*ppColor*/)
1980 return lcl_setFormattedNumeric_nothrow(dynamic_cast<DoubleNumericField&>(*m_pPainter), *this, _rxField, _rxFormatter);
1984 void DbNumericField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& _rxFormatter)
1986 lcl_setFormattedNumeric_nothrow(dynamic_cast<DoubleNumericField&>(*m_pWindow), *this, _rxField, _rxFormatter);
1990 void DbNumericField::updateFromModel( Reference< XPropertySet > _rxModel )
1992 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbNumericField::updateFromModel: invalid call!" );
1994 double dValue = 0;
1995 if ( _rxModel->getPropertyValue( FM_PROP_VALUE ) >>= dValue )
1996 static_cast< DoubleNumericField* >( m_pWindow.get() )->SetValue( dValue );
1997 else
1998 m_pWindow->SetText( OUString() );
2002 bool DbNumericField::commitControl()
2004 OUString aText( m_pWindow->GetText());
2005 Any aVal;
2007 if (!aText.isEmpty()) // not empty
2009 double fValue = static_cast<DoubleNumericField*>(m_pWindow.get())->GetValue();
2010 aVal <<= (double)fValue;
2012 m_rColumn.getModel()->setPropertyValue(FM_PROP_VALUE, aVal);
2013 return true;
2016 DbCurrencyField::DbCurrencyField(DbGridColumn& _rColumn)
2017 :DbSpinField( _rColumn )
2018 ,m_nScale( 0 )
2020 doPropertyListening( FM_PROP_DECIMAL_ACCURACY );
2021 doPropertyListening( FM_PROP_VALUEMIN );
2022 doPropertyListening( FM_PROP_VALUEMAX );
2023 doPropertyListening( FM_PROP_VALUESTEP );
2024 doPropertyListening( FM_PROP_STRICTFORMAT );
2025 doPropertyListening( FM_PROP_SHOWTHOUSANDSEP );
2026 doPropertyListening( FM_PROP_CURRENCYSYMBOL );
2030 void DbCurrencyField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2032 DBG_ASSERT( m_pWindow, "DbCurrencyField::implAdjustGenericFieldSetting: not to be called without window!" );
2033 DBG_ASSERT( _rxModel.is(), "DbCurrencyField::implAdjustGenericFieldSetting: invalid model!" );
2034 if ( m_pWindow && _rxModel.is() )
2036 m_nScale = getINT16( _rxModel->getPropertyValue( FM_PROP_DECIMAL_ACCURACY ) );
2037 double nMin = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMIN ) );
2038 double nMax = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMAX ) );
2039 double nStep = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUESTEP ) );
2040 bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2041 bool bThousand = getBOOL( _rxModel->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP ) );
2042 OUString aStr( getString( _rxModel->getPropertyValue(FM_PROP_CURRENCYSYMBOL ) ) );
2044 //fdo#42747 the min/max/first/last of vcl NumericFormatters needs to be
2045 //multiplied by the no of decimal places. See also
2046 //VclBuilder::mungeAdjustment
2047 int nMul = rtl_math_pow10Exp(1, m_nScale);
2048 nMin *= nMul;
2049 nMax *= nMul;
2051 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetUseThousandSep( bThousand );
2052 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetDecimalDigits( m_nScale );
2053 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetCurrencySymbol( aStr );
2054 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetFirst( nMin );
2055 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetLast( nMax );
2056 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetMin( nMin );
2057 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetMax( nMax );
2058 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetSpinSize( nStep );
2059 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetStrictFormat( bStrict );
2061 static_cast< LongCurrencyField* >( m_pPainter.get() )->SetUseThousandSep( bThousand );
2062 static_cast< LongCurrencyField* >( m_pPainter.get() )->SetDecimalDigits( m_nScale );
2063 static_cast< LongCurrencyField* >( m_pPainter.get() )->SetCurrencySymbol( aStr );
2064 static_cast< LongCurrencyField* >( m_pPainter.get() )->SetFirst( nMin );
2065 static_cast< LongCurrencyField* >( m_pPainter.get() )->SetLast( nMax );
2066 static_cast< LongCurrencyField* >( m_pPainter.get() )->SetMin( nMin );
2067 static_cast< LongCurrencyField* >( m_pPainter.get() )->SetMax( nMax );
2068 static_cast< LongCurrencyField* >( m_pPainter.get() )->SetStrictFormat( bStrict );
2073 VclPtr<SpinField> DbCurrencyField::createField( vcl::Window* _pParent, WinBits _nFieldStyle, const Reference< XPropertySet >& /*_rxModel*/ )
2075 return VclPtr<LongCurrencyField>::Create( _pParent, _nFieldStyle );
2079 double DbCurrencyField::GetCurrency(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter) const
2081 double fValue = GetValue(_rxField, xFormatter);
2082 if (m_nScale)
2084 // OSL_TRACE("double = %.64f ",fValue);
2085 fValue = ::rtl::math::pow10Exp(fValue, m_nScale);
2086 fValue = ::rtl::math::round(fValue, 0);
2088 return fValue;
2091 namespace
2094 static OUString lcl_setFormattedCurrency_nothrow( LongCurrencyField& _rField, const DbCurrencyField& _rControl,
2095 const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
2097 OUString sValue;
2098 if ( _rxField.is() )
2102 double fValue = _rControl.GetCurrency( _rxField, _rxFormatter );
2103 if ( !_rxField->wasNull() )
2105 _rField.SetValue( fValue );
2106 sValue = _rField.GetText();
2109 catch( const Exception& )
2111 DBG_UNHANDLED_EXCEPTION();
2114 return sValue;
2119 OUString DbCurrencyField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& _rxFormatter, Color** /*ppColor*/)
2121 return lcl_setFormattedCurrency_nothrow( dynamic_cast< LongCurrencyField& >( *m_pPainter ), *this, _rxField, _rxFormatter );
2125 void DbCurrencyField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& _rxFormatter)
2127 lcl_setFormattedCurrency_nothrow( dynamic_cast< LongCurrencyField& >( *m_pWindow ), *this, _rxField, _rxFormatter );
2131 void DbCurrencyField::updateFromModel( Reference< XPropertySet > _rxModel )
2133 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbCurrencyField::updateFromModel: invalid call!" );
2135 double dValue = 0;
2136 if ( _rxModel->getPropertyValue( FM_PROP_VALUE ) >>= dValue )
2138 if ( m_nScale )
2140 dValue = ::rtl::math::pow10Exp( dValue, m_nScale );
2141 dValue = ::rtl::math::round(dValue, 0);
2144 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetValue( dValue );
2146 else
2147 m_pWindow->SetText( OUString() );
2151 bool DbCurrencyField::commitControl()
2153 OUString aText(m_pWindow->GetText());
2154 Any aVal;
2155 if (!aText.isEmpty()) // not empty
2157 double fValue = static_cast<LongCurrencyField*>(m_pWindow.get())->GetValue();
2158 if (m_nScale)
2160 fValue /= ::rtl::math::pow10Exp(1.0, m_nScale);
2162 aVal <<= (double)fValue;
2164 m_rColumn.getModel()->setPropertyValue(FM_PROP_VALUE, aVal);
2165 return true;
2168 DbDateField::DbDateField( DbGridColumn& _rColumn )
2169 :DbSpinField( _rColumn )
2171 doPropertyListening( FM_PROP_DATEFORMAT );
2172 doPropertyListening( FM_PROP_DATEMIN );
2173 doPropertyListening( FM_PROP_DATEMAX );
2174 doPropertyListening( FM_PROP_STRICTFORMAT );
2175 doPropertyListening( FM_PROP_DATE_SHOW_CENTURY );
2179 VclPtr<SpinField> DbDateField::createField( vcl::Window* _pParent, WinBits _nFieldStyle, const Reference< XPropertySet >& _rxModel )
2181 // check if there is a DropDown property set to TRUE
2182 bool bDropDown = !hasProperty( FM_PROP_DROPDOWN, _rxModel )
2183 || getBOOL( _rxModel->getPropertyValue( FM_PROP_DROPDOWN ) );
2184 if ( bDropDown )
2185 _nFieldStyle |= WB_DROPDOWN;
2187 VclPtr<CalendarField> pField = VclPtr<CalendarField>::Create( _pParent, _nFieldStyle );
2189 pField->EnableToday();
2190 pField->EnableNone();
2192 return pField;
2196 void DbDateField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2198 DBG_ASSERT( m_pWindow, "DbDateField::implAdjustGenericFieldSetting: not to be called without window!" );
2199 DBG_ASSERT( _rxModel.is(), "DbDateField::implAdjustGenericFieldSetting: invalid model!" );
2200 if ( m_pWindow && _rxModel.is() )
2202 sal_Int16 nFormat = getINT16( _rxModel->getPropertyValue( FM_PROP_DATEFORMAT ) );
2203 util::Date aMin;
2204 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_DATEMIN ) >>= aMin );
2205 util::Date aMax;
2206 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_DATEMAX ) >>= aMax );
2207 bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2209 Any aCentury = _rxModel->getPropertyValue( FM_PROP_DATE_SHOW_CENTURY );
2210 if ( aCentury.getValueType().getTypeClass() != TypeClass_VOID )
2212 bool bShowDateCentury = getBOOL( aCentury );
2214 static_cast<DateField*>( m_pWindow.get() )->SetShowDateCentury( bShowDateCentury );
2215 static_cast<DateField*>( m_pPainter.get() )->SetShowDateCentury( bShowDateCentury );
2218 static_cast< DateField* >( m_pWindow.get() )->SetExtDateFormat( (ExtDateFieldFormat)nFormat );
2219 static_cast< DateField* >( m_pWindow.get() )->SetMin( aMin );
2220 static_cast< DateField* >( m_pWindow.get() )->SetMax( aMax );
2221 static_cast< DateField* >( m_pWindow.get() )->SetStrictFormat( bStrict );
2222 static_cast< DateField* >( m_pWindow.get() )->EnableEmptyFieldValue( true );
2224 static_cast< DateField* >( m_pPainter.get() )->SetExtDateFormat( (ExtDateFieldFormat)nFormat );
2225 static_cast< DateField* >( m_pPainter.get() )->SetMin( aMin );
2226 static_cast< DateField* >( m_pPainter.get() )->SetMax( aMax );
2227 static_cast< DateField* >( m_pPainter.get() )->SetStrictFormat( bStrict );
2228 static_cast< DateField* >( m_pPainter.get() )->EnableEmptyFieldValue( true );
2232 namespace
2235 static OUString lcl_setFormattedDate_nothrow( DateField& _rField, const Reference< XColumn >& _rxField )
2237 OUString sDate;
2238 if ( _rxField.is() )
2242 ::com::sun::star::util::Date aValue = _rxField->getDate();
2243 if ( _rxField->wasNull() )
2244 _rField.SetText( sDate );
2245 else
2247 _rField.SetDate( ::Date( aValue.Day, aValue.Month, aValue.Year ) );
2248 sDate = _rField.GetText();
2251 catch( const Exception& )
2253 DBG_UNHANDLED_EXCEPTION();
2256 return sDate;
2260 OUString DbDateField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
2262 return lcl_setFormattedDate_nothrow(dynamic_cast<DateField&>(*m_pPainter.get()), _rxField);
2266 void DbDateField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
2268 lcl_setFormattedDate_nothrow(dynamic_cast<DateField&>(*m_pWindow.get()), _rxField);
2272 void DbDateField::updateFromModel( Reference< XPropertySet > _rxModel )
2274 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbDateField::updateFromModel: invalid call!" );
2276 util::Date aDate;
2277 if ( _rxModel->getPropertyValue( FM_PROP_DATE ) >>= aDate )
2278 static_cast< DateField* >( m_pWindow.get() )->SetDate( ::Date( aDate ) );
2279 else
2280 static_cast< DateField* >( m_pWindow.get() )->SetText( OUString() );
2284 bool DbDateField::commitControl()
2286 OUString aText(m_pWindow->GetText());
2287 Any aVal;
2288 if (!aText.isEmpty())
2289 aVal <<= static_cast<DateField*>(m_pWindow.get())->GetDate().GetUNODate();
2290 else
2291 aVal.clear();
2293 m_rColumn.getModel()->setPropertyValue(FM_PROP_DATE, aVal);
2294 return true;
2297 DbTimeField::DbTimeField( DbGridColumn& _rColumn )
2298 :DbSpinField( _rColumn, ::com::sun::star::awt::TextAlign::LEFT )
2300 doPropertyListening( FM_PROP_TIMEFORMAT );
2301 doPropertyListening( FM_PROP_TIMEMIN );
2302 doPropertyListening( FM_PROP_TIMEMAX );
2303 doPropertyListening( FM_PROP_STRICTFORMAT );
2307 VclPtr<SpinField> DbTimeField::createField( vcl::Window* _pParent, WinBits _nFieldStyle, const Reference< XPropertySet >& /*_rxModel*/ )
2309 return VclPtr<TimeField>::Create( _pParent, _nFieldStyle );
2313 void DbTimeField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2315 DBG_ASSERT( m_pWindow, "DbTimeField::implAdjustGenericFieldSetting: not to be called without window!" );
2316 DBG_ASSERT( _rxModel.is(), "DbTimeField::implAdjustGenericFieldSetting: invalid model!" );
2317 if ( m_pWindow && _rxModel.is() )
2319 sal_Int16 nFormat = getINT16( _rxModel->getPropertyValue( FM_PROP_TIMEFORMAT ) );
2320 util::Time aMin;
2321 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_TIMEMIN ) >>= aMin );
2322 util::Time aMax;
2323 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_TIMEMAX ) >>= aMax );
2324 bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2326 static_cast< TimeField* >( m_pWindow.get() )->SetExtFormat( (ExtTimeFieldFormat)nFormat );
2327 static_cast< TimeField* >( m_pWindow.get() )->SetMin( aMin );
2328 static_cast< TimeField* >( m_pWindow.get() )->SetMax( aMax );
2329 static_cast< TimeField* >( m_pWindow.get() )->SetStrictFormat( bStrict );
2330 static_cast< TimeField* >( m_pWindow.get() )->EnableEmptyFieldValue( true );
2332 static_cast< TimeField* >( m_pPainter.get() )->SetExtFormat( (ExtTimeFieldFormat)nFormat );
2333 static_cast< TimeField* >( m_pPainter.get() )->SetMin( aMin );
2334 static_cast< TimeField* >( m_pPainter.get() )->SetMax( aMax );
2335 static_cast< TimeField* >( m_pPainter.get() )->SetStrictFormat( bStrict );
2336 static_cast< TimeField* >( m_pPainter.get() )->EnableEmptyFieldValue( true );
2340 namespace
2343 static OUString lcl_setFormattedTime_nothrow( TimeField& _rField, const Reference< XColumn >& _rxField )
2345 OUString sTime;
2346 if ( _rxField.is() )
2350 ::com::sun::star::util::Time aValue = _rxField->getTime();
2351 if ( _rxField->wasNull() )
2352 _rField.SetText( sTime );
2353 else
2355 _rField.SetTime( ::tools::Time( aValue ) );
2356 sTime = _rField.GetText();
2359 catch( const Exception& )
2361 DBG_UNHANDLED_EXCEPTION();
2364 return sTime;
2368 OUString DbTimeField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
2370 return lcl_setFormattedTime_nothrow( *static_cast< TimeField* >( m_pPainter.get() ), _rxField );
2374 void DbTimeField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
2376 lcl_setFormattedTime_nothrow( *static_cast< TimeField* >( m_pWindow.get() ), _rxField );
2380 void DbTimeField::updateFromModel( Reference< XPropertySet > _rxModel )
2382 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbTimeField::updateFromModel: invalid call!" );
2384 util::Time aTime;
2385 if ( _rxModel->getPropertyValue( FM_PROP_TIME ) >>= aTime )
2386 static_cast< TimeField* >( m_pWindow.get() )->SetTime( ::tools::Time( aTime ) );
2387 else
2388 static_cast< TimeField* >( m_pWindow.get() )->SetText( OUString() );
2392 bool DbTimeField::commitControl()
2394 OUString aText(m_pWindow->GetText());
2395 Any aVal;
2396 if (!aText.isEmpty())
2397 aVal <<= static_cast<TimeField*>(m_pWindow.get())->GetTime().GetUNOTime();
2398 else
2399 aVal.clear();
2401 m_rColumn.getModel()->setPropertyValue(FM_PROP_TIME, aVal);
2402 return true;
2405 DbComboBox::DbComboBox(DbGridColumn& _rColumn)
2406 :DbCellControl(_rColumn)
2408 setAlignedController( false );
2410 doPropertyListening( FM_PROP_STRINGITEMLIST );
2411 doPropertyListening( FM_PROP_LINECOUNT );
2415 void DbComboBox::_propertyChanged( const PropertyChangeEvent& _rEvent ) throw( RuntimeException )
2417 if ( _rEvent.PropertyName == FM_PROP_STRINGITEMLIST )
2419 SetList(_rEvent.NewValue);
2421 else
2423 DbCellControl::_propertyChanged( _rEvent ) ;
2428 void DbComboBox::SetList(const Any& rItems)
2430 ComboBoxControl* pField = static_cast<ComboBoxControl*>(m_pWindow.get());
2431 pField->Clear();
2433 ::comphelper::StringSequence aTest;
2434 if (rItems >>= aTest)
2436 const OUString* pStrings = aTest.getConstArray();
2437 sal_Int32 nItems = aTest.getLength();
2438 for (sal_Int32 i = 0; i < nItems; ++i, ++pStrings )
2439 pField->InsertEntry(*pStrings, LISTBOX_APPEND);
2441 // tell the grid control that this controller is invalid and has to be re-initialized
2442 invalidatedController();
2447 void DbComboBox::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2449 DBG_ASSERT( m_pWindow, "DbComboBox::implAdjustGenericFieldSetting: not to be called without window!" );
2450 DBG_ASSERT( _rxModel.is(), "DbComboBox::implAdjustGenericFieldSetting: invalid model!" );
2451 if ( m_pWindow && _rxModel.is() )
2453 sal_Int16 nLines = getINT16( _rxModel->getPropertyValue( FM_PROP_LINECOUNT ) );
2454 static_cast< ComboBoxControl* >( m_pWindow.get() )->SetDropDownLineCount( nLines );
2459 void DbComboBox::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor )
2461 m_rColumn.SetAlignmentFromModel(::com::sun::star::awt::TextAlign::LEFT);
2463 m_pWindow = VclPtr<ComboBoxControl>::Create( &rParent );
2465 // selection von rechts nach links
2466 AllSettings aSettings = m_pWindow->GetSettings();
2467 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2468 aStyleSettings.SetSelectionOptions(
2469 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2470 aSettings.SetStyleSettings(aStyleSettings);
2471 m_pWindow->SetSettings(aSettings, true);
2473 // some initial properties
2474 Reference< XPropertySet > xModel(m_rColumn.getModel());
2475 SetList( xModel->getPropertyValue( FM_PROP_STRINGITEMLIST ) );
2476 implAdjustGenericFieldSetting( xModel );
2478 DbCellControl::Init( rParent, xCursor );
2482 CellControllerRef DbComboBox::CreateController() const
2484 return new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2488 OUString DbComboBox::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter, Color** /*ppColor*/)
2490 const com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> xPS(_rxField, UNO_QUERY);
2491 ::dbtools::FormattedColumnValue fmter( xFormatter, xPS );
2493 return fmter.getFormattedValue();
2497 void DbComboBox::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
2499 m_pWindow->SetText(GetFormatText(_rxField, xFormatter));
2503 void DbComboBox::updateFromModel( Reference< XPropertySet > _rxModel )
2505 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbComboBox::updateFromModel: invalid call!" );
2507 OUString sText;
2508 _rxModel->getPropertyValue( FM_PROP_TEXT ) >>= sText;
2510 static_cast< ComboBox* >( m_pWindow.get() )->SetText( sText );
2511 static_cast< ComboBox* >( m_pWindow.get() )->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
2515 bool DbComboBox::commitControl()
2517 OUString aText( m_pWindow->GetText());
2518 m_rColumn.getModel()->setPropertyValue(FM_PROP_TEXT, makeAny(aText));
2519 return true;
2523 DbListBox::DbListBox(DbGridColumn& _rColumn)
2524 :DbCellControl(_rColumn)
2525 ,m_bBound(false)
2527 setAlignedController( false );
2529 doPropertyListening( FM_PROP_STRINGITEMLIST );
2530 doPropertyListening( FM_PROP_LINECOUNT );
2534 void DbListBox::_propertyChanged( const ::com::sun::star::beans::PropertyChangeEvent& _rEvent ) throw( RuntimeException )
2536 if ( _rEvent.PropertyName == FM_PROP_STRINGITEMLIST )
2538 SetList(_rEvent.NewValue);
2540 else
2542 DbCellControl::_propertyChanged( _rEvent ) ;
2547 void DbListBox::SetList(const Any& rItems)
2549 ListBoxControl* pField = static_cast<ListBoxControl*>(m_pWindow.get());
2551 pField->Clear();
2552 m_bBound = false;
2554 ::comphelper::StringSequence aTest;
2555 if (rItems >>= aTest)
2557 const OUString* pStrings = aTest.getConstArray();
2558 sal_Int32 nItems = aTest.getLength();
2559 if (nItems)
2561 for (sal_Int32 i = 0; i < nItems; ++i, ++pStrings )
2562 pField->InsertEntry(*pStrings, LISTBOX_APPEND);
2564 m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ) >>= m_aValueList;
2565 m_bBound = m_aValueList.getLength() > 0;
2567 // tell the grid control that this controller is invalid and has to be re-initialized
2568 invalidatedController();
2574 void DbListBox::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor)
2576 m_rColumn.SetAlignment(::com::sun::star::awt::TextAlign::LEFT);
2578 m_pWindow = VclPtr<ListBoxControl>::Create( &rParent );
2580 // some initial properties
2581 Reference< XPropertySet > xModel( m_rColumn.getModel() );
2582 SetList( xModel->getPropertyValue( FM_PROP_STRINGITEMLIST ) );
2583 implAdjustGenericFieldSetting( xModel );
2585 DbCellControl::Init( rParent, xCursor );
2589 void DbListBox::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2591 DBG_ASSERT( m_pWindow, "DbListBox::implAdjustGenericFieldSetting: not to be called without window!" );
2592 DBG_ASSERT( _rxModel.is(), "DbListBox::implAdjustGenericFieldSetting: invalid model!" );
2593 if ( m_pWindow && _rxModel.is() )
2595 sal_Int16 nLines = getINT16( _rxModel->getPropertyValue( FM_PROP_LINECOUNT ) );
2596 static_cast< ListBoxControl* >( m_pWindow.get() )->SetDropDownLineCount( nLines );
2601 CellControllerRef DbListBox::CreateController() const
2603 return new ListBoxCellController(static_cast<ListBoxControl*>(m_pWindow.get()));
2607 OUString DbListBox::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
2609 OUString sText;
2610 if ( _rxField.is() )
2614 sText = _rxField->getString();
2615 if ( m_bBound )
2617 Sequence< sal_Int16 > aPosSeq = ::comphelper::findValue( m_aValueList, sText, true );
2618 if ( aPosSeq.getLength() )
2619 sText = static_cast<ListBox*>(m_pWindow.get())->GetEntry(aPosSeq.getConstArray()[0]);
2620 else
2621 sText.clear();
2624 catch( const Exception& )
2626 DBG_UNHANDLED_EXCEPTION();
2629 return sText;
2633 void DbListBox::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
2635 OUString sFormattedText( GetFormatText( _rxField, xFormatter ) );
2636 if (!sFormattedText.isEmpty())
2637 static_cast< ListBox* >( m_pWindow.get() )->SelectEntry( sFormattedText );
2638 else
2639 static_cast< ListBox* >( m_pWindow.get() )->SetNoSelection();
2643 void DbListBox::updateFromModel( Reference< XPropertySet > _rxModel )
2645 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbListBox::updateFromModel: invalid call!" );
2647 Sequence< sal_Int16 > aSelection;
2648 _rxModel->getPropertyValue( FM_PROP_SELECT_SEQ );
2650 sal_Int16 nSelection = -1;
2651 if ( aSelection.getLength() > 0 )
2652 nSelection = aSelection[ 0 ];
2654 ListBox* pListBox = static_cast< ListBox* >( m_pWindow.get() );
2656 if ( ( nSelection >= 0 ) && ( nSelection < pListBox->GetEntryCount() ) )
2657 pListBox->SelectEntryPos( nSelection );
2658 else
2659 pListBox->SetNoSelection( );
2663 bool DbListBox::commitControl()
2665 Any aVal;
2666 Sequence<sal_Int16> aSelectSeq;
2667 if (static_cast<ListBox*>(m_pWindow.get())->GetSelectEntryCount())
2669 aSelectSeq.realloc(1);
2670 *(sal_Int16 *)aSelectSeq.getArray() = (sal_Int16)static_cast<ListBox*>(m_pWindow.get())->GetSelectEntryPos();
2672 aVal <<= aSelectSeq;
2673 m_rColumn.getModel()->setPropertyValue(FM_PROP_SELECT_SEQ, aVal);
2674 return true;
2677 DbFilterField::DbFilterField(const Reference< XComponentContext >& rxContext,DbGridColumn& _rColumn)
2678 :DbCellControl(_rColumn)
2679 ,OSQLParserClient(rxContext)
2680 ,m_nControlClass(::com::sun::star::form::FormComponentType::TEXTFIELD)
2681 ,m_bFilterList(false)
2682 ,m_bFilterListFilled(false)
2683 ,m_bBound(false)
2686 setAlignedController( false );
2690 DbFilterField::~DbFilterField()
2692 if (m_nControlClass == ::com::sun::star::form::FormComponentType::CHECKBOX)
2693 static_cast<CheckBoxControl*>(m_pWindow.get())->SetClickHdl( Link<>() );
2698 void DbFilterField::PaintCell(OutputDevice& rDev, const Rectangle& rRect)
2700 static const DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::VCenter | DrawTextFlags::Left;
2701 switch (m_nControlClass)
2703 case FormComponentType::CHECKBOX:
2704 DbCellControl::PaintCell( rDev, rRect );
2705 break;
2706 case FormComponentType::LISTBOX:
2707 rDev.DrawText(rRect, static_cast<ListBox*>(m_pWindow.get())->GetSelectEntry(), nStyle);
2708 break;
2709 default:
2710 rDev.DrawText(rRect, m_aText, nStyle);
2715 void DbFilterField::SetList(const Any& rItems, bool bComboBox)
2717 ::comphelper::StringSequence aTest;
2718 rItems >>= aTest;
2719 const OUString* pStrings = aTest.getConstArray();
2720 sal_Int32 nItems = aTest.getLength();
2721 if (nItems)
2723 if (bComboBox)
2725 ComboBox* pField = static_cast<ComboBox*>(m_pWindow.get());
2726 for (sal_Int32 i = 0; i < nItems; ++i, ++pStrings )
2727 pField->InsertEntry(*pStrings, LISTBOX_APPEND);
2729 else
2731 ListBox* pField = static_cast<ListBox*>(m_pWindow.get());
2732 for (sal_Int32 i = 0; i < nItems; ++i, ++pStrings )
2733 pField->InsertEntry(*pStrings, LISTBOX_APPEND);
2735 m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ) >>= m_aValueList;
2736 m_bBound = m_aValueList.getLength() > 0;
2742 void DbFilterField::CreateControl(vcl::Window* pParent, const Reference< ::com::sun::star::beans::XPropertySet >& xModel)
2744 switch (m_nControlClass)
2746 case ::com::sun::star::form::FormComponentType::CHECKBOX:
2747 m_pWindow = VclPtr<CheckBoxControl>::Create(pParent);
2748 m_pWindow->SetPaintTransparent( true );
2749 static_cast<CheckBoxControl*>(m_pWindow.get())->SetClickHdl( LINK( this, DbFilterField, OnClick ) );
2751 m_pPainter = VclPtr<CheckBoxControl>::Create(pParent);
2752 m_pPainter->SetPaintTransparent( true );
2753 m_pPainter->SetBackground();
2754 break;
2755 case ::com::sun::star::form::FormComponentType::LISTBOX:
2757 m_pWindow = VclPtr<ListBoxControl>::Create(pParent);
2758 sal_Int16 nLines = ::comphelper::getINT16(xModel->getPropertyValue(FM_PROP_LINECOUNT));
2759 Any aItems = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST);
2760 SetList(aItems, m_nControlClass == ::com::sun::star::form::FormComponentType::COMBOBOX);
2761 static_cast<ListBox*>(m_pWindow.get())->SetDropDownLineCount(nLines);
2762 } break;
2763 case ::com::sun::star::form::FormComponentType::COMBOBOX:
2765 m_pWindow = VclPtr<ComboBoxControl>::Create(pParent);
2767 AllSettings aSettings = m_pWindow->GetSettings();
2768 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2769 aStyleSettings.SetSelectionOptions(
2770 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2771 aSettings.SetStyleSettings(aStyleSettings);
2772 m_pWindow->SetSettings(aSettings, true);
2774 if (!m_bFilterList)
2776 sal_Int16 nLines = ::comphelper::getINT16(xModel->getPropertyValue(FM_PROP_LINECOUNT));
2777 Any aItems = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST);
2778 SetList(aItems, m_nControlClass == ::com::sun::star::form::FormComponentType::COMBOBOX);
2779 static_cast<ComboBox*>(m_pWindow.get())->SetDropDownLineCount(nLines);
2781 else
2782 static_cast<ComboBox*>(m_pWindow.get())->SetDropDownLineCount(5);
2784 } break;
2785 default:
2787 m_pWindow = VclPtr<Edit>::Create(pParent, WB_LEFT);
2788 AllSettings aSettings = m_pWindow->GetSettings();
2789 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2790 aStyleSettings.SetSelectionOptions(
2791 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2792 aSettings.SetStyleSettings(aStyleSettings);
2793 m_pWindow->SetSettings(aSettings, true);
2799 void DbFilterField::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor )
2801 Reference< ::com::sun::star::beans::XPropertySet > xModel(m_rColumn.getModel());
2802 m_rColumn.SetAlignment(::com::sun::star::awt::TextAlign::LEFT);
2804 if (xModel.is())
2806 m_bFilterList = ::comphelper::hasProperty(FM_PROP_FILTERPROPOSAL, xModel) && ::comphelper::getBOOL(xModel->getPropertyValue(FM_PROP_FILTERPROPOSAL));
2807 if (m_bFilterList)
2808 m_nControlClass = ::com::sun::star::form::FormComponentType::COMBOBOX;
2809 else
2811 sal_Int16 nClassId = ::comphelper::getINT16(xModel->getPropertyValue(FM_PROP_CLASSID));
2812 switch (nClassId)
2814 case FormComponentType::CHECKBOX:
2815 case FormComponentType::LISTBOX:
2816 case FormComponentType::COMBOBOX:
2817 m_nControlClass = nClassId;
2818 break;
2819 default:
2820 if (m_bFilterList)
2821 m_nControlClass = FormComponentType::COMBOBOX;
2822 else
2823 m_nControlClass = FormComponentType::TEXTFIELD;
2828 CreateControl( &rParent, xModel );
2829 DbCellControl::Init( rParent, xCursor );
2831 // filter cells are never readonly
2832 Edit* pAsEdit = dynamic_cast< Edit* >( m_pWindow.get() );
2833 if ( pAsEdit )
2834 pAsEdit->SetReadOnly( false );
2838 CellControllerRef DbFilterField::CreateController() const
2840 CellControllerRef xController;
2841 switch (m_nControlClass)
2843 case ::com::sun::star::form::FormComponentType::CHECKBOX:
2844 xController = new CheckBoxCellController(static_cast<CheckBoxControl*>(m_pWindow.get()));
2845 break;
2846 case ::com::sun::star::form::FormComponentType::LISTBOX:
2847 xController = new ListBoxCellController(static_cast<ListBoxControl*>(m_pWindow.get()));
2848 break;
2849 case ::com::sun::star::form::FormComponentType::COMBOBOX:
2850 xController = new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2851 break;
2852 default:
2853 if (m_bFilterList)
2854 xController = new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2855 else
2856 xController = new EditCellController(static_cast<Edit*>(m_pWindow.get()));
2858 return xController;
2862 void DbFilterField::updateFromModel( Reference< XPropertySet > _rxModel )
2864 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbFilterField::updateFromModel: invalid call!" );
2865 (void)_rxModel;
2867 OSL_FAIL( "DbListBox::updateFromModel: not implemented yet (how the hell did you reach this?)!" );
2868 // TODO: implement this.
2869 // remember: updateFromModel should be some kind of opposite of commitControl
2873 bool DbFilterField::commitControl()
2875 OUString aText(m_aText);
2876 switch (m_nControlClass)
2878 case ::com::sun::star::form::FormComponentType::CHECKBOX:
2879 return true;
2880 case ::com::sun::star::form::FormComponentType::LISTBOX:
2881 aText.clear();
2882 if (static_cast<ListBox*>(m_pWindow.get())->GetSelectEntryCount())
2884 sal_Int16 nPos = (sal_Int16)static_cast<ListBox*>(m_pWindow.get())->GetSelectEntryPos();
2885 if ( ( nPos >= 0 ) && ( nPos < m_aValueList.getLength() ) )
2886 aText = m_aValueList.getConstArray()[nPos];
2889 if (m_aText != aText)
2891 m_aText = aText;
2892 m_aCommitLink.Call(this);
2894 return true;
2895 default:
2896 aText = m_pWindow->GetText();
2899 if (m_aText != aText)
2901 // check the text with the SQL-Parser
2902 OUString aNewText(comphelper::string::stripEnd(aText, ' '));
2903 if (!aNewText.isEmpty())
2905 OUString aErrorMsg;
2906 Reference< XNumberFormatter > xNumberFormatter(m_rColumn.GetParent().getNumberFormatter());
2908 std::shared_ptr< OSQLParseNode > pParseNode = predicateTree(aErrorMsg, aNewText,xNumberFormatter, m_rColumn.GetField());
2909 if (pParseNode != nullptr)
2911 OUString aPreparedText;
2913 ::com::sun::star::lang::Locale aAppLocale = Application::GetSettings().GetUILanguageTag().getLocale();
2915 Reference< XRowSet > xDataSourceRowSet(
2916 Reference< XInterface >(*m_rColumn.GetParent().getDataSource()), UNO_QUERY);
2917 Reference< XConnection > xConnection(getConnection(xDataSourceRowSet));
2919 pParseNode->parseNodeToPredicateStr(aPreparedText,
2920 xConnection,
2921 xNumberFormatter,
2922 m_rColumn.GetField(),
2923 OUString(),
2924 aAppLocale,
2925 '.',
2926 getParseContext());
2927 m_aText = aPreparedText;
2929 else
2932 SQLException aError;
2933 aError.Message = aErrorMsg;
2934 displayException(aError, m_pWindow->GetParent());
2935 // TODO: transport the title
2937 return false;
2940 else
2941 m_aText = aText;
2943 m_pWindow->SetText(m_aText);
2944 m_aCommitLink.Call(this);
2946 return true;
2950 void DbFilterField::SetText(const OUString& rText)
2952 m_aText = rText;
2953 switch (m_nControlClass)
2955 case ::com::sun::star::form::FormComponentType::CHECKBOX:
2957 TriState eState;
2958 if (rText == "1")
2959 eState = TRISTATE_TRUE;
2960 else if (rText == "0")
2961 eState = TRISTATE_FALSE;
2962 else
2963 eState = TRISTATE_INDET;
2965 static_cast<CheckBoxControl*>(m_pWindow.get())->GetBox().SetState(eState);
2966 static_cast<CheckBoxControl*>(m_pPainter.get())->GetBox().SetState(eState);
2967 } break;
2968 case ::com::sun::star::form::FormComponentType::LISTBOX:
2970 Sequence<sal_Int16> aPosSeq = ::comphelper::findValue(m_aValueList, m_aText, true);
2971 if (aPosSeq.getLength())
2972 static_cast<ListBox*>(m_pWindow.get())->SelectEntryPos(aPosSeq.getConstArray()[0], true);
2973 else
2974 static_cast<ListBox*>(m_pWindow.get())->SetNoSelection();
2975 } break;
2976 default:
2977 m_pWindow->SetText(m_aText);
2980 // now force a repaint on the window
2981 m_rColumn.GetParent().RowModified(0,m_rColumn.GetId());
2985 void DbFilterField::Update()
2987 // should we fill the combobox with a filter proposal?
2988 if (m_bFilterList && !m_bFilterListFilled)
2990 m_bFilterListFilled = true;
2991 Reference< ::com::sun::star::beans::XPropertySet > xField = m_rColumn.GetField();
2992 if (!xField.is())
2993 return;
2995 OUString aName;
2996 xField->getPropertyValue(FM_PROP_NAME) >>= aName;
2998 // the columnmodel
2999 Reference< ::com::sun::star::container::XChild > xModelAsChild(m_rColumn.getModel(), UNO_QUERY);
3000 // the grid model
3001 xModelAsChild = Reference< ::com::sun::star::container::XChild > (xModelAsChild->getParent(),UNO_QUERY);
3002 Reference< XRowSet > xForm(xModelAsChild->getParent(), UNO_QUERY);
3003 if (!xForm.is())
3004 return;
3006 Reference<XPropertySet> xFormProp(xForm,UNO_QUERY);
3007 Reference< XTablesSupplier > xSupTab;
3008 xFormProp->getPropertyValue("SingleSelectQueryComposer") >>= xSupTab;
3010 Reference< XConnection > xConnection(getConnection(xForm));
3011 if (!xSupTab.is())
3012 return;
3014 // search the field
3015 Reference< XColumnsSupplier > xSupCol(xSupTab,UNO_QUERY);
3016 Reference< ::com::sun::star::container::XNameAccess > xFieldNames = xSupCol->getColumns();
3017 if (!xFieldNames->hasByName(aName))
3018 return;
3020 Reference< ::com::sun::star::container::XNameAccess > xTablesNames = xSupTab->getTables();
3021 Reference< ::com::sun::star::beans::XPropertySet > xComposerFieldAsSet(xFieldNames->getByName(aName),UNO_QUERY);
3023 if (xComposerFieldAsSet.is() && ::comphelper::hasProperty(FM_PROP_TABLENAME, xComposerFieldAsSet) &&
3024 ::comphelper::hasProperty(FM_PROP_FIELDSOURCE, xComposerFieldAsSet))
3026 OUString aFieldName;
3027 OUString aTableName;
3028 xComposerFieldAsSet->getPropertyValue(FM_PROP_FIELDSOURCE) >>= aFieldName;
3029 xComposerFieldAsSet->getPropertyValue(FM_PROP_TABLENAME) >>= aTableName;
3031 // no possibility to create a select statement
3032 // looking for the complete table name
3033 if (!xTablesNames->hasByName(aTableName))
3034 return;
3036 // ein Statement aufbauen und abschicken als query
3037 // Access to the connection
3038 Reference< XStatement > xStatement;
3039 Reference< XResultSet > xListCursor;
3040 Reference< ::com::sun::star::sdb::XColumn > xDataField;
3044 Reference< XDatabaseMetaData > xMeta = xConnection->getMetaData();
3046 OUString aQuote(xMeta->getIdentifierQuoteString());
3047 OUStringBuffer aStatement("SELECT DISTINCT ");
3048 aStatement.append(quoteName(aQuote, aName));
3049 if (!aFieldName.isEmpty() && aName != aFieldName)
3051 aStatement.append(" AS ");
3052 aStatement.append(quoteName(aQuote, aFieldName));
3055 aStatement.append(" FROM ");
3057 Reference< XPropertySet > xTableNameAccess(xTablesNames->getByName(aTableName), UNO_QUERY_THROW);
3058 aStatement.append(composeTableNameForSelect(xConnection, xTableNameAccess));
3060 xStatement = xConnection->createStatement();
3061 Reference< ::com::sun::star::beans::XPropertySet > xStatementProps(xStatement, UNO_QUERY);
3062 xStatementProps->setPropertyValue(FM_PROP_ESCAPE_PROCESSING, makeAny(true));
3064 xListCursor = xStatement->executeQuery(aStatement.makeStringAndClear());
3066 Reference< ::com::sun::star::sdbcx::XColumnsSupplier > xSupplyCols(xListCursor, UNO_QUERY);
3067 Reference< ::com::sun::star::container::XIndexAccess > xFields(xSupplyCols->getColumns(), UNO_QUERY);
3068 xDataField.set(xFields->getByIndex(0), css::uno::UNO_QUERY);
3069 if (!xDataField.is())
3070 return;
3072 catch(const Exception&)
3074 ::comphelper::disposeComponent(xStatement);
3075 return;
3078 sal_Int16 i = 0;
3079 ::std::vector< OUString > aStringList;
3080 aStringList.reserve(16);
3081 OUString aStr;
3082 com::sun::star::util::Date aNullDate = m_rColumn.GetParent().getNullDate();
3083 sal_Int32 nFormatKey = m_rColumn.GetKey();
3084 Reference< XNumberFormatter > xFormatter = m_rColumn.GetParent().getNumberFormatter();
3085 sal_Int16 nKeyType = ::comphelper::getNumberFormatType(xFormatter->getNumberFormatsSupplier()->getNumberFormats(), nFormatKey);
3087 while (!xListCursor->isAfterLast() && i++ < SHRT_MAX) // max anzahl eintraege
3089 aStr = getFormattedValue(xDataField, xFormatter, aNullDate, nFormatKey, nKeyType);
3090 aStringList.push_back(aStr);
3091 (void)xListCursor->next();
3094 // filling the entries for the combobox
3095 for (::std::vector< OUString >::const_iterator iter = aStringList.begin();
3096 iter != aStringList.end(); ++iter)
3097 static_cast<ComboBox*>(m_pWindow.get())->InsertEntry(*iter, LISTBOX_APPEND);
3103 OUString DbFilterField::GetFormatText(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
3105 return OUString();
3109 void DbFilterField::UpdateFromField(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/)
3111 OSL_FAIL( "DbFilterField::UpdateFromField: cannot update a filter control from a field!" );
3115 IMPL_LINK_NOARG(DbFilterField, OnClick)
3117 TriState eState = static_cast<CheckBoxControl*>(m_pWindow.get())->GetBox().GetState();
3118 OUString aText;
3120 switch (eState)
3122 case TRISTATE_TRUE:
3123 aText = "1";
3124 break;
3125 case TRISTATE_FALSE:
3126 aText = "0";
3127 break;
3128 case TRISTATE_INDET:
3129 break;
3132 if (m_aText != aText)
3134 m_aText = aText;
3135 m_aCommitLink.Call(this);
3137 return 1;
3140 TYPEINIT0(FmXGridCell);
3144 FmXGridCell::FmXGridCell( DbGridColumn* pColumn, DbCellControl* _pControl )
3145 :OComponentHelper(m_aMutex)
3146 ,m_pColumn(pColumn)
3147 ,m_pCellControl( _pControl )
3148 ,m_aWindowListeners( m_aMutex )
3149 ,m_aFocusListeners( m_aMutex )
3150 ,m_aKeyListeners( m_aMutex )
3151 ,m_aMouseListeners( m_aMutex )
3152 ,m_aMouseMotionListeners( m_aMutex )
3157 void FmXGridCell::init()
3159 vcl::Window* pEventWindow( getEventWindow() );
3160 if ( pEventWindow )
3161 pEventWindow->AddEventListener( LINK( this, FmXGridCell, OnWindowEvent ) );
3165 vcl::Window* FmXGridCell::getEventWindow() const
3167 if ( m_pCellControl )
3168 return &m_pCellControl->GetWindow();
3169 return NULL;
3173 FmXGridCell::~FmXGridCell()
3175 if (!OComponentHelper::rBHelper.bDisposed)
3177 acquire();
3178 dispose();
3184 void FmXGridCell::SetTextLineColor()
3186 if (m_pCellControl)
3187 m_pCellControl->SetTextLineColor();
3191 void FmXGridCell::SetTextLineColor(const Color& _rColor)
3193 if (m_pCellControl)
3194 m_pCellControl->SetTextLineColor(_rColor);
3197 // XTypeProvider
3199 Sequence< Type > SAL_CALL FmXGridCell::getTypes( ) throw (RuntimeException, std::exception)
3201 Sequence< uno::Type > aTypes = ::comphelper::concatSequences(
3202 ::cppu::OComponentHelper::getTypes(),
3203 FmXGridCell_Base::getTypes()
3205 if ( m_pCellControl )
3206 aTypes = ::comphelper::concatSequences(
3207 aTypes,
3208 FmXGridCell_WindowBase::getTypes()
3210 return aTypes;
3214 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXGridCell )
3216 // OComponentHelper
3218 void FmXGridCell::disposing()
3220 lang::EventObject aEvent( *this );
3221 m_aWindowListeners.disposeAndClear( aEvent );
3222 m_aFocusListeners.disposeAndClear( aEvent );
3223 m_aKeyListeners.disposeAndClear( aEvent );
3224 m_aMouseListeners.disposeAndClear( aEvent );
3225 m_aMouseMotionListeners.disposeAndClear( aEvent );
3227 OComponentHelper::disposing();
3228 m_pColumn = NULL;
3229 DELETEZ(m_pCellControl);
3233 Any SAL_CALL FmXGridCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException, std::exception)
3235 Any aReturn = OComponentHelper::queryAggregation( _rType );
3237 if ( !aReturn.hasValue() )
3238 aReturn = FmXGridCell_Base::queryInterface( _rType );
3240 if ( !aReturn.hasValue() && ( m_pCellControl != NULL ) )
3241 aReturn = FmXGridCell_WindowBase::queryInterface( _rType );
3243 return aReturn;
3246 // ::com::sun::star::awt::XControl
3248 Reference< XInterface > FmXGridCell::getContext() throw( RuntimeException, std::exception )
3250 return Reference< XInterface > ();
3254 Reference< ::com::sun::star::awt::XControlModel > FmXGridCell::getModel() throw( ::com::sun::star::uno::RuntimeException, std::exception )
3256 return Reference< ::com::sun::star::awt::XControlModel > (m_pColumn->getModel(), UNO_QUERY);
3259 // ::com::sun::star::form::XBoundControl
3261 sal_Bool FmXGridCell::getLock() throw( RuntimeException, std::exception )
3263 return m_pColumn->isLocked();
3267 void FmXGridCell::setLock(sal_Bool _bLock) throw( RuntimeException, std::exception )
3269 if (getLock() == _bLock)
3270 return;
3271 else
3273 ::osl::MutexGuard aGuard(m_aMutex);
3274 m_pColumn->setLock(_bLock);
3279 void SAL_CALL FmXGridCell::setPosSize( ::sal_Int32 _XX, ::sal_Int32 _Y, ::sal_Int32 _Width, ::sal_Int32 _Height, ::sal_Int16 _Flags ) throw (RuntimeException, std::exception)
3281 OSL_FAIL( "FmXGridCell::setPosSize: not implemented" );
3282 (void)_XX;
3283 (void)_Y;
3284 (void)_Width;
3285 (void)_Height;
3286 (void)_Flags;
3287 // not allowed to tamper with this for a grid cell
3291 awt::Rectangle SAL_CALL FmXGridCell::getPosSize( ) throw (RuntimeException, std::exception)
3293 OSL_FAIL( "FmXGridCell::getPosSize: not implemented" );
3294 return awt::Rectangle();
3298 void SAL_CALL FmXGridCell::setVisible( sal_Bool _Visible ) throw (RuntimeException, std::exception)
3300 OSL_FAIL( "FmXGridCell::setVisible: not implemented" );
3301 (void)_Visible;
3302 // not allowed to tamper with this for a grid cell
3306 void SAL_CALL FmXGridCell::setEnable( sal_Bool _Enable ) throw (RuntimeException, std::exception)
3308 OSL_FAIL( "FmXGridCell::setEnable: not implemented" );
3309 (void)_Enable;
3310 // not allowed to tamper with this for a grid cell
3314 void SAL_CALL FmXGridCell::setFocus( ) throw (RuntimeException, std::exception)
3316 OSL_FAIL( "FmXGridCell::setFocus: not implemented" );
3317 // not allowed to tamper with this for a grid cell
3321 void SAL_CALL FmXGridCell::addWindowListener( const Reference< awt::XWindowListener >& _rxListener ) throw (RuntimeException, std::exception)
3323 m_aWindowListeners.addInterface( _rxListener );
3327 void SAL_CALL FmXGridCell::removeWindowListener( const Reference< awt::XWindowListener >& _rxListener ) throw (RuntimeException, std::exception)
3329 m_aWindowListeners.removeInterface( _rxListener );
3333 void SAL_CALL FmXGridCell::addFocusListener( const Reference< awt::XFocusListener >& _rxListener ) throw (RuntimeException, std::exception)
3335 m_aFocusListeners.addInterface( _rxListener );
3339 void SAL_CALL FmXGridCell::removeFocusListener( const Reference< awt::XFocusListener >& _rxListener ) throw (RuntimeException, std::exception)
3341 m_aFocusListeners.removeInterface( _rxListener );
3345 void SAL_CALL FmXGridCell::addKeyListener( const Reference< awt::XKeyListener >& _rxListener ) throw (RuntimeException, std::exception)
3347 m_aKeyListeners.addInterface( _rxListener );
3351 void SAL_CALL FmXGridCell::removeKeyListener( const Reference< awt::XKeyListener >& _rxListener ) throw (RuntimeException, std::exception)
3353 m_aKeyListeners.removeInterface( _rxListener );
3357 void SAL_CALL FmXGridCell::addMouseListener( const Reference< awt::XMouseListener >& _rxListener ) throw (RuntimeException, std::exception)
3359 m_aMouseListeners.addInterface( _rxListener );
3363 void SAL_CALL FmXGridCell::removeMouseListener( const Reference< awt::XMouseListener >& _rxListener ) throw (RuntimeException, std::exception)
3365 m_aMouseListeners.removeInterface( _rxListener );
3369 void SAL_CALL FmXGridCell::addMouseMotionListener( const Reference< awt::XMouseMotionListener >& _rxListener ) throw (RuntimeException, std::exception)
3371 m_aMouseMotionListeners.addInterface( _rxListener );
3375 void SAL_CALL FmXGridCell::removeMouseMotionListener( const Reference< awt::XMouseMotionListener >& _rxListener ) throw (RuntimeException, std::exception)
3377 m_aMouseMotionListeners.removeInterface( _rxListener );
3381 void SAL_CALL FmXGridCell::addPaintListener( const Reference< awt::XPaintListener >& _rxListener ) throw (RuntimeException, std::exception)
3383 OSL_FAIL( "FmXGridCell::addPaintListener: not implemented" );
3384 (void)_rxListener;
3388 void SAL_CALL FmXGridCell::removePaintListener( const Reference< awt::XPaintListener >& _rxListener ) throw (RuntimeException, std::exception)
3390 OSL_FAIL( "FmXGridCell::removePaintListener: not implemented" );
3391 (void)_rxListener;
3395 IMPL_LINK( FmXGridCell, OnWindowEvent, VclWindowEvent*, _pEvent )
3397 ENSURE_OR_THROW( _pEvent, "illegal event pointer" );
3398 ENSURE_OR_THROW( _pEvent->GetWindow(), "illegal window" );
3399 onWindowEvent( _pEvent->GetId(), *_pEvent->GetWindow(), _pEvent->GetData() );
3400 return 1L;
3404 void FmXGridCell::onFocusGained( const awt::FocusEvent& _rEvent )
3406 m_aFocusListeners.notifyEach( &awt::XFocusListener::focusGained, _rEvent );
3410 void FmXGridCell::onFocusLost( const awt::FocusEvent& _rEvent )
3412 m_aFocusListeners.notifyEach( &awt::XFocusListener::focusLost, _rEvent );
3416 void FmXGridCell::onWindowEvent( const sal_uIntPtr _nEventId, const vcl::Window& _rWindow, const void* _pEventData )
3418 switch ( _nEventId )
3420 case VCLEVENT_CONTROL_GETFOCUS:
3421 case VCLEVENT_WINDOW_GETFOCUS:
3422 case VCLEVENT_CONTROL_LOSEFOCUS:
3423 case VCLEVENT_WINDOW_LOSEFOCUS:
3425 if ( ( _rWindow.IsCompoundControl()
3426 && ( _nEventId == VCLEVENT_CONTROL_GETFOCUS
3427 || _nEventId == VCLEVENT_CONTROL_LOSEFOCUS
3430 || ( !_rWindow.IsCompoundControl()
3431 && ( _nEventId == VCLEVENT_WINDOW_GETFOCUS
3432 || _nEventId == VCLEVENT_WINDOW_LOSEFOCUS
3437 if ( !m_aFocusListeners.getLength() )
3438 break;
3440 bool bFocusGained = ( _nEventId == VCLEVENT_CONTROL_GETFOCUS ) || ( _nEventId == VCLEVENT_WINDOW_GETFOCUS );
3442 awt::FocusEvent aEvent;
3443 aEvent.Source = *this;
3444 aEvent.FocusFlags = _rWindow.GetGetFocusFlags();
3445 aEvent.Temporary = sal_False;
3447 if ( bFocusGained )
3448 onFocusGained( aEvent );
3449 else
3450 onFocusLost( aEvent );
3453 break;
3454 case VCLEVENT_WINDOW_MOUSEBUTTONDOWN:
3455 case VCLEVENT_WINDOW_MOUSEBUTTONUP:
3457 if ( !m_aMouseListeners.getLength() )
3458 break;
3460 const bool bButtonDown = ( _nEventId == VCLEVENT_WINDOW_MOUSEBUTTONDOWN );
3462 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast< const ::MouseEvent* >( _pEventData ), *this ) );
3463 m_aMouseListeners.notifyEach( bButtonDown ? &awt::XMouseListener::mousePressed : &awt::XMouseListener::mouseReleased, aEvent );
3465 break;
3466 case VCLEVENT_WINDOW_MOUSEMOVE:
3468 const MouseEvent& rMouseEvent = *static_cast< const ::MouseEvent* >( _pEventData );
3469 if ( rMouseEvent.IsEnterWindow() || rMouseEvent.IsLeaveWindow() )
3471 if ( m_aMouseListeners.getLength() != 0 )
3473 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
3474 m_aMouseListeners.notifyEach( rMouseEvent.IsEnterWindow() ? &awt::XMouseListener::mouseEntered: &awt::XMouseListener::mouseExited, aEvent );
3477 else if ( !rMouseEvent.IsEnterWindow() && !rMouseEvent.IsLeaveWindow() )
3479 if ( m_aMouseMotionListeners.getLength() != 0 )
3481 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
3482 aEvent.ClickCount = 0;
3483 const bool bSimpleMove = bool( rMouseEvent.GetMode() & MouseEventModifiers::SIMPLEMOVE );
3484 m_aMouseMotionListeners.notifyEach( bSimpleMove ? &awt::XMouseMotionListener::mouseMoved: &awt::XMouseMotionListener::mouseDragged, aEvent );
3488 break;
3489 case VCLEVENT_WINDOW_KEYINPUT:
3490 case VCLEVENT_WINDOW_KEYUP:
3492 if ( !m_aKeyListeners.getLength() )
3493 break;
3495 const bool bKeyPressed = ( _nEventId == VCLEVENT_WINDOW_KEYINPUT );
3496 awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent( *static_cast< const ::KeyEvent* >( _pEventData ), *this ) );
3497 m_aKeyListeners.notifyEach( bKeyPressed ? &awt::XKeyListener::keyPressed: &awt::XKeyListener::keyReleased, aEvent );
3499 break;
3503 TYPEINIT1(FmXDataCell, FmXGridCell);
3505 void FmXDataCell::PaintFieldToCell(OutputDevice& rDev, const Rectangle& rRect,
3506 const Reference< ::com::sun::star::sdb::XColumn >& _rxField,
3507 const Reference< XNumberFormatter >& xFormatter)
3509 m_pCellControl->PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
3513 void FmXDataCell::UpdateFromColumn()
3515 Reference< ::com::sun::star::sdb::XColumn > xField(m_pColumn->GetCurrentFieldValue());
3516 if (xField.is())
3517 m_pCellControl->UpdateFromField(xField, m_pColumn->GetParent().getNumberFormatter());
3520 TYPEINIT1(FmXTextCell, FmXDataCell);
3522 FmXTextCell::FmXTextCell( DbGridColumn* pColumn, DbCellControl& _rControl )
3523 :FmXDataCell( pColumn, _rControl )
3524 ,m_bFastPaint( true )
3529 void FmXTextCell::PaintFieldToCell(OutputDevice& rDev,
3530 const Rectangle& rRect,
3531 const Reference< ::com::sun::star::sdb::XColumn >& _rxField,
3532 const Reference< XNumberFormatter >& xFormatter)
3534 if ( !m_bFastPaint )
3536 FmXDataCell::PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
3537 return;
3540 DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::VCenter;
3541 if ( ( rDev.GetOutDevType() == OUTDEV_WINDOW ) && !static_cast< vcl::Window& >( rDev ).IsEnabled() )
3542 nStyle |= DrawTextFlags::Disable;
3544 switch (m_pColumn->GetAlignment())
3546 case ::com::sun::star::awt::TextAlign::RIGHT:
3547 nStyle |= DrawTextFlags::Right;
3548 break;
3549 case ::com::sun::star::awt::TextAlign::CENTER:
3550 nStyle |= DrawTextFlags::Center;
3551 break;
3552 default:
3553 nStyle |= DrawTextFlags::Left;
3556 Color* pColor = NULL;
3557 OUString aText = GetText(_rxField, xFormatter, &pColor);
3558 if (pColor != NULL)
3560 Color aOldTextColor( rDev.GetTextColor() );
3561 rDev.SetTextColor( *pColor );
3562 rDev.DrawText(rRect, aText, nStyle);
3563 rDev.SetTextColor( aOldTextColor );
3565 else
3566 rDev.DrawText(rRect, aText, nStyle);
3569 FmXEditCell::FmXEditCell( DbGridColumn* pColumn, DbCellControl& _rControl )
3570 :FmXTextCell( pColumn, _rControl )
3571 ,m_aTextListeners(m_aMutex)
3572 ,m_aChangeListeners( m_aMutex )
3573 ,m_pEditImplementation( NULL )
3574 ,m_bOwnEditImplementation( false )
3577 DbTextField* pTextField = PTR_CAST( DbTextField, &_rControl );
3578 if ( pTextField )
3581 m_pEditImplementation = pTextField->GetEditImplementation();
3582 if ( !pTextField->IsSimpleEdit() )
3583 m_bFastPaint = false;
3585 else
3587 m_pEditImplementation = new EditImplementation( static_cast< Edit& >( _rControl.GetWindow() ) );
3588 m_bOwnEditImplementation = true;
3593 FmXEditCell::~FmXEditCell()
3595 if (!OComponentHelper::rBHelper.bDisposed)
3597 acquire();
3598 dispose();
3604 // OComponentHelper
3606 void FmXEditCell::disposing()
3608 ::com::sun::star::lang::EventObject aEvt(*this);
3609 m_aTextListeners.disposeAndClear(aEvt);
3610 m_aChangeListeners.disposeAndClear(aEvt);
3612 m_pEditImplementation->SetModifyHdl( Link<>() );
3613 if ( m_bOwnEditImplementation )
3614 delete m_pEditImplementation;
3615 m_pEditImplementation = NULL;
3617 FmXDataCell::disposing();
3621 Any SAL_CALL FmXEditCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException, std::exception)
3623 Any aReturn = FmXTextCell::queryAggregation( _rType );
3625 if ( !aReturn.hasValue() )
3626 aReturn = FmXEditCell_Base::queryInterface( _rType );
3628 return aReturn;
3632 Sequence< ::com::sun::star::uno::Type > SAL_CALL FmXEditCell::getTypes( ) throw(RuntimeException, std::exception)
3634 return ::comphelper::concatSequences(
3635 FmXTextCell::getTypes(),
3636 FmXEditCell_Base::getTypes()
3641 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXEditCell )
3643 // ::com::sun::star::awt::XTextComponent
3645 void SAL_CALL FmXEditCell::addTextListener(const Reference< ::com::sun::star::awt::XTextListener >& l) throw( RuntimeException, std::exception )
3647 m_aTextListeners.addInterface( l );
3651 void SAL_CALL FmXEditCell::removeTextListener(const Reference< ::com::sun::star::awt::XTextListener >& l) throw( RuntimeException, std::exception )
3653 m_aTextListeners.removeInterface( l );
3657 void SAL_CALL FmXEditCell::setText( const OUString& aText ) throw( RuntimeException, std::exception )
3659 ::osl::MutexGuard aGuard( m_aMutex );
3661 if ( m_pEditImplementation )
3663 m_pEditImplementation->SetText( aText );
3665 // In JAVA wird auch ein textChanged ausgeloest, in VCL nicht.
3666 // ::com::sun::star::awt::Toolkit soll JAVA-komform sein...
3667 onTextChanged();
3672 void SAL_CALL FmXEditCell::insertText(const ::com::sun::star::awt::Selection& rSel, const OUString& aText) throw(RuntimeException, std::exception)
3674 ::osl::MutexGuard aGuard( m_aMutex );
3676 if ( m_pEditImplementation )
3678 m_pEditImplementation->SetSelection( Selection( rSel.Min, rSel.Max ) );
3679 m_pEditImplementation->ReplaceSelected( aText );
3684 OUString SAL_CALL FmXEditCell::getText() throw( RuntimeException, std::exception )
3686 ::osl::MutexGuard aGuard( m_aMutex );
3688 OUString aText;
3689 if ( m_pEditImplementation )
3691 if ( m_pEditImplementation->GetControl().IsVisible() && m_pColumn->GetParent().getDisplaySynchron())
3693 // if the display isn't sync with the cursor we can't ask the edit field
3694 LineEnd eLineEndFormat = getModelLineEndSetting( m_pColumn->getModel() );
3695 aText = m_pEditImplementation->GetText( eLineEndFormat );
3697 else
3699 Reference< ::com::sun::star::sdb::XColumn > xField(m_pColumn->GetCurrentFieldValue());
3700 if (xField.is())
3701 aText = GetText(xField, m_pColumn->GetParent().getNumberFormatter());
3704 return aText;
3708 OUString SAL_CALL FmXEditCell::getSelectedText() throw( RuntimeException, std::exception )
3710 ::osl::MutexGuard aGuard( m_aMutex );
3712 OUString aText;
3713 if ( m_pEditImplementation )
3715 LineEnd eLineEndFormat = m_pColumn ? getModelLineEndSetting( m_pColumn->getModel() ) : LINEEND_LF;
3716 aText = m_pEditImplementation->GetSelected( eLineEndFormat );
3718 return aText;
3722 void SAL_CALL FmXEditCell::setSelection( const ::com::sun::star::awt::Selection& aSelection ) throw( RuntimeException, std::exception )
3724 ::osl::MutexGuard aGuard( m_aMutex );
3726 if ( m_pEditImplementation )
3727 m_pEditImplementation->SetSelection( Selection( aSelection.Min, aSelection.Max ) );
3731 ::com::sun::star::awt::Selection SAL_CALL FmXEditCell::getSelection() throw( RuntimeException, std::exception )
3733 ::osl::MutexGuard aGuard( m_aMutex );
3735 Selection aSel;
3736 if ( m_pEditImplementation )
3737 aSel = m_pEditImplementation->GetSelection();
3739 return ::com::sun::star::awt::Selection(aSel.Min(), aSel.Max());
3743 sal_Bool SAL_CALL FmXEditCell::isEditable() throw( RuntimeException, std::exception )
3745 ::osl::MutexGuard aGuard( m_aMutex );
3747 return ( m_pEditImplementation && !m_pEditImplementation->IsReadOnly() && m_pEditImplementation->GetControl().IsEnabled() ) ? sal_True : sal_False;
3751 void SAL_CALL FmXEditCell::setEditable( sal_Bool bEditable ) throw( RuntimeException, std::exception )
3753 ::osl::MutexGuard aGuard( m_aMutex );
3755 if ( m_pEditImplementation )
3756 m_pEditImplementation->SetReadOnly( !bEditable );
3760 sal_Int16 SAL_CALL FmXEditCell::getMaxTextLen() throw( RuntimeException, std::exception )
3762 ::osl::MutexGuard aGuard( m_aMutex );
3764 return m_pEditImplementation ? m_pEditImplementation->GetMaxTextLen() : 0;
3768 void SAL_CALL FmXEditCell::setMaxTextLen( sal_Int16 nLen ) throw( RuntimeException, std::exception )
3770 ::osl::MutexGuard aGuard( m_aMutex );
3772 if ( m_pEditImplementation )
3773 m_pEditImplementation->SetMaxTextLen( nLen );
3777 void SAL_CALL FmXEditCell::addChangeListener( const Reference< form::XChangeListener >& _Listener ) throw (RuntimeException, std::exception)
3779 m_aChangeListeners.addInterface( _Listener );
3783 void SAL_CALL FmXEditCell::removeChangeListener( const Reference< form::XChangeListener >& _Listener ) throw (RuntimeException, std::exception)
3785 m_aChangeListeners.removeInterface( _Listener );
3789 void FmXEditCell::onTextChanged()
3791 ::com::sun::star::awt::TextEvent aEvent;
3792 aEvent.Source = *this;
3793 m_aTextListeners.notifyEach( &awt::XTextListener::textChanged, aEvent );
3797 void FmXEditCell::onFocusGained( const awt::FocusEvent& _rEvent )
3799 FmXTextCell::onFocusGained( _rEvent );
3800 m_sValueOnEnter = getText();
3804 void FmXEditCell::onFocusLost( const awt::FocusEvent& _rEvent )
3806 FmXTextCell::onFocusLost( _rEvent );
3808 if ( getText() != m_sValueOnEnter )
3810 lang::EventObject aEvent( *this );
3811 m_aChangeListeners.notifyEach( &XChangeListener::changed, aEvent );
3816 void FmXEditCell::onWindowEvent( const sal_uIntPtr _nEventId, const vcl::Window& _rWindow, const void* _pEventData )
3818 switch ( _nEventId )
3820 case VCLEVENT_EDIT_MODIFY:
3822 if ( m_pEditImplementation && m_aTextListeners.getLength() )
3823 onTextChanged();
3824 return;
3828 FmXTextCell::onWindowEvent( _nEventId, _rWindow, _pEventData );
3831 FmXCheckBoxCell::FmXCheckBoxCell( DbGridColumn* pColumn, DbCellControl& _rControl )
3832 :FmXDataCell( pColumn, _rControl )
3833 ,m_aItemListeners(m_aMutex)
3834 ,m_aActionListeners( m_aMutex )
3835 ,m_pBox( & static_cast< CheckBoxControl& >( _rControl.GetWindow() ).GetBox() )
3840 FmXCheckBoxCell::~FmXCheckBoxCell()
3842 if (!OComponentHelper::rBHelper.bDisposed)
3844 acquire();
3845 dispose();
3850 // OComponentHelper
3852 void FmXCheckBoxCell::disposing()
3854 ::com::sun::star::lang::EventObject aEvt(*this);
3855 m_aItemListeners.disposeAndClear(aEvt);
3856 m_aActionListeners.disposeAndClear(aEvt);
3858 static_cast< CheckBoxControl& >( m_pCellControl->GetWindow() ).SetClickHdl(Link<>());
3859 m_pBox = NULL;
3861 FmXDataCell::disposing();
3865 Any SAL_CALL FmXCheckBoxCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException, std::exception)
3867 Any aReturn = FmXDataCell::queryAggregation( _rType );
3869 if ( !aReturn.hasValue() )
3870 aReturn = FmXCheckBoxCell_Base::queryInterface( _rType );
3872 return aReturn;
3876 Sequence< ::com::sun::star::uno::Type > SAL_CALL FmXCheckBoxCell::getTypes( ) throw(RuntimeException, std::exception)
3878 return ::comphelper::concatSequences(
3879 FmXDataCell::getTypes(),
3880 FmXCheckBoxCell_Base::getTypes()
3885 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXCheckBoxCell )
3888 void SAL_CALL FmXCheckBoxCell::addItemListener( const Reference< ::com::sun::star::awt::XItemListener >& l ) throw( RuntimeException, std::exception )
3890 m_aItemListeners.addInterface( l );
3894 void SAL_CALL FmXCheckBoxCell::removeItemListener( const Reference< ::com::sun::star::awt::XItemListener >& l ) throw( RuntimeException, std::exception )
3896 m_aItemListeners.removeInterface( l );
3900 void SAL_CALL FmXCheckBoxCell::setState( short n ) throw( RuntimeException, std::exception )
3902 ::osl::MutexGuard aGuard( m_aMutex );
3904 if (m_pBox)
3906 UpdateFromColumn();
3907 m_pBox->SetState( (TriState)n );
3912 short SAL_CALL FmXCheckBoxCell::getState() throw( RuntimeException, std::exception )
3914 ::osl::MutexGuard aGuard( m_aMutex );
3916 if (m_pBox)
3918 UpdateFromColumn();
3919 return (short)m_pBox->GetState();
3921 return TRISTATE_INDET;
3925 void SAL_CALL FmXCheckBoxCell::enableTriState( sal_Bool b ) throw( RuntimeException, std::exception )
3927 ::osl::MutexGuard aGuard( m_aMutex );
3929 if (m_pBox)
3930 m_pBox->EnableTriState( b );
3934 void SAL_CALL FmXCheckBoxCell::addActionListener( const Reference< awt::XActionListener >& _Listener ) throw (RuntimeException, std::exception)
3936 m_aActionListeners.addInterface( _Listener );
3940 void SAL_CALL FmXCheckBoxCell::removeActionListener( const Reference< awt::XActionListener >& _Listener ) throw (RuntimeException, std::exception)
3942 m_aActionListeners.removeInterface( _Listener );
3946 void SAL_CALL FmXCheckBoxCell::setLabel( const OUString& _Label ) throw (RuntimeException, std::exception)
3948 SolarMutexGuard aGuard;
3949 if ( m_pColumn )
3951 DbGridControl& rGrid( m_pColumn->GetParent() );
3952 rGrid.SetColumnTitle( rGrid.GetColumnId( m_pColumn->GetFieldPos() ), _Label );
3957 void SAL_CALL FmXCheckBoxCell::setActionCommand( const OUString& _Command ) throw (RuntimeException, std::exception)
3959 m_aActionCommand = _Command;
3963 vcl::Window* FmXCheckBoxCell::getEventWindow() const
3965 return m_pBox;
3969 void FmXCheckBoxCell::onWindowEvent( const sal_uIntPtr _nEventId, const vcl::Window& _rWindow, const void* _pEventData )
3971 switch ( _nEventId )
3973 case VCLEVENT_CHECKBOX_TOGGLE:
3975 // check boxes are to be committed immediately (this holds for ordinary check box controls in
3976 // documents, and this must hold for check boxes in grid columns, too
3977 // 91210 - 22.08.2001 - frank.schoenheit@sun.com
3978 m_pCellControl->Commit();
3980 Reference< XWindow > xKeepAlive( this );
3981 if ( m_aItemListeners.getLength() && m_pBox )
3983 awt::ItemEvent aEvent;
3984 aEvent.Source = *this;
3985 aEvent.Highlighted = 0;
3986 aEvent.Selected = m_pBox->GetState();
3987 m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
3989 if ( m_aActionListeners.getLength() )
3991 awt::ActionEvent aEvent;
3992 aEvent.Source = *this;
3993 aEvent.ActionCommand = m_aActionCommand;
3994 m_aActionListeners.notifyEach( &awt::XActionListener::actionPerformed, aEvent );
3997 break;
3999 default:
4000 FmXDataCell::onWindowEvent( _nEventId, _rWindow, _pEventData );
4001 break;
4005 FmXListBoxCell::FmXListBoxCell(DbGridColumn* pColumn, DbCellControl& _rControl)
4006 :FmXTextCell( pColumn, _rControl )
4007 ,m_aItemListeners(m_aMutex)
4008 ,m_aActionListeners(m_aMutex)
4009 ,m_pBox( &static_cast< ListBox& >( _rControl.GetWindow() ) )
4012 m_pBox->SetDoubleClickHdl( LINK( this, FmXListBoxCell, OnDoubleClick ) );
4016 FmXListBoxCell::~FmXListBoxCell()
4018 if (!OComponentHelper::rBHelper.bDisposed)
4020 acquire();
4021 dispose();
4026 // OComponentHelper
4028 void FmXListBoxCell::disposing()
4030 ::com::sun::star::lang::EventObject aEvt(*this);
4031 m_aItemListeners.disposeAndClear(aEvt);
4032 m_aActionListeners.disposeAndClear(aEvt);
4034 m_pBox->SetSelectHdl( Link<>() );
4035 m_pBox->SetDoubleClickHdl( Link<>() );
4036 m_pBox = NULL;
4038 FmXTextCell::disposing();
4042 Any SAL_CALL FmXListBoxCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException, std::exception)
4044 Any aReturn = FmXTextCell::queryAggregation(_rType);
4046 if ( !aReturn.hasValue() )
4047 aReturn = FmXListBoxCell_Base::queryInterface( _rType );
4049 return aReturn;
4053 Sequence< ::com::sun::star::uno::Type > SAL_CALL FmXListBoxCell::getTypes( ) throw(RuntimeException, std::exception)
4055 return ::comphelper::concatSequences(
4056 FmXTextCell::getTypes(),
4057 FmXListBoxCell_Base::getTypes()
4062 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXListBoxCell )
4065 void SAL_CALL FmXListBoxCell::addItemListener(const Reference< ::com::sun::star::awt::XItemListener >& l) throw( RuntimeException, std::exception )
4067 m_aItemListeners.addInterface( l );
4071 void SAL_CALL FmXListBoxCell::removeItemListener(const Reference< ::com::sun::star::awt::XItemListener >& l) throw( RuntimeException, std::exception )
4073 m_aItemListeners.removeInterface( l );
4077 void SAL_CALL FmXListBoxCell::addActionListener(const Reference< ::com::sun::star::awt::XActionListener >& l) throw( RuntimeException, std::exception )
4079 m_aActionListeners.addInterface( l );
4083 void SAL_CALL FmXListBoxCell::removeActionListener(const Reference< ::com::sun::star::awt::XActionListener >& l) throw( RuntimeException, std::exception )
4085 m_aActionListeners.removeInterface( l );
4089 void SAL_CALL FmXListBoxCell::addItem(const OUString& aItem, sal_Int16 nPos) throw( RuntimeException, std::exception )
4091 ::osl::MutexGuard aGuard( m_aMutex );
4092 if (m_pBox)
4093 m_pBox->InsertEntry( aItem, nPos );
4097 void SAL_CALL FmXListBoxCell::addItems(const ::comphelper::StringSequence& aItems, sal_Int16 nPos) throw( RuntimeException, std::exception )
4099 ::osl::MutexGuard aGuard( m_aMutex );
4100 if (m_pBox)
4102 sal_uInt16 nP = nPos;
4103 for ( sal_uInt16 n = 0; n < aItems.getLength(); n++ )
4105 m_pBox->InsertEntry( aItems.getConstArray()[n], nP );
4106 if ( nPos != -1 ) // Nicht wenn 0xFFFF, weil LIST_APPEND
4107 nP++;
4113 void SAL_CALL FmXListBoxCell::removeItems(sal_Int16 nPos, sal_Int16 nCount) throw( RuntimeException, std::exception )
4115 ::osl::MutexGuard aGuard( m_aMutex );
4116 if ( m_pBox )
4118 for ( sal_uInt16 n = nCount; n; )
4119 m_pBox->RemoveEntry( nPos + (--n) );
4124 sal_Int16 SAL_CALL FmXListBoxCell::getItemCount() throw( RuntimeException, std::exception )
4126 ::osl::MutexGuard aGuard( m_aMutex );
4127 return m_pBox ? m_pBox->GetEntryCount() : 0;
4131 OUString SAL_CALL FmXListBoxCell::getItem(sal_Int16 nPos) throw( RuntimeException, std::exception )
4133 ::osl::MutexGuard aGuard( m_aMutex );
4134 return m_pBox ? OUString(m_pBox->GetEntry(nPos)) : OUString();
4137 ::comphelper::StringSequence SAL_CALL FmXListBoxCell::getItems() throw( RuntimeException, std::exception )
4139 ::osl::MutexGuard aGuard( m_aMutex );
4141 ::comphelper::StringSequence aSeq;
4142 if (m_pBox)
4144 sal_uInt16 nEntries = m_pBox ->GetEntryCount();
4145 aSeq = ::comphelper::StringSequence( nEntries );
4146 for ( sal_uInt16 n = nEntries; n; )
4148 --n;
4149 aSeq.getArray()[n] = m_pBox ->GetEntry( n );
4152 return aSeq;
4156 sal_Int16 SAL_CALL FmXListBoxCell::getSelectedItemPos() throw( RuntimeException, std::exception )
4158 ::osl::MutexGuard aGuard( m_aMutex );
4159 if (m_pBox)
4161 UpdateFromColumn();
4162 sal_Int32 nPos = m_pBox->GetSelectEntryPos();
4163 if (nPos > SHRT_MAX || nPos < SHRT_MIN)
4164 throw std::out_of_range("awt::XListBox::getSelectedItemPos can only return a short");
4165 return nPos;
4167 return 0;
4171 Sequence< sal_Int16 > SAL_CALL FmXListBoxCell::getSelectedItemsPos() throw( RuntimeException, std::exception )
4173 ::osl::MutexGuard aGuard( m_aMutex );
4174 Sequence<sal_Int16> aSeq;
4176 if (m_pBox)
4178 UpdateFromColumn();
4179 sal_uInt16 nSelEntries = m_pBox->GetSelectEntryCount();
4180 aSeq = Sequence<sal_Int16>( nSelEntries );
4181 for ( sal_uInt16 n = 0; n < nSelEntries; n++ )
4182 aSeq.getArray()[n] = m_pBox->GetSelectEntryPos( n );
4184 return aSeq;
4187 OUString SAL_CALL FmXListBoxCell::getSelectedItem() throw( RuntimeException, std::exception )
4189 ::osl::MutexGuard aGuard( m_aMutex );
4191 OUString aItem;
4193 if (m_pBox)
4195 UpdateFromColumn();
4196 aItem = m_pBox->GetSelectEntry();
4199 return aItem;
4203 ::comphelper::StringSequence SAL_CALL FmXListBoxCell::getSelectedItems() throw( RuntimeException, std::exception )
4205 ::osl::MutexGuard aGuard( m_aMutex );
4207 ::comphelper::StringSequence aSeq;
4209 if (m_pBox)
4211 UpdateFromColumn();
4212 sal_uInt16 nSelEntries = m_pBox->GetSelectEntryCount();
4213 aSeq = ::comphelper::StringSequence( nSelEntries );
4214 for ( sal_uInt16 n = 0; n < nSelEntries; n++ )
4215 aSeq.getArray()[n] = m_pBox->GetSelectEntry( n );
4217 return aSeq;
4221 void SAL_CALL FmXListBoxCell::selectItemPos(sal_Int16 nPos, sal_Bool bSelect) throw( RuntimeException, std::exception )
4223 ::osl::MutexGuard aGuard( m_aMutex );
4225 if (m_pBox)
4226 m_pBox->SelectEntryPos( nPos, bSelect );
4230 void SAL_CALL FmXListBoxCell::selectItemsPos(const Sequence< sal_Int16 >& aPositions, sal_Bool bSelect) throw( RuntimeException, std::exception )
4232 ::osl::MutexGuard aGuard( m_aMutex );
4234 if (m_pBox)
4236 for ( sal_uInt16 n = (sal_uInt16)aPositions.getLength(); n; )
4237 m_pBox->SelectEntryPos( (sal_uInt16) aPositions.getConstArray()[--n], bSelect );
4242 void SAL_CALL FmXListBoxCell::selectItem(const OUString& aItem, sal_Bool bSelect) throw( RuntimeException, std::exception )
4244 ::osl::MutexGuard aGuard( m_aMutex );
4246 if (m_pBox)
4247 m_pBox->SelectEntry( aItem, bSelect );
4251 sal_Bool SAL_CALL FmXListBoxCell::isMutipleMode() throw( RuntimeException, std::exception )
4253 ::osl::MutexGuard aGuard( m_aMutex );
4255 bool bMulti = false;
4256 if (m_pBox)
4257 bMulti = m_pBox->IsMultiSelectionEnabled();
4258 return bMulti;
4262 void SAL_CALL FmXListBoxCell::setMultipleMode(sal_Bool bMulti) throw( RuntimeException, std::exception )
4264 ::osl::MutexGuard aGuard( m_aMutex );
4266 if (m_pBox)
4267 m_pBox->EnableMultiSelection( bMulti );
4271 sal_Int16 SAL_CALL FmXListBoxCell::getDropDownLineCount() throw( RuntimeException, std::exception )
4273 ::osl::MutexGuard aGuard( m_aMutex );
4275 sal_Int16 nLines = 0;
4276 if (m_pBox)
4277 nLines = m_pBox->GetDropDownLineCount();
4279 return nLines;
4283 void SAL_CALL FmXListBoxCell::setDropDownLineCount(sal_Int16 nLines) throw( RuntimeException, std::exception )
4285 ::osl::MutexGuard aGuard( m_aMutex );
4287 if (m_pBox)
4288 m_pBox->SetDropDownLineCount( nLines );
4292 void SAL_CALL FmXListBoxCell::makeVisible(sal_Int16 nEntry) throw( RuntimeException, std::exception )
4294 ::osl::MutexGuard aGuard( m_aMutex );
4296 if (m_pBox)
4297 m_pBox->SetTopEntry( nEntry );
4301 void FmXListBoxCell::onWindowEvent( const sal_uIntPtr _nEventId, const vcl::Window& _rWindow, const void* _pEventData )
4303 if ( ( &_rWindow == m_pBox )
4304 && ( _nEventId == VCLEVENT_LISTBOX_SELECT )
4307 OnDoubleClick( NULL );
4309 ::com::sun::star::awt::ItemEvent aEvent;
4310 aEvent.Source = *this;
4311 aEvent.Highlighted = 0;
4313 // Bei Mehrfachselektion 0xFFFF, sonst die ID
4314 aEvent.Selected = (m_pBox->GetSelectEntryCount() == 1 )
4315 ? m_pBox->GetSelectEntryPos() : 0xFFFF;
4317 m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4318 return;
4321 FmXTextCell::onWindowEvent( _nEventId, _rWindow, _pEventData );
4326 IMPL_LINK_NOARG(FmXListBoxCell, OnDoubleClick)
4328 if (m_pBox)
4330 ::cppu::OInterfaceIteratorHelper aIt( m_aActionListeners );
4332 ::com::sun::star::awt::ActionEvent aEvent;
4333 aEvent.Source = *this;
4334 aEvent.ActionCommand = m_pBox->GetSelectEntry();
4336 while( aIt.hasMoreElements() )
4337 static_cast< ::com::sun::star::awt::XActionListener *>(aIt.next())->actionPerformed( aEvent );
4339 return 1;
4342 FmXComboBoxCell::FmXComboBoxCell( DbGridColumn* pColumn, DbCellControl& _rControl )
4343 :FmXTextCell( pColumn, _rControl )
4344 ,m_aItemListeners( m_aMutex )
4345 ,m_aActionListeners( m_aMutex )
4346 ,m_pComboBox( &static_cast< ComboBox& >( _rControl.GetWindow() ) )
4351 FmXComboBoxCell::~FmXComboBoxCell()
4353 if ( !OComponentHelper::rBHelper.bDisposed )
4355 acquire();
4356 dispose();
4362 void FmXComboBoxCell::disposing()
4364 ::com::sun::star::lang::EventObject aEvt(*this);
4365 m_aItemListeners.disposeAndClear(aEvt);
4366 m_aActionListeners.disposeAndClear(aEvt);
4368 FmXTextCell::disposing();
4372 Any SAL_CALL FmXComboBoxCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException, std::exception)
4374 Any aReturn = FmXTextCell::queryAggregation(_rType);
4376 if ( !aReturn.hasValue() )
4377 aReturn = FmXComboBoxCell_Base::queryInterface( _rType );
4379 return aReturn;
4383 Sequence< Type > SAL_CALL FmXComboBoxCell::getTypes( ) throw(RuntimeException, std::exception)
4385 return ::comphelper::concatSequences(
4386 FmXTextCell::getTypes(),
4387 FmXComboBoxCell_Base::getTypes()
4392 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXComboBoxCell )
4395 void SAL_CALL FmXComboBoxCell::addItemListener(const Reference< awt::XItemListener >& l) throw( RuntimeException, std::exception )
4397 m_aItemListeners.addInterface( l );
4401 void SAL_CALL FmXComboBoxCell::removeItemListener(const Reference< awt::XItemListener >& l) throw( RuntimeException, std::exception )
4403 m_aItemListeners.removeInterface( l );
4407 void SAL_CALL FmXComboBoxCell::addActionListener(const Reference< awt::XActionListener >& l) throw( RuntimeException, std::exception )
4409 m_aActionListeners.addInterface( l );
4413 void SAL_CALL FmXComboBoxCell::removeActionListener(const Reference< awt::XActionListener >& l) throw( RuntimeException, std::exception )
4415 m_aActionListeners.removeInterface( l );
4419 void SAL_CALL FmXComboBoxCell::addItem( const OUString& _Item, sal_Int16 _Pos ) throw( RuntimeException, std::exception )
4421 ::osl::MutexGuard aGuard( m_aMutex );
4422 if ( m_pComboBox )
4423 m_pComboBox->InsertEntry( _Item, _Pos );
4427 void SAL_CALL FmXComboBoxCell::addItems( const Sequence< OUString >& _Items, sal_Int16 _Pos ) throw( RuntimeException, std::exception )
4429 ::osl::MutexGuard aGuard( m_aMutex );
4430 if ( m_pComboBox )
4432 sal_uInt16 nP = _Pos;
4433 for ( sal_uInt16 n = 0; n < _Items.getLength(); n++ )
4435 m_pComboBox->InsertEntry( _Items.getConstArray()[n], nP );
4436 if ( _Pos != -1 )
4437 nP++;
4443 void SAL_CALL FmXComboBoxCell::removeItems( sal_Int16 _Pos, sal_Int16 _Count ) throw( RuntimeException, std::exception )
4445 ::osl::MutexGuard aGuard( m_aMutex );
4446 if ( m_pComboBox )
4448 for ( sal_uInt16 n = _Count; n; )
4449 m_pComboBox->RemoveEntryAt( _Pos + (--n) );
4454 sal_Int16 SAL_CALL FmXComboBoxCell::getItemCount() throw( RuntimeException, std::exception )
4456 ::osl::MutexGuard aGuard( m_aMutex );
4457 return m_pComboBox ? m_pComboBox->GetEntryCount() : 0;
4461 OUString SAL_CALL FmXComboBoxCell::getItem( sal_Int16 _Pos ) throw( RuntimeException, std::exception )
4463 ::osl::MutexGuard aGuard( m_aMutex );
4464 return m_pComboBox ? OUString(m_pComboBox->GetEntry(_Pos)) : OUString();
4467 Sequence< OUString > SAL_CALL FmXComboBoxCell::getItems() throw( RuntimeException, std::exception )
4469 ::osl::MutexGuard aGuard( m_aMutex );
4471 Sequence< OUString > aItems;
4472 if ( m_pComboBox )
4474 sal_uInt16 nEntries = m_pComboBox->GetEntryCount();
4475 aItems.realloc( nEntries );
4476 OUString* pItem = aItems.getArray();
4477 for ( sal_uInt16 n=0; n<nEntries; ++n, ++pItem )
4478 *pItem = m_pComboBox->GetEntry( n );
4480 return aItems;
4484 sal_Int16 SAL_CALL FmXComboBoxCell::getDropDownLineCount() throw( RuntimeException, std::exception )
4486 ::osl::MutexGuard aGuard( m_aMutex );
4488 sal_Int16 nLines = 0;
4489 if ( m_pComboBox )
4490 nLines = m_pComboBox->GetDropDownLineCount();
4492 return nLines;
4496 void SAL_CALL FmXComboBoxCell::setDropDownLineCount(sal_Int16 nLines) throw( RuntimeException, std::exception )
4498 ::osl::MutexGuard aGuard( m_aMutex );
4499 if ( m_pComboBox )
4500 m_pComboBox->SetDropDownLineCount( nLines );
4504 void FmXComboBoxCell::onWindowEvent( const sal_uIntPtr _nEventId, const vcl::Window& _rWindow, const void* _pEventData )
4507 switch ( _nEventId )
4509 case VCLEVENT_COMBOBOX_SELECT:
4511 awt::ItemEvent aEvent;
4512 aEvent.Source = *this;
4513 aEvent.Highlighted = 0;
4515 // Bei Mehrfachselektion 0xFFFF, sonst die ID
4516 aEvent.Selected = ( m_pComboBox->GetSelectEntryCount() == 1 )
4517 ? m_pComboBox->GetSelectEntryPos()
4518 : 0xFFFF;
4519 m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4521 break;
4523 default:
4524 FmXTextCell::onWindowEvent( _nEventId, _rWindow, _pEventData );
4525 break;
4529 TYPEINIT1(FmXFilterCell, FmXGridCell);
4531 FmXFilterCell::FmXFilterCell(DbGridColumn* pColumn, DbCellControl* pControl )
4532 :FmXGridCell( pColumn, pControl )
4533 ,m_aTextListeners(m_aMutex)
4536 DBG_ASSERT( m_pCellControl->ISA( DbFilterField ), "FmXFilterCell::FmXFilterCell: invalid cell control!" );
4537 static_cast< DbFilterField* >( m_pCellControl )->SetCommitHdl( LINK( this, FmXFilterCell, OnCommit ) );
4541 FmXFilterCell::~FmXFilterCell()
4543 if (!OComponentHelper::rBHelper.bDisposed)
4545 acquire();
4546 dispose();
4551 // XUnoTunnel
4553 sal_Int64 SAL_CALL FmXFilterCell::getSomething( const Sequence< sal_Int8 >& _rIdentifier ) throw(RuntimeException, std::exception)
4555 sal_Int64 nReturn(0);
4557 if ( (_rIdentifier.getLength() == 16)
4558 && (0 == memcmp( getUnoTunnelId().getConstArray(), _rIdentifier.getConstArray(), 16 ))
4561 nReturn = reinterpret_cast<sal_Int64>(this);
4564 return nReturn;
4567 namespace
4569 class theFmXFilterCellUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theFmXFilterCellUnoTunnelId > {};
4572 const Sequence<sal_Int8>& FmXFilterCell::getUnoTunnelId()
4574 return theFmXFilterCellUnoTunnelId::get().getSeq();
4578 void FmXFilterCell::PaintCell( OutputDevice& rDev, const Rectangle& rRect )
4580 static_cast< DbFilterField* >( m_pCellControl )->PaintCell( rDev, rRect );
4583 // OComponentHelper
4585 void FmXFilterCell::disposing()
4587 ::com::sun::star::lang::EventObject aEvt(*this);
4588 m_aTextListeners.disposeAndClear(aEvt);
4590 static_cast<DbFilterField*>(m_pCellControl)->SetCommitHdl(Link<>());
4592 FmXGridCell::disposing();
4596 Any SAL_CALL FmXFilterCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException, std::exception)
4598 Any aReturn = FmXGridCell::queryAggregation(_rType);
4600 if ( !aReturn.hasValue() )
4601 aReturn = FmXFilterCell_Base::queryInterface( _rType );
4603 return aReturn;
4607 Sequence< ::com::sun::star::uno::Type > SAL_CALL FmXFilterCell::getTypes( ) throw(RuntimeException, std::exception)
4609 return ::comphelper::concatSequences(
4610 FmXGridCell::getTypes(),
4611 FmXFilterCell_Base::getTypes()
4616 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXFilterCell )
4618 // ::com::sun::star::awt::XTextComponent
4620 void SAL_CALL FmXFilterCell::addTextListener(const Reference< ::com::sun::star::awt::XTextListener >& l) throw( RuntimeException, std::exception )
4622 m_aTextListeners.addInterface( l );
4626 void SAL_CALL FmXFilterCell::removeTextListener(const Reference< ::com::sun::star::awt::XTextListener >& l) throw( RuntimeException, std::exception )
4628 m_aTextListeners.removeInterface( l );
4632 void SAL_CALL FmXFilterCell::setText( const OUString& aText ) throw( RuntimeException, std::exception )
4634 ::osl::MutexGuard aGuard( m_aMutex );
4635 static_cast<DbFilterField*>(m_pCellControl)->SetText(aText);
4639 void SAL_CALL FmXFilterCell::insertText( const ::com::sun::star::awt::Selection& /*rSel*/, const OUString& /*aText*/ ) throw( RuntimeException, std::exception )
4644 OUString SAL_CALL FmXFilterCell::getText() throw( RuntimeException, std::exception )
4646 ::osl::MutexGuard aGuard( m_aMutex );
4647 return static_cast<DbFilterField*>(m_pCellControl)->GetText();
4651 OUString SAL_CALL FmXFilterCell::getSelectedText() throw( RuntimeException, std::exception )
4653 return getText();
4657 void SAL_CALL FmXFilterCell::setSelection( const ::com::sun::star::awt::Selection& /*aSelection*/ ) throw( RuntimeException, std::exception )
4662 ::com::sun::star::awt::Selection SAL_CALL FmXFilterCell::getSelection() throw( RuntimeException, std::exception )
4664 return ::com::sun::star::awt::Selection();
4668 sal_Bool SAL_CALL FmXFilterCell::isEditable() throw( RuntimeException, std::exception )
4670 return sal_True;
4674 void SAL_CALL FmXFilterCell::setEditable( sal_Bool /*bEditable*/ ) throw( RuntimeException, std::exception )
4679 sal_Int16 SAL_CALL FmXFilterCell::getMaxTextLen() throw( RuntimeException, std::exception )
4681 return 0;
4685 void SAL_CALL FmXFilterCell::setMaxTextLen( sal_Int16 /*nLen*/ ) throw( RuntimeException, std::exception )
4690 IMPL_LINK_NOARG(FmXFilterCell, OnCommit)
4692 ::cppu::OInterfaceIteratorHelper aIt( m_aTextListeners );
4693 ::com::sun::star::awt::TextEvent aEvt;
4694 aEvt.Source = *this;
4695 while( aIt.hasMoreElements() )
4696 static_cast< ::com::sun::star::awt::XTextListener *>(aIt.next())->textChanged( aEvt );
4697 return 1;
4700 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */