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 //_________________________________________________________________________________________________________________
37 //_________________________________________________________________________________________________________________
38 #include <threadhelp/resetableguard.hxx>
41 //_________________________________________________________________________________________________________________
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>
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>
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>
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>
79 #include <dispatch/uieventloghelper.hxx>
81 #include "helper/mischelper.hxx"
83 //_________________________________________________________________________________________________________________
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
;
98 DEFINE_XSERVICEINFO_MULTISERVICE ( LanguageSelectionMenuController
,
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()
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
);
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();
134 void SAL_CALL
LanguageSelectionMenuController::statusChanged( const FeatureStateEvent
& Event
) throw ( RuntimeException
)
136 vos::OGuard
aSolarMutexGuard( Application::GetSolarMutex() );
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
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
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
);
243 pPopupMenu
= (PopupMenu
*)pVCLPopupMenu
->GetMenu();
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
;
270 //1--add current language
271 if(m_aCurLang
.getLength())
273 LangItems
[m_aCurLang
]=m_aCurLang
;
276 SvtLanguageTable aLangTable
;
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
));
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
;
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
328 LATIN + ASIAN + COMPLEX : 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)
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())
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
);
365 aCmd
+=(String
)it
->first
;
366 pPopupMenu
->SetItemCommand(nItemId
,aCmd
);
372 pPopupMenu
->InsertItem( nItemId
, String(FwlResId( STR_LANGSTATUS_NONE
)) );
374 aCmd
+=String::CreateFromAscii("LANGUAGE_NONE");
375 pPopupMenu
->SetItemCommand(nItemId
,aCmd
);
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
);
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
);
419 void SAL_CALL
LanguageSelectionMenuController::initialize( const Sequence
< Any
>& aArguments
) throw ( Exception
, RuntimeException
)
421 ResetableGuard
aLock( m_aLock
);
423 sal_Bool
bInitalized( m_bInitialized
);
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" ));