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
28 #include <hintids.hxx>
29
30 #include <editeng/tstpitem.hxx>
31 #include <editeng/lrspitem.hxx>
32 #include <editeng/scripttypeitem.hxx>
33 #include <com/sun/star/i18n/ScriptType.hdl>
34 #include <txatbase.hxx>
35 #include <txtftn.hxx>
36 #include <fmtftn.hxx>
37 #include <editsh.hxx>
38 #include <edimp.hxx> // fuer MACROS
39 #include <doc.hxx>
40 #include <swundo.hxx> // fuer UNDO-Ids
41 #include <ndtxt.hxx>
42 #include <ftnidx.hxx>
43 #include <expfld.hxx>
44 #include <rootfrm.hxx>
45 #include <cntfrm.hxx>
46 #include <breakit.hxx>
47 #include <txtfld.hxx>
48 #include <fmtfld.hxx>
49 #include <crsskip.hxx>
50 #include <txtfrm.hxx> // SwTxtFrm
51 #include <scriptinfo.hxx>
52 #include <svl/ctloptions.hxx>
53 #include <charfmt.hxx> // #i27615#
54 #include <numrule.hxx>
55
56
57 /*************************************
58 * harte Formatierung (Attribute)
59 *************************************/
60
61 // wenn Selektion groesser Max Nodes oder mehr als Max Selektionen
62 // => keine Attribute
getMaxLookup()63 const sal_uInt16& getMaxLookup()
64 {
65 static const sal_uInt16 nMaxLookup = 1000;
66 return nMaxLookup;
67 }
68
69 // --> OD 2008-01-16 #newlistlevelattrs#
GetCurAttr(SfxItemSet & rSet,const bool bMergeIndentValuesOfNumRule) const70 sal_Bool SwEditShell::GetCurAttr( SfxItemSet& rSet,
71 const bool bMergeIndentValuesOfNumRule ) const
72 // <--
73 {
74 if( GetCrsrCnt() > getMaxLookup() )
75 {
76 rSet.InvalidateAllItems();
77 return sal_False;
78 }
79
80 SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() );
81 SfxItemSet *pSet = &rSet;
82
83 FOREACHPAM_START(this)
84
85 // #i27615# if the cursor is in front of the numbering label
86 // the attributes to get are those from the numbering format.
87 if (PCURCRSR->IsInFrontOfLabel())
88 {
89 SwTxtNode * pTxtNd =
90 PCURCRSR->GetPoint()->nNode.GetNode().GetTxtNode();
91
92 if (pTxtNd)
93 {
94 SwNumRule * pNumRule = pTxtNd->GetNumRule();
95
96 if (pNumRule)
97 {
98 const String & aCharFmtName =
99 pNumRule->Get(static_cast<sal_uInt16>(pTxtNd->GetActualListLevel())).GetCharFmtName();
100 SwCharFmt * pCharFmt =
101 GetDoc()->FindCharFmtByName(aCharFmtName);
102
103 if (pCharFmt)
104 rSet.Put(pCharFmt->GetAttrSet());
105 }
106 }
107
108 continue;
109 }
110
111 sal_uLong nSttNd = PCURCRSR->GetMark()->nNode.GetIndex(),
112 nEndNd = PCURCRSR->GetPoint()->nNode.GetIndex();
113 xub_StrLen nSttCnt = PCURCRSR->GetMark()->nContent.GetIndex(),
114 nEndCnt = PCURCRSR->GetPoint()->nContent.GetIndex();
115
116 if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt ))
117 {
118 sal_uLong nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp;
119 nTmp = nSttCnt; nSttCnt = nEndCnt; nEndCnt = (xub_StrLen)nTmp;
120 }
121
122 if( nEndNd - nSttNd >= getMaxLookup() )
123 {
124 rSet.ClearItem();
125 rSet.InvalidateAllItems();
126 return sal_False;
127 }
128
129 // beim 1.Node traegt der Node die Werte in den GetSet ein (Initial)
130 // alle weiteren Nodes werden zum GetSet zu gemergt
131 for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
132 {
133 SwNode* pNd = GetDoc()->GetNodes()[ n ];
134 switch( pNd->GetNodeType() )
135 {
136 case ND_TEXTNODE:
137 {
138 xub_StrLen nStt = n == nSttNd ? nSttCnt : 0,
139 nEnd = n == nEndNd ? nEndCnt
140 : ((SwTxtNode*)pNd)->GetTxt().Len();
141 // --> OD 2008-01-16 #newlistlevelattrs#
142 ((SwTxtNode*)pNd)->GetAttr( *pSet, nStt, nEnd,
143 sal_False, sal_True,
144 bMergeIndentValuesOfNumRule );
145 // <--
146 }
147 break;
148 case ND_GRFNODE:
149 case ND_OLENODE:
150 ((SwCntntNode*)pNd)->GetAttr( *pSet );
151 break;
152
153 default:
154 pNd = 0;
155 }
156
157 if( pNd )
158 {
159 if( pSet != &rSet )
160 rSet.MergeValues( aSet );
161
162 if( aSet.Count() )
163 aSet.ClearItem();
164 }
165 pSet = &aSet;
166 }
167
168 FOREACHPAM_END()
169
170 return sal_True;
171 }
172
GetCurTxtFmtColl() const173 SwTxtFmtColl* SwEditShell::GetCurTxtFmtColl() const
174 {
175 SwTxtFmtColl *pFmt = 0;
176
177 if ( GetCrsrCnt() > getMaxLookup() )
178 return 0;
179
180 FOREACHPAM_START(this)
181
182 sal_uLong nSttNd = PCURCRSR->GetMark()->nNode.GetIndex(),
183 nEndNd = PCURCRSR->GetPoint()->nNode.GetIndex();
184 xub_StrLen nSttCnt = PCURCRSR->GetMark()->nContent.GetIndex(),
185 nEndCnt = PCURCRSR->GetPoint()->nContent.GetIndex();
186
187 if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt ))
188 {
189 sal_uLong nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp;
190 nTmp = nSttCnt; nSttCnt = nEndCnt; nEndCnt = (xub_StrLen)nTmp;
191 }
192
193 if( nEndNd - nSttNd >= getMaxLookup() )
194 {
195 pFmt = 0;
196 break;
197 }
198
199 for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
200 {
201 SwNode* pNd = GetDoc()->GetNodes()[ n ];
202 if( pNd->IsTxtNode() )
203 {
204 if( !pFmt )
205 pFmt = ((SwTxtNode*)pNd)->GetTxtColl();
206 else if( pFmt == ((SwTxtNode*)pNd)->GetTxtColl() ) // ???
207 break;
208 }
209 }
210
211 FOREACHPAM_END()
212 return pFmt;
213 }
214
215
216
GetCurFtn(SwFmtFtn * pFillFtn)217 sal_Bool SwEditShell::GetCurFtn( SwFmtFtn* pFillFtn )
218 {
219 // der Cursor muss auf dem akt. Fussnoten-Anker stehen:
220 SwPaM* pCrsr = GetCrsr();
221 SwTxtNode* pTxtNd = pCrsr->GetNode()->GetTxtNode();
222 if( !pTxtNd )
223 return sal_False;
224
225 SwTxtAttr *const pFtn = pTxtNd->GetTxtAttrForCharAt(
226 pCrsr->GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN);
227 if( pFtn && pFillFtn )
228 {
229 // Daten vom Attribut uebertragen
230 const SwFmtFtn &rFtn = ((SwTxtFtn*)pFtn)->GetFtn();
231 pFillFtn->SetNumber( rFtn );
232 pFillFtn->SetEndNote( rFtn.IsEndNote() );
233 }
234 return 0 != pFtn;
235 }
236
237
SetCurFtn(const SwFmtFtn & rFillFtn)238 bool SwEditShell::SetCurFtn( const SwFmtFtn& rFillFtn )
239 {
240 bool bChgd = false;
241 StartAllAction();
242
243 SwPaM* pCrsr = GetCrsr(), *pFirst = pCrsr;
244 do {
245 bChgd |=
246 pDoc->SetCurFtn( *pCrsr, rFillFtn.GetNumStr(), rFillFtn.GetNumber(), rFillFtn.IsEndNote() );
247
248 } while( pFirst != ( pCrsr = (SwPaM*)pCrsr->GetNext() ));
249
250 EndAllAction();
251 return bChgd;
252 }
253
254
255
256 /*sal_uInt16 SwEditShell::GetFtnCnt( sal_Bool bEndNotes = sal_False ) const
257 {
258 const SwFtnIdxs &rIdxs = pDoc->GetFtnIdxs();
259 sal_uInt16 nCnt = 0;
260 for ( sal_uInt16 i = 0; i < rIdxs.Count(); ++i )
261 {
262 const SwFmtFtn &rFtn = rIdxs[i]->GetFtn();
263 if ( bEndNotes == rFtn.IsEndNote() )
264 nCnt++;
265 }
266 return nCnt;
267 } */
268
269
HasFtns(bool bEndNotes) const270 bool SwEditShell::HasFtns( bool bEndNotes ) const
271 {
272 const SwFtnIdxs &rIdxs = pDoc->GetFtnIdxs();
273 for ( sal_uInt16 i = 0; i < rIdxs.Count(); ++i )
274 {
275 const SwFmtFtn &rFtn = rIdxs[i]->GetFtn();
276 if ( bEndNotes == rFtn.IsEndNote() )
277 return sal_True;
278 }
279 return sal_False;
280 }
281
282
283 // gebe Liste aller Fussnoten und deren Anfangstexte
GetSeqFtnList(SwSeqFldList & rList,bool bEndNotes)284 sal_uInt16 SwEditShell::GetSeqFtnList( SwSeqFldList& rList, bool bEndNotes )
285 {
286 if( rList.Count() )
287 rList.Remove( 0, rList.Count() );
288
289 sal_uInt16 n, nFtnCnt = pDoc->GetFtnIdxs().Count();
290 SwTxtFtn* pTxtFtn;
291 for( n = 0; n < nFtnCnt; ++n )
292 {
293 pTxtFtn = pDoc->GetFtnIdxs()[ n ];
294 const SwFmtFtn& rFtn = pTxtFtn->GetFtn();
295 if ( rFtn.IsEndNote() != bEndNotes )
296 continue;
297
298 SwNodeIndex* pIdx = pTxtFtn->GetStartNode();
299 if( pIdx )
300 {
301 SwNodeIndex aIdx( *pIdx, 1 );
302 SwTxtNode* pTxtNd = aIdx.GetNode().GetTxtNode();
303 if( !pTxtNd )
304 pTxtNd = (SwTxtNode*)pDoc->GetNodes().GoNext( &aIdx );
305
306 if( pTxtNd )
307 {
308 String sTxt( rFtn.GetViewNumStr( *pDoc ));
309 if( sTxt.Len() )
310 sTxt += ' ';
311 sTxt += pTxtNd->GetExpandTxt( 0, USHRT_MAX );
312
313 _SeqFldLstElem* pNew = new _SeqFldLstElem( sTxt,
314 pTxtFtn->GetSeqRefNo() );
315 while( rList.InsertSort( pNew ) )
316 pNew->sDlgEntry += ' ';
317 }
318 }
319 }
320
321 return rList.Count();
322 }
323
324
325 // linken Rand ueber Objectleiste einstellen (aenhlich dem Stufen von
326 // Numerierungen)
IsMoveLeftMargin(sal_Bool bRight,sal_Bool bModulus) const327 sal_Bool SwEditShell::IsMoveLeftMargin( sal_Bool bRight, sal_Bool bModulus ) const
328 {
329 sal_Bool bRet = sal_True;
330
331 const SvxTabStopItem& rTabItem = (SvxTabStopItem&)GetDoc()->
332 GetDefault( RES_PARATR_TABSTOP );
333 sal_uInt16 nDefDist = static_cast<sal_uInt16>(rTabItem.Count() ? rTabItem[0].GetTabPos() : 1134);
334 if( !nDefDist )
335 return sal_False;
336
337 FOREACHPAM_START(this)
338
339 sal_uLong nSttNd = PCURCRSR->GetMark()->nNode.GetIndex(),
340 nEndNd = PCURCRSR->GetPoint()->nNode.GetIndex();
341
342 if( nSttNd > nEndNd )
343 {
344 sal_uLong nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp;
345 }
346
347 SwCntntNode* pCNd;
348 for( sal_uLong n = nSttNd; bRet && n <= nEndNd; ++n )
349 if( 0 != ( pCNd = GetDoc()->GetNodes()[ n ]->GetTxtNode() ))
350 {
351 const SvxLRSpaceItem& rLS = (SvxLRSpaceItem&)
352 pCNd->GetAttr( RES_LR_SPACE );
353 if( bRight )
354 {
355 long nNext = rLS.GetTxtLeft() + nDefDist;
356 if( bModulus )
357 nNext = ( nNext / nDefDist ) * nDefDist;
358 SwFrm* pFrm = pCNd->getLayoutFrm( GetLayout() );
359 if ( pFrm )
360 {
361 const sal_uInt16 nFrmWidth = static_cast<sal_uInt16>( pFrm->IsVertical() ?
362 pFrm->Frm().Height() :
363 pFrm->Frm().Width() );
364 bRet = nFrmWidth > ( nNext + MM50 );
365 }
366 else
367 bRet = sal_False;
368 }
369 }
370
371 if( !bRet )
372 break;
373
374 FOREACHPAM_END()
375 return bRet;
376 }
377
MoveLeftMargin(sal_Bool bRight,sal_Bool bModulus)378 void SwEditShell::MoveLeftMargin( sal_Bool bRight, sal_Bool bModulus )
379 {
380 StartAllAction();
381 StartUndo( UNDO_START );
382
383 SwPaM* pCrsr = GetCrsr();
384 if( pCrsr->GetNext() != pCrsr ) // Mehrfachselektion ?
385 {
386 SwPamRanges aRangeArr( *pCrsr );
387 SwPaM aPam( *pCrsr->GetPoint() );
388 for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
389 GetDoc()->MoveLeftMargin( aRangeArr.SetPam( n, aPam ),
390 bRight, bModulus );
391 }
392 else
393 GetDoc()->MoveLeftMargin( *pCrsr, bRight, bModulus );
394
395 EndUndo( UNDO_END );
396 EndAllAction();
397 }
398
399
lcl_SetScriptFlags(sal_uInt16 nType)400 inline sal_uInt16 lcl_SetScriptFlags( sal_uInt16 nType )
401 {
402 sal_uInt16 nRet;
403 switch( nType )
404 {
405 case ::com::sun::star::i18n::ScriptType::LATIN: nRet = SCRIPTTYPE_LATIN; break;
406 case ::com::sun::star::i18n::ScriptType::ASIAN: nRet = SCRIPTTYPE_ASIAN; break;
407 case ::com::sun::star::i18n::ScriptType::COMPLEX: nRet = SCRIPTTYPE_COMPLEX; break;
408 default: nRet = 0;
409 }
410 return nRet;
411 }
412
lcl_IsNoEndTxtAttrAtPos(const SwTxtNode & rTNd,xub_StrLen nPos,sal_uInt16 & rScrpt,sal_Bool bInSelection,sal_Bool bNum)413 sal_Bool lcl_IsNoEndTxtAttrAtPos( const SwTxtNode& rTNd, xub_StrLen nPos,
414 sal_uInt16 &rScrpt, sal_Bool bInSelection, sal_Bool bNum )
415 {
416 sal_Bool bRet = sal_False;
417 const String& rTxt = rTNd.GetTxt();
418 String sExp;
419
420 // consider numbering
421 if ( bNum )
422 {
423 bRet = sal_False;
424
425 if ( rTNd.IsInList() )
426 {
427 ASSERT( rTNd.GetNumRule(),
428 "<lcl_IsNoEndTxtAttrAtPos(..)> - no list style found at text node. Serious defect -> please inform OD." );
429 const SwNumRule* pNumRule = rTNd.GetNumRule();
430 //Modified for i119959,2012.6.12
431 //Under this scenario,this pointer is null,but on win,it doesn't crash immediately
432 //it exits with exception,and associated memory will have problem which leads to crash problem in
433 //other place in dev env...
434 if ( pNumRule )
435 {
436 //End
437 const SwNumFmt &rNumFmt = pNumRule->Get( static_cast<sal_uInt16>(rTNd.GetActualListLevel()) );
438 if( SVX_NUM_BITMAP != rNumFmt.GetNumberingType() )
439 {
440 if ( SVX_NUM_CHAR_SPECIAL == rNumFmt.GetNumberingType() )
441 sExp = rNumFmt.GetBulletChar();
442 else
443 sExp = rTNd.GetNumString();
444 }
445 //Modified for i119959,2012.6.12
446 //Under this scenario,this pointer is null,but on win,it doesn't crash immediately
447 //it exits with exception,and associated memory will have problem which leads to crash problem in
448 //other place in dev env...
449 }
450 //End
451 }
452 }
453
454 // and fields
455 if ( CH_TXTATR_BREAKWORD == rTxt.GetChar( nPos ) )
456 {
457 const SwTxtAttr* const pAttr = rTNd.GetTxtAttrForCharAt( nPos );
458 if (pAttr)
459 {
460 bRet = sal_True; // all other than fields can be
461 // defined as weak-script ?
462 if ( RES_TXTATR_FIELD == pAttr->Which() )
463 {
464 const SwField* const pFld = pAttr->GetFmtFld().GetField();
465 if (pFld)
466 {
467 sExp += pFld->ExpandField(true);
468 }
469 }
470 }
471 }
472
473 xub_StrLen nEnd = sExp.Len();
474 if ( nEnd )
475 {
476 xub_StrLen n;
477 if( bInSelection )
478 {
479 sal_uInt16 nScript;
480 for( n = 0; n < nEnd; n = (xub_StrLen)
481 pBreakIt->GetBreakIter()->endOfScript( sExp, n, nScript ))
482 {
483 nScript = pBreakIt->GetBreakIter()->getScriptType( sExp, n );
484 rScrpt |= lcl_SetScriptFlags( nScript );
485 }
486 }
487 else
488 rScrpt |= lcl_SetScriptFlags( pBreakIt->GetBreakIter()->
489 getScriptType( sExp, nEnd-1 ));
490 }
491
492 return bRet;
493 }
494
495
496 // returns the scripttype of the selection
GetScriptType() const497 sal_uInt16 SwEditShell::GetScriptType() const
498 {
499 sal_uInt16 nRet = 0;
500 //if( pBreakIt->GetBreakIter().is() )
501 {
502 FOREACHPAM_START(this)
503
504 const SwPosition *pStt = PCURCRSR->Start(),
505 *pEnd = pStt == PCURCRSR->GetMark()
506 ? PCURCRSR->GetPoint()
507 : PCURCRSR->GetMark();
508 if( pStt == pEnd || *pStt == *pEnd )
509 {
510 const SwTxtNode* pTNd = pStt->nNode.GetNode().GetTxtNode();
511 if( pTNd )
512 {
513 // try to get SwScriptInfo
514 const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTNd );
515
516 xub_StrLen nPos = pStt->nContent.GetIndex();
517 //Task 90448: we need the scripttype of the previous
518 // position, if no selection exist!
519 if( nPos )
520 {
521 SwIndex aIdx( pStt->nContent );
522 if( pTNd->GoPrevious( &aIdx, CRSR_SKIP_CHARS ) )
523 nPos = aIdx.GetIndex();
524 }
525
526 sal_uInt16 nScript;
527
528 if ( pTNd->GetTxt().Len() )
529 {
530 nScript = pScriptInfo ?
531 pScriptInfo->ScriptType( nPos ) :
532 pBreakIt->GetBreakIter()->getScriptType( pTNd->GetTxt(), nPos );
533 }
534 else
535 nScript = GetI18NScriptTypeOfLanguage( (sal_uInt16)GetAppLanguage() );
536
537 if( !lcl_IsNoEndTxtAttrAtPos( *pTNd, nPos, nRet, sal_False, sal_False ))
538 nRet |= lcl_SetScriptFlags( nScript );
539 }
540 }
541 else if ( pBreakIt->GetBreakIter().is() )
542 {
543 sal_uLong nEndIdx = pEnd->nNode.GetIndex();
544 SwNodeIndex aIdx( pStt->nNode );
545 for( ; aIdx.GetIndex() <= nEndIdx; aIdx++ )
546 if( aIdx.GetNode().IsTxtNode() )
547 {
548 const SwTxtNode* pTNd = aIdx.GetNode().GetTxtNode();
549 const String& rTxt = pTNd->GetTxt();
550
551 // try to get SwScriptInfo
552 const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTNd );
553
554 xub_StrLen nChg = aIdx == pStt->nNode
555 ? pStt->nContent.GetIndex()
556 : 0,
557 nEndPos = aIdx == nEndIdx
558 ? pEnd->nContent.GetIndex()
559 : rTxt.Len();
560
561 ASSERT( nEndPos <= rTxt.Len(), "Index outside the range - endless loop!" );
562 if( nEndPos > rTxt.Len() )
563 nEndPos = rTxt.Len();
564
565 sal_uInt16 nScript;
566 while( nChg < nEndPos )
567 {
568 nScript = pScriptInfo ?
569 pScriptInfo->ScriptType( nChg ) :
570 pBreakIt->GetBreakIter()->getScriptType(
571 rTxt, nChg );
572
573 if( !lcl_IsNoEndTxtAttrAtPos( *pTNd, nChg, nRet, sal_True,
574 0 == nChg && rTxt.Len() == nEndPos ) )
575 nRet |= lcl_SetScriptFlags( nScript );
576
577 if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN |
578 SCRIPTTYPE_COMPLEX) == nRet )
579 break;
580
581 xub_StrLen nFldPos = nChg+1;
582
583 nChg = pScriptInfo ?
584 pScriptInfo->NextScriptChg( nChg ) :
585 (xub_StrLen)pBreakIt->GetBreakIter()->endOfScript(
586 rTxt, nChg, nScript );
587
588 nFldPos = rTxt.Search(
589 CH_TXTATR_BREAKWORD, nFldPos );
590 if( nFldPos < nChg )
591 nChg = nFldPos;
592 }
593 if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN |
594 SCRIPTTYPE_COMPLEX) == nRet )
595 break;
596 }
597 }
598 if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN |
599 SCRIPTTYPE_COMPLEX) == nRet )
600 break;
601
602 FOREACHPAM_END()
603 }
604 if( !nRet )
605 nRet = SvtLanguageOptions::GetScriptTypeOfLanguage( LANGUAGE_SYSTEM );
606 return nRet;
607 }
608
609
GetCurLang() const610 sal_uInt16 SwEditShell::GetCurLang() const
611 {
612 const SwPaM* pCrsr = GetCrsr();
613 const SwPosition& rPos = *pCrsr->GetPoint();
614 const SwTxtNode* pTNd = rPos.nNode.GetNode().GetTxtNode();
615 sal_uInt16 nLang;
616 if( pTNd )
617 {
618 //JP 24.9.2001: if exist no selection, then get the language before
619 // the current character!
620 xub_StrLen nPos = rPos.nContent.GetIndex();
621 if( nPos && !pCrsr->HasMark() )
622 --nPos;
623 nLang = pTNd->GetLang( nPos );
624 }
625 else
626 nLang = LANGUAGE_DONTKNOW;
627 return nLang;
628 }
629
GetScalingOfSelectedText() const630 sal_uInt16 SwEditShell::GetScalingOfSelectedText() const
631 {
632 const SwPaM* pCrsr = GetCrsr();
633 const SwPosition* pStt = pCrsr->Start();
634 const SwTxtNode* pTNd = pStt->nNode.GetNode().GetTxtNode();
635 ASSERT( pTNd, "no textnode available" );
636
637 sal_uInt16 nScaleWidth;
638 if( pTNd )
639 {
640 xub_StrLen nStt = pStt->nContent.GetIndex(), nEnd;
641 const SwPosition* pEnd = pStt == pCrsr->GetPoint()
642 ? pCrsr->GetMark()
643 : pCrsr->GetPoint();
644 if( pStt->nNode == pEnd->nNode )
645 nEnd = pEnd->nContent.GetIndex();
646 else
647 nEnd = pTNd->GetTxt().Len();
648 nScaleWidth = pTNd->GetScalingOfSelectedText( nStt, nEnd );
649 }
650 else
651 nScaleWidth = 100; // default are no scaling -> 100%
652 return nScaleWidth;
653 }
654