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