1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
22 #include <sal/macros.h>
23 #include <sal/log.hxx>
25 #include <svx/strings.hrc>
26 #include <svx/fmtools.hxx>
27 #include <gridcell.hxx>
28 #include <gridcols.hxx>
29 #include <sdbdatacolumn.hxx>
31 #include <com/sun/star/awt/LineEndFormat.hpp>
32 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
33 #include <com/sun/star/awt/VisualEffect.hpp>
34 #include <com/sun/star/container/XChild.hpp>
35 #include <com/sun/star/container/XIndexAccess.hpp>
36 #include <com/sun/star/container/XNamed.hpp>
37 #include <com/sun/star/form/FormComponentType.hpp>
38 #include <com/sun/star/form/XBoundComponent.hpp>
39 #include <com/sun/star/script/XEventAttacherManager.hpp>
40 #include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
41 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
42 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
43 #include <com/sun/star/sdbc/ColumnValue.hpp>
44 #include <com/sun/star/sdbc/DataType.hpp>
45 #include <com/sun/star/sdbc/SQLException.hpp>
46 #include <com/sun/star/sdbc/XRowSet.hpp>
47 #include <com/sun/star/sdbc/XStatement.hpp>
48 #include <com/sun/star/util/NumberFormat.hpp>
49 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
50 #include <com/sun/star/util/XNumberFormatter.hpp>
51 #include <com/sun/star/util/Time.hpp>
52 #include <com/sun/star/util/Date.hpp>
54 #include <comphelper/numbers.hxx>
55 #include <comphelper/property.hxx>
56 #include <comphelper/servicehelper.hxx>
57 #include <comphelper/string.hxx>
58 #include <comphelper/types.hxx>
59 #include <connectivity/formattedcolumnvalue.hxx>
60 #include <cppuhelper/typeprovider.hxx>
61 #include <i18nlangtag/lang.h>
63 #include <rtl/math.hxx>
64 #include <svtools/calendar.hxx>
65 #include <vcl/fmtfield.hxx>
66 #include <svl/numuno.hxx>
67 #include <svl/zforlist.hxx>
68 #include <svx/dialmgr.hxx>
69 #include <toolkit/helper/vclunohelper.hxx>
70 #include <tools/debug.hxx>
71 #include <tools/diagnose_ex.h>
72 #include <vcl/longcurr.hxx>
73 #include <vcl/settings.hxx>
74 #include <vcl/svapp.hxx>
75 #include <connectivity/dbtools.hxx>
76 #include <connectivity/dbconversion.hxx>
77 #include <connectivity/sqlnode.hxx>
81 using namespace ::connectivity
;
82 using namespace ::svxform
;
83 using namespace ::comphelper
;
84 using namespace ::svt
;
85 using namespace ::com::sun::star
;
86 using namespace ::com::sun::star::uno
;
87 using namespace ::com::sun::star::sdbc
;
88 using namespace ::com::sun::star::sdbcx
;
89 using namespace ::com::sun::star::sdb
;
90 using namespace ::com::sun::star::beans
;
91 using namespace ::com::sun::star::form
;
92 using namespace ::dbtools::DBTypeConversion
;
93 using namespace ::dbtools
;
95 using ::com::sun::star::util::XNumberFormatter
;
97 const char INVALIDTEXT
[] = "###";
98 const char OBJECTTEXT
[] = "<OBJECT>";
105 LineEnd
getModelLineEndSetting( const Reference
< XPropertySet
>& _rxModel
)
107 LineEnd eFormat
= LINEEND_LF
;
111 sal_Int16 nLineEndFormat
= awt::LineEndFormat::LINE_FEED
;
113 Reference
< XPropertySetInfo
> xPSI
;
115 xPSI
= _rxModel
->getPropertySetInfo();
117 OSL_ENSURE( xPSI
.is(), "getModelLineEndSetting: invalid column model!" );
118 if ( xPSI
.is() && xPSI
->hasPropertyByName( FM_PROP_LINEENDFORMAT
) )
120 OSL_VERIFY( _rxModel
->getPropertyValue( FM_PROP_LINEENDFORMAT
) >>= nLineEndFormat
);
122 switch ( nLineEndFormat
)
124 case awt::LineEndFormat::CARRIAGE_RETURN
: eFormat
= LINEEND_CR
; break;
125 case awt::LineEndFormat::LINE_FEED
: eFormat
= LINEEND_LF
; break;
126 case awt::LineEndFormat::CARRIAGE_RETURN_LINE_FEED
: eFormat
= LINEEND_CRLF
; break;
128 OSL_FAIL( "getModelLineEndSetting: what's this?" );
132 catch( const Exception
& )
134 DBG_UNHANDLED_EXCEPTION("svx");
135 OSL_FAIL( "getModelLineEndSetting: caught an exception!" );
145 CellControllerRef
DbGridColumn::s_xEmptyController
;
148 void DbGridColumn::CreateControl(sal_Int32 _nFieldPos
, const Reference
< css::beans::XPropertySet
>& xField
, sal_Int32 nTypeId
)
152 m_nTypeId
= static_cast<sal_Int16
>(nTypeId
);
153 if (xField
!= m_xField
)
157 xField
->getPropertyValue(FM_PROP_FORMATKEY
) >>= m_nFormatKey
;
158 m_nFieldPos
= static_cast<sal_Int16
>(_nFieldPos
);
159 m_bReadOnly
= ::comphelper::getBOOL(xField
->getPropertyValue(FM_PROP_ISREADONLY
));
160 m_bAutoValue
= ::comphelper::getBOOL(xField
->getPropertyValue(FM_PROP_AUTOINCREMENT
));
161 m_nFieldType
= static_cast<sal_Int16
>(::comphelper::getINT32(xField
->getPropertyValue(FM_PROP_FIELDTYPE
)));
163 switch (m_nFieldType
)
167 case DataType::TIMESTAMP
:
169 case DataType::BOOLEAN
:
170 case DataType::TINYINT
:
171 case DataType::SMALLINT
:
172 case DataType::INTEGER
:
173 case DataType::BIGINT
:
174 case DataType::FLOAT
:
176 case DataType::DOUBLE
:
177 case DataType::NUMERIC
:
178 case DataType::DECIMAL
:
179 m_nAlign
= css::awt::TextAlign::RIGHT
;
183 m_nAlign
= css::awt::TextAlign::LEFT
;
188 std::unique_ptr
<DbCellControl
> pCellControl
;
189 if (m_rParent
.IsFilterMode())
191 pCellControl
.reset(new DbFilterField(m_rParent
.getContext(),*this));
198 case TYPE_CHECKBOX
: pCellControl
.reset(new DbCheckBox(*this)); break;
199 case TYPE_COMBOBOX
: pCellControl
.reset(new DbComboBox(*this)); break;
200 case TYPE_CURRENCYFIELD
: pCellControl
.reset(new DbCurrencyField(*this)); break;
201 case TYPE_DATEFIELD
: pCellControl
.reset(new DbDateField(*this)); break;
202 case TYPE_LISTBOX
: pCellControl
.reset(new DbListBox(*this)); break;
203 case TYPE_NUMERICFIELD
: pCellControl
.reset(new DbNumericField(*this)); break;
204 case TYPE_PATTERNFIELD
: pCellControl
.reset(new DbPatternField( *this, m_rParent
.getContext() )); break;
205 case TYPE_TEXTFIELD
: pCellControl
.reset(new DbTextField(*this)); break;
206 case TYPE_TIMEFIELD
: pCellControl
.reset(new DbTimeField(*this)); break;
207 case TYPE_FORMATTEDFIELD
: pCellControl
.reset(new DbFormattedField(*this)); break;
209 OSL_FAIL("DbGridColumn::CreateControl: Unknown Column");
214 Reference
< XRowSet
> xCur
;
215 if (m_rParent
.getDataSource())
216 xCur
.set(Reference
< XInterface
>(*m_rParent
.getDataSource()), UNO_QUERY
);
217 // TODO : the cursor wrapper should use an XRowSet interface, too
219 pCellControl
->Init( m_rParent
.GetDataWindow(), xCur
);
221 // now create the control wrapper
222 auto pTempCellControl
= pCellControl
.get();
223 if (m_rParent
.IsFilterMode())
224 m_pCell
= new FmXFilterCell(this, std::unique_ptr
<DbFilterField
>(static_cast<DbFilterField
*>(pCellControl
.release())));
229 case TYPE_CHECKBOX
: m_pCell
= new FmXCheckBoxCell( this, std::move(pCellControl
) ); break;
230 case TYPE_LISTBOX
: m_pCell
= new FmXListBoxCell( this, std::move(pCellControl
) ); break;
231 case TYPE_COMBOBOX
: m_pCell
= new FmXComboBoxCell( this, std::move(pCellControl
) ); break;
233 m_pCell
= new FmXEditCell( this, std::move(pCellControl
) );
238 impl_toggleScriptManager_nothrow( true );
240 // only if we use have a bound field, we use a controller for displaying the
241 // window in the grid
243 m_xController
= pTempCellControl
->CreateController();
247 void DbGridColumn::impl_toggleScriptManager_nothrow( bool _bAttach
)
251 Reference
< container::XChild
> xChild( m_xModel
, UNO_QUERY_THROW
);
252 Reference
< script::XEventAttacherManager
> xManager( xChild
->getParent(), UNO_QUERY_THROW
);
253 Reference
< container::XIndexAccess
> xContainer( xChild
->getParent(), UNO_QUERY_THROW
);
255 sal_Int32
nIndexInParent( getElementPos( xContainer
, m_xModel
) );
257 Reference
< XInterface
> xCellInterface( *m_pCell
, UNO_QUERY
);
259 xManager
->attach( nIndexInParent
, xCellInterface
, makeAny( xCellInterface
) );
261 xManager
->detach( nIndexInParent
, xCellInterface
);
263 catch( const Exception
& )
265 DBG_UNHANDLED_EXCEPTION("svx");
269 void DbGridColumn::UpdateFromField(const DbGridRow
* pRow
, const Reference
< XNumberFormatter
>& xFormatter
)
271 if (FmXFilterCell
* pCell
= dynamic_cast<FmXFilterCell
*>(m_pCell
.get()))
273 else if (pRow
&& pRow
->IsValid() && m_nFieldPos
>= 0 && m_pCell
.is() && pRow
->HasField(m_nFieldPos
))
275 dynamic_cast<FmXDataCell
&>(*m_pCell
).UpdateFromField( pRow
->GetField( m_nFieldPos
).getColumn(), xFormatter
);
279 bool DbGridColumn::Commit()
282 if (!m_bInSave
&& m_pCell
.is())
285 bResult
= m_pCell
->Commit();
287 // store the data into the model
288 FmXDataCell
* pDataCell
= dynamic_cast<FmXDataCell
*>( m_pCell
.get() );
289 if (bResult
&& pDataCell
)
291 Reference
< css::form::XBoundComponent
> xComp(m_xModel
, UNO_QUERY
);
293 bResult
= xComp
->commit();
301 DbGridColumn::~DbGridColumn()
307 void DbGridColumn::setModel(const css::uno::Reference
< css::beans::XPropertySet
>& _xModel
)
310 impl_toggleScriptManager_nothrow( false );
315 impl_toggleScriptManager_nothrow( true );
319 void DbGridColumn::Clear()
323 impl_toggleScriptManager_nothrow( false );
329 m_xController
= nullptr;
335 m_bAutoValue
= false;
336 m_nFieldType
= DataType::OTHER
;
340 sal_Int16
DbGridColumn::SetAlignment(sal_Int16 _nAlign
)
347 m_xField
->getPropertyValue(FM_PROP_FIELDTYPE
) >>= nType
;
351 case DataType::NUMERIC
:
352 case DataType::DECIMAL
:
353 case DataType::DOUBLE
:
355 case DataType::BIGINT
:
356 case DataType::INTEGER
:
357 case DataType::SMALLINT
:
358 case DataType::TINYINT
:
361 case DataType::TIMESTAMP
:
362 _nAlign
= css::awt::TextAlign::RIGHT
;
365 case DataType::BOOLEAN
:
366 _nAlign
= css::awt::TextAlign::CENTER
;
369 _nAlign
= css::awt::TextAlign::LEFT
;
374 _nAlign
= css::awt::TextAlign::LEFT
;
378 if (m_pCell
.is() && m_pCell
->isAlignedController())
379 m_pCell
->AlignControl(m_nAlign
);
385 sal_Int16
DbGridColumn::SetAlignmentFromModel(sal_Int16 nStandardAlign
)
387 Any
aAlign( m_xModel
->getPropertyValue(FM_PROP_ALIGN
));
388 if (aAlign
.hasValue())
390 sal_Int16 nTest
= sal_Int16();
391 if (aAlign
>>= nTest
)
392 nStandardAlign
= nTest
;
394 return SetAlignment(nStandardAlign
);
398 void DbGridColumn::setLock(bool _bLock
)
400 if (m_bLocked
== _bLock
)
404 // is the column we represent active ?
406 return; // no, it isn't (or at least it shouldn't be ...)
408 if (m_rParent
.GetCurColumnId() == m_nId
)
410 m_rParent
.DeactivateCell();
411 m_rParent
.ActivateCell(m_rParent
.GetCurRow(), m_rParent
.GetCurColumnId());
416 OUString
DbGridColumn::GetCellText(const DbGridRow
* pRow
, const Reference
< XNumberFormatter
>& xFormatter
) const
419 if (m_pCell
.is() && dynamic_cast<const FmXFilterCell
*>( m_pCell
.get() ) != nullptr)
422 if (!pRow
|| !pRow
->IsValid())
424 else if (pRow
->HasField(m_nFieldPos
))
426 aText
= GetCellText( pRow
->GetField( m_nFieldPos
).getColumn(), xFormatter
);
432 OUString
DbGridColumn::GetCellText(const Reference
< css::sdb::XColumn
>& xField
, const Reference
< XNumberFormatter
>& xFormatter
) const
437 FmXTextCell
* pTextCell
= dynamic_cast<FmXTextCell
*>( m_pCell
.get() );
439 aText
= pTextCell
->GetText(xField
, xFormatter
);
447 Reference
< css::sdb::XColumn
> DbGridColumn::GetCurrentFieldValue() const
449 Reference
< css::sdb::XColumn
> xField
;
450 const DbGridRowRef xRow
= m_rParent
.GetCurrentRow();
451 if (xRow
.is() && xRow
->HasField(m_nFieldPos
))
453 xField
= xRow
->GetField(m_nFieldPos
).getColumn();
459 void DbGridColumn::Paint(OutputDevice
& rDev
,
460 const tools::Rectangle
& rRect
,
461 const DbGridRow
* pRow
,
462 const Reference
< XNumberFormatter
>& xFormatter
)
464 bool bEnabled
= ( rDev
.GetOutDevType() != OUTDEV_WINDOW
)
465 || ( static_cast< vcl::Window
& >( rDev
).IsEnabled() );
467 FmXDataCell
* pDataCell
= dynamic_cast<FmXDataCell
*>( m_pCell
.get() );
470 if (!pRow
|| !pRow
->IsValid())
472 DrawTextFlags nStyle
= DrawTextFlags::Clip
| DrawTextFlags::Center
;
474 nStyle
|= DrawTextFlags::Disable
;
476 rDev
.DrawText(rRect
, OUString(INVALIDTEXT
), nStyle
);
478 else if (m_bAutoValue
&& pRow
->IsNew())
480 DrawTextFlags nStyle
= DrawTextFlags::Clip
| DrawTextFlags::VCenter
;
482 nStyle
|= DrawTextFlags::Disable
;
484 switch (GetAlignment())
486 case css::awt::TextAlign::RIGHT
:
487 nStyle
|= DrawTextFlags::Right
;
489 case css::awt::TextAlign::CENTER
:
490 nStyle
|= DrawTextFlags::Center
;
493 nStyle
|= DrawTextFlags::Left
;
496 rDev
.DrawText(rRect
, SvxResId(RID_STR_AUTOFIELD
), nStyle
);
498 else if (pRow
->HasField(m_nFieldPos
))
500 pDataCell
->PaintFieldToCell(rDev
, rRect
, pRow
->GetField( m_nFieldPos
).getColumn(), xFormatter
);
503 else if (!m_pCell
.is())
505 if (!pRow
|| !pRow
->IsValid())
507 DrawTextFlags nStyle
= DrawTextFlags::Clip
| DrawTextFlags::Center
;
509 nStyle
|= DrawTextFlags::Disable
;
511 rDev
.DrawText(rRect
, OUString(INVALIDTEXT
), nStyle
);
513 else if (pRow
->HasField(m_nFieldPos
) && m_bObject
)
515 DrawTextFlags nStyle
= DrawTextFlags::Clip
| DrawTextFlags::Center
;
517 nStyle
|= DrawTextFlags::Disable
;
518 rDev
.DrawText(rRect
, OUString(OBJECTTEXT
), nStyle
);
521 else if ( dynamic_cast<const FmXFilterCell
*>( m_pCell
.get() ) != nullptr )
522 static_cast< FmXFilterCell
* >( m_pCell
.get() )->PaintCell( rDev
, rRect
);
526 void DbGridColumn::ImplInitWindow( vcl::Window
const & rParent
, const InitWindowFacet _eInitWhat
)
529 m_pCell
->ImplInitWindow( rParent
, _eInitWhat
);
536 DbCellControl::DbCellControl( DbGridColumn
& _rColumn
)
537 :OPropertyChangeListener(m_aMutex
)
538 ,m_bTransparent( false )
539 ,m_bAlignedController( true )
540 ,m_bAccessingValueProperty( false )
541 ,m_rColumn( _rColumn
)
542 ,m_pPainter( nullptr )
543 ,m_pWindow( nullptr )
545 Reference
< XPropertySet
> xColModelProps
= _rColumn
.getModel();
546 if ( !xColModelProps
.is() )
549 // if our model's format key changes we want to propagate the new value to our windows
550 m_pModelChangeBroadcaster
= new ::comphelper::OPropertyChangeMultiplexer(this, _rColumn
.getModel());
552 // be listener for some common properties
553 implDoPropertyListening( FM_PROP_READONLY
, false );
554 implDoPropertyListening( FM_PROP_ENABLED
, false );
556 // add as listener for all known "value" properties
557 implDoPropertyListening( FM_PROP_VALUE
, false );
558 implDoPropertyListening( FM_PROP_STATE
, false );
559 implDoPropertyListening( FM_PROP_TEXT
, false );
560 implDoPropertyListening( FM_PROP_EFFECTIVE_VALUE
, false );
561 implDoPropertyListening( FM_PROP_SELECT_SEQ
, false );
562 implDoPropertyListening( FM_PROP_DATE
, false );
563 implDoPropertyListening( FM_PROP_TIME
, false );
565 // be listener at the bound field as well
568 Reference
< XPropertySetInfo
> xPSI( xColModelProps
->getPropertySetInfo(), UNO_SET_THROW
);
569 if ( xPSI
->hasPropertyByName( FM_PROP_BOUNDFIELD
) )
571 Reference
< XPropertySet
> xField
;
572 xColModelProps
->getPropertyValue( FM_PROP_BOUNDFIELD
) >>= xField
;
575 m_pFieldChangeBroadcaster
= new ::comphelper::OPropertyChangeMultiplexer(this, xField
);
576 m_pFieldChangeBroadcaster
->addProperty( FM_PROP_ISREADONLY
);
580 catch( const Exception
& )
582 DBG_UNHANDLED_EXCEPTION("svx");
583 OSL_FAIL( "DbCellControl::doPropertyListening: caught an exception!" );
588 void DbCellControl::implDoPropertyListening(const OUString
& _rPropertyName
, bool _bWarnIfNotExistent
)
592 Reference
< XPropertySet
> xColModelProps
= m_rColumn
.getModel();
593 Reference
< XPropertySetInfo
> xPSI
;
594 if ( xColModelProps
.is() )
595 xPSI
= xColModelProps
->getPropertySetInfo();
597 DBG_ASSERT( !_bWarnIfNotExistent
|| ( xPSI
.is() && xPSI
->hasPropertyByName( _rPropertyName
) ),
598 "DbCellControl::doPropertyListening: no property set info or non-existent property!" );
600 if ( xPSI
.is() && xPSI
->hasPropertyByName( _rPropertyName
) )
601 m_pModelChangeBroadcaster
->addProperty( _rPropertyName
);
603 catch( const Exception
& )
605 DBG_UNHANDLED_EXCEPTION("svx");
606 OSL_FAIL( "DbCellControl::doPropertyListening: caught an exception!" );
611 void DbCellControl::doPropertyListening(const OUString
& _rPropertyName
)
613 implDoPropertyListening( _rPropertyName
, true );
616 static void lcl_clearBroadCaster(rtl::Reference
<::comphelper::OPropertyChangeMultiplexer
>& _pBroadcaster
)
618 if ( _pBroadcaster
.is() )
620 _pBroadcaster
->dispose();
621 _pBroadcaster
.clear();
622 // no delete, this is done implicitly
626 DbCellControl::~DbCellControl()
628 lcl_clearBroadCaster(m_pModelChangeBroadcaster
);
629 lcl_clearBroadCaster(m_pFieldChangeBroadcaster
);
631 m_pWindow
.disposeAndClear();
632 m_pPainter
.disposeAndClear();
635 void DbCellControl::implValuePropertyChanged( )
637 OSL_ENSURE( !isValuePropertyLocked(),
638 "DbCellControl::implValuePropertyChanged: not to be called with the value property locked!" );
642 if ( m_rColumn
.getModel().is() )
643 updateFromModel( m_rColumn
.getModel() );
648 void DbCellControl::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& /*_rxModel*/ )
650 // nothing to do here
654 void DbCellControl::_propertyChanged(const PropertyChangeEvent
& _rEvent
)
656 SolarMutexGuard aGuard
;
658 Reference
< XPropertySet
> xSourceProps( _rEvent
.Source
, UNO_QUERY
);
660 if ( _rEvent
.PropertyName
== FM_PROP_VALUE
661 || _rEvent
.PropertyName
== FM_PROP_STATE
662 || _rEvent
.PropertyName
== FM_PROP_TEXT
663 || _rEvent
.PropertyName
== FM_PROP_EFFECTIVE_VALUE
664 || _rEvent
.PropertyName
== FM_PROP_SELECT_SEQ
665 || _rEvent
.PropertyName
== FM_PROP_DATE
666 || _rEvent
.PropertyName
== FM_PROP_TIME
668 { // it was one of the known "value" properties
669 if ( !isValuePropertyLocked() )
671 implValuePropertyChanged( );
674 else if ( _rEvent
.PropertyName
== FM_PROP_READONLY
)
676 implAdjustReadOnly( xSourceProps
, true);
678 else if ( _rEvent
.PropertyName
== FM_PROP_ISREADONLY
)
680 bool bReadOnly
= true;
681 _rEvent
.NewValue
>>= bReadOnly
;
682 m_rColumn
.SetReadOnly(bReadOnly
);
683 implAdjustReadOnly( xSourceProps
, false);
685 else if ( _rEvent
.PropertyName
== FM_PROP_ENABLED
)
687 implAdjustEnabled( xSourceProps
);
690 implAdjustGenericFieldSetting( xSourceProps
);
694 bool DbCellControl::Commit()
696 // lock the listening for value property changes
698 // commit the content of the control into the model's value property
699 bool bReturn
= false;
702 bReturn
= commitControl();
704 catch( const Exception
& )
706 DBG_UNHANDLED_EXCEPTION("svx");
708 // unlock the listening for value property changes
709 unlockValueProperty();
715 void DbCellControl::ImplInitWindow( vcl::Window
const & rParent
, const InitWindowFacet _eInitWhat
)
717 vcl::Window
* pWindows
[] = { m_pPainter
, m_pWindow
};
719 if (_eInitWhat
& InitWindowFacet::WritingMode
)
721 for (vcl::Window
* pWindow
: pWindows
)
724 pWindow
->EnableRTL(rParent
.IsRTLEnabled());
728 if (_eInitWhat
& InitWindowFacet::Font
)
730 for (vcl::Window
* pWindow
: pWindows
)
735 pWindow
->SetZoom(rParent
.GetZoom());
737 const StyleSettings
& rStyleSettings
= pWindow
->GetSettings().GetStyleSettings();
738 vcl::Font aFont
= rStyleSettings
.GetFieldFont();
739 aFont
.SetTransparent(isTransparent());
741 if (rParent
.IsControlFont())
743 pWindow
->SetControlFont(rParent
.GetControlFont());
744 aFont
.Merge(rParent
.GetControlFont());
747 pWindow
->SetControlFont();
749 pWindow
->SetZoomedPointFont(*pWindow
, aFont
); // FIXME RenderContext
753 if ((_eInitWhat
& InitWindowFacet::Font
) || (_eInitWhat
& InitWindowFacet::Foreground
))
755 Color
aTextColor(rParent
.IsControlForeground() ? rParent
.GetControlForeground() : rParent
.GetTextColor());
757 bool bTextLineColor
= rParent
.IsTextLineColor();
758 Color
aTextLineColor(rParent
.GetTextLineColor());
760 for (vcl::Window
* pWindow
: pWindows
)
764 pWindow
->SetTextColor(aTextColor
);
765 if (rParent
.IsControlForeground())
766 pWindow
->SetControlForeground(aTextColor
);
769 pWindow
->SetTextLineColor();
771 pWindow
->SetTextLineColor(aTextLineColor
);
776 if (_eInitWhat
& InitWindowFacet::Background
)
778 if (rParent
.IsControlBackground())
780 Color
aColor(rParent
.GetControlBackground());
781 for (vcl::Window
* pWindow
: pWindows
)
786 pWindow
->SetBackground();
789 pWindow
->SetBackground(aColor
);
790 pWindow
->SetControlBackground(aColor
);
792 pWindow
->SetFillColor(aColor
);
801 m_pPainter
->SetBackground();
803 m_pPainter
->SetBackground(rParent
.GetBackground());
804 m_pPainter
->SetFillColor(rParent
.GetFillColor());
810 m_pWindow
->SetBackground(rParent
.GetBackground());
812 m_pWindow
->SetFillColor(rParent
.GetFillColor());
819 void DbCellControl::implAdjustReadOnly( const Reference
< XPropertySet
>& _rxModel
,bool i_bReadOnly
)
821 DBG_ASSERT( m_pWindow
, "DbCellControl::implAdjustReadOnly: not to be called without window!" );
822 DBG_ASSERT( _rxModel
.is(), "DbCellControl::implAdjustReadOnly: invalid model!" );
823 if ( m_pWindow
&& _rxModel
.is() )
825 Edit
* pEditWindow
= dynamic_cast< Edit
* >( m_pWindow
.get() );
828 bool bReadOnly
= m_rColumn
.IsReadOnly();
831 _rxModel
->getPropertyValue( i_bReadOnly
? OUString(FM_PROP_READONLY
) : OUString(FM_PROP_ISREADONLY
)) >>= bReadOnly
;
833 static_cast< Edit
* >( m_pWindow
.get() )->SetReadOnly( bReadOnly
);
839 void DbCellControl::implAdjustEnabled( const Reference
< XPropertySet
>& _rxModel
)
841 DBG_ASSERT( m_pWindow
, "DbCellControl::implAdjustEnabled: not to be called without window!" );
842 DBG_ASSERT( _rxModel
.is(), "DbCellControl::implAdjustEnabled: invalid model!" );
843 if ( m_pWindow
&& _rxModel
.is() )
846 _rxModel
->getPropertyValue( FM_PROP_ENABLED
) >>= bEnable
;
847 m_pWindow
->Enable( bEnable
);
852 void DbCellControl::Init( vcl::Window
& rParent
, const Reference
< XRowSet
>& _rxCursor
)
854 ImplInitWindow( rParent
, InitWindowFacet::All
);
859 if ( isAlignedController() )
860 AlignControl( m_rColumn
.GetAlignment() );
864 // some other common properties
865 Reference
< XPropertySet
> xModel( m_rColumn
.getModel(), UNO_SET_THROW
);
866 Reference
< XPropertySetInfo
> xModelPSI( xModel
->getPropertySetInfo(), UNO_SET_THROW
);
868 if ( xModelPSI
->hasPropertyByName( FM_PROP_READONLY
) )
870 implAdjustReadOnly( xModel
,true );
873 if ( xModelPSI
->hasPropertyByName( FM_PROP_ENABLED
) )
875 implAdjustEnabled( xModel
);
878 if ( xModelPSI
->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR
) )
880 sal_Int16 nWheelBehavior
= css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY
;
881 OSL_VERIFY( xModel
->getPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR
) >>= nWheelBehavior
);
882 MouseWheelBehaviour nVclSetting
= MouseWheelBehaviour::FocusOnly
;
883 switch ( nWheelBehavior
)
885 case css::awt::MouseWheelBehavior::SCROLL_DISABLED
: nVclSetting
= MouseWheelBehaviour::Disable
; break;
886 case css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY
: nVclSetting
= MouseWheelBehaviour::FocusOnly
; break;
887 case css::awt::MouseWheelBehavior::SCROLL_ALWAYS
: nVclSetting
= MouseWheelBehaviour::ALWAYS
; break;
889 OSL_FAIL( "DbCellControl::Init: invalid MouseWheelBehavior!" );
893 AllSettings aSettings
= m_pWindow
->GetSettings();
894 MouseSettings aMouseSettings
= aSettings
.GetMouseSettings();
895 aMouseSettings
.SetWheelBehavior( nVclSetting
);
896 aSettings
.SetMouseSettings( aMouseSettings
);
897 m_pWindow
->SetSettings( aSettings
, true );
900 catch( const Exception
& )
902 DBG_UNHANDLED_EXCEPTION("svx");
905 m_xCursor
= _rxCursor
;
906 if ( m_rColumn
.getModel().is() )
907 updateFromModel( m_rColumn
.getModel() );
911 void DbCellControl::SetTextLineColor()
914 m_pWindow
->SetTextLineColor();
916 m_pPainter
->SetTextLineColor();
920 void DbCellControl::SetTextLineColor(const Color
& _rColor
)
923 m_pWindow
->SetTextLineColor(_rColor
);
925 m_pPainter
->SetTextLineColor(_rColor
);
930 void lcl_implAlign( vcl::Window
* _pWindow
, WinBits _nAlignmentBit
)
932 WinBits nStyle
= _pWindow
->GetStyle();
933 nStyle
&= ~(WB_LEFT
| WB_RIGHT
| WB_CENTER
);
934 _pWindow
->SetStyle( nStyle
| _nAlignmentBit
);
939 void DbCellControl::AlignControl(sal_Int16 nAlignment
)
941 WinBits nAlignmentBit
= 0;
944 case css::awt::TextAlign::RIGHT
:
945 nAlignmentBit
= WB_RIGHT
;
947 case css::awt::TextAlign::CENTER
:
948 nAlignmentBit
= WB_CENTER
;
951 nAlignmentBit
= WB_LEFT
;
954 lcl_implAlign( m_pWindow
, nAlignmentBit
);
956 lcl_implAlign( m_pPainter
, nAlignmentBit
);
960 void DbCellControl::PaintCell( OutputDevice
& _rDev
, const tools::Rectangle
& _rRect
)
962 if ( m_pPainter
->GetParent() == &_rDev
)
964 m_pPainter
->SetPaintTransparent( true );
965 m_pPainter
->SetBackground( );
966 m_pPainter
->SetControlBackground( _rDev
.GetFillColor() );
967 m_pPainter
->SetControlForeground( _rDev
.GetTextColor() );
968 m_pPainter
->SetTextColor( _rDev
.GetTextColor() );
969 m_pPainter
->SetTextFillColor( _rDev
.GetTextColor() );
971 vcl::Font
aFont( _rDev
.GetFont() );
972 aFont
.SetTransparent( true );
973 m_pPainter
->SetFont( aFont
);
975 m_pPainter
->SetPosSizePixel( _rRect
.TopLeft(), _rRect
.GetSize() );
977 m_pPainter
->Update();
978 m_pPainter
->SetParentUpdateMode( false );
980 m_pPainter
->SetParentUpdateMode( true );
983 m_pPainter
->Draw( &_rDev
, _rRect
.TopLeft(), _rRect
.GetSize(), DrawFlags::NONE
);
987 void DbCellControl::PaintFieldToCell( OutputDevice
& _rDev
, const tools::Rectangle
& _rRect
, const Reference
< XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& _rxFormatter
)
989 m_pPainter
->SetText( GetFormatText( _rxField
, _rxFormatter
) );
990 PaintCell( _rDev
, _rRect
);
994 double DbCellControl::GetValue(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& xFormatter
) const
997 if (m_rColumn
.IsNumeric())
1001 fValue
= _rxField
->getDouble();
1003 catch(const Exception
&) { }
1007 bool bSuccess
= false;
1010 fValue
= _rxField
->getDouble();
1013 catch(const Exception
&) { }
1018 fValue
= xFormatter
->convertStringToNumber(m_rColumn
.GetKey(), _rxField
->getString());
1020 catch(const Exception
&) { }
1027 void DbCellControl::invalidatedController()
1029 m_rColumn
.GetParent().refreshController(m_rColumn
.GetId(), DbGridControl::GrantControlAccess());
1034 DbLimitedLengthField::DbLimitedLengthField( DbGridColumn
& _rColumn
)
1035 :DbCellControl( _rColumn
)
1037 doPropertyListening( FM_PROP_MAXTEXTLEN
);
1041 void DbLimitedLengthField::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& _rxModel
)
1043 DBG_ASSERT( m_pWindow
, "DbLimitedLengthField::implAdjustGenericFieldSetting: not to be called without window!" );
1044 DBG_ASSERT( _rxModel
.is(), "DbLimitedLengthField::implAdjustGenericFieldSetting: invalid model!" );
1045 if ( m_pWindow
&& _rxModel
.is() )
1047 sal_Int16 nMaxLen
= 0;
1048 _rxModel
->getPropertyValue( FM_PROP_MAXTEXTLEN
) >>= nMaxLen
;
1049 implSetMaxTextLen( nMaxLen
);
1053 void DbLimitedLengthField::implSetEffectiveMaxTextLen( sal_Int32 _nMaxLen
)
1055 dynamic_cast<Edit
&>(*m_pWindow
).SetMaxTextLen(_nMaxLen
);
1057 dynamic_cast<Edit
&>(*m_pPainter
).SetMaxTextLen(_nMaxLen
);
1060 DbTextField::DbTextField(DbGridColumn
& _rColumn
)
1061 :DbLimitedLengthField(_rColumn
)
1062 ,m_bIsSimpleEdit( true )
1067 DbTextField::~DbTextField( )
1069 m_pPainterImplementation
.reset();
1074 void DbTextField::Init( vcl::Window
& rParent
, const Reference
< XRowSet
>& xCursor
)
1076 sal_Int16 nAlignment
= m_rColumn
.SetAlignmentFromModel(-1);
1078 Reference
< XPropertySet
> xModel( m_rColumn
.getModel() );
1080 WinBits nStyle
= WB_LEFT
;
1083 case awt::TextAlign::RIGHT
:
1087 case awt::TextAlign::CENTER
:
1092 // is this a multi-line field?
1093 bool bIsMultiLine
= false;
1098 OSL_VERIFY( xModel
->getPropertyValue( FM_PROP_MULTILINE
) >>= bIsMultiLine
);
1101 catch( const Exception
& )
1103 DBG_UNHANDLED_EXCEPTION("svx");
1104 OSL_FAIL( "DbTextField::Init: caught an exception while determining the multi-line capabilities!" );
1107 m_bIsSimpleEdit
= !bIsMultiLine
;
1110 m_pWindow
= VclPtr
<MultiLineTextCell
>::Create( &rParent
, nStyle
);
1111 m_pEdit
.reset(new MultiLineEditImplementation( *static_cast< MultiLineTextCell
* >( m_pWindow
.get() ) ));
1113 m_pPainter
= VclPtr
<MultiLineTextCell
>::Create( &rParent
, nStyle
);
1114 m_pPainterImplementation
.reset(new MultiLineEditImplementation( *static_cast< MultiLineTextCell
* >( m_pPainter
.get() ) ));
1118 m_pWindow
= VclPtr
<Edit
>::Create( &rParent
, nStyle
);
1119 m_pEdit
.reset(new EditImplementation( *static_cast< Edit
* >( m_pWindow
.get() ) ));
1121 m_pPainter
= VclPtr
<Edit
>::Create( &rParent
, nStyle
);
1122 m_pPainterImplementation
.reset(new EditImplementation( *static_cast< Edit
* >( m_pPainter
.get() ) ));
1125 if ( WB_LEFT
== nStyle
)
1127 // this is so that when getting the focus, the selection is oriented left-to-right
1128 AllSettings aSettings
= m_pWindow
->GetSettings();
1129 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
1130 aStyleSettings
.SetSelectionOptions(
1131 aStyleSettings
.GetSelectionOptions() | SelectionOptions::ShowFirst
);
1132 aSettings
.SetStyleSettings(aStyleSettings
);
1133 m_pWindow
->SetSettings(aSettings
);
1136 implAdjustGenericFieldSetting( xModel
);
1138 DbLimitedLengthField::Init( rParent
, xCursor
);
1142 CellControllerRef
DbTextField::CreateController() const
1144 return new EditCellController( m_pEdit
.get() );
1148 void DbTextField::PaintFieldToCell( OutputDevice
& _rDev
, const tools::Rectangle
& _rRect
, const Reference
< XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& _rxFormatter
)
1150 if ( m_pPainterImplementation
)
1151 m_pPainterImplementation
->SetText( GetFormatText( _rxField
, _rxFormatter
) );
1153 DbLimitedLengthField::PaintFieldToCell( _rDev
, _rRect
, _rxField
, _rxFormatter
);
1157 OUString
DbTextField::GetFormatText(const Reference
< XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& xFormatter
, Color
** /*ppColor*/)
1162 const css::uno::Reference
<css::beans::XPropertySet
> xPS(_rxField
, UNO_QUERY
);
1163 FormattedColumnValue
fmter( xFormatter
, xPS
);
1167 return fmter
.getFormattedValue();
1169 catch( const Exception
& )
1171 DBG_UNHANDLED_EXCEPTION("svx");
1178 void DbTextField::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& xFormatter
)
1180 m_pEdit
->SetText( GetFormatText( _rxField
, xFormatter
) );
1181 m_pEdit
->SetSelection( Selection( SELECTION_MAX
, SELECTION_MIN
) );
1185 void DbTextField::updateFromModel( Reference
< XPropertySet
> _rxModel
)
1187 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbTextField::updateFromModel: invalid call!" );
1190 _rxModel
->getPropertyValue( FM_PROP_TEXT
) >>= sText
;
1192 sal_Int32 nMaxTextLen
= m_pEdit
->GetMaxTextLen();
1193 if ( EDIT_NOLIMIT
!= nMaxTextLen
&& sText
.getLength() > nMaxTextLen
)
1195 sal_Int32 nDiff
= sText
.getLength() - nMaxTextLen
;
1196 sText
= sText
.replaceAt(sText
.getLength() - nDiff
,nDiff
, OUString());
1200 m_pEdit
->SetText( sText
);
1201 m_pEdit
->SetSelection( Selection( SELECTION_MAX
, SELECTION_MIN
) );
1205 bool DbTextField::commitControl()
1207 OUString
aText( m_pEdit
->GetText( getModelLineEndSetting( m_rColumn
.getModel() ) ) );
1208 // we have to check if the length before we can decide if the value was modified
1209 sal_Int32 nMaxTextLen
= m_pEdit
->GetMaxTextLen();
1210 if ( EDIT_NOLIMIT
!= nMaxTextLen
)
1213 m_rColumn
.getModel()->getPropertyValue( FM_PROP_TEXT
) >>= sOldValue
;
1214 // if the new value didn't change we must set the old long value again
1215 if ( sOldValue
.getLength() > nMaxTextLen
&& sOldValue
.compareTo(aText
,nMaxTextLen
) == 0 )
1218 m_rColumn
.getModel()->setPropertyValue( FM_PROP_TEXT
, makeAny( aText
) );
1223 void DbTextField::implSetEffectiveMaxTextLen( sal_Int32 _nMaxLen
)
1226 m_pEdit
->SetMaxTextLen( _nMaxLen
);
1227 if ( m_pPainterImplementation
)
1228 m_pPainterImplementation
->SetMaxTextLen( _nMaxLen
);
1231 DbFormattedField::DbFormattedField(DbGridColumn
& _rColumn
)
1232 :DbLimitedLengthField(_rColumn
)
1234 // if our model's format key changes we want to propagate the new value to our windows
1235 doPropertyListening( FM_PROP_FORMATKEY
);
1239 DbFormattedField::~DbFormattedField()
1244 void DbFormattedField::Init( vcl::Window
& rParent
, const Reference
< XRowSet
>& xCursor
)
1246 sal_Int16 nAlignment
= m_rColumn
.SetAlignmentFromModel(-1);
1248 Reference
< css::beans::XPropertySet
> xUnoModel
= m_rColumn
.getModel();
1252 case css::awt::TextAlign::RIGHT
:
1253 m_pWindow
= VclPtr
<FormattedField
>::Create( &rParent
, WB_RIGHT
);
1254 m_pPainter
= VclPtr
<FormattedField
>::Create( &rParent
, WB_RIGHT
);
1257 case css::awt::TextAlign::CENTER
:
1258 m_pWindow
= VclPtr
<FormattedField
>::Create( &rParent
, WB_CENTER
);
1259 m_pPainter
= VclPtr
<FormattedField
>::Create( &rParent
, WB_CENTER
);
1262 m_pWindow
= VclPtr
<FormattedField
>::Create( &rParent
, WB_LEFT
);
1263 m_pPainter
= VclPtr
<FormattedField
>::Create( &rParent
, WB_LEFT
);
1265 // Everything just so that the selection goes from right to left when getting focus
1266 AllSettings aSettings
= m_pWindow
->GetSettings();
1267 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
1268 aStyleSettings
.SetSelectionOptions(
1269 aStyleSettings
.GetSelectionOptions() | SelectionOptions::ShowFirst
);
1270 aSettings
.SetStyleSettings(aStyleSettings
);
1271 m_pWindow
->SetSettings(aSettings
);
1274 implAdjustGenericFieldSetting( xUnoModel
);
1276 static_cast< FormattedField
* >( m_pWindow
.get() )->SetStrictFormat( false );
1277 static_cast< FormattedField
* >( m_pPainter
.get() )->SetStrictFormat( false );
1278 // if one allows any formatting, one cannot make an entry check anyway
1279 // (the FormattedField does not support that anyway, only derived classes)
1281 // get the formatter from the uno model
1282 // (I could theoretically also go via the css::util::NumberFormatter, which the cursor would
1283 // surely give me. The problem is that I can not really rely on the fact that the two
1284 // formatters are the same. Clean is the whole thing if I go via the UNO model.)
1285 sal_Int32 nFormatKey
= -1;
1287 // let's see if the model has one ...
1288 DBG_ASSERT(::comphelper::hasProperty(FM_PROP_FORMATSSUPPLIER
, xUnoModel
), "DbFormattedField::Init : invalid UNO model !");
1289 Any
aSupplier( xUnoModel
->getPropertyValue(FM_PROP_FORMATSSUPPLIER
));
1290 if (aSupplier
.hasValue())
1292 m_xSupplier
.set(aSupplier
, css::uno::UNO_QUERY
);
1293 if (m_xSupplier
.is())
1295 // if we take the supplier from the model, then also the key
1296 Any
aFmtKey( xUnoModel
->getPropertyValue(FM_PROP_FORMATKEY
));
1297 if (aFmtKey
.hasValue())
1299 DBG_ASSERT(aFmtKey
.getValueType().getTypeClass() == TypeClass_LONG
, "DbFormattedField::Init : invalid format key property (no sal_Int32) !");
1300 nFormatKey
= ::comphelper::getINT32(aFmtKey
);
1304 SAL_INFO("svx.fmcomp", "DbFormattedField::Init : my uno-model has no format-key, but a formats supplier !");
1305 // the OFormattedModel which we usually are working with ensures that the model has a format key
1306 // as soon as the form is loaded. Unfortunally this method here is called from within loaded, too.
1307 // So if our LoadListener is called before the LoadListener of the model, this "else case" is
1309 // Of course our property listener for the FormatKey property will notify us if the prop is changed,
1310 // so this here isn't really bad...
1316 // No? Maybe the css::form::component::Form behind the cursor?
1317 if (!m_xSupplier
.is())
1320 { // If we take the formatter from the cursor, then also the key from the field to which we are bound
1321 m_xSupplier
= getNumberFormats(getConnection(xCursor
));
1323 if (m_rColumn
.GetField().is())
1324 nFormatKey
= ::comphelper::getINT32(m_rColumn
.GetField()->getPropertyValue(FM_PROP_FORMATKEY
));
1328 SvNumberFormatter
* pFormatterUsed
= nullptr;
1329 if (m_xSupplier
.is())
1331 SvNumberFormatsSupplierObj
* pImplmentation
= comphelper::getUnoTunnelImplementation
<SvNumberFormatsSupplierObj
>(m_xSupplier
);
1333 pFormatterUsed
= pImplmentation
->GetNumberFormatter();
1335 // Everything is invalid: the supplier is of the wrong type, then we can not
1336 // rely on a standard formatter to know the (possibly non-standard) key.
1340 // a standard formatter ...
1341 if (pFormatterUsed
== nullptr)
1343 pFormatterUsed
= static_cast<FormattedField
*>(m_pWindow
.get())->StandardFormatter();
1344 DBG_ASSERT(pFormatterUsed
!= nullptr, "DbFormattedField::Init : no standard formatter given by the numeric field !");
1346 // ... and a standard key
1347 if (nFormatKey
== -1)
1350 static_cast<FormattedField
*>(m_pWindow
.get())->SetFormatter(pFormatterUsed
);
1351 static_cast<FormattedField
*>(m_pPainter
.get())->SetFormatter(pFormatterUsed
);
1353 static_cast<FormattedField
*>(m_pWindow
.get())->SetFormatKey(nFormatKey
);
1354 static_cast<FormattedField
*>(m_pPainter
.get())->SetFormatKey(nFormatKey
);
1356 static_cast<FormattedField
*>(m_pWindow
.get())->TreatAsNumber(m_rColumn
.IsNumeric());
1357 static_cast<FormattedField
*>(m_pPainter
.get())->TreatAsNumber(m_rColumn
.IsNumeric());
1359 // min and max values
1360 if (m_rColumn
.IsNumeric())
1362 bool bClearMin
= true;
1363 if (::comphelper::hasProperty(FM_PROP_EFFECTIVE_MIN
, xUnoModel
))
1365 Any
aMin( xUnoModel
->getPropertyValue(FM_PROP_EFFECTIVE_MIN
));
1366 if (aMin
.getValueType().getTypeClass() != TypeClass_VOID
)
1368 DBG_ASSERT(aMin
.getValueType().getTypeClass() == TypeClass_DOUBLE
, "DbFormattedField::Init : the model has an invalid min value !");
1369 double dMin
= ::comphelper::getDouble(aMin
);
1370 static_cast<FormattedField
*>(m_pWindow
.get())->SetMinValue(dMin
);
1371 static_cast<FormattedField
*>(m_pPainter
.get())->SetMinValue(dMin
);
1377 static_cast<FormattedField
*>(m_pWindow
.get())->ClearMinValue();
1378 static_cast<FormattedField
*>(m_pPainter
.get())->ClearMinValue();
1380 bool bClearMax
= true;
1381 if (::comphelper::hasProperty(FM_PROP_EFFECTIVE_MAX
, xUnoModel
))
1383 Any
aMin( xUnoModel
->getPropertyValue(FM_PROP_EFFECTIVE_MAX
));
1384 if (aMin
.getValueType().getTypeClass() != TypeClass_VOID
)
1386 DBG_ASSERT(aMin
.getValueType().getTypeClass() == TypeClass_DOUBLE
, "DbFormattedField::Init : the model has an invalid max value !");
1387 double dMin
= ::comphelper::getDouble(aMin
);
1388 static_cast<FormattedField
*>(m_pWindow
.get())->SetMaxValue(dMin
);
1389 static_cast<FormattedField
*>(m_pPainter
.get())->SetMaxValue(dMin
);
1395 static_cast<FormattedField
*>(m_pWindow
.get())->ClearMaxValue();
1396 static_cast<FormattedField
*>(m_pPainter
.get())->ClearMaxValue();
1400 // the default value
1401 Any
aDefault( xUnoModel
->getPropertyValue(FM_PROP_EFFECTIVE_DEFAULT
));
1402 if (aDefault
.hasValue())
1403 { // the thing can be a double or a string
1404 switch (aDefault
.getValueType().getTypeClass())
1406 case TypeClass_DOUBLE
:
1407 if (m_rColumn
.IsNumeric())
1409 static_cast<FormattedField
*>(m_pWindow
.get())->SetDefaultValue(::comphelper::getDouble(aDefault
));
1410 static_cast<FormattedField
*>(m_pPainter
.get())->SetDefaultValue(::comphelper::getDouble(aDefault
));
1414 OUString sConverted
;
1416 pFormatterUsed
->GetOutputString(::comphelper::getDouble(aDefault
), 0, sConverted
, &pDummy
);
1417 static_cast<FormattedField
*>(m_pWindow
.get())->SetDefaultText(sConverted
);
1418 static_cast<FormattedField
*>(m_pPainter
.get())->SetDefaultText(sConverted
);
1421 case TypeClass_STRING
:
1423 OUString
sDefault( ::comphelper::getString(aDefault
) );
1424 if (m_rColumn
.IsNumeric())
1427 sal_uInt32
nTestFormat(0);
1428 if (pFormatterUsed
->IsNumberFormat(sDefault
, nTestFormat
, dVal
))
1430 static_cast<FormattedField
*>(m_pWindow
.get())->SetDefaultValue(dVal
);
1431 static_cast<FormattedField
*>(m_pPainter
.get())->SetDefaultValue(dVal
);
1436 static_cast<FormattedField
*>(m_pWindow
.get())->SetDefaultText(sDefault
);
1437 static_cast<FormattedField
*>(m_pPainter
.get())->SetDefaultText(sDefault
);
1442 OSL_FAIL( "DbFormattedField::Init: unexpected value type!" );
1446 DbLimitedLengthField::Init( rParent
, xCursor
);
1450 CellControllerRef
DbFormattedField::CreateController() const
1452 return new ::svt::FormattedFieldCellController( static_cast< FormattedField
* >( m_pWindow
.get() ) );
1456 void DbFormattedField::_propertyChanged( const PropertyChangeEvent
& _rEvent
)
1458 if (_rEvent
.PropertyName
== FM_PROP_FORMATKEY
)
1460 sal_Int32 nNewKey
= _rEvent
.NewValue
.hasValue() ? ::comphelper::getINT32(_rEvent
.NewValue
) : 0;
1462 DBG_ASSERT(m_pWindow
&& m_pPainter
, "DbFormattedField::_propertyChanged : where are my windows ?");
1464 static_cast< FormattedField
* >( m_pWindow
.get() )->SetFormatKey( nNewKey
);
1466 static_cast< FormattedField
* >( m_pPainter
.get() )->SetFormatKey( nNewKey
);
1470 DbLimitedLengthField::_propertyChanged( _rEvent
);
1475 OUString
DbFormattedField::GetFormatText(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& /*xFormatter*/, Color
** ppColor
)
1477 // no color specification by default
1478 if (ppColor
!= nullptr)
1481 // NULL value -> empty text
1488 if (m_rColumn
.IsNumeric())
1490 // The IsNumeric at the column says nothing about the class of the used format, but
1491 // about the class of the field bound to the column. So when you bind a FormattedField
1492 // column to a double field and format it as text, m_rColumn.IsNumeric() returns
1493 // sal_True. So that simply means that I can query the contents of the variant using
1494 // getDouble, and then I can leave the rest (the formatting) to the FormattedField.
1495 double dValue
= getValue( _rxField
, m_rColumn
.GetParent().getNullDate() );
1496 if (_rxField
->wasNull())
1498 static_cast<FormattedField
*>(m_pPainter
.get())->SetValue(dValue
);
1502 // Here I can not work with a double, since the field can not provide it to me.
1503 // So simply bind the text from the css::util::NumberFormatter to the correct css::form::component::Form.
1504 aText
= _rxField
->getString();
1505 if (_rxField
->wasNull())
1507 static_cast<FormattedField
*>(m_pPainter
.get())->SetTextFormatted(aText
);
1510 catch( const Exception
& )
1512 DBG_UNHANDLED_EXCEPTION("svx");
1515 aText
= m_pPainter
->GetText();
1516 if (ppColor
!= nullptr)
1517 *ppColor
= static_cast<FormattedField
*>(m_pPainter
.get())->GetLastOutputColor();
1523 void DbFormattedField::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& /*xFormatter*/)
1527 FormattedField
* pFormattedWindow
= static_cast<FormattedField
*>(m_pWindow
.get());
1529 { // NULL value -> empty text
1530 m_pWindow
->SetText(OUString());
1532 else if (m_rColumn
.IsNumeric())
1534 // The IsNumeric at the column says nothing about the class of the used format, but
1535 // about the class of the field bound to the column. So when you bind a FormattedField
1536 // column to a double field and format it as text, m_rColumn.IsNumeric() returns
1537 // sal_True. So that simply means that I can query the contents of the variant using
1538 // getDouble, and then I can leave the rest (the formatting) to the FormattedField.
1539 double dValue
= getValue( _rxField
, m_rColumn
.GetParent().getNullDate() );
1540 if (_rxField
->wasNull())
1541 m_pWindow
->SetText(OUString());
1543 pFormattedWindow
->SetValue(dValue
);
1547 // Here I can not work with a double, since the field can not provide it to me.
1548 // So simply bind the text from the css::util::NumberFormatter to the correct css::form::component::Form.
1549 OUString
sText( _rxField
->getString());
1551 pFormattedWindow
->SetTextFormatted( sText
);
1552 pFormattedWindow
->SetSelection( Selection( SELECTION_MAX
, SELECTION_MIN
) );
1555 catch( const Exception
& )
1557 DBG_UNHANDLED_EXCEPTION("svx");
1562 void DbFormattedField::updateFromModel( Reference
< XPropertySet
> _rxModel
)
1564 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbFormattedField::updateFromModel: invalid call!" );
1566 FormattedField
* pFormattedWindow
= static_cast< FormattedField
* >( m_pWindow
.get() );
1569 Any aValue
= _rxModel
->getPropertyValue( FM_PROP_EFFECTIVE_VALUE
);
1570 if ( !aValue
.hasValue() || (aValue
>>= sText
) )
1571 { // our effective value is transferred as string
1572 pFormattedWindow
->SetTextFormatted( sText
);
1573 pFormattedWindow
->SetSelection( Selection( SELECTION_MAX
, SELECTION_MIN
) );
1579 pFormattedWindow
->SetValue(dValue
);
1584 bool DbFormattedField::commitControl()
1587 FormattedField
& rField
= *static_cast<FormattedField
*>(m_pWindow
.get());
1588 DBG_ASSERT(&rField
== m_pWindow
, "DbFormattedField::commitControl : can't work with a window other than my own !");
1589 if (m_rColumn
.IsNumeric())
1591 if (!rField
.GetText().isEmpty())
1592 aNewVal
<<= rField
.GetValue();
1593 // an empty string is passed on as void by default, to start with
1596 aNewVal
<<= rField
.GetTextValue();
1598 m_rColumn
.getModel()->setPropertyValue(FM_PROP_EFFECTIVE_VALUE
, aNewVal
);
1602 DbCheckBox::DbCheckBox( DbGridColumn
& _rColumn
)
1603 :DbCellControl( _rColumn
)
1605 setAlignedController( false );
1610 void setCheckBoxStyle( vcl::Window
* _pWindow
, bool bMono
)
1612 AllSettings aSettings
= _pWindow
->GetSettings();
1613 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
1615 aStyleSettings
.SetOptions( aStyleSettings
.GetOptions() | StyleSettingsOptions::Mono
);
1617 aStyleSettings
.SetOptions( aStyleSettings
.GetOptions() & (~StyleSettingsOptions::Mono
) );
1618 aSettings
.SetStyleSettings( aStyleSettings
);
1619 _pWindow
->SetSettings( aSettings
);
1624 void DbCheckBox::Init( vcl::Window
& rParent
, const Reference
< XRowSet
>& xCursor
)
1626 setTransparent( true );
1628 m_pWindow
= VclPtr
<CheckBoxControl
>::Create( &rParent
);
1629 m_pPainter
= VclPtr
<CheckBoxControl
>::Create( &rParent
);
1631 m_pWindow
->SetPaintTransparent( true );
1632 m_pPainter
->SetPaintTransparent( true );
1634 m_pPainter
->SetBackground();
1638 Reference
< XPropertySet
> xModel( m_rColumn
.getModel(), UNO_SET_THROW
);
1640 sal_Int16 nStyle
= awt::VisualEffect::LOOK3D
;
1641 OSL_VERIFY( xModel
->getPropertyValue( FM_PROP_VISUALEFFECT
) >>= nStyle
);
1643 setCheckBoxStyle( m_pWindow
, nStyle
== awt::VisualEffect::FLAT
);
1644 setCheckBoxStyle( m_pPainter
, nStyle
== awt::VisualEffect::FLAT
);
1646 bool bTristate
= true;
1647 OSL_VERIFY( xModel
->getPropertyValue( FM_PROP_TRISTATE
) >>= bTristate
);
1648 static_cast< CheckBoxControl
* >( m_pWindow
.get() )->GetBox().EnableTriState( bTristate
);
1649 static_cast< CheckBoxControl
* >( m_pPainter
.get() )->GetBox().EnableTriState( bTristate
);
1651 catch( const Exception
& )
1653 DBG_UNHANDLED_EXCEPTION("svx");
1656 DbCellControl::Init( rParent
, xCursor
);
1660 CellControllerRef
DbCheckBox::CreateController() const
1662 return new CheckBoxCellController(static_cast<CheckBoxControl
*>(m_pWindow
.get()));
1665 static void lcl_setCheckBoxState( const Reference
< css::sdb::XColumn
>& _rxField
,
1666 CheckBoxControl
* _pCheckBoxControl
)
1668 TriState eState
= TRISTATE_INDET
;
1673 bool bValue
= _rxField
->getBoolean();
1674 if (!_rxField
->wasNull())
1675 eState
= bValue
? TRISTATE_TRUE
: TRISTATE_FALSE
;
1677 catch( const Exception
& )
1679 DBG_UNHANDLED_EXCEPTION("svx");
1682 _pCheckBoxControl
->GetBox().SetState(eState
);
1686 void DbCheckBox::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& /*xFormatter*/)
1688 lcl_setCheckBoxState( _rxField
, static_cast<CheckBoxControl
*>(m_pWindow
.get()) );
1692 void DbCheckBox::PaintFieldToCell(OutputDevice
& rDev
, const tools::Rectangle
& rRect
,
1693 const Reference
< css::sdb::XColumn
>& _rxField
,
1694 const Reference
< XNumberFormatter
>& xFormatter
)
1696 lcl_setCheckBoxState( _rxField
, static_cast<CheckBoxControl
*>(m_pPainter
.get()) );
1697 DbCellControl::PaintFieldToCell( rDev
, rRect
, _rxField
, xFormatter
);
1701 void DbCheckBox::updateFromModel( Reference
< XPropertySet
> _rxModel
)
1703 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbCheckBox::updateFromModel: invalid call!" );
1705 sal_Int16 nState
= TRISTATE_INDET
;
1706 _rxModel
->getPropertyValue( FM_PROP_STATE
) >>= nState
;
1707 static_cast< CheckBoxControl
* >( m_pWindow
.get() )->GetBox().SetState( static_cast< TriState
>( nState
) );
1711 bool DbCheckBox::commitControl()
1713 m_rColumn
.getModel()->setPropertyValue( FM_PROP_STATE
,
1714 makeAny( static_cast<sal_Int16
>( static_cast< CheckBoxControl
* >( m_pWindow
.get() )->GetBox().GetState() ) ) );
1719 OUString
DbCheckBox::GetFormatText(const Reference
< XColumn
>& /*_rxField*/, const Reference
< XNumberFormatter
>& /*xFormatter*/, Color
** /*ppColor*/)
1724 DbPatternField::DbPatternField( DbGridColumn
& _rColumn
, const Reference
<XComponentContext
>& _rContext
)
1725 :DbCellControl( _rColumn
)
1726 ,m_xContext( _rContext
)
1728 doPropertyListening( FM_PROP_LITERALMASK
);
1729 doPropertyListening( FM_PROP_EDITMASK
);
1730 doPropertyListening( FM_PROP_STRICTFORMAT
);
1734 void DbPatternField::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& _rxModel
)
1736 DBG_ASSERT( m_pWindow
, "DbPatternField::implAdjustGenericFieldSetting: not to be called without window!" );
1737 DBG_ASSERT( _rxModel
.is(), "DbPatternField::implAdjustGenericFieldSetting: invalid model!" );
1738 if ( !m_pWindow
|| !_rxModel
.is() )
1743 bool bStrict
= false;
1745 _rxModel
->getPropertyValue( FM_PROP_LITERALMASK
) >>= aLitMask
;
1746 _rxModel
->getPropertyValue( FM_PROP_EDITMASK
) >>= aEditMask
;
1747 _rxModel
->getPropertyValue( FM_PROP_STRICTFORMAT
) >>= bStrict
;
1749 OString
aAsciiEditMask(OUStringToOString(aEditMask
, RTL_TEXTENCODING_ASCII_US
));
1751 static_cast< PatternField
* >( m_pWindow
.get() )->SetMask( aAsciiEditMask
, aLitMask
);
1752 static_cast< PatternField
* >( m_pPainter
.get() )->SetMask( aAsciiEditMask
, aLitMask
);
1753 static_cast< PatternField
* >( m_pWindow
.get() )->SetStrictFormat( bStrict
);
1754 static_cast< PatternField
* >( m_pPainter
.get() )->SetStrictFormat( bStrict
);
1758 void DbPatternField::Init( vcl::Window
& rParent
, const Reference
< XRowSet
>& xCursor
)
1760 m_rColumn
.SetAlignmentFromModel(-1);
1762 m_pWindow
= VclPtr
<PatternField
>::Create( &rParent
, 0 );
1763 m_pPainter
= VclPtr
<PatternField
>::Create( &rParent
, 0 );
1765 Reference
< XPropertySet
> xModel( m_rColumn
.getModel() );
1766 implAdjustGenericFieldSetting( xModel
);
1768 DbCellControl::Init( rParent
, xCursor
);
1772 CellControllerRef
DbPatternField::CreateController() const
1774 return new SpinCellController( static_cast< PatternField
* >( m_pWindow
.get() ) );
1778 OUString
DbPatternField::impl_formatText( const OUString
& _rText
)
1780 m_pPainter
->SetText( _rText
);
1781 static_cast< PatternField
* >( m_pPainter
.get() )->ReformatAll();
1782 return m_pPainter
->GetText();
1786 OUString
DbPatternField::GetFormatText(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& /*xFormatter*/, Color
** /*ppColor*/)
1788 bool bIsForPaint
= _rxField
!= m_rColumn
.GetField();
1789 ::std::unique_ptr
< FormattedColumnValue
>& rpFormatter
= bIsForPaint
? m_pPaintFormatter
: m_pValueFormatter
;
1793 rpFormatter
= std::make_unique
< FormattedColumnValue
> (
1794 m_xContext
, getCursor(), Reference
< XPropertySet
>( _rxField
, UNO_QUERY
) );
1795 OSL_ENSURE(rpFormatter
, "DbPatternField::Init: no value formatter!");
1798 OSL_ENSURE( rpFormatter
->getColumn() == _rxField
, "DbPatternField::GetFormatText: my value formatter is working for another field ...!" );
1799 // re-creating the value formatter here every time would be quite expensive ...
1803 sText
= rpFormatter
->getFormattedValue();
1805 return impl_formatText( sText
);
1809 void DbPatternField::UpdateFromField( const Reference
< XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& _rxFormatter
)
1811 static_cast< Edit
* >( m_pWindow
.get() )->SetText( GetFormatText( _rxField
, _rxFormatter
) );
1812 static_cast< Edit
* >( m_pWindow
.get() )->SetSelection( Selection( SELECTION_MAX
, SELECTION_MIN
) );
1816 void DbPatternField::updateFromModel( Reference
< XPropertySet
> _rxModel
)
1818 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbPatternField::updateFromModel: invalid call!" );
1821 _rxModel
->getPropertyValue( FM_PROP_TEXT
) >>= sText
;
1823 static_cast< Edit
* >( m_pWindow
.get() )->SetText( impl_formatText( sText
) );
1824 static_cast< Edit
* >( m_pWindow
.get() )->SetSelection( Selection( SELECTION_MAX
, SELECTION_MIN
) );
1828 bool DbPatternField::commitControl()
1830 OUString
aText(m_pWindow
->GetText());
1831 m_rColumn
.getModel()->setPropertyValue(FM_PROP_TEXT
, makeAny(aText
));
1835 DbSpinField::DbSpinField( DbGridColumn
& _rColumn
, sal_Int16 _nStandardAlign
)
1836 :DbCellControl( _rColumn
)
1837 ,m_nStandardAlign( _nStandardAlign
)
1842 void DbSpinField::Init( vcl::Window
& _rParent
, const Reference
< XRowSet
>& _rxCursor
)
1844 m_rColumn
.SetAlignmentFromModel( m_nStandardAlign
);
1846 Reference
< XPropertySet
> xModel( m_rColumn
.getModel() );
1848 // determine the WinBits for the field
1849 WinBits nFieldStyle
= 0;
1850 if ( ::comphelper::getBOOL( xModel
->getPropertyValue( FM_PROP_SPIN
) ) )
1851 nFieldStyle
= WB_REPEAT
| WB_SPIN
;
1852 // create the fields
1853 m_pWindow
= createField( &_rParent
, nFieldStyle
, xModel
);
1854 m_pPainter
= createField( &_rParent
, nFieldStyle
, xModel
);
1856 // adjust all other settings which depend on the property values
1857 implAdjustGenericFieldSetting( xModel
);
1859 // call the base class
1860 DbCellControl::Init( _rParent
, _rxCursor
);
1864 CellControllerRef
DbSpinField::CreateController() const
1866 return new SpinCellController( static_cast< SpinField
* >( m_pWindow
.get() ) );
1869 DbNumericField::DbNumericField( DbGridColumn
& _rColumn
)
1870 :DbSpinField( _rColumn
)
1872 doPropertyListening( FM_PROP_DECIMAL_ACCURACY
);
1873 doPropertyListening( FM_PROP_VALUEMIN
);
1874 doPropertyListening( FM_PROP_VALUEMAX
);
1875 doPropertyListening( FM_PROP_VALUESTEP
);
1876 doPropertyListening( FM_PROP_STRICTFORMAT
);
1877 doPropertyListening( FM_PROP_SHOWTHOUSANDSEP
);
1881 void DbNumericField::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& _rxModel
)
1883 DBG_ASSERT( m_pWindow
, "DbNumericField::implAdjustGenericFieldSetting: not to be called without window!" );
1884 DBG_ASSERT( _rxModel
.is(), "DbNumericField::implAdjustGenericFieldSetting: invalid model!" );
1885 if ( !m_pWindow
|| !_rxModel
.is() )
1888 sal_Int32 nMin
= static_cast<sal_Int32
>(getDouble( _rxModel
->getPropertyValue( FM_PROP_VALUEMIN
) ));
1889 sal_Int32 nMax
= static_cast<sal_Int32
>(getDouble( _rxModel
->getPropertyValue( FM_PROP_VALUEMAX
) ));
1890 sal_Int32 nStep
= static_cast<sal_Int32
>(getDouble( _rxModel
->getPropertyValue( FM_PROP_VALUESTEP
) ));
1891 bool bStrict
= getBOOL( _rxModel
->getPropertyValue( FM_PROP_STRICTFORMAT
) );
1892 sal_Int16 nScale
= getINT16( _rxModel
->getPropertyValue( FM_PROP_DECIMAL_ACCURACY
) );
1893 bool bThousand
= getBOOL( _rxModel
->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP
) );
1895 static_cast< DoubleNumericField
* >( m_pWindow
.get() )->SetMinValue(nMin
);
1896 static_cast< DoubleNumericField
* >( m_pWindow
.get() )->SetMaxValue(nMax
);
1897 static_cast< DoubleNumericField
* >( m_pWindow
.get() )->SetSpinSize(nStep
);
1898 static_cast< DoubleNumericField
* >( m_pWindow
.get() )->SetStrictFormat(bStrict
);
1900 static_cast< DoubleNumericField
* >( m_pPainter
.get() )->SetMinValue(nMin
);
1901 static_cast< DoubleNumericField
* >( m_pPainter
.get() )->SetMaxValue(nMax
);
1902 static_cast< DoubleNumericField
* >( m_pPainter
.get() )->SetStrictFormat(bStrict
);
1905 // give a formatter to the field and the painter;
1906 // test first if I can get from the service behind a connection
1907 Reference
< css::util::XNumberFormatsSupplier
> xSupplier
;
1908 Reference
< XRowSet
> xForm
;
1909 if ( m_rColumn
.GetParent().getDataSource() )
1910 xForm
.set( Reference
< XInterface
>(*m_rColumn
.GetParent().getDataSource()), UNO_QUERY
);
1912 xSupplier
= getNumberFormats( getConnection( xForm
), true );
1913 SvNumberFormatter
* pFormatterUsed
= nullptr;
1914 if ( xSupplier
.is() )
1916 SvNumberFormatsSupplierObj
* pImplmentation
= comphelper::getUnoTunnelImplementation
<SvNumberFormatsSupplierObj
>( xSupplier
);
1917 pFormatterUsed
= pImplmentation
? pImplmentation
->GetNumberFormatter() : nullptr;
1919 if ( nullptr == pFormatterUsed
)
1920 { // the cursor didn't lead to success -> standard
1921 pFormatterUsed
= static_cast< DoubleNumericField
* >( m_pWindow
.get() )->StandardFormatter();
1922 DBG_ASSERT( pFormatterUsed
!= nullptr, "DbNumericField::implAdjustGenericFieldSetting: no standard formatter given by the numeric field !" );
1924 static_cast< DoubleNumericField
* >( m_pWindow
.get() )->SetFormatter( pFormatterUsed
);
1925 static_cast< DoubleNumericField
* >( m_pPainter
.get() )->SetFormatter( pFormatterUsed
);
1927 // and then generate a format which has the desired length after the decimal point, etc.
1928 LanguageType aAppLanguage
= Application::GetSettings().GetUILanguageTag().getLanguageType();
1929 OUString sFormatString
= pFormatterUsed
->GenerateFormat(0, aAppLanguage
, bThousand
, false, nScale
);
1931 static_cast< DoubleNumericField
* >( m_pWindow
.get() )->SetFormat( sFormatString
, aAppLanguage
);
1932 static_cast< DoubleNumericField
* >( m_pPainter
.get() )->SetFormat( sFormatString
, aAppLanguage
);
1936 VclPtr
<SpinField
> DbNumericField::createField( vcl::Window
* _pParent
, WinBits _nFieldStyle
, const Reference
< XPropertySet
>& /*_rxModel*/ )
1938 return VclPtr
<DoubleNumericField
>::Create( _pParent
, _nFieldStyle
);
1944 OUString
lcl_setFormattedNumeric_nothrow( DoubleNumericField
& _rField
, const DbCellControl
& _rControl
,
1945 const Reference
< XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& _rxFormatter
)
1948 if ( _rxField
.is() )
1952 double fValue
= _rControl
.GetValue( _rxField
, _rxFormatter
);
1953 if ( !_rxField
->wasNull() )
1955 _rField
.SetValue( fValue
);
1956 sValue
= _rField
.GetText();
1959 catch( const Exception
& )
1961 DBG_UNHANDLED_EXCEPTION("svx");
1969 OUString
DbNumericField::GetFormatText(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< css::util::XNumberFormatter
>& _rxFormatter
, Color
** /*ppColor*/)
1971 return lcl_setFormattedNumeric_nothrow(dynamic_cast<DoubleNumericField
&>(*m_pPainter
), *this, _rxField
, _rxFormatter
);
1975 void DbNumericField::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< css::util::XNumberFormatter
>& _rxFormatter
)
1977 lcl_setFormattedNumeric_nothrow(dynamic_cast<DoubleNumericField
&>(*m_pWindow
), *this, _rxField
, _rxFormatter
);
1981 void DbNumericField::updateFromModel( Reference
< XPropertySet
> _rxModel
)
1983 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbNumericField::updateFromModel: invalid call!" );
1986 if ( _rxModel
->getPropertyValue( FM_PROP_VALUE
) >>= dValue
)
1987 static_cast< DoubleNumericField
* >( m_pWindow
.get() )->SetValue( dValue
);
1989 m_pWindow
->SetText( OUString() );
1993 bool DbNumericField::commitControl()
1995 OUString
aText( m_pWindow
->GetText());
1998 if (!aText
.isEmpty()) // not empty
2000 double fValue
= static_cast<DoubleNumericField
*>(m_pWindow
.get())->GetValue();
2003 m_rColumn
.getModel()->setPropertyValue(FM_PROP_VALUE
, aVal
);
2007 DbCurrencyField::DbCurrencyField(DbGridColumn
& _rColumn
)
2008 :DbSpinField( _rColumn
)
2011 doPropertyListening( FM_PROP_DECIMAL_ACCURACY
);
2012 doPropertyListening( FM_PROP_VALUEMIN
);
2013 doPropertyListening( FM_PROP_VALUEMAX
);
2014 doPropertyListening( FM_PROP_VALUESTEP
);
2015 doPropertyListening( FM_PROP_STRICTFORMAT
);
2016 doPropertyListening( FM_PROP_SHOWTHOUSANDSEP
);
2017 doPropertyListening( FM_PROP_CURRENCYSYMBOL
);
2021 void DbCurrencyField::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& _rxModel
)
2023 DBG_ASSERT( m_pWindow
, "DbCurrencyField::implAdjustGenericFieldSetting: not to be called without window!" );
2024 DBG_ASSERT( _rxModel
.is(), "DbCurrencyField::implAdjustGenericFieldSetting: invalid model!" );
2025 if ( !m_pWindow
|| !_rxModel
.is() )
2028 m_nScale
= getINT16( _rxModel
->getPropertyValue( FM_PROP_DECIMAL_ACCURACY
) );
2029 double nMin
= getDouble( _rxModel
->getPropertyValue( FM_PROP_VALUEMIN
) );
2030 double nMax
= getDouble( _rxModel
->getPropertyValue( FM_PROP_VALUEMAX
) );
2031 double nStep
= getDouble( _rxModel
->getPropertyValue( FM_PROP_VALUESTEP
) );
2032 bool bStrict
= getBOOL( _rxModel
->getPropertyValue( FM_PROP_STRICTFORMAT
) );
2033 bool bThousand
= getBOOL( _rxModel
->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP
) );
2034 OUString
aStr( getString( _rxModel
->getPropertyValue(FM_PROP_CURRENCYSYMBOL
) ) );
2036 //fdo#42747 the min/max/first/last of vcl NumericFormatters needs to be
2037 //multiplied by the no of decimal places. See also
2038 //VclBuilder::mungeAdjustment
2039 int nMul
= rtl_math_pow10Exp(1, m_nScale
);
2043 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetUseThousandSep( bThousand
);
2044 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetDecimalDigits( m_nScale
);
2045 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetCurrencySymbol( aStr
);
2046 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetFirst( nMin
);
2047 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetLast( nMax
);
2048 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetMin( nMin
);
2049 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetMax( nMax
);
2050 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetSpinSize( nStep
);
2051 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetStrictFormat( bStrict
);
2053 static_cast< LongCurrencyField
* >( m_pPainter
.get() )->SetUseThousandSep( bThousand
);
2054 static_cast< LongCurrencyField
* >( m_pPainter
.get() )->SetDecimalDigits( m_nScale
);
2055 static_cast< LongCurrencyField
* >( m_pPainter
.get() )->SetCurrencySymbol( aStr
);
2056 static_cast< LongCurrencyField
* >( m_pPainter
.get() )->SetFirst( nMin
);
2057 static_cast< LongCurrencyField
* >( m_pPainter
.get() )->SetLast( nMax
);
2058 static_cast< LongCurrencyField
* >( m_pPainter
.get() )->SetMin( nMin
);
2059 static_cast< LongCurrencyField
* >( m_pPainter
.get() )->SetMax( nMax
);
2060 static_cast< LongCurrencyField
* >( m_pPainter
.get() )->SetStrictFormat( bStrict
);
2064 VclPtr
<SpinField
> DbCurrencyField::createField( vcl::Window
* _pParent
, WinBits _nFieldStyle
, const Reference
< XPropertySet
>& /*_rxModel*/ )
2066 return VclPtr
<LongCurrencyField
>::Create( _pParent
, _nFieldStyle
);
2070 double DbCurrencyField::GetCurrency(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& xFormatter
) const
2072 double fValue
= GetValue(_rxField
, xFormatter
);
2075 // SAL_INFO("svx",("double = %.64f ",fValue);
2076 fValue
= ::rtl::math::pow10Exp(fValue
, m_nScale
);
2077 fValue
= ::rtl::math::round(fValue
);
2085 OUString
lcl_setFormattedCurrency_nothrow( LongCurrencyField
& _rField
, const DbCurrencyField
& _rControl
,
2086 const Reference
< XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& _rxFormatter
)
2089 if ( _rxField
.is() )
2093 double fValue
= _rControl
.GetCurrency( _rxField
, _rxFormatter
);
2094 if ( !_rxField
->wasNull() )
2096 _rField
.SetValue( fValue
);
2097 sValue
= _rField
.GetText();
2100 catch( const Exception
& )
2102 DBG_UNHANDLED_EXCEPTION("svx");
2110 OUString
DbCurrencyField::GetFormatText(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< css::util::XNumberFormatter
>& _rxFormatter
, Color
** /*ppColor*/)
2112 return lcl_setFormattedCurrency_nothrow( dynamic_cast< LongCurrencyField
& >( *m_pPainter
), *this, _rxField
, _rxFormatter
);
2116 void DbCurrencyField::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< css::util::XNumberFormatter
>& _rxFormatter
)
2118 lcl_setFormattedCurrency_nothrow( dynamic_cast< LongCurrencyField
& >( *m_pWindow
), *this, _rxField
, _rxFormatter
);
2122 void DbCurrencyField::updateFromModel( Reference
< XPropertySet
> _rxModel
)
2124 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbCurrencyField::updateFromModel: invalid call!" );
2127 if ( _rxModel
->getPropertyValue( FM_PROP_VALUE
) >>= dValue
)
2131 dValue
= ::rtl::math::pow10Exp( dValue
, m_nScale
);
2132 dValue
= ::rtl::math::round(dValue
);
2135 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetValue( dValue
);
2138 m_pWindow
->SetText( OUString() );
2142 bool DbCurrencyField::commitControl()
2144 OUString
aText(m_pWindow
->GetText());
2146 if (!aText
.isEmpty()) // not empty
2148 double fValue
= static_cast<LongCurrencyField
*>(m_pWindow
.get())->GetValue();
2151 fValue
/= ::rtl::math::pow10Exp(1.0, m_nScale
);
2155 m_rColumn
.getModel()->setPropertyValue(FM_PROP_VALUE
, aVal
);
2159 DbDateField::DbDateField( DbGridColumn
& _rColumn
)
2160 :DbSpinField( _rColumn
)
2162 doPropertyListening( FM_PROP_DATEFORMAT
);
2163 doPropertyListening( FM_PROP_DATEMIN
);
2164 doPropertyListening( FM_PROP_DATEMAX
);
2165 doPropertyListening( FM_PROP_STRICTFORMAT
);
2166 doPropertyListening( FM_PROP_DATE_SHOW_CENTURY
);
2170 VclPtr
<SpinField
> DbDateField::createField( vcl::Window
* _pParent
, WinBits _nFieldStyle
, const Reference
< XPropertySet
>& _rxModel
)
2172 // check if there is a DropDown property set to TRUE
2173 bool bDropDown
= !hasProperty( FM_PROP_DROPDOWN
, _rxModel
)
2174 || getBOOL( _rxModel
->getPropertyValue( FM_PROP_DROPDOWN
) );
2176 _nFieldStyle
|= WB_DROPDOWN
;
2178 VclPtr
<CalendarField
> pField
= VclPtr
<CalendarField
>::Create( _pParent
, _nFieldStyle
);
2180 pField
->EnableToday();
2181 pField
->EnableNone();
2187 void DbDateField::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& _rxModel
)
2189 DBG_ASSERT( m_pWindow
, "DbDateField::implAdjustGenericFieldSetting: not to be called without window!" );
2190 DBG_ASSERT( _rxModel
.is(), "DbDateField::implAdjustGenericFieldSetting: invalid model!" );
2191 if ( !m_pWindow
|| !_rxModel
.is() )
2194 sal_Int16 nFormat
= getINT16( _rxModel
->getPropertyValue( FM_PROP_DATEFORMAT
) );
2196 OSL_VERIFY( _rxModel
->getPropertyValue( FM_PROP_DATEMIN
) >>= aMin
);
2198 OSL_VERIFY( _rxModel
->getPropertyValue( FM_PROP_DATEMAX
) >>= aMax
);
2199 bool bStrict
= getBOOL( _rxModel
->getPropertyValue( FM_PROP_STRICTFORMAT
) );
2201 Any aCentury
= _rxModel
->getPropertyValue( FM_PROP_DATE_SHOW_CENTURY
);
2202 if ( aCentury
.getValueType().getTypeClass() != TypeClass_VOID
)
2204 bool bShowDateCentury
= getBOOL( aCentury
);
2206 static_cast<DateField
*>( m_pWindow
.get() )->SetShowDateCentury( bShowDateCentury
);
2207 static_cast<DateField
*>( m_pPainter
.get() )->SetShowDateCentury( bShowDateCentury
);
2210 static_cast< DateField
* >( m_pWindow
.get() )->SetExtDateFormat( static_cast<ExtDateFieldFormat
>(nFormat
) );
2211 static_cast< DateField
* >( m_pWindow
.get() )->SetMin( aMin
);
2212 static_cast< DateField
* >( m_pWindow
.get() )->SetMax( aMax
);
2213 static_cast< DateField
* >( m_pWindow
.get() )->SetStrictFormat( bStrict
);
2214 static_cast< DateField
* >( m_pWindow
.get() )->EnableEmptyFieldValue( true );
2216 static_cast< DateField
* >( m_pPainter
.get() )->SetExtDateFormat( static_cast<ExtDateFieldFormat
>(nFormat
) );
2217 static_cast< DateField
* >( m_pPainter
.get() )->SetMin( aMin
);
2218 static_cast< DateField
* >( m_pPainter
.get() )->SetMax( aMax
);
2219 static_cast< DateField
* >( m_pPainter
.get() )->SetStrictFormat( bStrict
);
2220 static_cast< DateField
* >( m_pPainter
.get() )->EnableEmptyFieldValue( true );
2226 OUString
lcl_setFormattedDate_nothrow( DateField
& _rField
, const Reference
< XColumn
>& _rxField
)
2229 if ( _rxField
.is() )
2233 css::util::Date aValue
= _rxField
->getDate();
2234 if ( _rxField
->wasNull() )
2235 _rField
.SetText( sDate
);
2238 _rField
.SetDate( ::Date( aValue
.Day
, aValue
.Month
, aValue
.Year
) );
2239 sDate
= _rField
.GetText();
2242 catch( const Exception
& )
2244 DBG_UNHANDLED_EXCEPTION("svx");
2251 OUString
DbDateField::GetFormatText(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< css::util::XNumberFormatter
>& /*xFormatter*/, Color
** /*ppColor*/)
2253 return lcl_setFormattedDate_nothrow(dynamic_cast<DateField
&>(*m_pPainter
.get()), _rxField
);
2257 void DbDateField::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& /*xFormatter*/)
2259 lcl_setFormattedDate_nothrow(dynamic_cast<DateField
&>(*m_pWindow
.get()), _rxField
);
2263 void DbDateField::updateFromModel( Reference
< XPropertySet
> _rxModel
)
2265 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbDateField::updateFromModel: invalid call!" );
2268 if ( _rxModel
->getPropertyValue( FM_PROP_DATE
) >>= aDate
)
2269 static_cast< DateField
* >( m_pWindow
.get() )->SetDate( ::Date( aDate
) );
2271 static_cast< DateField
* >( m_pWindow
.get() )->SetText( OUString() );
2275 bool DbDateField::commitControl()
2277 OUString
aText(m_pWindow
->GetText());
2279 if (!aText
.isEmpty())
2280 aVal
<<= static_cast<DateField
*>(m_pWindow
.get())->GetDate().GetUNODate();
2284 m_rColumn
.getModel()->setPropertyValue(FM_PROP_DATE
, aVal
);
2288 DbTimeField::DbTimeField( DbGridColumn
& _rColumn
)
2289 :DbSpinField( _rColumn
, css::awt::TextAlign::LEFT
)
2291 doPropertyListening( FM_PROP_TIMEFORMAT
);
2292 doPropertyListening( FM_PROP_TIMEMIN
);
2293 doPropertyListening( FM_PROP_TIMEMAX
);
2294 doPropertyListening( FM_PROP_STRICTFORMAT
);
2298 VclPtr
<SpinField
> DbTimeField::createField( vcl::Window
* _pParent
, WinBits _nFieldStyle
, const Reference
< XPropertySet
>& /*_rxModel*/ )
2300 return VclPtr
<TimeField
>::Create( _pParent
, _nFieldStyle
);
2304 void DbTimeField::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& _rxModel
)
2306 DBG_ASSERT( m_pWindow
, "DbTimeField::implAdjustGenericFieldSetting: not to be called without window!" );
2307 DBG_ASSERT( _rxModel
.is(), "DbTimeField::implAdjustGenericFieldSetting: invalid model!" );
2308 if ( !m_pWindow
|| !_rxModel
.is() )
2311 sal_Int16 nFormat
= getINT16( _rxModel
->getPropertyValue( FM_PROP_TIMEFORMAT
) );
2313 OSL_VERIFY( _rxModel
->getPropertyValue( FM_PROP_TIMEMIN
) >>= aMin
);
2315 OSL_VERIFY( _rxModel
->getPropertyValue( FM_PROP_TIMEMAX
) >>= aMax
);
2316 bool bStrict
= getBOOL( _rxModel
->getPropertyValue( FM_PROP_STRICTFORMAT
) );
2318 static_cast< TimeField
* >( m_pWindow
.get() )->SetExtFormat( static_cast<ExtTimeFieldFormat
>(nFormat
) );
2319 static_cast< TimeField
* >( m_pWindow
.get() )->SetMin( aMin
);
2320 static_cast< TimeField
* >( m_pWindow
.get() )->SetMax( aMax
);
2321 static_cast< TimeField
* >( m_pWindow
.get() )->SetStrictFormat( bStrict
);
2322 static_cast< TimeField
* >( m_pWindow
.get() )->EnableEmptyFieldValue( true );
2324 static_cast< TimeField
* >( m_pPainter
.get() )->SetExtFormat( static_cast<ExtTimeFieldFormat
>(nFormat
) );
2325 static_cast< TimeField
* >( m_pPainter
.get() )->SetMin( aMin
);
2326 static_cast< TimeField
* >( m_pPainter
.get() )->SetMax( aMax
);
2327 static_cast< TimeField
* >( m_pPainter
.get() )->SetStrictFormat( bStrict
);
2328 static_cast< TimeField
* >( m_pPainter
.get() )->EnableEmptyFieldValue( true );
2334 OUString
lcl_setFormattedTime_nothrow( TimeField
& _rField
, const Reference
< XColumn
>& _rxField
)
2337 if ( _rxField
.is() )
2341 css::util::Time aValue
= _rxField
->getTime();
2342 if ( _rxField
->wasNull() )
2343 _rField
.SetText( sTime
);
2346 _rField
.SetTime( ::tools::Time( aValue
) );
2347 sTime
= _rField
.GetText();
2350 catch( const Exception
& )
2352 DBG_UNHANDLED_EXCEPTION("svx");
2359 OUString
DbTimeField::GetFormatText(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< css::util::XNumberFormatter
>& /*xFormatter*/, Color
** /*ppColor*/)
2361 return lcl_setFormattedTime_nothrow( *static_cast< TimeField
* >( m_pPainter
.get() ), _rxField
);
2365 void DbTimeField::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& /*xFormatter*/)
2367 lcl_setFormattedTime_nothrow( *static_cast< TimeField
* >( m_pWindow
.get() ), _rxField
);
2371 void DbTimeField::updateFromModel( Reference
< XPropertySet
> _rxModel
)
2373 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbTimeField::updateFromModel: invalid call!" );
2376 if ( _rxModel
->getPropertyValue( FM_PROP_TIME
) >>= aTime
)
2377 static_cast< TimeField
* >( m_pWindow
.get() )->SetTime( ::tools::Time( aTime
) );
2379 static_cast< TimeField
* >( m_pWindow
.get() )->SetText( OUString() );
2383 bool DbTimeField::commitControl()
2385 OUString
aText(m_pWindow
->GetText());
2387 if (!aText
.isEmpty())
2388 aVal
<<= static_cast<TimeField
*>(m_pWindow
.get())->GetTime().GetUNOTime();
2392 m_rColumn
.getModel()->setPropertyValue(FM_PROP_TIME
, aVal
);
2396 DbComboBox::DbComboBox(DbGridColumn
& _rColumn
)
2397 :DbCellControl(_rColumn
)
2399 setAlignedController( false );
2401 doPropertyListening( FM_PROP_STRINGITEMLIST
);
2402 doPropertyListening( FM_PROP_LINECOUNT
);
2406 void DbComboBox::_propertyChanged( const PropertyChangeEvent
& _rEvent
)
2408 if ( _rEvent
.PropertyName
== FM_PROP_STRINGITEMLIST
)
2410 SetList(_rEvent
.NewValue
);
2414 DbCellControl::_propertyChanged( _rEvent
) ;
2419 void DbComboBox::SetList(const Any
& rItems
)
2421 ComboBoxControl
* pField
= static_cast<ComboBoxControl
*>(m_pWindow
.get());
2424 css::uno::Sequence
<OUString
> aTest
;
2425 if (rItems
>>= aTest
)
2427 for (const OUString
& rString
: std::as_const(aTest
))
2428 pField
->InsertEntry(rString
);
2430 // tell the grid control that this controller is invalid and has to be re-initialized
2431 invalidatedController();
2436 void DbComboBox::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& _rxModel
)
2438 DBG_ASSERT( m_pWindow
, "DbComboBox::implAdjustGenericFieldSetting: not to be called without window!" );
2439 DBG_ASSERT( _rxModel
.is(), "DbComboBox::implAdjustGenericFieldSetting: invalid model!" );
2440 if ( m_pWindow
&& _rxModel
.is() )
2442 sal_Int16 nLines
= getINT16( _rxModel
->getPropertyValue( FM_PROP_LINECOUNT
) );
2443 static_cast< ComboBoxControl
* >( m_pWindow
.get() )->SetDropDownLineCount( nLines
);
2448 void DbComboBox::Init( vcl::Window
& rParent
, const Reference
< XRowSet
>& xCursor
)
2450 m_rColumn
.SetAlignmentFromModel(css::awt::TextAlign::LEFT
);
2452 m_pWindow
= VclPtr
<ComboBoxControl
>::Create( &rParent
);
2454 // selection from right to left
2455 AllSettings aSettings
= m_pWindow
->GetSettings();
2456 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
2457 aStyleSettings
.SetSelectionOptions(
2458 aStyleSettings
.GetSelectionOptions() | SelectionOptions::ShowFirst
);
2459 aSettings
.SetStyleSettings(aStyleSettings
);
2460 m_pWindow
->SetSettings(aSettings
, true);
2462 // some initial properties
2463 Reference
< XPropertySet
> xModel(m_rColumn
.getModel());
2464 SetList( xModel
->getPropertyValue( FM_PROP_STRINGITEMLIST
) );
2465 implAdjustGenericFieldSetting( xModel
);
2467 DbCellControl::Init( rParent
, xCursor
);
2471 CellControllerRef
DbComboBox::CreateController() const
2473 return new ComboBoxCellController(static_cast<ComboBoxControl
*>(m_pWindow
.get()));
2477 OUString
DbComboBox::GetFormatText(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& xFormatter
, Color
** /*ppColor*/)
2479 const css::uno::Reference
<css::beans::XPropertySet
> xPS(_rxField
, UNO_QUERY
);
2480 ::dbtools::FormattedColumnValue
fmter( xFormatter
, xPS
);
2482 return fmter
.getFormattedValue();
2486 void DbComboBox::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& xFormatter
)
2488 m_pWindow
->SetText(GetFormatText(_rxField
, xFormatter
));
2492 void DbComboBox::updateFromModel( Reference
< XPropertySet
> _rxModel
)
2494 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbComboBox::updateFromModel: invalid call!" );
2497 _rxModel
->getPropertyValue( FM_PROP_TEXT
) >>= sText
;
2499 static_cast< ComboBox
* >( m_pWindow
.get() )->SetText( sText
);
2500 static_cast< ComboBox
* >( m_pWindow
.get() )->SetSelection( Selection( SELECTION_MAX
, SELECTION_MIN
) );
2504 bool DbComboBox::commitControl()
2506 OUString
aText( m_pWindow
->GetText());
2507 m_rColumn
.getModel()->setPropertyValue(FM_PROP_TEXT
, makeAny(aText
));
2512 DbListBox::DbListBox(DbGridColumn
& _rColumn
)
2513 :DbCellControl(_rColumn
)
2516 setAlignedController( false );
2518 doPropertyListening( FM_PROP_STRINGITEMLIST
);
2519 doPropertyListening( FM_PROP_LINECOUNT
);
2523 void DbListBox::_propertyChanged( const css::beans::PropertyChangeEvent
& _rEvent
)
2525 if ( _rEvent
.PropertyName
== FM_PROP_STRINGITEMLIST
)
2527 SetList(_rEvent
.NewValue
);
2531 DbCellControl::_propertyChanged( _rEvent
) ;
2536 void DbListBox::SetList(const Any
& rItems
)
2538 ListBoxControl
* pField
= static_cast<ListBoxControl
*>(m_pWindow
.get());
2543 css::uno::Sequence
<OUString
> aTest
;
2544 if (rItems
>>= aTest
)
2546 if (aTest
.hasElements())
2548 for (const OUString
& rString
: std::as_const(aTest
))
2549 pField
->InsertEntry(rString
);
2551 m_rColumn
.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ
) >>= m_aValueList
;
2552 m_bBound
= m_aValueList
.hasElements();
2554 // tell the grid control that this controller is invalid and has to be re-initialized
2555 invalidatedController();
2561 void DbListBox::Init( vcl::Window
& rParent
, const Reference
< XRowSet
>& xCursor
)
2563 m_rColumn
.SetAlignment(css::awt::TextAlign::LEFT
);
2565 m_pWindow
= VclPtr
<ListBoxControl
>::Create( &rParent
);
2567 // some initial properties
2568 Reference
< XPropertySet
> xModel( m_rColumn
.getModel() );
2569 SetList( xModel
->getPropertyValue( FM_PROP_STRINGITEMLIST
) );
2570 implAdjustGenericFieldSetting( xModel
);
2572 DbCellControl::Init( rParent
, xCursor
);
2576 void DbListBox::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& _rxModel
)
2578 DBG_ASSERT( m_pWindow
, "DbListBox::implAdjustGenericFieldSetting: not to be called without window!" );
2579 DBG_ASSERT( _rxModel
.is(), "DbListBox::implAdjustGenericFieldSetting: invalid model!" );
2580 if ( m_pWindow
&& _rxModel
.is() )
2582 sal_Int16 nLines
= getINT16( _rxModel
->getPropertyValue( FM_PROP_LINECOUNT
) );
2583 static_cast< ListBoxControl
* >( m_pWindow
.get() )->SetDropDownLineCount( nLines
);
2588 CellControllerRef
DbListBox::CreateController() const
2590 return new ListBoxCellController(static_cast<ListBoxControl
*>(m_pWindow
.get()));
2594 OUString
DbListBox::GetFormatText(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& /*xFormatter*/, Color
** /*ppColor*/)
2597 if ( _rxField
.is() )
2601 sText
= _rxField
->getString();
2604 sal_Int32 nPos
= ::comphelper::findValue( m_aValueList
, sText
);
2606 sText
= static_cast<ListBox
*>(m_pWindow
.get())->GetEntry(nPos
);
2611 catch( const Exception
& )
2613 DBG_UNHANDLED_EXCEPTION("svx");
2620 void DbListBox::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& xFormatter
)
2622 OUString
sFormattedText( GetFormatText( _rxField
, xFormatter
) );
2623 if (!sFormattedText
.isEmpty())
2624 static_cast< ListBox
* >( m_pWindow
.get() )->SelectEntry( sFormattedText
);
2626 static_cast< ListBox
* >( m_pWindow
.get() )->SetNoSelection();
2630 void DbListBox::updateFromModel( Reference
< XPropertySet
> _rxModel
)
2632 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbListBox::updateFromModel: invalid call!" );
2634 Sequence
< sal_Int16
> aSelection
;
2635 _rxModel
->getPropertyValue( FM_PROP_SELECT_SEQ
) >>= aSelection
;
2637 sal_Int16 nSelection
= -1;
2638 if ( aSelection
.hasElements() )
2639 nSelection
= aSelection
[ 0 ];
2641 ListBox
* pListBox
= static_cast< ListBox
* >( m_pWindow
.get() );
2643 if ( ( nSelection
>= 0 ) && ( nSelection
< pListBox
->GetEntryCount() ) )
2644 pListBox
->SelectEntryPos( nSelection
);
2646 pListBox
->SetNoSelection( );
2650 bool DbListBox::commitControl()
2653 Sequence
<sal_Int16
> aSelectSeq
;
2654 if (static_cast<ListBox
*>(m_pWindow
.get())->GetSelectedEntryCount())
2656 aSelectSeq
.realloc(1);
2657 *aSelectSeq
.getArray() = static_cast<sal_Int16
>(static_cast<ListBox
*>(m_pWindow
.get())->GetSelectedEntryPos());
2659 aVal
<<= aSelectSeq
;
2660 m_rColumn
.getModel()->setPropertyValue(FM_PROP_SELECT_SEQ
, aVal
);
2664 DbFilterField::DbFilterField(const Reference
< XComponentContext
>& rxContext
,DbGridColumn
& _rColumn
)
2665 :DbCellControl(_rColumn
)
2666 ,OSQLParserClient(rxContext
)
2667 ,m_nControlClass(css::form::FormComponentType::TEXTFIELD
)
2668 ,m_bFilterList(false)
2669 ,m_bFilterListFilled(false)
2672 setAlignedController( false );
2676 DbFilterField::~DbFilterField()
2678 if (m_nControlClass
== css::form::FormComponentType::CHECKBOX
)
2679 static_cast<CheckBoxControl
*>(m_pWindow
.get())->SetClickHdl( Link
<VclPtr
<CheckBox
>,void>() );
2684 void DbFilterField::PaintCell(OutputDevice
& rDev
, const tools::Rectangle
& rRect
)
2686 static const DrawTextFlags nStyle
= DrawTextFlags::Clip
| DrawTextFlags::VCenter
| DrawTextFlags::Left
;
2687 switch (m_nControlClass
)
2689 case FormComponentType::CHECKBOX
:
2690 DbCellControl::PaintCell( rDev
, rRect
);
2692 case FormComponentType::LISTBOX
:
2693 rDev
.DrawText(rRect
, static_cast<ListBox
*>(m_pWindow
.get())->GetSelectedEntry(), nStyle
);
2696 rDev
.DrawText(rRect
, m_aText
, nStyle
);
2701 void DbFilterField::SetList(const Any
& rItems
, bool bComboBox
)
2703 css::uno::Sequence
<OUString
> aTest
;
2705 if (aTest
.hasElements())
2709 ComboBox
* pField
= static_cast<ComboBox
*>(m_pWindow
.get());
2710 for (const OUString
& rString
: std::as_const(aTest
))
2711 pField
->InsertEntry(rString
);
2715 ListBox
* pField
= static_cast<ListBox
*>(m_pWindow
.get());
2716 for (const OUString
& rString
: std::as_const(aTest
))
2717 pField
->InsertEntry(rString
);
2719 m_rColumn
.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ
) >>= m_aValueList
;
2725 void DbFilterField::CreateControl(vcl::Window
* pParent
, const Reference
< css::beans::XPropertySet
>& xModel
)
2727 switch (m_nControlClass
)
2729 case css::form::FormComponentType::CHECKBOX
:
2730 m_pWindow
= VclPtr
<CheckBoxControl
>::Create(pParent
);
2731 m_pWindow
->SetPaintTransparent( true );
2732 static_cast<CheckBoxControl
*>(m_pWindow
.get())->SetClickHdl( LINK( this, DbFilterField
, OnClick
) );
2734 m_pPainter
= VclPtr
<CheckBoxControl
>::Create(pParent
);
2735 m_pPainter
->SetPaintTransparent( true );
2736 m_pPainter
->SetBackground();
2738 case css::form::FormComponentType::LISTBOX
:
2740 m_pWindow
= VclPtr
<ListBoxControl
>::Create(pParent
);
2741 sal_Int16 nLines
= ::comphelper::getINT16(xModel
->getPropertyValue(FM_PROP_LINECOUNT
));
2742 Any aItems
= xModel
->getPropertyValue(FM_PROP_STRINGITEMLIST
);
2743 SetList(aItems
, m_nControlClass
== css::form::FormComponentType::COMBOBOX
);
2744 static_cast<ListBox
*>(m_pWindow
.get())->SetDropDownLineCount(nLines
);
2746 case css::form::FormComponentType::COMBOBOX
:
2748 m_pWindow
= VclPtr
<ComboBoxControl
>::Create(pParent
);
2750 AllSettings aSettings
= m_pWindow
->GetSettings();
2751 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
2752 aStyleSettings
.SetSelectionOptions(
2753 aStyleSettings
.GetSelectionOptions() | SelectionOptions::ShowFirst
);
2754 aSettings
.SetStyleSettings(aStyleSettings
);
2755 m_pWindow
->SetSettings(aSettings
, true);
2759 sal_Int16 nLines
= ::comphelper::getINT16(xModel
->getPropertyValue(FM_PROP_LINECOUNT
));
2760 Any aItems
= xModel
->getPropertyValue(FM_PROP_STRINGITEMLIST
);
2761 SetList(aItems
, m_nControlClass
== css::form::FormComponentType::COMBOBOX
);
2762 static_cast<ComboBox
*>(m_pWindow
.get())->SetDropDownLineCount(nLines
);
2765 static_cast<ComboBox
*>(m_pWindow
.get())->SetDropDownLineCount(5);
2770 m_pWindow
= VclPtr
<Edit
>::Create(pParent
, WB_LEFT
);
2771 AllSettings aSettings
= m_pWindow
->GetSettings();
2772 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
2773 aStyleSettings
.SetSelectionOptions(
2774 aStyleSettings
.GetSelectionOptions() | SelectionOptions::ShowFirst
);
2775 aSettings
.SetStyleSettings(aStyleSettings
);
2776 m_pWindow
->SetSettings(aSettings
, true);
2782 void DbFilterField::Init( vcl::Window
& rParent
, const Reference
< XRowSet
>& xCursor
)
2784 Reference
< css::beans::XPropertySet
> xModel(m_rColumn
.getModel());
2785 m_rColumn
.SetAlignment(css::awt::TextAlign::LEFT
);
2789 m_bFilterList
= ::comphelper::hasProperty(FM_PROP_FILTERPROPOSAL
, xModel
) && ::comphelper::getBOOL(xModel
->getPropertyValue(FM_PROP_FILTERPROPOSAL
));
2791 m_nControlClass
= css::form::FormComponentType::COMBOBOX
;
2794 sal_Int16 nClassId
= ::comphelper::getINT16(xModel
->getPropertyValue(FM_PROP_CLASSID
));
2797 case FormComponentType::CHECKBOX
:
2798 case FormComponentType::LISTBOX
:
2799 case FormComponentType::COMBOBOX
:
2800 m_nControlClass
= nClassId
;
2804 m_nControlClass
= FormComponentType::COMBOBOX
;
2806 m_nControlClass
= FormComponentType::TEXTFIELD
;
2811 CreateControl( &rParent
, xModel
);
2812 DbCellControl::Init( rParent
, xCursor
);
2814 // filter cells are never readonly
2815 Edit
* pAsEdit
= dynamic_cast< Edit
* >( m_pWindow
.get() );
2817 pAsEdit
->SetReadOnly( false );
2821 CellControllerRef
DbFilterField::CreateController() const
2823 CellControllerRef xController
;
2824 switch (m_nControlClass
)
2826 case css::form::FormComponentType::CHECKBOX
:
2827 xController
= new CheckBoxCellController(static_cast<CheckBoxControl
*>(m_pWindow
.get()));
2829 case css::form::FormComponentType::LISTBOX
:
2830 xController
= new ListBoxCellController(static_cast<ListBoxControl
*>(m_pWindow
.get()));
2832 case css::form::FormComponentType::COMBOBOX
:
2833 xController
= new ComboBoxCellController(static_cast<ComboBoxControl
*>(m_pWindow
.get()));
2837 xController
= new ComboBoxCellController(static_cast<ComboBoxControl
*>(m_pWindow
.get()));
2839 xController
= new EditCellController(static_cast<Edit
*>(m_pWindow
.get()));
2845 void DbFilterField::updateFromModel( Reference
< XPropertySet
> _rxModel
)
2847 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbFilterField::updateFromModel: invalid call!" );
2849 OSL_FAIL( "DbListBox::updateFromModel: not implemented yet (how the hell did you reach this?)!" );
2850 // TODO: implement this.
2851 // remember: updateFromModel should be some kind of opposite of commitControl
2855 bool DbFilterField::commitControl()
2857 OUString
aText(m_aText
);
2858 switch (m_nControlClass
)
2860 case css::form::FormComponentType::CHECKBOX
:
2862 case css::form::FormComponentType::LISTBOX
:
2864 if (static_cast<ListBox
*>(m_pWindow
.get())->GetSelectedEntryCount())
2866 sal_Int16 nPos
= static_cast<sal_Int16
>(static_cast<ListBox
*>(m_pWindow
.get())->GetSelectedEntryPos());
2867 if ( ( nPos
>= 0 ) && ( nPos
< m_aValueList
.getLength() ) )
2868 aText
= m_aValueList
.getConstArray()[nPos
];
2871 if (m_aText
!= aText
)
2874 m_aCommitLink
.Call(*this);
2878 aText
= m_pWindow
->GetText();
2881 if (m_aText
!= aText
)
2883 // check the text with the SQL-Parser
2884 OUString
aNewText(comphelper::string::stripEnd(aText
, ' '));
2885 if (!aNewText
.isEmpty())
2888 Reference
< XNumberFormatter
> xNumberFormatter(m_rColumn
.GetParent().getNumberFormatter());
2890 std::unique_ptr
< OSQLParseNode
> pParseNode
= predicateTree(aErrorMsg
, aNewText
,xNumberFormatter
, m_rColumn
.GetField());
2891 if (pParseNode
!= nullptr)
2893 OUString aPreparedText
;
2895 css::lang::Locale aAppLocale
= Application::GetSettings().GetUILanguageTag().getLocale();
2897 Reference
< XRowSet
> xDataSourceRowSet(
2898 Reference
< XInterface
>(*m_rColumn
.GetParent().getDataSource()), UNO_QUERY
);
2899 Reference
< XConnection
> xConnection(getConnection(xDataSourceRowSet
));
2901 pParseNode
->parseNodeToPredicateStr(aPreparedText
,
2904 m_rColumn
.GetField(),
2909 m_aText
= aPreparedText
;
2914 SQLException aError
;
2915 aError
.Message
= aErrorMsg
;
2916 displayException(aError
, m_pWindow
->GetParent());
2917 // TODO: transport the title
2925 m_pWindow
->SetText(m_aText
);
2926 m_aCommitLink
.Call(*this);
2932 void DbFilterField::SetText(const OUString
& rText
)
2935 switch (m_nControlClass
)
2937 case css::form::FormComponentType::CHECKBOX
:
2941 eState
= TRISTATE_TRUE
;
2942 else if (rText
== "0")
2943 eState
= TRISTATE_FALSE
;
2945 eState
= TRISTATE_INDET
;
2947 static_cast<CheckBoxControl
*>(m_pWindow
.get())->GetBox().SetState(eState
);
2948 static_cast<CheckBoxControl
*>(m_pPainter
.get())->GetBox().SetState(eState
);
2950 case css::form::FormComponentType::LISTBOX
:
2952 sal_Int32 nPos
= ::comphelper::findValue(m_aValueList
, m_aText
);
2954 static_cast<ListBox
*>(m_pWindow
.get())->SelectEntryPos(nPos
);
2956 static_cast<ListBox
*>(m_pWindow
.get())->SetNoSelection();
2959 m_pWindow
->SetText(m_aText
);
2962 // now force a repaint on the window
2963 m_rColumn
.GetParent().RowModified(0);
2967 void DbFilterField::Update()
2969 // should we fill the combobox with a filter proposal?
2970 if (!m_bFilterList
|| m_bFilterListFilled
)
2973 m_bFilterListFilled
= true;
2974 Reference
< css::beans::XPropertySet
> xField
= m_rColumn
.GetField();
2979 xField
->getPropertyValue(FM_PROP_NAME
) >>= aName
;
2982 Reference
< css::container::XChild
> xModelAsChild(m_rColumn
.getModel(), UNO_QUERY
);
2984 xModelAsChild
.set(xModelAsChild
->getParent(),UNO_QUERY
);
2985 Reference
< XRowSet
> xForm(xModelAsChild
->getParent(), UNO_QUERY
);
2989 Reference
<XPropertySet
> xFormProp(xForm
,UNO_QUERY
);
2990 Reference
< XTablesSupplier
> xSupTab
;
2991 xFormProp
->getPropertyValue("SingleSelectQueryComposer") >>= xSupTab
;
2993 Reference
< XConnection
> xConnection(getConnection(xForm
));
2998 Reference
< XColumnsSupplier
> xSupCol(xSupTab
,UNO_QUERY
);
2999 Reference
< css::container::XNameAccess
> xFieldNames
= xSupCol
->getColumns();
3000 if (!xFieldNames
->hasByName(aName
))
3003 Reference
< css::container::XNameAccess
> xTablesNames
= xSupTab
->getTables();
3004 Reference
< css::beans::XPropertySet
> xComposerFieldAsSet(xFieldNames
->getByName(aName
),UNO_QUERY
);
3006 if (!xComposerFieldAsSet
.is() ||
3007 !::comphelper::hasProperty(FM_PROP_TABLENAME
, xComposerFieldAsSet
) ||
3008 !::comphelper::hasProperty(FM_PROP_FIELDSOURCE
, xComposerFieldAsSet
))
3011 OUString aFieldName
;
3012 OUString aTableName
;
3013 xComposerFieldAsSet
->getPropertyValue(FM_PROP_FIELDSOURCE
) >>= aFieldName
;
3014 xComposerFieldAsSet
->getPropertyValue(FM_PROP_TABLENAME
) >>= aTableName
;
3016 // no possibility to create a select statement
3017 // looking for the complete table name
3018 if (!xTablesNames
->hasByName(aTableName
))
3021 // build a statement and send as query;
3022 // Access to the connection
3023 Reference
< XStatement
> xStatement
;
3024 Reference
< XResultSet
> xListCursor
;
3025 Reference
< css::sdb::XColumn
> xDataField
;
3029 Reference
< XDatabaseMetaData
> xMeta
= xConnection
->getMetaData();
3031 OUString
aQuote(xMeta
->getIdentifierQuoteString());
3032 OUStringBuffer
aStatement("SELECT DISTINCT ");
3033 aStatement
.append(quoteName(aQuote
, aName
));
3034 if (!aFieldName
.isEmpty() && aName
!= aFieldName
)
3036 aStatement
.append(" AS ");
3037 aStatement
.append(quoteName(aQuote
, aFieldName
));
3040 aStatement
.append(" FROM ");
3042 Reference
< XPropertySet
> xTableNameAccess(xTablesNames
->getByName(aTableName
), UNO_QUERY_THROW
);
3043 aStatement
.append(composeTableNameForSelect(xConnection
, xTableNameAccess
));
3045 xStatement
= xConnection
->createStatement();
3046 Reference
< css::beans::XPropertySet
> xStatementProps(xStatement
, UNO_QUERY
);
3047 xStatementProps
->setPropertyValue(FM_PROP_ESCAPE_PROCESSING
, makeAny(true));
3049 xListCursor
= xStatement
->executeQuery(aStatement
.makeStringAndClear());
3051 Reference
< css::sdbcx::XColumnsSupplier
> xSupplyCols(xListCursor
, UNO_QUERY
);
3052 Reference
< css::container::XIndexAccess
> xFields(xSupplyCols
->getColumns(), UNO_QUERY
);
3053 xDataField
.set(xFields
->getByIndex(0), css::uno::UNO_QUERY
);
3054 if (!xDataField
.is())
3057 catch(const Exception
&)
3059 ::comphelper::disposeComponent(xStatement
);
3064 ::std::vector
< OUString
> aStringList
;
3065 aStringList
.reserve(16);
3067 css::util::Date aNullDate
= m_rColumn
.GetParent().getNullDate();
3068 sal_Int32 nFormatKey
= m_rColumn
.GetKey();
3069 Reference
< XNumberFormatter
> xFormatter
= m_rColumn
.GetParent().getNumberFormatter();
3070 sal_Int16 nKeyType
= ::comphelper::getNumberFormatType(xFormatter
->getNumberFormatsSupplier()->getNumberFormats(), nFormatKey
);
3072 while (!xListCursor
->isAfterLast() && i
++ < SHRT_MAX
) // max number of entries
3074 aStr
= getFormattedValue(xDataField
, xFormatter
, aNullDate
, nFormatKey
, nKeyType
);
3075 aStringList
.push_back(aStr
);
3076 (void)xListCursor
->next();
3079 // filling the entries for the combobox
3080 for (const auto& rString
: aStringList
)
3081 static_cast<ComboBox
*>(m_pWindow
.get())->InsertEntry(rString
);
3085 OUString
DbFilterField::GetFormatText(const Reference
< XColumn
>& /*_rxField*/, const Reference
< XNumberFormatter
>& /*xFormatter*/, Color
** /*ppColor*/)
3091 void DbFilterField::UpdateFromField(const Reference
< XColumn
>& /*_rxField*/, const Reference
< XNumberFormatter
>& /*xFormatter*/)
3093 OSL_FAIL( "DbFilterField::UpdateFromField: cannot update a filter control from a field!" );
3097 IMPL_LINK_NOARG(DbFilterField
, OnClick
, VclPtr
<CheckBox
>, void)
3099 TriState eState
= static_cast<CheckBoxControl
*>(m_pWindow
.get())->GetBox().GetState();
3100 OUStringBuffer aTextBuf
;
3102 Reference
< XRowSet
> xDataSourceRowSet(
3103 Reference
< XInterface
>(*m_rColumn
.GetParent().getDataSource()), UNO_QUERY
);
3104 Reference
< XConnection
> xConnection(getConnection(xDataSourceRowSet
));
3105 const sal_Int32 nBooleanComparisonMode
= ::dbtools::DatabaseMetaData( xConnection
).getBooleanComparisonMode();
3110 ::dbtools::getBooleanComparisonPredicate("", true, nBooleanComparisonMode
, aTextBuf
);
3112 case TRISTATE_FALSE
:
3113 ::dbtools::getBooleanComparisonPredicate("", false, nBooleanComparisonMode
, aTextBuf
);
3115 case TRISTATE_INDET
:
3119 const OUString
aText(aTextBuf
.makeStringAndClear());
3121 if (m_aText
!= aText
)
3124 m_aCommitLink
.Call(*this);
3129 FmXGridCell::FmXGridCell( DbGridColumn
* pColumn
, std::unique_ptr
<DbCellControl
> _pControl
)
3130 :OComponentHelper(m_aMutex
)
3132 ,m_pCellControl( std::move(_pControl
) )
3133 ,m_aWindowListeners( m_aMutex
)
3134 ,m_aFocusListeners( m_aMutex
)
3135 ,m_aKeyListeners( m_aMutex
)
3136 ,m_aMouseListeners( m_aMutex
)
3137 ,m_aMouseMotionListeners( m_aMutex
)
3142 void FmXGridCell::init()
3144 vcl::Window
* pEventWindow( getEventWindow() );
3146 pEventWindow
->AddEventListener( LINK( this, FmXGridCell
, OnWindowEvent
) );
3150 vcl::Window
* FmXGridCell::getEventWindow() const
3152 if ( m_pCellControl
)
3153 return &m_pCellControl
->GetWindow();
3158 FmXGridCell::~FmXGridCell()
3160 if (!OComponentHelper::rBHelper
.bDisposed
)
3169 void FmXGridCell::SetTextLineColor()
3172 m_pCellControl
->SetTextLineColor();
3176 void FmXGridCell::SetTextLineColor(const Color
& _rColor
)
3179 m_pCellControl
->SetTextLineColor(_rColor
);
3184 Sequence
< Type
> SAL_CALL
FmXGridCell::getTypes( )
3186 Sequence
< uno::Type
> aTypes
= ::comphelper::concatSequences(
3187 ::cppu::OComponentHelper::getTypes(),
3188 FmXGridCell_Base::getTypes()
3190 if ( m_pCellControl
)
3191 aTypes
= ::comphelper::concatSequences(
3193 FmXGridCell_WindowBase::getTypes()
3199 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXGridCell
)
3203 void FmXGridCell::disposing()
3205 lang::EventObject
aEvent( *this );
3206 m_aWindowListeners
.disposeAndClear( aEvent
);
3207 m_aFocusListeners
.disposeAndClear( aEvent
);
3208 m_aKeyListeners
.disposeAndClear( aEvent
);
3209 m_aMouseListeners
.disposeAndClear( aEvent
);
3210 m_aMouseMotionListeners
.disposeAndClear( aEvent
);
3212 OComponentHelper::disposing();
3213 m_pColumn
= nullptr;
3214 m_pCellControl
.reset();
3218 Any SAL_CALL
FmXGridCell::queryAggregation( const css::uno::Type
& _rType
)
3220 Any aReturn
= OComponentHelper::queryAggregation( _rType
);
3222 if ( !aReturn
.hasValue() )
3223 aReturn
= FmXGridCell_Base::queryInterface( _rType
);
3225 if ( !aReturn
.hasValue() && ( m_pCellControl
!= nullptr ) )
3226 aReturn
= FmXGridCell_WindowBase::queryInterface( _rType
);
3231 // css::awt::XControl
3233 Reference
< XInterface
> FmXGridCell::getContext()
3235 return Reference
< XInterface
> ();
3239 Reference
< css::awt::XControlModel
> FmXGridCell::getModel()
3241 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3242 return Reference
< css::awt::XControlModel
> (m_pColumn
->getModel(), UNO_QUERY
);
3245 // css::form::XBoundControl
3247 sal_Bool
FmXGridCell::getLock()
3249 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3250 return m_pColumn
->isLocked();
3254 void FmXGridCell::setLock(sal_Bool _bLock
)
3256 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3257 if (getLock() == _bLock
)
3261 ::osl::MutexGuard
aGuard(m_aMutex
);
3262 m_pColumn
->setLock(_bLock
);
3267 void SAL_CALL
FmXGridCell::setPosSize( ::sal_Int32
, ::sal_Int32
, ::sal_Int32
, ::sal_Int32
, ::sal_Int16
)
3269 OSL_FAIL( "FmXGridCell::setPosSize: not implemented" );
3270 // not allowed to tamper with this for a grid cell
3274 awt::Rectangle SAL_CALL
FmXGridCell::getPosSize( )
3276 OSL_FAIL( "FmXGridCell::getPosSize: not implemented" );
3277 return awt::Rectangle();
3281 void SAL_CALL
FmXGridCell::setVisible( sal_Bool
)
3283 OSL_FAIL( "FmXGridCell::setVisible: not implemented" );
3284 // not allowed to tamper with this for a grid cell
3288 void SAL_CALL
FmXGridCell::setEnable( sal_Bool
)
3290 OSL_FAIL( "FmXGridCell::setEnable: not implemented" );
3291 // not allowed to tamper with this for a grid cell
3295 void SAL_CALL
FmXGridCell::setFocus( )
3297 OSL_FAIL( "FmXGridCell::setFocus: not implemented" );
3298 // not allowed to tamper with this for a grid cell
3302 void SAL_CALL
FmXGridCell::addWindowListener( const Reference
< awt::XWindowListener
>& _rxListener
)
3304 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3305 m_aWindowListeners
.addInterface( _rxListener
);
3309 void SAL_CALL
FmXGridCell::removeWindowListener( const Reference
< awt::XWindowListener
>& _rxListener
)
3311 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3312 m_aWindowListeners
.removeInterface( _rxListener
);
3316 void SAL_CALL
FmXGridCell::addFocusListener( const Reference
< awt::XFocusListener
>& _rxListener
)
3318 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3319 m_aFocusListeners
.addInterface( _rxListener
);
3323 void SAL_CALL
FmXGridCell::removeFocusListener( const Reference
< awt::XFocusListener
>& _rxListener
)
3325 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3326 m_aFocusListeners
.removeInterface( _rxListener
);
3330 void SAL_CALL
FmXGridCell::addKeyListener( const Reference
< awt::XKeyListener
>& _rxListener
)
3332 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3333 m_aKeyListeners
.addInterface( _rxListener
);
3337 void SAL_CALL
FmXGridCell::removeKeyListener( const Reference
< awt::XKeyListener
>& _rxListener
)
3339 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3340 m_aKeyListeners
.removeInterface( _rxListener
);
3344 void SAL_CALL
FmXGridCell::addMouseListener( const Reference
< awt::XMouseListener
>& _rxListener
)
3346 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3347 m_aMouseListeners
.addInterface( _rxListener
);
3351 void SAL_CALL
FmXGridCell::removeMouseListener( const Reference
< awt::XMouseListener
>& _rxListener
)
3353 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3354 m_aMouseListeners
.removeInterface( _rxListener
);
3358 void SAL_CALL
FmXGridCell::addMouseMotionListener( const Reference
< awt::XMouseMotionListener
>& _rxListener
)
3360 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3361 m_aMouseMotionListeners
.addInterface( _rxListener
);
3365 void SAL_CALL
FmXGridCell::removeMouseMotionListener( const Reference
< awt::XMouseMotionListener
>& _rxListener
)
3367 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3368 m_aMouseMotionListeners
.removeInterface( _rxListener
);
3372 void SAL_CALL
FmXGridCell::addPaintListener( const Reference
< awt::XPaintListener
>& )
3374 OSL_FAIL( "FmXGridCell::addPaintListener: not implemented" );
3378 void SAL_CALL
FmXGridCell::removePaintListener( const Reference
< awt::XPaintListener
>& )
3380 OSL_FAIL( "FmXGridCell::removePaintListener: not implemented" );
3384 IMPL_LINK( FmXGridCell
, OnWindowEvent
, VclWindowEvent
&, _rEvent
, void )
3386 ENSURE_OR_THROW( _rEvent
.GetWindow(), "illegal window" );
3387 onWindowEvent( _rEvent
.GetId(), *_rEvent
.GetWindow(), _rEvent
.GetData() );
3391 void FmXGridCell::onFocusGained( const awt::FocusEvent
& _rEvent
)
3393 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3394 m_aFocusListeners
.notifyEach( &awt::XFocusListener::focusGained
, _rEvent
);
3398 void FmXGridCell::onFocusLost( const awt::FocusEvent
& _rEvent
)
3400 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3401 m_aFocusListeners
.notifyEach( &awt::XFocusListener::focusLost
, _rEvent
);
3405 void FmXGridCell::onWindowEvent( const VclEventId _nEventId
, const vcl::Window
& _rWindow
, const void* _pEventData
)
3407 switch ( _nEventId
)
3409 case VclEventId::ControlGetFocus
:
3410 case VclEventId::WindowGetFocus
:
3411 case VclEventId::ControlLoseFocus
:
3412 case VclEventId::WindowLoseFocus
:
3414 if ( ( _rWindow
.IsCompoundControl()
3415 && ( _nEventId
== VclEventId::ControlGetFocus
3416 || _nEventId
== VclEventId::ControlLoseFocus
3419 || ( !_rWindow
.IsCompoundControl()
3420 && ( _nEventId
== VclEventId::WindowGetFocus
3421 || _nEventId
== VclEventId::WindowLoseFocus
3426 if ( !m_aFocusListeners
.getLength() )
3429 bool bFocusGained
= ( _nEventId
== VclEventId::ControlGetFocus
) || ( _nEventId
== VclEventId::WindowGetFocus
);
3431 awt::FocusEvent aEvent
;
3432 aEvent
.Source
= *this;
3433 aEvent
.FocusFlags
= static_cast<sal_Int16
>(_rWindow
.GetGetFocusFlags());
3434 aEvent
.Temporary
= false;
3437 onFocusGained( aEvent
);
3439 onFocusLost( aEvent
);
3443 case VclEventId::WindowMouseButtonDown
:
3444 case VclEventId::WindowMouseButtonUp
:
3446 if ( !m_aMouseListeners
.getLength() )
3449 const bool bButtonDown
= ( _nEventId
== VclEventId::WindowMouseButtonDown
);
3451 awt::MouseEvent
aEvent( VCLUnoHelper::createMouseEvent( *static_cast< const ::MouseEvent
* >( _pEventData
), *this ) );
3452 m_aMouseListeners
.notifyEach( bButtonDown
? &awt::XMouseListener::mousePressed
: &awt::XMouseListener::mouseReleased
, aEvent
);
3455 case VclEventId::WindowMouseMove
:
3457 const MouseEvent
& rMouseEvent
= *static_cast< const ::MouseEvent
* >( _pEventData
);
3458 if ( rMouseEvent
.IsEnterWindow() || rMouseEvent
.IsLeaveWindow() )
3460 if ( m_aMouseListeners
.getLength() != 0 )
3462 awt::MouseEvent
aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent
, *this ) );
3463 m_aMouseListeners
.notifyEach( rMouseEvent
.IsEnterWindow() ? &awt::XMouseListener::mouseEntered
: &awt::XMouseListener::mouseExited
, aEvent
);
3466 else if ( !rMouseEvent
.IsEnterWindow() && !rMouseEvent
.IsLeaveWindow() )
3468 if ( m_aMouseMotionListeners
.getLength() != 0 )
3470 awt::MouseEvent
aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent
, *this ) );
3471 aEvent
.ClickCount
= 0;
3472 const bool bSimpleMove
= bool( rMouseEvent
.GetMode() & MouseEventModifiers::SIMPLEMOVE
);
3473 m_aMouseMotionListeners
.notifyEach( bSimpleMove
? &awt::XMouseMotionListener::mouseMoved
: &awt::XMouseMotionListener::mouseDragged
, aEvent
);
3478 case VclEventId::WindowKeyInput
:
3479 case VclEventId::WindowKeyUp
:
3481 if ( !m_aKeyListeners
.getLength() )
3484 const bool bKeyPressed
= ( _nEventId
== VclEventId::WindowKeyInput
);
3485 awt::KeyEvent
aEvent( VCLUnoHelper::createKeyEvent( *static_cast< const ::KeyEvent
* >( _pEventData
), *this ) );
3486 m_aKeyListeners
.notifyEach( bKeyPressed
? &awt::XKeyListener::keyPressed
: &awt::XKeyListener::keyReleased
, aEvent
);
3494 void FmXDataCell::PaintFieldToCell(OutputDevice
& rDev
, const tools::Rectangle
& rRect
,
3495 const Reference
< css::sdb::XColumn
>& _rxField
,
3496 const Reference
< XNumberFormatter
>& xFormatter
)
3498 m_pCellControl
->PaintFieldToCell( rDev
, rRect
, _rxField
, xFormatter
);
3502 void FmXDataCell::UpdateFromColumn()
3504 Reference
< css::sdb::XColumn
> xField(m_pColumn
->GetCurrentFieldValue());
3506 m_pCellControl
->UpdateFromField(xField
, m_pColumn
->GetParent().getNumberFormatter());
3510 FmXTextCell::FmXTextCell( DbGridColumn
* pColumn
, std::unique_ptr
<DbCellControl
> pControl
)
3511 :FmXDataCell( pColumn
, std::move(pControl
) )
3512 ,m_bFastPaint( true )
3517 void FmXTextCell::PaintFieldToCell(OutputDevice
& rDev
,
3518 const tools::Rectangle
& rRect
,
3519 const Reference
< css::sdb::XColumn
>& _rxField
,
3520 const Reference
< XNumberFormatter
>& xFormatter
)
3522 if ( !m_bFastPaint
)
3524 FmXDataCell::PaintFieldToCell( rDev
, rRect
, _rxField
, xFormatter
);
3528 DrawTextFlags nStyle
= DrawTextFlags::Clip
| DrawTextFlags::VCenter
;
3529 if ( ( rDev
.GetOutDevType() == OUTDEV_WINDOW
) && !static_cast< vcl::Window
& >( rDev
).IsEnabled() )
3530 nStyle
|= DrawTextFlags::Disable
;
3532 switch (m_pColumn
->GetAlignment())
3534 case css::awt::TextAlign::RIGHT
:
3535 nStyle
|= DrawTextFlags::Right
;
3537 case css::awt::TextAlign::CENTER
:
3538 nStyle
|= DrawTextFlags::Center
;
3541 nStyle
|= DrawTextFlags::Left
;
3546 Color
* pColor
= nullptr;
3547 OUString aText
= GetText(_rxField
, xFormatter
, &pColor
);
3548 if (pColor
!= nullptr)
3550 Color
aOldTextColor( rDev
.GetTextColor() );
3551 rDev
.SetTextColor( *pColor
);
3552 rDev
.DrawText(rRect
, aText
, nStyle
);
3553 rDev
.SetTextColor( aOldTextColor
);
3556 rDev
.DrawText(rRect
, aText
, nStyle
);
3558 catch (const Exception
&)
3560 TOOLS_WARN_EXCEPTION("svx.fmcomp", "PaintFieldToCell");
3564 FmXEditCell::FmXEditCell( DbGridColumn
* pColumn
, std::unique_ptr
<DbCellControl
> pControl
)
3565 :FmXTextCell( pColumn
, std::move(pControl
) )
3566 ,m_aTextListeners(m_aMutex
)
3567 ,m_aChangeListeners( m_aMutex
)
3568 ,m_pEditImplementation( nullptr )
3569 ,m_bOwnEditImplementation( false )
3572 DbTextField
* pTextField
= dynamic_cast<DbTextField
*>( m_pCellControl
.get() );
3576 m_pEditImplementation
= pTextField
->GetEditImplementation();
3577 if ( !pTextField
->IsSimpleEdit() )
3578 m_bFastPaint
= false;
3582 m_pEditImplementation
= new EditImplementation( static_cast< Edit
& >( m_pCellControl
->GetWindow() ) );
3583 m_bOwnEditImplementation
= true;
3588 FmXEditCell::~FmXEditCell()
3590 if (!OComponentHelper::rBHelper
.bDisposed
)
3601 void FmXEditCell::disposing()
3603 css::lang::EventObject
aEvt(*this);
3604 m_aTextListeners
.disposeAndClear(aEvt
);
3605 m_aChangeListeners
.disposeAndClear(aEvt
);
3607 m_pEditImplementation
->SetModifyHdl( Link
<Edit
&,void>() );
3608 if ( m_bOwnEditImplementation
)
3609 delete m_pEditImplementation
;
3610 m_pEditImplementation
= nullptr;
3612 FmXDataCell::disposing();
3616 Any SAL_CALL
FmXEditCell::queryAggregation( const css::uno::Type
& _rType
)
3618 Any aReturn
= FmXTextCell::queryAggregation( _rType
);
3620 if ( !aReturn
.hasValue() )
3621 aReturn
= FmXEditCell_Base::queryInterface( _rType
);
3627 Sequence
< css::uno::Type
> SAL_CALL
FmXEditCell::getTypes( )
3629 return ::comphelper::concatSequences(
3630 FmXTextCell::getTypes(),
3631 FmXEditCell_Base::getTypes()
3636 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXEditCell
)
3638 // css::awt::XTextComponent
3640 void SAL_CALL
FmXEditCell::addTextListener(const Reference
< css::awt::XTextListener
>& l
)
3642 m_aTextListeners
.addInterface( l
);
3646 void SAL_CALL
FmXEditCell::removeTextListener(const Reference
< css::awt::XTextListener
>& l
)
3648 m_aTextListeners
.removeInterface( l
);
3652 void SAL_CALL
FmXEditCell::setText( const OUString
& aText
)
3654 ::osl::MutexGuard
aGuard( m_aMutex
);
3656 if ( m_pEditImplementation
)
3658 m_pEditImplementation
->SetText( aText
);
3660 // In Java, a textChanged is fired as well; not in VCL.
3661 // css::awt::Toolkit must be Java-compliant...
3667 void SAL_CALL
FmXEditCell::insertText(const css::awt::Selection
& rSel
, const OUString
& aText
)
3669 ::osl::MutexGuard
aGuard( m_aMutex
);
3671 if ( m_pEditImplementation
)
3673 m_pEditImplementation
->SetSelection( Selection( rSel
.Min
, rSel
.Max
) );
3674 m_pEditImplementation
->ReplaceSelected( aText
);
3679 OUString SAL_CALL
FmXEditCell::getText()
3681 ::osl::MutexGuard
aGuard( m_aMutex
);
3684 if ( m_pEditImplementation
)
3686 if ( m_pEditImplementation
->GetControl().IsVisible() && m_pColumn
->GetParent().getDisplaySynchron())
3688 // if the display isn't sync with the cursor we can't ask the edit field
3689 LineEnd eLineEndFormat
= getModelLineEndSetting( m_pColumn
->getModel() );
3690 aText
= m_pEditImplementation
->GetText( eLineEndFormat
);
3694 Reference
< css::sdb::XColumn
> xField(m_pColumn
->GetCurrentFieldValue());
3696 aText
= GetText(xField
, m_pColumn
->GetParent().getNumberFormatter());
3703 OUString SAL_CALL
FmXEditCell::getSelectedText()
3705 ::osl::MutexGuard
aGuard( m_aMutex
);
3708 if ( m_pEditImplementation
)
3710 LineEnd eLineEndFormat
= m_pColumn
? getModelLineEndSetting( m_pColumn
->getModel() ) : LINEEND_LF
;
3711 aText
= m_pEditImplementation
->GetSelected( eLineEndFormat
);
3717 void SAL_CALL
FmXEditCell::setSelection( const css::awt::Selection
& aSelection
)
3719 ::osl::MutexGuard
aGuard( m_aMutex
);
3721 if ( m_pEditImplementation
)
3722 m_pEditImplementation
->SetSelection( Selection( aSelection
.Min
, aSelection
.Max
) );
3726 css::awt::Selection SAL_CALL
FmXEditCell::getSelection()
3728 ::osl::MutexGuard
aGuard( m_aMutex
);
3731 if ( m_pEditImplementation
)
3732 aSel
= m_pEditImplementation
->GetSelection();
3734 return css::awt::Selection(aSel
.Min(), aSel
.Max());
3738 sal_Bool SAL_CALL
FmXEditCell::isEditable()
3740 ::osl::MutexGuard
aGuard( m_aMutex
);
3742 return m_pEditImplementation
&& !m_pEditImplementation
->IsReadOnly() && m_pEditImplementation
->GetControl().IsEnabled();
3746 void SAL_CALL
FmXEditCell::setEditable( sal_Bool bEditable
)
3748 ::osl::MutexGuard
aGuard( m_aMutex
);
3750 if ( m_pEditImplementation
)
3751 m_pEditImplementation
->SetReadOnly( !bEditable
);
3755 sal_Int16 SAL_CALL
FmXEditCell::getMaxTextLen()
3757 ::osl::MutexGuard
aGuard( m_aMutex
);
3759 return m_pEditImplementation
? m_pEditImplementation
->GetMaxTextLen() : 0;
3763 void SAL_CALL
FmXEditCell::setMaxTextLen( sal_Int16 nLen
)
3765 ::osl::MutexGuard
aGuard( m_aMutex
);
3767 if ( m_pEditImplementation
)
3768 m_pEditImplementation
->SetMaxTextLen( nLen
);
3772 void SAL_CALL
FmXEditCell::addChangeListener( const Reference
< form::XChangeListener
>& Listener
)
3774 m_aChangeListeners
.addInterface( Listener
);
3778 void SAL_CALL
FmXEditCell::removeChangeListener( const Reference
< form::XChangeListener
>& Listener
)
3780 m_aChangeListeners
.removeInterface( Listener
);
3784 void FmXEditCell::onTextChanged()
3786 css::awt::TextEvent aEvent
;
3787 aEvent
.Source
= *this;
3788 m_aTextListeners
.notifyEach( &awt::XTextListener::textChanged
, aEvent
);
3792 void FmXEditCell::onFocusGained( const awt::FocusEvent
& _rEvent
)
3794 FmXTextCell::onFocusGained( _rEvent
);
3795 m_sValueOnEnter
= getText();
3799 void FmXEditCell::onFocusLost( const awt::FocusEvent
& _rEvent
)
3801 FmXTextCell::onFocusLost( _rEvent
);
3803 if ( getText() != m_sValueOnEnter
)
3805 lang::EventObject
aEvent( *this );
3806 m_aChangeListeners
.notifyEach( &XChangeListener::changed
, aEvent
);
3811 void FmXEditCell::onWindowEvent( const VclEventId _nEventId
, const vcl::Window
& _rWindow
, const void* _pEventData
)
3813 switch ( _nEventId
)
3815 case VclEventId::EditModify
:
3817 if ( m_pEditImplementation
&& m_aTextListeners
.getLength() )
3824 FmXTextCell::onWindowEvent( _nEventId
, _rWindow
, _pEventData
);
3827 FmXCheckBoxCell::FmXCheckBoxCell( DbGridColumn
* pColumn
, std::unique_ptr
<DbCellControl
> pControl
)
3828 :FmXDataCell( pColumn
, std::move(pControl
) )
3829 ,m_aItemListeners(m_aMutex
)
3830 ,m_aActionListeners( m_aMutex
)
3831 ,m_pBox( & static_cast< CheckBoxControl
& >( m_pCellControl
->GetWindow() ).GetBox() )
3836 FmXCheckBoxCell::~FmXCheckBoxCell()
3838 if (!OComponentHelper::rBHelper
.bDisposed
)
3848 void FmXCheckBoxCell::disposing()
3850 css::lang::EventObject
aEvt(*this);
3851 m_aItemListeners
.disposeAndClear(aEvt
);
3852 m_aActionListeners
.disposeAndClear(aEvt
);
3854 static_cast< CheckBoxControl
& >( m_pCellControl
->GetWindow() ).SetClickHdl(Link
<VclPtr
<CheckBox
>,void>());
3857 FmXDataCell::disposing();
3861 Any SAL_CALL
FmXCheckBoxCell::queryAggregation( const css::uno::Type
& _rType
)
3863 Any aReturn
= FmXDataCell::queryAggregation( _rType
);
3865 if ( !aReturn
.hasValue() )
3866 aReturn
= FmXCheckBoxCell_Base::queryInterface( _rType
);
3872 Sequence
< css::uno::Type
> SAL_CALL
FmXCheckBoxCell::getTypes( )
3874 return ::comphelper::concatSequences(
3875 FmXDataCell::getTypes(),
3876 FmXCheckBoxCell_Base::getTypes()
3881 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXCheckBoxCell
)
3884 void SAL_CALL
FmXCheckBoxCell::addItemListener( const Reference
< css::awt::XItemListener
>& l
)
3886 m_aItemListeners
.addInterface( l
);
3890 void SAL_CALL
FmXCheckBoxCell::removeItemListener( const Reference
< css::awt::XItemListener
>& l
)
3892 m_aItemListeners
.removeInterface( l
);
3896 void SAL_CALL
FmXCheckBoxCell::setState( sal_Int16 n
)
3898 ::osl::MutexGuard
aGuard( m_aMutex
);
3903 m_pBox
->SetState( static_cast<TriState
>(n
) );
3908 sal_Int16 SAL_CALL
FmXCheckBoxCell::getState()
3910 ::osl::MutexGuard
aGuard( m_aMutex
);
3915 return static_cast<sal_Int16
>(m_pBox
->GetState());
3917 return TRISTATE_INDET
;
3921 void SAL_CALL
FmXCheckBoxCell::enableTriState( sal_Bool b
)
3923 ::osl::MutexGuard
aGuard( m_aMutex
);
3926 m_pBox
->EnableTriState( b
);
3930 void SAL_CALL
FmXCheckBoxCell::addActionListener( const Reference
< awt::XActionListener
>& Listener
)
3932 m_aActionListeners
.addInterface( Listener
);
3936 void SAL_CALL
FmXCheckBoxCell::removeActionListener( const Reference
< awt::XActionListener
>& Listener
)
3938 m_aActionListeners
.removeInterface( Listener
);
3942 void SAL_CALL
FmXCheckBoxCell::setLabel( const OUString
& Label
)
3944 SolarMutexGuard aGuard
;
3947 DbGridControl
& rGrid( m_pColumn
->GetParent() );
3948 rGrid
.SetColumnTitle( rGrid
.GetColumnId( m_pColumn
->GetFieldPos() ), Label
);
3953 void SAL_CALL
FmXCheckBoxCell::setActionCommand( const OUString
& Command
)
3955 m_aActionCommand
= Command
;
3959 vcl::Window
* FmXCheckBoxCell::getEventWindow() const
3965 void FmXCheckBoxCell::onWindowEvent( const VclEventId _nEventId
, const vcl::Window
& _rWindow
, const void* _pEventData
)
3967 switch ( _nEventId
)
3969 case VclEventId::CheckboxToggle
:
3971 // check boxes are to be committed immediately (this holds for ordinary check box controls in
3972 // documents, and this must hold for check boxes in grid columns, too
3973 // 91210 - 22.08.2001 - frank.schoenheit@sun.com
3974 m_pCellControl
->Commit();
3976 Reference
< XWindow
> xKeepAlive( this );
3977 if ( m_aItemListeners
.getLength() && m_pBox
)
3979 awt::ItemEvent aEvent
;
3980 aEvent
.Source
= *this;
3981 aEvent
.Highlighted
= 0;
3982 aEvent
.Selected
= m_pBox
->GetState();
3983 m_aItemListeners
.notifyEach( &awt::XItemListener::itemStateChanged
, aEvent
);
3985 if ( m_aActionListeners
.getLength() )
3987 awt::ActionEvent aEvent
;
3988 aEvent
.Source
= *this;
3989 aEvent
.ActionCommand
= m_aActionCommand
;
3990 m_aActionListeners
.notifyEach( &awt::XActionListener::actionPerformed
, aEvent
);
3996 FmXDataCell::onWindowEvent( _nEventId
, _rWindow
, _pEventData
);
4001 FmXListBoxCell::FmXListBoxCell(DbGridColumn
* pColumn
, std::unique_ptr
<DbCellControl
> pControl
)
4002 :FmXTextCell( pColumn
, std::move(pControl
) )
4003 ,m_aItemListeners(m_aMutex
)
4004 ,m_aActionListeners(m_aMutex
)
4005 ,m_pBox( &static_cast< ListBox
& >( m_pCellControl
->GetWindow() ) )
4008 m_pBox
->SetDoubleClickHdl( LINK( this, FmXListBoxCell
, OnDoubleClick
) );
4012 FmXListBoxCell::~FmXListBoxCell()
4014 if (!OComponentHelper::rBHelper
.bDisposed
)
4024 void FmXListBoxCell::disposing()
4026 css::lang::EventObject
aEvt(*this);
4027 m_aItemListeners
.disposeAndClear(aEvt
);
4028 m_aActionListeners
.disposeAndClear(aEvt
);
4030 m_pBox
->SetSelectHdl( Link
<ListBox
&,void>() );
4031 m_pBox
->SetDoubleClickHdl( Link
<ListBox
&,void>() );
4034 FmXTextCell::disposing();
4038 Any SAL_CALL
FmXListBoxCell::queryAggregation( const css::uno::Type
& _rType
)
4040 Any aReturn
= FmXTextCell::queryAggregation(_rType
);
4042 if ( !aReturn
.hasValue() )
4043 aReturn
= FmXListBoxCell_Base::queryInterface( _rType
);
4049 Sequence
< css::uno::Type
> SAL_CALL
FmXListBoxCell::getTypes( )
4051 return ::comphelper::concatSequences(
4052 FmXTextCell::getTypes(),
4053 FmXListBoxCell_Base::getTypes()
4058 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXListBoxCell
)
4061 void SAL_CALL
FmXListBoxCell::addItemListener(const Reference
< css::awt::XItemListener
>& l
)
4063 m_aItemListeners
.addInterface( l
);
4067 void SAL_CALL
FmXListBoxCell::removeItemListener(const Reference
< css::awt::XItemListener
>& l
)
4069 m_aItemListeners
.removeInterface( l
);
4073 void SAL_CALL
FmXListBoxCell::addActionListener(const Reference
< css::awt::XActionListener
>& l
)
4075 m_aActionListeners
.addInterface( l
);
4079 void SAL_CALL
FmXListBoxCell::removeActionListener(const Reference
< css::awt::XActionListener
>& l
)
4081 m_aActionListeners
.removeInterface( l
);
4085 void SAL_CALL
FmXListBoxCell::addItem(const OUString
& aItem
, sal_Int16 nPos
)
4087 ::osl::MutexGuard
aGuard( m_aMutex
);
4089 m_pBox
->InsertEntry( aItem
, nPos
);
4093 void SAL_CALL
FmXListBoxCell::addItems(const css::uno::Sequence
<OUString
>& aItems
, sal_Int16 nPos
)
4095 ::osl::MutexGuard
aGuard( m_aMutex
);
4098 sal_uInt16 nP
= nPos
;
4099 for ( const auto& rItem
: aItems
)
4101 m_pBox
->InsertEntry( rItem
, nP
);
4102 if ( nPos
!= -1 ) // Not if 0xFFFF, because LIST_APPEND
4109 void SAL_CALL
FmXListBoxCell::removeItems(sal_Int16 nPos
, sal_Int16 nCount
)
4111 ::osl::MutexGuard
aGuard( m_aMutex
);
4114 for ( sal_uInt16 n
= nCount
; n
; )
4115 m_pBox
->RemoveEntry( nPos
+ (--n
) );
4120 sal_Int16 SAL_CALL
FmXListBoxCell::getItemCount()
4122 ::osl::MutexGuard
aGuard( m_aMutex
);
4123 return m_pBox
? m_pBox
->GetEntryCount() : 0;
4127 OUString SAL_CALL
FmXListBoxCell::getItem(sal_Int16 nPos
)
4129 ::osl::MutexGuard
aGuard( m_aMutex
);
4130 return m_pBox
? m_pBox
->GetEntry(nPos
) : OUString();
4133 css::uno::Sequence
<OUString
> SAL_CALL
FmXListBoxCell::getItems()
4135 ::osl::MutexGuard
aGuard( m_aMutex
);
4137 css::uno::Sequence
<OUString
> aSeq
;
4140 const sal_Int32 nEntries
= m_pBox
->GetEntryCount();
4141 aSeq
= css::uno::Sequence
<OUString
>( nEntries
);
4142 for ( sal_Int32 n
= nEntries
; n
; )
4145 aSeq
.getArray()[n
] = m_pBox
->GetEntry( n
);
4152 sal_Int16 SAL_CALL
FmXListBoxCell::getSelectedItemPos()
4154 ::osl::MutexGuard
aGuard( m_aMutex
);
4158 sal_Int32 nPos
= m_pBox
->GetSelectedEntryPos();
4159 if (nPos
> SHRT_MAX
|| nPos
< SHRT_MIN
)
4160 throw std::out_of_range("awt::XListBox::getSelectedItemPos can only return a short");
4167 Sequence
< sal_Int16
> SAL_CALL
FmXListBoxCell::getSelectedItemsPos()
4169 ::osl::MutexGuard
aGuard( m_aMutex
);
4170 Sequence
<sal_Int16
> aSeq
;
4175 const sal_Int32 nSelEntries
= m_pBox
->GetSelectedEntryCount();
4176 aSeq
= Sequence
<sal_Int16
>( nSelEntries
);
4177 for ( sal_Int32 n
= 0; n
< nSelEntries
; ++n
)
4178 aSeq
.getArray()[n
] = m_pBox
->GetSelectedEntryPos( n
);
4183 OUString SAL_CALL
FmXListBoxCell::getSelectedItem()
4185 ::osl::MutexGuard
aGuard( m_aMutex
);
4192 aItem
= m_pBox
->GetSelectedEntry();
4199 css::uno::Sequence
<OUString
> SAL_CALL
FmXListBoxCell::getSelectedItems()
4201 ::osl::MutexGuard
aGuard( m_aMutex
);
4203 css::uno::Sequence
<OUString
> aSeq
;
4208 const sal_Int32 nSelEntries
= m_pBox
->GetSelectedEntryCount();
4209 aSeq
= css::uno::Sequence
<OUString
>( nSelEntries
);
4210 for ( sal_Int32 n
= 0; n
< nSelEntries
; ++n
)
4211 aSeq
.getArray()[n
] = m_pBox
->GetSelectedEntry( n
);
4217 void SAL_CALL
FmXListBoxCell::selectItemPos(sal_Int16 nPos
, sal_Bool bSelect
)
4219 ::osl::MutexGuard
aGuard( m_aMutex
);
4222 m_pBox
->SelectEntryPos( nPos
, bSelect
);
4226 void SAL_CALL
FmXListBoxCell::selectItemsPos(const Sequence
< sal_Int16
>& aPositions
, sal_Bool bSelect
)
4228 ::osl::MutexGuard
aGuard( m_aMutex
);
4232 for ( sal_uInt16 n
= static_cast<sal_uInt16
>(aPositions
.getLength()); n
; )
4233 m_pBox
->SelectEntryPos( static_cast<sal_uInt16
>(aPositions
.getConstArray()[--n
]), bSelect
);
4238 void SAL_CALL
FmXListBoxCell::selectItem(const OUString
& aItem
, sal_Bool bSelect
)
4240 ::osl::MutexGuard
aGuard( m_aMutex
);
4243 m_pBox
->SelectEntry( aItem
, bSelect
);
4247 sal_Bool SAL_CALL
FmXListBoxCell::isMutipleMode()
4249 ::osl::MutexGuard
aGuard( m_aMutex
);
4251 bool bMulti
= false;
4253 bMulti
= m_pBox
->IsMultiSelectionEnabled();
4258 void SAL_CALL
FmXListBoxCell::setMultipleMode(sal_Bool bMulti
)
4260 ::osl::MutexGuard
aGuard( m_aMutex
);
4263 m_pBox
->EnableMultiSelection( bMulti
);
4267 sal_Int16 SAL_CALL
FmXListBoxCell::getDropDownLineCount()
4269 ::osl::MutexGuard
aGuard( m_aMutex
);
4271 sal_Int16 nLines
= 0;
4273 nLines
= m_pBox
->GetDropDownLineCount();
4279 void SAL_CALL
FmXListBoxCell::setDropDownLineCount(sal_Int16 nLines
)
4281 ::osl::MutexGuard
aGuard( m_aMutex
);
4284 m_pBox
->SetDropDownLineCount( nLines
);
4288 void SAL_CALL
FmXListBoxCell::makeVisible(sal_Int16 nEntry
)
4290 ::osl::MutexGuard
aGuard( m_aMutex
);
4293 m_pBox
->SetTopEntry( nEntry
);
4297 void FmXListBoxCell::onWindowEvent( const VclEventId _nEventId
, const vcl::Window
& _rWindow
, const void* _pEventData
)
4299 if ( ( &_rWindow
== m_pBox
)
4300 && ( _nEventId
== VclEventId::ListboxSelect
)
4303 OnDoubleClick( *m_pBox
);
4305 css::awt::ItemEvent aEvent
;
4306 aEvent
.Source
= *this;
4307 aEvent
.Highlighted
= 0;
4309 // with multiple selection 0xFFFF, otherwise the ID
4310 aEvent
.Selected
= (m_pBox
->GetSelectedEntryCount() == 1 )
4311 ? m_pBox
->GetSelectedEntryPos() : 0xFFFF;
4313 m_aItemListeners
.notifyEach( &awt::XItemListener::itemStateChanged
, aEvent
);
4317 FmXTextCell::onWindowEvent( _nEventId
, _rWindow
, _pEventData
);
4321 IMPL_LINK_NOARG(FmXListBoxCell
, OnDoubleClick
, ListBox
&, void)
4325 ::comphelper::OInterfaceIteratorHelper2
aIt( m_aActionListeners
);
4327 css::awt::ActionEvent aEvent
;
4328 aEvent
.Source
= *this;
4329 aEvent
.ActionCommand
= m_pBox
->GetSelectedEntry();
4331 while( aIt
.hasMoreElements() )
4332 static_cast< css::awt::XActionListener
*>(aIt
.next())->actionPerformed( aEvent
);
4336 FmXComboBoxCell::FmXComboBoxCell( DbGridColumn
* pColumn
, std::unique_ptr
<DbCellControl
> pControl
)
4337 :FmXTextCell( pColumn
, std::move(pControl
) )
4338 ,m_aItemListeners( m_aMutex
)
4339 ,m_aActionListeners( m_aMutex
)
4340 ,m_pComboBox( &static_cast< ComboBox
& >( m_pCellControl
->GetWindow() ) )
4345 FmXComboBoxCell::~FmXComboBoxCell()
4347 if ( !OComponentHelper::rBHelper
.bDisposed
)
4356 void FmXComboBoxCell::disposing()
4358 css::lang::EventObject
aEvt(*this);
4359 m_aItemListeners
.disposeAndClear(aEvt
);
4360 m_aActionListeners
.disposeAndClear(aEvt
);
4362 FmXTextCell::disposing();
4366 Any SAL_CALL
FmXComboBoxCell::queryAggregation( const css::uno::Type
& _rType
)
4368 Any aReturn
= FmXTextCell::queryAggregation(_rType
);
4370 if ( !aReturn
.hasValue() )
4371 aReturn
= FmXComboBoxCell_Base::queryInterface( _rType
);
4377 Sequence
< Type
> SAL_CALL
FmXComboBoxCell::getTypes( )
4379 return ::comphelper::concatSequences(
4380 FmXTextCell::getTypes(),
4381 FmXComboBoxCell_Base::getTypes()
4386 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXComboBoxCell
)
4389 void SAL_CALL
FmXComboBoxCell::addItemListener(const Reference
< awt::XItemListener
>& l
)
4391 m_aItemListeners
.addInterface( l
);
4395 void SAL_CALL
FmXComboBoxCell::removeItemListener(const Reference
< awt::XItemListener
>& l
)
4397 m_aItemListeners
.removeInterface( l
);
4401 void SAL_CALL
FmXComboBoxCell::addActionListener(const Reference
< awt::XActionListener
>& l
)
4403 m_aActionListeners
.addInterface( l
);
4407 void SAL_CALL
FmXComboBoxCell::removeActionListener(const Reference
< awt::XActionListener
>& l
)
4409 m_aActionListeners
.removeInterface( l
);
4413 void SAL_CALL
FmXComboBoxCell::addItem( const OUString
& Item
, sal_Int16 Pos
)
4415 ::osl::MutexGuard
aGuard( m_aMutex
);
4417 m_pComboBox
->InsertEntry( Item
, Pos
);
4421 void SAL_CALL
FmXComboBoxCell::addItems( const Sequence
< OUString
>& Items
, sal_Int16 Pos
)
4423 ::osl::MutexGuard
aGuard( m_aMutex
);
4426 sal_uInt16 nP
= Pos
;
4427 for ( const auto& rItem
: Items
)
4429 m_pComboBox
->InsertEntry( rItem
, nP
);
4437 void SAL_CALL
FmXComboBoxCell::removeItems( sal_Int16 Pos
, sal_Int16 Count
)
4439 ::osl::MutexGuard
aGuard( m_aMutex
);
4442 for ( sal_uInt16 n
= Count
; n
; )
4443 m_pComboBox
->RemoveEntryAt( Pos
+ (--n
) );
4448 sal_Int16 SAL_CALL
FmXComboBoxCell::getItemCount()
4450 ::osl::MutexGuard
aGuard( m_aMutex
);
4451 return m_pComboBox
? m_pComboBox
->GetEntryCount() : 0;
4455 OUString SAL_CALL
FmXComboBoxCell::getItem( sal_Int16 Pos
)
4457 ::osl::MutexGuard
aGuard( m_aMutex
);
4458 return m_pComboBox
? m_pComboBox
->GetEntry(Pos
) : OUString();
4461 Sequence
< OUString
> SAL_CALL
FmXComboBoxCell::getItems()
4463 ::osl::MutexGuard
aGuard( m_aMutex
);
4465 Sequence
< OUString
> aItems
;
4468 const sal_Int32 nEntries
= m_pComboBox
->GetEntryCount();
4469 aItems
.realloc( nEntries
);
4470 OUString
* pItem
= aItems
.getArray();
4471 for ( sal_Int32 n
=0; n
<nEntries
; ++n
, ++pItem
)
4472 *pItem
= m_pComboBox
->GetEntry( n
);
4478 sal_Int16 SAL_CALL
FmXComboBoxCell::getDropDownLineCount()
4480 ::osl::MutexGuard
aGuard( m_aMutex
);
4482 sal_Int16 nLines
= 0;
4484 nLines
= m_pComboBox
->GetDropDownLineCount();
4490 void SAL_CALL
FmXComboBoxCell::setDropDownLineCount(sal_Int16 nLines
)
4492 ::osl::MutexGuard
aGuard( m_aMutex
);
4494 m_pComboBox
->SetDropDownLineCount( nLines
);
4498 void FmXComboBoxCell::onWindowEvent( const VclEventId _nEventId
, const vcl::Window
& _rWindow
, const void* _pEventData
)
4501 switch ( _nEventId
)
4503 case VclEventId::ComboboxSelect
:
4505 awt::ItemEvent aEvent
;
4506 aEvent
.Source
= *this;
4507 aEvent
.Highlighted
= 0;
4509 // with multiple selection 0xFFFF, otherwise the ID
4510 aEvent
.Selected
= ( m_pComboBox
->GetSelectedEntryCount() == 1 )
4511 ? m_pComboBox
->GetSelectedEntryPos()
4513 m_aItemListeners
.notifyEach( &awt::XItemListener::itemStateChanged
, aEvent
);
4518 FmXTextCell::onWindowEvent( _nEventId
, _rWindow
, _pEventData
);
4524 FmXFilterCell::FmXFilterCell(DbGridColumn
* pColumn
, std::unique_ptr
<DbFilterField
> pControl
)
4525 :FmXGridCell( pColumn
, std::move(pControl
) )
4526 ,m_aTextListeners(m_aMutex
)
4528 static_cast<DbFilterField
*>(m_pCellControl
.get())->SetCommitHdl( LINK( this, FmXFilterCell
, OnCommit
) );
4532 FmXFilterCell::~FmXFilterCell()
4534 if (!OComponentHelper::rBHelper
.bDisposed
)
4544 sal_Int64 SAL_CALL
FmXFilterCell::getSomething( const Sequence
< sal_Int8
>& _rIdentifier
)
4546 sal_Int64
nReturn(0);
4548 if ( isUnoTunnelId
<FmXFilterCell
>(_rIdentifier
) )
4550 nReturn
= reinterpret_cast<sal_Int64
>(this);
4558 class theFmXFilterCellUnoTunnelId
: public rtl::Static
< UnoTunnelIdInit
, theFmXFilterCellUnoTunnelId
> {};
4561 const Sequence
<sal_Int8
>& FmXFilterCell::getUnoTunnelId()
4563 return theFmXFilterCellUnoTunnelId::get().getSeq();
4567 void FmXFilterCell::PaintCell( OutputDevice
& rDev
, const tools::Rectangle
& rRect
)
4569 static_cast< DbFilterField
* >( m_pCellControl
.get() )->PaintCell( rDev
, rRect
);
4574 void FmXFilterCell::disposing()
4576 css::lang::EventObject
aEvt(*this);
4577 m_aTextListeners
.disposeAndClear(aEvt
);
4579 static_cast<DbFilterField
*>(m_pCellControl
.get())->SetCommitHdl(Link
<DbFilterField
&,void>());
4581 FmXGridCell::disposing();
4585 Any SAL_CALL
FmXFilterCell::queryAggregation( const css::uno::Type
& _rType
)
4587 Any aReturn
= FmXGridCell::queryAggregation(_rType
);
4589 if ( !aReturn
.hasValue() )
4590 aReturn
= FmXFilterCell_Base::queryInterface( _rType
);
4596 Sequence
< css::uno::Type
> SAL_CALL
FmXFilterCell::getTypes( )
4598 return ::comphelper::concatSequences(
4599 FmXGridCell::getTypes(),
4600 FmXFilterCell_Base::getTypes()
4605 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXFilterCell
)
4607 // css::awt::XTextComponent
4609 void SAL_CALL
FmXFilterCell::addTextListener(const Reference
< css::awt::XTextListener
>& l
)
4611 m_aTextListeners
.addInterface( l
);
4615 void SAL_CALL
FmXFilterCell::removeTextListener(const Reference
< css::awt::XTextListener
>& l
)
4617 m_aTextListeners
.removeInterface( l
);
4621 void SAL_CALL
FmXFilterCell::setText( const OUString
& aText
)
4623 ::osl::MutexGuard
aGuard( m_aMutex
);
4624 static_cast<DbFilterField
*>(m_pCellControl
.get())->SetText(aText
);
4628 void SAL_CALL
FmXFilterCell::insertText( const css::awt::Selection
& /*rSel*/, const OUString
& /*aText*/ )
4633 OUString SAL_CALL
FmXFilterCell::getText()
4635 ::osl::MutexGuard
aGuard( m_aMutex
);
4636 return static_cast<DbFilterField
*>(m_pCellControl
.get())->GetText();
4640 OUString SAL_CALL
FmXFilterCell::getSelectedText()
4646 void SAL_CALL
FmXFilterCell::setSelection( const css::awt::Selection
& /*aSelection*/ )
4651 css::awt::Selection SAL_CALL
FmXFilterCell::getSelection()
4653 return css::awt::Selection();
4657 sal_Bool SAL_CALL
FmXFilterCell::isEditable()
4663 void SAL_CALL
FmXFilterCell::setEditable( sal_Bool
/*bEditable*/ )
4668 sal_Int16 SAL_CALL
FmXFilterCell::getMaxTextLen()
4674 void SAL_CALL
FmXFilterCell::setMaxTextLen( sal_Int16
/*nLen*/ )
4679 IMPL_LINK_NOARG(FmXFilterCell
, OnCommit
, DbFilterField
&, void)
4681 ::comphelper::OInterfaceIteratorHelper2
aIt( m_aTextListeners
);
4682 css::awt::TextEvent aEvt
;
4683 aEvt
.Source
= *this;
4684 while( aIt
.hasMoreElements() )
4685 static_cast< css::awt::XTextListener
*>(aIt
.next())->textChanged( aEvt
);
4688 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */