1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <hintids.hxx>
22 #include <editeng/tstpitem.hxx>
23 #include <editeng/lrspitem.hxx>
24 #include <com/sun/star/i18n/ScriptType.hpp>
25 #include <com/sun/star/i18n/XBreakIterator.hpp>
26 #include <txatbase.hxx>
36 #include <rootfrm.hxx>
38 #include <breakit.hxx>
41 #include <scriptinfo.hxx>
42 #include <svl/itemiter.hxx>
43 #include <svl/languageoptions.hxx>
44 #include <charfmt.hxx>
45 #include <numrule.hxx>
48 * hard Formatting (Attributes)
51 // if selection is bigger as max nodes or more than max selections
53 static sal_uInt16
getMaxLookup()
58 bool SwEditShell::GetPaMAttr( SwPaM
* pPaM
, SfxItemSet
& rSet
,
59 const bool bMergeIndentValuesOfNumRule
) const
61 // ??? pPaM can be different from the Cursor ???
62 if( GetCursorCnt() > getMaxLookup() )
64 rSet
.InvalidateAllItems();
68 SfxItemSet
aSet( *rSet
.GetPool(), rSet
.GetRanges() );
69 SfxItemSet
*pSet
= &rSet
;
71 for(SwPaM
& rCurrentPaM
: pPaM
->GetRingContainer())
73 // #i27615# if the cursor is in front of the numbering label
74 // the attributes to get are those from the numbering format.
75 if (rCurrentPaM
.IsInFrontOfLabel())
77 SwTextNode
const*const pTextNd
= sw::GetParaPropsNode(*GetLayout(),
78 rCurrentPaM
.GetPoint()->nNode
);
82 SwNumRule
* pNumRule
= pTextNd
->GetNumRule();
86 int nListLevel
= pTextNd
->GetActualListLevel();
91 if (nListLevel
>= MAXLEVEL
)
92 nListLevel
= MAXLEVEL
- 1;
94 const OUString
& aCharFormatName
=
95 pNumRule
->Get(static_cast<sal_uInt16
>(nListLevel
)).GetCharFormatName();
96 SwCharFormat
* pCharFormat
=
97 GetDoc()->FindCharFormatByName(aCharFormatName
);
100 rSet
.Put(pCharFormat
->GetAttrSet());
107 sal_uLong nSttNd
= rCurrentPaM
.GetMark()->nNode
.GetIndex(),
108 nEndNd
= rCurrentPaM
.GetPoint()->nNode
.GetIndex();
109 sal_Int32 nSttCnt
= rCurrentPaM
.GetMark()->nContent
.GetIndex();
110 sal_Int32 nEndCnt
= rCurrentPaM
.GetPoint()->nContent
.GetIndex();
112 if( nSttNd
> nEndNd
|| ( nSttNd
== nEndNd
&& nSttCnt
> nEndCnt
))
114 std::swap(nSttNd
, nEndNd
);
115 std::swap(nSttCnt
, nEndCnt
);
118 if( nEndNd
- nSttNd
>= getMaxLookup() )
121 rSet
.InvalidateAllItems();
125 // at first node the node enter his values into the GetSet (Initial)
126 // all additional nodes are additional merged to GetSet
127 for( sal_uLong n
= nSttNd
; n
<= nEndNd
; ++n
)
129 SwNode
* pNd
= GetDoc()->GetNodes()[ n
];
130 switch( pNd
->GetNodeType() )
132 case SwNodeType::Text
:
134 const sal_Int32 nStt
= (n
== nSttNd
) ? nSttCnt
: 0;
135 const sal_Int32 nEnd
= (n
== nEndNd
)
137 : pNd
->GetTextNode()->GetText().getLength();
139 static_cast<SwTextNode
*>(pNd
)->GetParaAttr(*pSet
, nStt
, nEnd
,
141 bMergeIndentValuesOfNumRule
,
145 case SwNodeType::Grf
:
146 case SwNodeType::Ole
:
147 static_cast<SwContentNode
*>(pNd
)->GetAttr( *pSet
);
158 if (!GetLayout()->HasMergedParas()
159 || pNd
->GetRedlineMergeFlag() != SwNode::Merge::Hidden
)
161 rSet
.MergeValues( aSet
);
176 bool SwEditShell::GetCurAttr( SfxItemSet
& rSet
,
177 const bool bMergeIndentValuesOfNumRule
) const
179 return GetPaMAttr( GetCursor(), rSet
, bMergeIndentValuesOfNumRule
);
182 void SwEditShell::GetCurParAttr( SfxItemSet
& rSet
) const
184 GetPaMParAttr( GetCursor(), rSet
);
187 bool SwEditShell::GetPaMParAttr( SwPaM
* pPaM
, SfxItemSet
& rSet
) const
189 // number of nodes the function has explored so far
190 sal_uInt16 numberOfLookup
= 0;
192 SfxItemSet
aSet( *rSet
.GetPool(), rSet
.GetRanges() );
193 SfxItemSet
* pSet
= &rSet
;
195 for(SwPaM
& rCurrentPaM
: pPaM
->GetRingContainer())
196 { // for all the point and mark (selections)
198 // get the start and the end node of the current selection
199 sal_uLong nSttNd
= rCurrentPaM
.GetMark()->nNode
.GetIndex(),
200 nEndNd
= rCurrentPaM
.GetPoint()->nNode
.GetIndex();
202 // reverse start and end if there number aren't sorted correctly
203 if( nSttNd
> nEndNd
)
204 std::swap(nSttNd
, nEndNd
);
206 // for all the nodes in the current selection
207 // get the node (paragraph) attributes
208 // and merge them in rSet
209 for( sal_uLong n
= nSttNd
; n
<= nEndNd
; ++n
)
212 SwNode
* pNd
= GetDoc()->GetNodes()[ n
];
214 if (GetLayout()->HasMergedParas()
215 && pNd
->GetRedlineMergeFlag() == SwNode::Merge::Hidden
)
220 if( pNd
->IsTextNode() )
222 // get the node (paragraph) attributes
223 sw::GetAttrMerged(*pSet
, *pNd
->GetTextNode(), GetLayout());
225 if( pSet
!= &rSet
&& aSet
.Count() )
227 rSet
.MergeValues( aSet
);
236 // if the maximum number of node that can be inspected has been reached
237 if (numberOfLookup
>= getMaxLookup())
245 SwTextFormatColl
* SwEditShell::GetCurTextFormatColl( ) const
247 return GetPaMTextFormatColl( GetCursor() );
250 SwTextFormatColl
* SwEditShell::GetPaMTextFormatColl( SwPaM
* pPaM
) const
252 // number of nodes the function have explored so far
253 sal_uInt16 numberOfLookup
= 0;
255 for(SwPaM
& rCurrentPaM
: pPaM
->GetRingContainer())
256 { // for all the point and mark (selections)
258 // get the start and the end node of the current selection
259 sal_uLong nSttNd
= rCurrentPaM
.GetMark()->nNode
.GetIndex(),
260 nEndNd
= rCurrentPaM
.GetPoint()->nNode
.GetIndex();
262 // reverse start and end if they aren't sorted correctly
263 if( nSttNd
> nEndNd
)
264 std::swap(nSttNd
, nEndNd
);
266 // for all the nodes in the current Point and Mark
267 for( sal_uLong n
= nSttNd
; n
<= nEndNd
; ++n
)
270 SwNode
* pNd
= GetDoc()->GetNodes()[ n
];
274 // if the maximum number of node that can be inspected has been reached
275 if (numberOfLookup
>= getMaxLookup())
278 if( pNd
->IsTextNode() )
280 SwTextNode
*const pTextNode(sw::GetParaPropsNode(*GetLayout(), SwNodeIndex(*pNd
)));
281 // if it's a text node get its named paragraph format
282 SwTextFormatColl
*const pFormat
= pTextNode
->GetTextColl();
284 // if the paragraph format exist stop here and return it
285 if( pFormat
!= nullptr )
291 // if none of the selected node contain a named paragraph format
295 std::vector
<std::pair
< const SfxPoolItem
*, std::unique_ptr
<SwPaM
> >> SwEditShell::GetItemWithPaM( sal_uInt16 nWhich
)
297 assert(isCHRATR(nWhich
)); // sw_redlinehide: only thing that works
298 std::vector
<std::pair
< const SfxPoolItem
*, std::unique_ptr
<SwPaM
> >> vItem
;
299 for(SwPaM
& rCurrentPaM
: GetCursor()->GetRingContainer())
300 { // for all the point and mark (selections)
302 // get the start and the end node of the current selection
303 sal_uLong nSttNd
= rCurrentPaM
.Start()->nNode
.GetIndex(),
304 nEndNd
= rCurrentPaM
.End()->nNode
.GetIndex();
305 sal_Int32 nSttCnt
= rCurrentPaM
.Start()->nContent
.GetIndex();
306 sal_Int32 nEndCnt
= rCurrentPaM
.End()->nContent
.GetIndex();
308 SwPaM
* pNewPaM
= nullptr;
309 const SfxPoolItem
* pItem
= nullptr;
311 // for all the nodes in the current selection
312 for( sal_uLong n
= nSttNd
; n
<= nEndNd
; ++n
)
314 SwNode
* pNd
= GetDoc()->GetNodes()[ n
];
315 if( pNd
->IsTextNode() )
317 SwTextNode
* pTextNd
= static_cast< SwTextNode
* >( pNd
);
318 const sal_Int32 nStt
= (n
== nSttNd
) ? nSttCnt
: 0;
319 const sal_Int32 nEnd
= (n
== nEndNd
)
320 ? nEndCnt
: pTextNd
->GetText().getLength();
321 SwTextFrame
const* pFrame
;
322 const SwScriptInfo
*const pScriptInfo
=
323 SwScriptInfo::GetScriptInfo(*pTextNd
, &pFrame
);
324 TextFrameIndex
const iStt(pScriptInfo
325 ? pFrame
->MapModelToView(pTextNd
, nStt
)
326 : TextFrameIndex(-1/*invalid, do not use*/));
327 sal_uInt8 nScript
= pScriptInfo
328 ? pScriptInfo
->ScriptType(iStt
)
329 : css::i18n::ScriptType::WEAK
;
330 nWhich
= GetWhichOfScript( nWhich
, nScript
);
332 // item from attribute set
333 if( pTextNd
->HasSwAttrSet() )
335 pNewPaM
= new SwPaM(*pNd
, nStt
, *pNd
, nEnd
);
336 pItem
= pTextNd
->GetSwAttrSet().GetItem( nWhich
);
337 vItem
.emplace_back( pItem
, std::unique_ptr
<SwPaM
>(pNewPaM
) );
340 if( !pTextNd
->HasHints() )
343 // items with limited range
344 const size_t nSize
= pTextNd
->GetpSwpHints()->Count();
345 for( size_t m
= 0; m
< nSize
; m
++ )
347 const SwTextAttr
* pHt
= pTextNd
->GetpSwpHints()->Get(m
);
348 if( pHt
->Which() == RES_TXTATR_AUTOFMT
||
349 pHt
->Which() == RES_TXTATR_CHARFMT
||
350 pHt
->Which() == RES_TXTATR_INETFMT
)
352 const sal_Int32 nAttrStart
= pHt
->GetStart();
353 const sal_Int32
* pAttrEnd
= pHt
->End();
355 // Ignore items not in selection
356 if( nAttrStart
> nEnd
)
358 if( *pAttrEnd
<= nStt
)
361 nScript
= pScriptInfo
362 ? pScriptInfo
->ScriptType(iStt
)
363 : css::i18n::ScriptType::WEAK
;
364 nWhich
= GetWhichOfScript( nWhich
, nScript
);
365 const SfxItemSet
* pAutoSet
= CharFormat::GetItemSet( pHt
->GetAttr() );
368 SfxItemIter
aItemIter( *pAutoSet
);
369 pItem
= aItemIter
.GetCurItem();
372 if( pItem
->Which() == nWhich
)
374 sal_Int32 nStart
= 0, nStop
= 0;
375 if( nAttrStart
< nStt
) // Attribute starts before selection
379 if( *pAttrEnd
> nEnd
) // Attribute ends after selection
383 pNewPaM
= new SwPaM(*pNd
, nStart
, *pNd
, nStop
);
384 vItem
.emplace_back( pItem
, std::unique_ptr
<SwPaM
>(pNewPaM
) );
387 pItem
= aItemIter
.NextItem();
390 if( !pItem
&& !pTextNd
->HasSwAttrSet() )
392 pNewPaM
= new SwPaM(*pNd
, nStt
, *pNd
, nEnd
);
393 pItem
= pAutoSet
->GetPool()->GetPoolDefaultItem( nWhich
);
394 vItem
.emplace_back( pItem
, std::unique_ptr
<SwPaM
>(pNewPaM
) );
405 bool SwEditShell::GetCurFootnote( SwFormatFootnote
* pFillFootnote
)
407 // The cursor must be positioned on the current footnotes anchor:
408 SwPaM
* pCursor
= GetCursor();
409 SwTextNode
* pTextNd
= pCursor
->GetNode().GetTextNode();
413 SwTextAttr
*const pFootnote
= pTextNd
->GetTextAttrForCharAt(
414 pCursor
->GetPoint()->nContent
.GetIndex(), RES_TXTATR_FTN
);
415 if( pFootnote
&& pFillFootnote
)
417 // Transfer data from the attribute
418 const SwFormatFootnote
&rFootnote
= static_cast<SwTextFootnote
*>(pFootnote
)->GetFootnote();
419 pFillFootnote
->SetNumber( rFootnote
);
420 pFillFootnote
->SetEndNote( rFootnote
.IsEndNote() );
422 return nullptr != pFootnote
;
425 bool SwEditShell::SetCurFootnote( const SwFormatFootnote
& rFillFootnote
)
430 for(const SwPaM
& rCursor
: GetCursor()->GetRingContainer())
433 mxDoc
->SetCurFootnote(rCursor
, rFillFootnote
.GetNumStr(), rFillFootnote
.IsEndNote());
441 bool SwEditShell::HasFootnotes( bool bEndNotes
) const
443 const SwFootnoteIdxs
&rIdxs
= mxDoc
->GetFootnoteIdxs();
444 for ( auto pIdx
: rIdxs
)
446 const SwFormatFootnote
&rFootnote
= pIdx
->GetFootnote();
447 if ( bEndNotes
== rFootnote
.IsEndNote() )
453 /// Give a List of all footnotes and their beginning texts
454 size_t SwEditShell::GetSeqFootnoteList( SwSeqFieldList
& rList
, bool bEndNotes
)
458 IDocumentRedlineAccess
& rIDRA(mxDoc
->getIDocumentRedlineAccess());
460 const size_t nFootnoteCnt
= mxDoc
->GetFootnoteIdxs().size();
461 SwTextFootnote
* pTextFootnote
;
462 for( size_t n
= 0; n
< nFootnoteCnt
; ++n
)
464 pTextFootnote
= mxDoc
->GetFootnoteIdxs()[ n
];
465 const SwFormatFootnote
& rFootnote
= pTextFootnote
->GetFootnote();
466 if ( rFootnote
.IsEndNote() != bEndNotes
)
469 SwNodeIndex
* pIdx
= pTextFootnote
->GetStartNode();
472 SwNodeIndex
aIdx( *pIdx
, 1 );
473 SwTextNode
* pTextNd
= aIdx
.GetNode().GetTextNode();
475 pTextNd
= static_cast<SwTextNode
*>(mxDoc
->GetNodes().GoNext( &aIdx
));
479 if (GetLayout()->IsHideRedlines()
480 && sw::IsFootnoteDeleted(rIDRA
, *pTextFootnote
))
485 OUString
sText(rFootnote
.GetViewNumStr(*mxDoc
, GetLayout()));
486 if( !sText
.isEmpty() )
488 sText
+= pTextNd
->GetExpandText(GetLayout());
490 SeqFieldLstElem
aNew( sText
, pTextFootnote
->GetSeqRefNo() );
491 while( rList
.InsertSort( aNew
) )
492 aNew
.sDlgEntry
+= " ";
497 return rList
.Count();
500 /// Adjust left margin via object bar (similar to adjustment of numerations).
501 bool SwEditShell::IsMoveLeftMargin( bool bRight
, bool bModulus
) const
505 const SvxTabStopItem
& rTabItem
= GetDoc()->GetDefault( RES_PARATR_TABSTOP
);
506 sal_uInt16 nDefDist
= static_cast<sal_uInt16
>(rTabItem
.Count() ? rTabItem
[0].GetTabPos() : 1134);
510 for(SwPaM
& rPaM
: GetCursor()->GetRingContainer())
512 sal_uLong nSttNd
= rPaM
.GetMark()->nNode
.GetIndex(),
513 nEndNd
= rPaM
.GetPoint()->nNode
.GetIndex();
515 if( nSttNd
> nEndNd
)
516 std::swap(nSttNd
, nEndNd
);
519 for( sal_uLong n
= nSttNd
; bRet
&& n
<= nEndNd
; ++n
)
521 pCNd
= GetDoc()->GetNodes()[ n
]->GetTextNode();
522 if( nullptr != pCNd
)
524 pCNd
= sw::GetParaPropsNode(*GetLayout(), *pCNd
);
525 const SvxLRSpaceItem
& rLS
= static_cast<const SvxLRSpaceItem
&>(
526 pCNd
->GetAttr( RES_LR_SPACE
));
529 tools::Long nNext
= rLS
.GetTextLeft() + nDefDist
;
531 nNext
= ( nNext
/ nDefDist
) * nDefDist
;
532 SwFrame
* pFrame
= pCNd
->getLayoutFrame( GetLayout() );
535 const sal_uInt16 nFrameWidth
= static_cast<sal_uInt16
>( pFrame
->IsVertical() ?
536 pFrame
->getFrameArea().Height() :
537 pFrame
->getFrameArea().Width() );
538 bRet
= nFrameWidth
> ( nNext
+ MM50
);
553 void SwEditShell::MoveLeftMargin( bool bRight
, bool bModulus
)
556 StartUndo( SwUndoId::START
);
558 SwPaM
* pCursor
= GetCursor();
559 if( pCursor
->GetNext() != pCursor
) // Multiple selection ?
561 SwPamRanges
aRangeArr( *pCursor
);
562 SwPaM
aPam( *pCursor
->GetPoint() );
563 for( size_t n
= 0; n
< aRangeArr
.Count(); ++n
)
564 GetDoc()->MoveLeftMargin( aRangeArr
.SetPam( n
, aPam
),
565 bRight
, bModulus
, GetLayout() );
568 GetDoc()->MoveLeftMargin( *pCursor
, bRight
, bModulus
, GetLayout() );
570 EndUndo( SwUndoId::END
);
574 static SvtScriptType
lcl_SetScriptFlags( sal_uInt16 nType
)
578 case css::i18n::ScriptType::LATIN
:
579 return SvtScriptType::LATIN
;
580 case css::i18n::ScriptType::ASIAN
:
581 return SvtScriptType::ASIAN
;
582 case css::i18n::ScriptType::COMPLEX
:
583 return SvtScriptType::COMPLEX
;
585 return SvtScriptType::NONE
;
589 static bool lcl_IsNoEndTextAttrAtPos(SwRootFrame
const& rLayout
,
590 const SwTextNode
& rTNd
, sal_Int32
const nPos
,
591 SvtScriptType
&rScrpt
, bool bInSelection
, bool bNum
)
596 // consider numbering
600 SwTextNode
const*const pPropsNode(sw::GetParaPropsNode(rLayout
, rTNd
));
601 if (pPropsNode
->IsInList())
603 OSL_ENSURE( pPropsNode
->GetNumRule(),
604 "<lcl_IsNoEndTextAttrAtPos(..)> - no list style found at text node. Serious defect." );
605 const SwNumRule
* pNumRule
= pPropsNode
->GetNumRule();
608 int nListLevel
= pPropsNode
->GetActualListLevel();
613 if (nListLevel
>= MAXLEVEL
)
614 nListLevel
= MAXLEVEL
- 1;
616 const SwNumFormat
&rNumFormat
= pNumRule
->Get( static_cast<sal_uInt16
>(nListLevel
) );
617 if( SVX_NUM_BITMAP
!= rNumFormat
.GetNumberingType() )
619 if ( SVX_NUM_CHAR_SPECIAL
== rNumFormat
.GetNumberingType() )
621 sal_UCS4 cBullet
= rNumFormat
.GetBulletChar();
622 sExp
= OUString(&cBullet
, 1);
625 sExp
= pPropsNode
->GetNumString(true, MAXLEVEL
, &rLayout
);
632 if (nPos
< rTNd
.GetText().getLength() && CH_TXTATR_BREAKWORD
== rTNd
.GetText()[nPos
])
634 const SwTextAttr
* const pAttr
= rTNd
.GetTextAttrForCharAt( nPos
);
637 bRet
= true; // all other than fields can be
638 // defined as weak-script ?
639 if ( RES_TXTATR_FIELD
== pAttr
->Which() )
641 const SwField
* const pField
= pAttr
->GetFormatField().GetField();
644 sExp
+= pField
->ExpandField(true, &rLayout
);
650 const sal_Int32 nEnd
= sExp
.getLength();
656 for( sal_Int32 n
= 0; n
< nEnd
;
657 n
= g_pBreakIt
->GetBreakIter()->endOfScript( sExp
, n
, nScript
))
659 nScript
= g_pBreakIt
->GetBreakIter()->getScriptType( sExp
, n
);
660 rScrpt
|= lcl_SetScriptFlags( nScript
);
664 rScrpt
|= lcl_SetScriptFlags( g_pBreakIt
->GetBreakIter()->
665 getScriptType( sExp
, nEnd
-1 ));
671 /// returns the script type of the selection
672 SvtScriptType
SwEditShell::GetScriptType() const
674 SvtScriptType nRet
= SvtScriptType::NONE
;
677 for(SwPaM
& rPaM
: GetCursor()->GetRingContainer())
679 const SwPosition
*pStt
= rPaM
.Start(),
680 *pEnd
= pStt
== rPaM
.GetMark()
683 if( pStt
== pEnd
|| *pStt
== *pEnd
)
685 const SwTextNode
* pTNd
= pStt
->nNode
.GetNode().GetTextNode();
688 // try to get SwScriptInfo
689 SwTextFrame
const* pFrame
;
690 const SwScriptInfo
*const pScriptInfo
=
691 SwScriptInfo::GetScriptInfo(*pTNd
, &pFrame
);
693 sal_Int32 nPos
= pStt
->nContent
.GetIndex();
694 //Task 90448: we need the scripttype of the previous
695 // position, if no selection exist!
698 SwIndex
aIdx( pStt
->nContent
);
699 if( pTNd
->GoPrevious( &aIdx
, CRSR_SKIP_CHARS
) )
700 nPos
= aIdx
.GetIndex();
705 if (!pTNd
->GetText().isEmpty())
707 nScript
= pScriptInfo
708 ? pScriptInfo
->ScriptType(pFrame
->MapModelToView(pTNd
, nPos
))
709 : g_pBreakIt
->GetBreakIter()->getScriptType( pTNd
->GetText(), nPos
);
712 nScript
= SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() );
714 if (!lcl_IsNoEndTextAttrAtPos(*GetLayout(), *pTNd
, nPos
, nRet
, false, false))
715 nRet
|= lcl_SetScriptFlags( nScript
);
720 sal_uLong nEndIdx
= pEnd
->nNode
.GetIndex();
721 SwNodeIndex
aIdx( pStt
->nNode
);
722 for( ; aIdx
.GetIndex() <= nEndIdx
; ++aIdx
)
723 if( aIdx
.GetNode().IsTextNode() )
725 const SwTextNode
* pTNd
= aIdx
.GetNode().GetTextNode();
726 const OUString
& rText
= pTNd
->GetText();
728 // try to get SwScriptInfo
729 SwTextFrame
const* pFrame
;
730 const SwScriptInfo
*const pScriptInfo
=
731 SwScriptInfo::GetScriptInfo(*pTNd
, &pFrame
);
733 sal_Int32 nChg
= aIdx
== pStt
->nNode
734 ? pStt
->nContent
.GetIndex()
736 sal_Int32 nEndPos
= aIdx
== nEndIdx
737 ? pEnd
->nContent
.GetIndex()
740 OSL_ENSURE( nEndPos
<= rText
.getLength(),
741 "Index outside the range - endless loop!" );
742 if (nEndPos
> rText
.getLength())
743 nEndPos
= rText
.getLength();
745 bool const isUntilEnd(pScriptInfo
746 ? pFrame
->MapViewToModelPos(TextFrameIndex(pFrame
->GetText().getLength())) <= *pEnd
747 : rText
.getLength() == nEndPos
);
749 while( nChg
< nEndPos
)
751 TextFrameIndex
iChg(pScriptInfo
752 ? pFrame
->MapModelToView(pTNd
, nChg
)
753 : TextFrameIndex(-1/*invalid, do not use*/));
754 nScript
= pScriptInfo
?
755 pScriptInfo
->ScriptType( iChg
) :
756 g_pBreakIt
->GetBreakIter()->getScriptType(
759 if (!lcl_IsNoEndTextAttrAtPos(*GetLayout(), *pTNd
, nChg
, nRet
, true,
760 TextFrameIndex(0) == iChg
&& isUntilEnd
))
762 nRet
|= lcl_SetScriptFlags( nScript
);
765 if( (SvtScriptType::LATIN
| SvtScriptType::ASIAN
|
766 SvtScriptType::COMPLEX
) == nRet
)
769 sal_Int32 nFieldPos
= nChg
+1;
773 iChg
= pScriptInfo
->NextScriptChg(iChg
);
774 if (iChg
== TextFrameIndex(COMPLETE_STRING
))
780 std::pair
<SwTextNode
*, sal_Int32
> const tmp(
781 pFrame
->MapViewToModel(iChg
));
782 nChg
= (tmp
.first
== pTNd
)
789 nChg
= g_pBreakIt
->GetBreakIter()->endOfScript(
790 rText
, nChg
, nScript
);
793 nFieldPos
= rText
.indexOf(
794 CH_TXTATR_BREAKWORD
, nFieldPos
);
795 if ((-1 != nFieldPos
) && (nFieldPos
< nChg
))
798 if( (SvtScriptType::LATIN
| SvtScriptType::ASIAN
|
799 SvtScriptType::COMPLEX
) == nRet
)
803 if( (SvtScriptType::LATIN
| SvtScriptType::ASIAN
|
804 SvtScriptType::COMPLEX
) == nRet
)
809 if( nRet
== SvtScriptType::NONE
)
810 nRet
= SvtLanguageOptions::GetScriptTypeOfLanguage( LANGUAGE_SYSTEM
);
814 LanguageType
SwEditShell::GetCurLang() const
816 const SwPaM
* pCursor
= GetCursor();
817 const SwPosition
& rPos
= *pCursor
->GetPoint();
818 const SwTextNode
* pTNd
= rPos
.nNode
.GetNode().GetTextNode();
822 //JP 24.9.2001: if exist no selection, then get the language before
823 // the current character!
824 sal_Int32 nPos
= rPos
.nContent
.GetIndex();
825 if( nPos
&& !pCursor
->HasMark() )
827 nLang
= pTNd
->GetLang( nPos
);
830 nLang
= LANGUAGE_DONTKNOW
;
834 sal_uInt16
SwEditShell::GetScalingOfSelectedText() const
836 const SwPaM
* pCursor
= GetCursor();
837 const SwPosition
* pStt
= pCursor
->Start();
838 const SwTextNode
* pTNd
= pStt
->nNode
.GetNode().GetTextNode();
839 OSL_ENSURE( pTNd
, "no textnode available" );
841 sal_uInt16 nScaleWidth
;
844 SwTextFrame
*const pFrame(static_cast<SwTextFrame
*>(
845 pTNd
->getLayoutFrame(GetLayout(), pStt
)));
846 assert(pFrame
); // shell cursor must be positioned in node with frame
847 TextFrameIndex
const nStart(pFrame
->MapModelToViewPos(*pStt
));
848 TextFrameIndex
const nEnd(
849 sw::FrameContainsNode(*pFrame
, pCursor
->End()->nNode
.GetIndex())
850 ? pFrame
->MapModelToViewPos(*pCursor
->End())
851 : TextFrameIndex(pFrame
->GetText().getLength()));
852 nScaleWidth
= pFrame
->GetScalingOfSelectedText(nStart
, nEnd
);
855 nScaleWidth
= 100; // default are no scaling -> 100%
859 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */