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 .
20 #include "standardcontrol.hxx"
21 #include "pcrcommon.hxx"
23 #include <com/sun/star/util/DateTime.hpp>
24 #include <com/sun/star/util/Date.hpp>
25 #include <com/sun/star/util/Time.hpp>
26 #include <com/sun/star/util/Color.hpp>
27 #include <com/sun/star/util/MeasureUnit.hpp>
28 #include <com/sun/star/inspection/PropertyControlType.hpp>
29 #include <comphelper/string.hxx>
30 #include <rtl/math.hxx>
31 #include <sfx2/objsh.hxx>
34 // ugly dependencies for the OColorControl
35 #include <svx/svxids.hrc>
36 #include <svx/drawitem.hxx>
37 #include <svx/xtable.hxx>
39 #include <vcl/floatwin.hxx>
40 #include <svtools/svmedit.hxx>
41 #include <svtools/colorcfg.hxx>
42 #include <unotools/syslocale.hxx>
43 #include <unotools/datetime.hxx>
44 #include <i18nlangtag/languagetag.hxx>
45 #include <vcl/button.hxx>
46 #include <vcl/svapp.hxx>
47 #include <vcl/settings.hxx>
51 #include <boost/bind.hpp>
52 #include <boost/scoped_ptr.hpp>
59 using namespace ::com::sun::star
;
60 using namespace ::com::sun::star::uno
;
61 using namespace ::com::sun::star::awt
;
62 using namespace ::com::sun::star::lang
;
63 using namespace ::com::sun::star::util
;
64 using namespace ::com::sun::star::beans
;
65 using namespace ::com::sun::star::inspection
;
71 OTimeControl::OTimeControl( vcl::Window
* pParent
, WinBits nWinStyle
)
72 :OTimeControl_Base( PropertyControlType::TimeField
, pParent
, nWinStyle
)
74 getTypedControlWindow()->SetStrictFormat( true );
75 getTypedControlWindow()->SetFormat( TimeFieldFormat::F_SEC
);
76 getTypedControlWindow()->EnableEmptyFieldValue( true );
80 void SAL_CALL
OTimeControl::setValue( const Any
& _rValue
) throw (IllegalTypeException
, RuntimeException
, std::exception
)
83 if ( !( _rValue
>>= aUNOTime
) )
85 getTypedControlWindow()->SetText( "" );
86 getTypedControlWindow()->SetEmptyTime();
90 getTypedControlWindow()->SetTime( ::tools::Time(aUNOTime
) );
95 Any SAL_CALL
OTimeControl::getValue() throw (RuntimeException
, std::exception
)
98 if ( !getTypedControlWindow()->GetText().isEmpty() )
100 aPropValue
<<= getTypedControlWindow()->GetTime().GetUNOTime();
106 Type SAL_CALL
OTimeControl::getValueType() throw (RuntimeException
, std::exception
)
108 return ::cppu::UnoType
<util::Time
>::get();
115 ODateControl::ODateControl( vcl::Window
* pParent
, WinBits nWinStyle
)
116 :ODateControl_Base( PropertyControlType::DateField
, pParent
, nWinStyle
| WB_DROPDOWN
)
118 WindowType
* pControlWindow
= getTypedControlWindow();
119 pControlWindow
->SetStrictFormat(true);
121 pControlWindow
->SetMin( ::Date( 1,1,1600 ) );
122 pControlWindow
->SetFirst( ::Date( 1,1,1600 ) );
123 pControlWindow
->SetLast( ::Date( 1, 1, 9999 ) );
124 pControlWindow
->SetMax( ::Date( 1, 1, 9999 ) );
126 pControlWindow
->SetExtDateFormat( XTDATEF_SYSTEM_SHORT_YYYY
);
127 pControlWindow
->EnableEmptyFieldValue( true );
131 void SAL_CALL
ODateControl::setValue( const Any
& _rValue
) throw (IllegalTypeException
, RuntimeException
, std::exception
)
134 if ( !( _rValue
>>= aUNODate
) )
136 getTypedControlWindow()->SetText( "" );
137 getTypedControlWindow()->SetEmptyDate();
141 ::Date
aDate( aUNODate
.Day
, aUNODate
.Month
, aUNODate
.Year
);
142 getTypedControlWindow()->SetDate( aDate
);
147 Any SAL_CALL
ODateControl::getValue() throw (RuntimeException
, std::exception
)
150 if ( !getTypedControlWindow()->GetText().isEmpty() )
152 ::Date
aDate( getTypedControlWindow()->GetDate() );
153 aPropValue
<<= aDate
.GetUNODate();
159 Type SAL_CALL
ODateControl::getValueType() throw (RuntimeException
, std::exception
)
161 return ::cppu::UnoType
<util::Date
>::get();
168 OEditControl::OEditControl(vcl::Window
* _pParent
, bool _bPW
, WinBits _nWinStyle
)
169 :OEditControl_Base( _bPW
? PropertyControlType::CharacterField
: PropertyControlType::TextField
, _pParent
, _nWinStyle
)
171 m_bIsPassword
= _bPW
;
174 getTypedControlWindow()->SetMaxTextLen( 1 );
178 void SAL_CALL
OEditControl::setValue( const Any
& _rValue
) throw (IllegalTypeException
, RuntimeException
, std::exception
)
183 sal_Int16 nValue
= 0;
187 sText
= OUString(static_cast<sal_Unicode
>(nValue
));
193 getTypedControlWindow()->SetText( sText
);
197 Any SAL_CALL
OEditControl::getValue() throw (RuntimeException
, std::exception
)
201 OUString
sText( getTypedControlWindow()->GetText() );
204 if ( !sText
.isEmpty() )
205 aPropValue
<<= (sal_Int16
)sText
[0];
208 aPropValue
<<= sText
;
214 Type SAL_CALL
OEditControl::getValueType() throw (RuntimeException
, std::exception
)
216 return m_bIsPassword
? ::cppu::UnoType
<sal_Int16
>::get() : ::cppu::UnoType
<OUString
>::get();
220 void OEditControl::modified()
222 OEditControl_Base::modified();
224 // for password controls, we fire a commit for every single change
226 m_aImplControl
.notifyModifiedValue();
230 static long ImplCalcLongValue( double nValue
, sal_uInt16 nDigits
)
233 for ( sal_uInt16 d
= 0; d
< nDigits
; ++d
)
236 if ( n
> ::std::numeric_limits
< long >::max() )
237 return ::std::numeric_limits
< long >::max();
242 static double ImplCalcDoubleValue( long nValue
, sal_uInt16 nDigits
)
245 for ( sal_uInt16 d
= 0; d
< nDigits
; ++d
)
251 // class ODateTimeControl
254 ODateTimeControl::ODateTimeControl( vcl::Window
* _pParent
, WinBits _nWinStyle
)
255 :ODateTimeControl_Base( PropertyControlType::DateTimeField
, _pParent
, _nWinStyle
)
257 getTypedControlWindow()->EnableEmptyField( true );
259 // determine a default format
260 LanguageType eSysLanguage
= SvtSysLocale().GetLanguageTag().getLanguageType( false);
262 getTypedControlWindow()->SetFormatter( getTypedControlWindow()->StandardFormatter() );
263 SvNumberFormatter
* pFormatter
= getTypedControlWindow()->GetFormatter();
264 sal_uLong nStandardDateTimeFormat
= pFormatter
->GetStandardFormat( css::util::NumberFormat::DATETIME
, eSysLanguage
);
266 getTypedControlWindow()->SetFormatKey( nStandardDateTimeFormat
);
270 void SAL_CALL
ODateTimeControl::setValue( const Any
& _rValue
) throw (IllegalTypeException
, RuntimeException
, std::exception
)
272 if ( !_rValue
.hasValue() )
274 getTypedControlWindow()->SetText( "" );
278 util::DateTime aUNODateTime
;
279 OSL_VERIFY( _rValue
>>= aUNODateTime
);
281 ::DateTime
aDateTime( ::DateTime::EMPTY
);
282 ::utl::typeConvert( aUNODateTime
, aDateTime
);
284 double nValue
= aDateTime
- ::DateTime( *getTypedControlWindow()->GetFormatter()->GetNullDate() );
285 getTypedControlWindow()->SetValue( nValue
);
290 Any SAL_CALL
ODateTimeControl::getValue() throw (RuntimeException
, std::exception
)
293 if ( !getTypedControlWindow()->GetText().isEmpty() )
295 double nValue
= getTypedControlWindow()->GetValue();
297 ::DateTime
aDateTime( *getTypedControlWindow()->GetFormatter()->GetNullDate() );
299 // add the "days" part
300 double nDays
= floor( nValue
);
303 // add the "time" part
304 double nTime
= nValue
- nDays
;
305 nTime
= ::rtl::math::round( nTime
* 86400.0 ) / 86400.0;
306 // we're not interested in 100th seconds, and this here prevents rounding errors
309 util::DateTime aUNODateTime
;
310 ::utl::typeConvert( aDateTime
, aUNODateTime
);
312 aPropValue
<<= aUNODateTime
;
318 Type SAL_CALL
ODateTimeControl::getValueType() throw (RuntimeException
, std::exception
)
320 return ::cppu::UnoType
<util::DateTime
>::get();
327 HyperlinkInput::HyperlinkInput( vcl::Window
* _pParent
, WinBits _nWinStyle
)
328 :Edit( _pParent
, _nWinStyle
)
330 ::svtools::ColorConfig aColorConfig
;
331 ::svtools::ColorConfigValue
aLinkColor( aColorConfig
.GetColorValue( ::svtools::LINKS
) );
333 AllSettings
aAllSettings( GetSettings() );
334 StyleSettings
aStyleSettings( aAllSettings
.GetStyleSettings() );
336 vcl::Font
aFieldFont( aStyleSettings
.GetFieldFont() );
337 aFieldFont
.SetUnderline( UNDERLINE_SINGLE
);
338 aFieldFont
.SetColor( aLinkColor
.nColor
);
339 aStyleSettings
.SetFieldFont( aFieldFont
);
341 aStyleSettings
.SetFieldTextColor( aLinkColor
.nColor
);
343 aAllSettings
.SetStyleSettings( aStyleSettings
);
344 SetSettings( aAllSettings
);
348 void HyperlinkInput::MouseMove( const ::MouseEvent
& rMEvt
)
350 Edit::MouseMove( rMEvt
);
352 PointerStyle
ePointerStyle( PointerStyle::Text
);
354 if ( !rMEvt
.IsLeaveWindow() )
356 if ( impl_textHitTest( rMEvt
.GetPosPixel() ) )
357 ePointerStyle
= PointerStyle::RefHand
;
360 SetPointer( Pointer( ePointerStyle
) );
364 void HyperlinkInput::MouseButtonDown( const ::MouseEvent
& rMEvt
)
366 Edit::MouseButtonDown( rMEvt
);
368 if ( impl_textHitTest( rMEvt
.GetPosPixel() ) )
369 m_aMouseButtonDownPos
= rMEvt
.GetPosPixel();
371 m_aMouseButtonDownPos
.X() = m_aMouseButtonDownPos
.Y() = -1;
375 void HyperlinkInput::MouseButtonUp( const ::MouseEvent
& rMEvt
)
377 Edit::MouseButtonUp( rMEvt
);
379 impl_checkEndClick( rMEvt
);
383 bool HyperlinkInput::impl_textHitTest( const ::Point
& _rWindowPos
)
385 sal_Int32 nPos
= GetCharPos( _rWindowPos
);
386 return ( ( nPos
!= EDIT_NOLIMIT
) && ( nPos
< GetText().getLength() ) );
390 void HyperlinkInput::impl_checkEndClick( const ::MouseEvent
& rMEvt
)
392 const MouseSettings
& rMouseSettings( GetSettings().GetMouseSettings() );
393 if ( ( std::abs( rMEvt
.GetPosPixel().X() - m_aMouseButtonDownPos
.X() ) < rMouseSettings
.GetStartDragWidth() )
394 && ( std::abs( rMEvt
.GetPosPixel().Y() - m_aMouseButtonDownPos
.Y() ) < rMouseSettings
.GetStartDragHeight() )
396 Application::PostUserEvent( m_aClickHandler
);
400 void HyperlinkInput::Tracking( const TrackingEvent
& rTEvt
)
402 Edit::Tracking( rTEvt
);
404 if ( rTEvt
.IsTrackingEnded() )
405 impl_checkEndClick( rTEvt
.GetMouseEvent() );
409 //= OHyperlinkControl
412 OHyperlinkControl::OHyperlinkControl( vcl::Window
* _pParent
, WinBits _nWinStyle
)
413 :OHyperlinkControl_Base( PropertyControlType::HyperlinkField
, _pParent
, _nWinStyle
)
414 ,m_aActionListeners( m_aMutex
)
416 getTypedControlWindow()->SetClickHdl( LINK( this, OHyperlinkControl
, OnHyperlinkClicked
) );
420 Any SAL_CALL
OHyperlinkControl::getValue() throw (RuntimeException
, std::exception
)
422 OUString sText
= getTypedControlWindow()->GetText();
423 return makeAny( sText
);
427 void SAL_CALL
OHyperlinkControl::setValue( const Any
& _value
) throw (IllegalTypeException
, RuntimeException
, std::exception
)
431 getTypedControlWindow()->SetText( sText
);
435 Type SAL_CALL
OHyperlinkControl::getValueType() throw (RuntimeException
, std::exception
)
437 return ::cppu::UnoType
<OUString
>::get();
441 void SAL_CALL
OHyperlinkControl::addActionListener( const Reference
< XActionListener
>& listener
) throw (RuntimeException
, std::exception
)
444 m_aActionListeners
.addInterface( listener
);
448 void SAL_CALL
OHyperlinkControl::removeActionListener( const Reference
< XActionListener
>& listener
) throw (RuntimeException
, std::exception
)
450 m_aActionListeners
.removeInterface( listener
);
454 void SAL_CALL
OHyperlinkControl::disposing()
456 OHyperlinkControl_Base::disposing();
458 EventObject
aEvent( *this );
459 m_aActionListeners
.disposeAndClear( aEvent
);
463 IMPL_LINK_NOARG( OHyperlinkControl
, OnHyperlinkClicked
)
465 ActionEvent
aEvent( *this, OUString( "clicked" ) );
466 m_aActionListeners
.forEach
< XActionListener
>(
468 &XActionListener::actionPerformed
,
469 _1
, boost::cref(aEvent
) ) );
478 ONumericControl::ONumericControl( vcl::Window
* _pParent
, WinBits _nWinStyle
)
479 :ONumericControl_Base( PropertyControlType::NumericField
, _pParent
, _nWinStyle
)
480 ,m_eValueUnit( FUNIT_NONE
)
481 ,m_nFieldToUNOValueFactor( 1 )
483 MetricField::SetDefaultUnit( FUNIT_NONE
);
485 getTypedControlWindow()->EnableEmptyFieldValue( true );
486 getTypedControlWindow()->SetStrictFormat( true );
487 Optional
< double > value( getMaxValue() );
488 value
.Value
= -value
.Value
;
489 setMinValue( value
);
493 ::sal_Int16 SAL_CALL
ONumericControl::getDecimalDigits() throw (RuntimeException
, std::exception
)
495 return getTypedControlWindow()->GetDecimalDigits();
499 void SAL_CALL
ONumericControl::setDecimalDigits( ::sal_Int16 _decimaldigits
) throw (RuntimeException
, std::exception
)
501 getTypedControlWindow()->SetDecimalDigits( _decimaldigits
);
505 Optional
< double > SAL_CALL
ONumericControl::getMinValue() throw (RuntimeException
, std::exception
)
507 Optional
< double > aReturn( sal_True
, 0 );
509 sal_Int64 minValue
= getTypedControlWindow()->GetMin();
510 if ( minValue
== ::std::numeric_limits
< sal_Int64
>::min() )
511 aReturn
.IsPresent
= sal_False
;
513 aReturn
.Value
= (double)minValue
;
519 void SAL_CALL
ONumericControl::setMinValue( const Optional
< double >& _minvalue
) throw (RuntimeException
, std::exception
)
521 if ( !_minvalue
.IsPresent
)
522 getTypedControlWindow()->SetMin( ::std::numeric_limits
< sal_Int64
>::min() );
524 getTypedControlWindow()->SetMin( impl_apiValueToFieldValue_nothrow( _minvalue
.Value
) , m_eValueUnit
);
528 Optional
< double > SAL_CALL
ONumericControl::getMaxValue() throw (RuntimeException
, std::exception
)
530 Optional
< double > aReturn( sal_True
, 0 );
532 sal_Int64 maxValue
= getTypedControlWindow()->GetMax();
533 if ( maxValue
== ::std::numeric_limits
< sal_Int64
>::max() )
534 aReturn
.IsPresent
= sal_False
;
536 aReturn
.Value
= (double)maxValue
;
542 void SAL_CALL
ONumericControl::setMaxValue( const Optional
< double >& _maxvalue
) throw (RuntimeException
, std::exception
)
544 if ( !_maxvalue
.IsPresent
)
545 getTypedControlWindow()->SetMax( ::std::numeric_limits
< sal_Int64
>::max() );
547 getTypedControlWindow()->SetMax( impl_apiValueToFieldValue_nothrow( _maxvalue
.Value
), m_eValueUnit
);
551 ::sal_Int16 SAL_CALL
ONumericControl::getDisplayUnit() throw (RuntimeException
, std::exception
)
553 return VCLUnoHelper::ConvertToMeasurementUnit( getTypedControlWindow()->GetUnit(), 1 );
557 void SAL_CALL
ONumericControl::setDisplayUnit( ::sal_Int16 _displayunit
) throw (IllegalArgumentException
, RuntimeException
, std::exception
)
559 if ( ( _displayunit
< MeasureUnit::MM_100TH
) || ( _displayunit
> MeasureUnit::PERCENT
) )
560 throw IllegalArgumentException();
561 if ( ( _displayunit
== MeasureUnit::MM_100TH
)
562 || ( _displayunit
== MeasureUnit::MM_10TH
)
563 || ( _displayunit
== MeasureUnit::INCH_1000TH
)
564 || ( _displayunit
== MeasureUnit::INCH_100TH
)
565 || ( _displayunit
== MeasureUnit::INCH_10TH
)
566 || ( _displayunit
== MeasureUnit::PERCENT
)
568 throw IllegalArgumentException();
570 sal_Int16 nDummyFactor
= 1;
571 FieldUnit eFieldUnit
= VCLUnoHelper::ConvertToFieldUnit( _displayunit
, nDummyFactor
);
572 if ( nDummyFactor
!= 1 )
573 // everything which survived the checks above should result in a factor of 1, i.e.,
574 // it should have a direct counterpart as FieldUnit
575 throw RuntimeException();
576 getTypedControlWindow()->MetricFormatter::SetUnit( eFieldUnit
);
580 ::sal_Int16 SAL_CALL
ONumericControl::getValueUnit() throw (RuntimeException
, std::exception
)
582 return VCLUnoHelper::ConvertToMeasurementUnit( m_eValueUnit
, m_nFieldToUNOValueFactor
);
586 void SAL_CALL
ONumericControl::setValueUnit( ::sal_Int16 _valueunit
) throw (RuntimeException
, std::exception
)
588 if ( ( _valueunit
< MeasureUnit::MM_100TH
) || ( _valueunit
> MeasureUnit::PERCENT
) )
589 throw IllegalArgumentException();
590 m_eValueUnit
= VCLUnoHelper::ConvertToFieldUnit( _valueunit
, m_nFieldToUNOValueFactor
);
594 void SAL_CALL
ONumericControl::setValue( const Any
& _rValue
) throw (IllegalTypeException
, RuntimeException
, std::exception
)
596 if ( !_rValue
.hasValue() )
598 getTypedControlWindow()->SetText( "" );
599 getTypedControlWindow()->SetEmptyFieldValue();
604 OSL_VERIFY( _rValue
>>= nValue
);
605 long nControlValue
= impl_apiValueToFieldValue_nothrow( nValue
);
606 getTypedControlWindow()->SetValue( nControlValue
, m_eValueUnit
);
611 long ONumericControl::impl_apiValueToFieldValue_nothrow( double _nApiValue
) const
613 long nControlValue
= ImplCalcLongValue( _nApiValue
, getTypedControlWindow()->GetDecimalDigits() );
614 nControlValue
/= m_nFieldToUNOValueFactor
;
615 return nControlValue
;
619 double ONumericControl::impl_fieldValueToApiValue_nothrow( sal_Int64 _nFieldValue
) const
621 double nApiValue
= ImplCalcDoubleValue( (long)_nFieldValue
, getTypedControlWindow()->GetDecimalDigits() );
622 nApiValue
*= m_nFieldToUNOValueFactor
;
627 Any SAL_CALL
ONumericControl::getValue() throw (RuntimeException
, std::exception
)
630 if ( !getTypedControlWindow()->GetText().isEmpty() )
632 double nValue
= impl_fieldValueToApiValue_nothrow( getTypedControlWindow()->GetValue( m_eValueUnit
) );
633 aPropValue
<<= nValue
;
639 Type SAL_CALL
ONumericControl::getValueType() throw (RuntimeException
, std::exception
)
641 return ::cppu::UnoType
<double>::get();
647 #define LB_DEFAULT_COUNT 20
649 OUString
MakeHexStr(sal_uInt32 nVal
, sal_Int32 nLength
)
654 char c
= char(nVal
& 0x000F);
660 while (aStr
.getLength() < nLength
) aStr
.insert(0, '0');
661 return aStr
.makeStringAndClear();
665 OColorControl::OColorControl(vcl::Window
* pParent
, WinBits nWinStyle
)
666 :OColorControl_Base( PropertyControlType::ColorListBox
, pParent
, nWinStyle
)
668 // initialize the color listbox
669 XColorListRef pColorList
;
670 SfxObjectShell
* pDocSh
= SfxObjectShell::Current();
671 const SfxPoolItem
* pItem
= pDocSh
? pDocSh
->GetItem( SID_COLOR_TABLE
) : NULL
;
674 DBG_ASSERT(pItem
->ISA(SvxColorListItem
), "OColorControl::OColorControl: invalid color item!");
675 pColorList
= static_cast<const SvxColorListItem
*>( pItem
)->GetColorList();
678 if ( !pColorList
.is() )
679 pColorList
= XColorList::GetStdColorList();
682 DBG_ASSERT(pColorList
.is(), "OColorControl::OColorControl: no color table!");
684 if ( pColorList
.is() )
686 for (sal_uInt16 i
= 0; i
< pColorList
->Count(); ++i
)
688 XColorEntry
* pEntry
= pColorList
->GetColor( i
);
689 getTypedControlWindow()->InsertEntry( pEntry
->GetColor(), pEntry
->GetName() );
693 getTypedControlWindow()->SetDropDownLineCount( LB_DEFAULT_COUNT
);
694 if ( ( nWinStyle
& WB_READONLY
) != 0 )
696 getTypedControlWindow()->SetReadOnly( true );
697 getTypedControlWindow()->Enable( true );
702 void SAL_CALL
OColorControl::setValue( const Any
& _rValue
) throw (IllegalTypeException
, RuntimeException
, std::exception
)
704 if ( _rValue
.hasValue() )
706 ::com::sun::star::util::Color nColor
= COL_TRANSPARENT
;
707 if ( _rValue
>>= nColor
)
709 ::Color
aRgbCol((ColorData
)nColor
);
711 getTypedControlWindow()->SelectEntry( aRgbCol
);
712 if ( !getTypedControlWindow()->IsEntrySelected( aRgbCol
) )
713 { // the given color is not part of the list -> insert a new entry with the hex code of the color
715 aStr
+= MakeHexStr(nColor
,8);
716 getTypedControlWindow()->InsertEntry( aRgbCol
, aStr
);
717 getTypedControlWindow()->SelectEntry( aRgbCol
);
722 OUString sNonColorValue
;
723 if ( !( _rValue
>>= sNonColorValue
) )
724 throw IllegalTypeException();
725 getTypedControlWindow()->SelectEntry( sNonColorValue
);
726 if ( !getTypedControlWindow()->IsEntrySelected( sNonColorValue
) )
727 getTypedControlWindow()->SetNoSelection();
731 getTypedControlWindow()->SetNoSelection();
735 Any SAL_CALL
OColorControl::getValue() throw (RuntimeException
, std::exception
)
738 if ( getTypedControlWindow()->GetSelectEntryCount() > 0 )
740 OUString sSelectedEntry
= getTypedControlWindow()->GetSelectEntry();
741 if ( m_aNonColorEntries
.find( sSelectedEntry
) != m_aNonColorEntries
.end() )
742 aPropValue
<<= sSelectedEntry
;
745 ::Color aRgbCol
= getTypedControlWindow()->GetSelectEntryColor();
746 aPropValue
<<= (::com::sun::star::util::Color
)aRgbCol
.GetColor();
753 Type SAL_CALL
OColorControl::getValueType() throw (RuntimeException
, std::exception
)
755 return ::cppu::UnoType
<sal_Int32
>::get();
759 void SAL_CALL
OColorControl::clearList() throw (RuntimeException
, std::exception
)
761 getTypedControlWindow()->Clear();
765 void SAL_CALL
OColorControl::prependListEntry( const OUString
& NewEntry
) throw (RuntimeException
, std::exception
)
767 getTypedControlWindow()->InsertEntry( NewEntry
, 0 );
768 m_aNonColorEntries
.insert( NewEntry
);
772 void SAL_CALL
OColorControl::appendListEntry( const OUString
& NewEntry
) throw (RuntimeException
, std::exception
)
774 getTypedControlWindow()->InsertEntry( NewEntry
);
775 m_aNonColorEntries
.insert( NewEntry
);
778 Sequence
< OUString
> SAL_CALL
OColorControl::getListEntries( ) throw (RuntimeException
, std::exception
)
780 if ( !m_aNonColorEntries
.empty() )
781 return Sequence
< OUString
>(&(*m_aNonColorEntries
.begin()),m_aNonColorEntries
.size());
782 return Sequence
< OUString
>();
786 void OColorControl::modified()
788 OColorControl_Base::modified();
790 if ( !getTypedControlWindow()->IsTravelSelect() )
792 m_aImplControl
.notifyModifiedValue();
799 OListboxControl::OListboxControl( vcl::Window
* pParent
, WinBits nWinStyle
)
800 :OListboxControl_Base( PropertyControlType::ListBox
, pParent
, nWinStyle
)
802 getTypedControlWindow()->SetDropDownLineCount( LB_DEFAULT_COUNT
);
803 if ( ( nWinStyle
& WB_READONLY
) != 0 )
805 getTypedControlWindow()->SetReadOnly( true );
806 getTypedControlWindow()->Enable( true );
811 Any SAL_CALL
OListboxControl::getValue() throw (RuntimeException
, std::exception
)
813 OUString
sControlValue( getTypedControlWindow()->GetSelectEntry() );
816 if ( !sControlValue
.isEmpty() )
817 aPropValue
<<= sControlValue
;
822 Type SAL_CALL
OListboxControl::getValueType() throw (RuntimeException
, std::exception
)
824 return ::cppu::UnoType
<OUString
>::get();
828 void SAL_CALL
OListboxControl::setValue( const Any
& _rValue
) throw (IllegalTypeException
, RuntimeException
, std::exception
)
830 if ( !_rValue
.hasValue() )
831 getTypedControlWindow()->SetNoSelection();
835 _rValue
>>= sSelection
;
837 if ( !sSelection
.equals( getTypedControlWindow()->GetSelectEntry() ) )
838 getTypedControlWindow()->SelectEntry( sSelection
);
840 if ( !getTypedControlWindow()->IsEntrySelected( sSelection
) )
842 getTypedControlWindow()->InsertEntry( sSelection
, 0 );
843 getTypedControlWindow()->SelectEntry( sSelection
);
849 void SAL_CALL
OListboxControl::clearList() throw (RuntimeException
, std::exception
)
851 getTypedControlWindow()->Clear();
855 void SAL_CALL
OListboxControl::prependListEntry( const OUString
& NewEntry
) throw (RuntimeException
, std::exception
)
857 getTypedControlWindow()->InsertEntry( NewEntry
, 0 );
861 void SAL_CALL
OListboxControl::appendListEntry( const OUString
& NewEntry
) throw (RuntimeException
, std::exception
)
863 getTypedControlWindow()->InsertEntry( NewEntry
);
866 Sequence
< OUString
> SAL_CALL
OListboxControl::getListEntries( ) throw (RuntimeException
, std::exception
)
868 const sal_uInt16 nCount
= getTypedControlWindow()->GetEntryCount();
869 Sequence
< OUString
> aRet(nCount
);
870 OUString
* pIter
= aRet
.getArray();
871 for (sal_uInt16 i
= 0; i
< nCount
; ++i
,++pIter
)
872 *pIter
= getTypedControlWindow()->GetEntry(i
);
878 void OListboxControl::modified()
880 OListboxControl_Base::modified();
882 if ( !getTypedControlWindow()->IsTravelSelect() )
884 m_aImplControl
.notifyModifiedValue();
891 OComboboxControl::OComboboxControl( vcl::Window
* pParent
, WinBits nWinStyle
)
892 :OComboboxControl_Base( PropertyControlType::ComboBox
, pParent
, nWinStyle
)
894 getTypedControlWindow()->SetDropDownLineCount( LB_DEFAULT_COUNT
);
895 getTypedControlWindow()->SetSelectHdl( LINK( this, OComboboxControl
, OnEntrySelected
) );
899 void SAL_CALL
OComboboxControl::setValue( const Any
& _rValue
) throw (IllegalTypeException
, RuntimeException
, std::exception
)
903 getTypedControlWindow()->SetText( sText
);
907 Any SAL_CALL
OComboboxControl::getValue() throw (RuntimeException
, std::exception
)
909 return makeAny( OUString( getTypedControlWindow()->GetText() ) );
913 Type SAL_CALL
OComboboxControl::getValueType() throw (RuntimeException
, std::exception
)
915 return ::cppu::UnoType
<OUString
>::get();
919 void SAL_CALL
OComboboxControl::clearList() throw (RuntimeException
, std::exception
)
921 getTypedControlWindow()->Clear();
925 void SAL_CALL
OComboboxControl::prependListEntry( const OUString
& NewEntry
) throw (RuntimeException
, std::exception
)
927 getTypedControlWindow()->InsertEntry( NewEntry
, 0 );
931 void SAL_CALL
OComboboxControl::appendListEntry( const OUString
& NewEntry
) throw (RuntimeException
, std::exception
)
933 getTypedControlWindow()->InsertEntry( NewEntry
);
936 Sequence
< OUString
> SAL_CALL
OComboboxControl::getListEntries( ) throw (RuntimeException
, std::exception
)
938 const sal_uInt16 nCount
= getTypedControlWindow()->GetEntryCount();
939 Sequence
< OUString
> aRet(nCount
);
940 OUString
* pIter
= aRet
.getArray();
941 for (sal_uInt16 i
= 0; i
< nCount
; ++i
,++pIter
)
942 *pIter
= getTypedControlWindow()->GetEntry(i
);
948 IMPL_LINK_NOARG( OComboboxControl
, OnEntrySelected
)
950 if ( !getTypedControlWindow()->IsTravelSelect() )
952 m_aImplControl
.notifyModifiedValue();
957 //= OMultilineFloatingEdit
959 class OMultilineFloatingEdit
: public FloatingWindow
962 VclPtr
<MultiLineEdit
> m_aImplEdit
;
965 virtual void Resize() SAL_OVERRIDE
;
968 OMultilineFloatingEdit(vcl::Window
* _pParen
);
969 virtual ~OMultilineFloatingEdit();
970 virtual void dispose() SAL_OVERRIDE
;
971 MultiLineEdit
& getEdit() { return *m_aImplEdit
.get(); }
974 virtual bool PreNotify(NotifyEvent
& _rNEvt
) SAL_OVERRIDE
;
978 OMultilineFloatingEdit::OMultilineFloatingEdit(vcl::Window
* _pParent
)
979 :FloatingWindow(_pParent
, WB_BORDER
)
980 ,m_aImplEdit(VclPtr
<MultiLineEdit
>::Create(this, WB_VSCROLL
|WB_IGNORETAB
|WB_NOBORDER
))
985 OMultilineFloatingEdit::~OMultilineFloatingEdit()
990 void OMultilineFloatingEdit::dispose()
992 m_aImplEdit
.disposeAndClear();
993 FloatingWindow::dispose();
996 void OMultilineFloatingEdit::Resize()
998 m_aImplEdit
->SetSizePixel(GetOutputSizePixel());
1002 bool OMultilineFloatingEdit::PreNotify(NotifyEvent
& _rNEvt
)
1004 bool nResult
= true;
1006 MouseNotifyEvent nSwitch
= _rNEvt
.GetType();
1007 if (MouseNotifyEvent::KEYINPUT
== nSwitch
)
1009 const vcl::KeyCode
& aKeyCode
= _rNEvt
.GetKeyEvent()->GetKeyCode();
1010 sal_uInt16 nKey
= aKeyCode
.GetCode();
1012 if ( ( (KEY_RETURN
== nKey
)
1013 && !aKeyCode
.IsShift()
1015 || ( (KEY_UP
== nKey
)
1016 && aKeyCode
.IsMod2()
1023 nResult
=FloatingWindow::PreNotify(_rNEvt
);
1026 nResult
=FloatingWindow::PreNotify(_rNEvt
);
1032 //= DropDownEditControl_Base
1035 DropDownEditControl::DropDownEditControl( vcl::Window
* _pParent
, WinBits _nStyle
)
1036 :DropDownEditControl_Base( _pParent
, _nStyle
)
1037 ,m_pFloatingEdit( NULL
)
1038 ,m_pDropdownButton( NULL
)
1039 ,m_nOperationMode( eStringList
)
1040 ,m_bDropdown( false )
1042 SetCompoundControl( true );
1044 m_pImplEdit
= VclPtr
<MultiLineEdit
>::Create( this, WB_TABSTOP
| WB_IGNORETAB
| WB_NOBORDER
| (_nStyle
& WB_READONLY
) );
1045 SetSubEdit( m_pImplEdit
);
1046 m_pImplEdit
->Show();
1048 if ( _nStyle
& WB_DROPDOWN
)
1050 m_pDropdownButton
= VclPtr
<PushButton
>::Create( this, WB_NOLIGHTBORDER
| WB_RECTSTYLE
| WB_NOTABSTOP
);
1051 m_pDropdownButton
->SetSymbol(SymbolType::SPIN_DOWN
);
1052 m_pDropdownButton
->SetClickHdl( LINK( this, DropDownEditControl
, DropDownHdl
) );
1053 m_pDropdownButton
->Show();
1056 m_pFloatingEdit
= VclPtr
<OMultilineFloatingEdit
>::Create(this);
1058 m_pFloatingEdit
->SetPopupModeEndHdl( LINK( this, DropDownEditControl
, ReturnHdl
) );
1059 m_pFloatingEdit
->getEdit().SetReadOnly( ( _nStyle
& WB_READONLY
) != 0 );
1063 void DropDownEditControl::setControlHelper( ControlHelper
& _rControlHelper
)
1065 DropDownEditControl_Base::setControlHelper( _rControlHelper
);
1066 m_pFloatingEdit
->getEdit().SetModifyHdl( LINK( &_rControlHelper
, ControlHelper
, ModifiedHdl
) );
1067 m_pImplEdit
->SetGetFocusHdl( LINK( &_rControlHelper
, ControlHelper
, GetFocusHdl
) );
1068 m_pImplEdit
->SetModifyHdl( LINK( &_rControlHelper
, ControlHelper
, ModifiedHdl
) );
1069 m_pImplEdit
->SetLoseFocusHdl( LINK( &_rControlHelper
, ControlHelper
, LoseFocusHdl
) );
1073 DropDownEditControl::~DropDownEditControl()
1078 void DropDownEditControl::dispose()
1080 SetSubEdit(nullptr);
1081 m_pImplEdit
.disposeAndClear();
1082 m_pFloatingEdit
.disposeAndClear();
1083 m_pDropdownButton
.disposeAndClear();
1084 DropDownEditControl_Base::dispose();
1088 void DropDownEditControl::Resize()
1090 ::Size aOutSz
= GetOutputSizePixel();
1092 if (m_pDropdownButton
!=nullptr)
1094 long nSBWidth
= GetSettings().GetStyleSettings().GetScrollBarSize();
1095 nSBWidth
= CalcZoom( nSBWidth
);
1096 m_pImplEdit
->setPosSizePixel( 0, 1, aOutSz
.Width() - nSBWidth
, aOutSz
.Height()-2 );
1097 m_pDropdownButton
->setPosSizePixel( aOutSz
.Width() - nSBWidth
, 0, nSBWidth
, aOutSz
.Height() );
1100 m_pImplEdit
->setPosSizePixel( 0, 1, aOutSz
.Width(), aOutSz
.Height()-2 );
1104 bool DropDownEditControl::PreNotify( NotifyEvent
& rNEvt
)
1106 bool nResult
= true;
1108 if (rNEvt
.GetType() == MouseNotifyEvent::KEYINPUT
)
1110 const vcl::KeyCode
& aKeyCode
= rNEvt
.GetKeyEvent()->GetKeyCode();
1111 sal_uInt16 nKey
= aKeyCode
.GetCode();
1113 if ( nKey
== KEY_RETURN
&& !aKeyCode
.IsShift() )
1117 m_pHelper
->LoseFocusHdl( m_pImplEdit
.get() );
1118 m_pHelper
->activateNextControl();
1121 else if ( nKey
== KEY_DOWN
&& aKeyCode
.IsMod2() )
1124 ShowDropDown( true );
1126 else if ( KEYGROUP_CURSOR
== aKeyCode
.GetGroup()
1128 || KEYGROUP_FKEYS
== aKeyCode
.GetGroup()
1129 || m_nOperationMode
== eMultiLineText
1132 nResult
= DropDownEditControl_Base::PreNotify( rNEvt
);
1134 else if ( m_nOperationMode
== eStringList
)
1136 Selection aSel
= m_pImplEdit
->GetSelection();
1137 if ( aSel
.Min() != aSel
.Max() )
1139 aSel
.Min() = FindPos( aSel
.Min() );
1140 aSel
.Max() = FindPos( aSel
.Max() );
1144 aSel
.Min() = FindPos( aSel
.Min() );
1145 aSel
.Max() = aSel
.Min();
1148 ShowDropDown( true );
1149 m_pFloatingEdit
->getEdit().GrabFocus();
1150 m_pFloatingEdit
->getEdit().SetSelection( aSel
);
1151 vcl::Window
* pFocusWin
= Application::GetFocusWindow();
1152 pFocusWin
->KeyInput( *rNEvt
.GetKeyEvent() );
1156 nResult
= DropDownEditControl_Base::PreNotify(rNEvt
);
1165 StlSyntaxSequence
< OUString
> lcl_convertMultiLineToList( const OUString
& _rCompsedTextWithLineBreaks
)
1167 sal_Int32 nLines
= comphelper::string::getTokenCount(_rCompsedTextWithLineBreaks
, '\n');
1168 StlSyntaxSequence
< OUString
> aStrings( nLines
);
1169 StlSyntaxSequence
< OUString
>::iterator stringItem
= aStrings
.begin();
1170 for ( sal_Int32 token
= 0; token
< nLines
; ++token
, ++stringItem
)
1171 *stringItem
= _rCompsedTextWithLineBreaks
.getToken( token
, '\n' );
1175 OUString
lcl_convertListToMultiLine( const StlSyntaxSequence
< OUString
>& _rStrings
)
1177 OUString sMultiLineText
;
1178 for ( StlSyntaxSequence
< OUString
>::const_iterator item
= _rStrings
.begin();
1179 item
!= _rStrings
.end();
1182 sMultiLineText
+= *item
;
1183 if ( ++item
!= _rStrings
.end() )
1184 sMultiLineText
+= "\n";
1186 return sMultiLineText
;
1190 OUString
lcl_convertListToDisplayText( const StlSyntaxSequence
< OUString
>& _rStrings
)
1192 OUStringBuffer aComposed
;
1193 for ( StlSyntaxSequence
< OUString
>::const_iterator strings
= _rStrings
.begin();
1194 strings
!= _rStrings
.end();
1198 if ( strings
!= _rStrings
.begin() )
1199 aComposed
.append( ';' );
1200 aComposed
.append( '\"' );
1201 aComposed
.append( *strings
);
1202 aComposed
.append( '\"' );
1204 return aComposed
.makeStringAndClear();
1209 #define STD_HEIGHT 100
1210 bool DropDownEditControl::ShowDropDown( bool bShow
)
1214 ::Point aMePos
= GetPosPixel();
1215 aMePos
= GetParent()->OutputToScreenPixel( aMePos
);
1216 ::Size aSize
=GetSizePixel();
1217 ::Rectangle
aRect(aMePos
,aSize
);
1218 aSize
.Height() = STD_HEIGHT
;
1219 m_pFloatingEdit
->SetOutputSizePixel(aSize
);
1220 m_pFloatingEdit
->StartPopupMode( aRect
, FloatWinPopupFlags::Down
);
1222 m_pFloatingEdit
->Show();
1223 m_pFloatingEdit
->getEdit().GrabFocus();
1224 m_pFloatingEdit
->getEdit().SetSelection(Selection(m_pFloatingEdit
->getEdit().GetText().getLength()));
1226 if ( m_nOperationMode
== eMultiLineText
)
1227 m_pFloatingEdit
->getEdit().SetText( m_pImplEdit
->GetText() );
1228 m_pImplEdit
->SetText("");
1232 m_pFloatingEdit
->Hide();
1233 m_pFloatingEdit
->Invalidate();
1234 m_pFloatingEdit
->Update();
1236 // transfer the text from the floating edit to our own edit
1237 OUString
sDisplayText( m_pFloatingEdit
->getEdit().GetText() );
1238 if ( m_nOperationMode
== eStringList
)
1239 sDisplayText
= lcl_convertListToDisplayText( lcl_convertMultiLineToList( sDisplayText
) );
1241 m_pImplEdit
->SetText( sDisplayText
);
1242 GetParent()->Invalidate( INVALIDATE_CHILDREN
);
1243 m_bDropdown
= false;
1244 m_pImplEdit
->GrabFocus();
1251 long DropDownEditControl::FindPos(long nSinglePos
)
1255 OUString aStr
= m_pFloatingEdit
->getEdit().GetText();
1256 OUString aStr1
= GetText();
1258 if ((nSinglePos
== 0) || (nSinglePos
== aStr1
.getLength()))
1263 if (!aStr
.isEmpty())
1266 sal_Int32 nCount
= comphelper::string::getTokenCount(aStr
, '\n');
1268 OUString aInput
= aStr
.getToken(0,'\n' );
1270 if (!aInput
.isEmpty())
1278 if (nSinglePos
<= aOutput
.getLength())
1280 nPos
=nSinglePos
-nDiff
;
1284 for (sal_Int32 i
=1; i
<nCount
; ++i
)
1286 aInput
=aStr
.getToken((sal_uInt16
)i
, '\n');
1287 if (!aInput
.isEmpty())
1295 if (nSinglePos
<= aOutput
.getLength())
1297 nPos
=nSinglePos
-nDiff
;
1308 IMPL_LINK( DropDownEditControl
, ReturnHdl
, OMultilineFloatingEdit
*, /*pMEd*/)
1311 OUString aStr
= m_pFloatingEdit
->getEdit().GetText();
1312 OUString aStr2
= GetText();
1313 ShowDropDown(false);
1315 if (aStr
!=aStr2
|| ( m_nOperationMode
== eStringList
) )
1318 m_pHelper
->notifyModifiedValue();
1325 IMPL_LINK( DropDownEditControl
, DropDownHdl
, PushButton
*, /*pPb*/ )
1327 ShowDropDown(!m_bDropdown
);
1332 void DropDownEditControl::SetStringListValue( const StlSyntaxSequence
< OUString
>& _rStrings
)
1334 SetText( lcl_convertListToDisplayText( _rStrings
) );
1335 m_pFloatingEdit
->getEdit().SetText( lcl_convertListToMultiLine( _rStrings
) );
1339 StlSyntaxSequence
< OUString
> DropDownEditControl::GetStringListValue() const
1341 return lcl_convertMultiLineToList( m_pFloatingEdit
->getEdit().GetText() );
1345 void DropDownEditControl::SetTextValue( const OUString
& _rText
)
1347 OSL_PRECOND( m_nOperationMode
== eMultiLineText
, "DropDownEditControl::SetTextValue: illegal call!" );
1349 m_pFloatingEdit
->getEdit().SetText( _rText
);
1354 OUString
DropDownEditControl::GetTextValue() const
1356 OSL_PRECOND( m_nOperationMode
== eMultiLineText
, "DropDownEditControl::GetTextValue: illegal call!" );
1361 //= OMultilineEditControl
1364 OMultilineEditControl::OMultilineEditControl( vcl::Window
* pParent
, MultiLineOperationMode _eMode
, WinBits nWinStyle
)
1365 :OMultilineEditControl_Base( _eMode
== eMultiLineText
? PropertyControlType::MultiLineTextField
: PropertyControlType::StringListField
1367 , ( nWinStyle
| WB_DIALOGCONTROL
) & ( ~WB_READONLY
| ~WB_DROPDOWN
)
1370 getTypedControlWindow()->setOperationMode( _eMode
);
1374 void SAL_CALL
OMultilineEditControl::setValue( const Any
& _rValue
) throw (IllegalTypeException
, RuntimeException
, std::exception
)
1376 impl_checkDisposed_throw();
1378 switch ( getTypedControlWindow()->getOperationMode() )
1380 case eMultiLineText
:
1383 if ( !( _rValue
>>= sText
) && _rValue
.hasValue() )
1384 throw IllegalTypeException();
1385 getTypedControlWindow()->SetTextValue( sText
);
1390 Sequence
< OUString
> aStringLines
;
1391 if ( !( _rValue
>>= aStringLines
) && _rValue
.hasValue() )
1392 throw IllegalTypeException();
1393 getTypedControlWindow()->SetStringListValue( aStringLines
);
1400 Any SAL_CALL
OMultilineEditControl::getValue() throw (RuntimeException
, std::exception
)
1402 impl_checkDisposed_throw();
1405 switch ( getTypedControlWindow()->getOperationMode() )
1407 case eMultiLineText
:
1408 aValue
<<= getTypedControlWindow()->GetTextValue();
1411 aValue
<<= getTypedControlWindow()->GetStringListValue();
1418 Type SAL_CALL
OMultilineEditControl::getValueType() throw (RuntimeException
, std::exception
)
1420 if ( getTypedControlWindow()->getOperationMode() == eMultiLineText
)
1421 return ::cppu::UnoType
<OUString
>::get();
1422 return cppu::UnoType
<Sequence
< OUString
>>::get();
1429 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */