LibreOffice Module sc (master)  1
editutil.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 <scitems.hxx>
22 #include <editeng/eeitem.hxx>
23 
24 #include <svx/algitem.hxx>
25 #include <svtools/colorcfg.hxx>
26 #include <editeng/editstat.hxx>
27 #include <editeng/flditem.hxx>
28 #include <editeng/numitem.hxx>
29 #include <editeng/justifyitem.hxx>
30 #include <editeng/editobj.hxx>
31 #include <vcl/outdev.hxx>
32 #include <svl/inethist.hxx>
33 #include <sfx2/objsh.hxx>
34 #include <osl/diagnose.h>
35 
36 #include <com/sun/star/text/textfield/Type.hpp>
37 #include <com/sun/star/document/XDocumentProperties.hpp>
38 
39 #include <editutil.hxx>
40 #include <global.hxx>
41 #include <attrib.hxx>
42 #include <document.hxx>
43 #include <docpool.hxx>
44 #include <patattr.hxx>
45 #include <scmod.hxx>
46 #include <inputopt.hxx>
47 #include <compiler.hxx>
48 
49 using namespace com::sun::star;
50 
51 // delimiters additionally to EditEngine default:
52 
54  const Point& rCellPos,
55  OutputDevice* pDevice, double nScaleX, double nScaleY,
56  const Fraction& rX, const Fraction& rY, bool bPrintTwips ) :
57  pDoc(pDocument),nCol(nX),nRow(nY),nTab(nZ),
58  aCellPos(rCellPos),pDev(pDevice),
59  nPPTX(nScaleX),nPPTY(nScaleY),aZoomX(rX),aZoomY(rY),
60  bInPrintTwips(bPrintTwips) {}
61 
62 OUString ScEditUtil::ModifyDelimiters( const OUString& rOld )
63 {
64  // underscore is used in function argument names
65  OUString aRet = rOld.replaceAll("_", "") +
66  "=()+-*/^&<>" +
67  ScCompiler::GetNativeSymbol(ocSep); // argument separator is localized.
68  return aRet;
69 }
70 
71 static OUString lcl_GetDelimitedString( const EditEngine& rEngine, const char c )
72 {
73  sal_Int32 nParCount = rEngine.GetParagraphCount();
74  OUStringBuffer aRet( nParCount * 80 );
75  for (sal_Int32 nPar=0; nPar<nParCount; nPar++)
76  {
77  if (nPar > 0)
78  aRet.append(c);
79  aRet.append( rEngine.GetText( nPar ));
80  }
81  return aRet.makeStringAndClear();
82 }
83 
84 static OUString lcl_GetDelimitedString( const EditTextObject& rEdit, const char c )
85 {
86  sal_Int32 nParCount = rEdit.GetParagraphCount();
87  OUStringBuffer aRet( nParCount * 80 );
88  for (sal_Int32 nPar=0; nPar<nParCount; nPar++)
89  {
90  if (nPar > 0)
91  aRet.append(c);
92  aRet.append( rEdit.GetText( nPar ));
93  }
94  return aRet.makeStringAndClear();
95 }
96 
98 {
99  return lcl_GetDelimitedString(rEngine, ' ');
100 }
101 OUString ScEditUtil::GetMultilineString( const EditEngine& rEngine )
102 {
103  return lcl_GetDelimitedString(rEngine, '\n');
104 }
105 
107 {
108  return lcl_GetDelimitedString(rEdit, '\n');
109 }
110 
111 OUString ScEditUtil::GetString( const EditTextObject& rEditText, const ScDocument* pDoc )
112 {
113  if( !rEditText.HasField())
114  return GetMultilineString( rEditText );
115 
116  static osl::Mutex aMutex;
117  osl::MutexGuard aGuard( aMutex);
118  // ScFieldEditEngine is needed to resolve field contents.
119  if (pDoc)
120  {
121  /* TODO: make ScDocument::GetEditEngine() const? Most likely it's only
122  * not const because of the pointer assignment, make that mutable, and
123  * then remove the ugly const_cast here. */
124  EditEngine& rEE = const_cast<ScDocument*>(pDoc)->GetEditEngine();
125  rEE.SetText( rEditText);
126  return GetMultilineString( rEE);
127  }
128  else
129  {
131  rEE.SetText( rEditText);
132  return GetMultilineString( rEE);
133  }
134 }
135 
136 std::unique_ptr<EditTextObject> ScEditUtil::CreateURLObjectFromURL( ScDocument& rDoc, const OUString& rURL, const OUString& rText )
137 {
138  SvxURLField aUrlField( rURL, rText, SvxURLFormat::AppDefault);
139  EditEngine& rEE = rDoc.GetEditEngine();
140  rEE.SetText( EMPTY_OUSTRING );
143 
144  return rEE.CreateTextObject();
145 }
146 
148 {
149  static const struct {
150  sal_uInt16 nAttrType;
151  sal_uInt16 nCharType;
152  } AttrTypeMap[] = {
157  };
158 
159  const SfxItemSet& rSet = rAttr.GetItemSet();
160  const SfxPoolItem* pItem;
161  for (size_t i = 0; i < SAL_N_ELEMENTS(AttrTypeMap); ++i)
162  {
163  if ( rSet.GetItemState(AttrTypeMap[i].nAttrType, false, &pItem) == SfxItemState::SET )
164  rEditText.RemoveCharAttribs(AttrTypeMap[i].nCharType);
165  }
166 }
167 
168 std::unique_ptr<EditTextObject> ScEditUtil::Clone( const EditTextObject& rObj, ScDocument& rDestDoc )
169 {
170  std::unique_ptr<EditTextObject> pNew;
171 
172  EditEngine& rEngine = rDestDoc.GetEditEngine();
173  if (rObj.HasOnlineSpellErrors())
174  {
175  EEControlBits nControl = rEngine.GetControlWord();
176  const EEControlBits nSpellControl = EEControlBits::ONLINESPELLING | EEControlBits::ALLOWBIGOBJS;
177  bool bNewControl = ( (nControl & nSpellControl) != nSpellControl );
178  if (bNewControl)
179  rEngine.SetControlWord(nControl | nSpellControl);
180  rEngine.SetText(rObj);
181  pNew = rEngine.CreateTextObject();
182  if (bNewControl)
183  rEngine.SetControlWord(nControl);
184  }
185  else
186  {
187  rEngine.SetText(rObj);
188  pNew = rEngine.CreateTextObject();
189  }
190 
191  return pNew;
192 }
193 
195  const SvxFieldData& rFieldData, const ScDocument* pDoc, std::optional<Color>* ppTextColor )
196 {
197  OUString aRet;
198  switch (rFieldData.GetClassId())
199  {
200  case text::textfield::Type::URL:
201  {
202  const SvxURLField& rField = static_cast<const SvxURLField&>(rFieldData);
203  const OUString& aURL = rField.GetURL();
204 
205  switch (rField.GetFormat())
206  {
207  case SvxURLFormat::AppDefault: //TODO: configurable with App???
208  case SvxURLFormat::Repr:
209  aRet = rField.GetRepresentation();
210  break;
211  case SvxURLFormat::Url:
212  aRet = aURL;
213  break;
214  default:
215  ;
216  }
217 
220 
221  if (ppTextColor)
222  *ppTextColor = SC_MOD()->GetColorConfig().GetColorValue(eEntry).nColor;
223  }
224  break;
225  case text::textfield::Type::EXTENDED_TIME:
226  {
227  const SvxExtTimeField& rField = static_cast<const SvxExtTimeField&>(rFieldData);
228  if (pDoc)
229  aRet = rField.GetFormatted(*pDoc->GetFormatTable(), ScGlobal::eLnge);
230  else
231  {
232  /* TODO: quite expensive, we could have a global formatter? */
234  aRet = rField.GetFormatted(aFormatter, ScGlobal::eLnge);
235  }
236  }
237  break;
239  {
240  Date aDate(Date::SYSTEM);
241  aRet = ScGlobal::getLocaleDataPtr()->getDate(aDate);
242  }
243  break;
244  case text::textfield::Type::DOCINFO_TITLE:
245  {
246  if (pDoc)
247  {
248  SfxObjectShell* pDocShell = pDoc->GetDocumentShell();
249  if (pDocShell)
250  {
251  aRet = pDocShell->getDocProperties()->getTitle();
252  if (aRet.isEmpty())
253  aRet = pDocShell->GetTitle();
254  }
255  }
256  if (aRet.isEmpty())
257  aRet = "?";
258  }
259  break;
261  {
262  const SvxTableField& rField = static_cast<const SvxTableField&>(rFieldData);
263  SCTAB nTab = rField.GetTab();
264  OUString aName;
265  if (pDoc && pDoc->GetName(nTab, aName))
266  aRet = aName;
267  else
268  aRet = "?";
269  }
270  break;
271  default:
272  aRet = "?";
273  }
274 
275  if (aRet.isEmpty()) // empty is yuck
276  aRet = " "; // space is default of EditEngine
277 
278  return aRet;
279 }
280 
281 tools::Rectangle ScEditUtil::GetEditArea( const ScPatternAttr* pPattern, bool bForceToTop )
282 {
283  // bForceToTop = always align to top, for editing
284  // (sal_False for querying URLs etc.)
285 
286  if (!pPattern)
287  pPattern = pDoc->GetPattern( nCol, nRow, nTab );
288 
289  Point aStartPos = aCellPos;
290 
291  bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
292  tools::Long nLayoutSign = bLayoutRTL ? -1 : 1;
293 
294  const ScMergeAttr* pMerge = &pPattern->GetItem(ATTR_MERGE);
295  tools::Long nCellX = pDoc->GetColWidth(nCol,nTab);
296  if (!bInPrintTwips)
297  nCellX = static_cast<tools::Long>( nCellX * nPPTX );
298  if ( pMerge->GetColMerge() > 1 )
299  {
300  SCCOL nCountX = pMerge->GetColMerge();
301  for (SCCOL i=1; i<nCountX; i++)
302  {
303  tools::Long nColWidth = pDoc->GetColWidth(nCol+i,nTab);
304  nCellX += (bInPrintTwips ? nColWidth : static_cast<tools::Long>( nColWidth * nPPTX ));
305  }
306  }
308  if (!bInPrintTwips)
309  nCellY = static_cast<tools::Long>( nCellY * nPPTY );
310  if ( pMerge->GetRowMerge() > 1 )
311  {
312  SCROW nCountY = pMerge->GetRowMerge();
313  if (bInPrintTwips)
314  nCellY += pDoc->GetRowHeight(nRow + 1, nRow + nCountY - 1, nTab);
315  else
316  nCellY += static_cast<tools::Long>(pDoc->GetScaledRowHeight( nRow+1, nRow+nCountY-1, nTab, nPPTY));
317  }
318 
319  const SvxMarginItem* pMargin = &pPattern->GetItem(ATTR_MARGIN);
320  sal_uInt16 nIndent = 0;
321  if ( pPattern->GetItem(ATTR_HOR_JUSTIFY).GetValue() ==
322  SvxCellHorJustify::Left )
323  nIndent = pPattern->GetItem(ATTR_INDENT).GetValue();
324  tools::Long nDifX = pMargin->GetLeftMargin() + nIndent;
325  if (!bInPrintTwips)
326  nDifX = static_cast<tools::Long>( nDifX * nPPTX );
327  aStartPos.AdjustX(nDifX * nLayoutSign );
328  nCellX -= nDifX + (bInPrintTwips ? pMargin->GetRightMargin() :
329  static_cast<tools::Long>( pMargin->GetRightMargin() * nPPTX )); // due to line feed, etc.
330 
331  // align vertical position to the one in the table
332 
333  tools::Long nDifY;
334  tools::Long nTopMargin = pMargin->GetTopMargin();
335  if (!bInPrintTwips)
336  nTopMargin = static_cast<tools::Long>( nTopMargin * nPPTY );
337  SvxCellVerJustify eJust = pPattern->GetItem(ATTR_VER_JUSTIFY).GetValue();
338 
339  // asian vertical is always edited top-aligned
340  bool bAsianVertical = pPattern->GetItem( ATTR_STACKED ).GetValue() &&
341  pPattern->GetItem( ATTR_VERTICAL_ASIAN ).GetValue();
342 
343  if ( eJust == SvxCellVerJustify::Top ||
344  ( bForceToTop && ( SC_MOD()->GetInputOptions().GetTextWysiwyg() || bAsianVertical ) ) )
345  nDifY = nTopMargin;
346  else
347  {
348  MapMode aMode = pDev->GetMapMode();
349  pDev->SetMapMode(MapMode(bInPrintTwips ? MapUnit::MapTwip : MapUnit::MapPixel));
350 
351  tools::Long nTextHeight = pDoc->GetNeededSize( nCol, nRow, nTab,
352  pDev, nPPTX, nPPTY, aZoomX, aZoomY, false /* bWidth */,
353  false /* bTotalSize */, bInPrintTwips );
354  if (!nTextHeight)
355  { // empty cell
356  vcl::Font aFont;
357  // font color doesn't matter here
358  pPattern->GetFont( aFont, SC_AUTOCOL_BLACK, pDev, &aZoomY );
359  pDev->SetFont(aFont);
360  nTextHeight = pDev->GetTextHeight() + nTopMargin +
361  (bInPrintTwips ? pMargin->GetBottomMargin() :
362  static_cast<tools::Long>( pMargin->GetBottomMargin() * nPPTY ));
363  }
364 
365  pDev->SetMapMode(aMode);
366 
367  if ( nTextHeight > nCellY + nTopMargin || bForceToTop )
368  nDifY = 0; // too large -> begin at the top
369  else
370  {
371  if ( eJust == SvxCellVerJustify::Center )
372  nDifY = nTopMargin + ( nCellY - nTextHeight ) / 2;
373  else
374  nDifY = nCellY - nTextHeight + nTopMargin; // JUSTIFY_BOTTOM
375  }
376  }
377 
378  aStartPos.AdjustY(nDifY );
379  nCellY -= nDifY;
380 
381  if ( bLayoutRTL )
382  aStartPos.AdjustX( -(nCellX - 2) ); // excluding grid on both sides
383 
384  // -1 -> don't overwrite grid
385  return tools::Rectangle( aStartPos, Size(nCellX-1,nCellY-1) );
386 }
387 
389  bNeedsObject( false ),
390  bNeedsCellAttr( false )
391 {
392  if ( pEngine->GetParagraphCount() > 1 )
393  {
394  bNeedsObject = true; //TODO: find cell attributes ?
395  }
396  else
397  {
398  const SfxPoolItem* pItem = nullptr;
399  pEditAttrs.reset( new SfxItemSet( pEngine->GetAttribs(
400  ESelection(0,0,0,pEngine->GetTextLen(0)), EditEngineAttribs::OnlyHard ) ) );
401  const SfxItemSet& rEditDefaults = pEngine->GetDefaults();
402 
403  for (sal_uInt16 nId = EE_CHAR_START; nId <= EE_CHAR_END && !bNeedsObject; nId++)
404  {
405  SfxItemState eState = pEditAttrs->GetItemState( nId, false, &pItem );
406  if (eState == SfxItemState::DONTCARE)
407  bNeedsObject = true;
408  else if (eState == SfxItemState::SET)
409  {
412  {
413  // Escapement and kerning are kept in EditEngine because there are no
414  // corresponding cell format items. User defined attributes are kept in
415  // EditEngine because "user attributes applied to all the text" is different
416  // from "user attributes applied to the cell".
417 
418  if ( *pItem != rEditDefaults.Get(nId) )
419  bNeedsObject = true;
420  }
421  else
422  if (!bNeedsCellAttr)
423  if ( *pItem != rEditDefaults.Get(nId) )
424  bNeedsCellAttr = true;
425  // rEditDefaults contains the defaults from the cell format
426  }
427  }
428 
429  // contains field commands?
430 
431  SfxItemState eFieldState = pEditAttrs->GetItemState( EE_FEATURE_FIELD, false );
432  if ( eFieldState == SfxItemState::DONTCARE || eFieldState == SfxItemState::SET )
433  bNeedsObject = true;
434 
435  // not converted characters?
436 
437  SfxItemState eConvState = pEditAttrs->GetItemState( EE_FEATURE_NOTCONV, false );
438  if ( eConvState == SfxItemState::DONTCARE || eConvState == SfxItemState::SET )
439  bNeedsObject = true;
440  }
441 }
442 
444 {
445 }
446 
448  bool bDeleteEnginePoolP )
449  :
450  pEnginePool( pEnginePoolP ),
451  pDefaults( nullptr ),
452  bDeleteEnginePool( bDeleteEnginePoolP ),
453  bDeleteDefaults( false )
454 {
455 }
456 
458  :
459  pEnginePool( rOrg.bDeleteEnginePool ? rOrg.pEnginePool->Clone() : rOrg.pEnginePool ),
460  pDefaults( nullptr ),
461  bDeleteEnginePool( rOrg.bDeleteEnginePool ),
462  bDeleteDefaults( false )
463 {
464 }
465 
467 {
468  if ( bDeleteDefaults )
469  delete pDefaults;
470  if ( bDeleteEnginePool )
472 }
473 
475  bool bDeleteEnginePoolP )
476  :
477  ScEnginePoolHelper( pEnginePoolP, bDeleteEnginePoolP ),
478  EditEngine( pEnginePoolP )
479 {
480  // All EditEngines use ScGlobal::GetEditDefaultLanguage as DefaultLanguage.
481  // DefaultLanguage for InputHandler's EditEngine is updated later.
482 
484 }
485 
487  :
488  ScEnginePoolHelper( rOrg ),
489  EditEngine( pEnginePool )
490 {
492 }
493 
495 {
496 }
497 
498 void ScEditEngineDefaulter::SetDefaults( const SfxItemSet& rSet, bool bRememberCopy )
499 {
500  if ( bRememberCopy )
501  {
502  if ( bDeleteDefaults )
503  delete pDefaults;
504  pDefaults = new SfxItemSet( rSet );
505  bDeleteDefaults = true;
506  }
507  const SfxItemSet& rNewSet = bRememberCopy ? *pDefaults : rSet;
508  bool bUndo = IsUndoEnabled();
509  EnableUndo( false );
510  bool bUpdateMode = GetUpdateMode();
511  if ( bUpdateMode )
512  SetUpdateMode( false );
513  sal_Int32 nPara = GetParagraphCount();
514  for ( sal_Int32 j=0; j<nPara; j++ )
515  {
516  SetParaAttribs( j, rNewSet );
517  }
518  if ( bUpdateMode )
519  SetUpdateMode( true );
520  if ( bUndo )
521  EnableUndo( true );
522 }
523 
524 void ScEditEngineDefaulter::SetDefaults( std::unique_ptr<SfxItemSet> pSet )
525 {
526  if ( bDeleteDefaults )
527  delete pDefaults;
528  pDefaults = pSet.release();
529  bDeleteDefaults = true;
530  if ( pDefaults )
531  SetDefaults( *pDefaults, false );
532 }
533 
535 {
536  if ( !pDefaults )
537  {
539  bDeleteDefaults = true;
540  }
541  pDefaults->Put( rItem );
542  SetDefaults( *pDefaults, false );
543 }
544 
546 {
547  if ( !pDefaults )
548  {
550  bDeleteDefaults = true;
551  }
552  return *pDefaults;
553 }
554 
556 {
557  bool bUpdateMode = GetUpdateMode();
558  if ( bUpdateMode )
559  SetUpdateMode( false );
560  SetText( rTextObject );
561  if ( pDefaults )
562  SetDefaults( *pDefaults, false );
563  if ( bUpdateMode )
564  SetUpdateMode( true );
565 }
566 
568  const SfxItemSet& rSet, bool bRememberCopy )
569 {
570  bool bUpdateMode = GetUpdateMode();
571  if ( bUpdateMode )
572  SetUpdateMode( false );
573  SetText( rTextObject );
574  SetDefaults( rSet, bRememberCopy );
575  if ( bUpdateMode )
576  SetUpdateMode( true );
577 }
578 
580  std::unique_ptr<SfxItemSet> pSet )
581 {
582  bool bUpdateMode = GetUpdateMode();
583  if ( bUpdateMode )
584  SetUpdateMode( false );
585  SetText( rTextObject );
586  SetDefaults( std::move(pSet) );
587  if ( bUpdateMode )
588  SetUpdateMode( true );
589 }
590 
592 {
593  bool bUpdateMode = GetUpdateMode();
594  if ( bUpdateMode )
595  SetUpdateMode( false );
596  SetText( rText );
597  if ( pDefaults )
598  SetDefaults( *pDefaults, false );
599  if ( bUpdateMode )
600  SetUpdateMode( true );
601 }
602 
603 void ScEditEngineDefaulter::SetTextNewDefaults( const OUString& rText,
604  const SfxItemSet& rSet )
605 {
606  bool bUpdateMode = GetUpdateMode();
607  if ( bUpdateMode )
608  SetUpdateMode( false );
609  SetText( rText );
610  SetDefaults( rSet );
611  if ( bUpdateMode )
612  SetUpdateMode( true );
613 }
614 
615 void ScEditEngineDefaulter::SetTextNewDefaults( const OUString& rText,
616  std::unique_ptr<SfxItemSet> pSet )
617 {
618  bool bUpdateMode = GetUpdateMode();
619  if ( bUpdateMode )
620  SetUpdateMode( false );
621  SetText( rText );
622  SetDefaults( std::move(pSet) );
623  if ( bUpdateMode )
624  SetUpdateMode( true );
625 }
626 
628 {
629  if ( pDefaults )
630  {
631  sal_Int32 nPara = GetParagraphCount();
632  for ( sal_Int32 j=0; j<nPara; j++ )
633  SetParaAttribs( j, *pDefaults );
634  }
635 }
636 
638 {
639  std::unique_ptr<SfxItemSet> pCharItems;
640  bool bUpdateMode = GetUpdateMode();
641  if ( bUpdateMode )
642  SetUpdateMode( false );
643  sal_Int32 nParCount = GetParagraphCount();
644  for (sal_Int32 nPar=0; nPar<nParCount; nPar++)
645  {
646  const SfxItemSet& rParaAttribs = GetParaAttribs( nPar );
647  sal_uInt16 nWhich;
648  for (nWhich = EE_CHAR_START; nWhich <= EE_CHAR_END; nWhich ++)
649  {
650  const SfxPoolItem* pParaItem;
651  if ( rParaAttribs.GetItemState( nWhich, false, &pParaItem ) == SfxItemState::SET )
652  {
653  // if defaults are set, use only items that are different from default
654  if ( !pDefaults || *pParaItem != pDefaults->Get(nWhich) )
655  {
656  if (!pCharItems)
657  pCharItems.reset(new SfxItemSet( GetEmptyItemSet() ));
658  pCharItems->Put( *pParaItem );
659  }
660  }
661  }
662 
663  if ( pCharItems )
664  {
665  std::vector<sal_Int32> aPortions;
666  GetPortions( nPar, aPortions );
667 
668  // loop through the portions of the paragraph, and set only those items
669  // that are not overridden by existing character attributes
670 
671  sal_Int32 nStart = 0;
672  for ( const sal_Int32 nEnd : aPortions )
673  {
674  ESelection aSel( nPar, nStart, nPar, nEnd );
675  SfxItemSet aOldCharAttrs = GetAttribs( aSel );
676  SfxItemSet aNewCharAttrs = *pCharItems;
677  for (nWhich = EE_CHAR_START; nWhich <= EE_CHAR_END; nWhich ++)
678  {
679  // Clear those items that are different from existing character attributes.
680  // Where no character attributes are set, GetAttribs returns the paragraph attributes.
681  const SfxPoolItem* pItem;
682  if ( aNewCharAttrs.GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
683  *pItem != aOldCharAttrs.Get(nWhich) )
684  {
685  aNewCharAttrs.ClearItem(nWhich);
686  }
687  }
688  if ( aNewCharAttrs.Count() )
689  QuickSetAttribs( aNewCharAttrs, aSel );
690 
691  nStart = nEnd;
692  }
693 
694  pCharItems.reset();
695  }
696 
697  if ( rParaAttribs.Count() )
698  {
699  // clear all paragraph attributes (including defaults),
700  // so they are not contained in resulting EditTextObjects
701 
702  SetParaAttribs( nPar, SfxItemSet( *rParaAttribs.GetPool(), rParaAttribs.GetRanges() ) );
703  }
704  }
705  if ( bUpdateMode )
706  SetUpdateMode( true );
707 }
708 
710  : ScFieldEditEngine( pDoc, pDoc->GetEnginePool() )
711 {
714 }
715 
717  SfxItemPool* pEngineItemPool, ScDocument* pDoc, SfxItemPool* pTextObjectPool )
718  : ScFieldEditEngine( pDoc, pEngineItemPool, pTextObjectPool )
719 {
720  if ( pTextObjectPool )
721  SetEditTextObjectPool( pTextObjectPool );
722  Init( rPattern );
723 }
724 
725 void ScTabEditEngine::Init( const ScPatternAttr& rPattern )
726 {
727  SetRefMapMode(MapMode(MapUnit::Map100thMM));
728  auto pEditDefaults = std::make_unique<SfxItemSet>( GetEmptyItemSet() );
729  rPattern.FillEditItemSet( pEditDefaults.get() );
730  SetDefaults( std::move(pEditDefaults) );
731  // we have no StyleSheets for text
732  SetControlWord( GetControlWord() & ~EEControlBits::RTFSTYLESHEETS );
733 }
734 
735 // field commands for header and footer
736 
737 // numbers from \sw\source\core\doc\numbers.cxx
738 
739 static OUString lcl_GetCharStr( sal_Int32 nNo )
740 {
741  OSL_ENSURE( nNo, "0 is an invalid number !!" );
742  OUString aStr;
743 
744  const sal_Int32 coDiff = 'Z' - 'A' +1;
745  sal_Int32 nCalc;
746 
747  do {
748  nCalc = nNo % coDiff;
749  if( !nCalc )
750  nCalc = coDiff;
751  aStr = OUStringChar( sal_Unicode('a' - 1 + nCalc) ) + aStr;
752  nNo = sal::static_int_cast<sal_Int32>( nNo - nCalc );
753  if( nNo )
754  nNo /= coDiff;
755  } while( nNo );
756  return aStr;
757 }
758 
759 static OUString lcl_GetNumStr(sal_Int32 nNo, SvxNumType eType)
760 {
761  OUString aTmpStr('0');
762  if( nNo )
763  {
764  switch( eType )
765  {
766  case css::style::NumberingType::CHARS_UPPER_LETTER:
767  case css::style::NumberingType::CHARS_LOWER_LETTER:
768  aTmpStr = lcl_GetCharStr( nNo );
769  break;
770 
771  case css::style::NumberingType::ROMAN_UPPER:
772  case css::style::NumberingType::ROMAN_LOWER:
773  if( nNo < 4000 )
774  aTmpStr = SvxNumberFormat::CreateRomanString( nNo, ( eType == css::style::NumberingType::ROMAN_UPPER ) );
775  else
776  aTmpStr.clear();
777  break;
778 
779  case css::style::NumberingType::NUMBER_NONE:
780  aTmpStr.clear();
781  break;
782 
783 // CHAR_SPECIAL:
784 // ????
785 
786 // case ARABIC: is default now
787  default:
788  aTmpStr = OUString::number(nNo);
789  break;
790  }
791 
792  if( css::style::NumberingType::CHARS_UPPER_LETTER == eType )
793  aTmpStr = aTmpStr.toAsciiUpperCase();
794  }
795  return aTmpStr;
796 }
797 
799  : aDateTime ( DateTime::EMPTY )
800 {
801  nPageNo = nTotalPages = 0;
803 }
804 
806  : ScEditEngineDefaulter( pEnginePoolP,true/*bDeleteEnginePoolP*/ )
807 {
808 }
809 
811  sal_Int32 /* nPara */, sal_Int32 /* nPos */,
812  std::optional<Color>& /* rTxtColor */, std::optional<Color>& /* rFldColor */ )
813 {
814  const SvxFieldData* pFieldData = rField.GetField();
815  if (!pFieldData)
816  return "?";
817 
818  OUString aRet;
819  sal_Int32 nClsId = pFieldData->GetClassId();
820  switch (nClsId)
821  {
822  case text::textfield::Type::PAGE:
824  break;
825  case text::textfield::Type::PAGES:
827  break;
828  case text::textfield::Type::EXTENDED_TIME:
829  case text::textfield::Type::TIME:
830  // For now, time field in the header / footer is always dynamic.
832  break;
833  case text::textfield::Type::DOCINFO_TITLE:
834  aRet = aData.aTitle;
835  break;
836  case text::textfield::Type::EXTENDED_FILE:
837  {
838  switch (static_cast<const SvxExtFileField*>(pFieldData)->GetFormat())
839  {
840  case SvxFileFormat::PathFull :
841  aRet = aData.aLongDocName;
842  break;
843  default:
844  aRet = aData.aShortDocName;
845  }
846  }
847  break;
849  aRet = aData.aTabName;
850  break;
853  break;
854  default:
855  aRet = "?";
856  }
857 
858  return aRet;
859 }
860 
861 // field data
862 
864  ScDocument* pDoc, SfxItemPool* pEnginePoolP,
865  SfxItemPool* pTextObjectPool, bool bDeleteEnginePoolP) :
866  ScEditEngineDefaulter( pEnginePoolP, bDeleteEnginePoolP ),
867  mpDoc(pDoc), bExecuteURL(true)
868 {
869  if ( pTextObjectPool )
870  SetEditTextObjectPool( pTextObjectPool );
871  SetControlWord( EEControlBits(GetControlWord() | EEControlBits::MARKFIELDS) & ~EEControlBits::RTFSTYLESHEETS );
872 }
873 
875  sal_Int32 /* nPara */, sal_Int32 /* nPos */,
876  std::optional<Color>& rTxtColor, std::optional<Color>& /* rFldColor */ )
877 {
878  const SvxFieldData* pFieldData = rField.GetField();
879 
880  if (!pFieldData)
881  return " ";
882 
883  return ScEditUtil::GetCellFieldValue(*pFieldData, mpDoc, &rTxtColor);
884 }
885 
887 {
888  if (!bExecuteURL)
889  return;
890  if (const SvxURLField* pURLField = dynamic_cast<const SvxURLField*>(rField.GetField()))
891  {
892  ScGlobal::OpenURL(pURLField->GetURL(), pURLField->GetTargetFrame());
893  }
894 }
895 
897  SfxItemPool* pTextObjectPool ) :
898  ScEditEngineDefaulter( pEnginePoolP, false/*bDeleteEnginePoolP*/ )
899 {
900  if ( pTextObjectPool )
901  SetEditTextObjectPool( pTextObjectPool );
902  SetControlWord( EEControlBits(GetControlWord() | EEControlBits::MARKFIELDS) & ~EEControlBits::RTFSTYLESHEETS );
903 }
904 
905 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
tools::Rectangle GetEditArea(const ScPatternAttr *pPattern, bool bForceToTop)
Definition: editutil.cxx:281
std::unique_ptr< SfxItemSet > pEditAttrs
Definition: editutil.hxx:91
virtual ~ScEditEngineDefaulter() override
Definition: editutil.cxx:494
OUString aLongDocName
Definition: editutil.hxx:205
constexpr double nPPTY
SCCOL GetColMerge() const
Definition: attrib.hxx:69
OUString GetText(LineEnd eEnd=LINEEND_LF) const
EEControlBits GetControlWord() const
URL aURL
Fraction aZoomX
Definition: editutil.hxx:47
Fraction aZoomY
Definition: editutil.hxx:48
static OUString CreateRomanString(sal_uLong nNo, bool bUpper)
void SetDefaults(const SfxItemSet &rDefaults, bool bRememberCopy=true)
Creates a copy of SfxItemSet if bRememberCopy set.
Definition: editutil.cxx:498
constexpr TypedWhichId< SvxAutoKernItem > EE_CHAR_PAIRKERNING(EE_CHAR_START+11)
SCTAB nTab
Definition: editutil.hxx:42
SCROW nRow
Definition: editutil.hxx:41
SfxItemSet * pDefaults
Definition: editutil.hxx:109
constexpr TypedWhichId< SvxKerningItem > EE_CHAR_KERNING(EE_CHAR_START+12)
constexpr TypedWhichId< ScPatternAttr > ATTR_PATTERN(156)
#define EMPTY_OUSTRING
Definition: global.hxx:216
OUString GetTitle(sal_uInt16 nMaxLen=0) const
const SfxItemSet & GetEmptyItemSet() const
void SetUpdateMode(bool bUpdate, bool bRestoring=false)
constexpr TypedWhichId< SfxBoolItem > ATTR_VERTICAL_ASIAN(137)
Point aCellPos
Definition: editutil.hxx:43
ScEditEngineDefaulter(SfxItemPool *pEnginePool, bool bDeleteEnginePool=false)
bDeleteEnginePool: Engine becomes the owner of the pool and deletes it on destruction ...
Definition: editutil.cxx:474
void QuickInsertField(const SvxFieldItem &rFld, const ESelection &rSel)
virtual OUString CalcFieldValue(const SvxFieldItem &rField, sal_Int32 nPara, sal_Int32 nPos, std::optional< Color > &rTxtColor, std::optional< Color > &rFldColor) override
Definition: editutil.cxx:874
long Long
static void OpenURL(const OUString &rURL, const OUString &rTarget, bool bIgnoreSettings=false)
Open the specified URL.
Definition: global.cxx:759
sal_Int16 nId
const SfxItemSet & GetItemSet() const
const MapMode & GetMapMode() const
ScFieldEditEngine(ScDocument *pDoc, SfxItemPool *pEnginePool, SfxItemPool *pTextObjectPool=nullptr, bool bDeleteEnginePool=false)
Definition: editutil.cxx:863
double nPPTY
Definition: editutil.hxx:46
sal_Int16 GetRightMargin() const
constexpr TypedWhichId< SvxFontItem > ATTR_FONT(100)
EEControlBits
static std::unique_ptr< EditTextObject > CreateURLObjectFromURL(ScDocument &rDoc, const OUString &rURL, const OUString &rText)
Definition: editutil.cxx:136
void SetMapMode()
bool HasOnlineSpellErrors() const
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT(EE_CHAR_START+2)
SfxItemSet GetAttribs(sal_Int32 nPara, sal_Int32 nStart, sal_Int32 nEnd, GetAttribsFlags nFlags=GetAttribsFlags::ALL) const
constexpr TypedWhichId< ScMergeAttr > ATTR_MERGE(144)
css::uno::Reference< css::document::XDocumentProperties > getDocProperties() const
SC_DLLPUBLIC sal_uInt16 GetRowHeight(SCROW nRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4159
SvxNumType
ScHeaderFieldData aData
Definition: editutil.hxx:220
constexpr TypedWhichId< ScIndentItem > ATTR_INDENT(131)
SC_DLLPUBLIC ScDocumentPool * GetPool()
Definition: document.cxx:6054
ScDocument * pDoc
Definition: editutil.hxx:39
virtual OUString CalcFieldValue(const SvxFieldItem &rField, sal_Int32 nPara, sal_Int32 nPos, std::optional< Color > &rTxtColor, std::optional< Color > &rFldColor) override
Definition: editutil.cxx:810
sal_uInt16 sal_Unicode
virtual ~ScEnginePoolHelper()
Definition: editutil.cxx:466
SvxCellVerJustify
ScNoteEditEngine(SfxItemPool *pEnginePool, SfxItemPool *pTextObjectPool)
Definition: editutil.cxx:896
void SetText(const OUString &rStr)
void SetControlWord(EEControlBits nWord)
SVX_NUM_ARABIC
Mutex aMutex
void Init(const ScPatternAttr &rPattern)
Definition: editutil.cxx:725
ScEditAttrTester(ScEditEngineDefaulter *pEng)
Definition: editutil.cxx:388
OUString aShortDocName
Definition: editutil.hxx:206
static OUString lcl_GetDelimitedString(const EditEngine &rEngine, const char c)
Definition: editutil.cxx:71
SC_DLLPUBLIC const ScPatternAttr * GetPattern(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4733
constexpr TypedWhichId< SvxWeightItem > EE_CHAR_WEIGHT(EE_CHAR_START+4)
OUString GetText(sal_Int32 nPara) const
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Definition: patattr.hxx:71
ocSep
#define SAL_N_ELEMENTS(arr)
bool IsUndoEnabled() const
constexpr double nPPTX
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:438
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
bool RemoveCharAttribs(sal_uInt16 nWhich)
static void GetFont(vcl::Font &rFont, const SfxItemSet &rItemSet, ScAutoFontColorMode eAutoMode, const OutputDevice *pOutDev=nullptr, const Fraction *pScale=nullptr, const SfxItemSet *pCondSet=nullptr, SvtScriptType nScript=SvtScriptType::NONE, const Color *pBackConfigColor=nullptr, const Color *pTextConfigColor=nullptr)
Static helper function to fill a font object from the passed item set.
Definition: patattr.cxx:216
static const OUString & GetNativeSymbol(OpCode eOp)
tools::Long nTotalPages
Definition: editutil.hxx:210
bool HasField(sal_Int32 nType=css::text::textfield::Type::UNSPECIFIED) const
void SetTextCurrentDefaults(const EditTextObject &rTextObject)
SetText and apply defaults already set.
Definition: editutil.cxx:555
static ScFieldEditEngine & GetStaticFieldEditEngine()
A static instance of ScFieldEditEngine not capable of resolving document specific fields...
Definition: global.cxx:1054
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
void SetDefaultItem(const SfxPoolItem &rItem)
Set the item in the default ItemSet which is created if it doesn't exist yet.
Definition: editutil.cxx:534
static INetURLHistory * GetOrCreate()
int i
Reference< XAnimationNode > Clone(const Reference< XAnimationNode > &xSourceNode, const SdPage *pSource, const SdPage *pTarget)
sal_uInt32 GetTextLen() const
sal_Int16 SCCOL
Definition: types.hxx:22
constexpr TypedWhichId< SvxVerJustifyItem > ATTR_VER_JUSTIFY(132)
sal_uLong GetScaledRowHeight(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, double fScale, const sal_uLong *pnMaxHeight=nullptr) const
Definition: document.cxx:4196
#define SC_MOD()
Definition: scmod.hxx:250
void RepeatDefaults()
Re-apply existing defaults if set, same as in SetText, but without EnableUndo/SetUpdateMode.
Definition: editutil.cxx:627
bool bInPrintTwips
Definition: editutil.hxx:49
sal_uInt16 Count() const
OUString aTabName
Definition: editutil.hxx:207
std::unique_ptr< EditTextObject > CreateTextObject()
ScHeaderEditEngine(SfxItemPool *pEnginePool)
Definition: editutil.cxx:805
constexpr sal_uInt16 EE_CHAR_START(EE_PARA_END+1)
OUString GetFormatted(SvNumberFormatter &rFormatter, LanguageType eLanguage) const
const OUString & GetRepresentation() const
constexpr TypedWhichId< ScVerticalStackCell > ATTR_STACKED(134)
constexpr sal_uInt16 EE_CHAR_END(EE_CHAR_START+32)
static OUString lcl_GetNumStr(sal_Int32 nNo, SvxNumType eType)
Definition: editutil.cxx:759
static SC_DLLPUBLIC LanguageType eLnge
Definition: global.hxx:549
void SetDefaultLanguage(LanguageType eLang)
const SfxPoolItem & GetDefaultItem(sal_uInt16 nWhich) const
SfxItemPool * GetPool() const
sal_Int16 GetBottomMargin() const
static LanguageType GetEditDefaultLanguage()
Definition: global.cxx:858
sal_Int32 GetParagraphCount() const
static OUString GetCellFieldValue(const SvxFieldData &rFieldData, const ScDocument *pDoc, std::optional< Color > *ppTextColor)
Definition: editutil.cxx:194
ScEditUtil(ScDocument *pDocument, SCCOL nX, SCROW nY, SCTAB nZ, const Point &rCellPos, OutputDevice *pDevice, double nScaleX, double nScaleY, const Fraction &rX, const Fraction &rY, bool bPrintTwips=false)
Definition: editutil.cxx:53
const OUString & GetURL() const
virtual sal_Int32 GetClassId() const
bool QueryUrl(const INetURLObject &rUrl)
sal_Int32 GetParagraphCount() const
static SC_DLLPUBLIC const LocaleDataWrapper * getLocaleDataPtr()
Definition: global.cxx:1000
constexpr sal_uInt16 EE_FEATURE_NOTCONV(EE_FEATURE_LINEBR+1)
OUString getDate(const Date &rDate) const
void SetRefMapMode(const MapMode &rMapMode)
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
sal_Int32 SCROW
Definition: types.hxx:18
static void Free(SfxItemPool *pPool)
tools::Long const nTopMargin
SfxItemState
SfxItemPool * pEnginePool
Definition: editutil.hxx:108
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
constexpr TypedWhichId< SvxEscapementItem > EE_CHAR_ESCAPEMENT(EE_CHAR_START+10)
void SetFont(const vcl::Font &rNewFont)
double nPPTX
Definition: editutil.hxx:45
bool GetUpdateMode() const
virtual void FieldClicked(const SvxFieldItem &rField) override
Definition: editutil.cxx:886
tools::Long GetTextHeight() const
OUString aName
constexpr TypedWhichId< SvxColorItem > EE_CHAR_COLOR(EE_CHAR_START+0)
void EnableUndo(bool bEnable)
void GetPortions(sal_Int32 nPara, std::vector< sal_Int32 > &rList)
static OUString ModifyDelimiters(const OUString &rOld)
Definition: editutil.cxx:62
sal_Int16 GetLeftMargin() const
const SfxItemSet & GetDefaults()
Returns the stored defaults, used to find non-default character attributes.
Definition: editutil.cxx:545
constexpr TypedWhichId< SvxWeightItem > ATTR_FONT_WEIGHT(102)
constexpr TypedWhichId< SvxHorJustifyItem > ATTR_HOR_JUSTIFY(129)
ScEnginePoolHelper(SfxItemPool *pEnginePool, bool bDeleteEnginePool)
Definition: editutil.cxx:447
void QuickSetAttribs(const SfxItemSet &rSet, const ESelection &rSel)
tools::Long GetNeededSize(SCCOL nCol, SCROW nRow, SCTAB nTab, OutputDevice *pDev, double nPPTX, double nPPTY, const Fraction &rZoomX, const Fraction &rZoomY, bool bWidth, bool bTotalSize=false, bool bInPrintTwips=false)
Definition: document.cxx:4251
Reference< XComponentContext > getProcessComponentContext()
#define EE_TEXTPOS_MAX_COUNT
ScTabEditEngine(ScDocument *pDoc)
Definition: editutil.cxx:709
static OUString lcl_GetCharStr(sal_Int32 nNo)
Definition: editutil.cxx:739
DateTime aDateTime
Definition: editutil.hxx:208
constexpr TypedWhichId< SvxFontItem > EE_CHAR_FONTINFO(EE_CHAR_START+1)
static OUString GetSpaceDelimitedString(const EditEngine &rEngine)
Retrieves string with paragraphs delimited by spaces.
Definition: editutil.cxx:97
static void RemoveCharAttribs(EditTextObject &rEditText, const ScPatternAttr &rAttr)
Definition: editutil.cxx:147
SC_DLLPUBLIC SfxItemPool * GetEditPool() const
Definition: documen2.cxx:444
int GetTab() const
SC_DLLPUBLIC bool IsLayoutRTL(SCTAB nTab) const
Definition: document.cxx:992
tools::Long nPageNo
Definition: editutil.hxx:209
static SC_DLLPUBLIC OUString GetString(const EditTextObject &rEditText, const ScDocument *pDoc)
Retrieves string with paragraphs delimited by new lines (' ').
Definition: editutil.cxx:111
const sal_uInt16 * GetRanges() const
virtual void SetParaAttribs(sal_Int32 nPara, const SfxItemSet &rSet)
ScDocument * mpDoc
Definition: editutil.hxx:176
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1055
static std::unique_ptr< EditTextObject > Clone(const EditTextObject &rSrc, ScDocument &rDestDoc)
Definition: editutil.cxx:168
VclPtr< OutputDevice > pDev
Definition: editutil.hxx:44
SCCOL nCol
Definition: editutil.hxx:40
constexpr sal_uInt16 EE_FEATURE_FIELD(EE_FEATURE_NOTCONV+1)
SCROW GetRowMerge() const
Definition: attrib.hxx:70
SvxNumType eNumType
Definition: editutil.hxx:211
OUString getTime(const tools::Time &rTime, bool bSec=true, bool b100Sec=false) const
#define EE_PARA_MAX_COUNT
SC_DLLPUBLIC sal_uInt16 GetColWidth(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4118
constexpr TypedWhichId< SvxColorItem > ATTR_FONT_COLOR(109)
void SetTextNewDefaults(const EditTextObject &rTextObject, const SfxItemSet &rDefaults, bool bRememberCopy=true)
Current defaults are not applied, new defaults are applied.
Definition: editutil.cxx:567
constexpr TypedWhichId< SvxFontHeightItem > ATTR_FONT_HEIGHT(101)
void RemoveParaAttribs()
Paragraph attributes that are not defaults are copied to character attributes and all paragraph attri...
Definition: editutil.cxx:637
static OUString GetMultilineString(const EditEngine &rEngine)
Retrieves string with paragraphs delimited by new lines (' ').
Definition: editutil.cxx:101
aStr
SC_DLLPUBLIC bool GetName(SCTAB nTab, OUString &rName) const
Definition: document.cxx:211
void SetEditTextObjectPool(SfxItemPool *pPool)
SC_DLLPUBLIC ScFieldEditEngine & GetEditEngine()
Definition: documen2.cxx:454
const SfxItemSet & GetParaAttribs(sal_Int32 nPara) const
constexpr TypedWhichId< SvXMLAttrContainerItem > EE_CHAR_XMLATTRIBS(EE_CHAR_START+28)
sal_Int16 SCTAB
Definition: types.hxx:23
constexpr TypedWhichId< SvxMarginItem > ATTR_MARGIN(143)
const SvxFieldData * GetField() const
void FillEditItemSet(SfxItemSet *pEditSet, const SfxItemSet *pCondSet=nullptr) const
Converts all Calc items contained in the own item set to edit engine items and puts them into pEditSe...
Definition: patattr.cxx:776
SvxURLFormat GetFormat() const
sal_Int16 GetTopMargin() const