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 // 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 206 inline bool lcl_checkScriptType( sal_Int16 nScriptType, LanguageType nLang ) 207 { 208 return 0 != (nScriptType & SvtLanguageOptions::GetScriptTypeOfLanguage( nLang )); 209 } 210 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 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 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 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 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 ---------------------------------------------------------------------------*/ 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 -----------------------------------------------------------------------*/ 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