update dev300-m58
[ooovba.git] / framework / source / uielement / spinfieldtoolbarcontroller.cxx
blob12aa429d8c156f78c88b587f08b3f98c6e669a3e
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 $
10 * $Revision: 1.9 $
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"
34 #include <stdio.h>
35 #include <wchar.h>
37 #ifndef __FRAMEWORK_UIELEMENT_SPINFIELDTOOLBARCONTROLLER_HXX
38 #include "uielement/spinfieldtoolbarcontroller.hxx"
39 #endif
41 //_________________________________________________________________________________________________________________
42 // my own includes
43 //_________________________________________________________________________________________________________________
45 #ifndef __FRAMEWORK_TOOLBAR_HXX_
46 #include "uielement/toolbar.hxx"
47 #endif
49 //_________________________________________________________________________________________________________________
50 // interface includes
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 //_________________________________________________________________________________________________________________
62 // other includes
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>
69 #endif
70 #include <tools/urlobj.hxx>
71 #ifdef WINNT
72 #include <systools/win32/snprintf.h>
73 #endif
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;
83 namespace framework
86 // ------------------------------------------------------------------
88 // Wrapper class to notify controller about events from combobox.
89 // Unfortunaltly the events are notifed through virtual methods instead
90 // of Listeners.
92 class SpinfieldControl : public SpinField
94 public:
95 SpinfieldControl( Window* pParent, WinBits nStyle, ISpinfieldListener* pSpinFieldListener );
96 virtual ~SpinfieldControl();
98 virtual void Up();
99 virtual void Down();
100 virtual void First();
101 virtual void Last();
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 );
110 private:
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()
127 SpinField::Up();
128 if ( m_pSpinFieldListener )
129 m_pSpinFieldListener->Up();
132 void SpinfieldControl::Down()
134 SpinField::Down();
135 if ( m_pSpinFieldListener )
136 m_pSpinFieldListener->Down();
139 void SpinfieldControl::First()
141 SpinField::First();
142 if ( m_pSpinFieldListener )
143 m_pSpinFieldListener->First();
146 void SpinfieldControl::Last()
148 SpinField::First();
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()
162 SpinField::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 )
197 long nRet( 0 );
198 if ( m_pSpinFieldListener )
199 nRet = m_pSpinFieldListener->PreNotify( rNEvt );
200 if ( nRet == 0 )
201 nRet = SpinField::PreNotify( rNEvt );
203 return nRet;
206 // ------------------------------------------------------------------
208 SpinfieldToolbarController::SpinfieldToolbarController(
209 const Reference< XMultiServiceFactory >& rServiceManager,
210 const Reference< XFrame >& rFrame,
211 ToolBox* pToolbar,
212 USHORT nID,
213 sal_Int32 nWidth,
214 const ::rtl::OUString& aCommand ) :
215 ComplexToolbarController( rServiceManager, rFrame, pToolbar, nID, aCommand )
216 , m_bFloat( false )
217 , m_bMaxSet( false )
218 , m_bMinSet( false )
219 , m_nMax( 0.0 )
220 , m_nMin( 0.0 )
221 , m_nValue( 0.0 )
222 , m_nStep( 0.0 )
223 , m_pSpinfieldControl( 0 )
225 m_pSpinfieldControl = new SpinfieldControl( m_pToolbar, WB_SPIN|WB_BORDER, this );
226 if ( nWidth == 0 )
227 nWidth = 100;
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" ));
267 if ( m_bFloat )
268 aArgs[1].Value <<= aSpinfieldText.toDouble();
269 else
270 aArgs[1].Value <<= aSpinfieldText.toInt32();
271 return aArgs;
274 // ------------------------------------------------------------------
276 void SpinfieldToolbarController::Up()
278 double nValue = m_nValue + m_nStep;
279 if ( m_bMaxSet && nValue > m_nMax )
280 return;
282 m_nValue = nValue;
284 rtl::OUString aText = impl_formatOutputString( m_nValue );
285 m_pSpinfieldControl->SetText( aText );
286 execute( 0 );
289 void SpinfieldToolbarController::Down()
291 double nValue = m_nValue - m_nStep;
292 if ( m_bMinSet && nValue < m_nMin )
293 return;
295 m_nValue = nValue;
297 rtl::OUString aText = impl_formatOutputString( m_nValue );
298 m_pSpinfieldControl->SetText( aText );
299 execute( 0 );
302 void SpinfieldToolbarController::First()
304 if ( m_bMinSet )
306 m_nValue = m_nMin;
308 rtl::OUString aText = impl_formatOutputString( m_nValue );
309 m_pSpinfieldControl->SetText( aText );
310 execute( 0 );
314 void SpinfieldToolbarController::Last()
316 if ( m_bMaxSet )
318 m_nValue = m_nMax;
320 rtl::OUString aText = impl_formatOutputString( m_nValue );
321 m_pSpinfieldControl->SetText( aText );
322 execute( 0 );
326 void SpinfieldToolbarController::Modify()
328 notifyTextChanged( m_pSpinfieldControl->GetText() );
331 void SpinfieldToolbarController::KeyInput( const ::KeyEvent& /*rKEvt*/ )
335 void SpinfieldToolbarController::GetFocus()
337 notifyFocusGet();
340 void SpinfieldToolbarController::LoseFocus()
342 notifyFocusLost();
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() );
364 return 1;
368 return 0;
371 // --------------------------------------------------------
373 void SpinfieldToolbarController::executeControlCommand( const ::com::sun::star::frame::ControlCommand& rControlCommand )
375 rtl::OUString aValue;
376 rtl::OUString aMax;
377 rtl::OUString aMin;
378 rtl::OUString aStep;
379 bool bFloatValue( false );
381 if ( rControlCommand.Command.equalsAsciiL( "SetStep", 7 ))
383 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
385 sal_Int32 nValue;
386 double fValue;
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 );
394 break;
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 ))
404 sal_Int32 nValue;
405 double fValue;
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;
413 break;
417 else if ( rControlCommand.Command.equalsAsciiL( "SetValues", 9 ))
419 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
421 sal_Int32 nValue;
422 double fValue;
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++ )
451 sal_Int32 nValue;
452 double fValue;
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 );
460 break;
464 else if ( rControlCommand.Command.equalsAsciiL( "SetUpperLimit", 13 ))
466 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
468 sal_Int32 nValue;
469 double fValue;
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 );
477 break;
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;
488 break;
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();
506 m_bMaxSet = true;
508 if ( aMin.getLength() > 0 )
510 m_nMin = aMin.toDouble();
511 m_bMinSet = true;
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 );
524 bFloat = 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;
534 bFloat = true;
537 return bValueValid;
540 rtl::OUString SpinfieldToolbarController::impl_formatOutputString( double fValue )
542 if ( m_aOutFormat.getLength() == 0 )
544 if ( m_bFloat )
545 return rtl::OUString::valueOf( fValue );
546 else
547 return rtl::OUString::valueOf( sal_Int32( fValue ));
549 else
551 #ifdef WNT
552 sal_Unicode aBuffer[128];
554 aBuffer[0] = 0;
555 if ( m_bFloat )
556 snwprintf( reinterpret_cast<wchar_t *>(aBuffer), 128, reinterpret_cast<const wchar_t *>(m_aOutFormat.getStr()), fValue );
557 else
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 );
562 #else
563 // Currently we have no support for a format string using sal_Unicode. wchar_t
564 // is 32 bit on Unix platform!
565 char aBuffer[128];
567 ::rtl::OString aFormat = OUStringToOString( m_aOutFormat, osl_getThreadTextEncoding() );
568 if ( m_bFloat )
569 snprintf( aBuffer, 128, aFormat.getStr(), fValue );
570 else
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() );
576 #endif
580 } // namespace