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>
31 : #include <doc.hxx>
32 : #include <swundo.hxx>
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>
43 : #include <scriptinfo.hxx>
44 : #include <svl/ctloptions.hxx>
45 : #include <charfmt.hxx>
46 : #include <numrule.hxx>
47 :
48 : #include <algorithm>
49 :
50 : /*
51 : * hard Formatting (Attributes)
52 : */
53 :
54 : // if selection is bigger as max nodes or more than max selections
55 : // => no attributes
56 30079 : const sal_uInt16& getMaxLookup()
57 : {
58 : static const sal_uInt16 nMaxLookup = 1000;
59 30079 : return nMaxLookup;
60 : }
61 :
62 13441 : sal_Bool SwEditShell::GetPaMAttr( SwPaM* pPaM, SfxItemSet& rSet,
63 : const bool bMergeIndentValuesOfNumRule ) const
64 : {
65 : // ??? pPaM can be different from the Cursor ???
66 13441 : if( GetCrsrCnt() > getMaxLookup() )
67 : {
68 0 : rSet.InvalidateAllItems();
69 0 : return sal_False;
70 : }
71 :
72 13441 : SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() );
73 13441 : SfxItemSet *pSet = &rSet;
74 :
75 13441 : SwPaM* pStartPaM = pPaM;
76 13495 : 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 13495 : 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 0 : int nListLevel = pTxtNd->GetActualListLevel();
90 :
91 0 : if (nListLevel < 0)
92 0 : nListLevel = 0;
93 :
94 0 : if (nListLevel >= MAXLEVEL)
95 0 : nListLevel = MAXLEVEL - 1;
96 :
97 : const OUString & aCharFmtName =
98 0 : pNumRule->Get(static_cast<sal_uInt16>(nListLevel)).GetCharFmtName();
99 : SwCharFmt * pCharFmt =
100 0 : GetDoc()->FindCharFmtByName(aCharFmtName);
101 :
102 0 : if (pCharFmt)
103 0 : rSet.Put(pCharFmt->GetAttrSet());
104 : }
105 : }
106 :
107 0 : continue;
108 : }
109 :
110 13495 : sal_uLong nSttNd = pPaM->GetMark()->nNode.GetIndex(),
111 13495 : nEndNd = pPaM->GetPoint()->nNode.GetIndex();
112 13495 : sal_Int32 nSttCnt = pPaM->GetMark()->nContent.GetIndex();
113 13495 : sal_Int32 nEndCnt = pPaM->GetPoint()->nContent.GetIndex();
114 :
115 13495 : if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt ))
116 : {
117 30 : std::swap(nSttNd, nEndNd);
118 30 : std::swap(nSttCnt, nEndCnt);
119 : }
120 :
121 13495 : if( nEndNd - nSttNd >= getMaxLookup() )
122 : {
123 0 : rSet.ClearItem();
124 0 : rSet.InvalidateAllItems();
125 0 : return sal_False;
126 : }
127 :
128 : // at first node the node enter his values into the GetSet (Initial)
129 : // all additional nodes are additional merged to GetSet
130 26990 : for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
131 : {
132 13495 : SwNode* pNd = GetDoc()->GetNodes()[ n ];
133 13495 : switch( pNd->GetNodeType() )
134 : {
135 : case ND_TEXTNODE:
136 : {
137 13495 : const sal_Int32 nStt = (n == nSttNd) ? nSttCnt : 0;
138 13495 : const sal_Int32 nEnd = (n == nEndNd)
139 : ? nEndCnt
140 13495 : : static_cast<SwTxtNode*>(pNd)->GetTxt().getLength();
141 :
142 : ((SwTxtNode*)pNd)->GetAttr( *pSet, nStt, nEnd,
143 : false, true,
144 13495 : bMergeIndentValuesOfNumRule );
145 : }
146 13495 : break;
147 : case ND_GRFNODE:
148 : case ND_OLENODE:
149 0 : ((SwCntntNode*)pNd)->GetAttr( *pSet );
150 0 : break;
151 :
152 : default:
153 0 : pNd = 0;
154 : }
155 :
156 13495 : if( pNd )
157 : {
158 13495 : if( pSet != &rSet )
159 54 : rSet.MergeValues( aSet );
160 :
161 13495 : if( aSet.Count() )
162 8 : aSet.ClearItem();
163 : }
164 13495 : pSet = &aSet;
165 : }
166 :
167 13495 : } while ( ( pPaM = (SwPaM*)pPaM->GetNext() ) != pStartPaM );
168 :
169 13441 : return sal_True;
170 : }
171 :
172 13441 : sal_Bool SwEditShell::GetCurAttr( SfxItemSet& rSet,
173 : const bool bMergeIndentValuesOfNumRule ) const
174 : {
175 13441 : return GetPaMAttr( GetCrsr(), rSet, bMergeIndentValuesOfNumRule );
176 : }
177 :
178 0 : sal_Bool SwEditShell::GetCurParAttr( SfxItemSet& rSet) const
179 : {
180 0 : return GetPaMParAttr( GetCrsr(), rSet );
181 : }
182 :
183 0 : sal_Bool SwEditShell::GetPaMParAttr( SwPaM* pPaM, SfxItemSet& rSet ) const
184 : {
185 : // number of nodes the function has explored so far
186 0 : sal_uInt16 numberOfLookup = 0;
187 :
188 0 : SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() );
189 0 : SfxItemSet* pSet = &rSet;
190 :
191 0 : SwPaM* pStartPaM = pPaM;
192 0 : do { // for all the point and mark (selections)
193 :
194 : // get the start and the end node of the current selection
195 0 : sal_uLong nSttNd = pPaM->GetMark()->nNode.GetIndex(),
196 0 : nEndNd = pPaM->GetPoint()->nNode.GetIndex();
197 :
198 : // reverse start and end if there number aren't sorted correctly
199 0 : if( nSttNd > nEndNd )
200 0 : std::swap(nSttNd, nEndNd);
201 :
202 : // for all the nodes in the current selection
203 : // get the node (paragraph) attributes
204 : // and merge them in rSet
205 0 : for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
206 : {
207 : // get the node
208 0 : SwNode* pNd = GetDoc()->GetNodes()[ n ];
209 :
210 0 : if( pNd->IsTxtNode() )
211 : {
212 : // get the node (paragraph) attributes
213 0 : static_cast<SwCntntNode*>(pNd)->GetAttr(*pSet);
214 :
215 0 : if( pSet != &rSet && aSet.Count() )
216 : {
217 0 : rSet.MergeValues( aSet );
218 0 : aSet.ClearItem();
219 : }
220 :
221 0 : pSet = &aSet;
222 : }
223 :
224 0 : ++numberOfLookup;
225 :
226 : // if the maximum number of node that can be inspected has been reached
227 0 : if (numberOfLookup >= getMaxLookup())
228 0 : return sal_False;
229 : }
230 0 : } while ( ( pPaM = static_cast<SwPaM*>(pPaM->GetNext()) ) != pStartPaM );
231 :
232 0 : return sal_True;
233 : }
234 :
235 3143 : SwTxtFmtColl* SwEditShell::GetCurTxtFmtColl( ) const
236 : {
237 3143 : return GetPaMTxtFmtColl( GetCrsr() );
238 : }
239 :
240 3143 : SwTxtFmtColl* SwEditShell::GetPaMTxtFmtColl( SwPaM* pPaM ) const
241 : {
242 : // number of nodes the function have explored so far
243 3143 : sal_uInt16 numberOfLookup = 0;
244 :
245 3143 : SwPaM* pStartPaM = pPaM;
246 0 : do { // for all the point and mark (selections)
247 :
248 : // get the start and the end node of the current selection
249 3143 : sal_uLong nSttNd = pPaM->GetMark()->nNode.GetIndex(),
250 3143 : nEndNd = pPaM->GetPoint()->nNode.GetIndex();
251 :
252 : // reverse start and end if they aren't sorted correctly
253 3143 : if( nSttNd > nEndNd )
254 0 : std::swap(nSttNd, nEndNd);
255 :
256 : // for all the nodes in the current Point and Mark
257 3143 : for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
258 : {
259 : // get the node
260 3143 : SwNode* pNd = GetDoc()->GetNodes()[ n ];
261 :
262 3143 : ++numberOfLookup;
263 :
264 : // if the maximum number of node that can be inspected has been reached
265 3143 : if (numberOfLookup >= getMaxLookup())
266 3143 : return NULL;
267 :
268 3143 : if( pNd->IsTxtNode() )
269 : {
270 : // if it's a text node get its named paragraph format
271 3143 : SwTxtFmtColl* pFmt = static_cast<SwTxtNode*>(pNd)->GetTxtColl();
272 :
273 : // if the paragraph format exist stop here and return it
274 3143 : if( pFmt != NULL )
275 3143 : return pFmt;
276 : }
277 : }
278 0 : } while ( ( pPaM = static_cast<SwPaM*>(pPaM->GetNext()) ) != pStartPaM );
279 :
280 : // if none of the selected node contain a named paragraph format
281 0 : return NULL;
282 : }
283 :
284 7 : sal_Bool SwEditShell::GetCurFtn( SwFmtFtn* pFillFtn )
285 : {
286 : // The cursor must be positioned on the current footnotes anchor:
287 7 : SwPaM* pCrsr = GetCrsr();
288 7 : SwTxtNode* pTxtNd = pCrsr->GetNode()->GetTxtNode();
289 7 : if( !pTxtNd )
290 0 : return sal_False;
291 :
292 : SwTxtAttr *const pFtn = pTxtNd->GetTxtAttrForCharAt(
293 7 : pCrsr->GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN);
294 7 : if( pFtn && pFillFtn )
295 : {
296 : // Transfer data from the attribute
297 0 : const SwFmtFtn &rFtn = ((SwTxtFtn*)pFtn)->GetFtn();
298 0 : pFillFtn->SetNumber( rFtn );
299 0 : pFillFtn->SetEndNote( rFtn.IsEndNote() );
300 : }
301 7 : return 0 != pFtn;
302 : }
303 :
304 0 : bool SwEditShell::SetCurFtn( const SwFmtFtn& rFillFtn )
305 : {
306 0 : bool bChgd = false;
307 0 : StartAllAction();
308 :
309 0 : SwPaM* pCrsr = GetCrsr(), *pFirst = pCrsr;
310 0 : do {
311 : bChgd |=
312 0 : mpDoc->SetCurFtn( *pCrsr, rFillFtn.GetNumStr(), rFillFtn.GetNumber(), rFillFtn.IsEndNote() );
313 :
314 0 : } while( pFirst != ( pCrsr = (SwPaM*)pCrsr->GetNext() ));
315 :
316 0 : EndAllAction();
317 0 : return bChgd;
318 : }
319 :
320 0 : bool SwEditShell::HasFtns( bool bEndNotes ) const
321 : {
322 0 : const SwFtnIdxs &rIdxs = mpDoc->GetFtnIdxs();
323 0 : for ( sal_uInt16 i = 0; i < rIdxs.size(); ++i )
324 : {
325 0 : const SwFmtFtn &rFtn = rIdxs[i]->GetFtn();
326 0 : if ( bEndNotes == rFtn.IsEndNote() )
327 0 : return true;
328 : }
329 0 : return false;
330 : }
331 :
332 : /// Give a List of all footnotes and their beginning texts
333 0 : sal_uInt16 SwEditShell::GetSeqFtnList( SwSeqFldList& rList, bool bEndNotes )
334 : {
335 0 : rList.Clear();
336 :
337 0 : sal_uInt16 n, nFtnCnt = mpDoc->GetFtnIdxs().size();
338 : SwTxtFtn* pTxtFtn;
339 0 : for( n = 0; n < nFtnCnt; ++n )
340 : {
341 0 : pTxtFtn = mpDoc->GetFtnIdxs()[ n ];
342 0 : const SwFmtFtn& rFtn = pTxtFtn->GetFtn();
343 0 : if ( rFtn.IsEndNote() != bEndNotes )
344 0 : continue;
345 :
346 0 : SwNodeIndex* pIdx = pTxtFtn->GetStartNode();
347 0 : if( pIdx )
348 : {
349 0 : SwNodeIndex aIdx( *pIdx, 1 );
350 0 : SwTxtNode* pTxtNd = aIdx.GetNode().GetTxtNode();
351 0 : if( !pTxtNd )
352 0 : pTxtNd = (SwTxtNode*)mpDoc->GetNodes().GoNext( &aIdx );
353 :
354 0 : if( pTxtNd )
355 : {
356 0 : OUString sTxt( rFtn.GetViewNumStr( *mpDoc ));
357 0 : if( !sTxt.isEmpty() )
358 0 : sTxt += " ";
359 0 : sTxt += pTxtNd->GetExpandTxt( 0, -1 );
360 :
361 : _SeqFldLstElem* pNew = new _SeqFldLstElem( sTxt,
362 0 : pTxtFtn->GetSeqRefNo() );
363 0 : while( rList.InsertSort( pNew ) )
364 0 : pNew->sDlgEntry += " ";
365 0 : }
366 : }
367 : }
368 :
369 0 : return rList.Count();
370 : }
371 :
372 : /// Adjust left margin via object bar (similar to adjustment of numerations).
373 1358 : bool SwEditShell::IsMoveLeftMargin( bool bRight, bool bModulus ) const
374 : {
375 1358 : bool bRet = true;
376 :
377 : const SvxTabStopItem& rTabItem = (SvxTabStopItem&)GetDoc()->
378 1358 : GetDefault( RES_PARATR_TABSTOP );
379 1358 : sal_uInt16 nDefDist = static_cast<sal_uInt16>(rTabItem.Count() ? rTabItem[0].GetTabPos() : 1134);
380 1358 : if( !nDefDist )
381 0 : return false;
382 :
383 2732 : FOREACHPAM_START(GetCrsr())
384 :
385 1382 : sal_uLong nSttNd = PCURCRSR->GetMark()->nNode.GetIndex(),
386 1382 : nEndNd = PCURCRSR->GetPoint()->nNode.GetIndex();
387 :
388 1382 : if( nSttNd > nEndNd )
389 0 : std::swap(nSttNd, nEndNd);
390 :
391 : SwCntntNode* pCNd;
392 2764 : for( sal_uLong n = nSttNd; bRet && n <= nEndNd; ++n )
393 1382 : if( 0 != ( pCNd = GetDoc()->GetNodes()[ n ]->GetTxtNode() ))
394 : {
395 : const SvxLRSpaceItem& rLS = (SvxLRSpaceItem&)
396 1382 : pCNd->GetAttr( RES_LR_SPACE );
397 1382 : if( bRight )
398 : {
399 691 : long nNext = rLS.GetTxtLeft() + nDefDist;
400 691 : if( bModulus )
401 691 : nNext = ( nNext / nDefDist ) * nDefDist;
402 691 : SwFrm* pFrm = pCNd->getLayoutFrm( GetLayout() );
403 691 : if ( pFrm )
404 : {
405 691 : const sal_uInt16 nFrmWidth = static_cast<sal_uInt16>( pFrm->IsVertical() ?
406 0 : pFrm->Frm().Height() :
407 691 : pFrm->Frm().Width() );
408 691 : bRet = nFrmWidth > ( nNext + MM50 );
409 : }
410 : else
411 0 : bRet = false;
412 : }
413 : }
414 :
415 1382 : if( !bRet )
416 8 : break;
417 :
418 1374 : FOREACHPAM_END()
419 1358 : return bRet;
420 : }
421 :
422 0 : void SwEditShell::MoveLeftMargin( bool bRight, bool bModulus )
423 : {
424 0 : StartAllAction();
425 0 : StartUndo( UNDO_START );
426 :
427 0 : SwPaM* pCrsr = GetCrsr();
428 0 : if( pCrsr->GetNext() != pCrsr ) // Multiple selection ?
429 : {
430 0 : SwPamRanges aRangeArr( *pCrsr );
431 0 : SwPaM aPam( *pCrsr->GetPoint() );
432 0 : for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n )
433 0 : GetDoc()->MoveLeftMargin( aRangeArr.SetPam( n, aPam ),
434 0 : bRight, bModulus );
435 : }
436 : else
437 0 : GetDoc()->MoveLeftMargin( *pCrsr, bRight, bModulus );
438 :
439 0 : EndUndo( UNDO_END );
440 0 : EndAllAction();
441 0 : }
442 :
443 3465 : static inline sal_uInt16 lcl_SetScriptFlags( sal_uInt16 nType )
444 : {
445 : sal_uInt16 nRet;
446 3465 : switch( nType )
447 : {
448 3461 : case ::com::sun::star::i18n::ScriptType::LATIN: nRet = SCRIPTTYPE_LATIN; break;
449 0 : case ::com::sun::star::i18n::ScriptType::ASIAN: nRet = SCRIPTTYPE_ASIAN; break;
450 0 : case ::com::sun::star::i18n::ScriptType::COMPLEX: nRet = SCRIPTTYPE_COMPLEX; break;
451 4 : default: nRet = 0;
452 : }
453 3465 : return nRet;
454 : }
455 :
456 4153 : static bool lcl_IsNoEndTxtAttrAtPos( const SwTxtNode& rTNd, sal_Int32 nPos,
457 : sal_uInt16 &rScrpt, bool bInSelection, bool bNum )
458 : {
459 4153 : bool bRet = false;
460 4153 : OUString sExp;
461 :
462 : // consider numbering
463 4153 : if ( bNum )
464 : {
465 20 : bRet = false;
466 :
467 20 : 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 : int nListLevel = rTNd.GetActualListLevel();
475 :
476 0 : if (nListLevel < 0)
477 0 : nListLevel = 0;
478 :
479 0 : if (nListLevel >= MAXLEVEL)
480 0 : nListLevel = MAXLEVEL - 1;
481 :
482 0 : const SwNumFmt &rNumFmt = pNumRule->Get( static_cast<sal_uInt16>(nListLevel) );
483 0 : if( SVX_NUM_BITMAP != rNumFmt.GetNumberingType() )
484 : {
485 0 : if ( SVX_NUM_CHAR_SPECIAL == rNumFmt.GetNumberingType() )
486 0 : sExp = OUString(rNumFmt.GetBulletChar());
487 : else
488 0 : sExp = rTNd.GetNumString();
489 : }
490 : }
491 : }
492 : }
493 :
494 : // and fields
495 4153 : if (nPos < rTNd.GetTxt().getLength() && CH_TXTATR_BREAKWORD == rTNd.GetTxt()[nPos])
496 : {
497 703 : const SwTxtAttr* const pAttr = rTNd.GetTxtAttrForCharAt( nPos );
498 703 : if (pAttr)
499 : {
500 703 : bRet = true; // all other than fields can be
501 : // defined as weak-script ?
502 703 : if ( RES_TXTATR_FIELD == pAttr->Which() )
503 : {
504 20 : const SwField* const pFld = pAttr->GetFmtFld().GetField();
505 20 : if (pFld)
506 : {
507 20 : sExp += pFld->ExpandField(true);
508 : }
509 : }
510 : }
511 : }
512 :
513 4153 : const sal_Int32 nEnd = sExp.getLength();
514 4153 : if ( nEnd )
515 : {
516 15 : if( bInSelection )
517 : {
518 : sal_uInt16 nScript;
519 0 : for( sal_Int32 n = 0; n < nEnd;
520 0 : n = g_pBreakIt->GetBreakIter()->endOfScript( sExp, n, nScript ))
521 : {
522 0 : nScript = g_pBreakIt->GetBreakIter()->getScriptType( sExp, n );
523 0 : rScrpt |= lcl_SetScriptFlags( nScript );
524 : }
525 : }
526 : else
527 30 : rScrpt |= lcl_SetScriptFlags( g_pBreakIt->GetBreakIter()->
528 15 : getScriptType( sExp, nEnd-1 ));
529 : }
530 :
531 4153 : return bRet;
532 : }
533 :
534 : /// returns the script type of the selection
535 4111 : sal_uInt16 SwEditShell::GetScriptType() const
536 : {
537 4111 : sal_uInt16 nRet = 0;
538 :
539 : {
540 8264 : FOREACHPAM_START(GetCrsr())
541 :
542 4153 : const SwPosition *pStt = PCURCRSR->Start(),
543 4153 : *pEnd = pStt == PCURCRSR->GetMark()
544 : ? PCURCRSR->GetPoint()
545 4153 : : PCURCRSR->GetMark();
546 4153 : if( pStt == pEnd || *pStt == *pEnd )
547 : {
548 4133 : const SwTxtNode* pTNd = pStt->nNode.GetNode().GetTxtNode();
549 4133 : if( pTNd )
550 : {
551 : // try to get SwScriptInfo
552 4133 : const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTNd );
553 :
554 4133 : sal_Int32 nPos = pStt->nContent.GetIndex();
555 : //Task 90448: we need the scripttype of the previous
556 : // position, if no selection exist!
557 4133 : if( nPos )
558 : {
559 1059 : SwIndex aIdx( pStt->nContent );
560 1059 : if( pTNd->GoPrevious( &aIdx, CRSR_SKIP_CHARS ) )
561 1059 : nPos = aIdx.GetIndex();
562 : }
563 :
564 : sal_uInt16 nScript;
565 :
566 4133 : if (!pTNd->GetTxt().isEmpty())
567 : {
568 : nScript = pScriptInfo ?
569 1075 : pScriptInfo->ScriptType( nPos ) :
570 2170 : g_pBreakIt->GetBreakIter()->getScriptType( pTNd->GetTxt(), nPos );
571 : }
572 : else
573 3038 : nScript = GetI18NScriptTypeOfLanguage( (sal_uInt16)GetAppLanguage() );
574 :
575 4133 : if( !lcl_IsNoEndTxtAttrAtPos( *pTNd, nPos, nRet, false, false ))
576 3430 : nRet |= lcl_SetScriptFlags( nScript );
577 : }
578 : }
579 20 : else if ( g_pBreakIt->GetBreakIter().is() )
580 : {
581 20 : sal_uLong nEndIdx = pEnd->nNode.GetIndex();
582 20 : SwNodeIndex aIdx( pStt->nNode );
583 40 : for( ; aIdx.GetIndex() <= nEndIdx; ++aIdx )
584 20 : if( aIdx.GetNode().IsTxtNode() )
585 : {
586 20 : const SwTxtNode* pTNd = aIdx.GetNode().GetTxtNode();
587 20 : const OUString& rTxt = pTNd->GetTxt();
588 :
589 : // try to get SwScriptInfo
590 20 : const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTNd );
591 :
592 20 : sal_Int32 nChg = aIdx == pStt->nNode
593 20 : ? pStt->nContent.GetIndex()
594 40 : : 0;
595 20 : sal_Int32 nEndPos = aIdx == nEndIdx
596 20 : ? pEnd->nContent.GetIndex()
597 40 : : rTxt.getLength();
598 :
599 : OSL_ENSURE( nEndPos <= rTxt.getLength(),
600 : "Index outside the range - endless loop!" );
601 20 : if (nEndPos > rTxt.getLength())
602 0 : nEndPos = rTxt.getLength();
603 :
604 : sal_uInt16 nScript;
605 60 : while( nChg < nEndPos )
606 : {
607 : nScript = pScriptInfo ?
608 20 : pScriptInfo->ScriptType( nChg ) :
609 20 : g_pBreakIt->GetBreakIter()->getScriptType(
610 60 : rTxt, nChg );
611 :
612 20 : if( !lcl_IsNoEndTxtAttrAtPos( *pTNd, nChg, nRet, true,
613 20 : 0 == nChg && rTxt.getLength() == nEndPos))
614 20 : nRet |= lcl_SetScriptFlags( nScript );
615 :
616 20 : if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN |
617 20 : SCRIPTTYPE_COMPLEX) == nRet )
618 0 : break;
619 :
620 20 : sal_Int32 nFldPos = nChg+1;
621 :
622 : nChg = pScriptInfo ?
623 : pScriptInfo->NextScriptChg( nChg ) :
624 20 : g_pBreakIt->GetBreakIter()->endOfScript(
625 40 : rTxt, nChg, nScript );
626 :
627 : nFldPos = rTxt.indexOf(
628 20 : CH_TXTATR_BREAKWORD, nFldPos);
629 20 : if ((-1 != nFldPos) && (nFldPos < nChg))
630 0 : nChg = nFldPos;
631 : }
632 20 : if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN |
633 20 : SCRIPTTYPE_COMPLEX) == nRet )
634 0 : break;
635 20 : }
636 : }
637 4153 : if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN |
638 4153 : SCRIPTTYPE_COMPLEX) == nRet )
639 0 : break;
640 :
641 4153 : FOREACHPAM_END()
642 : }
643 4111 : if( !nRet )
644 692 : nRet = SvtLanguageOptions::GetScriptTypeOfLanguage( LANGUAGE_SYSTEM );
645 4111 : return nRet;
646 : }
647 :
648 0 : sal_uInt16 SwEditShell::GetCurLang() const
649 : {
650 0 : const SwPaM* pCrsr = GetCrsr();
651 0 : const SwPosition& rPos = *pCrsr->GetPoint();
652 0 : const SwTxtNode* pTNd = rPos.nNode.GetNode().GetTxtNode();
653 : sal_uInt16 nLang;
654 0 : if( pTNd )
655 : {
656 : //JP 24.9.2001: if exist no selection, then get the language before
657 : // the current character!
658 0 : sal_Int32 nPos = rPos.nContent.GetIndex();
659 0 : if( nPos && !pCrsr->HasMark() )
660 0 : --nPos;
661 0 : nLang = pTNd->GetLang( nPos );
662 : }
663 : else
664 0 : nLang = LANGUAGE_DONTKNOW;
665 0 : return nLang;
666 : }
667 :
668 0 : sal_uInt16 SwEditShell::GetScalingOfSelectedText() const
669 : {
670 0 : const SwPaM* pCrsr = GetCrsr();
671 0 : const SwPosition* pStt = pCrsr->Start();
672 0 : const SwTxtNode* pTNd = pStt->nNode.GetNode().GetTxtNode();
673 : OSL_ENSURE( pTNd, "no textnode available" );
674 :
675 : sal_uInt16 nScaleWidth;
676 0 : if( pTNd )
677 : {
678 0 : const SwPosition* pEnd = pStt == pCrsr->GetPoint()
679 : ? pCrsr->GetMark()
680 0 : : pCrsr->GetPoint();
681 0 : const sal_Int32 nStt = pStt->nContent.GetIndex();
682 0 : const sal_Int32 nEnd = pStt->nNode == pEnd->nNode
683 0 : ? pEnd->nContent.GetIndex()
684 0 : : pTNd->GetTxt().getLength();
685 0 : nScaleWidth = pTNd->GetScalingOfSelectedText( nStt, nEnd );
686 : }
687 : else
688 0 : nScaleWidth = 100; // default are no scaling -> 100%
689 0 : return nScaleWidth;
690 : }
691 :
692 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|