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