Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <com/sun/star/awt/FontDescriptor.hpp>
21 : #include <com/sun/star/frame/status/FontHeight.hpp>
22 : #include <com/sun/star/frame/XDispatchProvider.hpp>
23 : #include <com/sun/star/beans/PropertyValue.hpp>
24 : #include <com/sun/star/lang/XServiceInfo.hpp>
25 :
26 : #include <rtl/ref.hxx>
27 : #include <vcl/svapp.hxx>
28 : #include <vcl/window.hxx>
29 : #include <vcl/settings.hxx>
30 : #include <toolkit/helper/vclunohelper.hxx>
31 : #include <svtools/ctrltool.hxx>
32 : #include <svtools/ctrlbox.hxx>
33 : #include <svtools/toolboxcontroller.hxx>
34 : #include <osl/mutex.hxx>
35 : #include <comphelper/processfactory.hxx>
36 : #include <cppuhelper/supportsservice.hxx>
37 :
38 : #include <boost/scoped_ptr.hpp>
39 :
40 : #define LOGICAL_EDIT_HEIGHT 12
41 :
42 : using namespace ::com::sun::star;
43 :
44 : namespace {
45 :
46 : class SvxFontSizeBox_Impl;
47 : class FontHeightToolBoxControl : public svt::ToolboxController,
48 : public lang::XServiceInfo
49 : {
50 : public:
51 : FontHeightToolBoxControl(
52 : const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >& rServiceManager );
53 : virtual ~FontHeightToolBoxControl();
54 :
55 : // XInterface
56 : virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
57 : virtual void SAL_CALL acquire() throw () SAL_OVERRIDE;
58 : virtual void SAL_CALL release() throw () SAL_OVERRIDE;
59 :
60 : // XServiceInfo
61 : virtual OUString SAL_CALL getImplementationName() throw( ::com::sun::star::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
62 : virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw( ::com::sun::star::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
63 : virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() throw( ::com::sun::star::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
64 :
65 : // XComponent
66 : virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
67 :
68 : // XStatusListener
69 : virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
70 :
71 : // XToolbarController
72 : virtual void SAL_CALL execute( sal_Int16 KeyModifier ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
73 : virtual void SAL_CALL click() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
74 : virtual void SAL_CALL doubleClick() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
75 : virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > SAL_CALL createPopupWindow() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
76 : virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > SAL_CALL createItemWindow( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& Parent ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
77 :
78 : void dispatchCommand( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rArgs );
79 : using svt::ToolboxController::dispatchCommand;
80 :
81 : private:
82 : SvxFontSizeBox_Impl* m_pBox;
83 : ::com::sun::star::awt::FontDescriptor m_aCurrentFont;
84 : };
85 :
86 3896 : class SvxFontSizeBox_Impl : public FontSizeBox
87 : {
88 : public:
89 : SvxFontSizeBox_Impl( vcl::Window* pParent,
90 : const uno::Reference< frame::XDispatchProvider >& rDispatchProvider,
91 : const uno::Reference< frame::XFrame >& _xFrame,
92 : FontHeightToolBoxControl& rCtrl );
93 :
94 : void statusChanged_Impl( long nHeight, bool bErase = false );
95 : void UpdateFont( const ::com::sun::star::awt::FontDescriptor& rCurrentFont );
96 : void SetOptimalSize();
97 :
98 : virtual bool Notify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
99 :
100 : protected:
101 : virtual void Select() SAL_OVERRIDE;
102 : virtual void DataChanged( const DataChangedEvent& rDCEvt ) SAL_OVERRIDE;
103 :
104 : private:
105 : FontHeightToolBoxControl* m_pCtrl;
106 : OUString m_aCurText;
107 : Size m_aLogicalSize;
108 : bool m_bRelease;
109 : uno::Reference< frame::XDispatchProvider > m_xDispatchProvider;
110 : uno::Reference< frame::XFrame > m_xFrame;
111 : uno::Reference< awt::XWindow > m_xOldFocusWindow;
112 :
113 : void ReleaseFocus_Impl();
114 : };
115 :
116 1948 : SvxFontSizeBox_Impl::SvxFontSizeBox_Impl(
117 : vcl::Window* _pParent,
118 : const uno::Reference< frame::XDispatchProvider >& _rDispatchProvider,
119 : const uno::Reference< frame::XFrame >& _xFrame,
120 : FontHeightToolBoxControl& _rCtrl ) :
121 :
122 : FontSizeBox( _pParent, WinBits( WB_DROPDOWN ) ),
123 :
124 : m_pCtrl ( &_rCtrl ),
125 : m_aLogicalSize ( 0,100 ),
126 : m_bRelease ( true ),
127 : m_xDispatchProvider ( _rDispatchProvider ),
128 1948 : m_xFrame ( _xFrame )
129 : {
130 1948 : SetValue( 0 );
131 1948 : SetText( "" );
132 1948 : }
133 :
134 :
135 :
136 0 : void SvxFontSizeBox_Impl::ReleaseFocus_Impl()
137 : {
138 0 : if ( !m_bRelease )
139 : {
140 0 : m_bRelease = true;
141 0 : return;
142 : }
143 :
144 0 : if ( m_xFrame.is() && m_xFrame->getContainerWindow().is() )
145 0 : m_xFrame->getContainerWindow()->setFocus();
146 : }
147 :
148 :
149 :
150 0 : void SvxFontSizeBox_Impl::Select()
151 : {
152 0 : FontSizeBox::Select();
153 :
154 0 : if ( !IsTravelSelect() )
155 : {
156 0 : sal_Int64 nSelVal = GetValue();
157 0 : float fSelVal = float( nSelVal ) / 10;
158 :
159 0 : uno::Sequence< beans::PropertyValue > aArgs( 1 );
160 0 : aArgs[0].Name = "FontHeight.Height";
161 0 : aArgs[0].Value = uno::makeAny( fSelVal );
162 :
163 : /* #i33380# DR 2004-09-03 Moved the following line above the Dispatch() call.
164 : This instance may be deleted in the meantime (i.e. when a dialog is opened
165 : while in Dispatch()), accessing members will crash in this case. */
166 0 : ReleaseFocus_Impl();
167 :
168 0 : m_pCtrl->dispatchCommand( aArgs );
169 : }
170 0 : }
171 :
172 :
173 :
174 2058 : void SvxFontSizeBox_Impl::statusChanged_Impl( long nPoint, bool bErase )
175 : {
176 2058 : if ( !bErase )
177 : {
178 : // Metric Umrechnen
179 2058 : long nVal = nPoint;
180 :
181 : // ge"andert => neuen Wert setzen
182 2058 : if ( GetValue() != nVal )
183 1682 : SetValue( nVal );
184 : }
185 : else
186 : {
187 : // Wert in der Anzeige l"oschen
188 0 : SetValue( -1L );
189 0 : SetText( "" );
190 : }
191 2058 : SaveValue();
192 2058 : }
193 :
194 :
195 :
196 4006 : void SvxFontSizeBox_Impl::UpdateFont( const ::com::sun::star::awt::FontDescriptor& rCurrentFont )
197 : {
198 : // Sizes-Liste auff"ullen
199 4006 : sal_Int64 nOldVal = GetValue(); // alten Wert merken
200 4006 : const FontList* _pFontList = NULL;
201 4006 : boost::scoped_ptr<FontList> aHold( new FontList( this ));
202 4006 : _pFontList = aHold.get();
203 :
204 4006 : if ( !rCurrentFont.Name.isEmpty() )
205 : {
206 2058 : vcl::FontInfo _aFontInfo;
207 2058 : _aFontInfo.SetName( rCurrentFont.Name );
208 2058 : _aFontInfo.SetStyleName( rCurrentFont.StyleName );
209 2058 : _aFontInfo.SetHeight( rCurrentFont.Height );
210 2058 : Fill( &_aFontInfo, _pFontList );
211 : }
212 : else
213 : {
214 1948 : Fill( NULL, _pFontList );
215 : }
216 4006 : SetValue( nOldVal ); // alten Wert wiederherstellen
217 4006 : m_aCurText = GetText(); // zum R"ucksetzen bei ESC merken
218 4006 : }
219 :
220 :
221 :
222 0 : bool SvxFontSizeBox_Impl::Notify( NotifyEvent& rNEvt )
223 : {
224 0 : bool nHandled = false;
225 :
226 0 : if ( rNEvt.GetType() == EVENT_KEYINPUT )
227 : {
228 0 : sal_uInt16 nCode = rNEvt.GetKeyEvent()->GetKeyCode().GetCode();
229 :
230 0 : switch ( nCode )
231 : {
232 : case KEY_RETURN:
233 : case KEY_TAB:
234 : {
235 0 : if ( KEY_TAB == nCode )
236 0 : m_bRelease = false;
237 : else
238 0 : nHandled = true;
239 0 : Select();
240 0 : break;
241 : }
242 :
243 : case KEY_ESCAPE:
244 0 : SetText( m_aCurText );
245 0 : ReleaseFocus_Impl();
246 0 : nHandled = true;
247 0 : break;
248 : }
249 : }
250 0 : else if( EVENT_LOSEFOCUS == rNEvt.GetType() )
251 : {
252 0 : vcl::Window* pFocusWin = Application::GetFocusWindow();
253 0 : if(!HasFocus() && GetSubEdit() != pFocusWin)
254 0 : SetText(GetSavedValue());
255 : }
256 :
257 0 : return nHandled || FontSizeBox::Notify( rNEvt );
258 : }
259 :
260 1948 : void SvxFontSizeBox_Impl::SetOptimalSize()
261 : {
262 1948 : Size aPrefSize(LogicToPixel(m_aLogicalSize, MAP_APPFONT));
263 1948 : aPrefSize.Width() = get_preferred_size().Width();
264 1948 : SetSizePixel(aPrefSize);
265 1948 : Size aDropSize(LogicToPixel(Size(0, LOGICAL_EDIT_HEIGHT), MAP_APPFONT));
266 1948 : aDropSize.Width() = aPrefSize.Width();
267 1948 : SetDropDownSizePixel(aDropSize);
268 1948 : }
269 :
270 :
271 :
272 0 : void SvxFontSizeBox_Impl::DataChanged( const DataChangedEvent& rDCEvt )
273 : {
274 0 : if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
275 0 : (rDCEvt.GetFlags() & SETTINGS_STYLE) )
276 : {
277 0 : SetOptimalSize();
278 : }
279 :
280 0 : FontSizeBox::DataChanged( rDCEvt );
281 0 : }
282 :
283 1948 : FontHeightToolBoxControl::FontHeightToolBoxControl( const uno::Reference< uno::XComponentContext >& rxContext )
284 : : svt::ToolboxController( rxContext,
285 : uno::Reference< frame::XFrame >(),
286 : OUString( ".uno:FontHeight" ) ),
287 1948 : m_pBox( NULL )
288 : {
289 1948 : addStatusListener( OUString( ".uno:CharFontName" ));
290 1948 : }
291 :
292 3896 : FontHeightToolBoxControl::~FontHeightToolBoxControl()
293 : {
294 3896 : }
295 :
296 : // XInterface
297 18678 : ::com::sun::star::uno::Any SAL_CALL FontHeightToolBoxControl::queryInterface( const ::com::sun::star::uno::Type& aType )
298 : throw (::com::sun::star::uno::RuntimeException, std::exception)
299 : {
300 18678 : uno::Any a = ToolboxController::queryInterface( aType );
301 18678 : if ( a.hasValue() )
302 17468 : return a;
303 :
304 1210 : return ::cppu::queryInterface( aType, static_cast< lang::XServiceInfo* >( this ));
305 : }
306 :
307 70945 : void SAL_CALL FontHeightToolBoxControl::acquire() throw ()
308 : {
309 70945 : ToolboxController::acquire();
310 70945 : }
311 :
312 70945 : void SAL_CALL FontHeightToolBoxControl::release() throw ()
313 : {
314 70945 : ToolboxController::release();
315 70945 : }
316 :
317 : // XServiceInfo
318 0 : sal_Bool SAL_CALL FontHeightToolBoxControl::supportsService( const OUString& ServiceName )
319 : throw(uno::RuntimeException, std::exception)
320 : {
321 0 : return cppu::supportsService(this, ServiceName);
322 : }
323 :
324 0 : OUString SAL_CALL FontHeightToolBoxControl::getImplementationName()
325 : throw( uno::RuntimeException, std::exception )
326 : {
327 0 : return OUString("com.sun.star.svx.FontHeightToolBoxController");
328 : }
329 :
330 0 : uno::Sequence< OUString > SAL_CALL FontHeightToolBoxControl::getSupportedServiceNames( )
331 : throw( uno::RuntimeException, std::exception )
332 : {
333 0 : uno::Sequence< OUString > aSNS( 1 );
334 0 : aSNS.getArray()[0] = "com.sun.star.frame.ToolbarController";
335 0 : return aSNS;
336 : }
337 :
338 : // XComponent
339 1948 : void SAL_CALL FontHeightToolBoxControl::dispose()
340 : throw (uno::RuntimeException, std::exception)
341 : {
342 1948 : svt::ToolboxController::dispose();
343 :
344 1948 : SolarMutexGuard aSolarMutexGuard;
345 1948 : delete m_pBox;
346 1948 : m_pBox = 0;
347 1948 : }
348 :
349 : // XStatusListener
350 4116 : void SAL_CALL FontHeightToolBoxControl::statusChanged(
351 : const frame::FeatureStateEvent& rEvent )
352 : throw ( uno::RuntimeException, std::exception )
353 : {
354 4116 : if ( m_pBox )
355 : {
356 4116 : SolarMutexGuard aSolarMutexGuard;
357 4116 : if ( rEvent.FeatureURL.Path == "FontHeight" )
358 : {
359 2058 : if ( rEvent.IsEnabled )
360 : {
361 2058 : m_pBox->Enable();
362 2058 : frame::status::FontHeight aFontHeight;
363 2058 : if ( rEvent.State >>= aFontHeight )
364 2058 : m_pBox->statusChanged_Impl( long( 10. * aFontHeight.Height ), false );
365 : else
366 0 : m_pBox->statusChanged_Impl( long( -1 ), true );
367 : }
368 : else
369 0 : m_pBox->Disable();
370 : }
371 2058 : else if ( rEvent.FeatureURL.Path == "CharFontName" )
372 : {
373 2058 : if ( rEvent.State >>= m_aCurrentFont )
374 2058 : m_pBox->UpdateFont( m_aCurrentFont );
375 4116 : }
376 : }
377 4116 : }
378 :
379 : // XToolbarController
380 0 : void SAL_CALL FontHeightToolBoxControl::execute( sal_Int16 /*KeyModifier*/ )
381 : throw (::com::sun::star::uno::RuntimeException, std::exception)
382 : {
383 0 : }
384 :
385 0 : void SAL_CALL FontHeightToolBoxControl::click()
386 : throw (::com::sun::star::uno::RuntimeException, std::exception)
387 : {
388 0 : }
389 :
390 0 : void SAL_CALL FontHeightToolBoxControl::doubleClick()
391 : throw (::com::sun::star::uno::RuntimeException, std::exception)
392 : {
393 0 : }
394 :
395 0 : uno::Reference< awt::XWindow > SAL_CALL FontHeightToolBoxControl::createPopupWindow()
396 : throw (::com::sun::star::uno::RuntimeException, std::exception)
397 : {
398 0 : return uno::Reference< awt::XWindow >();
399 : }
400 :
401 1948 : uno::Reference< awt::XWindow > SAL_CALL FontHeightToolBoxControl::createItemWindow(
402 : const uno::Reference< awt::XWindow >& Parent )
403 : throw (::com::sun::star::uno::RuntimeException, std::exception)
404 : {
405 1948 : uno::Reference< awt::XWindow > xItemWindow;
406 3896 : uno::Reference< awt::XWindow > xParent( Parent );
407 :
408 1948 : vcl::Window* pParent = VCLUnoHelper::GetWindow( xParent );
409 1948 : if ( pParent )
410 : {
411 1948 : SolarMutexGuard aSolarMutexGuard;
412 : m_pBox = new SvxFontSizeBox_Impl(
413 : pParent,
414 : uno::Reference< frame::XDispatchProvider >( m_xFrame, uno::UNO_QUERY ),
415 : m_xFrame,
416 1948 : *this );
417 : //Get the box to fill itself with all its sizes
418 1948 : m_pBox->UpdateFont(m_aCurrentFont);
419 : //Make it size itself to its optimal size re above sizes
420 1948 : m_pBox->SetOptimalSize();
421 1948 : xItemWindow = VCLUnoHelper::GetInterface( m_pBox );
422 : }
423 :
424 3896 : return xItemWindow;
425 : }
426 :
427 0 : void FontHeightToolBoxControl::dispatchCommand(
428 : const uno::Sequence< beans::PropertyValue >& rArgs )
429 : {
430 0 : uno::Reference< frame::XDispatchProvider > xDispatchProvider( m_xFrame, uno::UNO_QUERY );
431 0 : if ( xDispatchProvider.is() )
432 : {
433 0 : util::URL aURL;
434 0 : uno::Reference< frame::XDispatch > xDispatch;
435 0 : uno::Reference< util::XURLTransformer > xURLTransformer = getURLTransformer();
436 :
437 0 : aURL.Complete = ".uno:FontHeight";
438 0 : xURLTransformer->parseStrict( aURL );
439 0 : xDispatch = xDispatchProvider->queryDispatch( aURL, OUString(), 0 );
440 0 : if ( xDispatch.is() )
441 0 : xDispatch->dispatch( aURL, rArgs );
442 0 : }
443 0 : }
444 :
445 : }
446 :
447 : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
448 1948 : com_sun_star_svx_FontHeightToolBoxController_get_implementation(
449 : css::uno::XComponentContext *rxContext,
450 : css::uno::Sequence<css::uno::Any> const &)
451 : {
452 1948 : return cppu::acquire(new FontHeightToolBoxControl(rxContext));
453 594 : }
454 :
455 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|