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 <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>
52 #include <layout/core/helper.hxx>
54 using namespace ::com::sun::star
;
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
) )
85 class ButtonImpl
: public ControlImpl
86 , public ::cppu::WeakImplHelper1
< awt::XActionListener
>
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 );
104 virtual void Click() { /* make me pure virtual? */ };
111 virtual void SetClickHdl( Link
const& link
)
116 void SAL_CALL
disposing( lang::EventObject
const& e
)
117 throw (uno::RuntimeException
)
119 mxButton
->removeActionListener( this );
120 ControlImpl::disposing (e
);
124 virtual void SAL_CALL
actionPerformed( const awt::ActionEvent
& )
125 throw (uno::RuntimeException
)
130 maClickHdl
.Call( static_cast<Window
*>( mpWindow
) );
133 bool SetModeImage( uno::Reference
< graphic::XGraphic
> xGraph
)
135 setProperty( "Graphic", uno::Any( xGraph
) );
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() )
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
) );
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
>
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 );
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
);
221 virtual void SAL_CALL
itemStateChanged( const awt::ItemEvent
& )
222 throw (uno::RuntimeException
)
224 maToggleHdl
.Call( static_cast<Window
*>( mpWindow
) );
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()
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
>
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() )
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
);
291 mxRadioButton
->setState( !!bCheck
);
298 if ( !mxRadioButton
.is() )
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 );
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
>
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 );
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() )
414 getImpl().mxCheckBox
->setState( !!bCheck
);
417 bool CheckBox::IsChecked() const
419 if ( !getImpl().mxCheckBox
.is() )
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 \
437 t##Impl( Context *context, PeerHandle const& peer, Window *window ) \
438 : parent##Impl( context, peer, window ) \
443 if (Dialog *d = static_cast<Dialog *> (mpCtx)) \
444 d->EndDialog( response ); \
448 /* Common button types currently unavailable in OOo: */
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
486 std::list
< Window
*> maAdvanced
;
487 std::list
< Window
*> maSimple
;
490 rtl::OUString mAdvancedLabel
;
491 rtl::OUString mSimpleLabel
;
494 Window
* Remove( std::list
< Window
*> lst
, Window
* w
)
496 for ( std::list
< Window
*>::iterator it
= maAdvanced
.begin();
497 it
!= maAdvanced
.end(); it
++ )
507 AdvancedButtonImpl( Context
*context
, PeerHandle
const& peer
, Window
*window
)
508 : PushButtonImpl( context
, peer
, window
)
509 , bAdvancedMode( false )
511 // Button::GetStandardText( BUTTON_ADVANCED );
512 // Button::GetStandardText( BUTTON_SIMPLE );
513 , mAdvancedLabel( rtl::OUString::createFromAscii( "Advanced..." ) )
514 , mSimpleLabel( rtl::OUString::createFromAscii( "Simple..." ) )
519 bAdvancedMode
= !bAdvancedMode
;
527 ::PushButton
*b
= static_cast<PushButton
*> (mpWindow
)->GetPushButton ();
528 b
->SetSymbolAlign (SYMBOLALIGN_RIGHT
);
529 b
->SetSmallSymbol ();
530 //mpWindow->SetStyle (mpWindow->GetStyle() | WB_CENTER);
534 ::PushButton
*b
= static_cast<PushButton
*> (mpWindow
)->GetPushButton ();
535 b
->SetSymbol (SYMBOL_PAGEUP
);
537 if (mSimpleLabel
.getLength ())
538 b
->SetText (mSimpleLabel
);
539 for ( std::list
< Window
*>::iterator it
= maAdvanced
.begin();
540 it
!= maAdvanced
.end(); it
++ )
542 for ( std::list
< Window
*>::iterator it
= maSimple
.begin();
543 it
!= maSimple
.end(); it
++ )
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
);
556 for ( std::list
< Window
*>::iterator it
= maAdvanced
.begin();
557 it
!= maAdvanced
.end(); it
++ )
559 for ( std::list
< Window
*>::iterator it
= maSimple
.begin();
560 it
!= maSimple
.end(); it
++ )
565 void AddAdvanced( Window
* w
)
567 maAdvanced
.push_back( w
);
568 if ( !bAdvancedMode
)
571 void AddSimple( Window
* w
)
573 maSimple
.push_back( w
);
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
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
); }
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