Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <hintids.hxx>
21 :
22 : #include <editeng/tstpitem.hxx>
23 : #include <editeng/lrspitem.hxx>
24 : #include <editeng/scripttypeitem.hxx>
25 : #include <com/sun/star/i18n/ScriptType.hpp>
26 : #include <txatbase.hxx>
27 : #include <txtftn.hxx>
28 : #include <fmtftn.hxx>
29 : #include <editsh.hxx>
30 : #include <edimp.hxx> // fuer MACROS
31 : #include <doc.hxx>
32 : #include <swundo.hxx> // fuer UNDO-Ids
33 : #include <ndtxt.hxx>
34 : #include <ftnidx.hxx>
35 : #include <expfld.hxx>
36 : #include <rootfrm.hxx>
37 : #include <cntfrm.hxx>
38 : #include <breakit.hxx>
39 : #include <txtfld.hxx>
40 : #include <fmtfld.hxx>
41 : #include <crsskip.hxx>
42 : #include <txtfrm.hxx> // SwTxtFrm
43 : #include <scriptinfo.hxx>
44 : #include <svl/ctloptions.hxx>
45 : #include <charfmt.hxx> // #i27615#
46 : #include <numrule.hxx>
47 :
48 : #include <algorithm>
49 :
50 : /*************************************
51 : * harte Formatierung (Attribute)
52 : *************************************/
53 :
54 : // wenn Selektion groesser Max Nodes oder mehr als Max Selektionen
55 : // => keine Attribute
56 1108 : const sal_uInt16& getMaxLookup()
57 : {
58 : static const sal_uInt16 nMaxLookup = 1000;
59 1108 : return nMaxLookup;
60 : }
61 :
62 545 : sal_Bool SwEditShell::GetPaMAttr( SwPaM* pPaM, SfxItemSet& rSet,
63 : const bool bMergeIndentValuesOfNumRule ) const
64 : {
65 : // ??? pPaM can be different from the Cursor ???
66 545 : if( GetCrsrCnt() > getMaxLookup() )
67 : {
68 0 : rSet.InvalidateAllItems();
69 0 : return sal_False;
70 : }
71 :
72 545 : SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() );
73 545 : SfxItemSet *pSet = &rSet;
74 :
75 545 : SwPaM* pStartPaM = pPaM;
76 545 : do {
77 : // #i27615# if the cursor is in front of the numbering label
78 : // the attributes to get are those from the numbering format.
79 545 : if (pPaM->IsInFrontOfLabel())
80 : {
81 0 : SwTxtNode * pTxtNd = pPaM->GetPoint()->nNode.GetNode().GetTxtNode();
82 :
83 0 : if (pTxtNd)
84 : {
85 0 : SwNumRule * pNumRule = pTxtNd->GetNumRule();
86 :
87 0 : if (pNumRule)
88 : {
89 : const String & aCharFmtName =
90 0 : pNumRule->Get(static_cast<sal_uInt16>(pTxtNd->GetActualListLevel())).GetCharFmtName();
91 : SwCharFmt * pCharFmt =
92 0 : GetDoc()->FindCharFmtByName(aCharFmtName);
93 :
94 0 : if (pCharFmt)
95 0 : rSet.Put(pCharFmt->GetAttrSet());
96 : }
97 : }
98 :
99 0 : continue;
100 : }
101 :
102 545 : sal_uLong nSttNd = pPaM->GetMark()->nNode.GetIndex(),
103 545 : nEndNd = pPaM->GetPoint()->nNode.GetIndex();
104 545 : xub_StrLen nSttCnt = pPaM->GetMark()->nContent.GetIndex(),
105 545 : nEndCnt = pPaM->GetPoint()->nContent.GetIndex();
106 :
107 545 : if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt ))
108 : {
109 0 : std::swap(nSttNd, nEndNd);
110 0 : std::swap(nSttCnt, nEndCnt);
111 : }
112 :
113 545 : if( nEndNd - nSttNd >= getMaxLookup() )
114 : {
115 0 : rSet.ClearItem();
116 0 : rSet.InvalidateAllItems();
117 0 : return sal_False;
118 : }
119 :
120 : // beim 1.Node traegt der Node die Werte in den GetSet ein (Initial)
121 : // alle weiteren Nodes werden zum GetSet zu gemergt
122 1090 : for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
123 : {
124 545 : SwNode* pNd = GetDoc()->GetNodes()[ n ];
125 545 : switch( pNd->GetNodeType() )
126 : {
127 : case ND_TEXTNODE:
128 : {
129 545 : xub_StrLen nStt = n == nSttNd ? nSttCnt : 0,
130 : nEnd = n == nEndNd ? nEndCnt
131 545 : : ((SwTxtNode*)pNd)->GetTxt().Len();
132 :
133 : ((SwTxtNode*)pNd)->GetAttr( *pSet, nStt, nEnd,
134 : sal_False, sal_True,
135 545 : bMergeIndentValuesOfNumRule );
136 : }
137 545 : break;
138 : case ND_GRFNODE:
139 : case ND_OLENODE:
140 0 : ((SwCntntNode*)pNd)->GetAttr( *pSet );
141 0 : break;
142 :
143 : default:
144 0 : pNd = 0;
145 : }
146 :
147 545 : if( pNd )
148 : {
149 545 : if( pSet != &rSet )
150 0 : rSet.MergeValues( aSet );
151 :
152 545 : if( aSet.Count() )
153 0 : aSet.ClearItem();
154 : }
155 545 : pSet = &aSet;
156 : }
157 :
158 545 : } while ( ( pPaM = (SwPaM*)pPaM->GetNext() ) != pStartPaM );
159 :
160 545 : return sal_True;
161 : }
162 :
163 545 : sal_Bool SwEditShell::GetCurAttr( SfxItemSet& rSet,
164 : const bool bMergeIndentValuesOfNumRule ) const
165 : {
166 545 : return GetPaMAttr( GetCrsr(), rSet, bMergeIndentValuesOfNumRule );
167 : }
168 :
169 0 : sal_Bool SwEditShell::GetCurParAttr( SfxItemSet& rSet) const
170 : {
171 0 : return GetPaMParAttr( GetCrsr(), rSet );
172 : }
173 :
174 0 : sal_Bool SwEditShell::GetPaMParAttr( SwPaM* pPaM, SfxItemSet& rSet ) const
175 : {
176 : // number of nodes the function has explored so far
177 0 : sal_uInt16 numberOfLookup = 0;
178 :
179 0 : SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() );
180 0 : SfxItemSet* pSet = &rSet;
181 :
182 0 : SwPaM* pStartPaM = pPaM;
183 0 : do { // for all the point and mark (selections)
184 :
185 : // get the start and the end node of the current selection
186 0 : sal_uLong nSttNd = pPaM->GetMark()->nNode.GetIndex(),
187 0 : nEndNd = pPaM->GetPoint()->nNode.GetIndex();
188 :
189 : // reverse start and end if there number aren't sorted correctly
190 0 : if( nSttNd > nEndNd )
191 0 : std::swap(nSttNd, nEndNd);
192 :
193 : // for all the nodes in the current selection
194 : // get the node (paragraph) attributes
195 : // and merge them in rSet
196 0 : for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
197 : {
198 : // get the node
199 0 : SwNode* pNd = GetDoc()->GetNodes()[ n ];
200 :
201 0 : if( pNd->IsTxtNode() )
202 : {
203 : // get the node (paragraph) attributes
204 0 : static_cast<SwCntntNode*>(pNd)->GetAttr(*pSet);
205 :
206 0 : if( pSet != &rSet && aSet.Count() )
207 : {
208 0 : rSet.MergeValues( aSet );
209 0 : aSet.ClearItem();
210 : }
211 :
212 0 : pSet = &aSet;
213 : }
214 :
215 0 : ++numberOfLookup;
216 :
217 : // if the maximum number of node that can be inspected has been reached
218 0 : if (numberOfLookup >= getMaxLookup())
219 0 : return sal_False;
220 : }
221 0 : } while ( ( pPaM = static_cast<SwPaM*>(pPaM->GetNext()) ) != pStartPaM );
222 :
223 0 : return sal_True;
224 : }
225 :
226 18 : SwTxtFmtColl* SwEditShell::GetCurTxtFmtColl( ) const
227 : {
228 18 : return GetPaMTxtFmtColl( GetCrsr() );
229 : }
230 :
231 18 : SwTxtFmtColl* SwEditShell::GetPaMTxtFmtColl( SwPaM* pPaM ) const
232 : {
233 : // number of nodes the function have explored so far
234 18 : sal_uInt16 numberOfLookup = 0;
235 :
236 18 : SwPaM* pStartPaM = pPaM;
237 0 : do { // for all the point and mark (selections)
238 :
239 : // get the start and the end node of the current selection
240 18 : sal_uLong nSttNd = pPaM->GetMark()->nNode.GetIndex(),
241 18 : nEndNd = pPaM->GetPoint()->nNode.GetIndex();
242 :
243 : // reverse start and end if they aren't sorted correctly
244 18 : if( nSttNd > nEndNd )
245 0 : std::swap(nSttNd, nEndNd);
246 :
247 : // for all the nodes in the current Point and Mark
248 18 : for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
249 : {
250 : // get the node
251 18 : SwNode* pNd = GetDoc()->GetNodes()[ n ];
252 :
253 18 : ++numberOfLookup;
254 :
255 : // if the maximum number of node that can be inspected has been reached
256 18 : if (numberOfLookup >= getMaxLookup())
257 0 : return NULL;
258 :
259 18 : if( pNd->IsTxtNode() )
260 : {
261 : // if it's a text node get its named paragraph format
262 18 : SwTxtFmtColl* pFmt = static_cast<SwTxtNode*>(pNd)->GetTxtColl();
263 :
264 : // if the paragraph format exist stop here and return it
265 18 : if( pFmt != NULL )
266 18 : return pFmt;
267 : }
268 : }
269 0 : } while ( ( pPaM = static_cast<SwPaM*>(pPaM->GetNext()) ) != pStartPaM );
270 :
271 : // if none of the selected node contain a named paragraph format
272 0 : return NULL;
273 : }
274 :
275 :
276 :
277 0 : sal_Bool SwEditShell::GetCurFtn( SwFmtFtn* pFillFtn )
278 : {
279 : // der Cursor muss auf dem akt. Fussnoten-Anker stehen:
280 0 : SwPaM* pCrsr = GetCrsr();
281 0 : SwTxtNode* pTxtNd = pCrsr->GetNode()->GetTxtNode();
282 0 : if( !pTxtNd )
283 0 : return sal_False;
284 :
285 : SwTxtAttr *const pFtn = pTxtNd->GetTxtAttrForCharAt(
286 0 : pCrsr->GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN);
287 0 : if( pFtn && pFillFtn )
288 : {
289 : // Daten vom Attribut uebertragen
290 0 : const SwFmtFtn &rFtn = ((SwTxtFtn*)pFtn)->GetFtn();
291 0 : pFillFtn->SetNumber( rFtn );
292 0 : pFillFtn->SetEndNote( rFtn.IsEndNote() );
293 : }
294 0 : return 0 != pFtn;
295 : }
296 :
297 :
298 0 : bool SwEditShell::SetCurFtn( const SwFmtFtn& rFillFtn )
299 : {
300 0 : bool bChgd = false;
301 0 : StartAllAction();
302 :
303 0 : SwPaM* pCrsr = GetCrsr(), *pFirst = pCrsr;
304 0 : do {
305 0 : bChgd |= pDoc->SetCurFtn( *pCrsr, rFillFtn.GetNumStr(),
306 0 : rFillFtn.GetNumber(),
307 0 : rFillFtn.IsEndNote() );
308 :
309 0 : } while( pFirst != ( pCrsr = (SwPaM*)pCrsr->GetNext() ));
310 :
311 0 : EndAllAction();
312 0 : return bChgd;
313 : }
314 :
315 :
316 0 : bool SwEditShell::HasFtns( bool bEndNotes ) const
317 : {
318 0 : const SwFtnIdxs &rIdxs = pDoc->GetFtnIdxs();
319 0 : for ( sal_uInt16 i = 0; i < rIdxs.size(); ++i )
320 : {
321 0 : const SwFmtFtn &rFtn = rIdxs[i]->GetFtn();
322 0 : if ( bEndNotes == rFtn.IsEndNote() )
323 0 : return true;
324 : }
325 0 : return false;
326 : }
327 :
328 :
329 : // gebe Liste aller Fussnoten und deren Anfangstexte
330 0 : sal_uInt16 SwEditShell::GetSeqFtnList( SwSeqFldList& rList, bool bEndNotes )
331 : {
332 0 : rList.Clear();
333 :
334 0 : sal_uInt16 n, nFtnCnt = pDoc->GetFtnIdxs().size();
335 : SwTxtFtn* pTxtFtn;
336 0 : for( n = 0; n < nFtnCnt; ++n )
337 : {
338 0 : pTxtFtn = pDoc->GetFtnIdxs()[ n ];
339 0 : const SwFmtFtn& rFtn = pTxtFtn->GetFtn();
340 0 : if ( rFtn.IsEndNote() != bEndNotes )
341 0 : continue;
342 :
343 0 : SwNodeIndex* pIdx = pTxtFtn->GetStartNode();
344 0 : if( pIdx )
345 : {
346 0 : SwNodeIndex aIdx( *pIdx, 1 );
347 0 : SwTxtNode* pTxtNd = aIdx.GetNode().GetTxtNode();
348 0 : if( !pTxtNd )
349 0 : pTxtNd = (SwTxtNode*)pDoc->GetNodes().GoNext( &aIdx );
350 :
351 0 : if( pTxtNd )
352 : {
353 0 : String sTxt( rFtn.GetViewNumStr( *pDoc ));
354 0 : if( sTxt.Len() )
355 0 : sTxt += ' ';
356 0 : sTxt += pTxtNd->GetExpandTxt( 0, USHRT_MAX );
357 :
358 : _SeqFldLstElem* pNew = new _SeqFldLstElem( sTxt,
359 0 : pTxtFtn->GetSeqRefNo() );
360 0 : while( rList.InsertSort( pNew ) )
361 0 : pNew->sDlgEntry += ' ';
362 0 : }
363 : }
364 : }
365 :
366 0 : return rList.Count();
367 : }
368 :
369 :
370 : // Adjust left margin via object bar (similar to adjustment of numerations).
371 10 : bool SwEditShell::IsMoveLeftMargin( bool bRight, bool bModulus ) const
372 : {
373 10 : bool bRet = true;
374 :
375 : const SvxTabStopItem& rTabItem = (SvxTabStopItem&)GetDoc()->
376 10 : GetDefault( RES_PARATR_TABSTOP );
377 10 : sal_uInt16 nDefDist = static_cast<sal_uInt16>(rTabItem.Count() ? rTabItem[0].GetTabPos() : 1134);
378 10 : if( !nDefDist )
379 0 : return false;
380 :
381 20 : FOREACHPAM_START(this)
382 :
383 10 : sal_uLong nSttNd = PCURCRSR->GetMark()->nNode.GetIndex(),
384 10 : nEndNd = PCURCRSR->GetPoint()->nNode.GetIndex();
385 :
386 10 : if( nSttNd > nEndNd )
387 0 : std::swap(nSttNd, nEndNd);
388 :
389 : SwCntntNode* pCNd;
390 20 : for( sal_uLong n = nSttNd; bRet && n <= nEndNd; ++n )
391 10 : if( 0 != ( pCNd = GetDoc()->GetNodes()[ n ]->GetTxtNode() ))
392 : {
393 : const SvxLRSpaceItem& rLS = (SvxLRSpaceItem&)
394 10 : pCNd->GetAttr( RES_LR_SPACE );
395 10 : if( bRight )
396 : {
397 5 : long nNext = rLS.GetTxtLeft() + nDefDist;
398 5 : if( bModulus )
399 5 : nNext = ( nNext / nDefDist ) * nDefDist;
400 5 : SwFrm* pFrm = pCNd->getLayoutFrm( GetLayout() );
401 5 : if ( pFrm )
402 : {
403 5 : const sal_uInt16 nFrmWidth = static_cast<sal_uInt16>( pFrm->IsVertical() ?
404 0 : pFrm->Frm().Height() :
405 5 : pFrm->Frm().Width() );
406 5 : bRet = nFrmWidth > ( nNext + MM50 );
407 : }
408 : else
409 0 : bRet = false;
410 : }
411 : }
412 :
413 10 : if( !bRet )
414 : break;
415 :
416 10 : FOREACHPAM_END()
417 10 : return bRet;
418 : }
419 :
420 0 : void SwEditShell::MoveLeftMargin( bool bRight, bool bModulus )
421 : {
422 0 : StartAllAction();
423 0 : StartUndo( UNDO_START );
424 :
425 0 : SwPaM* pCrsr = GetCrsr();
426 0 : if( pCrsr->GetNext() != pCrsr ) // Mehrfachselektion ?
427 : {
428 0 : SwPamRanges aRangeArr( *pCrsr );
429 0 : SwPaM aPam( *pCrsr->GetPoint() );
430 0 : for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
431 0 : GetDoc()->MoveLeftMargin( aRangeArr.SetPam( n, aPam ),
432 0 : bRight, bModulus );
433 : }
434 : else
435 0 : GetDoc()->MoveLeftMargin( *pCrsr, bRight, bModulus );
436 :
437 0 : EndUndo( UNDO_END );
438 0 : EndAllAction();
439 0 : }
440 :
441 :
442 29 : static inline sal_uInt16 lcl_SetScriptFlags( sal_uInt16 nType )
443 : {
444 : sal_uInt16 nRet;
445 29 : switch( nType )
446 : {
447 29 : case ::com::sun::star::i18n::ScriptType::LATIN: nRet = SCRIPTTYPE_LATIN; break;
448 0 : case ::com::sun::star::i18n::ScriptType::ASIAN: nRet = SCRIPTTYPE_ASIAN; break;
449 0 : case ::com::sun::star::i18n::ScriptType::COMPLEX: nRet = SCRIPTTYPE_COMPLEX; break;
450 0 : default: nRet = 0;
451 : }
452 29 : return nRet;
453 : }
454 :
455 29 : static bool lcl_IsNoEndTxtAttrAtPos( const SwTxtNode& rTNd, xub_StrLen nPos,
456 : sal_uInt16 &rScrpt, bool bInSelection, bool bNum )
457 : {
458 29 : bool bRet = false;
459 29 : const String& rTxt = rTNd.GetTxt();
460 29 : String sExp;
461 :
462 : // consider numbering
463 29 : if ( bNum )
464 : {
465 0 : bRet = false;
466 :
467 0 : if ( rTNd.IsInList() )
468 : {
469 : OSL_ENSURE( rTNd.GetNumRule(),
470 : "<lcl_IsNoEndTxtAttrAtPos(..)> - no list style found at text node. Serious defect -> please inform OD." );
471 0 : const SwNumRule* pNumRule = rTNd.GetNumRule();
472 0 : if(pNumRule)
473 : {
474 0 : const SwNumFmt &rNumFmt = pNumRule->Get( static_cast<sal_uInt16>(rTNd.GetActualListLevel()) );
475 0 : if( SVX_NUM_BITMAP != rNumFmt.GetNumberingType() )
476 : {
477 0 : if ( SVX_NUM_CHAR_SPECIAL == rNumFmt.GetNumberingType() )
478 0 : sExp = rNumFmt.GetBulletChar();
479 : else
480 0 : sExp = rTNd.GetNumString();
481 : }
482 : }
483 : }
484 : }
485 :
486 : // and fields
487 29 : if ( CH_TXTATR_BREAKWORD == rTxt.GetChar( nPos ) )
488 : {
489 0 : const SwTxtAttr* const pAttr = rTNd.GetTxtAttrForCharAt( nPos );
490 0 : if (pAttr)
491 : {
492 0 : bRet = true; // all other than fields can be
493 : // defined as weak-script ?
494 0 : if ( RES_TXTATR_FIELD == pAttr->Which() )
495 : {
496 0 : const SwField* const pFld = pAttr->GetFld().GetFld();
497 0 : if (pFld)
498 : {
499 0 : sExp += pFld->ExpandField(true);
500 : }
501 : }
502 : }
503 : }
504 :
505 29 : xub_StrLen nEnd = sExp.Len();
506 29 : if ( nEnd )
507 : {
508 : xub_StrLen n;
509 0 : if( bInSelection )
510 : {
511 : sal_uInt16 nScript;
512 0 : for( n = 0; n < nEnd; n = (xub_StrLen)
513 0 : pBreakIt->GetBreakIter()->endOfScript( sExp, n, nScript ))
514 : {
515 0 : nScript = pBreakIt->GetBreakIter()->getScriptType( sExp, n );
516 0 : rScrpt |= lcl_SetScriptFlags( nScript );
517 : }
518 : }
519 : else
520 0 : rScrpt |= lcl_SetScriptFlags( pBreakIt->GetBreakIter()->
521 0 : getScriptType( sExp, nEnd-1 ));
522 : }
523 :
524 29 : return bRet;
525 : }
526 :
527 :
528 : // returns the scripttpye of the selection
529 29 : sal_uInt16 SwEditShell::GetScriptType() const
530 : {
531 29 : sal_uInt16 nRet = 0;
532 :
533 : {
534 58 : FOREACHPAM_START(this)
535 :
536 29 : const SwPosition *pStt = PCURCRSR->Start(),
537 29 : *pEnd = pStt == PCURCRSR->GetMark()
538 : ? PCURCRSR->GetPoint()
539 29 : : PCURCRSR->GetMark();
540 29 : if( pStt == pEnd || *pStt == *pEnd )
541 : {
542 29 : const SwTxtNode* pTNd = pStt->nNode.GetNode().GetTxtNode();
543 29 : if( pTNd )
544 : {
545 : // try to get SwScriptInfo
546 29 : const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTNd );
547 :
548 29 : xub_StrLen nPos = pStt->nContent.GetIndex();
549 : //Task 90448: we need the scripttype of the previous
550 : // position, if no selection exist!
551 29 : if( nPos )
552 : {
553 0 : SwIndex aIdx( pStt->nContent );
554 0 : if( pTNd->GoPrevious( &aIdx, CRSR_SKIP_CHARS ) )
555 0 : nPos = aIdx.GetIndex();
556 : }
557 :
558 : sal_uInt16 nScript;
559 :
560 29 : if ( pTNd->GetTxt().Len() )
561 : {
562 : nScript = pScriptInfo ?
563 17 : pScriptInfo->ScriptType( nPos ) :
564 34 : pBreakIt->GetBreakIter()->getScriptType( pTNd->GetTxt(), nPos );
565 : }
566 : else
567 12 : nScript = GetI18NScriptTypeOfLanguage( (sal_uInt16)GetAppLanguage() );
568 :
569 29 : if( !lcl_IsNoEndTxtAttrAtPos( *pTNd, nPos, nRet, false, false ))
570 29 : nRet |= lcl_SetScriptFlags( nScript );
571 : }
572 : }
573 0 : else if ( pBreakIt->GetBreakIter().is() )
574 : {
575 0 : sal_uLong nEndIdx = pEnd->nNode.GetIndex();
576 0 : SwNodeIndex aIdx( pStt->nNode );
577 0 : for( ; aIdx.GetIndex() <= nEndIdx; ++aIdx )
578 0 : if( aIdx.GetNode().IsTxtNode() )
579 : {
580 0 : const SwTxtNode* pTNd = aIdx.GetNode().GetTxtNode();
581 0 : const String& rTxt = pTNd->GetTxt();
582 :
583 : // try to get SwScriptInfo
584 0 : const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTNd );
585 :
586 0 : xub_StrLen nChg = aIdx == pStt->nNode
587 0 : ? pStt->nContent.GetIndex()
588 0 : : 0,
589 0 : nEndPos = aIdx == nEndIdx
590 0 : ? pEnd->nContent.GetIndex()
591 0 : : rTxt.Len();
592 :
593 : OSL_ENSURE( nEndPos <= rTxt.Len(), "Index outside the range - endless loop!" );
594 0 : if( nEndPos > rTxt.Len() )
595 0 : nEndPos = rTxt.Len();
596 :
597 : sal_uInt16 nScript;
598 0 : while( nChg < nEndPos )
599 : {
600 : nScript = pScriptInfo ?
601 0 : pScriptInfo->ScriptType( nChg ) :
602 0 : pBreakIt->GetBreakIter()->getScriptType(
603 0 : rTxt, nChg );
604 :
605 0 : if( !lcl_IsNoEndTxtAttrAtPos( *pTNd, nChg, nRet, true,
606 0 : 0 == nChg && rTxt.Len() == nEndPos ) )
607 0 : nRet |= lcl_SetScriptFlags( nScript );
608 :
609 0 : if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN |
610 : SCRIPTTYPE_COMPLEX) == nRet )
611 0 : break;
612 :
613 0 : xub_StrLen nFldPos = nChg+1;
614 :
615 : nChg = pScriptInfo ?
616 0 : pScriptInfo->NextScriptChg( nChg ) :
617 0 : (xub_StrLen)pBreakIt->GetBreakIter()->endOfScript(
618 0 : rTxt, nChg, nScript );
619 :
620 : nFldPos = rTxt.Search(
621 0 : CH_TXTATR_BREAKWORD, nFldPos );
622 0 : if( nFldPos < nChg )
623 0 : nChg = nFldPos;
624 : }
625 0 : if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN |
626 : SCRIPTTYPE_COMPLEX) == nRet )
627 0 : break;
628 0 : }
629 : }
630 29 : if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN |
631 : SCRIPTTYPE_COMPLEX) == nRet )
632 0 : break;
633 :
634 29 : FOREACHPAM_END()
635 : }
636 29 : if( !nRet )
637 0 : nRet = SvtLanguageOptions::GetScriptTypeOfLanguage( LANGUAGE_SYSTEM );
638 29 : return nRet;
639 : }
640 :
641 :
642 0 : sal_uInt16 SwEditShell::GetCurLang() const
643 : {
644 0 : const SwPaM* pCrsr = GetCrsr();
645 0 : const SwPosition& rPos = *pCrsr->GetPoint();
646 0 : const SwTxtNode* pTNd = rPos.nNode.GetNode().GetTxtNode();
647 : sal_uInt16 nLang;
648 0 : if( pTNd )
649 : {
650 : //JP 24.9.2001: if exist no selection, then get the language before
651 : // the current character!
652 0 : xub_StrLen nPos = rPos.nContent.GetIndex();
653 0 : if( nPos && !pCrsr->HasMark() )
654 0 : --nPos;
655 0 : nLang = pTNd->GetLang( nPos );
656 : }
657 : else
658 0 : nLang = LANGUAGE_DONTKNOW;
659 0 : return nLang;
660 : }
661 :
662 0 : sal_uInt16 SwEditShell::GetScalingOfSelectedText() const
663 : {
664 0 : const SwPaM* pCrsr = GetCrsr();
665 0 : const SwPosition* pStt = pCrsr->Start();
666 0 : const SwTxtNode* pTNd = pStt->nNode.GetNode().GetTxtNode();
667 : OSL_ENSURE( pTNd, "no textnode available" );
668 :
669 : sal_uInt16 nScaleWidth;
670 0 : if( pTNd )
671 : {
672 0 : xub_StrLen nStt = pStt->nContent.GetIndex(), nEnd;
673 0 : const SwPosition* pEnd = pStt == pCrsr->GetPoint()
674 : ? pCrsr->GetMark()
675 0 : : pCrsr->GetPoint();
676 0 : if( pStt->nNode == pEnd->nNode )
677 0 : nEnd = pEnd->nContent.GetIndex();
678 : else
679 0 : nEnd = pTNd->GetTxt().Len();
680 0 : nScaleWidth = pTNd->GetScalingOfSelectedText( nStt, nEnd );
681 : }
682 : else
683 0 : nScaleWidth = 100; // default are no scaling -> 100%
684 0 : return nScaleWidth;
685 : }
686 :
687 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|