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 <sal/config.h>
22 #include <uielement/fontsizemenucontroller.hxx>
26 #include <com/sun/star/awt/MenuItemStyle.hpp>
27 #include <com/sun/star/beans/PropertyValue.hpp>
28 #include <com/sun/star/frame/XDispatchProvider.hpp>
29 #include <com/sun/star/view/XPrintable.hpp>
30 #include <com/sun/star/util/XURLTransformer.hpp>
32 #include <vcl/svapp.hxx>
33 #include <vcl/i18nhelp.hxx>
34 #include <vcl/print.hxx>
35 #include <vcl/settings.hxx>
36 #include <svtools/ctrltool.hxx>
37 #include <toolkit/awt/vclxmenu.hxx>
38 #include <osl/mutex.hxx>
40 #include <cppuhelper/supportsservice.hxx>
44 using namespace com::sun::star::uno
;
45 using namespace com::sun::star::lang
;
46 using namespace com::sun::star::frame
;
47 using namespace com::sun::star::beans
;
48 using namespace com::sun::star::util
;
49 using namespace com::sun::star::view
;
54 OUString SAL_CALL
FontSizeMenuController::getImplementationName()
56 return u
"com.sun.star.comp.framework.FontSizeMenuController"_ustr
;
59 sal_Bool SAL_CALL
FontSizeMenuController::supportsService( const OUString
& sServiceName
)
61 return cppu::supportsService(this, sServiceName
);
64 css::uno::Sequence
< OUString
> SAL_CALL
FontSizeMenuController::getSupportedServiceNames()
66 return { SERVICENAME_POPUPMENUCONTROLLER
};
69 FontSizeMenuController::FontSizeMenuController( const css::uno::Reference
< css::uno::XComponentContext
>& xContext
) :
70 svt::PopupMenuControllerBase( xContext
)
74 FontSizeMenuController::~FontSizeMenuController()
79 OUString
FontSizeMenuController::retrievePrinterName( css::uno::Reference
< css::frame::XFrame
> const & rFrame
)
81 OUString aPrinterName
;
85 Reference
< XController
> xController
= m_xFrame
->getController();
86 if ( xController
.is() )
88 Reference
< XPrintable
> xPrintable( xController
->getModel(), UNO_QUERY
);
89 if ( xPrintable
.is() )
91 const Sequence
< PropertyValue
> aPrinterSeq
= xPrintable
->getPrinter();
92 for ( PropertyValue
const & prop
: aPrinterSeq
)
94 if ( prop
.Name
== "Name" )
96 prop
.Value
>>= aPrinterName
;
108 void FontSizeMenuController::setCurHeight( tools::Long nHeight
, Reference
< css::awt::XPopupMenu
> const & rPopupMenu
)
111 sal_uInt16 nChecked
= 0;
112 sal_uInt16 nItemCount
= rPopupMenu
->getItemCount();
113 for( sal_uInt16 i
= 0; i
< nItemCount
; i
++ )
115 sal_uInt16 nItemId
= rPopupMenu
->getItemId( i
);
117 if ( m_aHeightArray
[i
] == nHeight
)
119 rPopupMenu
->checkItem( nItemId
, true );
123 if ( rPopupMenu
->isItemChecked( nItemId
) )
128 rPopupMenu
->checkItem( nChecked
, false );
132 void FontSizeMenuController::fillPopupMenu( Reference
< css::awt::XPopupMenu
> const & rPopupMenu
)
134 resetPopupMenu( rPopupMenu
);
136 std::unique_ptr
<FontList
> pFontList
;
137 ScopedVclPtr
<Printer
> pInfoPrinter
;
138 OUString aPrinterName
;
140 SolarMutexGuard aSolarMutexGuard
;
142 // try to retrieve printer name of document
143 aPrinterName
= retrievePrinterName( m_xFrame
);
144 if ( !aPrinterName
.isEmpty() )
146 pInfoPrinter
.disposeAndReset(VclPtr
<Printer
>::Create( aPrinterName
));
147 if ( pInfoPrinter
&& pInfoPrinter
->GetFontFaceCollectionCount() > 0 )
148 pFontList
.reset(new FontList( pInfoPrinter
.get() ));
152 pFontList
.reset(new FontList( Application::GetDefaultDevice() ));
154 // setup font size array
155 m_aHeightArray
.clear();
157 sal_uInt16 nPos
= 0; // Id is nPos+1
158 static constexpr OUString
aFontHeightCommand( u
".uno:FontHeight?FontHeight.Height:float="_ustr
);
160 // first insert font size names (for simplified/traditional chinese)
161 FontSizeNames
aFontSizeNames( Application::GetSettings().GetUILanguageTag().getLanguageType() );
164 if (!aFontSizeNames
.IsEmpty())
166 // for scalable fonts all font size names
167 sal_Int32 nCount
= aFontSizeNames
.Count();
168 for( sal_Int32 i
= 0; i
< nCount
; i
++ )
170 OUString aSizeName
= aFontSizeNames
.GetIndexName( i
);
171 sal_Int32 nSize
= aFontSizeNames
.GetIndexSize( i
);
172 m_aHeightArray
.push_back(nSize
);
173 rPopupMenu
->insertItem(nPos
+ 1, aSizeName
, css::awt::MenuItemStyle::RADIOCHECK
| css::awt::MenuItemStyle::AUTOCHECK
, nPos
);
175 // Create dispatchable .uno command and set it
176 float fPoint
= float(nSize
) / 10;
177 aCommand
= aFontHeightCommand
+ OUString::number( fPoint
);
178 rPopupMenu
->setCommand(nPos
+ 1, aCommand
);
184 // then insert numerical font size values
185 const vcl::I18nHelper
& rI18nHelper
= Application::GetSettings().GetUILocaleI18nHelper();
186 const int* pAry
= FontList::GetStdSizeAry();
187 const int* pTempAry
= pAry
;
190 m_aHeightArray
.push_back(*pTempAry
);
191 rPopupMenu
->insertItem(nPos
+ 1, rI18nHelper
.GetNum(*pTempAry
, 1, true, false),
192 css::awt::MenuItemStyle::RADIOCHECK
| css::awt::MenuItemStyle::AUTOCHECK
, nPos
);
194 // Create dispatchable .uno command and set it
195 float fPoint
= float(*pTempAry
) / 10;
196 aCommand
= aFontHeightCommand
+ OUString::number( fPoint
);
197 rPopupMenu
->setCommand(nPos
+ 1, aCommand
);
203 setCurHeight( tools::Long( m_aFontHeight
.Height
* 10), rPopupMenu
);
207 void SAL_CALL
FontSizeMenuController::disposing( const EventObject
& )
209 Reference
< css::awt::XMenuListener
> xHolder(this);
211 std::unique_lock
aLock( m_aMutex
);
214 m_xCurrentFontDispatch
.clear();
215 if ( m_xPopupMenu
.is() )
216 m_xPopupMenu
->removeMenuListener( Reference
< css::awt::XMenuListener
>(this) );
217 m_xPopupMenu
.clear();
221 void SAL_CALL
FontSizeMenuController::statusChanged( const FeatureStateEvent
& Event
)
223 css::awt::FontDescriptor aFontDescriptor
;
224 css::frame::status::FontHeight aFontHeight
;
226 if ( Event
.State
>>= aFontDescriptor
)
228 std::unique_lock
aLock( m_aMutex
);
230 if ( m_xPopupMenu
.is() )
231 fillPopupMenu( m_xPopupMenu
);
233 else if ( Event
.State
>>= aFontHeight
)
235 std::unique_lock
aLock( m_aMutex
);
236 m_aFontHeight
= aFontHeight
;
238 if ( m_xPopupMenu
.is() )
240 SolarMutexGuard aSolarMutexGuard
;
241 setCurHeight( tools::Long( m_aFontHeight
.Height
* 10), m_xPopupMenu
);
246 // XPopupMenuController
247 void FontSizeMenuController::impl_setPopupMenu(std::unique_lock
<std::mutex
>& /*rGuard*/)
249 Reference
< XDispatchProvider
> xDispatchProvider( m_xFrame
, UNO_QUERY
);
250 css::util::URL aTargetURL
;
251 // Register for font name updates which gives us info about the current font!
252 aTargetURL
.Complete
= ".uno:CharFontName";
253 m_xURLTransformer
->parseStrict( aTargetURL
);
254 m_xCurrentFontDispatch
= xDispatchProvider
->queryDispatch( aTargetURL
, OUString(), 0 );
257 void SAL_CALL
FontSizeMenuController::updatePopupMenu()
259 std::unique_lock
aLock( m_aMutex
);
261 throwIfDisposed(aLock
);
263 Reference
< XDispatch
> xDispatch( m_xCurrentFontDispatch
);
264 css::util::URL aTargetURL
;
265 aTargetURL
.Complete
= ".uno:CharFontName";
266 m_xURLTransformer
->parseStrict( aTargetURL
);
269 if ( xDispatch
.is() )
271 xDispatch
->addStatusListener( static_cast< XStatusListener
* >(this), aTargetURL
);
272 xDispatch
->removeStatusListener( static_cast< XStatusListener
* >(this), aTargetURL
);
275 svt::PopupMenuControllerBase::updatePopupMenu();
279 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
280 framework_FontSizeMenuController_get_implementation(
281 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const& )
283 return cppu::acquire(new framework::FontSizeMenuController(context
));
286 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */