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