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