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 orginal 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