fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / framework / source / uielement / langselectionstatusbarcontroller.cxx
blobe348cb8ddd90df98c88023a3cf0fc4e4f59b1a04
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <classes/fwkresid.hxx>
21 #include <services.h>
22 #include <classes/resource.hrc>
23 #include <osl/mutex.hxx>
24 #include <vcl/svapp.hxx>
25 #include <vcl/window.hxx>
26 #include <vcl/status.hxx>
27 #include <toolkit/helper/convert.hxx>
29 #include <boost/noncopyable.hpp>
30 #include <cppuhelper/supportsservice.hxx>
31 #include <toolkit/helper/vclunohelper.hxx>
32 #include <com/sun/star/awt/PopupMenu.hpp>
33 #include <com/sun/star/awt/PopupMenuDirection.hpp>
34 #include <svtools/langtab.hxx>
35 #include <svtools/statusbarcontroller.hxx>
36 #include <sal/types.h>
37 #include <com/sun/star/awt/MenuItemStyle.hpp>
38 #include <com/sun/star/document/XDocumentLanguages.hpp>
39 #include <i18nlangtag/mslangid.hxx>
40 #include <com/sun/star/i18n/ScriptType.hpp>
41 #include <com/sun/star/frame/XModule.hpp>
42 #include <com/sun/star/frame/XModel.hpp>
44 #include <com/sun/star/frame/XFrame.hpp>
45 #include <com/sun/star/frame/XDispatch.hpp>
46 #include <com/sun/star/frame/XDispatchProvider.hpp>
47 #include <comphelper/processfactory.hxx>
49 #include <tools/gen.hxx>
50 #include <com/sun/star/awt/Command.hpp>
51 #include <svl/languageoptions.hxx>
53 #include "helper/mischelper.hxx"
55 #include <rtl/ustrbuf.hxx>
56 #include <rtl/ref.hxx>
58 #include <macros/generic.hxx>
59 #include <macros/xinterface.hxx>
60 #include <macros/xtypeprovider.hxx>
61 #include <macros/xserviceinfo.hxx>
62 #include <stdtypes.h>
64 #include <map>
65 #include <set>
67 using namespace ::cppu;
68 using namespace ::com::sun::star;
69 using namespace css::uno;
70 using namespace css::lang;
71 using namespace css::frame;
72 using namespace css::i18n;
73 using namespace css::document;
74 using namespace framework;
76 namespace {
78 class LangSelectionStatusbarController:
79 public svt::StatusbarController, private boost::noncopyable
81 public:
82 explicit LangSelectionStatusbarController( const css::uno::Reference< css::uno::XComponentContext >& xContext );
84 // XInitialization
85 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
87 // XStatusListener
88 virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& Event ) throw ( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
90 // XStatusbarController
91 virtual void SAL_CALL command( const css::awt::Point& aPos,
92 ::sal_Int32 nCommand,
93 sal_Bool bMouseEvent,
94 const css::uno::Any& aData ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
95 virtual void SAL_CALL click( const css::awt::Point& aPos ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
97 private:
98 virtual ~LangSelectionStatusbarController() {}
100 bool m_bShowMenu; // if the menu is to be displayed or not (depending on the selected object/text)
101 SvtScriptType m_nScriptType; // the flags for the different script types available in the selection, LATIN = 0x0001, ASIAN = 0x0002, COMPLEX = 0x0004
102 OUString m_aCurLang; // the language of the current selection, "*" if there are more than one languages
103 OUString m_aKeyboardLang; // the keyboard language
104 OUString m_aGuessedTextLang; // the 'guessed' language for the selection, "" if none could be guessed
105 LanguageGuessingHelper m_aLangGuessHelper;
107 void LangMenu( const css::awt::Point& aPos ) throw (css::uno::RuntimeException);
110 LangSelectionStatusbarController::LangSelectionStatusbarController( const uno::Reference< uno::XComponentContext >& xContext ) :
111 svt::StatusbarController( xContext, uno::Reference< frame::XFrame >(), OUString(), 0 ),
112 m_bShowMenu( true ),
113 m_nScriptType( SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX ),
114 m_aLangGuessHelper( xContext )
118 void SAL_CALL LangSelectionStatusbarController::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
119 throw (css::uno::Exception, css::uno::RuntimeException, std::exception)
121 SolarMutexGuard aSolarMutexGuard;
123 svt::StatusbarController::initialize( aArguments );
125 if ( m_xStatusbarItem.is() )
127 m_xStatusbarItem->setText( FWK_RESSTR(STR_LANGSTATUS_MULTIPLE_LANGUAGES) );
128 m_xStatusbarItem->setQuickHelpText(FWK_RESSTR(STR_LANGSTATUS_HINT));
132 void LangSelectionStatusbarController::LangMenu(
133 const css::awt::Point& aPos )
134 throw (css::uno::RuntimeException)
136 if (!m_bShowMenu)
137 return;
139 //add context menu
140 Reference< awt::XPopupMenu > xPopupMenu( awt::PopupMenu::create( m_xContext ) );
141 //sub menu that contains all items except the last two items: Separator + Set Language for Paragraph
142 Reference< awt::XPopupMenu > subPopupMenu( awt::PopupMenu::create( m_xContext ) );
144 // get languages to be displayed in the menu
145 std::set< OUString > aLangItems;
146 FillLangItems( aLangItems, m_xFrame, m_aLangGuessHelper,
147 m_nScriptType, m_aCurLang, m_aKeyboardLang, m_aGuessedTextLang );
149 // add first few entries to main menu
150 sal_Int16 nItemId = static_cast< sal_Int16 >(MID_LANG_SEL_1);
151 const OUString sAsterisk("*"); // multiple languages in current selection
152 const OUString sEmpty; // 'no language found' from language guessing
153 const OUString sNone( SvtLanguageTable::GetLanguageString( LANGUAGE_NONE ));
154 std::map< sal_Int16, OUString > aLangMap;
155 std::set< OUString >::const_iterator it;
156 for (it = aLangItems.begin(); it != aLangItems.end(); ++it)
158 const OUString & rStr( *it );
159 if ( rStr != sNone &&
160 rStr != sAsterisk &&
161 rStr != sEmpty)
163 DBG_ASSERT( MID_LANG_SEL_1 <= nItemId && nItemId <= MID_LANG_SEL_9,
164 "nItemId outside of expected range!" );
165 xPopupMenu->insertItem( nItemId, rStr, 0, nItemId );
166 if ( rStr == m_aCurLang )
168 //make a sign for the current language
169 xPopupMenu->checkItem( nItemId, sal_True );
171 aLangMap[ nItemId ] = rStr;
172 ++nItemId;
176 xPopupMenu->insertItem( MID_LANG_SEL_NONE, FWK_RESSTR(STR_LANGSTATUS_NONE), 0, MID_LANG_SEL_NONE );
177 if ( sNone == m_aCurLang )
178 xPopupMenu->checkItem( MID_LANG_SEL_NONE, sal_True );
179 xPopupMenu->insertItem( MID_LANG_SEL_RESET, FWK_RESSTR(STR_RESET_TO_DEFAULT_LANGUAGE), 0, MID_LANG_SEL_RESET );
180 xPopupMenu->insertItem( MID_LANG_SEL_MORE, FWK_RESSTR(STR_LANGSTATUS_MORE), 0, MID_LANG_SEL_MORE );
182 // add entries to submenu ('set language for paragraph')
183 nItemId = static_cast< sal_Int16 >(MID_LANG_PARA_1);
184 for (it = aLangItems.begin(); it != aLangItems.end(); ++it)
186 const OUString & rStr( *it );
187 if( rStr != sNone &&
188 rStr != sAsterisk &&
189 rStr != sEmpty)
191 DBG_ASSERT( MID_LANG_PARA_1 <= nItemId && nItemId <= MID_LANG_PARA_9,
192 "nItemId outside of expected range!" );
193 subPopupMenu->insertItem( nItemId, rStr, 0, nItemId );
194 aLangMap[nItemId] = rStr;
195 ++nItemId;
198 subPopupMenu->insertItem( MID_LANG_PARA_NONE, FWK_RESSTR(STR_LANGSTATUS_NONE), 0, MID_LANG_PARA_NONE );
199 subPopupMenu->insertItem( MID_LANG_PARA_RESET, FWK_RESSTR(STR_RESET_TO_DEFAULT_LANGUAGE), 0, MID_LANG_PARA_RESET );
200 subPopupMenu->insertItem( MID_LANG_PARA_MORE, FWK_RESSTR(STR_LANGSTATUS_MORE), 0, MID_LANG_PARA_MORE );
202 // add last two entries to main menu
203 xPopupMenu->insertSeparator( MID_LANG_PARA_SEPARATOR );
204 xPopupMenu->insertItem( MID_LANG_PARA_STRING, FWK_RESSTR(STR_SET_LANGUAGE_FOR_PARAGRAPH), 0, MID_LANG_PARA_STRING );
205 xPopupMenu->setPopupMenu( MID_LANG_PARA_STRING, subPopupMenu );
207 // now display the popup menu and execute every command ...
209 Reference< awt::XWindowPeer > xParent( m_xParentWindow, UNO_QUERY );
210 com::sun::star::awt::Rectangle aRect( aPos.X, aPos.Y, 0, 0 );
211 sal_Int16 nId = xPopupMenu->execute( xParent, aRect, com::sun::star::awt::PopupMenuDirection::EXECUTE_UP+16 );
212 //click "More..."
213 if ( nId && m_xFrame.is() )
215 OUStringBuffer aBuff;
216 //set selected language as current language for selection
217 const OUString aSelectedLang = aLangMap[nId];
219 if (MID_LANG_SEL_1 <= nId && nId <= MID_LANG_SEL_9)
221 aBuff.append( ".uno:LanguageStatus?Language:string=Current_" );
222 aBuff.append( aSelectedLang );
224 else if (nId == MID_LANG_SEL_NONE)
226 //set None as current language for selection
227 aBuff.append( ".uno:LanguageStatus?Language:string=Current_LANGUAGE_NONE" );
229 else if (nId == MID_LANG_SEL_RESET)
231 // reset language attributes for selection
232 aBuff.append( ".uno:LanguageStatus?Language:string=Current_RESET_LANGUAGES" );
234 else if (nId == MID_LANG_SEL_MORE)
236 //open the dialog "format/character" for current selection
237 aBuff.append( ".uno:FontDialog?Page:string=font" );
239 else if (MID_LANG_PARA_1 <= nId && nId <= MID_LANG_PARA_9)
241 aBuff.append( ".uno:LanguageStatus?Language:string=Paragraph_" );
242 aBuff.append( aSelectedLang );
244 else if (nId == MID_LANG_PARA_NONE)
246 //set None as language for current paragraph
247 aBuff.append( ".uno:LanguageStatus?Language:string=Paragraph_LANGUAGE_NONE" );
249 else if (nId == MID_LANG_PARA_RESET)
251 // reset language attributes for paragraph
252 aBuff.append( ".uno:LanguageStatus?Language:string=Paragraph_RESET_LANGUAGES" );
254 else if (nId == MID_LANG_PARA_MORE)
256 //open the dialog "format/character" for current paragraph
257 aBuff.append( ".uno:FontDialogForParagraph" );
260 const Sequence< beans::PropertyValue > aDummyArgs;
261 execute( aBuff.makeStringAndClear(), aDummyArgs );
265 void SAL_CALL LangSelectionStatusbarController::command(
266 const css::awt::Point& aPos,
267 ::sal_Int32 nCommand,
268 sal_Bool /*bMouseEvent*/,
269 const css::uno::Any& /*aData*/ )
270 throw (css::uno::RuntimeException, std::exception)
272 if ( nCommand & ::awt::Command::CONTEXTMENU )
274 LangMenu( aPos );
278 void SAL_CALL LangSelectionStatusbarController::click(
279 const css::awt::Point& aPos )
280 throw (css::uno::RuntimeException, std::exception)
282 LangMenu( aPos );
285 // XStatusListener
286 void SAL_CALL LangSelectionStatusbarController::statusChanged( const FeatureStateEvent& Event )
287 throw ( RuntimeException, std::exception )
289 // This function will be called when observed data changes,
290 // for example the selection or keyboard language.
291 // - It displays the language in use in the status bar
292 // - and it stores the relevant data for creating the menu
293 // at some later point in the member variables
294 // m_nScriptType, m_aCurLang, m_aKeyboardLang, m_aGuessedText
296 SolarMutexGuard aSolarMutexGuard;
298 if ( m_bDisposed )
299 return;
301 m_bShowMenu = true;
302 m_nScriptType = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX; //set the default value
304 if ( m_xStatusbarItem.is() )
306 OUString aStrValue;
307 Sequence< OUString > aSeq;
309 if ( Event.State >>= aStrValue )
310 m_xStatusbarItem->setText( aStrValue );
311 else if ( Event.State >>= aSeq )
313 if ( aSeq.getLength() == 4 )
315 OUString aStatusText = aSeq[0];
316 if (aStatusText == "*")
318 aStatusText = FWK_RESSTR(STR_LANGSTATUS_MULTIPLE_LANGUAGES);
320 m_xStatusbarItem->setText( aStatusText );
322 // Retrieve all other values from the sequence and
323 // store it members!
324 m_aCurLang = aSeq[0];
325 m_nScriptType = static_cast< SvtScriptType >( aSeq[1].toInt32() );
326 m_aKeyboardLang = aSeq[2];
327 m_aGuessedTextLang = aSeq[3];
330 else if ( !Event.State.hasValue() )
332 m_xStatusbarItem->setText( OUString() );
333 m_bShowMenu = false; // no language -> no menu
340 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
341 com_sun_star_comp_framework_LangSelectionStatusbarController_get_implementation(
342 css::uno::XComponentContext *context,
343 css::uno::Sequence<css::uno::Any> const &)
345 return cppu::acquire(new LangSelectionStatusbarController(context));
348 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */