merge the formfield patch from ooo-build
[ooovba.git] / sw / source / ui / lingu / olmenu.cxx
blob52540f21dd141881cce8de4edec093ef4364a395
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: olmenu.cxx,v $
10 * $Revision: 1.41 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
34 #include <hintids.hxx>
36 #ifndef _SVSTDARR_HXX
37 #define _SVSTDARR_STRINGSDTOR
38 #include <svtools/svstdarr.hxx>
39 #endif
40 #include <svtools/lingucfg.hxx>
41 #include <svtools/linguprops.hxx>
42 #include <svtools/filter.hxx>
43 #include <svx/impgrf.hxx>
44 #include <svx/svxacorr.hxx>
45 #include <sfx2/dispatch.hxx>
46 #include <sfx2/imagemgr.hxx>
47 #include <osl/file.hxx>
48 #include <rtl/string.hxx>
50 #include <i18npool/mslangid.hxx>
51 #include <linguistic/lngprops.hxx>
52 #include <linguistic/misc.hxx>
53 #include <comphelper/processfactory.hxx>
54 #include <svx/unolingu.hxx>
55 #include <com/sun/star/uno/Any.hxx>
56 #include <com/sun/star/frame/XStorable.hpp>
57 #include <com/sun/star/linguistic2/XSpellChecker1.hpp>
58 #include <com/sun/star/linguistic2/XLanguageGuessing.hpp>
59 #include <com/sun/star/linguistic2/SingleProofreadingError.hpp>
60 #include <com/sun/star/lang/XServiceInfo.hpp>
61 #include <com/sun/star/container/XIndexAccess.hpp>
62 #include <com/sun/star/container/XNameAccess.hpp>
63 #include <com/sun/star/frame/XModuleManager.hpp>
64 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
65 #include <com/sun/star/i18n/ScriptType.hpp>
66 #include <svx/dlgutil.hxx>
67 #include <svtools/itemset.hxx>
68 #include <svx/langitem.hxx>
69 #include <svx/splwrap.hxx>
70 #include <vcl/svapp.hxx>
71 #include <vcl/settings.hxx>
72 #include <svtools/lingucfg.hxx>
73 #include <svx/acorrcfg.hxx>
74 #include <swmodule.hxx>
75 #include <cmdid.h>
76 #include <helpid.h>
77 #include <swtypes.hxx>
78 #include <wrtsh.hxx>
79 #include <view.hxx>
80 #include <docsh.hxx> //CheckSpellChanges
81 #include <olmenu.hxx>
82 #include <swundo.hxx>
83 #include <crsskip.hxx>
84 #include <ndtxt.hxx>
85 #include <olmenu.hrc>
86 #include <doc.hxx>
88 // -> #111827#
89 #include <SwRewriter.hxx>
90 #include <comcore.hrc>
91 #include <undobj.hxx>
92 // <- #111827#
94 #include <unomid.h>
95 #include <svtools/languageoptions.hxx>
96 #include <map>
97 #include <svtools/langtab.hxx>
98 #include <com/sun/star/document/XDocumentLanguages.hpp>
99 #include <edtwin.hxx>
100 #include <sfx2/sfxdlg.hxx>
101 #include "swabstdlg.hxx"
102 #include "chrdlg.hrc"
103 #include <svx/brshitem.hxx>
104 #include <svtools/stritem.hxx>
105 #include <viewopt.hxx>
106 #include <uitool.hxx>
108 #include <wview.hxx>
109 #include <sfx2/request.hxx>
111 #include <vcl/msgbox.hxx>
113 #include <langhelper.hxx>
115 using namespace ::com::sun::star;
116 using ::rtl::OUString;
118 extern void lcl_CharDialog( SwWrtShell &rWrtSh, BOOL bUseDialog, USHORT nSlot,const SfxItemSet *pArgs, SfxRequest *pReq );
121 /*--------------------------------------------------------------------------
123 ---------------------------------------------------------------------------*/
125 // tries to determine the language of 'rText'
127 LanguageType lcl_CheckLanguage(
128 const OUString &rText,
129 uno::Reference< linguistic2::XSpellChecker1 > xSpell,
130 uno::Reference< linguistic2::XLanguageGuessing > xLangGuess,
131 sal_Bool bIsParaText )
133 LanguageType nLang = LANGUAGE_NONE;
134 if (bIsParaText) // check longer texts with language-guessing...
136 if (!xLangGuess.is())
137 return nLang;
139 lang::Locale aLocale( xLangGuess->guessPrimaryLanguage( rText, 0, rText.getLength()) );
141 // get language as from "Tools/Options - Language Settings - Languages: Locale setting"
142 LanguageType nTmpLang = Application::GetSettings().GetLanguage();
144 // if the result from language guessing does not provide a 'Country' part
145 // try to get it by looking up the locale setting of the office.
146 if (aLocale.Country.getLength() == 0)
148 lang::Locale aTmpLocale = SvxCreateLocale( nTmpLang );
149 if (aTmpLocale.Language == aLocale.Language)
150 nLang = nTmpLang;
152 if (nLang == LANGUAGE_NONE) // language not found by looking up the system language...
153 nLang = MsLangId::convertLocaleToLanguageWithFallback( aLocale );
154 if (nLang == LANGUAGE_SYSTEM)
155 nLang = nTmpLang;
156 if (nLang == LANGUAGE_DONTKNOW)
157 nLang = LANGUAGE_NONE;
159 else // check single word
161 if (!xSpell.is())
162 return nLang;
165 // build list of languages to check
167 LanguageType aLangList[4];
168 const AllSettings& rSettings = Application::GetSettings();
169 SvtLinguOptions aLinguOpt;
170 SvtLinguConfig().GetOptions( aLinguOpt );
171 // The default document language from "Tools/Options - Language Settings - Languages: Western"
172 aLangList[0] = MsLangId::resolveSystemLanguageByScriptType(aLinguOpt.nDefaultLanguage, ::com::sun::star::i18n::ScriptType::LATIN);
173 // The one from "Tools/Options - Language Settings - Languages: User interface"
174 aLangList[1] = rSettings.GetUILanguage();
175 // The one from "Tools/Options - Language Settings - Languages: Locale setting"
176 aLangList[2] = rSettings.GetLanguage();
177 // en-US
178 aLangList[3] = LANGUAGE_ENGLISH_US;
179 #ifdef DEBUG
180 lang::Locale a0( SvxCreateLocale( aLangList[0] ) );
181 lang::Locale a1( SvxCreateLocale( aLangList[1] ) );
182 lang::Locale a2( SvxCreateLocale( aLangList[2] ) );
183 lang::Locale a3( SvxCreateLocale( aLangList[3] ) );
184 #endif
186 INT32 nCount = sizeof(aLangList) / sizeof(aLangList[0]);
187 for (INT32 i = 0; i < nCount; i++)
189 INT16 nTmpLang = aLangList[i];
190 if (nTmpLang != LANGUAGE_NONE && nTmpLang != LANGUAGE_DONTKNOW)
192 if (xSpell->hasLanguage( nTmpLang ) &&
193 xSpell->isValid( rText, nTmpLang, uno::Sequence< beans::PropertyValue >() ))
195 nLang = nTmpLang;
196 break;
202 return nLang;
206 /// @returns : the language for the selected text that is set for the
207 /// specified attribute (script type).
208 /// If there are more than one languages used LANGUAGE_DONTKNOW will be returned.
209 /// @param nLangWhichId : one of
210 /// RES_CHRATR_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CTL_LANGUAGE,
211 /// @returns: the language in use for the selected text.
212 /// 'In use' means the language(s) matching the script type(s) of the
213 /// selected text. Or in other words, the language a spell checker would use.
214 /// If there is more than one language LANGUAGE_DONTKNOW will be returned.
215 // check if nScriptType includes the script type associated to nLang
216 inline bool lcl_checkScriptType( sal_Int16 nScriptType, LanguageType nLang )
218 return 0 != (nScriptType & SvtLanguageOptions::GetScriptTypeOfLanguage( nLang ));
221 USHORT SwSpellPopup::fillLangPopupMenu(
222 PopupMenu *pPopupMenu,
223 USHORT Lang_Start,
224 uno::Sequence< ::rtl::OUString > aSeq,
225 SwWrtShell* pWrtSh,
226 USHORT nLangTable )
228 if (!pPopupMenu)
229 return 0;
231 //Reference< awt::XMenuExtended > m_xMenuExtended( m_xPopupMenu, UNO_QUERY );
232 std::map< ::rtl::OUString, ::rtl::OUString > LangItems;
234 SvtLanguageTable aLanguageTable;
235 USHORT nItemId = Lang_Start;
236 rtl::OUString curLang = aSeq[0];
237 USHORT nScriptType = static_cast< sal_Int16 >(aSeq[1].toInt32());
238 rtl::OUString keyboardLang = aSeq[2];
239 rtl::OUString guessLang = aSeq[3];
241 //1--add current language
242 if(curLang!=OUString::createFromAscii(""))
244 LangItems[curLang]=curLang;
247 SvtLanguageTable aLangTable;
248 //2--System
249 const AllSettings& rAllSettings=Application::GetSettings();
250 LanguageType rSystemLanguage = rAllSettings.GetLanguage();
251 if(rSystemLanguage!=LANGUAGE_DONTKNOW)
253 if (lcl_checkScriptType(nScriptType,rSystemLanguage ))
254 LangItems[OUString(aLangTable.GetString(rSystemLanguage))]=OUString(aLangTable.GetString(rSystemLanguage));
257 //3--UI
258 LanguageType rUILanguage = rAllSettings.GetUILanguage();
259 if(rUILanguage!=LANGUAGE_DONTKNOW)
261 if (lcl_checkScriptType(nScriptType, rUILanguage ))
262 LangItems[OUString(aLangTable.GetString(rUILanguage))]=OUString(aLangTable.GetString(rUILanguage));
265 //4--guessed language
266 if(guessLang!=OUString::createFromAscii(""))
268 if (lcl_checkScriptType(nScriptType, aLanguageTable.GetType(guessLang)))
269 LangItems[guessLang]=guessLang;
273 //5--keyboard language
274 if(keyboardLang!=OUString::createFromAscii(""))
276 if (lcl_checkScriptType(nScriptType, aLanguageTable.GetType(keyboardLang)))
277 LangItems[keyboardLang]=keyboardLang;
280 //6--all languages used in current document
281 uno::Reference< com::sun::star::frame::XModel > xModel;
282 uno::Reference< com::sun::star::frame::XController > xController( pWrtSh->GetView().GetViewFrame()->GetFrame()->GetFrameInterface()->getController(), uno::UNO_QUERY );
283 if ( xController.is() )
284 xModel = xController->getModel();
286 uno::Reference< document::XDocumentLanguages > xDocumentLanguages( xModel, uno::UNO_QUERY );
287 /*the description of nScriptType
288 LATIN : 1
289 ASIAN : 2
290 COMPLEX:4
291 LATIN + ASIAN : 3
292 LATIN + COMPLEX : 5
293 ASIAN + COMPLEX : 6
294 LATIN + ASIAN + COMPLEX : 7
297 sal_Int16 nCount=7;
298 if(xDocumentLanguages.is())
300 uno::Sequence< lang::Locale > rLocales(xDocumentLanguages->getDocumentLanguages(nScriptType,nCount));
301 if(rLocales.getLength()>0)
303 for(USHORT i = 0; i<rLocales.getLength();++i)
305 if (LangItems.size()==7)
306 break;
307 const lang::Locale& rLocale=rLocales[i];
308 if(lcl_checkScriptType(nScriptType, aLanguageTable.GetType(rLocale.Language)))
309 LangItems[ rtl::OUString(rLocale.Language)]=OUString(rLocale.Language);
314 for (std::map< rtl::OUString, rtl::OUString >::const_iterator it = LangItems.begin(); it != LangItems.end(); ++it)
316 rtl::OUString aEntryTxt( it->first );
317 if (aEntryTxt != rtl::OUString( aLangTable.GetString( LANGUAGE_NONE ) )&&
318 aEntryTxt != rtl::OUString::createFromAscii("*") &&
319 aEntryTxt.getLength() > 0)
321 ++nItemId;
322 if (nLangTable == 0) // language for selection
323 aLangTable_Text[nItemId] = aEntryTxt;
324 else if (nLangTable == 1) // language for paragraph
325 aLangTable_Paragraph[nItemId] = aEntryTxt;
326 else if (nLangTable == 2) // language for document
327 aLangTable_Document[nItemId] = aEntryTxt;
329 pPopupMenu->InsertItem( nItemId, aEntryTxt, MIB_RADIOCHECK );
330 if (aEntryTxt == curLang)
332 //make a check mark for the current language
333 pPopupMenu->CheckItem( nItemId, TRUE );
338 //7--none
339 nItemId++;
340 pPopupMenu->InsertItem( nItemId, String(SW_RES( STR_LANGSTATUS_NONE )), MIB_RADIOCHECK );
342 //More...
343 nItemId++;
344 pPopupMenu->InsertItem( nItemId, String(SW_RES( STR_LANGSTATUS_MORE )), MIB_RADIOCHECK );
346 return nItemId - Lang_Start; // return number of inserted entries
350 static Image lcl_GetImageFromPngUrl( const OUString &rFileUrl )
352 Image aRes;
353 OUString aTmp;
354 osl::FileBase::getSystemPathFromFileURL( rFileUrl, aTmp );
355 // ::rtl::OString aPath = OString( aTmp.getStr(), aTmp.getLength(), osl_getThreadTextEncoding() );
356 #if defined(WNT)
357 // aTmp = lcl_Win_GetShortPathName( aTmp );
358 #endif
359 Graphic aGraphic;
360 const String aFilterName( RTL_CONSTASCII_USTRINGPARAM( IMP_PNG ) );
361 if( GRFILTER_OK == LoadGraphic( aTmp, aFilterName, aGraphic ) )
363 aRes = Image( aGraphic.GetBitmapEx() );
365 return aRes;
369 ::rtl::OUString RetrieveLabelFromCommand( const ::rtl::OUString& aCmdURL )
371 ::rtl::OUString aLabel;
372 if ( aCmdURL.getLength() )
376 uno::Reference< container::XNameAccess > xNameAccess( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii("com.sun.star.frame.UICommandDescription") ), uno::UNO_QUERY );
377 if ( xNameAccess.is() )
379 uno::Reference< container::XNameAccess > xUICommandLabels;
380 const ::rtl::OUString aModule( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextDocument" ) );
381 uno::Any a = xNameAccess->getByName( aModule );
382 uno::Reference< container::XNameAccess > xUICommands;
383 a >>= xUICommandLabels;
384 rtl::OUString aStr;
385 uno::Sequence< beans::PropertyValue > aPropSeq;
386 a = xUICommandLabels->getByName( aCmdURL );
387 if ( a >>= aPropSeq )
389 for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ )
391 if ( aPropSeq[i].Name.equalsAscii( "Name" ))
393 aPropSeq[i].Value >>= aStr;
394 break;
398 aLabel = aStr;
401 catch ( uno::Exception& )
406 return aLabel;
410 SwSpellPopup::SwSpellPopup(
411 SwWrtShell* pWrtSh,
412 const uno::Reference< linguistic2::XSpellAlternatives > &xAlt,
413 const String &rParaText ) :
414 PopupMenu( SW_RES(MN_SPELL_POPUP) ),
415 pSh( pWrtSh ),
416 xSpellAlt(xAlt),
417 bGrammarResults(false)
419 DBG_ASSERT(xSpellAlt.is(), "no spelling alternatives available");
421 CreateAutoMnemonics();
422 nCheckedLanguage = LANGUAGE_NONE;
423 if (xSpellAlt.is())
425 nCheckedLanguage = SvxLocaleToLanguage( xSpellAlt->getLocale() );
426 aSuggestions = xSpellAlt->getAlternatives();
428 sal_Int16 nStringCount = static_cast< sal_Int16 >( aSuggestions.getLength() );
430 SvtLinguConfig aCfg;
431 const bool bIsDark = Application::GetSettings().GetStyleSettings().GetWindowColor().IsDark();
433 PopupMenu *pMenu = GetPopupMenu(MN_AUTOCORR);
434 pMenu->SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS);
435 sal_Bool bEnable = sal_False;
436 if( nStringCount )
438 Image aImage;
439 OUString aSuggestionImageUrl;
440 uno::Reference< container::XNamed > xNamed( xSpellAlt, uno::UNO_QUERY );
441 if (xNamed.is())
443 aSuggestionImageUrl = aCfg.GetSpellAndGrammarContextSuggestionImage( xNamed->getName(), bIsDark );
444 aImage = Image( lcl_GetImageFromPngUrl( aSuggestionImageUrl ) );
447 InsertSeparator(0);
448 bEnable = sal_True;
449 for( sal_uInt16 i = 0, nPos = 1, nId = MN_AUTOCORR_START + 1;
450 i < nStringCount; ++i, ++nPos, ++nId )
452 const String aEntry = aSuggestions[ i ];
453 InsertItem( nPos, aEntry, 0, i );
454 SetHelpId( nPos, HID_LINGU_REPLACE);
456 if (aSuggestionImageUrl.getLength() > 0)
457 SetItemImage( nPos, aImage );
459 pMenu->InsertItem( nId, aEntry );
460 pMenu->SetHelpId( nPos, HID_LINGU_AUTOCORR);
464 OUString aIgnoreSelection( String( SW_RES( STR_IGNORE_SELECTION ) ) );
465 OUString aSpellingAndGrammar = RetrieveLabelFromCommand( C2U(".uno:SpellingAndGrammarDialog") );
466 SetItemText( MN_SPELLING, aSpellingAndGrammar );
467 USHORT nItemPos = GetItemPos( MN_IGNORE );
468 InsertItem( MN_IGNORE_SELECTION, aIgnoreSelection, 0, nItemPos );
469 SetHelpId( MN_IGNORE_SELECTION, HID_LINGU_IGNORE_SELECTION);
471 EnableItem( MN_AUTOCORR, bEnable );
473 uno::Reference< linguistic2::XLanguageGuessing > xLG = SW_MOD()->GetLanguageGuesser();
474 nGuessLangWord = LANGUAGE_NONE;
475 nGuessLangPara = LANGUAGE_NONE;
476 if (xSpellAlt.is() && xLG.is())
478 nGuessLangWord = lcl_CheckLanguage( xSpellAlt->getWord(), ::GetSpellChecker(), xLG, sal_False );
479 nGuessLangPara = lcl_CheckLanguage( rParaText, ::GetSpellChecker(), xLG, sal_True );
481 if (nGuessLangWord != LANGUAGE_NONE || nGuessLangPara != LANGUAGE_NONE)
483 // make sure LANGUAGE_NONE gets not used as menu entry
484 if (nGuessLangWord == LANGUAGE_NONE)
485 nGuessLangWord = nGuessLangPara;
486 if (nGuessLangPara == LANGUAGE_NONE)
487 nGuessLangPara = nGuessLangWord;
490 pMenu = GetPopupMenu(MN_INSERT);
492 bEnable = FALSE; // enable MN_INSERT?
494 pMenu->CreateAutoMnemonics();
495 uno::Reference< linguistic2::XDictionaryList > xDicList( SvxGetDictionaryList() );
496 if (xDicList.is())
498 // add the default positive dictionary to dic-list (if not already done).
499 // This is to ensure that there is at least one dictionary to which
500 // words could be added.
501 uno::Reference< linguistic2::XDictionary > xDic( SvxGetOrCreatePosDic( xDicList ) );
502 if (xDic.is())
503 xDic->setActive( sal_True );
505 aDics = xDicList->getDictionaries();
506 const uno::Reference< linguistic2::XDictionary > *pDic = aDics.getConstArray();
507 USHORT nDicCount = static_cast< USHORT >(aDics.getLength());
509 for( USHORT i = 0; i < nDicCount; i++ )
511 uno::Reference< linguistic2::XDictionary > xDicTmp( pDic[i], uno::UNO_QUERY );
512 if (!xDicTmp.is() || SvxGetIgnoreAllList() == xDicTmp)
513 continue;
515 uno::Reference< frame::XStorable > xStor( xDicTmp, uno::UNO_QUERY );
516 LanguageType nActLanguage = SvxLocaleToLanguage( xDicTmp->getLocale() );
517 if( xDicTmp->isActive()
518 && xDicTmp->getDictionaryType() != linguistic2::DictionaryType_NEGATIVE
519 && (nCheckedLanguage == nActLanguage || LANGUAGE_NONE == nActLanguage )
520 && (!xStor.is() || !xStor->isReadonly()) )
522 // the extra 1 is because of the (possible) external
523 // linguistic entry above
524 USHORT nPos = MN_INSERT_START + i + 1;
525 pMenu->InsertItem( nPos, xDicTmp->getName() );
526 bEnable = sal_True;
528 uno::Reference< lang::XServiceInfo > xSvcInfo( xDicTmp, uno::UNO_QUERY );
529 if (xSvcInfo.is())
531 OUString aDictionaryImageUrl( aCfg.GetSpellAndGrammarContextDictionaryImage(
532 xSvcInfo->getImplementationName(), bIsDark) );
533 if (aDictionaryImageUrl.getLength() > 0)
535 Image aImage( lcl_GetImageFromPngUrl( aDictionaryImageUrl ) );
536 pMenu->SetItemImage( nPos, aImage );
542 EnableItem( MN_INSERT, bEnable );
544 //ADD NEW LANGUAGE MENU ITEM
545 ///////////////////////////////////////////////////////////////////////////
546 String aScriptTypesInUse( String::CreateFromInt32( pWrtSh->GetScriptType() ) );
547 SvtLanguageTable aLangTable;
549 // get keyboard language
550 String aKeyboardLang;
551 LanguageType nLang = LANGUAGE_DONTKNOW;
552 SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
553 nLang = rEditWin.GetInputLanguage();
554 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
555 aKeyboardLang = aLangTable.GetString( nLang );
557 // get the language that is in use
558 const String aMultipleLanguages = String::CreateFromAscii("*");
559 String aCurrentLang = aMultipleLanguages;
560 nLang = SwLangHelper::GetCurrentLanguage( *pWrtSh );
561 if (nLang != LANGUAGE_DONTKNOW)
562 aCurrentLang = aLangTable.GetString( nLang );
564 // build sequence for status value
565 uno::Sequence< ::rtl::OUString > aSeq( 4 );
566 aSeq[0] = aCurrentLang;
567 aSeq[1] = aScriptTypesInUse;
568 aSeq[2] = aKeyboardLang;
569 aSeq[3] = aLangTable.GetString(nGuessLangWord);
571 pMenu = GetPopupMenu(MN_LANGUAGE_SELECTION);
572 nNumLanguageTextEntries = fillLangPopupMenu( pMenu, MN_LANGUAGE_SELECTION_START, aSeq, pWrtSh, 0 );
573 EnableItem( MN_LANGUAGE_SELECTION, true );
575 pMenu = GetPopupMenu(MN_LANGUAGE_PARAGRAPH);
576 nNumLanguageParaEntries = fillLangPopupMenu( pMenu, MN_LANGUAGE_PARAGRAPH_START, aSeq, pWrtSh, 1 );
577 EnableItem( MN_LANGUAGE_PARAGRAPH, true );
579 pMenu = GetPopupMenu(MN_LANGUAGE_ALL_TEXT);
580 nNumLanguageDocEntries = fillLangPopupMenu( pMenu, MN_LANGUAGE_ALL_TEXT_START, aSeq, pWrtSh, 2 );
581 EnableItem( MN_LANGUAGE_ALL_TEXT, true );
583 uno::Reference< frame::XFrame > xFrame = pWrtSh->GetView().GetViewFrame()->GetFrame()->GetFrameInterface();
584 Image rImg = ::GetImage( xFrame,
585 ::rtl::OUString::createFromAscii(".uno:SpellingAndGrammarDialog"), sal_False,
586 Application::GetSettings().GetStyleSettings().GetWindowColor().IsDark() );
587 SetItemImage( MN_SPELLING, rImg );
588 //////////////////////////////////////////////////////////////////////////////////
590 RemoveDisabledEntries( TRUE, TRUE );
591 SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS);
594 /*--------------------------------------------------------------------------
596 ---------------------------------------------------------------------------*/
598 SwSpellPopup::SwSpellPopup(
599 SwWrtShell *pWrtSh,
600 const linguistic2::ProofreadingResult &rResult,
601 sal_Int32 nErrorInResult,
602 const uno::Sequence< rtl::OUString > &rSuggestions,
603 const String &rParaText ) :
604 PopupMenu( SW_RES(MN_SPELL_POPUP) ),
605 pSh( pWrtSh ),
606 aSuggestions( rSuggestions ),
607 bGrammarResults( true ),
608 aInfo16( SW_RES(IMG_INFO_16) )
610 nCheckedLanguage = SvxLocaleToLanguage( rResult.aLocale );
612 sal_Int16 nItemId = 1;
613 sal_Int16 nPos = 0;
614 OUString aMessageText( rResult.aErrors[ nErrorInResult ].aShortComment );
615 InsertSeparator( nPos++ );
616 InsertItem( nItemId, aMessageText, MIB_NOSELECT, nPos++ );
617 SetItemImage( nItemId, aInfo16 );
618 ++nItemId;
620 CreateAutoMnemonics();
622 InsertSeparator( nPos++ );
623 sal_Int32 nStringCount = aSuggestions.getLength();
624 if ( nStringCount ) // suggestions available...
626 Image aImage;
627 OUString aSuggestionImageUrl;
628 uno::Reference< lang::XServiceInfo > xInfo( rResult.xProofreader, uno::UNO_QUERY );
629 if (xInfo.is())
631 aSuggestionImageUrl = SvtLinguConfig().GetSpellAndGrammarContextSuggestionImage( xInfo->getImplementationName() );
632 aImage = Image( lcl_GetImageFromPngUrl( aSuggestionImageUrl ) );
635 for (sal_uInt16 i = 0; i < nStringCount; ++i)
637 const String aEntry = aSuggestions[ i ];
638 InsertItem( nItemId, aEntry, 0, nPos++ );
639 SetHelpId( nItemId, HID_LINGU_REPLACE );
641 if (aSuggestionImageUrl.getLength() > 0)
642 SetItemImage( nItemId, aImage );
644 ++nItemId;
646 InsertSeparator( nPos++ );
649 OUString aIgnoreSelection( String( SW_RES( STR_IGNORE_SELECTION ) ) );
650 OUString aSpellingAndGrammar = RetrieveLabelFromCommand( C2U(".uno:SpellingAndGrammarDialog") );
651 SetItemText( MN_SPELLING, aSpellingAndGrammar );
652 USHORT nItemPos = GetItemPos( MN_IGNORE );
653 InsertItem( MN_IGNORE_SELECTION, aIgnoreSelection, 0, nItemPos );
654 SetHelpId( MN_IGNORE_SELECTION, HID_LINGU_IGNORE_SELECTION);
656 EnableItem( MN_AUTOCORR, false );
658 uno::Reference< linguistic2::XLanguageGuessing > xLG = SW_MOD()->GetLanguageGuesser();
659 nGuessLangWord = LANGUAGE_NONE;
660 nGuessLangPara = LANGUAGE_NONE;
661 if (xLG.is())
663 // nGuessLangWord = lcl_CheckLanguage( xSpellAlt->getWord(), ::GetSpellChecker(), xLG, sal_False );
664 nGuessLangPara = lcl_CheckLanguage( rParaText, ::GetSpellChecker(), xLG, sal_True );
666 if (nGuessLangWord != LANGUAGE_NONE || nGuessLangPara != LANGUAGE_NONE)
668 // make sure LANGUAGE_NONE gets not used as menu entry
669 if (nGuessLangWord == LANGUAGE_NONE)
670 nGuessLangWord = nGuessLangPara;
671 if (nGuessLangPara == LANGUAGE_NONE)
672 nGuessLangPara = nGuessLangWord;
675 EnableItem( MN_IGNORE, false );
676 EnableItem( MN_INSERT, false );
678 //ADD NEW LANGUAGE MENU ITEM
679 ///////////////////////////////////////////////////////////////////////////
680 String aScriptTypesInUse( String::CreateFromInt32( pWrtSh->GetScriptType() ) );
681 SvtLanguageTable aLangTable;
683 // get keyboard language
684 String aKeyboardLang;
685 LanguageType nLang = LANGUAGE_DONTKNOW;
686 SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
687 nLang = rEditWin.GetInputLanguage();
688 if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
689 aKeyboardLang = aLangTable.GetString( nLang );
691 // get the language that is in use
692 const String aMultipleLanguages = String::CreateFromAscii("*");
693 String aCurrentLang = aMultipleLanguages;
694 nLang = SwLangHelper::GetCurrentLanguage( *pWrtSh );
695 if (nLang != LANGUAGE_DONTKNOW)
696 aCurrentLang = aLangTable.GetString( nLang );
698 // build sequence for status value
699 uno::Sequence< ::rtl::OUString > aSeq( 4 );
700 aSeq[0] = aCurrentLang;
701 aSeq[1] = aScriptTypesInUse;
702 aSeq[2] = aKeyboardLang;
703 aSeq[3] = aLangTable.GetString(nGuessLangWord);
705 PopupMenu *pMenu = GetPopupMenu(MN_LANGUAGE_SELECTION);
706 nNumLanguageTextEntries = fillLangPopupMenu( pMenu, MN_LANGUAGE_SELECTION_START, aSeq, pWrtSh, 0 );
707 EnableItem( MN_LANGUAGE_SELECTION, true );
709 pMenu = GetPopupMenu(MN_LANGUAGE_PARAGRAPH);
710 nNumLanguageParaEntries = fillLangPopupMenu( pMenu, MN_LANGUAGE_PARAGRAPH_START, aSeq, pWrtSh, 1 );
711 EnableItem( MN_LANGUAGE_PARAGRAPH, true );
713 pMenu = GetPopupMenu(MN_LANGUAGE_ALL_TEXT);
714 nNumLanguageDocEntries = fillLangPopupMenu( pMenu, MN_LANGUAGE_ALL_TEXT_START, aSeq, pWrtSh, 2 );
715 EnableItem( MN_LANGUAGE_ALL_TEXT, true );
717 uno::Reference< frame::XFrame > xFrame = pWrtSh->GetView().GetViewFrame()->GetFrame()->GetFrameInterface();
718 Image rImg = ::GetImage( xFrame,
719 ::rtl::OUString::createFromAscii(".uno:SpellingAndGrammarDialog"), sal_False,
720 Application::GetSettings().GetStyleSettings().GetWindowColor().IsDark() );
721 SetItemImage( MN_SPELLING, rImg );
723 //////////////////////////////////////////////////////////////////////////////////
725 RemoveDisabledEntries( TRUE, TRUE );
726 SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS);
729 /*--------------------------------------------------------------------------
731 ---------------------------------------------------------------------------*/
732 sal_uInt16 SwSpellPopup::Execute( const Rectangle& rWordPos, Window* pWin )
734 // SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS);
735 sal_uInt16 nRet = PopupMenu::Execute(pWin, pWin->LogicToPixel(rWordPos));
736 Execute( nRet );
737 return nRet;
739 /*-- 19.01.2006 08:15:48---------------------------------------------------
741 -----------------------------------------------------------------------*/
742 void SwSpellPopup::Execute( USHORT nId )
744 if (bGrammarResults && nId == 1)
745 return; // nothing to do since it is the error message (short comment)
747 sal_Bool bAutoCorr = sal_False;
748 if( nId > MN_AUTOCORR_START && nId < MN_LANGUAGE_SELECTION_START && nId != USHRT_MAX )
750 nId -= MN_AUTOCORR_START;
751 bAutoCorr = sal_True;
754 if( nId && nId != USHRT_MAX)
756 int nAltIdx = bGrammarResults ? nId - 2 : nId - 1;
757 if ( nAltIdx >= 0 && nAltIdx < aSuggestions.getLength() && (bGrammarResults || xSpellAlt.is()) )
759 sal_Bool bOldIns = pSh->IsInsMode();
760 pSh->SetInsMode( sal_True );
762 DBG_ASSERT( 0 <= nAltIdx && nAltIdx <= aSuggestions.getLength(), "index out of range");
763 String aTmp( aSuggestions[ nAltIdx ] );
764 String aOrig( bGrammarResults ? OUString() : xSpellAlt->getWord() );
766 // if orginal word has a trailing . (likely the end of a sentence)
767 // and the replacement text hasn't, then add it to the replacement
768 if (aTmp.Len() && aOrig.Len() &&
769 '.' == aOrig.GetChar( aOrig.Len() - 1) && /* !IsAlphaNumeric ??*/
770 '.' != aTmp.GetChar( aTmp.Len() - 1))
772 aTmp += '.';
775 // #111827#
776 SwRewriter aRewriter;
778 aRewriter.AddRule(UNDO_ARG1, pSh->GetCrsrDescr());
779 aRewriter.AddRule(UNDO_ARG2, String(SW_RES(STR_YIELDS)));
782 String aTmpStr;
784 aTmpStr += String(SW_RES(STR_START_QUOTE));
785 aTmpStr += aTmp;
786 aTmpStr += String(SW_RES(STR_END_QUOTE));
787 aRewriter.AddRule(UNDO_ARG3, aTmpStr);
790 pSh->StartUndo(UNDO_UI_REPLACE, &aRewriter);
791 pSh->StartAction();
792 pSh->DelLeft();
794 pSh->Insert( aTmp );
795 /* #102505# EndAction/EndUndo moved down since insertion
796 of temporary auto correction is now undoable two and
797 must reside in the same undo group.*/
800 // nur aufnehmen, wenn es NICHT schon in der Autokorrektur vorhanden ist
801 SvxAutoCorrect* pACorr = SvxAutoCorrCfg::Get()->GetAutoCorrect();
803 String aOrigWord( bGrammarResults ? OUString() : xSpellAlt->getWord() ) ;
804 String aNewWord;
805 if( nId )
806 aNewWord = aSuggestions[ nAltIdx ];
807 else
808 aNewWord = aOrigWord;
809 SvxPrepareAutoCorrect( aOrigWord, aNewWord );
811 if( bAutoCorr )
813 pACorr->PutText( aOrigWord, aNewWord, nCheckedLanguage );
816 /* #102505# EndAction/EndUndo moved down since insertion
817 of temporary auto correction is now undoable two and
818 must reside in the same undo group.*/
819 pSh->EndAction();
820 pSh->EndUndo(UNDO_UI_REPLACE);
822 pSh->SetInsMode( bOldIns );
824 else
826 if (nId < MN_LANGUAGE_SELECTION_START)
828 switch( nId )
830 case MN_SPELLING:
832 if (bGrammarResults)
834 SvtLinguConfig().SetProperty( A2OU( UPN_IS_GRAMMAR_INTERACTIVE ), uno::makeAny( sal_True ));
836 pSh->Left(CRSR_SKIP_CHARS, FALSE, 1, FALSE );
838 uno::Reference<linguistic2::XDictionaryList> xDictionaryList( SvxGetDictionaryList() );
839 SvxDicListChgClamp aClamp( xDictionaryList );
840 pSh->GetView().GetViewFrame()->GetDispatcher()->
841 Execute( FN_SPELL_GRAMMAR_DIALOG, SFX_CALLMODE_ASYNCHRON );
844 break;
845 case MN_IGNORE_SELECTION :
847 SwPaM *pPaM = pSh->GetCrsr();
848 if (pPaM)
849 pSh->IgnoreGrammarErrorAt( *pPaM );
851 break;
852 case MN_IGNORE :
854 uno::Reference< linguistic2::XDictionary > xDictionary( SvxGetIgnoreAllList(), uno::UNO_QUERY );
855 linguistic::AddEntryToDic(
856 xDictionary,
857 xSpellAlt->getWord(), sal_False,
858 aEmptyStr, LANGUAGE_NONE );
860 break;
861 case MN_INSERT:
862 DBG_ERROR("geht noch nicht!");
863 break;
864 case MN_LANGUAGE_WORD:
865 case MN_LANGUAGE_PARA:
867 pSh->StartAction();
869 if( MN_LANGUAGE_PARA == nId )
871 if( !pSh->IsSttPara() )
872 pSh->MovePara( fnParaCurr, fnParaStart );
873 pSh->SwapPam();
874 if( !pSh->IsEndPara() )
875 pSh->MovePara( fnParaCurr, fnParaEnd );
878 LanguageType nLangToUse = (MN_LANGUAGE_PARA == nId) ? nGuessLangPara : nGuessLangWord;
879 sal_uInt16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( nLangToUse );
880 USHORT nResId = 0;
881 switch (nScriptType)
883 case SCRIPTTYPE_COMPLEX : nResId = RES_CHRATR_CTL_LANGUAGE; break;
884 case SCRIPTTYPE_ASIAN : nResId = RES_CHRATR_CJK_LANGUAGE; break;
885 default /*SCRIPTTYPE_LATIN*/: nResId = RES_CHRATR_LANGUAGE; break;
887 SfxItemSet aSet(pSh->GetAttrPool(), nResId, nResId );
888 aSet.Put( SvxLanguageItem( nLangToUse, nResId ) );
889 pSh->SetAttr( aSet );
891 pSh->EndAction();
893 break;
894 default:
895 if(nId >= MN_INSERT_START )
897 OUString aWord( xSpellAlt->getWord() );
898 INT32 nDicIdx = nId - MN_INSERT_START - 1;
899 DBG_ASSERT( nDicIdx < aDics.getLength(),
900 "dictionary index out of range" );
901 uno::Reference< linguistic2::XDictionary > xDic =
902 aDics.getConstArray()[nDicIdx];
903 INT16 nAddRes = linguistic::AddEntryToDic( xDic,
904 aWord, FALSE, aEmptyStr, LANGUAGE_NONE );
905 // save modified user-dictionary if it is persistent
906 uno::Reference< frame::XStorable > xSavDic( xDic, uno::UNO_QUERY );
907 if (xSavDic.is())
908 xSavDic->store();
910 if (DIC_ERR_NONE != nAddRes
911 && !xDic->getEntry( aWord ).is())
913 SvxDicError(
914 &pSh->GetView().GetViewFrame()->GetWindow(),
915 nAddRes );
920 else
922 SfxItemSet aCoreSet( pSh->GetView().GetPool(),
923 RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE,
924 RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CJK_LANGUAGE,
925 RES_CHRATR_CTL_LANGUAGE, RES_CHRATR_CTL_LANGUAGE,
926 0 );
927 String aNewLangTxt;
929 // pSh->StartAction();
931 if (nId >= MN_LANGUAGE_SELECTION_START && nId < MN_LANGUAGE_SELECTION_START + nNumLanguageTextEntries - 1)
933 //Set language for current selection
934 aNewLangTxt=aLangTable_Text[nId];
935 SwLangHelper::SetLanguage( *pSh, aNewLangTxt, true, aCoreSet );
937 else if (nId == MN_LANGUAGE_SELECTION_START + nNumLanguageTextEntries - 1)
939 //Set Language_None for current selection
940 SwLangHelper::SetLanguage_None( *pSh, true, aCoreSet );
942 else if (nId == MN_LANGUAGE_SELECTION_START + nNumLanguageTextEntries)
944 //Open Format/Character Dialog
945 lcl_CharDialog( *pSh, true, nId, 0, 0 );
947 else if (nId >= MN_LANGUAGE_PARAGRAPH_START && nId < MN_LANGUAGE_PARAGRAPH_START + nNumLanguageParaEntries - 1)
949 //Set language for current paragraph
950 aNewLangTxt=aLangTable_Paragraph[nId];
951 pSh->Push(); // save cursor
952 SwLangHelper::SelectCurrentPara( *pSh );
953 SwLangHelper::SetLanguage( *pSh, aNewLangTxt, true, aCoreSet );
954 pSh->Pop( FALSE ); // restore cursor
956 else if (nId == MN_LANGUAGE_PARAGRAPH_START + nNumLanguageParaEntries - 1)
958 //Set Language_None for current paragraph
959 pSh->Push(); // save cursor
960 SwLangHelper::SelectCurrentPara( *pSh );
961 SwLangHelper::SetLanguage_None( *pSh, true, aCoreSet );
962 pSh->Pop( FALSE ); // restore cursor
964 else if (nId == MN_LANGUAGE_PARAGRAPH_START + nNumLanguageParaEntries)
966 pSh->Push(); // save cursor
967 SwLangHelper::SelectCurrentPara( *pSh );
968 //Open Format/Character Dialog
969 lcl_CharDialog( *pSh, true, nId, 0, 0 );
970 pSh->Pop( FALSE ); // restore cursor
972 else if (nId >= MN_LANGUAGE_ALL_TEXT_START && nId < MN_LANGUAGE_ALL_TEXT_START + nNumLanguageDocEntries - 1)
974 //Set selected language as the default language
975 aNewLangTxt=aLangTable_Document[nId];
976 SwLangHelper::SetLanguage( *pSh, aNewLangTxt, false, aCoreSet );
978 else if (nId == MN_LANGUAGE_ALL_TEXT_START + nNumLanguageDocEntries - 1)
980 //Set Language_None as the default language
981 SwLangHelper::SetLanguage_None( *pSh, false, aCoreSet );
983 else if (nId == MN_LANGUAGE_ALL_TEXT_START + nNumLanguageDocEntries)
985 // open the dialog "Tools/Options/Language Settings - Language"
986 SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
987 if (pFact)
989 VclAbstractDialog* pDlg = pFact->CreateVclDialog( pSh->GetView().GetWindow(), SID_LANGUAGE_OPTIONS );
990 pDlg->Execute();
991 delete pDlg;
995 // pSh->EndAction();
1000 pSh->EnterStdMode();