bump product version to 5.0.4.1
[LibreOffice.git] / svx / source / fmcomp / gridcell.cxx
blobf82e42f67266ce66ee65db499c7d4c9714a8861e
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 );
575 implDoPropertyListening( FM_PROP_SELECT_SEQ, false );
576 implDoPropertyListening( FM_PROP_DATE, false );
577 implDoPropertyListening( FM_PROP_TIME, false );
579 // be listener at the bound field as well
582 Reference< XPropertySetInfo > xPSI( xColModelProps->getPropertySetInfo(), UNO_SET_THROW );
583 if ( xPSI->hasPropertyByName( FM_PROP_BOUNDFIELD ) )
585 Reference< XPropertySet > xField;
586 xColModelProps->getPropertyValue( FM_PROP_BOUNDFIELD ) >>= xField;
587 if ( xField.is() )
589 m_pFieldChangeBroadcaster = new ::comphelper::OPropertyChangeMultiplexer(this, xField);
590 m_pFieldChangeBroadcaster->acquire();
591 m_pFieldChangeBroadcaster->addProperty( FM_PROP_ISREADONLY );
595 catch( const Exception& )
597 OSL_FAIL( "DbCellControl::doPropertyListening: caught an exception!" );
598 DBG_UNHANDLED_EXCEPTION();
604 void DbCellControl::implDoPropertyListening(const OUString& _rPropertyName, bool _bWarnIfNotExistent)
608 Reference< XPropertySet > xColModelProps( m_rColumn.getModel(), UNO_QUERY );
609 Reference< XPropertySetInfo > xPSI;
610 if ( xColModelProps.is() )
611 xPSI = xColModelProps->getPropertySetInfo();
613 DBG_ASSERT( !_bWarnIfNotExistent || ( xPSI.is() && xPSI->hasPropertyByName( _rPropertyName ) ),
614 "DbCellControl::doPropertyListening: no property set info or non-existent property!" );
615 (void)_bWarnIfNotExistent;
617 if ( xPSI.is() && xPSI->hasPropertyByName( _rPropertyName ) )
618 m_pModelChangeBroadcaster->addProperty( _rPropertyName );
620 catch( const Exception& )
622 OSL_FAIL( "DbCellControl::doPropertyListening: caught an exception!" );
623 DBG_UNHANDLED_EXCEPTION();
628 void DbCellControl::doPropertyListening(const OUString& _rPropertyName)
630 implDoPropertyListening( _rPropertyName );
633 static void lcl_clearBroadCaster(::comphelper::OPropertyChangeMultiplexer*& _pBroadcaster)
635 if ( _pBroadcaster )
637 _pBroadcaster->dispose();
638 _pBroadcaster->release();
639 _pBroadcaster = NULL;
640 // no delete, this is done implicitly
644 DbCellControl::~DbCellControl()
646 lcl_clearBroadCaster(m_pModelChangeBroadcaster);
647 lcl_clearBroadCaster(m_pFieldChangeBroadcaster);
649 m_pWindow.disposeAndClear();
650 m_pPainter.disposeAndClear();
653 void DbCellControl::implValuePropertyChanged( )
655 OSL_ENSURE( !isValuePropertyLocked(),
656 "DbCellControl::implValuePropertyChanged: not to be called with the value property locked!" );
658 if ( m_pWindow )
660 if ( m_rColumn.getModel().is() )
661 updateFromModel( m_rColumn.getModel() );
666 void DbCellControl::implAdjustGenericFieldSetting( const Reference< XPropertySet >& /*_rxModel*/ )
668 // nothing to do here
672 void DbCellControl::_propertyChanged(const PropertyChangeEvent& _rEvent) throw(RuntimeException)
674 SolarMutexGuard aGuard;
676 Reference< XPropertySet > xSourceProps( _rEvent.Source, UNO_QUERY );
678 if ( _rEvent.PropertyName == FM_PROP_VALUE
679 || _rEvent.PropertyName == FM_PROP_STATE
680 || _rEvent.PropertyName == FM_PROP_TEXT
681 || _rEvent.PropertyName == FM_PROP_EFFECTIVE_VALUE
682 || _rEvent.PropertyName == FM_PROP_SELECT_SEQ
683 || _rEvent.PropertyName == FM_PROP_DATE
684 || _rEvent.PropertyName == FM_PROP_TIME
686 { // it was one of the known "value" properties
687 if ( !isValuePropertyLocked() )
689 implValuePropertyChanged( );
692 else if ( _rEvent.PropertyName == FM_PROP_READONLY )
694 implAdjustReadOnly( xSourceProps, true);
696 else if ( _rEvent.PropertyName == FM_PROP_ISREADONLY )
698 bool bReadOnly = true;
699 _rEvent.NewValue >>= bReadOnly;
700 m_rColumn.SetReadOnly(bReadOnly);
701 implAdjustReadOnly( xSourceProps, false);
703 else if ( _rEvent.PropertyName == FM_PROP_ENABLED )
705 implAdjustEnabled( xSourceProps );
707 else
708 implAdjustGenericFieldSetting( xSourceProps );
712 bool DbCellControl::Commit()
714 // lock the listening for value property changes
715 lockValueProperty();
716 // commit the content of the control into the model's value property
717 bool bReturn = false;
720 bReturn = commitControl();
722 catch( const Exception& )
724 DBG_UNHANDLED_EXCEPTION();
726 // unlock the listening for value property changes
727 unlockValueProperty();
728 // outta here
729 return bReturn;
733 void DbCellControl::ImplInitWindow( vcl::Window& rParent, const InitWindowFacet _eInitWhat )
735 vcl::Window* pWindows[] = { m_pPainter, m_pWindow };
737 if ((_eInitWhat & InitWritingMode) != 0)
739 for (size_t i = 0; i < sizeof(pWindows) / sizeof(pWindows[0]); ++i)
741 if (pWindows[i])
742 pWindows[i]->EnableRTL(rParent.IsRTLEnabled());
746 if ((_eInitWhat & InitFontFacet) != 0)
748 for (size_t i = 0; i < sizeof(pWindows) / sizeof(pWindows[0]); ++i)
750 if (!pWindows[i])
751 continue;
753 pWindows[i]->SetZoom(rParent.GetZoom());
755 const StyleSettings& rStyleSettings = pWindows[i]->GetSettings().GetStyleSettings();
756 vcl::Font aFont = rStyleSettings.GetFieldFont();
757 aFont.SetTransparent(isTransparent());
759 if (rParent.IsControlFont())
761 pWindows[i]->SetControlFont(rParent.GetControlFont());
762 aFont.Merge(rParent.GetControlFont());
764 else
765 pWindows[i]->SetControlFont();
767 pWindows[i]->SetZoomedPointFont(*pWindows[i], aFont); // FIXME RenderContext
771 if (((_eInitWhat & InitFontFacet) != 0) || ((_eInitWhat & InitForeground) != 0))
773 Color aTextColor(rParent.IsControlForeground() ? rParent.GetControlForeground() : rParent.GetTextColor());
775 bool bTextLineColor = rParent.IsTextLineColor();
776 Color aTextLineColor(rParent.GetTextLineColor());
778 for (size_t i=0; i < sizeof(pWindows) / sizeof(pWindows[0]); ++i)
780 if (pWindows[i])
782 pWindows[i]->SetTextColor(aTextColor);
783 if (rParent.IsControlForeground())
784 pWindows[i]->SetControlForeground(aTextColor);
786 if (bTextLineColor)
787 pWindows[i]->SetTextLineColor();
788 else
789 pWindows[i]->SetTextLineColor(aTextLineColor);
794 if ((_eInitWhat & InitBackground) != 0)
796 if (rParent.IsControlBackground())
798 Color aColor(rParent.GetControlBackground());
799 for (size_t i=0; i < sizeof(pWindows) / sizeof(pWindows[0]); ++i)
801 if (pWindows[i])
803 if (isTransparent())
804 pWindows[i]->SetBackground();
805 else
807 pWindows[i]->SetBackground(aColor);
808 pWindows[i]->SetControlBackground(aColor);
810 pWindows[i]->SetFillColor(aColor);
814 else
816 if (m_pPainter)
818 if (isTransparent())
819 m_pPainter->SetBackground();
820 else
821 m_pPainter->SetBackground(rParent.GetBackground());
822 m_pPainter->SetFillColor(rParent.GetFillColor());
825 if (m_pWindow)
827 if (isTransparent())
828 m_pWindow->SetBackground(rParent.GetBackground());
829 else
830 m_pWindow->SetFillColor(rParent.GetFillColor());
837 void DbCellControl::implAdjustReadOnly( const Reference< XPropertySet >& _rxModel,bool i_bReadOnly )
839 DBG_ASSERT( m_pWindow, "DbCellControl::implAdjustReadOnly: not to be called without window!" );
840 DBG_ASSERT( _rxModel.is(), "DbCellControl::implAdjustReadOnly: invalid model!" );
841 if ( m_pWindow && _rxModel.is() )
843 Edit* pEditWindow = dynamic_cast< Edit* >( m_pWindow.get() );
844 if ( pEditWindow )
846 bool bReadOnly = m_rColumn.IsReadOnly();
847 if ( !bReadOnly )
849 _rxModel->getPropertyValue( i_bReadOnly ? OUString(FM_PROP_READONLY) : OUString(FM_PROP_ISREADONLY)) >>= bReadOnly;
851 static_cast< Edit* >( m_pWindow.get() )->SetReadOnly( bReadOnly );
857 void DbCellControl::implAdjustEnabled( const Reference< XPropertySet >& _rxModel )
859 DBG_ASSERT( m_pWindow, "DbCellControl::implAdjustEnabled: not to be called without window!" );
860 DBG_ASSERT( _rxModel.is(), "DbCellControl::implAdjustEnabled: invalid model!" );
861 if ( m_pWindow && _rxModel.is() )
863 bool bEnable = true;
864 _rxModel->getPropertyValue( FM_PROP_ENABLED ) >>= bEnable;
865 m_pWindow->Enable( bEnable );
870 void DbCellControl::Init( vcl::Window& rParent, const Reference< XRowSet >& _rxCursor )
872 ImplInitWindow( rParent, InitAll );
874 if ( m_pWindow )
876 // align the control
877 if ( isAlignedController() )
878 AlignControl( m_rColumn.GetAlignment() );
882 // some other common properties
883 Reference< XPropertySet > xModel( m_rColumn.getModel(), UNO_SET_THROW );
884 Reference< XPropertySetInfo > xModelPSI( xModel->getPropertySetInfo(), UNO_SET_THROW );
886 if ( xModelPSI->hasPropertyByName( FM_PROP_READONLY ) )
888 implAdjustReadOnly( xModel,true );
891 if ( xModelPSI->hasPropertyByName( FM_PROP_ENABLED ) )
893 implAdjustEnabled( xModel );
896 if ( xModelPSI->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) )
898 sal_Int16 nWheelBehavior = css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY;
899 OSL_VERIFY( xModel->getPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) >>= nWheelBehavior );
900 MouseWheelBehaviour nVclSetting = MouseWheelBehaviour::FocusOnly;
901 switch ( nWheelBehavior )
903 case css::awt::MouseWheelBehavior::SCROLL_DISABLED: nVclSetting = MouseWheelBehaviour::Disable; break;
904 case css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY: nVclSetting = MouseWheelBehaviour::FocusOnly; break;
905 case css::awt::MouseWheelBehavior::SCROLL_ALWAYS: nVclSetting = MouseWheelBehaviour::ALWAYS; break;
906 default:
907 OSL_FAIL( "DbCellControl::Init: invalid MouseWheelBehavior!" );
908 break;
911 AllSettings aSettings = m_pWindow->GetSettings();
912 MouseSettings aMouseSettings = aSettings.GetMouseSettings();
913 aMouseSettings.SetWheelBehavior( nVclSetting );
914 aSettings.SetMouseSettings( aMouseSettings );
915 m_pWindow->SetSettings( aSettings, true );
918 catch( const Exception& )
920 DBG_UNHANDLED_EXCEPTION();
923 m_xCursor = _rxCursor;
924 if ( m_rColumn.getModel().is() )
925 updateFromModel( m_rColumn.getModel() );
929 void DbCellControl::SetTextLineColor()
931 if (m_pWindow)
932 m_pWindow->SetTextLineColor();
933 if (m_pPainter)
934 m_pPainter->SetTextLineColor();
938 void DbCellControl::SetTextLineColor(const Color& _rColor)
940 if (m_pWindow)
941 m_pWindow->SetTextLineColor(_rColor);
942 if (m_pPainter)
943 m_pPainter->SetTextLineColor(_rColor);
946 namespace
948 static void lcl_implAlign( vcl::Window* _pWindow, WinBits _nAlignmentBit )
950 WinBits nStyle = _pWindow->GetStyle();
951 nStyle &= ~(WB_LEFT | WB_RIGHT | WB_CENTER);
952 _pWindow->SetStyle( nStyle | _nAlignmentBit );
957 void DbCellControl::AlignControl(sal_Int16 nAlignment)
959 WinBits nAlignmentBit = 0;
960 switch (nAlignment)
962 case ::com::sun::star::awt::TextAlign::RIGHT:
963 nAlignmentBit = WB_RIGHT;
964 break;
965 case ::com::sun::star::awt::TextAlign::CENTER:
966 nAlignmentBit = WB_CENTER;
967 break;
968 default:
969 nAlignmentBit = WB_LEFT;
970 break;
972 lcl_implAlign( m_pWindow, nAlignmentBit );
973 if ( m_pPainter )
974 lcl_implAlign( m_pPainter, nAlignmentBit );
978 void DbCellControl::PaintCell( OutputDevice& _rDev, const Rectangle& _rRect )
980 if ( m_pPainter->GetParent() == &_rDev )
982 m_pPainter->SetPaintTransparent( true );
983 m_pPainter->SetBackground( );
984 m_pPainter->SetControlBackground( _rDev.GetFillColor() );
985 m_pPainter->SetControlForeground( _rDev.GetTextColor() );
986 m_pPainter->SetTextColor( _rDev.GetTextColor() );
987 m_pPainter->SetTextFillColor( _rDev.GetTextColor() );
989 vcl::Font aFont( _rDev.GetFont() );
990 aFont.SetTransparent( true );
991 m_pPainter->SetFont( aFont );
993 m_pPainter->SetPosSizePixel( _rRect.TopLeft(), _rRect.GetSize() );
994 m_pPainter->Show();
995 m_pPainter->Update();
996 m_pPainter->SetParentUpdateMode( false );
997 m_pPainter->Hide();
998 m_pPainter->SetParentUpdateMode( true );
1000 else
1001 m_pPainter->Draw( &_rDev, _rRect.TopLeft(), _rRect.GetSize(), 0 );
1005 void DbCellControl::PaintFieldToCell( OutputDevice& _rDev, const Rectangle& _rRect, const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1007 m_pPainter->SetText( GetFormatText( _rxField, _rxFormatter ) );
1008 PaintCell( _rDev, _rRect );
1012 double DbCellControl::GetValue(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter) const
1014 double fValue = 0;
1015 if (m_rColumn.IsNumeric())
1019 fValue = _rxField->getDouble();
1021 catch(const Exception&) { }
1023 else
1025 bool bSuccess = false;
1028 fValue = _rxField->getDouble();
1029 bSuccess = true;
1031 catch(const Exception&) { }
1032 if (!bSuccess)
1036 fValue = xFormatter->convertStringToNumber(m_rColumn.GetKey(), _rxField->getString());
1038 catch(const Exception&) { }
1041 return fValue;
1045 void DbCellControl::invalidatedController()
1047 m_rColumn.GetParent().refreshController(m_rColumn.GetId(), DbGridControl::GrantControlAccess());
1050 // CellModels
1052 DbLimitedLengthField::DbLimitedLengthField( DbGridColumn& _rColumn )
1053 :DbCellControl( _rColumn )
1055 doPropertyListening( FM_PROP_MAXTEXTLEN );
1059 void DbLimitedLengthField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1061 DBG_ASSERT( m_pWindow, "DbLimitedLengthField::implAdjustGenericFieldSetting: not to be called without window!" );
1062 DBG_ASSERT( _rxModel.is(), "DbLimitedLengthField::implAdjustGenericFieldSetting: invalid model!" );
1063 if ( m_pWindow && _rxModel.is() )
1065 sal_Int16 nMaxLen = 0;
1066 _rxModel->getPropertyValue( FM_PROP_MAXTEXTLEN ) >>= nMaxLen;
1067 implSetMaxTextLen( nMaxLen );
1071 void DbLimitedLengthField::implSetEffectiveMaxTextLen( sal_Int32 _nMaxLen )
1073 dynamic_cast<Edit&>(*m_pWindow).SetMaxTextLen(_nMaxLen);
1074 if (m_pPainter)
1075 dynamic_cast<Edit&>(*m_pPainter).SetMaxTextLen(_nMaxLen);
1078 DbTextField::DbTextField(DbGridColumn& _rColumn)
1079 :DbLimitedLengthField(_rColumn)
1080 ,m_pEdit( NULL )
1081 ,m_pPainterImplementation( NULL )
1082 ,m_bIsSimpleEdit( true )
1087 DbTextField::~DbTextField( )
1089 DELETEZ( m_pPainterImplementation );
1090 DELETEZ( m_pEdit );
1094 void DbTextField::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor)
1096 sal_Int16 nAlignment = m_rColumn.SetAlignmentFromModel(-1);
1098 Reference< XPropertySet > xModel( m_rColumn.getModel() );
1100 WinBits nStyle = WB_LEFT;
1101 switch (nAlignment)
1103 case awt::TextAlign::RIGHT:
1104 nStyle = WB_RIGHT;
1105 break;
1107 case awt::TextAlign::CENTER:
1108 nStyle = WB_CENTER;
1109 break;
1112 // is this a multi-line field?
1113 bool bIsMultiLine = false;
1116 if ( xModel.is() )
1118 OSL_VERIFY( xModel->getPropertyValue( FM_PROP_MULTILINE ) >>= bIsMultiLine );
1121 catch( const Exception& )
1123 OSL_FAIL( "DbTextField::Init: caught an exception while determining the multi-line capabilities!" );
1124 DBG_UNHANDLED_EXCEPTION();
1127 m_bIsSimpleEdit = !bIsMultiLine;
1128 if ( bIsMultiLine )
1130 m_pWindow = VclPtr<MultiLineTextCell>::Create( &rParent, nStyle );
1131 m_pEdit = new MultiLineEditImplementation( *static_cast< MultiLineTextCell* >( m_pWindow.get() ) );
1133 m_pPainter = VclPtr<MultiLineTextCell>::Create( &rParent, nStyle );
1134 m_pPainterImplementation = new MultiLineEditImplementation( *static_cast< MultiLineTextCell* >( m_pPainter.get() ) );
1136 else
1138 m_pWindow = VclPtr<Edit>::Create( &rParent, nStyle );
1139 m_pEdit = new EditImplementation( *static_cast< Edit* >( m_pWindow.get() ) );
1141 m_pPainter = VclPtr<Edit>::Create( &rParent, nStyle );
1142 m_pPainterImplementation = new EditImplementation( *static_cast< Edit* >( m_pPainter.get() ) );
1145 if ( WB_LEFT == nStyle )
1147 // this is so that when getting the focus, the selection is oriented left-to-right
1148 AllSettings aSettings = m_pWindow->GetSettings();
1149 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1150 aStyleSettings.SetSelectionOptions(
1151 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
1152 aSettings.SetStyleSettings(aStyleSettings);
1153 m_pWindow->SetSettings(aSettings);
1156 implAdjustGenericFieldSetting( xModel );
1158 DbLimitedLengthField::Init( rParent, xCursor );
1162 CellControllerRef DbTextField::CreateController() const
1164 return new EditCellController( m_pEdit );
1168 void DbTextField::PaintFieldToCell( OutputDevice& _rDev, const Rectangle& _rRect, const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1170 if ( m_pPainterImplementation )
1171 m_pPainterImplementation->SetText( GetFormatText( _rxField, _rxFormatter, NULL ) );
1173 DbLimitedLengthField::PaintFieldToCell( _rDev, _rRect, _rxField, _rxFormatter );
1177 OUString DbTextField::GetFormatText(const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter, Color** /*ppColor*/)
1179 const com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> xPS(_rxField, UNO_QUERY);
1180 FormattedColumnValue fmter( xFormatter, xPS );
1182 return fmter.getFormattedValue();
1186 void DbTextField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
1188 m_pEdit->SetText( GetFormatText( _rxField, xFormatter ) );
1189 m_pEdit->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1193 void DbTextField::updateFromModel( Reference< XPropertySet > _rxModel )
1195 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbTextField::updateFromModel: invalid call!" );
1197 OUString sText;
1198 _rxModel->getPropertyValue( FM_PROP_TEXT ) >>= sText;
1200 sal_Int32 nMaxTextLen = m_pEdit->GetMaxTextLen();
1201 if ( EDIT_NOLIMIT != nMaxTextLen && sText.getLength() > nMaxTextLen )
1203 sal_Int32 nDiff = sText.getLength() - nMaxTextLen;
1204 sText = sText.replaceAt(sText.getLength() - nDiff,nDiff, OUString());
1208 m_pEdit->SetText( sText );
1209 m_pEdit->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1213 bool DbTextField::commitControl()
1215 OUString aText( m_pEdit->GetText( getModelLineEndSetting( m_rColumn.getModel() ) ) );
1216 // we have to check if the length before we can decide if the value was modified
1217 sal_Int32 nMaxTextLen = m_pEdit->GetMaxTextLen();
1218 if ( EDIT_NOLIMIT != nMaxTextLen )
1220 OUString sOldValue;
1221 m_rColumn.getModel()->getPropertyValue( FM_PROP_TEXT ) >>= sOldValue;
1222 // if the new value didn't change we must set the old long value again
1223 if ( sOldValue.getLength() > nMaxTextLen && sOldValue.compareTo(aText,nMaxTextLen) == 0 )
1224 aText = sOldValue;
1226 m_rColumn.getModel()->setPropertyValue( FM_PROP_TEXT, makeAny( aText ) );
1227 return true;
1231 void DbTextField::implSetEffectiveMaxTextLen( sal_Int32 _nMaxLen )
1233 if ( m_pEdit )
1234 m_pEdit->SetMaxTextLen( _nMaxLen );
1235 if ( m_pPainterImplementation )
1236 m_pPainterImplementation->SetMaxTextLen( _nMaxLen );
1239 DbFormattedField::DbFormattedField(DbGridColumn& _rColumn)
1240 :DbLimitedLengthField(_rColumn)
1241 ,m_nKeyType(::com::sun::star::util::NumberFormat::UNDEFINED)
1244 // if our model's format key changes we want to propagate the new value to our windows
1245 doPropertyListening( FM_PROP_FORMATKEY );
1249 DbFormattedField::~DbFormattedField()
1254 void DbFormattedField::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor)
1256 sal_Int16 nAlignment = m_rColumn.SetAlignmentFromModel(-1);
1258 Reference< ::com::sun::star::beans::XPropertySet > xUnoModel = m_rColumn.getModel();
1260 switch (nAlignment)
1262 case ::com::sun::star::awt::TextAlign::RIGHT:
1263 m_pWindow = VclPtr<FormattedField>::Create( &rParent, WB_RIGHT );
1264 m_pPainter = VclPtr<FormattedField>::Create( &rParent, WB_RIGHT );
1265 break;
1267 case ::com::sun::star::awt::TextAlign::CENTER:
1268 m_pWindow = VclPtr<FormattedField>::Create( &rParent, WB_CENTER );
1269 m_pPainter = VclPtr<FormattedField>::Create( &rParent, WB_CENTER );
1270 break;
1271 default:
1272 m_pWindow = VclPtr<FormattedField>::Create( &rParent, WB_LEFT );
1273 m_pPainter = VclPtr<FormattedField>::Create( &rParent, WB_LEFT );
1275 // Alles nur damit die Selektion bei Focuserhalt von rechts nach links geht
1276 AllSettings aSettings = m_pWindow->GetSettings();
1277 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1278 aStyleSettings.SetSelectionOptions(
1279 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
1280 aSettings.SetStyleSettings(aStyleSettings);
1281 m_pWindow->SetSettings(aSettings);
1284 implAdjustGenericFieldSetting( xUnoModel );
1286 static_cast< FormattedField* >( m_pWindow.get() )->SetStrictFormat( false );
1287 static_cast< FormattedField* >( m_pPainter.get() )->SetStrictFormat( false );
1288 // wenn man _irgendeine_ Formatierung zulaesst, kann man da sowieso keine Eingabe-Ueberpruefung
1289 // machen (das FormattedField unterstuetzt das sowieso nicht, nur abgeleitete Klassen)
1291 // von dem Uno-Model den Formatter besorgen
1292 // (Ich koennte theoretisch auch ueber den ::com::sun::star::util::NumberFormatter gehen, den mir der Cursor bestimmt
1293 // liefern wuerde. Das Problem dabei ist, dass ich mich eigentlich nicht darauf verlassen
1294 // kann, dass die beiden Formatter die selben sind, sauber ist das Ganze, wenn ich ueber das
1295 // UNO-Model gehe.)
1296 sal_Int32 nFormatKey = -1;
1298 // mal sehen, ob das Model einen hat ...
1299 DBG_ASSERT(::comphelper::hasProperty(FM_PROP_FORMATSSUPPLIER, xUnoModel), "DbFormattedField::Init : invalid UNO model !");
1300 Any aSupplier( xUnoModel->getPropertyValue(FM_PROP_FORMATSSUPPLIER));
1301 if (aSupplier.hasValue())
1303 m_xSupplier.set(aSupplier, css::uno::UNO_QUERY);
1304 if (m_xSupplier.is())
1306 // wenn wir den Supplier vom Model nehmen, dann auch den Key
1307 Any aFmtKey( xUnoModel->getPropertyValue(FM_PROP_FORMATKEY));
1308 if (aFmtKey.hasValue())
1310 DBG_ASSERT(aFmtKey.getValueType().getTypeClass() == TypeClass_LONG, "DbFormattedField::Init : invalid format key property (no sal_Int32) !");
1311 nFormatKey = ::comphelper::getINT32(aFmtKey);
1313 else
1315 DBG_WARNING("DbFormattedField::Init : my uno-model has no format-key, but a formats supplier !");
1316 // the OFormattedModel which we usually are working with ensures that the model has a format key
1317 // as soon as the form is loaded. Unfortunally this method here is called from within loaded, too.
1318 // So if our LoadListener is called before the LoadListener of the model, this "else case" is
1319 // allowed.
1320 // Of course our property listener for the FormatKey property will notify us if the prop is changed,
1321 // so this here isn't really bad ....
1322 nFormatKey = 0;
1327 // nein ? vielleicht die ::com::sun::star::form::component::Form hinter dem Cursor ?
1328 if (!m_xSupplier.is())
1330 Reference< XRowSet > xCursorForm(xCursor, UNO_QUERY);
1331 if (xCursorForm.is())
1332 { // wenn wir vom Cursor den Formatter nehmen, dann auch den Key vom Feld, an das wir gebunden sind
1333 m_xSupplier = getNumberFormats(getConnection(xCursorForm), false);
1335 if (m_rColumn.GetField().is())
1336 nFormatKey = ::comphelper::getINT32(m_rColumn.GetField()->getPropertyValue(FM_PROP_FORMATKEY));
1340 SvNumberFormatter* pFormatterUsed = NULL;
1341 if (m_xSupplier.is())
1343 SvNumberFormatsSupplierObj* pImplmentation = SvNumberFormatsSupplierObj::getImplementation(m_xSupplier);
1344 if (pImplmentation)
1345 pFormatterUsed = pImplmentation->GetNumberFormatter();
1346 else
1347 // alles hingfaellig : der Supplier ist vom falschen Typ, dann koennen wir uns auch nicht darauf verlassen, dass
1348 // ein Standard-Formatter den (eventuell nicht-Standard-)Key kennt.
1349 nFormatKey = -1;
1352 // einen Standard-Formatter ...
1353 if (pFormatterUsed == NULL)
1355 pFormatterUsed = static_cast<FormattedField*>(m_pWindow.get())->StandardFormatter();
1356 DBG_ASSERT(pFormatterUsed != NULL, "DbFormattedField::Init : no standard formatter given by the numeric field !");
1358 // ... und einen Standard-Key
1359 if (nFormatKey == -1)
1360 nFormatKey = 0;
1362 m_nKeyType = comphelper::getNumberFormatType(m_xSupplier->getNumberFormats(), nFormatKey);
1364 static_cast<FormattedField*>(m_pWindow.get())->SetFormatter(pFormatterUsed);
1365 static_cast<FormattedField*>(m_pPainter.get())->SetFormatter(pFormatterUsed);
1367 static_cast<FormattedField*>(m_pWindow.get())->SetFormatKey(nFormatKey);
1368 static_cast<FormattedField*>(m_pPainter.get())->SetFormatKey(nFormatKey);
1370 static_cast<FormattedField*>(m_pWindow.get())->TreatAsNumber(m_rColumn.IsNumeric());
1371 static_cast<FormattedField*>(m_pPainter.get())->TreatAsNumber(m_rColumn.IsNumeric());
1373 // Min- und Max-Werte
1374 if (m_rColumn.IsNumeric())
1376 bool bClearMin = true;
1377 if (::comphelper::hasProperty(FM_PROP_EFFECTIVE_MIN, xUnoModel))
1379 Any aMin( xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_MIN));
1380 if (aMin.getValueType().getTypeClass() != TypeClass_VOID)
1382 DBG_ASSERT(aMin.getValueType().getTypeClass() == TypeClass_DOUBLE, "DbFormattedField::Init : the model has an invalid min value !");
1383 double dMin = ::comphelper::getDouble(aMin);
1384 static_cast<FormattedField*>(m_pWindow.get())->SetMinValue(dMin);
1385 static_cast<FormattedField*>(m_pPainter.get())->SetMinValue(dMin);
1386 bClearMin = false;
1389 if (bClearMin)
1391 static_cast<FormattedField*>(m_pWindow.get())->ClearMinValue();
1392 static_cast<FormattedField*>(m_pPainter.get())->ClearMinValue();
1394 bool bClearMax = true;
1395 if (::comphelper::hasProperty(FM_PROP_EFFECTIVE_MAX, xUnoModel))
1397 Any aMin( xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_MAX));
1398 if (aMin.getValueType().getTypeClass() != TypeClass_VOID)
1400 DBG_ASSERT(aMin.getValueType().getTypeClass() == TypeClass_DOUBLE, "DbFormattedField::Init : the model has an invalid max value !");
1401 double dMin = ::comphelper::getDouble(aMin);
1402 static_cast<FormattedField*>(m_pWindow.get())->SetMaxValue(dMin);
1403 static_cast<FormattedField*>(m_pPainter.get())->SetMaxValue(dMin);
1404 bClearMax = false;
1407 if (bClearMax)
1409 static_cast<FormattedField*>(m_pWindow.get())->ClearMaxValue();
1410 static_cast<FormattedField*>(m_pPainter.get())->ClearMaxValue();
1414 // den Default-Wert
1415 Any aDefault( xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_DEFAULT));
1416 if (aDefault.hasValue())
1417 { // das Ding kann ein double oder ein String sein
1418 switch (aDefault.getValueType().getTypeClass())
1420 case TypeClass_DOUBLE:
1421 if (m_rColumn.IsNumeric())
1423 static_cast<FormattedField*>(m_pWindow.get())->SetDefaultValue(::comphelper::getDouble(aDefault));
1424 static_cast<FormattedField*>(m_pPainter.get())->SetDefaultValue(::comphelper::getDouble(aDefault));
1426 else
1428 OUString sConverted;
1429 Color* pDummy;
1430 pFormatterUsed->GetOutputString(::comphelper::getDouble(aDefault), 0, sConverted, &pDummy);
1431 static_cast<FormattedField*>(m_pWindow.get())->SetDefaultText(sConverted);
1432 static_cast<FormattedField*>(m_pPainter.get())->SetDefaultText(sConverted);
1434 break;
1435 case TypeClass_STRING:
1437 OUString sDefault( ::comphelper::getString(aDefault) );
1438 if (m_rColumn.IsNumeric())
1440 double dVal;
1441 sal_uInt32 nTestFormat(0);
1442 if (pFormatterUsed->IsNumberFormat(sDefault, nTestFormat, dVal))
1444 static_cast<FormattedField*>(m_pWindow.get())->SetDefaultValue(dVal);
1445 static_cast<FormattedField*>(m_pPainter.get())->SetDefaultValue(dVal);
1448 else
1450 static_cast<FormattedField*>(m_pWindow.get())->SetDefaultText(sDefault);
1451 static_cast<FormattedField*>(m_pPainter.get())->SetDefaultText(sDefault);
1454 break;
1455 default:
1456 OSL_FAIL( "DbFormattedField::Init: unexpected value type!" );
1457 break;
1460 DbLimitedLengthField::Init( rParent, xCursor );
1464 CellControllerRef DbFormattedField::CreateController() const
1466 return new ::svt::FormattedFieldCellController( static_cast< FormattedField* >( m_pWindow.get() ) );
1470 void DbFormattedField::_propertyChanged( const PropertyChangeEvent& _rEvent ) throw( RuntimeException )
1472 if (_rEvent.PropertyName == FM_PROP_FORMATKEY )
1474 sal_Int32 nNewKey = _rEvent.NewValue.hasValue() ? ::comphelper::getINT32(_rEvent.NewValue) : 0;
1475 m_nKeyType = comphelper::getNumberFormatType(m_xSupplier->getNumberFormats(), nNewKey);
1477 DBG_ASSERT(m_pWindow && m_pPainter, "DbFormattedField::_propertyChanged : where are my windows ?");
1478 if (m_pWindow)
1479 static_cast< FormattedField* >( m_pWindow.get() )->SetFormatKey( nNewKey );
1480 if (m_pPainter)
1481 static_cast< FormattedField* >( m_pPainter.get() )->SetFormatKey( nNewKey );
1483 else
1485 DbLimitedLengthField::_propertyChanged( _rEvent );
1490 OUString DbFormattedField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, Color** ppColor)
1492 // defaultmaessig keine Farb-Angabe
1493 if (ppColor != NULL)
1494 *ppColor = NULL;
1496 // NULL-Wert -> leerer Text
1497 if (!_rxField.is())
1498 return OUString();
1500 OUString aText;
1503 if (m_rColumn.IsNumeric())
1505 // das IsNumeric an der Column sagt nichts aus ueber die Klasse des benutzen Formates, sondern
1506 // ueber die des an die Column gebundenen Feldes. Wenn man also eine FormattedField-Spalte an
1507 // ein double-Feld bindet und als Text formatiert, liefert m_rColumn.IsNumeric() sal_True. Das heisst
1508 // also einfach, dass ich den Inhalt der Variant mittels getDouble abfragen kann, und dann kann
1509 // ich den Rest (die Formatierung) dem FormattedField ueberlassen.
1510 double dValue = getValue( _rxField, m_rColumn.GetParent().getNullDate() );
1511 if (_rxField->wasNull())
1512 return aText;
1513 static_cast<FormattedField*>(m_pPainter.get())->SetValue(dValue);
1515 else
1517 // Hier kann ich nicht mit einem double arbeiten, da das Feld mir keines liefern kann.
1518 // Also einfach den Text vom ::com::sun::star::util::NumberFormatter in die richtige ::com::sun::star::form::component::Form brinden lassen.
1519 aText = _rxField->getString();
1520 if (_rxField->wasNull())
1521 return aText;
1522 static_cast<FormattedField*>(m_pPainter.get())->SetTextFormatted(aText);
1525 catch( const Exception& )
1527 DBG_UNHANDLED_EXCEPTION();
1530 aText = m_pPainter->GetText();
1531 if (ppColor != NULL)
1532 *ppColor = static_cast<FormattedField*>(m_pPainter.get())->GetLastOutputColor();
1534 return aText;
1538 void DbFormattedField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
1542 FormattedField* pFormattedWindow = static_cast<FormattedField*>(m_pWindow.get());
1543 if (!_rxField.is())
1544 { // NULL-Wert -> leerer Text
1545 m_pWindow->SetText(OUString());
1547 else if (m_rColumn.IsNumeric())
1549 // das IsNumeric an der Column sagt nichts aus ueber die Klasse des benutzen Formates, sondern
1550 // ueber die des an die Column gebundenen Feldes. Wenn man also eine FormattedField-Spalte an
1551 // ein double-Feld bindet und als Text formatiert, liefert m_rColumn.IsNumeric() sal_True. Das heisst
1552 // also einfach, dass ich den Inhalt der Variant mittels getDouble abfragen kann, und dann kann
1553 // ich den Rest (die Formatierung) dem FormattedField ueberlassen.
1554 double dValue = getValue( _rxField, m_rColumn.GetParent().getNullDate() );
1555 if (_rxField->wasNull())
1556 m_pWindow->SetText(OUString());
1557 else
1558 pFormattedWindow->SetValue(dValue);
1560 else
1562 // Hier kann ich nicht mit einem double arbeiten, da das Feld mir keines liefern kann.
1563 // Also einfach den Text vom ::com::sun::star::util::NumberFormatter in die richtige ::com::sun::star::form::component::Form brinden lassen.
1564 OUString sText( _rxField->getString());
1566 pFormattedWindow->SetTextFormatted( sText );
1567 pFormattedWindow->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1570 catch( const Exception& )
1572 DBG_UNHANDLED_EXCEPTION();
1577 void DbFormattedField::updateFromModel( Reference< XPropertySet > _rxModel )
1579 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbFormattedField::updateFromModel: invalid call!" );
1581 FormattedField* pFormattedWindow = static_cast< FormattedField* >( m_pWindow.get() );
1583 OUString sText;
1584 Any aValue = _rxModel->getPropertyValue( FM_PROP_EFFECTIVE_VALUE );
1585 if ( !aValue.hasValue() || (aValue >>= sText) )
1586 { // our effective value is transferred as string
1587 pFormattedWindow->SetTextFormatted( sText );
1588 pFormattedWindow->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1590 else
1592 double dValue = 0;
1593 aValue >>= dValue;
1594 pFormattedWindow->SetValue(dValue);
1599 bool DbFormattedField::commitControl()
1601 Any aNewVal;
1602 FormattedField& rField = *static_cast<FormattedField*>(m_pWindow.get());
1603 DBG_ASSERT(&rField == m_pWindow, "DbFormattedField::commitControl : can't work with a window other than my own !");
1604 if (m_rColumn.IsNumeric())
1606 if (!rField.GetText().isEmpty())
1607 aNewVal <<= rField.GetValue();
1608 // ein LeerString wird erst mal standardmaessig als void weitergereicht
1610 else
1611 aNewVal <<= OUString(rField.GetTextValue());
1613 m_rColumn.getModel()->setPropertyValue(FM_PROP_EFFECTIVE_VALUE, aNewVal);
1614 return true;
1617 DbCheckBox::DbCheckBox( DbGridColumn& _rColumn )
1618 :DbCellControl( _rColumn, true )
1620 setAlignedController( false );
1623 namespace
1625 void setCheckBoxStyle( vcl::Window* _pWindow, bool bMono )
1627 AllSettings aSettings = _pWindow->GetSettings();
1628 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1629 if( bMono )
1630 aStyleSettings.SetOptions( aStyleSettings.GetOptions() | StyleSettingsOptions::Mono );
1631 else
1632 aStyleSettings.SetOptions( aStyleSettings.GetOptions() & (~StyleSettingsOptions::Mono) );
1633 aSettings.SetStyleSettings( aStyleSettings );
1634 _pWindow->SetSettings( aSettings );
1639 void DbCheckBox::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor )
1641 setTransparent( true );
1643 m_pWindow = VclPtr<CheckBoxControl>::Create( &rParent );
1644 m_pPainter = VclPtr<CheckBoxControl>::Create( &rParent );
1646 m_pWindow->SetPaintTransparent( true );
1647 m_pPainter->SetPaintTransparent( true );
1649 m_pPainter->SetBackground();
1653 Reference< XPropertySet > xModel( m_rColumn.getModel(), UNO_SET_THROW );
1655 sal_Int16 nStyle = awt::VisualEffect::LOOK3D;
1656 OSL_VERIFY( xModel->getPropertyValue( FM_PROP_VISUALEFFECT ) >>= nStyle );
1658 setCheckBoxStyle( m_pWindow, nStyle == awt::VisualEffect::FLAT );
1659 setCheckBoxStyle( m_pPainter, nStyle == awt::VisualEffect::FLAT );
1661 bool bTristate = true;
1662 OSL_VERIFY( xModel->getPropertyValue( FM_PROP_TRISTATE ) >>= bTristate );
1663 static_cast< CheckBoxControl* >( m_pWindow.get() )->GetBox().EnableTriState( bTristate );
1664 static_cast< CheckBoxControl* >( m_pPainter.get() )->GetBox().EnableTriState( bTristate );
1666 catch( const Exception& )
1668 DBG_UNHANDLED_EXCEPTION();
1671 DbCellControl::Init( rParent, xCursor );
1675 CellControllerRef DbCheckBox::CreateController() const
1677 return new CheckBoxCellController(static_cast<CheckBoxControl*>(m_pWindow.get()));
1680 static void lcl_setCheckBoxState( const Reference< ::com::sun::star::sdb::XColumn >& _rxField,
1681 CheckBoxControl* _pCheckBoxControl )
1683 TriState eState = TRISTATE_INDET;
1684 if (_rxField.is())
1688 bool bValue = _rxField->getBoolean();
1689 if (!_rxField->wasNull())
1690 eState = bValue ? TRISTATE_TRUE : TRISTATE_FALSE;
1692 catch( const Exception& )
1694 DBG_UNHANDLED_EXCEPTION();
1697 _pCheckBoxControl->GetBox().SetState(eState);
1701 void DbCheckBox::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
1703 lcl_setCheckBoxState( _rxField, static_cast<CheckBoxControl*>(m_pWindow.get()) );
1707 void DbCheckBox::PaintFieldToCell(OutputDevice& rDev, const Rectangle& rRect,
1708 const Reference< ::com::sun::star::sdb::XColumn >& _rxField,
1709 const Reference< XNumberFormatter >& xFormatter)
1711 lcl_setCheckBoxState( _rxField, static_cast<CheckBoxControl*>(m_pPainter.get()) );
1712 DbCellControl::PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
1716 void DbCheckBox::updateFromModel( Reference< XPropertySet > _rxModel )
1718 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbCheckBox::updateFromModel: invalid call!" );
1720 sal_Int16 nState = TRISTATE_INDET;
1721 _rxModel->getPropertyValue( FM_PROP_STATE ) >>= nState;
1722 static_cast< CheckBoxControl* >( m_pWindow.get() )->GetBox().SetState( static_cast< TriState >( nState ) );
1726 bool DbCheckBox::commitControl()
1728 m_rColumn.getModel()->setPropertyValue( FM_PROP_STATE,
1729 makeAny( (sal_Int16)( static_cast< CheckBoxControl* >( m_pWindow.get() )->GetBox().GetState() ) ) );
1730 return true;
1734 OUString DbCheckBox::GetFormatText(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
1736 return OUString();
1739 DbPatternField::DbPatternField( DbGridColumn& _rColumn, const Reference<XComponentContext>& _rContext )
1740 :DbCellControl( _rColumn )
1741 ,m_xContext( _rContext )
1743 doPropertyListening( FM_PROP_LITERALMASK );
1744 doPropertyListening( FM_PROP_EDITMASK );
1745 doPropertyListening( FM_PROP_STRICTFORMAT );
1749 void DbPatternField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1751 DBG_ASSERT( m_pWindow, "DbPatternField::implAdjustGenericFieldSetting: not to be called without window!" );
1752 DBG_ASSERT( _rxModel.is(), "DbPatternField::implAdjustGenericFieldSetting: invalid model!" );
1753 if ( m_pWindow && _rxModel.is() )
1755 OUString aLitMask;
1756 OUString aEditMask;
1757 bool bStrict = false;
1759 _rxModel->getPropertyValue( FM_PROP_LITERALMASK ) >>= aLitMask;
1760 _rxModel->getPropertyValue( FM_PROP_EDITMASK ) >>= aEditMask;
1761 _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) >>= bStrict;
1763 OString aAsciiEditMask(OUStringToOString(aEditMask, RTL_TEXTENCODING_ASCII_US));
1765 static_cast< PatternField* >( m_pWindow.get() )->SetMask( aAsciiEditMask, aLitMask );
1766 static_cast< PatternField* >( m_pPainter.get() )->SetMask( aAsciiEditMask, aLitMask );
1767 static_cast< PatternField* >( m_pWindow.get() )->SetStrictFormat( bStrict );
1768 static_cast< PatternField* >( m_pPainter.get() )->SetStrictFormat( bStrict );
1773 void DbPatternField::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor)
1775 m_rColumn.SetAlignmentFromModel(-1);
1777 m_pWindow = VclPtr<PatternField>::Create( &rParent, 0 );
1778 m_pPainter= VclPtr<PatternField>::Create( &rParent, 0 );
1780 Reference< XPropertySet > xModel( m_rColumn.getModel() );
1781 implAdjustGenericFieldSetting( xModel );
1783 DbCellControl::Init( rParent, xCursor );
1787 CellControllerRef DbPatternField::CreateController() const
1789 return new SpinCellController( static_cast< PatternField* >( m_pWindow.get() ) );
1793 OUString DbPatternField::impl_formatText( const OUString& _rText )
1795 m_pPainter->SetText( _rText );
1796 static_cast< PatternField* >( m_pPainter.get() )->ReformatAll();
1797 return m_pPainter->GetText();
1801 OUString DbPatternField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
1803 bool bIsForPaint = _rxField != m_rColumn.GetField();
1804 ::std::unique_ptr< FormattedColumnValue >& rpFormatter = bIsForPaint ? m_pPaintFormatter : m_pValueFormatter;
1806 if ( !rpFormatter.get() )
1808 rpFormatter = ::std::unique_ptr< FormattedColumnValue> (
1809 new FormattedColumnValue(m_xContext, getCursor(), Reference< XPropertySet >( _rxField, UNO_QUERY ) ) );
1810 OSL_ENSURE( rpFormatter.get(), "DbPatternField::Init: no value formatter!" );
1812 else
1813 OSL_ENSURE( rpFormatter->getColumn() == _rxField, "DbPatternField::GetFormatText: my value formatter is working for another field ...!" );
1814 // re-creating the value formatter here every time would be quite expensive ...
1816 OUString sText;
1817 if ( rpFormatter.get() )
1818 sText = rpFormatter->getFormattedValue();
1820 return impl_formatText( sText );
1824 void DbPatternField::UpdateFromField( const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1826 static_cast< Edit* >( m_pWindow.get() )->SetText( GetFormatText( _rxField, _rxFormatter ) );
1827 static_cast< Edit* >( m_pWindow.get() )->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1831 void DbPatternField::updateFromModel( Reference< XPropertySet > _rxModel )
1833 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbPatternField::updateFromModel: invalid call!" );
1835 OUString sText;
1836 _rxModel->getPropertyValue( FM_PROP_TEXT ) >>= sText;
1838 static_cast< Edit* >( m_pWindow.get() )->SetText( impl_formatText( sText ) );
1839 static_cast< Edit* >( m_pWindow.get() )->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1843 bool DbPatternField::commitControl()
1845 OUString aText(m_pWindow->GetText());
1846 m_rColumn.getModel()->setPropertyValue(FM_PROP_TEXT, makeAny(aText));
1847 return true;
1850 DbSpinField::DbSpinField( DbGridColumn& _rColumn, sal_Int16 _nStandardAlign )
1851 :DbCellControl( _rColumn )
1852 ,m_nStandardAlign( _nStandardAlign )
1857 void DbSpinField::Init( vcl::Window& _rParent, const Reference< XRowSet >& _rxCursor )
1859 m_rColumn.SetAlignmentFromModel( m_nStandardAlign );
1861 Reference< XPropertySet > xModel( m_rColumn.getModel() );
1863 // determine the WinBits for the field
1864 WinBits nFieldStyle = 0;
1865 if ( ::comphelper::getBOOL( xModel->getPropertyValue( FM_PROP_SPIN ) ) )
1866 nFieldStyle = WB_REPEAT | WB_SPIN;
1867 // create the fields
1868 m_pWindow = createField( &_rParent, nFieldStyle, xModel );
1869 m_pPainter = createField( &_rParent, nFieldStyle, xModel );
1871 // adjust all other settings which depend on the property values
1872 implAdjustGenericFieldSetting( xModel );
1874 // call the base class
1875 DbCellControl::Init( _rParent, _rxCursor );
1879 CellControllerRef DbSpinField::CreateController() const
1881 return new SpinCellController( static_cast< SpinField* >( m_pWindow.get() ) );
1884 DbNumericField::DbNumericField( DbGridColumn& _rColumn )
1885 :DbSpinField( _rColumn )
1887 doPropertyListening( FM_PROP_DECIMAL_ACCURACY );
1888 doPropertyListening( FM_PROP_VALUEMIN );
1889 doPropertyListening( FM_PROP_VALUEMAX );
1890 doPropertyListening( FM_PROP_VALUESTEP );
1891 doPropertyListening( FM_PROP_STRICTFORMAT );
1892 doPropertyListening( FM_PROP_SHOWTHOUSANDSEP );
1896 void DbNumericField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1898 DBG_ASSERT( m_pWindow, "DbNumericField::implAdjustGenericFieldSetting: not to be called without window!" );
1899 DBG_ASSERT( _rxModel.is(), "DbNumericField::implAdjustGenericFieldSetting: invalid model!" );
1900 if ( m_pWindow && _rxModel.is() )
1902 sal_Int32 nMin = (sal_Int32)getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMIN ) );
1903 sal_Int32 nMax = (sal_Int32)getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMAX ) );
1904 sal_Int32 nStep = (sal_Int32)getDouble( _rxModel->getPropertyValue( FM_PROP_VALUESTEP ) );
1905 bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
1906 sal_Int16 nScale = getINT16( _rxModel->getPropertyValue( FM_PROP_DECIMAL_ACCURACY ) );
1907 bool bThousand = getBOOL( _rxModel->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP ) );
1909 static_cast< DoubleNumericField* >( m_pWindow.get() )->SetMinValue(nMin);
1910 static_cast< DoubleNumericField* >( m_pWindow.get() )->SetMaxValue(nMax);
1911 static_cast< DoubleNumericField* >( m_pWindow.get() )->SetSpinSize(nStep);
1912 static_cast< DoubleNumericField* >( m_pWindow.get() )->SetStrictFormat(bStrict);
1914 static_cast< DoubleNumericField* >( m_pPainter.get() )->SetMinValue(nMin);
1915 static_cast< DoubleNumericField* >( m_pPainter.get() )->SetMaxValue(nMax);
1916 static_cast< DoubleNumericField* >( m_pPainter.get() )->SetStrictFormat(bStrict);
1919 // dem Field und dem Painter einen Formatter spendieren
1920 // zuerst testen, ob ich von dem Service hinter einer Connection bekommen kann
1921 Reference< ::com::sun::star::util::XNumberFormatsSupplier > xSupplier;
1922 Reference< XRowSet > xForm;
1923 if ( m_rColumn.GetParent().getDataSource() )
1924 xForm = Reference< XRowSet >( Reference< XInterface >(*m_rColumn.GetParent().getDataSource()), UNO_QUERY );
1925 if ( xForm.is() )
1926 xSupplier = getNumberFormats( getConnection( xForm ), true );
1927 SvNumberFormatter* pFormatterUsed = NULL;
1928 if ( xSupplier.is() )
1930 SvNumberFormatsSupplierObj* pImplmentation = SvNumberFormatsSupplierObj::getImplementation( xSupplier );
1931 pFormatterUsed = pImplmentation ? pImplmentation->GetNumberFormatter() : NULL;
1933 if ( NULL == pFormatterUsed )
1934 { // der Cursor fuehrte nicht zum Erfolg -> Standard
1935 pFormatterUsed = static_cast< DoubleNumericField* >( m_pWindow.get() )->StandardFormatter();
1936 DBG_ASSERT( pFormatterUsed != NULL, "DbNumericField::implAdjustGenericFieldSetting: no standard formatter given by the numeric field !" );
1938 static_cast< DoubleNumericField* >( m_pWindow.get() )->SetFormatter( pFormatterUsed );
1939 static_cast< DoubleNumericField* >( m_pPainter.get() )->SetFormatter( pFormatterUsed );
1941 // und dann ein Format generieren, dass die gewuenschten Nachkommastellen usw. hat
1942 LanguageType aAppLanguage = Application::GetSettings().GetUILanguageTag().getLanguageType();
1943 OUString sFormatString = pFormatterUsed->GenerateFormat(0, aAppLanguage, bThousand, false, nScale);
1945 static_cast< DoubleNumericField* >( m_pWindow.get() )->SetFormat( sFormatString, aAppLanguage );
1946 static_cast< DoubleNumericField* >( m_pPainter.get() )->SetFormat( sFormatString, aAppLanguage );
1951 VclPtr<SpinField> DbNumericField::createField( vcl::Window* _pParent, WinBits _nFieldStyle, const Reference< XPropertySet >& /*_rxModel*/ )
1953 return VclPtr<DoubleNumericField>::Create( _pParent, _nFieldStyle );
1956 namespace
1959 static OUString lcl_setFormattedNumeric_nothrow( DoubleNumericField& _rField, const DbCellControl& _rControl,
1960 const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1962 OUString sValue;
1963 if ( _rxField.is() )
1967 double fValue = _rControl.GetValue( _rxField, _rxFormatter );
1968 if ( !_rxField->wasNull() )
1970 _rField.SetValue( fValue );
1971 sValue = _rField.GetText();
1974 catch( const Exception& )
1976 DBG_UNHANDLED_EXCEPTION();
1979 return sValue;
1984 OUString DbNumericField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& _rxFormatter, Color** /*ppColor*/)
1986 return lcl_setFormattedNumeric_nothrow(dynamic_cast<DoubleNumericField&>(*m_pPainter), *this, _rxField, _rxFormatter);
1990 void DbNumericField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& _rxFormatter)
1992 lcl_setFormattedNumeric_nothrow(dynamic_cast<DoubleNumericField&>(*m_pWindow), *this, _rxField, _rxFormatter);
1996 void DbNumericField::updateFromModel( Reference< XPropertySet > _rxModel )
1998 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbNumericField::updateFromModel: invalid call!" );
2000 double dValue = 0;
2001 if ( _rxModel->getPropertyValue( FM_PROP_VALUE ) >>= dValue )
2002 static_cast< DoubleNumericField* >( m_pWindow.get() )->SetValue( dValue );
2003 else
2004 m_pWindow->SetText( OUString() );
2008 bool DbNumericField::commitControl()
2010 OUString aText( m_pWindow->GetText());
2011 Any aVal;
2013 if (!aText.isEmpty()) // not empty
2015 double fValue = static_cast<DoubleNumericField*>(m_pWindow.get())->GetValue();
2016 aVal <<= (double)fValue;
2018 m_rColumn.getModel()->setPropertyValue(FM_PROP_VALUE, aVal);
2019 return true;
2022 DbCurrencyField::DbCurrencyField(DbGridColumn& _rColumn)
2023 :DbSpinField( _rColumn )
2024 ,m_nScale( 0 )
2026 doPropertyListening( FM_PROP_DECIMAL_ACCURACY );
2027 doPropertyListening( FM_PROP_VALUEMIN );
2028 doPropertyListening( FM_PROP_VALUEMAX );
2029 doPropertyListening( FM_PROP_VALUESTEP );
2030 doPropertyListening( FM_PROP_STRICTFORMAT );
2031 doPropertyListening( FM_PROP_SHOWTHOUSANDSEP );
2032 doPropertyListening( FM_PROP_CURRENCYSYMBOL );
2036 void DbCurrencyField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2038 DBG_ASSERT( m_pWindow, "DbCurrencyField::implAdjustGenericFieldSetting: not to be called without window!" );
2039 DBG_ASSERT( _rxModel.is(), "DbCurrencyField::implAdjustGenericFieldSetting: invalid model!" );
2040 if ( m_pWindow && _rxModel.is() )
2042 m_nScale = getINT16( _rxModel->getPropertyValue( FM_PROP_DECIMAL_ACCURACY ) );
2043 double nMin = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMIN ) );
2044 double nMax = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMAX ) );
2045 double nStep = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUESTEP ) );
2046 bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2047 bool bThousand = getBOOL( _rxModel->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP ) );
2048 OUString aStr( getString( _rxModel->getPropertyValue(FM_PROP_CURRENCYSYMBOL ) ) );
2050 //fdo#42747 the min/max/first/last of vcl NumericFormatters needs to be
2051 //multiplied by the no of decimal places. See also
2052 //VclBuilder::mungeAdjustment
2053 int nMul = rtl_math_pow10Exp(1, m_nScale);
2054 nMin *= nMul;
2055 nMax *= nMul;
2057 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetUseThousandSep( bThousand );
2058 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetDecimalDigits( m_nScale );
2059 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetCurrencySymbol( aStr );
2060 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetFirst( nMin );
2061 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetLast( nMax );
2062 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetMin( nMin );
2063 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetMax( nMax );
2064 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetSpinSize( nStep );
2065 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetStrictFormat( bStrict );
2067 static_cast< LongCurrencyField* >( m_pPainter.get() )->SetUseThousandSep( bThousand );
2068 static_cast< LongCurrencyField* >( m_pPainter.get() )->SetDecimalDigits( m_nScale );
2069 static_cast< LongCurrencyField* >( m_pPainter.get() )->SetCurrencySymbol( aStr );
2070 static_cast< LongCurrencyField* >( m_pPainter.get() )->SetFirst( nMin );
2071 static_cast< LongCurrencyField* >( m_pPainter.get() )->SetLast( nMax );
2072 static_cast< LongCurrencyField* >( m_pPainter.get() )->SetMin( nMin );
2073 static_cast< LongCurrencyField* >( m_pPainter.get() )->SetMax( nMax );
2074 static_cast< LongCurrencyField* >( m_pPainter.get() )->SetStrictFormat( bStrict );
2079 VclPtr<SpinField> DbCurrencyField::createField( vcl::Window* _pParent, WinBits _nFieldStyle, const Reference< XPropertySet >& /*_rxModel*/ )
2081 return VclPtr<LongCurrencyField>::Create( _pParent, _nFieldStyle );
2085 double DbCurrencyField::GetCurrency(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter) const
2087 double fValue = GetValue(_rxField, xFormatter);
2088 if (m_nScale)
2090 // OSL_TRACE("double = %.64f ",fValue);
2091 fValue = ::rtl::math::pow10Exp(fValue, m_nScale);
2092 fValue = ::rtl::math::round(fValue, 0);
2094 return fValue;
2097 namespace
2100 static OUString lcl_setFormattedCurrency_nothrow( LongCurrencyField& _rField, const DbCurrencyField& _rControl,
2101 const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
2103 OUString sValue;
2104 if ( _rxField.is() )
2108 double fValue = _rControl.GetCurrency( _rxField, _rxFormatter );
2109 if ( !_rxField->wasNull() )
2111 _rField.SetValue( fValue );
2112 sValue = _rField.GetText();
2115 catch( const Exception& )
2117 DBG_UNHANDLED_EXCEPTION();
2120 return sValue;
2125 OUString DbCurrencyField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& _rxFormatter, Color** /*ppColor*/)
2127 return lcl_setFormattedCurrency_nothrow( dynamic_cast< LongCurrencyField& >( *m_pPainter ), *this, _rxField, _rxFormatter );
2131 void DbCurrencyField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& _rxFormatter)
2133 lcl_setFormattedCurrency_nothrow( dynamic_cast< LongCurrencyField& >( *m_pWindow ), *this, _rxField, _rxFormatter );
2137 void DbCurrencyField::updateFromModel( Reference< XPropertySet > _rxModel )
2139 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbCurrencyField::updateFromModel: invalid call!" );
2141 double dValue = 0;
2142 if ( _rxModel->getPropertyValue( FM_PROP_VALUE ) >>= dValue )
2144 if ( m_nScale )
2146 dValue = ::rtl::math::pow10Exp( dValue, m_nScale );
2147 dValue = ::rtl::math::round(dValue, 0);
2150 static_cast< LongCurrencyField* >( m_pWindow.get() )->SetValue( dValue );
2152 else
2153 m_pWindow->SetText( OUString() );
2157 bool DbCurrencyField::commitControl()
2159 OUString aText(m_pWindow->GetText());
2160 Any aVal;
2161 if (!aText.isEmpty()) // not empty
2163 double fValue = static_cast<LongCurrencyField*>(m_pWindow.get())->GetValue();
2164 if (m_nScale)
2166 fValue /= ::rtl::math::pow10Exp(1.0, m_nScale);
2168 aVal <<= (double)fValue;
2170 m_rColumn.getModel()->setPropertyValue(FM_PROP_VALUE, aVal);
2171 return true;
2174 DbDateField::DbDateField( DbGridColumn& _rColumn )
2175 :DbSpinField( _rColumn )
2177 doPropertyListening( FM_PROP_DATEFORMAT );
2178 doPropertyListening( FM_PROP_DATEMIN );
2179 doPropertyListening( FM_PROP_DATEMAX );
2180 doPropertyListening( FM_PROP_STRICTFORMAT );
2181 doPropertyListening( FM_PROP_DATE_SHOW_CENTURY );
2185 VclPtr<SpinField> DbDateField::createField( vcl::Window* _pParent, WinBits _nFieldStyle, const Reference< XPropertySet >& _rxModel )
2187 // check if there is a DropDown property set to TRUE
2188 bool bDropDown = !hasProperty( FM_PROP_DROPDOWN, _rxModel )
2189 || getBOOL( _rxModel->getPropertyValue( FM_PROP_DROPDOWN ) );
2190 if ( bDropDown )
2191 _nFieldStyle |= WB_DROPDOWN;
2193 VclPtr<CalendarField> pField = VclPtr<CalendarField>::Create( _pParent, _nFieldStyle );
2195 pField->EnableToday();
2196 pField->EnableNone();
2198 return pField;
2202 void DbDateField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2204 DBG_ASSERT( m_pWindow, "DbDateField::implAdjustGenericFieldSetting: not to be called without window!" );
2205 DBG_ASSERT( _rxModel.is(), "DbDateField::implAdjustGenericFieldSetting: invalid model!" );
2206 if ( m_pWindow && _rxModel.is() )
2208 sal_Int16 nFormat = getINT16( _rxModel->getPropertyValue( FM_PROP_DATEFORMAT ) );
2209 util::Date aMin;
2210 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_DATEMIN ) >>= aMin );
2211 util::Date aMax;
2212 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_DATEMAX ) >>= aMax );
2213 bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2215 Any aCentury = _rxModel->getPropertyValue( FM_PROP_DATE_SHOW_CENTURY );
2216 if ( aCentury.getValueType().getTypeClass() != TypeClass_VOID )
2218 bool bShowDateCentury = getBOOL( aCentury );
2220 static_cast<DateField*>( m_pWindow.get() )->SetShowDateCentury( bShowDateCentury );
2221 static_cast<DateField*>( m_pPainter.get() )->SetShowDateCentury( bShowDateCentury );
2224 static_cast< DateField* >( m_pWindow.get() )->SetExtDateFormat( (ExtDateFieldFormat)nFormat );
2225 static_cast< DateField* >( m_pWindow.get() )->SetMin( aMin );
2226 static_cast< DateField* >( m_pWindow.get() )->SetMax( aMax );
2227 static_cast< DateField* >( m_pWindow.get() )->SetStrictFormat( bStrict );
2228 static_cast< DateField* >( m_pWindow.get() )->EnableEmptyFieldValue( true );
2230 static_cast< DateField* >( m_pPainter.get() )->SetExtDateFormat( (ExtDateFieldFormat)nFormat );
2231 static_cast< DateField* >( m_pPainter.get() )->SetMin( aMin );
2232 static_cast< DateField* >( m_pPainter.get() )->SetMax( aMax );
2233 static_cast< DateField* >( m_pPainter.get() )->SetStrictFormat( bStrict );
2234 static_cast< DateField* >( m_pPainter.get() )->EnableEmptyFieldValue( true );
2238 namespace
2241 static OUString lcl_setFormattedDate_nothrow( DateField& _rField, const Reference< XColumn >& _rxField )
2243 OUString sDate;
2244 if ( _rxField.is() )
2248 ::com::sun::star::util::Date aValue = _rxField->getDate();
2249 if ( _rxField->wasNull() )
2250 _rField.SetText( sDate );
2251 else
2253 _rField.SetDate( ::Date( aValue.Day, aValue.Month, aValue.Year ) );
2254 sDate = _rField.GetText();
2257 catch( const Exception& )
2259 DBG_UNHANDLED_EXCEPTION();
2262 return sDate;
2266 OUString DbDateField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
2268 return lcl_setFormattedDate_nothrow(dynamic_cast<DateField&>(*m_pPainter.get()), _rxField);
2272 void DbDateField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
2274 lcl_setFormattedDate_nothrow(dynamic_cast<DateField&>(*m_pWindow.get()), _rxField);
2278 void DbDateField::updateFromModel( Reference< XPropertySet > _rxModel )
2280 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbDateField::updateFromModel: invalid call!" );
2282 util::Date aDate;
2283 if ( _rxModel->getPropertyValue( FM_PROP_DATE ) >>= aDate )
2284 static_cast< DateField* >( m_pWindow.get() )->SetDate( ::Date( aDate ) );
2285 else
2286 static_cast< DateField* >( m_pWindow.get() )->SetText( OUString() );
2290 bool DbDateField::commitControl()
2292 OUString aText(m_pWindow->GetText());
2293 Any aVal;
2294 if (!aText.isEmpty())
2295 aVal <<= static_cast<DateField*>(m_pWindow.get())->GetDate().GetUNODate();
2296 else
2297 aVal.clear();
2299 m_rColumn.getModel()->setPropertyValue(FM_PROP_DATE, aVal);
2300 return true;
2303 DbTimeField::DbTimeField( DbGridColumn& _rColumn )
2304 :DbSpinField( _rColumn, ::com::sun::star::awt::TextAlign::LEFT )
2306 doPropertyListening( FM_PROP_TIMEFORMAT );
2307 doPropertyListening( FM_PROP_TIMEMIN );
2308 doPropertyListening( FM_PROP_TIMEMAX );
2309 doPropertyListening( FM_PROP_STRICTFORMAT );
2313 VclPtr<SpinField> DbTimeField::createField( vcl::Window* _pParent, WinBits _nFieldStyle, const Reference< XPropertySet >& /*_rxModel*/ )
2315 return VclPtr<TimeField>::Create( _pParent, _nFieldStyle );
2319 void DbTimeField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2321 DBG_ASSERT( m_pWindow, "DbTimeField::implAdjustGenericFieldSetting: not to be called without window!" );
2322 DBG_ASSERT( _rxModel.is(), "DbTimeField::implAdjustGenericFieldSetting: invalid model!" );
2323 if ( m_pWindow && _rxModel.is() )
2325 sal_Int16 nFormat = getINT16( _rxModel->getPropertyValue( FM_PROP_TIMEFORMAT ) );
2326 util::Time aMin;
2327 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_TIMEMIN ) >>= aMin );
2328 util::Time aMax;
2329 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_TIMEMAX ) >>= aMax );
2330 bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2332 static_cast< TimeField* >( m_pWindow.get() )->SetExtFormat( (ExtTimeFieldFormat)nFormat );
2333 static_cast< TimeField* >( m_pWindow.get() )->SetMin( aMin );
2334 static_cast< TimeField* >( m_pWindow.get() )->SetMax( aMax );
2335 static_cast< TimeField* >( m_pWindow.get() )->SetStrictFormat( bStrict );
2336 static_cast< TimeField* >( m_pWindow.get() )->EnableEmptyFieldValue( true );
2338 static_cast< TimeField* >( m_pPainter.get() )->SetExtFormat( (ExtTimeFieldFormat)nFormat );
2339 static_cast< TimeField* >( m_pPainter.get() )->SetMin( aMin );
2340 static_cast< TimeField* >( m_pPainter.get() )->SetMax( aMax );
2341 static_cast< TimeField* >( m_pPainter.get() )->SetStrictFormat( bStrict );
2342 static_cast< TimeField* >( m_pPainter.get() )->EnableEmptyFieldValue( true );
2346 namespace
2349 static OUString lcl_setFormattedTime_nothrow( TimeField& _rField, const Reference< XColumn >& _rxField )
2351 OUString sTime;
2352 if ( _rxField.is() )
2356 ::com::sun::star::util::Time aValue = _rxField->getTime();
2357 if ( _rxField->wasNull() )
2358 _rField.SetText( sTime );
2359 else
2361 _rField.SetTime( ::tools::Time( aValue ) );
2362 sTime = _rField.GetText();
2365 catch( const Exception& )
2367 DBG_UNHANDLED_EXCEPTION();
2370 return sTime;
2374 OUString DbTimeField::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< ::com::sun::star::util::XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
2376 return lcl_setFormattedTime_nothrow( *static_cast< TimeField* >( m_pPainter.get() ), _rxField );
2380 void DbTimeField::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
2382 lcl_setFormattedTime_nothrow( *static_cast< TimeField* >( m_pWindow.get() ), _rxField );
2386 void DbTimeField::updateFromModel( Reference< XPropertySet > _rxModel )
2388 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbTimeField::updateFromModel: invalid call!" );
2390 util::Time aTime;
2391 if ( _rxModel->getPropertyValue( FM_PROP_TIME ) >>= aTime )
2392 static_cast< TimeField* >( m_pWindow.get() )->SetTime( ::tools::Time( aTime ) );
2393 else
2394 static_cast< TimeField* >( m_pWindow.get() )->SetText( OUString() );
2398 bool DbTimeField::commitControl()
2400 OUString aText(m_pWindow->GetText());
2401 Any aVal;
2402 if (!aText.isEmpty())
2403 aVal <<= static_cast<TimeField*>(m_pWindow.get())->GetTime().GetUNOTime();
2404 else
2405 aVal.clear();
2407 m_rColumn.getModel()->setPropertyValue(FM_PROP_TIME, aVal);
2408 return true;
2411 DbComboBox::DbComboBox(DbGridColumn& _rColumn)
2412 :DbCellControl(_rColumn)
2414 setAlignedController( false );
2416 doPropertyListening( FM_PROP_STRINGITEMLIST );
2417 doPropertyListening( FM_PROP_LINECOUNT );
2421 void DbComboBox::_propertyChanged( const PropertyChangeEvent& _rEvent ) throw( RuntimeException )
2423 if ( _rEvent.PropertyName == FM_PROP_STRINGITEMLIST )
2425 SetList(_rEvent.NewValue);
2427 else
2429 DbCellControl::_propertyChanged( _rEvent ) ;
2434 void DbComboBox::SetList(const Any& rItems)
2436 ComboBoxControl* pField = static_cast<ComboBoxControl*>(m_pWindow.get());
2437 pField->Clear();
2439 ::comphelper::StringSequence aTest;
2440 if (rItems >>= aTest)
2442 const OUString* pStrings = aTest.getConstArray();
2443 sal_Int32 nItems = aTest.getLength();
2444 for (sal_Int32 i = 0; i < nItems; ++i, ++pStrings )
2445 pField->InsertEntry(*pStrings, LISTBOX_APPEND);
2447 // tell the grid control that this controller is invalid and has to be re-initialized
2448 invalidatedController();
2453 void DbComboBox::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2455 DBG_ASSERT( m_pWindow, "DbComboBox::implAdjustGenericFieldSetting: not to be called without window!" );
2456 DBG_ASSERT( _rxModel.is(), "DbComboBox::implAdjustGenericFieldSetting: invalid model!" );
2457 if ( m_pWindow && _rxModel.is() )
2459 sal_Int16 nLines = getINT16( _rxModel->getPropertyValue( FM_PROP_LINECOUNT ) );
2460 static_cast< ComboBoxControl* >( m_pWindow.get() )->SetDropDownLineCount( nLines );
2465 void DbComboBox::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor )
2467 m_rColumn.SetAlignmentFromModel(::com::sun::star::awt::TextAlign::LEFT);
2469 m_pWindow = VclPtr<ComboBoxControl>::Create( &rParent );
2471 // selection von rechts nach links
2472 AllSettings aSettings = m_pWindow->GetSettings();
2473 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2474 aStyleSettings.SetSelectionOptions(
2475 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2476 aSettings.SetStyleSettings(aStyleSettings);
2477 m_pWindow->SetSettings(aSettings, true);
2479 // some initial properties
2480 Reference< XPropertySet > xModel(m_rColumn.getModel());
2481 SetList( xModel->getPropertyValue( FM_PROP_STRINGITEMLIST ) );
2482 implAdjustGenericFieldSetting( xModel );
2484 DbCellControl::Init( rParent, xCursor );
2488 CellControllerRef DbComboBox::CreateController() const
2490 return new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2494 OUString DbComboBox::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter, Color** /*ppColor*/)
2496 const com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> xPS(_rxField, UNO_QUERY);
2497 ::dbtools::FormattedColumnValue fmter( xFormatter, xPS );
2499 return fmter.getFormattedValue();
2503 void DbComboBox::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
2505 m_pWindow->SetText(GetFormatText(_rxField, xFormatter));
2509 void DbComboBox::updateFromModel( Reference< XPropertySet > _rxModel )
2511 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbComboBox::updateFromModel: invalid call!" );
2513 OUString sText;
2514 _rxModel->getPropertyValue( FM_PROP_TEXT ) >>= sText;
2516 static_cast< ComboBox* >( m_pWindow.get() )->SetText( sText );
2517 static_cast< ComboBox* >( m_pWindow.get() )->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
2521 bool DbComboBox::commitControl()
2523 OUString aText( m_pWindow->GetText());
2524 m_rColumn.getModel()->setPropertyValue(FM_PROP_TEXT, makeAny(aText));
2525 return true;
2529 DbListBox::DbListBox(DbGridColumn& _rColumn)
2530 :DbCellControl(_rColumn)
2531 ,m_bBound(false)
2533 setAlignedController( false );
2535 doPropertyListening( FM_PROP_STRINGITEMLIST );
2536 doPropertyListening( FM_PROP_LINECOUNT );
2540 void DbListBox::_propertyChanged( const ::com::sun::star::beans::PropertyChangeEvent& _rEvent ) throw( RuntimeException )
2542 if ( _rEvent.PropertyName == FM_PROP_STRINGITEMLIST )
2544 SetList(_rEvent.NewValue);
2546 else
2548 DbCellControl::_propertyChanged( _rEvent ) ;
2553 void DbListBox::SetList(const Any& rItems)
2555 ListBoxControl* pField = static_cast<ListBoxControl*>(m_pWindow.get());
2557 pField->Clear();
2558 m_bBound = false;
2560 ::comphelper::StringSequence aTest;
2561 if (rItems >>= aTest)
2563 const OUString* pStrings = aTest.getConstArray();
2564 sal_Int32 nItems = aTest.getLength();
2565 if (nItems)
2567 for (sal_Int32 i = 0; i < nItems; ++i, ++pStrings )
2568 pField->InsertEntry(*pStrings, LISTBOX_APPEND);
2570 m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ) >>= m_aValueList;
2571 m_bBound = m_aValueList.getLength() > 0;
2573 // tell the grid control that this controller is invalid and has to be re-initialized
2574 invalidatedController();
2580 void DbListBox::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor)
2582 m_rColumn.SetAlignment(::com::sun::star::awt::TextAlign::LEFT);
2584 m_pWindow = VclPtr<ListBoxControl>::Create( &rParent );
2586 // some initial properties
2587 Reference< XPropertySet > xModel( m_rColumn.getModel() );
2588 SetList( xModel->getPropertyValue( FM_PROP_STRINGITEMLIST ) );
2589 implAdjustGenericFieldSetting( xModel );
2591 DbCellControl::Init( rParent, xCursor );
2595 void DbListBox::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2597 DBG_ASSERT( m_pWindow, "DbListBox::implAdjustGenericFieldSetting: not to be called without window!" );
2598 DBG_ASSERT( _rxModel.is(), "DbListBox::implAdjustGenericFieldSetting: invalid model!" );
2599 if ( m_pWindow && _rxModel.is() )
2601 sal_Int16 nLines = getINT16( _rxModel->getPropertyValue( FM_PROP_LINECOUNT ) );
2602 static_cast< ListBoxControl* >( m_pWindow.get() )->SetDropDownLineCount( nLines );
2607 CellControllerRef DbListBox::CreateController() const
2609 return new ListBoxCellController(static_cast<ListBoxControl*>(m_pWindow.get()));
2613 OUString DbListBox::GetFormatText(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
2615 OUString sText;
2616 if ( _rxField.is() )
2620 sText = _rxField->getString();
2621 if ( m_bBound )
2623 Sequence< sal_Int16 > aPosSeq = ::comphelper::findValue( m_aValueList, sText, true );
2624 if ( aPosSeq.getLength() )
2625 sText = static_cast<ListBox*>(m_pWindow.get())->GetEntry(aPosSeq.getConstArray()[0]);
2626 else
2627 sText.clear();
2630 catch( const Exception& )
2632 DBG_UNHANDLED_EXCEPTION();
2635 return sText;
2639 void DbListBox::UpdateFromField(const Reference< ::com::sun::star::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
2641 OUString sFormattedText( GetFormatText( _rxField, xFormatter ) );
2642 if (!sFormattedText.isEmpty())
2643 static_cast< ListBox* >( m_pWindow.get() )->SelectEntry( sFormattedText );
2644 else
2645 static_cast< ListBox* >( m_pWindow.get() )->SetNoSelection();
2649 void DbListBox::updateFromModel( Reference< XPropertySet > _rxModel )
2651 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbListBox::updateFromModel: invalid call!" );
2653 Sequence< sal_Int16 > aSelection;
2654 _rxModel->getPropertyValue( FM_PROP_SELECT_SEQ ) >>= aSelection;
2656 sal_Int16 nSelection = -1;
2657 if ( aSelection.getLength() > 0 )
2658 nSelection = aSelection[ 0 ];
2660 ListBox* pListBox = static_cast< ListBox* >( m_pWindow.get() );
2662 if ( ( nSelection >= 0 ) && ( nSelection < pListBox->GetEntryCount() ) )
2663 pListBox->SelectEntryPos( nSelection );
2664 else
2665 pListBox->SetNoSelection( );
2669 bool DbListBox::commitControl()
2671 Any aVal;
2672 Sequence<sal_Int16> aSelectSeq;
2673 if (static_cast<ListBox*>(m_pWindow.get())->GetSelectEntryCount())
2675 aSelectSeq.realloc(1);
2676 *(sal_Int16 *)aSelectSeq.getArray() = (sal_Int16)static_cast<ListBox*>(m_pWindow.get())->GetSelectEntryPos();
2678 aVal <<= aSelectSeq;
2679 m_rColumn.getModel()->setPropertyValue(FM_PROP_SELECT_SEQ, aVal);
2680 return true;
2683 DbFilterField::DbFilterField(const Reference< XComponentContext >& rxContext,DbGridColumn& _rColumn)
2684 :DbCellControl(_rColumn)
2685 ,OSQLParserClient(rxContext)
2686 ,m_nControlClass(::com::sun::star::form::FormComponentType::TEXTFIELD)
2687 ,m_bFilterList(false)
2688 ,m_bFilterListFilled(false)
2689 ,m_bBound(false)
2692 setAlignedController( false );
2696 DbFilterField::~DbFilterField()
2698 if (m_nControlClass == ::com::sun::star::form::FormComponentType::CHECKBOX)
2699 static_cast<CheckBoxControl*>(m_pWindow.get())->SetClickHdl( Link<>() );
2704 void DbFilterField::PaintCell(OutputDevice& rDev, const Rectangle& rRect)
2706 static const DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::VCenter | DrawTextFlags::Left;
2707 switch (m_nControlClass)
2709 case FormComponentType::CHECKBOX:
2710 DbCellControl::PaintCell( rDev, rRect );
2711 break;
2712 case FormComponentType::LISTBOX:
2713 rDev.DrawText(rRect, static_cast<ListBox*>(m_pWindow.get())->GetSelectEntry(), nStyle);
2714 break;
2715 default:
2716 rDev.DrawText(rRect, m_aText, nStyle);
2721 void DbFilterField::SetList(const Any& rItems, bool bComboBox)
2723 ::comphelper::StringSequence aTest;
2724 rItems >>= aTest;
2725 const OUString* pStrings = aTest.getConstArray();
2726 sal_Int32 nItems = aTest.getLength();
2727 if (nItems)
2729 if (bComboBox)
2731 ComboBox* pField = static_cast<ComboBox*>(m_pWindow.get());
2732 for (sal_Int32 i = 0; i < nItems; ++i, ++pStrings )
2733 pField->InsertEntry(*pStrings, LISTBOX_APPEND);
2735 else
2737 ListBox* pField = static_cast<ListBox*>(m_pWindow.get());
2738 for (sal_Int32 i = 0; i < nItems; ++i, ++pStrings )
2739 pField->InsertEntry(*pStrings, LISTBOX_APPEND);
2741 m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ) >>= m_aValueList;
2742 m_bBound = m_aValueList.getLength() > 0;
2748 void DbFilterField::CreateControl(vcl::Window* pParent, const Reference< ::com::sun::star::beans::XPropertySet >& xModel)
2750 switch (m_nControlClass)
2752 case ::com::sun::star::form::FormComponentType::CHECKBOX:
2753 m_pWindow = VclPtr<CheckBoxControl>::Create(pParent);
2754 m_pWindow->SetPaintTransparent( true );
2755 static_cast<CheckBoxControl*>(m_pWindow.get())->SetClickHdl( LINK( this, DbFilterField, OnClick ) );
2757 m_pPainter = VclPtr<CheckBoxControl>::Create(pParent);
2758 m_pPainter->SetPaintTransparent( true );
2759 m_pPainter->SetBackground();
2760 break;
2761 case ::com::sun::star::form::FormComponentType::LISTBOX:
2763 m_pWindow = VclPtr<ListBoxControl>::Create(pParent);
2764 sal_Int16 nLines = ::comphelper::getINT16(xModel->getPropertyValue(FM_PROP_LINECOUNT));
2765 Any aItems = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST);
2766 SetList(aItems, m_nControlClass == ::com::sun::star::form::FormComponentType::COMBOBOX);
2767 static_cast<ListBox*>(m_pWindow.get())->SetDropDownLineCount(nLines);
2768 } break;
2769 case ::com::sun::star::form::FormComponentType::COMBOBOX:
2771 m_pWindow = VclPtr<ComboBoxControl>::Create(pParent);
2773 AllSettings aSettings = m_pWindow->GetSettings();
2774 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2775 aStyleSettings.SetSelectionOptions(
2776 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2777 aSettings.SetStyleSettings(aStyleSettings);
2778 m_pWindow->SetSettings(aSettings, true);
2780 if (!m_bFilterList)
2782 sal_Int16 nLines = ::comphelper::getINT16(xModel->getPropertyValue(FM_PROP_LINECOUNT));
2783 Any aItems = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST);
2784 SetList(aItems, m_nControlClass == ::com::sun::star::form::FormComponentType::COMBOBOX);
2785 static_cast<ComboBox*>(m_pWindow.get())->SetDropDownLineCount(nLines);
2787 else
2788 static_cast<ComboBox*>(m_pWindow.get())->SetDropDownLineCount(5);
2790 } break;
2791 default:
2793 m_pWindow = VclPtr<Edit>::Create(pParent, WB_LEFT);
2794 AllSettings aSettings = m_pWindow->GetSettings();
2795 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2796 aStyleSettings.SetSelectionOptions(
2797 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2798 aSettings.SetStyleSettings(aStyleSettings);
2799 m_pWindow->SetSettings(aSettings, true);
2805 void DbFilterField::Init( vcl::Window& rParent, const Reference< XRowSet >& xCursor )
2807 Reference< ::com::sun::star::beans::XPropertySet > xModel(m_rColumn.getModel());
2808 m_rColumn.SetAlignment(::com::sun::star::awt::TextAlign::LEFT);
2810 if (xModel.is())
2812 m_bFilterList = ::comphelper::hasProperty(FM_PROP_FILTERPROPOSAL, xModel) && ::comphelper::getBOOL(xModel->getPropertyValue(FM_PROP_FILTERPROPOSAL));
2813 if (m_bFilterList)
2814 m_nControlClass = ::com::sun::star::form::FormComponentType::COMBOBOX;
2815 else
2817 sal_Int16 nClassId = ::comphelper::getINT16(xModel->getPropertyValue(FM_PROP_CLASSID));
2818 switch (nClassId)
2820 case FormComponentType::CHECKBOX:
2821 case FormComponentType::LISTBOX:
2822 case FormComponentType::COMBOBOX:
2823 m_nControlClass = nClassId;
2824 break;
2825 default:
2826 if (m_bFilterList)
2827 m_nControlClass = FormComponentType::COMBOBOX;
2828 else
2829 m_nControlClass = FormComponentType::TEXTFIELD;
2834 CreateControl( &rParent, xModel );
2835 DbCellControl::Init( rParent, xCursor );
2837 // filter cells are never readonly
2838 Edit* pAsEdit = dynamic_cast< Edit* >( m_pWindow.get() );
2839 if ( pAsEdit )
2840 pAsEdit->SetReadOnly( false );
2844 CellControllerRef DbFilterField::CreateController() const
2846 CellControllerRef xController;
2847 switch (m_nControlClass)
2849 case ::com::sun::star::form::FormComponentType::CHECKBOX:
2850 xController = new CheckBoxCellController(static_cast<CheckBoxControl*>(m_pWindow.get()));
2851 break;
2852 case ::com::sun::star::form::FormComponentType::LISTBOX:
2853 xController = new ListBoxCellController(static_cast<ListBoxControl*>(m_pWindow.get()));
2854 break;
2855 case ::com::sun::star::form::FormComponentType::COMBOBOX:
2856 xController = new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2857 break;
2858 default:
2859 if (m_bFilterList)
2860 xController = new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2861 else
2862 xController = new EditCellController(static_cast<Edit*>(m_pWindow.get()));
2864 return xController;
2868 void DbFilterField::updateFromModel( Reference< XPropertySet > _rxModel )
2870 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbFilterField::updateFromModel: invalid call!" );
2871 (void)_rxModel;
2873 OSL_FAIL( "DbListBox::updateFromModel: not implemented yet (how the hell did you reach this?)!" );
2874 // TODO: implement this.
2875 // remember: updateFromModel should be some kind of opposite of commitControl
2879 bool DbFilterField::commitControl()
2881 OUString aText(m_aText);
2882 switch (m_nControlClass)
2884 case ::com::sun::star::form::FormComponentType::CHECKBOX:
2885 return true;
2886 case ::com::sun::star::form::FormComponentType::LISTBOX:
2887 aText.clear();
2888 if (static_cast<ListBox*>(m_pWindow.get())->GetSelectEntryCount())
2890 sal_Int16 nPos = (sal_Int16)static_cast<ListBox*>(m_pWindow.get())->GetSelectEntryPos();
2891 if ( ( nPos >= 0 ) && ( nPos < m_aValueList.getLength() ) )
2892 aText = m_aValueList.getConstArray()[nPos];
2895 if (m_aText != aText)
2897 m_aText = aText;
2898 m_aCommitLink.Call(this);
2900 return true;
2901 default:
2902 aText = m_pWindow->GetText();
2905 if (m_aText != aText)
2907 // check the text with the SQL-Parser
2908 OUString aNewText(comphelper::string::stripEnd(aText, ' '));
2909 if (!aNewText.isEmpty())
2911 OUString aErrorMsg;
2912 Reference< XNumberFormatter > xNumberFormatter(m_rColumn.GetParent().getNumberFormatter());
2914 std::shared_ptr< OSQLParseNode > pParseNode = predicateTree(aErrorMsg, aNewText,xNumberFormatter, m_rColumn.GetField());
2915 if (pParseNode != nullptr)
2917 OUString aPreparedText;
2919 ::com::sun::star::lang::Locale aAppLocale = Application::GetSettings().GetUILanguageTag().getLocale();
2921 Reference< XRowSet > xDataSourceRowSet(
2922 Reference< XInterface >(*m_rColumn.GetParent().getDataSource()), UNO_QUERY);
2923 Reference< XConnection > xConnection(getConnection(xDataSourceRowSet));
2925 pParseNode->parseNodeToPredicateStr(aPreparedText,
2926 xConnection,
2927 xNumberFormatter,
2928 m_rColumn.GetField(),
2929 OUString(),
2930 aAppLocale,
2931 '.',
2932 getParseContext());
2933 m_aText = aPreparedText;
2935 else
2938 SQLException aError;
2939 aError.Message = aErrorMsg;
2940 displayException(aError, m_pWindow->GetParent());
2941 // TODO: transport the title
2943 return false;
2946 else
2947 m_aText = aText;
2949 m_pWindow->SetText(m_aText);
2950 m_aCommitLink.Call(this);
2952 return true;
2956 void DbFilterField::SetText(const OUString& rText)
2958 m_aText = rText;
2959 switch (m_nControlClass)
2961 case ::com::sun::star::form::FormComponentType::CHECKBOX:
2963 TriState eState;
2964 if (rText == "1")
2965 eState = TRISTATE_TRUE;
2966 else if (rText == "0")
2967 eState = TRISTATE_FALSE;
2968 else
2969 eState = TRISTATE_INDET;
2971 static_cast<CheckBoxControl*>(m_pWindow.get())->GetBox().SetState(eState);
2972 static_cast<CheckBoxControl*>(m_pPainter.get())->GetBox().SetState(eState);
2973 } break;
2974 case ::com::sun::star::form::FormComponentType::LISTBOX:
2976 Sequence<sal_Int16> aPosSeq = ::comphelper::findValue(m_aValueList, m_aText, true);
2977 if (aPosSeq.getLength())
2978 static_cast<ListBox*>(m_pWindow.get())->SelectEntryPos(aPosSeq.getConstArray()[0], true);
2979 else
2980 static_cast<ListBox*>(m_pWindow.get())->SetNoSelection();
2981 } break;
2982 default:
2983 m_pWindow->SetText(m_aText);
2986 // now force a repaint on the window
2987 m_rColumn.GetParent().RowModified(0,m_rColumn.GetId());
2991 void DbFilterField::Update()
2993 // should we fill the combobox with a filter proposal?
2994 if (m_bFilterList && !m_bFilterListFilled)
2996 m_bFilterListFilled = true;
2997 Reference< ::com::sun::star::beans::XPropertySet > xField = m_rColumn.GetField();
2998 if (!xField.is())
2999 return;
3001 OUString aName;
3002 xField->getPropertyValue(FM_PROP_NAME) >>= aName;
3004 // the columnmodel
3005 Reference< ::com::sun::star::container::XChild > xModelAsChild(m_rColumn.getModel(), UNO_QUERY);
3006 // the grid model
3007 xModelAsChild = Reference< ::com::sun::star::container::XChild > (xModelAsChild->getParent(),UNO_QUERY);
3008 Reference< XRowSet > xForm(xModelAsChild->getParent(), UNO_QUERY);
3009 if (!xForm.is())
3010 return;
3012 Reference<XPropertySet> xFormProp(xForm,UNO_QUERY);
3013 Reference< XTablesSupplier > xSupTab;
3014 xFormProp->getPropertyValue("SingleSelectQueryComposer") >>= xSupTab;
3016 Reference< XConnection > xConnection(getConnection(xForm));
3017 if (!xSupTab.is())
3018 return;
3020 // search the field
3021 Reference< XColumnsSupplier > xSupCol(xSupTab,UNO_QUERY);
3022 Reference< ::com::sun::star::container::XNameAccess > xFieldNames = xSupCol->getColumns();
3023 if (!xFieldNames->hasByName(aName))
3024 return;
3026 Reference< ::com::sun::star::container::XNameAccess > xTablesNames = xSupTab->getTables();
3027 Reference< ::com::sun::star::beans::XPropertySet > xComposerFieldAsSet(xFieldNames->getByName(aName),UNO_QUERY);
3029 if (xComposerFieldAsSet.is() && ::comphelper::hasProperty(FM_PROP_TABLENAME, xComposerFieldAsSet) &&
3030 ::comphelper::hasProperty(FM_PROP_FIELDSOURCE, xComposerFieldAsSet))
3032 OUString aFieldName;
3033 OUString aTableName;
3034 xComposerFieldAsSet->getPropertyValue(FM_PROP_FIELDSOURCE) >>= aFieldName;
3035 xComposerFieldAsSet->getPropertyValue(FM_PROP_TABLENAME) >>= aTableName;
3037 // no possibility to create a select statement
3038 // looking for the complete table name
3039 if (!xTablesNames->hasByName(aTableName))
3040 return;
3042 // ein Statement aufbauen und abschicken als query
3043 // Access to the connection
3044 Reference< XStatement > xStatement;
3045 Reference< XResultSet > xListCursor;
3046 Reference< ::com::sun::star::sdb::XColumn > xDataField;
3050 Reference< XDatabaseMetaData > xMeta = xConnection->getMetaData();
3052 OUString aQuote(xMeta->getIdentifierQuoteString());
3053 OUStringBuffer aStatement("SELECT DISTINCT ");
3054 aStatement.append(quoteName(aQuote, aName));
3055 if (!aFieldName.isEmpty() && aName != aFieldName)
3057 aStatement.append(" AS ");
3058 aStatement.append(quoteName(aQuote, aFieldName));
3061 aStatement.append(" FROM ");
3063 Reference< XPropertySet > xTableNameAccess(xTablesNames->getByName(aTableName), UNO_QUERY_THROW);
3064 aStatement.append(composeTableNameForSelect(xConnection, xTableNameAccess));
3066 xStatement = xConnection->createStatement();
3067 Reference< ::com::sun::star::beans::XPropertySet > xStatementProps(xStatement, UNO_QUERY);
3068 xStatementProps->setPropertyValue(FM_PROP_ESCAPE_PROCESSING, makeAny(true));
3070 xListCursor = xStatement->executeQuery(aStatement.makeStringAndClear());
3072 Reference< ::com::sun::star::sdbcx::XColumnsSupplier > xSupplyCols(xListCursor, UNO_QUERY);
3073 Reference< ::com::sun::star::container::XIndexAccess > xFields(xSupplyCols->getColumns(), UNO_QUERY);
3074 xDataField.set(xFields->getByIndex(0), css::uno::UNO_QUERY);
3075 if (!xDataField.is())
3076 return;
3078 catch(const Exception&)
3080 ::comphelper::disposeComponent(xStatement);
3081 return;
3084 sal_Int16 i = 0;
3085 ::std::vector< OUString > aStringList;
3086 aStringList.reserve(16);
3087 OUString aStr;
3088 com::sun::star::util::Date aNullDate = m_rColumn.GetParent().getNullDate();
3089 sal_Int32 nFormatKey = m_rColumn.GetKey();
3090 Reference< XNumberFormatter > xFormatter = m_rColumn.GetParent().getNumberFormatter();
3091 sal_Int16 nKeyType = ::comphelper::getNumberFormatType(xFormatter->getNumberFormatsSupplier()->getNumberFormats(), nFormatKey);
3093 while (!xListCursor->isAfterLast() && i++ < SHRT_MAX) // max anzahl eintraege
3095 aStr = getFormattedValue(xDataField, xFormatter, aNullDate, nFormatKey, nKeyType);
3096 aStringList.push_back(aStr);
3097 (void)xListCursor->next();
3100 // filling the entries for the combobox
3101 for (::std::vector< OUString >::const_iterator iter = aStringList.begin();
3102 iter != aStringList.end(); ++iter)
3103 static_cast<ComboBox*>(m_pWindow.get())->InsertEntry(*iter, LISTBOX_APPEND);
3109 OUString DbFilterField::GetFormatText(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/, Color** /*ppColor*/)
3111 return OUString();
3115 void DbFilterField::UpdateFromField(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/)
3117 OSL_FAIL( "DbFilterField::UpdateFromField: cannot update a filter control from a field!" );
3121 IMPL_LINK_NOARG(DbFilterField, OnClick)
3123 TriState eState = static_cast<CheckBoxControl*>(m_pWindow.get())->GetBox().GetState();
3124 OUString aText;
3126 switch (eState)
3128 case TRISTATE_TRUE:
3129 aText = "1";
3130 break;
3131 case TRISTATE_FALSE:
3132 aText = "0";
3133 break;
3134 case TRISTATE_INDET:
3135 break;
3138 if (m_aText != aText)
3140 m_aText = aText;
3141 m_aCommitLink.Call(this);
3143 return 1;
3146 TYPEINIT0(FmXGridCell);
3150 FmXGridCell::FmXGridCell( DbGridColumn* pColumn, DbCellControl* _pControl )
3151 :OComponentHelper(m_aMutex)
3152 ,m_pColumn(pColumn)
3153 ,m_pCellControl( _pControl )
3154 ,m_aWindowListeners( m_aMutex )
3155 ,m_aFocusListeners( m_aMutex )
3156 ,m_aKeyListeners( m_aMutex )
3157 ,m_aMouseListeners( m_aMutex )
3158 ,m_aMouseMotionListeners( m_aMutex )
3163 void FmXGridCell::init()
3165 vcl::Window* pEventWindow( getEventWindow() );
3166 if ( pEventWindow )
3167 pEventWindow->AddEventListener( LINK( this, FmXGridCell, OnWindowEvent ) );
3171 vcl::Window* FmXGridCell::getEventWindow() const
3173 if ( m_pCellControl )
3174 return &m_pCellControl->GetWindow();
3175 return NULL;
3179 FmXGridCell::~FmXGridCell()
3181 if (!OComponentHelper::rBHelper.bDisposed)
3183 acquire();
3184 dispose();
3190 void FmXGridCell::SetTextLineColor()
3192 if (m_pCellControl)
3193 m_pCellControl->SetTextLineColor();
3197 void FmXGridCell::SetTextLineColor(const Color& _rColor)
3199 if (m_pCellControl)
3200 m_pCellControl->SetTextLineColor(_rColor);
3203 // XTypeProvider
3205 Sequence< Type > SAL_CALL FmXGridCell::getTypes( ) throw (RuntimeException, std::exception)
3207 Sequence< uno::Type > aTypes = ::comphelper::concatSequences(
3208 ::cppu::OComponentHelper::getTypes(),
3209 FmXGridCell_Base::getTypes()
3211 if ( m_pCellControl )
3212 aTypes = ::comphelper::concatSequences(
3213 aTypes,
3214 FmXGridCell_WindowBase::getTypes()
3216 return aTypes;
3220 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXGridCell )
3222 // OComponentHelper
3224 void FmXGridCell::disposing()
3226 lang::EventObject aEvent( *this );
3227 m_aWindowListeners.disposeAndClear( aEvent );
3228 m_aFocusListeners.disposeAndClear( aEvent );
3229 m_aKeyListeners.disposeAndClear( aEvent );
3230 m_aMouseListeners.disposeAndClear( aEvent );
3231 m_aMouseMotionListeners.disposeAndClear( aEvent );
3233 OComponentHelper::disposing();
3234 m_pColumn = NULL;
3235 DELETEZ(m_pCellControl);
3239 Any SAL_CALL FmXGridCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException, std::exception)
3241 Any aReturn = OComponentHelper::queryAggregation( _rType );
3243 if ( !aReturn.hasValue() )
3244 aReturn = FmXGridCell_Base::queryInterface( _rType );
3246 if ( !aReturn.hasValue() && ( m_pCellControl != NULL ) )
3247 aReturn = FmXGridCell_WindowBase::queryInterface( _rType );
3249 return aReturn;
3252 // ::com::sun::star::awt::XControl
3254 Reference< XInterface > FmXGridCell::getContext() throw( RuntimeException, std::exception )
3256 return Reference< XInterface > ();
3260 Reference< ::com::sun::star::awt::XControlModel > FmXGridCell::getModel() throw( ::com::sun::star::uno::RuntimeException, std::exception )
3262 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3263 return Reference< ::com::sun::star::awt::XControlModel > (m_pColumn->getModel(), UNO_QUERY);
3266 // ::com::sun::star::form::XBoundControl
3268 sal_Bool FmXGridCell::getLock() throw( RuntimeException, std::exception )
3270 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3271 return m_pColumn->isLocked();
3275 void FmXGridCell::setLock(sal_Bool _bLock) throw( RuntimeException, std::exception )
3277 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3278 if (getLock() == _bLock)
3279 return;
3280 else
3282 ::osl::MutexGuard aGuard(m_aMutex);
3283 m_pColumn->setLock(_bLock);
3288 void SAL_CALL FmXGridCell::setPosSize( ::sal_Int32 _XX, ::sal_Int32 _Y, ::sal_Int32 _Width, ::sal_Int32 _Height, ::sal_Int16 _Flags ) throw (RuntimeException, std::exception)
3290 OSL_FAIL( "FmXGridCell::setPosSize: not implemented" );
3291 (void)_XX;
3292 (void)_Y;
3293 (void)_Width;
3294 (void)_Height;
3295 (void)_Flags;
3296 // not allowed to tamper with this for a grid cell
3300 awt::Rectangle SAL_CALL FmXGridCell::getPosSize( ) throw (RuntimeException, std::exception)
3302 OSL_FAIL( "FmXGridCell::getPosSize: not implemented" );
3303 return awt::Rectangle();
3307 void SAL_CALL FmXGridCell::setVisible( sal_Bool _Visible ) throw (RuntimeException, std::exception)
3309 OSL_FAIL( "FmXGridCell::setVisible: not implemented" );
3310 (void)_Visible;
3311 // not allowed to tamper with this for a grid cell
3315 void SAL_CALL FmXGridCell::setEnable( sal_Bool _Enable ) throw (RuntimeException, std::exception)
3317 OSL_FAIL( "FmXGridCell::setEnable: not implemented" );
3318 (void)_Enable;
3319 // not allowed to tamper with this for a grid cell
3323 void SAL_CALL FmXGridCell::setFocus( ) throw (RuntimeException, std::exception)
3325 OSL_FAIL( "FmXGridCell::setFocus: not implemented" );
3326 // not allowed to tamper with this for a grid cell
3330 void SAL_CALL FmXGridCell::addWindowListener( const Reference< awt::XWindowListener >& _rxListener ) throw (RuntimeException, std::exception)
3332 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3333 m_aWindowListeners.addInterface( _rxListener );
3337 void SAL_CALL FmXGridCell::removeWindowListener( const Reference< awt::XWindowListener >& _rxListener ) throw (RuntimeException, std::exception)
3339 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3340 m_aWindowListeners.removeInterface( _rxListener );
3344 void SAL_CALL FmXGridCell::addFocusListener( const Reference< awt::XFocusListener >& _rxListener ) throw (RuntimeException, std::exception)
3346 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3347 m_aFocusListeners.addInterface( _rxListener );
3351 void SAL_CALL FmXGridCell::removeFocusListener( const Reference< awt::XFocusListener >& _rxListener ) throw (RuntimeException, std::exception)
3353 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3354 m_aFocusListeners.removeInterface( _rxListener );
3358 void SAL_CALL FmXGridCell::addKeyListener( const Reference< awt::XKeyListener >& _rxListener ) throw (RuntimeException, std::exception)
3360 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3361 m_aKeyListeners.addInterface( _rxListener );
3365 void SAL_CALL FmXGridCell::removeKeyListener( const Reference< awt::XKeyListener >& _rxListener ) throw (RuntimeException, std::exception)
3367 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3368 m_aKeyListeners.removeInterface( _rxListener );
3372 void SAL_CALL FmXGridCell::addMouseListener( const Reference< awt::XMouseListener >& _rxListener ) throw (RuntimeException, std::exception)
3374 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3375 m_aMouseListeners.addInterface( _rxListener );
3379 void SAL_CALL FmXGridCell::removeMouseListener( const Reference< awt::XMouseListener >& _rxListener ) throw (RuntimeException, std::exception)
3381 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3382 m_aMouseListeners.removeInterface( _rxListener );
3386 void SAL_CALL FmXGridCell::addMouseMotionListener( const Reference< awt::XMouseMotionListener >& _rxListener ) throw (RuntimeException, std::exception)
3388 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3389 m_aMouseMotionListeners.addInterface( _rxListener );
3393 void SAL_CALL FmXGridCell::removeMouseMotionListener( const Reference< awt::XMouseMotionListener >& _rxListener ) throw (RuntimeException, std::exception)
3395 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3396 m_aMouseMotionListeners.removeInterface( _rxListener );
3400 void SAL_CALL FmXGridCell::addPaintListener( const Reference< awt::XPaintListener >& _rxListener ) throw (RuntimeException, std::exception)
3402 OSL_FAIL( "FmXGridCell::addPaintListener: not implemented" );
3403 (void)_rxListener;
3407 void SAL_CALL FmXGridCell::removePaintListener( const Reference< awt::XPaintListener >& _rxListener ) throw (RuntimeException, std::exception)
3409 OSL_FAIL( "FmXGridCell::removePaintListener: not implemented" );
3410 (void)_rxListener;
3414 IMPL_LINK( FmXGridCell, OnWindowEvent, VclWindowEvent*, _pEvent )
3416 ENSURE_OR_THROW( _pEvent, "illegal event pointer" );
3417 ENSURE_OR_THROW( _pEvent->GetWindow(), "illegal window" );
3418 onWindowEvent( _pEvent->GetId(), *_pEvent->GetWindow(), _pEvent->GetData() );
3419 return 1L;
3423 void FmXGridCell::onFocusGained( const awt::FocusEvent& _rEvent )
3425 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3426 m_aFocusListeners.notifyEach( &awt::XFocusListener::focusGained, _rEvent );
3430 void FmXGridCell::onFocusLost( const awt::FocusEvent& _rEvent )
3432 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3433 m_aFocusListeners.notifyEach( &awt::XFocusListener::focusLost, _rEvent );
3437 void FmXGridCell::onWindowEvent( const sal_uIntPtr _nEventId, const vcl::Window& _rWindow, const void* _pEventData )
3439 switch ( _nEventId )
3441 case VCLEVENT_CONTROL_GETFOCUS:
3442 case VCLEVENT_WINDOW_GETFOCUS:
3443 case VCLEVENT_CONTROL_LOSEFOCUS:
3444 case VCLEVENT_WINDOW_LOSEFOCUS:
3446 if ( ( _rWindow.IsCompoundControl()
3447 && ( _nEventId == VCLEVENT_CONTROL_GETFOCUS
3448 || _nEventId == VCLEVENT_CONTROL_LOSEFOCUS
3451 || ( !_rWindow.IsCompoundControl()
3452 && ( _nEventId == VCLEVENT_WINDOW_GETFOCUS
3453 || _nEventId == VCLEVENT_WINDOW_LOSEFOCUS
3458 if ( !m_aFocusListeners.getLength() )
3459 break;
3461 bool bFocusGained = ( _nEventId == VCLEVENT_CONTROL_GETFOCUS ) || ( _nEventId == VCLEVENT_WINDOW_GETFOCUS );
3463 awt::FocusEvent aEvent;
3464 aEvent.Source = *this;
3465 aEvent.FocusFlags = _rWindow.GetGetFocusFlags();
3466 aEvent.Temporary = sal_False;
3468 if ( bFocusGained )
3469 onFocusGained( aEvent );
3470 else
3471 onFocusLost( aEvent );
3474 break;
3475 case VCLEVENT_WINDOW_MOUSEBUTTONDOWN:
3476 case VCLEVENT_WINDOW_MOUSEBUTTONUP:
3478 if ( !m_aMouseListeners.getLength() )
3479 break;
3481 const bool bButtonDown = ( _nEventId == VCLEVENT_WINDOW_MOUSEBUTTONDOWN );
3483 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( *static_cast< const ::MouseEvent* >( _pEventData ), *this ) );
3484 m_aMouseListeners.notifyEach( bButtonDown ? &awt::XMouseListener::mousePressed : &awt::XMouseListener::mouseReleased, aEvent );
3486 break;
3487 case VCLEVENT_WINDOW_MOUSEMOVE:
3489 const MouseEvent& rMouseEvent = *static_cast< const ::MouseEvent* >( _pEventData );
3490 if ( rMouseEvent.IsEnterWindow() || rMouseEvent.IsLeaveWindow() )
3492 if ( m_aMouseListeners.getLength() != 0 )
3494 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
3495 m_aMouseListeners.notifyEach( rMouseEvent.IsEnterWindow() ? &awt::XMouseListener::mouseEntered: &awt::XMouseListener::mouseExited, aEvent );
3498 else if ( !rMouseEvent.IsEnterWindow() && !rMouseEvent.IsLeaveWindow() )
3500 if ( m_aMouseMotionListeners.getLength() != 0 )
3502 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
3503 aEvent.ClickCount = 0;
3504 const bool bSimpleMove = bool( rMouseEvent.GetMode() & MouseEventModifiers::SIMPLEMOVE );
3505 m_aMouseMotionListeners.notifyEach( bSimpleMove ? &awt::XMouseMotionListener::mouseMoved: &awt::XMouseMotionListener::mouseDragged, aEvent );
3509 break;
3510 case VCLEVENT_WINDOW_KEYINPUT:
3511 case VCLEVENT_WINDOW_KEYUP:
3513 if ( !m_aKeyListeners.getLength() )
3514 break;
3516 const bool bKeyPressed = ( _nEventId == VCLEVENT_WINDOW_KEYINPUT );
3517 awt::KeyEvent aEvent( VCLUnoHelper::createKeyEvent( *static_cast< const ::KeyEvent* >( _pEventData ), *this ) );
3518 m_aKeyListeners.notifyEach( bKeyPressed ? &awt::XKeyListener::keyPressed: &awt::XKeyListener::keyReleased, aEvent );
3520 break;
3524 TYPEINIT1(FmXDataCell, FmXGridCell);
3526 void FmXDataCell::PaintFieldToCell(OutputDevice& rDev, const Rectangle& rRect,
3527 const Reference< ::com::sun::star::sdb::XColumn >& _rxField,
3528 const Reference< XNumberFormatter >& xFormatter)
3530 m_pCellControl->PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
3534 void FmXDataCell::UpdateFromColumn()
3536 Reference< ::com::sun::star::sdb::XColumn > xField(m_pColumn->GetCurrentFieldValue());
3537 if (xField.is())
3538 m_pCellControl->UpdateFromField(xField, m_pColumn->GetParent().getNumberFormatter());
3541 TYPEINIT1(FmXTextCell, FmXDataCell);
3543 FmXTextCell::FmXTextCell( DbGridColumn* pColumn, DbCellControl& _rControl )
3544 :FmXDataCell( pColumn, _rControl )
3545 ,m_bFastPaint( true )
3550 void FmXTextCell::PaintFieldToCell(OutputDevice& rDev,
3551 const Rectangle& rRect,
3552 const Reference< ::com::sun::star::sdb::XColumn >& _rxField,
3553 const Reference< XNumberFormatter >& xFormatter)
3555 if ( !m_bFastPaint )
3557 FmXDataCell::PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
3558 return;
3561 DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::VCenter;
3562 if ( ( rDev.GetOutDevType() == OUTDEV_WINDOW ) && !static_cast< vcl::Window& >( rDev ).IsEnabled() )
3563 nStyle |= DrawTextFlags::Disable;
3565 switch (m_pColumn->GetAlignment())
3567 case ::com::sun::star::awt::TextAlign::RIGHT:
3568 nStyle |= DrawTextFlags::Right;
3569 break;
3570 case ::com::sun::star::awt::TextAlign::CENTER:
3571 nStyle |= DrawTextFlags::Center;
3572 break;
3573 default:
3574 nStyle |= DrawTextFlags::Left;
3577 Color* pColor = NULL;
3578 OUString aText = GetText(_rxField, xFormatter, &pColor);
3579 if (pColor != NULL)
3581 Color aOldTextColor( rDev.GetTextColor() );
3582 rDev.SetTextColor( *pColor );
3583 rDev.DrawText(rRect, aText, nStyle);
3584 rDev.SetTextColor( aOldTextColor );
3586 else
3587 rDev.DrawText(rRect, aText, nStyle);
3590 FmXEditCell::FmXEditCell( DbGridColumn* pColumn, DbCellControl& _rControl )
3591 :FmXTextCell( pColumn, _rControl )
3592 ,m_aTextListeners(m_aMutex)
3593 ,m_aChangeListeners( m_aMutex )
3594 ,m_pEditImplementation( NULL )
3595 ,m_bOwnEditImplementation( false )
3598 DbTextField* pTextField = PTR_CAST( DbTextField, &_rControl );
3599 if ( pTextField )
3602 m_pEditImplementation = pTextField->GetEditImplementation();
3603 if ( !pTextField->IsSimpleEdit() )
3604 m_bFastPaint = false;
3606 else
3608 m_pEditImplementation = new EditImplementation( static_cast< Edit& >( _rControl.GetWindow() ) );
3609 m_bOwnEditImplementation = true;
3614 FmXEditCell::~FmXEditCell()
3616 if (!OComponentHelper::rBHelper.bDisposed)
3618 acquire();
3619 dispose();
3625 // OComponentHelper
3627 void FmXEditCell::disposing()
3629 ::com::sun::star::lang::EventObject aEvt(*this);
3630 m_aTextListeners.disposeAndClear(aEvt);
3631 m_aChangeListeners.disposeAndClear(aEvt);
3633 m_pEditImplementation->SetModifyHdl( Link<>() );
3634 if ( m_bOwnEditImplementation )
3635 delete m_pEditImplementation;
3636 m_pEditImplementation = NULL;
3638 FmXDataCell::disposing();
3642 Any SAL_CALL FmXEditCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException, std::exception)
3644 Any aReturn = FmXTextCell::queryAggregation( _rType );
3646 if ( !aReturn.hasValue() )
3647 aReturn = FmXEditCell_Base::queryInterface( _rType );
3649 return aReturn;
3653 Sequence< ::com::sun::star::uno::Type > SAL_CALL FmXEditCell::getTypes( ) throw(RuntimeException, std::exception)
3655 return ::comphelper::concatSequences(
3656 FmXTextCell::getTypes(),
3657 FmXEditCell_Base::getTypes()
3662 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXEditCell )
3664 // ::com::sun::star::awt::XTextComponent
3666 void SAL_CALL FmXEditCell::addTextListener(const Reference< ::com::sun::star::awt::XTextListener >& l) throw( RuntimeException, std::exception )
3668 m_aTextListeners.addInterface( l );
3672 void SAL_CALL FmXEditCell::removeTextListener(const Reference< ::com::sun::star::awt::XTextListener >& l) throw( RuntimeException, std::exception )
3674 m_aTextListeners.removeInterface( l );
3678 void SAL_CALL FmXEditCell::setText( const OUString& aText ) throw( RuntimeException, std::exception )
3680 ::osl::MutexGuard aGuard( m_aMutex );
3682 if ( m_pEditImplementation )
3684 m_pEditImplementation->SetText( aText );
3686 // In JAVA wird auch ein textChanged ausgeloest, in VCL nicht.
3687 // ::com::sun::star::awt::Toolkit soll JAVA-komform sein...
3688 onTextChanged();
3693 void SAL_CALL FmXEditCell::insertText(const ::com::sun::star::awt::Selection& rSel, const OUString& aText) throw(RuntimeException, std::exception)
3695 ::osl::MutexGuard aGuard( m_aMutex );
3697 if ( m_pEditImplementation )
3699 m_pEditImplementation->SetSelection( Selection( rSel.Min, rSel.Max ) );
3700 m_pEditImplementation->ReplaceSelected( aText );
3705 OUString SAL_CALL FmXEditCell::getText() throw( RuntimeException, std::exception )
3707 ::osl::MutexGuard aGuard( m_aMutex );
3709 OUString aText;
3710 if ( m_pEditImplementation )
3712 if ( m_pEditImplementation->GetControl().IsVisible() && m_pColumn->GetParent().getDisplaySynchron())
3714 // if the display isn't sync with the cursor we can't ask the edit field
3715 LineEnd eLineEndFormat = getModelLineEndSetting( m_pColumn->getModel() );
3716 aText = m_pEditImplementation->GetText( eLineEndFormat );
3718 else
3720 Reference< ::com::sun::star::sdb::XColumn > xField(m_pColumn->GetCurrentFieldValue());
3721 if (xField.is())
3722 aText = GetText(xField, m_pColumn->GetParent().getNumberFormatter());
3725 return aText;
3729 OUString SAL_CALL FmXEditCell::getSelectedText() throw( RuntimeException, std::exception )
3731 ::osl::MutexGuard aGuard( m_aMutex );
3733 OUString aText;
3734 if ( m_pEditImplementation )
3736 LineEnd eLineEndFormat = m_pColumn ? getModelLineEndSetting( m_pColumn->getModel() ) : LINEEND_LF;
3737 aText = m_pEditImplementation->GetSelected( eLineEndFormat );
3739 return aText;
3743 void SAL_CALL FmXEditCell::setSelection( const ::com::sun::star::awt::Selection& aSelection ) throw( RuntimeException, std::exception )
3745 ::osl::MutexGuard aGuard( m_aMutex );
3747 if ( m_pEditImplementation )
3748 m_pEditImplementation->SetSelection( Selection( aSelection.Min, aSelection.Max ) );
3752 ::com::sun::star::awt::Selection SAL_CALL FmXEditCell::getSelection() throw( RuntimeException, std::exception )
3754 ::osl::MutexGuard aGuard( m_aMutex );
3756 Selection aSel;
3757 if ( m_pEditImplementation )
3758 aSel = m_pEditImplementation->GetSelection();
3760 return ::com::sun::star::awt::Selection(aSel.Min(), aSel.Max());
3764 sal_Bool SAL_CALL FmXEditCell::isEditable() throw( RuntimeException, std::exception )
3766 ::osl::MutexGuard aGuard( m_aMutex );
3768 return ( m_pEditImplementation && !m_pEditImplementation->IsReadOnly() && m_pEditImplementation->GetControl().IsEnabled() ) ? sal_True : sal_False;
3772 void SAL_CALL FmXEditCell::setEditable( sal_Bool bEditable ) throw( RuntimeException, std::exception )
3774 ::osl::MutexGuard aGuard( m_aMutex );
3776 if ( m_pEditImplementation )
3777 m_pEditImplementation->SetReadOnly( !bEditable );
3781 sal_Int16 SAL_CALL FmXEditCell::getMaxTextLen() throw( RuntimeException, std::exception )
3783 ::osl::MutexGuard aGuard( m_aMutex );
3785 return m_pEditImplementation ? m_pEditImplementation->GetMaxTextLen() : 0;
3789 void SAL_CALL FmXEditCell::setMaxTextLen( sal_Int16 nLen ) throw( RuntimeException, std::exception )
3791 ::osl::MutexGuard aGuard( m_aMutex );
3793 if ( m_pEditImplementation )
3794 m_pEditImplementation->SetMaxTextLen( nLen );
3798 void SAL_CALL FmXEditCell::addChangeListener( const Reference< form::XChangeListener >& _Listener ) throw (RuntimeException, std::exception)
3800 m_aChangeListeners.addInterface( _Listener );
3804 void SAL_CALL FmXEditCell::removeChangeListener( const Reference< form::XChangeListener >& _Listener ) throw (RuntimeException, std::exception)
3806 m_aChangeListeners.removeInterface( _Listener );
3810 void FmXEditCell::onTextChanged()
3812 ::com::sun::star::awt::TextEvent aEvent;
3813 aEvent.Source = *this;
3814 m_aTextListeners.notifyEach( &awt::XTextListener::textChanged, aEvent );
3818 void FmXEditCell::onFocusGained( const awt::FocusEvent& _rEvent )
3820 FmXTextCell::onFocusGained( _rEvent );
3821 m_sValueOnEnter = getText();
3825 void FmXEditCell::onFocusLost( const awt::FocusEvent& _rEvent )
3827 FmXTextCell::onFocusLost( _rEvent );
3829 if ( getText() != m_sValueOnEnter )
3831 lang::EventObject aEvent( *this );
3832 m_aChangeListeners.notifyEach( &XChangeListener::changed, aEvent );
3837 void FmXEditCell::onWindowEvent( const sal_uIntPtr _nEventId, const vcl::Window& _rWindow, const void* _pEventData )
3839 switch ( _nEventId )
3841 case VCLEVENT_EDIT_MODIFY:
3843 if ( m_pEditImplementation && m_aTextListeners.getLength() )
3844 onTextChanged();
3845 return;
3849 FmXTextCell::onWindowEvent( _nEventId, _rWindow, _pEventData );
3852 FmXCheckBoxCell::FmXCheckBoxCell( DbGridColumn* pColumn, DbCellControl& _rControl )
3853 :FmXDataCell( pColumn, _rControl )
3854 ,m_aItemListeners(m_aMutex)
3855 ,m_aActionListeners( m_aMutex )
3856 ,m_pBox( & static_cast< CheckBoxControl& >( _rControl.GetWindow() ).GetBox() )
3861 FmXCheckBoxCell::~FmXCheckBoxCell()
3863 if (!OComponentHelper::rBHelper.bDisposed)
3865 acquire();
3866 dispose();
3871 // OComponentHelper
3873 void FmXCheckBoxCell::disposing()
3875 ::com::sun::star::lang::EventObject aEvt(*this);
3876 m_aItemListeners.disposeAndClear(aEvt);
3877 m_aActionListeners.disposeAndClear(aEvt);
3879 static_cast< CheckBoxControl& >( m_pCellControl->GetWindow() ).SetClickHdl(Link<>());
3880 m_pBox = NULL;
3882 FmXDataCell::disposing();
3886 Any SAL_CALL FmXCheckBoxCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException, std::exception)
3888 Any aReturn = FmXDataCell::queryAggregation( _rType );
3890 if ( !aReturn.hasValue() )
3891 aReturn = FmXCheckBoxCell_Base::queryInterface( _rType );
3893 return aReturn;
3897 Sequence< ::com::sun::star::uno::Type > SAL_CALL FmXCheckBoxCell::getTypes( ) throw(RuntimeException, std::exception)
3899 return ::comphelper::concatSequences(
3900 FmXDataCell::getTypes(),
3901 FmXCheckBoxCell_Base::getTypes()
3906 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXCheckBoxCell )
3909 void SAL_CALL FmXCheckBoxCell::addItemListener( const Reference< ::com::sun::star::awt::XItemListener >& l ) throw( RuntimeException, std::exception )
3911 m_aItemListeners.addInterface( l );
3915 void SAL_CALL FmXCheckBoxCell::removeItemListener( const Reference< ::com::sun::star::awt::XItemListener >& l ) throw( RuntimeException, std::exception )
3917 m_aItemListeners.removeInterface( l );
3921 void SAL_CALL FmXCheckBoxCell::setState( short n ) throw( RuntimeException, std::exception )
3923 ::osl::MutexGuard aGuard( m_aMutex );
3925 if (m_pBox)
3927 UpdateFromColumn();
3928 m_pBox->SetState( (TriState)n );
3933 short SAL_CALL FmXCheckBoxCell::getState() throw( RuntimeException, std::exception )
3935 ::osl::MutexGuard aGuard( m_aMutex );
3937 if (m_pBox)
3939 UpdateFromColumn();
3940 return (short)m_pBox->GetState();
3942 return TRISTATE_INDET;
3946 void SAL_CALL FmXCheckBoxCell::enableTriState( sal_Bool b ) throw( RuntimeException, std::exception )
3948 ::osl::MutexGuard aGuard( m_aMutex );
3950 if (m_pBox)
3951 m_pBox->EnableTriState( b );
3955 void SAL_CALL FmXCheckBoxCell::addActionListener( const Reference< awt::XActionListener >& _Listener ) throw (RuntimeException, std::exception)
3957 m_aActionListeners.addInterface( _Listener );
3961 void SAL_CALL FmXCheckBoxCell::removeActionListener( const Reference< awt::XActionListener >& _Listener ) throw (RuntimeException, std::exception)
3963 m_aActionListeners.removeInterface( _Listener );
3967 void SAL_CALL FmXCheckBoxCell::setLabel( const OUString& _Label ) throw (RuntimeException, std::exception)
3969 SolarMutexGuard aGuard;
3970 if ( m_pColumn )
3972 DbGridControl& rGrid( m_pColumn->GetParent() );
3973 rGrid.SetColumnTitle( rGrid.GetColumnId( m_pColumn->GetFieldPos() ), _Label );
3978 void SAL_CALL FmXCheckBoxCell::setActionCommand( const OUString& _Command ) throw (RuntimeException, std::exception)
3980 m_aActionCommand = _Command;
3984 vcl::Window* FmXCheckBoxCell::getEventWindow() const
3986 return m_pBox;
3990 void FmXCheckBoxCell::onWindowEvent( const sal_uIntPtr _nEventId, const vcl::Window& _rWindow, const void* _pEventData )
3992 switch ( _nEventId )
3994 case VCLEVENT_CHECKBOX_TOGGLE:
3996 // check boxes are to be committed immediately (this holds for ordinary check box controls in
3997 // documents, and this must hold for check boxes in grid columns, too
3998 // 91210 - 22.08.2001 - frank.schoenheit@sun.com
3999 m_pCellControl->Commit();
4001 Reference< XWindow > xKeepAlive( this );
4002 if ( m_aItemListeners.getLength() && m_pBox )
4004 awt::ItemEvent aEvent;
4005 aEvent.Source = *this;
4006 aEvent.Highlighted = 0;
4007 aEvent.Selected = m_pBox->GetState();
4008 m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4010 if ( m_aActionListeners.getLength() )
4012 awt::ActionEvent aEvent;
4013 aEvent.Source = *this;
4014 aEvent.ActionCommand = m_aActionCommand;
4015 m_aActionListeners.notifyEach( &awt::XActionListener::actionPerformed, aEvent );
4018 break;
4020 default:
4021 FmXDataCell::onWindowEvent( _nEventId, _rWindow, _pEventData );
4022 break;
4026 FmXListBoxCell::FmXListBoxCell(DbGridColumn* pColumn, DbCellControl& _rControl)
4027 :FmXTextCell( pColumn, _rControl )
4028 ,m_aItemListeners(m_aMutex)
4029 ,m_aActionListeners(m_aMutex)
4030 ,m_pBox( &static_cast< ListBox& >( _rControl.GetWindow() ) )
4033 m_pBox->SetDoubleClickHdl( LINK( this, FmXListBoxCell, OnDoubleClick ) );
4037 FmXListBoxCell::~FmXListBoxCell()
4039 if (!OComponentHelper::rBHelper.bDisposed)
4041 acquire();
4042 dispose();
4047 // OComponentHelper
4049 void FmXListBoxCell::disposing()
4051 ::com::sun::star::lang::EventObject aEvt(*this);
4052 m_aItemListeners.disposeAndClear(aEvt);
4053 m_aActionListeners.disposeAndClear(aEvt);
4055 m_pBox->SetSelectHdl( Link<>() );
4056 m_pBox->SetDoubleClickHdl( Link<>() );
4057 m_pBox = NULL;
4059 FmXTextCell::disposing();
4063 Any SAL_CALL FmXListBoxCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException, std::exception)
4065 Any aReturn = FmXTextCell::queryAggregation(_rType);
4067 if ( !aReturn.hasValue() )
4068 aReturn = FmXListBoxCell_Base::queryInterface( _rType );
4070 return aReturn;
4074 Sequence< ::com::sun::star::uno::Type > SAL_CALL FmXListBoxCell::getTypes( ) throw(RuntimeException, std::exception)
4076 return ::comphelper::concatSequences(
4077 FmXTextCell::getTypes(),
4078 FmXListBoxCell_Base::getTypes()
4083 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXListBoxCell )
4086 void SAL_CALL FmXListBoxCell::addItemListener(const Reference< ::com::sun::star::awt::XItemListener >& l) throw( RuntimeException, std::exception )
4088 m_aItemListeners.addInterface( l );
4092 void SAL_CALL FmXListBoxCell::removeItemListener(const Reference< ::com::sun::star::awt::XItemListener >& l) throw( RuntimeException, std::exception )
4094 m_aItemListeners.removeInterface( l );
4098 void SAL_CALL FmXListBoxCell::addActionListener(const Reference< ::com::sun::star::awt::XActionListener >& l) throw( RuntimeException, std::exception )
4100 m_aActionListeners.addInterface( l );
4104 void SAL_CALL FmXListBoxCell::removeActionListener(const Reference< ::com::sun::star::awt::XActionListener >& l) throw( RuntimeException, std::exception )
4106 m_aActionListeners.removeInterface( l );
4110 void SAL_CALL FmXListBoxCell::addItem(const OUString& aItem, sal_Int16 nPos) throw( RuntimeException, std::exception )
4112 ::osl::MutexGuard aGuard( m_aMutex );
4113 if (m_pBox)
4114 m_pBox->InsertEntry( aItem, nPos );
4118 void SAL_CALL FmXListBoxCell::addItems(const ::comphelper::StringSequence& aItems, sal_Int16 nPos) throw( RuntimeException, std::exception )
4120 ::osl::MutexGuard aGuard( m_aMutex );
4121 if (m_pBox)
4123 sal_uInt16 nP = nPos;
4124 for ( sal_uInt16 n = 0; n < aItems.getLength(); n++ )
4126 m_pBox->InsertEntry( aItems.getConstArray()[n], nP );
4127 if ( nPos != -1 ) // Nicht wenn 0xFFFF, weil LIST_APPEND
4128 nP++;
4134 void SAL_CALL FmXListBoxCell::removeItems(sal_Int16 nPos, sal_Int16 nCount) throw( RuntimeException, std::exception )
4136 ::osl::MutexGuard aGuard( m_aMutex );
4137 if ( m_pBox )
4139 for ( sal_uInt16 n = nCount; n; )
4140 m_pBox->RemoveEntry( nPos + (--n) );
4145 sal_Int16 SAL_CALL FmXListBoxCell::getItemCount() throw( RuntimeException, std::exception )
4147 ::osl::MutexGuard aGuard( m_aMutex );
4148 return m_pBox ? m_pBox->GetEntryCount() : 0;
4152 OUString SAL_CALL FmXListBoxCell::getItem(sal_Int16 nPos) throw( RuntimeException, std::exception )
4154 ::osl::MutexGuard aGuard( m_aMutex );
4155 return m_pBox ? OUString(m_pBox->GetEntry(nPos)) : OUString();
4158 ::comphelper::StringSequence SAL_CALL FmXListBoxCell::getItems() throw( RuntimeException, std::exception )
4160 ::osl::MutexGuard aGuard( m_aMutex );
4162 ::comphelper::StringSequence aSeq;
4163 if (m_pBox)
4165 sal_uInt16 nEntries = m_pBox ->GetEntryCount();
4166 aSeq = ::comphelper::StringSequence( nEntries );
4167 for ( sal_uInt16 n = nEntries; n; )
4169 --n;
4170 aSeq.getArray()[n] = m_pBox ->GetEntry( n );
4173 return aSeq;
4177 sal_Int16 SAL_CALL FmXListBoxCell::getSelectedItemPos() throw( RuntimeException, std::exception )
4179 ::osl::MutexGuard aGuard( m_aMutex );
4180 if (m_pBox)
4182 UpdateFromColumn();
4183 sal_Int32 nPos = m_pBox->GetSelectEntryPos();
4184 if (nPos > SHRT_MAX || nPos < SHRT_MIN)
4185 throw std::out_of_range("awt::XListBox::getSelectedItemPos can only return a short");
4186 return nPos;
4188 return 0;
4192 Sequence< sal_Int16 > SAL_CALL FmXListBoxCell::getSelectedItemsPos() throw( RuntimeException, std::exception )
4194 ::osl::MutexGuard aGuard( m_aMutex );
4195 Sequence<sal_Int16> aSeq;
4197 if (m_pBox)
4199 UpdateFromColumn();
4200 sal_uInt16 nSelEntries = m_pBox->GetSelectEntryCount();
4201 aSeq = Sequence<sal_Int16>( nSelEntries );
4202 for ( sal_uInt16 n = 0; n < nSelEntries; n++ )
4203 aSeq.getArray()[n] = m_pBox->GetSelectEntryPos( n );
4205 return aSeq;
4208 OUString SAL_CALL FmXListBoxCell::getSelectedItem() throw( RuntimeException, std::exception )
4210 ::osl::MutexGuard aGuard( m_aMutex );
4212 OUString aItem;
4214 if (m_pBox)
4216 UpdateFromColumn();
4217 aItem = m_pBox->GetSelectEntry();
4220 return aItem;
4224 ::comphelper::StringSequence SAL_CALL FmXListBoxCell::getSelectedItems() throw( RuntimeException, std::exception )
4226 ::osl::MutexGuard aGuard( m_aMutex );
4228 ::comphelper::StringSequence aSeq;
4230 if (m_pBox)
4232 UpdateFromColumn();
4233 sal_uInt16 nSelEntries = m_pBox->GetSelectEntryCount();
4234 aSeq = ::comphelper::StringSequence( nSelEntries );
4235 for ( sal_uInt16 n = 0; n < nSelEntries; n++ )
4236 aSeq.getArray()[n] = m_pBox->GetSelectEntry( n );
4238 return aSeq;
4242 void SAL_CALL FmXListBoxCell::selectItemPos(sal_Int16 nPos, sal_Bool bSelect) throw( RuntimeException, std::exception )
4244 ::osl::MutexGuard aGuard( m_aMutex );
4246 if (m_pBox)
4247 m_pBox->SelectEntryPos( nPos, bSelect );
4251 void SAL_CALL FmXListBoxCell::selectItemsPos(const Sequence< sal_Int16 >& aPositions, sal_Bool bSelect) throw( RuntimeException, std::exception )
4253 ::osl::MutexGuard aGuard( m_aMutex );
4255 if (m_pBox)
4257 for ( sal_uInt16 n = (sal_uInt16)aPositions.getLength(); n; )
4258 m_pBox->SelectEntryPos( (sal_uInt16) aPositions.getConstArray()[--n], bSelect );
4263 void SAL_CALL FmXListBoxCell::selectItem(const OUString& aItem, sal_Bool bSelect) throw( RuntimeException, std::exception )
4265 ::osl::MutexGuard aGuard( m_aMutex );
4267 if (m_pBox)
4268 m_pBox->SelectEntry( aItem, bSelect );
4272 sal_Bool SAL_CALL FmXListBoxCell::isMutipleMode() throw( RuntimeException, std::exception )
4274 ::osl::MutexGuard aGuard( m_aMutex );
4276 bool bMulti = false;
4277 if (m_pBox)
4278 bMulti = m_pBox->IsMultiSelectionEnabled();
4279 return bMulti;
4283 void SAL_CALL FmXListBoxCell::setMultipleMode(sal_Bool bMulti) throw( RuntimeException, std::exception )
4285 ::osl::MutexGuard aGuard( m_aMutex );
4287 if (m_pBox)
4288 m_pBox->EnableMultiSelection( bMulti );
4292 sal_Int16 SAL_CALL FmXListBoxCell::getDropDownLineCount() throw( RuntimeException, std::exception )
4294 ::osl::MutexGuard aGuard( m_aMutex );
4296 sal_Int16 nLines = 0;
4297 if (m_pBox)
4298 nLines = m_pBox->GetDropDownLineCount();
4300 return nLines;
4304 void SAL_CALL FmXListBoxCell::setDropDownLineCount(sal_Int16 nLines) throw( RuntimeException, std::exception )
4306 ::osl::MutexGuard aGuard( m_aMutex );
4308 if (m_pBox)
4309 m_pBox->SetDropDownLineCount( nLines );
4313 void SAL_CALL FmXListBoxCell::makeVisible(sal_Int16 nEntry) throw( RuntimeException, std::exception )
4315 ::osl::MutexGuard aGuard( m_aMutex );
4317 if (m_pBox)
4318 m_pBox->SetTopEntry( nEntry );
4322 void FmXListBoxCell::onWindowEvent( const sal_uIntPtr _nEventId, const vcl::Window& _rWindow, const void* _pEventData )
4324 if ( ( &_rWindow == m_pBox )
4325 && ( _nEventId == VCLEVENT_LISTBOX_SELECT )
4328 OnDoubleClick( NULL );
4330 ::com::sun::star::awt::ItemEvent aEvent;
4331 aEvent.Source = *this;
4332 aEvent.Highlighted = 0;
4334 // Bei Mehrfachselektion 0xFFFF, sonst die ID
4335 aEvent.Selected = (m_pBox->GetSelectEntryCount() == 1 )
4336 ? m_pBox->GetSelectEntryPos() : 0xFFFF;
4338 m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4339 return;
4342 FmXTextCell::onWindowEvent( _nEventId, _rWindow, _pEventData );
4347 IMPL_LINK_NOARG(FmXListBoxCell, OnDoubleClick)
4349 if (m_pBox)
4351 ::cppu::OInterfaceIteratorHelper aIt( m_aActionListeners );
4353 ::com::sun::star::awt::ActionEvent aEvent;
4354 aEvent.Source = *this;
4355 aEvent.ActionCommand = m_pBox->GetSelectEntry();
4357 while( aIt.hasMoreElements() )
4358 static_cast< ::com::sun::star::awt::XActionListener *>(aIt.next())->actionPerformed( aEvent );
4360 return 1;
4363 FmXComboBoxCell::FmXComboBoxCell( DbGridColumn* pColumn, DbCellControl& _rControl )
4364 :FmXTextCell( pColumn, _rControl )
4365 ,m_aItemListeners( m_aMutex )
4366 ,m_aActionListeners( m_aMutex )
4367 ,m_pComboBox( &static_cast< ComboBox& >( _rControl.GetWindow() ) )
4372 FmXComboBoxCell::~FmXComboBoxCell()
4374 if ( !OComponentHelper::rBHelper.bDisposed )
4376 acquire();
4377 dispose();
4383 void FmXComboBoxCell::disposing()
4385 ::com::sun::star::lang::EventObject aEvt(*this);
4386 m_aItemListeners.disposeAndClear(aEvt);
4387 m_aActionListeners.disposeAndClear(aEvt);
4389 FmXTextCell::disposing();
4393 Any SAL_CALL FmXComboBoxCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException, std::exception)
4395 Any aReturn = FmXTextCell::queryAggregation(_rType);
4397 if ( !aReturn.hasValue() )
4398 aReturn = FmXComboBoxCell_Base::queryInterface( _rType );
4400 return aReturn;
4404 Sequence< Type > SAL_CALL FmXComboBoxCell::getTypes( ) throw(RuntimeException, std::exception)
4406 return ::comphelper::concatSequences(
4407 FmXTextCell::getTypes(),
4408 FmXComboBoxCell_Base::getTypes()
4413 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXComboBoxCell )
4416 void SAL_CALL FmXComboBoxCell::addItemListener(const Reference< awt::XItemListener >& l) throw( RuntimeException, std::exception )
4418 m_aItemListeners.addInterface( l );
4422 void SAL_CALL FmXComboBoxCell::removeItemListener(const Reference< awt::XItemListener >& l) throw( RuntimeException, std::exception )
4424 m_aItemListeners.removeInterface( l );
4428 void SAL_CALL FmXComboBoxCell::addActionListener(const Reference< awt::XActionListener >& l) throw( RuntimeException, std::exception )
4430 m_aActionListeners.addInterface( l );
4434 void SAL_CALL FmXComboBoxCell::removeActionListener(const Reference< awt::XActionListener >& l) throw( RuntimeException, std::exception )
4436 m_aActionListeners.removeInterface( l );
4440 void SAL_CALL FmXComboBoxCell::addItem( const OUString& _Item, sal_Int16 _Pos ) throw( RuntimeException, std::exception )
4442 ::osl::MutexGuard aGuard( m_aMutex );
4443 if ( m_pComboBox )
4444 m_pComboBox->InsertEntry( _Item, _Pos );
4448 void SAL_CALL FmXComboBoxCell::addItems( const Sequence< OUString >& _Items, sal_Int16 _Pos ) throw( RuntimeException, std::exception )
4450 ::osl::MutexGuard aGuard( m_aMutex );
4451 if ( m_pComboBox )
4453 sal_uInt16 nP = _Pos;
4454 for ( sal_uInt16 n = 0; n < _Items.getLength(); n++ )
4456 m_pComboBox->InsertEntry( _Items.getConstArray()[n], nP );
4457 if ( _Pos != -1 )
4458 nP++;
4464 void SAL_CALL FmXComboBoxCell::removeItems( sal_Int16 _Pos, sal_Int16 _Count ) throw( RuntimeException, std::exception )
4466 ::osl::MutexGuard aGuard( m_aMutex );
4467 if ( m_pComboBox )
4469 for ( sal_uInt16 n = _Count; n; )
4470 m_pComboBox->RemoveEntryAt( _Pos + (--n) );
4475 sal_Int16 SAL_CALL FmXComboBoxCell::getItemCount() throw( RuntimeException, std::exception )
4477 ::osl::MutexGuard aGuard( m_aMutex );
4478 return m_pComboBox ? m_pComboBox->GetEntryCount() : 0;
4482 OUString SAL_CALL FmXComboBoxCell::getItem( sal_Int16 _Pos ) throw( RuntimeException, std::exception )
4484 ::osl::MutexGuard aGuard( m_aMutex );
4485 return m_pComboBox ? OUString(m_pComboBox->GetEntry(_Pos)) : OUString();
4488 Sequence< OUString > SAL_CALL FmXComboBoxCell::getItems() throw( RuntimeException, std::exception )
4490 ::osl::MutexGuard aGuard( m_aMutex );
4492 Sequence< OUString > aItems;
4493 if ( m_pComboBox )
4495 sal_uInt16 nEntries = m_pComboBox->GetEntryCount();
4496 aItems.realloc( nEntries );
4497 OUString* pItem = aItems.getArray();
4498 for ( sal_uInt16 n=0; n<nEntries; ++n, ++pItem )
4499 *pItem = m_pComboBox->GetEntry( n );
4501 return aItems;
4505 sal_Int16 SAL_CALL FmXComboBoxCell::getDropDownLineCount() throw( RuntimeException, std::exception )
4507 ::osl::MutexGuard aGuard( m_aMutex );
4509 sal_Int16 nLines = 0;
4510 if ( m_pComboBox )
4511 nLines = m_pComboBox->GetDropDownLineCount();
4513 return nLines;
4517 void SAL_CALL FmXComboBoxCell::setDropDownLineCount(sal_Int16 nLines) throw( RuntimeException, std::exception )
4519 ::osl::MutexGuard aGuard( m_aMutex );
4520 if ( m_pComboBox )
4521 m_pComboBox->SetDropDownLineCount( nLines );
4525 void FmXComboBoxCell::onWindowEvent( const sal_uIntPtr _nEventId, const vcl::Window& _rWindow, const void* _pEventData )
4528 switch ( _nEventId )
4530 case VCLEVENT_COMBOBOX_SELECT:
4532 awt::ItemEvent aEvent;
4533 aEvent.Source = *this;
4534 aEvent.Highlighted = 0;
4536 // Bei Mehrfachselektion 0xFFFF, sonst die ID
4537 aEvent.Selected = ( m_pComboBox->GetSelectEntryCount() == 1 )
4538 ? m_pComboBox->GetSelectEntryPos()
4539 : 0xFFFF;
4540 m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4542 break;
4544 default:
4545 FmXTextCell::onWindowEvent( _nEventId, _rWindow, _pEventData );
4546 break;
4550 TYPEINIT1(FmXFilterCell, FmXGridCell);
4552 FmXFilterCell::FmXFilterCell(DbGridColumn* pColumn, DbCellControl* pControl )
4553 :FmXGridCell( pColumn, pControl )
4554 ,m_aTextListeners(m_aMutex)
4557 DBG_ASSERT( m_pCellControl->ISA( DbFilterField ), "FmXFilterCell::FmXFilterCell: invalid cell control!" );
4558 static_cast< DbFilterField* >( m_pCellControl )->SetCommitHdl( LINK( this, FmXFilterCell, OnCommit ) );
4562 FmXFilterCell::~FmXFilterCell()
4564 if (!OComponentHelper::rBHelper.bDisposed)
4566 acquire();
4567 dispose();
4572 // XUnoTunnel
4574 sal_Int64 SAL_CALL FmXFilterCell::getSomething( const Sequence< sal_Int8 >& _rIdentifier ) throw(RuntimeException, std::exception)
4576 sal_Int64 nReturn(0);
4578 if ( (_rIdentifier.getLength() == 16)
4579 && (0 == memcmp( getUnoTunnelId().getConstArray(), _rIdentifier.getConstArray(), 16 ))
4582 nReturn = reinterpret_cast<sal_Int64>(this);
4585 return nReturn;
4588 namespace
4590 class theFmXFilterCellUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theFmXFilterCellUnoTunnelId > {};
4593 const Sequence<sal_Int8>& FmXFilterCell::getUnoTunnelId()
4595 return theFmXFilterCellUnoTunnelId::get().getSeq();
4599 void FmXFilterCell::PaintCell( OutputDevice& rDev, const Rectangle& rRect )
4601 static_cast< DbFilterField* >( m_pCellControl )->PaintCell( rDev, rRect );
4604 // OComponentHelper
4606 void FmXFilterCell::disposing()
4608 ::com::sun::star::lang::EventObject aEvt(*this);
4609 m_aTextListeners.disposeAndClear(aEvt);
4611 static_cast<DbFilterField*>(m_pCellControl)->SetCommitHdl(Link<>());
4613 FmXGridCell::disposing();
4617 Any SAL_CALL FmXFilterCell::queryAggregation( const ::com::sun::star::uno::Type& _rType ) throw(RuntimeException, std::exception)
4619 Any aReturn = FmXGridCell::queryAggregation(_rType);
4621 if ( !aReturn.hasValue() )
4622 aReturn = FmXFilterCell_Base::queryInterface( _rType );
4624 return aReturn;
4628 Sequence< ::com::sun::star::uno::Type > SAL_CALL FmXFilterCell::getTypes( ) throw(RuntimeException, std::exception)
4630 return ::comphelper::concatSequences(
4631 FmXGridCell::getTypes(),
4632 FmXFilterCell_Base::getTypes()
4637 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXFilterCell )
4639 // ::com::sun::star::awt::XTextComponent
4641 void SAL_CALL FmXFilterCell::addTextListener(const Reference< ::com::sun::star::awt::XTextListener >& l) throw( RuntimeException, std::exception )
4643 m_aTextListeners.addInterface( l );
4647 void SAL_CALL FmXFilterCell::removeTextListener(const Reference< ::com::sun::star::awt::XTextListener >& l) throw( RuntimeException, std::exception )
4649 m_aTextListeners.removeInterface( l );
4653 void SAL_CALL FmXFilterCell::setText( const OUString& aText ) throw( RuntimeException, std::exception )
4655 ::osl::MutexGuard aGuard( m_aMutex );
4656 static_cast<DbFilterField*>(m_pCellControl)->SetText(aText);
4660 void SAL_CALL FmXFilterCell::insertText( const ::com::sun::star::awt::Selection& /*rSel*/, const OUString& /*aText*/ ) throw( RuntimeException, std::exception )
4665 OUString SAL_CALL FmXFilterCell::getText() throw( RuntimeException, std::exception )
4667 ::osl::MutexGuard aGuard( m_aMutex );
4668 return static_cast<DbFilterField*>(m_pCellControl)->GetText();
4672 OUString SAL_CALL FmXFilterCell::getSelectedText() throw( RuntimeException, std::exception )
4674 return getText();
4678 void SAL_CALL FmXFilterCell::setSelection( const ::com::sun::star::awt::Selection& /*aSelection*/ ) throw( RuntimeException, std::exception )
4683 ::com::sun::star::awt::Selection SAL_CALL FmXFilterCell::getSelection() throw( RuntimeException, std::exception )
4685 return ::com::sun::star::awt::Selection();
4689 sal_Bool SAL_CALL FmXFilterCell::isEditable() throw( RuntimeException, std::exception )
4691 return sal_True;
4695 void SAL_CALL FmXFilterCell::setEditable( sal_Bool /*bEditable*/ ) throw( RuntimeException, std::exception )
4700 sal_Int16 SAL_CALL FmXFilterCell::getMaxTextLen() throw( RuntimeException, std::exception )
4702 return 0;
4706 void SAL_CALL FmXFilterCell::setMaxTextLen( sal_Int16 /*nLen*/ ) throw( RuntimeException, std::exception )
4711 IMPL_LINK_NOARG(FmXFilterCell, OnCommit)
4713 ::cppu::OInterfaceIteratorHelper aIt( m_aTextListeners );
4714 ::com::sun::star::awt::TextEvent aEvt;
4715 aEvt.Source = *this;
4716 while( aIt.hasMoreElements() )
4717 static_cast< ::com::sun::star::awt::XTextListener *>(aIt.next())->textChanged( aEvt );
4718 return 1;
4721 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */