fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / framework / source / uielement / spinfieldtoolbarcontroller.cxx
blob3d60f613e000afb823974314fd31346e1b36b760
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <stdio.h>
21 #include <wchar.h>
23 #include "uielement/spinfieldtoolbarcontroller.hxx"
25 #include <com/sun/star/util/XURLTransformer.hpp>
26 #include <com/sun/star/frame/XDispatchProvider.hpp>
27 #include <com/sun/star/beans/PropertyValue.hpp>
28 #include <com/sun/star/frame/status/ItemStatus.hpp>
29 #include <com/sun/star/frame/status/ItemState.hpp>
30 #include <com/sun/star/frame/status/Visibility.hpp>
31 #include <com/sun/star/frame/XControlNotificationListener.hpp>
33 #include <svtools/toolboxcontroller.hxx>
34 #include <osl/mutex.hxx>
35 #include <vcl/svapp.hxx>
36 #include <vcl/mnemonic.hxx>
37 #include <vcl/toolbox.hxx>
38 #ifdef WINNT
39 #include <systools/win32/snprintf.h>
40 #endif
42 using namespace ::com::sun::star;
43 using namespace ::com::sun::star::uno;
44 using namespace ::com::sun::star::beans;
45 using namespace ::com::sun::star::lang;
46 using namespace ::com::sun::star::frame;
47 using namespace ::com::sun::star::frame::status;
48 using namespace ::com::sun::star::util;
50 namespace framework
53 // Wrapper class to notify controller about events from combobox.
54 // Unfortunaltly the events are notifed through virtual methods instead
55 // of Listeners.
57 class SpinfieldControl : public SpinField
59 public:
60 SpinfieldControl( vcl::Window* pParent, WinBits nStyle, ISpinfieldListener* pSpinFieldListener );
61 virtual ~SpinfieldControl();
62 virtual void dispose() SAL_OVERRIDE;
64 virtual void Up() SAL_OVERRIDE;
65 virtual void Down() SAL_OVERRIDE;
66 virtual void First() SAL_OVERRIDE;
67 virtual void Last() SAL_OVERRIDE;
68 virtual void KeyInput( const ::KeyEvent& rKEvt ) SAL_OVERRIDE;
69 virtual void Modify() SAL_OVERRIDE;
70 virtual void GetFocus() SAL_OVERRIDE;
71 virtual void LoseFocus() SAL_OVERRIDE;
72 virtual void StateChanged( StateChangedType nType ) SAL_OVERRIDE;
73 virtual void DataChanged( const DataChangedEvent& rDCEvt ) SAL_OVERRIDE;
74 virtual bool PreNotify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
76 private:
77 ISpinfieldListener* m_pSpinFieldListener;
80 SpinfieldControl::SpinfieldControl( vcl::Window* pParent, WinBits nStyle, ISpinfieldListener* pSpinFieldListener ) :
81 SpinField( pParent, nStyle )
82 , m_pSpinFieldListener( pSpinFieldListener )
86 SpinfieldControl::~SpinfieldControl()
88 disposeOnce();
91 void SpinfieldControl::dispose()
93 m_pSpinFieldListener = 0;
94 SpinField::dispose();
97 void SpinfieldControl::Up()
99 SpinField::Up();
100 if ( m_pSpinFieldListener )
101 m_pSpinFieldListener->Up();
104 void SpinfieldControl::Down()
106 SpinField::Down();
107 if ( m_pSpinFieldListener )
108 m_pSpinFieldListener->Down();
111 void SpinfieldControl::First()
113 SpinField::First();
114 if ( m_pSpinFieldListener )
115 m_pSpinFieldListener->First();
118 void SpinfieldControl::Last()
120 SpinField::First();
121 if ( m_pSpinFieldListener )
122 m_pSpinFieldListener->Last();
125 void SpinfieldControl::KeyInput( const ::KeyEvent& rKEvt )
127 SpinField::KeyInput( rKEvt );
128 if ( m_pSpinFieldListener )
129 m_pSpinFieldListener->KeyInput( rKEvt );
132 void SpinfieldControl::Modify()
134 SpinField::Modify();
135 if ( m_pSpinFieldListener )
136 m_pSpinFieldListener->Modify();
139 void SpinfieldControl::GetFocus()
141 SpinField::GetFocus();
142 if ( m_pSpinFieldListener )
143 m_pSpinFieldListener->GetFocus();
146 void SpinfieldControl::LoseFocus()
148 SpinField::GetFocus();
149 if ( m_pSpinFieldListener )
150 m_pSpinFieldListener->GetFocus();
153 void SpinfieldControl::StateChanged( StateChangedType nType )
155 SpinField::StateChanged( nType );
156 if ( m_pSpinFieldListener )
157 m_pSpinFieldListener->StateChanged( nType );
160 void SpinfieldControl::DataChanged( const DataChangedEvent& rDCEvt )
162 SpinField::DataChanged( rDCEvt );
163 if ( m_pSpinFieldListener )
164 m_pSpinFieldListener->DataChanged( rDCEvt );
167 bool SpinfieldControl::PreNotify( NotifyEvent& rNEvt )
169 bool nRet = false;
170 if ( m_pSpinFieldListener )
171 nRet = m_pSpinFieldListener->PreNotify( rNEvt );
172 if ( !nRet )
173 nRet = SpinField::PreNotify( rNEvt );
175 return nRet;
178 SpinfieldToolbarController::SpinfieldToolbarController(
179 const Reference< XComponentContext >& rxContext,
180 const Reference< XFrame >& rFrame,
181 ToolBox* pToolbar,
182 sal_uInt16 nID,
183 sal_Int32 nWidth,
184 const OUString& aCommand ) :
185 ComplexToolbarController( rxContext, rFrame, pToolbar, nID, aCommand )
186 , m_bFloat( false )
187 , m_bMaxSet( false )
188 , m_bMinSet( false )
189 , m_nMax( 0.0 )
190 , m_nMin( 0.0 )
191 , m_nValue( 0.0 )
192 , m_nStep( 0.0 )
193 , m_pSpinfieldControl( 0 )
195 m_pSpinfieldControl = VclPtr<SpinfieldControl>::Create( m_pToolbar, WB_SPIN|WB_BORDER, this );
196 if ( nWidth == 0 )
197 nWidth = 100;
199 // Calculate height of the spin field according to the application font height
200 sal_Int32 nHeight = getFontSizePixel( m_pSpinfieldControl ) + 5 + 1;
202 m_pSpinfieldControl->SetSizePixel( ::Size( nWidth, nHeight ));
203 m_pToolbar->SetItemWindow( m_nID, m_pSpinfieldControl );
206 SpinfieldToolbarController::~SpinfieldToolbarController()
210 void SAL_CALL SpinfieldToolbarController::dispose()
211 throw ( RuntimeException, std::exception )
213 SolarMutexGuard aSolarMutexGuard;
215 m_pToolbar->SetItemWindow( m_nID, 0 );
216 m_pSpinfieldControl.disposeAndClear();
218 ComplexToolbarController::dispose();
221 Sequence<PropertyValue> SpinfieldToolbarController::getExecuteArgs(sal_Int16 KeyModifier) const
223 Sequence<PropertyValue> aArgs( 2 );
224 OUString aSpinfieldText = m_pSpinfieldControl->GetText();
226 // Add key modifier to argument list
227 aArgs[0].Name = "KeyModifier";
228 aArgs[0].Value <<= KeyModifier;
229 aArgs[1].Name = "Value";
230 if ( m_bFloat )
231 aArgs[1].Value <<= aSpinfieldText.toDouble();
232 else
233 aArgs[1].Value <<= aSpinfieldText.toInt32();
234 return aArgs;
237 void SpinfieldToolbarController::Up()
239 double nValue = m_nValue + m_nStep;
240 if ( m_bMaxSet && nValue > m_nMax )
241 return;
243 m_nValue = nValue;
245 OUString aText = impl_formatOutputString( m_nValue );
246 m_pSpinfieldControl->SetText( aText );
247 execute( 0 );
250 void SpinfieldToolbarController::Down()
252 double nValue = m_nValue - m_nStep;
253 if ( m_bMinSet && nValue < m_nMin )
254 return;
256 m_nValue = nValue;
258 OUString aText = impl_formatOutputString( m_nValue );
259 m_pSpinfieldControl->SetText( aText );
260 execute( 0 );
263 void SpinfieldToolbarController::First()
265 if ( m_bMinSet )
267 m_nValue = m_nMin;
269 OUString aText = impl_formatOutputString( m_nValue );
270 m_pSpinfieldControl->SetText( aText );
271 execute( 0 );
275 void SpinfieldToolbarController::Last()
277 if ( m_bMaxSet )
279 m_nValue = m_nMax;
281 OUString aText = impl_formatOutputString( m_nValue );
282 m_pSpinfieldControl->SetText( aText );
283 execute( 0 );
287 void SpinfieldToolbarController::Modify()
289 notifyTextChanged( m_pSpinfieldControl->GetText() );
292 void SpinfieldToolbarController::KeyInput( const ::KeyEvent& /*rKEvt*/ )
296 void SpinfieldToolbarController::GetFocus()
298 notifyFocusGet();
301 void SpinfieldToolbarController::LoseFocus()
303 notifyFocusLost();
306 void SpinfieldToolbarController::StateChanged( StateChangedType /*nType*/ )
310 void SpinfieldToolbarController::DataChanged( const DataChangedEvent& /*rDCEvt*/ )
314 bool SpinfieldToolbarController::PreNotify( NotifyEvent& rNEvt )
316 if( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
318 const ::KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
319 const vcl::KeyCode& rKeyCode = pKeyEvent->GetKeyCode();
320 if(( rKeyCode.GetModifier() | rKeyCode.GetCode()) == KEY_RETURN )
322 // Call execute only with non-empty text
323 if ( !m_pSpinfieldControl->GetText().isEmpty() )
324 execute( rKeyCode.GetModifier() );
325 return true;
329 return false;
332 void SpinfieldToolbarController::executeControlCommand( const ::com::sun::star::frame::ControlCommand& rControlCommand )
334 OUString aValue;
335 OUString aMax;
336 OUString aMin;
337 OUString aStep;
338 bool bFloatValue( false );
340 if ( rControlCommand.Command == "SetStep" )
342 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
344 if ( rControlCommand.Arguments[i].Name == "Step" )
346 sal_Int32 nValue;
347 double fValue;
348 bool bFloat( false );
349 if ( impl_getValue( rControlCommand.Arguments[i].Value, nValue, fValue, bFloat ))
350 aStep = bFloat ? OUString::number( fValue ) :
351 OUString::number( nValue );
352 break;
356 else if ( rControlCommand.Command == "SetValue" )
358 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
360 if ( rControlCommand.Arguments[i].Name == "Value" )
362 sal_Int32 nValue;
363 double fValue;
364 bool bFloat( false );
366 if ( impl_getValue( rControlCommand.Arguments[i].Value, nValue, fValue, bFloat ))
368 aValue = bFloat ? OUString::number( fValue ) : OUString::number( nValue );
369 bFloatValue = bFloat;
371 break;
375 else if ( rControlCommand.Command == "SetValues" )
377 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
379 sal_Int32 nValue;
380 double fValue;
381 bool bFloat( false );
383 OUString aName = rControlCommand.Arguments[i].Name;
384 if ( impl_getValue( rControlCommand.Arguments[i].Value, nValue, fValue, bFloat ))
386 if ( aName == "Value" )
388 aValue = bFloat ? OUString::number( fValue ) : OUString::number( nValue );
389 bFloatValue = bFloat;
391 else if ( aName == "Step" )
392 aStep = bFloat ? OUString::number( fValue ) :
393 OUString::number( nValue );
394 else if ( aName == "LowerLimit" )
395 aMin = bFloat ? OUString::number( fValue ) :
396 OUString::number( nValue );
397 else if ( aName == "UpperLimit" )
398 aMax = bFloat ? OUString::number( fValue ) :
399 OUString::number( nValue );
401 else if ( aName == "OutputFormat" )
402 rControlCommand.Arguments[i].Value >>= m_aOutFormat;
405 else if ( rControlCommand.Command == "SetLowerLimit" )
407 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
409 if ( rControlCommand.Arguments[i].Name == "LowerLimit" )
411 sal_Int32 nValue;
412 double fValue;
413 bool bFloat( false );
414 if ( impl_getValue( rControlCommand.Arguments[i].Value, nValue, fValue, bFloat ))
415 aMin = bFloat ? OUString::number( fValue ) :
416 OUString::number( nValue );
417 break;
421 else if ( rControlCommand.Command == "SetUpperLimit" )
423 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
425 if ( rControlCommand.Arguments[i].Name == "UpperLimit" )
427 sal_Int32 nValue;
428 double fValue;
429 bool bFloat( false );
430 if ( impl_getValue( rControlCommand.Arguments[i].Value, nValue, fValue, bFloat ))
431 aMax = bFloat ? OUString::number( fValue ) :
432 OUString::number( nValue );
433 break;
437 else if ( rControlCommand.Command == "SetOutputFormat" )
439 for ( sal_Int32 i = 0; i < rControlCommand.Arguments.getLength(); i++ )
441 if ( rControlCommand.Arguments[i].Name == "OutputFormat" )
443 rControlCommand.Arguments[i].Value >>= m_aOutFormat;
444 break;
449 // Check values and set members
450 if ( !aValue.isEmpty() )
452 m_bFloat = bFloatValue;
453 m_nValue = aValue.toDouble();
455 OUString aOutString = impl_formatOutputString( m_nValue );
456 m_pSpinfieldControl->SetText( aOutString );
457 notifyTextChanged( aOutString );
459 if ( !aMax.isEmpty() )
461 m_nMax = aMax.toDouble();
462 m_bMaxSet = true;
464 if ( !aMin.isEmpty() )
466 m_nMin = aMin.toDouble();
467 m_bMinSet = true;
469 if ( !aStep.isEmpty() )
470 m_nStep = aStep.toDouble();
473 bool SpinfieldToolbarController::impl_getValue(
474 const Any& rAny, sal_Int32& nValue, double& fValue, bool& bFloat )
476 using ::com::sun::star::uno::TypeClass;
478 bool bValueValid( false );
480 bFloat = false;
481 TypeClass aTypeClass = rAny.getValueTypeClass();
482 if (( aTypeClass == TypeClass( typelib_TypeClass_LONG )) ||
483 ( aTypeClass == TypeClass( typelib_TypeClass_SHORT )) ||
484 ( aTypeClass == TypeClass( typelib_TypeClass_BYTE )))
485 bValueValid = rAny >>= nValue;
486 else if (( aTypeClass == TypeClass( typelib_TypeClass_FLOAT )) ||
487 ( aTypeClass == TypeClass( typelib_TypeClass_DOUBLE )))
489 bValueValid = rAny >>= fValue;
490 bFloat = true;
493 return bValueValid;
496 OUString SpinfieldToolbarController::impl_formatOutputString( double fValue )
498 if ( m_aOutFormat.isEmpty() )
500 if ( m_bFloat )
501 return OUString::number( fValue );
502 else
503 return OUString::number( sal_Int32( fValue ));
505 else
507 #ifdef WNT
508 sal_Unicode aBuffer[128];
510 aBuffer[0] = 0;
511 if ( m_bFloat )
512 snwprintf( reinterpret_cast<wchar_t *>(aBuffer), 128, reinterpret_cast<const wchar_t *>(m_aOutFormat.getStr()), fValue );
513 else
514 snwprintf( reinterpret_cast<wchar_t *>(aBuffer), 128, reinterpret_cast<const wchar_t *>(m_aOutFormat.getStr()), sal_Int32( fValue ));
516 sal_Int32 nSize = rtl_ustr_getLength( aBuffer );
517 return OUString( aBuffer, nSize );
518 #else
519 // Currently we have no support for a format string using sal_Unicode. wchar_t
520 // is 32 bit on Unix platform!
521 char aBuffer[128];
523 OString aFormat = OUStringToOString( m_aOutFormat, osl_getThreadTextEncoding() );
524 if ( m_bFloat )
525 snprintf( aBuffer, 128, aFormat.getStr(), fValue );
526 else
527 snprintf( aBuffer, 128, aFormat.getStr(), static_cast<long>( fValue ));
529 sal_Int32 nSize = strlen( aBuffer );
530 OString aTmp( aBuffer, nSize );
531 return OStringToOUString( aTmp, osl_getThreadTextEncoding() );
532 #endif
536 } // namespace
538 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */