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 0 : const sal_uInt16& getMaxLookup()
57 : {
58 : static const sal_uInt16 nMaxLookup = 1000;
59 0 : return nMaxLookup;
60 : }
61 :
62 0 : sal_Bool SwEditShell::GetPaMAttr( SwPaM* pPaM, SfxItemSet& rSet,
63 : const bool bMergeIndentValuesOfNumRule ) const
64 : {
65 : // ??? pPaM can be different from the Cursor ???
66 0 : if( GetCrsrCnt() > getMaxLookup() )
67 : {
68 0 : rSet.InvalidateAllItems();
69 0 : return sal_False;
70 : }
71 :
72 0 : SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() );
73 0 : SfxItemSet *pSet = &rSet;
74 :
75 0 : SwPaM* pStartPaM = pPaM;
76 0 : 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 0 : 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 0 : sal_uLong nSttNd = pPaM->GetMark()->nNode.GetIndex(),
111 0 : nEndNd = pPaM->GetPoint()->nNode.GetIndex();
112 0 : sal_Int32 nSttCnt = pPaM->GetMark()->nContent.GetIndex();
113 0 : sal_Int32 nEndCnt = pPaM->GetPoint()->nContent.GetIndex();
114 :
115 0 : if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt ))
116 : {
117 0 : std::swap(nSttNd, nEndNd);
118 0 : std::swap(nSttCnt, nEndCnt);
119 : }
120 :
121 0 : 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 0 : for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
131 : {
132 0 : SwNode* pNd = GetDoc()->GetNodes()[ n ];
133 0 : switch( pNd->GetNodeType() )
134 : {
135 : case ND_TEXTNODE:
136 : {
137 0 : const sal_Int32 nStt = (n == nSttNd) ? nSttCnt : 0;
138 0 : const sal_Int32 nEnd = (n == nEndNd)
139 : ? nEndCnt
140 0 : : static_cast<SwTxtNode*>(pNd)->GetTxt().getLength();
141 :
142 : ((SwTxtNode*)pNd)->GetAttr( *pSet, nStt, nEnd,
143 : false, true,
144 0 : bMergeIndentValuesOfNumRule );
145 : }
146 0 : 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 0 : if( pNd )
157 : {
158 0 : if( pSet != &rSet )
159 0 : rSet.MergeValues( aSet );
160 :
161 0 : if( aSet.Count() )
162 0 : aSet.ClearItem();
163 : }
164 0 : pSet = &aSet;
165 : }
166 :
167 0 : } while ( ( pPaM = (SwPaM*)pPaM->GetNext() ) != pStartPaM );
168 :
169 0 : return sal_True;
170 : }
171 :
172 0 : sal_Bool SwEditShell::GetCurAttr( SfxItemSet& rSet,
173 : const bool bMergeIndentValuesOfNumRule ) const
174 : {
175 0 : 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 0 : SwTxtFmtColl* SwEditShell::GetCurTxtFmtColl( ) const
236 : {
237 0 : return GetPaMTxtFmtColl( GetCrsr() );
238 : }
239 :
240 0 : SwTxtFmtColl* SwEditShell::GetPaMTxtFmtColl( SwPaM* pPaM ) const
241 : {
242 : // number of nodes the function have explored so far
243 0 : sal_uInt16 numberOfLookup = 0;
244 :
245 0 : 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 0 : sal_uLong nSttNd = pPaM->GetMark()->nNode.GetIndex(),
250 0 : nEndNd = pPaM->GetPoint()->nNode.GetIndex();
251 :
252 : // reverse start and end if they aren't sorted correctly
253 0 : if( nSttNd > nEndNd )
254 0 : std::swap(nSttNd, nEndNd);
255 :
256 : // for all the nodes in the current Point and Mark
257 0 : for( sal_uLong n = nSttNd; n <= nEndNd; ++n )
258 : {
259 : // get the node
260 0 : SwNode* pNd = GetDoc()->GetNodes()[ n ];
261 :
262 0 : ++numberOfLookup;
263 :
264 : // if the maximum number of node that can be inspected has been reached
265 0 : if (numberOfLookup >= getMaxLookup())
266 0 : return NULL;
267 :
268 0 : if( pNd->IsTxtNode() )
269 : {
270 : // if it's a text node get its named paragraph format
271 0 : SwTxtFmtColl* pFmt = static_cast<SwTxtNode*>(pNd)->GetTxtColl();
272 :
273 : // if the paragraph format exist stop here and return it
274 0 : if( pFmt != NULL )
275 0 : 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 0 : sal_Bool SwEditShell::GetCurFtn( SwFmtFtn* pFillFtn )
285 : {
286 : // The cursor must be positioned on the current footnotes anchor:
287 0 : SwPaM* pCrsr = GetCrsr();
288 0 : SwTxtNode* pTxtNd = pCrsr->GetNode()->GetTxtNode();
289 0 : if( !pTxtNd )
290 0 : return sal_False;
291 :
292 : SwTxtAttr *const pFtn = pTxtNd->GetTxtAttrForCharAt(
293 0 : pCrsr->GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN);
294 0 : 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 0 : 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 0 : bool SwEditShell::IsMoveLeftMargin( bool bRight, bool bModulus ) const
374 : {
375 0 : bool bRet = true;
376 :
377 : const SvxTabStopItem& rTabItem = (SvxTabStopItem&)GetDoc()->
378 0 : GetDefault( RES_PARATR_TABSTOP );
379 0 : sal_uInt16 nDefDist = static_cast<sal_uInt16>(rTabItem.Count() ? rTabItem[0].GetTabPos() : 1134);
380 0 : if( !nDefDist )
381 0 : return false;
382 :
383 0 : FOREACHPAM_START(GetCrsr())
384 :
385 0 : sal_uLong nSttNd = PCURCRSR->GetMark()->nNode.GetIndex(),
386 0 : nEndNd = PCURCRSR->GetPoint()->nNode.GetIndex();
387 :
388 0 : if( nSttNd > nEndNd )
389 0 : std::swap(nSttNd, nEndNd);
390 :
391 : SwCntntNode* pCNd;
392 0 : for( sal_uLong n = nSttNd; bRet && n <= nEndNd; ++n )
393 0 : if( 0 != ( pCNd = GetDoc()->GetNodes()[ n ]->GetTxtNode() ))
394 : {
395 : const SvxLRSpaceItem& rLS = (SvxLRSpaceItem&)
396 0 : pCNd->GetAttr( RES_LR_SPACE );
397 0 : if( bRight )
398 : {
399 0 : long nNext = rLS.GetTxtLeft() + nDefDist;
400 0 : if( bModulus )
401 0 : nNext = ( nNext / nDefDist ) * nDefDist;
402 0 : SwFrm* pFrm = pCNd->getLayoutFrm( GetLayout() );
403 0 : if ( pFrm )
404 : {
405 0 : const sal_uInt16 nFrmWidth = static_cast<sal_uInt16>( pFrm->IsVertical() ?
406 0 : pFrm->Frm().Height() :
407 0 : pFrm->Frm().Width() );
408 0 : bRet = nFrmWidth > ( nNext + MM50 );
409 : }
410 : else
411 0 : bRet = false;
412 : }
413 : }
414 :
415 0 : if( !bRet )
416 0 : break;
417 :
418 0 : FOREACHPAM_END()
419 0 : 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 0 : static inline sal_uInt16 lcl_SetScriptFlags( sal_uInt16 nType )
444 : {
445 : sal_uInt16 nRet;
446 0 : switch( nType )
447 : {
448 0 : 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 0 : default: nRet = 0;
452 : }
453 0 : return nRet;
454 : }
455 :
456 0 : static bool lcl_IsNoEndTxtAttrAtPos( const SwTxtNode& rTNd, sal_Int32 nPos,
457 : sal_uInt16 &rScrpt, bool bInSelection, bool bNum )
458 : {
459 0 : bool bRet = false;
460 0 : OUString sExp;
461 :
462 : // consider numbering
463 0 : 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 : 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 0 : if (nPos < rTNd.GetTxt().getLength() && CH_TXTATR_BREAKWORD == rTNd.GetTxt()[nPos])
496 : {
497 0 : const SwTxtAttr* const pAttr = rTNd.GetTxtAttrForCharAt( nPos );
498 0 : if (pAttr)
499 : {
500 0 : bRet = true; // all other than fields can be
501 : // defined as weak-script ?
502 0 : if ( RES_TXTATR_FIELD == pAttr->Which() )
503 : {
504 0 : const SwField* const pFld = pAttr->GetFmtFld().GetField();
505 0 : if (pFld)
506 : {
507 0 : sExp += pFld->ExpandField(true);
508 : }
509 : }
510 : }
511 : }
512 :
513 0 : const sal_Int32 nEnd = sExp.getLength();
514 0 : if ( nEnd )
515 : {
516 0 : 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 0 : rScrpt |= lcl_SetScriptFlags( g_pBreakIt->GetBreakIter()->
528 0 : getScriptType( sExp, nEnd-1 ));
529 : }
530 :
531 0 : return bRet;
532 : }
533 :
534 : /// returns the script type of the selection
535 0 : sal_uInt16 SwEditShell::GetScriptType() const
536 : {
537 0 : sal_uInt16 nRet = 0;
538 :
539 : {
540 0 : FOREACHPAM_START(GetCrsr())
541 :
542 0 : const SwPosition *pStt = PCURCRSR->Start(),
543 0 : *pEnd = pStt == PCURCRSR->GetMark()
544 : ? PCURCRSR->GetPoint()
545 0 : : PCURCRSR->GetMark();
546 0 : if( pStt == pEnd || *pStt == *pEnd )
547 : {
548 0 : const SwTxtNode* pTNd = pStt->nNode.GetNode().GetTxtNode();
549 0 : if( pTNd )
550 : {
551 : // try to get SwScriptInfo
552 0 : const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTNd );
553 :
554 0 : sal_Int32 nPos = pStt->nContent.GetIndex();
555 : //Task 90448: we need the scripttype of the previous
556 : // position, if no selection exist!
557 0 : if( nPos )
558 : {
559 0 : SwIndex aIdx( pStt->nContent );
560 0 : if( pTNd->GoPrevious( &aIdx, CRSR_SKIP_CHARS ) )
561 0 : nPos = aIdx.GetIndex();
562 : }
563 :
564 : sal_uInt16 nScript;
565 :
566 0 : if (!pTNd->GetTxt().isEmpty())
567 : {
568 : nScript = pScriptInfo ?
569 0 : pScriptInfo->ScriptType( nPos ) :
570 0 : g_pBreakIt->GetBreakIter()->getScriptType( pTNd->GetTxt(), nPos );
571 : }
572 : else
573 0 : nScript = GetI18NScriptTypeOfLanguage( (sal_uInt16)GetAppLanguage() );
574 :
575 0 : if( !lcl_IsNoEndTxtAttrAtPos( *pTNd, nPos, nRet, false, false ))
576 0 : nRet |= lcl_SetScriptFlags( nScript );
577 : }
578 : }
579 0 : else if ( g_pBreakIt->GetBreakIter().is() )
580 : {
581 0 : sal_uLong nEndIdx = pEnd->nNode.GetIndex();
582 0 : SwNodeIndex aIdx( pStt->nNode );
583 0 : for( ; aIdx.GetIndex() <= nEndIdx; ++aIdx )
584 0 : if( aIdx.GetNode().IsTxtNode() )
585 : {
586 0 : const SwTxtNode* pTNd = aIdx.GetNode().GetTxtNode();
587 0 : const OUString& rTxt = pTNd->GetTxt();
588 :
589 : // try to get SwScriptInfo
590 0 : const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTNd );
591 :
592 0 : sal_Int32 nChg = aIdx == pStt->nNode
593 0 : ? pStt->nContent.GetIndex()
594 0 : : 0;
595 0 : sal_Int32 nEndPos = aIdx == nEndIdx
596 0 : ? pEnd->nContent.GetIndex()
597 0 : : rTxt.getLength();
598 :
599 : OSL_ENSURE( nEndPos <= rTxt.getLength(),
600 : "Index outside the range - endless loop!" );
601 0 : if (nEndPos > rTxt.getLength())
602 0 : nEndPos = rTxt.getLength();
603 :
604 : sal_uInt16 nScript;
605 0 : while( nChg < nEndPos )
606 : {
607 : nScript = pScriptInfo ?
608 0 : pScriptInfo->ScriptType( nChg ) :
609 0 : g_pBreakIt->GetBreakIter()->getScriptType(
610 0 : rTxt, nChg );
611 :
612 0 : if( !lcl_IsNoEndTxtAttrAtPos( *pTNd, nChg, nRet, true,
613 0 : 0 == nChg && rTxt.getLength() == nEndPos))
614 0 : nRet |= lcl_SetScriptFlags( nScript );
615 :
616 0 : if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN |
617 0 : SCRIPTTYPE_COMPLEX) == nRet )
618 0 : break;
619 :
620 0 : sal_Int32 nFldPos = nChg+1;
621 :
622 : nChg = pScriptInfo ?
623 : pScriptInfo->NextScriptChg( nChg ) :
624 0 : g_pBreakIt->GetBreakIter()->endOfScript(
625 0 : rTxt, nChg, nScript );
626 :
627 : nFldPos = rTxt.indexOf(
628 0 : CH_TXTATR_BREAKWORD, nFldPos);
629 0 : if ((-1 != nFldPos) && (nFldPos < nChg))
630 0 : nChg = nFldPos;
631 : }
632 0 : if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN |
633 0 : SCRIPTTYPE_COMPLEX) == nRet )
634 0 : break;
635 0 : }
636 : }
637 0 : if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN |
638 0 : SCRIPTTYPE_COMPLEX) == nRet )
639 0 : break;
640 :
641 0 : FOREACHPAM_END()
642 : }
643 0 : if( !nRet )
644 0 : nRet = SvtLanguageOptions::GetScriptTypeOfLanguage( LANGUAGE_SYSTEM );
645 0 : 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: */
|