merge the formfield patch from ooo-build
[ooovba.git] / toolkit / source / layout / vcl / wbutton.cxx
blob0b8b412993150e59f6d4ceabeeac1ec1b2210833
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 <com/sun/star/awt/PosSize.hpp>
35 #include <com/sun/star/awt/XActionListener.hpp>
36 #include <com/sun/star/awt/XButton.hpp>
37 #include <com/sun/star/awt/XCheckBox.hpp>
38 #include <com/sun/star/awt/XRadioButton.hpp>
39 #include <com/sun/star/graphic/XGraphic.hpp>
40 #include <cppuhelper/implbase1.hxx>
41 #include <toolkit/awt/vclxwindow.hxx>
42 #include <toolkit/awt/vclxwindows.hxx>
43 #include <toolkit/helper/convert.hxx>
44 #include <vcl/button.hxx>
45 #include <vcl/event.hxx>
46 #include <vcl/msgbox.hxx>
47 #include <vcl/svapp.hxx>
48 #include <vcl/window.hxx>
50 #include <list>
52 #include <layout/core/helper.hxx>
54 using namespace ::com::sun::star;
56 using rtl::OUString;
58 namespace layout
61 class ImageImpl
63 public:
64 uno::Reference< graphic::XGraphic > mxGraphic;
65 ImageImpl( const char *pName )
66 : mxGraphic( layoutimpl::loadGraphic( pName ) )
68 if ( !mxGraphic.is() )
70 DBG_ERROR1( "ERROR: failed to load image: `%s'\n", pName );
75 Image::Image( const char *pName )
76 : pImpl( new ImageImpl( pName ) )
80 Image::~Image()
82 delete pImpl;
85 class ButtonImpl : public ControlImpl
86 , public ::cppu::WeakImplHelper1< awt::XActionListener >
88 Link maClickHdl;
90 public:
91 uno::Reference< awt::XButton > mxButton;
92 ButtonImpl( Context *context, const PeerHandle &peer, Window *window )
93 : ControlImpl( context, peer, window )
94 , mxButton( peer, uno::UNO_QUERY )
96 /* We have default action when clicked, always listen. */
97 mxButton->addActionListener( this );
100 ~ButtonImpl()
104 virtual void Click() { /* make me pure virtual? */ };
106 Link& GetClickHdl ()
108 return maClickHdl;
111 virtual void SetClickHdl( Link const& link )
113 maClickHdl = link;
116 void SAL_CALL disposing( lang::EventObject const& e )
117 throw (uno::RuntimeException)
119 mxButton->removeActionListener( this );
120 ControlImpl::disposing (e);
121 mxButton.clear ();
124 virtual void SAL_CALL actionPerformed( const awt::ActionEvent& )
125 throw (uno::RuntimeException)
127 if ( !maClickHdl )
128 Click();
129 else
130 maClickHdl.Call( static_cast<Window *>( mpWindow ) );
133 bool SetModeImage( uno::Reference< graphic::XGraphic > xGraph )
135 setProperty( "Graphic", uno::Any( xGraph ) );
136 return true;
140 Button::~Button ()
144 String Button::GetStandardText (sal_uInt16 button_type)
146 return ::Button::GetStandardText (button_type);
149 void Button::SetText( OUString const& rStr )
151 if ( !getImpl().mxButton.is() )
152 return;
153 getImpl().mxButton->setLabel( rStr );
156 void Button::SetClickHdl( const Link& link )
158 if (&getImpl () && getImpl().mxButton.is ())
159 getImpl().SetClickHdl( link );
162 Link& Button::GetClickHdl ()
164 return getImpl().GetClickHdl ();
167 bool Button::SetModeImage (Image const& image)
169 return getImpl().SetModeImage (image.getImpl().mxGraphic);
172 bool Button::SetModeImage (::Image const& image, BmpColorMode mode)
174 return GetButton ()->SetModeImage (image, mode);
177 void Button::SetImageAlign( ImageAlign eAlign )
179 getImpl().setProperty( "ImageAlign", uno::Any( (sal_Int16) eAlign ) );
182 void Button::Click()
186 IMPL_GET_IMPL( Button );
187 IMPL_CONSTRUCTORS( Button, Control, "button" );
188 IMPL_GET_WINDOW (Button);
190 class PushButtonImpl : public ButtonImpl
191 , public ::cppu::WeakImplHelper1< awt::XItemListener >
193 Link maToggleHdl;
194 public:
195 PushButtonImpl( Context *context, const PeerHandle &peer, Window *window )
196 : ButtonImpl( context, peer, window )
200 void SetToggleHdl( const Link& link )
202 // XButton doesn't have an explicit event for Toggle. Anyway, it is a
203 // superset of the clicks: all clicks, and explicit toggles
204 if (!link && !!maToggleHdl)
205 mxButton->removeActionListener( this );
206 else if (!!link && !maToggleHdl)
207 mxButton->addActionListener( this );
208 maToggleHdl = link;
210 void SAL_CALL disposing( lang::EventObject const& e )
211 throw (uno::RuntimeException)
213 ButtonImpl::disposing (e);
215 virtual void SAL_CALL actionPerformed( awt::ActionEvent const& e )
216 throw (uno::RuntimeException)
218 ButtonImpl::actionPerformed( e );
219 fireToggle();
221 virtual void SAL_CALL itemStateChanged( const awt::ItemEvent& )
222 throw (uno::RuntimeException)
224 maToggleHdl.Call( static_cast<Window *>( mpWindow ) );
226 void fireToggle()
228 maToggleHdl.Call( static_cast<Window *>( mpWindow ) );
233 PushButton::~PushButton ()
235 SetToggleHdl (Link ());
238 void PushButton::Check( bool bCheck )
240 getImpl().setProperty( "State", uno::Any( (sal_Int16) !!bCheck ) );
241 // XButton doesn't have explicit toggle event
242 getImpl().fireToggle();
245 bool PushButton::IsChecked() const
247 return !!( getImpl().getProperty( "State" ).get< sal_Int16 >() );
250 void PushButton::Toggle()
252 Check( true );
255 void PushButton::SetToggleHdl( const Link& link )
257 if (&getImpl () && getImpl().mxButton.is ())
258 getImpl().SetToggleHdl( link );
261 IMPL_GET_IMPL( PushButton );
262 IMPL_CONSTRUCTORS( PushButton, Button, "pushbutton" );
263 IMPL_GET_WINDOW (PushButton);
265 class RadioButtonImpl : public ButtonImpl
266 , public ::cppu::WeakImplHelper1< awt::XItemListener >
268 Link maToggleHdl;
269 public:
270 uno::Reference< awt::XRadioButton > mxRadioButton;
271 RadioButtonImpl( Context *context, const PeerHandle &peer, Window *window )
272 : ButtonImpl( context, peer, window )
273 , mxRadioButton( peer, uno::UNO_QUERY )
277 void Check( bool bCheck )
279 if ( !mxRadioButton.is() )
280 return;
282 #if 1
283 // Have setState fire item event for
284 // RadioGroups::RadioGroup::itemStateChanged ()
285 ::RadioButton *r = static_cast<RadioButton*>(mpWindow)->GetRadioButton ();
286 bool state = r->IsRadioCheckEnabled ();
287 r->EnableRadioCheck();
288 mxRadioButton->setState( !!bCheck );
289 r->EnableRadioCheck (state);
290 #else
291 mxRadioButton->setState( !!bCheck );
292 #endif
293 fireToggle();
296 bool IsChecked()
298 if ( !mxRadioButton.is() )
299 return false;
300 return mxRadioButton->getState();
303 void SetToggleHdl( const Link& link )
305 if (!link && !!maToggleHdl)
306 mxRadioButton->removeItemListener( this );
307 else if (!!link && !maToggleHdl)
308 mxRadioButton->addItemListener( this );
309 maToggleHdl = link;
312 inline void fireToggle()
314 maToggleHdl.Call( static_cast<Window *>( mpWindow ) );
317 virtual void SetClickHdl( const Link& link )
319 // Keep RadioGroups::RadioGroup's actionListener at HEAD
320 // of list. This way, it can handle RadioGroup's button
321 // states before all other callbacks and make sure the
322 // client code has the right state.
324 // IWBN to add an XRadioButton2 and layout::VCLXRadioButton
325 // with {get,set}RadioGroup() (and a "radiogroup" property
326 // even) and handle the grouping here in RadioButtonImpl.
327 uno::Reference< uno::XInterface > x = static_cast<VCLXRadioButton*> (mpWindow->GetVCLXWindow ())->getFirstActionListener ();
328 uno::Reference< awt::XActionListener > a = uno::Reference< awt::XActionListener> (x ,uno::UNO_QUERY );
329 mxButton->removeActionListener (a);
330 ButtonImpl::SetClickHdl (link);
331 mxButton->addActionListener (a);
334 void SAL_CALL disposing( lang::EventObject const& e )
335 throw (uno::RuntimeException)
337 ButtonImpl::disposing (e);
340 virtual void SAL_CALL itemStateChanged( const awt::ItemEvent& )
341 throw (uno::RuntimeException)
343 maToggleHdl.Call( static_cast<Window *>( mpWindow ) );
347 RadioButton::~RadioButton ()
349 SetToggleHdl (Link ());
352 void RadioButton::Check( bool bCheck )
354 getImpl().Check( bCheck );
357 bool RadioButton::IsChecked() const
359 return getImpl().IsChecked();
362 void RadioButton::SetToggleHdl( const Link& link )
364 if (&getImpl () && getImpl().mxRadioButton.is ())
365 getImpl().SetToggleHdl( link );
368 IMPL_GET_IMPL( RadioButton );
369 IMPL_GET_WINDOW( RadioButton );
370 IMPL_GET_VCLXWINDOW( RadioButton );
371 IMPL_CONSTRUCTORS( RadioButton, Button, "radiobutton" );
373 class CheckBoxImpl : public ButtonImpl
374 , public ::cppu::WeakImplHelper1< awt::XItemListener >
376 Link maToggleHdl;
377 public:
378 uno::Reference< awt::XCheckBox > mxCheckBox;
379 CheckBoxImpl( Context *context, const PeerHandle &peer, Window *window )
380 : ButtonImpl( context, peer, window )
381 , mxCheckBox( peer, uno::UNO_QUERY )
385 void SetToggleHdl( const Link& link )
387 if (!link && !!maToggleHdl)
388 mxCheckBox->removeItemListener( this );
389 else if (!!link && !maToggleHdl)
390 mxCheckBox->addItemListener( this );
391 maToggleHdl = link;
393 void SAL_CALL disposing( lang::EventObject const& e )
394 throw (uno::RuntimeException)
396 ButtonImpl::disposing (e);
398 virtual void SAL_CALL itemStateChanged( const awt::ItemEvent& )
399 throw (uno::RuntimeException)
401 maToggleHdl.Call( static_cast<Window *>( mpWindow ) );
405 CheckBox::~CheckBox ()
407 SetToggleHdl (Link ());
410 void CheckBox::Check( bool bCheck )
412 if ( !getImpl().mxCheckBox.is() )
413 return;
414 getImpl().mxCheckBox->setState( !!bCheck );
417 bool CheckBox::IsChecked() const
419 if ( !getImpl().mxCheckBox.is() )
420 return false;
421 return getImpl().mxCheckBox->getState() != 0;
424 void CheckBox::SetToggleHdl( const Link& link )
426 if (&getImpl () && getImpl().mxCheckBox.is ())
427 getImpl().SetToggleHdl( link );
430 IMPL_GET_IMPL( CheckBox );
431 IMPL_CONSTRUCTORS( CheckBox, Button, "checkbox" );
433 #define BUTTON_IMPL(t, parent, response) \
434 class t##Impl : public parent##Impl \
436 public: \
437 t##Impl( Context *context, PeerHandle const& peer, Window *window ) \
438 : parent##Impl( context, peer, window ) \
441 void Click() \
443 if (Dialog *d = static_cast<Dialog *> (mpCtx)) \
444 d->EndDialog( response ); \
448 /* Common button types currently unavailable in OOo: */
449 /* mpReset */
450 /* mpApply */
451 /* mpAction */
452 #define RET_RESET 6
453 #define RET_APPLY 7
454 #define BUTTONID_RESET RET_RESET
455 #define BUTTONID_APPLY RET_APPLY
457 BUTTON_IMPL( OKButton, PushButton, BUTTONID_OK );
458 BUTTON_IMPL( CancelButton, PushButton, BUTTONID_CANCEL );
459 BUTTON_IMPL( YesButton, PushButton, BUTTONID_YES );
460 BUTTON_IMPL( NoButton, PushButton, BUTTONID_NO );
461 BUTTON_IMPL( RetryButton, PushButton, BUTTONID_RETRY );
462 BUTTON_IMPL( IgnoreButton, PushButton, BUTTONID_IGNORE );
463 BUTTON_IMPL( ResetButton, PushButton, BUTTONID_RESET );
464 BUTTON_IMPL( ApplyButton, PushButton, BUTTONID_APPLY ); /* Deprecated? */
465 BUTTON_IMPL( HelpButton, PushButton, BUTTONID_HELP );
467 IMPL_CONSTRUCTORS( OKButton, PushButton, "okbutton" );
468 IMPL_CONSTRUCTORS( CancelButton, PushButton, "cancelbutton" );
469 IMPL_CONSTRUCTORS( YesButton, PushButton, "yesbutton" );
470 IMPL_CONSTRUCTORS( NoButton, PushButton, "nobutton" );
471 IMPL_CONSTRUCTORS( RetryButton, PushButton, "retrybutton" );
472 IMPL_CONSTRUCTORS( IgnoreButton, PushButton, "ignorebutton" );
473 IMPL_CONSTRUCTORS( ResetButton, PushButton, "resetbutton" );
474 IMPL_CONSTRUCTORS( ApplyButton, PushButton, "applybutton" ); /* Deprecated? */
475 IMPL_CONSTRUCTORS( HelpButton, PushButton, "helpbutton" );
477 IMPL_IMPL (ImageButton, PushButton)
480 IMPL_CONSTRUCTORS( ImageButton, PushButton, "imagebutton" );
482 class AdvancedButtonImpl : public PushButtonImpl
484 protected:
485 bool bAdvancedMode;
486 std::list< Window*> maAdvanced;
487 std::list< Window*> maSimple;
489 public:
490 rtl::OUString mAdvancedLabel;
491 rtl::OUString mSimpleLabel;
493 protected:
494 Window* Remove( std::list< Window*> lst, Window* w )
496 for ( std::list< Window*>::iterator it = maAdvanced.begin();
497 it != maAdvanced.end(); it++ )
498 if ( *it == w )
500 lst.erase( it );
501 return *it;
503 return 0;
506 public:
507 AdvancedButtonImpl( Context *context, PeerHandle const& peer, Window *window )
508 : PushButtonImpl( context, peer, window )
509 , bAdvancedMode( false )
510 // TODO: i18n
511 // Button::GetStandardText( BUTTON_ADVANCED );
512 // Button::GetStandardText( BUTTON_SIMPLE );
513 , mAdvancedLabel( rtl::OUString::createFromAscii( "Advanced..." ) )
514 , mSimpleLabel( rtl::OUString::createFromAscii( "Simple..." ) )
517 void Click()
519 bAdvancedMode = !bAdvancedMode;
520 if ( bAdvancedMode )
521 advancedMode();
522 else
523 simpleMode();
525 void setAlign ()
527 ::PushButton *b = static_cast<PushButton*> (mpWindow)->GetPushButton ();
528 b->SetSymbolAlign (SYMBOLALIGN_RIGHT);
529 b->SetSmallSymbol ();
530 //mpWindow->SetStyle (mpWindow->GetStyle() | WB_CENTER);
532 void advancedMode()
534 ::PushButton *b = static_cast<PushButton*> (mpWindow)->GetPushButton ();
535 b->SetSymbol (SYMBOL_PAGEUP);
536 setAlign ();
537 if (mSimpleLabel.getLength ())
538 b->SetText (mSimpleLabel);
539 for ( std::list< Window*>::iterator it = maAdvanced.begin();
540 it != maAdvanced.end(); it++ )
541 ( *it )->Show();
542 for ( std::list< Window*>::iterator it = maSimple.begin();
543 it != maSimple.end(); it++ )
544 ( *it )->Hide();
546 redraw ();
548 void simpleMode()
550 //mxButton->setLabel( mSimpleLabel );
551 ::PushButton *b = static_cast<PushButton*> (mpWindow)->GetPushButton ();
552 b->SetSymbol (SYMBOL_PAGEDOWN);
553 if (mAdvancedLabel.getLength ())
554 b->SetText (mAdvancedLabel);
555 setAlign ();
556 for ( std::list< Window*>::iterator it = maAdvanced.begin();
557 it != maAdvanced.end(); it++ )
558 ( *it )->Hide();
559 for ( std::list< Window*>::iterator it = maSimple.begin();
560 it != maSimple.end(); it++ )
561 ( *it )->Show();
563 redraw (true);
565 void AddAdvanced( Window* w )
567 maAdvanced.push_back( w );
568 if ( !bAdvancedMode )
569 w->Hide();
571 void AddSimple( Window* w )
573 maSimple.push_back( w );
574 if ( bAdvancedMode )
575 w->Hide();
577 void RemoveAdvanced( Window* w )
579 Remove( maAdvanced, w );
581 void RemoveSimple( Window* w )
583 Remove( maSimple, w );
587 void AdvancedButton::AddAdvanced( Window* w )
589 getImpl().AddAdvanced( w );
592 void AdvancedButton::AddSimple( Window* w )
594 getImpl().AddSimple( w );
597 void AdvancedButton::RemoveAdvanced( Window* w )
599 getImpl().RemoveAdvanced( w );
602 void AdvancedButton::RemoveSimple( Window* w )
604 getImpl().RemoveSimple( w );
607 void AdvancedButton::SetAdvancedText (rtl::OUString const& text)
609 if (text.getLength ())
610 getImpl ().mAdvancedLabel = text;
613 void AdvancedButton::SetSimpleText (rtl::OUString const& text)
615 if (text.getLength ())
616 getImpl ().mSimpleLabel = text;
619 rtl::OUString AdvancedButton::GetAdvancedText () const
621 return getImpl ().mAdvancedLabel;
624 rtl::OUString AdvancedButton::GetSimpleText () const
626 return getImpl ().mSimpleLabel;
629 void AdvancedButton::SetDelta (int)
633 IMPL_CONSTRUCTORS_BODY( AdvancedButton, PushButton, "advancedbutton", getImpl().simpleMode () );
634 IMPL_GET_IMPL( AdvancedButton );
637 class MoreButtonImpl : public AdvancedButtonImpl
639 public:
640 MoreButtonImpl( Context *context, PeerHandle const& peer, Window *window )
641 : AdvancedButtonImpl( context, peer, window)
643 mSimpleLabel = Button::GetStandardText( BUTTON_MORE );
644 mAdvancedLabel = Button::GetStandardText( BUTTON_LESS );
646 void AddWindow( Window* w ) { AddAdvanced( w ); }
647 void RemoveWindow( Window* w ) { RemoveAdvanced( w ); }
650 // TODO
651 //BUTTON_IMPL( MoreButton, PushButton, 0 );
652 IMPL_CONSTRUCTORS_BODY( MoreButton, AdvancedButton, "morebutton", getImpl().simpleMode () );
653 IMPL_GET_IMPL( MoreButton );
655 void MoreButton::AddWindow( Window* w )
657 getImpl().AddWindow( w );
660 void MoreButton::RemoveWindow( Window* w )
662 getImpl().RemoveWindow( w );
665 void MoreButton::SetMoreText (rtl::OUString const& text)
667 SetAdvancedText (text);
670 void MoreButton::SetLessText (rtl::OUString const& text)
672 SetSimpleText (text);
675 rtl::OUString MoreButton::GetMoreText () const
677 return GetAdvancedText ();
680 rtl::OUString MoreButton::GetLessText () const
682 return GetSimpleText ();
685 } // namespace layout