xref: /trunk/main/sw/source/ui/shells/langhelper.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_sw.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <string.h>
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <vcl/window.hxx>
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir #include <wrtsh.hxx>
36*cdf0e10cSrcweir 
37*cdf0e10cSrcweir #include <sfx2/bindings.hxx>
38*cdf0e10cSrcweir #include <sfx2/dispatch.hxx>
39*cdf0e10cSrcweir #include <sfx2/request.hxx>
40*cdf0e10cSrcweir #include <editeng/eeitem.hxx>
41*cdf0e10cSrcweir #include <editeng/editeng.hxx>
42*cdf0e10cSrcweir #include <editeng/editdata.hxx>
43*cdf0e10cSrcweir #include <editeng/outliner.hxx>
44*cdf0e10cSrcweir #include <editeng/editview.hxx>
45*cdf0e10cSrcweir #include <editeng/scripttypeitem.hxx>
46*cdf0e10cSrcweir #include <editeng/langitem.hxx>
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir #include <svl/languageoptions.hxx>
49*cdf0e10cSrcweir #include <svtools/langtab.hxx>
50*cdf0e10cSrcweir #include <svl/slstitm.hxx>
51*cdf0e10cSrcweir #include <svl/svstdarr.hxx>
52*cdf0e10cSrcweir #include <svl/stritem.hxx>
53*cdf0e10cSrcweir 
54*cdf0e10cSrcweir #include <ndtxt.hxx>
55*cdf0e10cSrcweir #include <pam.hxx>
56*cdf0e10cSrcweir #include <view.hxx>
57*cdf0e10cSrcweir #include <viewopt.hxx>
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir #include "swabstdlg.hxx"
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir #include <vcl/msgbox.hxx>
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir #include <langhelper.hxx>
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir using namespace ::com::sun::star;
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir namespace SwLangHelper
68*cdf0e10cSrcweir {
69*cdf0e10cSrcweir 
70*cdf0e10cSrcweir     sal_uInt16 GetLanguageStatus( OutlinerView* pOLV, SfxItemSet& rSet )
71*cdf0e10cSrcweir     {
72*cdf0e10cSrcweir         ESelection aSelection = pOLV->GetSelection();
73*cdf0e10cSrcweir         EditView& rEditView=pOLV->GetEditView();
74*cdf0e10cSrcweir         EditEngine* pEditEngine=rEditView.GetEditEngine();
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir         // the value of used script types
77*cdf0e10cSrcweir         const sal_uInt16 nScriptType =pOLV->GetSelectedScriptType();
78*cdf0e10cSrcweir         String aScriptTypesInUse( String::CreateFromInt32( nScriptType ) );//pEditEngine->GetScriptType(aSelection)
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir         SvtLanguageTable aLangTable;
81*cdf0e10cSrcweir 
82*cdf0e10cSrcweir         // get keyboard language
83*cdf0e10cSrcweir         String aKeyboardLang;
84*cdf0e10cSrcweir         LanguageType nLang = LANGUAGE_DONTKNOW;
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir         Window* pWin = rEditView.GetWindow();
87*cdf0e10cSrcweir         if(pWin)
88*cdf0e10cSrcweir             nLang = pWin->GetInputLanguage();
89*cdf0e10cSrcweir         if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_SYSTEM)
90*cdf0e10cSrcweir             aKeyboardLang = aLangTable.GetString( nLang );
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir         // get the language that is in use
93*cdf0e10cSrcweir         const String aMultipleLanguages = String::CreateFromAscii("*");
94*cdf0e10cSrcweir         String aCurrentLang = aMultipleLanguages;
95*cdf0e10cSrcweir         SfxItemSet aSet(pOLV->GetAttribs());
96*cdf0e10cSrcweir         nLang = SwLangHelper::GetCurrentLanguage( aSet,nScriptType );
97*cdf0e10cSrcweir         if (nLang != LANGUAGE_DONTKNOW)
98*cdf0e10cSrcweir             aCurrentLang = aLangTable.GetString( nLang );
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir         // build sequence for status value
101*cdf0e10cSrcweir         uno::Sequence< ::rtl::OUString > aSeq( 4 );
102*cdf0e10cSrcweir         aSeq[0] = aCurrentLang;
103*cdf0e10cSrcweir         aSeq[1] = aScriptTypesInUse;
104*cdf0e10cSrcweir         aSeq[2] = aKeyboardLang;
105*cdf0e10cSrcweir         aSeq[3] = SwLangHelper::GetTextForLanguageGuessing( pEditEngine, aSelection );
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir         // set sequence as status value
108*cdf0e10cSrcweir         SfxStringListItem aItem( SID_LANGUAGE_STATUS );
109*cdf0e10cSrcweir         aItem.SetStringList( aSeq );
110*cdf0e10cSrcweir         rSet.Put( aItem, SID_LANGUAGE_STATUS );
111*cdf0e10cSrcweir         return 0;
112*cdf0e10cSrcweir     }
113*cdf0e10cSrcweir 
114*cdf0e10cSrcweir     bool SetLanguageStatus( OutlinerView* pOLV, SfxRequest &rReq, SwView &rView, SwWrtShell &rSh )
115*cdf0e10cSrcweir     {
116*cdf0e10cSrcweir         bool bRestoreSelection = false;
117*cdf0e10cSrcweir         SfxItemSet aEditAttr(pOLV->GetAttribs());
118*cdf0e10cSrcweir         ESelection   aSelection  = pOLV->GetSelection();
119*cdf0e10cSrcweir         EditView   & rEditView   = pOLV->GetEditView();
120*cdf0e10cSrcweir         EditEngine * pEditEngine = rEditView.GetEditEngine();
121*cdf0e10cSrcweir 
122*cdf0e10cSrcweir         // get the language
123*cdf0e10cSrcweir         String aNewLangTxt;
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir         SFX_REQUEST_ARG( rReq, pItem, SfxStringItem, SID_LANGUAGE_STATUS , sal_False );
126*cdf0e10cSrcweir         if (pItem)
127*cdf0e10cSrcweir             aNewLangTxt = pItem->GetValue();
128*cdf0e10cSrcweir 
129*cdf0e10cSrcweir         //!! Remember the view frame right now...
130*cdf0e10cSrcweir         //!! (call to GetView().GetViewFrame() will break if the
131*cdf0e10cSrcweir         //!! SwTextShell got destroyed meanwhile.)
132*cdf0e10cSrcweir         SfxViewFrame *pViewFrame = rView.GetViewFrame();
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir         if (aNewLangTxt.EqualsAscii( "*" ))
135*cdf0e10cSrcweir         {
136*cdf0e10cSrcweir             // open the dialog "Tools/Options/Language Settings - Language"
137*cdf0e10cSrcweir             SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
138*cdf0e10cSrcweir             if (pFact)
139*cdf0e10cSrcweir             {
140*cdf0e10cSrcweir                 VclAbstractDialog* pDlg = pFact->CreateVclDialog( rView.GetWindow(), SID_LANGUAGE_OPTIONS );
141*cdf0e10cSrcweir                 pDlg->Execute();
142*cdf0e10cSrcweir                 delete pDlg;
143*cdf0e10cSrcweir             }
144*cdf0e10cSrcweir         }
145*cdf0e10cSrcweir         else
146*cdf0e10cSrcweir         {
147*cdf0e10cSrcweir             // setting the new language...
148*cdf0e10cSrcweir             if (aNewLangTxt.Len() > 0)
149*cdf0e10cSrcweir             {
150*cdf0e10cSrcweir                 const String aSelectionLangPrefix( String::CreateFromAscii("Current_") );
151*cdf0e10cSrcweir                 const String aParagraphLangPrefix( String::CreateFromAscii("Paragraph_") );
152*cdf0e10cSrcweir                 const String aDocumentLangPrefix( String::CreateFromAscii("Default_") );
153*cdf0e10cSrcweir                 const String aStrNone( String::CreateFromAscii("LANGUAGE_NONE") );
154*cdf0e10cSrcweir                 const String aStrResetLangs( String::CreateFromAscii("RESET_LANGUAGES") );
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir                 xub_StrLen nPos = 0;
157*cdf0e10cSrcweir                 bool bForSelection = true;
158*cdf0e10cSrcweir                 bool bForParagraph = false;
159*cdf0e10cSrcweir                 if (STRING_NOTFOUND != (nPos = aNewLangTxt.Search( aSelectionLangPrefix, 0 )))
160*cdf0e10cSrcweir                 {
161*cdf0e10cSrcweir                     // ... for the current selection
162*cdf0e10cSrcweir                     aNewLangTxt = aNewLangTxt.Erase( nPos, aSelectionLangPrefix.Len() );
163*cdf0e10cSrcweir                     bForSelection = true;
164*cdf0e10cSrcweir                 }
165*cdf0e10cSrcweir                 else if (STRING_NOTFOUND != (nPos = aNewLangTxt.Search( aParagraphLangPrefix , 0 )))
166*cdf0e10cSrcweir                 {
167*cdf0e10cSrcweir                     // ... for the current paragraph language
168*cdf0e10cSrcweir                     aNewLangTxt = aNewLangTxt.Erase( nPos, aParagraphLangPrefix.Len() );
169*cdf0e10cSrcweir                     bForSelection = true;
170*cdf0e10cSrcweir                     bForParagraph = true;
171*cdf0e10cSrcweir                 }
172*cdf0e10cSrcweir                 else if (STRING_NOTFOUND != (nPos = aNewLangTxt.Search( aDocumentLangPrefix , 0 )))
173*cdf0e10cSrcweir                 {
174*cdf0e10cSrcweir                     // ... as default document language
175*cdf0e10cSrcweir                     aNewLangTxt = aNewLangTxt.Erase( nPos, aDocumentLangPrefix.Len() );
176*cdf0e10cSrcweir                     bForSelection = false;
177*cdf0e10cSrcweir                 }
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir                 if (bForParagraph)
180*cdf0e10cSrcweir                 {
181*cdf0e10cSrcweir                     bRestoreSelection = true;
182*cdf0e10cSrcweir                     SwLangHelper::SelectPara( rEditView, aSelection );
183*cdf0e10cSrcweir                     aSelection = pOLV->GetSelection();
184*cdf0e10cSrcweir                 }
185*cdf0e10cSrcweir                 if (!bForSelection) // document language to be changed...
186*cdf0e10cSrcweir                 {
187*cdf0e10cSrcweir                     rSh.StartAction();
188*cdf0e10cSrcweir                     rSh.LockView( sal_True );
189*cdf0e10cSrcweir                     rSh.Push();
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir                     // prepare to apply new language to all text in document
192*cdf0e10cSrcweir                     rSh.SelAll();
193*cdf0e10cSrcweir                     rSh.ExtendedSelectAll();
194*cdf0e10cSrcweir                 }
195*cdf0e10cSrcweir 
196*cdf0e10cSrcweir                 if (aNewLangTxt == aStrNone)
197*cdf0e10cSrcweir                     SwLangHelper::SetLanguage_None( rSh, pOLV, aSelection, bForSelection, aEditAttr );
198*cdf0e10cSrcweir                 else if (aNewLangTxt == aStrResetLangs)
199*cdf0e10cSrcweir                     SwLangHelper::ResetLanguages( rSh, pOLV, aSelection, bForSelection );
200*cdf0e10cSrcweir                 else
201*cdf0e10cSrcweir                     SwLangHelper::SetLanguage( rSh, pOLV, aSelection, aNewLangTxt, bForSelection, aEditAttr );
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir                 // ugly hack, as it seems that EditView/EditEngine does not update their spellchecking marks
204*cdf0e10cSrcweir                 // when setting a new language attribute
205*cdf0e10cSrcweir                 if (bForSelection)
206*cdf0e10cSrcweir                 {
207*cdf0e10cSrcweir                     const SwViewOption* pVOpt = rView.GetWrtShellPtr()->GetViewOptions();
208*cdf0e10cSrcweir                     sal_uLong nCntrl = pEditEngine->GetControlWord();
209*cdf0e10cSrcweir                     // turn off
210*cdf0e10cSrcweir                     if (!pVOpt->IsOnlineSpell())
211*cdf0e10cSrcweir                         nCntrl &= ~EE_CNTRL_ONLINESPELLING;
212*cdf0e10cSrcweir                     else
213*cdf0e10cSrcweir                         nCntrl &= ~EE_CNTRL_ONLINESPELLING;
214*cdf0e10cSrcweir                     pEditEngine->SetControlWord(nCntrl);
215*cdf0e10cSrcweir 
216*cdf0e10cSrcweir                     //turn back on
217*cdf0e10cSrcweir                     if (pVOpt->IsOnlineSpell())
218*cdf0e10cSrcweir                         nCntrl |= EE_CNTRL_ONLINESPELLING;
219*cdf0e10cSrcweir                     else
220*cdf0e10cSrcweir                         nCntrl &= ~EE_CNTRL_ONLINESPELLING;
221*cdf0e10cSrcweir                     pEditEngine->SetControlWord(nCntrl);
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir                     pEditEngine->CompleteOnlineSpelling();
224*cdf0e10cSrcweir                     rEditView.Invalidate();
225*cdf0e10cSrcweir                 }
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir                 if (!bForSelection)
228*cdf0e10cSrcweir                 {
229*cdf0e10cSrcweir                     // need to release view and restore selection...
230*cdf0e10cSrcweir                     rSh.Pop( sal_False );
231*cdf0e10cSrcweir                     rSh.LockView( sal_False );
232*cdf0e10cSrcweir                     rSh.EndAction();
233*cdf0e10cSrcweir                 }
234*cdf0e10cSrcweir             }
235*cdf0e10cSrcweir         }
236*cdf0e10cSrcweir 
237*cdf0e10cSrcweir         // invalidate slot to get the new language displayed
238*cdf0e10cSrcweir         pViewFrame->GetBindings().Invalidate( rReq.GetSlot() );
239*cdf0e10cSrcweir 
240*cdf0e10cSrcweir         rReq.Done();
241*cdf0e10cSrcweir         return bRestoreSelection;
242*cdf0e10cSrcweir     }
243*cdf0e10cSrcweir 
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir     void SetLanguage( SwWrtShell &rWrtSh, const String &rLangText, bool bIsForSelection, SfxItemSet &rCoreSet )
246*cdf0e10cSrcweir     {
247*cdf0e10cSrcweir         SetLanguage( rWrtSh, 0 , ESelection(), rLangText, bIsForSelection, rCoreSet );
248*cdf0e10cSrcweir     }
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir     void SetLanguage( SwWrtShell &rWrtSh, OutlinerView* pOLV, ESelection aSelection, const String &rLangText, bool bIsForSelection, SfxItemSet &rCoreSet )
251*cdf0e10cSrcweir     {
252*cdf0e10cSrcweir         const LanguageType nLang = SvtLanguageTable().GetType( rLangText );
253*cdf0e10cSrcweir         if (nLang != LANGUAGE_DONTKNOW)
254*cdf0e10cSrcweir         {
255*cdf0e10cSrcweir             sal_uInt16 nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( nLang );
256*cdf0e10cSrcweir 
257*cdf0e10cSrcweir             EditEngine* pEditEngine = pOLV ? pOLV->GetEditView().GetEditEngine() : NULL;
258*cdf0e10cSrcweir             DBG_ASSERT( !pOLV || pEditEngine, "OutlinerView without EditEngine???" );
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir             //get ScriptType
261*cdf0e10cSrcweir             sal_uInt16 nLangWhichId = 0;
262*cdf0e10cSrcweir             bool bIsSingleScriptType = true;
263*cdf0e10cSrcweir             switch (nScriptType)
264*cdf0e10cSrcweir             {
265*cdf0e10cSrcweir                 case SCRIPTTYPE_LATIN :    nLangWhichId = pEditEngine ? EE_CHAR_LANGUAGE : RES_CHRATR_LANGUAGE; break;
266*cdf0e10cSrcweir                 case SCRIPTTYPE_ASIAN :    nLangWhichId = pEditEngine ? EE_CHAR_LANGUAGE_CJK : RES_CHRATR_CJK_LANGUAGE; break;
267*cdf0e10cSrcweir                 case SCRIPTTYPE_COMPLEX :  nLangWhichId = pEditEngine ? EE_CHAR_LANGUAGE_CTL : RES_CHRATR_CTL_LANGUAGE; break;
268*cdf0e10cSrcweir                 default:
269*cdf0e10cSrcweir                     bIsSingleScriptType = false;
270*cdf0e10cSrcweir                     DBG_ERROR( "unexpected case" );
271*cdf0e10cSrcweir             }
272*cdf0e10cSrcweir             if (bIsSingleScriptType)
273*cdf0e10cSrcweir             {
274*cdf0e10cSrcweir                 // change language for selection or paragraph
275*cdf0e10cSrcweir                 // (for paragraph is handled by previosuly having set the selection to the
276*cdf0e10cSrcweir                 // whole paragraph)
277*cdf0e10cSrcweir                 if (bIsForSelection)
278*cdf0e10cSrcweir                 {
279*cdf0e10cSrcweir                     // apply language to current selection
280*cdf0e10cSrcweir                     if (pEditEngine)
281*cdf0e10cSrcweir                     {
282*cdf0e10cSrcweir                         rCoreSet.Put( SvxLanguageItem( nLang, nLangWhichId ));
283*cdf0e10cSrcweir                         pEditEngine->QuickSetAttribs( rCoreSet, aSelection);
284*cdf0e10cSrcweir                     }
285*cdf0e10cSrcweir                     else
286*cdf0e10cSrcweir                     {
287*cdf0e10cSrcweir                         rWrtSh.GetCurAttr( rCoreSet );
288*cdf0e10cSrcweir                         rCoreSet.Put( SvxLanguageItem( nLang, nLangWhichId ));
289*cdf0e10cSrcweir                         rWrtSh.SetAttr( rCoreSet );
290*cdf0e10cSrcweir                     }
291*cdf0e10cSrcweir                 }
292*cdf0e10cSrcweir                 else // change language for all text
293*cdf0e10cSrcweir                 {
294*cdf0e10cSrcweir                     // set document default language
295*cdf0e10cSrcweir                     switch (nLangWhichId)
296*cdf0e10cSrcweir                     {
297*cdf0e10cSrcweir                          case EE_CHAR_LANGUAGE :      nLangWhichId = RES_CHRATR_LANGUAGE; break;
298*cdf0e10cSrcweir                          case EE_CHAR_LANGUAGE_CJK :  nLangWhichId = RES_CHRATR_CJK_LANGUAGE; break;
299*cdf0e10cSrcweir                          case EE_CHAR_LANGUAGE_CTL :  nLangWhichId = RES_CHRATR_CTL_LANGUAGE; break;
300*cdf0e10cSrcweir                     }
301*cdf0e10cSrcweir                     rWrtSh.SetDefault( SvxLanguageItem( nLang, nLangWhichId ) );
302*cdf0e10cSrcweir 
303*cdf0e10cSrcweir                     // #i102191: hard set respective language attribute in text document
304*cdf0e10cSrcweir                     // (for all text in the document - which should be selected by now...)
305*cdf0e10cSrcweir                     rWrtSh.SetAttr( SvxLanguageItem( nLang, nLangWhichId ) );
306*cdf0e10cSrcweir                 }
307*cdf0e10cSrcweir             }
308*cdf0e10cSrcweir         }
309*cdf0e10cSrcweir     }
310*cdf0e10cSrcweir 
311*cdf0e10cSrcweir     void SetLanguage_None( SwWrtShell &rWrtSh, bool bIsForSelection, SfxItemSet &rCoreSet )
312*cdf0e10cSrcweir     {
313*cdf0e10cSrcweir         SetLanguage_None( rWrtSh,0,ESelection(),bIsForSelection,rCoreSet );
314*cdf0e10cSrcweir     }
315*cdf0e10cSrcweir 
316*cdf0e10cSrcweir     void SetLanguage_None( SwWrtShell &rWrtSh, OutlinerView* pOLV, ESelection aSelection, bool bIsForSelection, SfxItemSet &rCoreSet )
317*cdf0e10cSrcweir     {
318*cdf0e10cSrcweir         // EditEngine IDs
319*cdf0e10cSrcweir         const sal_uInt16 aLangWhichId_EE[3] =
320*cdf0e10cSrcweir         {
321*cdf0e10cSrcweir             EE_CHAR_LANGUAGE,
322*cdf0e10cSrcweir             EE_CHAR_LANGUAGE_CJK,
323*cdf0e10cSrcweir             EE_CHAR_LANGUAGE_CTL
324*cdf0e10cSrcweir         };
325*cdf0e10cSrcweir 
326*cdf0e10cSrcweir         // Writewr IDs
327*cdf0e10cSrcweir         const sal_uInt16 aLangWhichId_Writer[3] =
328*cdf0e10cSrcweir         {
329*cdf0e10cSrcweir             RES_CHRATR_LANGUAGE,
330*cdf0e10cSrcweir             RES_CHRATR_CJK_LANGUAGE,
331*cdf0e10cSrcweir             RES_CHRATR_CTL_LANGUAGE
332*cdf0e10cSrcweir         };
333*cdf0e10cSrcweir 
334*cdf0e10cSrcweir         if (bIsForSelection)
335*cdf0e10cSrcweir         {
336*cdf0e10cSrcweir             // change language for selection or paragraph
337*cdf0e10cSrcweir             // (for paragraph is handled by previosuly having set the selection to the
338*cdf0e10cSrcweir             // whole paragraph)
339*cdf0e10cSrcweir 
340*cdf0e10cSrcweir             EditEngine* pEditEngine = pOLV ? pOLV->GetEditView().GetEditEngine() : NULL;
341*cdf0e10cSrcweir             DBG_ASSERT( !pOLV || pEditEngine, "OutlinerView without EditEngine???" );
342*cdf0e10cSrcweir             if (pEditEngine)
343*cdf0e10cSrcweir             {
344*cdf0e10cSrcweir                 for (sal_uInt16 i = 0; i < 3; ++i)
345*cdf0e10cSrcweir                     rCoreSet.Put( SvxLanguageItem( LANGUAGE_NONE, aLangWhichId_EE[i] ));
346*cdf0e10cSrcweir                 pEditEngine->QuickSetAttribs( rCoreSet, aSelection);
347*cdf0e10cSrcweir             }
348*cdf0e10cSrcweir             else
349*cdf0e10cSrcweir             {
350*cdf0e10cSrcweir                 rWrtSh.GetCurAttr( rCoreSet );
351*cdf0e10cSrcweir                 for (sal_uInt16 i = 0; i < 3; ++i)
352*cdf0e10cSrcweir                     rCoreSet.Put( SvxLanguageItem( LANGUAGE_NONE, aLangWhichId_Writer[i] ));
353*cdf0e10cSrcweir                 rWrtSh.SetAttr( rCoreSet );
354*cdf0e10cSrcweir             }
355*cdf0e10cSrcweir         }
356*cdf0e10cSrcweir         else // change language for all text
357*cdf0e10cSrcweir         {
358*cdf0e10cSrcweir             SvUShortsSort aAttribs;
359*cdf0e10cSrcweir             for (sal_uInt16 i = 0; i < 3; ++i)
360*cdf0e10cSrcweir             {
361*cdf0e10cSrcweir                 rWrtSh.SetDefault( SvxLanguageItem( LANGUAGE_NONE, aLangWhichId_Writer[i] ) );
362*cdf0e10cSrcweir                 aAttribs.Insert( aLangWhichId_Writer[i] );
363*cdf0e10cSrcweir             }
364*cdf0e10cSrcweir 
365*cdf0e10cSrcweir             // set all language attributes to default
366*cdf0e10cSrcweir             // (for all text in the document - which should be selected by now...)
367*cdf0e10cSrcweir             rWrtSh.ResetAttr( &aAttribs );
368*cdf0e10cSrcweir         }
369*cdf0e10cSrcweir     }
370*cdf0e10cSrcweir 
371*cdf0e10cSrcweir     void ResetLanguages( SwWrtShell &rWrtSh, bool bIsForSelection )
372*cdf0e10cSrcweir     {
373*cdf0e10cSrcweir         ResetLanguages( rWrtSh, 0 , ESelection(), bIsForSelection );
374*cdf0e10cSrcweir     }
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir     void ResetLanguages( SwWrtShell &rWrtSh, OutlinerView* pOLV, ESelection aSelection, bool bIsForSelection )
377*cdf0e10cSrcweir     {
378*cdf0e10cSrcweir         (void) bIsForSelection;
379*cdf0e10cSrcweir         (void) aSelection;
380*cdf0e10cSrcweir 
381*cdf0e10cSrcweir         // reset language for current selection.
382*cdf0e10cSrcweir         // The selection should already have been expanded to the whole paragraph or
383*cdf0e10cSrcweir         // to all text in the document if those are the ranges where to reset
384*cdf0e10cSrcweir         // the language attributes
385*cdf0e10cSrcweir 
386*cdf0e10cSrcweir         if (pOLV)
387*cdf0e10cSrcweir         {
388*cdf0e10cSrcweir             EditView &rEditView = pOLV->GetEditView();
389*cdf0e10cSrcweir             rEditView.RemoveAttribs( true, EE_CHAR_LANGUAGE );
390*cdf0e10cSrcweir             rEditView.RemoveAttribs( true, EE_CHAR_LANGUAGE_CJK );
391*cdf0e10cSrcweir             rEditView.RemoveAttribs( true, EE_CHAR_LANGUAGE_CTL );
392*cdf0e10cSrcweir         }
393*cdf0e10cSrcweir         else
394*cdf0e10cSrcweir         {
395*cdf0e10cSrcweir             SvUShortsSort aAttribs;
396*cdf0e10cSrcweir             aAttribs.Insert( RES_CHRATR_LANGUAGE );
397*cdf0e10cSrcweir             aAttribs.Insert( RES_CHRATR_CJK_LANGUAGE );
398*cdf0e10cSrcweir             aAttribs.Insert( RES_CHRATR_CTL_LANGUAGE );
399*cdf0e10cSrcweir             rWrtSh.ResetAttr( &aAttribs );
400*cdf0e10cSrcweir         }
401*cdf0e10cSrcweir     }
402*cdf0e10cSrcweir 
403*cdf0e10cSrcweir 
404*cdf0e10cSrcweir     /// @returns : the language for the selected text that is set for the
405*cdf0e10cSrcweir     ///     specified attribute (script type).
406*cdf0e10cSrcweir     ///     If there are more than one languages used LANGUAGE_DONTKNOW will be returned.
407*cdf0e10cSrcweir     /// @param nLangWhichId : one of
408*cdf0e10cSrcweir     ///     RES_CHRATR_LANGUAGE, RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CTL_LANGUAGE,
409*cdf0e10cSrcweir     LanguageType GetLanguage( SwWrtShell &rSh, sal_uInt16 nLangWhichId )
410*cdf0e10cSrcweir     {
411*cdf0e10cSrcweir         SfxItemSet aSet( rSh.GetAttrPool(), nLangWhichId, nLangWhichId );
412*cdf0e10cSrcweir         rSh.GetCurAttr( aSet );
413*cdf0e10cSrcweir 
414*cdf0e10cSrcweir         return GetLanguage(aSet,nLangWhichId);
415*cdf0e10cSrcweir     }
416*cdf0e10cSrcweir 
417*cdf0e10cSrcweir     LanguageType GetLanguage( SfxItemSet aSet, sal_uInt16 nLangWhichId )
418*cdf0e10cSrcweir     {
419*cdf0e10cSrcweir 
420*cdf0e10cSrcweir         LanguageType nLang = LANGUAGE_SYSTEM;
421*cdf0e10cSrcweir 
422*cdf0e10cSrcweir         const SfxPoolItem *pItem = 0;
423*cdf0e10cSrcweir         SfxItemState nState = aSet.GetItemState( nLangWhichId, sal_True, &pItem );
424*cdf0e10cSrcweir         if (nState > SFX_ITEM_DEFAULT && pItem)
425*cdf0e10cSrcweir         {
426*cdf0e10cSrcweir             // the item is set and can be used
427*cdf0e10cSrcweir             nLang = (dynamic_cast< const SvxLanguageItem* >(pItem))->GetLanguage();
428*cdf0e10cSrcweir         }
429*cdf0e10cSrcweir         else if (nState == SFX_ITEM_DEFAULT)
430*cdf0e10cSrcweir         {
431*cdf0e10cSrcweir             // since the attribute is not set: retrieve the default value
432*cdf0e10cSrcweir             nLang = (dynamic_cast< const SvxLanguageItem& >(aSet.GetPool()->GetDefaultItem( nLangWhichId ))).GetLanguage();
433*cdf0e10cSrcweir         }
434*cdf0e10cSrcweir         else if (nState == SFX_ITEM_DONTCARE)
435*cdf0e10cSrcweir         {
436*cdf0e10cSrcweir             // there is more than one language...
437*cdf0e10cSrcweir             nLang = LANGUAGE_DONTKNOW;
438*cdf0e10cSrcweir         }
439*cdf0e10cSrcweir         DBG_ASSERT( nLang != LANGUAGE_SYSTEM, "failed to get the language?" );
440*cdf0e10cSrcweir 
441*cdf0e10cSrcweir         return nLang;
442*cdf0e10cSrcweir     }
443*cdf0e10cSrcweir 
444*cdf0e10cSrcweir     /// @returns: the language in use for the selected text.
445*cdf0e10cSrcweir     ///     'In use' means the language(s) matching the script type(s) of the
446*cdf0e10cSrcweir     ///     selected text. Or in other words, the language a spell checker would use.
447*cdf0e10cSrcweir     ///     If there is more than one language LANGUAGE_DONTKNOW will be returned.
448*cdf0e10cSrcweir     LanguageType GetCurrentLanguage( SwWrtShell &rSh )
449*cdf0e10cSrcweir     {
450*cdf0e10cSrcweir         // get all script types used in current selection
451*cdf0e10cSrcweir         const sal_uInt16 nScriptType = rSh.GetScriptType();
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir         //set language attribute to use according to the script type
454*cdf0e10cSrcweir         sal_uInt16 nLangWhichId = 0;
455*cdf0e10cSrcweir         bool bIsSingleScriptType = true;
456*cdf0e10cSrcweir         switch (nScriptType)
457*cdf0e10cSrcweir         {
458*cdf0e10cSrcweir              case SCRIPTTYPE_LATIN :    nLangWhichId = RES_CHRATR_LANGUAGE; break;
459*cdf0e10cSrcweir              case SCRIPTTYPE_ASIAN :    nLangWhichId = RES_CHRATR_CJK_LANGUAGE; break;
460*cdf0e10cSrcweir              case SCRIPTTYPE_COMPLEX :  nLangWhichId = RES_CHRATR_CTL_LANGUAGE; break;
461*cdf0e10cSrcweir              default: bIsSingleScriptType = false; break;
462*cdf0e10cSrcweir         }
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir         // get language according to the script type(s) in use
465*cdf0e10cSrcweir         LanguageType nCurrentLang = LANGUAGE_SYSTEM;
466*cdf0e10cSrcweir         if (bIsSingleScriptType)
467*cdf0e10cSrcweir             nCurrentLang = GetLanguage( rSh, nLangWhichId );
468*cdf0e10cSrcweir         else
469*cdf0e10cSrcweir         {
470*cdf0e10cSrcweir             // check if all script types are set to LANGUAGE_NONE and return
471*cdf0e10cSrcweir             // that if this is the case. Otherwise, having multiple script types
472*cdf0e10cSrcweir             // in use always means there are several languages in use...
473*cdf0e10cSrcweir             const sal_uInt16 aScriptTypes[3] =
474*cdf0e10cSrcweir             {
475*cdf0e10cSrcweir                 RES_CHRATR_LANGUAGE,
476*cdf0e10cSrcweir                 RES_CHRATR_CJK_LANGUAGE,
477*cdf0e10cSrcweir                 RES_CHRATR_CTL_LANGUAGE
478*cdf0e10cSrcweir             };
479*cdf0e10cSrcweir             nCurrentLang = LANGUAGE_NONE;
480*cdf0e10cSrcweir             for (sal_uInt16 i = 0; i < 3; ++i)
481*cdf0e10cSrcweir             {
482*cdf0e10cSrcweir                 LanguageType nTmpLang = GetLanguage( rSh, aScriptTypes[i] );
483*cdf0e10cSrcweir                 if (nTmpLang != LANGUAGE_NONE)
484*cdf0e10cSrcweir                 {
485*cdf0e10cSrcweir                     nCurrentLang = LANGUAGE_DONTKNOW;
486*cdf0e10cSrcweir                     break;
487*cdf0e10cSrcweir                 }
488*cdf0e10cSrcweir             }
489*cdf0e10cSrcweir         }
490*cdf0e10cSrcweir         DBG_ASSERT( nCurrentLang != LANGUAGE_SYSTEM, "failed to get the language?" );
491*cdf0e10cSrcweir 
492*cdf0e10cSrcweir         return nCurrentLang;
493*cdf0e10cSrcweir     }
494*cdf0e10cSrcweir 
495*cdf0e10cSrcweir     /// @returns: the language in use for the selected text.
496*cdf0e10cSrcweir     ///     'In use' means the language(s) matching the script type(s) of the
497*cdf0e10cSrcweir     ///     selected text. Or in other words, the language a spell checker would use.
498*cdf0e10cSrcweir     ///     If there is more than one language LANGUAGE_DONTKNOW will be returned.
499*cdf0e10cSrcweir     LanguageType GetCurrentLanguage( SfxItemSet aSet, sal_uInt16 nScriptType )
500*cdf0e10cSrcweir     {
501*cdf0e10cSrcweir         //set language attribute to use according to the script type
502*cdf0e10cSrcweir         sal_uInt16 nLangWhichId = 0;
503*cdf0e10cSrcweir         bool bIsSingleScriptType = true;
504*cdf0e10cSrcweir         switch (nScriptType)
505*cdf0e10cSrcweir         {
506*cdf0e10cSrcweir              case SCRIPTTYPE_LATIN :    nLangWhichId = EE_CHAR_LANGUAGE; break;
507*cdf0e10cSrcweir              case SCRIPTTYPE_ASIAN :    nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
508*cdf0e10cSrcweir              case SCRIPTTYPE_COMPLEX :  nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
509*cdf0e10cSrcweir              default: bIsSingleScriptType = false;
510*cdf0e10cSrcweir         }
511*cdf0e10cSrcweir 
512*cdf0e10cSrcweir         // get language according to the script type(s) in use
513*cdf0e10cSrcweir         LanguageType nCurrentLang = LANGUAGE_SYSTEM;
514*cdf0e10cSrcweir         if (bIsSingleScriptType)
515*cdf0e10cSrcweir             nCurrentLang = GetLanguage( aSet, nLangWhichId );
516*cdf0e10cSrcweir         else
517*cdf0e10cSrcweir         {
518*cdf0e10cSrcweir             // check if all script types are set to LANGUAGE_NONE and return
519*cdf0e10cSrcweir             // that if this is the case. Otherwise, having multiple script types
520*cdf0e10cSrcweir             // in use always means there are several languages in use...
521*cdf0e10cSrcweir             const sal_uInt16 aScriptTypes[3] =
522*cdf0e10cSrcweir             {
523*cdf0e10cSrcweir                 EE_CHAR_LANGUAGE,
524*cdf0e10cSrcweir                 EE_CHAR_LANGUAGE_CJK,
525*cdf0e10cSrcweir                 EE_CHAR_LANGUAGE_CTL
526*cdf0e10cSrcweir             };
527*cdf0e10cSrcweir             nCurrentLang = LANGUAGE_NONE;
528*cdf0e10cSrcweir             for (sal_uInt16 i = 0; i < 3; ++i)
529*cdf0e10cSrcweir             {
530*cdf0e10cSrcweir                 LanguageType nTmpLang = GetLanguage( aSet, aScriptTypes[i] );
531*cdf0e10cSrcweir                 if (nTmpLang != LANGUAGE_NONE)
532*cdf0e10cSrcweir                 {
533*cdf0e10cSrcweir                     nCurrentLang = LANGUAGE_DONTKNOW;
534*cdf0e10cSrcweir                     break;
535*cdf0e10cSrcweir                 }
536*cdf0e10cSrcweir             }
537*cdf0e10cSrcweir         }
538*cdf0e10cSrcweir         DBG_ASSERT( nCurrentLang != LANGUAGE_SYSTEM, "failed to get the language?" );
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir         return nCurrentLang;
541*cdf0e10cSrcweir     }
542*cdf0e10cSrcweir 
543*cdf0e10cSrcweir     String GetTextForLanguageGuessing( SwWrtShell &rSh )
544*cdf0e10cSrcweir     {
545*cdf0e10cSrcweir         // string for guessing language
546*cdf0e10cSrcweir         String aText;
547*cdf0e10cSrcweir         SwPaM *pCrsr = rSh.GetCrsr();
548*cdf0e10cSrcweir         SwTxtNode *pNode = pCrsr->GetNode()->GetTxtNode();
549*cdf0e10cSrcweir         if (pNode)
550*cdf0e10cSrcweir         {
551*cdf0e10cSrcweir             aText = pNode->GetTxt();
552*cdf0e10cSrcweir             if (aText.Len() > 0)
553*cdf0e10cSrcweir             {
554*cdf0e10cSrcweir                 xub_StrLen nStt = 0;
555*cdf0e10cSrcweir                 xub_StrLen nEnd = pCrsr->GetPoint()->nContent.GetIndex();
556*cdf0e10cSrcweir                 // at most 100 chars to the left...
557*cdf0e10cSrcweir                 nStt = nEnd > 100 ? nEnd - 100 : 0;
558*cdf0e10cSrcweir                 // ... and 100 to the right of the cursor position
559*cdf0e10cSrcweir                 nEnd = aText.Len() - nEnd > 100 ? nEnd + 100 : aText.Len();
560*cdf0e10cSrcweir                 aText = aText.Copy( nStt, nEnd - nStt );
561*cdf0e10cSrcweir             }
562*cdf0e10cSrcweir         }
563*cdf0e10cSrcweir         return aText;
564*cdf0e10cSrcweir     }
565*cdf0e10cSrcweir 
566*cdf0e10cSrcweir     String GetTextForLanguageGuessing( EditEngine* rEditEngine, ESelection aDocSelection )
567*cdf0e10cSrcweir     {
568*cdf0e10cSrcweir         // string for guessing language
569*cdf0e10cSrcweir         String aText;
570*cdf0e10cSrcweir 
571*cdf0e10cSrcweir         aText = rEditEngine->GetText(aDocSelection);
572*cdf0e10cSrcweir         if (aText.Len() > 0)
573*cdf0e10cSrcweir         {
574*cdf0e10cSrcweir             xub_StrLen nStt = 0;
575*cdf0e10cSrcweir             xub_StrLen nEnd = aDocSelection.nEndPos;
576*cdf0e10cSrcweir             // at most 100 chars to the left...
577*cdf0e10cSrcweir             nStt = nEnd > 100 ? nEnd - 100 : 0;
578*cdf0e10cSrcweir             // ... and 100 to the right of the cursor position
579*cdf0e10cSrcweir             nEnd = aText.Len() - nEnd > 100 ? nEnd + 100 : aText.Len();
580*cdf0e10cSrcweir             aText = aText.Copy( nStt, nEnd - nStt );
581*cdf0e10cSrcweir         }
582*cdf0e10cSrcweir 
583*cdf0e10cSrcweir         return aText;
584*cdf0e10cSrcweir     }
585*cdf0e10cSrcweir 
586*cdf0e10cSrcweir 
587*cdf0e10cSrcweir     void SelectPara( EditView &rEditView, const ESelection &rCurSel )
588*cdf0e10cSrcweir     {
589*cdf0e10cSrcweir         ESelection aParaSel( rCurSel.nStartPara, 0, rCurSel.nStartPara, USHRT_MAX );
590*cdf0e10cSrcweir         rEditView.SetSelection( aParaSel );
591*cdf0e10cSrcweir     }
592*cdf0e10cSrcweir 
593*cdf0e10cSrcweir     void SelectCurrentPara( SwWrtShell &rWrtSh )
594*cdf0e10cSrcweir     {
595*cdf0e10cSrcweir         // select current para
596*cdf0e10cSrcweir         if (!rWrtSh.IsSttPara())
597*cdf0e10cSrcweir             rWrtSh.MovePara( fnParaCurr, fnParaStart );
598*cdf0e10cSrcweir         if (!rWrtSh.HasMark())
599*cdf0e10cSrcweir             rWrtSh.SetMark();
600*cdf0e10cSrcweir         rWrtSh.SwapPam();
601*cdf0e10cSrcweir         if (!rWrtSh.IsEndPara())
602*cdf0e10cSrcweir             rWrtSh.MovePara( fnParaCurr, fnParaEnd );
603*cdf0e10cSrcweir     #if OSL_DEBUG_LEVEL > 1
604*cdf0e10cSrcweir         String aSelTxt;
605*cdf0e10cSrcweir         rWrtSh.GetSelectedText( aSelTxt );
606*cdf0e10cSrcweir         (void) aSelTxt;
607*cdf0e10cSrcweir     #endif
608*cdf0e10cSrcweir     }
609*cdf0e10cSrcweir }
610*cdf0e10cSrcweir 
611