merge the formfield patch from ooo-build
[ooovba.git] / toolkit / source / layout / vcl / wfield.cxx
blob5187badfe7b3f255c8bd295eec303f831fe23534
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
9 * $RCSfile$
11 * $Revision$
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;
50 using rtl::OUString;
52 #define LAYOUT_API_CALLS_HANDLER 0
54 namespace layout
57 class EditImpl : public ControlImpl
58 , public ::cppu::WeakImplHelper1< awt::XTextListener >
60 public:
61 Link maModifyHdl;
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 )
70 ~EditImpl ();
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);
92 mxEdit.clear ();
95 void EditImpl::SetModifyHdl( Link const& link )
97 if (!link && !!maModifyHdl)
98 mxEdit->removeTextListener( this );
99 else if (!!link && !maModifyHdl)
100 mxEdit->addTextListener( this );
101 maModifyHdl = link;
104 Edit::~Edit ()
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();
134 return OUString();
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
149 public:
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
161 public:
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
172 public:
173 NumericFieldImpl( Context *context, const PeerHandle &peer, Window *window )
174 : SpinFieldImpl( context, peer, window )
179 class MetricFieldImpl : public SpinFieldImpl
181 public:
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
194 protected:
195 PeerHandle mpeer;
196 public:
197 explicit FormatterBaseImpl( const PeerHandle &peer )
198 : mpeer( peer )
203 FormatterBase::FormatterBase( FormatterBaseImpl *pFormatImpl )
204 : mpFormatImpl( pFormatImpl )
208 class NumericFormatterImpl : public FormatterBaseImpl
210 public:
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++ )
224 n /= 10;
225 return n;
226 } // FIXME: burn that CPU ! cut/paste from vclxwindows.cxx
227 sal_Int64 doubleToValue( double nValue )
229 sal_Int16 nDigits = mxField->getDecimalDigits();
230 double n = nValue;
231 for ( sal_uInt16 d = 0; d < nDigits; d++ )
232 n *= 10;
233 return (sal_Int64) n;
237 class MetricFormatterImpl : public FormatterBaseImpl
239 public:
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() ) \
262 return; \
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() )
276 return 0;
277 return getFormatImpl().doubleToValue( getFormatImpl().mxField->getValue() );
280 #undef SET_IMPL
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() ) \
297 return; \
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 )
307 #undef SET_IMPL
309 void MetricFormatter::SetSpinSize( sal_Int64 nValue )
311 if ( !getFormatImpl().mxField.is() )
312 return;
313 getFormatImpl().mxField->setSpinSize( nValue );
316 sal_Int64 MetricFormatter::GetValue( FieldUnit nUnit ) const
318 if ( !getFormatImpl().mxField.is() )
319 return 0;
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 >
329 public:
330 uno::Reference< awt::XComboBox > mxComboBox;
332 Link maClickHdl;
333 Link maSelectHdl;
335 Window *parent;
337 ComboBoxImpl( Context *context, const PeerHandle &peer, Window *window )
338 : EditImpl( context, peer, window )
339 , mxComboBox( peer, uno::UNO_QUERY )
343 ~ComboBoxImpl ();
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 );
350 return 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 )
366 return i;
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 );
387 maClickHdl = link;
390 void SetSelectHdl( Link const& link )
392 if (!link && !!maSelectHdl)
393 mxComboBox->removeItemListener( this );
394 else if (!!link && !maSelectHdl)
395 mxComboBox->addItemListener( this );
396 maSelectHdl = link;
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 );
406 if ( !pComboBox )
407 return;
408 maClickHdl.Call( pComboBox );
411 void SAL_CALL itemStateChanged( awt::ItemEvent const&)
412 throw (uno::RuntimeException)
414 ComboBox* pComboBox = static_cast<ComboBox*>( mpWindow );
415 if ( !pComboBox )
416 return;
417 maSelectHdl.Call( pComboBox );
421 ComboBox::~ComboBox ()
423 #ifndef __SUNPRO_CC
424 OSL_TRACE ("%s: deleting ComboBox for window: %p", __FUNCTION__, GetWindow ());
425 #endif
426 SetClickHdl (Link ());
427 SetSelectHdl (Link ());
430 ComboBoxImpl::~ComboBoxImpl ()
432 #ifndef __SUNPRO_CC
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));
435 #endif
438 void ComboBoxImpl::disposing( lang::EventObject const& e )
439 throw (uno::RuntimeException)
441 EditImpl::disposing (e);
442 mxComboBox.clear ();
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))
508 return *c;
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 >
517 Link maClickHdl;
518 Link maSelectHdl;
519 Link maDoubleClickHdl;
521 public:
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 );
535 return 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 );
548 return 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 )
559 return i;
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 ];
593 else
594 nSelected = mxListBox->getSelectedItemPos();
595 return nSelected;
598 virtual void SAL_CALL disposing( lang::EventObject const& e )
599 throw (uno::RuntimeException)
601 ControlImpl::disposing (e);
602 mxListBox.clear ();
605 Link& GetClickHdl ()
607 return maClickHdl;
610 void SetClickHdl( Link const& link )
612 if (!link && !!maClickHdl)
613 mxListBox->removeActionListener( this );
614 else if (!!link && !maClickHdl)
615 mxListBox->addActionListener( this );
616 maClickHdl = link;
619 void SAL_CALL actionPerformed( const awt::ActionEvent& /* rEvent */ )
620 throw (uno::RuntimeException)
622 maClickHdl.Call( mpWindow );
625 Link& GetSelectHdl ()
627 return maSelectHdl;
630 void SetSelectHdl( Link const& link )
632 if (!link && !!maSelectHdl)
633 mxListBox->removeItemListener( this );
634 else if (!!link && !maSelectHdl)
635 mxListBox->addItemListener( this );
636 maSelectHdl = link;
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)
675 ListBox::~ListBox ()
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