1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 #include "wrapper.hxx"
34 #include <comphelper/processfactory.hxx>
35 #include <com/sun/star/awt/XMetricField.hpp>
36 #include <com/sun/star/awt/XNumericField.hpp>
37 #include <com/sun/star/awt/XTextComponent.hpp>
38 #include <com/sun/star/awt/XListBox.hpp>
39 #include <com/sun/star/awt/XComboBox.hpp>
40 #include <cppuhelper/implbase1.hxx>
41 #include <com/sun/star/awt/XActionListener.hpp>
42 #include <com/sun/star/awt/XItemListener.hpp>
43 #include <com/sun/star/awt/XMouseListener.hpp>
44 #include <vcl/combobox.hxx>
45 #include <vcl/lstbox.hxx>
47 #include <toolkit/awt/vclxwindows.hxx>
49 using namespace ::com::sun::star
;
52 #define LAYOUT_API_CALLS_HANDLER 0
57 class EditImpl
: public ControlImpl
58 , public ::cppu::WeakImplHelper1
< awt::XTextListener
>
63 uno::Reference
< awt::XTextComponent
> mxEdit
;
64 EditImpl( Context
*context
, const PeerHandle
&peer
, Window
*window
)
65 : ControlImpl( context
, peer
, window
)
66 , mxEdit( peer
, uno::UNO_QUERY
)
72 virtual void SAL_CALL
disposing( lang::EventObject
const& e
)
73 throw (uno::RuntimeException
);
75 virtual void SetModifyHdl( Link
const& link
);
77 void SAL_CALL
textChanged( const awt::TextEvent
& /* rEvent */ )
78 throw (uno::RuntimeException
)
80 maModifyHdl
.Call( mpWindow
);
84 EditImpl::~EditImpl ()
88 void SAL_CALL
EditImpl::disposing( lang::EventObject
const& e
)
89 throw (uno::RuntimeException
)
91 ControlImpl::disposing (e
);
95 void EditImpl::SetModifyHdl( Link
const& link
)
97 if (!link
&& !!maModifyHdl
)
98 mxEdit
->removeTextListener( this );
99 else if (!!link
&& !maModifyHdl
)
100 mxEdit
->addTextListener( this );
106 SetModifyHdl (Link ());
109 void Edit::SetSelection( Selection
const& rSelection
)
111 #if LAYOUT_API_CALLS_HANDLER
112 if ( !getImpl().mxEdit
.is() )
113 getImpl().mxEdit
->setSelection( awt::Selection( rSelection
.Min(), rSelection
.Max() ) );
114 #else /* !LAYOUT_API_CALLS_HANDLER */
115 GetEdit ()->SetSelection (rSelection
);
116 #endif /* !LAYOUT_API_CALLS_HANDLER */
119 void Edit::SetText( OUString
const& rStr
)
121 #if LAYOUT_API_CALLS_HANDLER
122 if ( getImpl().mxEdit
.is() )
123 /// this calls handlers; endless loop in numfmt.cxx
124 getImpl().mxEdit
->setText( rStr
);
125 #else /* !LAYOUT_API_CALLS_HANDLER */
126 GetEdit ()->SetText (rStr
);
127 #endif /* !LAYOUT_API_CALLS_HANDLER */
130 String
Edit::GetText() const
132 if ( !getImpl().mxEdit
.is() )
133 return getImpl().mxEdit
->getText();
137 void Edit::SetModifyHdl( const Link
& link
)
139 if (&getImpl () && getImpl().mxEdit
.is ())
140 getImpl().SetModifyHdl( link
);
143 IMPL_CONSTRUCTORS( Edit
, Control
, "edit" );
144 IMPL_GET_IMPL( Edit
);
145 IMPL_GET_WINDOW (Edit
);
147 class MultiLineEditImpl
: public EditImpl
150 MultiLineEditImpl( Context
*context
, const PeerHandle
&peer
, Window
*window
)
151 : EditImpl( context
, peer
, window
)
156 IMPL_CONSTRUCTORS( MultiLineEdit
, Edit
, "multilineedit" );
157 IMPL_GET_IMPL( MultiLineEdit
);
159 class SpinFieldImpl
: public EditImpl
162 SpinFieldImpl( Context
*context
, const PeerHandle
&peer
, Window
*window
)
163 : EditImpl( context
, peer
, window
)
168 IMPL_CONSTRUCTORS( SpinField
, Edit
, "spinfield" );
170 class NumericFieldImpl
: public SpinFieldImpl
173 NumericFieldImpl( Context
*context
, const PeerHandle
&peer
, Window
*window
)
174 : SpinFieldImpl( context
, peer
, window
)
179 class MetricFieldImpl
: public SpinFieldImpl
182 MetricFieldImpl( Context
*context
, const PeerHandle
&peer
, Window
*window
)
183 : SpinFieldImpl( context
, peer
, window
)
188 IMPL_GET_IMPL( SpinField
);
189 IMPL_GET_IMPL( NumericField
);
190 IMPL_GET_IMPL( MetricField
);
192 class FormatterBaseImpl
197 explicit FormatterBaseImpl( const PeerHandle
&peer
)
203 FormatterBase::FormatterBase( FormatterBaseImpl
*pFormatImpl
)
204 : mpFormatImpl( pFormatImpl
)
208 class NumericFormatterImpl
: public FormatterBaseImpl
211 uno::Reference
< awt::XNumericField
> mxField
;
212 explicit NumericFormatterImpl( const PeerHandle
&peer
)
213 : FormatterBaseImpl( peer
)
214 , mxField( peer
, uno::UNO_QUERY
)
218 // FIXME: burn that CPU ! cut/paste from vclxwindows.cxx
219 double valueToDouble( sal_Int64 nValue
)
221 sal_Int16 nDigits
= mxField
->getDecimalDigits();
222 double n
= (double)nValue
;
223 for ( sal_uInt16 d
= 0; d
< nDigits
; d
++ )
226 } // FIXME: burn that CPU ! cut/paste from vclxwindows.cxx
227 sal_Int64
doubleToValue( double nValue
)
229 sal_Int16 nDigits
= mxField
->getDecimalDigits();
231 for ( sal_uInt16 d
= 0; d
< nDigits
; d
++ )
233 return (sal_Int64
) n
;
237 class MetricFormatterImpl
: public FormatterBaseImpl
240 uno::Reference
< awt::XMetricField
> mxField
;
241 explicit MetricFormatterImpl( const PeerHandle
&peer
)
242 : FormatterBaseImpl( peer
)
243 , mxField( peer
, uno::UNO_QUERY
)
248 NumericFormatter::NumericFormatter( FormatterBaseImpl
*pImpl
)
249 : FormatterBase( pImpl
)
253 NumericFormatterImpl
& NumericFormatter::getFormatImpl() const
255 return *( static_cast<NumericFormatterImpl
*>( mpFormatImpl
) );
258 #define SET_IMPL(vclmethod, idlmethod) \
259 void NumericFormatter::vclmethod( sal_Int64 nValue ) \
261 if ( !getFormatImpl().mxField.is() ) \
263 getFormatImpl().mxField->idlmethod( getFormatImpl().valueToDouble( nValue ) ); \
266 SET_IMPL( SetMin
, setMin
)
267 SET_IMPL( SetMax
, setMax
)
268 SET_IMPL( SetLast
, setLast
)
269 SET_IMPL( SetFirst
, setFirst
)
270 SET_IMPL( SetValue
, setValue
)
271 SET_IMPL( SetSpinSize
, setSpinSize
)
273 sal_Int64
NumericFormatter::GetValue() const
275 if ( !getFormatImpl().mxField
.is() )
277 return getFormatImpl().doubleToValue( getFormatImpl().mxField
->getValue() );
282 IMPL_CONSTRUCTORS_2( NumericField
, SpinField
, NumericFormatter
, "numericfield" );
284 MetricFormatter::MetricFormatter( FormatterBaseImpl
*pImpl
)
285 : FormatterBase( pImpl
)
288 MetricFormatterImpl
& MetricFormatter::getFormatImpl() const
289 { return *( static_cast<MetricFormatterImpl
*>( mpFormatImpl
) ); }
291 #define MetricUnitVclToUno(a) ((sal_uInt16)(a))
293 #define SET_IMPL(vclmethod, idlmethod) \
294 void MetricFormatter::vclmethod( sal_Int64 nValue, FieldUnit nUnit ) \
296 if ( !getFormatImpl().mxField.is() ) \
298 getFormatImpl().mxField->idlmethod( nValue, MetricUnitVclToUno( nUnit ) ); \
301 SET_IMPL( SetMin
, setMin
)
302 SET_IMPL( SetMax
, setMax
)
303 SET_IMPL( SetLast
, setLast
)
304 SET_IMPL( SetFirst
, setFirst
)
305 SET_IMPL( SetValue
, setValue
)
309 void MetricFormatter::SetSpinSize( sal_Int64 nValue
)
311 if ( !getFormatImpl().mxField
.is() )
313 getFormatImpl().mxField
->setSpinSize( nValue
);
316 sal_Int64
MetricFormatter::GetValue( FieldUnit nUnit
) const
318 if ( !getFormatImpl().mxField
.is() )
320 return getFormatImpl().mxField
->getValue( MetricUnitVclToUno( nUnit
) );
323 IMPL_CONSTRUCTORS_2( MetricField
, SpinField
, MetricFormatter
, "metricfield" );
325 class ComboBoxImpl
: public EditImpl
326 , public ::cppu::WeakImplHelper1
< awt::XActionListener
>
327 , public ::cppu::WeakImplHelper1
< awt::XItemListener
>
330 uno::Reference
< awt::XComboBox
> mxComboBox
;
337 ComboBoxImpl( Context
*context
, const PeerHandle
&peer
, Window
*window
)
338 : EditImpl( context
, peer
, window
)
339 , mxComboBox( peer
, uno::UNO_QUERY
)
345 sal_uInt16
InsertEntry( OUString
const& rStr
, sal_uInt16 nPos
)
347 if ( nPos
== COMBOBOX_APPEND
)
348 nPos
= GetEntryCount();
349 mxComboBox
->addItem( rtl::OUString( rStr
), nPos
);
353 void RemoveEntry( sal_uInt16 nPos
)
355 mxComboBox
->removeItems( nPos
, 1 );
358 sal_uInt16
GetEntryPos( String
const& rStr
) const
360 uno::Sequence
< rtl::OUString
> aItems( mxComboBox
->getItems() );
361 rtl::OUString
rKey( rStr
);
362 sal_uInt16 n
= sal::static_int_cast
< sal_uInt16
>(aItems
.getLength());
363 for (sal_uInt16 i
= 0; i
< n
; i
++)
365 if ( aItems
[ i
] == rKey
)
368 return COMBOBOX_ENTRY_NOTFOUND
;
371 OUString
GetEntry( sal_uInt16 nPos
) const
373 return OUString( mxComboBox
->getItem( nPos
) );
376 sal_uInt16
GetEntryCount() const
378 return mxComboBox
->getItemCount();
381 void SetClickHdl( Link
const& link
)
383 if (!link
&& !!maClickHdl
)
384 mxComboBox
->removeActionListener( this );
385 else if (!!link
&& !maClickHdl
)
386 mxComboBox
->addActionListener( this );
390 void SetSelectHdl( Link
const& link
)
392 if (!link
&& !!maSelectHdl
)
393 mxComboBox
->removeItemListener( this );
394 else if (!!link
&& !maSelectHdl
)
395 mxComboBox
->addItemListener( this );
399 void SAL_CALL
disposing( lang::EventObject
const& e
)
400 throw (uno::RuntimeException
);
402 void SAL_CALL
actionPerformed (const awt::ActionEvent
&)
403 throw (uno::RuntimeException
)
405 ComboBox
* pComboBox
= static_cast<ComboBox
*>( mpWindow
);
408 maClickHdl
.Call( pComboBox
);
411 void SAL_CALL
itemStateChanged( awt::ItemEvent
const&)
412 throw (uno::RuntimeException
)
414 ComboBox
* pComboBox
= static_cast<ComboBox
*>( mpWindow
);
417 maSelectHdl
.Call( pComboBox
);
421 ComboBox::~ComboBox ()
424 OSL_TRACE ("%s: deleting ComboBox for window: %p", __FUNCTION__
, GetWindow ());
426 SetClickHdl (Link ());
427 SetSelectHdl (Link ());
430 ComboBoxImpl::~ComboBoxImpl ()
433 OSL_TRACE ("%s: deleting ComboBoxImpl for window: %p", __FUNCTION__
, mpWindow
? mpWindow
->GetWindow () : 0);
434 OSL_TRACE ("%s: deleting ComboBoxImpl for listener: %p", __FUNCTION__
, static_cast<XFocusListener
*> (this));
438 void ComboBoxImpl::disposing( lang::EventObject
const& e
)
439 throw (uno::RuntimeException
)
441 EditImpl::disposing (e
);
445 sal_uInt16
ComboBox::InsertEntry( String
const& rStr
, sal_uInt16 nPos
)
447 return getImpl().InsertEntry( rStr
, nPos
);
450 void ComboBox::RemoveEntry( String
const& rStr
)
452 getImpl().RemoveEntry( GetEntryPos( rStr
) );
455 void ComboBox::RemoveEntry( sal_uInt16 nPos
)
457 getImpl().RemoveEntry( nPos
);
460 void ComboBox::Clear()
462 uno::Sequence
< rtl::OUString
> aNoItems
;
463 getImpl().setProperty( "StringItemList", uno::Any( aNoItems
) );
466 sal_uInt16
ComboBox::GetEntryPos( String
const& rStr
) const
468 return getImpl().GetEntryPos( rStr
);
471 String
ComboBox::GetEntry( sal_uInt16 nPos
) const
473 rtl::OUString rItem
= getImpl().mxComboBox
->getItem( nPos
);
474 return OUString( rItem
);
477 sal_uInt16
ComboBox::GetEntryCount() const
479 return getImpl().GetEntryCount();
482 void ComboBox::SetClickHdl( const Link
& link
)
484 if (&getImpl () && getImpl().mxComboBox
.is ())
485 getImpl().SetClickHdl( link
);
488 void ComboBox::SetSelectHdl( const Link
& link
)
490 if (&getImpl () && getImpl().mxComboBox
.is ())
491 getImpl().SetSelectHdl( link
);
494 void ComboBox::EnableAutocomplete (bool enable
, bool matchCase
)
496 GetComboBox ()->EnableAutocomplete (enable
, matchCase
);
499 IMPL_CONSTRUCTORS_BODY( ComboBox
, Edit
, "combobox", getImpl().parent
= parent
; );
500 IMPL_GET_WINDOW (ComboBox
);
501 /// IMPL_GET_IMPL( ComboBox );
503 static ComboBoxImpl
* null_combobox_impl
= 0;
505 ComboBoxImpl
&ComboBox::getImpl () const
507 if (ComboBoxImpl
* c
= static_cast<ComboBoxImpl
*>(mpImpl
))
509 return *null_combobox_impl
;
512 class ListBoxImpl
: public ControlImpl
513 , public ::cppu::WeakImplHelper1
< awt::XActionListener
>
514 , public ::cppu::WeakImplHelper1
< awt::XItemListener
>
515 , public ::cppu::WeakImplHelper1
< awt::XMouseListener
>
519 Link maDoubleClickHdl
;
522 uno::Reference
< awt::XListBox
> mxListBox
;
523 ListBoxImpl( Context
*context
, const PeerHandle
&peer
, Window
*window
)
524 : ControlImpl( context
, peer
, window
)
525 , mxListBox( peer
, uno::UNO_QUERY
)
527 SelectEntryPos (0, true);
530 sal_uInt16
InsertEntry (String
const& rStr
, sal_uInt16 nPos
)
532 if ( nPos
== LISTBOX_APPEND
)
533 nPos
= mxListBox
->getItemCount();
534 mxListBox
->addItem( rtl::OUString( rStr
), nPos
);
538 void RemoveEntry( sal_uInt16 nPos
)
540 mxListBox
->removeItems( nPos
, 1 );
543 sal_uInt16
RemoveEntry( String
const& rStr
, sal_uInt16 nPos
)
545 if ( nPos
== LISTBOX_APPEND
)
546 nPos
= mxListBox
->getItemCount();
547 mxListBox
->addItem( rtl::OUString( rStr
), nPos
);
551 sal_uInt16
GetEntryPos( String
const& rStr
) const
553 uno::Sequence
< rtl::OUString
> aItems( mxListBox
->getItems() );
554 rtl::OUString
rKey( rStr
);
555 sal_uInt16 n
= sal::static_int_cast
< sal_uInt16
>(aItems
.getLength());
556 for (sal_uInt16 i
= 0; i
< n
; i
++)
558 if ( aItems
[ i
] == rKey
)
561 return LISTBOX_ENTRY_NOTFOUND
;
564 OUString
GetEntry( sal_uInt16 nPos
) const
566 return mxListBox
->getItem( nPos
);
569 sal_uInt16
GetEntryCount() const
571 return mxListBox
->getItemCount();
574 void SelectEntryPos( sal_uInt16 nPos
, bool bSelect
)
576 mxListBox
->selectItemPos( nPos
, bSelect
);
579 sal_uInt16
GetSelectEntryCount() const
581 return sal::static_int_cast
< sal_uInt16
>( mxListBox
->getSelectedItems().getLength() );
584 sal_uInt16
GetSelectEntryPos( sal_uInt16 nSelIndex
) const
586 sal_uInt16 nSelected
= 0;
587 if ( mxListBox
->isMutipleMode() )
589 uno::Sequence
< short > aItems( mxListBox
->getSelectedItemsPos() );
590 if ( nSelIndex
< aItems
.getLength() )
591 nSelected
= aItems
[ nSelIndex
];
594 nSelected
= mxListBox
->getSelectedItemPos();
598 virtual void SAL_CALL
disposing( lang::EventObject
const& e
)
599 throw (uno::RuntimeException
)
601 ControlImpl::disposing (e
);
610 void SetClickHdl( Link
const& link
)
612 if (!link
&& !!maClickHdl
)
613 mxListBox
->removeActionListener( this );
614 else if (!!link
&& !maClickHdl
)
615 mxListBox
->addActionListener( this );
619 void SAL_CALL
actionPerformed( const awt::ActionEvent
& /* rEvent */ )
620 throw (uno::RuntimeException
)
622 maClickHdl
.Call( mpWindow
);
625 Link
& GetSelectHdl ()
630 void SetSelectHdl( Link
const& link
)
632 if (!link
&& !!maSelectHdl
)
633 mxListBox
->removeItemListener( this );
634 else if (!!link
&& !maSelectHdl
)
635 mxListBox
->addItemListener( this );
639 void SAL_CALL
itemStateChanged (awt::ItemEvent
const&)
640 throw (uno::RuntimeException
)
642 maSelectHdl
.Call (static_cast <ListBox
*> (mpWindow
));
645 Link
& GetDoubleClickHdl ()
647 return maDoubleClickHdl
;
650 void SetDoubleClickHdl (Link
const& link
)
652 if (!link
&& !!maDoubleClickHdl
)
653 mxWindow
->removeMouseListener (this);
654 else if (!!link
&& !maSelectHdl
)
655 mxWindow
->addMouseListener (this);
656 maDoubleClickHdl
= link
;
659 void SAL_CALL
mousePressed (awt::MouseEvent
const&) throw (uno::RuntimeException
)
662 void SAL_CALL
mouseReleased (awt::MouseEvent
const& e
) throw (uno::RuntimeException
)
664 if (e
.ClickCount
== 2)
665 maDoubleClickHdl
.Call (mpWindow
);
667 void SAL_CALL
mouseEntered (awt::MouseEvent
const&) throw (uno::RuntimeException
)
670 void SAL_CALL
mouseExited (awt::MouseEvent
const&) throw (uno::RuntimeException
)
677 SetClickHdl (Link ());
678 SetSelectHdl (Link ());
681 sal_uInt16
ListBox::InsertEntry (String
const& rStr
, sal_uInt16 nPos
)
683 return getImpl().InsertEntry(rStr
, nPos
);
686 void ListBox::RemoveEntry( sal_uInt16 nPos
)
688 return getImpl().RemoveEntry( nPos
);
691 void ListBox::RemoveEntry( String
const& rStr
)
693 return getImpl().RemoveEntry( GetEntryPos( rStr
) );
696 void ListBox::Clear()
698 uno::Sequence
< rtl::OUString
> aNoItems
;
699 getImpl().setProperty( "StringItemList", uno::Any( aNoItems
) );
702 sal_uInt16
ListBox::GetEntryPos( String
const& rStr
) const
704 return getImpl().GetEntryPos( rStr
);
707 String
ListBox::GetEntry( sal_uInt16 nPos
) const
709 return getImpl().GetEntry( nPos
);
712 sal_uInt16
ListBox::GetEntryCount() const
714 return getImpl().GetEntryCount();
717 void ListBox::SelectEntryPos( sal_uInt16 nPos
, bool bSelect
)
719 #if LAYOUT_API_CALLS_HANDLER
720 getImpl().SelectEntryPos( nPos
, bSelect
);
721 #else /* !LAYOUT_API_CALLS_HANDLER */
722 GetListBox ()->SelectEntryPos (nPos
, bSelect
);
723 #endif /* !LAYOUT_API_CALLS_HANDLER */
726 void ListBox::SelectEntry( String
const& rStr
, bool bSelect
)
728 SelectEntryPos( GetEntryPos( rStr
), bSelect
);
731 sal_uInt16
ListBox::GetSelectEntryCount() const
733 return getImpl().GetSelectEntryCount();
736 sal_uInt16
ListBox::GetSelectEntryPos( sal_uInt16 nSelIndex
) const
738 return getImpl().GetSelectEntryPos( nSelIndex
);
741 String
ListBox::GetSelectEntry( sal_uInt16 nSelIndex
) const
743 return GetEntry( GetSelectEntryPos( nSelIndex
) );
746 Link
& ListBox::GetSelectHdl ()
748 return getImpl ().GetSelectHdl ();
751 void ListBox::SetSelectHdl( Link
const& link
)
753 getImpl().SetSelectHdl( link
);
756 Link
& ListBox::GetClickHdl ()
758 return getImpl ().GetSelectHdl ();
761 void ListBox::SetClickHdl( Link
const& link
)
763 if (&getImpl () && getImpl().mxListBox
.is ())
764 getImpl().SetClickHdl( link
);
767 Link
& ListBox::GetDoubleClickHdl ()
769 return getImpl ().GetSelectHdl ();
772 void ListBox::SetDoubleClickHdl( Link
const& link
)
774 getImpl().SetDoubleClickHdl( link
);
777 void ListBox::SetEntryData( sal_uInt16 pos
, void* data
)
779 GetListBox ()->SetEntryData (pos
, data
);
782 void* ListBox::GetEntryData( sal_uInt16 pos
) const
784 return GetListBox ()->GetEntryData (pos
);
787 void ListBox::SetNoSelection ()
789 GetListBox ()->SetNoSelection ();
792 IMPL_CONSTRUCTORS (ListBox
, Control
, "listbox");
793 IMPL_GET_IMPL (ListBox
);
794 IMPL_GET_WINDOW (ListBox
);
796 IMPL_IMPL (MultiListBox
, ListBox
)
797 IMPL_CONSTRUCTORS_BODY( MultiListBox
, ListBox
, "multilistbox", GetMultiListBox()->EnableMultiSelection( true ); );
798 IMPL_GET_IMPL( MultiListBox
);
799 IMPL_GET_WINDOW( MultiListBox
);
800 } // namespace layout