1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: olmenu.cxx,v $
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>
37 #define _SVSTDARR_STRINGSDTOR
38 #include <svtools/svstdarr.hxx>
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>
77 #include <swtypes.hxx>
80 #include <docsh.hxx> //CheckSpellChanges
83 #include <crsskip.hxx>
89 #include <SwRewriter.hxx>
90 #include <comcore.hrc>
95 #include <svtools/languageoptions.hxx>
97 #include <svtools/langtab.hxx>
98 #include <com/sun/star/document/XDocumentLanguages.hpp>
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>
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())
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
)
152 if (nLang
== LANGUAGE_NONE
) // language not found by looking up the system language...
153 nLang
= MsLangId::convertLocaleToLanguageWithFallback( aLocale
);
154 if (nLang
== LANGUAGE_SYSTEM
)
156 if (nLang
== LANGUAGE_DONTKNOW
)
157 nLang
= LANGUAGE_NONE
;
159 else // check single word
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();
178 aLangList
[3] = LANGUAGE_ENGLISH_US
;
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] ) );
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
>() ))
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
,
224 uno::Sequence
< ::rtl::OUString
> aSeq
,
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
;
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
));
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
294 LATIN + ASIAN + COMPLEX : 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)
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)
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
);
340 pPopupMenu
->InsertItem( nItemId
, String(SW_RES( STR_LANGSTATUS_NONE
)), MIB_RADIOCHECK
);
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
)
354 osl::FileBase::getSystemPathFromFileURL( rFileUrl
, aTmp
);
355 // ::rtl::OString aPath = OString( aTmp.getStr(), aTmp.getLength(), osl_getThreadTextEncoding() );
357 // aTmp = lcl_Win_GetShortPathName( aTmp );
360 const String
aFilterName( RTL_CONSTASCII_USTRINGPARAM( IMP_PNG
) );
361 if( GRFILTER_OK
== LoadGraphic( aTmp
, aFilterName
, aGraphic
) )
363 aRes
= Image( aGraphic
.GetBitmapEx() );
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
;
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
;
401 catch ( uno::Exception
& )
410 SwSpellPopup::SwSpellPopup(
412 const uno::Reference
< linguistic2::XSpellAlternatives
> &xAlt
,
413 const String
&rParaText
) :
414 PopupMenu( SW_RES(MN_SPELL_POPUP
) ),
417 bGrammarResults(false)
419 DBG_ASSERT(xSpellAlt
.is(), "no spelling alternatives available");
421 CreateAutoMnemonics();
422 nCheckedLanguage
= LANGUAGE_NONE
;
425 nCheckedLanguage
= SvxLocaleToLanguage( xSpellAlt
->getLocale() );
426 aSuggestions
= xSpellAlt
->getAlternatives();
428 sal_Int16 nStringCount
= static_cast< sal_Int16
>( aSuggestions
.getLength() );
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
;
439 OUString aSuggestionImageUrl
;
440 uno::Reference
< container::XNamed
> xNamed( xSpellAlt
, uno::UNO_QUERY
);
443 aSuggestionImageUrl
= aCfg
.GetSpellAndGrammarContextSuggestionImage( xNamed
->getName(), bIsDark
);
444 aImage
= Image( lcl_GetImageFromPngUrl( aSuggestionImageUrl
) );
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() );
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
) );
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
)
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() );
528 uno::Reference
< lang::XServiceInfo
> xSvcInfo( xDicTmp
, uno::UNO_QUERY
);
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(
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
) ),
606 aSuggestions( rSuggestions
),
607 bGrammarResults( true ),
608 aInfo16( SW_RES(IMG_INFO_16
) )
610 nCheckedLanguage
= SvxLocaleToLanguage( rResult
.aLocale
);
612 sal_Int16 nItemId
= 1;
614 OUString
aMessageText( rResult
.aErrors
[ nErrorInResult
].aShortComment
);
615 InsertSeparator( nPos
++ );
616 InsertItem( nItemId
, aMessageText
, MIB_NOSELECT
, nPos
++ );
617 SetItemImage( nItemId
, aInfo16
);
620 CreateAutoMnemonics();
622 InsertSeparator( nPos
++ );
623 sal_Int32 nStringCount
= aSuggestions
.getLength();
624 if ( nStringCount
) // suggestions available...
627 OUString aSuggestionImageUrl
;
628 uno::Reference
< lang::XServiceInfo
> xInfo( rResult
.xProofreader
, uno::UNO_QUERY
);
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
);
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
;
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
));
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))
776 SwRewriter aRewriter
;
778 aRewriter
.AddRule(UNDO_ARG1
, pSh
->GetCrsrDescr());
779 aRewriter
.AddRule(UNDO_ARG2
, String(SW_RES(STR_YIELDS
)));
784 aTmpStr
+= String(SW_RES(STR_START_QUOTE
));
786 aTmpStr
+= String(SW_RES(STR_END_QUOTE
));
787 aRewriter
.AddRule(UNDO_ARG3
, aTmpStr
);
790 pSh
->StartUndo(UNDO_UI_REPLACE
, &aRewriter
);
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() ) ;
806 aNewWord
= aSuggestions
[ nAltIdx
];
808 aNewWord
= aOrigWord
;
809 SvxPrepareAutoCorrect( aOrigWord
, aNewWord
);
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.*/
820 pSh
->EndUndo(UNDO_UI_REPLACE
);
822 pSh
->SetInsMode( bOldIns
);
826 if (nId
< MN_LANGUAGE_SELECTION_START
)
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
);
845 case MN_IGNORE_SELECTION
:
847 SwPaM
*pPaM
= pSh
->GetCrsr();
849 pSh
->IgnoreGrammarErrorAt( *pPaM
);
854 uno::Reference
< linguistic2::XDictionary
> xDictionary( SvxGetIgnoreAllList(), uno::UNO_QUERY
);
855 linguistic::AddEntryToDic(
857 xSpellAlt
->getWord(), sal_False
,
858 aEmptyStr
, LANGUAGE_NONE
);
862 DBG_ERROR("geht noch nicht!");
864 case MN_LANGUAGE_WORD
:
865 case MN_LANGUAGE_PARA
:
869 if( MN_LANGUAGE_PARA
== nId
)
871 if( !pSh
->IsSttPara() )
872 pSh
->MovePara( fnParaCurr
, fnParaStart
);
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
);
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
);
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
);
910 if (DIC_ERR_NONE
!= nAddRes
911 && !xDic
->getEntry( aWord
).is())
914 &pSh
->GetView().GetViewFrame()->GetWindow(),
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
,
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();
989 VclAbstractDialog
* pDlg
= pFact
->CreateVclDialog( pSh
->GetView().GetWindow(), SID_LANGUAGE_OPTIONS
);
1000 pSh
->EnterStdMode();