sd: keep a non-owning pointer to the OverridingShell
[LibreOffice.git] / svx / source / fmcomp / gridcell.cxx
blobd43351da912a8845bf312744dac32fd4b1a36d97
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 <memory>
22 #include <sal/log.hxx>
23 #include <fmprop.hxx>
24 #include <svx/strings.hrc>
25 #include <svx/fmtools.hxx>
26 #include <gridcell.hxx>
27 #include <gridcols.hxx>
28 #include <sdbdatacolumn.hxx>
30 #include <com/sun/star/awt/LineEndFormat.hpp>
31 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
32 #include <com/sun/star/awt/VisualEffect.hpp>
33 #include <com/sun/star/container/XChild.hpp>
34 #include <com/sun/star/container/XIndexAccess.hpp>
35 #include <com/sun/star/form/FormComponentType.hpp>
36 #include <com/sun/star/form/XBoundComponent.hpp>
37 #include <com/sun/star/script/XEventAttacherManager.hpp>
38 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
39 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
40 #include <com/sun/star/sdbc/DataType.hpp>
41 #include <com/sun/star/sdbc/SQLException.hpp>
42 #include <com/sun/star/sdbc/XRowSet.hpp>
43 #include <com/sun/star/sdbc/XStatement.hpp>
44 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
45 #include <com/sun/star/util/XNumberFormatter.hpp>
46 #include <com/sun/star/util/Time.hpp>
47 #include <com/sun/star/util/Date.hpp>
49 #include <comphelper/numbers.hxx>
50 #include <comphelper/property.hxx>
51 #include <comphelper/servicehelper.hxx>
52 #include <comphelper/string.hxx>
53 #include <comphelper/types.hxx>
54 #include <connectivity/formattedcolumnvalue.hxx>
55 #include <i18nlangtag/lang.h>
56 #include <o3tl/safeint.hxx>
57 #include <svl/numformat.hxx>
58 #include <svl/numuno.hxx>
59 #include <svx/dialmgr.hxx>
60 #include <toolkit/helper/listenermultiplexer.hxx>
61 #include <toolkit/helper/vclunohelper.hxx>
62 #include <tools/debug.hxx>
63 #include <tools/fract.hxx>
64 #include <comphelper/diagnose_ex.hxx>
65 #include <vcl/settings.hxx>
66 #include <vcl/svapp.hxx>
67 #include <connectivity/dbtools.hxx>
68 #include <connectivity/dbconversion.hxx>
69 #include <connectivity/sqlnode.hxx>
71 using namespace ::connectivity;
72 using namespace ::svxform;
73 using namespace ::comphelper;
74 using namespace ::svt;
75 using namespace ::com::sun::star;
76 using namespace ::com::sun::star::uno;
77 using namespace ::com::sun::star::sdbc;
78 using namespace ::com::sun::star::sdbcx;
79 using namespace ::com::sun::star::sdb;
80 using namespace ::com::sun::star::beans;
81 using namespace ::com::sun::star::form;
82 using namespace ::dbtools::DBTypeConversion;
83 using namespace ::dbtools;
85 using ::com::sun::star::util::XNumberFormatter;
87 constexpr OUString INVALIDTEXT = u"###"_ustr;
88 constexpr OUString OBJECTTEXT = u"<OBJECT>"_ustr;
91 //= helper
93 namespace
95 LineEnd getModelLineEndSetting( const Reference< XPropertySet >& _rxModel )
97 LineEnd eFormat = LINEEND_LF;
99 try
101 sal_Int16 nLineEndFormat = awt::LineEndFormat::LINE_FEED;
103 Reference< XPropertySetInfo > xPSI;
104 if ( _rxModel.is() )
105 xPSI = _rxModel->getPropertySetInfo();
107 OSL_ENSURE( xPSI.is(), "getModelLineEndSetting: invalid column model!" );
108 if ( xPSI.is() && xPSI->hasPropertyByName( FM_PROP_LINEENDFORMAT ) )
110 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_LINEENDFORMAT ) >>= nLineEndFormat );
112 switch ( nLineEndFormat )
114 case awt::LineEndFormat::CARRIAGE_RETURN: eFormat = LINEEND_CR; break;
115 case awt::LineEndFormat::LINE_FEED: eFormat = LINEEND_LF; break;
116 case awt::LineEndFormat::CARRIAGE_RETURN_LINE_FEED: eFormat = LINEEND_CRLF; break;
117 default:
118 OSL_FAIL( "getModelLineEndSetting: what's this?" );
122 catch( const Exception& )
124 TOOLS_WARN_EXCEPTION( "svx", "getModelLineEndSetting" );
126 return eFormat;
131 //= DbGridColumn
134 CellControllerRef DbGridColumn::s_xEmptyController;
137 void DbGridColumn::CreateControl(sal_Int32 _nFieldPos, const Reference< css::beans::XPropertySet >& xField, sal_Int32 nTypeId)
139 Clear();
141 m_nTypeId = static_cast<sal_Int16>(nTypeId);
142 if (xField != m_xField)
144 // initial setting
145 m_xField = xField;
146 xField->getPropertyValue(FM_PROP_FORMATKEY) >>= m_nFormatKey;
147 m_nFieldPos = static_cast<sal_Int16>(_nFieldPos);
148 m_bReadOnly = ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_ISREADONLY));
149 m_bAutoValue = ::comphelper::getBOOL(xField->getPropertyValue(FM_PROP_AUTOINCREMENT));
150 m_nFieldType = static_cast<sal_Int16>(::comphelper::getINT32(xField->getPropertyValue(FM_PROP_FIELDTYPE)));
152 switch (m_nFieldType)
154 case DataType::DATE:
155 case DataType::TIME:
156 case DataType::TIMESTAMP:
157 case DataType::BIT:
158 case DataType::BOOLEAN:
159 case DataType::TINYINT:
160 case DataType::SMALLINT:
161 case DataType::INTEGER:
162 case DataType::BIGINT:
163 case DataType::FLOAT:
164 case DataType::REAL:
165 case DataType::DOUBLE:
166 case DataType::NUMERIC:
167 case DataType::DECIMAL:
168 m_nAlign = css::awt::TextAlign::RIGHT;
169 m_bNumeric = true;
170 break;
171 default:
172 m_nAlign = css::awt::TextAlign::LEFT;
173 break;
177 std::unique_ptr<DbCellControl> pCellControl;
178 if (m_rParent.IsFilterMode())
180 pCellControl.reset(new DbFilterField(m_rParent.getContext(),*this));
182 else
185 switch (nTypeId)
187 case TYPE_CHECKBOX: pCellControl.reset(new DbCheckBox(*this)); break;
188 case TYPE_COMBOBOX: pCellControl.reset(new DbComboBox(*this)); break;
189 case TYPE_CURRENCYFIELD: pCellControl.reset(new DbCurrencyField(*this)); break;
190 case TYPE_DATEFIELD: pCellControl.reset(new DbDateField(*this)); break;
191 case TYPE_LISTBOX: pCellControl.reset(new DbListBox(*this)); break;
192 case TYPE_NUMERICFIELD: pCellControl.reset(new DbNumericField(*this)); break;
193 case TYPE_PATTERNFIELD: pCellControl.reset(new DbPatternField( *this, m_rParent.getContext() )); break;
194 case TYPE_TEXTFIELD: pCellControl.reset(new DbTextField(*this)); break;
195 case TYPE_TIMEFIELD: pCellControl.reset(new DbTimeField(*this)); break;
196 case TYPE_FORMATTEDFIELD: pCellControl.reset(new DbFormattedField(*this)); break;
197 default:
198 OSL_FAIL("DbGridColumn::CreateControl: Unknown Column");
199 return;
203 Reference< XRowSet > xCur;
204 if (m_rParent.getDataSource())
205 xCur.set(Reference< XInterface >(*m_rParent.getDataSource()), UNO_QUERY);
206 // TODO : the cursor wrapper should use an XRowSet interface, too
208 pCellControl->Init( m_rParent.GetDataWindow(), xCur );
210 // now create the control wrapper
211 auto pTempCellControl = pCellControl.get();
212 if (m_rParent.IsFilterMode())
213 m_pCell = new FmXFilterCell(this, std::unique_ptr<DbFilterField>(static_cast<DbFilterField*>(pCellControl.release())));
214 else
216 switch (nTypeId)
218 case TYPE_CHECKBOX: m_pCell = new FmXCheckBoxCell( this, std::move(pCellControl) ); break;
219 case TYPE_LISTBOX: m_pCell = new FmXListBoxCell( this, std::move(pCellControl) ); break;
220 case TYPE_COMBOBOX: m_pCell = new FmXComboBoxCell( this, std::move(pCellControl) ); break;
221 default:
222 m_pCell = new FmXEditCell( this, std::move(pCellControl) );
225 m_pCell->init();
227 impl_toggleScriptManager_nothrow( true );
229 // only if we use have a bound field, we use a controller for displaying the
230 // window in the grid
231 if (m_xField.is())
232 m_xController = pTempCellControl->CreateController();
236 void DbGridColumn::impl_toggleScriptManager_nothrow( bool _bAttach )
240 Reference< container::XChild > xChild( m_xModel, UNO_QUERY_THROW );
241 Reference< script::XEventAttacherManager > xManager( xChild->getParent(), UNO_QUERY_THROW );
242 Reference< container::XIndexAccess > xContainer( xChild->getParent(), UNO_QUERY_THROW );
244 sal_Int32 nIndexInParent( getElementPos( xContainer, m_xModel ) );
246 Reference< XInterface > xCellInterface( *m_pCell, UNO_QUERY );
247 if ( _bAttach )
248 xManager->attach( nIndexInParent, xCellInterface, Any( xCellInterface ) );
249 else
250 xManager->detach( nIndexInParent, xCellInterface );
252 catch( const Exception& )
254 DBG_UNHANDLED_EXCEPTION("svx");
258 void DbGridColumn::UpdateFromField(const DbGridRow* pRow, const Reference< XNumberFormatter >& xFormatter)
260 if (FmXFilterCell* pCell = dynamic_cast<FmXFilterCell*>(m_pCell.get()))
261 pCell->Update();
262 else if (pRow && pRow->IsValid() && m_nFieldPos >= 0 && m_pCell.is() && pRow->HasField(m_nFieldPos))
264 dynamic_cast<FmXDataCell&>(*m_pCell).UpdateFromField( pRow->GetField( m_nFieldPos ).getColumn(), xFormatter );
268 bool DbGridColumn::Commit()
270 bool bResult = true;
271 if (!m_bInSave && m_pCell.is())
273 m_bInSave = true;
274 bResult = m_pCell->Commit();
276 // store the data into the model
277 FmXDataCell* pDataCell = dynamic_cast<FmXDataCell*>( m_pCell.get() );
278 if (bResult && pDataCell)
280 Reference< css::form::XBoundComponent > xComp(m_xModel, UNO_QUERY);
281 if (xComp.is())
282 bResult = xComp->commit();
284 m_bInSave = false;
286 return bResult;
289 DbGridColumn::~DbGridColumn()
291 Clear();
294 void DbGridColumn::setModel(const css::uno::Reference< css::beans::XPropertySet >& _xModel)
296 if ( m_pCell.is() )
297 impl_toggleScriptManager_nothrow( false );
299 m_xModel = _xModel;
301 if ( m_pCell.is() )
302 impl_toggleScriptManager_nothrow( true );
306 void DbGridColumn::Clear()
308 if ( m_pCell.is() )
310 impl_toggleScriptManager_nothrow( false );
312 m_pCell->dispose();
313 m_pCell.clear();
316 m_xController = nullptr;
317 m_xField = nullptr;
319 m_nFormatKey = 0;
320 m_nFieldPos = -1;
321 m_bReadOnly = true;
322 m_bAutoValue = false;
323 m_nFieldType = DataType::OTHER;
327 sal_Int16 DbGridColumn::SetAlignment(sal_Int16 _nAlign)
329 if (_nAlign == -1)
330 { // 'Standard'
331 if (m_xField.is())
333 sal_Int32 nType = 0;
334 m_xField->getPropertyValue(FM_PROP_FIELDTYPE) >>= nType;
336 switch (nType)
338 case DataType::NUMERIC:
339 case DataType::DECIMAL:
340 case DataType::DOUBLE:
341 case DataType::REAL:
342 case DataType::BIGINT:
343 case DataType::INTEGER:
344 case DataType::SMALLINT:
345 case DataType::TINYINT:
346 case DataType::DATE:
347 case DataType::TIME:
348 case DataType::TIMESTAMP:
349 _nAlign = css::awt::TextAlign::RIGHT;
350 break;
351 case DataType::BIT:
352 case DataType::BOOLEAN:
353 _nAlign = css::awt::TextAlign::CENTER;
354 break;
355 default:
356 _nAlign = css::awt::TextAlign::LEFT;
357 break;
360 else
361 _nAlign = css::awt::TextAlign::LEFT;
364 m_nAlign = _nAlign;
365 if (m_pCell.is() && m_pCell->isAlignedController())
366 m_pCell->AlignControl(m_nAlign);
368 return m_nAlign;
372 sal_Int16 DbGridColumn::SetAlignmentFromModel(sal_Int16 nStandardAlign)
374 Any aAlign( m_xModel->getPropertyValue(FM_PROP_ALIGN));
375 if (aAlign.hasValue())
377 sal_Int16 nTest = sal_Int16();
378 if (aAlign >>= nTest)
379 nStandardAlign = nTest;
381 return SetAlignment(nStandardAlign);
385 void DbGridColumn::setLock(bool _bLock)
387 if (m_bLocked == _bLock)
388 return;
389 m_bLocked = _bLock;
391 // is the column we represent active ?
392 if (m_bHidden)
393 return; // no, it isn't (or at least it shouldn't be ...)
395 if (m_rParent.GetCurColumnId() == m_nId)
397 m_rParent.DeactivateCell();
398 m_rParent.ActivateCell(m_rParent.GetCurRow(), m_rParent.GetCurColumnId());
403 OUString DbGridColumn::GetCellText(const DbGridRow* pRow, const Reference< XNumberFormatter >& xFormatter) const
405 OUString aText;
406 if (m_pCell.is() && dynamic_cast<const FmXFilterCell*>( m_pCell.get() ) != nullptr)
407 return aText;
409 if (!pRow || !pRow->IsValid())
410 aText = INVALIDTEXT;
411 else if (pRow->HasField(m_nFieldPos))
413 aText = GetCellText( pRow->GetField( m_nFieldPos ).getColumn(), xFormatter );
415 return aText;
418 OUString DbGridColumn::GetCellText(const Reference< css::sdb::XColumn >& xField, const Reference< XNumberFormatter >& xFormatter) const
420 OUString aText;
421 if (xField.is())
423 FmXTextCell* pTextCell = dynamic_cast<FmXTextCell*>( m_pCell.get() );
424 if (pTextCell)
425 aText = pTextCell->GetText(xField, xFormatter);
426 else if (m_bObject)
427 aText = OBJECTTEXT;
429 return aText;
432 Reference< css::sdb::XColumn > DbGridColumn::GetCurrentFieldValue() const
434 Reference< css::sdb::XColumn > xField;
435 const DbGridRowRef xRow = m_rParent.GetCurrentRow();
436 if (xRow.is() && xRow->HasField(m_nFieldPos))
438 xField = xRow->GetField(m_nFieldPos).getColumn();
440 return xField;
444 void DbGridColumn::Paint(OutputDevice& rDev,
445 const tools::Rectangle& rRect,
446 const DbGridRow* pRow,
447 const Reference< XNumberFormatter >& xFormatter)
449 bool bEnabled = ( rDev.GetOutDevType() != OUTDEV_WINDOW )
450 || ( rDev.GetOwnerWindow()->IsEnabled() );
452 FmXDataCell* pDataCell = dynamic_cast<FmXDataCell*>( m_pCell.get() );
453 if (pDataCell)
455 if (!pRow || !pRow->IsValid())
457 DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::Center;
458 if ( !bEnabled )
459 nStyle |= DrawTextFlags::Disable;
461 rDev.DrawText(rRect, INVALIDTEXT, nStyle);
463 else if (m_bAutoValue && pRow->IsNew())
465 DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::VCenter;
466 if ( !bEnabled )
467 nStyle |= DrawTextFlags::Disable;
469 switch (GetAlignment())
471 case css::awt::TextAlign::RIGHT:
472 nStyle |= DrawTextFlags::Right;
473 break;
474 case css::awt::TextAlign::CENTER:
475 nStyle |= DrawTextFlags::Center;
476 break;
477 default:
478 nStyle |= DrawTextFlags::Left;
481 rDev.DrawText(rRect, SvxResId(RID_STR_AUTOFIELD), nStyle);
483 else if (pRow->HasField(m_nFieldPos))
485 pDataCell->PaintFieldToCell(rDev, rRect, pRow->GetField( m_nFieldPos ).getColumn(), xFormatter);
488 else if (!m_pCell.is())
490 if (!pRow || !pRow->IsValid())
492 DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::Center;
493 if ( !bEnabled )
494 nStyle |= DrawTextFlags::Disable;
496 rDev.DrawText(rRect, INVALIDTEXT, nStyle);
498 else if (pRow->HasField(m_nFieldPos) && m_bObject)
500 DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::Center;
501 if ( !bEnabled )
502 nStyle |= DrawTextFlags::Disable;
503 rDev.DrawText(rRect, OBJECTTEXT, nStyle);
506 else if ( auto pFilterCell = dynamic_cast<FmXFilterCell*>( m_pCell.get() ) )
507 pFilterCell->PaintCell( rDev, rRect );
511 void DbGridColumn::ImplInitWindow( vcl::Window const & rParent, const InitWindowFacet _eInitWhat )
513 if ( m_pCell.is() )
514 m_pCell->ImplInitWindow( rParent, _eInitWhat );
518 //= cell controls
521 DbCellControl::DbCellControl( DbGridColumn& _rColumn )
522 :OPropertyChangeListener()
523 ,m_bTransparent( false )
524 ,m_bAlignedController( true )
525 ,m_bAccessingValueProperty( false )
526 ,m_rColumn( _rColumn )
527 ,m_pPainter( nullptr )
528 ,m_pWindow( nullptr )
530 const Reference< XPropertySet >& xColModelProps = _rColumn.getModel();
531 if ( !xColModelProps.is() )
532 return;
534 // if our model's format key changes we want to propagate the new value to our windows
535 m_pModelChangeBroadcaster = new ::comphelper::OPropertyChangeMultiplexer(this, _rColumn.getModel());
537 // be listener for some common properties
538 implDoPropertyListening( FM_PROP_READONLY, false );
539 implDoPropertyListening( FM_PROP_ENABLED, false );
541 // add as listener for all known "value" properties
542 implDoPropertyListening( FM_PROP_VALUE, false );
543 implDoPropertyListening( FM_PROP_STATE, false );
544 implDoPropertyListening( FM_PROP_TEXT, false );
545 implDoPropertyListening( FM_PROP_EFFECTIVE_VALUE, false );
546 implDoPropertyListening( FM_PROP_SELECT_SEQ, false );
547 implDoPropertyListening( FM_PROP_DATE, false );
548 implDoPropertyListening( FM_PROP_TIME, false );
550 // be listener at the bound field as well
553 Reference< XPropertySetInfo > xPSI( xColModelProps->getPropertySetInfo(), UNO_SET_THROW );
554 if ( xPSI->hasPropertyByName( FM_PROP_BOUNDFIELD ) )
556 Reference< XPropertySet > xField;
557 xColModelProps->getPropertyValue( FM_PROP_BOUNDFIELD ) >>= xField;
558 if ( xField.is() )
560 m_pFieldChangeBroadcaster = new ::comphelper::OPropertyChangeMultiplexer(this, xField);
561 m_pFieldChangeBroadcaster->addProperty( FM_PROP_ISREADONLY );
565 catch( const Exception& )
567 TOOLS_WARN_EXCEPTION( "svx", "DbCellControl::doPropertyListening" );
572 void DbCellControl::implDoPropertyListening(const OUString& _rPropertyName, bool _bWarnIfNotExistent)
576 Reference< XPropertySet > xColModelProps = m_rColumn.getModel();
577 Reference< XPropertySetInfo > xPSI;
578 if ( xColModelProps.is() )
579 xPSI = xColModelProps->getPropertySetInfo();
581 DBG_ASSERT( !_bWarnIfNotExistent || ( xPSI.is() && xPSI->hasPropertyByName( _rPropertyName ) ),
582 "DbCellControl::doPropertyListening: no property set info or non-existent property!" );
584 if ( xPSI.is() && xPSI->hasPropertyByName( _rPropertyName ) )
585 m_pModelChangeBroadcaster->addProperty( _rPropertyName );
587 catch( const Exception& )
589 TOOLS_WARN_EXCEPTION( "svx", "DbCellControl::doPropertyListening" );
594 void DbCellControl::doPropertyListening(const OUString& _rPropertyName)
596 implDoPropertyListening( _rPropertyName, true );
599 static void lcl_clearBroadCaster(rtl::Reference<::comphelper::OPropertyChangeMultiplexer>& _pBroadcaster)
601 if ( _pBroadcaster.is() )
603 _pBroadcaster->dispose();
604 _pBroadcaster.clear();
605 // no delete, this is done implicitly
609 DbCellControl::~DbCellControl()
611 lcl_clearBroadCaster(m_pModelChangeBroadcaster);
612 lcl_clearBroadCaster(m_pFieldChangeBroadcaster);
614 m_pWindow.disposeAndClear();
615 m_pPainter.disposeAndClear();
618 void DbCellControl::implValuePropertyChanged( )
620 OSL_ENSURE( !isValuePropertyLocked(),
621 "DbCellControl::implValuePropertyChanged: not to be called with the value property locked!" );
623 if ( m_pWindow )
625 if ( m_rColumn.getModel().is() )
626 updateFromModel( m_rColumn.getModel() );
631 void DbCellControl::implAdjustGenericFieldSetting( const Reference< XPropertySet >& /*_rxModel*/ )
633 // nothing to do here
637 void DbCellControl::_propertyChanged(const PropertyChangeEvent& _rEvent)
639 SolarMutexGuard aGuard;
641 Reference< XPropertySet > xSourceProps( _rEvent.Source, UNO_QUERY );
643 if ( _rEvent.PropertyName == FM_PROP_VALUE
644 || _rEvent.PropertyName == FM_PROP_STATE
645 || _rEvent.PropertyName == FM_PROP_TEXT
646 || _rEvent.PropertyName == FM_PROP_EFFECTIVE_VALUE
647 || _rEvent.PropertyName == FM_PROP_SELECT_SEQ
648 || _rEvent.PropertyName == FM_PROP_DATE
649 || _rEvent.PropertyName == FM_PROP_TIME
651 { // it was one of the known "value" properties
652 if ( !isValuePropertyLocked() )
654 implValuePropertyChanged( );
657 else if ( _rEvent.PropertyName == FM_PROP_READONLY )
659 implAdjustReadOnly( xSourceProps, true);
661 else if ( _rEvent.PropertyName == FM_PROP_ISREADONLY )
663 bool bReadOnly = true;
664 _rEvent.NewValue >>= bReadOnly;
665 m_rColumn.SetReadOnly(bReadOnly);
666 implAdjustReadOnly( xSourceProps, false);
668 else if ( _rEvent.PropertyName == FM_PROP_ENABLED )
670 implAdjustEnabled( xSourceProps );
672 else
673 implAdjustGenericFieldSetting( xSourceProps );
676 bool DbCellControl::Commit()
678 // lock the listening for value property changes
679 lockValueProperty();
680 // commit the content of the control into the model's value property
681 bool bReturn = false;
684 bReturn = commitControl();
686 catch( const Exception& )
688 DBG_UNHANDLED_EXCEPTION("svx");
690 // unlock the listening for value property changes
691 unlockValueProperty();
692 // outta here
693 return bReturn;
696 void DbCellControl::ImplInitWindow( vcl::Window const & rParent, const InitWindowFacet _eInitWhat )
698 svt::ControlBase* pWindows[] = { m_pPainter, m_pWindow };
700 if (_eInitWhat & InitWindowFacet::WritingMode)
702 for (svt::ControlBase* pWindow : pWindows)
704 if (pWindow)
705 pWindow->EnableRTL(rParent.IsRTLEnabled());
709 if (_eInitWhat & InitWindowFacet::Font)
711 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
712 const Fraction& rZoom = rParent.GetZoom();
714 for (svt::ControlBase* pWindow : pWindows)
716 if (!pWindow)
717 continue;
719 vcl::Font aFont = rStyleSettings.GetFieldFont();
720 aFont.SetTransparent(isTransparent());
722 if (rParent.IsControlFont())
723 aFont.Merge(rParent.GetControlFont());
725 if (rZoom.GetNumerator() != rZoom.GetDenominator())
727 Size aSize = aFont.GetFontSize();
728 aSize.setWidth(std::round(double(aSize.Width() * rZoom)));
729 aSize.setHeight(std::round(double(aSize.Height() * rZoom)));
730 aFont.SetFontSize(aSize);
733 pWindow->SetPointFont(aFont);
737 if ((_eInitWhat & InitWindowFacet::Font) || (_eInitWhat & InitWindowFacet::Foreground))
739 Color aTextColor(rParent.IsControlForeground() ? rParent.GetControlForeground() : rParent.GetTextColor());
741 bool bTextLineColor = rParent.IsTextLineColor();
742 Color aTextLineColor(rParent.GetTextLineColor());
744 for (svt::ControlBase* pWindow : pWindows)
746 if (pWindow)
748 pWindow->SetTextColor(aTextColor);
749 if (rParent.IsControlForeground())
750 pWindow->SetControlForeground(aTextColor);
752 if (bTextLineColor)
753 pWindow->SetTextLineColor();
754 else
755 pWindow->SetTextLineColor(aTextLineColor);
760 if (!(_eInitWhat & InitWindowFacet::Background))
761 return;
763 if (rParent.IsControlBackground())
765 Color aColor(rParent.GetControlBackground());
766 for (svt::ControlBase* pWindow : pWindows)
768 if (pWindow)
770 if (isTransparent())
771 pWindow->SetBackground();
772 else
774 pWindow->SetBackground(aColor);
775 pWindow->SetControlBackground(aColor);
777 pWindow->GetOutDev()->SetFillColor(aColor);
781 else
783 if (m_pPainter)
785 if (isTransparent())
786 m_pPainter->SetBackground();
787 else
788 m_pPainter->SetBackground(rParent.GetBackground());
789 m_pPainter->GetOutDev()->SetFillColor(rParent.GetOutDev()->GetFillColor());
792 if (m_pWindow)
794 if (isTransparent())
795 m_pWindow->SetBackground(rParent.GetBackground());
796 else
797 m_pWindow->GetOutDev()->SetFillColor(rParent.GetOutDev()->GetFillColor());
802 void DbCellControl::implAdjustReadOnly( const Reference< XPropertySet >& _rxModel,bool i_bReadOnly )
804 DBG_ASSERT( m_pWindow, "DbCellControl::implAdjustReadOnly: not to be called without window!" );
805 DBG_ASSERT( _rxModel.is(), "DbCellControl::implAdjustReadOnly: invalid model!" );
806 if ( !(m_pWindow && _rxModel.is()) )
807 return;
809 bool bReadOnly = m_rColumn.IsReadOnly();
810 if ( !bReadOnly )
812 _rxModel->getPropertyValue( i_bReadOnly ? FM_PROP_READONLY : FM_PROP_ISREADONLY) >>= bReadOnly;
814 m_pWindow->SetEditableReadOnly(bReadOnly);
817 void DbCellControl::implAdjustEnabled( const Reference< XPropertySet >& _rxModel )
819 DBG_ASSERT( m_pWindow, "DbCellControl::implAdjustEnabled: not to be called without window!" );
820 DBG_ASSERT( _rxModel.is(), "DbCellControl::implAdjustEnabled: invalid model!" );
821 if ( m_pWindow && _rxModel.is() )
823 bool bEnable = true;
824 _rxModel->getPropertyValue( FM_PROP_ENABLED ) >>= bEnable;
825 m_pWindow->Enable( bEnable );
829 void DbCellControl::Init(BrowserDataWin& rParent, const Reference< XRowSet >& _rxCursor)
831 ImplInitWindow( rParent, InitWindowFacet::All );
833 if ( m_pWindow )
835 // align the control
836 if ( isAlignedController() )
837 AlignControl( m_rColumn.GetAlignment() );
841 // some other common properties
842 Reference< XPropertySet > xModel( m_rColumn.getModel(), UNO_SET_THROW );
843 Reference< XPropertySetInfo > xModelPSI( xModel->getPropertySetInfo(), UNO_SET_THROW );
845 if ( xModelPSI->hasPropertyByName( FM_PROP_READONLY ) )
847 implAdjustReadOnly( xModel,true );
850 if ( xModelPSI->hasPropertyByName( FM_PROP_ENABLED ) )
852 implAdjustEnabled( xModel );
855 if ( xModelPSI->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) )
857 sal_Int16 nWheelBehavior = css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY;
858 OSL_VERIFY( xModel->getPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) >>= nWheelBehavior );
859 MouseWheelBehaviour nVclSetting = MouseWheelBehaviour::FocusOnly;
860 switch ( nWheelBehavior )
862 case css::awt::MouseWheelBehavior::SCROLL_DISABLED: nVclSetting = MouseWheelBehaviour::Disable; break;
863 case css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY: nVclSetting = MouseWheelBehaviour::FocusOnly; break;
864 case css::awt::MouseWheelBehavior::SCROLL_ALWAYS: nVclSetting = MouseWheelBehaviour::ALWAYS; break;
865 default:
866 OSL_FAIL( "DbCellControl::Init: invalid MouseWheelBehavior!" );
867 break;
870 AllSettings aSettings = m_pWindow->GetSettings();
871 MouseSettings aMouseSettings = aSettings.GetMouseSettings();
872 aMouseSettings.SetWheelBehavior( nVclSetting );
873 aSettings.SetMouseSettings( aMouseSettings );
874 m_pWindow->SetSettings( aSettings, true );
877 catch( const Exception& )
879 DBG_UNHANDLED_EXCEPTION("svx");
882 m_xCursor = _rxCursor;
883 if ( m_rColumn.getModel().is() )
884 updateFromModel( m_rColumn.getModel() );
888 void DbCellControl::SetTextLineColor()
890 if (m_pWindow)
891 m_pWindow->SetTextLineColor();
892 if (m_pPainter)
893 m_pPainter->SetTextLineColor();
897 void DbCellControl::SetTextLineColor(const Color& _rColor)
899 if (m_pWindow)
900 m_pWindow->SetTextLineColor(_rColor);
901 if (m_pPainter)
902 m_pPainter->SetTextLineColor(_rColor);
905 namespace
907 void lcl_implAlign( vcl::Window* _pWindow, WinBits _nAlignmentBit )
909 if (EditControlBase* pControl = dynamic_cast<EditControlBase*>(_pWindow))
911 switch (_nAlignmentBit)
913 case WB_LEFT:
914 pControl->get_widget().set_alignment(TxtAlign::Left);
915 break;
916 case WB_CENTER:
917 pControl->get_widget().set_alignment(TxtAlign::Center);
918 break;
919 case WB_RIGHT:
920 pControl->get_widget().set_alignment(TxtAlign::Right);
921 break;
923 return;
926 WinBits nStyle = _pWindow->GetStyle();
927 nStyle &= ~(WB_LEFT | WB_RIGHT | WB_CENTER);
928 _pWindow->SetStyle( nStyle | _nAlignmentBit );
932 void DbCellControl::AlignControl(sal_Int16 nAlignment)
934 WinBits nAlignmentBit = 0;
935 switch (nAlignment)
937 case css::awt::TextAlign::RIGHT:
938 nAlignmentBit = WB_RIGHT;
939 break;
940 case css::awt::TextAlign::CENTER:
941 nAlignmentBit = WB_CENTER;
942 break;
943 default:
944 nAlignmentBit = WB_LEFT;
945 break;
947 lcl_implAlign( m_pWindow, nAlignmentBit );
948 if ( m_pPainter )
949 lcl_implAlign( m_pPainter, nAlignmentBit );
952 void DbCellControl::PaintCell(OutputDevice& rDev, const tools::Rectangle& rRect)
954 m_pPainter->SetSizePixel(rRect.GetSize());
955 m_pPainter->Draw(&rDev, rRect.TopLeft(), SystemTextColorFlags::NONE);
958 void DbCellControl::PaintFieldToCell( OutputDevice& _rDev, const tools::Rectangle& _rRect, const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
960 m_pPainter->SetText( GetFormatText( _rxField, _rxFormatter ) );
961 PaintCell( _rDev, _rRect );
964 double DbCellControl::GetValue(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter) const
966 double fValue = 0;
967 if (m_rColumn.IsNumeric())
971 fValue = _rxField->getDouble();
973 catch(const Exception&) { }
975 else
977 bool bSuccess = false;
980 fValue = _rxField->getDouble();
981 bSuccess = true;
983 catch(const Exception&) { }
984 if (!bSuccess)
988 fValue = xFormatter->convertStringToNumber(m_rColumn.GetKey(), _rxField->getString());
990 catch(const Exception&) { }
993 return fValue;
996 void DbCellControl::invalidatedController()
998 m_rColumn.GetParent().refreshController(m_rColumn.GetId(), DbGridControl::GrantControlAccess());
1001 // CellModels
1003 DbLimitedLengthField::DbLimitedLengthField( DbGridColumn& _rColumn )
1004 :DbCellControl( _rColumn )
1006 doPropertyListening( FM_PROP_MAXTEXTLEN );
1010 void DbLimitedLengthField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1012 DBG_ASSERT( m_pWindow, "DbLimitedLengthField::implAdjustGenericFieldSetting: not to be called without window!" );
1013 DBG_ASSERT( _rxModel.is(), "DbLimitedLengthField::implAdjustGenericFieldSetting: invalid model!" );
1014 if ( m_pWindow && _rxModel.is() )
1016 sal_Int16 nMaxLen = 0;
1017 _rxModel->getPropertyValue( FM_PROP_MAXTEXTLEN ) >>= nMaxLen;
1018 implSetMaxTextLen( nMaxLen );
1022 void DbLimitedLengthField::implSetEffectiveMaxTextLen(sal_Int32 nMaxLen)
1024 dynamic_cast<EditControlBase&>(*m_pWindow).get_widget().set_max_length(nMaxLen);
1025 if (m_pPainter)
1026 dynamic_cast<EditControlBase&>(*m_pPainter).get_widget().set_max_length(nMaxLen);
1029 DbTextField::DbTextField(DbGridColumn& _rColumn)
1030 :DbLimitedLengthField(_rColumn)
1031 ,m_bIsMultiLineEdit(false)
1035 DbTextField::~DbTextField( )
1037 m_pPainterImplementation.reset();
1038 m_pEdit.reset();
1041 void DbTextField::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
1043 sal_Int16 nAlignment = m_rColumn.SetAlignmentFromModel(-1);
1045 Reference< XPropertySet > xModel( m_rColumn.getModel() );
1047 bool bLeftAlign = true;
1049 // is this a multi-line field?
1050 bool bIsMultiLine = false;
1053 if ( xModel.is() )
1055 OSL_VERIFY( xModel->getPropertyValue( FM_PROP_MULTILINE ) >>= bIsMultiLine );
1058 catch( const Exception& )
1060 TOOLS_WARN_EXCEPTION("svx",
1061 "caught an exception while determining the multi-line capabilities!");
1064 m_bIsMultiLineEdit = bIsMultiLine;
1065 if ( bIsMultiLine )
1067 auto xEditControl = VclPtr<MultiLineTextCell>::Create(&rParent);
1068 auto xEditPainter = VclPtr<MultiLineTextCell>::Create(&rParent);
1070 switch (nAlignment)
1072 case awt::TextAlign::RIGHT:
1073 xEditControl->get_widget().set_alignment(TxtAlign::Right);
1074 xEditPainter->get_widget().set_alignment(TxtAlign::Right);
1075 bLeftAlign = false;
1076 break;
1077 case awt::TextAlign::CENTER:
1078 xEditControl->get_widget().set_alignment(TxtAlign::Center);
1079 xEditPainter->get_widget().set_alignment(TxtAlign::Center);
1080 bLeftAlign = false;
1081 break;
1084 m_pWindow = xEditControl;
1085 m_pEdit.reset(new MultiLineEditImplementation(*xEditControl));
1087 m_pPainter = xEditPainter;
1088 m_pPainterImplementation.reset(new MultiLineEditImplementation(*xEditPainter));
1090 else
1092 auto xEditControl = VclPtr<EditControl>::Create(&rParent);
1093 auto xEditPainter = VclPtr<EditControl>::Create(&rParent);
1095 switch (nAlignment)
1097 case awt::TextAlign::RIGHT:
1098 xEditControl->get_widget().set_alignment(TxtAlign::Right);
1099 xEditPainter->get_widget().set_alignment(TxtAlign::Right);
1100 bLeftAlign = false;
1101 break;
1102 case awt::TextAlign::CENTER:
1103 xEditControl->get_widget().set_alignment(TxtAlign::Center);
1104 xEditPainter->get_widget().set_alignment(TxtAlign::Center);
1105 bLeftAlign = false;
1106 break;
1109 m_pWindow = xEditControl;
1110 m_pEdit.reset(new EntryImplementation(*xEditControl));
1112 m_pPainter = xEditPainter;
1113 m_pPainterImplementation.reset(new EntryImplementation(*xEditPainter));
1116 if (bLeftAlign)
1118 // this is so that when getting the focus, the selection is oriented left-to-right
1119 AllSettings aSettings = m_pWindow->GetSettings();
1120 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1121 aStyleSettings.SetSelectionOptions(
1122 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
1123 aSettings.SetStyleSettings(aStyleSettings);
1124 m_pWindow->SetSettings(aSettings);
1127 implAdjustGenericFieldSetting( xModel );
1129 DbLimitedLengthField::Init( rParent, xCursor );
1132 CellControllerRef DbTextField::CreateController() const
1134 return new EditCellController( m_pEdit.get() );
1137 void DbTextField::PaintFieldToCell( OutputDevice& _rDev, const tools::Rectangle& _rRect, const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1139 if ( m_pPainterImplementation )
1140 m_pPainterImplementation->SetText( GetFormatText( _rxField, _rxFormatter ) );
1142 DbLimitedLengthField::PaintFieldToCell( _rDev, _rRect, _rxField, _rxFormatter );
1145 OUString DbTextField::GetFormatText(const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter, const Color** /*ppColor*/)
1147 if (!_rxField.is())
1148 return OUString();
1150 const css::uno::Reference<css::beans::XPropertySet> xPS(_rxField, UNO_QUERY);
1151 FormattedColumnValue fmter( xFormatter, xPS );
1155 return fmter.getFormattedValue();
1157 catch( const Exception& )
1159 DBG_UNHANDLED_EXCEPTION("svx");
1161 return OUString();
1165 void DbTextField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
1167 m_pEdit->SetText( GetFormatText( _rxField, xFormatter ) );
1168 m_pEdit->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1171 void DbTextField::updateFromModel( Reference< XPropertySet > _rxModel )
1173 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbTextField::updateFromModel: invalid call!" );
1175 OUString sText;
1176 _rxModel->getPropertyValue( FM_PROP_TEXT ) >>= sText;
1178 sal_Int32 nMaxTextLen = m_pEdit->GetMaxTextLen();
1179 if (nMaxTextLen > 0 && sText.getLength() > nMaxTextLen)
1181 sal_Int32 nDiff = sText.getLength() - nMaxTextLen;
1182 sText = sText.replaceAt(sText.getLength() - nDiff,nDiff, u"");
1185 m_pEdit->SetText( sText );
1186 m_pEdit->SetSelection( Selection( SELECTION_MAX, SELECTION_MIN ) );
1189 bool DbTextField::commitControl()
1191 OUString aText( m_pEdit->GetText( getModelLineEndSetting( m_rColumn.getModel() ) ) );
1192 // we have to check if the length before we can decide if the value was modified
1193 sal_Int32 nMaxTextLen = m_pEdit->GetMaxTextLen();
1194 if (nMaxTextLen > 0)
1196 OUString sOldValue;
1197 m_rColumn.getModel()->getPropertyValue( FM_PROP_TEXT ) >>= sOldValue;
1198 // if the new value didn't change we must set the old long value again
1199 if ( sOldValue.getLength() > nMaxTextLen && sOldValue.compareTo(aText,nMaxTextLen) == 0 )
1200 aText = sOldValue;
1202 m_rColumn.getModel()->setPropertyValue( FM_PROP_TEXT, Any( aText ) );
1203 return true;
1206 void DbTextField::implSetEffectiveMaxTextLen( sal_Int32 _nMaxLen )
1208 if ( m_pEdit )
1209 m_pEdit->SetMaxTextLen( _nMaxLen );
1210 if ( m_pPainterImplementation )
1211 m_pPainterImplementation->SetMaxTextLen( _nMaxLen );
1214 DbFormattedField::DbFormattedField(DbGridColumn& _rColumn)
1215 :DbLimitedLengthField(_rColumn)
1217 // if our model's format key changes we want to propagate the new value to our windows
1218 doPropertyListening( FM_PROP_FORMATKEY );
1221 DbFormattedField::~DbFormattedField()
1225 void DbFormattedField::Init( BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
1227 sal_Int16 nAlignment = m_rColumn.SetAlignmentFromModel(-1);
1229 Reference< css::beans::XPropertySet > xUnoModel = m_rColumn.getModel();
1231 auto xEditControl = VclPtr<FormattedControl>::Create(&rParent, false);
1232 auto xEditPainter = VclPtr<FormattedControl>::Create(&rParent, false);
1234 weld::EntryFormatter& rControlFormatter = xEditControl->get_formatter();
1235 weld::EntryFormatter& rPainterFormatter = xEditPainter->get_formatter();
1237 m_pWindow = xEditControl.get();
1238 m_pPainter = xEditPainter.get();
1240 switch (nAlignment)
1242 case awt::TextAlign::RIGHT:
1243 xEditControl->get_widget().set_alignment(TxtAlign::Right);
1244 xEditPainter->get_widget().set_alignment(TxtAlign::Right);
1245 break;
1246 case awt::TextAlign::CENTER:
1247 xEditControl->get_widget().set_alignment(TxtAlign::Center);
1248 xEditPainter->get_widget().set_alignment(TxtAlign::Center);
1249 break;
1250 default:
1252 // Everything just so that the selection goes from right to left when getting focus
1253 SelectionOptions eOptions = rControlFormatter.GetEntrySelectionOptions();
1254 rControlFormatter.SetEntrySelectionOptions(eOptions | SelectionOptions::ShowFirst);
1255 break;
1259 implAdjustGenericFieldSetting( xUnoModel );
1261 rControlFormatter.SetStrictFormat(false);
1262 rPainterFormatter.SetStrictFormat(false);
1263 // if one allows any formatting, one cannot make an entry check anyway
1264 // (the FormattedField does not support that anyway, only derived classes)
1266 // get the formatter from the uno model
1267 // (I could theoretically also go via the css::util::NumberFormatter, which the cursor would
1268 // surely give me. The problem is that I can not really rely on the fact that the two
1269 // formatters are the same. Clean is the whole thing if I go via the UNO model.)
1270 sal_Int32 nFormatKey = -1;
1272 // let's see if the model has one ...
1273 DBG_ASSERT(::comphelper::hasProperty(FM_PROP_FORMATSSUPPLIER, xUnoModel), "DbFormattedField::Init : invalid UNO model !");
1274 Any aSupplier( xUnoModel->getPropertyValue(FM_PROP_FORMATSSUPPLIER));
1275 if (aSupplier.hasValue())
1277 m_xSupplier.set(aSupplier, css::uno::UNO_QUERY);
1278 if (m_xSupplier.is())
1280 // if we take the supplier from the model, then also the key
1281 Any aFmtKey( xUnoModel->getPropertyValue(FM_PROP_FORMATKEY));
1282 if (aFmtKey.hasValue())
1284 DBG_ASSERT(aFmtKey.getValueTypeClass() == TypeClass_LONG, "DbFormattedField::Init : invalid format key property (no sal_Int32) !");
1285 nFormatKey = ::comphelper::getINT32(aFmtKey);
1287 else
1289 SAL_INFO("svx.fmcomp", "DbFormattedField::Init : my uno-model has no format-key, but a formats supplier !");
1290 // the OFormattedModel which we usually are working with ensures that the model has a format key
1291 // as soon as the form is loaded. Unfortunally this method here is called from within loaded, too.
1292 // So if our LoadListener is called before the LoadListener of the model, this "else case" is
1293 // allowed.
1294 // Of course our property listener for the FormatKey property will notify us if the prop is changed,
1295 // so this here isn't really bad...
1296 nFormatKey = 0;
1301 // No? Maybe the css::form::component::Form behind the cursor?
1302 if (!m_xSupplier.is())
1304 if (xCursor.is())
1305 { // If we take the formatter from the cursor, then also the key from the field to which we are bound
1306 m_xSupplier = getNumberFormats(getConnection(xCursor));
1308 if (m_rColumn.GetField().is())
1309 nFormatKey = ::comphelper::getINT32(m_rColumn.GetField()->getPropertyValue(FM_PROP_FORMATKEY));
1313 SvNumberFormatter* pFormatterUsed = nullptr;
1314 if (m_xSupplier.is())
1316 SvNumberFormatsSupplierObj* pImplementation = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>(m_xSupplier);
1317 if (pImplementation)
1318 pFormatterUsed = pImplementation->GetNumberFormatter();
1319 else
1320 // Everything is invalid: the supplier is of the wrong type, then we can not
1321 // rely on a standard formatter to know the (possibly non-standard) key.
1322 nFormatKey = -1;
1325 // a standard formatter ...
1326 if (pFormatterUsed == nullptr)
1328 pFormatterUsed = rControlFormatter.StandardFormatter();
1329 DBG_ASSERT(pFormatterUsed != nullptr, "DbFormattedField::Init : no standard formatter given by the numeric field !");
1331 // ... and a standard key
1332 if (nFormatKey == -1)
1333 nFormatKey = 0;
1335 rControlFormatter.SetFormatter(pFormatterUsed);
1336 rPainterFormatter.SetFormatter(pFormatterUsed);
1338 rControlFormatter.SetFormatKey(nFormatKey);
1339 rPainterFormatter.SetFormatKey(nFormatKey);
1341 rControlFormatter.TreatAsNumber(m_rColumn.IsNumeric());
1342 rPainterFormatter.TreatAsNumber(m_rColumn.IsNumeric());
1344 // min and max values
1345 if (m_rColumn.IsNumeric())
1347 bool bClearMin = true;
1348 if (::comphelper::hasProperty(FM_PROP_EFFECTIVE_MIN, xUnoModel))
1350 Any aMin( xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_MIN));
1351 if (aMin.getValueTypeClass() != TypeClass_VOID)
1353 DBG_ASSERT(aMin.getValueTypeClass() == TypeClass_DOUBLE, "DbFormattedField::Init : the model has an invalid min value !");
1354 double dMin = ::comphelper::getDouble(aMin);
1355 rControlFormatter.SetMinValue(dMin);
1356 rPainterFormatter.SetMinValue(dMin);
1357 bClearMin = false;
1360 if (bClearMin)
1362 rControlFormatter.ClearMinValue();
1363 rPainterFormatter.ClearMinValue();
1365 bool bClearMax = true;
1366 if (::comphelper::hasProperty(FM_PROP_EFFECTIVE_MAX, xUnoModel))
1368 Any aMax(xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_MAX));
1369 if (aMax.getValueTypeClass() != TypeClass_VOID)
1371 DBG_ASSERT(aMax.getValueTypeClass() == TypeClass_DOUBLE, "DbFormattedField::Init : the model has an invalid max value !");
1372 double dMax = ::comphelper::getDouble(aMax);
1373 rControlFormatter.SetMaxValue(dMax);
1374 rPainterFormatter.SetMaxValue(dMax);
1375 bClearMax = false;
1378 if (bClearMax)
1380 rControlFormatter.ClearMaxValue();
1381 rPainterFormatter.ClearMaxValue();
1385 // the default value
1386 Any aDefault( xUnoModel->getPropertyValue(FM_PROP_EFFECTIVE_DEFAULT));
1387 if (aDefault.hasValue())
1388 { // the thing can be a double or a string
1389 switch (aDefault.getValueTypeClass())
1391 case TypeClass_DOUBLE:
1392 if (m_rColumn.IsNumeric())
1394 rControlFormatter.SetDefaultValue(::comphelper::getDouble(aDefault));
1395 rPainterFormatter.SetDefaultValue(::comphelper::getDouble(aDefault));
1397 else
1399 OUString sConverted;
1400 const Color* pDummy;
1401 pFormatterUsed->GetOutputString(::comphelper::getDouble(aDefault), 0, sConverted, &pDummy);
1402 rControlFormatter.SetDefaultText(sConverted);
1403 rPainterFormatter.SetDefaultText(sConverted);
1405 break;
1406 case TypeClass_STRING:
1408 OUString sDefault( ::comphelper::getString(aDefault) );
1409 if (m_rColumn.IsNumeric())
1411 double dVal;
1412 sal_uInt32 nTestFormat(0);
1413 if (pFormatterUsed->IsNumberFormat(sDefault, nTestFormat, dVal))
1415 rControlFormatter.SetDefaultValue(dVal);
1416 rPainterFormatter.SetDefaultValue(dVal);
1419 else
1421 rControlFormatter.SetDefaultText(sDefault);
1422 rPainterFormatter.SetDefaultText(sDefault);
1425 break;
1426 default:
1427 OSL_FAIL( "DbFormattedField::Init: unexpected value type!" );
1428 break;
1431 DbLimitedLengthField::Init( rParent, xCursor );
1434 CellControllerRef DbFormattedField::CreateController() const
1436 return new ::svt::FormattedFieldCellController(static_cast<FormattedControlBase*>(m_pWindow.get()));
1439 void DbFormattedField::_propertyChanged( const PropertyChangeEvent& _rEvent )
1441 if (_rEvent.PropertyName == FM_PROP_FORMATKEY )
1443 sal_Int32 nNewKey = _rEvent.NewValue.hasValue() ? ::comphelper::getINT32(_rEvent.NewValue) : 0;
1445 DBG_ASSERT(m_pWindow && m_pPainter, "DbFormattedField::_propertyChanged : where are my windows ?");
1446 if (m_pWindow)
1447 static_cast<FormattedControlBase*>(m_pWindow.get())->get_formatter().SetFormatKey(nNewKey);
1448 if (m_pPainter)
1449 static_cast<FormattedControlBase*>(m_pPainter.get())->get_formatter().SetFormatKey(nNewKey);
1451 else
1453 DbLimitedLengthField::_propertyChanged( _rEvent );
1457 OUString DbFormattedField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, const Color** ppColor)
1459 // no color specification by default
1460 if (ppColor != nullptr)
1461 *ppColor = nullptr;
1463 // NULL value -> empty text
1464 if (!_rxField.is())
1465 return OUString();
1467 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pPainter.get());
1468 weld::EntryFormatter& rPainterFormatter = pControl->get_formatter();
1470 OUString aText;
1473 if (m_rColumn.IsNumeric())
1475 // The IsNumeric at the column says nothing about the class of the used format, but
1476 // about the class of the field bound to the column. So when you bind a FormattedField
1477 // column to a double field and format it as text, m_rColumn.IsNumeric() returns
1478 // sal_True. So that simply means that I can query the contents of the variant using
1479 // getDouble, and then I can leave the rest (the formatting) to the FormattedField.
1480 double dValue = getValue( _rxField, m_rColumn.GetParent().getNullDate() );
1481 if (_rxField->wasNull())
1482 return aText;
1483 rPainterFormatter.SetValue(dValue);
1485 else
1487 // Here I can not work with a double, since the field can not provide it to me.
1488 // So simply bind the text from the css::util::NumberFormatter to the correct css::form::component::Form.
1489 aText = _rxField->getString();
1490 if (_rxField->wasNull())
1491 return aText;
1492 rPainterFormatter.SetTextFormatted(aText);
1495 catch( const Exception& )
1497 DBG_UNHANDLED_EXCEPTION("svx");
1500 aText = pControl->get_widget().get_text();
1501 if (ppColor != nullptr)
1502 *ppColor = rPainterFormatter.GetLastOutputColor();
1504 return aText;
1507 void DbFormattedField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
1511 FormattedControlBase* pEditControl = static_cast<FormattedControlBase*>(m_pWindow.get());
1512 weld::Entry& rEntry = pEditControl->get_widget();
1513 weld::EntryFormatter& rEditFormatter = pEditControl->get_formatter();
1515 if (!_rxField.is())
1517 // NULL value -> empty text
1518 rEntry.set_text(OUString());
1520 else if (m_rColumn.IsNumeric())
1522 // The IsNumeric at the column says nothing about the class of the used format, but
1523 // about the class of the field bound to the column. So when you bind a FormattedField
1524 // column to a double field and format it as text, m_rColumn.IsNumeric() returns
1525 // sal_True. So that simply means that I can query the contents of the variant using
1526 // getDouble, and then I can leave the rest (the formatting) to the FormattedField.
1527 double dValue = getValue( _rxField, m_rColumn.GetParent().getNullDate() );
1528 if (_rxField->wasNull())
1529 rEntry.set_text(OUString());
1530 else
1531 rEditFormatter.SetValue(dValue);
1533 else
1535 // Here I can not work with a double, since the field can not provide it to me.
1536 // So simply bind the text from the css::util::NumberFormatter to the correct css::form::component::Form.
1537 OUString sText( _rxField->getString());
1539 rEditFormatter.SetTextFormatted( sText );
1540 rEntry.select_region(0, -1);
1543 catch( const Exception& )
1545 DBG_UNHANDLED_EXCEPTION("svx");
1549 void DbFormattedField::updateFromModel( Reference< XPropertySet > _rxModel )
1551 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbFormattedField::updateFromModel: invalid call!" );
1553 FormattedControlBase* pEditControl = static_cast<FormattedControlBase*>(m_pWindow.get());
1554 weld::Entry& rEntry = pEditControl->get_widget();
1555 weld::EntryFormatter& rEditFormatter = pEditControl->get_formatter();
1557 OUString sText;
1558 Any aValue = _rxModel->getPropertyValue( FM_PROP_EFFECTIVE_VALUE );
1559 if ( !aValue.hasValue() || (aValue >>= sText) )
1561 // our effective value is transferred as string
1562 rEditFormatter.SetTextFormatted( sText );
1563 rEntry.select_region(0, -1);
1565 else
1567 double dValue = 0;
1568 aValue >>= dValue;
1569 rEditFormatter.SetValue(dValue);
1573 bool DbFormattedField::commitControl()
1575 Any aNewVal;
1577 FormattedControlBase* pEditControl = static_cast<FormattedControlBase*>(m_pWindow.get());
1578 weld::Entry& rEntry = pEditControl->get_widget();
1579 weld::EntryFormatter& rEditFormatter = pEditControl->get_formatter();
1581 if (m_rColumn.IsNumeric())
1583 if (!rEntry.get_text().isEmpty())
1584 aNewVal <<= rEditFormatter.GetValue();
1585 // an empty string is passed on as void by default, to start with
1587 else
1588 aNewVal <<= rEditFormatter.GetTextValue();
1590 m_rColumn.getModel()->setPropertyValue(FM_PROP_EFFECTIVE_VALUE, aNewVal);
1591 return true;
1594 DbCheckBox::DbCheckBox( DbGridColumn& _rColumn )
1595 :DbCellControl( _rColumn )
1597 setAlignedController( false );
1600 namespace
1602 void setCheckBoxStyle( vcl::Window* _pWindow, bool bMono )
1604 AllSettings aSettings = _pWindow->GetSettings();
1605 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1606 if( bMono )
1607 aStyleSettings.SetOptions( aStyleSettings.GetOptions() | StyleSettingsOptions::Mono );
1608 else
1609 aStyleSettings.SetOptions( aStyleSettings.GetOptions() & (~StyleSettingsOptions::Mono) );
1610 aSettings.SetStyleSettings( aStyleSettings );
1611 _pWindow->SetSettings( aSettings );
1615 void DbCheckBox::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
1617 setTransparent( true );
1619 m_pWindow = VclPtr<CheckBoxControl>::Create( &rParent );
1620 m_pPainter = VclPtr<CheckBoxControl>::Create( &rParent );
1622 m_pWindow->SetPaintTransparent( true );
1623 m_pPainter->SetPaintTransparent( true );
1625 m_pPainter->SetBackground();
1629 Reference< XPropertySet > xModel( m_rColumn.getModel(), UNO_SET_THROW );
1631 sal_Int16 nStyle = awt::VisualEffect::LOOK3D;
1632 OSL_VERIFY( xModel->getPropertyValue( FM_PROP_VISUALEFFECT ) >>= nStyle );
1634 setCheckBoxStyle( m_pWindow, nStyle == awt::VisualEffect::FLAT );
1635 setCheckBoxStyle( m_pPainter, nStyle == awt::VisualEffect::FLAT );
1637 bool bTristate = true;
1638 OSL_VERIFY( xModel->getPropertyValue( FM_PROP_TRISTATE ) >>= bTristate );
1639 static_cast< CheckBoxControl* >( m_pWindow.get() )->EnableTriState( bTristate );
1640 static_cast< CheckBoxControl* >( m_pPainter.get() )->EnableTriState( bTristate );
1642 catch( const Exception& )
1644 DBG_UNHANDLED_EXCEPTION("svx");
1647 DbCellControl::Init( rParent, xCursor );
1650 CellControllerRef DbCheckBox::CreateController() const
1652 return new CheckBoxCellController(static_cast<CheckBoxControl*>(m_pWindow.get()));
1655 static void lcl_setCheckBoxState( const Reference< css::sdb::XColumn >& _rxField,
1656 CheckBoxControl* _pCheckBoxControl )
1658 TriState eState = TRISTATE_INDET;
1659 if (_rxField.is())
1663 bool bValue = _rxField->getBoolean();
1664 if (!_rxField->wasNull())
1665 eState = bValue ? TRISTATE_TRUE : TRISTATE_FALSE;
1667 catch( const Exception& )
1669 DBG_UNHANDLED_EXCEPTION("svx");
1672 _pCheckBoxControl->SetState(eState);
1675 void DbCheckBox::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
1677 lcl_setCheckBoxState( _rxField, static_cast<CheckBoxControl*>(m_pWindow.get()) );
1680 void DbCheckBox::PaintFieldToCell(OutputDevice& rDev, const tools::Rectangle& rRect,
1681 const Reference< css::sdb::XColumn >& _rxField,
1682 const Reference< XNumberFormatter >& xFormatter)
1684 CheckBoxControl* pControl = static_cast<CheckBoxControl*>(m_pPainter.get());
1685 lcl_setCheckBoxState( _rxField, pControl );
1687 Size aBoxSize;
1689 switch (rDev.GetOutDevType())
1691 case OUTDEV_WINDOW:
1692 case OUTDEV_VIRDEV:
1693 aBoxSize = pControl->GetBox().get_preferred_size();
1694 break;
1695 case OUTDEV_PRINTER:
1696 case OUTDEV_PDF:
1698 auto nSize = std::min(rRect.GetWidth(), rRect.GetHeight());
1699 aBoxSize = Size(nSize, nSize);
1700 break;
1704 tools::Rectangle aRect(Point(rRect.Left() + ((rRect.GetWidth() - aBoxSize.Width()) / 2),
1705 rRect.Top() + ((rRect.GetHeight() - aBoxSize.Height()) / 2)),
1706 aBoxSize);
1708 DbCellControl::PaintFieldToCell(rDev, aRect, _rxField, xFormatter);
1711 void DbCheckBox::PaintCell(OutputDevice& rDev, const tools::Rectangle& rRect)
1713 switch (rDev.GetOutDevType())
1715 case OUTDEV_WINDOW:
1716 case OUTDEV_VIRDEV:
1717 DbCellControl::PaintCell(rDev, rRect);
1718 break;
1719 case OUTDEV_PRINTER:
1720 case OUTDEV_PDF:
1722 TriState eState = static_cast<CheckBoxControl*>(m_pWindow.get())->GetState();
1724 MapMode aResMapMode(MapUnit::Map100thMM);
1725 Size aImageSize = rDev.LogicToPixel(Size(300, 300), aResMapMode);
1726 Size aBrd1Size = rDev.LogicToPixel(Size(20, 20), aResMapMode);
1727 Size aBrd2Size = rDev.LogicToPixel(Size(30, 30), aResMapMode);
1728 int nCheckWidth = rDev.LogicToPixel(Size(20, 20), aResMapMode).Width();
1730 tools::Rectangle aStateRect;
1731 aStateRect.SetLeft(rRect.Left() + ((rRect.GetWidth() - aImageSize.Width()) / 2));
1732 aStateRect.SetTop(rRect.Top() + ((rRect.GetHeight() - aImageSize.Height()) / 2));
1733 aStateRect.SetRight(aStateRect.Left() + aImageSize.Width() - 1);
1734 aStateRect.SetBottom(aStateRect.Top() + aImageSize.Height() - 1);
1736 rDev.Push();
1737 rDev.SetMapMode();
1739 rDev.SetLineColor();
1740 rDev.SetFillColor(COL_BLACK);
1741 rDev.DrawRect(aStateRect);
1742 aStateRect.AdjustLeft(aBrd1Size.Width());
1743 aStateRect.AdjustTop(aBrd1Size.Height());
1744 aStateRect.AdjustRight(-aBrd1Size.Width());
1745 aStateRect.AdjustBottom(-aBrd1Size.Height());
1746 if (eState == TRISTATE_INDET)
1747 rDev.SetFillColor(COL_LIGHTGRAY);
1748 else
1749 rDev.SetFillColor(COL_WHITE);
1750 rDev.DrawRect(aStateRect);
1752 if (eState == TRISTATE_TRUE)
1754 aStateRect.AdjustLeft(aBrd2Size.Width());
1755 aStateRect.AdjustTop(aBrd2Size.Height());
1756 aStateRect.AdjustRight(-aBrd2Size.Width());
1757 aStateRect.AdjustBottom(-aBrd2Size.Height());
1758 Point aPos11(aStateRect.TopLeft());
1759 Point aPos12(aStateRect.BottomRight());
1760 Point aPos21(aStateRect.TopRight());
1761 Point aPos22(aStateRect.BottomLeft());
1762 Point aTempPos11(aPos11);
1763 Point aTempPos12(aPos12);
1764 Point aTempPos21(aPos21);
1765 Point aTempPos22(aPos22);
1766 rDev.SetLineColor(COL_BLACK);
1767 int nDX = 0;
1768 for (int i = 0; i < nCheckWidth; i++)
1770 if ( !(i % 2) )
1772 aTempPos11.setX(aPos11.X() + nDX);
1773 aTempPos12.setX(aPos12.X() + nDX);
1774 aTempPos21.setX(aPos21.X() + nDX);
1775 aTempPos22.setX(aPos22.X() + nDX);
1777 else
1779 nDX++;
1780 aTempPos11.setX(aPos11.X() - nDX);
1781 aTempPos12.setX(aPos12.X() - nDX);
1782 aTempPos21.setX(aPos21.X() - nDX);
1783 aTempPos22.setX(aPos22.X() - nDX);
1785 rDev.DrawLine(aTempPos11, aTempPos12);
1786 rDev.DrawLine(aTempPos21, aTempPos22);
1790 rDev.Pop();
1791 break;
1796 void DbCheckBox::updateFromModel( Reference< XPropertySet > _rxModel )
1798 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbCheckBox::updateFromModel: invalid call!" );
1800 sal_Int16 nState = TRISTATE_INDET;
1801 _rxModel->getPropertyValue( FM_PROP_STATE ) >>= nState;
1802 static_cast< CheckBoxControl* >( m_pWindow.get() )->SetState( static_cast< TriState >( nState ) );
1805 bool DbCheckBox::commitControl()
1807 m_rColumn.getModel()->setPropertyValue( FM_PROP_STATE,
1808 Any( static_cast<sal_Int16>( static_cast< CheckBoxControl* >( m_pWindow.get() )->GetState() ) ) );
1809 return true;
1812 OUString DbCheckBox::GetFormatText(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
1814 return OUString();
1817 DbPatternField::DbPatternField( DbGridColumn& _rColumn, const Reference<XComponentContext>& _rContext )
1818 :DbCellControl( _rColumn )
1819 ,m_xContext( _rContext )
1821 doPropertyListening( FM_PROP_LITERALMASK );
1822 doPropertyListening( FM_PROP_EDITMASK );
1823 doPropertyListening( FM_PROP_STRICTFORMAT );
1826 void DbPatternField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1828 DBG_ASSERT( m_pWindow, "DbPatternField::implAdjustGenericFieldSetting: not to be called without window!" );
1829 DBG_ASSERT( _rxModel.is(), "DbPatternField::implAdjustGenericFieldSetting: invalid model!" );
1830 if ( !m_pWindow || !_rxModel.is() )
1831 return;
1833 OUString aLitMask;
1834 OUString aEditMask;
1835 bool bStrict = false;
1837 _rxModel->getPropertyValue( FM_PROP_LITERALMASK ) >>= aLitMask;
1838 _rxModel->getPropertyValue( FM_PROP_EDITMASK ) >>= aEditMask;
1839 _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) >>= bStrict;
1841 OString aAsciiEditMask(OUStringToOString(aEditMask, RTL_TEXTENCODING_ASCII_US));
1843 weld::PatternFormatter& rEditFormatter = static_cast<PatternControl*>(m_pWindow.get())->get_formatter();
1844 rEditFormatter.SetMask(aAsciiEditMask, aLitMask);
1845 rEditFormatter.SetStrictFormat(bStrict);
1847 weld::PatternFormatter& rPaintFormatter = static_cast<PatternControl*>(m_pPainter.get())->get_formatter();
1848 rPaintFormatter.SetMask(aAsciiEditMask, aLitMask);
1849 rPaintFormatter.SetStrictFormat(bStrict);
1852 void DbPatternField::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
1854 m_rColumn.SetAlignmentFromModel(-1);
1856 m_pWindow = VclPtr<PatternControl>::Create(&rParent);
1857 m_pPainter= VclPtr<PatternControl>::Create(&rParent);
1859 Reference< XPropertySet > xModel( m_rColumn.getModel() );
1860 implAdjustGenericFieldSetting( xModel );
1862 DbCellControl::Init( rParent, xCursor );
1865 CellControllerRef DbPatternField::CreateController() const
1867 return new EditCellController(static_cast<PatternControl*>(m_pWindow.get()));
1870 OUString DbPatternField::impl_formatText( const OUString& _rText )
1872 weld::PatternFormatter& rPaintFormatter = static_cast<PatternControl*>(m_pPainter.get())->get_formatter();
1873 rPaintFormatter.get_widget().set_text(_rText);
1874 rPaintFormatter.ReformatAll();
1875 return rPaintFormatter.get_widget().get_text();
1878 OUString DbPatternField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
1880 bool bIsForPaint = _rxField != m_rColumn.GetField();
1881 ::std::unique_ptr< FormattedColumnValue >& rpFormatter = bIsForPaint ? m_pPaintFormatter : m_pValueFormatter;
1883 if (!rpFormatter)
1885 rpFormatter = std::make_unique< FormattedColumnValue> (
1886 m_xContext, getCursor(), Reference< XPropertySet >( _rxField, UNO_QUERY ) );
1887 OSL_ENSURE(rpFormatter, "DbPatternField::Init: no value formatter!");
1889 else
1890 OSL_ENSURE( rpFormatter->getColumn() == _rxField, "DbPatternField::GetFormatText: my value formatter is working for another field ...!" );
1891 // re-creating the value formatter here every time would be quite expensive ...
1893 OUString sText;
1894 if (rpFormatter)
1895 sText = rpFormatter->getFormattedValue();
1897 return impl_formatText( sText );
1900 void DbPatternField::UpdateFromField( const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
1902 weld::Entry& rEntry = static_cast<PatternControl*>(m_pWindow.get())->get_widget();
1903 rEntry.set_text(GetFormatText(_rxField, _rxFormatter));
1904 rEntry.select_region(-1, 0);
1907 void DbPatternField::updateFromModel( Reference< XPropertySet > _rxModel )
1909 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbPatternField::updateFromModel: invalid call!" );
1911 OUString sText;
1912 _rxModel->getPropertyValue( FM_PROP_TEXT ) >>= sText;
1914 weld::Entry& rEntry = static_cast<PatternControl*>(m_pWindow.get())->get_widget();
1915 rEntry.set_text(impl_formatText(sText));
1916 rEntry.select_region(-1, 0);
1919 bool DbPatternField::commitControl()
1921 weld::Entry& rEntry = static_cast<PatternControl*>(m_pWindow.get())->get_widget();
1922 m_rColumn.getModel()->setPropertyValue(FM_PROP_TEXT, Any(rEntry.get_text()));
1923 return true;
1926 DbSpinField::DbSpinField( DbGridColumn& _rColumn, sal_Int16 _nStandardAlign )
1927 :DbCellControl( _rColumn )
1928 ,m_nStandardAlign( _nStandardAlign )
1932 void DbSpinField::Init(BrowserDataWin& _rParent, const Reference< XRowSet >& _rxCursor)
1934 m_rColumn.SetAlignmentFromModel( m_nStandardAlign );
1936 Reference< XPropertySet > xModel( m_rColumn.getModel() );
1938 // determine if we need a spinbutton version
1939 bool bSpinButton(false);
1940 if ( ::comphelper::getBOOL( xModel->getPropertyValue( FM_PROP_SPIN ) ) )
1941 bSpinButton = true;
1942 // create the fields
1943 m_pWindow = createField( &_rParent, bSpinButton, xModel );
1944 m_pPainter = createField( &_rParent, bSpinButton, xModel );
1946 // adjust all other settings which depend on the property values
1947 implAdjustGenericFieldSetting( xModel );
1949 // call the base class
1950 DbCellControl::Init( _rParent, _rxCursor );
1953 CellControllerRef DbSpinField::CreateController() const
1955 return new ::svt::FormattedFieldCellController(static_cast<FormattedControlBase*>(m_pWindow.get()));
1958 DbNumericField::DbNumericField( DbGridColumn& _rColumn )
1959 :DbSpinField( _rColumn )
1961 doPropertyListening( FM_PROP_DECIMAL_ACCURACY );
1962 doPropertyListening( FM_PROP_VALUEMIN );
1963 doPropertyListening( FM_PROP_VALUEMAX );
1964 doPropertyListening( FM_PROP_VALUESTEP );
1965 doPropertyListening( FM_PROP_STRICTFORMAT );
1966 doPropertyListening( FM_PROP_SHOWTHOUSANDSEP );
1969 void DbNumericField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
1971 DBG_ASSERT( m_pWindow, "DbNumericField::implAdjustGenericFieldSetting: not to be called without window!" );
1972 DBG_ASSERT( _rxModel.is(), "DbNumericField::implAdjustGenericFieldSetting: invalid model!" );
1973 if ( !m_pWindow || !_rxModel.is() )
1974 return;
1976 sal_Int32 nMin = static_cast<sal_Int32>(getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMIN ) ));
1977 sal_Int32 nMax = static_cast<sal_Int32>(getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMAX ) ));
1978 sal_Int32 nStep = static_cast<sal_Int32>(getDouble( _rxModel->getPropertyValue( FM_PROP_VALUESTEP ) ));
1979 bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
1980 sal_Int16 nScale = getINT16( _rxModel->getPropertyValue( FM_PROP_DECIMAL_ACCURACY ) );
1981 bool bThousand = getBOOL( _rxModel->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP ) );
1983 Formatter& rEditFormatter = static_cast<FormattedControlBase*>(m_pWindow.get())->get_formatter();
1984 rEditFormatter.SetMinValue(nMin);
1985 rEditFormatter.SetMaxValue(nMax);
1986 rEditFormatter.SetSpinSize(nStep);
1987 rEditFormatter.SetStrictFormat(bStrict);
1989 Formatter& rPaintFormatter = static_cast<FormattedControlBase*>(m_pPainter.get())->get_formatter();
1990 rPaintFormatter.SetMinValue(nMin);
1991 rPaintFormatter.SetMaxValue(nMax);
1992 rPaintFormatter.SetStrictFormat(bStrict);
1994 // give a formatter to the field and the painter;
1995 // test first if I can get from the service behind a connection
1996 Reference< css::util::XNumberFormatsSupplier > xSupplier;
1997 Reference< XRowSet > xForm;
1998 if ( m_rColumn.GetParent().getDataSource() )
1999 xForm.set( Reference< XInterface >(*m_rColumn.GetParent().getDataSource()), UNO_QUERY );
2000 if ( xForm.is() )
2001 xSupplier = getNumberFormats( getConnection( xForm ), true );
2002 SvNumberFormatter* pFormatterUsed = nullptr;
2003 if ( xSupplier.is() )
2005 SvNumberFormatsSupplierObj* pImplementation = comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>( xSupplier );
2006 pFormatterUsed = pImplementation ? pImplementation->GetNumberFormatter() : nullptr;
2008 if ( nullptr == pFormatterUsed )
2009 { // the cursor didn't lead to success -> standard
2010 pFormatterUsed = rEditFormatter.StandardFormatter();
2011 DBG_ASSERT( pFormatterUsed != nullptr, "DbNumericField::implAdjustGenericFieldSetting: no standard formatter given by the numeric field !" );
2013 rEditFormatter.SetFormatter( pFormatterUsed );
2014 rPaintFormatter.SetFormatter( pFormatterUsed );
2016 // and then generate a format which has the desired length after the decimal point, etc.
2017 LanguageType aAppLanguage = Application::GetSettings().GetUILanguageTag().getLanguageType();
2018 OUString sFormatString = pFormatterUsed->GenerateFormat(0, aAppLanguage, bThousand, false, nScale);
2020 rEditFormatter.SetFormat( sFormatString, aAppLanguage );
2021 rPaintFormatter.SetFormat( sFormatString, aAppLanguage );
2024 VclPtr<svt::ControlBase> DbNumericField::createField(BrowserDataWin* pParent, bool bSpinButton, const Reference<XPropertySet>& /*rxModel*/)
2026 return VclPtr<DoubleNumericControl>::Create(pParent, bSpinButton);
2029 namespace
2031 OUString lcl_setFormattedNumeric_nothrow( FormattedControlBase& _rField, const DbCellControl& _rControl,
2032 const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
2034 OUString sValue;
2035 if ( _rxField.is() )
2039 double fValue = _rControl.GetValue( _rxField, _rxFormatter );
2040 if ( !_rxField->wasNull() )
2042 _rField.get_formatter().SetValue(fValue);
2043 sValue = _rField.get_widget().get_text();
2046 catch( const Exception& )
2048 DBG_UNHANDLED_EXCEPTION("svx");
2051 return sValue;
2055 OUString DbNumericField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& _rxFormatter, const Color** /*ppColor*/)
2057 return lcl_setFormattedNumeric_nothrow(dynamic_cast<FormattedControlBase&>(*m_pPainter), *this, _rxField, _rxFormatter);
2060 void DbNumericField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& _rxFormatter)
2062 lcl_setFormattedNumeric_nothrow(dynamic_cast<FormattedControlBase&>(*m_pWindow), *this, _rxField, _rxFormatter);
2065 void DbNumericField::updateFromModel( Reference< XPropertySet > _rxModel )
2067 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbNumericField::updateFromModel: invalid call!" );
2069 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2070 Formatter& rFormatter = pControl->get_formatter();
2072 double dValue = 0;
2073 if ( _rxModel->getPropertyValue( FM_PROP_VALUE ) >>= dValue )
2074 rFormatter.SetValue(dValue);
2075 else
2077 pControl->get_widget().set_text(OUString());
2078 rFormatter.InvalidateValueState();
2082 bool DbNumericField::commitControl()
2084 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2085 OUString aText(pControl->get_widget().get_text());
2086 Any aVal;
2088 if (!aText.isEmpty()) // not empty
2090 Formatter& rFormatter = pControl->get_formatter();
2091 double fValue = rFormatter.GetValue();
2092 aVal <<= fValue;
2094 m_rColumn.getModel()->setPropertyValue(FM_PROP_VALUE, aVal);
2095 return true;
2098 DbCurrencyField::DbCurrencyField(DbGridColumn& _rColumn)
2099 :DbSpinField( _rColumn )
2101 doPropertyListening( FM_PROP_DECIMAL_ACCURACY );
2102 doPropertyListening( FM_PROP_VALUEMIN );
2103 doPropertyListening( FM_PROP_VALUEMAX );
2104 doPropertyListening( FM_PROP_VALUESTEP );
2105 doPropertyListening( FM_PROP_STRICTFORMAT );
2106 doPropertyListening( FM_PROP_SHOWTHOUSANDSEP );
2107 doPropertyListening( FM_PROP_CURRENCYSYMBOL );
2110 void DbCurrencyField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2112 DBG_ASSERT( m_pWindow, "DbCurrencyField::implAdjustGenericFieldSetting: not to be called without window!" );
2113 DBG_ASSERT( _rxModel.is(), "DbCurrencyField::implAdjustGenericFieldSetting: invalid model!" );
2114 if ( !m_pWindow || !_rxModel.is() )
2115 return;
2117 sal_Int16 nScale = getINT16( _rxModel->getPropertyValue( FM_PROP_DECIMAL_ACCURACY ) );
2118 double nMin = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMIN ) );
2119 double nMax = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUEMAX ) );
2120 double nStep = getDouble( _rxModel->getPropertyValue( FM_PROP_VALUESTEP ) );
2121 bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2122 bool bThousand = getBOOL( _rxModel->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP ) );
2123 OUString aStr( getString( _rxModel->getPropertyValue(FM_PROP_CURRENCYSYMBOL ) ) );
2125 Formatter& rEditFormatter = static_cast<FormattedControlBase*>(m_pWindow.get())->get_formatter();
2126 rEditFormatter.SetDecimalDigits(nScale);
2127 rEditFormatter.SetMinValue(nMin);
2128 rEditFormatter.SetMaxValue(nMax);
2129 rEditFormatter.SetSpinSize(nStep);
2130 rEditFormatter.SetStrictFormat(bStrict);
2131 weld::LongCurrencyFormatter& rCurrencyEditFormatter = static_cast<weld::LongCurrencyFormatter&>(rEditFormatter);
2132 rCurrencyEditFormatter.SetUseThousandSep(bThousand);
2133 rCurrencyEditFormatter.SetCurrencySymbol(aStr);
2135 Formatter& rPaintFormatter = static_cast<FormattedControlBase*>(m_pPainter.get())->get_formatter();
2136 rPaintFormatter.SetDecimalDigits(nScale);
2137 rPaintFormatter.SetMinValue(nMin);
2138 rPaintFormatter.SetMaxValue(nMax);
2139 rPaintFormatter.SetStrictFormat(bStrict);
2140 weld::LongCurrencyFormatter& rPaintCurrencyFormatter = static_cast<weld::LongCurrencyFormatter&>(rPaintFormatter);
2141 rPaintCurrencyFormatter.SetUseThousandSep(bThousand);
2142 rPaintCurrencyFormatter.SetCurrencySymbol(aStr);
2145 VclPtr<svt::ControlBase> DbCurrencyField::createField(BrowserDataWin* pParent, bool bSpinButton, const Reference< XPropertySet >& /*rxModel*/)
2147 return VclPtr<LongCurrencyControl>::Create(pParent, bSpinButton);
2150 namespace
2152 OUString lcl_setFormattedCurrency_nothrow( FormattedControlBase& _rField, const DbCurrencyField& _rControl,
2153 const Reference< XColumn >& _rxField, const Reference< XNumberFormatter >& _rxFormatter )
2155 OUString sValue;
2156 if ( _rxField.is() )
2160 double fValue = _rControl.GetValue( _rxField, _rxFormatter );
2161 if ( !_rxField->wasNull() )
2163 _rField.get_formatter().SetValue(fValue);
2164 sValue = _rField.get_widget().get_text();
2167 catch( const Exception& )
2169 DBG_UNHANDLED_EXCEPTION("svx");
2172 return sValue;
2176 OUString DbCurrencyField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& _rxFormatter, const Color** /*ppColor*/)
2178 return lcl_setFormattedCurrency_nothrow(dynamic_cast<FormattedControlBase&>(*m_pPainter), *this, _rxField, _rxFormatter);
2181 void DbCurrencyField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& _rxFormatter)
2183 lcl_setFormattedCurrency_nothrow(dynamic_cast<FormattedControlBase&>(*m_pWindow), *this, _rxField, _rxFormatter);
2186 void DbCurrencyField::updateFromModel( Reference< XPropertySet > _rxModel )
2188 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbCurrencyField::updateFromModel: invalid call!" );
2190 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2191 Formatter& rFormatter = pControl->get_formatter();
2193 double dValue = 0;
2194 if ( _rxModel->getPropertyValue( FM_PROP_VALUE ) >>= dValue )
2195 rFormatter.SetValue(dValue);
2196 else
2198 pControl->get_widget().set_text(OUString());
2199 rFormatter.InvalidateValueState();
2203 bool DbCurrencyField::commitControl()
2205 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2206 OUString aText(pControl->get_widget().get_text());
2207 Any aVal;
2209 if (!aText.isEmpty()) // not empty
2211 Formatter& rFormatter = pControl->get_formatter();
2212 double fValue = rFormatter.GetValue();
2213 aVal <<= fValue;
2215 m_rColumn.getModel()->setPropertyValue(FM_PROP_VALUE, aVal);
2216 return true;
2219 DbDateField::DbDateField( DbGridColumn& _rColumn )
2220 :DbSpinField( _rColumn )
2222 doPropertyListening( FM_PROP_DATEFORMAT );
2223 doPropertyListening( FM_PROP_DATEMIN );
2224 doPropertyListening( FM_PROP_DATEMAX );
2225 doPropertyListening( FM_PROP_STRICTFORMAT );
2226 doPropertyListening( FM_PROP_DATE_SHOW_CENTURY );
2229 VclPtr<svt::ControlBase> DbDateField::createField(BrowserDataWin* pParent, bool bSpinButton, const Reference< XPropertySet >& rxModel)
2231 // check if there is a DropDown property set to TRUE
2232 bool bDropDown = !hasProperty( FM_PROP_DROPDOWN, rxModel )
2233 || getBOOL( rxModel->getPropertyValue( FM_PROP_DROPDOWN ) );
2234 // given the apparent inability to set a custom up/down action for a gtk
2235 // spinbutton to have different up/down dates depending on the zone the
2236 // mouse is in, show the dropdown calendar for both the spin or dropdown case
2237 return VclPtr<DateControl>::Create(pParent, bSpinButton || bDropDown);
2240 void DbDateField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2242 DBG_ASSERT( m_pWindow, "DbDateField::implAdjustGenericFieldSetting: not to be called without window!" );
2243 DBG_ASSERT( _rxModel.is(), "DbDateField::implAdjustGenericFieldSetting: invalid model!" );
2244 if ( !m_pWindow || !_rxModel.is() )
2245 return;
2247 sal_Int16 nFormat = getINT16( _rxModel->getPropertyValue( FM_PROP_DATEFORMAT ) );
2248 util::Date aMin;
2249 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_DATEMIN ) >>= aMin );
2250 util::Date aMax;
2251 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_DATEMAX ) >>= aMax );
2252 bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2254 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2255 weld::DateFormatter& rControlFormatter = static_cast<weld::DateFormatter&>(pControl->get_formatter());
2257 FormattedControlBase* pPainter = static_cast<FormattedControlBase*>(m_pPainter.get());
2258 weld::DateFormatter& rPainterFormatter = static_cast<weld::DateFormatter&>(pPainter->get_formatter());
2260 Any aCentury = _rxModel->getPropertyValue( FM_PROP_DATE_SHOW_CENTURY );
2261 if ( aCentury.getValueTypeClass() != TypeClass_VOID )
2263 bool bShowDateCentury = getBOOL( aCentury );
2265 rControlFormatter.SetShowDateCentury(bShowDateCentury);
2266 rPainterFormatter.SetShowDateCentury(bShowDateCentury);
2269 rControlFormatter.SetExtDateFormat( static_cast<ExtDateFieldFormat>(nFormat) );
2270 rControlFormatter.SetMin( ::Date(aMin) );
2271 rControlFormatter.SetMax( ::Date(aMax) );
2272 rControlFormatter.SetStrictFormat( bStrict );
2273 rControlFormatter.EnableEmptyField( true );
2275 rPainterFormatter.SetExtDateFormat( static_cast<ExtDateFieldFormat>(nFormat) );
2276 rPainterFormatter.SetMin( ::Date(aMin) );
2277 rPainterFormatter.SetMax( ::Date(aMax) );
2278 rPainterFormatter.SetStrictFormat( bStrict );
2279 rPainterFormatter.EnableEmptyField( true );
2282 namespace
2284 OUString lcl_setFormattedDate_nothrow(DateControl& _rField, const Reference<XColumn>& _rxField)
2286 OUString sDate;
2287 if ( _rxField.is() )
2291 css::util::Date aValue = _rxField->getDate();
2292 if (!_rxField->wasNull())
2294 _rField.SetDate(::Date(aValue.Day, aValue.Month, aValue.Year));
2295 sDate = _rField.get_widget().get_text();
2298 catch( const Exception& )
2300 DBG_UNHANDLED_EXCEPTION("svx");
2303 return sDate;
2307 OUString DbDateField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
2309 return lcl_setFormattedDate_nothrow(*static_cast<DateControl*>(m_pPainter.get()), _rxField);
2312 void DbDateField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
2314 lcl_setFormattedDate_nothrow(*static_cast<DateControl*>(m_pWindow.get()), _rxField);
2317 void DbDateField::updateFromModel( Reference< XPropertySet > _rxModel )
2319 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbDateField::updateFromModel: invalid call!" );
2321 DateControl* pControl = static_cast<DateControl*>(m_pWindow.get());
2323 util::Date aDate;
2324 if ( _rxModel->getPropertyValue( FM_PROP_DATE ) >>= aDate )
2325 pControl->SetDate(::Date(aDate));
2326 else
2327 pControl->get_widget().set_text(OUString());
2330 bool DbDateField::commitControl()
2332 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2333 OUString aText(pControl->get_widget().get_text());
2334 Any aVal;
2336 if (!aText.isEmpty()) // not empty
2338 weld::DateFormatter& rControlFormatter = static_cast<weld::DateFormatter&>(pControl->get_formatter());
2339 aVal <<= rControlFormatter.GetDate().GetUNODate();
2342 m_rColumn.getModel()->setPropertyValue(FM_PROP_DATE, aVal);
2343 return true;
2346 DbTimeField::DbTimeField( DbGridColumn& _rColumn )
2347 :DbSpinField( _rColumn, css::awt::TextAlign::LEFT )
2349 doPropertyListening( FM_PROP_TIMEFORMAT );
2350 doPropertyListening( FM_PROP_TIMEMIN );
2351 doPropertyListening( FM_PROP_TIMEMAX );
2352 doPropertyListening( FM_PROP_STRICTFORMAT );
2355 VclPtr<svt::ControlBase> DbTimeField::createField(BrowserDataWin* pParent, bool bSpinButton, const Reference< XPropertySet >& /*rxModel*/ )
2357 return VclPtr<TimeControl>::Create(pParent, bSpinButton);
2360 void DbTimeField::implAdjustGenericFieldSetting( const Reference< XPropertySet >& _rxModel )
2362 DBG_ASSERT( m_pWindow, "DbTimeField::implAdjustGenericFieldSetting: not to be called without window!" );
2363 DBG_ASSERT( _rxModel.is(), "DbTimeField::implAdjustGenericFieldSetting: invalid model!" );
2364 if ( !m_pWindow || !_rxModel.is() )
2365 return;
2367 sal_Int16 nFormat = getINT16( _rxModel->getPropertyValue( FM_PROP_TIMEFORMAT ) );
2368 util::Time aMin;
2369 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_TIMEMIN ) >>= aMin );
2370 util::Time aMax;
2371 OSL_VERIFY( _rxModel->getPropertyValue( FM_PROP_TIMEMAX ) >>= aMax );
2372 bool bStrict = getBOOL( _rxModel->getPropertyValue( FM_PROP_STRICTFORMAT ) );
2374 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2375 weld::TimeFormatter& rControlFormatter = static_cast<weld::TimeFormatter&>(pControl->get_formatter());
2377 rControlFormatter.SetExtFormat(static_cast<ExtTimeFieldFormat>(nFormat));
2378 rControlFormatter.SetMin(tools::Time(aMin));
2379 rControlFormatter.SetMax(tools::Time(aMax));
2380 rControlFormatter.SetStrictFormat(bStrict);
2381 rControlFormatter.EnableEmptyField(true);
2383 FormattedControlBase* pPainter = static_cast<FormattedControlBase*>(m_pPainter.get());
2384 weld::TimeFormatter& rPainterFormatter = static_cast<weld::TimeFormatter&>(pPainter->get_formatter());
2386 rPainterFormatter.SetExtFormat(static_cast<ExtTimeFieldFormat>(nFormat));
2387 rPainterFormatter.SetMin(tools::Time(aMin));
2388 rPainterFormatter.SetMax(tools::Time(aMax));
2389 rPainterFormatter.SetStrictFormat(bStrict);
2390 rPainterFormatter.EnableEmptyField(true);
2393 namespace
2395 OUString lcl_setFormattedTime_nothrow(TimeControl& _rField, const Reference<XColumn>& _rxField)
2397 OUString sTime;
2398 if ( _rxField.is() )
2402 css::util::Time aValue = _rxField->getTime();
2403 if (!_rxField->wasNull())
2405 static_cast<weld::TimeFormatter&>(_rField.get_formatter()).SetTime( ::tools::Time( aValue ) );
2406 sTime = _rField.get_widget().get_text();
2409 catch( const Exception& )
2411 DBG_UNHANDLED_EXCEPTION("svx");
2414 return sTime;
2418 OUString DbTimeField::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< css::util::XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
2420 return lcl_setFormattedTime_nothrow(*static_cast<TimeControl*>(m_pPainter.get()), _rxField);
2423 void DbTimeField::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/)
2425 lcl_setFormattedTime_nothrow(*static_cast<TimeControl*>(m_pWindow.get()), _rxField);
2428 void DbTimeField::updateFromModel( Reference< XPropertySet > _rxModel )
2430 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbTimeField::updateFromModel: invalid call!" );
2432 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2433 weld::TimeFormatter& rControlFormatter = static_cast<weld::TimeFormatter&>(pControl->get_formatter());
2435 util::Time aTime;
2436 if ( _rxModel->getPropertyValue( FM_PROP_TIME ) >>= aTime )
2437 rControlFormatter.SetTime(::tools::Time(aTime));
2438 else
2439 pControl->get_widget().set_text(OUString());
2442 bool DbTimeField::commitControl()
2444 FormattedControlBase* pControl = static_cast<FormattedControlBase*>(m_pWindow.get());
2445 OUString aText(pControl->get_widget().get_text());
2446 Any aVal;
2448 if (!aText.isEmpty()) // not empty
2450 weld::TimeFormatter& rControlFormatter = static_cast<weld::TimeFormatter&>(pControl->get_formatter());
2451 aVal <<= rControlFormatter.GetTime().GetUNOTime();
2454 m_rColumn.getModel()->setPropertyValue(FM_PROP_TIME, aVal);
2455 return true;
2458 DbComboBox::DbComboBox(DbGridColumn& _rColumn)
2459 :DbCellControl(_rColumn)
2461 setAlignedController( false );
2463 doPropertyListening( FM_PROP_STRINGITEMLIST );
2464 doPropertyListening( FM_PROP_LINECOUNT );
2467 void DbComboBox::_propertyChanged( const PropertyChangeEvent& _rEvent )
2469 if ( _rEvent.PropertyName == FM_PROP_STRINGITEMLIST )
2471 SetList(_rEvent.NewValue);
2473 else
2475 DbCellControl::_propertyChanged( _rEvent ) ;
2479 void DbComboBox::SetList(const Any& rItems)
2481 ComboBoxControl* pField = static_cast<ComboBoxControl*>(m_pWindow.get());
2482 weld::ComboBox& rComboBox = pField->get_widget();
2483 rComboBox.clear();
2485 css::uno::Sequence<OUString> aTest;
2486 if (rItems >>= aTest)
2488 for (const OUString& rString : aTest)
2489 rComboBox.append_text(rString);
2491 // tell the grid control that this controller is invalid and has to be re-initialized
2492 invalidatedController();
2496 void DbComboBox::implAdjustGenericFieldSetting(const Reference<XPropertySet>&)
2498 // we no longer pay attention to FM_PROP_LINECOUNT
2501 void DbComboBox::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
2503 m_rColumn.SetAlignmentFromModel(css::awt::TextAlign::LEFT);
2505 m_pWindow = VclPtr<ComboBoxControl>::Create( &rParent );
2507 // selection from right to left
2508 AllSettings aSettings = m_pWindow->GetSettings();
2509 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2510 aStyleSettings.SetSelectionOptions(
2511 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2512 aSettings.SetStyleSettings(aStyleSettings);
2513 m_pWindow->SetSettings(aSettings, true);
2515 // some initial properties
2516 Reference< XPropertySet > xModel(m_rColumn.getModel());
2517 SetList( xModel->getPropertyValue( FM_PROP_STRINGITEMLIST ) );
2518 implAdjustGenericFieldSetting( xModel );
2520 DbCellControl::Init( rParent, xCursor );
2523 CellControllerRef DbComboBox::CreateController() const
2525 return new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2528 OUString DbComboBox::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter, const Color** /*ppColor*/)
2530 const css::uno::Reference<css::beans::XPropertySet> xPS(_rxField, UNO_QUERY);
2531 ::dbtools::FormattedColumnValue fmter( xFormatter, xPS );
2533 return fmter.getFormattedValue();
2536 void DbComboBox::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
2538 ComboBoxControl* pControl = static_cast<ComboBoxControl*>(m_pWindow.get());
2539 pControl->get_widget().set_entry_text(GetFormatText(_rxField, xFormatter));
2542 void DbComboBox::updateFromModel( Reference< XPropertySet > _rxModel )
2544 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbComboBox::updateFromModel: invalid call!" );
2546 OUString sText;
2547 _rxModel->getPropertyValue( FM_PROP_TEXT ) >>= sText;
2549 ComboBoxControl* pControl = static_cast<ComboBoxControl*>(m_pWindow.get());
2550 weld::ComboBox& rComboBox = pControl->get_widget();
2552 OUString sOldActive = rComboBox.get_active_text();
2553 rComboBox.set_entry_text(sText);
2554 rComboBox.select_entry_region(0, -1);
2556 if (sOldActive != rComboBox.get_active_text())
2557 pControl->TriggerAuxModify();
2560 bool DbComboBox::commitControl()
2562 ComboBoxControl* pControl = static_cast<ComboBoxControl*>(m_pWindow.get());
2563 weld::ComboBox& rComboBox = pControl->get_widget();
2564 OUString aText(rComboBox.get_active_text());
2565 m_rColumn.getModel()->setPropertyValue(FM_PROP_TEXT, Any(aText));
2566 return true;
2570 DbListBox::DbListBox(DbGridColumn& _rColumn)
2571 :DbCellControl(_rColumn)
2572 ,m_bBound(false)
2574 setAlignedController( false );
2576 doPropertyListening( FM_PROP_STRINGITEMLIST );
2577 doPropertyListening( FM_PROP_LINECOUNT );
2580 void DbListBox::_propertyChanged( const css::beans::PropertyChangeEvent& _rEvent )
2582 if ( _rEvent.PropertyName == FM_PROP_STRINGITEMLIST )
2584 SetList(_rEvent.NewValue);
2586 else
2588 DbCellControl::_propertyChanged( _rEvent ) ;
2592 void DbListBox::SetList(const Any& rItems)
2594 ListBoxControl* pField = static_cast<ListBoxControl*>(m_pWindow.get());
2596 weld::ComboBox& rFieldList = pField->get_widget();
2598 rFieldList.clear();
2599 m_bBound = false;
2601 css::uno::Sequence<OUString> aTest;
2602 if (!(rItems >>= aTest))
2603 return;
2605 if (aTest.hasElements())
2607 for (const OUString& rString : aTest)
2608 rFieldList.append_text(rString);
2610 m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ) >>= m_aValueList;
2611 m_bBound = m_aValueList.hasElements();
2613 // tell the grid control that this controller is invalid and has to be re-initialized
2614 invalidatedController();
2618 void DbListBox::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
2620 m_rColumn.SetAlignment(css::awt::TextAlign::LEFT);
2622 m_pWindow = VclPtr<ListBoxControl>::Create( &rParent );
2624 // some initial properties
2625 Reference< XPropertySet > xModel( m_rColumn.getModel() );
2626 SetList( xModel->getPropertyValue( FM_PROP_STRINGITEMLIST ) );
2627 implAdjustGenericFieldSetting( xModel );
2629 DbCellControl::Init( rParent, xCursor );
2632 void DbListBox::implAdjustGenericFieldSetting(const Reference<XPropertySet>& _rxModel)
2634 DBG_ASSERT( m_pWindow, "DbListBox::implAdjustGenericFieldSetting: not to be called without window!" );
2635 DBG_ASSERT( _rxModel.is(), "DbListBox::implAdjustGenericFieldSetting: invalid model!" );
2636 if ( m_pWindow && _rxModel.is() )
2638 sal_Int16 nLines = getINT16( _rxModel->getPropertyValue( FM_PROP_LINECOUNT ) );
2639 weld::ComboBox& rComboBox = static_cast<ListBoxControl*>(m_pWindow.get())->get_widget();
2640 rComboBox.set_max_drop_down_rows(nLines);
2644 CellControllerRef DbListBox::CreateController() const
2646 return new ListBoxCellController(static_cast<ListBoxControl*>(m_pWindow.get()));
2649 OUString DbListBox::GetFormatText(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
2651 OUString sText;
2652 if ( _rxField.is() )
2656 sText = _rxField->getString();
2657 if ( m_bBound )
2659 sal_Int32 nPos = ::comphelper::findValue( m_aValueList, sText );
2660 if ( nPos != -1 )
2661 sText = static_cast<svt::ListBoxControl*>(m_pWindow.get())->get_widget().get_text(nPos);
2662 else
2663 sText.clear();
2666 catch( const Exception& )
2668 DBG_UNHANDLED_EXCEPTION("svx");
2671 return sText;
2674 void DbListBox::UpdateFromField(const Reference< css::sdb::XColumn >& _rxField, const Reference< XNumberFormatter >& xFormatter)
2676 OUString sFormattedText( GetFormatText( _rxField, xFormatter ) );
2677 weld::ComboBox& rComboBox = static_cast<ListBoxControl*>(m_pWindow.get())->get_widget();
2678 if (!sFormattedText.isEmpty())
2679 rComboBox.set_active_text(sFormattedText);
2680 else
2681 rComboBox.set_active(-1);
2684 void DbListBox::updateFromModel( Reference< XPropertySet > _rxModel )
2686 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbListBox::updateFromModel: invalid call!" );
2688 Sequence< sal_Int16 > aSelection;
2689 _rxModel->getPropertyValue( FM_PROP_SELECT_SEQ ) >>= aSelection;
2691 sal_Int16 nSelection = -1;
2692 if ( aSelection.hasElements() )
2693 nSelection = aSelection[ 0 ];
2695 ListBoxControl* pControl = static_cast<ListBoxControl*>(m_pWindow.get());
2696 weld::ComboBox& rComboBox = pControl->get_widget();
2698 int nOldActive = rComboBox.get_active();
2699 if (nSelection >= 0 && nSelection < rComboBox.get_count())
2700 rComboBox.set_active(nSelection);
2701 else
2702 rComboBox.set_active(-1);
2704 if (nOldActive != rComboBox.get_active())
2705 pControl->TriggerAuxModify();
2708 bool DbListBox::commitControl()
2710 Any aVal;
2711 Sequence<sal_Int16> aSelectSeq;
2712 weld::ComboBox& rComboBox = static_cast<ListBoxControl*>(m_pWindow.get())->get_widget();
2713 auto nActive = rComboBox.get_active();
2714 if (nActive != -1)
2716 aSelectSeq.realloc(1);
2717 *aSelectSeq.getArray() = static_cast<sal_Int16>(nActive);
2719 aVal <<= aSelectSeq;
2720 m_rColumn.getModel()->setPropertyValue(FM_PROP_SELECT_SEQ, aVal);
2721 return true;
2724 DbFilterField::DbFilterField(const Reference< XComponentContext >& rxContext,DbGridColumn& _rColumn)
2725 :DbCellControl(_rColumn)
2726 ,OSQLParserClient(rxContext)
2727 ,m_nControlClass(css::form::FormComponentType::TEXTFIELD)
2728 ,m_bFilterList(false)
2729 ,m_bFilterListFilled(false)
2732 setAlignedController( false );
2735 DbFilterField::~DbFilterField()
2737 if (m_nControlClass == css::form::FormComponentType::CHECKBOX)
2738 static_cast<CheckBoxControl*>(m_pWindow.get())->SetToggleHdl(Link<weld::CheckButton&,void>());
2742 void DbFilterField::PaintCell(OutputDevice& rDev, const tools::Rectangle& rRect)
2744 static const DrawTextFlags nStyle = DrawTextFlags::Clip | DrawTextFlags::VCenter | DrawTextFlags::Left;
2745 switch (m_nControlClass)
2747 case FormComponentType::CHECKBOX:
2749 // center the checkbox within the space available
2750 CheckBoxControl* pControl = static_cast<CheckBoxControl*>(m_pPainter.get());
2751 Size aBoxSize = pControl->GetBox().get_preferred_size();
2752 tools::Rectangle aRect(Point(rRect.Left() + ((rRect.GetWidth() - aBoxSize.Width()) / 2),
2753 rRect.Top() + ((rRect.GetHeight() - aBoxSize.Height()) / 2)),
2754 aBoxSize);
2756 DbCellControl::PaintCell(rDev, aRect);
2757 break;
2759 case FormComponentType::LISTBOX:
2760 rDev.DrawText(rRect, static_cast<ListBoxControl*>(m_pWindow.get())->get_widget().get_active_text(), nStyle);
2761 break;
2762 default:
2763 rDev.DrawText(rRect, m_aText, nStyle);
2767 void DbFilterField::SetList(const Any& rItems, bool bComboBox)
2769 css::uno::Sequence<OUString> aTest;
2770 rItems >>= aTest;
2771 if (!aTest.hasElements())
2772 return;
2774 if (bComboBox)
2776 ComboBoxControl* pField = static_cast<ComboBoxControl*>(m_pWindow.get());
2777 weld::ComboBox& rComboBox = pField->get_widget();
2778 for (const OUString& rString : aTest)
2779 rComboBox.append_text(rString);
2781 else
2783 ListBoxControl* pField = static_cast<ListBoxControl*>(m_pWindow.get());
2784 weld::ComboBox& rFieldBox = pField->get_widget();
2785 for (const OUString& rString : aTest)
2786 rFieldBox.append_text(rString);
2788 m_rColumn.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ) >>= m_aValueList;
2792 void DbFilterField::CreateControl(BrowserDataWin* pParent, const Reference< css::beans::XPropertySet >& xModel)
2794 switch (m_nControlClass)
2796 case css::form::FormComponentType::CHECKBOX:
2797 m_pWindow = VclPtr<CheckBoxControl>::Create(pParent);
2798 m_pWindow->SetPaintTransparent( true );
2799 static_cast<CheckBoxControl*>(m_pWindow.get())->SetToggleHdl(LINK(this, DbFilterField, OnToggle));
2801 m_pPainter = VclPtr<CheckBoxControl>::Create(pParent);
2802 m_pPainter->SetPaintTransparent( true );
2803 m_pPainter->SetBackground();
2804 break;
2805 case css::form::FormComponentType::LISTBOX:
2807 m_pWindow = VclPtr<ListBoxControl>::Create(pParent);
2808 Any aItems = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST);
2809 SetList(aItems, false);
2810 } break;
2811 case css::form::FormComponentType::COMBOBOX:
2813 m_pWindow = VclPtr<ComboBoxControl>::Create(pParent);
2815 AllSettings aSettings = m_pWindow->GetSettings();
2816 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2817 aStyleSettings.SetSelectionOptions(
2818 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2819 aSettings.SetStyleSettings(aStyleSettings);
2820 m_pWindow->SetSettings(aSettings, true);
2822 if (!m_bFilterList)
2824 Any aItems = xModel->getPropertyValue(FM_PROP_STRINGITEMLIST);
2825 SetList(aItems, true);
2828 } break;
2829 default:
2831 m_pWindow = VclPtr<EditControl>::Create(pParent);
2832 AllSettings aSettings = m_pWindow->GetSettings();
2833 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2834 aStyleSettings.SetSelectionOptions(
2835 aStyleSettings.GetSelectionOptions() | SelectionOptions::ShowFirst);
2836 aSettings.SetStyleSettings(aStyleSettings);
2837 m_pWindow->SetSettings(aSettings, true);
2842 void DbFilterField::Init(BrowserDataWin& rParent, const Reference< XRowSet >& xCursor)
2844 Reference< css::beans::XPropertySet > xModel(m_rColumn.getModel());
2845 m_rColumn.SetAlignment(css::awt::TextAlign::LEFT);
2847 if (xModel.is())
2849 m_bFilterList = ::comphelper::hasProperty(FM_PROP_FILTERPROPOSAL, xModel) && ::comphelper::getBOOL(xModel->getPropertyValue(FM_PROP_FILTERPROPOSAL));
2850 if (m_bFilterList)
2851 m_nControlClass = css::form::FormComponentType::COMBOBOX;
2852 else
2854 sal_Int16 nClassId = ::comphelper::getINT16(xModel->getPropertyValue(FM_PROP_CLASSID));
2855 switch (nClassId)
2857 case FormComponentType::CHECKBOX:
2858 case FormComponentType::LISTBOX:
2859 case FormComponentType::COMBOBOX:
2860 m_nControlClass = nClassId;
2861 break;
2862 default:
2863 if (m_bFilterList)
2864 m_nControlClass = FormComponentType::COMBOBOX;
2865 else
2866 m_nControlClass = FormComponentType::TEXTFIELD;
2871 CreateControl( &rParent, xModel );
2872 DbCellControl::Init( rParent, xCursor );
2874 // filter cells are never readonly
2875 m_pWindow->SetEditableReadOnly(false);
2878 CellControllerRef DbFilterField::CreateController() const
2880 CellControllerRef xController;
2881 switch (m_nControlClass)
2883 case css::form::FormComponentType::CHECKBOX:
2884 xController = new CheckBoxCellController(static_cast<CheckBoxControl*>(m_pWindow.get()));
2885 break;
2886 case css::form::FormComponentType::LISTBOX:
2887 xController = new ListBoxCellController(static_cast<ListBoxControl*>(m_pWindow.get()));
2888 break;
2889 case css::form::FormComponentType::COMBOBOX:
2890 xController = new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2891 break;
2892 default:
2893 if (m_bFilterList)
2894 xController = new ComboBoxCellController(static_cast<ComboBoxControl*>(m_pWindow.get()));
2895 else
2896 xController = new EditCellController(static_cast<EditControlBase*>(m_pWindow.get()));
2898 return xController;
2901 void DbFilterField::updateFromModel( Reference< XPropertySet > _rxModel )
2903 OSL_ENSURE( _rxModel.is() && m_pWindow, "DbFilterField::updateFromModel: invalid call!" );
2905 OSL_FAIL( "DbFilterField::updateFromModel: not implemented yet (how the hell did you reach this?)!" );
2906 // TODO: implement this.
2907 // remember: updateFromModel should be some kind of opposite of commitControl
2910 bool DbFilterField::commitControl()
2912 OUString aText(m_aText);
2913 switch (m_nControlClass)
2915 case css::form::FormComponentType::CHECKBOX:
2916 return true;
2917 case css::form::FormComponentType::LISTBOX:
2919 aText.clear();
2920 weld::ComboBox& rComboBox = static_cast<svt::ListBoxControl*>(m_pWindow.get())->get_widget();
2921 auto nActive = rComboBox.get_active();
2922 if (nActive != -1)
2924 sal_Int16 nPos = static_cast<sal_Int16>(nActive);
2925 if ( ( nPos >= 0 ) && ( nPos < m_aValueList.getLength() ) )
2926 aText = m_aValueList.getConstArray()[nPos];
2929 if (m_aText != aText)
2931 m_aText = aText;
2932 m_aCommitLink.Call(*this);
2934 return true;
2936 case css::form::FormComponentType::COMBOBOX:
2938 aText = static_cast<ComboBoxControl*>(m_pWindow.get())->get_widget().get_active_text();
2939 break;
2941 default:
2943 aText = static_cast<EditControlBase*>(m_pWindow.get())->get_widget().get_text();
2944 break;
2948 if (m_aText != aText)
2950 // check the text with the SQL-Parser
2951 OUString aNewText(comphelper::string::stripEnd(aText, ' '));
2952 if (!aNewText.isEmpty())
2954 OUString aErrorMsg;
2955 Reference< XNumberFormatter > xNumberFormatter(m_rColumn.GetParent().getNumberFormatter());
2957 std::unique_ptr< OSQLParseNode > pParseNode = predicateTree(aErrorMsg, aNewText,xNumberFormatter, m_rColumn.GetField());
2958 if (pParseNode != nullptr)
2960 OUString aPreparedText;
2962 css::lang::Locale aAppLocale = Application::GetSettings().GetUILanguageTag().getLocale();
2964 Reference< XRowSet > xDataSourceRowSet(
2965 Reference< XInterface >(*m_rColumn.GetParent().getDataSource()), UNO_QUERY);
2966 Reference< XConnection > xConnection(getConnection(xDataSourceRowSet));
2968 pParseNode->parseNodeToPredicateStr(aPreparedText,
2969 xConnection,
2970 xNumberFormatter,
2971 m_rColumn.GetField(),
2972 OUString(),
2973 aAppLocale,
2974 u"."_ustr,
2975 getParseContext());
2976 m_aText = aPreparedText;
2978 else
2981 SQLException aError(aErrorMsg, {}, {}, 0, {});
2982 displayException(aError, VCLUnoHelper::GetInterface(m_pWindow->GetParent()));
2983 // TODO: transport the title
2985 return false;
2988 else
2989 m_aText = aText;
2991 m_pWindow->SetText(m_aText);
2992 m_aCommitLink.Call(*this);
2994 return true;
2998 void DbFilterField::SetText(const OUString& rText)
3000 m_aText = rText;
3001 switch (m_nControlClass)
3003 case css::form::FormComponentType::CHECKBOX:
3005 TriState eState;
3006 if (rText == "1")
3007 eState = TRISTATE_TRUE;
3008 else if (rText == "0")
3009 eState = TRISTATE_FALSE;
3010 else
3011 eState = TRISTATE_INDET;
3013 static_cast<CheckBoxControl*>(m_pWindow.get())->SetState(eState);
3014 static_cast<CheckBoxControl*>(m_pPainter.get())->SetState(eState);
3015 } break;
3016 case css::form::FormComponentType::LISTBOX:
3018 sal_Int32 nPos = ::comphelper::findValue(m_aValueList, m_aText);
3019 static_cast<ListBoxControl*>(m_pWindow.get())->get_widget().set_active(nPos);
3020 } break;
3021 case css::form::FormComponentType::COMBOBOX:
3023 static_cast<ComboBoxControl*>(m_pWindow.get())->get_widget().set_entry_text(m_aText);
3024 break;
3026 default:
3028 static_cast<EditControlBase*>(m_pWindow.get())->get_widget().set_text(m_aText);
3029 break;
3033 // now force a repaint on the window
3034 m_rColumn.GetParent().RowModified(0);
3038 void DbFilterField::Update()
3040 // should we fill the combobox with a filter proposal?
3041 if (!m_bFilterList || m_bFilterListFilled)
3042 return;
3044 m_bFilterListFilled = true;
3045 Reference< css::beans::XPropertySet > xField = m_rColumn.GetField();
3046 if (!xField.is())
3047 return;
3049 OUString aName;
3050 xField->getPropertyValue(FM_PROP_NAME) >>= aName;
3052 // the columnmodel
3053 Reference< css::container::XChild > xModelAsChild(m_rColumn.getModel(), UNO_QUERY);
3054 // the grid model
3055 xModelAsChild.set(xModelAsChild->getParent(),UNO_QUERY);
3056 Reference< XRowSet > xForm(xModelAsChild->getParent(), UNO_QUERY);
3057 if (!xForm.is())
3058 return;
3060 Reference<XPropertySet> xFormProp(xForm,UNO_QUERY);
3061 Reference< XTablesSupplier > xSupTab;
3062 xFormProp->getPropertyValue(u"SingleSelectQueryComposer"_ustr) >>= xSupTab;
3064 Reference< XConnection > xConnection(getConnection(xForm));
3065 if (!xSupTab.is())
3066 return;
3068 // search the field
3069 Reference< XColumnsSupplier > xSupCol(xSupTab,UNO_QUERY);
3070 Reference< css::container::XNameAccess > xFieldNames = xSupCol->getColumns();
3071 if (!xFieldNames->hasByName(aName))
3072 return;
3074 Reference< css::container::XNameAccess > xTablesNames = xSupTab->getTables();
3075 Reference< css::beans::XPropertySet > xComposerFieldAsSet(xFieldNames->getByName(aName),UNO_QUERY);
3077 if (!xComposerFieldAsSet.is() ||
3078 !::comphelper::hasProperty(FM_PROP_TABLENAME, xComposerFieldAsSet) ||
3079 !::comphelper::hasProperty(FM_PROP_FIELDSOURCE, xComposerFieldAsSet))
3080 return;
3082 OUString aFieldName;
3083 OUString aTableName;
3084 xComposerFieldAsSet->getPropertyValue(FM_PROP_FIELDSOURCE) >>= aFieldName;
3085 xComposerFieldAsSet->getPropertyValue(FM_PROP_TABLENAME) >>= aTableName;
3087 // no possibility to create a select statement
3088 // looking for the complete table name
3089 if (!xTablesNames->hasByName(aTableName))
3090 return;
3092 // build a statement and send as query;
3093 // Access to the connection
3094 Reference< XStatement > xStatement;
3095 Reference< XResultSet > xListCursor;
3096 Reference< css::sdb::XColumn > xDataField;
3100 Reference< XDatabaseMetaData > xMeta = xConnection->getMetaData();
3102 OUString aQuote(xMeta->getIdentifierQuoteString());
3103 OUStringBuffer aStatement("SELECT DISTINCT "
3104 + quoteName(aQuote, aName));
3105 if (!aFieldName.isEmpty() && aName != aFieldName)
3107 aStatement.append(" AS "
3108 + quoteName(aQuote, aFieldName));
3111 aStatement.append(" FROM ");
3113 Reference< XPropertySet > xTableNameAccess(xTablesNames->getByName(aTableName), UNO_QUERY_THROW);
3114 aStatement.append(composeTableNameForSelect(xConnection, xTableNameAccess));
3116 xStatement = xConnection->createStatement();
3117 Reference< css::beans::XPropertySet > xStatementProps(xStatement, UNO_QUERY);
3118 xStatementProps->setPropertyValue(FM_PROP_ESCAPE_PROCESSING, Any(true));
3120 xListCursor = xStatement->executeQuery(aStatement.makeStringAndClear());
3122 Reference< css::sdbcx::XColumnsSupplier > xSupplyCols(xListCursor, UNO_QUERY);
3123 Reference< css::container::XIndexAccess > xFields(xSupplyCols->getColumns(), UNO_QUERY);
3124 xDataField.set(xFields->getByIndex(0), css::uno::UNO_QUERY);
3125 if (!xDataField.is())
3126 return;
3128 catch(const Exception&)
3130 ::comphelper::disposeComponent(xStatement);
3131 return;
3134 sal_Int16 i = 0;
3135 ::std::vector< OUString > aStringList;
3136 aStringList.reserve(16);
3137 OUString aStr;
3138 css::util::Date aNullDate = m_rColumn.GetParent().getNullDate();
3139 sal_Int32 nFormatKey = m_rColumn.GetKey();
3140 Reference< XNumberFormatter > xFormatter = m_rColumn.GetParent().getNumberFormatter();
3141 sal_Int16 nKeyType = ::comphelper::getNumberFormatType(xFormatter->getNumberFormatsSupplier()->getNumberFormats(), nFormatKey);
3143 while (!xListCursor->isAfterLast() && i++ < SHRT_MAX) // max number of entries
3145 aStr = getFormattedValue(xDataField, xFormatter, aNullDate, nFormatKey, nKeyType);
3146 aStringList.push_back(aStr);
3147 (void)xListCursor->next();
3150 ComboBoxControl* pField = static_cast<ComboBoxControl*>(m_pWindow.get());
3151 weld::ComboBox& rComboBox = pField->get_widget();
3152 // filling the entries for the combobox
3153 for (const auto& rString : aStringList)
3154 rComboBox.append_text(rString);
3157 OUString DbFilterField::GetFormatText(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/, const Color** /*ppColor*/)
3159 return OUString();
3162 void DbFilterField::UpdateFromField(const Reference< XColumn >& /*_rxField*/, const Reference< XNumberFormatter >& /*xFormatter*/)
3164 OSL_FAIL( "DbFilterField::UpdateFromField: cannot update a filter control from a field!" );
3167 IMPL_LINK_NOARG(DbFilterField, OnToggle, weld::CheckButton&, void)
3169 TriState eState = static_cast<CheckBoxControl*>(m_pWindow.get())->GetState();
3170 OUStringBuffer aTextBuf;
3172 Reference< XRowSet > xDataSourceRowSet(
3173 Reference< XInterface >(*m_rColumn.GetParent().getDataSource()), UNO_QUERY);
3174 Reference< XConnection > xConnection(getConnection(xDataSourceRowSet));
3175 const sal_Int32 nBooleanComparisonMode = ::dbtools::DatabaseMetaData( xConnection ).getBooleanComparisonMode();
3177 switch (eState)
3179 case TRISTATE_TRUE:
3180 ::dbtools::getBooleanComparisonPredicate(u"", true, nBooleanComparisonMode, aTextBuf);
3181 break;
3182 case TRISTATE_FALSE:
3183 ::dbtools::getBooleanComparisonPredicate(u"", false, nBooleanComparisonMode, aTextBuf);
3184 break;
3185 case TRISTATE_INDET:
3186 break;
3189 const OUString aText(aTextBuf.makeStringAndClear());
3191 if (m_aText != aText)
3193 m_aText = aText;
3194 m_aCommitLink.Call(*this);
3198 FmXGridCell::FmXGridCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> _pControl )
3199 :OComponentHelper(m_aMutex)
3200 ,m_pColumn(pColumn)
3201 ,m_pCellControl( std::move(_pControl) )
3202 ,m_aWindowListeners( m_aMutex )
3203 ,m_aFocusListeners( m_aMutex )
3204 ,m_aKeyListeners( m_aMutex )
3205 ,m_aMouseListeners( m_aMutex )
3206 ,m_aMouseMotionListeners( m_aMutex )
3210 void FmXGridCell::init()
3212 svt::ControlBase* pEventWindow( getEventWindow() );
3213 if ( pEventWindow )
3215 pEventWindow->SetFocusInHdl(LINK( this, FmXGridCell, OnFocusGained));
3216 pEventWindow->SetFocusOutHdl(LINK( this, FmXGridCell, OnFocusLost));
3217 pEventWindow->SetMousePressHdl(LINK( this, FmXGridCell, OnMousePress));
3218 pEventWindow->SetMouseReleaseHdl(LINK( this, FmXGridCell, OnMouseRelease));
3219 pEventWindow->SetMouseMoveHdl(LINK( this, FmXGridCell, OnMouseMove));
3220 pEventWindow->SetKeyInputHdl( LINK( this, FmXGridCell, OnKeyInput) );
3221 pEventWindow->SetKeyReleaseHdl( LINK( this, FmXGridCell, OnKeyRelease) );
3225 svt::ControlBase* FmXGridCell::getEventWindow() const
3227 if ( m_pCellControl )
3228 return &m_pCellControl->GetWindow();
3229 return nullptr;
3232 FmXGridCell::~FmXGridCell()
3234 if (!OComponentHelper::rBHelper.bDisposed)
3236 acquire();
3237 dispose();
3242 void FmXGridCell::SetTextLineColor()
3244 if (m_pCellControl)
3245 m_pCellControl->SetTextLineColor();
3248 void FmXGridCell::SetTextLineColor(const Color& _rColor)
3250 if (m_pCellControl)
3251 m_pCellControl->SetTextLineColor(_rColor);
3254 // XTypeProvider
3256 Sequence< Type > SAL_CALL FmXGridCell::getTypes( )
3258 Sequence< uno::Type > aTypes = ::comphelper::concatSequences(
3259 ::cppu::OComponentHelper::getTypes(),
3260 FmXGridCell_Base::getTypes()
3262 if ( m_pCellControl )
3263 aTypes = ::comphelper::concatSequences(
3264 aTypes,
3265 FmXGridCell_WindowBase::getTypes()
3267 return aTypes;
3271 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXGridCell )
3273 // OComponentHelper
3275 void FmXGridCell::disposing()
3277 lang::EventObject aEvent( *this );
3278 m_aWindowListeners.disposeAndClear( aEvent );
3279 m_aFocusListeners.disposeAndClear( aEvent );
3280 m_aKeyListeners.disposeAndClear( aEvent );
3281 m_aMouseListeners.disposeAndClear( aEvent );
3282 m_aMouseMotionListeners.disposeAndClear( aEvent );
3284 OComponentHelper::disposing();
3285 m_pColumn = nullptr;
3286 m_pCellControl.reset();
3290 Any SAL_CALL FmXGridCell::queryAggregation( const css::uno::Type& _rType )
3292 Any aReturn = OComponentHelper::queryAggregation( _rType );
3294 if ( !aReturn.hasValue() )
3295 aReturn = FmXGridCell_Base::queryInterface( _rType );
3297 if ( !aReturn.hasValue() && ( m_pCellControl != nullptr ) )
3298 aReturn = FmXGridCell_WindowBase::queryInterface( _rType );
3300 return aReturn;
3303 // css::awt::XControl
3305 Reference< XInterface > FmXGridCell::getContext()
3307 return Reference< XInterface > ();
3311 Reference< css::awt::XControlModel > FmXGridCell::getModel()
3313 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3314 return Reference< css::awt::XControlModel > (m_pColumn->getModel(), UNO_QUERY);
3317 // css::form::XBoundControl
3319 sal_Bool FmXGridCell::getLock()
3321 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3322 return m_pColumn->isLocked();
3326 void FmXGridCell::setLock(sal_Bool _bLock)
3328 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3329 if (getLock() == _bLock)
3330 return;
3331 else
3333 ::osl::MutexGuard aGuard(m_aMutex);
3334 m_pColumn->setLock(_bLock);
3339 void SAL_CALL FmXGridCell::setPosSize( ::sal_Int32, ::sal_Int32, ::sal_Int32, ::sal_Int32, ::sal_Int16 )
3341 OSL_FAIL( "FmXGridCell::setPosSize: not implemented" );
3342 // not allowed to tamper with this for a grid cell
3346 awt::Rectangle SAL_CALL FmXGridCell::getPosSize( )
3348 OSL_FAIL( "FmXGridCell::getPosSize: not implemented" );
3349 return awt::Rectangle();
3353 void SAL_CALL FmXGridCell::setVisible( sal_Bool )
3355 OSL_FAIL( "FmXGridCell::setVisible: not implemented" );
3356 // not allowed to tamper with this for a grid cell
3360 void SAL_CALL FmXGridCell::setEnable( sal_Bool )
3362 OSL_FAIL( "FmXGridCell::setEnable: not implemented" );
3363 // not allowed to tamper with this for a grid cell
3367 void SAL_CALL FmXGridCell::setFocus( )
3369 OSL_FAIL( "FmXGridCell::setFocus: not implemented" );
3370 // not allowed to tamper with this for a grid cell
3374 void SAL_CALL FmXGridCell::addWindowListener( const Reference< awt::XWindowListener >& _rxListener )
3376 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3377 m_aWindowListeners.addInterface( _rxListener );
3381 void SAL_CALL FmXGridCell::removeWindowListener( const Reference< awt::XWindowListener >& _rxListener )
3383 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3384 m_aWindowListeners.removeInterface( _rxListener );
3388 void SAL_CALL FmXGridCell::addFocusListener( const Reference< awt::XFocusListener >& _rxListener )
3390 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3391 m_aFocusListeners.addInterface( _rxListener );
3395 void SAL_CALL FmXGridCell::removeFocusListener( const Reference< awt::XFocusListener >& _rxListener )
3397 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3398 m_aFocusListeners.removeInterface( _rxListener );
3402 void SAL_CALL FmXGridCell::addKeyListener( const Reference< awt::XKeyListener >& _rxListener )
3404 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3405 m_aKeyListeners.addInterface( _rxListener );
3409 void SAL_CALL FmXGridCell::removeKeyListener( const Reference< awt::XKeyListener >& _rxListener )
3411 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3412 m_aKeyListeners.removeInterface( _rxListener );
3416 void SAL_CALL FmXGridCell::addMouseListener( const Reference< awt::XMouseListener >& _rxListener )
3418 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3419 m_aMouseListeners.addInterface( _rxListener );
3423 void SAL_CALL FmXGridCell::removeMouseListener( const Reference< awt::XMouseListener >& _rxListener )
3425 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3426 m_aMouseListeners.removeInterface( _rxListener );
3430 void SAL_CALL FmXGridCell::addMouseMotionListener( const Reference< awt::XMouseMotionListener >& _rxListener )
3432 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3433 m_aMouseMotionListeners.addInterface( _rxListener );
3437 void SAL_CALL FmXGridCell::removeMouseMotionListener( const Reference< awt::XMouseMotionListener >& _rxListener )
3439 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3440 m_aMouseMotionListeners.removeInterface( _rxListener );
3443 void SAL_CALL FmXGridCell::addPaintListener( const Reference< awt::XPaintListener >& )
3445 OSL_FAIL( "FmXGridCell::addPaintListener: not implemented" );
3448 void SAL_CALL FmXGridCell::removePaintListener( const Reference< awt::XPaintListener >& )
3450 OSL_FAIL( "FmXGridCell::removePaintListener: not implemented" );
3453 void FmXGridCell::onFocusGained( const awt::FocusEvent& _rEvent )
3455 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3456 m_aFocusListeners.notifyEach( &awt::XFocusListener::focusGained, _rEvent );
3459 void FmXGridCell::onFocusLost( const awt::FocusEvent& _rEvent )
3461 checkDisposed(OComponentHelper::rBHelper.bDisposed);
3462 m_aFocusListeners.notifyEach( &awt::XFocusListener::focusLost, _rEvent );
3465 IMPL_LINK_NOARG(FmXGridCell, OnFocusGained, LinkParamNone*, void)
3467 if (!m_aFocusListeners.getLength())
3468 return;
3470 awt::FocusEvent aEvent;
3471 aEvent.Source = *this;
3472 aEvent.Temporary = false;
3474 onFocusGained(aEvent);
3477 IMPL_LINK_NOARG(FmXGridCell, OnFocusLost, LinkParamNone*, void)
3479 if (!m_aFocusListeners.getLength())
3480 return;
3482 awt::FocusEvent aEvent;
3483 aEvent.Source = *this;
3484 aEvent.Temporary = false;
3486 onFocusLost(aEvent);
3489 IMPL_LINK(FmXGridCell, OnMousePress, const MouseEvent&, rEventData, void)
3491 if (!m_aMouseListeners.getLength())
3492 return;
3494 awt::MouseEvent aEvent(VCLUnoHelper::createMouseEvent(rEventData, *this));
3495 m_aMouseListeners.notifyEach(&awt::XMouseListener::mousePressed, aEvent);
3498 IMPL_LINK(FmXGridCell, OnMouseRelease, const MouseEvent&, rEventData, void)
3500 if (!m_aMouseListeners.getLength())
3501 return;
3503 awt::MouseEvent aEvent(VCLUnoHelper::createMouseEvent(rEventData, *this));
3504 m_aMouseListeners.notifyEach(&awt::XMouseListener::mouseReleased, aEvent);
3507 IMPL_LINK(FmXGridCell, OnMouseMove, const MouseEvent&, rMouseEvent, void)
3509 if ( rMouseEvent.IsEnterWindow() || rMouseEvent.IsLeaveWindow() )
3511 if ( m_aMouseListeners.getLength() != 0 )
3513 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
3514 m_aMouseListeners.notifyEach( rMouseEvent.IsEnterWindow() ? &awt::XMouseListener::mouseEntered: &awt::XMouseListener::mouseExited, aEvent );
3517 else if ( !rMouseEvent.IsEnterWindow() && !rMouseEvent.IsLeaveWindow() )
3519 if ( m_aMouseMotionListeners.getLength() != 0 )
3521 awt::MouseEvent aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent, *this ) );
3522 aEvent.ClickCount = 0;
3523 const bool bSimpleMove = bool( rMouseEvent.GetMode() & MouseEventModifiers::SIMPLEMOVE );
3524 m_aMouseMotionListeners.notifyEach( bSimpleMove ? &awt::XMouseMotionListener::mouseMoved: &awt::XMouseMotionListener::mouseDragged, aEvent );
3529 IMPL_LINK(FmXGridCell, OnKeyInput, const KeyEvent&, rEventData, void)
3531 if (!m_aKeyListeners.getLength())
3532 return;
3534 awt::KeyEvent aEvent(VCLUnoHelper::createKeyEvent(rEventData, *this));
3535 m_aKeyListeners.notifyEach(&awt::XKeyListener::keyPressed, aEvent);
3538 IMPL_LINK(FmXGridCell, OnKeyRelease, const KeyEvent&, rEventData, void)
3540 if (!m_aKeyListeners.getLength())
3541 return;
3543 awt::KeyEvent aEvent(VCLUnoHelper::createKeyEvent(rEventData, *this));
3544 m_aKeyListeners.notifyEach(&awt::XKeyListener::keyReleased, aEvent);
3547 void FmXDataCell::PaintFieldToCell(OutputDevice& rDev, const tools::Rectangle& rRect,
3548 const Reference< css::sdb::XColumn >& _rxField,
3549 const Reference< XNumberFormatter >& xFormatter)
3551 m_pCellControl->PaintFieldToCell( rDev, rRect, _rxField, xFormatter );
3554 void FmXDataCell::UpdateFromColumn()
3556 Reference< css::sdb::XColumn > xField(m_pColumn->GetCurrentFieldValue());
3557 if (xField.is())
3558 m_pCellControl->UpdateFromField(xField, m_pColumn->GetParent().getNumberFormatter());
3561 FmXTextCell::FmXTextCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
3562 :FmXDataCell( pColumn, std::move(pControl) )
3563 ,m_bIsMultiLineText(false)
3567 void FmXTextCell::PaintFieldToCell(OutputDevice& rDev,
3568 const tools::Rectangle& rRect,
3569 const Reference< css::sdb::XColumn >& _rxField,
3570 const Reference< XNumberFormatter >& xFormatter)
3572 DrawTextFlags nStyle = DrawTextFlags::Clip;
3573 if ( ( rDev.GetOutDevType() == OUTDEV_WINDOW ) && !rDev.GetOwnerWindow()->IsEnabled() )
3574 nStyle |= DrawTextFlags::Disable;
3576 switch (m_pColumn->GetAlignment())
3578 case css::awt::TextAlign::RIGHT:
3579 nStyle |= DrawTextFlags::Right;
3580 break;
3581 case css::awt::TextAlign::CENTER:
3582 nStyle |= DrawTextFlags::Center;
3583 break;
3584 default:
3585 nStyle |= DrawTextFlags::Left;
3588 if (!m_bIsMultiLineText)
3589 nStyle |= DrawTextFlags::VCenter;
3590 else
3591 nStyle |= DrawTextFlags::Top | DrawTextFlags::MultiLine | DrawTextFlags::WordBreak;
3595 const Color* pColor = nullptr;
3596 OUString aText = GetText(_rxField, xFormatter, &pColor);
3597 if (pColor != nullptr)
3599 Color aOldTextColor( rDev.GetTextColor() );
3600 rDev.SetTextColor( *pColor );
3601 rDev.DrawText(rRect, aText, nStyle);
3602 rDev.SetTextColor( aOldTextColor );
3604 else
3605 rDev.DrawText(rRect, aText, nStyle);
3607 catch (const Exception&)
3609 TOOLS_WARN_EXCEPTION("svx.fmcomp", "PaintFieldToCell");
3613 FmXEditCell::FmXEditCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
3614 :FmXTextCell( pColumn, std::move(pControl) )
3615 ,m_aTextListeners(m_aMutex)
3616 ,m_aChangeListeners( m_aMutex )
3617 ,m_pEditImplementation( nullptr )
3618 ,m_bOwnEditImplementation( false )
3621 DbTextField* pTextField = dynamic_cast<DbTextField*>( m_pCellControl.get() );
3622 if ( pTextField )
3625 m_pEditImplementation = pTextField->GetEditImplementation();
3626 m_bIsMultiLineText = pTextField->IsMultiLineEdit();
3628 else
3630 m_pEditImplementation = new EntryImplementation(static_cast<EditControlBase&>(m_pCellControl->GetWindow()));
3631 m_bOwnEditImplementation = true;
3633 m_pEditImplementation->SetAuxModifyHdl(LINK(this, FmXEditCell, ModifyHdl));
3636 FmXEditCell::~FmXEditCell()
3638 if (!OComponentHelper::rBHelper.bDisposed)
3640 acquire();
3641 dispose();
3645 // OComponentHelper
3646 void FmXEditCell::disposing()
3648 css::lang::EventObject aEvt(*this);
3649 m_aTextListeners.disposeAndClear(aEvt);
3650 m_aChangeListeners.disposeAndClear(aEvt);
3652 if ( m_bOwnEditImplementation )
3653 delete m_pEditImplementation;
3654 m_pEditImplementation = nullptr;
3656 FmXDataCell::disposing();
3659 Any SAL_CALL FmXEditCell::queryAggregation( const css::uno::Type& _rType )
3661 Any aReturn = FmXTextCell::queryAggregation( _rType );
3663 if ( !aReturn.hasValue() )
3664 aReturn = FmXEditCell_Base::queryInterface( _rType );
3666 return aReturn;
3669 Sequence< css::uno::Type > SAL_CALL FmXEditCell::getTypes( )
3671 return ::comphelper::concatSequences(
3672 FmXTextCell::getTypes(),
3673 FmXEditCell_Base::getTypes()
3677 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXEditCell )
3679 // css::awt::XTextComponent
3680 void SAL_CALL FmXEditCell::addTextListener(const Reference< css::awt::XTextListener >& l)
3682 m_aTextListeners.addInterface( l );
3686 void SAL_CALL FmXEditCell::removeTextListener(const Reference< css::awt::XTextListener >& l)
3688 m_aTextListeners.removeInterface( l );
3691 void SAL_CALL FmXEditCell::setText( const OUString& aText )
3693 ::osl::MutexGuard aGuard( m_aMutex );
3695 if ( m_pEditImplementation )
3697 m_pEditImplementation->SetText( aText );
3699 // In Java, a textChanged is fired as well; not in VCL.
3700 // css::awt::Toolkit must be Java-compliant...
3701 onTextChanged();
3705 void SAL_CALL FmXEditCell::insertText(const css::awt::Selection& rSel, const OUString& aText)
3707 ::osl::MutexGuard aGuard( m_aMutex );
3709 if ( m_pEditImplementation )
3711 m_pEditImplementation->SetSelection( Selection( rSel.Min, rSel.Max ) );
3712 m_pEditImplementation->ReplaceSelected( aText );
3716 OUString SAL_CALL FmXEditCell::getText()
3718 ::osl::MutexGuard aGuard( m_aMutex );
3720 OUString aText;
3721 if ( m_pEditImplementation )
3723 if ( m_pEditImplementation->GetControl().IsVisible() && m_pColumn->GetParent().getDisplaySynchron())
3725 // if the display isn't sync with the cursor we can't ask the edit field
3726 LineEnd eLineEndFormat = getModelLineEndSetting( m_pColumn->getModel() );
3727 aText = m_pEditImplementation->GetText( eLineEndFormat );
3729 else
3731 Reference< css::sdb::XColumn > xField(m_pColumn->GetCurrentFieldValue());
3732 if (xField.is())
3733 aText = GetText(xField, m_pColumn->GetParent().getNumberFormatter());
3736 return aText;
3739 OUString SAL_CALL FmXEditCell::getSelectedText()
3741 ::osl::MutexGuard aGuard( m_aMutex );
3743 OUString aText;
3744 if ( m_pEditImplementation )
3746 LineEnd eLineEndFormat = m_pColumn ? getModelLineEndSetting( m_pColumn->getModel() ) : LINEEND_LF;
3747 aText = m_pEditImplementation->GetSelected( eLineEndFormat );
3749 return aText;
3752 void SAL_CALL FmXEditCell::setSelection( const css::awt::Selection& aSelection )
3754 ::osl::MutexGuard aGuard( m_aMutex );
3756 if ( m_pEditImplementation )
3757 m_pEditImplementation->SetSelection( Selection( aSelection.Min, aSelection.Max ) );
3760 css::awt::Selection SAL_CALL FmXEditCell::getSelection()
3762 ::osl::MutexGuard aGuard( m_aMutex );
3764 Selection aSel;
3765 if ( m_pEditImplementation )
3766 aSel = m_pEditImplementation->GetSelection();
3768 return css::awt::Selection(aSel.Min(), aSel.Max());
3771 sal_Bool SAL_CALL FmXEditCell::isEditable()
3773 ::osl::MutexGuard aGuard( m_aMutex );
3775 return m_pEditImplementation && !m_pEditImplementation->IsReadOnly() && m_pEditImplementation->GetControl().IsEnabled();
3778 void SAL_CALL FmXEditCell::setEditable( sal_Bool bEditable )
3780 ::osl::MutexGuard aGuard( m_aMutex );
3782 if ( m_pEditImplementation )
3783 m_pEditImplementation->SetReadOnly( !bEditable );
3786 sal_Int16 SAL_CALL FmXEditCell::getMaxTextLen()
3788 ::osl::MutexGuard aGuard( m_aMutex );
3790 return m_pEditImplementation ? m_pEditImplementation->GetMaxTextLen() : 0;
3793 void SAL_CALL FmXEditCell::setMaxTextLen( sal_Int16 nLen )
3795 ::osl::MutexGuard aGuard( m_aMutex );
3797 if ( m_pEditImplementation )
3798 m_pEditImplementation->SetMaxTextLen( nLen );
3801 void SAL_CALL FmXEditCell::addChangeListener( const Reference< form::XChangeListener >& Listener )
3803 m_aChangeListeners.addInterface( Listener );
3806 void SAL_CALL FmXEditCell::removeChangeListener( const Reference< form::XChangeListener >& Listener )
3808 m_aChangeListeners.removeInterface( Listener );
3811 void FmXEditCell::onTextChanged()
3813 css::awt::TextEvent aEvent;
3814 aEvent.Source = *this;
3815 m_aTextListeners.notifyEach( &awt::XTextListener::textChanged, aEvent );
3818 void FmXEditCell::onFocusGained( const awt::FocusEvent& _rEvent )
3820 FmXTextCell::onFocusGained( _rEvent );
3821 m_sValueOnEnter = getText();
3824 void FmXEditCell::onFocusLost( const awt::FocusEvent& _rEvent )
3826 FmXTextCell::onFocusLost( _rEvent );
3828 if ( getText() != m_sValueOnEnter )
3830 lang::EventObject aEvent( *this );
3831 m_aChangeListeners.notifyEach( &XChangeListener::changed, aEvent );
3835 IMPL_LINK_NOARG(FmXEditCell, ModifyHdl, LinkParamNone*, void)
3837 if (m_aTextListeners.getLength())
3838 onTextChanged();
3841 FmXCheckBoxCell::FmXCheckBoxCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
3842 :FmXDataCell( pColumn, std::move(pControl) )
3843 ,m_aItemListeners(m_aMutex)
3844 ,m_aActionListeners( m_aMutex )
3845 ,m_pBox( & static_cast< CheckBoxControl& >( m_pCellControl->GetWindow() ) )
3847 m_pBox->SetAuxModifyHdl(LINK(this, FmXCheckBoxCell, ModifyHdl));
3850 FmXCheckBoxCell::~FmXCheckBoxCell()
3852 if (!OComponentHelper::rBHelper.bDisposed)
3854 acquire();
3855 dispose();
3859 // OComponentHelper
3860 void FmXCheckBoxCell::disposing()
3862 css::lang::EventObject aEvt(*this);
3863 m_aItemListeners.disposeAndClear(aEvt);
3864 m_aActionListeners.disposeAndClear(aEvt);
3866 m_pBox->SetToggleHdl(Link<weld::CheckButton&,void>());
3867 m_pBox = nullptr;
3869 FmXDataCell::disposing();
3873 Any SAL_CALL FmXCheckBoxCell::queryAggregation( const css::uno::Type& _rType )
3875 Any aReturn = FmXDataCell::queryAggregation( _rType );
3877 if ( !aReturn.hasValue() )
3878 aReturn = FmXCheckBoxCell_Base::queryInterface( _rType );
3880 return aReturn;
3884 Sequence< css::uno::Type > SAL_CALL FmXCheckBoxCell::getTypes( )
3886 return ::comphelper::concatSequences(
3887 FmXDataCell::getTypes(),
3888 FmXCheckBoxCell_Base::getTypes()
3893 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXCheckBoxCell )
3895 void SAL_CALL FmXCheckBoxCell::addItemListener( const Reference< css::awt::XItemListener >& l )
3897 m_aItemListeners.addInterface( l );
3900 void SAL_CALL FmXCheckBoxCell::removeItemListener( const Reference< css::awt::XItemListener >& l )
3902 m_aItemListeners.removeInterface( l );
3905 void SAL_CALL FmXCheckBoxCell::setState( sal_Int16 n )
3907 ::osl::MutexGuard aGuard( m_aMutex );
3909 if (m_pBox)
3911 UpdateFromColumn();
3912 m_pBox->SetState( static_cast<TriState>(n) );
3916 sal_Int16 SAL_CALL FmXCheckBoxCell::getState()
3918 ::osl::MutexGuard aGuard( m_aMutex );
3920 if (m_pBox)
3922 UpdateFromColumn();
3923 return static_cast<sal_Int16>(m_pBox->GetState());
3925 return TRISTATE_INDET;
3928 void SAL_CALL FmXCheckBoxCell::enableTriState(sal_Bool b)
3930 ::osl::MutexGuard aGuard( m_aMutex );
3932 if (m_pBox)
3933 m_pBox->EnableTriState( b );
3936 void SAL_CALL FmXCheckBoxCell::addActionListener( const Reference< awt::XActionListener >& Listener )
3938 m_aActionListeners.addInterface( Listener );
3942 void SAL_CALL FmXCheckBoxCell::removeActionListener( const Reference< awt::XActionListener >& Listener )
3944 m_aActionListeners.removeInterface( Listener );
3947 void SAL_CALL FmXCheckBoxCell::setLabel( const OUString& Label )
3949 SolarMutexGuard aGuard;
3950 if ( m_pColumn )
3952 DbGridControl& rGrid( m_pColumn->GetParent() );
3953 rGrid.SetColumnTitle( rGrid.GetColumnId( m_pColumn->GetFieldPos() ), Label );
3957 void SAL_CALL FmXCheckBoxCell::setActionCommand( const OUString& Command )
3959 m_aActionCommand = Command;
3962 IMPL_LINK_NOARG(FmXCheckBoxCell, ModifyHdl, LinkParamNone*, void)
3964 // check boxes are to be committed immediately (this holds for ordinary check box controls in
3965 // documents, and this must hold for check boxes in grid columns, too
3966 // 91210 - 22.08.2001 - frank.schoenheit@sun.com
3967 m_pCellControl->Commit();
3969 Reference< XWindow > xKeepAlive( this );
3970 if ( m_aItemListeners.getLength() && m_pBox )
3972 awt::ItemEvent aEvent;
3973 aEvent.Source = *this;
3974 aEvent.Highlighted = 0;
3975 aEvent.Selected = m_pBox->GetState();
3976 m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
3978 if ( m_aActionListeners.getLength() )
3980 awt::ActionEvent aEvent;
3981 aEvent.Source = *this;
3982 aEvent.ActionCommand = m_aActionCommand;
3983 m_aActionListeners.notifyEach( &awt::XActionListener::actionPerformed, aEvent );
3987 FmXListBoxCell::FmXListBoxCell(DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl)
3988 : FmXTextCell(pColumn, std::move(pControl))
3989 , m_aItemListeners(m_aMutex)
3990 , m_aActionListeners(m_aMutex)
3991 , m_pBox(&static_cast<svt::ListBoxControl&>(m_pCellControl->GetWindow()))
3992 , m_nLines(Application::GetSettings().GetStyleSettings().GetListBoxMaximumLineCount())
3993 , m_bMulti(false)
3995 m_pBox->SetAuxModifyHdl(LINK(this, FmXListBoxCell, ChangedHdl));
3998 FmXListBoxCell::~FmXListBoxCell()
4000 if (!OComponentHelper::rBHelper.bDisposed)
4002 acquire();
4003 dispose();
4007 // OComponentHelper
4008 void FmXListBoxCell::disposing()
4010 css::lang::EventObject aEvt(*this);
4011 m_aItemListeners.disposeAndClear(aEvt);
4012 m_aActionListeners.disposeAndClear(aEvt);
4014 m_pBox->SetAuxModifyHdl(Link<bool,void>());
4015 m_pBox = nullptr;
4017 FmXTextCell::disposing();
4020 Any SAL_CALL FmXListBoxCell::queryAggregation( const css::uno::Type& _rType )
4022 Any aReturn = FmXTextCell::queryAggregation(_rType);
4024 if ( !aReturn.hasValue() )
4025 aReturn = FmXListBoxCell_Base::queryInterface( _rType );
4027 return aReturn;
4030 Sequence< css::uno::Type > SAL_CALL FmXListBoxCell::getTypes( )
4032 return ::comphelper::concatSequences(
4033 FmXTextCell::getTypes(),
4034 FmXListBoxCell_Base::getTypes()
4038 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXListBoxCell )
4040 void SAL_CALL FmXListBoxCell::addItemListener(const Reference< css::awt::XItemListener >& l)
4042 m_aItemListeners.addInterface( l );
4045 void SAL_CALL FmXListBoxCell::removeItemListener(const Reference< css::awt::XItemListener >& l)
4047 m_aItemListeners.removeInterface( l );
4050 void SAL_CALL FmXListBoxCell::addActionListener(const Reference< css::awt::XActionListener >& l)
4052 m_aActionListeners.addInterface( l );
4055 void SAL_CALL FmXListBoxCell::removeActionListener(const Reference< css::awt::XActionListener >& l)
4057 m_aActionListeners.removeInterface( l );
4060 void SAL_CALL FmXListBoxCell::addItem(const OUString& aItem, sal_Int16 nPos)
4062 ::osl::MutexGuard aGuard( m_aMutex );
4063 if (m_pBox)
4065 weld::ComboBox& rBox = m_pBox->get_widget();
4066 rBox.insert_text(nPos, aItem);
4070 void SAL_CALL FmXListBoxCell::addItems(const css::uno::Sequence<OUString>& aItems, sal_Int16 nPos)
4072 ::osl::MutexGuard aGuard( m_aMutex );
4073 if (m_pBox)
4075 weld::ComboBox& rBox = m_pBox->get_widget();
4076 sal_uInt16 nP = nPos;
4077 for ( const auto& rItem : aItems )
4079 rBox.insert_text(nP, rItem);
4080 if ( nPos != -1 ) // Not if 0xFFFF, because LIST_APPEND
4081 nP++;
4086 void SAL_CALL FmXListBoxCell::removeItems(sal_Int16 nPos, sal_Int16 nCount)
4088 ::osl::MutexGuard aGuard( m_aMutex );
4089 if ( m_pBox )
4091 weld::ComboBox& rBox = m_pBox->get_widget();
4092 for ( sal_uInt16 n = nCount; n; )
4093 rBox.remove( nPos + (--n) );
4097 sal_Int16 SAL_CALL FmXListBoxCell::getItemCount()
4099 ::osl::MutexGuard aGuard( m_aMutex );
4100 if (!m_pBox)
4101 return 0;
4102 weld::ComboBox& rBox = m_pBox->get_widget();
4103 return rBox.get_count();
4106 OUString SAL_CALL FmXListBoxCell::getItem(sal_Int16 nPos)
4108 ::osl::MutexGuard aGuard( m_aMutex );
4109 if (!m_pBox)
4110 return OUString();
4111 weld::ComboBox& rBox = m_pBox->get_widget();
4112 return rBox.get_text(nPos);
4115 css::uno::Sequence<OUString> SAL_CALL FmXListBoxCell::getItems()
4117 ::osl::MutexGuard aGuard( m_aMutex );
4119 css::uno::Sequence<OUString> aSeq;
4120 if (m_pBox)
4122 weld::ComboBox& rBox = m_pBox->get_widget();
4123 const sal_Int32 nEntries = rBox.get_count();
4124 aSeq = css::uno::Sequence<OUString>( nEntries );
4125 for ( sal_Int32 n = nEntries; n; )
4127 --n;
4128 aSeq.getArray()[n] = rBox.get_text( n );
4131 return aSeq;
4134 sal_Int16 SAL_CALL FmXListBoxCell::getSelectedItemPos()
4136 ::osl::MutexGuard aGuard( m_aMutex );
4137 if (m_pBox)
4139 UpdateFromColumn();
4140 weld::ComboBox& rBox = m_pBox->get_widget();
4141 int nPos = rBox.get_active();
4142 if (nPos == -1)
4143 return -1; // nothing selected
4144 if (nPos > SHRT_MAX || nPos < SHRT_MIN)
4145 throw std::out_of_range("awt::XListBox::getSelectedItemPos can only return a short");
4146 return nPos;
4148 return -1; // nothing selected
4151 Sequence< sal_Int16 > SAL_CALL FmXListBoxCell::getSelectedItemsPos()
4153 ::osl::MutexGuard aGuard( m_aMutex );
4155 if (m_pBox)
4157 UpdateFromColumn();
4158 weld::ComboBox& rBox = m_pBox->get_widget();
4159 auto nActive = rBox.get_active();
4160 if (nActive != -1)
4162 return { o3tl::narrowing<short>(nActive) };
4165 return {};
4168 OUString SAL_CALL FmXListBoxCell::getSelectedItem()
4170 ::osl::MutexGuard aGuard( m_aMutex );
4172 OUString aItem;
4174 if (m_pBox)
4176 UpdateFromColumn();
4177 weld::ComboBox& rBox = m_pBox->get_widget();
4178 aItem = rBox.get_active_text();
4181 return aItem;
4184 css::uno::Sequence<OUString> SAL_CALL FmXListBoxCell::getSelectedItems()
4186 ::osl::MutexGuard aGuard( m_aMutex );
4188 if (m_pBox)
4190 UpdateFromColumn();
4191 weld::ComboBox& rBox = m_pBox->get_widget();
4192 auto nActive = rBox.get_active();
4193 if (nActive != -1)
4195 return { rBox.get_text(nActive) };
4198 return {};
4201 void SAL_CALL FmXListBoxCell::selectItemPos(sal_Int16 nPos, sal_Bool bSelect)
4203 ::osl::MutexGuard aGuard( m_aMutex );
4205 if (m_pBox)
4207 weld::ComboBox& rBox = m_pBox->get_widget();
4208 if (bSelect)
4209 rBox.set_active(nPos);
4210 else if (nPos == rBox.get_active())
4211 rBox.set_active(-1);
4215 void SAL_CALL FmXListBoxCell::selectItemsPos(const Sequence< sal_Int16 >& aPositions, sal_Bool bSelect)
4217 ::osl::MutexGuard aGuard( m_aMutex );
4219 if (m_pBox)
4221 weld::ComboBox& rBox = m_pBox->get_widget();
4222 for ( sal_uInt16 n = static_cast<sal_uInt16>(aPositions.getLength()); n; )
4224 auto nPos = static_cast<sal_uInt16>(aPositions.getConstArray()[--n]);
4225 if (bSelect)
4226 rBox.set_active(nPos);
4227 else if (nPos == rBox.get_active())
4228 rBox.set_active(-1);
4233 void SAL_CALL FmXListBoxCell::selectItem(const OUString& aItem, sal_Bool bSelect)
4235 ::osl::MutexGuard aGuard( m_aMutex );
4237 if (m_pBox)
4239 weld::ComboBox& rBox = m_pBox->get_widget();
4240 auto nPos = rBox.find_text(aItem);
4241 if (bSelect)
4242 rBox.set_active(nPos);
4243 else if (nPos == rBox.get_active())
4244 rBox.set_active(-1);
4248 sal_Bool SAL_CALL FmXListBoxCell::isMutipleMode()
4250 ::osl::MutexGuard aGuard( m_aMutex );
4252 return m_bMulti;
4255 void SAL_CALL FmXListBoxCell::setMultipleMode(sal_Bool bMulti)
4257 ::osl::MutexGuard aGuard( m_aMutex );
4259 m_bMulti = bMulti;
4262 sal_Int16 SAL_CALL FmXListBoxCell::getDropDownLineCount()
4264 ::osl::MutexGuard aGuard( m_aMutex );
4265 return m_nLines;
4268 void SAL_CALL FmXListBoxCell::setDropDownLineCount(sal_Int16 nLines)
4270 ::osl::MutexGuard aGuard( m_aMutex );
4272 m_nLines = nLines; // just store it to return it
4275 void SAL_CALL FmXListBoxCell::makeVisible(sal_Int16 /*nEntry*/)
4279 IMPL_LINK(FmXListBoxCell, ChangedHdl, bool, bInteractive, void)
4281 if (!m_pBox)
4282 return;
4284 weld::ComboBox& rBox = m_pBox->get_widget();
4286 if (bInteractive && !rBox.changed_by_direct_pick())
4287 return;
4289 OnDoubleClick();
4291 css::awt::ItemEvent aEvent;
4292 aEvent.Source = *this;
4293 aEvent.Highlighted = 0;
4295 // with multiple selection 0xFFFF, otherwise the ID
4296 aEvent.Selected = (rBox.get_active() != -1 )
4297 ? rBox.get_active() : 0xFFFF;
4299 m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4302 void FmXListBoxCell::OnDoubleClick()
4304 css::awt::ActionEvent aEvent;
4305 aEvent.Source = *this;
4306 weld::ComboBox& rBox = m_pBox->get_widget();
4307 aEvent.ActionCommand = rBox.get_active_text();
4309 m_aActionListeners.notifyEach( &css::awt::XActionListener::actionPerformed, aEvent );
4312 FmXComboBoxCell::FmXComboBoxCell( DbGridColumn* pColumn, std::unique_ptr<DbCellControl> pControl )
4313 :FmXTextCell( pColumn, std::move(pControl) )
4314 ,m_aItemListeners( m_aMutex )
4315 ,m_aActionListeners( m_aMutex )
4316 ,m_pComboBox(&static_cast<ComboBoxControl&>(m_pCellControl->GetWindow()))
4317 ,m_nLines(Application::GetSettings().GetStyleSettings().GetListBoxMaximumLineCount())
4319 m_pComboBox->SetAuxModifyHdl(LINK(this, FmXComboBoxCell, ChangedHdl));
4322 FmXComboBoxCell::~FmXComboBoxCell()
4324 if ( !OComponentHelper::rBHelper.bDisposed )
4326 acquire();
4327 dispose();
4332 void FmXComboBoxCell::disposing()
4334 css::lang::EventObject aEvt(*this);
4335 m_aItemListeners.disposeAndClear(aEvt);
4336 m_aActionListeners.disposeAndClear(aEvt);
4338 m_pComboBox->SetAuxModifyHdl(Link<bool,void>());
4339 m_pComboBox = nullptr;
4341 FmXTextCell::disposing();
4344 Any SAL_CALL FmXComboBoxCell::queryAggregation( const css::uno::Type& _rType )
4346 Any aReturn = FmXTextCell::queryAggregation(_rType);
4348 if ( !aReturn.hasValue() )
4349 aReturn = FmXComboBoxCell_Base::queryInterface( _rType );
4351 return aReturn;
4354 Sequence< Type > SAL_CALL FmXComboBoxCell::getTypes( )
4356 return ::comphelper::concatSequences(
4357 FmXTextCell::getTypes(),
4358 FmXComboBoxCell_Base::getTypes()
4362 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXComboBoxCell )
4364 void SAL_CALL FmXComboBoxCell::addItemListener(const Reference< awt::XItemListener >& l)
4366 m_aItemListeners.addInterface( l );
4369 void SAL_CALL FmXComboBoxCell::removeItemListener(const Reference< awt::XItemListener >& l)
4371 m_aItemListeners.removeInterface( l );
4374 void SAL_CALL FmXComboBoxCell::addActionListener(const Reference< awt::XActionListener >& l)
4376 m_aActionListeners.addInterface( l );
4380 void SAL_CALL FmXComboBoxCell::removeActionListener(const Reference< awt::XActionListener >& l)
4382 m_aActionListeners.removeInterface( l );
4385 void SAL_CALL FmXComboBoxCell::addItem( const OUString& Item, sal_Int16 Pos )
4387 ::osl::MutexGuard aGuard( m_aMutex );
4388 if (!m_pComboBox)
4389 return;
4390 weld::ComboBox& rBox = m_pComboBox->get_widget();
4391 rBox.insert_text(Pos, Item);
4394 void SAL_CALL FmXComboBoxCell::addItems( const Sequence< OUString >& Items, sal_Int16 Pos )
4396 ::osl::MutexGuard aGuard( m_aMutex );
4397 if (!m_pComboBox)
4398 return;
4399 weld::ComboBox& rBox = m_pComboBox->get_widget();
4400 sal_uInt16 nP = Pos;
4401 for ( const auto& rItem : Items )
4403 rBox.insert_text(nP, rItem);
4404 if ( Pos != -1 )
4405 nP++;
4409 void SAL_CALL FmXComboBoxCell::removeItems( sal_Int16 Pos, sal_Int16 Count )
4411 ::osl::MutexGuard aGuard( m_aMutex );
4412 if (!m_pComboBox)
4413 return;
4414 weld::ComboBox& rBox = m_pComboBox->get_widget();
4415 for ( sal_uInt16 n = Count; n; )
4416 rBox.remove( Pos + (--n) );
4419 sal_Int16 SAL_CALL FmXComboBoxCell::getItemCount()
4421 ::osl::MutexGuard aGuard( m_aMutex );
4422 if (!m_pComboBox)
4423 return 0;
4424 weld::ComboBox& rBox = m_pComboBox->get_widget();
4425 return rBox.get_count();
4428 OUString SAL_CALL FmXComboBoxCell::getItem( sal_Int16 Pos )
4430 ::osl::MutexGuard aGuard( m_aMutex );
4431 if (!m_pComboBox)
4432 return OUString();
4433 weld::ComboBox& rBox = m_pComboBox->get_widget();
4434 return rBox.get_text(Pos);
4437 Sequence< OUString > SAL_CALL FmXComboBoxCell::getItems()
4439 ::osl::MutexGuard aGuard( m_aMutex );
4441 Sequence< OUString > aItems;
4442 if (m_pComboBox)
4444 weld::ComboBox& rBox = m_pComboBox->get_widget();
4445 const sal_Int32 nEntries = rBox.get_count();
4446 aItems.realloc( nEntries );
4447 OUString* pItem = aItems.getArray();
4448 for ( sal_Int32 n=0; n<nEntries; ++n, ++pItem )
4449 *pItem = rBox.get_text(n);
4451 return aItems;
4454 sal_Int16 SAL_CALL FmXComboBoxCell::getDropDownLineCount()
4456 ::osl::MutexGuard aGuard( m_aMutex );
4457 return m_nLines;
4460 void SAL_CALL FmXComboBoxCell::setDropDownLineCount(sal_Int16 nLines)
4462 ::osl::MutexGuard aGuard( m_aMutex );
4463 m_nLines = nLines; // just store it to return it
4466 IMPL_LINK(FmXComboBoxCell, ChangedHdl, bool, bInteractive, void)
4468 if (!m_pComboBox)
4469 return;
4471 weld::ComboBox& rComboBox = m_pComboBox->get_widget();
4473 if (bInteractive && !rComboBox.changed_by_direct_pick())
4474 return;
4476 awt::ItemEvent aEvent;
4477 aEvent.Source = *this;
4478 aEvent.Highlighted = 0;
4480 // with invalid selection 0xFFFF, otherwise the position
4481 aEvent.Selected = ( rComboBox.get_active() != -1 )
4482 ? rComboBox.get_active()
4483 : 0xFFFF;
4484 m_aItemListeners.notifyEach( &awt::XItemListener::itemStateChanged, aEvent );
4487 FmXFilterCell::FmXFilterCell(DbGridColumn* pColumn, std::unique_ptr<DbFilterField> pControl )
4488 :FmXGridCell( pColumn, std::move(pControl) )
4489 ,m_aTextListeners(m_aMutex)
4491 static_cast<DbFilterField*>(m_pCellControl.get())->SetCommitHdl( LINK( this, FmXFilterCell, OnCommit ) );
4494 FmXFilterCell::~FmXFilterCell()
4496 if (!OComponentHelper::rBHelper.bDisposed)
4498 acquire();
4499 dispose();
4504 void FmXFilterCell::PaintCell( OutputDevice& rDev, const tools::Rectangle& rRect )
4506 static_cast< DbFilterField* >( m_pCellControl.get() )->PaintCell( rDev, rRect );
4509 // OComponentHelper
4511 void FmXFilterCell::disposing()
4513 css::lang::EventObject aEvt(*this);
4514 m_aTextListeners.disposeAndClear(aEvt);
4516 static_cast<DbFilterField*>(m_pCellControl.get())->SetCommitHdl(Link<DbFilterField&,void>());
4518 FmXGridCell::disposing();
4522 Any SAL_CALL FmXFilterCell::queryAggregation( const css::uno::Type& _rType )
4524 Any aReturn = FmXGridCell::queryAggregation(_rType);
4526 if ( !aReturn.hasValue() )
4527 aReturn = FmXFilterCell_Base::queryInterface( _rType );
4529 return aReturn;
4533 Sequence< css::uno::Type > SAL_CALL FmXFilterCell::getTypes( )
4535 return ::comphelper::concatSequences(
4536 FmXGridCell::getTypes(),
4537 FmXFilterCell_Base::getTypes()
4542 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXFilterCell )
4544 // css::awt::XTextComponent
4546 void SAL_CALL FmXFilterCell::addTextListener(const Reference< css::awt::XTextListener >& l)
4548 m_aTextListeners.addInterface( l );
4552 void SAL_CALL FmXFilterCell::removeTextListener(const Reference< css::awt::XTextListener >& l)
4554 m_aTextListeners.removeInterface( l );
4557 void SAL_CALL FmXFilterCell::setText( const OUString& aText )
4559 ::osl::MutexGuard aGuard( m_aMutex );
4560 static_cast<DbFilterField*>(m_pCellControl.get())->SetText(aText);
4563 void SAL_CALL FmXFilterCell::insertText( const css::awt::Selection& /*rSel*/, const OUString& /*aText*/ )
4567 OUString SAL_CALL FmXFilterCell::getText()
4569 ::osl::MutexGuard aGuard( m_aMutex );
4570 return static_cast<DbFilterField*>(m_pCellControl.get())->GetText();
4573 OUString SAL_CALL FmXFilterCell::getSelectedText()
4575 return getText();
4578 void SAL_CALL FmXFilterCell::setSelection( const css::awt::Selection& /*aSelection*/ )
4582 css::awt::Selection SAL_CALL FmXFilterCell::getSelection()
4584 return css::awt::Selection();
4587 sal_Bool SAL_CALL FmXFilterCell::isEditable()
4589 return true;
4592 void SAL_CALL FmXFilterCell::setEditable( sal_Bool /*bEditable*/ )
4596 sal_Int16 SAL_CALL FmXFilterCell::getMaxTextLen()
4598 return 0;
4601 void SAL_CALL FmXFilterCell::setMaxTextLen( sal_Int16 /*nLen*/ )
4605 IMPL_LINK_NOARG(FmXFilterCell, OnCommit, DbFilterField&, void)
4607 css::awt::TextEvent aEvt;
4608 aEvt.Source = *this;
4609 m_aTextListeners.notifyEach( &css::awt::XTextListener::textChanged, aEvt );
4612 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */