merge the formfield patch from ooo-build
[ooovba.git] / framework / source / uielement / langselectionmenucontroller.cxx
bloba2f8ec271a5fb6c95da9c2ca26aeede5026e82e8
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: langselectionmenucontroller.cxx,v $
10 * $Revision: 1.6.40.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
33 #include <uielement/langselectionmenucontroller.hxx>
35 //_________________________________________________________________________________________________________________
36 // my own includes
37 //_________________________________________________________________________________________________________________
38 #include <threadhelp/resetableguard.hxx>
39 #include "services.h"
41 //_________________________________________________________________________________________________________________
42 // interface includes
43 //_________________________________________________________________________________________________________________
44 #include <com/sun/star/awt/XDevice.hpp>
45 #include <com/sun/star/beans/PropertyValue.hpp>
46 #include <com/sun/star/awt/MenuItemStyle.hpp>
47 #include <com/sun/star/frame/XDispatchProvider.hpp>
49 //_________________________________________________________________________________________________________________
50 // includes of other projects
51 //_________________________________________________________________________________________________________________
53 #ifndef _VCL_MENU_HXX_
54 #include <vcl/menu.hxx>
55 #endif
56 #include <vcl/svapp.hxx>
57 #include <vcl/i18nhelp.hxx>
58 #include <tools/urlobj.hxx>
59 #include <rtl/ustrbuf.hxx>
60 #ifndef _VCL_MNEMONIC_HXX_
61 #include <vcl/mnemonic.hxx>
62 #endif
63 #include <com/sun/star/awt/XMenuExtended.hpp>
64 #include <comphelper/processfactory.hxx>
66 #include <com/sun/star/document/XDocumentLanguages.hpp>
67 #include <com/sun/star/frame/XPopupMenuController.hpp>
68 #include <com/sun/star/linguistic2/XLanguageGuessing.hpp>
69 #include <map>
70 #include <i18npool/mslangid.hxx>
71 #include <svtools/languageoptions.hxx>
72 #include <com/sun/star/awt/MenuItemStyle.hpp>
73 #include <svtools/langtab.hxx>
74 #include <classes/fwlresid.hxx>
76 #ifndef __FRAMEWORK_CLASSES_RESOURCE_HRC_
77 #include <classes/resource.hrc>
78 #endif
79 #include <dispatch/uieventloghelper.hxx>
81 #include "helper/mischelper.hxx"
83 //_________________________________________________________________________________________________________________
84 // Defines
85 //_________________________________________________________________________________________________________________
87 using namespace ::com::sun::star;
88 using namespace com::sun::star::uno;
89 using namespace com::sun::star::lang;
90 using namespace com::sun::star::frame;
91 using namespace com::sun::star::beans;
92 using namespace com::sun::star::util;
95 namespace framework
98 DEFINE_XSERVICEINFO_MULTISERVICE ( LanguageSelectionMenuController ,
99 OWeakObject ,
100 SERVICENAME_POPUPMENUCONTROLLER ,
101 IMPLEMENTATIONNAME_LANGUAGESELECTIONMENUCONTROLLER
104 DEFINE_INIT_SERVICE ( LanguageSelectionMenuController, {} )
106 LanguageSelectionMenuController::LanguageSelectionMenuController( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) :
107 PopupMenuControllerBase( xServiceManager ),
108 m_bShowMenu( sal_True )
109 ,m_aLangGuessHelper(xServiceManager)
113 LanguageSelectionMenuController::~LanguageSelectionMenuController()
117 // XEventListener
118 void SAL_CALL LanguageSelectionMenuController::disposing( const EventObject& ) throw ( RuntimeException )
120 Reference< css::awt::XMenuListener > xHolder(( OWeakObject *)this, UNO_QUERY );
122 ResetableGuard aLock( m_aLock );
123 m_xFrame.clear();
124 m_xDispatch.clear();
125 m_xLanguageDispatch.clear();
126 m_xServiceManager.clear();
128 if ( m_xPopupMenu.is() )
129 m_xPopupMenu->removeMenuListener( Reference< css::awt::XMenuListener >(( OWeakObject *)this, UNO_QUERY ));
130 m_xPopupMenu.clear();
133 // XStatusListener
134 void SAL_CALL LanguageSelectionMenuController::statusChanged( const FeatureStateEvent& Event ) throw ( RuntimeException )
136 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
138 if ( m_bDisposed )
139 return;
141 m_bShowMenu = sal_True;
142 m_nScriptType=7;//set the default value
144 rtl::OUString aStrValue;
145 Sequence< ::rtl::OUString > aSeq;
147 if ( Event.State >>= aStrValue )
149 m_aCurrentLanguage=aStrValue;
151 else if ( Event.State >>= aSeq )
153 if ( aSeq.getLength() == 4 )
155 // Retrieve all other values from the sequence and
156 // store it members!
157 m_aCurLang=aSeq[0];
158 m_nScriptType= static_cast< sal_Int16 >(aSeq[1].toInt32());
159 m_aKeyboardLang=aSeq[2];
160 m_aGuessedText=aSeq[3];
163 else if ( !Event.State.hasValue() )
165 m_bShowMenu = sal_False; // no language -> no sub-menu entries -> disable menu
169 // XMenuListener
170 void LanguageSelectionMenuController::impl_select(const Reference< XDispatch >& _xDispatch,const ::com::sun::star::util::URL& aTargetURL)
172 Reference< XDispatch > xDispatch = _xDispatch;
174 if ( aTargetURL.Complete == m_aMenuCommandURL_Font )
175 { //open format/character dialog for current selection
176 xDispatch = m_xMenuDispatch_Font;
178 else if ( aTargetURL.Complete == m_aMenuCommandURL_Lang )
179 { //open language tab-page in tools/options dialog
180 xDispatch = m_xMenuDispatch_Lang;
182 else if ( aTargetURL.Complete == m_aMenuCommandURL_CharDlgForParagraph )
183 { //open format/character dialog for current selection
184 xDispatch = m_xMenuDispatch_CharDlgForParagraph;
187 if ( !xDispatch.is() )
189 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
190 if ( xDispatchProvider.is() )
191 xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
194 if ( xDispatch.is() )
196 Sequence<PropertyValue> aArgs;
197 if(::comphelper::UiEventsLogger::isEnabled()) //#i88653#
198 UiEventLogHelper(::rtl::OUString::createFromAscii("LanguageSelectionMenuController")).log(m_xServiceManager, m_xFrame, aTargetURL, aArgs);
199 xDispatch->dispatch( aTargetURL, aArgs );
203 // XPopupMenuController
204 void LanguageSelectionMenuController::impl_setPopupMenu()
206 Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
208 com::sun::star::util::URL aTargetURL;
210 // Register for language updates
211 aTargetURL.Complete = m_aLangStatusCommandURL;
212 m_xURLTransformer->parseStrict( aTargetURL );
213 m_xLanguageDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
215 // Register for setting languages and opening language dialog
216 aTargetURL.Complete = m_aMenuCommandURL_Lang;
217 m_xURLTransformer->parseStrict( aTargetURL );
218 m_xMenuDispatch_Lang = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
220 // Register for opening character dialog
221 aTargetURL.Complete = m_aMenuCommandURL_Font;
222 m_xURLTransformer->parseStrict( aTargetURL );
223 m_xMenuDispatch_Font = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
225 // Register for opening character dialog with preselected paragraph
226 aTargetURL.Complete = m_aMenuCommandURL_CharDlgForParagraph;
227 m_xURLTransformer->parseStrict( aTargetURL );
228 m_xMenuDispatch_CharDlgForParagraph = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
231 void LanguageSelectionMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopupMenu , const Mode eMode )
233 VCLXPopupMenu* pVCLPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
234 PopupMenu* pPopupMenu = 0;
236 vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
238 resetPopupMenu( rPopupMenu );
239 if (!m_bShowMenu)
240 return;
242 if ( pVCLPopupMenu )
243 pPopupMenu = (PopupMenu *)pVCLPopupMenu->GetMenu();
245 String aCmd;
246 String aCmd_Dialog;
247 String aCmd_Language;
248 if( eMode == MODE_SetLanguageSelectionMenu )
250 aCmd_Dialog+=String::CreateFromAscii(".uno:FontDialog?Language:string=*");
251 aCmd_Language+=String::CreateFromAscii(".uno:LanguageStatus?Language:string=Current_");
253 else if ( eMode == MODE_SetLanguageParagraphMenu )
255 aCmd_Dialog+=String::CreateFromAscii(".uno:FontDialogForParagraph");
256 aCmd_Language+=String::CreateFromAscii(".uno:LanguageStatus?Language:string=Paragraph_");
258 else if ( eMode == MODE_SetLanguageAllTextMenu )
260 aCmd_Dialog+=String::CreateFromAscii(".uno:LanguageStatus?Language:string=*");
261 aCmd_Language+=String::CreateFromAscii(".uno:LanguageStatus?Language:string=Default_");
264 //Reference< awt::XMenuExtended > m_xMenuExtended( m_xPopupMenu, UNO_QUERY );
265 std::map< ::rtl::OUString, ::rtl::OUString > LangItems;
267 SvtLanguageTable aLanguageTable;
268 USHORT nItemId = 1;
270 //1--add current language
271 if(m_aCurLang.getLength())
273 LangItems[m_aCurLang]=m_aCurLang;
276 SvtLanguageTable aLangTable;
277 //2--System
278 const AllSettings& rAllSettings=Application::GetSettings();
279 LanguageType rSystemLanguage = rAllSettings.GetLanguage();
280 if(rSystemLanguage!=LANGUAGE_DONTKNOW)
282 if (IsScriptTypeMatchingToLanguage(m_nScriptType,rSystemLanguage ))
283 LangItems[::rtl::OUString(aLangTable.GetString(rSystemLanguage))]=::rtl::OUString(aLangTable.GetString(rSystemLanguage));
286 //3--UI
287 LanguageType rUILanguage = rAllSettings.GetUILanguage();
288 if(rUILanguage!=LANGUAGE_DONTKNOW)
290 if (IsScriptTypeMatchingToLanguage(m_nScriptType, rUILanguage ))
291 LangItems[::rtl::OUString(aLangTable.GetString(rUILanguage))]=::rtl::OUString(aLangTable.GetString(rUILanguage));
294 //4--guessed language
295 uno::Reference< linguistic2::XLanguageGuessing > xLangGuesser( m_aLangGuessHelper.GetGuesser() );
296 if (xLangGuesser.is() && m_aGuessedText.getLength() > 0)
298 ::com::sun::star::lang::Locale aLocale(xLangGuesser->guessPrimaryLanguage( m_aGuessedText, 0, m_aGuessedText.getLength()) );
299 LanguageType nLang = MsLangId::convertLocaleToLanguageWithFallback( aLocale );
300 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_NONE && nLang != LANGUAGE_SYSTEM
301 && IsScriptTypeMatchingToLanguage( m_nScriptType, nLang ))
302 LangItems[aLangTable.GetString(nLang)]=aLangTable.GetString(nLang);
305 //5--keyboard language
306 if(m_aKeyboardLang!=::rtl::OUString::createFromAscii(""))
308 if (IsScriptTypeMatchingToLanguage(m_nScriptType, aLanguageTable.GetType(m_aKeyboardLang)))
309 LangItems[m_aKeyboardLang] = m_aKeyboardLang;
312 //6--all languages used in current document
313 Reference< com::sun::star::frame::XModel > xModel;
314 if ( m_xFrame.is() )
316 Reference< com::sun::star::frame::XController > xController( m_xFrame->getController(), UNO_QUERY );
317 if ( xController.is() )
318 xModel = xController->getModel();
320 Reference< document::XDocumentLanguages > xDocumentLanguages( xModel, UNO_QUERY );
321 /*the description of m_nScriptType
322 LATIN : 1
323 ASIAN : 2
324 COMPLEX:4
325 LATIN + ASIAN : 3
326 LATIN + COMPLEX : 5
327 ASIAN + COMPLEX : 6
328 LATIN + ASIAN + COMPLEX : 7
331 sal_Int16 nCount=7;
332 if(xDocumentLanguages.is())
334 Sequence< Locale > rLocales(xDocumentLanguages->getDocumentLanguages(m_nScriptType,nCount));
335 if(rLocales.getLength()>0)
337 for(USHORT i = 0; i<rLocales.getLength();++i)
339 if (LangItems.size()==7)
340 break;
341 const Locale& rLocale=rLocales[i];
342 if(IsScriptTypeMatchingToLanguage(m_nScriptType, aLanguageTable.GetType(rLocale.Language)))
343 LangItems[rLocale.Language] = rLocale.Language;
347 std::map< sal_Int16, ::rtl::OUString > LangTable;
349 const ::rtl::OUString sAsterix(RTL_CONSTASCII_USTRINGPARAM("*"));
350 for(std::map< ::rtl::OUString, ::rtl::OUString >::const_iterator it = LangItems.begin(); it != LangItems.end(); ++it)
352 if(it->first != ::rtl::OUString( aLangTable.GetString( LANGUAGE_NONE ) )&&
353 it->first != sAsterix &&
354 it->first.getLength())
356 ++nItemId;
357 pPopupMenu->InsertItem( nItemId,it->first);
358 LangTable[nItemId] = it->first;
359 if(it->first == m_aCurLang && eMode == MODE_SetLanguageSelectionMenu )
361 //make a sign for the current language
362 pPopupMenu->CheckItem(nItemId,TRUE);
364 aCmd=aCmd_Language;
365 aCmd+=(String)it->first;
366 pPopupMenu->SetItemCommand(nItemId,aCmd);
370 //7--none
371 nItemId++;
372 pPopupMenu->InsertItem( nItemId, String(FwlResId( STR_LANGSTATUS_NONE )) );
373 aCmd=aCmd_Language;
374 aCmd+=String::CreateFromAscii("LANGUAGE_NONE");
375 pPopupMenu->SetItemCommand(nItemId,aCmd);
377 //More...
378 nItemId++;
379 pPopupMenu->InsertItem( nItemId, String(FwlResId( STR_LANGSTATUS_MORE )));
380 pPopupMenu->SetItemCommand(nItemId,aCmd_Dialog);
384 void SAL_CALL LanguageSelectionMenuController::updatePopupMenu() throw ( ::com::sun::star::uno::RuntimeException )
386 PopupMenuControllerBase::updatePopupMenu();
388 // Force status update to get information about the current languages
389 ResetableGuard aLock( m_aLock );
390 Reference< XDispatch > xDispatch( m_xLanguageDispatch );
391 com::sun::star::util::URL aTargetURL;
392 aTargetURL.Complete = m_aLangStatusCommandURL;
393 m_xURLTransformer->parseStrict( aTargetURL );
394 aLock.unlock();
396 if ( xDispatch.is() )
398 xDispatch->addStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL );
399 xDispatch->removeStatusListener( SAL_STATIC_CAST( XStatusListener*, this ), aTargetURL );
402 // TODO: Fill menu with the information retrieved by the status update
404 if( m_aCommandURL.equalsAscii( ".uno:SetLanguageSelectionMenu" ))
406 fillPopupMenu(m_xPopupMenu, MODE_SetLanguageSelectionMenu );
408 else if( m_aCommandURL.equalsAscii( ".uno:SetLanguageParagraphMenu" ))
410 fillPopupMenu(m_xPopupMenu, MODE_SetLanguageParagraphMenu );
412 else if( m_aCommandURL.equalsAscii( ".uno:SetLanguageAllTextMenu" ))
414 fillPopupMenu(m_xPopupMenu, MODE_SetLanguageAllTextMenu );
418 // XInitialization
419 void SAL_CALL LanguageSelectionMenuController::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
421 ResetableGuard aLock( m_aLock );
423 sal_Bool bInitalized( m_bInitialized );
424 if ( !bInitalized )
426 PopupMenuControllerBase::initialize(aArguments);
428 if ( m_bInitialized )
430 m_aLangStatusCommandURL = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:LanguageStatus" ));
431 m_aMenuCommandURL_Lang = m_aLangStatusCommandURL;
432 m_aMenuCommandURL_Font = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontDialog" ));
433 m_aMenuCommandURL_CharDlgForParagraph = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FontDialogForParagraph" ));