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: spinfieldtoolbarcontroller.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
37 #ifndef __FRAMEWORK_UIELEMENT_SPINFIELDTOOLBARCONTROLLER_HXX
38 #include "uielement/spinfieldtoolbarcontroller.hxx"
41 //_________________________________________________________________________________________________________________
43 //_________________________________________________________________________________________________________________
45 #ifndef __FRAMEWORK_TOOLBAR_HXX_
46 #include "uielement/toolbar.hxx"
49 //_________________________________________________________________________________________________________________
51 //_________________________________________________________________________________________________________________
52 #include <com/sun/star/util/XURLTransformer.hpp>
53 #include <com/sun/star/frame/XDispatchProvider.hpp>
54 #include <com/sun/star/beans/PropertyValue.hpp>
55 #include <com/sun/star/lang/DisposedException.hpp>
56 #include <com/sun/star/frame/status/ItemStatus.hpp>
57 #include <com/sun/star/frame/status/ItemState.hpp>
58 #include <com/sun/star/frame/status/Visibility.hpp>
59 #include <com/sun/star/frame/XControlNotificationListener.hpp>
61 //_________________________________________________________________________________________________________________
63 //_________________________________________________________________________________________________________________
64 #include <svtools/toolboxcontroller.hxx>
65 #include <vos/mutex.hxx>
66 #include <vcl/svapp.hxx>
67 #ifndef _VCL_MNEMONIC_HXX_
68 #include <vcl/mnemonic.hxx>
70 #include <tools/urlobj.hxx>
72 #include <systools/win32/snprintf.h>
75 using namespace ::com::sun::star
;
76 using namespace ::com::sun::star::uno
;
77 using namespace ::com::sun::star::beans
;
78 using namespace ::com::sun::star::lang
;
79 using namespace ::com::sun::star::frame
;
80 using namespace ::com::sun::star::frame::status
;
81 using namespace ::com::sun::star::util
;
86 // ------------------------------------------------------------------
88 // Wrapper class to notify controller about events from combobox.
89 // Unfortunaltly the events are notifed through virtual methods instead
92 class SpinfieldControl
: public SpinField
95 SpinfieldControl( Window
* pParent
, WinBits nStyle
, ISpinfieldListener
* pSpinFieldListener
);
96 virtual ~SpinfieldControl();
100 virtual void First();
102 virtual void KeyInput( const ::KeyEvent
& rKEvt
);
103 virtual void Modify();
104 virtual void GetFocus();
105 virtual void LoseFocus();
106 virtual void StateChanged( StateChangedType nType
);
107 virtual void DataChanged( const DataChangedEvent
& rDCEvt
);
108 virtual long PreNotify( NotifyEvent
& rNEvt
);
111 ISpinfieldListener
* m_pSpinFieldListener
;
114 SpinfieldControl::SpinfieldControl( Window
* pParent
, WinBits nStyle
, ISpinfieldListener
* pSpinFieldListener
) :
115 SpinField( pParent
, nStyle
)
116 , m_pSpinFieldListener( pSpinFieldListener
)
120 SpinfieldControl::~SpinfieldControl()
122 m_pSpinFieldListener
= 0;
125 void SpinfieldControl::Up()
128 if ( m_pSpinFieldListener
)
129 m_pSpinFieldListener
->Up();
132 void SpinfieldControl::Down()
135 if ( m_pSpinFieldListener
)
136 m_pSpinFieldListener
->Down();
139 void SpinfieldControl::First()
142 if ( m_pSpinFieldListener
)
143 m_pSpinFieldListener
->First();
146 void SpinfieldControl::Last()
149 if ( m_pSpinFieldListener
)
150 m_pSpinFieldListener
->Last();
153 void SpinfieldControl::KeyInput( const ::KeyEvent
& rKEvt
)
155 SpinField::KeyInput( rKEvt
);
156 if ( m_pSpinFieldListener
)
157 m_pSpinFieldListener
->KeyInput( rKEvt
);
160 void SpinfieldControl::Modify()
163 if ( m_pSpinFieldListener
)
164 m_pSpinFieldListener
->Modify();
167 void SpinfieldControl::GetFocus()
169 SpinField::GetFocus();
170 if ( m_pSpinFieldListener
)
171 m_pSpinFieldListener
->GetFocus();
174 void SpinfieldControl::LoseFocus()
176 SpinField::GetFocus();
177 if ( m_pSpinFieldListener
)
178 m_pSpinFieldListener
->GetFocus();
181 void SpinfieldControl::StateChanged( StateChangedType nType
)
183 SpinField::StateChanged( nType
);
184 if ( m_pSpinFieldListener
)
185 m_pSpinFieldListener
->StateChanged( nType
);
188 void SpinfieldControl::DataChanged( const DataChangedEvent
& rDCEvt
)
190 SpinField::DataChanged( rDCEvt
);
191 if ( m_pSpinFieldListener
)
192 m_pSpinFieldListener
->DataChanged( rDCEvt
);
195 long SpinfieldControl::PreNotify( NotifyEvent
& rNEvt
)
198 if ( m_pSpinFieldListener
)
199 nRet
= m_pSpinFieldListener
->PreNotify( rNEvt
);
201 nRet
= SpinField::PreNotify( rNEvt
);
206 // ------------------------------------------------------------------
208 SpinfieldToolbarController::SpinfieldToolbarController(
209 const Reference
< XMultiServiceFactory
>& rServiceManager
,
210 const Reference
< XFrame
>& rFrame
,
214 const ::rtl::OUString
& aCommand
) :
215 ComplexToolbarController( rServiceManager
, rFrame
, pToolbar
, nID
, aCommand
)
223 , m_pSpinfieldControl( 0 )
225 m_pSpinfieldControl
= new SpinfieldControl( m_pToolbar
, WB_SPIN
|WB_BORDER
, this );
229 // Calculate height of the spin field according to the application font height
230 sal_Int32 nHeight
= getFontSizePixel( m_pSpinfieldControl
) + 5 + 1;
232 m_pSpinfieldControl
->SetSizePixel( ::Size( nWidth
, nHeight
));
233 m_pToolbar
->SetItemWindow( m_nID
, m_pSpinfieldControl
);
236 // ------------------------------------------------------------------
238 SpinfieldToolbarController::~SpinfieldToolbarController()
242 // ------------------------------------------------------------------
244 void SAL_CALL
SpinfieldToolbarController::dispose()
245 throw ( RuntimeException
)
247 vos::OGuard
aSolarMutexGuard( Application::GetSolarMutex() );
249 m_pToolbar
->SetItemWindow( m_nID
, 0 );
250 delete m_pSpinfieldControl
;
252 ComplexToolbarController::dispose();
254 m_pSpinfieldControl
= 0;
257 // ------------------------------------------------------------------
258 Sequence
<PropertyValue
> SpinfieldToolbarController::getExecuteArgs(sal_Int16 KeyModifier
) const
260 Sequence
<PropertyValue
> aArgs( 2 );
261 ::rtl::OUString aSpinfieldText
= m_pSpinfieldControl
->GetText();
263 // Add key modifier to argument list
264 aArgs
[0].Name
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeyModifier" ));
265 aArgs
[0].Value
<<= KeyModifier
;
266 aArgs
[1].Name
= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Value" ));
268 aArgs
[1].Value
<<= aSpinfieldText
.toDouble();
270 aArgs
[1].Value
<<= aSpinfieldText
.toInt32();
274 // ------------------------------------------------------------------
276 void SpinfieldToolbarController::Up()
278 double nValue
= m_nValue
+ m_nStep
;
279 if ( m_bMaxSet
&& nValue
> m_nMax
)
284 rtl::OUString aText
= impl_formatOutputString( m_nValue
);
285 m_pSpinfieldControl
->SetText( aText
);
289 void SpinfieldToolbarController::Down()
291 double nValue
= m_nValue
- m_nStep
;
292 if ( m_bMinSet
&& nValue
< m_nMin
)
297 rtl::OUString aText
= impl_formatOutputString( m_nValue
);
298 m_pSpinfieldControl
->SetText( aText
);
302 void SpinfieldToolbarController::First()
308 rtl::OUString aText
= impl_formatOutputString( m_nValue
);
309 m_pSpinfieldControl
->SetText( aText
);
314 void SpinfieldToolbarController::Last()
320 rtl::OUString aText
= impl_formatOutputString( m_nValue
);
321 m_pSpinfieldControl
->SetText( aText
);
326 void SpinfieldToolbarController::Modify()
328 notifyTextChanged( m_pSpinfieldControl
->GetText() );
331 void SpinfieldToolbarController::KeyInput( const ::KeyEvent
& /*rKEvt*/ )
335 void SpinfieldToolbarController::GetFocus()
340 void SpinfieldToolbarController::LoseFocus()
345 void SpinfieldToolbarController::StateChanged( StateChangedType
/*nType*/ )
349 void SpinfieldToolbarController::DataChanged( const DataChangedEvent
& /*rDCEvt*/ )
353 long SpinfieldToolbarController::PreNotify( NotifyEvent
& rNEvt
)
355 if( rNEvt
.GetType() == EVENT_KEYINPUT
)
357 const ::KeyEvent
* pKeyEvent
= rNEvt
.GetKeyEvent();
358 const KeyCode
& rKeyCode
= pKeyEvent
->GetKeyCode();
359 if(( rKeyCode
.GetModifier() | rKeyCode
.GetCode()) == KEY_RETURN
)
361 // Call execute only with non-empty text
362 if ( m_pSpinfieldControl
->GetText().Len() > 0 )
363 execute( rKeyCode
.GetModifier() );
371 // --------------------------------------------------------
373 void SpinfieldToolbarController::executeControlCommand( const ::com::sun::star::frame::ControlCommand
& rControlCommand
)
375 rtl::OUString aValue
;
379 bool bFloatValue( false );
381 if ( rControlCommand
.Command
.equalsAsciiL( "SetStep", 7 ))
383 for ( sal_Int32 i
= 0; i
< rControlCommand
.Arguments
.getLength(); i
++ )
387 bool bFloat( false );
389 if ( rControlCommand
.Arguments
[i
].Name
.equalsAsciiL( "Step", 4 ))
391 if ( impl_getValue( rControlCommand
.Arguments
[i
].Value
, nValue
, fValue
, bFloat
))
392 aStep
= bFloat
? ::rtl::OUString::valueOf( fValue
) :
393 ::rtl::OUString::valueOf( nValue
);
398 else if ( rControlCommand
.Command
.equalsAsciiL( "SetValue", 8 ))
400 for ( sal_Int32 i
= 0; i
< rControlCommand
.Arguments
.getLength(); i
++ )
402 if ( rControlCommand
.Arguments
[i
].Name
.equalsAsciiL( "Value", 5 ))
406 bool bFloat( false );
408 if ( impl_getValue( rControlCommand
.Arguments
[i
].Value
, nValue
, fValue
, bFloat
))
410 aValue
= bFloat
? ::rtl::OUString::valueOf( fValue
) : ::rtl::OUString::valueOf( nValue
);
411 bFloatValue
= bFloat
;
417 else if ( rControlCommand
.Command
.equalsAsciiL( "SetValues", 9 ))
419 for ( sal_Int32 i
= 0; i
< rControlCommand
.Arguments
.getLength(); i
++ )
423 bool bFloat( false );
425 rtl::OUString aName
= rControlCommand
.Arguments
[i
].Name
;
426 if ( impl_getValue( rControlCommand
.Arguments
[i
].Value
, nValue
, fValue
, bFloat
))
428 if ( aName
.equalsAsciiL( "Value", 5 ))
430 aValue
= bFloat
? ::rtl::OUString::valueOf( fValue
) : ::rtl::OUString::valueOf( nValue
);
431 bFloatValue
= bFloat
;
433 else if ( aName
.equalsAsciiL( "Step", 4 ))
434 aStep
= bFloat
? ::rtl::OUString::valueOf( fValue
) :
435 ::rtl::OUString::valueOf( nValue
);
436 else if ( aName
.equalsAsciiL( "LowerLimit", 10 ))
437 aMin
= bFloat
? ::rtl::OUString::valueOf( fValue
) :
438 ::rtl::OUString::valueOf( nValue
);
439 else if ( aName
.equalsAsciiL( "UpperLimit", 10 ))
440 aMax
= bFloat
? ::rtl::OUString::valueOf( fValue
) :
441 ::rtl::OUString::valueOf( nValue
);
443 else if ( aName
.equalsAsciiL( "OutputFormat", 12 ))
444 rControlCommand
.Arguments
[i
].Value
>>= m_aOutFormat
;
447 else if ( rControlCommand
.Command
.equalsAsciiL( "SetLowerLimit", 13 ))
449 for ( sal_Int32 i
= 0; i
< rControlCommand
.Arguments
.getLength(); i
++ )
453 bool bFloat( false );
455 if ( rControlCommand
.Arguments
[i
].Name
.equalsAsciiL( "LowerLimit", 10 ))
457 if ( impl_getValue( rControlCommand
.Arguments
[i
].Value
, nValue
, fValue
, bFloat
))
458 aMin
= bFloat
? ::rtl::OUString::valueOf( fValue
) :
459 ::rtl::OUString::valueOf( nValue
);
464 else if ( rControlCommand
.Command
.equalsAsciiL( "SetUpperLimit", 13 ))
466 for ( sal_Int32 i
= 0; i
< rControlCommand
.Arguments
.getLength(); i
++ )
470 bool bFloat( false );
472 if ( rControlCommand
.Arguments
[i
].Name
.equalsAsciiL( "UpperLimit", 10 ))
474 if ( impl_getValue( rControlCommand
.Arguments
[i
].Value
, nValue
, fValue
, bFloat
))
475 aMax
= bFloat
? ::rtl::OUString::valueOf( fValue
) :
476 ::rtl::OUString::valueOf( nValue
);
481 else if ( rControlCommand
.Command
.equalsAsciiL( "SetOutputFormat", 15 ))
483 for ( sal_Int32 i
= 0; i
< rControlCommand
.Arguments
.getLength(); i
++ )
485 if ( rControlCommand
.Arguments
[i
].Name
.equalsAsciiL( "OutputFormat", 10 ))
487 rControlCommand
.Arguments
[i
].Value
>>= m_aOutFormat
;
493 // Check values and set members
494 if ( aValue
.getLength() > 0 )
496 m_bFloat
= bFloatValue
;
497 m_nValue
= aValue
.toDouble();
499 rtl::OUString aOutString
= impl_formatOutputString( m_nValue
);
500 m_pSpinfieldControl
->SetText( aOutString
);
501 notifyTextChanged( aOutString
);
503 if ( aMax
.getLength() > 0 )
505 m_nMax
= aMax
.toDouble();
508 if ( aMin
.getLength() > 0 )
510 m_nMin
= aMin
.toDouble();
513 if ( aStep
.getLength() > 0 )
514 m_nStep
= aStep
.toDouble();
517 bool SpinfieldToolbarController::impl_getValue(
518 const Any
& rAny
, sal_Int32
& nValue
, double& fValue
, bool& bFloat
)
520 using ::com::sun::star::uno::TypeClass
;
522 bool bValueValid( false );
525 TypeClass aTypeClass
= rAny
.getValueTypeClass();
526 if (( aTypeClass
== TypeClass( typelib_TypeClass_LONG
)) ||
527 ( aTypeClass
== TypeClass( typelib_TypeClass_SHORT
)) ||
528 ( aTypeClass
== TypeClass( typelib_TypeClass_BYTE
)))
529 bValueValid
= rAny
>>= nValue
;
530 else if (( aTypeClass
== TypeClass( typelib_TypeClass_FLOAT
)) ||
531 ( aTypeClass
== TypeClass( typelib_TypeClass_DOUBLE
)))
533 bValueValid
= rAny
>>= fValue
;
540 rtl::OUString
SpinfieldToolbarController::impl_formatOutputString( double fValue
)
542 if ( m_aOutFormat
.getLength() == 0 )
545 return rtl::OUString::valueOf( fValue
);
547 return rtl::OUString::valueOf( sal_Int32( fValue
));
552 sal_Unicode aBuffer
[128];
556 snwprintf( reinterpret_cast<wchar_t *>(aBuffer
), 128, reinterpret_cast<const wchar_t *>(m_aOutFormat
.getStr()), fValue
);
558 snwprintf( reinterpret_cast<wchar_t *>(aBuffer
), 128, reinterpret_cast<const wchar_t *>(m_aOutFormat
.getStr()), sal_Int32( fValue
));
560 sal_Int32 nSize
= rtl_ustr_getLength( aBuffer
);
561 return rtl::OUString( aBuffer
, nSize
);
563 // Currently we have no support for a format string using sal_Unicode. wchar_t
564 // is 32 bit on Unix platform!
567 ::rtl::OString aFormat
= OUStringToOString( m_aOutFormat
, osl_getThreadTextEncoding() );
569 snprintf( aBuffer
, 128, aFormat
.getStr(), fValue
);
571 snprintf( aBuffer
, 128, aFormat
.getStr(), static_cast<long>( fValue
));
573 sal_Int32 nSize
= strlen( aBuffer
);
574 rtl::OString
aTmp( aBuffer
, nSize
);
575 return rtl::OStringToOUString( aTmp
, osl_getThreadTextEncoding() );