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