1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #include "tbunocontroller.hxx"
32 
33 #include <com/sun/star/frame/status/FontHeight.hpp>
34 #include <com/sun/star/frame/XDispatchProvider.hpp>
35 #include <com/sun/star/beans/PropertyValue.hpp>
36 
37 #include <vcl/svapp.hxx>
38 #include <vcl/window.hxx>
39 #include <toolkit/helper/vclunohelper.hxx>
40 #include <svtools/ctrltool.hxx>
41 #include <svtools/ctrlbox.hxx>
42 #include <vos/mutex.hxx>
43 
44 #include <memory>
45 
46 #define LOGICAL_EDIT_HEIGHT         12
47 
48 using namespace ::com::sun::star;
49 
50 namespace svx
51 {
52 
53 class FontHeightToolBoxControl;
54 class SvxFontSizeBox_Impl : public FontSizeBox
55 {
56 public:
57                         SvxFontSizeBox_Impl( Window* pParent,
58                                              const uno::Reference< frame::XDispatchProvider >& rDispatchProvider,
59                                              const uno::Reference< frame::XFrame >& _xFrame,
60 										     FontHeightToolBoxControl& rCtrl );
61 
62     void                statusChanged_Impl( long nHeight, bool bErase = false );
63     void                UpdateFont( const ::com::sun::star::awt::FontDescriptor& rCurrentFont );
64 
65     virtual long		Notify( NotifyEvent& rNEvt );
66 
67 protected:
68 	virtual void        Select();
69     virtual void        DataChanged( const DataChangedEvent& rDCEvt );
70 
71 private:
72 	FontHeightToolBoxControl*	               m_pCtrl;
73 	String							           m_aCurText;
74     Size                                       m_aLogicalSize;
75 	sal_Bool							           m_bRelease;
76     uno::Reference< frame::XDispatchProvider > m_xDispatchProvider;
77     uno::Reference< frame::XFrame >            m_xFrame;
78     uno::Reference< awt::XWindow >             m_xOldFocusWindow;
79 
80 	void				ReleaseFocus_Impl();
81 };
82 
83 //========================================================================
84 // class SvxFontSizeBox_Impl --------------------------------------------------
85 //========================================================================
86 
87 SvxFontSizeBox_Impl::SvxFontSizeBox_Impl(
88     Window*                                           _pParent,
89     const uno::Reference< frame::XDispatchProvider >& _rDispatchProvider,
90     const uno::Reference< frame::XFrame >&            _xFrame,
91     FontHeightToolBoxControl&                         _rCtrl ) :
92 
93 	FontSizeBox( _pParent, WinBits( WB_DROPDOWN ) ),
94 
95 	m_pCtrl		        ( &_rCtrl ),
96     m_aLogicalSize      ( 30,100 ),
97 	m_bRelease	        ( sal_True ),
98     m_xDispatchProvider ( _rDispatchProvider ),
99     m_xFrame            ( _xFrame )
100 {
101     SetSizePixel( LogicToPixel( m_aLogicalSize, MAP_APPFONT ));
102 	SetValue( 0 );
103 	SetText( String() );
104 }
105 
106 // -----------------------------------------------------------------------
107 
108 void SvxFontSizeBox_Impl::ReleaseFocus_Impl()
109 {
110 	if ( !m_bRelease )
111 	{
112 		m_bRelease = sal_True;
113 		return;
114     }
115 
116     if ( m_xFrame.is() && m_xFrame->getContainerWindow().is() )
117         m_xFrame->getContainerWindow()->setFocus();
118 }
119 
120 // -----------------------------------------------------------------------
121 
122 void SvxFontSizeBox_Impl::Select()
123 {
124 	FontSizeBox::Select();
125 
126 	if ( !IsTravelSelect() )
127 	{
128 		sal_Int64 nSelVal = GetValue();
129 		float fSelVal     = float( nSelVal ) / 10;
130 
131         uno::Sequence< beans::PropertyValue > aArgs( 1 );
132         aArgs[0].Name  = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FontHeight.Height" ));
133         aArgs[0].Value = uno::makeAny( fSelVal );
134 
135         /*  #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
136             This instance may be deleted in the meantime (i.e. when a dialog is opened
137             while in Dispatch()), accessing members will crash in this case. */
138         ReleaseFocus_Impl();
139 
140         m_pCtrl->dispatchCommand( aArgs );
141 	}
142 }
143 
144 // -----------------------------------------------------------------------
145 
146 void SvxFontSizeBox_Impl::statusChanged_Impl( long nPoint, bool bErase )
147 {
148 	if ( !bErase )
149 	{
150 		// Metric Umrechnen
151         long nVal = nPoint;
152 
153 		// ge"andert => neuen Wert setzen
154 		if ( GetValue() != nVal )
155 			SetValue( nVal );
156 	}
157 	else
158 	{
159 		// Wert in der Anzeige l"oschen
160 		SetValue( -1L );
161 		SetText( String() );
162 	}
163     SaveValue();
164 }
165 
166 // -----------------------------------------------------------------------
167 
168 void SvxFontSizeBox_Impl::UpdateFont( const ::com::sun::star::awt::FontDescriptor& rCurrentFont )
169 {
170 	// Sizes-Liste auff"ullen
171 	sal_Int64 nOldVal = GetValue(); // alten Wert merken
172     const FontList* _pFontList = NULL;
173     ::std::auto_ptr<FontList> aHold( new FontList( this ));
174     _pFontList = aHold.get();
175 
176     if ( rCurrentFont.Name.getLength() > 0 )
177 	{
178         FontInfo _aFontInfo;
179         _aFontInfo.SetName( rCurrentFont.Name );
180         _aFontInfo.SetStyleName( rCurrentFont.StyleName );
181         _aFontInfo.SetHeight( rCurrentFont.Height );
182         Fill( &_aFontInfo, _pFontList );
183 	}
184 	else
185 	{
186 		Fill( NULL, _pFontList );
187 	}
188 	SetValue( nOldVal ); // alten Wert wiederherstellen
189 	m_aCurText = GetText(); // zum R"ucksetzen bei ESC merken
190 }
191 
192 // -----------------------------------------------------------------------
193 
194 long SvxFontSizeBox_Impl::Notify( NotifyEvent& rNEvt )
195 {
196 	long nHandled = 0;
197 
198 	if ( rNEvt.GetType() == EVENT_KEYINPUT )
199 	{
200 		sal_uInt16 nCode = rNEvt.GetKeyEvent()->GetKeyCode().GetCode();
201 
202 		switch ( nCode )
203 		{
204 			case KEY_RETURN:
205 			case KEY_TAB:
206 			{
207 				if ( KEY_TAB == nCode )
208 					m_bRelease = sal_False;
209 				else
210 					nHandled = 1;
211 				Select();
212 				break;
213 			}
214 
215 			case KEY_ESCAPE:
216 				SetText( m_aCurText );
217 				ReleaseFocus_Impl();
218 				nHandled = 1;
219 				break;
220 		}
221 	}
222     else if( EVENT_LOSEFOCUS == rNEvt.GetType() )
223 	{
224 		Window* pFocusWin = Application::GetFocusWindow();
225 		if(!HasFocus() && GetSubEdit() != pFocusWin)
226 			SetText(GetSavedValue());
227 	}
228 
229     return nHandled ? nHandled : FontSizeBox::Notify( rNEvt );
230 }
231 
232 // ---------------------------------------------------------------------------
233 
234 void SvxFontSizeBox_Impl::DataChanged( const DataChangedEvent& rDCEvt )
235 {
236 	if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
237          (rDCEvt.GetFlags() & SETTINGS_STYLE) )
238     {
239         SetSizePixel( LogicToPixel( m_aLogicalSize, MAP_APPFONT ));
240         Size aDropSize( m_aLogicalSize.Width(), LOGICAL_EDIT_HEIGHT );
241         SetDropDownSizePixel( LogicToPixel( aDropSize, MAP_APPFONT ));
242     }
243 
244     FontSizeBox::DataChanged( rDCEvt );
245 }
246 
247 //========================================================================
248 // class FontHeightToolBoxControl
249 //========================================================================
250 
251 FontHeightToolBoxControl::FontHeightToolBoxControl(
252     const uno::Reference< lang::XMultiServiceFactory >& rServiceManager ) :
253     svt::ToolboxController( rServiceManager,
254                             uno::Reference< frame::XFrame >(),
255                             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontHeight" )) ),
256     m_pBox( NULL )
257 {
258     addStatusListener( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:CharFontName" )));
259 }
260 
261 FontHeightToolBoxControl::~FontHeightToolBoxControl()
262 {
263 }
264 
265 // XInterface
266 ::com::sun::star::uno::Any SAL_CALL FontHeightToolBoxControl::queryInterface( const ::com::sun::star::uno::Type& aType )
267 throw (::com::sun::star::uno::RuntimeException)
268 {
269     uno::Any a = ToolboxController::queryInterface( aType );
270     if ( a.hasValue() )
271         return a;
272 
273     return ::cppu::queryInterface( aType, static_cast< lang::XServiceInfo* >( this ));
274 }
275 
276 void SAL_CALL FontHeightToolBoxControl::acquire() throw ()
277 {
278     ToolboxController::acquire();
279 }
280 
281 void SAL_CALL FontHeightToolBoxControl::release() throw ()
282 {
283     ToolboxController::release();
284 }
285 
286 // XServiceInfo
287 sal_Bool SAL_CALL FontHeightToolBoxControl::supportsService( const ::rtl::OUString& ServiceName )
288 throw(uno::RuntimeException)
289 {
290     const uno::Sequence< ::rtl::OUString > aSNL( getSupportedServiceNames() );
291     const ::rtl::OUString * pArray = aSNL.getConstArray();
292 
293     for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
294         if( pArray[i] == ServiceName )
295             return true;
296 
297     return false;
298 }
299 
300 ::rtl::OUString SAL_CALL FontHeightToolBoxControl::getImplementationName()
301 throw( uno::RuntimeException )
302 {
303 	return getImplementationName_Static();
304 }
305 
306 uno::Sequence< ::rtl::OUString > SAL_CALL FontHeightToolBoxControl::getSupportedServiceNames(  )
307 throw( uno::RuntimeException )
308 {
309     return getSupportedServiceNames_Static();
310 }
311 
312 uno::Sequence< ::rtl::OUString > FontHeightToolBoxControl::getSupportedServiceNames_Static()
313 throw()
314 {
315     uno::Sequence< ::rtl::OUString > aSNS( 1 );
316     aSNS.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ToolbarController" ));
317     return aSNS;
318 }
319 
320 // XComponent
321 void SAL_CALL FontHeightToolBoxControl::dispose()
322 throw (uno::RuntimeException)
323 {
324     svt::ToolboxController::dispose();
325 
326     vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
327     delete m_pBox;
328     m_pBox = 0;
329 }
330 
331 // XStatusListener
332 void SAL_CALL FontHeightToolBoxControl::statusChanged(
333     const frame::FeatureStateEvent& rEvent )
334 throw ( uno::RuntimeException )
335 {
336     if ( m_pBox )
337     {
338         vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
339         if ( rEvent.FeatureURL.Path.equalsAscii( "FontHeight" ))
340         {
341 	        if ( rEvent.IsEnabled )
342 	        {
343                 m_pBox->Enable();
344                 frame::status::FontHeight aFontHeight;
345                 if ( rEvent.State >>= aFontHeight )
346                     m_pBox->statusChanged_Impl( long( 10. * aFontHeight.Height ), false );
347                 else
348                     m_pBox->statusChanged_Impl( long( -1 ), true );
349             }
350             else
351                 m_pBox->Disable();
352         }
353         else if ( rEvent.FeatureURL.Path.equalsAscii( "CharFontName" ))
354         {
355             if ( rEvent.State >>= m_aCurrentFont )
356                 m_pBox->UpdateFont( m_aCurrentFont );
357         }
358     }
359 }
360 
361 // XToolbarController
362 void SAL_CALL FontHeightToolBoxControl::execute( sal_Int16 /*KeyModifier*/ )
363 throw (::com::sun::star::uno::RuntimeException)
364 {
365 }
366 
367 void SAL_CALL FontHeightToolBoxControl::click()
368 throw (::com::sun::star::uno::RuntimeException)
369 {
370 }
371 
372 void SAL_CALL FontHeightToolBoxControl::doubleClick()
373 throw (::com::sun::star::uno::RuntimeException)
374 {
375 }
376 
377 uno::Reference< awt::XWindow > SAL_CALL FontHeightToolBoxControl::createPopupWindow()
378 throw (::com::sun::star::uno::RuntimeException)
379 {
380     return uno::Reference< awt::XWindow >();
381 }
382 
383 uno::Reference< awt::XWindow > SAL_CALL FontHeightToolBoxControl::createItemWindow(
384     const uno::Reference< awt::XWindow >& Parent )
385     throw (::com::sun::star::uno::RuntimeException)
386 {
387     uno::Reference< awt::XWindow > xItemWindow;
388     uno::Reference< awt::XWindow > xParent( Parent );
389 
390     Window* pParent = VCLUnoHelper::GetWindow( xParent );
391     if ( pParent )
392     {
393         vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
394         m_pBox = new SvxFontSizeBox_Impl(
395                         pParent,
396                         uno::Reference< frame::XDispatchProvider >( m_xFrame, uno::UNO_QUERY ),
397                         m_xFrame,
398                         *this );
399         xItemWindow = VCLUnoHelper::GetInterface( m_pBox );
400     }
401 
402     return xItemWindow;
403 }
404 
405 void FontHeightToolBoxControl::dispatchCommand(
406     const uno::Sequence< beans::PropertyValue >& rArgs )
407 {
408     uno::Reference< frame::XDispatchProvider > xDispatchProvider( m_xFrame, uno::UNO_QUERY );
409     if ( xDispatchProvider.is() )
410     {
411         util::URL                               aURL;
412         uno::Reference< frame::XDispatch >      xDispatch;
413         uno::Reference< util::XURLTransformer > xURLTransformer = getURLTransformer();
414 
415         aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontHeight" ));
416         xURLTransformer->parseStrict( aURL );
417         xDispatch = xDispatchProvider->queryDispatch( aURL, ::rtl::OUString(), 0 );
418         if ( xDispatch.is() )
419             xDispatch->dispatch( aURL, rArgs );
420     }
421 }
422 
423 uno::Reference< uno::XInterface > SAL_CALL FontHeightToolBoxControl_createInstance(
424     const uno::Reference< lang::XMultiServiceFactory >& rSMgr )
425 {
426 	return *new FontHeightToolBoxControl( rSMgr );
427 }
428 
429 }
430