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