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>
24 #include "svx/fmresids.hrc"
25 #include "svx/fmtools.hxx"
26 #include "gridcell.hxx"
27 #include "gridcols.hxx"
28 #include "sdbdatacolumn.hxx"
30 #include <com/sun/star/awt/LineEndFormat.hpp>
31 #include <com/sun/star/awt/MouseWheelBehavior.hpp>
32 #include <com/sun/star/awt/VisualEffect.hpp>
33 #include <com/sun/star/container/XChild.hpp>
34 #include <com/sun/star/container/XNamed.hpp>
35 #include <com/sun/star/form/FormComponentType.hpp>
36 #include <com/sun/star/form/XBoundComponent.hpp>
37 #include <com/sun/star/script/XEventAttacherManager.hpp>
38 #include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
39 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
40 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
41 #include <com/sun/star/sdbc/ColumnValue.hpp>
42 #include <com/sun/star/sdbc/DataType.hpp>
43 #include <com/sun/star/sdbc/XStatement.hpp>
44 #include <com/sun/star/util/NumberFormat.hpp>
45 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
46 #include <com/sun/star/util/Time.hpp>
47 #include <com/sun/star/util/Date.hpp>
49 #include <comphelper/numbers.hxx>
50 #include <comphelper/property.hxx>
51 #include <comphelper/servicehelper.hxx>
52 #include <comphelper/string.hxx>
53 #include <connectivity/formattedcolumnvalue.hxx>
54 #include <cppuhelper/typeprovider.hxx>
55 #include <i18nlangtag/lang.h>
56 #include <o3tl/make_unique.hxx>
58 #include <rtl/math.hxx>
59 #include <svtools/calendar.hxx>
60 #include <svtools/fmtfield.hxx>
61 #include <svl/numuno.hxx>
62 #include <svtools/svmedit.hxx>
63 #include <svx/dialmgr.hxx>
64 #include <toolkit/helper/vclunohelper.hxx>
65 #include <tools/diagnose_ex.h>
66 #include <vcl/longcurr.hxx>
67 #include <vcl/settings.hxx>
68 #include <connectivity/dbtools.hxx>
69 #include <connectivity/dbconversion.hxx>
70 #include <connectivity/sqlnode.hxx>
74 using namespace ::connectivity
;
75 using namespace ::svxform
;
76 using namespace ::comphelper
;
77 using namespace ::svt
;
78 using namespace ::com::sun::star
;
79 using namespace ::com::sun::star::uno
;
80 using namespace ::com::sun::star::sdbc
;
81 using namespace ::com::sun::star::sdbcx
;
82 using namespace ::com::sun::star::sdb
;
83 using namespace ::com::sun::star::beans
;
84 using namespace ::com::sun::star::form
;
85 using namespace ::dbtools::DBTypeConversion
;
86 using namespace ::dbtools
;
88 using ::com::sun::star::util::XNumberFormatter
;
90 const char INVALIDTEXT
[] = "###";
91 const char OBJECTTEXT
[] = "<OBJECT>";
98 LineEnd
getModelLineEndSetting( const Reference
< XPropertySet
>& _rxModel
)
100 LineEnd eFormat
= LINEEND_LF
;
104 sal_Int16 nLineEndFormat
= awt::LineEndFormat::LINE_FEED
;
106 Reference
< XPropertySetInfo
> xPSI
;
108 xPSI
= _rxModel
->getPropertySetInfo();
110 OSL_ENSURE( xPSI
.is(), "getModelLineEndSetting: invalid column model!" );
111 if ( xPSI
.is() && xPSI
->hasPropertyByName( FM_PROP_LINEENDFORMAT
) )
113 OSL_VERIFY( _rxModel
->getPropertyValue( FM_PROP_LINEENDFORMAT
) >>= nLineEndFormat
);
115 switch ( nLineEndFormat
)
117 case awt::LineEndFormat::CARRIAGE_RETURN
: eFormat
= LINEEND_CR
; break;
118 case awt::LineEndFormat::LINE_FEED
: eFormat
= LINEEND_LF
; break;
119 case awt::LineEndFormat::CARRIAGE_RETURN_LINE_FEED
: eFormat
= LINEEND_CRLF
; break;
121 OSL_FAIL( "getModelLineEndSetting: what's this?" );
125 catch( const Exception
& )
127 OSL_FAIL( "getModelLineEndSetting: caught an exception!" );
128 DBG_UNHANDLED_EXCEPTION();
138 CellControllerRef
DbGridColumn::s_xEmptyController
;
141 void DbGridColumn::CreateControl(sal_Int32 _nFieldPos
, const Reference
< css::beans::XPropertySet
>& xField
, sal_Int32 nTypeId
)
145 m_nTypeId
= (sal_Int16
)nTypeId
;
146 if (xField
!= m_xField
)
150 xField
->getPropertyValue(FM_PROP_FORMATKEY
) >>= m_nFormatKey
;
151 m_nFieldPos
= (sal_Int16
)_nFieldPos
;
152 m_bReadOnly
= ::comphelper::getBOOL(xField
->getPropertyValue(FM_PROP_ISREADONLY
));
153 m_bAutoValue
= ::comphelper::getBOOL(xField
->getPropertyValue(FM_PROP_AUTOINCREMENT
));
154 m_nFieldType
= (sal_Int16
)::comphelper::getINT32(xField
->getPropertyValue(FM_PROP_FIELDTYPE
));
156 switch (m_nFieldType
)
160 case DataType::TIMESTAMP
:
164 case DataType::BOOLEAN
:
165 case DataType::TINYINT
:
166 case DataType::SMALLINT
:
167 case DataType::INTEGER
:
168 case DataType::BIGINT
:
169 case DataType::FLOAT
:
171 case DataType::DOUBLE
:
172 case DataType::NUMERIC
:
173 case DataType::DECIMAL
:
174 m_nAlign
= css::awt::TextAlign::RIGHT
;
178 m_nAlign
= css::awt::TextAlign::LEFT
;
183 DbCellControl
* pCellControl
= nullptr;
184 if (m_rParent
.IsFilterMode())
186 pCellControl
= new DbFilterField(m_rParent
.getContext(),*this);
193 case TYPE_CHECKBOX
: pCellControl
= new DbCheckBox(*this); break;
194 case TYPE_COMBOBOX
: pCellControl
= new DbComboBox(*this); break;
195 case TYPE_CURRENCYFIELD
: pCellControl
= new DbCurrencyField(*this); break;
196 case TYPE_DATEFIELD
: pCellControl
= new DbDateField(*this); break;
197 case TYPE_LISTBOX
: pCellControl
= new DbListBox(*this); break;
198 case TYPE_NUMERICFIELD
: pCellControl
= new DbNumericField(*this); break;
199 case TYPE_PATTERNFIELD
: pCellControl
= new DbPatternField( *this, m_rParent
.getContext() ); break;
200 case TYPE_TEXTFIELD
: pCellControl
= new DbTextField(*this); break;
201 case TYPE_TIMEFIELD
: pCellControl
= new DbTimeField(*this); break;
202 case TYPE_FORMATTEDFIELD
: pCellControl
= new DbFormattedField(*this); break;
204 OSL_FAIL("DbGridColumn::CreateControl: Unknown Column");
209 Reference
< XRowSet
> xCur
;
210 if (m_rParent
.getDataSource())
211 xCur
.set(Reference
< XInterface
>(*m_rParent
.getDataSource()), UNO_QUERY
);
212 // TODO : the cursor wrapper should use an XRowSet interface, too
214 pCellControl
->Init( m_rParent
.GetDataWindow(), xCur
);
216 // now create the control wrapper
217 if (m_rParent
.IsFilterMode())
218 m_pCell
= new FmXFilterCell(this, pCellControl
);
223 case TYPE_CHECKBOX
: m_pCell
= new FmXCheckBoxCell( this, *pCellControl
); break;
224 case TYPE_LISTBOX
: m_pCell
= new FmXListBoxCell( this, *pCellControl
); break;
225 case TYPE_COMBOBOX
: m_pCell
= new FmXComboBoxCell( this, *pCellControl
); break;
227 m_pCell
= new FmXEditCell( this, *pCellControl
);
232 impl_toggleScriptManager_nothrow( true );
234 // only if we use have a bound field, we use a controller for displaying the
235 // window in the grid
237 m_xController
= pCellControl
->CreateController();
241 void DbGridColumn::impl_toggleScriptManager_nothrow( bool _bAttach
)
245 Reference
< container::XChild
> xChild( m_xModel
, UNO_QUERY_THROW
);
246 Reference
< script::XEventAttacherManager
> xManager( xChild
->getParent(), UNO_QUERY_THROW
);
247 Reference
< container::XIndexAccess
> xContainer( xChild
->getParent(), UNO_QUERY_THROW
);
249 sal_Int32
nIndexInParent( getElementPos( xContainer
, m_xModel
) );
251 Reference
< XInterface
> xCellInterface( *m_pCell
, UNO_QUERY
);
253 xManager
->attach( nIndexInParent
, xCellInterface
, makeAny( xCellInterface
) );
255 xManager
->detach( nIndexInParent
, xCellInterface
);
257 catch( const Exception
& )
259 DBG_UNHANDLED_EXCEPTION();
263 void DbGridColumn::UpdateFromField(const DbGridRow
* pRow
, const Reference
< XNumberFormatter
>& xFormatter
)
265 if (FmXFilterCell
* pCell
= dynamic_cast<FmXFilterCell
*>(m_pCell
.get()))
267 else if (pRow
&& pRow
->IsValid() && m_nFieldPos
>= 0 && m_pCell
.is() && pRow
->HasField(m_nFieldPos
))
269 dynamic_cast<FmXDataCell
&>(*m_pCell
).UpdateFromField( pRow
->GetField( m_nFieldPos
).getColumn(), xFormatter
);
273 bool DbGridColumn::Commit()
276 if (!m_bInSave
&& m_pCell
.is())
279 bResult
= m_pCell
->Commit();
281 // store the data into the model
282 FmXDataCell
* pDataCell
= dynamic_cast<FmXDataCell
*>( m_pCell
.get() );
283 if (bResult
&& pDataCell
)
285 Reference
< css::form::XBoundComponent
> xComp(m_xModel
, UNO_QUERY
);
287 bResult
= xComp
->commit();
295 DbGridColumn::~DbGridColumn()
301 void DbGridColumn::setModel(const css::uno::Reference
< css::beans::XPropertySet
>& _xModel
)
304 impl_toggleScriptManager_nothrow( false );
309 impl_toggleScriptManager_nothrow( true );
313 void DbGridColumn::Clear()
317 impl_toggleScriptManager_nothrow( false );
323 m_xController
= nullptr;
329 m_bAutoValue
= false;
330 m_nFieldType
= DataType::OTHER
;
334 sal_Int16
DbGridColumn::SetAlignment(sal_Int16 _nAlign
)
341 m_xField
->getPropertyValue(FM_PROP_FIELDTYPE
) >>= nType
;
345 case DataType::NUMERIC
:
346 case DataType::DECIMAL
:
347 case DataType::DOUBLE
:
349 case DataType::BIGINT
:
350 case DataType::INTEGER
:
351 case DataType::SMALLINT
:
352 case DataType::TINYINT
:
355 case DataType::TIMESTAMP
:
356 _nAlign
= css::awt::TextAlign::RIGHT
;
359 case DataType::BOOLEAN
:
360 _nAlign
= css::awt::TextAlign::CENTER
;
363 _nAlign
= css::awt::TextAlign::LEFT
;
368 _nAlign
= css::awt::TextAlign::LEFT
;
372 if (m_pCell
.is() && m_pCell
->isAlignedController())
373 m_pCell
->AlignControl(m_nAlign
);
379 sal_Int16
DbGridColumn::SetAlignmentFromModel(sal_Int16 nStandardAlign
)
381 Any
aAlign( m_xModel
->getPropertyValue(FM_PROP_ALIGN
));
382 if (aAlign
.hasValue())
384 sal_Int16 nTest
= sal_Int16();
385 if (aAlign
>>= nTest
)
386 nStandardAlign
= nTest
;
388 return SetAlignment(nStandardAlign
);
392 void DbGridColumn::setLock(bool _bLock
)
394 if (m_bLocked
== _bLock
)
398 // is the column we represent active ?
400 return; // no, it isn't (or at least it shouldn't be ...)
402 if (m_rParent
.GetCurColumnId() == m_nId
)
404 m_rParent
.DeactivateCell();
405 m_rParent
.ActivateCell(m_rParent
.GetCurRow(), m_rParent
.GetCurColumnId());
410 OUString
DbGridColumn::GetCellText(const DbGridRow
* pRow
, const Reference
< XNumberFormatter
>& xFormatter
) const
413 if (m_pCell
.is() && dynamic_cast<const FmXFilterCell
*>( m_pCell
.get() ) != nullptr)
416 if (!pRow
|| !pRow
->IsValid())
418 else if (pRow
->HasField(m_nFieldPos
))
420 aText
= GetCellText( pRow
->GetField( m_nFieldPos
).getColumn(), xFormatter
);
426 OUString
DbGridColumn::GetCellText(const Reference
< css::sdb::XColumn
>& xField
, const Reference
< XNumberFormatter
>& xFormatter
) const
431 FmXTextCell
* pTextCell
= dynamic_cast<FmXTextCell
*>( m_pCell
.get() );
433 aText
= pTextCell
->GetText(xField
, xFormatter
);
441 Reference
< css::sdb::XColumn
> DbGridColumn::GetCurrentFieldValue() const
443 Reference
< css::sdb::XColumn
> xField
;
444 const DbGridRowRef xRow
= m_rParent
.GetCurrentRow();
445 if (xRow
.is() && xRow
->HasField(m_nFieldPos
))
447 xField
= xRow
->GetField(m_nFieldPos
).getColumn();
453 void DbGridColumn::Paint(OutputDevice
& rDev
,
454 const tools::Rectangle
& rRect
,
455 const DbGridRow
* pRow
,
456 const Reference
< XNumberFormatter
>& xFormatter
)
458 bool bEnabled
= ( rDev
.GetOutDevType() != OUTDEV_WINDOW
)
459 || ( static_cast< vcl::Window
& >( rDev
).IsEnabled() );
461 FmXDataCell
* pDataCell
= dynamic_cast<FmXDataCell
*>( m_pCell
.get() );
464 if (!pRow
|| !pRow
->IsValid())
466 DrawTextFlags nStyle
= DrawTextFlags::Clip
| DrawTextFlags::Center
;
468 nStyle
|= DrawTextFlags::Disable
;
470 rDev
.DrawText(rRect
, OUString(INVALIDTEXT
), nStyle
);
472 else if (m_bAutoValue
&& pRow
->IsNew())
474 DrawTextFlags nStyle
= DrawTextFlags::Clip
| DrawTextFlags::VCenter
;
476 nStyle
|= DrawTextFlags::Disable
;
478 switch (GetAlignment())
480 case css::awt::TextAlign::RIGHT
:
481 nStyle
|= DrawTextFlags::Right
;
483 case css::awt::TextAlign::CENTER
:
484 nStyle
|= DrawTextFlags::Center
;
487 nStyle
|= DrawTextFlags::Left
;
490 rDev
.DrawText(rRect
, SvxResId(RID_STR_AUTOFIELD
), nStyle
);
492 else if (pRow
->HasField(m_nFieldPos
))
494 pDataCell
->PaintFieldToCell(rDev
, rRect
, pRow
->GetField( m_nFieldPos
).getColumn(), xFormatter
);
497 else if (!m_pCell
.is())
499 if (!pRow
|| !pRow
->IsValid())
501 DrawTextFlags nStyle
= DrawTextFlags::Clip
| DrawTextFlags::Center
;
503 nStyle
|= DrawTextFlags::Disable
;
505 rDev
.DrawText(rRect
, OUString(INVALIDTEXT
), nStyle
);
507 else if (pRow
->HasField(m_nFieldPos
) && m_bObject
)
509 DrawTextFlags nStyle
= DrawTextFlags::Clip
| DrawTextFlags::Center
;
511 nStyle
|= DrawTextFlags::Disable
;
512 rDev
.DrawText(rRect
, OUString(OBJECTTEXT
), nStyle
);
515 else if ( dynamic_cast<const FmXFilterCell
*>( m_pCell
.get() ) != nullptr )
516 static_cast< FmXFilterCell
* >( m_pCell
.get() )->PaintCell( rDev
, rRect
);
520 void DbGridColumn::ImplInitWindow( vcl::Window
& rParent
, const InitWindowFacet _eInitWhat
)
523 m_pCell
->ImplInitWindow( rParent
, _eInitWhat
);
530 DbCellControl::DbCellControl( DbGridColumn
& _rColumn
)
531 :OPropertyChangeListener(m_aMutex
)
532 ,m_bTransparent( false )
533 ,m_bAlignedController( true )
534 ,m_bAccessingValueProperty( false )
535 ,m_rColumn( _rColumn
)
536 ,m_pPainter( nullptr )
537 ,m_pWindow( nullptr )
539 Reference
< XPropertySet
> xColModelProps( _rColumn
.getModel(), UNO_QUERY
);
540 if ( xColModelProps
.is() )
542 // if our model's format key changes we want to propagate the new value to our windows
543 m_pModelChangeBroadcaster
= new ::comphelper::OPropertyChangeMultiplexer(this, Reference
< css::beans::XPropertySet
> (_rColumn
.getModel(), UNO_QUERY
));
545 // be listener for some common properties
546 implDoPropertyListening( FM_PROP_READONLY
, false );
547 implDoPropertyListening( FM_PROP_ENABLED
, false );
549 // add as listener for all known "value" properties
550 implDoPropertyListening( FM_PROP_VALUE
, false );
551 implDoPropertyListening( FM_PROP_STATE
, false );
552 implDoPropertyListening( FM_PROP_TEXT
, false );
553 implDoPropertyListening( FM_PROP_EFFECTIVE_VALUE
, false );
554 implDoPropertyListening( FM_PROP_SELECT_SEQ
, false );
555 implDoPropertyListening( FM_PROP_DATE
, false );
556 implDoPropertyListening( FM_PROP_TIME
, false );
558 // be listener at the bound field as well
561 Reference
< XPropertySetInfo
> xPSI( xColModelProps
->getPropertySetInfo(), UNO_SET_THROW
);
562 if ( xPSI
->hasPropertyByName( FM_PROP_BOUNDFIELD
) )
564 Reference
< XPropertySet
> xField
;
565 xColModelProps
->getPropertyValue( FM_PROP_BOUNDFIELD
) >>= xField
;
568 m_pFieldChangeBroadcaster
= new ::comphelper::OPropertyChangeMultiplexer(this, xField
);
569 m_pFieldChangeBroadcaster
->addProperty( FM_PROP_ISREADONLY
);
573 catch( const Exception
& )
575 OSL_FAIL( "DbCellControl::doPropertyListening: caught an exception!" );
576 DBG_UNHANDLED_EXCEPTION();
582 void DbCellControl::implDoPropertyListening(const OUString
& _rPropertyName
, bool _bWarnIfNotExistent
)
586 Reference
< XPropertySet
> xColModelProps( m_rColumn
.getModel(), UNO_QUERY
);
587 Reference
< XPropertySetInfo
> xPSI
;
588 if ( xColModelProps
.is() )
589 xPSI
= xColModelProps
->getPropertySetInfo();
591 DBG_ASSERT( !_bWarnIfNotExistent
|| ( xPSI
.is() && xPSI
->hasPropertyByName( _rPropertyName
) ),
592 "DbCellControl::doPropertyListening: no property set info or non-existent property!" );
593 (void)_bWarnIfNotExistent
;
595 if ( xPSI
.is() && xPSI
->hasPropertyByName( _rPropertyName
) )
596 m_pModelChangeBroadcaster
->addProperty( _rPropertyName
);
598 catch( const Exception
& )
600 OSL_FAIL( "DbCellControl::doPropertyListening: caught an exception!" );
601 DBG_UNHANDLED_EXCEPTION();
606 void DbCellControl::doPropertyListening(const OUString
& _rPropertyName
)
608 implDoPropertyListening( _rPropertyName
, true );
611 static void lcl_clearBroadCaster(rtl::Reference
<::comphelper::OPropertyChangeMultiplexer
>& _pBroadcaster
)
613 if ( _pBroadcaster
.is() )
615 _pBroadcaster
->dispose();
616 _pBroadcaster
.clear();
617 // no delete, this is done implicitly
621 DbCellControl::~DbCellControl()
623 lcl_clearBroadCaster(m_pModelChangeBroadcaster
);
624 lcl_clearBroadCaster(m_pFieldChangeBroadcaster
);
626 m_pWindow
.disposeAndClear();
627 m_pPainter
.disposeAndClear();
630 void DbCellControl::implValuePropertyChanged( )
632 OSL_ENSURE( !isValuePropertyLocked(),
633 "DbCellControl::implValuePropertyChanged: not to be called with the value property locked!" );
637 if ( m_rColumn
.getModel().is() )
638 updateFromModel( m_rColumn
.getModel() );
643 void DbCellControl::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& /*_rxModel*/ )
645 // nothing to do here
649 void DbCellControl::_propertyChanged(const PropertyChangeEvent
& _rEvent
)
651 SolarMutexGuard aGuard
;
653 Reference
< XPropertySet
> xSourceProps( _rEvent
.Source
, UNO_QUERY
);
655 if ( _rEvent
.PropertyName
== FM_PROP_VALUE
656 || _rEvent
.PropertyName
== FM_PROP_STATE
657 || _rEvent
.PropertyName
== FM_PROP_TEXT
658 || _rEvent
.PropertyName
== FM_PROP_EFFECTIVE_VALUE
659 || _rEvent
.PropertyName
== FM_PROP_SELECT_SEQ
660 || _rEvent
.PropertyName
== FM_PROP_DATE
661 || _rEvent
.PropertyName
== FM_PROP_TIME
663 { // it was one of the known "value" properties
664 if ( !isValuePropertyLocked() )
666 implValuePropertyChanged( );
669 else if ( _rEvent
.PropertyName
== FM_PROP_READONLY
)
671 implAdjustReadOnly( xSourceProps
, true);
673 else if ( _rEvent
.PropertyName
== FM_PROP_ISREADONLY
)
675 bool bReadOnly
= true;
676 _rEvent
.NewValue
>>= bReadOnly
;
677 m_rColumn
.SetReadOnly(bReadOnly
);
678 implAdjustReadOnly( xSourceProps
, false);
680 else if ( _rEvent
.PropertyName
== FM_PROP_ENABLED
)
682 implAdjustEnabled( xSourceProps
);
685 implAdjustGenericFieldSetting( xSourceProps
);
689 bool DbCellControl::Commit()
691 // lock the listening for value property changes
693 // commit the content of the control into the model's value property
694 bool bReturn
= false;
697 bReturn
= commitControl();
699 catch( const Exception
& )
701 DBG_UNHANDLED_EXCEPTION();
703 // unlock the listening for value property changes
704 unlockValueProperty();
710 void DbCellControl::ImplInitWindow( vcl::Window
& rParent
, const InitWindowFacet _eInitWhat
)
712 vcl::Window
* pWindows
[] = { m_pPainter
, m_pWindow
};
714 if (_eInitWhat
& InitWindowFacet::WritingMode
)
716 for (vcl::Window
* pWindow
: pWindows
)
719 pWindow
->EnableRTL(rParent
.IsRTLEnabled());
723 if (_eInitWhat
& InitWindowFacet::Font
)
725 for (vcl::Window
* pWindow
: pWindows
)
730 pWindow
->SetZoom(rParent
.GetZoom());
732 const StyleSettings
& rStyleSettings
= pWindow
->GetSettings().GetStyleSettings();
733 vcl::Font aFont
= rStyleSettings
.GetFieldFont();
734 aFont
.SetTransparent(isTransparent());
736 if (rParent
.IsControlFont())
738 pWindow
->SetControlFont(rParent
.GetControlFont());
739 aFont
.Merge(rParent
.GetControlFont());
742 pWindow
->SetControlFont();
744 pWindow
->SetZoomedPointFont(*pWindow
, aFont
); // FIXME RenderContext
748 if ((_eInitWhat
& InitWindowFacet::Font
) || (_eInitWhat
& InitWindowFacet::Foreground
))
750 Color
aTextColor(rParent
.IsControlForeground() ? rParent
.GetControlForeground() : rParent
.GetTextColor());
752 bool bTextLineColor
= rParent
.IsTextLineColor();
753 Color
aTextLineColor(rParent
.GetTextLineColor());
755 for (vcl::Window
* pWindow
: pWindows
)
759 pWindow
->SetTextColor(aTextColor
);
760 if (rParent
.IsControlForeground())
761 pWindow
->SetControlForeground(aTextColor
);
764 pWindow
->SetTextLineColor();
766 pWindow
->SetTextLineColor(aTextLineColor
);
771 if (_eInitWhat
& InitWindowFacet::Background
)
773 if (rParent
.IsControlBackground())
775 Color
aColor(rParent
.GetControlBackground());
776 for (vcl::Window
* pWindow
: pWindows
)
781 pWindow
->SetBackground();
784 pWindow
->SetBackground(aColor
);
785 pWindow
->SetControlBackground(aColor
);
787 pWindow
->SetFillColor(aColor
);
796 m_pPainter
->SetBackground();
798 m_pPainter
->SetBackground(rParent
.GetBackground());
799 m_pPainter
->SetFillColor(rParent
.GetFillColor());
805 m_pWindow
->SetBackground(rParent
.GetBackground());
807 m_pWindow
->SetFillColor(rParent
.GetFillColor());
814 void DbCellControl::implAdjustReadOnly( const Reference
< XPropertySet
>& _rxModel
,bool i_bReadOnly
)
816 DBG_ASSERT( m_pWindow
, "DbCellControl::implAdjustReadOnly: not to be called without window!" );
817 DBG_ASSERT( _rxModel
.is(), "DbCellControl::implAdjustReadOnly: invalid model!" );
818 if ( m_pWindow
&& _rxModel
.is() )
820 Edit
* pEditWindow
= dynamic_cast< Edit
* >( m_pWindow
.get() );
823 bool bReadOnly
= m_rColumn
.IsReadOnly();
826 _rxModel
->getPropertyValue( i_bReadOnly
? OUString(FM_PROP_READONLY
) : OUString(FM_PROP_ISREADONLY
)) >>= bReadOnly
;
828 static_cast< Edit
* >( m_pWindow
.get() )->SetReadOnly( bReadOnly
);
834 void DbCellControl::implAdjustEnabled( const Reference
< XPropertySet
>& _rxModel
)
836 DBG_ASSERT( m_pWindow
, "DbCellControl::implAdjustEnabled: not to be called without window!" );
837 DBG_ASSERT( _rxModel
.is(), "DbCellControl::implAdjustEnabled: invalid model!" );
838 if ( m_pWindow
&& _rxModel
.is() )
841 _rxModel
->getPropertyValue( FM_PROP_ENABLED
) >>= bEnable
;
842 m_pWindow
->Enable( bEnable
);
847 void DbCellControl::Init( vcl::Window
& rParent
, const Reference
< XRowSet
>& _rxCursor
)
849 ImplInitWindow( rParent
, InitWindowFacet::All
);
854 if ( isAlignedController() )
855 AlignControl( m_rColumn
.GetAlignment() );
859 // some other common properties
860 Reference
< XPropertySet
> xModel( m_rColumn
.getModel(), UNO_SET_THROW
);
861 Reference
< XPropertySetInfo
> xModelPSI( xModel
->getPropertySetInfo(), UNO_SET_THROW
);
863 if ( xModelPSI
->hasPropertyByName( FM_PROP_READONLY
) )
865 implAdjustReadOnly( xModel
,true );
868 if ( xModelPSI
->hasPropertyByName( FM_PROP_ENABLED
) )
870 implAdjustEnabled( xModel
);
873 if ( xModelPSI
->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR
) )
875 sal_Int16 nWheelBehavior
= css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY
;
876 OSL_VERIFY( xModel
->getPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR
) >>= nWheelBehavior
);
877 MouseWheelBehaviour nVclSetting
= MouseWheelBehaviour::FocusOnly
;
878 switch ( nWheelBehavior
)
880 case css::awt::MouseWheelBehavior::SCROLL_DISABLED
: nVclSetting
= MouseWheelBehaviour::Disable
; break;
881 case css::awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY
: nVclSetting
= MouseWheelBehaviour::FocusOnly
; break;
882 case css::awt::MouseWheelBehavior::SCROLL_ALWAYS
: nVclSetting
= MouseWheelBehaviour::ALWAYS
; break;
884 OSL_FAIL( "DbCellControl::Init: invalid MouseWheelBehavior!" );
888 AllSettings aSettings
= m_pWindow
->GetSettings();
889 MouseSettings aMouseSettings
= aSettings
.GetMouseSettings();
890 aMouseSettings
.SetWheelBehavior( nVclSetting
);
891 aSettings
.SetMouseSettings( aMouseSettings
);
892 m_pWindow
->SetSettings( aSettings
, true );
895 catch( const Exception
& )
897 DBG_UNHANDLED_EXCEPTION();
900 m_xCursor
= _rxCursor
;
901 if ( m_rColumn
.getModel().is() )
902 updateFromModel( m_rColumn
.getModel() );
906 void DbCellControl::SetTextLineColor()
909 m_pWindow
->SetTextLineColor();
911 m_pPainter
->SetTextLineColor();
915 void DbCellControl::SetTextLineColor(const Color
& _rColor
)
918 m_pWindow
->SetTextLineColor(_rColor
);
920 m_pPainter
->SetTextLineColor(_rColor
);
925 void lcl_implAlign( vcl::Window
* _pWindow
, WinBits _nAlignmentBit
)
927 WinBits nStyle
= _pWindow
->GetStyle();
928 nStyle
&= ~(WB_LEFT
| WB_RIGHT
| WB_CENTER
);
929 _pWindow
->SetStyle( nStyle
| _nAlignmentBit
);
934 void DbCellControl::AlignControl(sal_Int16 nAlignment
)
936 WinBits nAlignmentBit
= 0;
939 case css::awt::TextAlign::RIGHT
:
940 nAlignmentBit
= WB_RIGHT
;
942 case css::awt::TextAlign::CENTER
:
943 nAlignmentBit
= WB_CENTER
;
946 nAlignmentBit
= WB_LEFT
;
949 lcl_implAlign( m_pWindow
, nAlignmentBit
);
951 lcl_implAlign( m_pPainter
, nAlignmentBit
);
955 void DbCellControl::PaintCell( OutputDevice
& _rDev
, const tools::Rectangle
& _rRect
)
957 if ( m_pPainter
->GetParent() == &_rDev
)
959 m_pPainter
->SetPaintTransparent( true );
960 m_pPainter
->SetBackground( );
961 m_pPainter
->SetControlBackground( _rDev
.GetFillColor() );
962 m_pPainter
->SetControlForeground( _rDev
.GetTextColor() );
963 m_pPainter
->SetTextColor( _rDev
.GetTextColor() );
964 m_pPainter
->SetTextFillColor( _rDev
.GetTextColor() );
966 vcl::Font
aFont( _rDev
.GetFont() );
967 aFont
.SetTransparent( true );
968 m_pPainter
->SetFont( aFont
);
970 m_pPainter
->SetPosSizePixel( _rRect
.TopLeft(), _rRect
.GetSize() );
972 m_pPainter
->Update();
973 m_pPainter
->SetParentUpdateMode( false );
975 m_pPainter
->SetParentUpdateMode( true );
978 m_pPainter
->Draw( &_rDev
, _rRect
.TopLeft(), _rRect
.GetSize(), DrawFlags::NONE
);
982 void DbCellControl::PaintFieldToCell( OutputDevice
& _rDev
, const tools::Rectangle
& _rRect
, const Reference
< XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& _rxFormatter
)
984 m_pPainter
->SetText( GetFormatText( _rxField
, _rxFormatter
) );
985 PaintCell( _rDev
, _rRect
);
989 double DbCellControl::GetValue(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& xFormatter
) const
992 if (m_rColumn
.IsNumeric())
996 fValue
= _rxField
->getDouble();
998 catch(const Exception
&) { }
1002 bool bSuccess
= false;
1005 fValue
= _rxField
->getDouble();
1008 catch(const Exception
&) { }
1013 fValue
= xFormatter
->convertStringToNumber(m_rColumn
.GetKey(), _rxField
->getString());
1015 catch(const Exception
&) { }
1022 void DbCellControl::invalidatedController()
1024 m_rColumn
.GetParent().refreshController(m_rColumn
.GetId(), DbGridControl::GrantControlAccess());
1029 DbLimitedLengthField::DbLimitedLengthField( DbGridColumn
& _rColumn
)
1030 :DbCellControl( _rColumn
)
1032 doPropertyListening( FM_PROP_MAXTEXTLEN
);
1036 void DbLimitedLengthField::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& _rxModel
)
1038 DBG_ASSERT( m_pWindow
, "DbLimitedLengthField::implAdjustGenericFieldSetting: not to be called without window!" );
1039 DBG_ASSERT( _rxModel
.is(), "DbLimitedLengthField::implAdjustGenericFieldSetting: invalid model!" );
1040 if ( m_pWindow
&& _rxModel
.is() )
1042 sal_Int16 nMaxLen
= 0;
1043 _rxModel
->getPropertyValue( FM_PROP_MAXTEXTLEN
) >>= nMaxLen
;
1044 implSetMaxTextLen( nMaxLen
);
1048 void DbLimitedLengthField::implSetEffectiveMaxTextLen( sal_Int32 _nMaxLen
)
1050 dynamic_cast<Edit
&>(*m_pWindow
).SetMaxTextLen(_nMaxLen
);
1052 dynamic_cast<Edit
&>(*m_pPainter
).SetMaxTextLen(_nMaxLen
);
1055 DbTextField::DbTextField(DbGridColumn
& _rColumn
)
1056 :DbLimitedLengthField(_rColumn
)
1058 ,m_pPainterImplementation( nullptr )
1059 ,m_bIsSimpleEdit( true )
1064 DbTextField::~DbTextField( )
1066 DELETEZ( m_pPainterImplementation
);
1071 void DbTextField::Init( vcl::Window
& rParent
, const Reference
< XRowSet
>& xCursor
)
1073 sal_Int16 nAlignment
= m_rColumn
.SetAlignmentFromModel(-1);
1075 Reference
< XPropertySet
> xModel( m_rColumn
.getModel() );
1077 WinBits nStyle
= WB_LEFT
;
1080 case awt::TextAlign::RIGHT
:
1084 case awt::TextAlign::CENTER
:
1089 // is this a multi-line field?
1090 bool bIsMultiLine
= false;
1095 OSL_VERIFY( xModel
->getPropertyValue( FM_PROP_MULTILINE
) >>= bIsMultiLine
);
1098 catch( const Exception
& )
1100 OSL_FAIL( "DbTextField::Init: caught an exception while determining the multi-line capabilities!" );
1101 DBG_UNHANDLED_EXCEPTION();
1104 m_bIsSimpleEdit
= !bIsMultiLine
;
1107 m_pWindow
= VclPtr
<MultiLineTextCell
>::Create( &rParent
, nStyle
);
1108 m_pEdit
= new MultiLineEditImplementation( *static_cast< MultiLineTextCell
* >( m_pWindow
.get() ) );
1110 m_pPainter
= VclPtr
<MultiLineTextCell
>::Create( &rParent
, nStyle
);
1111 m_pPainterImplementation
= new MultiLineEditImplementation( *static_cast< MultiLineTextCell
* >( m_pPainter
.get() ) );
1115 m_pWindow
= VclPtr
<Edit
>::Create( &rParent
, nStyle
);
1116 m_pEdit
= new EditImplementation( *static_cast< Edit
* >( m_pWindow
.get() ) );
1118 m_pPainter
= VclPtr
<Edit
>::Create( &rParent
, nStyle
);
1119 m_pPainterImplementation
= new EditImplementation( *static_cast< Edit
* >( m_pPainter
.get() ) );
1122 if ( WB_LEFT
== nStyle
)
1124 // this is so that when getting the focus, the selection is oriented left-to-right
1125 AllSettings aSettings
= m_pWindow
->GetSettings();
1126 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
1127 aStyleSettings
.SetSelectionOptions(
1128 aStyleSettings
.GetSelectionOptions() | SelectionOptions::ShowFirst
);
1129 aSettings
.SetStyleSettings(aStyleSettings
);
1130 m_pWindow
->SetSettings(aSettings
);
1133 implAdjustGenericFieldSetting( xModel
);
1135 DbLimitedLengthField::Init( rParent
, xCursor
);
1139 CellControllerRef
DbTextField::CreateController() const
1141 return new EditCellController( m_pEdit
);
1145 void DbTextField::PaintFieldToCell( OutputDevice
& _rDev
, const tools::Rectangle
& _rRect
, const Reference
< XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& _rxFormatter
)
1147 if ( m_pPainterImplementation
)
1148 m_pPainterImplementation
->SetText( GetFormatText( _rxField
, _rxFormatter
) );
1150 DbLimitedLengthField::PaintFieldToCell( _rDev
, _rRect
, _rxField
, _rxFormatter
);
1154 OUString
DbTextField::GetFormatText(const Reference
< XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& xFormatter
, Color
** /*ppColor*/)
1156 const css::uno::Reference
<css::beans::XPropertySet
> xPS(_rxField
, UNO_QUERY
);
1157 FormattedColumnValue
fmter( xFormatter
, xPS
);
1159 return fmter
.getFormattedValue();
1163 void DbTextField::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& xFormatter
)
1165 m_pEdit
->SetText( GetFormatText( _rxField
, xFormatter
) );
1166 m_pEdit
->SetSelection( Selection( SELECTION_MAX
, SELECTION_MIN
) );
1170 void DbTextField::updateFromModel( Reference
< XPropertySet
> _rxModel
)
1172 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbTextField::updateFromModel: invalid call!" );
1175 _rxModel
->getPropertyValue( FM_PROP_TEXT
) >>= sText
;
1177 sal_Int32 nMaxTextLen
= m_pEdit
->GetMaxTextLen();
1178 if ( EDIT_NOLIMIT
!= nMaxTextLen
&& sText
.getLength() > nMaxTextLen
)
1180 sal_Int32 nDiff
= sText
.getLength() - nMaxTextLen
;
1181 sText
= sText
.replaceAt(sText
.getLength() - nDiff
,nDiff
, OUString());
1185 m_pEdit
->SetText( sText
);
1186 m_pEdit
->SetSelection( Selection( SELECTION_MAX
, SELECTION_MIN
) );
1190 bool DbTextField::commitControl()
1192 OUString
aText( m_pEdit
->GetText( getModelLineEndSetting( m_rColumn
.getModel() ) ) );
1193 // we have to check if the length before we can decide if the value was modified
1194 sal_Int32 nMaxTextLen
= m_pEdit
->GetMaxTextLen();
1195 if ( EDIT_NOLIMIT
!= nMaxTextLen
)
1198 m_rColumn
.getModel()->getPropertyValue( FM_PROP_TEXT
) >>= sOldValue
;
1199 // if the new value didn't change we must set the old long value again
1200 if ( sOldValue
.getLength() > nMaxTextLen
&& sOldValue
.compareTo(aText
,nMaxTextLen
) == 0 )
1203 m_rColumn
.getModel()->setPropertyValue( FM_PROP_TEXT
, makeAny( aText
) );
1208 void DbTextField::implSetEffectiveMaxTextLen( sal_Int32 _nMaxLen
)
1211 m_pEdit
->SetMaxTextLen( _nMaxLen
);
1212 if ( m_pPainterImplementation
)
1213 m_pPainterImplementation
->SetMaxTextLen( _nMaxLen
);
1216 DbFormattedField::DbFormattedField(DbGridColumn
& _rColumn
)
1217 :DbLimitedLengthField(_rColumn
)
1218 ,m_nKeyType(css::util::NumberFormat::UNDEFINED
)
1221 // if our model's format key changes we want to propagate the new value to our windows
1222 doPropertyListening( FM_PROP_FORMATKEY
);
1226 DbFormattedField::~DbFormattedField()
1231 void DbFormattedField::Init( vcl::Window
& rParent
, const Reference
< XRowSet
>& xCursor
)
1233 sal_Int16 nAlignment
= m_rColumn
.SetAlignmentFromModel(-1);
1235 Reference
< css::beans::XPropertySet
> xUnoModel
= m_rColumn
.getModel();
1239 case css::awt::TextAlign::RIGHT
:
1240 m_pWindow
= VclPtr
<FormattedField
>::Create( &rParent
, WB_RIGHT
);
1241 m_pPainter
= VclPtr
<FormattedField
>::Create( &rParent
, WB_RIGHT
);
1244 case css::awt::TextAlign::CENTER
:
1245 m_pWindow
= VclPtr
<FormattedField
>::Create( &rParent
, WB_CENTER
);
1246 m_pPainter
= VclPtr
<FormattedField
>::Create( &rParent
, WB_CENTER
);
1249 m_pWindow
= VclPtr
<FormattedField
>::Create( &rParent
, WB_LEFT
);
1250 m_pPainter
= VclPtr
<FormattedField
>::Create( &rParent
, WB_LEFT
);
1252 // Everything just so that the selection goes from right to left when getting focus
1253 AllSettings aSettings
= m_pWindow
->GetSettings();
1254 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
1255 aStyleSettings
.SetSelectionOptions(
1256 aStyleSettings
.GetSelectionOptions() | SelectionOptions::ShowFirst
);
1257 aSettings
.SetStyleSettings(aStyleSettings
);
1258 m_pWindow
->SetSettings(aSettings
);
1261 implAdjustGenericFieldSetting( xUnoModel
);
1263 static_cast< FormattedField
* >( m_pWindow
.get() )->SetStrictFormat( false );
1264 static_cast< FormattedField
* >( m_pPainter
.get() )->SetStrictFormat( false );
1265 // if one allows any formatting, one cannot make an entry check anyway
1266 // (the FormattedField does not support that anyway, only derived classes)
1268 // get the formatter from the uno model
1269 // (I could theoretically also go via the css::util::NumberFormatter, which the cursor would
1270 // surely give me. The problem is that I can not really rely on the fact that the two
1271 // formatters are the same. Clean is the whole thing if I go via the UNO model.)
1272 sal_Int32 nFormatKey
= -1;
1274 // let's see if the model has one ...
1275 DBG_ASSERT(::comphelper::hasProperty(FM_PROP_FORMATSSUPPLIER
, xUnoModel
), "DbFormattedField::Init : invalid UNO model !");
1276 Any
aSupplier( xUnoModel
->getPropertyValue(FM_PROP_FORMATSSUPPLIER
));
1277 if (aSupplier
.hasValue())
1279 m_xSupplier
.set(aSupplier
, css::uno::UNO_QUERY
);
1280 if (m_xSupplier
.is())
1282 // if we take the supplier from the model, then also the key
1283 Any
aFmtKey( xUnoModel
->getPropertyValue(FM_PROP_FORMATKEY
));
1284 if (aFmtKey
.hasValue())
1286 DBG_ASSERT(aFmtKey
.getValueType().getTypeClass() == TypeClass_LONG
, "DbFormattedField::Init : invalid format key property (no sal_Int32) !");
1287 nFormatKey
= ::comphelper::getINT32(aFmtKey
);
1291 SAL_INFO("svx.fmcomp", "DbFormattedField::Init : my uno-model has no format-key, but a formats supplier !");
1292 // the OFormattedModel which we usually are working with ensures that the model has a format key
1293 // as soon as the form is loaded. Unfortunally this method here is called from within loaded, too.
1294 // So if our LoadListener is called before the LoadListener of the model, this "else case" is
1296 // Of course our property listener for the FormatKey property will notify us if the prop is changed,
1297 // so this here isn't really bad ....
1303 // No? Maybe the css::form::component::Form behind the cursor?
1304 if (!m_xSupplier
.is())
1306 Reference
< XRowSet
> xCursorForm(xCursor
, UNO_QUERY
);
1307 if (xCursorForm
.is())
1308 { // If we take the formatter from the cursor, then also the key from the field to which we are bound
1309 m_xSupplier
= getNumberFormats(getConnection(xCursorForm
));
1311 if (m_rColumn
.GetField().is())
1312 nFormatKey
= ::comphelper::getINT32(m_rColumn
.GetField()->getPropertyValue(FM_PROP_FORMATKEY
));
1316 SvNumberFormatter
* pFormatterUsed
= nullptr;
1317 if (m_xSupplier
.is())
1319 SvNumberFormatsSupplierObj
* pImplmentation
= SvNumberFormatsSupplierObj::getImplementation(m_xSupplier
);
1321 pFormatterUsed
= pImplmentation
->GetNumberFormatter();
1323 // Everything is invalid: the supplier is of the wrong type, then we can not
1324 // rely on a standard formatter to know the (possibly non-standard) key.
1328 // a standard formatter ...
1329 if (pFormatterUsed
== nullptr)
1331 pFormatterUsed
= static_cast<FormattedField
*>(m_pWindow
.get())->StandardFormatter();
1332 DBG_ASSERT(pFormatterUsed
!= nullptr, "DbFormattedField::Init : no standard formatter given by the numeric field !");
1334 // ... and a standard key
1335 if (nFormatKey
== -1)
1338 m_nKeyType
= comphelper::getNumberFormatType(m_xSupplier
->getNumberFormats(), nFormatKey
);
1340 static_cast<FormattedField
*>(m_pWindow
.get())->SetFormatter(pFormatterUsed
);
1341 static_cast<FormattedField
*>(m_pPainter
.get())->SetFormatter(pFormatterUsed
);
1343 static_cast<FormattedField
*>(m_pWindow
.get())->SetFormatKey(nFormatKey
);
1344 static_cast<FormattedField
*>(m_pPainter
.get())->SetFormatKey(nFormatKey
);
1346 static_cast<FormattedField
*>(m_pWindow
.get())->TreatAsNumber(m_rColumn
.IsNumeric());
1347 static_cast<FormattedField
*>(m_pPainter
.get())->TreatAsNumber(m_rColumn
.IsNumeric());
1349 // min and max values
1350 if (m_rColumn
.IsNumeric())
1352 bool bClearMin
= true;
1353 if (::comphelper::hasProperty(FM_PROP_EFFECTIVE_MIN
, xUnoModel
))
1355 Any
aMin( xUnoModel
->getPropertyValue(FM_PROP_EFFECTIVE_MIN
));
1356 if (aMin
.getValueType().getTypeClass() != TypeClass_VOID
)
1358 DBG_ASSERT(aMin
.getValueType().getTypeClass() == TypeClass_DOUBLE
, "DbFormattedField::Init : the model has an invalid min value !");
1359 double dMin
= ::comphelper::getDouble(aMin
);
1360 static_cast<FormattedField
*>(m_pWindow
.get())->SetMinValue(dMin
);
1361 static_cast<FormattedField
*>(m_pPainter
.get())->SetMinValue(dMin
);
1367 static_cast<FormattedField
*>(m_pWindow
.get())->ClearMinValue();
1368 static_cast<FormattedField
*>(m_pPainter
.get())->ClearMinValue();
1370 bool bClearMax
= true;
1371 if (::comphelper::hasProperty(FM_PROP_EFFECTIVE_MAX
, xUnoModel
))
1373 Any
aMin( xUnoModel
->getPropertyValue(FM_PROP_EFFECTIVE_MAX
));
1374 if (aMin
.getValueType().getTypeClass() != TypeClass_VOID
)
1376 DBG_ASSERT(aMin
.getValueType().getTypeClass() == TypeClass_DOUBLE
, "DbFormattedField::Init : the model has an invalid max value !");
1377 double dMin
= ::comphelper::getDouble(aMin
);
1378 static_cast<FormattedField
*>(m_pWindow
.get())->SetMaxValue(dMin
);
1379 static_cast<FormattedField
*>(m_pPainter
.get())->SetMaxValue(dMin
);
1385 static_cast<FormattedField
*>(m_pWindow
.get())->ClearMaxValue();
1386 static_cast<FormattedField
*>(m_pPainter
.get())->ClearMaxValue();
1390 // the default value
1391 Any
aDefault( xUnoModel
->getPropertyValue(FM_PROP_EFFECTIVE_DEFAULT
));
1392 if (aDefault
.hasValue())
1393 { // the thing can be a double or a string
1394 switch (aDefault
.getValueType().getTypeClass())
1396 case TypeClass_DOUBLE
:
1397 if (m_rColumn
.IsNumeric())
1399 static_cast<FormattedField
*>(m_pWindow
.get())->SetDefaultValue(::comphelper::getDouble(aDefault
));
1400 static_cast<FormattedField
*>(m_pPainter
.get())->SetDefaultValue(::comphelper::getDouble(aDefault
));
1404 OUString sConverted
;
1406 pFormatterUsed
->GetOutputString(::comphelper::getDouble(aDefault
), 0, sConverted
, &pDummy
);
1407 static_cast<FormattedField
*>(m_pWindow
.get())->SetDefaultText(sConverted
);
1408 static_cast<FormattedField
*>(m_pPainter
.get())->SetDefaultText(sConverted
);
1411 case TypeClass_STRING
:
1413 OUString
sDefault( ::comphelper::getString(aDefault
) );
1414 if (m_rColumn
.IsNumeric())
1417 sal_uInt32
nTestFormat(0);
1418 if (pFormatterUsed
->IsNumberFormat(sDefault
, nTestFormat
, dVal
))
1420 static_cast<FormattedField
*>(m_pWindow
.get())->SetDefaultValue(dVal
);
1421 static_cast<FormattedField
*>(m_pPainter
.get())->SetDefaultValue(dVal
);
1426 static_cast<FormattedField
*>(m_pWindow
.get())->SetDefaultText(sDefault
);
1427 static_cast<FormattedField
*>(m_pPainter
.get())->SetDefaultText(sDefault
);
1432 OSL_FAIL( "DbFormattedField::Init: unexpected value type!" );
1436 DbLimitedLengthField::Init( rParent
, xCursor
);
1440 CellControllerRef
DbFormattedField::CreateController() const
1442 return new ::svt::FormattedFieldCellController( static_cast< FormattedField
* >( m_pWindow
.get() ) );
1446 void DbFormattedField::_propertyChanged( const PropertyChangeEvent
& _rEvent
)
1448 if (_rEvent
.PropertyName
== FM_PROP_FORMATKEY
)
1450 sal_Int32 nNewKey
= _rEvent
.NewValue
.hasValue() ? ::comphelper::getINT32(_rEvent
.NewValue
) : 0;
1451 m_nKeyType
= comphelper::getNumberFormatType(m_xSupplier
->getNumberFormats(), nNewKey
);
1453 DBG_ASSERT(m_pWindow
&& m_pPainter
, "DbFormattedField::_propertyChanged : where are my windows ?");
1455 static_cast< FormattedField
* >( m_pWindow
.get() )->SetFormatKey( nNewKey
);
1457 static_cast< FormattedField
* >( m_pPainter
.get() )->SetFormatKey( nNewKey
);
1461 DbLimitedLengthField::_propertyChanged( _rEvent
);
1466 OUString
DbFormattedField::GetFormatText(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& /*xFormatter*/, Color
** ppColor
)
1468 // no color specification by default
1469 if (ppColor
!= nullptr)
1472 // NULL value -> empty text
1479 if (m_rColumn
.IsNumeric())
1481 // The IsNumeric at the column says nothing about the class of the used format, but
1482 // about the class of the field bound to the column. So when you bind a FormattedField
1483 // column to a double field and format it as text, m_rColumn.IsNumeric() returns
1484 // sal_True. So that simply means that I can query the contents of the variant using
1485 // getDouble, and then I can leave the rest (the formatting) to the FormattedField.
1486 double dValue
= getValue( _rxField
, m_rColumn
.GetParent().getNullDate() );
1487 if (_rxField
->wasNull())
1489 static_cast<FormattedField
*>(m_pPainter
.get())->SetValue(dValue
);
1493 // Here I can not work with a double, since the field can not provide it to me.
1494 // So simply bind the text from the css::util::NumberFormatter to the correct css::form::component::Form.
1495 aText
= _rxField
->getString();
1496 if (_rxField
->wasNull())
1498 static_cast<FormattedField
*>(m_pPainter
.get())->SetTextFormatted(aText
);
1501 catch( const Exception
& )
1503 DBG_UNHANDLED_EXCEPTION();
1506 aText
= m_pPainter
->GetText();
1507 if (ppColor
!= nullptr)
1508 *ppColor
= static_cast<FormattedField
*>(m_pPainter
.get())->GetLastOutputColor();
1514 void DbFormattedField::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& /*xFormatter*/)
1518 FormattedField
* pFormattedWindow
= static_cast<FormattedField
*>(m_pWindow
.get());
1520 { // NULL value -> empty text
1521 m_pWindow
->SetText(OUString());
1523 else if (m_rColumn
.IsNumeric())
1525 // The IsNumeric at the column says nothing about the class of the used format, but
1526 // about the class of the field bound to the column. So when you bind a FormattedField
1527 // column to a double field and format it as text, m_rColumn.IsNumeric() returns
1528 // sal_True. So that simply means that I can query the contents of the variant using
1529 // getDouble, and then I can leave the rest (the formatting) to the FormattedField.
1530 double dValue
= getValue( _rxField
, m_rColumn
.GetParent().getNullDate() );
1531 if (_rxField
->wasNull())
1532 m_pWindow
->SetText(OUString());
1534 pFormattedWindow
->SetValue(dValue
);
1538 // Here I can not work with a double, since the field can not provide it to me.
1539 // So simply bind the text from the css::util::NumberFormatter to the correct css::form::component::Form.
1540 OUString
sText( _rxField
->getString());
1542 pFormattedWindow
->SetTextFormatted( sText
);
1543 pFormattedWindow
->SetSelection( Selection( SELECTION_MAX
, SELECTION_MIN
) );
1546 catch( const Exception
& )
1548 DBG_UNHANDLED_EXCEPTION();
1553 void DbFormattedField::updateFromModel( Reference
< XPropertySet
> _rxModel
)
1555 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbFormattedField::updateFromModel: invalid call!" );
1557 FormattedField
* pFormattedWindow
= static_cast< FormattedField
* >( m_pWindow
.get() );
1560 Any aValue
= _rxModel
->getPropertyValue( FM_PROP_EFFECTIVE_VALUE
);
1561 if ( !aValue
.hasValue() || (aValue
>>= sText
) )
1562 { // our effective value is transferred as string
1563 pFormattedWindow
->SetTextFormatted( sText
);
1564 pFormattedWindow
->SetSelection( Selection( SELECTION_MAX
, SELECTION_MIN
) );
1570 pFormattedWindow
->SetValue(dValue
);
1575 bool DbFormattedField::commitControl()
1578 FormattedField
& rField
= *static_cast<FormattedField
*>(m_pWindow
.get());
1579 DBG_ASSERT(&rField
== m_pWindow
, "DbFormattedField::commitControl : can't work with a window other than my own !");
1580 if (m_rColumn
.IsNumeric())
1582 if (!rField
.GetText().isEmpty())
1583 aNewVal
<<= rField
.GetValue();
1584 // an empty string is passed on as void by default, to start with
1587 aNewVal
<<= rField
.GetTextValue();
1589 m_rColumn
.getModel()->setPropertyValue(FM_PROP_EFFECTIVE_VALUE
, aNewVal
);
1593 DbCheckBox::DbCheckBox( DbGridColumn
& _rColumn
)
1594 :DbCellControl( _rColumn
)
1596 setAlignedController( false );
1601 void setCheckBoxStyle( vcl::Window
* _pWindow
, bool bMono
)
1603 AllSettings aSettings
= _pWindow
->GetSettings();
1604 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
1606 aStyleSettings
.SetOptions( aStyleSettings
.GetOptions() | StyleSettingsOptions::Mono
);
1608 aStyleSettings
.SetOptions( aStyleSettings
.GetOptions() & (~StyleSettingsOptions::Mono
) );
1609 aSettings
.SetStyleSettings( aStyleSettings
);
1610 _pWindow
->SetSettings( aSettings
);
1615 void DbCheckBox::Init( vcl::Window
& rParent
, const Reference
< XRowSet
>& xCursor
)
1617 setTransparent( true );
1619 m_pWindow
= VclPtr
<CheckBoxControl
>::Create( &rParent
);
1620 m_pPainter
= VclPtr
<CheckBoxControl
>::Create( &rParent
);
1622 m_pWindow
->SetPaintTransparent( true );
1623 m_pPainter
->SetPaintTransparent( true );
1625 m_pPainter
->SetBackground();
1629 Reference
< XPropertySet
> xModel( m_rColumn
.getModel(), UNO_SET_THROW
);
1631 sal_Int16 nStyle
= awt::VisualEffect::LOOK3D
;
1632 OSL_VERIFY( xModel
->getPropertyValue( FM_PROP_VISUALEFFECT
) >>= nStyle
);
1634 setCheckBoxStyle( m_pWindow
, nStyle
== awt::VisualEffect::FLAT
);
1635 setCheckBoxStyle( m_pPainter
, nStyle
== awt::VisualEffect::FLAT
);
1637 bool bTristate
= true;
1638 OSL_VERIFY( xModel
->getPropertyValue( FM_PROP_TRISTATE
) >>= bTristate
);
1639 static_cast< CheckBoxControl
* >( m_pWindow
.get() )->GetBox().EnableTriState( bTristate
);
1640 static_cast< CheckBoxControl
* >( m_pPainter
.get() )->GetBox().EnableTriState( bTristate
);
1642 catch( const Exception
& )
1644 DBG_UNHANDLED_EXCEPTION();
1647 DbCellControl::Init( rParent
, xCursor
);
1651 CellControllerRef
DbCheckBox::CreateController() const
1653 return new CheckBoxCellController(static_cast<CheckBoxControl
*>(m_pWindow
.get()));
1656 static void lcl_setCheckBoxState( const Reference
< css::sdb::XColumn
>& _rxField
,
1657 CheckBoxControl
* _pCheckBoxControl
)
1659 TriState eState
= TRISTATE_INDET
;
1664 bool bValue
= _rxField
->getBoolean();
1665 if (!_rxField
->wasNull())
1666 eState
= bValue
? TRISTATE_TRUE
: TRISTATE_FALSE
;
1668 catch( const Exception
& )
1670 DBG_UNHANDLED_EXCEPTION();
1673 _pCheckBoxControl
->GetBox().SetState(eState
);
1677 void DbCheckBox::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& /*xFormatter*/)
1679 lcl_setCheckBoxState( _rxField
, static_cast<CheckBoxControl
*>(m_pWindow
.get()) );
1683 void DbCheckBox::PaintFieldToCell(OutputDevice
& rDev
, const tools::Rectangle
& rRect
,
1684 const Reference
< css::sdb::XColumn
>& _rxField
,
1685 const Reference
< XNumberFormatter
>& xFormatter
)
1687 lcl_setCheckBoxState( _rxField
, static_cast<CheckBoxControl
*>(m_pPainter
.get()) );
1688 DbCellControl::PaintFieldToCell( rDev
, rRect
, _rxField
, xFormatter
);
1692 void DbCheckBox::updateFromModel( Reference
< XPropertySet
> _rxModel
)
1694 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbCheckBox::updateFromModel: invalid call!" );
1696 sal_Int16 nState
= TRISTATE_INDET
;
1697 _rxModel
->getPropertyValue( FM_PROP_STATE
) >>= nState
;
1698 static_cast< CheckBoxControl
* >( m_pWindow
.get() )->GetBox().SetState( static_cast< TriState
>( nState
) );
1702 bool DbCheckBox::commitControl()
1704 m_rColumn
.getModel()->setPropertyValue( FM_PROP_STATE
,
1705 makeAny( (sal_Int16
)( static_cast< CheckBoxControl
* >( m_pWindow
.get() )->GetBox().GetState() ) ) );
1710 OUString
DbCheckBox::GetFormatText(const Reference
< XColumn
>& /*_rxField*/, const Reference
< XNumberFormatter
>& /*xFormatter*/, Color
** /*ppColor*/)
1715 DbPatternField::DbPatternField( DbGridColumn
& _rColumn
, const Reference
<XComponentContext
>& _rContext
)
1716 :DbCellControl( _rColumn
)
1717 ,m_xContext( _rContext
)
1719 doPropertyListening( FM_PROP_LITERALMASK
);
1720 doPropertyListening( FM_PROP_EDITMASK
);
1721 doPropertyListening( FM_PROP_STRICTFORMAT
);
1725 void DbPatternField::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& _rxModel
)
1727 DBG_ASSERT( m_pWindow
, "DbPatternField::implAdjustGenericFieldSetting: not to be called without window!" );
1728 DBG_ASSERT( _rxModel
.is(), "DbPatternField::implAdjustGenericFieldSetting: invalid model!" );
1729 if ( m_pWindow
&& _rxModel
.is() )
1733 bool bStrict
= false;
1735 _rxModel
->getPropertyValue( FM_PROP_LITERALMASK
) >>= aLitMask
;
1736 _rxModel
->getPropertyValue( FM_PROP_EDITMASK
) >>= aEditMask
;
1737 _rxModel
->getPropertyValue( FM_PROP_STRICTFORMAT
) >>= bStrict
;
1739 OString
aAsciiEditMask(OUStringToOString(aEditMask
, RTL_TEXTENCODING_ASCII_US
));
1741 static_cast< PatternField
* >( m_pWindow
.get() )->SetMask( aAsciiEditMask
, aLitMask
);
1742 static_cast< PatternField
* >( m_pPainter
.get() )->SetMask( aAsciiEditMask
, aLitMask
);
1743 static_cast< PatternField
* >( m_pWindow
.get() )->SetStrictFormat( bStrict
);
1744 static_cast< PatternField
* >( m_pPainter
.get() )->SetStrictFormat( bStrict
);
1749 void DbPatternField::Init( vcl::Window
& rParent
, const Reference
< XRowSet
>& xCursor
)
1751 m_rColumn
.SetAlignmentFromModel(-1);
1753 m_pWindow
= VclPtr
<PatternField
>::Create( &rParent
, 0 );
1754 m_pPainter
= VclPtr
<PatternField
>::Create( &rParent
, 0 );
1756 Reference
< XPropertySet
> xModel( m_rColumn
.getModel() );
1757 implAdjustGenericFieldSetting( xModel
);
1759 DbCellControl::Init( rParent
, xCursor
);
1763 CellControllerRef
DbPatternField::CreateController() const
1765 return new SpinCellController( static_cast< PatternField
* >( m_pWindow
.get() ) );
1769 OUString
DbPatternField::impl_formatText( const OUString
& _rText
)
1771 m_pPainter
->SetText( _rText
);
1772 static_cast< PatternField
* >( m_pPainter
.get() )->ReformatAll();
1773 return m_pPainter
->GetText();
1777 OUString
DbPatternField::GetFormatText(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& /*xFormatter*/, Color
** /*ppColor*/)
1779 bool bIsForPaint
= _rxField
!= m_rColumn
.GetField();
1780 ::std::unique_ptr
< FormattedColumnValue
>& rpFormatter
= bIsForPaint
? m_pPaintFormatter
: m_pValueFormatter
;
1782 if ( !rpFormatter
.get() )
1784 rpFormatter
= o3tl::make_unique
< FormattedColumnValue
> (
1785 m_xContext
, getCursor(), Reference
< XPropertySet
>( _rxField
, UNO_QUERY
) );
1786 OSL_ENSURE( rpFormatter
.get(), "DbPatternField::Init: no value formatter!" );
1789 OSL_ENSURE( rpFormatter
->getColumn() == _rxField
, "DbPatternField::GetFormatText: my value formatter is working for another field ...!" );
1790 // re-creating the value formatter here every time would be quite expensive ...
1793 if ( rpFormatter
.get() )
1794 sText
= rpFormatter
->getFormattedValue();
1796 return impl_formatText( sText
);
1800 void DbPatternField::UpdateFromField( const Reference
< XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& _rxFormatter
)
1802 static_cast< Edit
* >( m_pWindow
.get() )->SetText( GetFormatText( _rxField
, _rxFormatter
) );
1803 static_cast< Edit
* >( m_pWindow
.get() )->SetSelection( Selection( SELECTION_MAX
, SELECTION_MIN
) );
1807 void DbPatternField::updateFromModel( Reference
< XPropertySet
> _rxModel
)
1809 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbPatternField::updateFromModel: invalid call!" );
1812 _rxModel
->getPropertyValue( FM_PROP_TEXT
) >>= sText
;
1814 static_cast< Edit
* >( m_pWindow
.get() )->SetText( impl_formatText( sText
) );
1815 static_cast< Edit
* >( m_pWindow
.get() )->SetSelection( Selection( SELECTION_MAX
, SELECTION_MIN
) );
1819 bool DbPatternField::commitControl()
1821 OUString
aText(m_pWindow
->GetText());
1822 m_rColumn
.getModel()->setPropertyValue(FM_PROP_TEXT
, makeAny(aText
));
1826 DbSpinField::DbSpinField( DbGridColumn
& _rColumn
, sal_Int16 _nStandardAlign
)
1827 :DbCellControl( _rColumn
)
1828 ,m_nStandardAlign( _nStandardAlign
)
1833 void DbSpinField::Init( vcl::Window
& _rParent
, const Reference
< XRowSet
>& _rxCursor
)
1835 m_rColumn
.SetAlignmentFromModel( m_nStandardAlign
);
1837 Reference
< XPropertySet
> xModel( m_rColumn
.getModel() );
1839 // determine the WinBits for the field
1840 WinBits nFieldStyle
= 0;
1841 if ( ::comphelper::getBOOL( xModel
->getPropertyValue( FM_PROP_SPIN
) ) )
1842 nFieldStyle
= WB_REPEAT
| WB_SPIN
;
1843 // create the fields
1844 m_pWindow
= createField( &_rParent
, nFieldStyle
, xModel
);
1845 m_pPainter
= createField( &_rParent
, nFieldStyle
, xModel
);
1847 // adjust all other settings which depend on the property values
1848 implAdjustGenericFieldSetting( xModel
);
1850 // call the base class
1851 DbCellControl::Init( _rParent
, _rxCursor
);
1855 CellControllerRef
DbSpinField::CreateController() const
1857 return new SpinCellController( static_cast< SpinField
* >( m_pWindow
.get() ) );
1860 DbNumericField::DbNumericField( DbGridColumn
& _rColumn
)
1861 :DbSpinField( _rColumn
)
1863 doPropertyListening( FM_PROP_DECIMAL_ACCURACY
);
1864 doPropertyListening( FM_PROP_VALUEMIN
);
1865 doPropertyListening( FM_PROP_VALUEMAX
);
1866 doPropertyListening( FM_PROP_VALUESTEP
);
1867 doPropertyListening( FM_PROP_STRICTFORMAT
);
1868 doPropertyListening( FM_PROP_SHOWTHOUSANDSEP
);
1872 void DbNumericField::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& _rxModel
)
1874 DBG_ASSERT( m_pWindow
, "DbNumericField::implAdjustGenericFieldSetting: not to be called without window!" );
1875 DBG_ASSERT( _rxModel
.is(), "DbNumericField::implAdjustGenericFieldSetting: invalid model!" );
1876 if ( m_pWindow
&& _rxModel
.is() )
1878 sal_Int32 nMin
= (sal_Int32
)getDouble( _rxModel
->getPropertyValue( FM_PROP_VALUEMIN
) );
1879 sal_Int32 nMax
= (sal_Int32
)getDouble( _rxModel
->getPropertyValue( FM_PROP_VALUEMAX
) );
1880 sal_Int32 nStep
= (sal_Int32
)getDouble( _rxModel
->getPropertyValue( FM_PROP_VALUESTEP
) );
1881 bool bStrict
= getBOOL( _rxModel
->getPropertyValue( FM_PROP_STRICTFORMAT
) );
1882 sal_Int16 nScale
= getINT16( _rxModel
->getPropertyValue( FM_PROP_DECIMAL_ACCURACY
) );
1883 bool bThousand
= getBOOL( _rxModel
->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP
) );
1885 static_cast< DoubleNumericField
* >( m_pWindow
.get() )->SetMinValue(nMin
);
1886 static_cast< DoubleNumericField
* >( m_pWindow
.get() )->SetMaxValue(nMax
);
1887 static_cast< DoubleNumericField
* >( m_pWindow
.get() )->SetSpinSize(nStep
);
1888 static_cast< DoubleNumericField
* >( m_pWindow
.get() )->SetStrictFormat(bStrict
);
1890 static_cast< DoubleNumericField
* >( m_pPainter
.get() )->SetMinValue(nMin
);
1891 static_cast< DoubleNumericField
* >( m_pPainter
.get() )->SetMaxValue(nMax
);
1892 static_cast< DoubleNumericField
* >( m_pPainter
.get() )->SetStrictFormat(bStrict
);
1895 // give a formatter to the field and the painter;
1896 // test first if I can get from the service behind a connection
1897 Reference
< css::util::XNumberFormatsSupplier
> xSupplier
;
1898 Reference
< XRowSet
> xForm
;
1899 if ( m_rColumn
.GetParent().getDataSource() )
1900 xForm
.set( Reference
< XInterface
>(*m_rColumn
.GetParent().getDataSource()), UNO_QUERY
);
1902 xSupplier
= getNumberFormats( getConnection( xForm
), true );
1903 SvNumberFormatter
* pFormatterUsed
= nullptr;
1904 if ( xSupplier
.is() )
1906 SvNumberFormatsSupplierObj
* pImplmentation
= SvNumberFormatsSupplierObj::getImplementation( xSupplier
);
1907 pFormatterUsed
= pImplmentation
? pImplmentation
->GetNumberFormatter() : nullptr;
1909 if ( nullptr == pFormatterUsed
)
1910 { // the cursor didn't lead to success -> standard
1911 pFormatterUsed
= static_cast< DoubleNumericField
* >( m_pWindow
.get() )->StandardFormatter();
1912 DBG_ASSERT( pFormatterUsed
!= nullptr, "DbNumericField::implAdjustGenericFieldSetting: no standard formatter given by the numeric field !" );
1914 static_cast< DoubleNumericField
* >( m_pWindow
.get() )->SetFormatter( pFormatterUsed
);
1915 static_cast< DoubleNumericField
* >( m_pPainter
.get() )->SetFormatter( pFormatterUsed
);
1917 // and then generate a format which has the desired length after the decimal point, etc.
1918 LanguageType aAppLanguage
= Application::GetSettings().GetUILanguageTag().getLanguageType();
1919 OUString sFormatString
= pFormatterUsed
->GenerateFormat(0, aAppLanguage
, bThousand
, false, nScale
);
1921 static_cast< DoubleNumericField
* >( m_pWindow
.get() )->SetFormat( sFormatString
, aAppLanguage
);
1922 static_cast< DoubleNumericField
* >( m_pPainter
.get() )->SetFormat( sFormatString
, aAppLanguage
);
1927 VclPtr
<SpinField
> DbNumericField::createField( vcl::Window
* _pParent
, WinBits _nFieldStyle
, const Reference
< XPropertySet
>& /*_rxModel*/ )
1929 return VclPtr
<DoubleNumericField
>::Create( _pParent
, _nFieldStyle
);
1935 OUString
lcl_setFormattedNumeric_nothrow( DoubleNumericField
& _rField
, const DbCellControl
& _rControl
,
1936 const Reference
< XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& _rxFormatter
)
1939 if ( _rxField
.is() )
1943 double fValue
= _rControl
.GetValue( _rxField
, _rxFormatter
);
1944 if ( !_rxField
->wasNull() )
1946 _rField
.SetValue( fValue
);
1947 sValue
= _rField
.GetText();
1950 catch( const Exception
& )
1952 DBG_UNHANDLED_EXCEPTION();
1960 OUString
DbNumericField::GetFormatText(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< css::util::XNumberFormatter
>& _rxFormatter
, Color
** /*ppColor*/)
1962 return lcl_setFormattedNumeric_nothrow(dynamic_cast<DoubleNumericField
&>(*m_pPainter
), *this, _rxField
, _rxFormatter
);
1966 void DbNumericField::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< css::util::XNumberFormatter
>& _rxFormatter
)
1968 lcl_setFormattedNumeric_nothrow(dynamic_cast<DoubleNumericField
&>(*m_pWindow
), *this, _rxField
, _rxFormatter
);
1972 void DbNumericField::updateFromModel( Reference
< XPropertySet
> _rxModel
)
1974 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbNumericField::updateFromModel: invalid call!" );
1977 if ( _rxModel
->getPropertyValue( FM_PROP_VALUE
) >>= dValue
)
1978 static_cast< DoubleNumericField
* >( m_pWindow
.get() )->SetValue( dValue
);
1980 m_pWindow
->SetText( OUString() );
1984 bool DbNumericField::commitControl()
1986 OUString
aText( m_pWindow
->GetText());
1989 if (!aText
.isEmpty()) // not empty
1991 double fValue
= static_cast<DoubleNumericField
*>(m_pWindow
.get())->GetValue();
1994 m_rColumn
.getModel()->setPropertyValue(FM_PROP_VALUE
, aVal
);
1998 DbCurrencyField::DbCurrencyField(DbGridColumn
& _rColumn
)
1999 :DbSpinField( _rColumn
)
2002 doPropertyListening( FM_PROP_DECIMAL_ACCURACY
);
2003 doPropertyListening( FM_PROP_VALUEMIN
);
2004 doPropertyListening( FM_PROP_VALUEMAX
);
2005 doPropertyListening( FM_PROP_VALUESTEP
);
2006 doPropertyListening( FM_PROP_STRICTFORMAT
);
2007 doPropertyListening( FM_PROP_SHOWTHOUSANDSEP
);
2008 doPropertyListening( FM_PROP_CURRENCYSYMBOL
);
2012 void DbCurrencyField::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& _rxModel
)
2014 DBG_ASSERT( m_pWindow
, "DbCurrencyField::implAdjustGenericFieldSetting: not to be called without window!" );
2015 DBG_ASSERT( _rxModel
.is(), "DbCurrencyField::implAdjustGenericFieldSetting: invalid model!" );
2016 if ( m_pWindow
&& _rxModel
.is() )
2018 m_nScale
= getINT16( _rxModel
->getPropertyValue( FM_PROP_DECIMAL_ACCURACY
) );
2019 double nMin
= getDouble( _rxModel
->getPropertyValue( FM_PROP_VALUEMIN
) );
2020 double nMax
= getDouble( _rxModel
->getPropertyValue( FM_PROP_VALUEMAX
) );
2021 double nStep
= getDouble( _rxModel
->getPropertyValue( FM_PROP_VALUESTEP
) );
2022 bool bStrict
= getBOOL( _rxModel
->getPropertyValue( FM_PROP_STRICTFORMAT
) );
2023 bool bThousand
= getBOOL( _rxModel
->getPropertyValue( FM_PROP_SHOWTHOUSANDSEP
) );
2024 OUString
aStr( getString( _rxModel
->getPropertyValue(FM_PROP_CURRENCYSYMBOL
) ) );
2026 //fdo#42747 the min/max/first/last of vcl NumericFormatters needs to be
2027 //multiplied by the no of decimal places. See also
2028 //VclBuilder::mungeAdjustment
2029 int nMul
= rtl_math_pow10Exp(1, m_nScale
);
2033 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetUseThousandSep( bThousand
);
2034 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetDecimalDigits( m_nScale
);
2035 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetCurrencySymbol( aStr
);
2036 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetFirst( nMin
);
2037 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetLast( nMax
);
2038 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetMin( nMin
);
2039 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetMax( nMax
);
2040 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetSpinSize( nStep
);
2041 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetStrictFormat( bStrict
);
2043 static_cast< LongCurrencyField
* >( m_pPainter
.get() )->SetUseThousandSep( bThousand
);
2044 static_cast< LongCurrencyField
* >( m_pPainter
.get() )->SetDecimalDigits( m_nScale
);
2045 static_cast< LongCurrencyField
* >( m_pPainter
.get() )->SetCurrencySymbol( aStr
);
2046 static_cast< LongCurrencyField
* >( m_pPainter
.get() )->SetFirst( nMin
);
2047 static_cast< LongCurrencyField
* >( m_pPainter
.get() )->SetLast( nMax
);
2048 static_cast< LongCurrencyField
* >( m_pPainter
.get() )->SetMin( nMin
);
2049 static_cast< LongCurrencyField
* >( m_pPainter
.get() )->SetMax( nMax
);
2050 static_cast< LongCurrencyField
* >( m_pPainter
.get() )->SetStrictFormat( bStrict
);
2055 VclPtr
<SpinField
> DbCurrencyField::createField( vcl::Window
* _pParent
, WinBits _nFieldStyle
, const Reference
< XPropertySet
>& /*_rxModel*/ )
2057 return VclPtr
<LongCurrencyField
>::Create( _pParent
, _nFieldStyle
);
2061 double DbCurrencyField::GetCurrency(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& xFormatter
) const
2063 double fValue
= GetValue(_rxField
, xFormatter
);
2066 // SAL_INFO("svx",("double = %.64f ",fValue);
2067 fValue
= ::rtl::math::pow10Exp(fValue
, m_nScale
);
2068 fValue
= ::rtl::math::round(fValue
);
2076 OUString
lcl_setFormattedCurrency_nothrow( LongCurrencyField
& _rField
, const DbCurrencyField
& _rControl
,
2077 const Reference
< XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& _rxFormatter
)
2080 if ( _rxField
.is() )
2084 double fValue
= _rControl
.GetCurrency( _rxField
, _rxFormatter
);
2085 if ( !_rxField
->wasNull() )
2087 _rField
.SetValue( fValue
);
2088 sValue
= _rField
.GetText();
2091 catch( const Exception
& )
2093 DBG_UNHANDLED_EXCEPTION();
2101 OUString
DbCurrencyField::GetFormatText(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< css::util::XNumberFormatter
>& _rxFormatter
, Color
** /*ppColor*/)
2103 return lcl_setFormattedCurrency_nothrow( dynamic_cast< LongCurrencyField
& >( *m_pPainter
), *this, _rxField
, _rxFormatter
);
2107 void DbCurrencyField::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< css::util::XNumberFormatter
>& _rxFormatter
)
2109 lcl_setFormattedCurrency_nothrow( dynamic_cast< LongCurrencyField
& >( *m_pWindow
), *this, _rxField
, _rxFormatter
);
2113 void DbCurrencyField::updateFromModel( Reference
< XPropertySet
> _rxModel
)
2115 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbCurrencyField::updateFromModel: invalid call!" );
2118 if ( _rxModel
->getPropertyValue( FM_PROP_VALUE
) >>= dValue
)
2122 dValue
= ::rtl::math::pow10Exp( dValue
, m_nScale
);
2123 dValue
= ::rtl::math::round(dValue
);
2126 static_cast< LongCurrencyField
* >( m_pWindow
.get() )->SetValue( dValue
);
2129 m_pWindow
->SetText( OUString() );
2133 bool DbCurrencyField::commitControl()
2135 OUString
aText(m_pWindow
->GetText());
2137 if (!aText
.isEmpty()) // not empty
2139 double fValue
= static_cast<LongCurrencyField
*>(m_pWindow
.get())->GetValue();
2142 fValue
/= ::rtl::math::pow10Exp(1.0, m_nScale
);
2146 m_rColumn
.getModel()->setPropertyValue(FM_PROP_VALUE
, aVal
);
2150 DbDateField::DbDateField( DbGridColumn
& _rColumn
)
2151 :DbSpinField( _rColumn
)
2153 doPropertyListening( FM_PROP_DATEFORMAT
);
2154 doPropertyListening( FM_PROP_DATEMIN
);
2155 doPropertyListening( FM_PROP_DATEMAX
);
2156 doPropertyListening( FM_PROP_STRICTFORMAT
);
2157 doPropertyListening( FM_PROP_DATE_SHOW_CENTURY
);
2161 VclPtr
<SpinField
> DbDateField::createField( vcl::Window
* _pParent
, WinBits _nFieldStyle
, const Reference
< XPropertySet
>& _rxModel
)
2163 // check if there is a DropDown property set to TRUE
2164 bool bDropDown
= !hasProperty( FM_PROP_DROPDOWN
, _rxModel
)
2165 || getBOOL( _rxModel
->getPropertyValue( FM_PROP_DROPDOWN
) );
2167 _nFieldStyle
|= WB_DROPDOWN
;
2169 VclPtr
<CalendarField
> pField
= VclPtr
<CalendarField
>::Create( _pParent
, _nFieldStyle
);
2171 pField
->EnableToday();
2172 pField
->EnableNone();
2178 void DbDateField::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& _rxModel
)
2180 DBG_ASSERT( m_pWindow
, "DbDateField::implAdjustGenericFieldSetting: not to be called without window!" );
2181 DBG_ASSERT( _rxModel
.is(), "DbDateField::implAdjustGenericFieldSetting: invalid model!" );
2182 if ( m_pWindow
&& _rxModel
.is() )
2184 sal_Int16 nFormat
= getINT16( _rxModel
->getPropertyValue( FM_PROP_DATEFORMAT
) );
2186 OSL_VERIFY( _rxModel
->getPropertyValue( FM_PROP_DATEMIN
) >>= aMin
);
2188 OSL_VERIFY( _rxModel
->getPropertyValue( FM_PROP_DATEMAX
) >>= aMax
);
2189 bool bStrict
= getBOOL( _rxModel
->getPropertyValue( FM_PROP_STRICTFORMAT
) );
2191 Any aCentury
= _rxModel
->getPropertyValue( FM_PROP_DATE_SHOW_CENTURY
);
2192 if ( aCentury
.getValueType().getTypeClass() != TypeClass_VOID
)
2194 bool bShowDateCentury
= getBOOL( aCentury
);
2196 static_cast<DateField
*>( m_pWindow
.get() )->SetShowDateCentury( bShowDateCentury
);
2197 static_cast<DateField
*>( m_pPainter
.get() )->SetShowDateCentury( bShowDateCentury
);
2200 static_cast< DateField
* >( m_pWindow
.get() )->SetExtDateFormat( (ExtDateFieldFormat
)nFormat
);
2201 static_cast< DateField
* >( m_pWindow
.get() )->SetMin( aMin
);
2202 static_cast< DateField
* >( m_pWindow
.get() )->SetMax( aMax
);
2203 static_cast< DateField
* >( m_pWindow
.get() )->SetStrictFormat( bStrict
);
2204 static_cast< DateField
* >( m_pWindow
.get() )->EnableEmptyFieldValue( true );
2206 static_cast< DateField
* >( m_pPainter
.get() )->SetExtDateFormat( (ExtDateFieldFormat
)nFormat
);
2207 static_cast< DateField
* >( m_pPainter
.get() )->SetMin( aMin
);
2208 static_cast< DateField
* >( m_pPainter
.get() )->SetMax( aMax
);
2209 static_cast< DateField
* >( m_pPainter
.get() )->SetStrictFormat( bStrict
);
2210 static_cast< DateField
* >( m_pPainter
.get() )->EnableEmptyFieldValue( true );
2217 OUString
lcl_setFormattedDate_nothrow( DateField
& _rField
, const Reference
< XColumn
>& _rxField
)
2220 if ( _rxField
.is() )
2224 css::util::Date aValue
= _rxField
->getDate();
2225 if ( _rxField
->wasNull() )
2226 _rField
.SetText( sDate
);
2229 _rField
.SetDate( ::Date( aValue
.Day
, aValue
.Month
, aValue
.Year
) );
2230 sDate
= _rField
.GetText();
2233 catch( const Exception
& )
2235 DBG_UNHANDLED_EXCEPTION();
2242 OUString
DbDateField::GetFormatText(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< css::util::XNumberFormatter
>& /*xFormatter*/, Color
** /*ppColor*/)
2244 return lcl_setFormattedDate_nothrow(dynamic_cast<DateField
&>(*m_pPainter
.get()), _rxField
);
2248 void DbDateField::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& /*xFormatter*/)
2250 lcl_setFormattedDate_nothrow(dynamic_cast<DateField
&>(*m_pWindow
.get()), _rxField
);
2254 void DbDateField::updateFromModel( Reference
< XPropertySet
> _rxModel
)
2256 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbDateField::updateFromModel: invalid call!" );
2259 if ( _rxModel
->getPropertyValue( FM_PROP_DATE
) >>= aDate
)
2260 static_cast< DateField
* >( m_pWindow
.get() )->SetDate( ::Date( aDate
) );
2262 static_cast< DateField
* >( m_pWindow
.get() )->SetText( OUString() );
2266 bool DbDateField::commitControl()
2268 OUString
aText(m_pWindow
->GetText());
2270 if (!aText
.isEmpty())
2271 aVal
<<= static_cast<DateField
*>(m_pWindow
.get())->GetDate().GetUNODate();
2275 m_rColumn
.getModel()->setPropertyValue(FM_PROP_DATE
, aVal
);
2279 DbTimeField::DbTimeField( DbGridColumn
& _rColumn
)
2280 :DbSpinField( _rColumn
, css::awt::TextAlign::LEFT
)
2282 doPropertyListening( FM_PROP_TIMEFORMAT
);
2283 doPropertyListening( FM_PROP_TIMEMIN
);
2284 doPropertyListening( FM_PROP_TIMEMAX
);
2285 doPropertyListening( FM_PROP_STRICTFORMAT
);
2289 VclPtr
<SpinField
> DbTimeField::createField( vcl::Window
* _pParent
, WinBits _nFieldStyle
, const Reference
< XPropertySet
>& /*_rxModel*/ )
2291 return VclPtr
<TimeField
>::Create( _pParent
, _nFieldStyle
);
2295 void DbTimeField::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& _rxModel
)
2297 DBG_ASSERT( m_pWindow
, "DbTimeField::implAdjustGenericFieldSetting: not to be called without window!" );
2298 DBG_ASSERT( _rxModel
.is(), "DbTimeField::implAdjustGenericFieldSetting: invalid model!" );
2299 if ( m_pWindow
&& _rxModel
.is() )
2301 sal_Int16 nFormat
= getINT16( _rxModel
->getPropertyValue( FM_PROP_TIMEFORMAT
) );
2303 OSL_VERIFY( _rxModel
->getPropertyValue( FM_PROP_TIMEMIN
) >>= aMin
);
2305 OSL_VERIFY( _rxModel
->getPropertyValue( FM_PROP_TIMEMAX
) >>= aMax
);
2306 bool bStrict
= getBOOL( _rxModel
->getPropertyValue( FM_PROP_STRICTFORMAT
) );
2308 static_cast< TimeField
* >( m_pWindow
.get() )->SetExtFormat( (ExtTimeFieldFormat
)nFormat
);
2309 static_cast< TimeField
* >( m_pWindow
.get() )->SetMin( aMin
);
2310 static_cast< TimeField
* >( m_pWindow
.get() )->SetMax( aMax
);
2311 static_cast< TimeField
* >( m_pWindow
.get() )->SetStrictFormat( bStrict
);
2312 static_cast< TimeField
* >( m_pWindow
.get() )->EnableEmptyFieldValue( true );
2314 static_cast< TimeField
* >( m_pPainter
.get() )->SetExtFormat( (ExtTimeFieldFormat
)nFormat
);
2315 static_cast< TimeField
* >( m_pPainter
.get() )->SetMin( aMin
);
2316 static_cast< TimeField
* >( m_pPainter
.get() )->SetMax( aMax
);
2317 static_cast< TimeField
* >( m_pPainter
.get() )->SetStrictFormat( bStrict
);
2318 static_cast< TimeField
* >( m_pPainter
.get() )->EnableEmptyFieldValue( true );
2325 OUString
lcl_setFormattedTime_nothrow( TimeField
& _rField
, const Reference
< XColumn
>& _rxField
)
2328 if ( _rxField
.is() )
2332 css::util::Time aValue
= _rxField
->getTime();
2333 if ( _rxField
->wasNull() )
2334 _rField
.SetText( sTime
);
2337 _rField
.SetTime( ::tools::Time( aValue
) );
2338 sTime
= _rField
.GetText();
2341 catch( const Exception
& )
2343 DBG_UNHANDLED_EXCEPTION();
2350 OUString
DbTimeField::GetFormatText(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< css::util::XNumberFormatter
>& /*xFormatter*/, Color
** /*ppColor*/)
2352 return lcl_setFormattedTime_nothrow( *static_cast< TimeField
* >( m_pPainter
.get() ), _rxField
);
2356 void DbTimeField::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& /*xFormatter*/)
2358 lcl_setFormattedTime_nothrow( *static_cast< TimeField
* >( m_pWindow
.get() ), _rxField
);
2362 void DbTimeField::updateFromModel( Reference
< XPropertySet
> _rxModel
)
2364 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbTimeField::updateFromModel: invalid call!" );
2367 if ( _rxModel
->getPropertyValue( FM_PROP_TIME
) >>= aTime
)
2368 static_cast< TimeField
* >( m_pWindow
.get() )->SetTime( ::tools::Time( aTime
) );
2370 static_cast< TimeField
* >( m_pWindow
.get() )->SetText( OUString() );
2374 bool DbTimeField::commitControl()
2376 OUString
aText(m_pWindow
->GetText());
2378 if (!aText
.isEmpty())
2379 aVal
<<= static_cast<TimeField
*>(m_pWindow
.get())->GetTime().GetUNOTime();
2383 m_rColumn
.getModel()->setPropertyValue(FM_PROP_TIME
, aVal
);
2387 DbComboBox::DbComboBox(DbGridColumn
& _rColumn
)
2388 :DbCellControl(_rColumn
)
2390 setAlignedController( false );
2392 doPropertyListening( FM_PROP_STRINGITEMLIST
);
2393 doPropertyListening( FM_PROP_LINECOUNT
);
2397 void DbComboBox::_propertyChanged( const PropertyChangeEvent
& _rEvent
)
2399 if ( _rEvent
.PropertyName
== FM_PROP_STRINGITEMLIST
)
2401 SetList(_rEvent
.NewValue
);
2405 DbCellControl::_propertyChanged( _rEvent
) ;
2410 void DbComboBox::SetList(const Any
& rItems
)
2412 ComboBoxControl
* pField
= static_cast<ComboBoxControl
*>(m_pWindow
.get());
2415 css::uno::Sequence
<OUString
> aTest
;
2416 if (rItems
>>= aTest
)
2418 const OUString
* pStrings
= aTest
.getConstArray();
2419 sal_Int32 nItems
= aTest
.getLength();
2420 for (sal_Int32 i
= 0; i
< nItems
; ++i
, ++pStrings
)
2421 pField
->InsertEntry(*pStrings
);
2423 // tell the grid control that this controller is invalid and has to be re-initialized
2424 invalidatedController();
2429 void DbComboBox::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& _rxModel
)
2431 DBG_ASSERT( m_pWindow
, "DbComboBox::implAdjustGenericFieldSetting: not to be called without window!" );
2432 DBG_ASSERT( _rxModel
.is(), "DbComboBox::implAdjustGenericFieldSetting: invalid model!" );
2433 if ( m_pWindow
&& _rxModel
.is() )
2435 sal_Int16 nLines
= getINT16( _rxModel
->getPropertyValue( FM_PROP_LINECOUNT
) );
2436 static_cast< ComboBoxControl
* >( m_pWindow
.get() )->SetDropDownLineCount( nLines
);
2441 void DbComboBox::Init( vcl::Window
& rParent
, const Reference
< XRowSet
>& xCursor
)
2443 m_rColumn
.SetAlignmentFromModel(css::awt::TextAlign::LEFT
);
2445 m_pWindow
= VclPtr
<ComboBoxControl
>::Create( &rParent
);
2447 // selection from right to left
2448 AllSettings aSettings
= m_pWindow
->GetSettings();
2449 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
2450 aStyleSettings
.SetSelectionOptions(
2451 aStyleSettings
.GetSelectionOptions() | SelectionOptions::ShowFirst
);
2452 aSettings
.SetStyleSettings(aStyleSettings
);
2453 m_pWindow
->SetSettings(aSettings
, true);
2455 // some initial properties
2456 Reference
< XPropertySet
> xModel(m_rColumn
.getModel());
2457 SetList( xModel
->getPropertyValue( FM_PROP_STRINGITEMLIST
) );
2458 implAdjustGenericFieldSetting( xModel
);
2460 DbCellControl::Init( rParent
, xCursor
);
2464 CellControllerRef
DbComboBox::CreateController() const
2466 return new ComboBoxCellController(static_cast<ComboBoxControl
*>(m_pWindow
.get()));
2470 OUString
DbComboBox::GetFormatText(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& xFormatter
, Color
** /*ppColor*/)
2472 const css::uno::Reference
<css::beans::XPropertySet
> xPS(_rxField
, UNO_QUERY
);
2473 ::dbtools::FormattedColumnValue
fmter( xFormatter
, xPS
);
2475 return fmter
.getFormattedValue();
2479 void DbComboBox::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& xFormatter
)
2481 m_pWindow
->SetText(GetFormatText(_rxField
, xFormatter
));
2485 void DbComboBox::updateFromModel( Reference
< XPropertySet
> _rxModel
)
2487 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbComboBox::updateFromModel: invalid call!" );
2490 _rxModel
->getPropertyValue( FM_PROP_TEXT
) >>= sText
;
2492 static_cast< ComboBox
* >( m_pWindow
.get() )->SetText( sText
);
2493 static_cast< ComboBox
* >( m_pWindow
.get() )->SetSelection( Selection( SELECTION_MAX
, SELECTION_MIN
) );
2497 bool DbComboBox::commitControl()
2499 OUString
aText( m_pWindow
->GetText());
2500 m_rColumn
.getModel()->setPropertyValue(FM_PROP_TEXT
, makeAny(aText
));
2505 DbListBox::DbListBox(DbGridColumn
& _rColumn
)
2506 :DbCellControl(_rColumn
)
2509 setAlignedController( false );
2511 doPropertyListening( FM_PROP_STRINGITEMLIST
);
2512 doPropertyListening( FM_PROP_LINECOUNT
);
2516 void DbListBox::_propertyChanged( const css::beans::PropertyChangeEvent
& _rEvent
)
2518 if ( _rEvent
.PropertyName
== FM_PROP_STRINGITEMLIST
)
2520 SetList(_rEvent
.NewValue
);
2524 DbCellControl::_propertyChanged( _rEvent
) ;
2529 void DbListBox::SetList(const Any
& rItems
)
2531 ListBoxControl
* pField
= static_cast<ListBoxControl
*>(m_pWindow
.get());
2536 css::uno::Sequence
<OUString
> aTest
;
2537 if (rItems
>>= aTest
)
2539 const OUString
* pStrings
= aTest
.getConstArray();
2540 sal_Int32 nItems
= aTest
.getLength();
2543 for (sal_Int32 i
= 0; i
< nItems
; ++i
, ++pStrings
)
2544 pField
->InsertEntry(*pStrings
);
2546 m_rColumn
.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ
) >>= m_aValueList
;
2547 m_bBound
= m_aValueList
.getLength() > 0;
2549 // tell the grid control that this controller is invalid and has to be re-initialized
2550 invalidatedController();
2556 void DbListBox::Init( vcl::Window
& rParent
, const Reference
< XRowSet
>& xCursor
)
2558 m_rColumn
.SetAlignment(css::awt::TextAlign::LEFT
);
2560 m_pWindow
= VclPtr
<ListBoxControl
>::Create( &rParent
);
2562 // some initial properties
2563 Reference
< XPropertySet
> xModel( m_rColumn
.getModel() );
2564 SetList( xModel
->getPropertyValue( FM_PROP_STRINGITEMLIST
) );
2565 implAdjustGenericFieldSetting( xModel
);
2567 DbCellControl::Init( rParent
, xCursor
);
2571 void DbListBox::implAdjustGenericFieldSetting( const Reference
< XPropertySet
>& _rxModel
)
2573 DBG_ASSERT( m_pWindow
, "DbListBox::implAdjustGenericFieldSetting: not to be called without window!" );
2574 DBG_ASSERT( _rxModel
.is(), "DbListBox::implAdjustGenericFieldSetting: invalid model!" );
2575 if ( m_pWindow
&& _rxModel
.is() )
2577 sal_Int16 nLines
= getINT16( _rxModel
->getPropertyValue( FM_PROP_LINECOUNT
) );
2578 static_cast< ListBoxControl
* >( m_pWindow
.get() )->SetDropDownLineCount( nLines
);
2583 CellControllerRef
DbListBox::CreateController() const
2585 return new ListBoxCellController(static_cast<ListBoxControl
*>(m_pWindow
.get()));
2589 OUString
DbListBox::GetFormatText(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& /*xFormatter*/, Color
** /*ppColor*/)
2592 if ( _rxField
.is() )
2596 sText
= _rxField
->getString();
2599 Sequence
< sal_Int16
> aPosSeq
= ::comphelper::findValue( m_aValueList
, sText
, true );
2600 if ( aPosSeq
.getLength() )
2601 sText
= static_cast<ListBox
*>(m_pWindow
.get())->GetEntry(aPosSeq
.getConstArray()[0]);
2606 catch( const Exception
& )
2608 DBG_UNHANDLED_EXCEPTION();
2615 void DbListBox::UpdateFromField(const Reference
< css::sdb::XColumn
>& _rxField
, const Reference
< XNumberFormatter
>& xFormatter
)
2617 OUString
sFormattedText( GetFormatText( _rxField
, xFormatter
) );
2618 if (!sFormattedText
.isEmpty())
2619 static_cast< ListBox
* >( m_pWindow
.get() )->SelectEntry( sFormattedText
);
2621 static_cast< ListBox
* >( m_pWindow
.get() )->SetNoSelection();
2625 void DbListBox::updateFromModel( Reference
< XPropertySet
> _rxModel
)
2627 OSL_ENSURE( _rxModel
.is() && m_pWindow
, "DbListBox::updateFromModel: invalid call!" );
2629 Sequence
< sal_Int16
> aSelection
;
2630 _rxModel
->getPropertyValue( FM_PROP_SELECT_SEQ
) >>= aSelection
;
2632 sal_Int16 nSelection
= -1;
2633 if ( aSelection
.getLength() > 0 )
2634 nSelection
= aSelection
[ 0 ];
2636 ListBox
* pListBox
= static_cast< ListBox
* >( m_pWindow
.get() );
2638 if ( ( nSelection
>= 0 ) && ( nSelection
< pListBox
->GetEntryCount() ) )
2639 pListBox
->SelectEntryPos( nSelection
);
2641 pListBox
->SetNoSelection( );
2645 bool DbListBox::commitControl()
2648 Sequence
<sal_Int16
> aSelectSeq
;
2649 if (static_cast<ListBox
*>(m_pWindow
.get())->GetSelectEntryCount())
2651 aSelectSeq
.realloc(1);
2652 *aSelectSeq
.getArray() = (sal_Int16
)static_cast<ListBox
*>(m_pWindow
.get())->GetSelectEntryPos();
2654 aVal
<<= aSelectSeq
;
2655 m_rColumn
.getModel()->setPropertyValue(FM_PROP_SELECT_SEQ
, aVal
);
2659 DbFilterField::DbFilterField(const Reference
< XComponentContext
>& rxContext
,DbGridColumn
& _rColumn
)
2660 :DbCellControl(_rColumn
)
2661 ,OSQLParserClient(rxContext
)
2662 ,m_nControlClass(css::form::FormComponentType::TEXTFIELD
)
2663 ,m_bFilterList(false)
2664 ,m_bFilterListFilled(false)
2668 setAlignedController( false );
2672 DbFilterField::~DbFilterField()
2674 if (m_nControlClass
== css::form::FormComponentType::CHECKBOX
)
2675 static_cast<CheckBoxControl
*>(m_pWindow
.get())->SetClickHdl( Link
<VclPtr
<CheckBox
>,void>() );
2680 void DbFilterField::PaintCell(OutputDevice
& rDev
, const tools::Rectangle
& rRect
)
2682 static const DrawTextFlags nStyle
= DrawTextFlags::Clip
| DrawTextFlags::VCenter
| DrawTextFlags::Left
;
2683 switch (m_nControlClass
)
2685 case FormComponentType::CHECKBOX
:
2686 DbCellControl::PaintCell( rDev
, rRect
);
2688 case FormComponentType::LISTBOX
:
2689 rDev
.DrawText(rRect
, static_cast<ListBox
*>(m_pWindow
.get())->GetSelectEntry(), nStyle
);
2692 rDev
.DrawText(rRect
, m_aText
, nStyle
);
2697 void DbFilterField::SetList(const Any
& rItems
, bool bComboBox
)
2699 css::uno::Sequence
<OUString
> aTest
;
2701 const OUString
* pStrings
= aTest
.getConstArray();
2702 sal_Int32 nItems
= aTest
.getLength();
2707 ComboBox
* pField
= static_cast<ComboBox
*>(m_pWindow
.get());
2708 for (sal_Int32 i
= 0; i
< nItems
; ++i
, ++pStrings
)
2709 pField
->InsertEntry(*pStrings
);
2713 ListBox
* pField
= static_cast<ListBox
*>(m_pWindow
.get());
2714 for (sal_Int32 i
= 0; i
< nItems
; ++i
, ++pStrings
)
2715 pField
->InsertEntry(*pStrings
);
2717 m_rColumn
.getModel()->getPropertyValue(FM_PROP_VALUE_SEQ
) >>= m_aValueList
;
2718 m_bBound
= m_aValueList
.getLength() > 0;
2724 void DbFilterField::CreateControl(vcl::Window
* pParent
, const Reference
< css::beans::XPropertySet
>& xModel
)
2726 switch (m_nControlClass
)
2728 case css::form::FormComponentType::CHECKBOX
:
2729 m_pWindow
= VclPtr
<CheckBoxControl
>::Create(pParent
);
2730 m_pWindow
->SetPaintTransparent( true );
2731 static_cast<CheckBoxControl
*>(m_pWindow
.get())->SetClickHdl( LINK( this, DbFilterField
, OnClick
) );
2733 m_pPainter
= VclPtr
<CheckBoxControl
>::Create(pParent
);
2734 m_pPainter
->SetPaintTransparent( true );
2735 m_pPainter
->SetBackground();
2737 case css::form::FormComponentType::LISTBOX
:
2739 m_pWindow
= VclPtr
<ListBoxControl
>::Create(pParent
);
2740 sal_Int16 nLines
= ::comphelper::getINT16(xModel
->getPropertyValue(FM_PROP_LINECOUNT
));
2741 Any aItems
= xModel
->getPropertyValue(FM_PROP_STRINGITEMLIST
);
2742 SetList(aItems
, m_nControlClass
== css::form::FormComponentType::COMBOBOX
);
2743 static_cast<ListBox
*>(m_pWindow
.get())->SetDropDownLineCount(nLines
);
2745 case css::form::FormComponentType::COMBOBOX
:
2747 m_pWindow
= VclPtr
<ComboBoxControl
>::Create(pParent
);
2749 AllSettings aSettings
= m_pWindow
->GetSettings();
2750 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
2751 aStyleSettings
.SetSelectionOptions(
2752 aStyleSettings
.GetSelectionOptions() | SelectionOptions::ShowFirst
);
2753 aSettings
.SetStyleSettings(aStyleSettings
);
2754 m_pWindow
->SetSettings(aSettings
, true);
2758 sal_Int16 nLines
= ::comphelper::getINT16(xModel
->getPropertyValue(FM_PROP_LINECOUNT
));
2759 Any aItems
= xModel
->getPropertyValue(FM_PROP_STRINGITEMLIST
);
2760 SetList(aItems
, m_nControlClass
== css::form::FormComponentType::COMBOBOX
);
2761 static_cast<ComboBox
*>(m_pWindow
.get())->SetDropDownLineCount(nLines
);
2764 static_cast<ComboBox
*>(m_pWindow
.get())->SetDropDownLineCount(5);
2769 m_pWindow
= VclPtr
<Edit
>::Create(pParent
, WB_LEFT
);
2770 AllSettings aSettings
= m_pWindow
->GetSettings();
2771 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
2772 aStyleSettings
.SetSelectionOptions(
2773 aStyleSettings
.GetSelectionOptions() | SelectionOptions::ShowFirst
);
2774 aSettings
.SetStyleSettings(aStyleSettings
);
2775 m_pWindow
->SetSettings(aSettings
, true);
2781 void DbFilterField::Init( vcl::Window
& rParent
, const Reference
< XRowSet
>& xCursor
)
2783 Reference
< css::beans::XPropertySet
> xModel(m_rColumn
.getModel());
2784 m_rColumn
.SetAlignment(css::awt::TextAlign::LEFT
);
2788 m_bFilterList
= ::comphelper::hasProperty(FM_PROP_FILTERPROPOSAL
, xModel
) && ::comphelper::getBOOL(xModel
->getPropertyValue(FM_PROP_FILTERPROPOSAL
));
2790 m_nControlClass
= css::form::FormComponentType::COMBOBOX
;
2793 sal_Int16 nClassId
= ::comphelper::getINT16(xModel
->getPropertyValue(FM_PROP_CLASSID
));
2796 case FormComponentType::CHECKBOX
:
2797 case FormComponentType::LISTBOX
:
2798 case FormComponentType::COMBOBOX
:
2799 m_nControlClass
= nClassId
;
2803 m_nControlClass
= FormComponentType::COMBOBOX
;
2805 m_nControlClass
= FormComponentType::TEXTFIELD
;
2810 CreateControl( &rParent
, xModel
);
2811 DbCellControl::Init( rParent
, xCursor
);
2813 // filter cells are never readonly
2814 Edit
* pAsEdit
= dynamic_cast< Edit
* >( m_pWindow
.get() );
2816 pAsEdit
->SetReadOnly( false );
2820 CellControllerRef
DbFilterField::CreateController() const
2822 CellControllerRef xController
;
2823 switch (m_nControlClass
)
2825 case css::form::FormComponentType::CHECKBOX
:
2826 xController
= new CheckBoxCellController(static_cast<CheckBoxControl
*>(m_pWindow
.get()));
2828 case css::form::FormComponentType::LISTBOX
:
2829 xController
= new ListBoxCellController(static_cast<ListBoxControl
*>(m_pWindow
.get()));
2831 case css::form::FormComponentType::COMBOBOX
:
2832 xController
= new ComboBoxCellController(static_cast<ComboBoxControl
*>(m_pWindow
.get()));
2836 xController
= new ComboBoxCellController(static_cast<ComboBoxControl
*>(m_pWindow
.get()));
2838 xController
= new EditCellController(static_cast<Edit
*>(m_pWindow
.get()));
2844 void DbFilterField::updateFromModel( Reference
< XPropertySet
> _rxModel
)
2846 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())->GetSelectEntryCount())
2866 sal_Int16 nPos
= (sal_Int16
)static_cast<ListBox
*>(m_pWindow
.get())->GetSelectEntryPos();
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::shared_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 Sequence
<sal_Int16
> aPosSeq
= ::comphelper::findValue(m_aValueList
, m_aText
, true);
2953 if (aPosSeq
.getLength())
2954 static_cast<ListBox
*>(m_pWindow
.get())->SelectEntryPos(aPosSeq
.getConstArray()[0]);
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
)
2972 m_bFilterListFilled
= true;
2973 Reference
< css::beans::XPropertySet
> xField
= m_rColumn
.GetField();
2978 xField
->getPropertyValue(FM_PROP_NAME
) >>= aName
;
2981 Reference
< css::container::XChild
> xModelAsChild(m_rColumn
.getModel(), UNO_QUERY
);
2983 xModelAsChild
.set(xModelAsChild
->getParent(),UNO_QUERY
);
2984 Reference
< XRowSet
> xForm(xModelAsChild
->getParent(), UNO_QUERY
);
2988 Reference
<XPropertySet
> xFormProp(xForm
,UNO_QUERY
);
2989 Reference
< XTablesSupplier
> xSupTab
;
2990 xFormProp
->getPropertyValue("SingleSelectQueryComposer") >>= xSupTab
;
2992 Reference
< XConnection
> xConnection(getConnection(xForm
));
2997 Reference
< XColumnsSupplier
> xSupCol(xSupTab
,UNO_QUERY
);
2998 Reference
< css::container::XNameAccess
> xFieldNames
= xSupCol
->getColumns();
2999 if (!xFieldNames
->hasByName(aName
))
3002 Reference
< css::container::XNameAccess
> xTablesNames
= xSupTab
->getTables();
3003 Reference
< css::beans::XPropertySet
> xComposerFieldAsSet(xFieldNames
->getByName(aName
),UNO_QUERY
);
3005 if (xComposerFieldAsSet
.is() && ::comphelper::hasProperty(FM_PROP_TABLENAME
, xComposerFieldAsSet
) &&
3006 ::comphelper::hasProperty(FM_PROP_FIELDSOURCE
, xComposerFieldAsSet
))
3008 OUString aFieldName
;
3009 OUString aTableName
;
3010 xComposerFieldAsSet
->getPropertyValue(FM_PROP_FIELDSOURCE
) >>= aFieldName
;
3011 xComposerFieldAsSet
->getPropertyValue(FM_PROP_TABLENAME
) >>= aTableName
;
3013 // no possibility to create a select statement
3014 // looking for the complete table name
3015 if (!xTablesNames
->hasByName(aTableName
))
3018 // build a statement and send as query;
3019 // Access to the connection
3020 Reference
< XStatement
> xStatement
;
3021 Reference
< XResultSet
> xListCursor
;
3022 Reference
< css::sdb::XColumn
> xDataField
;
3026 Reference
< XDatabaseMetaData
> xMeta
= xConnection
->getMetaData();
3028 OUString
aQuote(xMeta
->getIdentifierQuoteString());
3029 OUStringBuffer
aStatement("SELECT DISTINCT ");
3030 aStatement
.append(quoteName(aQuote
, aName
));
3031 if (!aFieldName
.isEmpty() && aName
!= aFieldName
)
3033 aStatement
.append(" AS ");
3034 aStatement
.append(quoteName(aQuote
, aFieldName
));
3037 aStatement
.append(" FROM ");
3039 Reference
< XPropertySet
> xTableNameAccess(xTablesNames
->getByName(aTableName
), UNO_QUERY_THROW
);
3040 aStatement
.append(composeTableNameForSelect(xConnection
, xTableNameAccess
));
3042 xStatement
= xConnection
->createStatement();
3043 Reference
< css::beans::XPropertySet
> xStatementProps(xStatement
, UNO_QUERY
);
3044 xStatementProps
->setPropertyValue(FM_PROP_ESCAPE_PROCESSING
, makeAny(true));
3046 xListCursor
= xStatement
->executeQuery(aStatement
.makeStringAndClear());
3048 Reference
< css::sdbcx::XColumnsSupplier
> xSupplyCols(xListCursor
, UNO_QUERY
);
3049 Reference
< css::container::XIndexAccess
> xFields(xSupplyCols
->getColumns(), UNO_QUERY
);
3050 xDataField
.set(xFields
->getByIndex(0), css::uno::UNO_QUERY
);
3051 if (!xDataField
.is())
3054 catch(const Exception
&)
3056 ::comphelper::disposeComponent(xStatement
);
3061 ::std::vector
< OUString
> aStringList
;
3062 aStringList
.reserve(16);
3064 css::util::Date aNullDate
= m_rColumn
.GetParent().getNullDate();
3065 sal_Int32 nFormatKey
= m_rColumn
.GetKey();
3066 Reference
< XNumberFormatter
> xFormatter
= m_rColumn
.GetParent().getNumberFormatter();
3067 sal_Int16 nKeyType
= ::comphelper::getNumberFormatType(xFormatter
->getNumberFormatsSupplier()->getNumberFormats(), nFormatKey
);
3069 while (!xListCursor
->isAfterLast() && i
++ < SHRT_MAX
) // max anzahl eintraege
3071 aStr
= getFormattedValue(xDataField
, xFormatter
, aNullDate
, nFormatKey
, nKeyType
);
3072 aStringList
.push_back(aStr
);
3073 (void)xListCursor
->next();
3076 // filling the entries for the combobox
3077 for (::std::vector
< OUString
>::const_iterator iter
= aStringList
.begin();
3078 iter
!= aStringList
.end(); ++iter
)
3079 static_cast<ComboBox
*>(m_pWindow
.get())->InsertEntry(*iter
);
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();
3107 case TRISTATE_FALSE
:
3110 case TRISTATE_INDET
:
3114 if (m_aText
!= aText
)
3117 m_aCommitLink
.Call(*this);
3122 FmXGridCell::FmXGridCell( DbGridColumn
* pColumn
, DbCellControl
* _pControl
)
3123 :OComponentHelper(m_aMutex
)
3125 ,m_pCellControl( _pControl
)
3126 ,m_aWindowListeners( m_aMutex
)
3127 ,m_aFocusListeners( m_aMutex
)
3128 ,m_aKeyListeners( m_aMutex
)
3129 ,m_aMouseListeners( m_aMutex
)
3130 ,m_aMouseMotionListeners( m_aMutex
)
3135 void FmXGridCell::init()
3137 vcl::Window
* pEventWindow( getEventWindow() );
3139 pEventWindow
->AddEventListener( LINK( this, FmXGridCell
, OnWindowEvent
) );
3143 vcl::Window
* FmXGridCell::getEventWindow() const
3145 if ( m_pCellControl
)
3146 return &m_pCellControl
->GetWindow();
3151 FmXGridCell::~FmXGridCell()
3153 if (!OComponentHelper::rBHelper
.bDisposed
)
3162 void FmXGridCell::SetTextLineColor()
3165 m_pCellControl
->SetTextLineColor();
3169 void FmXGridCell::SetTextLineColor(const Color
& _rColor
)
3172 m_pCellControl
->SetTextLineColor(_rColor
);
3177 Sequence
< Type
> SAL_CALL
FmXGridCell::getTypes( )
3179 Sequence
< uno::Type
> aTypes
= ::comphelper::concatSequences(
3180 ::cppu::OComponentHelper::getTypes(),
3181 FmXGridCell_Base::getTypes()
3183 if ( m_pCellControl
)
3184 aTypes
= ::comphelper::concatSequences(
3186 FmXGridCell_WindowBase::getTypes()
3192 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXGridCell
)
3196 void FmXGridCell::disposing()
3198 lang::EventObject
aEvent( *this );
3199 m_aWindowListeners
.disposeAndClear( aEvent
);
3200 m_aFocusListeners
.disposeAndClear( aEvent
);
3201 m_aKeyListeners
.disposeAndClear( aEvent
);
3202 m_aMouseListeners
.disposeAndClear( aEvent
);
3203 m_aMouseMotionListeners
.disposeAndClear( aEvent
);
3205 OComponentHelper::disposing();
3206 m_pColumn
= nullptr;
3207 DELETEZ(m_pCellControl
);
3211 Any SAL_CALL
FmXGridCell::queryAggregation( const css::uno::Type
& _rType
)
3213 Any aReturn
= OComponentHelper::queryAggregation( _rType
);
3215 if ( !aReturn
.hasValue() )
3216 aReturn
= FmXGridCell_Base::queryInterface( _rType
);
3218 if ( !aReturn
.hasValue() && ( m_pCellControl
!= nullptr ) )
3219 aReturn
= FmXGridCell_WindowBase::queryInterface( _rType
);
3224 // css::awt::XControl
3226 Reference
< XInterface
> FmXGridCell::getContext()
3228 return Reference
< XInterface
> ();
3232 Reference
< css::awt::XControlModel
> FmXGridCell::getModel()
3234 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3235 return Reference
< css::awt::XControlModel
> (m_pColumn
->getModel(), UNO_QUERY
);
3238 // css::form::XBoundControl
3240 sal_Bool
FmXGridCell::getLock()
3242 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3243 return m_pColumn
->isLocked();
3247 void FmXGridCell::setLock(sal_Bool _bLock
)
3249 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3250 if (getLock() == _bLock
)
3254 ::osl::MutexGuard
aGuard(m_aMutex
);
3255 m_pColumn
->setLock(_bLock
);
3260 void SAL_CALL
FmXGridCell::setPosSize( ::sal_Int32
, ::sal_Int32
, ::sal_Int32
, ::sal_Int32
, ::sal_Int16
)
3262 OSL_FAIL( "FmXGridCell::setPosSize: not implemented" );
3263 // not allowed to tamper with this for a grid cell
3267 awt::Rectangle SAL_CALL
FmXGridCell::getPosSize( )
3269 OSL_FAIL( "FmXGridCell::getPosSize: not implemented" );
3270 return awt::Rectangle();
3274 void SAL_CALL
FmXGridCell::setVisible( sal_Bool
)
3276 OSL_FAIL( "FmXGridCell::setVisible: not implemented" );
3277 // not allowed to tamper with this for a grid cell
3281 void SAL_CALL
FmXGridCell::setEnable( sal_Bool
)
3283 OSL_FAIL( "FmXGridCell::setEnable: not implemented" );
3284 // not allowed to tamper with this for a grid cell
3288 void SAL_CALL
FmXGridCell::setFocus( )
3290 OSL_FAIL( "FmXGridCell::setFocus: not implemented" );
3291 // not allowed to tamper with this for a grid cell
3295 void SAL_CALL
FmXGridCell::addWindowListener( const Reference
< awt::XWindowListener
>& _rxListener
)
3297 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3298 m_aWindowListeners
.addInterface( _rxListener
);
3302 void SAL_CALL
FmXGridCell::removeWindowListener( const Reference
< awt::XWindowListener
>& _rxListener
)
3304 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3305 m_aWindowListeners
.removeInterface( _rxListener
);
3309 void SAL_CALL
FmXGridCell::addFocusListener( const Reference
< awt::XFocusListener
>& _rxListener
)
3311 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3312 m_aFocusListeners
.addInterface( _rxListener
);
3316 void SAL_CALL
FmXGridCell::removeFocusListener( const Reference
< awt::XFocusListener
>& _rxListener
)
3318 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3319 m_aFocusListeners
.removeInterface( _rxListener
);
3323 void SAL_CALL
FmXGridCell::addKeyListener( const Reference
< awt::XKeyListener
>& _rxListener
)
3325 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3326 m_aKeyListeners
.addInterface( _rxListener
);
3330 void SAL_CALL
FmXGridCell::removeKeyListener( const Reference
< awt::XKeyListener
>& _rxListener
)
3332 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3333 m_aKeyListeners
.removeInterface( _rxListener
);
3337 void SAL_CALL
FmXGridCell::addMouseListener( const Reference
< awt::XMouseListener
>& _rxListener
)
3339 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3340 m_aMouseListeners
.addInterface( _rxListener
);
3344 void SAL_CALL
FmXGridCell::removeMouseListener( const Reference
< awt::XMouseListener
>& _rxListener
)
3346 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3347 m_aMouseListeners
.removeInterface( _rxListener
);
3351 void SAL_CALL
FmXGridCell::addMouseMotionListener( const Reference
< awt::XMouseMotionListener
>& _rxListener
)
3353 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3354 m_aMouseMotionListeners
.addInterface( _rxListener
);
3358 void SAL_CALL
FmXGridCell::removeMouseMotionListener( const Reference
< awt::XMouseMotionListener
>& _rxListener
)
3360 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3361 m_aMouseMotionListeners
.removeInterface( _rxListener
);
3365 void SAL_CALL
FmXGridCell::addPaintListener( const Reference
< awt::XPaintListener
>& _rxListener
)
3367 OSL_FAIL( "FmXGridCell::addPaintListener: not implemented" );
3372 void SAL_CALL
FmXGridCell::removePaintListener( const Reference
< awt::XPaintListener
>& _rxListener
)
3374 OSL_FAIL( "FmXGridCell::removePaintListener: not implemented" );
3379 IMPL_LINK( FmXGridCell
, OnWindowEvent
, VclWindowEvent
&, _rEvent
, void )
3381 ENSURE_OR_THROW( _rEvent
.GetWindow(), "illegal window" );
3382 onWindowEvent( _rEvent
.GetId(), *_rEvent
.GetWindow(), _rEvent
.GetData() );
3386 void FmXGridCell::onFocusGained( const awt::FocusEvent
& _rEvent
)
3388 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3389 m_aFocusListeners
.notifyEach( &awt::XFocusListener::focusGained
, _rEvent
);
3393 void FmXGridCell::onFocusLost( const awt::FocusEvent
& _rEvent
)
3395 checkDisposed(OComponentHelper::rBHelper
.bDisposed
);
3396 m_aFocusListeners
.notifyEach( &awt::XFocusListener::focusLost
, _rEvent
);
3400 void FmXGridCell::onWindowEvent( const VclEventId _nEventId
, const vcl::Window
& _rWindow
, const void* _pEventData
)
3402 switch ( _nEventId
)
3404 case VclEventId::ControlGetFocus
:
3405 case VclEventId::WindowGetFocus
:
3406 case VclEventId::ControlLoseFocus
:
3407 case VclEventId::WindowLoseFocus
:
3409 if ( ( _rWindow
.IsCompoundControl()
3410 && ( _nEventId
== VclEventId::ControlGetFocus
3411 || _nEventId
== VclEventId::ControlLoseFocus
3414 || ( !_rWindow
.IsCompoundControl()
3415 && ( _nEventId
== VclEventId::WindowGetFocus
3416 || _nEventId
== VclEventId::WindowLoseFocus
3421 if ( !m_aFocusListeners
.getLength() )
3424 bool bFocusGained
= ( _nEventId
== VclEventId::ControlGetFocus
) || ( _nEventId
== VclEventId::WindowGetFocus
);
3426 awt::FocusEvent aEvent
;
3427 aEvent
.Source
= *this;
3428 aEvent
.FocusFlags
= static_cast<sal_Int16
>(_rWindow
.GetGetFocusFlags());
3429 aEvent
.Temporary
= false;
3432 onFocusGained( aEvent
);
3434 onFocusLost( aEvent
);
3438 case VclEventId::WindowMouseButtonDown
:
3439 case VclEventId::WindowMouseButtonUp
:
3441 if ( !m_aMouseListeners
.getLength() )
3444 const bool bButtonDown
= ( _nEventId
== VclEventId::WindowMouseButtonDown
);
3446 awt::MouseEvent
aEvent( VCLUnoHelper::createMouseEvent( *static_cast< const ::MouseEvent
* >( _pEventData
), *this ) );
3447 m_aMouseListeners
.notifyEach( bButtonDown
? &awt::XMouseListener::mousePressed
: &awt::XMouseListener::mouseReleased
, aEvent
);
3450 case VclEventId::WindowMouseMove
:
3452 const MouseEvent
& rMouseEvent
= *static_cast< const ::MouseEvent
* >( _pEventData
);
3453 if ( rMouseEvent
.IsEnterWindow() || rMouseEvent
.IsLeaveWindow() )
3455 if ( m_aMouseListeners
.getLength() != 0 )
3457 awt::MouseEvent
aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent
, *this ) );
3458 m_aMouseListeners
.notifyEach( rMouseEvent
.IsEnterWindow() ? &awt::XMouseListener::mouseEntered
: &awt::XMouseListener::mouseExited
, aEvent
);
3461 else if ( !rMouseEvent
.IsEnterWindow() && !rMouseEvent
.IsLeaveWindow() )
3463 if ( m_aMouseMotionListeners
.getLength() != 0 )
3465 awt::MouseEvent
aEvent( VCLUnoHelper::createMouseEvent( rMouseEvent
, *this ) );
3466 aEvent
.ClickCount
= 0;
3467 const bool bSimpleMove
= bool( rMouseEvent
.GetMode() & MouseEventModifiers::SIMPLEMOVE
);
3468 m_aMouseMotionListeners
.notifyEach( bSimpleMove
? &awt::XMouseMotionListener::mouseMoved
: &awt::XMouseMotionListener::mouseDragged
, aEvent
);
3473 case VclEventId::WindowKeyInput
:
3474 case VclEventId::WindowKeyUp
:
3476 if ( !m_aKeyListeners
.getLength() )
3479 const bool bKeyPressed
= ( _nEventId
== VclEventId::WindowKeyInput
);
3480 awt::KeyEvent
aEvent( VCLUnoHelper::createKeyEvent( *static_cast< const ::KeyEvent
* >( _pEventData
), *this ) );
3481 m_aKeyListeners
.notifyEach( bKeyPressed
? &awt::XKeyListener::keyPressed
: &awt::XKeyListener::keyReleased
, aEvent
);
3489 void FmXDataCell::PaintFieldToCell(OutputDevice
& rDev
, const tools::Rectangle
& rRect
,
3490 const Reference
< css::sdb::XColumn
>& _rxField
,
3491 const Reference
< XNumberFormatter
>& xFormatter
)
3493 m_pCellControl
->PaintFieldToCell( rDev
, rRect
, _rxField
, xFormatter
);
3497 void FmXDataCell::UpdateFromColumn()
3499 Reference
< css::sdb::XColumn
> xField(m_pColumn
->GetCurrentFieldValue());
3501 m_pCellControl
->UpdateFromField(xField
, m_pColumn
->GetParent().getNumberFormatter());
3505 FmXTextCell::FmXTextCell( DbGridColumn
* pColumn
, DbCellControl
& _rControl
)
3506 :FmXDataCell( pColumn
, _rControl
)
3507 ,m_bFastPaint( true )
3512 void FmXTextCell::PaintFieldToCell(OutputDevice
& rDev
,
3513 const tools::Rectangle
& rRect
,
3514 const Reference
< css::sdb::XColumn
>& _rxField
,
3515 const Reference
< XNumberFormatter
>& xFormatter
)
3517 if ( !m_bFastPaint
)
3519 FmXDataCell::PaintFieldToCell( rDev
, rRect
, _rxField
, xFormatter
);
3523 DrawTextFlags nStyle
= DrawTextFlags::Clip
| DrawTextFlags::VCenter
;
3524 if ( ( rDev
.GetOutDevType() == OUTDEV_WINDOW
) && !static_cast< vcl::Window
& >( rDev
).IsEnabled() )
3525 nStyle
|= DrawTextFlags::Disable
;
3527 switch (m_pColumn
->GetAlignment())
3529 case css::awt::TextAlign::RIGHT
:
3530 nStyle
|= DrawTextFlags::Right
;
3532 case css::awt::TextAlign::CENTER
:
3533 nStyle
|= DrawTextFlags::Center
;
3536 nStyle
|= DrawTextFlags::Left
;
3541 Color
* pColor
= nullptr;
3542 OUString aText
= GetText(_rxField
, xFormatter
, &pColor
);
3543 if (pColor
!= nullptr)
3545 Color
aOldTextColor( rDev
.GetTextColor() );
3546 rDev
.SetTextColor( *pColor
);
3547 rDev
.DrawText(rRect
, aText
, nStyle
);
3548 rDev
.SetTextColor( aOldTextColor
);
3551 rDev
.DrawText(rRect
, aText
, nStyle
);
3553 catch (const Exception
& e
)
3555 SAL_WARN("svx.fmcomp", "PaintFieldToCell: caught an exception: " << e
.Message
);
3559 FmXEditCell::FmXEditCell( DbGridColumn
* pColumn
, DbCellControl
& _rControl
)
3560 :FmXTextCell( pColumn
, _rControl
)
3561 ,m_aTextListeners(m_aMutex
)
3562 ,m_aChangeListeners( m_aMutex
)
3563 ,m_pEditImplementation( nullptr )
3564 ,m_bOwnEditImplementation( false )
3567 DbTextField
* pTextField
= dynamic_cast<DbTextField
*>( &_rControl
);
3571 m_pEditImplementation
= pTextField
->GetEditImplementation();
3572 if ( !pTextField
->IsSimpleEdit() )
3573 m_bFastPaint
= false;
3577 m_pEditImplementation
= new EditImplementation( static_cast< Edit
& >( _rControl
.GetWindow() ) );
3578 m_bOwnEditImplementation
= true;
3583 FmXEditCell::~FmXEditCell()
3585 if (!OComponentHelper::rBHelper
.bDisposed
)
3596 void FmXEditCell::disposing()
3598 css::lang::EventObject
aEvt(*this);
3599 m_aTextListeners
.disposeAndClear(aEvt
);
3600 m_aChangeListeners
.disposeAndClear(aEvt
);
3602 m_pEditImplementation
->SetModifyHdl( Link
<Edit
&,void>() );
3603 if ( m_bOwnEditImplementation
)
3604 delete m_pEditImplementation
;
3605 m_pEditImplementation
= nullptr;
3607 FmXDataCell::disposing();
3611 Any SAL_CALL
FmXEditCell::queryAggregation( const css::uno::Type
& _rType
)
3613 Any aReturn
= FmXTextCell::queryAggregation( _rType
);
3615 if ( !aReturn
.hasValue() )
3616 aReturn
= FmXEditCell_Base::queryInterface( _rType
);
3622 Sequence
< css::uno::Type
> SAL_CALL
FmXEditCell::getTypes( )
3624 return ::comphelper::concatSequences(
3625 FmXTextCell::getTypes(),
3626 FmXEditCell_Base::getTypes()
3631 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXEditCell
)
3633 // css::awt::XTextComponent
3635 void SAL_CALL
FmXEditCell::addTextListener(const Reference
< css::awt::XTextListener
>& l
)
3637 m_aTextListeners
.addInterface( l
);
3641 void SAL_CALL
FmXEditCell::removeTextListener(const Reference
< css::awt::XTextListener
>& l
)
3643 m_aTextListeners
.removeInterface( l
);
3647 void SAL_CALL
FmXEditCell::setText( const OUString
& aText
)
3649 ::osl::MutexGuard
aGuard( m_aMutex
);
3651 if ( m_pEditImplementation
)
3653 m_pEditImplementation
->SetText( aText
);
3655 // In Java, a textChanged is fired as well; not in VCL.
3656 // css::awt::Toolkit must be Java-compliant...
3662 void SAL_CALL
FmXEditCell::insertText(const css::awt::Selection
& rSel
, const OUString
& aText
)
3664 ::osl::MutexGuard
aGuard( m_aMutex
);
3666 if ( m_pEditImplementation
)
3668 m_pEditImplementation
->SetSelection( Selection( rSel
.Min
, rSel
.Max
) );
3669 m_pEditImplementation
->ReplaceSelected( aText
);
3674 OUString SAL_CALL
FmXEditCell::getText()
3676 ::osl::MutexGuard
aGuard( m_aMutex
);
3679 if ( m_pEditImplementation
)
3681 if ( m_pEditImplementation
->GetControl().IsVisible() && m_pColumn
->GetParent().getDisplaySynchron())
3683 // if the display isn't sync with the cursor we can't ask the edit field
3684 LineEnd eLineEndFormat
= getModelLineEndSetting( m_pColumn
->getModel() );
3685 aText
= m_pEditImplementation
->GetText( eLineEndFormat
);
3689 Reference
< css::sdb::XColumn
> xField(m_pColumn
->GetCurrentFieldValue());
3691 aText
= GetText(xField
, m_pColumn
->GetParent().getNumberFormatter());
3698 OUString SAL_CALL
FmXEditCell::getSelectedText()
3700 ::osl::MutexGuard
aGuard( m_aMutex
);
3703 if ( m_pEditImplementation
)
3705 LineEnd eLineEndFormat
= m_pColumn
? getModelLineEndSetting( m_pColumn
->getModel() ) : LINEEND_LF
;
3706 aText
= m_pEditImplementation
->GetSelected( eLineEndFormat
);
3712 void SAL_CALL
FmXEditCell::setSelection( const css::awt::Selection
& aSelection
)
3714 ::osl::MutexGuard
aGuard( m_aMutex
);
3716 if ( m_pEditImplementation
)
3717 m_pEditImplementation
->SetSelection( Selection( aSelection
.Min
, aSelection
.Max
) );
3721 css::awt::Selection SAL_CALL
FmXEditCell::getSelection()
3723 ::osl::MutexGuard
aGuard( m_aMutex
);
3726 if ( m_pEditImplementation
)
3727 aSel
= m_pEditImplementation
->GetSelection();
3729 return css::awt::Selection(aSel
.Min(), aSel
.Max());
3733 sal_Bool SAL_CALL
FmXEditCell::isEditable()
3735 ::osl::MutexGuard
aGuard( m_aMutex
);
3737 return m_pEditImplementation
&& !m_pEditImplementation
->IsReadOnly() && m_pEditImplementation
->GetControl().IsEnabled();
3741 void SAL_CALL
FmXEditCell::setEditable( sal_Bool bEditable
)
3743 ::osl::MutexGuard
aGuard( m_aMutex
);
3745 if ( m_pEditImplementation
)
3746 m_pEditImplementation
->SetReadOnly( !bEditable
);
3750 sal_Int16 SAL_CALL
FmXEditCell::getMaxTextLen()
3752 ::osl::MutexGuard
aGuard( m_aMutex
);
3754 return m_pEditImplementation
? m_pEditImplementation
->GetMaxTextLen() : 0;
3758 void SAL_CALL
FmXEditCell::setMaxTextLen( sal_Int16 nLen
)
3760 ::osl::MutexGuard
aGuard( m_aMutex
);
3762 if ( m_pEditImplementation
)
3763 m_pEditImplementation
->SetMaxTextLen( nLen
);
3767 void SAL_CALL
FmXEditCell::addChangeListener( const Reference
< form::XChangeListener
>& Listener
)
3769 m_aChangeListeners
.addInterface( Listener
);
3773 void SAL_CALL
FmXEditCell::removeChangeListener( const Reference
< form::XChangeListener
>& Listener
)
3775 m_aChangeListeners
.removeInterface( Listener
);
3779 void FmXEditCell::onTextChanged()
3781 css::awt::TextEvent aEvent
;
3782 aEvent
.Source
= *this;
3783 m_aTextListeners
.notifyEach( &awt::XTextListener::textChanged
, aEvent
);
3787 void FmXEditCell::onFocusGained( const awt::FocusEvent
& _rEvent
)
3789 FmXTextCell::onFocusGained( _rEvent
);
3790 m_sValueOnEnter
= getText();
3794 void FmXEditCell::onFocusLost( const awt::FocusEvent
& _rEvent
)
3796 FmXTextCell::onFocusLost( _rEvent
);
3798 if ( getText() != m_sValueOnEnter
)
3800 lang::EventObject
aEvent( *this );
3801 m_aChangeListeners
.notifyEach( &XChangeListener::changed
, aEvent
);
3806 void FmXEditCell::onWindowEvent( const VclEventId _nEventId
, const vcl::Window
& _rWindow
, const void* _pEventData
)
3808 switch ( _nEventId
)
3810 case VclEventId::EditModify
:
3812 if ( m_pEditImplementation
&& m_aTextListeners
.getLength() )
3819 FmXTextCell::onWindowEvent( _nEventId
, _rWindow
, _pEventData
);
3822 FmXCheckBoxCell::FmXCheckBoxCell( DbGridColumn
* pColumn
, DbCellControl
& _rControl
)
3823 :FmXDataCell( pColumn
, _rControl
)
3824 ,m_aItemListeners(m_aMutex
)
3825 ,m_aActionListeners( m_aMutex
)
3826 ,m_pBox( & static_cast< CheckBoxControl
& >( _rControl
.GetWindow() ).GetBox() )
3831 FmXCheckBoxCell::~FmXCheckBoxCell()
3833 if (!OComponentHelper::rBHelper
.bDisposed
)
3843 void FmXCheckBoxCell::disposing()
3845 css::lang::EventObject
aEvt(*this);
3846 m_aItemListeners
.disposeAndClear(aEvt
);
3847 m_aActionListeners
.disposeAndClear(aEvt
);
3849 static_cast< CheckBoxControl
& >( m_pCellControl
->GetWindow() ).SetClickHdl(Link
<VclPtr
<CheckBox
>,void>());
3852 FmXDataCell::disposing();
3856 Any SAL_CALL
FmXCheckBoxCell::queryAggregation( const css::uno::Type
& _rType
)
3858 Any aReturn
= FmXDataCell::queryAggregation( _rType
);
3860 if ( !aReturn
.hasValue() )
3861 aReturn
= FmXCheckBoxCell_Base::queryInterface( _rType
);
3867 Sequence
< css::uno::Type
> SAL_CALL
FmXCheckBoxCell::getTypes( )
3869 return ::comphelper::concatSequences(
3870 FmXDataCell::getTypes(),
3871 FmXCheckBoxCell_Base::getTypes()
3876 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXCheckBoxCell
)
3879 void SAL_CALL
FmXCheckBoxCell::addItemListener( const Reference
< css::awt::XItemListener
>& l
)
3881 m_aItemListeners
.addInterface( l
);
3885 void SAL_CALL
FmXCheckBoxCell::removeItemListener( const Reference
< css::awt::XItemListener
>& l
)
3887 m_aItemListeners
.removeInterface( l
);
3891 void SAL_CALL
FmXCheckBoxCell::setState( short n
)
3893 ::osl::MutexGuard
aGuard( m_aMutex
);
3898 m_pBox
->SetState( (TriState
)n
);
3903 short SAL_CALL
FmXCheckBoxCell::getState()
3905 ::osl::MutexGuard
aGuard( m_aMutex
);
3910 return (short)m_pBox
->GetState();
3912 return TRISTATE_INDET
;
3916 void SAL_CALL
FmXCheckBoxCell::enableTriState( sal_Bool b
)
3918 ::osl::MutexGuard
aGuard( m_aMutex
);
3921 m_pBox
->EnableTriState( b
);
3925 void SAL_CALL
FmXCheckBoxCell::addActionListener( const Reference
< awt::XActionListener
>& Listener
)
3927 m_aActionListeners
.addInterface( Listener
);
3931 void SAL_CALL
FmXCheckBoxCell::removeActionListener( const Reference
< awt::XActionListener
>& Listener
)
3933 m_aActionListeners
.removeInterface( Listener
);
3937 void SAL_CALL
FmXCheckBoxCell::setLabel( const OUString
& Label
)
3939 SolarMutexGuard aGuard
;
3942 DbGridControl
& rGrid( m_pColumn
->GetParent() );
3943 rGrid
.SetColumnTitle( rGrid
.GetColumnId( m_pColumn
->GetFieldPos() ), Label
);
3948 void SAL_CALL
FmXCheckBoxCell::setActionCommand( const OUString
& Command
)
3950 m_aActionCommand
= Command
;
3954 vcl::Window
* FmXCheckBoxCell::getEventWindow() const
3960 void FmXCheckBoxCell::onWindowEvent( const VclEventId _nEventId
, const vcl::Window
& _rWindow
, const void* _pEventData
)
3962 switch ( _nEventId
)
3964 case VclEventId::CheckboxToggle
:
3966 // check boxes are to be committed immediately (this holds for ordinary check box controls in
3967 // documents, and this must hold for check boxes in grid columns, too
3968 // 91210 - 22.08.2001 - frank.schoenheit@sun.com
3969 m_pCellControl
->Commit();
3971 Reference
< XWindow
> xKeepAlive( this );
3972 if ( m_aItemListeners
.getLength() && m_pBox
)
3974 awt::ItemEvent aEvent
;
3975 aEvent
.Source
= *this;
3976 aEvent
.Highlighted
= 0;
3977 aEvent
.Selected
= m_pBox
->GetState();
3978 m_aItemListeners
.notifyEach( &awt::XItemListener::itemStateChanged
, aEvent
);
3980 if ( m_aActionListeners
.getLength() )
3982 awt::ActionEvent aEvent
;
3983 aEvent
.Source
= *this;
3984 aEvent
.ActionCommand
= m_aActionCommand
;
3985 m_aActionListeners
.notifyEach( &awt::XActionListener::actionPerformed
, aEvent
);
3991 FmXDataCell::onWindowEvent( _nEventId
, _rWindow
, _pEventData
);
3996 FmXListBoxCell::FmXListBoxCell(DbGridColumn
* pColumn
, DbCellControl
& _rControl
)
3997 :FmXTextCell( pColumn
, _rControl
)
3998 ,m_aItemListeners(m_aMutex
)
3999 ,m_aActionListeners(m_aMutex
)
4000 ,m_pBox( &static_cast< ListBox
& >( _rControl
.GetWindow() ) )
4003 m_pBox
->SetDoubleClickHdl( LINK( this, FmXListBoxCell
, OnDoubleClick
) );
4007 FmXListBoxCell::~FmXListBoxCell()
4009 if (!OComponentHelper::rBHelper
.bDisposed
)
4019 void FmXListBoxCell::disposing()
4021 css::lang::EventObject
aEvt(*this);
4022 m_aItemListeners
.disposeAndClear(aEvt
);
4023 m_aActionListeners
.disposeAndClear(aEvt
);
4025 m_pBox
->SetSelectHdl( Link
<ListBox
&,void>() );
4026 m_pBox
->SetDoubleClickHdl( Link
<ListBox
&,void>() );
4029 FmXTextCell::disposing();
4033 Any SAL_CALL
FmXListBoxCell::queryAggregation( const css::uno::Type
& _rType
)
4035 Any aReturn
= FmXTextCell::queryAggregation(_rType
);
4037 if ( !aReturn
.hasValue() )
4038 aReturn
= FmXListBoxCell_Base::queryInterface( _rType
);
4044 Sequence
< css::uno::Type
> SAL_CALL
FmXListBoxCell::getTypes( )
4046 return ::comphelper::concatSequences(
4047 FmXTextCell::getTypes(),
4048 FmXListBoxCell_Base::getTypes()
4053 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXListBoxCell
)
4056 void SAL_CALL
FmXListBoxCell::addItemListener(const Reference
< css::awt::XItemListener
>& l
)
4058 m_aItemListeners
.addInterface( l
);
4062 void SAL_CALL
FmXListBoxCell::removeItemListener(const Reference
< css::awt::XItemListener
>& l
)
4064 m_aItemListeners
.removeInterface( l
);
4068 void SAL_CALL
FmXListBoxCell::addActionListener(const Reference
< css::awt::XActionListener
>& l
)
4070 m_aActionListeners
.addInterface( l
);
4074 void SAL_CALL
FmXListBoxCell::removeActionListener(const Reference
< css::awt::XActionListener
>& l
)
4076 m_aActionListeners
.removeInterface( l
);
4080 void SAL_CALL
FmXListBoxCell::addItem(const OUString
& aItem
, sal_Int16 nPos
)
4082 ::osl::MutexGuard
aGuard( m_aMutex
);
4084 m_pBox
->InsertEntry( aItem
, nPos
);
4088 void SAL_CALL
FmXListBoxCell::addItems(const css::uno::Sequence
<OUString
>& aItems
, sal_Int16 nPos
)
4090 ::osl::MutexGuard
aGuard( m_aMutex
);
4093 sal_uInt16 nP
= nPos
;
4094 for ( sal_Int32 n
= 0; n
< aItems
.getLength(); n
++ )
4096 m_pBox
->InsertEntry( aItems
.getConstArray()[n
], nP
);
4097 if ( nPos
!= -1 ) // Not if 0xFFFF, because LIST_APPEND
4104 void SAL_CALL
FmXListBoxCell::removeItems(sal_Int16 nPos
, sal_Int16 nCount
)
4106 ::osl::MutexGuard
aGuard( m_aMutex
);
4109 for ( sal_uInt16 n
= nCount
; n
; )
4110 m_pBox
->RemoveEntry( nPos
+ (--n
) );
4115 sal_Int16 SAL_CALL
FmXListBoxCell::getItemCount()
4117 ::osl::MutexGuard
aGuard( m_aMutex
);
4118 return m_pBox
? m_pBox
->GetEntryCount() : 0;
4122 OUString SAL_CALL
FmXListBoxCell::getItem(sal_Int16 nPos
)
4124 ::osl::MutexGuard
aGuard( m_aMutex
);
4125 return m_pBox
? OUString(m_pBox
->GetEntry(nPos
)) : OUString();
4128 css::uno::Sequence
<OUString
> SAL_CALL
FmXListBoxCell::getItems()
4130 ::osl::MutexGuard
aGuard( m_aMutex
);
4132 css::uno::Sequence
<OUString
> aSeq
;
4135 const sal_Int32 nEntries
= m_pBox
->GetEntryCount();
4136 aSeq
= css::uno::Sequence
<OUString
>( nEntries
);
4137 for ( sal_Int32 n
= nEntries
; n
; )
4140 aSeq
.getArray()[n
] = m_pBox
->GetEntry( n
);
4147 sal_Int16 SAL_CALL
FmXListBoxCell::getSelectedItemPos()
4149 ::osl::MutexGuard
aGuard( m_aMutex
);
4153 sal_Int32 nPos
= m_pBox
->GetSelectEntryPos();
4154 if (nPos
> SHRT_MAX
|| nPos
< SHRT_MIN
)
4155 throw std::out_of_range("awt::XListBox::getSelectedItemPos can only return a short");
4162 Sequence
< sal_Int16
> SAL_CALL
FmXListBoxCell::getSelectedItemsPos()
4164 ::osl::MutexGuard
aGuard( m_aMutex
);
4165 Sequence
<sal_Int16
> aSeq
;
4170 const sal_Int32 nSelEntries
= m_pBox
->GetSelectEntryCount();
4171 aSeq
= Sequence
<sal_Int16
>( nSelEntries
);
4172 for ( sal_Int32 n
= 0; n
< nSelEntries
; ++n
)
4173 aSeq
.getArray()[n
] = m_pBox
->GetSelectEntryPos( n
);
4178 OUString SAL_CALL
FmXListBoxCell::getSelectedItem()
4180 ::osl::MutexGuard
aGuard( m_aMutex
);
4187 aItem
= m_pBox
->GetSelectEntry();
4194 css::uno::Sequence
<OUString
> SAL_CALL
FmXListBoxCell::getSelectedItems()
4196 ::osl::MutexGuard
aGuard( m_aMutex
);
4198 css::uno::Sequence
<OUString
> aSeq
;
4203 const sal_Int32 nSelEntries
= m_pBox
->GetSelectEntryCount();
4204 aSeq
= css::uno::Sequence
<OUString
>( nSelEntries
);
4205 for ( sal_Int32 n
= 0; n
< nSelEntries
; ++n
)
4206 aSeq
.getArray()[n
] = m_pBox
->GetSelectEntry( n
);
4212 void SAL_CALL
FmXListBoxCell::selectItemPos(sal_Int16 nPos
, sal_Bool bSelect
)
4214 ::osl::MutexGuard
aGuard( m_aMutex
);
4217 m_pBox
->SelectEntryPos( nPos
, bSelect
);
4221 void SAL_CALL
FmXListBoxCell::selectItemsPos(const Sequence
< sal_Int16
>& aPositions
, sal_Bool bSelect
)
4223 ::osl::MutexGuard
aGuard( m_aMutex
);
4227 for ( sal_uInt16 n
= (sal_uInt16
)aPositions
.getLength(); n
; )
4228 m_pBox
->SelectEntryPos( (sal_uInt16
) aPositions
.getConstArray()[--n
], bSelect
);
4233 void SAL_CALL
FmXListBoxCell::selectItem(const OUString
& aItem
, sal_Bool bSelect
)
4235 ::osl::MutexGuard
aGuard( m_aMutex
);
4238 m_pBox
->SelectEntry( aItem
, bSelect
);
4242 sal_Bool SAL_CALL
FmXListBoxCell::isMutipleMode()
4244 ::osl::MutexGuard
aGuard( m_aMutex
);
4246 bool bMulti
= false;
4248 bMulti
= m_pBox
->IsMultiSelectionEnabled();
4253 void SAL_CALL
FmXListBoxCell::setMultipleMode(sal_Bool bMulti
)
4255 ::osl::MutexGuard
aGuard( m_aMutex
);
4258 m_pBox
->EnableMultiSelection( bMulti
);
4262 sal_Int16 SAL_CALL
FmXListBoxCell::getDropDownLineCount()
4264 ::osl::MutexGuard
aGuard( m_aMutex
);
4266 sal_Int16 nLines
= 0;
4268 nLines
= m_pBox
->GetDropDownLineCount();
4274 void SAL_CALL
FmXListBoxCell::setDropDownLineCount(sal_Int16 nLines
)
4276 ::osl::MutexGuard
aGuard( m_aMutex
);
4279 m_pBox
->SetDropDownLineCount( nLines
);
4283 void SAL_CALL
FmXListBoxCell::makeVisible(sal_Int16 nEntry
)
4285 ::osl::MutexGuard
aGuard( m_aMutex
);
4288 m_pBox
->SetTopEntry( nEntry
);
4292 void FmXListBoxCell::onWindowEvent( const VclEventId _nEventId
, const vcl::Window
& _rWindow
, const void* _pEventData
)
4294 if ( ( &_rWindow
== m_pBox
)
4295 && ( _nEventId
== VclEventId::ListboxSelect
)
4298 OnDoubleClick( *m_pBox
);
4300 css::awt::ItemEvent aEvent
;
4301 aEvent
.Source
= *this;
4302 aEvent
.Highlighted
= 0;
4304 // with multiple selection 0xFFFF, otherwise the ID
4305 aEvent
.Selected
= (m_pBox
->GetSelectEntryCount() == 1 )
4306 ? m_pBox
->GetSelectEntryPos() : 0xFFFF;
4308 m_aItemListeners
.notifyEach( &awt::XItemListener::itemStateChanged
, aEvent
);
4312 FmXTextCell::onWindowEvent( _nEventId
, _rWindow
, _pEventData
);
4316 IMPL_LINK_NOARG(FmXListBoxCell
, OnDoubleClick
, ListBox
&, void)
4320 ::comphelper::OInterfaceIteratorHelper2
aIt( m_aActionListeners
);
4322 css::awt::ActionEvent aEvent
;
4323 aEvent
.Source
= *this;
4324 aEvent
.ActionCommand
= m_pBox
->GetSelectEntry();
4326 while( aIt
.hasMoreElements() )
4327 static_cast< css::awt::XActionListener
*>(aIt
.next())->actionPerformed( aEvent
);
4331 FmXComboBoxCell::FmXComboBoxCell( DbGridColumn
* pColumn
, DbCellControl
& _rControl
)
4332 :FmXTextCell( pColumn
, _rControl
)
4333 ,m_aItemListeners( m_aMutex
)
4334 ,m_aActionListeners( m_aMutex
)
4335 ,m_pComboBox( &static_cast< ComboBox
& >( _rControl
.GetWindow() ) )
4340 FmXComboBoxCell::~FmXComboBoxCell()
4342 if ( !OComponentHelper::rBHelper
.bDisposed
)
4351 void FmXComboBoxCell::disposing()
4353 css::lang::EventObject
aEvt(*this);
4354 m_aItemListeners
.disposeAndClear(aEvt
);
4355 m_aActionListeners
.disposeAndClear(aEvt
);
4357 FmXTextCell::disposing();
4361 Any SAL_CALL
FmXComboBoxCell::queryAggregation( const css::uno::Type
& _rType
)
4363 Any aReturn
= FmXTextCell::queryAggregation(_rType
);
4365 if ( !aReturn
.hasValue() )
4366 aReturn
= FmXComboBoxCell_Base::queryInterface( _rType
);
4372 Sequence
< Type
> SAL_CALL
FmXComboBoxCell::getTypes( )
4374 return ::comphelper::concatSequences(
4375 FmXTextCell::getTypes(),
4376 FmXComboBoxCell_Base::getTypes()
4381 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXComboBoxCell
)
4384 void SAL_CALL
FmXComboBoxCell::addItemListener(const Reference
< awt::XItemListener
>& l
)
4386 m_aItemListeners
.addInterface( l
);
4390 void SAL_CALL
FmXComboBoxCell::removeItemListener(const Reference
< awt::XItemListener
>& l
)
4392 m_aItemListeners
.removeInterface( l
);
4396 void SAL_CALL
FmXComboBoxCell::addActionListener(const Reference
< awt::XActionListener
>& l
)
4398 m_aActionListeners
.addInterface( l
);
4402 void SAL_CALL
FmXComboBoxCell::removeActionListener(const Reference
< awt::XActionListener
>& l
)
4404 m_aActionListeners
.removeInterface( l
);
4408 void SAL_CALL
FmXComboBoxCell::addItem( const OUString
& Item
, sal_Int16 Pos
)
4410 ::osl::MutexGuard
aGuard( m_aMutex
);
4412 m_pComboBox
->InsertEntry( Item
, Pos
);
4416 void SAL_CALL
FmXComboBoxCell::addItems( const Sequence
< OUString
>& Items
, sal_Int16 Pos
)
4418 ::osl::MutexGuard
aGuard( m_aMutex
);
4421 sal_uInt16 nP
= Pos
;
4422 for ( sal_Int32 n
= 0; n
< Items
.getLength(); n
++ )
4424 m_pComboBox
->InsertEntry( Items
.getConstArray()[n
], nP
);
4432 void SAL_CALL
FmXComboBoxCell::removeItems( sal_Int16 Pos
, sal_Int16 Count
)
4434 ::osl::MutexGuard
aGuard( m_aMutex
);
4437 for ( sal_uInt16 n
= Count
; n
; )
4438 m_pComboBox
->RemoveEntryAt( Pos
+ (--n
) );
4443 sal_Int16 SAL_CALL
FmXComboBoxCell::getItemCount()
4445 ::osl::MutexGuard
aGuard( m_aMutex
);
4446 return m_pComboBox
? m_pComboBox
->GetEntryCount() : 0;
4450 OUString SAL_CALL
FmXComboBoxCell::getItem( sal_Int16 Pos
)
4452 ::osl::MutexGuard
aGuard( m_aMutex
);
4453 return m_pComboBox
? OUString(m_pComboBox
->GetEntry(Pos
)) : OUString();
4456 Sequence
< OUString
> SAL_CALL
FmXComboBoxCell::getItems()
4458 ::osl::MutexGuard
aGuard( m_aMutex
);
4460 Sequence
< OUString
> aItems
;
4463 const sal_Int32 nEntries
= m_pComboBox
->GetEntryCount();
4464 aItems
.realloc( nEntries
);
4465 OUString
* pItem
= aItems
.getArray();
4466 for ( sal_Int32 n
=0; n
<nEntries
; ++n
, ++pItem
)
4467 *pItem
= m_pComboBox
->GetEntry( n
);
4473 sal_Int16 SAL_CALL
FmXComboBoxCell::getDropDownLineCount()
4475 ::osl::MutexGuard
aGuard( m_aMutex
);
4477 sal_Int16 nLines
= 0;
4479 nLines
= m_pComboBox
->GetDropDownLineCount();
4485 void SAL_CALL
FmXComboBoxCell::setDropDownLineCount(sal_Int16 nLines
)
4487 ::osl::MutexGuard
aGuard( m_aMutex
);
4489 m_pComboBox
->SetDropDownLineCount( nLines
);
4493 void FmXComboBoxCell::onWindowEvent( const VclEventId _nEventId
, const vcl::Window
& _rWindow
, const void* _pEventData
)
4496 switch ( _nEventId
)
4498 case VclEventId::ComboboxSelect
:
4500 awt::ItemEvent aEvent
;
4501 aEvent
.Source
= *this;
4502 aEvent
.Highlighted
= 0;
4504 // with multiple selection 0xFFFF, otherwise the ID
4505 aEvent
.Selected
= ( m_pComboBox
->GetSelectEntryCount() == 1 )
4506 ? m_pComboBox
->GetSelectEntryPos()
4508 m_aItemListeners
.notifyEach( &awt::XItemListener::itemStateChanged
, aEvent
);
4513 FmXTextCell::onWindowEvent( _nEventId
, _rWindow
, _pEventData
);
4519 FmXFilterCell::FmXFilterCell(DbGridColumn
* pColumn
, DbCellControl
* pControl
)
4520 :FmXGridCell( pColumn
, pControl
)
4521 ,m_aTextListeners(m_aMutex
)
4524 DBG_ASSERT( dynamic_cast<const DbFilterField
*>( m_pCellControl
) != nullptr, "FmXFilterCell::FmXFilterCell: invalid cell control!" );
4525 static_cast< DbFilterField
* >( m_pCellControl
)->SetCommitHdl( LINK( this, FmXFilterCell
, OnCommit
) );
4529 FmXFilterCell::~FmXFilterCell()
4531 if (!OComponentHelper::rBHelper
.bDisposed
)
4541 sal_Int64 SAL_CALL
FmXFilterCell::getSomething( const Sequence
< sal_Int8
>& _rIdentifier
)
4543 sal_Int64
nReturn(0);
4545 if ( (_rIdentifier
.getLength() == 16)
4546 && (0 == memcmp( getUnoTunnelId().getConstArray(), _rIdentifier
.getConstArray(), 16 ))
4549 nReturn
= reinterpret_cast<sal_Int64
>(this);
4557 class theFmXFilterCellUnoTunnelId
: public rtl::Static
< UnoTunnelIdInit
, theFmXFilterCellUnoTunnelId
> {};
4560 const Sequence
<sal_Int8
>& FmXFilterCell::getUnoTunnelId()
4562 return theFmXFilterCellUnoTunnelId::get().getSeq();
4566 void FmXFilterCell::PaintCell( OutputDevice
& rDev
, const tools::Rectangle
& rRect
)
4568 static_cast< DbFilterField
* >( m_pCellControl
)->PaintCell( rDev
, rRect
);
4573 void FmXFilterCell::disposing()
4575 css::lang::EventObject
aEvt(*this);
4576 m_aTextListeners
.disposeAndClear(aEvt
);
4578 static_cast<DbFilterField
*>(m_pCellControl
)->SetCommitHdl(Link
<DbFilterField
&,void>());
4580 FmXGridCell::disposing();
4584 Any SAL_CALL
FmXFilterCell::queryAggregation( const css::uno::Type
& _rType
)
4586 Any aReturn
= FmXGridCell::queryAggregation(_rType
);
4588 if ( !aReturn
.hasValue() )
4589 aReturn
= FmXFilterCell_Base::queryInterface( _rType
);
4595 Sequence
< css::uno::Type
> SAL_CALL
FmXFilterCell::getTypes( )
4597 return ::comphelper::concatSequences(
4598 FmXGridCell::getTypes(),
4599 FmXFilterCell_Base::getTypes()
4604 IMPLEMENT_GET_IMPLEMENTATION_ID( FmXFilterCell
)
4606 // css::awt::XTextComponent
4608 void SAL_CALL
FmXFilterCell::addTextListener(const Reference
< css::awt::XTextListener
>& l
)
4610 m_aTextListeners
.addInterface( l
);
4614 void SAL_CALL
FmXFilterCell::removeTextListener(const Reference
< css::awt::XTextListener
>& l
)
4616 m_aTextListeners
.removeInterface( l
);
4620 void SAL_CALL
FmXFilterCell::setText( const OUString
& aText
)
4622 ::osl::MutexGuard
aGuard( m_aMutex
);
4623 static_cast<DbFilterField
*>(m_pCellControl
)->SetText(aText
);
4627 void SAL_CALL
FmXFilterCell::insertText( const css::awt::Selection
& /*rSel*/, const OUString
& /*aText*/ )
4632 OUString SAL_CALL
FmXFilterCell::getText()
4634 ::osl::MutexGuard
aGuard( m_aMutex
);
4635 return static_cast<DbFilterField
*>(m_pCellControl
)->GetText();
4639 OUString SAL_CALL
FmXFilterCell::getSelectedText()
4645 void SAL_CALL
FmXFilterCell::setSelection( const css::awt::Selection
& /*aSelection*/ )
4650 css::awt::Selection SAL_CALL
FmXFilterCell::getSelection()
4652 return css::awt::Selection();
4656 sal_Bool SAL_CALL
FmXFilterCell::isEditable()
4662 void SAL_CALL
FmXFilterCell::setEditable( sal_Bool
/*bEditable*/ )
4667 sal_Int16 SAL_CALL
FmXFilterCell::getMaxTextLen()
4673 void SAL_CALL
FmXFilterCell::setMaxTextLen( sal_Int16
/*nLen*/ )
4678 IMPL_LINK_NOARG(FmXFilterCell
, OnCommit
, DbFilterField
&, void)
4680 ::comphelper::OInterfaceIteratorHelper2
aIt( m_aTextListeners
);
4681 css::awt::TextEvent aEvt
;
4682 aEvt
.Source
= *this;
4683 while( aIt
.hasMoreElements() )
4684 static_cast< css::awt::XTextListener
*>(aIt
.next())->textChanged( aEvt
);
4687 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */