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