xref: /trunk/main/sw/source/ui/lingu/olmenu.cxx (revision 86e1cf34)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 #include "SwRewriter.hxx"
28 #include "chrdlg.hrc"
29 #include "cmdid.h"
30 #include "comcore.hrc"
31 #include "crsskip.hxx"
32 #include "doc.hxx"
33 #include "docsh.hxx"        //CheckSpellChanges
34 #include "edtwin.hxx"
35 #include "helpid.h"
36 #include "hintids.hxx"
37 #include "langhelper.hxx"
38 #include "ndtxt.hxx"
39 #include "olmenu.hrc"
40 #include "olmenu.hxx"
41 #include "swabstdlg.hxx"
42 #include "swmodule.hxx"
43 #include "swtypes.hxx"
44 #include "swundo.hxx"
45 #include "uitool.hxx"
46 #include "unomid.h"
47 #include "view.hxx"
48 #include "viewopt.hxx"
49 #include "wrtsh.hxx"
50 #include "wview.hxx"
51 #include "swabstdlg.hxx"
52 #include "chrdlg.hrc"
53 
54 
55 #ifndef _SVSTDARR_HXX
56 #define _SVSTDARR_STRINGSDTOR
57 #include <svl/svstdarr.hxx>
58 #endif
59 
60 #include <comphelper/processfactory.hxx>
61 #include <editeng/acorrcfg.hxx>
62 #include <editeng/svxacorr.hxx>
63 #include <editeng/langitem.hxx>
64 #include <editeng/splwrap.hxx>
65 #include <editeng/brshitem.hxx>
66 #include <editeng/unolingu.hxx>
67 #include <i18npool/mslangid.hxx>
68 #include <linguistic/lngprops.hxx>
69 #include <linguistic/misc.hxx>
70 #include <osl/file.hxx>
71 #include <rtl/string.hxx>
72 #include <svtools/filter.hxx>
73 #include <sfx2/dispatch.hxx>
74 #include <sfx2/imagemgr.hxx>
75 #include <sfx2/request.hxx>
76 #include <sfx2/sfxdlg.hxx>
77 #include <svl/itemset.hxx>
78 #include <svl/languageoptions.hxx>
79 #include <svl/stritem.hxx>
80 #include <svtools/filter.hxx>
81 #include <svtools/langtab.hxx>
82 #include <svx/dlgutil.hxx>
83 #include <unotools/lingucfg.hxx>
84 #include <unotools/linguprops.hxx>
85 #include <vcl/msgbox.hxx>
86 #include <vcl/settings.hxx>
87 #include <vcl/svapp.hxx>
88 
89 #include <map>
90 
91 #include <com/sun/star/container/XIndexAccess.hpp>
92 #include <com/sun/star/container/XNameAccess.hpp>
93 #include <com/sun/star/document/XDocumentLanguages.hpp>
94 #include <com/sun/star/frame/XModuleManager.hpp>
95 #include <com/sun/star/frame/XStorable.hpp>
96 #include <com/sun/star/i18n/ScriptType.hpp>
97 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
98 #include <com/sun/star/lang/XServiceInfo.hpp>
99 #include <com/sun/star/linguistic2/SingleProofreadingError.hpp>
100 #include <com/sun/star/linguistic2/XLanguageGuessing.hpp>
101 #include <com/sun/star/linguistic2/XSpellChecker1.hpp>
102 #include <com/sun/star/uno/Any.hxx>
103 
104 
105 using namespace ::com::sun::star;
106 using ::rtl::OUString;
107 
108 extern void lcl_CharDialog( SwWrtShell &rWrtSh, sal_Bool bUseDialog, sal_uInt16 nSlot,const SfxItemSet *pArgs, SfxRequest *pReq );
109 
110 
111 /*--------------------------------------------------------------------------
112 
113 ---------------------------------------------------------------------------*/
114 
115 // tries to determine the language of 'rText'
116 //
lcl_CheckLanguage(const OUString & rText,uno::Reference<linguistic2::XSpellChecker1> xSpell,uno::Reference<linguistic2::XLanguageGuessing> xLangGuess,sal_Bool bIsParaText)117 LanguageType lcl_CheckLanguage(
118 	const OUString &rText,
119     uno::Reference< linguistic2::XSpellChecker1 > xSpell,
120     uno::Reference< linguistic2::XLanguageGuessing > xLangGuess,
121 	sal_Bool bIsParaText )
122 {
123 	LanguageType  nLang = LANGUAGE_NONE;
124 	if (bIsParaText)	// check longer texts with language-guessing...
125 	{
126 		if (!xLangGuess.is())
127 			return nLang;
128 
129 		lang::Locale aLocale( xLangGuess->guessPrimaryLanguage( rText, 0, rText.getLength()) );
130 
131 		// get language as from "Tools/Options - Language Settings - Languages: Locale setting"
132         LanguageType nTmpLang = Application::GetSettings().GetLanguage();
133 
134 		// if the result from language guessing does not provide a 'Country' part
135 		// try to get it by looking up the locale setting of the office.
136         if (aLocale.Country.getLength() == 0)
137         {
138             lang::Locale aTmpLocale = SvxCreateLocale( nTmpLang );
139             if (aTmpLocale.Language == aLocale.Language)
140                 nLang = nTmpLang;
141         }
142         if (nLang == LANGUAGE_NONE) // language not found by looking up the system language...
143             nLang = MsLangId::convertLocaleToLanguageWithFallback( aLocale );
144 		if (nLang == LANGUAGE_SYSTEM)
145 			nLang = nTmpLang;
146 		if (nLang == LANGUAGE_DONTKNOW)
147 			nLang = LANGUAGE_NONE;
148 	}
149 	else	// check single word
150 	{
151 			if (!xSpell.is())
152 			return nLang;
153 
154 		//
155 		// build list of languages to check
156 		//
157 		LanguageType aLangList[4];
158 		const AllSettings& rSettings  = Application::GetSettings();
159 		SvtLinguOptions aLinguOpt;
160 		SvtLinguConfig().GetOptions( aLinguOpt );
161 		// The default document language from "Tools/Options - Language Settings - Languages: Western"
162 		aLangList[0] = MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage, ::com::sun::star::i18n::ScriptType::LATIN);
163 		// The one from "Tools/Options - Language Settings - Languages: User interface"
164 		aLangList[1] = rSettings.GetUILanguage();
165 		// The one from "Tools/Options - Language Settings - Languages: Locale setting"
166 		aLangList[2] = rSettings.GetLanguage();
167 		// en-US
168 		aLangList[3] = LANGUAGE_ENGLISH_US;
169 #ifdef DEBUG
170 		lang::Locale a0( SvxCreateLocale( aLangList[0] ) );
171 		lang::Locale a1( SvxCreateLocale( aLangList[1] ) );
172 		lang::Locale a2( SvxCreateLocale( aLangList[2] ) );
173 		lang::Locale a3( SvxCreateLocale( aLangList[3] ) );
174 #endif
175 
176 		sal_Int32   nCount = sizeof(aLangList) / sizeof(aLangList[0]);
177 		for (sal_Int32 i = 0;  i < nCount;  i++)
178 		{
179 			sal_Int16 nTmpLang = aLangList[i];
180 			if (nTmpLang != LANGUAGE_NONE  &&  nTmpLang != LANGUAGE_DONTKNOW)
181 			{
182 				if (xSpell->hasLanguage( nTmpLang ) &&
183                     xSpell->isValid( rText, nTmpLang, uno::Sequence< beans::PropertyValue >() ))
184 				{
185 					nLang = nTmpLang;
186 					break;
187 				}
188 			}
189 		}
190 	}
191 
192     return nLang;
193 }
194 
195 
196 /// @returns : the language for the selected text that is set for the
197 ///     specified attribute (script type).
198 ///     If there are more than one languages used LANGUAGE_DONTKNOW will be returned.
199 /// @param nLangWhichId : one of
200 ///     RES_CHRATR_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CTL_LANGUAGE,
201 /// @returns: the language in use for the selected text.
202 ///     'In use' means the language(s) matching the script type(s) of the
203 ///     selected text. Or in other words, the language a spell checker would use.
204 ///     If there is more than one language LANGUAGE_DONTKNOW will be returned.
205 // check if nScriptType includes the script type associated to nLang
lcl_checkScriptType(sal_Int16 nScriptType,LanguageType nLang)206 inline bool lcl_checkScriptType( sal_Int16 nScriptType, LanguageType nLang )
207 {
208 	return 0 != (nScriptType & SvtLanguageOptions::GetScriptTypeOfLanguage( nLang ));
209 }
210 
fillLangPopupMenu(PopupMenu * pPopupMenu,sal_uInt16 nLangItemIdStart,uno::Sequence<OUString> aSeq,SwWrtShell * pWrtSh,std::map<sal_Int16,::rtl::OUString> & rLangTable)211 void SwSpellPopup::fillLangPopupMenu(
212 	PopupMenu *pPopupMenu,
213     sal_uInt16 nLangItemIdStart,
214     uno::Sequence< OUString > aSeq,
215 	SwWrtShell* pWrtSh,
216     std::map< sal_Int16, ::rtl::OUString > &rLangTable )
217 {
218 	if (!pPopupMenu)
219         return;
220 
221     SvtLanguageTable    aLanguageTable;
222 
223     // set of languages to be displayed in the sub menus
224     std::set< OUString > aLangItems;
225 
226     OUString    aCurLang( aSeq[0] );
227     sal_uInt16      nScriptType = static_cast< sal_Int16 >(aSeq[1].toInt32());
228     OUString    aKeyboardLang( aSeq[2] );
229     OUString    aGuessedTextLang( aSeq[3] );
230 
231     if (aCurLang != OUString() &&
232         LANGUAGE_DONTKNOW != aLanguageTable.GetType( aCurLang ))
233         aLangItems.insert( aCurLang );
234 
235 	//2--System
236     const AllSettings& rAllSettings = Application::GetSettings();
237 	LanguageType rSystemLanguage = rAllSettings.GetLanguage();
238     if (rSystemLanguage != LANGUAGE_DONTKNOW)
239 	{
240         if (lcl_checkScriptType( nScriptType, rSystemLanguage ))
241             aLangItems.insert( aLanguageTable.GetString(rSystemLanguage) );
242 	}
243 
244 	//3--UI
245 	LanguageType rUILanguage = rAllSettings.GetUILanguage();
246     if (rUILanguage != LANGUAGE_DONTKNOW)
247 	{
248 		if (lcl_checkScriptType(nScriptType, rUILanguage ))
249             aLangItems.insert( aLanguageTable.GetString(rUILanguage) );
250 	}
251 
252 	//4--guessed language
253     if (aGuessedTextLang.getLength() > 0)
254 	{
255         if (lcl_checkScriptType(nScriptType, aLanguageTable.GetType(aGuessedTextLang)))
256             aLangItems.insert( aGuessedTextLang );
257 	}
258 
259 	//5--keyboard language
260     if (aKeyboardLang.getLength() > 0)
261 	{
262         if (lcl_checkScriptType(nScriptType, aLanguageTable.GetType(aKeyboardLang)))
263             aLangItems.insert( aKeyboardLang );
264 	}
265 
266 	//6--all languages used in current document
267 	uno::Reference< com::sun::star::frame::XModel > xModel;
268 	uno::Reference< com::sun::star::frame::XController > xController( pWrtSh->GetView().GetViewFrame()->GetFrame().GetFrameInterface()->getController(), uno::UNO_QUERY );
269 	if ( xController.is() )
270         xModel = xController->getModel();
271 	uno::Reference< document::XDocumentLanguages > xDocumentLanguages( xModel, uno::UNO_QUERY );
272     /*the description of nScriptType flags
273       LATIN :   0x0001
274       ASIAN :   0x0002
275       COMPLEX:  0x0004
276 	*/
277     const sal_Int16 nMaxCount = 7;
278     if (xDocumentLanguages.is())
279 	{
280         uno::Sequence< lang::Locale > rLocales( xDocumentLanguages->getDocumentLanguages( nScriptType, nMaxCount ) );
281         if (rLocales.getLength() > 0)
282 		{
283             for (sal_uInt16 i = 0; i < rLocales.getLength(); ++i)
284 			{
285                 if (aLangItems.size() == (size_t)nMaxCount)
286 					break;
287                 const lang::Locale& rLocale = rLocales[i];
288                 if (lcl_checkScriptType( nScriptType, aLanguageTable.GetType( rLocale.Language )))
289                     aLangItems.insert( rLocale.Language );
290 			}
291 		}
292 	}
293 
294 
295     sal_uInt16 nItemId = nLangItemIdStart;
296     const OUString sAsterix(RTL_CONSTASCII_USTRINGPARAM("*"));  // multiple languages in current selection
297     const OUString sEmpty;  // 'no language found' from language guessing
298     std::set< OUString >::const_iterator it;
299     for (it = aLangItems.begin(); it != aLangItems.end(); ++it)
300 	{
301         OUString aEntryTxt( *it );
302         if (aEntryTxt != OUString( aLanguageTable.GetString( LANGUAGE_NONE ) )&&
303             aEntryTxt != sAsterix &&
304             aEntryTxt != sEmpty)
305 		{
306             DBG_ASSERT( nLangItemIdStart <= nItemId && nItemId <= nLangItemIdStart + MN_MAX_NUM_LANG,
307                     "nItemId outside of expected range!" );
308 			pPopupMenu->InsertItem( nItemId, aEntryTxt, MIB_RADIOCHECK );
309             if (aEntryTxt == aCurLang)
310 			{
311 				//make a check mark for the current language
312 				pPopupMenu->CheckItem( nItemId, sal_True );
313 			}
314             rLangTable[ nItemId ] = aEntryTxt;
315             ++nItemId;
316 		}
317 	}
318 
319     pPopupMenu->InsertItem( nLangItemIdStart + MN_NONE_OFFSET,  String(SW_RES( STR_LANGSTATUS_NONE )), MIB_RADIOCHECK );
320     pPopupMenu->InsertItem( nLangItemIdStart + MN_RESET_OFFSET, String(SW_RES( STR_RESET_TO_DEFAULT_LANGUAGE )), MIB_RADIOCHECK );
321     pPopupMenu->InsertItem( nLangItemIdStart + MN_MORE_OFFSET,  String(SW_RES( STR_LANGSTATUS_MORE )), MIB_RADIOCHECK );
322 }
323 
324 
lcl_GetImageFromPngUrl(const OUString & rFileUrl)325 static Image lcl_GetImageFromPngUrl( const OUString &rFileUrl )
326 {
327     Image aRes;
328     OUString aTmp;
329     osl::FileBase::getSystemPathFromFileURL( rFileUrl, aTmp );
330 //    ::rtl::OString aPath = OString( aTmp.getStr(), aTmp.getLength(), osl_getThreadTextEncoding() );
331 #if defined(WNT)
332 //    aTmp = lcl_Win_GetShortPathName( aTmp );
333 #endif
334     Graphic aGraphic;
335     const String aFilterName( RTL_CONSTASCII_USTRINGPARAM( IMP_PNG ) );
336     if( GRFILTER_OK == GraphicFilter::LoadGraphic( aTmp, aFilterName, aGraphic ) )
337     {
338         aRes = Image( aGraphic.GetBitmapEx() );
339     }
340     return aRes;
341 }
342 
343 
RetrieveLabelFromCommand(const OUString & aCmdURL)344 OUString RetrieveLabelFromCommand( const OUString& aCmdURL )
345 {
346     OUString aLabel;
347 	if ( aCmdURL.getLength() )
348 	{
349 		try
350 		{
351             uno::Reference< container::XNameAccess > xNameAccess( ::comphelper::getProcessServiceFactory()->createInstance( OUString::createFromAscii("com.sun.star.frame.UICommandDescription") ), uno::UNO_QUERY );
352 			if ( xNameAccess.is() )
353 			{
354 		        uno::Reference< container::XNameAccess > xUICommandLabels;
355                 const OUString aModule( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextDocument" ) );
356 				uno::Any a = xNameAccess->getByName( aModule );
357 				uno::Reference< container::XNameAccess > xUICommands;
358 				a >>= xUICommandLabels;
359                 OUString aStr;
360 				uno::Sequence< beans::PropertyValue > aPropSeq;
361 				a = xUICommandLabels->getByName( aCmdURL );
362 				if ( a >>= aPropSeq )
363 				{
364 					for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
365 					{
366 						if ( aPropSeq[i].Name.equalsAscii( "Name" ))
367 						{
368 							aPropSeq[i].Value >>= aStr;
369 							break;
370 						}
371 					}
372 				}
373 				aLabel = aStr;
374 			}
375 		}
376 		catch ( uno::Exception& )
377 		{
378 		}
379 	}
380 
381     return aLabel;
382 }
383 
384 
SwSpellPopup(SwWrtShell * pWrtSh,const uno::Reference<linguistic2::XSpellAlternatives> & xAlt,const String & rParaText)385 SwSpellPopup::SwSpellPopup(
386         SwWrtShell* pWrtSh,
387         const uno::Reference< linguistic2::XSpellAlternatives >  &xAlt,
388         const String &rParaText ) :
389 PopupMenu( SW_RES(MN_SPELL_POPUP) ),
390 pSh( pWrtSh ),
391 xSpellAlt(xAlt),
392 bGrammarResults(false)
393 {
394 	DBG_ASSERT(xSpellAlt.is(), "no spelling alternatives available");
395 
396 //    CreateAutoMnemonics();
397     SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS);
398 
399     nCheckedLanguage = LANGUAGE_NONE;
400 	if (xSpellAlt.is())
401     {
402         nCheckedLanguage = SvxLocaleToLanguage( xSpellAlt->getLocale() );
403         aSuggestions = xSpellAlt->getAlternatives();
404     }
405     sal_Int16 nStringCount = static_cast< sal_Int16 >( aSuggestions.getLength() );
406 
407     SvtLinguConfig aCfg;
408     const bool bHC = Application::GetSettings().GetStyleSettings().GetHighContrastMode();
409 
410     PopupMenu *pMenu = GetPopupMenu(MN_AUTOCORR);
411     pMenu->SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS);
412 	sal_Bool bEnable = sal_False;
413 	if( nStringCount )
414 	{
415         Image aImage;
416         OUString aSuggestionImageUrl;
417         uno::Reference< container::XNamed > xNamed( xSpellAlt, uno::UNO_QUERY );
418         if (xNamed.is())
419         {
420             aSuggestionImageUrl = aCfg.GetSpellAndGrammarContextSuggestionImage( xNamed->getName(), bHC );
421             aImage = Image( lcl_GetImageFromPngUrl( aSuggestionImageUrl ) );
422         }
423 
424 		InsertSeparator(0);
425 		bEnable = sal_True;
426         sal_uInt16 nAutoCorrItemId  = MN_AUTOCORR_START;
427         sal_uInt16 nItemId          = MN_SUGGESTION_START;
428         for (sal_uInt16 i = 0; i < nStringCount; ++i)
429 		{
430             const String aEntry = aSuggestions[ i ];
431             InsertItem( nItemId, aEntry, 0, i );
432             SetHelpId( nItemId, HID_LINGU_REPLACE);
433             if (aSuggestionImageUrl.getLength() > 0)
434                 SetItemImage( nItemId, aImage );
435 
436             pMenu->InsertItem( nAutoCorrItemId, aEntry );
437             pMenu->SetHelpId( nAutoCorrItemId, HID_LINGU_AUTOCORR);
438 
439             ++nAutoCorrItemId;
440             ++nItemId;
441 		}
442 	}
443 
444     OUString aIgnoreSelection( String( SW_RES( STR_IGNORE_SELECTION ) ) );
445 	OUString aSpellingAndGrammar = RetrieveLabelFromCommand( C2U(".uno:SpellingAndGrammarDialog") );
446     SetItemText( MN_SPELLING_DLG, aSpellingAndGrammar );
447     sal_uInt16 nItemPos = GetItemPos( MN_IGNORE_WORD );
448     InsertItem( MN_IGNORE_SELECTION, aIgnoreSelection, 0, nItemPos );
449     SetHelpId( MN_IGNORE_SELECTION, HID_LINGU_IGNORE_SELECTION);
450 
451 	EnableItem( MN_AUTOCORR, bEnable );
452 
453     uno::Reference< linguistic2::XLanguageGuessing > xLG = SW_MOD()->GetLanguageGuesser();
454     nGuessLangWord = LANGUAGE_NONE;
455     nGuessLangPara = LANGUAGE_NONE;
456     if (xSpellAlt.is() && xLG.is())
457     {
458 		nGuessLangWord = lcl_CheckLanguage( xSpellAlt->getWord(), ::GetSpellChecker(), xLG, sal_False );
459 		nGuessLangPara = lcl_CheckLanguage( rParaText, ::GetSpellChecker(), xLG, sal_True );
460 	}
461 	if (nGuessLangWord != LANGUAGE_NONE || nGuessLangPara != LANGUAGE_NONE)
462 	{
463 		// make sure LANGUAGE_NONE gets not used as menu entry
464 		if (nGuessLangWord == LANGUAGE_NONE)
465 			nGuessLangWord = nGuessLangPara;
466 		if (nGuessLangPara == LANGUAGE_NONE)
467 			nGuessLangPara = nGuessLangWord;
468 	}
469 
470     pMenu = GetPopupMenu(MN_ADD_TO_DIC);
471 //    pMenu->CreateAutoMnemonics();
472     pMenu->SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS);     //! necessary to retrieve the correct dictionary name in 'Execute' below
473     bEnable = sal_False;    // enable MN_ADD_TO_DIC?
474     uno::Reference< linguistic2::XDictionaryList >    xDicList( SvxGetDictionaryList() );
475     if (xDicList.is())
476     {
477         // add the default positive dictionary to dic-list (if not already done).
478         // This is to ensure that there is at least one dictionary to which
479         // words could be added.
480         uno::Reference< linguistic2::XDictionary >  xDic( SvxGetOrCreatePosDic( xDicList ) );
481         if (xDic.is())
482             xDic->setActive( sal_True );
483 
484         aDics = xDicList->getDictionaries();
485         const uno::Reference< linguistic2::XDictionary >  *pDic = aDics.getConstArray();
486         sal_uInt16 nDicCount = static_cast< sal_uInt16 >(aDics.getLength());
487 
488         sal_uInt16 nItemId = MN_DICTIONARIES_START;
489         for( sal_uInt16 i = 0; i < nDicCount; i++ )
490         {
491             uno::Reference< linguistic2::XDictionary >  xDicTmp( pDic[i], uno::UNO_QUERY );
492             if (!xDicTmp.is() || SvxGetIgnoreAllList() == xDicTmp)
493                 continue;
494 
495             uno::Reference< frame::XStorable > xStor( xDicTmp, uno::UNO_QUERY );
496             LanguageType nActLanguage = SvxLocaleToLanguage( xDicTmp->getLocale() );
497             if( xDicTmp->isActive()
498                 &&  xDicTmp->getDictionaryType() != linguistic2::DictionaryType_NEGATIVE
499                 && (nCheckedLanguage == nActLanguage || LANGUAGE_NONE == nActLanguage )
500                 && (!xStor.is() || !xStor->isReadonly()) )
501             {
502                 // the extra 1 is because of the (possible) external
503                 // linguistic entry above
504                 pMenu->InsertItem( nItemId, xDicTmp->getName() );
505                 bEnable = sal_True;
506 
507                 uno::Reference< lang::XServiceInfo > xSvcInfo( xDicTmp, uno::UNO_QUERY );
508                 if (xSvcInfo.is())
509                 {
510                     OUString aDictionaryImageUrl( aCfg.GetSpellAndGrammarContextDictionaryImage(
511                             xSvcInfo->getImplementationName(), bHC) );
512                     if (aDictionaryImageUrl.getLength() > 0)
513                     {
514                         Image aImage( lcl_GetImageFromPngUrl( aDictionaryImageUrl ) );
515                         pMenu->SetItemImage( nItemId, aImage );
516                     }
517                 }
518 
519                 ++nItemId;
520             }
521         }
522 	}
523     EnableItem( MN_ADD_TO_DIC, bEnable );
524 
525 	//ADD NEW LANGUAGE MENU ITEM
526 	///////////////////////////////////////////////////////////////////////////
527 	String aScriptTypesInUse( String::CreateFromInt32( pWrtSh->GetScriptType() ) );
528     SvtLanguageTable aLanguageTable;
529 
530     // get keyboard language
531     String aKeyboardLang;
532     LanguageType nLang = LANGUAGE_DONTKNOW;
533     SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
534     nLang = rEditWin.GetInputLanguage();
535     if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
536         aKeyboardLang = aLanguageTable.GetString( nLang );
537 
538     // get the language that is in use
539     const String aMultipleLanguages = String::CreateFromAscii("*");
540     String aCurrentLang = aMultipleLanguages;
541     nLang = SwLangHelper::GetCurrentLanguage( *pWrtSh );
542     if (nLang != LANGUAGE_DONTKNOW)
543         aCurrentLang = aLanguageTable.GetString( nLang );
544 
545     // build sequence for status value
546     uno::Sequence< OUString > aSeq( 4 );
547     aSeq[0] = aCurrentLang;
548     aSeq[1] = aScriptTypesInUse;
549     aSeq[2] = aKeyboardLang;
550     aSeq[3] = aLanguageTable.GetString(nGuessLangWord);
551 
552     pMenu = GetPopupMenu(MN_SET_LANGUAGE_SELECTION);
553     fillLangPopupMenu( pMenu, MN_SET_LANGUAGE_SELECTION_START, aSeq, pWrtSh, aLangTable_Text );
554     EnableItem( MN_SET_LANGUAGE_SELECTION, true );
555 
556     pMenu = GetPopupMenu(MN_SET_LANGUAGE_PARAGRAPH);
557     fillLangPopupMenu( pMenu, MN_SET_LANGUAGE_PARAGRAPH_START, aSeq, pWrtSh, aLangTable_Paragraph );
558     EnableItem( MN_SET_LANGUAGE_PARAGRAPH, true );
559 /*
560     pMenu = GetPopupMenu(MN_SET_LANGUAGE_ALL_TEXT);
561     fillLangPopupMenu( pMenu, MN_SET_LANGUAGE_ALL_TEXT_START, aSeq, pWrtSh, aLangTable_Document );
562     EnableItem( MN_SET_LANGUAGE_ALL_TEXT, true );
563 */
564     uno::Reference< frame::XFrame > xFrame = pWrtSh->GetView().GetViewFrame()->GetFrame().GetFrameInterface();
565     Image rImg = ::GetImage( xFrame,
566             OUString::createFromAscii(".uno:SpellingAndGrammarDialog"), sal_False,
567             Application::GetSettings().GetStyleSettings().GetHighContrastMode() );
568     SetItemImage( MN_SPELLING_DLG, rImg );
569 
570     //////////////////////////////////////////////////////////////////////////////////
571 
572     RemoveDisabledEntries( sal_True, sal_True );
573 }
574 
575 /*--------------------------------------------------------------------------
576 
577 ---------------------------------------------------------------------------*/
578 
SwSpellPopup(SwWrtShell * pWrtSh,const linguistic2::ProofreadingResult & rResult,sal_Int32 nErrorInResult,const uno::Sequence<OUString> & rSuggestions,const String & rParaText)579 SwSpellPopup::SwSpellPopup(
580     SwWrtShell *pWrtSh,
581     const linguistic2::ProofreadingResult &rResult,
582     sal_Int32 nErrorInResult,
583     const uno::Sequence< OUString > &rSuggestions,
584     const String &rParaText ) :
585 PopupMenu( SW_RES(MN_SPELL_POPUP) ),
586 pSh( pWrtSh ),
587 aSuggestions( rSuggestions ),
588 bGrammarResults( true ),
589 aInfo16( SW_RES(IMG_INFO_16) )
590 {
591     nCheckedLanguage = SvxLocaleToLanguage( rResult.aLocale );
592 
593     sal_uInt16 nPos = 0;
594     OUString aMessageText( rResult.aErrors[ nErrorInResult ].aShortComment );
595     InsertSeparator( nPos++ );
596     InsertItem( MN_SHORT_COMMENT, aMessageText, MIB_NOSELECT, nPos++ );
597     SetItemImage( MN_SHORT_COMMENT, aInfo16 );
598 
599 //    CreateAutoMnemonics();
600     SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS);
601 
602     InsertSeparator( nPos++ );
603     sal_Int32 nStringCount = aSuggestions.getLength();
604     if ( nStringCount )     // suggestions available...
605     {
606         Image aImage;
607         OUString aSuggestionImageUrl;
608         uno::Reference< lang::XServiceInfo > xInfo( rResult.xProofreader, uno::UNO_QUERY );
609         if (xInfo.is())
610         {
611             aSuggestionImageUrl = SvtLinguConfig().GetSpellAndGrammarContextSuggestionImage( xInfo->getImplementationName() );
612             aImage = Image( lcl_GetImageFromPngUrl( aSuggestionImageUrl ) );
613         }
614 
615         sal_uInt16 nItemId = MN_SUGGESTION_START;
616         for (sal_uInt16 i = 0;  i < nStringCount;  ++i)
617         {
618             const String aEntry = aSuggestions[ i ];
619             InsertItem( nItemId, aEntry, 0, nPos++ );
620             SetHelpId( nItemId, HID_LINGU_REPLACE );
621             if (aSuggestionImageUrl.getLength() > 0)
622                 SetItemImage( nItemId, aImage );
623 
624             ++nItemId;
625         }
626         InsertSeparator( nPos++ );
627     }
628 
629     OUString aIgnoreSelection( String( SW_RES( STR_IGNORE_SELECTION ) ) );
630 	OUString aSpellingAndGrammar = RetrieveLabelFromCommand( C2U(".uno:SpellingAndGrammarDialog") );
631     SetItemText( MN_SPELLING_DLG, aSpellingAndGrammar );
632     sal_uInt16 nItemPos = GetItemPos( MN_IGNORE_WORD );
633     InsertItem( MN_IGNORE_SELECTION, aIgnoreSelection, 0, nItemPos );
634     SetHelpId( MN_IGNORE_SELECTION, HID_LINGU_IGNORE_SELECTION);
635 
636     EnableItem( MN_AUTOCORR, false );
637 
638     uno::Reference< linguistic2::XLanguageGuessing > xLG = SW_MOD()->GetLanguageGuesser();
639     nGuessLangWord = LANGUAGE_NONE;
640     nGuessLangPara = LANGUAGE_NONE;
641     if (xLG.is())
642     {
643 //        nGuessLangWord = lcl_CheckLanguage( xSpellAlt->getWord(), ::GetSpellChecker(), xLG, sal_False );
644         nGuessLangPara = lcl_CheckLanguage( rParaText, ::GetSpellChecker(), xLG, sal_True );
645     }
646     if (nGuessLangWord != LANGUAGE_NONE || nGuessLangPara != LANGUAGE_NONE)
647     {
648         // make sure LANGUAGE_NONE gets not used as menu entry
649         if (nGuessLangWord == LANGUAGE_NONE)
650             nGuessLangWord = nGuessLangPara;
651         if (nGuessLangPara == LANGUAGE_NONE)
652             nGuessLangPara = nGuessLangWord;
653     }
654 
655     EnableItem( MN_IGNORE_WORD, false );
656     EnableItem( MN_ADD_TO_DIC, false );
657 
658     //ADD NEW LANGUAGE MENU ITEM
659     ///////////////////////////////////////////////////////////////////////////
660     String aScriptTypesInUse( String::CreateFromInt32( pWrtSh->GetScriptType() ) );
661     SvtLanguageTable aLanguageTable;
662 
663     // get keyboard language
664     String aKeyboardLang;
665     LanguageType nLang = LANGUAGE_DONTKNOW;
666     SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
667     nLang = rEditWin.GetInputLanguage();
668     if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
669         aKeyboardLang = aLanguageTable.GetString( nLang );
670 
671     // get the language that is in use
672     const String aMultipleLanguages = String::CreateFromAscii("*");
673     String aCurrentLang = aMultipleLanguages;
674     nLang = SwLangHelper::GetCurrentLanguage( *pWrtSh );
675     if (nLang != LANGUAGE_DONTKNOW)
676         aCurrentLang = aLanguageTable.GetString( nLang );
677 
678     // build sequence for status value
679     uno::Sequence< OUString > aSeq( 4 );
680     aSeq[0] = aCurrentLang;
681     aSeq[1] = aScriptTypesInUse;
682     aSeq[2] = aKeyboardLang;
683     aSeq[3] = aLanguageTable.GetString(nGuessLangWord);
684 
685     PopupMenu *pMenu = GetPopupMenu(MN_SET_LANGUAGE_SELECTION);
686     fillLangPopupMenu( pMenu, MN_SET_LANGUAGE_SELECTION_START, aSeq, pWrtSh, aLangTable_Text );
687     EnableItem( MN_SET_LANGUAGE_SELECTION, true );
688 
689     pMenu = GetPopupMenu(MN_SET_LANGUAGE_PARAGRAPH);
690     fillLangPopupMenu( pMenu, MN_SET_LANGUAGE_PARAGRAPH_START, aSeq, pWrtSh, aLangTable_Paragraph );
691     EnableItem( MN_SET_LANGUAGE_PARAGRAPH, true );
692 /*
693     pMenu = GetPopupMenu(MN_SET_LANGUAGE_ALL_TEXT);
694     fillLangPopupMenu( pMenu, MN_SET_LANGUAGE_ALL_TEXT_START, aSeq, pWrtSh, aLangTable_Document );
695     EnableItem( MN_SET_LANGUAGE_ALL_TEXT, true );
696 */
697     uno::Reference< frame::XFrame > xFrame = pWrtSh->GetView().GetViewFrame()->GetFrame().GetFrameInterface();
698     Image rImg = ::GetImage( xFrame,
699             OUString::createFromAscii(".uno:SpellingAndGrammarDialog"), sal_False,
700             Application::GetSettings().GetStyleSettings().GetHighContrastMode() );
701     SetItemImage( MN_SPELLING_DLG, rImg );
702 
703     //////////////////////////////////////////////////////////////////////////////////
704 
705     RemoveDisabledEntries( sal_True, sal_True );
706 }
707 
708 /*--------------------------------------------------------------------------
709 
710 ---------------------------------------------------------------------------*/
Execute(const Rectangle & rWordPos,Window * pWin)711 sal_uInt16  SwSpellPopup::Execute( const Rectangle& rWordPos, Window* pWin )
712 {
713 //    SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS);
714 	sal_uInt16 nRet = PopupMenu::Execute(pWin, pWin->LogicToPixel(rWordPos));
715     Execute( nRet );
716     return nRet;
717 }
718 /*-- 19.01.2006 08:15:48---------------------------------------------------
719 
720   -----------------------------------------------------------------------*/
Execute(sal_uInt16 nId)721 void SwSpellPopup::Execute( sal_uInt16 nId )
722 {
723     if (nId == USHRT_MAX)
724         return;
725 
726     if (/*bGrammarResults && */nId == MN_SHORT_COMMENT)
727 		return;		// nothing to do since it is the error message (short comment)
728 
729     if ((MN_SUGGESTION_START <= nId && nId <= MN_SUGGESTION_END) ||
730         (MN_AUTOCORR_START <= nId && nId <= MN_AUTOCORR_END))
731     {
732         sal_Int32 nAltIdx = (MN_SUGGESTION_START <= nId && nId <= MN_SUGGESTION_END) ?
733                 nId - MN_SUGGESTION_START : nId - MN_AUTOCORR_START;
734         DBG_ASSERT( 0 <= nAltIdx && nAltIdx < aSuggestions.getLength(), "index out of range" );
735         if (0 <= nAltIdx && nAltIdx < aSuggestions.getLength() && (bGrammarResults || xSpellAlt.is()))
736         {
737             sal_Bool bOldIns = pSh->IsInsMode();
738             pSh->SetInsMode( sal_True );
739 
740             String aTmp( aSuggestions[ nAltIdx ] );
741             String aOrig( bGrammarResults ? OUString() : xSpellAlt->getWord() );
742 
743             // if original word has a trailing . (likely the end of a sentence)
744             // and the replacement text hasn't, then add it to the replacement
745             if (aTmp.Len() && aOrig.Len() &&
746                 '.' == aOrig.GetChar( aOrig.Len() - 1) && /* !IsAlphaNumeric ??*/
747                 '.' != aTmp.GetChar( aTmp.Len() - 1))
748             {
749                 aTmp += '.';
750             }
751 
752             // #111827#
753             SwRewriter aRewriter;
754 
755             aRewriter.AddRule(UNDO_ARG1, pSh->GetCrsrDescr());
756             aRewriter.AddRule(UNDO_ARG2, String(SW_RES(STR_YIELDS)));
757 
758             String aTmpStr( SW_RES(STR_START_QUOTE) );
759             aTmpStr += aTmp;
760             aTmpStr += String(SW_RES(STR_END_QUOTE));
761             aRewriter.AddRule(UNDO_ARG3, aTmpStr);
762 
763             pSh->StartUndo(UNDO_UI_REPLACE, &aRewriter);
764             pSh->StartAction();
765             pSh->DelLeft();
766 
767             pSh->Insert( aTmp );
768 
769             /* #102505# EndAction/EndUndo moved down since insertion
770                of temporary auto correction is now undoable two and
771                must reside in the same undo group.*/
772 
773             // nur aufnehmen, wenn es NICHT schon in der Autokorrektur vorhanden ist
774             SvxAutoCorrect* pACorr = SvxAutoCorrCfg::Get()->GetAutoCorrect();
775 
776             String aOrigWord( bGrammarResults ? OUString() : xSpellAlt->getWord() ) ;
777             String aNewWord( aSuggestions[ nAltIdx ] );
778             SvxPrepareAutoCorrect( aOrigWord, aNewWord );
779 
780             if (MN_AUTOCORR_START <= nId && nId <= MN_AUTOCORR_END)
781                 pACorr->PutText( aOrigWord, aNewWord, nCheckedLanguage );
782 
783             /* #102505# EndAction/EndUndo moved down since insertion
784                of temporary auto correction is now undoable two and
785                must reside in the same undo group.*/
786             pSh->EndAction();
787             pSh->EndUndo();
788 
789             pSh->SetInsMode( bOldIns );
790         }
791     }
792     else if (nId == MN_SPELLING_DLG)
793     {
794         if (bGrammarResults)
795         {
796             SvtLinguConfig().SetProperty( A2OU( UPN_IS_GRAMMAR_INTERACTIVE ), uno::makeAny( sal_True ));
797         }
798         pSh->Left(CRSR_SKIP_CHARS, sal_False, 1, sal_False );
799         {
800             uno::Reference<linguistic2::XDictionaryList> xDictionaryList( SvxGetDictionaryList() );
801             SvxDicListChgClamp aClamp( xDictionaryList );
802             pSh->GetView().GetViewFrame()->GetDispatcher()->
803                 Execute( FN_SPELL_GRAMMAR_DIALOG, SFX_CALLMODE_ASYNCHRON );
804         }
805     }
806     else if (nId == MN_IGNORE_SELECTION)
807     {
808         SwPaM *pPaM = pSh->GetCrsr();
809         if (pPaM)
810             pSh->IgnoreGrammarErrorAt( *pPaM );
811     }
812     else if (nId == MN_IGNORE_WORD)
813     {
814         uno::Reference< linguistic2::XDictionary > xDictionary( SvxGetIgnoreAllList(), uno::UNO_QUERY );
815         linguistic::AddEntryToDic( xDictionary,
816                 xSpellAlt->getWord(), sal_False, aEmptyStr, LANGUAGE_NONE );
817     }
818     else if (MN_DICTIONARIES_START <= nId && nId <= MN_DICTIONARIES_END)
819     {
820             OUString aWord( xSpellAlt->getWord() );
821 
822             PopupMenu *pMenu = GetPopupMenu(MN_ADD_TO_DIC);
823             String aDicName ( pMenu->GetItemText(nId) );
824 
825             uno::Reference< linguistic2::XDictionary >      xDic;
826             uno::Reference< linguistic2::XDictionaryList >  xDicList( SvxGetDictionaryList() );
827             if (xDicList.is())
828                 xDic = xDicList->getDictionaryByName( aDicName );
829 
830             if (xDic.is())
831             {
832                 sal_Int16 nAddRes = linguistic::AddEntryToDic( xDic, aWord, sal_False, aEmptyStr, LANGUAGE_NONE );
833                 // save modified user-dictionary if it is persistent
834                 uno::Reference< frame::XStorable >  xSavDic( xDic, uno::UNO_QUERY );
835                 if (xSavDic.is())
836                     xSavDic->store();
837 
838                 if (DIC_ERR_NONE != nAddRes
839                     && !xDic->getEntry( aWord ).is())
840                 {
841                     SvxDicError(
842                         &pSh->GetView().GetViewFrame()->GetWindow(),
843                         nAddRes );
844                 }
845             }
846     }
847     else
848     {
849         // Set language for selection or for paragraph...
850 
851         SfxItemSet aCoreSet( pSh->GetView().GetPool(),
852                     RES_CHRATR_LANGUAGE,        RES_CHRATR_LANGUAGE,
853                     RES_CHRATR_CJK_LANGUAGE,    RES_CHRATR_CJK_LANGUAGE,
854                     RES_CHRATR_CTL_LANGUAGE,    RES_CHRATR_CTL_LANGUAGE,
855                     0 );
856         String aNewLangTxt;
857 
858         if (MN_SET_LANGUAGE_SELECTION_START <= nId && nId <= MN_SET_LANGUAGE_SELECTION_END)
859         {
860             //Set language for current selection
861             aNewLangTxt = aLangTable_Text[nId];
862             SwLangHelper::SetLanguage( *pSh, aNewLangTxt, true, aCoreSet );
863         }
864         else if (nId == MN_SET_SELECTION_NONE)
865         {
866             //Set Language_None for current selection
867             SwLangHelper::SetLanguage_None( *pSh, true, aCoreSet );
868         }
869         else if (nId == MN_SET_SELECTION_RESET)
870         {
871             //reset languages for current selection
872             SwLangHelper::ResetLanguages( *pSh, true );
873         }
874         else if (nId == MN_SET_SELECTION_MORE)
875         {
876             //Open Format/Character Dialog
877             lcl_CharDialog( *pSh, true, nId, 0, 0 );
878         }
879         else if (MN_SET_LANGUAGE_PARAGRAPH_START <= nId && nId <= MN_SET_LANGUAGE_PARAGRAPH_END)
880         {
881             //Set language for current paragraph
882             aNewLangTxt = aLangTable_Paragraph[nId];
883             pSh->Push();        // save cursor
884             SwLangHelper::SelectCurrentPara( *pSh );
885             SwLangHelper::SetLanguage( *pSh, aNewLangTxt, true, aCoreSet );
886             pSh->Pop( sal_False );  // restore cursor
887         }
888         else if (nId == MN_SET_PARA_NONE)
889         {
890             //Set Language_None for current paragraph
891             pSh->Push();        // save cursor
892             SwLangHelper::SelectCurrentPara( *pSh );
893             SwLangHelper::SetLanguage_None( *pSh, true, aCoreSet );
894             pSh->Pop( sal_False );  // restore cursor
895         }
896         else if (nId == MN_SET_PARA_RESET)
897         {
898             //reset languages for current paragraph
899             pSh->Push();        // save cursor
900             SwLangHelper::SelectCurrentPara( *pSh );
901             SwLangHelper::ResetLanguages( *pSh, true );
902             pSh->Pop( sal_False );  // restore cursor
903         }
904         else if (nId == MN_SET_PARA_MORE)
905         {
906             pSh->Push();        // save cursor
907             SwLangHelper::SelectCurrentPara( *pSh );
908             //Open Format/Character Dialog
909             lcl_CharDialog( *pSh, true, nId, 0, 0 );
910             pSh->Pop( sal_False );  // restore cursor
911         }
912 #if 0
913         else if (nId == MN_SET_LANGUAGE_ALL_TEXT_START + nNumLanguageDocEntries - 1)
914         {
915             //Set Language_None as the default language
916             SwLangHelper::SetLanguage_None( *pSh, false, aCoreSet );
917         }
918         else if (nId == MN_SET_LANGUAGE_ALL_TEXT_START + nNumLanguageDocEntries)
919         {
920             // open the dialog "Tools/Options/Language Settings - Language"
921             SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
922             if (pFact)
923             {
924                 VclAbstractDialog* pDlg = pFact->CreateVclDialog( pSh->GetView().GetWindow(), SID_LANGUAGE_OPTIONS );
925                 pDlg->Execute();
926                 delete pDlg;
927             }
928         }
929 #endif
930     }
931 
932     pSh->EnterStdMode();
933 }
934