Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <uielement/fontsizemenucontroller.hxx>
30 : :
31 : : #include <threadhelp/resetableguard.hxx>
32 : : #include "services.h"
33 : :
34 : : #include <com/sun/star/awt/XDevice.hpp>
35 : : #include <com/sun/star/beans/PropertyValue.hpp>
36 : : #include <com/sun/star/awt/MenuItemStyle.hpp>
37 : : #include <com/sun/star/frame/XDispatchProvider.hpp>
38 : : #include <com/sun/star/view/XPrintable.hpp>
39 : :
40 : : #include <vcl/menu.hxx>
41 : : #include <tools/mapunit.hxx>
42 : : #include <vcl/svapp.hxx>
43 : : #include <vcl/i18nhelp.hxx>
44 : : #include <vcl/outdev.hxx>
45 : : #include <vcl/print.hxx>
46 : : #include <svtools/ctrltool.hxx>
47 : : #include <osl/mutex.hxx>
48 : :
49 : : //_________________________________________________________________________________________________________________
50 : : // Defines
51 : : //_________________________________________________________________________________________________________________
52 : :
53 : : using namespace com::sun::star::uno;
54 : : using namespace com::sun::star::lang;
55 : : using namespace com::sun::star::frame;
56 : : using namespace com::sun::star::beans;
57 : : using namespace com::sun::star::util;
58 : : using namespace com::sun::star::view;
59 : : using namespace com::sun::star::beans;
60 : :
61 : : namespace framework
62 : : {
63 : :
64 [ + - ][ + - ]: 32 : DEFINE_XSERVICEINFO_MULTISERVICE ( FontSizeMenuController ,
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ # # ]
[ # # ]
65 : : OWeakObject ,
66 : : SERVICENAME_POPUPMENUCONTROLLER ,
67 : : IMPLEMENTATIONNAME_FONTSIZEMENUCONTROLLER
68 : : )
69 : :
70 : 4 : DEFINE_INIT_SERVICE ( FontSizeMenuController, {} )
71 : :
72 : 4 : FontSizeMenuController::FontSizeMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
73 : : svt::PopupMenuControllerBase( xServiceManager ),
74 : 4 : m_pHeightArray( 0 )
75 : : {
76 : 4 : }
77 : :
78 : 4 : FontSizeMenuController::~FontSizeMenuController()
79 : : {
80 [ - + ]: 4 : delete []m_pHeightArray;
81 [ - + ]: 8 : }
82 : :
83 : : // private function
84 : 0 : rtl::OUString FontSizeMenuController::retrievePrinterName( com::sun::star::uno::Reference< com::sun::star::frame::XFrame >& rFrame )
85 : : {
86 : 0 : rtl::OUString aPrinterName;
87 : :
88 [ # # ]: 0 : if ( rFrame.is() )
89 : : {
90 [ # # ][ # # ]: 0 : Reference< XController > xController = m_xFrame->getController();
91 [ # # ]: 0 : if ( xController.is() )
92 : : {
93 [ # # ][ # # ]: 0 : Reference< XPrintable > xPrintable( xController->getModel(), UNO_QUERY );
[ # # ]
94 [ # # ]: 0 : if ( xPrintable.is() )
95 : : {
96 [ # # ][ # # ]: 0 : Sequence< PropertyValue > aPrinterSeq = xPrintable->getPrinter();
97 [ # # ]: 0 : for ( int i = 0; i < aPrinterSeq.getLength(); i++ )
98 : : {
99 [ # # ][ # # ]: 0 : if ( aPrinterSeq[i].Name == "Name" )
100 : : {
101 [ # # ]: 0 : aPrinterSeq[i].Value >>= aPrinterName;
102 : 0 : break;
103 : : }
104 [ # # ]: 0 : }
105 : 0 : }
106 : 0 : }
107 : : }
108 : :
109 : 0 : return aPrinterName;
110 : : }
111 : :
112 : : // private function
113 : 0 : void FontSizeMenuController::setCurHeight( long nHeight, Reference< css::awt::XPopupMenu >& rPopupMenu )
114 : : {
115 : : // check menu item
116 [ # # ][ # # ]: 0 : rtl::OUString aHeight = Application::GetSettings().GetUILocaleI18nHelper().GetNum( nHeight, 1, sal_True, sal_False );
[ # # ][ # # ]
[ # # ]
117 : 0 : sal_uInt16 nChecked = 0;
118 [ # # ][ # # ]: 0 : sal_uInt16 nItemCount = rPopupMenu->getItemCount();
119 [ # # ]: 0 : for( sal_uInt16 i = 0; i < nItemCount; i++ )
120 : : {
121 [ # # ][ # # ]: 0 : sal_uInt16 nItemId = rPopupMenu->getItemId( i );
122 : :
123 [ # # ]: 0 : if ( m_pHeightArray[i] == nHeight )
124 : : {
125 [ # # ][ # # ]: 0 : rPopupMenu->checkItem( nItemId, sal_True );
126 : 0 : return;
127 : : }
128 : :
129 [ # # ][ # # ]: 0 : if ( rPopupMenu->isItemChecked( nItemId ) )
[ # # ]
130 : 0 : nChecked = nItemId;
131 : : }
132 : :
133 [ # # ]: 0 : if ( nChecked )
134 [ # # ][ # # ]: 0 : rPopupMenu->checkItem( nChecked, sal_False );
[ # # ]
135 : : }
136 : :
137 : : // private function
138 : 0 : void FontSizeMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu )
139 : : {
140 : 0 : VCLXPopupMenu* pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
141 : 0 : PopupMenu* pVCLPopupMenu = 0;
142 : :
143 : 0 : resetPopupMenu( rPopupMenu );
144 [ # # ]: 0 : if ( pPopupMenu )
145 : 0 : pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
146 : :
147 [ # # ]: 0 : if ( pVCLPopupMenu )
148 : : {
149 : 0 : FontList* pFontList = 0;
150 : 0 : Printer* pInfoPrinter = 0;
151 : 0 : rtl::OUString aPrinterName;
152 : :
153 [ # # ]: 0 : SolarMutexGuard aSolarMutexGuard;
154 : :
155 : : // try to retrieve printer name of document
156 [ # # ]: 0 : aPrinterName = retrievePrinterName( m_xFrame );
157 [ # # ]: 0 : if ( !aPrinterName.isEmpty() )
158 : : {
159 [ # # ][ # # ]: 0 : pInfoPrinter = new Printer( aPrinterName );
160 [ # # ][ # # ]: 0 : if ( pInfoPrinter && pInfoPrinter->GetDevFontCount() > 0 )
[ # # ][ # # ]
161 [ # # ][ # # ]: 0 : pFontList = new FontList( pInfoPrinter );
162 : : }
163 : :
164 [ # # ]: 0 : if ( pFontList == 0 )
165 [ # # ][ # # ]: 0 : pFontList = new FontList( Application::GetDefaultDevice() );
[ # # ]
166 : :
167 [ # # ][ # # ]: 0 : FontInfo aFntInfo = pFontList->Get( m_aFontDescriptor.Name, m_aFontDescriptor.StyleName );
[ # # ][ # # ]
[ # # ]
168 : :
169 : : // setup font size array
170 [ # # ]: 0 : if ( m_pHeightArray )
171 : 0 : delete m_pHeightArray;
172 : :
173 : : const long* pTempAry;
174 [ # # ]: 0 : const long* pAry = pFontList->GetSizeAry( aFntInfo );
175 : 0 : sal_uInt16 nSizeCount = 0;
176 [ # # ]: 0 : while ( pAry[nSizeCount] )
177 : 0 : nSizeCount++;
178 : :
179 : 0 : sal_uInt16 nPos = 0;
180 : 0 : const rtl::OUString aFontHeightCommand( ".uno:FontHeight?FontHeight.Height:float=" );
181 : :
182 : : // first insert font size names (for simplified/traditional chinese)
183 : : float fPoint;
184 [ # # ][ # # ]: 0 : FontSizeNames aFontSizeNames( Application::GetSettings().GetUILanguage() );
[ # # ]
185 [ # # ]: 0 : m_pHeightArray = new long[nSizeCount+aFontSizeNames.Count()];
186 : 0 : rtl::OUString aCommand;
187 : :
188 [ # # ]: 0 : if ( !aFontSizeNames.IsEmpty() )
189 : : {
190 [ # # ][ # # ]: 0 : if ( pAry == pFontList->GetStdSizeAry() )
191 : : {
192 : : // for scalable fonts all font size names
193 : 0 : sal_uLong nCount = aFontSizeNames.Count();
194 [ # # ]: 0 : for( sal_uLong i = 0; i < nCount; i++ )
195 : : {
196 [ # # ]: 0 : String aSizeName = aFontSizeNames.GetIndexName( i );
197 [ # # ]: 0 : long nSize = aFontSizeNames.GetIndexSize( i );
198 : 0 : m_pHeightArray[nPos] = nSize;
199 : 0 : nPos++; // Id is nPos+1
200 [ # # ]: 0 : pVCLPopupMenu->InsertItem( nPos, aSizeName, MIB_RADIOCHECK | MIB_AUTOCHECK );
201 : 0 : fPoint = float( m_pHeightArray[nPos-1] ) / 10;
202 : :
203 : : // Create dispatchable .uno command and set it
204 : 0 : aCommand = aFontHeightCommand + rtl::OUString::valueOf( fPoint );
205 [ # # ][ # # ]: 0 : pVCLPopupMenu->SetItemCommand( nPos, aCommand );
[ # # ]
206 [ # # ]: 0 : }
207 : : }
208 : : else
209 : : {
210 : : // for fixed size fonts only selectable font size names
211 : 0 : pTempAry = pAry;
212 [ # # ]: 0 : while ( *pTempAry )
213 : : {
214 [ # # ]: 0 : String aSizeName = aFontSizeNames.Size2Name( *pTempAry );
215 [ # # ]: 0 : if ( aSizeName.Len() )
216 : : {
217 : 0 : m_pHeightArray[nPos] = *pTempAry;
218 : 0 : nPos++; // Id is nPos+1
219 [ # # ]: 0 : pVCLPopupMenu->InsertItem( nPos, aSizeName, MIB_RADIOCHECK | MIB_AUTOCHECK );
220 : 0 : fPoint = float( m_pHeightArray[nPos-1] ) / 10;
221 : :
222 : : // Create dispatchable .uno command and set it
223 : 0 : aCommand = aFontHeightCommand + rtl::OUString::valueOf( fPoint );
224 [ # # ][ # # ]: 0 : pVCLPopupMenu->SetItemCommand( nPos, aCommand );
[ # # ]
225 : : }
226 : 0 : pTempAry++;
227 [ # # ]: 0 : }
228 : : }
229 : : }
230 : :
231 : : // then insert numerical font size values
232 [ # # ][ # # ]: 0 : const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
233 : 0 : pTempAry = pAry;
234 [ # # ]: 0 : while ( *pTempAry )
235 : : {
236 : 0 : m_pHeightArray[nPos] = *pTempAry;
237 : 0 : nPos++; // Id is nPos+1
238 [ # # ][ # # ]: 0 : pVCLPopupMenu->InsertItem( nPos, rI18nHelper.GetNum( *pTempAry, 1, sal_True, sal_False ), MIB_RADIOCHECK | MIB_AUTOCHECK );
[ # # ]
239 : 0 : fPoint = float( m_pHeightArray[nPos-1] ) / 10;
240 : :
241 : : // Create dispatchable .uno command and set it
242 : 0 : aCommand = aFontHeightCommand + rtl::OUString::valueOf( fPoint );
243 [ # # ][ # # ]: 0 : pVCLPopupMenu->SetItemCommand( nPos, aCommand );
[ # # ]
244 : :
245 : 0 : pTempAry++;
246 : : }
247 : :
248 [ # # ]: 0 : setCurHeight( long( m_aFontHeight.Height * 10), rPopupMenu );
249 : :
250 [ # # ][ # # ]: 0 : delete pFontList;
251 [ # # ][ # # ]: 0 : delete pInfoPrinter;
[ # # ][ # # ]
252 : : }
253 : 0 : }
254 : :
255 : : // XEventListener
256 : 0 : void SAL_CALL FontSizeMenuController::disposing( const EventObject& ) throw ( RuntimeException )
257 : : {
258 [ # # ]: 0 : Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
259 : :
260 [ # # ]: 0 : osl::MutexGuard aLock( m_aMutex );
261 : 0 : m_xFrame.clear();
262 : 0 : m_xDispatch.clear();
263 : 0 : m_xCurrentFontDispatch.clear();
264 [ # # ]: 0 : if ( m_xPopupMenu.is() )
265 [ # # ][ # # ]: 0 : m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
[ # # ]
266 [ # # ]: 0 : m_xPopupMenu.clear();
267 : 0 : }
268 : :
269 : : // XStatusListener
270 : 2 : void SAL_CALL FontSizeMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException )
271 : : {
272 : 2 : com::sun::star::awt::FontDescriptor aFontDescriptor;
273 : 2 : ::com::sun::star::frame::status::FontHeight aFontHeight;
274 : :
275 [ - + ][ + - ]: 2 : if ( Event.State >>= aFontDescriptor )
276 : : {
277 [ # # ]: 0 : osl::MutexGuard aLock( m_aMutex );
278 : 0 : m_aFontDescriptor = aFontDescriptor;
279 : :
280 [ # # ]: 0 : if ( m_xPopupMenu.is() )
281 [ # # ][ # # ]: 0 : fillPopupMenu( m_xPopupMenu );
282 : :
283 : : }
284 [ + - ][ - + ]: 2 : else if ( Event.State >>= aFontHeight )
285 : : {
286 [ # # ]: 0 : osl::MutexGuard aLock( m_aMutex );
287 : 0 : m_aFontHeight = aFontHeight;
288 : :
289 [ # # ]: 0 : if ( m_xPopupMenu.is() )
290 : : {
291 [ # # ]: 0 : SolarMutexGuard aSolarMutexGuard;
292 [ # # ][ # # ]: 0 : setCurHeight( long( m_aFontHeight.Height * 10), m_xPopupMenu );
293 [ # # ]: 0 : }
294 : 2 : }
295 : 2 : }
296 : :
297 : : // XMenuListener
298 : 0 : void FontSizeMenuController::impl_select(const Reference< XDispatch >& _xDispatch,const ::com::sun::star::util::URL& aTargetURL)
299 : : {
300 [ # # ]: 0 : Sequence<PropertyValue> aArgs;
301 : : OSL_ENSURE(_xDispatch.is(),"FontSizeMenuController::impl_select: No dispatch");
302 [ # # ]: 0 : if ( _xDispatch.is() )
303 [ # # ][ # # ]: 0 : _xDispatch->dispatch( aTargetURL, aArgs );
[ # # ]
304 : 0 : }
305 : :
306 : : // XPopupMenuController
307 : 0 : void FontSizeMenuController::impl_setPopupMenu()
308 : : {
309 [ # # ]: 0 : Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
310 : 0 : com::sun::star::util::URL aTargetURL;
311 : : // Register for font name updates which gives us info about the current font!
312 : 0 : aTargetURL.Complete = rtl::OUString( ".uno:CharFontName" );
313 [ # # ][ # # ]: 0 : m_xURLTransformer->parseStrict( aTargetURL );
314 [ # # ][ # # ]: 0 : m_xCurrentFontDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
[ # # ]
315 : 0 : }
316 : :
317 : 2 : void SAL_CALL FontSizeMenuController::updatePopupMenu() throw ( ::com::sun::star::uno::RuntimeException )
318 : : {
319 [ + - ]: 2 : osl::ClearableMutexGuard aLock( m_aMutex );
320 : :
321 [ + - ]: 2 : throwIfDisposed();
322 : :
323 : 2 : Reference< XDispatch > xDispatch( m_xCurrentFontDispatch );
324 : 2 : com::sun::star::util::URL aTargetURL;
325 : 2 : aTargetURL.Complete = rtl::OUString( ".uno:CharFontName" );
326 [ + - ][ + - ]: 2 : m_xURLTransformer->parseStrict( aTargetURL );
327 [ + - ]: 2 : aLock.clear();
328 : :
329 [ - + ]: 2 : if ( xDispatch.is() )
330 : : {
331 [ # # ][ # # ]: 0 : xDispatch->addStatusListener( (static_cast< XStatusListener* >(this)), aTargetURL );
[ # # ]
332 [ # # ][ # # ]: 0 : xDispatch->removeStatusListener( (static_cast< XStatusListener* >(this)), aTargetURL );
[ # # ]
333 : : }
334 : :
335 [ + - ][ + - ]: 2 : svt::PopupMenuControllerBase::updatePopupMenu();
336 : 2 : }
337 : : }
338 : :
339 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|