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 : :
30 : : #include <uielement/langselectionmenucontroller.hxx>
31 : :
32 : : #include <threadhelp/resetableguard.hxx>
33 : : #include "services.h"
34 : :
35 : : #include <com/sun/star/awt/XDevice.hpp>
36 : : #include <com/sun/star/beans/PropertyValue.hpp>
37 : : #include <com/sun/star/awt/MenuItemStyle.hpp>
38 : : #include <com/sun/star/frame/XDispatchProvider.hpp>
39 : :
40 : : #include <vcl/menu.hxx>
41 : : #include <vcl/svapp.hxx>
42 : : #include <vcl/i18nhelp.hxx>
43 : : #include <rtl/ustrbuf.hxx>
44 : : #include <vcl/mnemonic.hxx>
45 : : #include <com/sun/star/awt/XMenuExtended.hpp>
46 : : #include <comphelper/processfactory.hxx>
47 : :
48 : : #include <com/sun/star/document/XDocumentLanguages.hpp>
49 : : #include <com/sun/star/frame/XPopupMenuController.hpp>
50 : : #include <com/sun/star/linguistic2/XLanguageGuessing.hpp>
51 : :
52 : : #include <i18npool/mslangid.hxx>
53 : : #include <svl/languageoptions.hxx>
54 : : #include <com/sun/star/awt/MenuItemStyle.hpp>
55 : : #include <svtools/langtab.hxx>
56 : : #include <classes/fwlresid.hxx>
57 : :
58 : : #include <classes/resource.hrc>
59 : :
60 : : #include "helper/mischelper.hxx"
61 : : #include <osl/mutex.hxx>
62 : :
63 : : #include <map>
64 : : #include <set>
65 : :
66 : : //_________________________________________________________________________________________________________________
67 : : // Defines
68 : : //_________________________________________________________________________________________________________________
69 : : using namespace ::com::sun::star;
70 : : using namespace com::sun::star::uno;
71 : : using namespace com::sun::star::lang;
72 : : using namespace com::sun::star::frame;
73 : : using namespace com::sun::star::beans;
74 : : using namespace com::sun::star::util;
75 : :
76 : : using ::rtl::OUString;
77 : :
78 : : namespace framework
79 : : {
80 : :
81 [ # # ][ # # ]: 8 : DEFINE_XSERVICEINFO_MULTISERVICE ( LanguageSelectionMenuController ,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
82 : : OWeakObject ,
83 : : SERVICENAME_POPUPMENUCONTROLLER ,
84 : : IMPLEMENTATIONNAME_LANGUAGESELECTIONMENUCONTROLLER
85 : : )
86 : :
87 : 0 : DEFINE_INIT_SERVICE ( LanguageSelectionMenuController, {} )
88 : :
89 : 0 : LanguageSelectionMenuController::LanguageSelectionMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
90 : : svt::PopupMenuControllerBase( xServiceManager ),
91 : : m_bShowMenu( sal_True ),
92 [ # # ]: 0 : m_aLangGuessHelper( xServiceManager )
93 : : {
94 : 0 : }
95 : :
96 [ # # ]: 0 : LanguageSelectionMenuController::~LanguageSelectionMenuController()
97 : : {
98 [ # # ]: 0 : }
99 : :
100 : : // XEventListener
101 : 0 : void SAL_CALL LanguageSelectionMenuController::disposing( const EventObject& ) throw ( RuntimeException )
102 : : {
103 [ # # ]: 0 : Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
104 : :
105 [ # # ]: 0 : osl::MutexGuard aLock( m_aMutex );
106 : 0 : m_xFrame.clear();
107 : 0 : m_xDispatch.clear();
108 : 0 : m_xLanguageDispatch.clear();
109 : 0 : m_xServiceManager.clear();
110 : :
111 [ # # ]: 0 : if ( m_xPopupMenu.is() )
112 [ # # ][ # # ]: 0 : m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
[ # # ]
113 [ # # ]: 0 : m_xPopupMenu.clear();
114 : 0 : }
115 : :
116 : : // XStatusListener
117 : 0 : void SAL_CALL LanguageSelectionMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException )
118 : : {
119 [ # # ]: 0 : SolarMutexGuard aSolarMutexGuard;
120 : :
121 [ # # ][ # # ]: 0 : if (rBHelper.bDisposed || rBHelper.bInDispose)
122 : 0 : return;
123 : :
124 : 0 : m_bShowMenu = sal_True;
125 : 0 : m_nScriptType = LS_SCRIPT_LATIN | LS_SCRIPT_ASIAN | LS_SCRIPT_COMPLEX; //set the default value
126 : :
127 [ # # ]: 0 : Sequence< OUString > aSeq;
128 : :
129 [ # # ][ # # ]: 0 : if ( Event.State >>= aSeq )
130 : : {
131 [ # # ]: 0 : if ( aSeq.getLength() == 4 )
132 : : {
133 : : // Retrieve all other values from the sequence and
134 : : // store it members!
135 [ # # ]: 0 : m_aCurLang = aSeq[0];
136 [ # # ]: 0 : m_nScriptType = static_cast< sal_Int16 >(aSeq[1].toInt32());
137 [ # # ]: 0 : m_aKeyboardLang = aSeq[2];
138 [ # # ]: 0 : m_aGuessedTextLang = aSeq[3];
139 : : }
140 : : }
141 [ # # ]: 0 : else if ( !Event.State.hasValue() )
142 : : {
143 : 0 : m_bShowMenu = sal_False; // no language -> no sub-menu entries -> disable menu
144 [ # # ][ # # ]: 0 : }
[ # # ]
145 : : }
146 : :
147 : : // XMenuListener
148 : 0 : void LanguageSelectionMenuController::impl_select(const Reference< XDispatch >& _xDispatch,const ::com::sun::star::util::URL& aTargetURL)
149 : : {
150 : 0 : Reference< XDispatch > xDispatch = _xDispatch;
151 : :
152 [ # # ]: 0 : if ( aTargetURL.Complete == m_aMenuCommandURL_Font )
153 : : { //open format/character dialog for current selection
154 [ # # ]: 0 : xDispatch = m_xMenuDispatch_Font;
155 : : }
156 [ # # ]: 0 : else if ( aTargetURL.Complete == m_aMenuCommandURL_Lang )
157 : : { //open language tab-page in tools/options dialog
158 [ # # ]: 0 : xDispatch = m_xMenuDispatch_Lang;
159 : : }
160 [ # # ]: 0 : else if ( aTargetURL.Complete == m_aMenuCommandURL_CharDlgForParagraph )
161 : : { //open format/character dialog for current selection
162 [ # # ]: 0 : xDispatch = m_xMenuDispatch_CharDlgForParagraph;
163 : : }
164 : :
165 [ # # ]: 0 : if ( !xDispatch.is() )
166 : : {
167 [ # # ]: 0 : Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
168 [ # # ]: 0 : if ( xDispatchProvider.is() )
169 [ # # ][ # # ]: 0 : xDispatch = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
[ # # ]
170 : : }
171 : :
172 [ # # ]: 0 : if ( xDispatch.is() )
173 : : {
174 [ # # ]: 0 : Sequence<PropertyValue> aArgs;
175 [ # # ][ # # ]: 0 : xDispatch->dispatch( aTargetURL, aArgs );
[ # # ]
176 : 0 : }
177 : 0 : }
178 : :
179 : : // XPopupMenuController
180 : 0 : void LanguageSelectionMenuController::impl_setPopupMenu()
181 : : {
182 [ # # ]: 0 : Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
183 : :
184 : 0 : com::sun::star::util::URL aTargetURL;
185 : :
186 : : // Register for language updates
187 : 0 : aTargetURL.Complete = m_aLangStatusCommandURL;
188 [ # # ][ # # ]: 0 : m_xURLTransformer->parseStrict( aTargetURL );
189 [ # # ][ # # ]: 0 : m_xLanguageDispatch = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
[ # # ]
190 : :
191 : : // Register for setting languages and opening language dialog
192 : 0 : aTargetURL.Complete = m_aMenuCommandURL_Lang;
193 [ # # ][ # # ]: 0 : m_xURLTransformer->parseStrict( aTargetURL );
194 [ # # ][ # # ]: 0 : m_xMenuDispatch_Lang = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
[ # # ]
195 : :
196 : : // Register for opening character dialog
197 : 0 : aTargetURL.Complete = m_aMenuCommandURL_Font;
198 [ # # ][ # # ]: 0 : m_xURLTransformer->parseStrict( aTargetURL );
199 [ # # ][ # # ]: 0 : m_xMenuDispatch_Font = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
[ # # ]
200 : :
201 : : // Register for opening character dialog with preselected paragraph
202 : 0 : aTargetURL.Complete = m_aMenuCommandURL_CharDlgForParagraph;
203 [ # # ][ # # ]: 0 : m_xURLTransformer->parseStrict( aTargetURL );
204 [ # # ][ # # ]: 0 : m_xMenuDispatch_CharDlgForParagraph = xDispatchProvider->queryDispatch( aTargetURL, OUString(), 0 );
[ # # ]
205 : 0 : }
206 : :
207 : 0 : void LanguageSelectionMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu , const Mode eMode )
208 : : {
209 : 0 : VCLXPopupMenu* pVCLPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
210 : 0 : PopupMenu* pPopupMenu = 0;
211 : :
212 [ # # ]: 0 : SolarMutexGuard aSolarMutexGuard;
213 : :
214 [ # # ]: 0 : resetPopupMenu( rPopupMenu );
215 [ # # ]: 0 : if (!m_bShowMenu)
216 : 0 : return;
217 : :
218 [ # # ]: 0 : if ( pVCLPopupMenu )
219 : 0 : pPopupMenu = (PopupMenu *)pVCLPopupMenu->GetMenu();
220 : :
221 [ # # ]: 0 : String aCmd;
222 [ # # ]: 0 : String aCmd_Dialog;
223 [ # # ]: 0 : String aCmd_Language;
224 [ # # ]: 0 : if( eMode == MODE_SetLanguageSelectionMenu )
225 : : {
226 [ # # ]: 0 : aCmd_Dialog.AppendAscii(".uno:FontDialog?Language:string=*");
227 [ # # ]: 0 : aCmd_Language.AppendAscii(".uno:LanguageStatus?Language:string=Current_");
228 : : }
229 [ # # ]: 0 : else if ( eMode == MODE_SetLanguageParagraphMenu )
230 : : {
231 [ # # ]: 0 : aCmd_Dialog.AppendAscii(".uno:FontDialogForParagraph");
232 [ # # ]: 0 : aCmd_Language.AppendAscii(".uno:LanguageStatus?Language:string=Paragraph_");
233 : : }
234 [ # # ]: 0 : else if ( eMode == MODE_SetLanguageAllTextMenu )
235 : : {
236 [ # # ]: 0 : aCmd_Dialog.AppendAscii(".uno:LanguageStatus?Language:string=*");
237 [ # # ]: 0 : aCmd_Language.AppendAscii(".uno:LanguageStatus?Language:string=Default_");
238 : : }
239 : :
240 [ # # ]: 0 : SvtLanguageTable aLanguageTable;
241 : :
242 : : // get languages to be displayed in the menu
243 [ # # ]: 0 : std::set< OUString > aLangItems;
244 : : FillLangItems( aLangItems, aLanguageTable, m_xFrame, m_aLangGuessHelper,
245 [ # # ]: 0 : m_nScriptType, m_aCurLang, m_aKeyboardLang, m_aGuessedTextLang );
246 : :
247 : : // now add menu entries
248 : : // the different menus purpose will be handled by the different string
249 : : // for aCmd_Dialog and aCmd_Language
250 : :
251 : 0 : sal_Int16 nItemId = 1; // in this control the item id is not important for executing the command
252 : 0 : const OUString sAsterix("*"); // multiple languages in current selection
253 : 0 : const OUString sEmpty; // 'no language found' from language guessing
254 [ # # ]: 0 : std::map< sal_Int16, OUString > aLangMap;
255 : 0 : std::set< OUString >::const_iterator it;
256 [ # # ]: 0 : for (it = aLangItems.begin(); it != aLangItems.end(); ++it)
257 : : {
258 : 0 : const OUString & rStr( *it );
259 [ # # # # : 0 : if (rStr != OUString( aLanguageTable.GetString( LANGUAGE_NONE ) )&&
# # ][ # # ]
[ # # # # ]
[ # # ]
260 : 0 : rStr != sAsterix &&
261 : 0 : rStr != sEmpty)
262 : : {
263 [ # # ][ # # ]: 0 : pPopupMenu->InsertItem( nItemId, rStr );
[ # # ]
264 [ # # ]: 0 : aCmd = aCmd_Language;
265 [ # # ][ # # ]: 0 : aCmd += String( rStr );
[ # # ]
266 [ # # ]: 0 : pPopupMenu->SetItemCommand( nItemId, aCmd );
267 [ # # ][ # # ]: 0 : if (rStr == m_aCurLang && eMode == MODE_SetLanguageSelectionMenu )
[ # # ]
268 : : {
269 : : //make a sign for the current language
270 [ # # ]: 0 : pPopupMenu->CheckItem( nItemId, sal_True );
271 : : }
272 [ # # ]: 0 : aLangMap[ nItemId ] = rStr;
273 : 0 : ++nItemId;
274 : : }
275 : : }
276 : :
277 : : // entry for LANGUAGE_NONE
278 : 0 : ++nItemId;
279 [ # # ][ # # ]: 0 : pPopupMenu->InsertItem( nItemId, String(FwlResId( STR_LANGSTATUS_NONE )) );
[ # # ][ # # ]
280 [ # # ]: 0 : aCmd=aCmd_Language;
281 [ # # ]: 0 : aCmd.AppendAscii("LANGUAGE_NONE");
282 [ # # ]: 0 : pPopupMenu->SetItemCommand( nItemId, aCmd );
283 : :
284 : : // entry for 'Reset to default language'
285 : 0 : ++nItemId;
286 [ # # ][ # # ]: 0 : pPopupMenu->InsertItem( nItemId, String(FwlResId( STR_RESET_TO_DEFAULT_LANGUAGE )) );
[ # # ][ # # ]
287 [ # # ]: 0 : aCmd=aCmd_Language;
288 [ # # ]: 0 : aCmd.AppendAscii("RESET_LANGUAGES");
289 [ # # ]: 0 : pPopupMenu->SetItemCommand( nItemId, aCmd );
290 : :
291 : : // entry for opening the Format/Character dialog
292 : 0 : ++nItemId;
293 [ # # ][ # # ]: 0 : pPopupMenu->InsertItem( nItemId, String(FwlResId( STR_LANGSTATUS_MORE )));
[ # # ][ # # ]
294 [ # # ][ # # ]: 0 : pPopupMenu->SetItemCommand( nItemId, aCmd_Dialog );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
295 : : }
296 : :
297 : :
298 : 0 : void SAL_CALL LanguageSelectionMenuController::updatePopupMenu() throw ( ::com::sun::star::uno::RuntimeException )
299 : : {
300 [ # # ]: 0 : svt::PopupMenuControllerBase::updatePopupMenu();
301 : :
302 : : // Force status update to get information about the current languages
303 [ # # ]: 0 : osl::ClearableMutexGuard aLock( m_aMutex );
304 : 0 : Reference< XDispatch > xDispatch( m_xLanguageDispatch );
305 : 0 : com::sun::star::util::URL aTargetURL;
306 : 0 : aTargetURL.Complete = m_aLangStatusCommandURL;
307 [ # # ][ # # ]: 0 : m_xURLTransformer->parseStrict( aTargetURL );
308 [ # # ]: 0 : aLock.clear();
309 : :
310 [ # # ]: 0 : if ( xDispatch.is() )
311 : : {
312 [ # # ][ # # ]: 0 : xDispatch->addStatusListener( (static_cast< XStatusListener* >(this)), aTargetURL );
[ # # ]
313 [ # # ][ # # ]: 0 : xDispatch->removeStatusListener( (static_cast< XStatusListener* >(this)), aTargetURL );
[ # # ]
314 : : }
315 : :
316 : : // TODO: Fill menu with the information retrieved by the status update
317 : :
318 [ # # ]: 0 : if ( m_aCommandURL == ".uno:SetLanguageSelectionMenu" )
319 : : {
320 [ # # ]: 0 : fillPopupMenu(m_xPopupMenu, MODE_SetLanguageSelectionMenu );
321 : : }
322 [ # # ]: 0 : else if ( m_aCommandURL == ".uno:SetLanguageParagraphMenu" )
323 : : {
324 [ # # ]: 0 : fillPopupMenu(m_xPopupMenu, MODE_SetLanguageParagraphMenu );
325 : : }
326 [ # # ]: 0 : else if ( m_aCommandURL == ".uno:SetLanguageAllTextMenu" )
327 : : {
328 [ # # ]: 0 : fillPopupMenu(m_xPopupMenu, MODE_SetLanguageAllTextMenu );
329 [ # # ]: 0 : }
330 : 0 : }
331 : :
332 : : // XInitialization
333 : 0 : void SAL_CALL LanguageSelectionMenuController::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
334 : : {
335 [ # # ]: 0 : osl::MutexGuard aLock( m_aMutex );
336 : :
337 : 0 : sal_Bool bInitalized( m_bInitialized );
338 [ # # ]: 0 : if ( !bInitalized )
339 : : {
340 [ # # ]: 0 : svt::PopupMenuControllerBase::initialize(aArguments);
341 : :
342 [ # # ]: 0 : if ( m_bInitialized )
343 : : {
344 : 0 : m_aLangStatusCommandURL = OUString( ".uno:LanguageStatus" );
345 : 0 : m_aMenuCommandURL_Lang = m_aLangStatusCommandURL;
346 : 0 : m_aMenuCommandURL_Font = OUString( ".uno:FontDialog" );
347 : 0 : m_aMenuCommandURL_CharDlgForParagraph = OUString( ".uno:FontDialogForParagraph" );
348 : : }
349 [ # # ]: 0 : }
350 : 0 : }
351 : :
352 : : }
353 : :
354 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|