LibreOffice Module sw (master)  1
edattr.cxx
Go to the documentation of this file.
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 <memory>
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 <osl/diagnose.h>
27 #include <txatbase.hxx>
28 #include <txtftn.hxx>
29 #include <fmtftn.hxx>
30 #include <editsh.hxx>
31 #include <edimp.hxx>
32 #include <doc.hxx>
33 #include <swundo.hxx>
34 #include <ndtxt.hxx>
35 #include <ftnidx.hxx>
36 #include <expfld.hxx>
37 #include <rootfrm.hxx>
38 #include <cntfrm.hxx>
39 #include <breakit.hxx>
40 #include <fmtfld.hxx>
41 #include <txtfrm.hxx>
42 #include <scriptinfo.hxx>
43 #include <svl/itemiter.hxx>
44 #include <svl/languageoptions.hxx>
45 #include <charfmt.hxx>
46 #include <numrule.hxx>
47 
48 /*
49  * hard Formatting (Attributes)
50  */
51 
52 // if selection is bigger as max nodes or more than max selections
53 // => no attributes
54 static sal_uInt16 getMaxLookup()
55 {
56  return 10000;
57 }
58 
60  const bool bMergeIndentValuesOfNumRule ) const
61 {
62  // ??? pPaM can be different from the Cursor ???
63  if( GetCursorCnt() > getMaxLookup() )
64  {
65  rSet.InvalidateAllItems();
66  return false;
67  }
68 
69  SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() );
70  SfxItemSet *pSet = &rSet;
71 
72  for(SwPaM& rCurrentPaM : pPaM->GetRingContainer())
73  {
74  // #i27615# if the cursor is in front of the numbering label
75  // the attributes to get are those from the numbering format.
76  if (rCurrentPaM.IsInFrontOfLabel())
77  {
78  SwTextNode const*const pTextNd = sw::GetParaPropsNode(*GetLayout(),
79  rCurrentPaM.GetPoint()->nNode);
80 
81  if (pTextNd)
82  {
83  SwNumRule * pNumRule = pTextNd->GetNumRule();
84 
85  if (pNumRule)
86  {
87  int nListLevel = pTextNd->GetActualListLevel();
88 
89  if (nListLevel < 0)
90  nListLevel = 0;
91 
92  if (nListLevel >= MAXLEVEL)
93  nListLevel = MAXLEVEL - 1;
94 
95  const OUString & aCharFormatName =
96  pNumRule->Get(o3tl::narrowing<sal_uInt16>(nListLevel)).GetCharFormatName();
97  SwCharFormat * pCharFormat =
98  GetDoc()->FindCharFormatByName(aCharFormatName);
99 
100  if (pCharFormat)
101  rSet.Put(pCharFormat->GetAttrSet());
102  }
103  }
104 
105  continue;
106  }
107 
108  SwNodeOffset nSttNd = rCurrentPaM.Start()->nNode.GetIndex(),
109  nEndNd = rCurrentPaM.End()->nNode.GetIndex();
110  sal_Int32 nSttCnt = rCurrentPaM.Start()->nContent.GetIndex();
111  sal_Int32 nEndCnt = rCurrentPaM.End()->nContent.GetIndex();
112 
113  if( sal_Int32(nEndNd - nSttNd) >= getMaxLookup() )
114  {
115  rSet.ClearItem();
116  rSet.InvalidateAllItems();
117  return false;
118  }
119 
120  // at first node the node enter his values into the GetSet (Initial)
121  // all additional nodes are additional merged to GetSet
122  for( SwNodeOffset n = nSttNd; n <= nEndNd; ++n )
123  {
124  SwNode* pNd = GetDoc()->GetNodes()[ n ];
125  switch( pNd->GetNodeType() )
126  {
127  case SwNodeType::Text:
128  {
129  const sal_Int32 nStt = (n == nSttNd) ? nSttCnt : 0;
130  const sal_Int32 nEnd = (n == nEndNd)
131  ? nEndCnt
132  : pNd->GetTextNode()->GetText().getLength();
133 
134  static_cast<SwTextNode*>(pNd)->GetParaAttr(*pSet, nStt, nEnd,
135  false, true,
136  bMergeIndentValuesOfNumRule,
137  GetLayout());
138  }
139  break;
140  case SwNodeType::Grf:
141  case SwNodeType::Ole:
142  static_cast<SwContentNode*>(pNd)->GetAttr( *pSet );
143  break;
144 
145  default:
146  pNd = nullptr;
147  }
148 
149  if( pNd )
150  {
151  if( pSet != &rSet )
152  {
153  if (!GetLayout()->HasMergedParas()
155  {
156  rSet.MergeValues( aSet );
157  }
158  }
159 
160  if( aSet.Count() )
161  aSet.ClearItem();
162  }
163  pSet = &aSet;
164  }
165 
166  }
167 
168  return true;
169 }
170 
172  const bool bMergeIndentValuesOfNumRule ) const
173 {
174  return GetPaMAttr( GetCursor(), rSet, bMergeIndentValuesOfNumRule );
175 }
176 
178 {
179  GetPaMParAttr( GetCursor(), rSet );
180 }
181 
182 void SwEditShell::GetPaMParAttr( SwPaM* pPaM, SfxItemSet& rSet ) const
183 {
184  // number of nodes the function has explored so far
185  sal_uInt16 numberOfLookup = 0;
186 
187  SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() );
188  SfxItemSet* pSet = &rSet;
189 
190  for(SwPaM& rCurrentPaM : pPaM->GetRingContainer())
191  { // for all the point and mark (selections)
192 
193  // get the start and the end node of the current selection
194  SwNodeOffset nSttNd = rCurrentPaM.GetMark()->nNode.GetIndex(),
195  nEndNd = rCurrentPaM.GetPoint()->nNode.GetIndex();
196 
197  // reverse start and end if there number aren't sorted correctly
198  if( nSttNd > nEndNd )
199  std::swap(nSttNd, nEndNd);
200 
201  // for all the nodes in the current selection
202  // get the node (paragraph) attributes
203  // and merge them in rSet
204  for( SwNodeOffset n = nSttNd; n <= nEndNd; ++n )
205  {
206  // get the node
207  SwNode* pNd = GetDoc()->GetNodes()[ n ];
208 
209  if (GetLayout()->HasMergedParas()
211  {
212  continue;
213  }
214 
215  if( pNd->IsTextNode() )
216  {
217  // get the node (paragraph) attributes
218  sw::GetAttrMerged(*pSet, *pNd->GetTextNode(), GetLayout());
219 
220  if( pSet != &rSet && aSet.Count() )
221  {
222  rSet.MergeValues( aSet );
223  aSet.ClearItem();
224  }
225 
226  pSet = &aSet;
227  }
228 
229  ++numberOfLookup;
230 
231  // if the maximum number of node that can be inspected has been reached
232  if (numberOfLookup >= getMaxLookup())
233  return;
234  }
235  }
236 }
237 
239 {
240  return GetPaMTextFormatColl( GetCursor() );
241 }
242 
244 {
245  // number of nodes the function have explored so far
246  sal_uInt16 numberOfLookup = 0;
247 
248  for(SwPaM& rCurrentPaM : pPaM->GetRingContainer())
249  { // for all the point and mark (selections)
250 
251  // get the start and the end node of the current selection
252  SwNodeOffset nSttNd = rCurrentPaM.Start()->nNode.GetIndex(),
253  nEndNd = rCurrentPaM.End()->nNode.GetIndex();
254 
255  // for all the nodes in the current Point and Mark
256  for( SwNodeOffset n = nSttNd; n <= nEndNd; ++n )
257  {
258  // get the node
259  SwNode* pNd = GetDoc()->GetNodes()[ n ];
260 
261  ++numberOfLookup;
262 
263  // if the maximum number of node that can be inspected has been reached
264  if (numberOfLookup >= getMaxLookup())
265  return nullptr;
266 
267  if( pNd->IsTextNode() )
268  {
269  SwTextNode *const pTextNode(sw::GetParaPropsNode(*GetLayout(), SwNodeIndex(*pNd)));
270  // if it's a text node get its named paragraph format
271  SwTextFormatColl *const pFormat = pTextNode->GetTextColl();
272 
273  // if the paragraph format exist stop here and return it
274  if( pFormat != nullptr )
275  return pFormat;
276  }
277  }
278  }
279 
280  // if none of the selected node contain a named paragraph format
281  return nullptr;
282 }
283 
284 std::vector<std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >> SwEditShell::GetItemWithPaM( sal_uInt16 nWhich )
285 {
286  assert(isCHRATR(nWhich)); // sw_redlinehide: only thing that works
287  std::vector<std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >> vItem;
288  for(SwPaM& rCurrentPaM : GetCursor()->GetRingContainer())
289  { // for all the point and mark (selections)
290 
291  // get the start and the end node of the current selection
292  SwNodeOffset nSttNd = rCurrentPaM.Start()->nNode.GetIndex(),
293  nEndNd = rCurrentPaM.End()->nNode.GetIndex();
294  sal_Int32 nSttCnt = rCurrentPaM.Start()->nContent.GetIndex();
295  sal_Int32 nEndCnt = rCurrentPaM.End()->nContent.GetIndex();
296 
297  SwPaM* pNewPaM = nullptr;
298  const SfxPoolItem* pItem = nullptr;
299 
300  // for all the nodes in the current selection
301  for( SwNodeOffset n = nSttNd; n <= nEndNd; ++n )
302  {
303  SwNode* pNd = GetDoc()->GetNodes()[ n ];
304  if( pNd->IsTextNode() )
305  {
306  SwTextNode* pTextNd = static_cast< SwTextNode* >( pNd );
307  const sal_Int32 nStt = (n == nSttNd) ? nSttCnt : 0;
308  const sal_Int32 nEnd = (n == nEndNd)
309  ? nEndCnt : pTextNd->GetText().getLength();
310  SwTextFrame const* pFrame;
311  const SwScriptInfo *const pScriptInfo =
312  SwScriptInfo::GetScriptInfo(*pTextNd, &pFrame);
313  TextFrameIndex const iStt(pScriptInfo
314  ? pFrame->MapModelToView(pTextNd, nStt)
315  : TextFrameIndex(-1/*invalid, do not use*/));
316  sal_uInt8 nScript = pScriptInfo
317  ? pScriptInfo->ScriptType(iStt)
318  : css::i18n::ScriptType::WEAK;
319  nWhich = GetWhichOfScript( nWhich, nScript );
320 
321  // item from attribute set
322  if( pTextNd->HasSwAttrSet() )
323  {
324  pNewPaM = new SwPaM(*pNd, nStt, *pNd, nEnd);
325  pItem = pTextNd->GetSwAttrSet().GetItem( nWhich );
326  vItem.emplace_back( pItem, std::unique_ptr<SwPaM>(pNewPaM) );
327  }
328 
329  if( !pTextNd->HasHints() )
330  continue;
331 
332  // items with limited range
333  const size_t nSize = pTextNd->GetpSwpHints()->Count();
334  for( size_t m = 0; m < nSize; m++ )
335  {
336  const SwTextAttr* pHt = pTextNd->GetpSwpHints()->Get(m);
337  if( pHt->Which() == RES_TXTATR_AUTOFMT ||
338  pHt->Which() == RES_TXTATR_CHARFMT ||
339  pHt->Which() == RES_TXTATR_INETFMT )
340  {
341  const sal_Int32 nAttrStart = pHt->GetStart();
342  const sal_Int32* pAttrEnd = pHt->End();
343 
344  // Ignore items not in selection
345  if( nAttrStart > nEnd )
346  break;
347  if( *pAttrEnd <= nStt )
348  continue;
349 
350  nScript = pScriptInfo
351  ? pScriptInfo->ScriptType(iStt)
352  : css::i18n::ScriptType::WEAK;
353  nWhich = GetWhichOfScript( nWhich, nScript );
354  const SfxItemSet* pAutoSet = CharFormat::GetItemSet( pHt->GetAttr() );
355  if( pAutoSet )
356  {
357  SfxItemIter aItemIter( *pAutoSet );
358  pItem = aItemIter.GetCurItem();
359  while( pItem )
360  {
361  if( pItem->Which() == nWhich )
362  {
363  sal_Int32 nStart = 0, nStop = 0;
364  if( nAttrStart < nStt ) // Attribute starts before selection
365  nStart = nStt;
366  else
367  nStart = nAttrStart;
368  if( *pAttrEnd > nEnd ) // Attribute ends after selection
369  nStop = nEnd;
370  else
371  nStop = *pAttrEnd;
372  pNewPaM = new SwPaM(*pNd, nStart, *pNd, nStop);
373  vItem.emplace_back( pItem, std::unique_ptr<SwPaM>(pNewPaM) );
374  break;
375  }
376  pItem = aItemIter.NextItem();
377  }
378  // default item
379  if( !pItem && !pTextNd->HasSwAttrSet() )
380  {
381  pNewPaM = new SwPaM(*pNd, nStt, *pNd, nEnd);
382  pItem = pAutoSet->GetPool()->GetPoolDefaultItem( nWhich );
383  vItem.emplace_back( pItem, std::unique_ptr<SwPaM>(pNewPaM) );
384  }
385  }
386  }
387  }
388  }
389  }
390  }
391  return vItem;
392 }
393 
395 {
396  // The cursor must be positioned on the current footnotes anchor:
397  SwPaM* pCursor = GetCursor();
398  SwTextNode* pTextNd = pCursor->GetNode().GetTextNode();
399  if( !pTextNd )
400  return false;
401 
402  SwTextAttr *const pFootnote = pTextNd->GetTextAttrForCharAt(
403  pCursor->GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN);
404  if( pFootnote && pFillFootnote )
405  {
406  // Transfer data from the attribute
407  const SwFormatFootnote &rFootnote = static_cast<SwTextFootnote*>(pFootnote)->GetFootnote();
408  pFillFootnote->SetNumber( rFootnote );
409  pFillFootnote->SetEndNote( rFootnote.IsEndNote() );
410  }
411  return nullptr != pFootnote;
412 }
413 
414 bool SwEditShell::SetCurFootnote( const SwFormatFootnote& rFillFootnote )
415 {
416  bool bChgd = false;
417  StartAllAction();
418 
419  for(const SwPaM& rCursor : GetCursor()->GetRingContainer())
420  {
421  bChgd |=
422  mxDoc->SetCurFootnote(rCursor, rFillFootnote.GetNumStr(), rFillFootnote.IsEndNote());
423 
424  }
425 
426  EndAllAction();
427  return bChgd;
428 }
429 
430 bool SwEditShell::HasFootnotes( bool bEndNotes ) const
431 {
432  const SwFootnoteIdxs &rIdxs = mxDoc->GetFootnoteIdxs();
433  for ( auto pIdx : rIdxs )
434  {
435  const SwFormatFootnote &rFootnote = pIdx->GetFootnote();
436  if ( bEndNotes == rFootnote.IsEndNote() )
437  return true;
438  }
439  return false;
440 }
441 
443 size_t SwEditShell::GetSeqFootnoteList( SwSeqFieldList& rList, bool bEndNotes )
444 {
445  rList.Clear();
446 
447  IDocumentRedlineAccess & rIDRA(mxDoc->getIDocumentRedlineAccess());
448 
449  const size_t nFootnoteCnt = mxDoc->GetFootnoteIdxs().size();
450  SwTextFootnote* pTextFootnote;
451  for( size_t n = 0; n < nFootnoteCnt; ++n )
452  {
453  pTextFootnote = mxDoc->GetFootnoteIdxs()[ n ];
454  const SwFormatFootnote& rFootnote = pTextFootnote->GetFootnote();
455  if ( rFootnote.IsEndNote() != bEndNotes )
456  continue;
457 
458  SwNodeIndex* pIdx = pTextFootnote->GetStartNode();
459  if( pIdx )
460  {
461  SwNodeIndex aIdx( *pIdx, 1 );
462  SwTextNode* pTextNd = aIdx.GetNode().GetTextNode();
463  if( !pTextNd )
464  pTextNd = static_cast<SwTextNode*>(mxDoc->GetNodes().GoNext( &aIdx ));
465 
466  if( pTextNd )
467  {
468  if (GetLayout()->IsHideRedlines()
469  && sw::IsFootnoteDeleted(rIDRA, *pTextFootnote))
470  {
471  continue;
472  }
473 
474  OUString sText(rFootnote.GetViewNumStr(*mxDoc, GetLayout()));
475  if( !sText.isEmpty() )
476  sText += " ";
477  sText += pTextNd->GetExpandText(GetLayout());
478 
479  SeqFieldLstElem aNew( sText, pTextFootnote->GetSeqRefNo() );
480  while( rList.InsertSort( aNew ) )
481  aNew.sDlgEntry += " ";
482  }
483  }
484  }
485 
486  return rList.Count();
487 }
488 
490 bool SwEditShell::IsMoveLeftMargin( bool bRight, bool bModulus ) const
491 {
492  bool bRet = true;
493 
494  constexpr sal_uInt16 constTwips_2cm = o3tl::toTwips(20, o3tl::Length::mm);
496 
497  const SvxTabStopItem& rTabItem = GetDoc()->GetDefault( RES_PARATR_TABSTOP );
498  sal_uInt16 nDefDist = o3tl::narrowing<sal_uInt16>(
499  rTabItem.Count() ? rTabItem[0].GetTabPos() : constTwips_2cm);
500 
501  if( !nDefDist )
502  return false;
503 
504  for(SwPaM& rPaM : GetCursor()->GetRingContainer())
505  {
506  SwNodeOffset nSttNd = rPaM.Start()->nNode.GetIndex(),
507  nEndNd = rPaM.End()->nNode.GetIndex();
508 
509  SwContentNode* pCNd;
510  for( SwNodeOffset n = nSttNd; bRet && n <= nEndNd; ++n )
511  {
512  pCNd = GetDoc()->GetNodes()[ n ]->GetTextNode();
513  if( nullptr != pCNd )
514  {
515  pCNd = sw::GetParaPropsNode(*GetLayout(), *pCNd);
516  const SvxLRSpaceItem& rLS = pCNd->GetAttr( RES_LR_SPACE );
517  if( bRight )
518  {
519  tools::Long nNext = rLS.GetTextLeft() + nDefDist;
520  if( bModulus )
521  nNext = ( nNext / nDefDist ) * nDefDist;
522  SwFrame* pFrame = pCNd->getLayoutFrame( GetLayout() );
523  if ( pFrame )
524  {
525  const SwTwips nFrameWidth = pFrame->IsVertical() ?
526  pFrame->getFrameArea().Height() :
527  pFrame->getFrameArea().Width();
528  bRet = nFrameWidth > (nNext + constTwips_5mm);
529  }
530  else
531  bRet = false;
532  }
533  }
534  }
535 
536  if( !bRet )
537  break;
538 
539  }
540  return bRet;
541 }
542 
543 void SwEditShell::MoveLeftMargin( bool bRight, bool bModulus )
544 {
545  StartAllAction();
547 
548  SwPaM* pCursor = GetCursor();
549  if( pCursor->GetNext() != pCursor ) // Multiple selection ?
550  {
551  SwPamRanges aRangeArr( *pCursor );
552  SwPaM aPam( *pCursor->GetPoint() );
553  for( size_t n = 0; n < aRangeArr.Count(); ++n )
554  GetDoc()->MoveLeftMargin( aRangeArr.SetPam( n, aPam ),
555  bRight, bModulus, GetLayout() );
556  }
557  else
558  GetDoc()->MoveLeftMargin( *pCursor, bRight, bModulus, GetLayout() );
559 
561  EndAllAction();
562 }
563 
564 static SvtScriptType lcl_SetScriptFlags( sal_uInt16 nType )
565 {
566  switch( nType )
567  {
568  case css::i18n::ScriptType::LATIN:
569  return SvtScriptType::LATIN;
570  case css::i18n::ScriptType::ASIAN:
571  return SvtScriptType::ASIAN;
572  case css::i18n::ScriptType::COMPLEX:
573  return SvtScriptType::COMPLEX;
574  default:
575  return SvtScriptType::NONE;
576  }
577 }
578 
579 static bool lcl_IsNoEndTextAttrAtPos(SwRootFrame const& rLayout,
580  const SwTextNode& rTNd, sal_Int32 const nPos,
581  SvtScriptType &rScrpt, bool bInSelection, bool bNum )
582 {
583  bool bRet = false;
584  OUString sExp;
585 
586  // consider numbering
587  if ( bNum )
588  {
589  bRet = false;
590  SwTextNode const*const pPropsNode(sw::GetParaPropsNode(rLayout, rTNd));
591  if (pPropsNode->IsInList())
592  {
593  OSL_ENSURE( pPropsNode->GetNumRule(),
594  "<lcl_IsNoEndTextAttrAtPos(..)> - no list style found at text node. Serious defect." );
595  const SwNumRule* pNumRule = pPropsNode->GetNumRule();
596  if(pNumRule)
597  {
598  int nListLevel = pPropsNode->GetActualListLevel();
599 
600  if (nListLevel < 0)
601  nListLevel = 0;
602 
603  if (nListLevel >= MAXLEVEL)
604  nListLevel = MAXLEVEL - 1;
605 
606  const SwNumFormat &rNumFormat = pNumRule->Get( o3tl::narrowing<sal_uInt16>(nListLevel) );
607  if( SVX_NUM_BITMAP != rNumFormat.GetNumberingType() )
608  {
609  if ( SVX_NUM_CHAR_SPECIAL == rNumFormat.GetNumberingType() )
610  {
611  sal_UCS4 cBullet = rNumFormat.GetBulletChar();
612  sExp = OUString(&cBullet, 1);
613  }
614  else
615  sExp = pPropsNode->GetNumString(true, MAXLEVEL, &rLayout);
616  }
617  }
618  }
619  }
620 
621  // and fields
622  if (nPos < rTNd.GetText().getLength() && CH_TXTATR_BREAKWORD == rTNd.GetText()[nPos])
623  {
624  const SwTextAttr* const pAttr = rTNd.GetTextAttrForCharAt( nPos );
625  if (pAttr)
626  {
627  bRet = true; // all other than fields can be
628  // defined as weak-script ?
629  if ( RES_TXTATR_FIELD == pAttr->Which() )
630  {
631  const SwField* const pField = pAttr->GetFormatField().GetField();
632  if (pField)
633  {
634  sExp += pField->ExpandField(true, &rLayout);
635  }
636  }
637  }
638  }
639 
640  const sal_Int32 nEnd = sExp.getLength();
641  if ( nEnd )
642  {
643  if( bInSelection )
644  {
645  sal_uInt16 nScript;
646  for( sal_Int32 n = 0; n < nEnd;
647  n = g_pBreakIt->GetBreakIter()->endOfScript( sExp, n, nScript ))
648  {
649  nScript = g_pBreakIt->GetBreakIter()->getScriptType( sExp, n );
650  rScrpt |= lcl_SetScriptFlags( nScript );
651  }
652  }
653  else
655  getScriptType( sExp, nEnd-1 ));
656  }
657 
658  return bRet;
659 }
660 
663 {
664  SvtScriptType nRet = SvtScriptType::NONE;
665 
666  {
667  for(SwPaM& rPaM : GetCursor()->GetRingContainer())
668  {
669  const SwPosition *pStt = rPaM.Start(),
670  *pEnd = rPaM.End();
671  if( pStt == pEnd || *pStt == *pEnd )
672  {
673  const SwTextNode* pTNd = pStt->nNode.GetNode().GetTextNode();
674  if( pTNd )
675  {
676  // try to get SwScriptInfo
677  SwTextFrame const* pFrame;
678  const SwScriptInfo *const pScriptInfo =
679  SwScriptInfo::GetScriptInfo(*pTNd, &pFrame);
680 
681  sal_Int32 nPos = pStt->nContent.GetIndex();
682  //Task 90448: we need the scripttype of the previous
683  // position, if no selection exist!
684  if( nPos )
685  {
686  SwIndex aIdx( pStt->nContent );
687  if( pTNd->GoPrevious( &aIdx, CRSR_SKIP_CHARS ) )
688  nPos = aIdx.GetIndex();
689  }
690 
691  sal_uInt16 nScript;
692 
693  if (!pTNd->GetText().isEmpty())
694  {
695  nScript = pScriptInfo
696  ? pScriptInfo->ScriptType(pFrame->MapModelToView(pTNd, nPos))
697  : g_pBreakIt->GetBreakIter()->getScriptType( pTNd->GetText(), nPos );
698  }
699  else
701 
702  if (!lcl_IsNoEndTextAttrAtPos(*GetLayout(), *pTNd, nPos, nRet, false, false))
703  nRet |= lcl_SetScriptFlags( nScript );
704  }
705  }
706  else
707  {
708  SwNodeOffset nEndIdx = pEnd->nNode.GetIndex();
709  SwNodeIndex aIdx( pStt->nNode );
710  for( ; aIdx.GetIndex() <= nEndIdx; ++aIdx )
711  if( aIdx.GetNode().IsTextNode() )
712  {
713  const SwTextNode* pTNd = aIdx.GetNode().GetTextNode();
714  const OUString& rText = pTNd->GetText();
715 
716  // try to get SwScriptInfo
717  SwTextFrame const* pFrame;
718  const SwScriptInfo *const pScriptInfo =
719  SwScriptInfo::GetScriptInfo(*pTNd, &pFrame);
720 
721  sal_Int32 nChg = aIdx == pStt->nNode
722  ? pStt->nContent.GetIndex()
723  : 0;
724  sal_Int32 nEndPos = aIdx == nEndIdx
725  ? pEnd->nContent.GetIndex()
726  : rText.getLength();
727 
728  OSL_ENSURE( nEndPos <= rText.getLength(),
729  "Index outside the range - endless loop!" );
730  if (nEndPos > rText.getLength())
731  nEndPos = rText.getLength();
732 
733  bool const isUntilEnd(pScriptInfo
734  ? pFrame->MapViewToModelPos(TextFrameIndex(pFrame->GetText().getLength())) <= *pEnd
735  : rText.getLength() == nEndPos);
736  sal_uInt16 nScript;
737  while( nChg < nEndPos )
738  {
739  TextFrameIndex iChg(pScriptInfo
740  ? pFrame->MapModelToView(pTNd, nChg)
741  : TextFrameIndex(-1/*invalid, do not use*/));
742  nScript = pScriptInfo ?
743  pScriptInfo->ScriptType( iChg ) :
744  g_pBreakIt->GetBreakIter()->getScriptType(
745  rText, nChg );
746 
747  if (!lcl_IsNoEndTextAttrAtPos(*GetLayout(), *pTNd, nChg, nRet, true,
748  TextFrameIndex(0) == iChg && isUntilEnd))
749  {
750  nRet |= lcl_SetScriptFlags( nScript );
751  }
752 
753  if( (SvtScriptType::LATIN | SvtScriptType::ASIAN |
754  SvtScriptType::COMPLEX) == nRet )
755  break;
756 
757  sal_Int32 nFieldPos = nChg+1;
758 
759  if (pScriptInfo)
760  {
761  iChg = pScriptInfo->NextScriptChg(iChg);
762  if (iChg == TextFrameIndex(COMPLETE_STRING))
763  {
764  nChg = pTNd->Len();
765  }
766  else
767  {
768  std::pair<SwTextNode*, sal_Int32> const tmp(
769  pFrame->MapViewToModel(iChg));
770  nChg = (tmp.first == pTNd)
771  ? tmp.second
772  : pTNd->Len();
773  }
774  }
775  else
776  {
777  nChg = g_pBreakIt->GetBreakIter()->endOfScript(
778  rText, nChg, nScript );
779  }
780 
781  nFieldPos = rText.indexOf(
782  CH_TXTATR_BREAKWORD, nFieldPos);
783  if ((-1 != nFieldPos) && (nFieldPos < nChg))
784  nChg = nFieldPos;
785  }
786  if( (SvtScriptType::LATIN | SvtScriptType::ASIAN |
787  SvtScriptType::COMPLEX) == nRet )
788  break;
789  }
790  }
791  if( (SvtScriptType::LATIN | SvtScriptType::ASIAN |
792  SvtScriptType::COMPLEX) == nRet )
793  break;
794 
795  }
796  }
797  if( nRet == SvtScriptType::NONE )
799  return nRet;
800 }
801 
803 {
804  const SwPaM* pCursor = GetCursor();
805  const SwPosition& rPos = *pCursor->GetPoint();
806  const SwTextNode* pTNd = rPos.nNode.GetNode().GetTextNode();
808  if( pTNd )
809  {
810  //JP 24.9.2001: if exist no selection, then get the language before
811  // the current character!
812  sal_Int32 nPos = rPos.nContent.GetIndex();
813  if( nPos && !pCursor->HasMark() )
814  --nPos;
815  nLang = pTNd->GetLang( nPos );
816  }
817  else
818  nLang = LANGUAGE_DONTKNOW;
819  return nLang;
820 }
821 
823 {
824  const SwPaM* pCursor = GetCursor();
825  const SwPosition* pStt = pCursor->Start();
826  const SwTextNode* pTNd = pStt->nNode.GetNode().GetTextNode();
827  OSL_ENSURE( pTNd, "no textnode available" );
828 
829  sal_uInt16 nScaleWidth;
830  if( pTNd )
831  {
832  SwTextFrame *const pFrame(static_cast<SwTextFrame *>(
833  pTNd->getLayoutFrame(GetLayout(), pStt)));
834  assert(pFrame); // shell cursor must be positioned in node with frame
835  TextFrameIndex const nStart(pFrame->MapModelToViewPos(*pStt));
836  TextFrameIndex const nEnd(
837  sw::FrameContainsNode(*pFrame, pCursor->End()->nNode.GetIndex())
838  ? pFrame->MapModelToViewPos(*pCursor->End())
839  : TextFrameIndex(pFrame->GetText().getLength()));
840  nScaleWidth = pFrame->GetScalingOfSelectedText(nStart, nEnd);
841  }
842  else
843  nScaleWidth = 100; // default are no scaling -> 100%
844  return nScaleWidth;
845 }
846 
847 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SvxNumType GetNumberingType() const
Base class of the Writer layout elements.
Definition: frame.hxx:314
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:159
void SetEndNote(bool b)
Definition: atrftn.cxx:173
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:224
SwTextFormatColl * GetCurTextFormatColl() const
Get the named paragraph format of the current selection.
Definition: edattr.cxx:238
Represents the style of a paragraph.
Definition: fmtcol.hxx:56
sal_uInt16 Count() const
Marks a position in the document model.
Definition: pam.hxx:36
constexpr TypedWhichId< SvxTabStopItem > RES_PARATR_TABSTOP(68)
SwTextNode const & GetAttrMerged(SfxItemSet &rFormatSet, SwTextNode const &rNode, SwRootFrame const *pLayout)
Definition: txtfrm.cxx:373
TextFrameIndex NextScriptChg(TextFrameIndex nPos) const
Definition: porlay.cxx:1800
const SwField * GetField() const
Definition: fmtfld.hxx:116
sal_UCS4 GetBulletChar() const
constexpr auto toTwips(N number, Length from)
sal_uInt32 sal_UCS4
bool isCHRATR(const sal_uInt16 nWhich)
Definition: hintids.hxx:479
const OUString & GetText() const
Definition: ndtxt.hxx:218
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:226
SwNodeIndex nNode
Definition: pam.hxx:38
const SfxPoolItem * GetPoolDefaultItem(sal_uInt16 nWhich) const
bool FrameContainsNode(SwContentFrame const &rFrame, SwNodeOffset nNodeIndex)
Definition: txtfrm.cxx:290
virtual sal_Int32 Len() const override
Definition: ndtxt.cxx:277
long Long
Base class of all fields.
Definition: fldbas.hxx:291
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1210
sal_Int64 n
const WhichRangesContainer & GetRanges() const
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:92
static SwScriptInfo * GetScriptInfo(const SwTextNode &rNode, SwTextFrame const **o_pFrame=nullptr, bool bAllowInvalid=false)
return a frame for the node, ScriptInfo is its member...
Definition: porlay.cxx:2523
OUString sDlgEntry
Definition: expfld.hxx:51
SwUndoId EndUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Closes parenthesis of nUndoId, not used by UI.
Definition: edws.cxx:234
bool IsFootnoteDeleted(IDocumentRedlineAccess const &rIDRA, SwTextFootnote const &rTextFootnote)
Definition: ftnidx.cxx:37
SwNode & GetNode() const
Definition: ndindex.hxx:119
static SvtScriptType lcl_SetScriptFlags(sal_uInt16 nType)
Definition: edattr.cxx:564
bool InsertSort(SeqFieldLstElem aNew)
Definition: expfld.cxx:731
bool IsEndNote() const
Definition: fmtftn.hxx:71
sal_uInt16 Which() const
Definition: txatbase.hxx:116
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1296
void GetCurParAttr(SfxItemSet &rSet) const
Get the paragraph format attribute(s) of the current selection.
Definition: edattr.cxx:177
void EndAllAction()
Definition: edws.cxx:97
The root element of a Writer document layout.
Definition: rootfrm.hxx:81
int GetActualListLevel() const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4139
OUString GetViewNumStr(const SwDoc &rDoc, SwRootFrame const *pLayout, bool bInclStrings=false) const
Returns string to be displayed of footnote / endnote.
Definition: atrftn.cxx:217
static LanguageType nLang
Definition: srtdlg.cxx:51
LanguageType GetCurLang() const
Definition: edattr.cxx:802
SwTextAttr * GetTextAttrForCharAt(const sal_Int32 nIndex, const sal_uInt16 nWhich=RES_TXTATR_END) const
get the text attribute at position nIndex which owns the dummy character CH_TXTATR_* at that position...
Definition: ndtxt.cxx:3068
SvtScriptType
#define CH_TXTATR_BREAKWORD
Definition: hintids.hxx:173
const SfxPoolItem * NextItem()
size_t Count()
Definition: expfld.hxx:66
SwNodeType GetNodeType() const
Definition: node.hxx:146
constexpr TypedWhichId< SwFormatFootnote > RES_TXTATR_FTN(59)
rtl::Reference< SwDoc > mxDoc
The document; never 0.
Definition: viewsh.hxx:171
SwIndex nContent
Definition: pam.hxx:39
const SwRect & getFrameArea() const
Definition: frame.hxx:179
A wrapper around SfxPoolItem to store the start position of (usually) a text portion, with an optional end.
Definition: txatbase.hxx:43
SwBreakIt * g_pBreakIt
Definition: breakit.cxx:33
const SfxPoolItem & GetDefault(sal_uInt16 nFormatHint) const
Get the default attribute in this document.
Definition: docfmt.cxx:664
sal_Int32 GetStart() const
Definition: txatbase.hxx:88
void Width(tools::Long nNew)
Definition: swrect.hxx:189
static bool lcl_IsNoEndTextAttrAtPos(SwRootFrame const &rLayout, const SwTextNode &rTNd, sal_Int32 const nPos, SvtScriptType &rScrpt, bool bInSelection, bool bNum)
Definition: edattr.cxx:579
constexpr TypedWhichId< SwFormatCharFormat > RES_TXTATR_CHARFMT(52)
SwDoc * GetDoc() const
Definition: viewsh.hxx:282
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:199
const OUString & GetNumStr() const
Definition: fmtftn.hxx:68
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:152
constexpr TypedWhichId< SwFormatAutoFormat > RES_TXTATR_AUTOFMT(50)
sal_uInt16 GetSeqRefNo() const
Definition: txtftn.hxx:64
sal_Int16 GetI18NScriptTypeOfLanguage(LanguageType nLang)
SwPaM * GetNext()
Definition: pam.hxx:265
SwPaM & SetPam(size_t nArrPos, SwPaM &rPam)
Definition: ednumber.cxx:98
constexpr TypedWhichId< SwFormatINetFormat > RES_TXTATR_INETFMT(51)
SVX_NUM_BITMAP
SVX_NUM_CHAR_SPECIAL
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:137
size_t Count() const
Definition: edimp.hxx:50
constexpr TypedWhichId< SwFormatField > RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN)
tools::Long GetTextLeft() const
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
size_t Count() const
Definition: ndhints.hxx:142
TextFrameIndex MapModelToViewPos(SwPosition const &rPos) const
Definition: txtfrm.cxx:1270
SvtScriptType GetScriptType() const
returns the script type of the selection
Definition: edattr.cxx:662
SwTextAttr * Get(size_t nPos) const
Definition: ndhints.hxx:144
const SwPosition * GetPoint() const
Definition: pam.hxx:208
#define LANGUAGE_SYSTEM
sal_uInt16 Count() const
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:206
void MoveLeftMargin(bool bRight, bool bModulus=true)
Definition: edattr.cxx:543
SwUndoId StartUndo(SwUndoId eUndoId=SwUndoId::EMPTY, const SwRewriter *pRewriter=nullptr)
Undo: set up Undo parenthesis, return nUndoId of this parenthesis.
Definition: edws.cxx:223
Marks a character position inside a document model node.
Definition: index.hxx:33
const SfxItemSet * GetItemSet(const SfxPoolItem &rAttr)
Returns the item set associated with a character/inet/auto style.
Definition: atrstck.cxx:133
sal_uInt16 GetWhichOfScript(sal_uInt16 nWhich, sal_uInt16 nScript)
Definition: hints.cxx:190
SwNumRule * GetNumRule(bool bInParent=true) const
Returns numbering rule of this text node.
Definition: ndtxt.cxx:2833
SvtScriptType GetScriptTypeOfLanguage(LanguageType nLang)
#define LANGUAGE_DONTKNOW
sal_uInt16 GetCursorCnt(bool bAll=true) const
Get the number of elements in the ring of cursors.
Definition: crsrsh.cxx:2745
Marks a node in the document model.
Definition: ndindex.hxx:30
size_t GetSeqFootnoteList(SwSeqFieldList &rList, bool bEndNotes=false)
Give a List of all footnotes and their beginning texts.
Definition: edattr.cxx:443
bool HasSwAttrSet() const
Definition: node.hxx:458
ring_container GetRingContainer()
Definition: ring.hxx:240
void MergeValues(const SfxItemSet &rSet)
Represents the style of a text portion.
Definition: charfmt.hxx:26
SfxItemPool * GetPool() const
const SwFormatFootnote & GetFootnote() const
Definition: txatbase.hxx:208
std::pair< SwTextNode *, sal_Int32 > MapViewToModel(TextFrameIndex nIndex) const
map position in potentially merged text frame to SwPosition
Definition: txtfrm.cxx:1234
tools::Long SwTwips
Definition: swtypes.hxx:51
const SwPosition * Start() const
Definition: pam.hxx:213
std::vector< std::pair< const SfxPoolItem *, std::unique_ptr< SwPaM > > > GetItemWithPaM(sal_uInt16 nWhich)
Get RES_CHRATR_* items of one type in the current selection.
Definition: edattr.cxx:284
bool GetPaMAttr(SwPaM *pPaM, SfxItemSet &, const bool bMergeIndentValuesOfNumRule=false) const
Apply / remove attributes.
Definition: edattr.cxx:59
SwTextNode * GetParaPropsNode(SwRootFrame const &rLayout, SwNodeIndex const &rNode)
Definition: txtfrm.cxx:330
sal_uInt16 GetScalingOfSelectedText(TextFrameIndex nStt, TextFrameIndex nEnd)
Calculates the width of the text part specified by nStart and nEnd, the height of the line containing...
Definition: itratr.cxx:1257
css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIter() const
Definition: breakit.hxx:62
const SwNumFormat & Get(sal_uInt16 i) const
Definition: number.cxx:86
SwCharFormat * FindCharFormatByName(const OUString &rName) const
Definition: doc.hxx:770
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
bool SetCurFootnote(const SwFormatFootnote &rFillFootnote)
Definition: edattr.cxx:414
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
OUString ExpandField(bool bCached, SwRootFrame const *pLayout) const
expand the field.
Definition: fldbas.cxx:484
void MoveLeftMargin(const SwPaM &rPam, bool bRight, bool bModulus, SwRootFrame const *pLayout=nullptr)
Adjust left margin via object bar (similar to adjustment of numerations).
Definition: docfmt.cxx:1639
sal_Int16 ScriptType(const TextFrameIndex nPos) const
Definition: porlay.cxx:1813
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:195
OUString GetExpandText(SwRootFrame const *pLayout, const sal_Int32 nIdx=0, const sal_Int32 nLen=-1, const bool bWithNum=false, const bool bAddSpaceAfterListLabelStr=false, const bool bWithSpacesForLevel=false, const ExpandMode eAdditionalMode=ExpandMode::ExpandFootnote) const
add 4th optional parameter indicating, when that a spa...
Definition: ndtxt.cxx:3412
bool IsMoveLeftMargin(bool bRight, bool bModulus=true) const
Adjust left margin via object bar (similar to adjustment of numerations).
Definition: edattr.cxx:490
unsigned char sal_uInt8
bool HasFootnotes(bool bEndNotes=false) const
Definition: edattr.cxx:430
TextFrameIndex MapModelToView(SwTextNode const *pNode, sal_Int32 nIndex) const
Definition: txtfrm.cxx:1255
sal_Int32 GetIndex() const
Definition: index.hxx:91
LanguageType GetAppLanguage()
Definition: init.cxx:725
SwNodes & GetNodes()
Definition: doc.hxx:408
const SwPosition * End() const
Definition: pam.hxx:218
LanguageType GetLang(const sal_Int32 nBegin, const sal_Int32 nLen=0, sal_uInt16 nScript=0) const
Definition: thints.cxx:3433
const sal_Int32 * End() const
Definition: txatbase.hxx:156
bool GetCurFootnote(SwFormatFootnote *pToFillFootnote=nullptr)
Query and set footnote-text/number. Set... to current SSelection!
Definition: edattr.cxx:394
void SetNumber(const SwFormatFootnote &rFootnote)
Definition: fmtftn.hxx:76
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding)...
Definition: rootfrm.hxx:421
bool GetCurAttr(SfxItemSet &, const bool bMergeIndentValuesOfNumRule=false) const
Definition: edattr.cxx:171
SwTextFormatColl * GetPaMTextFormatColl(SwPaM *pPaM) const
Get the named paragraph format of the selection(s) described by a SwPaM.
Definition: edattr.cxx:243
const SwAttrSet & GetSwAttrSet() const
Does node has already its own auto-attributes? Access to SwAttrSet.
Definition: node.hxx:724
constexpr sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:57
OUString GetNumString(const bool _bInclPrefixAndSuffixStrings=true, const unsigned int _nRestrictToThisLevel=MAXLEVEL, SwRootFrame const *pLayout=nullptr) const
Returns outline of numbering string.
Definition: ndtxt.cxx:3160
const SfxPoolItem & GetAttr() const
Definition: txatbase.hxx:167
void GetPaMParAttr(SwPaM *pPaM, SfxItemSet &rSet) const
Get the paragraph format attribute(s) of the selection(s) described by a SwPaM.
Definition: edattr.cxx:182
static sal_uInt16 getMaxLookup()
Definition: edattr.cxx:54
bool IsVertical() const
Definition: frame.hxx:973
const sal_uInt16 CRSR_SKIP_CHARS
Definition: swcrsr.hxx:65
SwNodeIndex * GetStartNode() const
Definition: txtftn.hxx:41
void InvalidateAllItems()
bool IsInList() const
Definition: ndtxt.cxx:4379
bool HasMergedParas() const
Definition: rootfrm.hxx:425
constexpr tools::Long constTwips_5mm
Definition: pggrid.cxx:38
tuple m
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:136
const SfxPoolItem & GetAttr(sal_uInt16 nWhich, bool bInParent=true) const
SS for PoolItems: hard attributation.
Definition: node.hxx:731
void StartAllAction()
For all views of this document.
Definition: edws.cxx:86
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
sal_uInt16 GetScalingOfSelectedText() const
Definition: edattr.cxx:822
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2172
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
bool IsTextNode() const
Definition: node.hxx:646
void Height(tools::Long nNew)
Definition: swrect.hxx:193
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1249
Merge GetRedlineMergeFlag() const
Definition: node.hxx:99
virtual OUString GetCharFormatName() const override
Definition: number.cxx:310
sal_uInt16 Which() const
bool GoPrevious(SwIndex *, sal_uInt16 nMode) const
Definition: node.cxx:1314
void Clear()
Definition: expfld.hxx:69
sal_uInt16 nPos
const SfxPoolItem * GetCurItem() const
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:864
bool HasHints() const
Definition: ndtxt.hxx:228
Base class of the Writer document model elements.
Definition: node.hxx:81
SwTextFormatColl * GetTextColl() const
Definition: ndtxt.hxx:858