1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <uielement/fontsizemenucontroller.hxx>
24 #include <com/sun/star/awt/XDevice.hpp>
25 #include <com/sun/star/beans/PropertyValue.hpp>
26 #include <com/sun/star/awt/MenuItemStyle.hpp>
27 #include <com/sun/star/frame/XDispatchProvider.hpp>
28 #include <com/sun/star/view/XPrintable.hpp>
30 #include <vcl/menu.hxx>
31 #include <tools/mapunit.hxx>
32 #include <vcl/svapp.hxx>
33 #include <vcl/i18nhelp.hxx>
34 #include <vcl/outdev.hxx>
35 #include <vcl/print.hxx>
36 #include <vcl/settings.hxx>
37 #include <svtools/ctrltool.hxx>
38 #include <osl/mutex.hxx>
39 #include <boost/scoped_ptr.hpp>
43 using namespace com::sun::star::uno
;
44 using namespace com::sun::star::lang
;
45 using namespace com::sun::star::frame
;
46 using namespace com::sun::star::beans
;
47 using namespace com::sun::star::util
;
48 using namespace com::sun::star::view
;
53 DEFINE_XSERVICEINFO_MULTISERVICE_2 ( FontSizeMenuController
,
55 SERVICENAME_POPUPMENUCONTROLLER
,
56 IMPLEMENTATIONNAME_FONTSIZEMENUCONTROLLER
59 DEFINE_INIT_SERVICE ( FontSizeMenuController
, {} )
61 FontSizeMenuController::FontSizeMenuController( const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XComponentContext
>& xContext
) :
62 svt::PopupMenuControllerBase( xContext
),
67 FontSizeMenuController::~FontSizeMenuController()
69 delete []m_pHeightArray
;
73 OUString
FontSizeMenuController::retrievePrinterName( com::sun::star::uno::Reference
< com::sun::star::frame::XFrame
>& rFrame
)
75 OUString aPrinterName
;
79 Reference
< XController
> xController
= m_xFrame
->getController();
80 if ( xController
.is() )
82 Reference
< XPrintable
> xPrintable( xController
->getModel(), UNO_QUERY
);
83 if ( xPrintable
.is() )
85 Sequence
< PropertyValue
> aPrinterSeq
= xPrintable
->getPrinter();
86 for ( int i
= 0; i
< aPrinterSeq
.getLength(); i
++ )
88 if ( aPrinterSeq
[i
].Name
== "Name" )
90 aPrinterSeq
[i
].Value
>>= aPrinterName
;
102 void FontSizeMenuController::setCurHeight( long nHeight
, Reference
< css::awt::XPopupMenu
>& rPopupMenu
)
105 sal_uInt16 nChecked
= 0;
106 sal_uInt16 nItemCount
= rPopupMenu
->getItemCount();
107 for( sal_uInt16 i
= 0; i
< nItemCount
; i
++ )
109 sal_uInt16 nItemId
= rPopupMenu
->getItemId( i
);
111 if ( m_pHeightArray
[i
] == nHeight
)
113 rPopupMenu
->checkItem( nItemId
, sal_True
);
117 if ( rPopupMenu
->isItemChecked( nItemId
) )
122 rPopupMenu
->checkItem( nChecked
, sal_False
);
126 void FontSizeMenuController::fillPopupMenu( Reference
< css::awt::XPopupMenu
>& rPopupMenu
)
128 VCLXPopupMenu
* pPopupMenu
= static_cast<VCLXPopupMenu
*>(VCLXMenu::GetImplementation( rPopupMenu
));
129 PopupMenu
* pVCLPopupMenu
= 0;
131 resetPopupMenu( rPopupMenu
);
133 pVCLPopupMenu
= static_cast<PopupMenu
*>(pPopupMenu
->GetMenu());
137 boost::scoped_ptr
<FontList
> pFontList
;
138 ScopedVclPtr
<Printer
> pInfoPrinter
;
139 OUString aPrinterName
;
141 SolarMutexGuard aSolarMutexGuard
;
143 // try to retrieve printer name of document
144 aPrinterName
= retrievePrinterName( m_xFrame
);
145 if ( !aPrinterName
.isEmpty() )
147 pInfoPrinter
.reset(VclPtr
<Printer
>::Create( aPrinterName
));
148 if ( pInfoPrinter
&& pInfoPrinter
->GetDevFontCount() > 0 )
149 pFontList
.reset(new FontList( pInfoPrinter
.get() ));
153 pFontList
.reset(new FontList( Application::GetDefaultDevice() ));
155 vcl::FontInfo aFntInfo
= pFontList
->Get( m_aFontDescriptor
.Name
, m_aFontDescriptor
.StyleName
);
157 // setup font size array
158 if ( m_pHeightArray
)
159 delete m_pHeightArray
;
161 const sal_IntPtr
* pTempAry
;
162 const sal_IntPtr
* pAry
= pFontList
->GetSizeAry( aFntInfo
);
163 sal_uInt16 nSizeCount
= 0;
164 while ( pAry
[nSizeCount
] )
168 const OUString
aFontHeightCommand( ".uno:FontHeight?FontHeight.Height:float=" );
170 // first insert font size names (for simplified/traditional chinese)
172 FontSizeNames
aFontSizeNames( Application::GetSettings().GetUILanguageTag().getLanguageType() );
173 m_pHeightArray
= new long[nSizeCount
+aFontSizeNames
.Count()];
176 if ( !aFontSizeNames
.IsEmpty() )
178 if ( pAry
== FontList::GetStdSizeAry() )
180 // for scalable fonts all font size names
181 sal_uLong nCount
= aFontSizeNames
.Count();
182 for( sal_uLong i
= 0; i
< nCount
; i
++ )
184 OUString aSizeName
= aFontSizeNames
.GetIndexName( i
);
185 long nSize
= aFontSizeNames
.GetIndexSize( i
);
186 m_pHeightArray
[nPos
] = nSize
;
187 nPos
++; // Id is nPos+1
188 pVCLPopupMenu
->InsertItem( nPos
, aSizeName
, MenuItemBits::RADIOCHECK
| MenuItemBits::AUTOCHECK
);
189 fPoint
= float( m_pHeightArray
[nPos
-1] ) / 10;
191 // Create dispatchable .uno command and set it
192 aCommand
= aFontHeightCommand
+ OUString::number( fPoint
);
193 pVCLPopupMenu
->SetItemCommand( nPos
, aCommand
);
198 // for fixed size fonts only selectable font size names
202 OUString aSizeName
= aFontSizeNames
.Size2Name( *pTempAry
);
203 if ( !aSizeName
.isEmpty() )
205 m_pHeightArray
[nPos
] = *pTempAry
;
206 nPos
++; // Id is nPos+1
207 pVCLPopupMenu
->InsertItem( nPos
, aSizeName
, MenuItemBits::RADIOCHECK
| MenuItemBits::AUTOCHECK
);
208 fPoint
= float( m_pHeightArray
[nPos
-1] ) / 10;
210 // Create dispatchable .uno command and set it
211 aCommand
= aFontHeightCommand
+ OUString::number( fPoint
);
212 pVCLPopupMenu
->SetItemCommand( nPos
, aCommand
);
219 // then insert numerical font size values
220 const vcl::I18nHelper
& rI18nHelper
= Application::GetSettings().GetUILocaleI18nHelper();
224 m_pHeightArray
[nPos
] = *pTempAry
;
225 nPos
++; // Id is nPos+1
226 pVCLPopupMenu
->InsertItem( nPos
, rI18nHelper
.GetNum( *pTempAry
, 1, true, false ), MenuItemBits::RADIOCHECK
| MenuItemBits::AUTOCHECK
);
227 fPoint
= float( m_pHeightArray
[nPos
-1] ) / 10;
229 // Create dispatchable .uno command and set it
230 aCommand
= aFontHeightCommand
+ OUString::number( fPoint
);
231 pVCLPopupMenu
->SetItemCommand( nPos
, aCommand
);
236 setCurHeight( long( m_aFontHeight
.Height
* 10), rPopupMenu
);
241 void SAL_CALL
FontSizeMenuController::disposing( const EventObject
& ) throw ( RuntimeException
, std::exception
)
243 Reference
< css::awt::XMenuListener
> xHolder(( OWeakObject
*)this, UNO_QUERY
);
245 osl::MutexGuard
aLock( m_aMutex
);
248 m_xCurrentFontDispatch
.clear();
249 if ( m_xPopupMenu
.is() )
250 m_xPopupMenu
->removeMenuListener( Reference
< css::awt::XMenuListener
>(( OWeakObject
*)this, UNO_QUERY
));
251 m_xPopupMenu
.clear();
255 void SAL_CALL
FontSizeMenuController::statusChanged( const FeatureStateEvent
& Event
) throw ( RuntimeException
, std::exception
)
257 com::sun::star::awt::FontDescriptor aFontDescriptor
;
258 ::com::sun::star::frame::status::FontHeight aFontHeight
;
260 if ( Event
.State
>>= aFontDescriptor
)
262 osl::MutexGuard
aLock( m_aMutex
);
263 m_aFontDescriptor
= aFontDescriptor
;
265 if ( m_xPopupMenu
.is() )
266 fillPopupMenu( m_xPopupMenu
);
269 else if ( Event
.State
>>= aFontHeight
)
271 osl::MutexGuard
aLock( m_aMutex
);
272 m_aFontHeight
= aFontHeight
;
274 if ( m_xPopupMenu
.is() )
276 SolarMutexGuard aSolarMutexGuard
;
277 setCurHeight( long( m_aFontHeight
.Height
* 10), m_xPopupMenu
);
283 void FontSizeMenuController::impl_select(const Reference
< XDispatch
>& _xDispatch
,const ::com::sun::star::util::URL
& aTargetURL
)
285 Sequence
<PropertyValue
> aArgs
;
286 OSL_ENSURE(_xDispatch
.is(),"FontSizeMenuController::impl_select: No dispatch");
287 if ( _xDispatch
.is() )
288 _xDispatch
->dispatch( aTargetURL
, aArgs
);
291 // XPopupMenuController
292 void FontSizeMenuController::impl_setPopupMenu()
294 Reference
< XDispatchProvider
> xDispatchProvider( m_xFrame
, UNO_QUERY
);
295 com::sun::star::util::URL aTargetURL
;
296 // Register for font name updates which gives us info about the current font!
297 aTargetURL
.Complete
= ".uno:CharFontName";
298 m_xURLTransformer
->parseStrict( aTargetURL
);
299 m_xCurrentFontDispatch
= xDispatchProvider
->queryDispatch( aTargetURL
, OUString(), 0 );
302 void SAL_CALL
FontSizeMenuController::updatePopupMenu() throw ( ::com::sun::star::uno::RuntimeException
, std::exception
)
304 osl::ClearableMutexGuard
aLock( m_aMutex
);
308 Reference
< XDispatch
> xDispatch( m_xCurrentFontDispatch
);
309 com::sun::star::util::URL aTargetURL
;
310 aTargetURL
.Complete
= ".uno:CharFontName";
311 m_xURLTransformer
->parseStrict( aTargetURL
);
314 if ( xDispatch
.is() )
316 xDispatch
->addStatusListener( (static_cast< XStatusListener
* >(this)), aTargetURL
);
317 xDispatch
->removeStatusListener( (static_cast< XStatusListener
* >(this)), aTargetURL
);
320 svt::PopupMenuControllerBase::updatePopupMenu();
324 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */