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