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