1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
30 #include "standardcontrol.hxx"
31 #include "pcrcommon.hxx"
32 
33 /** === begin UNO includes === **/
34 #include <com/sun/star/util/DateTime.hpp>
35 #include <com/sun/star/util/Date.hpp>
36 #include <com/sun/star/util/Time.hpp>
37 #include <com/sun/star/util/Color.hpp>
38 #include <com/sun/star/util/MeasureUnit.hpp>
39 #include <com/sun/star/inspection/PropertyControlType.hpp>
40 /** === end UNO includes === **/
41 #include <rtl/math.hxx>
42 #include <sfx2/objsh.hxx>
43 
44 //==================================================================
45 // ugly dependencies for the OColorControl
46 #ifndef _SVX_SVXIDS_HRC
47 #include <svx/svxids.hrc>
48 #endif
49 #include <svx/drawitem.hxx>
50 #include <svx/xtable.hxx>
51 //==================================================================
52 #include <vcl/floatwin.hxx>
53 #include <svtools/svmedit.hxx>
54 #include <svtools/colorcfg.hxx>
55 #include <unotools/syslocale.hxx>
56 #include <unotools/datetime.hxx>
57 #include <i18npool/mslangid.hxx>
58 #ifndef _SV_BUTTON_HXX
59 #include <vcl/button.hxx>
60 #endif
61 #include <vcl/svapp.hxx>
62 //==================================================================
63 
64 #include <memory>
65 #include <limits>
66 #include <boost/bind.hpp>
67 
68 //............................................................................
69 namespace pcr
70 {
71 //............................................................................
72 
73     using namespace ::com::sun::star;
74     using namespace ::com::sun::star::uno;
75     using namespace ::com::sun::star::awt;
76     using namespace ::com::sun::star::lang;
77     using namespace ::com::sun::star::util;
78     using namespace ::com::sun::star::beans;
79     using namespace ::com::sun::star::inspection;
80 
81 	//==================================================================
82 	//= OTimeControl
83 	//==================================================================
84 	//------------------------------------------------------------------
85 	OTimeControl::OTimeControl( Window* pParent, WinBits nWinStyle )
86         :OTimeControl_Base( PropertyControlType::TimeField, pParent, nWinStyle )
87     {
88 		getTypedControlWindow()->SetStrictFormat( sal_True );
89 		getTypedControlWindow()->SetFormat( TIMEF_SEC );
90 		getTypedControlWindow()->EnableEmptyFieldValue( sal_True );
91 	}
92 
93 	//------------------------------------------------------------------
94 	void SAL_CALL OTimeControl::setValue( const Any& _rValue ) throw (IllegalTypeException, RuntimeException)
95 	{
96         util::Time aUNOTime;
97         if ( !( _rValue >>= aUNOTime ) )
98 		{
99 			getTypedControlWindow()->SetText( String() );
100 			getTypedControlWindow()->SetEmptyTime();
101 		}
102 		else
103 		{
104             ::Time aTime( aUNOTime.Hours, aUNOTime.Minutes, aUNOTime.Seconds, aUNOTime.HundredthSeconds );
105             getTypedControlWindow()->SetTime( aTime );
106 		}
107 	}
108 
109 	//------------------------------------------------------------------
110 	Any SAL_CALL OTimeControl::getValue() throw (RuntimeException)
111 	{
112         Any aPropValue;
113 		if ( getTypedControlWindow()->GetText().Len()>0 )
114         {
115             ::Time aTime( getTypedControlWindow()->GetTime() );
116             util::Time aUNOTime( aTime.Get100Sec(), aTime.GetSec(), aTime.GetMin(), aTime.GetHour() );
117             aPropValue <<= aUNOTime;
118         }
119         return aPropValue;
120 	}
121 
122 	//------------------------------------------------------------------
123     Type SAL_CALL OTimeControl::getValueType() throw (RuntimeException)
124     {
125         return ::getCppuType( static_cast< util::Time* >( NULL ) );
126     }
127 
128 	//==================================================================
129 	//= ODateControl
130 	//==================================================================
131 	//------------------------------------------------------------------
132 	ODateControl::ODateControl( Window* pParent, WinBits nWinStyle )
133         :ODateControl_Base( PropertyControlType::DateField, pParent, nWinStyle | WB_DROPDOWN )
134 	{
135         WindowType* pControlWindow = getTypedControlWindow();
136 		pControlWindow->SetStrictFormat(sal_True);
137 
138         pControlWindow->SetMin( ::Date( 1,1,1600 ) );
139         pControlWindow->SetFirst( ::Date( 1,1,1600 ) );
140         pControlWindow->SetLast( ::Date( 1, 1, 9999 ) );
141         pControlWindow->SetMax( ::Date( 1, 1, 9999 ) );
142 
143 		pControlWindow->SetExtDateFormat( XTDATEF_SYSTEM_SHORT_YYYY );
144 		pControlWindow->EnableEmptyFieldValue( sal_True );
145 	}
146 
147 	//------------------------------------------------------------------
148 	void SAL_CALL ODateControl::setValue( const Any& _rValue ) throw (IllegalTypeException, RuntimeException)
149 	{
150         util::Date aUNODate;
151         if ( !( _rValue >>= aUNODate ) )
152 		{
153 			getTypedControlWindow()->SetText( String() );
154 			getTypedControlWindow()->SetEmptyDate();
155 		}
156 		else
157 		{
158             ::Date aDate( aUNODate.Day, aUNODate.Month, aUNODate.Year );
159             getTypedControlWindow()->SetDate( aDate );
160 		}
161 	}
162 
163 	//------------------------------------------------------------------
164 	Any SAL_CALL ODateControl::getValue() throw (RuntimeException)
165 	{
166         Any aPropValue;
167 		if ( getTypedControlWindow()->GetText().Len() > 0 )
168         {
169             ::Date aDate( getTypedControlWindow()->GetDate() );
170             util::Date aUNODate( aDate.GetDay(), aDate.GetMonth(), aDate.GetYear() );
171             aPropValue <<= aUNODate;
172         }
173         return aPropValue;
174 	}
175 
176 	//------------------------------------------------------------------
177     Type SAL_CALL ODateControl::getValueType() throw (RuntimeException)
178     {
179         return ::getCppuType( static_cast< util::Date* >( NULL ) );
180     }
181 
182 	//==================================================================
183 	//= OEditControl
184 	//==================================================================
185 	//------------------------------------------------------------------
186 	OEditControl::OEditControl(Window* _pParent, sal_Bool _bPW, WinBits _nWinStyle)
187         :OEditControl_Base( _bPW ? PropertyControlType::CharacterField : PropertyControlType::TextField, _pParent, _nWinStyle )
188 	{
189 		m_bIsPassword = _bPW;
190 
191 		if ( m_bIsPassword )
192 		   getTypedControlWindow()->SetMaxTextLen( 1 );
193 	}
194 
195 	//------------------------------------------------------------------
196 	void SAL_CALL OEditControl::setValue( const Any& _rValue ) throw (IllegalTypeException, RuntimeException)
197 	{
198         ::rtl::OUString sText;
199 		if ( m_bIsPassword )
200         {
201             sal_Int16 nValue = 0;
202             _rValue >>= nValue;
203             if ( nValue )
204             {
205 			    sal_Unicode nCharacter = nValue;
206                 sText = String( &nCharacter, 1 );
207             }
208         }
209         else
210             _rValue >>= sText;
211 
212 		getTypedControlWindow()->SetText( sText );
213 	}
214 
215 	//------------------------------------------------------------------
216 	Any SAL_CALL OEditControl::getValue() throw (RuntimeException)
217 	{
218         Any aPropValue;
219 
220         ::rtl::OUString sText( getTypedControlWindow()->GetText() );
221 		if ( m_bIsPassword )
222 		{
223 			if ( sText.getLength() )
224                 aPropValue <<= (sal_Int16)sText.getStr()[0];
225 		}
226         else
227             aPropValue <<= sText;
228 
229 		return aPropValue;
230 	}
231 
232 	//------------------------------------------------------------------
233     Type SAL_CALL OEditControl::getValueType() throw (RuntimeException)
234     {
235         return m_bIsPassword ? ::getCppuType( static_cast< sal_Int16* >( NULL ) ) : ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) );
236     }
237 
238 	//------------------------------------------------------------------
239 	void OEditControl::modified()
240 	{
241 		OEditControl_Base::modified();
242 
243 		// for pasword controls, we fire a commit for every single change
244 		if ( m_bIsPassword )
245 			m_aImplControl.notifyModifiedValue();
246 	}
247 
248 	//------------------------------------------------------------------
249 	static long ImplCalcLongValue( double nValue, sal_uInt16 nDigits )
250 	{
251 		double n = nValue;
252 		for ( sal_uInt16 d = 0; d < nDigits; ++d )
253 			n *= 10;
254 
255         if ( n > ::std::numeric_limits< long >::max() )
256             return ::std::numeric_limits< long >::max();
257 		return (long)n;
258 	}
259 
260 	//------------------------------------------------------------------
261 	static double ImplCalcDoubleValue( long nValue, sal_uInt16 nDigits )
262 	{
263 		double n = nValue;
264 		for ( sal_uInt16 d = 0; d < nDigits; ++d )
265 			n /= 10;
266 		return n;
267 	}
268 
269     //==================================================================
270 	// class ODateTimeControl
271 	//==================================================================
272 	//------------------------------------------------------------------
273 	ODateTimeControl::ODateTimeControl( Window* _pParent, WinBits _nWinStyle)
274         :ODateTimeControl_Base( PropertyControlType::DateTimeField, _pParent, _nWinStyle )
275 	{
276 		getTypedControlWindow()->EnableEmptyField( sal_True );
277 
278         // determine a default format
279         Locale aSysLocale = SvtSysLocale().GetLocaleData().getLocale();
280         LanguageType eSysLanguage = MsLangId::convertLocaleToLanguage( aSysLocale );
281 
282         getTypedControlWindow()->SetFormatter( getTypedControlWindow()->StandardFormatter() );
283         SvNumberFormatter* pFormatter = getTypedControlWindow()->GetFormatter();
284         sal_uLong nStandardDateTimeFormat = pFormatter->GetStandardFormat( NUMBERFORMAT_DATETIME, eSysLanguage );
285 
286         getTypedControlWindow()->SetFormatKey( nStandardDateTimeFormat );
287 	}
288 
289 	//------------------------------------------------------------------
290     void SAL_CALL ODateTimeControl::setValue( const Any& _rValue ) throw (IllegalTypeException, RuntimeException)
291     {
292 		if ( !_rValue.hasValue() )
293         {
294             getTypedControlWindow()->SetText( String() );
295         }
296         else
297         {
298             util::DateTime aUNODateTime;
299             OSL_VERIFY( _rValue >>= aUNODateTime );
300 
301             ::DateTime aDateTime;
302             ::utl::typeConvert( aUNODateTime, aDateTime );
303 
304             double nValue = aDateTime - ::DateTime( *getTypedControlWindow()->GetFormatter()->GetNullDate() );
305             getTypedControlWindow()->SetValue( nValue );
306         }
307     }
308 
309 	//------------------------------------------------------------------
310     Any SAL_CALL ODateTimeControl::getValue() throw (RuntimeException)
311     {
312         Any aPropValue;
313         if ( getTypedControlWindow()->GetText().Len() )
314         {
315             double nValue = getTypedControlWindow()->GetValue();
316 
317             ::DateTime aDateTime( *getTypedControlWindow()->GetFormatter()->GetNullDate() );
318 
319             // add the "days" part
320             double nDays = floor( nValue );
321             aDateTime += nDays;
322 
323             // add the "time" part
324             double nTime = nValue - nDays;
325             nTime = ::rtl::math::round( nTime * 86400.0 ) / 86400.0;
326                 // we're not interested in 100th seconds, and this here prevents rounding errors
327             aDateTime += nTime;
328 
329             util::DateTime aUNODateTime;
330             ::utl::typeConvert( aDateTime, aUNODateTime );
331 
332             aPropValue <<= aUNODateTime;
333         }
334         return aPropValue;
335     }
336 
337 	//------------------------------------------------------------------
338     Type SAL_CALL ODateTimeControl::getValueType() throw (RuntimeException)
339     {
340         return ::getCppuType( static_cast< util::DateTime* >( NULL ) );
341     }
342 
343     //========================================================================
344     //= HyperlinkInput
345     //========================================================================
346     //--------------------------------------------------------------------
347     HyperlinkInput::HyperlinkInput( Window* _pParent, WinBits _nWinStyle )
348         :Edit( _pParent, _nWinStyle )
349     {
350         ::svtools::ColorConfig aColorConfig;
351         ::svtools::ColorConfigValue aLinkColor( aColorConfig.GetColorValue( ::svtools::LINKS ) );
352 
353         AllSettings aAllSettings( GetSettings() );
354         StyleSettings aStyleSettings( aAllSettings.GetStyleSettings() );
355 
356         Font aFieldFont( aStyleSettings.GetFieldFont() );
357         aFieldFont.SetUnderline( UNDERLINE_SINGLE );
358         aFieldFont.SetColor( aLinkColor.nColor );
359         aStyleSettings.SetFieldFont( aFieldFont );
360 
361         aStyleSettings.SetFieldTextColor( aLinkColor.nColor );
362 
363         aAllSettings.SetStyleSettings( aStyleSettings );
364         SetSettings( aAllSettings );
365     }
366 
367     //--------------------------------------------------------------------
368     void HyperlinkInput::MouseMove( const ::MouseEvent& rMEvt )
369     {
370         Edit::MouseMove( rMEvt );
371 
372         PointerStyle ePointerStyle( POINTER_TEXT );
373 
374         if ( !rMEvt.IsLeaveWindow() )
375         {
376             if ( impl_textHitTest( rMEvt.GetPosPixel() ) )
377                 ePointerStyle = POINTER_REFHAND;
378         }
379 
380         SetPointer( Pointer( ePointerStyle ) );
381     }
382 
383     //--------------------------------------------------------------------
384     void HyperlinkInput::MouseButtonDown( const ::MouseEvent& rMEvt )
385     {
386         Edit::MouseButtonDown( rMEvt );
387 
388         if ( impl_textHitTest( rMEvt.GetPosPixel() ) )
389             m_aMouseButtonDownPos = rMEvt.GetPosPixel();
390         else
391             m_aMouseButtonDownPos.X() = m_aMouseButtonDownPos.Y() = -1;
392     }
393 
394     //--------------------------------------------------------------------
395     void HyperlinkInput::MouseButtonUp( const ::MouseEvent& rMEvt )
396     {
397         Edit::MouseButtonUp( rMEvt );
398 
399         impl_checkEndClick( rMEvt );
400     }
401 
402     //--------------------------------------------------------------------
403     bool HyperlinkInput::impl_textHitTest( const ::Point& _rWindowPos )
404     {
405         xub_StrLen nPos = GetCharPos( _rWindowPos );
406         return ( ( nPos != STRING_LEN ) && ( nPos < GetText().Len() ) );
407     }
408 
409     //--------------------------------------------------------------------
410     void HyperlinkInput::impl_checkEndClick( const ::MouseEvent rMEvt )
411     {
412         const MouseSettings& rMouseSettings( GetSettings().GetMouseSettings() );
413         if  (   ( abs( rMEvt.GetPosPixel().X() - m_aMouseButtonDownPos.X() ) < rMouseSettings.GetStartDragWidth() )
414             &&  ( abs( rMEvt.GetPosPixel().Y() - m_aMouseButtonDownPos.Y() ) < rMouseSettings.GetStartDragHeight() )
415             )
416             Application::PostUserEvent( m_aClickHandler );
417     }
418 
419     //--------------------------------------------------------------------
420     void HyperlinkInput::Tracking( const TrackingEvent& rTEvt )
421     {
422         Edit::Tracking( rTEvt );
423 
424         if ( rTEvt.IsTrackingEnded() )
425             impl_checkEndClick( rTEvt.GetMouseEvent() );
426     }
427 
428     //========================================================================
429     //= OHyperlinkControl
430     //========================================================================
431     //--------------------------------------------------------------------
432     OHyperlinkControl::OHyperlinkControl( Window* _pParent, WinBits _nWinStyle )
433         :OHyperlinkControl_Base( PropertyControlType::HyperlinkField, _pParent, _nWinStyle )
434         ,m_aActionListeners( m_aMutex )
435     {
436         getTypedControlWindow()->SetClickHdl( LINK( this, OHyperlinkControl, OnHyperlinkClicked ) );
437     }
438 
439     //--------------------------------------------------------------------
440     Any SAL_CALL OHyperlinkControl::getValue() throw (RuntimeException)
441     {
442         ::rtl::OUString sText = getTypedControlWindow()->GetText();
443         return makeAny( sText );
444     }
445 
446     //--------------------------------------------------------------------
447     void SAL_CALL OHyperlinkControl::setValue( const Any& _value ) throw (IllegalTypeException, RuntimeException)
448     {
449         ::rtl::OUString sText;
450         _value >>= sText;
451         getTypedControlWindow()->SetText( sText );
452     }
453 
454     //--------------------------------------------------------------------
455     Type SAL_CALL OHyperlinkControl::getValueType() throw (RuntimeException)
456     {
457         return ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) );
458     }
459 
460     //--------------------------------------------------------------------
461     void SAL_CALL OHyperlinkControl::addActionListener( const Reference< XActionListener >& listener ) throw (RuntimeException)
462     {
463         if ( listener.is() )
464             m_aActionListeners.addInterface( listener );
465     }
466 
467     //--------------------------------------------------------------------
468     void SAL_CALL OHyperlinkControl::removeActionListener( const Reference< XActionListener >& listener ) throw (RuntimeException)
469     {
470         m_aActionListeners.removeInterface( listener );
471     }
472 
473 	//------------------------------------------------------------------
474     void SAL_CALL OHyperlinkControl::disposing()
475     {
476         OHyperlinkControl_Base::disposing();
477 
478         EventObject aEvent( *this );
479         m_aActionListeners.disposeAndClear( aEvent );
480     }
481 
482 	//------------------------------------------------------------------
483     IMPL_LINK( OHyperlinkControl, OnHyperlinkClicked, void*, /*_NotInterestedIn*/ )
484     {
485         ActionEvent aEvent( *this, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "clicked" ) ) );
486         m_aActionListeners.forEach< XActionListener >(
487             boost::bind(
488                 &XActionListener::actionPerformed,
489                 _1, boost::cref(aEvent) ) );
490 
491         return 0;
492     }
493 
494     //==================================================================
495 	//= ONumericControl
496 	//==================================================================
497 	//------------------------------------------------------------------
498 	ONumericControl::ONumericControl( Window* _pParent, WinBits _nWinStyle )
499         :ONumericControl_Base( PropertyControlType::NumericField, _pParent, _nWinStyle )
500         ,m_eValueUnit( FUNIT_NONE )
501         ,m_nFieldToUNOValueFactor( 1 )
502 	{
503         getTypedControlWindow()->SetDefaultUnit( FUNIT_NONE );
504 
505 		getTypedControlWindow()->EnableEmptyFieldValue( sal_True );
506 		getTypedControlWindow()->SetStrictFormat( sal_True );
507         Optional< double > value( getMaxValue() );
508         value.Value = -value.Value;
509         setMinValue( value );
510 	}
511 
512     //--------------------------------------------------------------------
513     ::sal_Int16 SAL_CALL ONumericControl::getDecimalDigits() throw (RuntimeException)
514     {
515         return getTypedControlWindow()->GetDecimalDigits();
516     }
517 
518     //--------------------------------------------------------------------
519     void SAL_CALL ONumericControl::setDecimalDigits( ::sal_Int16 _decimaldigits ) throw (RuntimeException)
520     {
521         getTypedControlWindow()->SetDecimalDigits( _decimaldigits );
522     }
523 
524     //--------------------------------------------------------------------
525     Optional< double > SAL_CALL ONumericControl::getMinValue() throw (RuntimeException)
526     {
527         Optional< double > aReturn( sal_True, 0 );
528 
529         sal_Int64 minValue = getTypedControlWindow()->GetMin();
530         if ( minValue == ::std::numeric_limits< sal_Int64 >::min() )
531             aReturn.IsPresent = sal_False;
532         else
533             aReturn.Value = (double)minValue;
534 
535         return aReturn;
536     }
537 
538     //--------------------------------------------------------------------
539     void SAL_CALL ONumericControl::setMinValue( const Optional< double >& _minvalue ) throw (RuntimeException)
540     {
541         if ( !_minvalue.IsPresent )
542             getTypedControlWindow()->SetMin( ::std::numeric_limits< sal_Int64 >::min() );
543         else
544             getTypedControlWindow()->SetMin( impl_apiValueToFieldValue_nothrow( _minvalue.Value ) , m_eValueUnit);
545     }
546 
547     //--------------------------------------------------------------------
548     Optional< double > SAL_CALL ONumericControl::getMaxValue() throw (RuntimeException)
549     {
550         Optional< double > aReturn( sal_True, 0 );
551 
552         sal_Int64 maxValue = getTypedControlWindow()->GetMax();
553         if ( maxValue == ::std::numeric_limits< sal_Int64 >::max() )
554             aReturn.IsPresent = sal_False;
555         else
556             aReturn.Value = (double)maxValue;
557 
558         return aReturn;
559     }
560 
561     //--------------------------------------------------------------------
562     void SAL_CALL ONumericControl::setMaxValue( const Optional< double >& _maxvalue ) throw (RuntimeException)
563     {
564         if ( !_maxvalue.IsPresent )
565             getTypedControlWindow()->SetMax( ::std::numeric_limits< sal_Int64 >::max() );
566         else
567             getTypedControlWindow()->SetMax( impl_apiValueToFieldValue_nothrow( _maxvalue.Value ), m_eValueUnit );
568     }
569 
570     //--------------------------------------------------------------------
571     ::sal_Int16 SAL_CALL ONumericControl::getDisplayUnit() throw (RuntimeException)
572     {
573         return VCLUnoHelper::ConvertToMeasurementUnit( getTypedControlWindow()->GetUnit(), 1 );
574     }
575 
576     //--------------------------------------------------------------------
577     void SAL_CALL ONumericControl::setDisplayUnit( ::sal_Int16 _displayunit ) throw (IllegalArgumentException, RuntimeException)
578     {
579         if ( ( _displayunit < MeasureUnit::MM_100TH ) || ( _displayunit > MeasureUnit::PERCENT ) )
580             throw IllegalArgumentException();
581         if  (   ( _displayunit == MeasureUnit::MM_100TH )
582             ||  ( _displayunit == MeasureUnit::MM_10TH )
583             ||  ( _displayunit == MeasureUnit::INCH_1000TH )
584             ||  ( _displayunit == MeasureUnit::INCH_100TH )
585             ||  ( _displayunit == MeasureUnit::INCH_10TH )
586             ||  ( _displayunit == MeasureUnit::PERCENT )
587             )
588             throw IllegalArgumentException();
589 
590         sal_Int16 nDummyFactor = 1;
591         FieldUnit eFieldUnit = VCLUnoHelper::ConvertToFieldUnit( _displayunit, nDummyFactor );
592         if ( nDummyFactor != 1 )
593             // everything which survived the checks above should result in a factor of 1, i.e.,
594             // it should have a direct counterpart as FieldUnit
595             throw RuntimeException();
596         getTypedControlWindow()->SetUnit( eFieldUnit );
597     }
598 
599     //--------------------------------------------------------------------
600     ::sal_Int16 SAL_CALL ONumericControl::getValueUnit() throw (RuntimeException)
601     {
602         return VCLUnoHelper::ConvertToMeasurementUnit( m_eValueUnit, m_nFieldToUNOValueFactor );
603     }
604 
605     //--------------------------------------------------------------------
606     void SAL_CALL ONumericControl::setValueUnit( ::sal_Int16 _valueunit ) throw (RuntimeException)
607     {
608         if ( ( _valueunit < MeasureUnit::MM_100TH ) || ( _valueunit > MeasureUnit::PERCENT ) )
609             throw IllegalArgumentException();
610         m_eValueUnit = VCLUnoHelper::ConvertToFieldUnit( _valueunit, m_nFieldToUNOValueFactor );
611     }
612 
613     //--------------------------------------------------------------------
614     void SAL_CALL ONumericControl::setValue( const Any& _rValue ) throw (IllegalTypeException, RuntimeException)
615 	{
616 		if ( !_rValue.hasValue() )
617 		{
618 			getTypedControlWindow()->SetText( String() );
619 			getTypedControlWindow()->SetEmptyFieldValue();
620 		}
621 		else
622 		{
623             double nValue( 0 );
624             OSL_VERIFY( _rValue >>= nValue );
625             long nControlValue = impl_apiValueToFieldValue_nothrow( nValue );
626             getTypedControlWindow()->SetValue( nControlValue, m_eValueUnit );
627 		}
628 	}
629 
630 	//------------------------------------------------------------------
631     long ONumericControl::impl_apiValueToFieldValue_nothrow( double _nApiValue ) const
632     {
633         long nControlValue = ImplCalcLongValue( _nApiValue, getTypedControlWindow()->GetDecimalDigits() );
634         nControlValue /= m_nFieldToUNOValueFactor;
635         return nControlValue;
636     }
637 
638 	//------------------------------------------------------------------
639     double ONumericControl::impl_fieldValueToApiValue_nothrow( sal_Int64 _nFieldValue ) const
640     {
641 		double nApiValue = ImplCalcDoubleValue( (long)_nFieldValue, getTypedControlWindow()->GetDecimalDigits() );
642         nApiValue *= m_nFieldToUNOValueFactor;
643         return nApiValue;
644     }
645 
646 	//------------------------------------------------------------------
647 	Any SAL_CALL ONumericControl::getValue() throw (RuntimeException)
648 	{
649         Any aPropValue;
650 		if ( getTypedControlWindow()->GetText().Len() )
651         {
652             double nValue = impl_fieldValueToApiValue_nothrow( getTypedControlWindow()->GetValue( m_eValueUnit ) );
653             aPropValue <<= nValue;
654         }
655         return aPropValue;
656 	}
657 
658 	//------------------------------------------------------------------
659     Type SAL_CALL ONumericControl::getValueType() throw (RuntimeException)
660     {
661         return ::getCppuType( static_cast< double* >( NULL ) );
662     }
663 
664 	//==================================================================
665 	//= OColorControl
666 	//==================================================================
667 	#define LB_DEFAULT_COUNT 20
668 	//------------------------------------------------------------------
669 	String MakeHexStr(sal_uInt32 nVal, sal_uInt32 nLength)
670 	{
671 		String aStr;
672 		while (nVal>0)
673 		{
674 			char c=char(nVal & 0x000F);
675 			nVal>>=4;
676 			if (c<=9) c+='0';
677 			else c+='A'-10;
678 			aStr.Insert(c,0);
679 		}
680 		while (aStr.Len() < nLength) aStr.Insert('0',0);
681 		return aStr;
682 	}
683 
684 	//------------------------------------------------------------------
685 	OColorControl::OColorControl(Window* pParent, WinBits nWinStyle)
686         :OColorControl_Base( PropertyControlType::ColorListBox, pParent, nWinStyle )
687 	{
688 		// initialize the color listbox
689         XColorTable* pColorTable = NULL;
690         SfxObjectShell* pDocSh = SfxObjectShell::Current();
691         const SfxPoolItem* pItem = pDocSh ? pDocSh->GetItem( SID_COLOR_TABLE ) : NULL;
692         if ( pItem )
693         {
694             DBG_ASSERT(pItem->ISA(SvxColorTableItem), "OColorControl::OColorControl: invalid color item!");
695 		    pColorTable = ( (SvxColorTableItem*)pItem )->GetColorTable();
696         }
697 
698         if ( !pColorTable )
699 	    {
700 		    pColorTable = XColorTable::GetStdColorTable();
701 	    }
702 
703 
704 		DBG_ASSERT(pColorTable, "OColorControl::OColorControl: no color table!");
705 
706 		if (pColorTable)
707 		{
708 			for (sal_uInt16 i = 0; i < pColorTable->Count(); ++i)
709 			{
710 				XColorEntry* pEntry = pColorTable->GetColor( i );
711 				getTypedControlWindow()->InsertEntry( pEntry->GetColor(), pEntry->GetName() );
712 			}
713 		}
714 
715 		getTypedControlWindow()->SetDropDownLineCount( LB_DEFAULT_COUNT );
716         if ( ( nWinStyle & WB_READONLY ) != 0 )
717         {
718             getTypedControlWindow()->SetReadOnly( sal_True );
719             getTypedControlWindow()->Enable( sal_True );
720         }
721 	}
722 
723 	//------------------------------------------------------------------
724 	void SAL_CALL OColorControl::setValue( const Any& _rValue ) throw (IllegalTypeException, RuntimeException)
725 	{
726 		if ( _rValue.hasValue() )
727         {
728             ::com::sun::star::util::Color nColor = COL_TRANSPARENT;
729             if ( _rValue >>= nColor )
730             {
731                 ::Color aRgbCol((ColorData)nColor);
732 
733 				getTypedControlWindow()->SelectEntry( aRgbCol );
734 				if ( !getTypedControlWindow()->IsEntrySelected( aRgbCol ) )
735 				{	// the given color is not part of the list -> insert a new entry with the hex code of the color
736 					String aStr = String::CreateFromAscii("0x");
737 					aStr += MakeHexStr(nColor,8);
738 					getTypedControlWindow()->InsertEntry( aRgbCol, aStr );
739 					getTypedControlWindow()->SelectEntry( aRgbCol );
740 				}
741             }
742             else
743             {
744                 ::rtl::OUString sNonColorValue;
745                 if ( !( _rValue >>= sNonColorValue ) )
746                     throw IllegalTypeException();
747                 getTypedControlWindow()->SelectEntry( sNonColorValue );
748                 if ( !getTypedControlWindow()->IsEntrySelected( sNonColorValue ) )
749                     getTypedControlWindow()->SetNoSelection();
750             }
751 		}
752 		else
753 			getTypedControlWindow()->SetNoSelection();
754 	}
755 
756 	//------------------------------------------------------------------
757 	Any SAL_CALL OColorControl::getValue() throw (RuntimeException)
758 	{
759         Any aPropValue;
760 		if ( getTypedControlWindow()->GetSelectEntryCount() > 0 )
761 		{
762             ::rtl::OUString sSelectedEntry = getTypedControlWindow()->GetSelectEntry();
763             if ( m_aNonColorEntries.find( sSelectedEntry ) != m_aNonColorEntries.end() )
764                 aPropValue <<= sSelectedEntry;
765             else
766 			{
767                 ::Color aRgbCol = getTypedControlWindow()->GetSelectEntryColor();
768                 aPropValue <<= (::com::sun::star::util::Color)aRgbCol.GetColor();
769 			}
770 		}
771 		return aPropValue;
772 	}
773 
774 	//------------------------------------------------------------------
775     Type SAL_CALL OColorControl::getValueType() throw (RuntimeException)
776     {
777         return ::getCppuType( static_cast< sal_Int32* >( NULL ) );
778     }
779 
780 	//------------------------------------------------------------------
781 	void SAL_CALL OColorControl::clearList() throw (RuntimeException)
782 	{
783 		getTypedControlWindow()->Clear();
784 	}
785 
786 	//------------------------------------------------------------------
787 	void SAL_CALL OColorControl::prependListEntry( const ::rtl::OUString& NewEntry ) throw (RuntimeException)
788 	{
789 		getTypedControlWindow()->InsertEntry( NewEntry, 0 );
790         m_aNonColorEntries.insert( NewEntry );
791 	}
792 
793 	//------------------------------------------------------------------
794 	void SAL_CALL OColorControl::appendListEntry( const ::rtl::OUString& NewEntry ) throw (RuntimeException)
795 	{
796 		getTypedControlWindow()->InsertEntry( NewEntry );
797         m_aNonColorEntries.insert( NewEntry );
798 	}
799     //------------------------------------------------------------------
800     Sequence< ::rtl::OUString > SAL_CALL OColorControl::getListEntries(  ) throw (RuntimeException)
801     {
802         if ( !m_aNonColorEntries.empty() )
803             return Sequence< ::rtl::OUString >(&(*m_aNonColorEntries.begin()),m_aNonColorEntries.size());
804         return Sequence< ::rtl::OUString >();
805     }
806 
807 	//------------------------------------------------------------------
808 	void OColorControl::modified()
809 	{
810 		OColorControl_Base::modified();
811 
812 		if ( !getTypedControlWindow()->IsTravelSelect() )
813 			// fire a commit
814 			m_aImplControl.notifyModifiedValue();
815 	}
816 
817 	//==================================================================
818 	//= OListboxControl
819 	//==================================================================
820 	//------------------------------------------------------------------
821 	OListboxControl::OListboxControl( Window* pParent, WinBits nWinStyle)
822         :OListboxControl_Base( PropertyControlType::ListBox, pParent, nWinStyle )
823 	{
824 		getTypedControlWindow()->SetDropDownLineCount( LB_DEFAULT_COUNT );
825         if ( ( nWinStyle & WB_READONLY ) != 0 )
826         {
827             getTypedControlWindow()->SetReadOnly( sal_True );
828             getTypedControlWindow()->Enable( sal_True );
829         }
830 	}
831 
832 	//------------------------------------------------------------------
833 	Any SAL_CALL OListboxControl::getValue() throw (RuntimeException)
834 	{
835         ::rtl::OUString sControlValue( getTypedControlWindow()->GetSelectEntry() );
836 
837         Any aPropValue;
838         if ( sControlValue.getLength() )
839             aPropValue <<= sControlValue;
840 		return aPropValue;
841 	}
842 
843 	//------------------------------------------------------------------
844     Type SAL_CALL OListboxControl::getValueType() throw (RuntimeException)
845     {
846         return ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) );
847     }
848 
849 	//------------------------------------------------------------------
850 	void SAL_CALL OListboxControl::setValue( const Any& _rValue ) throw (IllegalTypeException, RuntimeException)
851 	{
852 		if ( !_rValue.hasValue() )
853             getTypedControlWindow()->SetNoSelection();
854         else
855 		{
856             ::rtl::OUString sSelection;
857             _rValue >>= sSelection;
858 
859             if ( !sSelection.equals( getTypedControlWindow()->GetSelectEntry() ) )
860 				getTypedControlWindow()->SelectEntry( sSelection );
861 
862 			if ( !getTypedControlWindow()->IsEntrySelected( sSelection ) )
863 			{
864 				getTypedControlWindow()->InsertEntry( sSelection, 0 );
865 				getTypedControlWindow()->SelectEntry( sSelection );
866 			}
867 		}
868 	}
869 
870 	//------------------------------------------------------------------
871 	void SAL_CALL OListboxControl::clearList() throw (RuntimeException)
872 	{
873 		getTypedControlWindow()->Clear();
874 	}
875 
876 	//------------------------------------------------------------------
877 	void SAL_CALL OListboxControl::prependListEntry( const ::rtl::OUString& NewEntry ) throw (RuntimeException)
878 	{
879 		getTypedControlWindow()->InsertEntry( NewEntry, 0 );
880 	}
881 
882 	//------------------------------------------------------------------
883 	void SAL_CALL OListboxControl::appendListEntry( const ::rtl::OUString& NewEntry ) throw (RuntimeException)
884 	{
885 		getTypedControlWindow()->InsertEntry( NewEntry );
886 	}
887     //------------------------------------------------------------------
888     Sequence< ::rtl::OUString > SAL_CALL OListboxControl::getListEntries(  ) throw (RuntimeException)
889     {
890         const sal_uInt16 nCount = getTypedControlWindow()->GetEntryCount();
891         Sequence< ::rtl::OUString > aRet(nCount);
892         ::rtl::OUString* pIter = aRet.getArray();
893         for (sal_uInt16 i = 0; i < nCount ; ++i,++pIter)
894             *pIter = getTypedControlWindow()->GetEntry(i);
895 
896         return aRet;
897     }
898 
899 	//------------------------------------------------------------------
900 	void OListboxControl::modified()
901 	{
902 		OListboxControl_Base::modified();
903 
904 		if ( !getTypedControlWindow()->IsTravelSelect() )
905 			// fire a commit
906 			m_aImplControl.notifyModifiedValue();
907 	}
908 
909 	//==================================================================
910 	//= OComboboxControl
911 	//==================================================================
912 	//------------------------------------------------------------------
913 	OComboboxControl::OComboboxControl( Window* pParent, WinBits nWinStyle)
914         :OComboboxControl_Base( PropertyControlType::ComboBox, pParent, nWinStyle )
915     {
916 		getTypedControlWindow()->SetDropDownLineCount( LB_DEFAULT_COUNT );
917         getTypedControlWindow()->SetSelectHdl( LINK( this, OComboboxControl, OnEntrySelected ) );
918 	}
919 
920 	//------------------------------------------------------------------
921 	void SAL_CALL OComboboxControl::setValue( const Any& _rValue ) throw (IllegalTypeException, RuntimeException)
922 	{
923 		::rtl::OUString sText;
924         _rValue >>= sText;
925 		getTypedControlWindow()->SetText( sText );
926 	}
927 
928 	//------------------------------------------------------------------
929 	Any SAL_CALL OComboboxControl::getValue() throw (RuntimeException)
930 	{
931         return makeAny( ::rtl::OUString( getTypedControlWindow()->GetText() ) );
932 	}
933 
934 	//------------------------------------------------------------------
935     Type SAL_CALL OComboboxControl::getValueType() throw (RuntimeException)
936     {
937         return ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) );
938     }
939 
940 	//------------------------------------------------------------------
941 	void SAL_CALL OComboboxControl::clearList() throw (RuntimeException)
942 	{
943 		getTypedControlWindow()->Clear();
944 	}
945 
946 	//------------------------------------------------------------------
947 	void SAL_CALL OComboboxControl::prependListEntry( const ::rtl::OUString& NewEntry ) throw (RuntimeException)
948 	{
949 		getTypedControlWindow()->InsertEntry( NewEntry, 0 );
950 	}
951 
952 	//------------------------------------------------------------------
953 	void SAL_CALL OComboboxControl::appendListEntry( const ::rtl::OUString& NewEntry ) throw (RuntimeException)
954 	{
955 		getTypedControlWindow()->InsertEntry( NewEntry );
956 	}
957     //------------------------------------------------------------------
958     Sequence< ::rtl::OUString > SAL_CALL OComboboxControl::getListEntries(  ) throw (RuntimeException)
959     {
960         const sal_uInt16 nCount = getTypedControlWindow()->GetEntryCount();
961         Sequence< ::rtl::OUString > aRet(nCount);
962         ::rtl::OUString* pIter = aRet.getArray();
963         for (sal_uInt16 i = 0; i < nCount ; ++i,++pIter)
964             *pIter = getTypedControlWindow()->GetEntry(i);
965 
966         return aRet;
967     }
968 
969 	//------------------------------------------------------------------
970     IMPL_LINK( OComboboxControl, OnEntrySelected, void*, /*_pNothing*/ )
971 	{
972 		if ( !getTypedControlWindow()->IsTravelSelect() )
973 			// fire a commit
974 			m_aImplControl.notifyModifiedValue();
975         return 0L;
976 	}
977 
978 	//==================================================================
979 	//= OMultilineFloatingEdit
980 	//==================================================================
981 	class OMultilineFloatingEdit : public FloatingWindow
982 	{
983 	private:
984 		MultiLineEdit	m_aImplEdit;
985 
986 	protected:
987 		virtual void	Resize();
988 
989 	public:
990 						OMultilineFloatingEdit(Window* _pParen);
991 		MultiLineEdit*  getEdit() { return &m_aImplEdit; }
992 
993 	protected:
994 		virtual long	PreNotify(NotifyEvent& _rNEvt);
995 	};
996 
997 	//------------------------------------------------------------------
998 	OMultilineFloatingEdit::OMultilineFloatingEdit(Window* _pParent)
999 		:FloatingWindow(_pParent, WB_BORDER)
1000 		,m_aImplEdit(this, WB_VSCROLL|WB_IGNORETAB|WB_NOBORDER)
1001 	{
1002 		m_aImplEdit.Show();
1003 	}
1004 
1005 	//------------------------------------------------------------------
1006 	void OMultilineFloatingEdit::Resize()
1007 	{
1008 		m_aImplEdit.SetSizePixel(GetOutputSizePixel());
1009 	}
1010 
1011 	//------------------------------------------------------------------
1012 	long OMultilineFloatingEdit::PreNotify(NotifyEvent& _rNEvt)
1013 	{
1014 		long nResult = sal_True;
1015 
1016 		sal_uInt16 nSwitch = _rNEvt.GetType();
1017 		if (EVENT_KEYINPUT == nSwitch)
1018 		{
1019 			const KeyCode& aKeyCode = _rNEvt.GetKeyEvent()->GetKeyCode();
1020 			sal_uInt16 nKey = aKeyCode.GetCode();
1021 
1022 			if	(	(	(KEY_RETURN == nKey)
1023 					&& !aKeyCode.IsShift()
1024 					)
1025 				||	(	(KEY_UP == nKey)
1026 					&&	aKeyCode.IsMod2()
1027 					)
1028 				)
1029 			{
1030 				EndPopupMode();
1031 			}
1032 			else
1033 				nResult=FloatingWindow::PreNotify(_rNEvt);
1034 		}
1035 		else
1036 			nResult=FloatingWindow::PreNotify(_rNEvt);
1037 
1038 		return nResult;
1039 	}
1040 
1041 	//==================================================================
1042 	//= DropDownEditControl_Base
1043 	//==================================================================
1044 	//------------------------------------------------------------------
1045     DropDownEditControl::DropDownEditControl( Window* _pParent, WinBits _nStyle )
1046         :DropDownEditControl_Base( _pParent, _nStyle )
1047 		,m_pFloatingEdit( NULL )
1048 		,m_pImplEdit( NULL )
1049 		,m_pDropdownButton( NULL )
1050         ,m_nOperationMode( eStringList )
1051 		,m_bDropdown( sal_False )
1052     {
1053         SetCompoundControl( sal_True );
1054 
1055 		m_pImplEdit = new MultiLineEdit( this, WB_TABSTOP | WB_IGNORETAB | WB_NOBORDER | (_nStyle & WB_READONLY) );
1056         SetSubEdit( m_pImplEdit );
1057 		m_pImplEdit->Show();
1058 
1059 		if ( _nStyle & WB_DROPDOWN )
1060 		{
1061 			m_pDropdownButton = new PushButton( this, WB_NOLIGHTBORDER | WB_RECTSTYLE | WB_NOTABSTOP);
1062 			m_pDropdownButton->SetSymbol(SYMBOL_SPIN_DOWN);
1063 			m_pDropdownButton->SetClickHdl( LINK( this, DropDownEditControl, DropDownHdl ) );
1064 			m_pDropdownButton->Show();
1065 		}
1066 
1067 		m_pFloatingEdit = new OMultilineFloatingEdit(this); //FloatingWindow
1068 
1069 		m_pFloatingEdit->SetPopupModeEndHdl( LINK( this, DropDownEditControl, ReturnHdl ) );
1070         m_pFloatingEdit->getEdit()->SetReadOnly( ( _nStyle & WB_READONLY ) != 0 );
1071     }
1072 
1073 	//------------------------------------------------------------------
1074     void DropDownEditControl::setControlHelper( ControlHelper& _rControlHelper )
1075     {
1076         DropDownEditControl_Base::setControlHelper( _rControlHelper );
1077 		m_pFloatingEdit->getEdit()->SetModifyHdl( LINK( &_rControlHelper, ControlHelper, ModifiedHdl ) );
1078 		m_pImplEdit->SetGetFocusHdl( LINK( &_rControlHelper, ControlHelper, GetFocusHdl ) );
1079 		m_pImplEdit->SetModifyHdl( LINK( &_rControlHelper, ControlHelper, ModifiedHdl ) );
1080 		m_pImplEdit->SetLoseFocusHdl( LINK( &_rControlHelper, ControlHelper, LoseFocusHdl ) );
1081     }
1082 
1083 	//------------------------------------------------------------------
1084 	DropDownEditControl::~DropDownEditControl()
1085 	{
1086 		{
1087 			::std::auto_ptr<Window> aTemp(m_pFloatingEdit);
1088 			m_pFloatingEdit = NULL;
1089 		}
1090 		{
1091 			::std::auto_ptr<Window> aTemp(m_pImplEdit);
1092             SetSubEdit( NULL );
1093 			m_pImplEdit = NULL;
1094 		}
1095 		{
1096 			::std::auto_ptr<Window> aTemp(m_pDropdownButton);
1097 			m_pDropdownButton = NULL;
1098 		}
1099 	}
1100 
1101 	//------------------------------------------------------------------
1102 	void DropDownEditControl::Resize()
1103 	{
1104         ::Size aOutSz = GetOutputSizePixel();
1105 
1106 		if (m_pDropdownButton!=NULL)
1107 		{
1108 			long nSBWidth = GetSettings().GetStyleSettings().GetScrollBarSize();
1109 			nSBWidth = CalcZoom( nSBWidth );
1110 			m_pImplEdit->SetPosSizePixel( 0, 1, aOutSz.Width() - nSBWidth, aOutSz.Height()-2 );
1111 			m_pDropdownButton->SetPosSizePixel( aOutSz.Width() - nSBWidth, 0, nSBWidth, aOutSz.Height() );
1112 		}
1113 		else
1114 			m_pImplEdit->SetPosSizePixel( 0, 1, aOutSz.Width(), aOutSz.Height()-2 );
1115 	}
1116 
1117 	//------------------------------------------------------------------
1118 	long DropDownEditControl::PreNotify( NotifyEvent& rNEvt )
1119 	{
1120 		long nResult = 1;
1121 
1122 		if (rNEvt.GetType() == EVENT_KEYINPUT)
1123 		{
1124 			const KeyCode& aKeyCode = rNEvt.GetKeyEvent()->GetKeyCode();
1125 			sal_uInt16 nKey = aKeyCode.GetCode();
1126 
1127 			if ( nKey == KEY_RETURN && !aKeyCode.IsShift() )
1128 			{
1129                 if ( m_pHelper )
1130                 {
1131 				    m_pHelper->LoseFocusHdl( m_pImplEdit );
1132                     m_pHelper->activateNextControl();
1133                 }
1134 			}
1135 			else if ( nKey == KEY_DOWN && aKeyCode.IsMod2() )
1136 			{
1137 				Invalidate();
1138 				ShowDropDown( sal_True );
1139 			}
1140 			else if (   KEYGROUP_CURSOR == aKeyCode.GetGroup()
1141                     ||  nKey == KEY_HELP
1142                     ||  KEYGROUP_FKEYS == aKeyCode.GetGroup()
1143                     ||  m_nOperationMode == eMultiLineText
1144                     )
1145 			{
1146                 nResult = DropDownEditControl_Base::PreNotify( rNEvt );
1147 			}
1148 			else if ( m_nOperationMode == eStringList )
1149 			{
1150 				Selection aSel = m_pImplEdit->GetSelection();
1151 				if ( aSel.Min() != aSel.Max() )
1152 				{
1153 					aSel.Min() = FindPos( aSel.Min() );
1154 					aSel.Max() = FindPos( aSel.Max() );
1155 				}
1156 				else
1157 				{
1158 					aSel.Min() = FindPos( aSel.Min() );
1159 					aSel.Max() = aSel.Min();
1160 				}
1161 				Invalidate();
1162 				ShowDropDown( sal_True );
1163 				m_pFloatingEdit->getEdit()->GrabFocus();
1164 				m_pFloatingEdit->getEdit()->SetSelection( aSel );
1165 				Window*	pFocusWin = Application::GetFocusWindow();
1166 				pFocusWin->KeyInput( *rNEvt.GetKeyEvent() );
1167 			}
1168 		}
1169 		else
1170 			nResult = DropDownEditControl_Base::PreNotify(rNEvt);
1171 
1172 		return nResult;
1173 	}
1174 
1175 	//------------------------------------------------------------------
1176     namespace
1177     {
1178 	    //..............................................................
1179         StlSyntaxSequence< ::rtl::OUString > lcl_convertMultiLineToList( const String& _rCompsedTextWithLineBreaks )
1180         {
1181             xub_StrLen nLines( _rCompsedTextWithLineBreaks.GetTokenCount( '\n' ) );
1182             StlSyntaxSequence< ::rtl::OUString > aStrings( nLines );
1183             StlSyntaxSequence< ::rtl::OUString >::iterator stringItem = aStrings.begin();
1184             for ( xub_StrLen token = 0; token < nLines; ++token, ++stringItem )
1185                 *stringItem = _rCompsedTextWithLineBreaks.GetToken( token, '\n' );
1186             return aStrings;
1187         }
1188 
1189         String lcl_convertListToMultiLine( const StlSyntaxSequence< ::rtl::OUString >& _rStrings )
1190         {
1191             String sMultiLineText;
1192             for (   StlSyntaxSequence< ::rtl::OUString >::const_iterator item = _rStrings.begin();
1193                     item != _rStrings.end();
1194                 )
1195             {
1196                 sMultiLineText += String( *item );
1197                 if ( ++item != _rStrings.end() )
1198                     sMultiLineText += '\n';
1199             }
1200             return sMultiLineText;
1201         }
1202 
1203         //..............................................................
1204         String lcl_convertListToDisplayText( const StlSyntaxSequence< ::rtl::OUString >& _rStrings )
1205         {
1206             ::rtl::OUStringBuffer aComposed;
1207             for (   StlSyntaxSequence< ::rtl::OUString >::const_iterator strings = _rStrings.begin();
1208                     strings != _rStrings.end();
1209                     ++strings
1210                 )
1211             {
1212                 if ( strings != _rStrings.begin() )
1213                     aComposed.append( (sal_Unicode)';' );
1214                 aComposed.append( (sal_Unicode)'\"' );
1215                 aComposed.append( *strings );
1216                 aComposed.append( (sal_Unicode)'\"' );
1217             }
1218             return aComposed.makeStringAndClear();
1219         }
1220     }
1221 
1222 	//------------------------------------------------------------------
1223 	#define STD_HEIGHT	100
1224 	sal_Bool DropDownEditControl::ShowDropDown( sal_Bool bShow )
1225 	{
1226 		if (bShow)
1227 		{
1228             ::Point aMePos= GetPosPixel();
1229 			aMePos = GetParent()->OutputToScreenPixel( aMePos );
1230             ::Size aSize=GetSizePixel();
1231             ::Rectangle aRect(aMePos,aSize);
1232 			aSize.Height() = STD_HEIGHT;
1233 			m_pFloatingEdit->SetOutputSizePixel(aSize);
1234 			m_pFloatingEdit->StartPopupMode( aRect, FLOATWIN_POPUPMODE_DOWN );
1235 
1236 			m_pFloatingEdit->Show();
1237 			m_pFloatingEdit->getEdit()->GrabFocus();
1238 			m_pFloatingEdit->getEdit()->SetSelection(Selection(m_pFloatingEdit->getEdit()->GetText().Len()));
1239 			m_bDropdown=sal_True;
1240 			if ( m_nOperationMode == eMultiLineText )
1241 				m_pFloatingEdit->getEdit()->SetText( m_pImplEdit->GetText() );
1242 			m_pImplEdit->SetText(String());
1243 		}
1244 		else
1245 		{
1246 			m_pFloatingEdit->Hide();
1247 			m_pFloatingEdit->Invalidate();
1248 			m_pFloatingEdit->Update();
1249 
1250             // transfer the text from the floating edit to our own edit
1251 			String sDisplayText( m_pFloatingEdit->getEdit()->GetText() );
1252             if ( m_nOperationMode == eStringList )
1253                 sDisplayText = lcl_convertListToDisplayText( lcl_convertMultiLineToList( sDisplayText ) );
1254 
1255 			m_pImplEdit->SetText( sDisplayText );
1256 			GetParent()->Invalidate( INVALIDATE_CHILDREN );
1257 			m_bDropdown = sal_False;
1258 			m_pImplEdit->GrabFocus();
1259 		}
1260 		return m_bDropdown;
1261 
1262 	}
1263 
1264 	//------------------------------------------------------------------
1265 	long DropDownEditControl::FindPos(long nSinglePos)
1266 	{
1267 		long nPos=0;
1268 		long nDiff=0;
1269 		String aOutput;
1270 		String aStr=m_pFloatingEdit->getEdit()->GetText();
1271 		String aStr1 = GetText();
1272 
1273 		if ((nSinglePos == 0) || (nSinglePos == aStr1.Len()))
1274 		{
1275 			return nSinglePos;
1276 		}
1277 
1278 		if (aStr.Len()>0)
1279 		{
1280 			sal_Int32 nCount = aStr.GetTokenCount('\n');
1281 
1282 			String aInput = aStr.GetToken(0,'\n' );
1283 
1284 			if (aInput.Len()>0)
1285 			{
1286 				aOutput+='\"';
1287 				nDiff++;
1288 				aOutput+=aInput;
1289 				aOutput+='\"';
1290 			}
1291 
1292 			if (nSinglePos <= aOutput.Len())
1293 			{
1294 				nPos=nSinglePos-nDiff;
1295 			}
1296 			else
1297 			{
1298 				for (sal_Int32 i=1; i<nCount; ++i)
1299 				{
1300 					aInput=aStr.GetToken((sal_uInt16)i, '\n');
1301 					if (aInput.Len()>0)
1302 					{
1303 						aOutput += ';';
1304 						aOutput += '\"';
1305 						nDiff += 2;
1306 						aOutput += aInput;
1307 						aOutput += '\"';
1308 
1309 						if (nSinglePos <= aOutput.Len())
1310 						{
1311 							nPos=nSinglePos-nDiff;
1312 							break;
1313 						}
1314 					}
1315 				}
1316 			}
1317 		}
1318 		return nPos;
1319 	}
1320 
1321 	//------------------------------------------------------------------
1322 	IMPL_LINK( DropDownEditControl, ReturnHdl, OMultilineFloatingEdit*, /*pMEd*/)
1323 	{
1324 
1325 		String aStr = m_pFloatingEdit->getEdit()->GetText();
1326 		String aStr2 = GetText();
1327 		ShowDropDown(sal_False);
1328 
1329 		if (aStr!=aStr2 || ( m_nOperationMode == eStringList ) )
1330 		{
1331 			if ( m_pHelper )
1332 			    m_pHelper->notifyModifiedValue();
1333 		}
1334 
1335 		return 0;
1336 	}
1337 
1338 	//------------------------------------------------------------------
1339 	IMPL_LINK( DropDownEditControl, DropDownHdl, PushButton*, /*pPb*/ )
1340 	{
1341 		ShowDropDown(!m_bDropdown);
1342 		return 0;
1343 	}
1344 
1345 	//------------------------------------------------------------------
1346     void DropDownEditControl::SetStringListValue( const StlSyntaxSequence< ::rtl::OUString >& _rStrings )
1347     {
1348 		SetText( lcl_convertListToDisplayText( _rStrings ) );
1349         m_pFloatingEdit->getEdit()->SetText( lcl_convertListToMultiLine( _rStrings ) );
1350     }
1351 
1352 	//------------------------------------------------------------------
1353     StlSyntaxSequence< ::rtl::OUString > DropDownEditControl::GetStringListValue() const
1354     {
1355         return lcl_convertMultiLineToList( m_pFloatingEdit->getEdit()->GetText() );
1356     }
1357 
1358 	//------------------------------------------------------------------
1359     void DropDownEditControl::SetTextValue( const ::rtl::OUString& _rText )
1360     {
1361         OSL_PRECOND( m_nOperationMode == eMultiLineText, "DropDownEditControl::SetTextValue: illegal call!" );
1362 
1363         m_pFloatingEdit->getEdit()->SetText( _rText );
1364 		SetText( _rText );
1365     }
1366 
1367 	//------------------------------------------------------------------
1368     ::rtl::OUString DropDownEditControl::GetTextValue() const
1369     {
1370         OSL_PRECOND( m_nOperationMode == eMultiLineText, "DropDownEditControl::GetTextValue: illegal call!" );
1371         return GetText();
1372     }
1373 
1374     //==================================================================
1375 	//= OMultilineEditControl
1376 	//==================================================================
1377 	//------------------------------------------------------------------
1378 	OMultilineEditControl::OMultilineEditControl( Window* pParent, MultiLineOperationMode _eMode, WinBits nWinStyle )
1379         :OMultilineEditControl_Base( _eMode == eMultiLineText ? PropertyControlType::MultiLineTextField : PropertyControlType::StringListField
1380                                    , pParent
1381                                    , ( nWinStyle | WB_DIALOGCONTROL ) & ( ~WB_READONLY | ~WB_DROPDOWN )
1382                                    , false )
1383 	{
1384         getTypedControlWindow()->setOperationMode( _eMode );
1385 	}
1386 
1387 	//------------------------------------------------------------------
1388 	void SAL_CALL OMultilineEditControl::setValue( const Any& _rValue ) throw (IllegalTypeException, RuntimeException)
1389 	{
1390         impl_checkDisposed_throw();
1391 
1392         switch ( getTypedControlWindow()->getOperationMode() )
1393         {
1394         case eMultiLineText:
1395         {
1396             ::rtl::OUString sText;
1397             if ( !( _rValue >>= sText ) && _rValue.hasValue() )
1398                 throw IllegalTypeException();
1399             getTypedControlWindow()->SetTextValue( sText );
1400         }
1401         break;
1402         case eStringList:
1403         {
1404             Sequence< ::rtl::OUString > aStringLines;
1405             if ( !( _rValue >>= aStringLines ) && _rValue.hasValue() )
1406                 throw IllegalTypeException();
1407             getTypedControlWindow()->SetStringListValue( aStringLines );
1408         }
1409         break;
1410         }
1411 	}
1412 
1413 	//------------------------------------------------------------------
1414 	Any SAL_CALL OMultilineEditControl::getValue() throw (RuntimeException)
1415 	{
1416         impl_checkDisposed_throw();
1417 
1418         Any aValue;
1419         switch ( getTypedControlWindow()->getOperationMode() )
1420         {
1421         case eMultiLineText:
1422             aValue <<= getTypedControlWindow()->GetTextValue();
1423             break;
1424         case eStringList:
1425             aValue <<= getTypedControlWindow()->GetStringListValue();
1426             break;
1427         }
1428         return aValue;
1429 	}
1430 
1431 	//------------------------------------------------------------------
1432     Type SAL_CALL OMultilineEditControl::getValueType() throw (RuntimeException)
1433     {
1434         if ( getTypedControlWindow()->getOperationMode() == eMultiLineText )
1435             return ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) );
1436         return ::getCppuType( static_cast< Sequence< ::rtl::OUString >* >( NULL ) );
1437     }
1438 
1439 //............................................................................
1440 } // namespace pcr
1441 //............................................................................
1442 
1443