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 <osl/mutex.hxx>
39 #include <cppuhelper/supportsservice.hxx>
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 OUString SAL_CALL
FontSizeMenuController::getImplementationName()
55 return "com.sun.star.comp.framework.FontSizeMenuController";
58 sal_Bool SAL_CALL
FontSizeMenuController::supportsService( const OUString
& sServiceName
)
60 return cppu::supportsService(this, sServiceName
);
63 css::uno::Sequence
< OUString
> SAL_CALL
FontSizeMenuController::getSupportedServiceNames()
65 return { SERVICENAME_POPUPMENUCONTROLLER
};
68 FontSizeMenuController::FontSizeMenuController( const css::uno::Reference
< css::uno::XComponentContext
>& xContext
) :
69 svt::PopupMenuControllerBase( xContext
)
73 FontSizeMenuController::~FontSizeMenuController()
78 OUString
FontSizeMenuController::retrievePrinterName( css::uno::Reference
< css::frame::XFrame
> const & rFrame
)
80 OUString aPrinterName
;
84 Reference
< XController
> xController
= m_xFrame
->getController();
85 if ( xController
.is() )
87 Reference
< XPrintable
> xPrintable( xController
->getModel(), UNO_QUERY
);
88 if ( xPrintable
.is() )
90 const Sequence
< PropertyValue
> aPrinterSeq
= xPrintable
->getPrinter();
91 for ( PropertyValue
const & prop
: aPrinterSeq
)
93 if ( prop
.Name
== "Name" )
95 prop
.Value
>>= aPrinterName
;
107 void FontSizeMenuController::setCurHeight( tools::Long nHeight
, Reference
< css::awt::XPopupMenu
> const & rPopupMenu
)
110 sal_uInt16 nChecked
= 0;
111 sal_uInt16 nItemCount
= rPopupMenu
->getItemCount();
112 for( sal_uInt16 i
= 0; i
< nItemCount
; i
++ )
114 sal_uInt16 nItemId
= rPopupMenu
->getItemId( i
);
116 if ( m_aHeightArray
[i
] == nHeight
)
118 rPopupMenu
->checkItem( nItemId
, true );
122 if ( rPopupMenu
->isItemChecked( nItemId
) )
127 rPopupMenu
->checkItem( nChecked
, false );
131 void FontSizeMenuController::fillPopupMenu( Reference
< css::awt::XPopupMenu
> const & rPopupMenu
)
133 resetPopupMenu( rPopupMenu
);
135 std::unique_ptr
<FontList
> pFontList
;
136 ScopedVclPtr
<Printer
> pInfoPrinter
;
137 OUString aPrinterName
;
139 SolarMutexGuard aSolarMutexGuard
;
141 // try to retrieve printer name of document
142 aPrinterName
= retrievePrinterName( m_xFrame
);
143 if ( !aPrinterName
.isEmpty() )
145 pInfoPrinter
.disposeAndReset(VclPtr
<Printer
>::Create( aPrinterName
));
146 if ( pInfoPrinter
&& pInfoPrinter
->GetFontFaceCollectionCount() > 0 )
147 pFontList
.reset(new FontList( pInfoPrinter
.get() ));
151 pFontList
.reset(new FontList( Application::GetDefaultDevice() ));
153 // setup font size array
154 m_aHeightArray
.clear();
156 sal_uInt16 nPos
= 0; // Id is nPos+1
157 static const OUStringLiteral
aFontHeightCommand( u
".uno:FontHeight?FontHeight.Height:float=" );
159 // first insert font size names (for simplified/traditional chinese)
160 FontSizeNames
aFontSizeNames( Application::GetSettings().GetUILanguageTag().getLanguageType() );
163 if (!aFontSizeNames
.IsEmpty())
165 // for scalable fonts all font size names
166 sal_Int32 nCount
= aFontSizeNames
.Count();
167 for( sal_Int32 i
= 0; i
< nCount
; i
++ )
169 OUString aSizeName
= aFontSizeNames
.GetIndexName( i
);
170 sal_Int32 nSize
= aFontSizeNames
.GetIndexSize( i
);
171 m_aHeightArray
.push_back(nSize
);
172 rPopupMenu
->insertItem(nPos
+ 1, aSizeName
, css::awt::MenuItemStyle::RADIOCHECK
| css::awt::MenuItemStyle::AUTOCHECK
, nPos
);
174 // Create dispatchable .uno command and set it
175 float fPoint
= float(nSize
) / 10;
176 aCommand
= aFontHeightCommand
+ OUString::number( fPoint
);
177 rPopupMenu
->setCommand(nPos
+ 1, aCommand
);
183 // then insert numerical font size values
184 const vcl::I18nHelper
& rI18nHelper
= Application::GetSettings().GetUILocaleI18nHelper();
185 const int* pAry
= FontList::GetStdSizeAry();
186 const int* pTempAry
= pAry
;
189 m_aHeightArray
.push_back(*pTempAry
);
190 rPopupMenu
->insertItem(nPos
+ 1, rI18nHelper
.GetNum(*pTempAry
, 1, true, false),
191 css::awt::MenuItemStyle::RADIOCHECK
| css::awt::MenuItemStyle::AUTOCHECK
, nPos
);
193 // Create dispatchable .uno command and set it
194 float fPoint
= float(*pTempAry
) / 10;
195 aCommand
= aFontHeightCommand
+ OUString::number( fPoint
);
196 rPopupMenu
->setCommand(nPos
+ 1, aCommand
);
202 setCurHeight( tools::Long( m_aFontHeight
.Height
* 10), rPopupMenu
);
206 void SAL_CALL
FontSizeMenuController::disposing( const EventObject
& )
208 Reference
< css::awt::XMenuListener
> xHolder(this);
210 osl::MutexGuard
aLock( m_aMutex
);
213 m_xCurrentFontDispatch
.clear();
214 if ( m_xPopupMenu
.is() )
215 m_xPopupMenu
->removeMenuListener( Reference
< css::awt::XMenuListener
>(this) );
216 m_xPopupMenu
.clear();
220 void SAL_CALL
FontSizeMenuController::statusChanged( const FeatureStateEvent
& Event
)
222 css::awt::FontDescriptor aFontDescriptor
;
223 css::frame::status::FontHeight aFontHeight
;
225 if ( Event
.State
>>= aFontDescriptor
)
227 osl::MutexGuard
aLock( m_aMutex
);
229 if ( m_xPopupMenu
.is() )
230 fillPopupMenu( m_xPopupMenu
);
232 else if ( Event
.State
>>= aFontHeight
)
234 osl::MutexGuard
aLock( m_aMutex
);
235 m_aFontHeight
= aFontHeight
;
237 if ( m_xPopupMenu
.is() )
239 SolarMutexGuard aSolarMutexGuard
;
240 setCurHeight( tools::Long( m_aFontHeight
.Height
* 10), m_xPopupMenu
);
245 // XPopupMenuController
246 void FontSizeMenuController::impl_setPopupMenu()
248 Reference
< XDispatchProvider
> xDispatchProvider( m_xFrame
, UNO_QUERY
);
249 css::util::URL aTargetURL
;
250 // Register for font name updates which gives us info about the current font!
251 aTargetURL
.Complete
= ".uno:CharFontName";
252 m_xURLTransformer
->parseStrict( aTargetURL
);
253 m_xCurrentFontDispatch
= xDispatchProvider
->queryDispatch( aTargetURL
, OUString(), 0 );
256 void SAL_CALL
FontSizeMenuController::updatePopupMenu()
258 osl::ClearableMutexGuard
aLock( m_aMutex
);
262 Reference
< XDispatch
> xDispatch( m_xCurrentFontDispatch
);
263 css::util::URL aTargetURL
;
264 aTargetURL
.Complete
= ".uno:CharFontName";
265 m_xURLTransformer
->parseStrict( aTargetURL
);
268 if ( xDispatch
.is() )
270 xDispatch
->addStatusListener( static_cast< XStatusListener
* >(this), aTargetURL
);
271 xDispatch
->removeStatusListener( static_cast< XStatusListener
* >(this), aTargetURL
);
274 svt::PopupMenuControllerBase::updatePopupMenu();
278 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
279 framework_FontSizeMenuController_get_implementation(
280 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const& )
282 return cppu::acquire(new framework::FontSizeMenuController(context
));
285 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */