LibreOffice Module sc (master)  1
viewfunc.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 <config_features.h>
21 
22 #include <scitems.hxx>
23 
24 #include <sfx2/app.hxx>
25 #include <svx/algitem.hxx>
26 #include <editeng/boxitem.hxx>
27 #include <editeng/editobj.hxx>
28 #include <editeng/langitem.hxx>
29 #include <editeng/shaditem.hxx>
30 #include <editeng/justifyitem.hxx>
31 #include <sfx2/bindings.hxx>
32 #include <svl/zforlist.hxx>
33 #include <svl/zformat.hxx>
34 #include <vcl/svapp.hxx>
35 #include <vcl/weld.hxx>
36 #include <vcl/virdev.hxx>
37 #include <vcl/waitobj.hxx>
38 #include <stdlib.h>
39 #include <unotools/charclass.hxx>
40 #include <vcl/uitest/logger.hxx>
42 
43 #include <viewfunc.hxx>
44 #include <tabvwsh.hxx>
45 #include <docsh.hxx>
46 #include <attrib.hxx>
47 #include <patattr.hxx>
48 #include <docpool.hxx>
49 #include <sc.hrc>
50 #include <strings.hrc>
51 #include <undocell.hxx>
52 #include <undoblk.hxx>
53 #include <refundo.hxx>
54 #include <olinetab.hxx>
55 #include <rangenam.hxx>
56 #include <globstr.hrc>
57 #include <global.hxx>
58 #include <stlsheet.hxx>
59 #include <editutil.hxx>
60 #include <formulacell.hxx>
61 #include <scresid.hxx>
62 #include <inputhdl.hxx>
63 #include <scmod.hxx>
64 #include <inputopt.hxx>
65 #include <compiler.hxx>
66 #include <docfunc.hxx>
67 #include <appoptio.hxx>
68 #include <sizedev.hxx>
69 #include <editable.hxx>
70 #include <scui_def.hxx>
71 #include <funcdesc.hxx>
72 #include <docuno.hxx>
73 #include <cellsuno.hxx>
74 #include <tokenarray.hxx>
75 #include <rowheightcontext.hxx>
76 #include <comphelper/lok.hxx>
77 #include <conditio.hxx>
78 #include <columnspanset.hxx>
79 
80 #include <memory>
81 
82 static void lcl_PostRepaintCondFormat( const ScConditionalFormat *pCondFmt, ScDocShell *pDocSh )
83 {
84  if( pCondFmt )
85  {
86  const ScRangeList& rRanges = pCondFmt->GetRange();
87 
88  pDocSh->PostPaint( rRanges, PaintPartFlags::All );
89  }
90 }
91 
92 ScViewFunc::ScViewFunc( vcl::Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
93  ScTabView( pParent, rDocSh, pViewShell ),
94  bFormatValid( false )
95 {
96 }
97 
99 {
100 }
101 
102 namespace {
103 
104 void collectUIInformation(const std::map<OUString, OUString>& aParameters, const OUString& rAction)
105 {
106  EventDescription aDescription;
107  aDescription.aID = "grid_window";
108  aDescription.aAction = rAction;
109  aDescription.aParameters = aParameters;
110  aDescription.aParent = "MainWindow";
111  aDescription.aKeyWord = "ScGridWinUIObject";
112 
113  UITestLogger::getInstance().logEvent(aDescription);
114 }
115 
116 }
117 
119 {
120  // anything to do?
121  if ( !SC_MOD()->GetInputOptions().GetExtendFormat() )
122  return;
123 
124  // start only with single cell (marked or cursor position)
125  ScRange aMarkRange;
126  bool bOk = (GetViewData().GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE);
127  if ( bOk && aMarkRange.aStart != aMarkRange.aEnd )
128  bOk = false;
129 
130  if (bOk)
131  {
132  bFormatValid = true;
133  aFormatSource = aMarkRange.aStart;
135  }
136  else
137  bFormatValid = false; // discard old range
138 }
139 
140 bool ScViewFunc::TestFormatArea( SCCOL nCol, SCROW nRow, SCTAB nTab, bool bAttrChanged )
141 {
142  // anything to do?
143  if ( !SC_MOD()->GetInputOptions().GetExtendFormat() )
144  return false;
145 
146  // Test: treat input with numberformat (bAttrChanged) always as new Attribute
147  // (discard old Area ). If not wanted, discard if-statement
148  if ( bAttrChanged )
149  {
150  StartFormatArea();
151  return false;
152  }
153 
155 
156  bool bFound = false;
157  ScRange aNewRange = aFormatArea;
158  if ( bFormatValid && nTab == aFormatSource.Tab() )
159  {
160  if ( nRow >= aFormatArea.aStart.Row() && nRow <= aFormatArea.aEnd.Row() )
161  {
162  // within range?
163  if ( nCol >= aFormatArea.aStart.Col() && nCol <= aFormatArea.aEnd.Col() )
164  {
165  bFound = true; // do not change range
166  }
167  // left ?
168  if ( nCol+1 == aFormatArea.aStart.Col() )
169  {
170  bFound = true;
171  aNewRange.aStart.SetCol( nCol );
172  }
173  // right ?
174  if ( nCol == aFormatArea.aEnd.Col()+1 )
175  {
176  bFound = true;
177  aNewRange.aEnd.SetCol( nCol );
178  }
179  }
180  if ( nCol >= aFormatArea.aStart.Col() && nCol <= aFormatArea.aEnd.Col() )
181  {
182  // top ?
183  if ( nRow+1 == aFormatArea.aStart.Row() )
184  {
185  bFound = true;
186  aNewRange.aStart.SetRow( nRow );
187  }
188  // bottom ?
189  if ( nRow == aFormatArea.aEnd.Row()+1 )
190  {
191  bFound = true;
192  aNewRange.aEnd.SetRow( nRow );
193  }
194  }
195  }
196 
197  if (bFound)
198  aFormatArea = aNewRange; // extend
199  else
200  bFormatValid = false; // outside of range -> break
201 
202  return bFound;
203 }
204 
206  bool bAttrChanged )
207 {
208  ScDocShell* pDocSh = GetViewData().GetDocShell();
209  ScDocument& rDoc = pDocSh->GetDocument();
210 
211  const ScPatternAttr* pSource = rDoc.GetPattern(
212  aFormatSource.Col(), aFormatSource.Row(), nTab );
213  if ( !pSource->GetItem(ATTR_MERGE).IsMerged() )
214  {
215  ScRange aRange( nCol, nRow, nTab, nCol, nRow, nTab );
216  ScMarkData aMark(rDoc.GetSheetLimits());
217  aMark.SetMarkArea( aRange );
218 
219  ScDocFunc &rFunc = GetViewData().GetDocFunc();
220 
221  // pOldPattern is only valid until call to ApplyAttributes!
222  const ScPatternAttr* pOldPattern = rDoc.GetPattern( nCol, nRow, nTab );
223  const ScStyleSheet* pSrcStyle = pSource->GetStyleSheet();
224  if ( pSrcStyle && pSrcStyle != pOldPattern->GetStyleSheet() )
225  rFunc.ApplyStyle( aMark, pSrcStyle->GetName(), false );
226 
227  rFunc.ApplyAttributes( aMark, *pSource, false );
228  }
229 
230  if ( bAttrChanged ) // value entered with number format?
231  aFormatSource.Set( nCol, nRow, nTab ); // then set a new source
232 }
233 
234 // additional routines
235 
236 sal_uInt16 ScViewFunc::GetOptimalColWidth( SCCOL nCol, SCTAB nTab, bool bFormula )
237 {
238  ScDocShell* pDocSh = GetViewData().GetDocShell();
239  ScDocument& rDoc = pDocSh->GetDocument();
240  ScMarkData& rMark = GetViewData().GetMarkData();
241 
242  double nPPTX = GetViewData().GetPPTX();
243  double nPPTY = GetViewData().GetPPTY();
244  Fraction aZoomX = GetViewData().GetZoomX();
245  Fraction aZoomY = GetViewData().GetZoomY();
246 
247  ScSizeDeviceProvider aProv(pDocSh);
248  if (aProv.IsPrinter())
249  {
250  nPPTX = aProv.GetPPTX();
251  nPPTY = aProv.GetPPTY();
252  aZoomX = aZoomY = Fraction( 1, 1 );
253  }
254 
255  sal_uInt16 nTwips = rDoc.GetOptimalColWidth( nCol, nTab, aProv.GetDevice(),
256  nPPTX, nPPTY, aZoomX, aZoomY, bFormula, &rMark );
257  return nTwips;
258 }
259 
260 bool ScViewFunc::SelectionEditable( bool* pOnlyNotBecauseOfMatrix /* = NULL */ )
261 {
262  bool bRet;
263  ScDocument& rDoc = GetViewData().GetDocument();
264  ScMarkData& rMark = GetViewData().GetMarkData();
265  if (rMark.IsMarked() || rMark.IsMultiMarked())
266  bRet = rDoc.IsSelectionEditable( rMark, pOnlyNotBecauseOfMatrix );
267  else
268  {
269  SCCOL nCol = GetViewData().GetCurX();
270  SCROW nRow = GetViewData().GetCurY();
271  SCTAB nTab = GetViewData().GetTabNo();
272  bRet = rDoc.IsBlockEditable( nTab, nCol, nRow, nCol, nRow,
273  pOnlyNotBecauseOfMatrix );
274  }
275  return bRet;
276 }
277 
278 static bool lcl_FunctionKnown( sal_uInt16 nOpCode )
279 {
281  if ( pFuncList )
282  {
283  sal_uLong nCount = pFuncList->GetCount();
284  for (sal_uLong i=0; i<nCount; i++)
285  if ( pFuncList->GetFunction(i)->nFIndex == nOpCode )
286  return true;
287  }
288  return false;
289 }
290 
291 static bool lcl_AddFunction( ScAppOptions& rAppOpt, sal_uInt16 nOpCode )
292 {
293  sal_uInt16 nOldCount = rAppOpt.GetLRUFuncListCount();
294  sal_uInt16* pOldList = rAppOpt.GetLRUFuncList();
295  sal_uInt16 nPos;
296  for (nPos=0; nPos<nOldCount; nPos++)
297  if (pOldList[nPos] == nOpCode) // is the function already in the list?
298  {
299  if ( nPos == 0 )
300  return false; // already at the top -> no change
301 
302  // count doesn't change, so the original array is modified
303 
304  for (sal_uInt16 nCopy=nPos; nCopy>0; nCopy--)
305  pOldList[nCopy] = pOldList[nCopy-1];
306  pOldList[0] = nOpCode;
307 
308  return true; // list has changed
309  }
310 
311  if ( !lcl_FunctionKnown( nOpCode ) )
312  return false; // not in function list -> no change
313 
314  sal_uInt16 nNewCount = std::min( static_cast<sal_uInt16>(nOldCount + 1), sal_uInt16(LRU_MAX) );
315  sal_uInt16 nNewList[LRU_MAX];
316  nNewList[0] = nOpCode;
317  for (nPos=1; nPos<nNewCount; nPos++)
318  nNewList[nPos] = pOldList[nPos-1];
319  rAppOpt.SetLRUFuncList( nNewList, nNewCount );
320 
321  return true; // list has changed
322 }
323 
324 namespace HelperNotifyChanges
325 {
326  static void NotifyIfChangesListeners(const ScDocShell &rDocShell, ScMarkData& rMark, SCCOL nCol, SCROW nRow)
327  {
328  if (ScModelObj *pModelObj = getMustPropagateChangesModel(rDocShell))
329  {
330  ScRangeList aChangeRanges;
331  for (const auto& rTab : rMark)
332  aChangeRanges.push_back( ScRange( nCol, nRow, rTab ) );
333 
334  HelperNotifyChanges::Notify(*pModelObj, aChangeRanges, "cell-change");
335  }
336  }
337 }
338 
339 // actual functions
340 
341 // input - undo OK
342 void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab,
343  const OUString& rString,
344  const EditTextObject* pData )
345 {
346  ScDocument& rDoc = GetViewData().GetDocument();
347  ScMarkData rMark(GetViewData().GetMarkData());
348  bool bRecord = rDoc.IsUndoEnabled();
349  SCTAB i;
350 
351  ScDocShell* pDocSh = GetViewData().GetDocShell();
352  ScDocFunc &rFunc = GetViewData().GetDocFunc();
353  ScDocShellModificator aModificator( *pDocSh );
354 
355  ScEditableTester aTester( rDoc, nCol,nRow, nCol,nRow, rMark );
356  if (!aTester.IsEditable())
357  {
358  ErrorMessage(aTester.GetMessageId());
359  PaintArea(nCol, nRow, nCol, nRow); // possibly the edit-engine is still painted there
360  return;
361  }
362 
363  if ( bRecord )
364  rFunc.EnterListAction( STR_UNDO_ENTERDATA );
365 
366  bool bFormula = false;
367 
368  // a single '=' character is handled as string (needed for special filters)
369  if ( rString.getLength() > 1 )
370  {
371  if ( rString[0] == '=' )
372  {
373  // handle as formula
374  bFormula = true;
375  }
376  else if ( rString[0] == '+' || rString[0] == '-' )
377  {
378  // if there is more than one leading '+' or '-' character, remove the additional ones
379  sal_Int32 nIndex = 1;
380  sal_Int32 nLen = rString.getLength();
381  while ( nIndex < nLen && ( rString[ nIndex ] == '+' || rString[ nIndex ] == '-' ) )
382  {
383  ++nIndex;
384  }
385  OUString aString = rString.replaceAt( 1, nIndex - 1, "" );
386 
387  // if the remaining part without the leading '+' or '-' character
388  // is non-empty and not a number, handle as formula
389  if ( aString.getLength() > 1 )
390  {
391  sal_uInt32 nFormat = 0;
392  rDoc.GetNumberFormat( nCol, nRow, nTab, nFormat );
393  SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
394  double fNumber = 0;
395  if ( !pFormatter->IsNumberFormat( aString, nFormat, fNumber ) )
396  {
397  bFormula = true;
398  }
399  }
400  }
401  }
402 
403  bool bNumFmtChanged = false;
404  if ( bFormula )
405  { // formula, compile with autoCorrection
406  i = rMark.GetFirstSelected();
407  ScAddress aPos( nCol, nRow, i );
408  ScCompiler aComp( rDoc, aPos, rDoc.GetGrammar(), true, false );
409 //2do: enable/disable autoCorrection via calcoptions
410  aComp.SetAutoCorrection( true );
411  if ( rString[0] == '+' || rString[0] == '-' )
412  {
413  aComp.SetExtendedErrorDetection( ScCompiler::EXTENDED_ERROR_DETECTION_NAME_BREAK );
414  }
415  OUString aFormula( rString );
416  std::unique_ptr< ScTokenArray > pArr;
417  bool bAgain;
418  do
419  {
420  bAgain = false;
421  bool bAddEqual = false;
422  pArr = aComp.CompileString( aFormula );
423  bool bCorrected = aComp.IsCorrected();
424  std::unique_ptr< ScTokenArray > pArrFirst;
425  if ( bCorrected )
426  { // try to parse with first parser-correction
427  pArrFirst = std::move( pArr );
428  pArr = aComp.CompileString( aComp.GetCorrectedFormula() );
429  }
430  if ( pArr->GetCodeError() == FormulaError::NONE )
431  {
432  bAddEqual = true;
433  aComp.CompileTokenArray();
434  bCorrected |= aComp.IsCorrected();
435  }
436  if ( bCorrected )
437  {
438  OUString aCorrectedFormula;
439  if ( bAddEqual )
440  {
441  aCorrectedFormula = "=" + aComp.GetCorrectedFormula();
442  }
443  else
444  aCorrectedFormula = aComp.GetCorrectedFormula();
445  short nResult;
446  if ( aCorrectedFormula.getLength() == 1 )
447  nResult = RET_NO; // empty formula, just '='
448  else
449  {
450  OUString aMessage = ScResId( SCSTR_FORMULA_AUTOCORRECTION ) + aCorrectedFormula;
451 
452  std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetViewData().GetDialogParent(),
453  VclMessageType::Question, VclButtonsType::YesNo,
454  aMessage));
455  xQueryBox->set_default_response(RET_YES);
456  nResult = xQueryBox->run();
457  }
458  if ( nResult == RET_YES )
459  {
460  aFormula = aCorrectedFormula;
461  bAgain = true;
462  }
463  else
464  {
465  if ( pArrFirst )
466  pArr = std::move( pArrFirst );
467  }
468  }
469  } while ( bAgain );
470  // to be used in multiple tabs, the formula must be compiled anew
471  // via ScFormulaCell copy-ctor because of RangeNames,
472  // the same code-array for all cells is not possible.
473  // If the array has an error, (it) must be RPN-erased in the newly generated
474  // cells and the error be set explicitly, so that
475  // via FormulaCell copy-ctor and Interpreter it will be, when possible,
476  // ironed out again, too intelligent... e.g.: =1))
477  FormulaError nError = pArr->GetCodeError();
478  if ( nError == FormulaError::NONE )
479  {
480  // update list of recent functions with all functions that
481  // are not within parentheses
482 
483  ScModule* pScMod = SC_MOD();
484  ScAppOptions aAppOpt = pScMod->GetAppOptions();
485  bool bOptChanged = false;
486 
487  formula::FormulaToken** ppToken = pArr->GetArray();
488  sal_uInt16 nTokens = pArr->GetLen();
489  sal_uInt16 nLevel = 0;
490  for (sal_uInt16 nTP=0; nTP<nTokens; nTP++)
491  {
492  formula::FormulaToken* pTok = ppToken[nTP];
493  OpCode eOp = pTok->GetOpCode();
494  if ( eOp == ocOpen )
495  ++nLevel;
496  else if ( eOp == ocClose && nLevel )
497  --nLevel;
498  if ( nLevel == 0 && pTok->IsFunction() &&
499  lcl_AddFunction( aAppOpt, sal::static_int_cast<sal_uInt16>( eOp ) ) )
500  bOptChanged = true;
501  }
502 
503  if ( bOptChanged )
504  {
505  pScMod->SetAppOptions(aAppOpt);
506  }
507  }
508 
509  ScFormulaCell aCell(rDoc, aPos, std::move( pArr ), formula::FormulaGrammar::GRAM_DEFAULT, ScMatrixMode::NONE);
510 
511  SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
512  for (const auto& rTab : rMark)
513  {
514  i = rTab;
515  aPos.SetTab( i );
516  const sal_uInt32 nIndex = rDoc.GetAttr(
517  nCol, nRow, i, ATTR_VALUE_FORMAT )->GetValue();
518  const SvNumFormatType nType = pFormatter->GetType( nIndex);
519  if (nType == SvNumFormatType::TEXT ||
520  ((rString[0] == '+' || rString[0] == '-') && nError != FormulaError::NONE && rString == aFormula))
521  {
522  if ( pData )
523  {
524  // A clone of pData will be stored in the cell.
525  rFunc.SetEditCell(aPos, *pData, true);
526  }
527  else
528  rFunc.SetStringCell(aPos, aFormula, true);
529  }
530  else
531  {
532  ScFormulaCell* pCell = new ScFormulaCell( aCell, rDoc, aPos );
533  if ( nError != FormulaError::NONE )
534  {
535  pCell->GetCode()->DelRPN();
536  pCell->SetErrCode( nError );
537  if(pCell->GetCode()->IsHyperLink())
538  pCell->GetCode()->SetHyperLink(false);
539  }
540  if (nType == SvNumFormatType::LOGICAL)
541  {
542  // Reset to General so the actual format can be determined
543  // after the cell has been interpreted. A sticky boolean
544  // number format is highly likely unwanted... see tdf#75650.
545  // General of same locale as current number format.
546  const SvNumberformat* pEntry = pFormatter->GetEntry( nIndex);
547  const LanguageType nLang = (pEntry ? pEntry->GetLanguage() : ScGlobal::eLnge);
548  const sal_uInt32 nFormat = pFormatter->GetStandardFormat( SvNumFormatType::NUMBER, nLang);
549  ScPatternAttr aPattern( rDoc.GetPool());
550  aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nFormat));
551  ScMarkData aMark(rDoc.GetSheetLimits());
552  aMark.SelectTable( i, true);
553  aMark.SetMarkArea( ScRange( aPos));
554  rFunc.ApplyAttributes( aMark, aPattern, false);
555  bNumFmtChanged = true;
556  }
557  rFunc.SetFormulaCell(aPos, pCell, true);
558  }
559  }
560  }
561  else
562  {
563  for (const auto& rTab : rMark)
564  {
565  bool bNumFmtSet = false;
566  rFunc.SetNormalString( bNumFmtSet, ScAddress( nCol, nRow, rTab ), rString, false );
567  if (bNumFmtSet)
568  {
569  /* FIXME: if set on any sheet results in changed only on
570  * sheet nTab for TestFormatArea() and DoAutoAttributes() */
571  bNumFmtChanged = true;
572  }
573  }
574  }
575 
576  bool bAutoFormat = TestFormatArea(nCol, nRow, nTab, bNumFmtChanged);
577 
578  if (bAutoFormat)
579  DoAutoAttributes(nCol, nRow, nTab, bNumFmtChanged);
580 
581  pDocSh->UpdateOle(GetViewData());
582 
583  HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh, rMark, nCol, nRow);
584 
585  if ( bRecord )
586  rFunc.EndListAction();
587 
588  aModificator.SetDocumentModified();
589  lcl_PostRepaintCondFormat( rDoc.GetCondFormat( nCol, nRow, nTab ), pDocSh );
590 }
591 
592 // enter value in single cell (on nTab only)
593 
594 void ScViewFunc::EnterValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rValue )
595 {
596  ScDocument& rDoc = GetViewData().GetDocument();
597  ScDocShell* pDocSh = GetViewData().GetDocShell();
598 
599  if (!pDocSh)
600  return;
601 
602  bool bUndo(rDoc.IsUndoEnabled());
603  ScDocShellModificator aModificator( *pDocSh );
604 
605  ScEditableTester aTester( rDoc, nTab, nCol,nRow, nCol,nRow );
606  if (aTester.IsEditable())
607  {
608  ScAddress aPos( nCol, nRow, nTab );
609  ScCellValue aUndoCell;
610  if (bUndo)
611  aUndoCell.assign(rDoc, aPos);
612 
613  rDoc.SetValue( nCol, nRow, nTab, rValue );
614 
615  // because of ChangeTrack after change in document
616  if (bUndo)
617  {
618  pDocSh->GetUndoManager()->AddUndoAction(
619  std::make_unique<ScUndoEnterValue>(pDocSh, aPos, aUndoCell, rValue));
620  }
621 
622  pDocSh->PostPaintCell( aPos );
623  pDocSh->UpdateOle(GetViewData());
624  aModificator.SetDocumentModified();
625  }
626  else
627  ErrorMessage(aTester.GetMessageId());
628 }
629 
630 void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab,
631  const EditTextObject& rData, bool bTestSimple )
632 {
633  ScDocShell* pDocSh = GetViewData().GetDocShell();
634  ScMarkData& rMark = GetViewData().GetMarkData();
635  ScDocument& rDoc = pDocSh->GetDocument();
636  bool bRecord = rDoc.IsUndoEnabled();
637 
638  ScDocShellModificator aModificator( *pDocSh );
639 
640  ScEditableTester aTester( rDoc, nTab, nCol,nRow, nCol,nRow );
641  if (aTester.IsEditable())
642  {
643 
644  // test for attribute
645 
646  bool bSimple = false;
647  bool bCommon = false;
648  std::unique_ptr<ScPatternAttr> pCellAttrs;
649  OUString aString;
650 
651  const ScPatternAttr* pOldPattern = rDoc.GetPattern( nCol, nRow, nTab );
652  ScTabEditEngine aEngine( *pOldPattern, rDoc.GetEnginePool(), &rDoc );
653  aEngine.SetTextCurrentDefaults(rData);
654 
655  if (bTestSimple) // test, if simple string without attribute
656  {
657  ScEditAttrTester aAttrTester( &aEngine );
658  bSimple = !aAttrTester.NeedsObject();
659  bCommon = aAttrTester.NeedsCellAttr();
660 
661  // formulas have to be recognized even if they're formatted
662  // (but common attributes are still collected)
663 
664  if ( !bSimple && aEngine.GetParagraphCount() == 1 )
665  {
666  OUString aParStr(aEngine.GetText( 0 ));
667  if ( aParStr[0] == '=' )
668  bSimple = true;
669  }
670 
671  if (bCommon) // attribute for tab
672  {
673  pCellAttrs.reset(new ScPatternAttr( *pOldPattern ));
674  pCellAttrs->GetFromEditItemSet( &aAttrTester.GetAttribs() );
676  }
677  }
678 
679  // #i97726# always get text for "repeat" of undo action
680  aString = ScEditUtil::GetSpaceDelimitedString(aEngine);
681 
682  // undo
683 
684  std::unique_ptr<EditTextObject> pUndoData;
685  ScUndoEnterData::ValuesType aOldValues;
686 
687  if (bRecord && !bSimple)
688  {
689  for (const auto& rTab : rMark)
690  {
691  ScUndoEnterData::Value aOldValue;
692  aOldValue.mnTab = rTab;
693  aOldValue.maCell.assign(rDoc, ScAddress(nCol, nRow, rTab));
694  aOldValues.push_back(aOldValue);
695  }
696 
697  pUndoData = rData.Clone();
698  }
699 
700  // enter data
701 
702  if (bCommon)
703  rDoc.ApplyPattern(nCol,nRow,nTab,*pCellAttrs);
704 
705  if (bSimple)
706  {
707  if (bCommon)
708  AdjustRowHeight(nRow,nRow);
709 
710  EnterData(nCol,nRow,nTab,aString);
711  }
712  else
713  {
714  for (const auto& rTab : rMark)
715  {
716  ScAddress aPos(nCol, nRow, rTab);
717  rDoc.SetEditText(aPos, rData, rDoc.GetEditPool());
718  }
719 
720  if ( bRecord )
721  { // because of ChangeTrack current first
722  pDocSh->GetUndoManager()->AddUndoAction(
723  std::make_unique<ScUndoEnterData>(pDocSh, ScAddress(nCol,nRow,nTab), aOldValues, aString, std::move(pUndoData)));
724  }
725 
726  HideAllCursors();
727 
728  AdjustRowHeight(nRow,nRow);
729 
730  for (const auto& rTab : rMark)
731  pDocSh->PostPaintCell( nCol, nRow, rTab );
732 
733  ShowAllCursors();
734 
735  pDocSh->UpdateOle(GetViewData());
736 
737  HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh, rMark, nCol, nRow);
738 
739  aModificator.SetDocumentModified();
740  }
741  lcl_PostRepaintCondFormat( rDoc.GetCondFormat( nCol, nRow, nTab ), pDocSh );
742  }
743  else
744  {
745  ErrorMessage(aTester.GetMessageId());
746  PaintArea( nCol, nRow, nCol, nRow ); // possibly the edit-engine is still painted there
747  }
748 }
749 
750 void ScViewFunc::EnterDataAtCursor( const OUString& rString )
751 {
752  SCCOL nPosX = GetViewData().GetCurX();
753  SCROW nPosY = GetViewData().GetCurY();
754  SCTAB nTab = GetViewData().GetTabNo();
755 
756  EnterData( nPosX, nPosY, nTab, rString );
757 }
758 
759 void ScViewFunc::EnterMatrix( const OUString& rString, ::formula::FormulaGrammar::Grammar eGram )
760 {
762  const SCCOL nCol = rData.GetCurX();
763  const SCROW nRow = rData.GetCurY();
764  const ScMarkData& rMark = rData.GetMarkData();
765  if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
766  {
767  // nothing marked -> temporarily calculate block
768  // with size of result formula to get the size
769 
770  ScDocument& rDoc = rData.GetDocument();
771  SCTAB nTab = rData.GetTabNo();
772  ScFormulaCell aFormCell( rDoc, ScAddress(nCol,nRow,nTab), rString, eGram, ScMatrixMode::Formula );
773 
774  SCSIZE nSizeX;
775  SCSIZE nSizeY;
776  aFormCell.GetResultDimensions( nSizeX, nSizeY );
777  if ( nSizeX != 0 && nSizeY != 0 &&
778  nCol+nSizeX-1 <= sal::static_int_cast<SCSIZE>(rDoc.MaxCol()) &&
779  nRow+nSizeY-1 <= sal::static_int_cast<SCSIZE>(rDoc.MaxRow()) )
780  {
781  ScRange aResult( nCol, nRow, nTab,
782  sal::static_int_cast<SCCOL>(nCol+nSizeX-1),
783  sal::static_int_cast<SCROW>(nRow+nSizeY-1), nTab );
784  MarkRange( aResult, false );
785  }
786  }
787 
788  ScRange aRange;
789  if (rData.GetSimpleArea(aRange) == SC_MARK_SIMPLE)
790  {
791  ScDocShell* pDocSh = rData.GetDocShell();
792  bool bSuccess = pDocSh->GetDocFunc().EnterMatrix(
793  aRange, &rMark, nullptr, rString, false, false, EMPTY_OUSTRING, eGram );
794  if (bSuccess)
795  pDocSh->UpdateOle(GetViewData());
796  else
797  PaintArea(nCol, nRow, nCol, nRow); // possibly the edit-engine is still painted there
798  }
799  else
800  ErrorMessage(STR_NOMULTISELECT);
801 }
802 
804 {
805  SvtScriptType nScript = SvtScriptType::NONE;
806 
807  ScDocument& rDoc = GetViewData().GetDocument();
808  const ScMarkData& rMark = GetViewData().GetMarkData();
809  if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
810  {
811  // no selection -> cursor
812 
813  nScript = rDoc.GetScriptType( GetViewData().GetCurX(),
814  GetViewData().GetCurY(), GetViewData().GetTabNo());
815  }
816  else
817  {
818  ScRangeList aRanges;
819  rMark.FillRangeListWithMarks( &aRanges, false );
820  nScript = rDoc.GetRangeScriptType(aRanges);
821  }
822 
823  if (nScript == SvtScriptType::NONE)
824  nScript = ScGlobal::GetDefaultScriptType();
825 
826  return nScript;
827 }
828 
830 {
831  // Don't use UnmarkFiltered in slot state functions, for performance reasons.
832  // The displayed state is always that of the whole selection including filtered rows.
833 
834  const ScMarkData& rMark = GetViewData().GetMarkData();
835  ScDocument& rDoc = GetViewData().GetDocument();
836  if ( rMark.IsMarked() || rMark.IsMultiMarked() )
837  {
838  // MarkToMulti is no longer necessary for rDoc.GetSelectionPattern
839  const ScPatternAttr* pAttr = rDoc.GetSelectionPattern( rMark );
840  return pAttr;
841  }
842  else
843  {
844  SCCOL nCol = GetViewData().GetCurX();
845  SCROW nRow = GetViewData().GetCurY();
846  SCTAB nTab = GetViewData().GetTabNo();
847 
848  ScMarkData aTempMark( rMark ); // copy sheet selection
849  aTempMark.SetMarkArea( ScRange( nCol, nRow, nTab ) );
850  const ScPatternAttr* pAttr = rDoc.GetSelectionPattern( aTempMark );
851  return pAttr;
852  }
853 }
854 
856  std::shared_ptr<SvxBoxItem>& rLineOuter,
857  std::shared_ptr<SvxBoxInfoItem>& rLineInner )
858 {
859  ScDocument& rDoc = GetViewData().GetDocument();
860  const ScMarkData& rMark = GetViewData().GetMarkData();
861 
862  if ( rMark.IsMarked() || rMark.IsMultiMarked() )
863  {
864  rDoc.GetSelectionFrame( rMark, *rLineOuter, *rLineInner );
865  }
866  else
867  {
868  const ScPatternAttr* pAttrs =
869  rDoc.GetPattern( GetViewData().GetCurX(),
870  GetViewData().GetCurY(),
871  GetViewData().GetTabNo() );
872 
873  rLineOuter.reset(pAttrs->GetItem(ATTR_BORDER).Clone());
874  rLineInner.reset(pAttrs->GetItem(ATTR_BORDER_INNER).Clone());
875 
876  rLineInner->SetTable(false);
877  rLineInner->SetDist(true);
878  rLineInner->SetMinDist(false);
879  }
880 }
881 
882 // apply attribute - undo OK
883 //
884 // complete set ( ATTR_STARTINDEX, ATTR_ENDINDEX )
885 
886 void ScViewFunc::ApplyAttributes( const SfxItemSet* pDialogSet,
887  const SfxItemSet* pOldSet,
888  bool bAdjustBlockHeight)
889 {
890  // not editable because of matrix only? attribute OK nonetheless
891  bool bOnlyNotBecauseOfMatrix;
892  if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
893  {
894  ErrorMessage(STR_PROTECTIONERR);
895  return;
896  }
897 
898  ScPatternAttr aOldAttrs( std::make_unique<SfxItemSet>(*pOldSet) );
899  ScPatternAttr aNewAttrs( std::make_unique<SfxItemSet>(*pDialogSet) );
900  aNewAttrs.DeleteUnchanged( &aOldAttrs );
901 
902  if ( pDialogSet->GetItemState( ATTR_VALUE_FORMAT ) == SfxItemState::SET )
903  { // don't reset to default SYSTEM GENERAL if not intended
904  sal_uInt32 nOldFormat =
905  pOldSet->Get( ATTR_VALUE_FORMAT ).GetValue();
906  sal_uInt32 nNewFormat =
907  pDialogSet->Get( ATTR_VALUE_FORMAT ).GetValue();
908  if ( nNewFormat != nOldFormat )
909  {
910  SvNumberFormatter* pFormatter =
912  const SvNumberformat* pOldEntry = pFormatter->GetEntry( nOldFormat );
913  LanguageType eOldLang =
914  pOldEntry ? pOldEntry->GetLanguage() : LANGUAGE_DONTKNOW;
915  const SvNumberformat* pNewEntry = pFormatter->GetEntry( nNewFormat );
916  LanguageType eNewLang =
917  pNewEntry ? pNewEntry->GetLanguage() : LANGUAGE_DONTKNOW;
918  if ( eNewLang != eOldLang )
919  {
920  aNewAttrs.GetItemSet().Put(
921  SvxLanguageItem( eNewLang, ATTR_LANGUAGE_FORMAT ) );
922 
923  // only the language has changed -> do not touch numberformat-attribute
924  sal_uInt32 nNewMod = nNewFormat % SV_COUNTRY_LANGUAGE_OFFSET;
925  if ( nNewMod == ( nOldFormat % SV_COUNTRY_LANGUAGE_OFFSET ) &&
926  nNewMod <= SV_MAX_COUNT_STANDARD_FORMATS )
927  aNewAttrs.GetItemSet().ClearItem( ATTR_VALUE_FORMAT );
928  }
929  }
930  }
931 
932  if (pDialogSet->HasItem(ATTR_FONT_LANGUAGE))
933  // font language has changed. Redo the online spelling.
934  ResetAutoSpell();
935 
936  const SvxBoxItem& rOldOuter = pOldSet->Get(ATTR_BORDER);
937  const SvxBoxItem& rNewOuter = pDialogSet->Get(ATTR_BORDER);
938  const SvxBoxInfoItem& rOldInner = pOldSet->Get(ATTR_BORDER_INNER);
939  const SvxBoxInfoItem& rNewInner = pDialogSet->Get(ATTR_BORDER_INNER);
940  SfxItemSet& rNewSet = aNewAttrs.GetItemSet();
941  SfxItemPool* pNewPool = rNewSet.GetPool();
942 
943  pNewPool->Put(rNewOuter); // don't delete yet
944  pNewPool->Put(rNewInner);
945  rNewSet.ClearItem( ATTR_BORDER );
946  rNewSet.ClearItem( ATTR_BORDER_INNER );
947 
948  /*
949  * establish whether border attribute is to be set:
950  * 1. new != old
951  * 2. is one of the borders not-DontCare (since 238.f: IsxxValid())
952  *
953  */
954 
955  bool bFrame = (pDialogSet->GetItemState( ATTR_BORDER ) != SfxItemState::DEFAULT)
956  || (pDialogSet->GetItemState( ATTR_BORDER_INNER ) != SfxItemState::DEFAULT);
957 
958  if (&rNewOuter == &rOldOuter && &rNewInner == &rOldInner)
959  bFrame = false;
960 
961  // this should be intercepted by the pool: ?!??!??
962 
963  if (bFrame && rNewOuter == rOldOuter && rNewInner == rOldInner)
964  bFrame = false;
965 
966  bFrame = bFrame
967  && ( rNewInner.IsValid(SvxBoxInfoItemValidFlags::LEFT)
968  || rNewInner.IsValid(SvxBoxInfoItemValidFlags::RIGHT)
969  || rNewInner.IsValid(SvxBoxInfoItemValidFlags::TOP)
970  || rNewInner.IsValid(SvxBoxInfoItemValidFlags::BOTTOM)
971  || rNewInner.IsValid(SvxBoxInfoItemValidFlags::HORI)
972  || rNewInner.IsValid(SvxBoxInfoItemValidFlags::VERT) );
973 
974  if (!bFrame)
975  ApplySelectionPattern( aNewAttrs ); // standard only
976  else
977  {
978  // if new items are default-items, overwrite the old items:
979 
980  bool bDefNewOuter = IsStaticDefaultItem(&rNewOuter);
981  bool bDefNewInner = IsStaticDefaultItem(&rNewInner);
982 
983  ApplyPatternLines( aNewAttrs,
984  bDefNewOuter ? rOldOuter : rNewOuter,
985  bDefNewInner ? &rOldInner : &rNewInner );
986  }
987 
988  pNewPool->Remove(rNewOuter); // release
989  pNewPool->Remove(rNewInner);
990 
991  // adjust height only if needed
992  if (bAdjustBlockHeight)
994 
995  // CellContentChanged is called in ApplySelectionPattern / ApplyPatternLines
996 }
997 
998 void ScViewFunc::ApplyAttr( const SfxPoolItem& rAttrItem, bool bAdjustBlockHeight )
999 {
1000  // not editable because of matrix only? attribute OK nonetheless
1001  bool bOnlyNotBecauseOfMatrix;
1002  if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
1003  {
1004  ErrorMessage(STR_PROTECTIONERR);
1005  return;
1006  }
1007 
1008  ScPatternAttr aNewAttrs( std::make_unique<SfxItemSet>( *GetViewData().GetDocument().GetPool(),
1010 
1011  aNewAttrs.GetItemSet().Put( rAttrItem );
1012  // if justify is set (with Buttons), always indentation 0
1013  if ( rAttrItem.Which() == ATTR_HOR_JUSTIFY )
1014  aNewAttrs.GetItemSet().Put( ScIndentItem( 0 ) );
1015  ApplySelectionPattern( aNewAttrs );
1016 
1017  // Prevent useless compute
1018  if (bAdjustBlockHeight)
1020 
1021  // CellContentChanged is called in ApplySelectionPattern
1022 }
1023 
1024 // patterns and borders
1025 
1026 void ScViewFunc::ApplyPatternLines( const ScPatternAttr& rAttr, const SvxBoxItem& rNewOuter,
1027  const SvxBoxInfoItem* pNewInner )
1028 {
1029  ScDocument& rDoc = GetViewData().GetDocument();
1030  ScMarkData aFuncMark( GetViewData().GetMarkData() ); // local copy for UnmarkFiltered
1031  ScViewUtil::UnmarkFiltered( aFuncMark, rDoc );
1032  bool bRecord = true;
1033  if (!rDoc.IsUndoEnabled())
1034  bRecord = false;
1035 
1036  bool bRemoveAdjCellBorder = rNewOuter.IsRemoveAdjacentCellBorder();
1037  ScRange aMarkRange, aMarkRangeWithEnvelope;
1038  aFuncMark.MarkToSimple();
1039  bool bMulti = aFuncMark.IsMultiMarked();
1040  if (bMulti)
1041  aFuncMark.GetMultiMarkArea( aMarkRange );
1042  else if (aFuncMark.IsMarked())
1043  aFuncMark.GetMarkArea( aMarkRange );
1044  else
1045  {
1046  aMarkRange = ScRange( GetViewData().GetCurX(),
1047  GetViewData().GetCurY(), GetViewData().GetTabNo() );
1048  DoneBlockMode();
1049  InitOwnBlockMode();
1050  aFuncMark.SetMarkArea(aMarkRange);
1051  MarkDataChanged();
1052  }
1053  if( bRemoveAdjCellBorder )
1054  aFuncMark.GetSelectionCover( aMarkRangeWithEnvelope );
1055  else
1056  aMarkRangeWithEnvelope = aMarkRange;
1057 
1058  ScDocShell* pDocSh = GetViewData().GetDocShell();
1059 
1060  ScDocShellModificator aModificator( *pDocSh );
1061 
1062  if (bRecord)
1063  {
1065  SCTAB nStartTab = aMarkRange.aStart.Tab();
1066  SCTAB nTabCount = rDoc.GetTableCount();
1067  bool bCopyOnlyMarked = false;
1068  if( !bRemoveAdjCellBorder )
1069  bCopyOnlyMarked = bMulti;
1070  pUndoDoc->InitUndo( rDoc, nStartTab, nStartTab );
1071  for (const auto& rTab : aFuncMark)
1072  if (rTab != nStartTab)
1073  pUndoDoc->AddUndoTab( rTab, rTab );
1074 
1075  ScRange aCopyRange = aMarkRangeWithEnvelope;
1076  aCopyRange.aStart.SetTab(0);
1077  aCopyRange.aEnd.SetTab(nTabCount-1);
1078  rDoc.CopyToDocument( aCopyRange, InsertDeleteFlags::ATTRIB, bCopyOnlyMarked, *pUndoDoc, &aFuncMark );
1079 
1080  pDocSh->GetUndoManager()->AddUndoAction(
1081  std::make_unique<ScUndoSelectionAttr>(
1082  pDocSh, aFuncMark,
1083  aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), aMarkRange.aStart.Tab(),
1084  aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), aMarkRange.aEnd.Tab(),
1085  std::move(pUndoDoc), bCopyOnlyMarked, &rAttr, &rNewOuter, pNewInner, &aMarkRangeWithEnvelope ) );
1086  }
1087 
1088  sal_uInt16 nExt = SC_PF_TESTMERGE;
1089  pDocSh->UpdatePaintExt( nExt, aMarkRangeWithEnvelope ); // content before the change
1090 
1091  rDoc.ApplySelectionFrame(aFuncMark, rNewOuter, pNewInner);
1092 
1093  pDocSh->UpdatePaintExt( nExt, aMarkRangeWithEnvelope ); // content after the change
1094 
1095  aFuncMark.MarkToMulti();
1096  rDoc.ApplySelectionPattern( rAttr, aFuncMark );
1097 
1098  pDocSh->PostPaint( aMarkRange, PaintPartFlags::Grid, nExt );
1099  pDocSh->UpdateOle(GetViewData());
1100  aModificator.SetDocumentModified();
1102 
1103  StartFormatArea();
1104 }
1105 
1106 // pattern only
1107 
1108 void ScViewFunc::ApplySelectionPattern( const ScPatternAttr& rAttr, bool bCursorOnly )
1109 {
1110  ScViewData& rViewData = GetViewData();
1111  ScDocShell* pDocSh = rViewData.GetDocShell();
1112  ScDocument& rDoc = pDocSh->GetDocument();
1113  ScMarkData aFuncMark( rViewData.GetMarkData() ); // local copy for UnmarkFiltered
1114  ScViewUtil::UnmarkFiltered( aFuncMark, rDoc );
1115 
1116  bool bRecord = true;
1117  if (!rDoc.IsUndoEnabled())
1118  bRecord = false;
1119 
1120  // State from old ItemSet doesn't matter for paint flags, as any change will be
1121  // from SfxItemState::SET in the new ItemSet (default is ignored in ApplyPattern).
1122  // New alignment is checked (check in PostPaint isn't enough) in case a right
1123  // alignment is changed to left.
1124  const SfxItemSet& rNewSet = rAttr.GetItemSet();
1125  bool bSetLines = rNewSet.GetItemState( ATTR_BORDER ) == SfxItemState::SET ||
1126  rNewSet.GetItemState( ATTR_SHADOW ) == SfxItemState::SET;
1127  bool bSetAlign = rNewSet.GetItemState( ATTR_HOR_JUSTIFY ) == SfxItemState::SET;
1128 
1129  sal_uInt16 nExtFlags = 0;
1130  if ( bSetLines )
1131  nExtFlags |= SC_PF_LINES;
1132  if ( bSetAlign )
1133  nExtFlags |= SC_PF_WHOLEROWS;
1134 
1135  ScDocShellModificator aModificator( *pDocSh );
1136 
1137  bool bMulti = aFuncMark.IsMultiMarked();
1138  aFuncMark.MarkToMulti();
1139  bool bOnlyTab = (!aFuncMark.IsMultiMarked() && !bCursorOnly && aFuncMark.GetSelectCount() > 1);
1140  if (bOnlyTab)
1141  {
1142  SCCOL nCol = rViewData.GetCurX();
1143  SCROW nRow = rViewData.GetCurY();
1144  SCTAB nTab = rViewData.GetTabNo();
1145  aFuncMark.SetMarkArea(ScRange(nCol,nRow,nTab));
1146  aFuncMark.MarkToMulti();
1147  }
1148 
1149  ScRangeList aChangeRanges;
1150 
1151  if (aFuncMark.IsMultiMarked() && !bCursorOnly)
1152  {
1153  ScRange aMarkRange;
1154  aFuncMark.GetMultiMarkArea( aMarkRange );
1155  SCTAB nTabCount = rDoc.GetTableCount();
1156  for (const auto& rTab : aFuncMark)
1157  {
1158  ScRange aChangeRange( aMarkRange );
1159  aChangeRange.aStart.SetTab( rTab );
1160  aChangeRange.aEnd.SetTab( rTab );
1161  aChangeRanges.push_back( aChangeRange );
1162  }
1163 
1164  SCCOL nStartCol = aMarkRange.aStart.Col();
1165  SCROW nStartRow = aMarkRange.aStart.Row();
1166  SCTAB nStartTab = aMarkRange.aStart.Tab();
1167  SCCOL nEndCol = aMarkRange.aEnd.Col();
1168  SCROW nEndRow = aMarkRange.aEnd.Row();
1169  SCTAB nEndTab = aMarkRange.aEnd.Tab();
1170 
1171  ScEditDataArray* pEditDataArray = nullptr;
1172  if (bRecord)
1173  {
1174  ScRange aCopyRange = aMarkRange;
1175  aCopyRange.aStart.SetTab(0);
1176  aCopyRange.aEnd.SetTab(nTabCount-1);
1177 
1179  pUndoDoc->InitUndo( rDoc, nStartTab, nStartTab );
1180  for (const auto& rTab : aFuncMark)
1181  if (rTab != nStartTab)
1182  pUndoDoc->AddUndoTab( rTab, rTab );
1183  rDoc.CopyToDocument( aCopyRange, InsertDeleteFlags::ATTRIB, bMulti, *pUndoDoc, &aFuncMark );
1184 
1185  aFuncMark.MarkToMulti();
1186 
1187  ScUndoSelectionAttr* pUndoAttr = new ScUndoSelectionAttr(
1188  pDocSh, aFuncMark, nStartCol, nStartRow, nStartTab,
1189  nEndCol, nEndRow, nEndTab, std::move(pUndoDoc), bMulti, &rAttr );
1190  pDocSh->GetUndoManager()->AddUndoAction(std::unique_ptr<ScUndoSelectionAttr>(pUndoAttr));
1191  pEditDataArray = pUndoAttr->GetDataArray();
1192  }
1193 
1194  rDoc.ApplySelectionPattern( rAttr, aFuncMark, pEditDataArray );
1195 
1196  pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
1197  nEndCol, nEndRow, nEndTab,
1198  PaintPartFlags::Grid, nExtFlags | SC_PF_TESTMERGE );
1199  pDocSh->UpdateOle(GetViewData());
1200  aModificator.SetDocumentModified();
1202  }
1203  else // single cell - simpler undo
1204  {
1205  SCCOL nCol = rViewData.GetCurX();
1206  SCROW nRow = rViewData.GetCurY();
1207  SCTAB nTab = rViewData.GetTabNo();
1208 
1209  std::unique_ptr<EditTextObject> pOldEditData;
1210  std::unique_ptr<EditTextObject> pNewEditData;
1211  ScAddress aPos(nCol, nRow, nTab);
1212  ScRefCellValue aCell(rDoc, aPos);
1213  if (aCell.meType == CELLTYPE_EDIT)
1214  {
1215  const EditTextObject* pEditObj = aCell.mpEditText;
1216  pOldEditData = pEditObj->Clone();
1217  rDoc.RemoveEditTextCharAttribs(aPos, rAttr);
1218  pEditObj = rDoc.GetEditText(aPos);
1219  pNewEditData = pEditObj->Clone();
1220  }
1221 
1222  aChangeRanges.push_back(aPos);
1223  std::unique_ptr<ScPatternAttr> pOldPat(new ScPatternAttr(*rDoc.GetPattern( nCol, nRow, nTab )));
1224 
1225  rDoc.ApplyPattern( nCol, nRow, nTab, rAttr );
1226 
1227  const ScPatternAttr* pNewPat = rDoc.GetPattern( nCol, nRow, nTab );
1228 
1229  if (bRecord)
1230  {
1231  std::unique_ptr<ScUndoCursorAttr> pUndo(new ScUndoCursorAttr(
1232  pDocSh, nCol, nRow, nTab, pOldPat.get(), pNewPat, &rAttr ));
1233  pUndo->SetEditData(std::move(pOldEditData), std::move(pNewEditData));
1234  pDocSh->GetUndoManager()->AddUndoAction(std::move(pUndo));
1235  }
1236  pOldPat.reset(); // is copied in undo (Pool)
1237 
1238  pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PaintPartFlags::Grid, nExtFlags | SC_PF_TESTMERGE );
1239  pDocSh->UpdateOle(GetViewData());
1240  aModificator.SetDocumentModified();
1242  }
1243 
1245  if (pModelObj)
1246  {
1247  css::uno::Sequence< css::beans::PropertyValue > aProperties;
1248  sal_Int32 nCount = 0;
1250  PropertyEntryVector_t aPropVector = rMap.getPropertyEntries();
1251  for ( sal_uInt16 nWhich = ATTR_PATTERN_START; nWhich <= ATTR_PATTERN_END; ++nWhich )
1252  {
1253  const SfxPoolItem* pItem = nullptr;
1254  if ( rNewSet.GetItemState( nWhich, true, &pItem ) == SfxItemState::SET && pItem )
1255  {
1256  for ( const auto& rProp : aPropVector)
1257  {
1258  if ( rProp.nWID == nWhich )
1259  {
1260  css::uno::Any aVal;
1261  pItem->QueryValue( aVal, rProp.nMemberId );
1262  aProperties.realloc( nCount + 1 );
1263  aProperties[ nCount ].Name = rProp.sName;
1264  aProperties[ nCount ].Value = aVal;
1265  ++nCount;
1266  }
1267  }
1268  }
1269  }
1270  HelperNotifyChanges::Notify(*pModelObj, aChangeRanges, "attribute", aProperties);
1271  }
1272 
1273  StartFormatArea();
1274 }
1275 
1277 {
1278  // ItemSet from UI, may have different pool
1279 
1280  bool bOnlyNotBecauseOfMatrix;
1281  if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
1282  {
1283  ErrorMessage(STR_PROTECTIONERR);
1284  return;
1285  }
1286 
1287  ScPatternAttr aNewAttrs( GetViewData().GetDocument().GetPool() );
1288  SfxItemSet& rNewSet = aNewAttrs.GetItemSet();
1289  rNewSet.Put( rItemSet, false );
1290  ApplySelectionPattern( aNewAttrs );
1291 
1293 }
1294 
1296 {
1297  // Don't use UnmarkFiltered in slot state functions, for performance reasons.
1298  // The displayed state is always that of the whole selection including filtered rows.
1299 
1300  const ScStyleSheet* pSheet = nullptr;
1301  ScViewData& rViewData = GetViewData();
1302  ScDocument& rDoc = rViewData.GetDocument();
1303  ScMarkData& rMark = rViewData.GetMarkData();
1304 
1305  if ( rMark.IsMarked() || rMark.IsMultiMarked() )
1306  pSheet = rDoc.GetSelectionStyle( rMark ); // MarkToMulti isn't necessary
1307  else
1308  pSheet = rDoc.GetStyle( rViewData.GetCurX(),
1309  rViewData.GetCurY(),
1310  rViewData.GetTabNo() );
1311 
1312  return pSheet;
1313 }
1314 
1316 {
1317  // not editable because of matrix only? attribute OK nonetheless
1318  bool bOnlyNotBecauseOfMatrix;
1319  if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
1320  {
1321  ErrorMessage(STR_PROTECTIONERR);
1322  return;
1323  }
1324 
1325  if ( !pStyleSheet) return;
1326 
1327  ScViewData& rViewData = GetViewData();
1328  ScDocShell* pDocSh = rViewData.GetDocShell();
1329  ScDocument& rDoc = pDocSh->GetDocument();
1330  ScMarkData aFuncMark( rViewData.GetMarkData() ); // local copy for UnmarkFiltered
1331  ScViewUtil::UnmarkFiltered( aFuncMark, rDoc );
1332  SCTAB nTabCount = rDoc.GetTableCount();
1333  bool bRecord = true;
1334  if (!rDoc.IsUndoEnabled())
1335  bRecord = false;
1336 
1337  ScDocShellModificator aModificator( *pDocSh );
1338 
1339  if ( aFuncMark.IsMarked() || aFuncMark.IsMultiMarked() )
1340  {
1341  ScRange aMarkRange;
1342  aFuncMark.MarkToMulti();
1343  aFuncMark.GetMultiMarkArea( aMarkRange );
1344 
1345  if ( bRecord )
1346  {
1347  SCTAB nTab = rViewData.GetTabNo();
1349  pUndoDoc->InitUndo( rDoc, nTab, nTab );
1350  for (const auto& rTab : aFuncMark)
1351  if (rTab != nTab)
1352  pUndoDoc->AddUndoTab( rTab, rTab );
1353 
1354  ScRange aCopyRange = aMarkRange;
1355  aCopyRange.aStart.SetTab(0);
1356  aCopyRange.aEnd.SetTab(nTabCount-1);
1357  rDoc.CopyToDocument( aCopyRange, InsertDeleteFlags::ATTRIB, true, *pUndoDoc, &aFuncMark );
1358  aFuncMark.MarkToMulti();
1359 
1360  OUString aName = pStyleSheet->GetName();
1361  pDocSh->GetUndoManager()->AddUndoAction(
1362  std::make_unique<ScUndoSelectionStyle>( pDocSh, aFuncMark, aMarkRange, aName, std::move(pUndoDoc) ) );
1363  }
1364 
1365  rDoc.ApplySelectionStyle( static_cast<const ScStyleSheet&>(*pStyleSheet), aFuncMark );
1366 
1367  if (!AdjustBlockHeight())
1368  rViewData.GetDocShell()->PostPaint( aMarkRange, PaintPartFlags::Grid );
1369 
1370  aFuncMark.MarkToSimple();
1371  }
1372  else
1373  {
1374  SCCOL nCol = rViewData.GetCurX();
1375  SCROW nRow = rViewData.GetCurY();
1376  SCTAB nTab = rViewData.GetTabNo();
1377 
1378  if ( bRecord )
1379  {
1381  pUndoDoc->InitUndo( rDoc, nTab, nTab );
1382  for (const auto& rTab : aFuncMark)
1383  if (rTab != nTab)
1384  pUndoDoc->AddUndoTab( rTab, rTab );
1385 
1386  ScRange aCopyRange( nCol, nRow, 0, nCol, nRow, nTabCount-1 );
1387  rDoc.CopyToDocument( aCopyRange, InsertDeleteFlags::ATTRIB, false, *pUndoDoc );
1388 
1389  ScRange aMarkRange ( nCol, nRow, nTab );
1390  ScMarkData aUndoMark = aFuncMark;
1391  aUndoMark.SetMultiMarkArea( aMarkRange );
1392 
1393  OUString aName = pStyleSheet->GetName();
1394  pDocSh->GetUndoManager()->AddUndoAction(
1395  std::make_unique<ScUndoSelectionStyle>( pDocSh, aUndoMark, aMarkRange, aName, std::move(pUndoDoc) ) );
1396  }
1397 
1398  for (const auto& rTab : aFuncMark)
1399  rDoc.ApplyStyle( nCol, nRow, rTab, static_cast<const ScStyleSheet&>(*pStyleSheet) );
1400 
1401  if (!AdjustBlockHeight())
1402  rViewData.GetDocShell()->PostPaintCell( nCol, nRow, nTab );
1403 
1404  }
1405 
1406  aModificator.SetDocumentModified();
1407 
1408  StartFormatArea();
1409 }
1410 
1412 {
1413  if ( !pStyleSheet) return;
1414 
1415  ScViewData& rViewData = GetViewData();
1416  ScDocument& rDoc = rViewData.GetDocument();
1417  ScDocShell* pDocSh = rViewData.GetDocShell();
1418 
1419  ScDocShellModificator aModificator( *pDocSh );
1420 
1422  pVirtDev->SetMapMode(MapMode(MapUnit::MapPixel));
1423  rDoc.StyleSheetChanged( pStyleSheet, true, pVirtDev,
1424  rViewData.GetPPTX(),
1425  rViewData.GetPPTY(),
1426  rViewData.GetZoomX(),
1427  rViewData.GetZoomY() );
1428 
1429  pDocSh->PostPaint( 0,0,0, rDoc.MaxCol(), rDoc.MaxRow(), MAXTAB, PaintPartFlags::Grid|PaintPartFlags::Left );
1430  aModificator.SetDocumentModified();
1431 
1432  ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
1433  if (pHdl)
1434  pHdl->ForgetLastPattern();
1435 }
1436 
1438 {
1439  if ( !pStyleSheet) return;
1440 
1441  ScViewData& rViewData = GetViewData();
1442  ScDocument& rDoc = rViewData.GetDocument();
1443  ScDocShell* pDocSh = rViewData.GetDocShell();
1444 
1445  ScDocShellModificator aModificator( *pDocSh );
1446 
1448  pVirtDev->SetMapMode(MapMode(MapUnit::MapPixel));
1449  rDoc.StyleSheetChanged( pStyleSheet, false, pVirtDev,
1450  rViewData.GetPPTX(),
1451  rViewData.GetPPTY(),
1452  rViewData.GetZoomX(),
1453  rViewData.GetZoomY() );
1454 
1455  pDocSh->PostPaint( 0,0,0, rDoc.MaxCol(), rDoc.MaxRow(), MAXTAB, PaintPartFlags::Grid|PaintPartFlags::Left );
1456  aModificator.SetDocumentModified();
1457 
1458  ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
1459  if (pHdl)
1460  pHdl->ForgetLastPattern();
1461 }
1462 
1463 
1465 {
1466  if (!comphelper::LibreOfficeKit::isActive() || nOffset == 0)
1467  return;
1468 
1469  SCTAB nCurrentTabIndex = GetViewData().GetTabNo();
1470  SfxViewShell* pCurrentViewShell = GetViewData().GetViewShell();
1471  SfxViewShell* pViewShell = SfxViewShell::GetFirst();
1472  while (pViewShell)
1473  {
1474  ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
1475  if (pTabViewShell && pTabViewShell->GetDocId() == pCurrentViewShell->GetDocId())
1476  {
1477  pTabViewShell->GetViewData().GetLOKWidthHelper(nCurrentTabIndex)->invalidateByIndex(nStartCol);
1478 
1479  // if we remove a column the cursor position and the current selection
1480  // in other views could need to be moved on the left by one column.
1481  if (pTabViewShell != this)
1482  {
1483  if (pTabViewShell->getPart() == nCurrentTabIndex)
1484  {
1485  SCCOL nX = pTabViewShell->GetViewData().GetCurX();
1486  if (nX > nStartCol || (nX == nStartCol && nOffset > 0))
1487  {
1488  ScInputHandler* pInputHdl = pTabViewShell->GetInputHandler();
1489  SCROW nY = pTabViewShell->GetViewData().GetCurY();
1490  pTabViewShell->SetCursor(nX + nOffset, nY);
1491  if (pInputHdl && pInputHdl->IsInputMode())
1492  {
1493  pInputHdl->SetModified();
1494  }
1495  }
1496 
1497  ScMarkData aMultiMark( pTabViewShell->GetViewData().GetMarkData() );
1498  aMultiMark.SetMarking( false );
1499  aMultiMark.MarkToMulti();
1500  if (aMultiMark.IsMultiMarked())
1501  {
1502  aMultiMark.ShiftCols(pTabViewShell->GetViewData().GetDocument(), nStartCol, nOffset);
1503  pTabViewShell->SetMarkData(aMultiMark);
1504  }
1505  }
1506  else
1507  {
1508  SCROW nX = pTabViewShell->GetViewData().GetCurXForTab(nCurrentTabIndex);
1509  if (nX > nStartCol || (nX == nStartCol && nOffset > 0))
1510  {
1511  pTabViewShell->GetViewData().SetCurXForTab(nX + nOffset, nCurrentTabIndex);
1512  }
1513  }
1514  }
1515  }
1516  pViewShell = SfxViewShell::GetNext(*pViewShell);
1517  }
1518 }
1519 
1521 {
1522  if (!comphelper::LibreOfficeKit::isActive() || nOffset == 0)
1523  return;
1524 
1525  SCTAB nCurrentTabIndex = GetViewData().GetTabNo();
1526  SfxViewShell* pCurrentViewShell = GetViewData().GetViewShell();
1527  SfxViewShell* pViewShell = SfxViewShell::GetFirst();
1528  while (pViewShell)
1529  {
1530  ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
1531  if (pTabViewShell && pTabViewShell->GetDocId() == pCurrentViewShell->GetDocId())
1532  {
1533  pTabViewShell->GetViewData().GetLOKHeightHelper(nCurrentTabIndex)->invalidateByIndex(nStartRow);
1534 
1535  // if we remove a row the cursor position and the current selection
1536  // in other views could need to be moved up by one row.
1537  if (pTabViewShell != this)
1538  {
1539  if (pTabViewShell->getPart() == nCurrentTabIndex)
1540  {
1541  SCROW nY = pTabViewShell->GetViewData().GetCurY();
1542  if (nY > nStartRow || (nY == nStartRow && nOffset > 0))
1543  {
1544  ScInputHandler* pInputHdl = pTabViewShell->GetInputHandler();
1545  SCCOL nX = pTabViewShell->GetViewData().GetCurX();
1546  pTabViewShell->SetCursor(nX, nY + nOffset);
1547  if (pInputHdl && pInputHdl->IsInputMode())
1548  {
1549  pInputHdl->SetModified();
1550  }
1551  }
1552 
1553  ScMarkData aMultiMark( pTabViewShell->GetViewData().GetMarkData() );
1554  aMultiMark.SetMarking( false );
1555  aMultiMark.MarkToMulti();
1556  if (aMultiMark.IsMultiMarked())
1557  {
1558  aMultiMark.ShiftRows(pTabViewShell->GetViewData().GetDocument(), nStartRow, nOffset);
1559  pTabViewShell->SetMarkData(aMultiMark);
1560  }
1561  }
1562  else
1563  {
1564  SCROW nY = pTabViewShell->GetViewData().GetCurYForTab(nCurrentTabIndex);
1565  if (nY > nStartRow || (nY == nStartRow && nOffset > 0))
1566  {
1567  pTabViewShell->GetViewData().SetCurYForTab(nY + nOffset, nCurrentTabIndex);
1568  }
1569  }
1570  }
1571  }
1572  pViewShell = SfxViewShell::GetNext(*pViewShell);
1573  }
1574 }
1575 
1577 {
1579  return;
1580 
1581  SCTAB nCurTab = GetViewData().GetTabNo();
1582  SfxViewShell* pCurrentViewShell = GetViewData().GetViewShell();
1583  SfxViewShell* pViewShell = SfxViewShell::GetFirst();
1584  while (pViewShell)
1585  {
1586  ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
1587  if (pTabViewShell && pTabViewShell->GetDocId() == pCurrentViewShell->GetDocId())
1588  {
1589  if (bWidth)
1590  pTabViewShell->GetViewData().GetLOKWidthHelper(nCurTab)->invalidateByIndex(nStart);
1591  else
1592  pTabViewShell->GetViewData().GetLOKHeightHelper(nCurTab)->invalidateByIndex(nStart);
1593  }
1594  pViewShell = SfxViewShell::GetNext(*pViewShell);
1595  }
1596 }
1597 
1598 // insert cells - undo OK
1599 
1600 bool ScViewFunc::InsertCells( InsCellCmd eCmd, bool bRecord, bool bPartOfPaste )
1601 {
1602  ScRange aRange;
1603  if (GetViewData().GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1604  {
1605  ScDocShell* pDocSh = GetViewData().GetDocShell();
1606  const ScMarkData& rMark = GetViewData().GetMarkData();
1607  bool bSuccess = pDocSh->GetDocFunc().InsertCells( aRange, &rMark, eCmd, bRecord, false, bPartOfPaste );
1608  if (bSuccess)
1609  {
1610  bool bInsertCols = ( eCmd == INS_INSCOLS_BEFORE || eCmd == INS_INSCOLS_AFTER);
1611  bool bInsertRows = ( eCmd == INS_INSROWS_BEFORE || eCmd == INS_INSROWS_AFTER );
1612 
1613  pDocSh->UpdateOle(GetViewData());
1615  ResetAutoSpell();
1616 
1617  if ( bInsertCols || bInsertRows )
1618  {
1619  OUString aOperation = bInsertRows ?
1620  OUString("insert-rows"):
1621  OUString("insert-columns");
1622  HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh, aRange, aOperation);
1623  }
1624 
1626  {
1627  if (bInsertCols)
1629 
1630  if (bInsertRows)
1632 
1634  bInsertCols, bInsertRows, true /* bSizes*/,
1635  true /* bHidden */, true /* bFiltered */,
1636  true /* bGroups */, GetViewData().GetTabNo());
1637  }
1638  }
1639  OUString aStartAddress = aRange.aStart.GetColRowString();
1640  OUString aEndAddress = aRange.aEnd.GetColRowString();
1641  collectUIInformation({{"RANGE", aStartAddress + ":" + aEndAddress}}, "INSERT_CELLS");
1642  return bSuccess;
1643  }
1644  else
1645  {
1646  ErrorMessage(STR_NOMULTISELECT);
1647  return false;
1648  }
1649 }
1650 
1651 // delete cells - undo OK
1652 
1654 {
1655  ScRange aRange;
1656  if ( GetViewData().GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
1657  {
1658  ScDocShell* pDocSh = GetViewData().GetDocShell();
1659  const ScMarkData& rMark = GetViewData().GetMarkData();
1660 
1661 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
1662  // #i94841# [Collaboration] if deleting rows is rejected, the content is sometimes wrong
1663  if ( pDocSh->IsDocShared() && ( eCmd == DelCellCmd::Rows || eCmd == DelCellCmd::Cols ) )
1664  {
1665  ScRange aDelRange( aRange.aStart );
1666  SCCOLROW nCount = 0;
1667  if ( eCmd == DelCellCmd::Rows )
1668  {
1669  nCount = sal::static_int_cast< SCCOLROW >( aRange.aEnd.Row() - aRange.aStart.Row() + 1 );
1670  }
1671  else
1672  {
1673  nCount = sal::static_int_cast< SCCOLROW >( aRange.aEnd.Col() - aRange.aStart.Col() + 1 );
1674  }
1675  while ( nCount > 0 )
1676  {
1677  pDocSh->GetDocFunc().DeleteCells( aDelRange, &rMark, eCmd, false );
1678  --nCount;
1679  }
1680  }
1681  else
1682 #endif
1683  {
1684  pDocSh->GetDocFunc().DeleteCells( aRange, &rMark, eCmd, false );
1685  }
1686 
1687  pDocSh->UpdateOle(GetViewData());
1689  ResetAutoSpell();
1690 
1691  if ( eCmd == DelCellCmd::Rows || eCmd == DelCellCmd::Cols )
1692  {
1693  OUString aOperation = ( eCmd == DelCellCmd::Rows) ?
1694  OUString("delete-rows"):
1695  OUString("delete-columns");
1696  HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh, aRange, aOperation);
1697  }
1698 
1699  // put cursor directly behind deleted range
1700  SCCOL nCurX = GetViewData().GetCurX();
1701  SCROW nCurY = GetViewData().GetCurY();
1702  if ( eCmd==DelCellCmd::CellsLeft || eCmd==DelCellCmd::Cols )
1703  nCurX = aRange.aStart.Col();
1704  else
1705  nCurY = aRange.aStart.Row();
1706  SetCursor( nCurX, nCurY );
1707 
1709  {
1710  bool bColsDeleted = (eCmd == DelCellCmd::Cols);
1711  bool bRowsDeleted = (eCmd == DelCellCmd::Rows);
1712  if (bColsDeleted)
1714 
1715  if (bRowsDeleted)
1717 
1719  bColsDeleted, bRowsDeleted, true /* bSizes*/,
1720  true /* bHidden */, true /* bFiltered */,
1721  true /* bGroups */, GetViewData().GetTabNo());
1722  }
1723  }
1724  else
1725  {
1726  if (eCmd == DelCellCmd::Cols)
1727  DeleteMulti( false );
1728  else if (eCmd == DelCellCmd::Rows)
1729  DeleteMulti( true );
1730  else
1731  ErrorMessage(STR_NOMULTISELECT);
1732  }
1733 
1734  OUString aStartAddress = aRange.aStart.GetColRowString();
1735  OUString aEndAddress = aRange.aEnd.GetColRowString();
1736  collectUIInformation({{"RANGE", aStartAddress + ":" + aEndAddress}}, "DELETE_CELLS");
1737 
1738  Unmark();
1739 }
1740 
1741 void ScViewFunc::DeleteMulti( bool bRows )
1742 {
1743  ScDocShell* pDocSh = GetViewData().GetDocShell();
1744  ScDocShellModificator aModificator( *pDocSh );
1745  SCTAB nTab = GetViewData().GetTabNo();
1746  ScDocument& rDoc = pDocSh->GetDocument();
1747  ScMarkData aFuncMark( GetViewData().GetMarkData() ); // local copy for UnmarkFiltered
1748  ScViewUtil::UnmarkFiltered( aFuncMark, rDoc );
1749 
1750  bool bRecord = true;
1751  if (!rDoc.IsUndoEnabled())
1752  bRecord = false;
1753 
1754  std::vector<sc::ColRowSpan> aSpans;
1755  if (bRows)
1756  aSpans = aFuncMark.GetMarkedRowSpans();
1757  else
1758  aSpans = aFuncMark.GetMarkedColSpans();
1759 
1760  if (aSpans.empty())
1761  {
1762  SCCOLROW nCurPos = bRows ? GetViewData().GetCurY() : GetViewData().GetCurX();
1763  aSpans.emplace_back(nCurPos, nCurPos);
1764  }
1765 
1766  // test if allowed
1767 
1768  const char* pErrorId = nullptr;
1769  bool bNeedRefresh = false;
1770  for (size_t i = 0, n = aSpans.size(); i < n && !pErrorId; ++i)
1771  {
1772  SCCOLROW nStart = aSpans[i].mnStart;
1773  SCCOLROW nEnd = aSpans[i].mnEnd;
1774 
1775  SCCOL nStartCol, nEndCol;
1776  SCROW nStartRow, nEndRow;
1777  if ( bRows )
1778  {
1779  nStartCol = 0;
1780  nEndCol = rDoc.MaxCol();
1781  nStartRow = static_cast<SCROW>(nStart);
1782  nEndRow = static_cast<SCROW>(nEnd);
1783  }
1784  else
1785  {
1786  nStartCol = static_cast<SCCOL>(nStart);
1787  nEndCol = static_cast<SCCOL>(nEnd);
1788  nStartRow = 0;
1789  nEndRow = rDoc.MaxRow();
1790  }
1791 
1792  // cell protection (only needed for first range, as all following cells are moved)
1793  if (i == 0)
1794  {
1795  // test to the end of the sheet
1796  ScEditableTester aTester( rDoc, nTab, nStartCol, nStartRow, rDoc.MaxCol(), rDoc.MaxRow() );
1797  if (!aTester.IsEditable())
1798  pErrorId = aTester.GetMessageId();
1799  }
1800 
1801  // merged cells
1802  SCCOL nMergeStartX = nStartCol;
1803  SCROW nMergeStartY = nStartRow;
1804  SCCOL nMergeEndX = nEndCol;
1805  SCROW nMergeEndY = nEndRow;
1806  rDoc.ExtendMerge( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, nTab );
1807  rDoc.ExtendOverlapped( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, nTab );
1808 
1809  if ( nMergeStartX != nStartCol || nMergeStartY != nStartRow )
1810  {
1811  // Disallow deleting parts of a merged cell.
1812  // Deleting the start is allowed (merge is removed), so the end doesn't have to be checked.
1813 
1814  pErrorId = STR_MSSG_DELETECELLS_0;
1815  }
1816  if ( nMergeEndX != nEndCol || nMergeEndY != nEndRow )
1817  {
1818  // detect if the start of a merged cell is deleted, so the merge flags can be refreshed
1819 
1820  bNeedRefresh = true;
1821  }
1822  }
1823 
1824  if (pErrorId)
1825  {
1826  ErrorMessage(pErrorId);
1827  return;
1828  }
1829 
1830  // proceed
1831 
1832  WaitObject aWait( GetFrameWin() ); // important for TrackFormulas in UpdateReference
1833 
1834  ScDocumentUniquePtr pUndoDoc;
1835  std::unique_ptr<ScRefUndoData> pUndoData;
1836  if (bRecord)
1837  {
1838  pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
1839  pUndoDoc->InitUndo( rDoc, nTab, nTab, !bRows, bRows ); // row height
1840 
1841  for (const sc::ColRowSpan & rSpan : aSpans)
1842  {
1843  SCCOLROW nStart = rSpan.mnStart;
1844  SCCOLROW nEnd = rSpan.mnEnd;
1845  if (bRows)
1846  rDoc.CopyToDocument( 0,nStart,nTab, rDoc.MaxCol(), nEnd,nTab, InsertDeleteFlags::ALL,false,*pUndoDoc );
1847  else
1848  rDoc.CopyToDocument( static_cast<SCCOL>(nStart),0,nTab,
1849  static_cast<SCCOL>(nEnd), rDoc.MaxRow(), nTab,
1850  InsertDeleteFlags::ALL,false,*pUndoDoc );
1851  }
1852 
1853  // all Formulas because of references
1854  SCTAB nTabCount = rDoc.GetTableCount();
1855  pUndoDoc->AddUndoTab( 0, nTabCount-1 );
1856  rDoc.CopyToDocument( 0,0,0, rDoc.MaxCol(), rDoc.MaxRow(), MAXTAB, InsertDeleteFlags::FORMULA,false,*pUndoDoc );
1857 
1858  pUndoData.reset(new ScRefUndoData( &rDoc ));
1859 
1860  rDoc.BeginDrawUndo();
1861  }
1862 
1863  std::vector<sc::ColRowSpan>::const_reverse_iterator ri = aSpans.rbegin(), riEnd = aSpans.rend();
1864  aFuncMark.SelectOneTable(nTab);
1865  for (; ri != riEnd; ++ri)
1866  {
1867  SCCOLROW nEnd = ri->mnEnd;
1868  SCCOLROW nStart = ri->mnStart;
1869 
1870  if (bRows)
1871  {
1872  rDoc.DeleteObjectsInArea(0, nStart, rDoc.MaxCol(), nEnd, aFuncMark, true);
1873  rDoc.DeleteRow(0, nTab, rDoc.MaxCol(), nTab, nStart, static_cast<SCSIZE>(nEnd - nStart + 1));
1874  }
1875  else
1876  {
1877  rDoc.DeleteObjectsInArea(nStart, 0, nEnd, rDoc.MaxRow(), aFuncMark, true);
1878  rDoc.DeleteCol(0, nTab, rDoc.MaxRow(), nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd - nStart + 1));
1879  }
1880  }
1881 
1882  if (bNeedRefresh)
1883  {
1884  SCCOLROW nFirstStart = aSpans[0].mnStart;
1885  SCCOL nStartCol = bRows ? 0 : static_cast<SCCOL>(nFirstStart);
1886  SCROW nStartRow = bRows ? static_cast<SCROW>(nFirstStart) : 0;
1887  SCCOL nEndCol = rDoc.MaxCol();
1888  SCROW nEndRow = rDoc.MaxRow();
1889 
1890  rDoc.RemoveFlagsTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, ScMF::Hor | ScMF::Ver );
1891  rDoc.ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab, true );
1892  }
1893 
1894  if (bRecord)
1895  {
1896  pDocSh->GetUndoManager()->AddUndoAction(
1897  std::make_unique<ScUndoDeleteMulti>(
1898  pDocSh, bRows, bNeedRefresh, nTab, aSpans, std::move(pUndoDoc), std::move(pUndoData)));
1899  }
1900 
1901  if (!AdjustRowHeight(0, rDoc.MaxRow()))
1902  {
1903  if (bRows)
1904  {
1905  pDocSh->PostPaint(
1906  0, aSpans[0].mnStart, nTab,
1907  rDoc.MaxCol(), rDoc.MaxRow(), nTab, (PaintPartFlags::Grid | PaintPartFlags::Left));
1908  }
1909  else
1910  {
1911  pDocSh->PostPaint(
1912  static_cast<SCCOL>(aSpans[0].mnStart), 0, nTab,
1913  rDoc.MaxCol(), rDoc.MaxRow(), nTab, (PaintPartFlags::Grid | PaintPartFlags::Top));
1914  }
1915  }
1916 
1917  ResetAutoSpell();
1918  aModificator.SetDocumentModified();
1919 
1921 
1922  // put cursor directly behind the first deleted range
1923  SCCOL nCurX = GetViewData().GetCurX();
1924  SCROW nCurY = GetViewData().GetCurY();
1925  if ( bRows )
1926  nCurY = aSpans[0].mnStart;
1927  else
1928  nCurX = static_cast<SCCOL>(aSpans[0].mnStart);
1929  SetCursor( nCurX, nCurY );
1930 
1931  SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreaLinksChanged ) );
1932 }
1933 
1934 // delete contents
1935 
1937 {
1938  ScViewData& rViewData = GetViewData();
1939  rViewData.SetPasteMode( ScPasteFlags::NONE );
1940  rViewData.GetViewShell()->UpdateCopySourceOverlay();
1941 
1942  // not editable because of matrix only? attribute OK nonetheless
1943  bool bOnlyNotBecauseOfMatrix;
1944  bool bEditable = SelectionEditable( &bOnlyNotBecauseOfMatrix );
1945  if ( !bEditable )
1946  {
1947  if ( !(bOnlyNotBecauseOfMatrix &&
1948  ((nFlags & (InsertDeleteFlags::ATTRIB | InsertDeleteFlags::EDITATTR)) == nFlags)) )
1949  {
1950  ErrorMessage(bOnlyNotBecauseOfMatrix ? STR_MATRIXFRAGMENTERR : STR_PROTECTIONERR);
1951  return;
1952  }
1953  }
1954 
1955  ScRange aMarkRange;
1956  bool bSimple = false;
1957 
1958  ScDocument& rDoc = GetViewData().GetDocument();
1959  ScDocShell* pDocSh = GetViewData().GetDocShell();
1960  ScMarkData aFuncMark( GetViewData().GetMarkData() ); // local copy for UnmarkFiltered
1961  ScViewUtil::UnmarkFiltered( aFuncMark, rDoc );
1962 
1963  bool bRecord =true;
1964  if (!rDoc.IsUndoEnabled())
1965  bRecord = false;
1966 
1967  if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() )
1968  {
1969  aMarkRange.aStart.SetCol(GetViewData().GetCurX());
1970  aMarkRange.aStart.SetRow(GetViewData().GetCurY());
1971  aMarkRange.aStart.SetTab(GetViewData().GetTabNo());
1972  aMarkRange.aEnd = aMarkRange.aStart;
1973  if ( rDoc.HasAttrib( aMarkRange, HasAttrFlags::Merged ) )
1974  {
1975  aFuncMark.SetMarkArea( aMarkRange );
1976  }
1977  else
1978  bSimple = true;
1979  }
1980 
1981  HideAllCursors(); // for if summary is cancelled
1982 
1983  ScDocFunc& rDocFunc = pDocSh->GetDocFunc();
1984  if (bSimple)
1985  rDocFunc.DeleteCell(aMarkRange.aStart, aFuncMark, nFlags, bRecord);
1986  else
1987  rDocFunc.DeleteContents(aFuncMark, nFlags, bRecord, false);
1988 
1989  pDocSh->UpdateOle(GetViewData());
1990 
1992  {
1993  ScRangeList aChangeRanges;
1994  if ( bSimple )
1995  {
1996  aChangeRanges.push_back( aMarkRange );
1997  }
1998  else
1999  {
2000  aFuncMark.FillRangeListWithMarks( &aChangeRanges, false );
2001  }
2002  HelperNotifyChanges::Notify(*pModelObj, aChangeRanges);
2003  }
2004 
2006  ShowAllCursors();
2007 
2008  if ( nFlags & InsertDeleteFlags::ATTRIB )
2009  {
2010  if ( nFlags & InsertDeleteFlags::CONTENTS )
2011  bFormatValid = false;
2012  else
2013  StartFormatArea(); // delete attribute is also attribute-change
2014  }
2015  OUString aStartAddress = aMarkRange.aStart.GetColRowString();
2016  OUString aEndAddress = aMarkRange.aEnd.GetColRowString();
2017  collectUIInformation({{"RANGE", aStartAddress + ":" + aEndAddress}}, "DELETE");
2018 }
2019 
2020 // column width/row height (via header) - undo OK
2021 
2023  bool bWidth, const std::vector<sc::ColRowSpan>& rRanges, ScSizeMode eMode,
2024  sal_uInt16 nSizeTwips, bool bRecord, const ScMarkData* pMarkData )
2025 {
2026  if (rRanges.empty())
2027  return;
2028 
2029  // Use view's mark if none specified, but do not modify the original data,
2030  // i.e. no MarkToMulti() on that.
2031  ScMarkData aMarkData( pMarkData ? *pMarkData : GetViewData().GetMarkData());
2032 
2033  ScDocShell* pDocSh = GetViewData().GetDocShell();
2034  ScDocument& rDoc = pDocSh->GetDocument();
2035  SCCOL nCurX = GetViewData().GetCurX();
2036  SCROW nCurY = GetViewData().GetCurY();
2037  SCTAB nFirstTab = aMarkData.GetFirstSelected();
2038  SCTAB nCurTab = GetViewData().GetTabNo();
2039  if (bRecord && !rDoc.IsUndoEnabled())
2040  bRecord = false;
2041 
2042  ScDocShellModificator aModificator( *pDocSh );
2043 
2044  bool bAllowed = true;
2045  for (const SCTAB& nTab : aMarkData)
2046  {
2047  bAllowed = std::all_of(rRanges.begin(), rRanges.end(),
2048  [&bWidth, &rDoc, &nTab](const sc::ColRowSpan& rRange) {
2049  bool bOnlyMatrix;
2050  bool bIsBlockEditable;
2051  if (bWidth)
2052  bIsBlockEditable = rDoc.IsBlockEditable(nTab, rRange.mnStart, 0, rRange.mnEnd, rDoc.MaxRow(), &bOnlyMatrix);
2053  else
2054  bIsBlockEditable = rDoc.IsBlockEditable(nTab, 0, rRange.mnStart, rDoc.MaxCol(), rRange.mnEnd, &bOnlyMatrix);
2055  return bIsBlockEditable || bOnlyMatrix;
2056  });
2057  if (!bAllowed)
2058  break;
2059  }
2060 
2061  // Allow users to resize cols/rows in readonly docs despite the r/o state.
2062  // It is frustrating to be unable to see content in mis-sized cells.
2063  if( !bAllowed && !pDocSh->IsReadOnly() )
2064  {
2065  ErrorMessage(STR_PROTECTIONERR);
2066  return;
2067  }
2068 
2069  SCCOLROW nStart = rRanges.front().mnStart;
2070  SCCOLROW nEnd = rRanges.back().mnEnd;
2071 
2072  OnLOKSetWidthOrHeight(nStart, bWidth);
2073 
2074  bool bFormula = false;
2075  if ( eMode == SC_SIZE_OPTIMAL )
2076  {
2077  const ScViewOptions& rOpts = GetViewData().GetOptions();
2078  bFormula = rOpts.GetOption( VOPT_FORMULAS );
2079  }
2080 
2081  ScDocumentUniquePtr pUndoDoc;
2082  std::unique_ptr<ScOutlineTable> pUndoTab;
2083  std::vector<sc::ColRowSpan> aUndoRanges;
2084 
2085  if ( bRecord )
2086  {
2087  rDoc.BeginDrawUndo(); // Drawing Updates
2088 
2089  pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
2090  for (const SCTAB& nTab : aMarkData)
2091  {
2092  if (bWidth)
2093  {
2094  if ( nTab == nFirstTab )
2095  pUndoDoc->InitUndo( rDoc, nTab, nTab, true );
2096  else
2097  pUndoDoc->AddUndoTab( nTab, nTab, true );
2098  rDoc.CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab,
2099  static_cast<SCCOL>(nEnd), rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE,
2100  false, *pUndoDoc );
2101  }
2102  else
2103  {
2104  if ( nTab == nFirstTab )
2105  pUndoDoc->InitUndo( rDoc, nTab, nTab, false, true );
2106  else
2107  pUndoDoc->AddUndoTab( nTab, nTab, false, true );
2108  rDoc.CopyToDocument( 0, nStart, nTab, rDoc.MaxCol(), nEnd, nTab, InsertDeleteFlags::NONE, false, *pUndoDoc );
2109  }
2110  }
2111 
2112  aUndoRanges = rRanges;
2113 
2115  ScOutlineTable* pTable = rDoc.GetOutlineTable( nCurTab );
2116  if (pTable)
2117  pUndoTab.reset(new ScOutlineTable( *pTable ));
2118  }
2119 
2120  if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
2121  aMarkData.MarkToMulti();
2122 
2123  bool bShow = nSizeTwips > 0 || eMode != SC_SIZE_DIRECT;
2124  bool bOutline = false;
2125 
2126  for (const SCTAB& nTab : aMarkData)
2127  {
2128  for (const sc::ColRowSpan & rRange : rRanges)
2129  {
2130  SCCOLROW nStartNo = rRange.mnStart;
2131  SCCOLROW nEndNo = rRange.mnEnd;
2132 
2133  if ( !bWidth ) // height always blockwise
2134  {
2135  if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
2136  {
2137  bool bAll = ( eMode==SC_SIZE_OPTIMAL );
2138  if (!bAll)
2139  {
2140  // delete CRFlags::ManualSize for all in range,
2141  // then SetOptimalHeight with bShrink = FALSE
2142  for (SCROW nRow = nStartNo; nRow <= nEndNo; ++nRow)
2143  {
2144  SCROW nLastRow = nRow;
2145  if (rDoc.RowHidden(nRow, nTab, nullptr, &nLastRow))
2146  {
2147  nRow = nLastRow;
2148  continue;
2149  }
2150 
2151  CRFlags nOld = rDoc.GetRowFlags(nRow, nTab);
2152  if (nOld & CRFlags::ManualSize)
2153  rDoc.SetRowFlags(nRow, nTab, nOld & ~CRFlags::ManualSize);
2154  }
2155  }
2156 
2157  double nPPTX = GetViewData().GetPPTX();
2158  double nPPTY = GetViewData().GetPPTY();
2159  Fraction aZoomX = GetViewData().GetZoomX();
2160  Fraction aZoomY = GetViewData().GetZoomY();
2161 
2162  ScSizeDeviceProvider aProv(pDocSh);
2163  if (aProv.IsPrinter())
2164  {
2165  nPPTX = aProv.GetPPTX();
2166  nPPTY = aProv.GetPPTY();
2167  aZoomX = aZoomY = Fraction( 1, 1 );
2168  }
2169 
2170  sc::RowHeightContext aCxt(rDoc.MaxRow(), nPPTX, nPPTY, aZoomX, aZoomY, aProv.GetDevice());
2171  aCxt.setForceAutoSize(bAll);
2172  aCxt.setExtraHeight(nSizeTwips);
2173  rDoc.SetOptimalHeight(aCxt, nStartNo, nEndNo, nTab);
2174  if (bAll)
2175  rDoc.ShowRows( nStartNo, nEndNo, nTab, true );
2176 
2177  // Manual-Flag already (re)set in SetOptimalHeight in case of bAll=sal_True
2178  // (set for Extra-Height, else reset).
2179  }
2180  else if ( eMode==SC_SIZE_DIRECT )
2181  {
2182  if (nSizeTwips)
2183  {
2184  rDoc.SetRowHeightRange( nStartNo, nEndNo, nTab, nSizeTwips );
2185  rDoc.SetManualHeight( nStartNo, nEndNo, nTab, true ); // height was set manually
2186  }
2187 
2188  rDoc.ShowRows( nStartNo, nEndNo, nTab, nSizeTwips != 0 );
2189 
2190  if (!bShow && nStartNo <= nCurY && nCurY <= nEndNo && nTab == nCurTab)
2191  {
2192  nCurY = -1;
2193  }
2194  }
2195  else if ( eMode==SC_SIZE_SHOW )
2196  {
2197  rDoc.ShowRows( nStartNo, nEndNo, nTab, true );
2198  }
2199  }
2200  else // column width
2201  {
2202  for (SCCOL nCol=static_cast<SCCOL>(nStartNo); nCol<=static_cast<SCCOL>(nEndNo); nCol++)
2203  {
2204  if ( eMode != SC_SIZE_VISOPT || !rDoc.ColHidden(nCol, nTab) )
2205  {
2206  sal_uInt16 nThisSize = nSizeTwips;
2207 
2208  if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
2209  nThisSize = nSizeTwips + GetOptimalColWidth( nCol, nTab, bFormula );
2210  if ( nThisSize )
2211  rDoc.SetColWidth( nCol, nTab, nThisSize );
2212 
2213  rDoc.ShowCol( nCol, nTab, bShow );
2214 
2215  if (!bShow && nCol == nCurX && nTab == nCurTab)
2216  {
2217  nCurX = -1;
2218  }
2219  }
2220  }
2221  }
2222 
2223  // adjust outline
2224  if (bWidth)
2225  {
2226  if ( rDoc.UpdateOutlineCol( static_cast<SCCOL>(nStartNo),
2227  static_cast<SCCOL>(nEndNo), nTab, bShow ) )
2228  bOutline = true;
2229  }
2230  else
2231  {
2232  if ( rDoc.UpdateOutlineRow( nStartNo, nEndNo, nTab, bShow ) )
2233  bOutline = true;
2234  }
2235  }
2236  rDoc.SetDrawPageSize(nTab);
2237  }
2238 
2239  if (!bOutline)
2240  pUndoTab.reset();
2241 
2242  if (bRecord)
2243  {
2244  pDocSh->GetUndoManager()->AddUndoAction(
2245  std::make_unique<ScUndoWidthOrHeight>(
2246  pDocSh, aMarkData, nStart, nCurTab, nEnd, nCurTab,
2247  std::move(pUndoDoc), aUndoRanges, std::move(pUndoTab), eMode, nSizeTwips, bWidth));
2248  }
2249 
2250  if (nCurX < 0)
2251  {
2252  MoveCursorRel( 1, 0, SC_FOLLOW_LINE, false );
2253  }
2254 
2255  if (nCurY < 0)
2256  {
2257  MoveCursorRel( 0, 1, SC_FOLLOW_LINE, false );
2258  }
2259 
2260  // fdo#36247 Ensure that the drawing layer's map mode scaling factors match
2261  // the new heights and widths.
2263 
2264  for (const SCTAB& nTab : aMarkData)
2265  rDoc.UpdatePageBreaks( nTab );
2266 
2267  bool bAffectsVisibility = (eMode != SC_SIZE_ORIGINAL && eMode != SC_SIZE_VISOPT);
2269  bWidth /* bColumns */, !bWidth /* bRows */,
2270  true /* bSizes*/, bAffectsVisibility /* bHidden */, bAffectsVisibility /* bFiltered */,
2271  false /* bGroups */, nCurTab);
2273 
2274  {
2275  for (const SCTAB& nTab : aMarkData)
2276  {
2277  if (bWidth)
2278  {
2279  if (rDoc.HasAttrib( static_cast<SCCOL>(nStart),0,nTab,
2280  static_cast<SCCOL>(nEnd), rDoc.MaxRow(), nTab,
2282  nStart = 0;
2283  if (nStart > 0) // go upwards because of Lines and cursor
2284  --nStart;
2285  pDocSh->PostPaint( static_cast<SCCOL>(nStart), 0, nTab,
2286  rDoc.MaxCol(), rDoc.MaxRow(), nTab, PaintPartFlags::Grid | PaintPartFlags::Top );
2287  }
2288  else
2289  {
2290  if (rDoc.HasAttrib( 0,nStart,nTab, rDoc.MaxCol(), nEnd,nTab, HasAttrFlags::Merged | HasAttrFlags::Overlapped ))
2291  nStart = 0;
2292  if (nStart != 0)
2293  --nStart;
2294  pDocSh->PostPaint( 0, nStart, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab, PaintPartFlags::Grid | PaintPartFlags::Left );
2295  }
2296  }
2297 
2298  pDocSh->UpdateOle(GetViewData());
2299  if( !pDocSh->IsReadOnly() )
2300  aModificator.SetDocumentModified();
2301  }
2302 
2303  if ( !bWidth )
2304  return;
2305 
2307  if (!pModelObj)
2308  return;
2309 
2310  ScRangeList aChangeRanges;
2311  for (const SCTAB& nTab : aMarkData)
2312  {
2313  for (const sc::ColRowSpan & rRange : rRanges)
2314  {
2315  SCCOL nStartCol = rRange.mnStart;
2316  SCCOL nEndCol = rRange.mnEnd;
2317  for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
2318  {
2319  aChangeRanges.push_back( ScRange( nCol, 0, nTab ) );
2320  }
2321  }
2322  }
2323  HelperNotifyChanges::Notify(*pModelObj, aChangeRanges, "column-resize");
2324 }
2325 
2326 // column width/row height (via marked range)
2327 
2328 void ScViewFunc::SetMarkedWidthOrHeight( bool bWidth, ScSizeMode eMode, sal_uInt16 nSizeTwips )
2329 {
2330  ScMarkData& rMark = GetViewData().GetMarkData();
2331 
2332  rMark.MarkToMulti();
2333  if (!rMark.IsMultiMarked())
2334  {
2335  SCCOL nCol = GetViewData().GetCurX();
2336  SCROW nRow = GetViewData().GetCurY();
2337  SCTAB nTab = GetViewData().GetTabNo();
2338  DoneBlockMode();
2339  InitOwnBlockMode();
2340  rMark.SetMultiMarkArea( ScRange( nCol,nRow,nTab ) );
2341  MarkDataChanged();
2342  }
2343 
2344  std::vector<sc::ColRowSpan> aRanges =
2345  bWidth ? rMark.GetMarkedColSpans() : rMark.GetMarkedRowSpans();
2346 
2347  SetWidthOrHeight(bWidth, aRanges, eMode, nSizeTwips);
2348 
2349  rMark.MarkToSimple();
2350 }
2351 
2352 void ScViewFunc::ModifyCellSize( ScDirection eDir, bool bOptimal )
2353 {
2355  // step size is also minimum
2356  constexpr sal_uInt16 nStepX = STD_COL_WIDTH / 5;
2357  sal_uInt16 nStepY = ScGlobal::nStdRowHeight;
2358 
2359  ScModule* pScMod = SC_MOD();
2360  bool bAnyEdit = pScMod->IsInputMode();
2361  SCCOL nCol = GetViewData().GetCurX();
2362  SCROW nRow = GetViewData().GetCurY();
2363  SCTAB nTab = GetViewData().GetTabNo();
2364  ScDocShell* pDocSh = GetViewData().GetDocShell();
2365  ScDocument& rDoc = pDocSh->GetDocument();
2366 
2367  bool bAllowed, bOnlyMatrix;
2368  if ( eDir == DIR_LEFT || eDir == DIR_RIGHT )
2369  bAllowed = rDoc.IsBlockEditable( nTab, nCol,0, nCol,rDoc.MaxRow(), &bOnlyMatrix );
2370  else
2371  bAllowed = rDoc.IsBlockEditable( nTab, 0,nRow, rDoc.MaxCol(), nRow, &bOnlyMatrix );
2372  if ( !bAllowed && !bOnlyMatrix )
2373  {
2374  ErrorMessage(STR_PROTECTIONERR);
2375  return;
2376  }
2377 
2378  HideAllCursors();
2379 
2380  sal_uInt16 nWidth = rDoc.GetColWidth( nCol, nTab );
2381  sal_uInt16 nHeight = rDoc.GetRowHeight( nRow, nTab );
2382  std::vector<sc::ColRowSpan> aRange(1, sc::ColRowSpan(0,0));
2383  if ( eDir == DIR_LEFT || eDir == DIR_RIGHT )
2384  {
2385  if (bOptimal) // width of this single cell
2386  {
2387  if ( bAnyEdit )
2388  {
2389  // when editing the actual entered width
2390  ScInputHandler* pHdl = pScMod->GetInputHdl( GetViewData().GetViewShell() );
2391  if (pHdl)
2392  {
2393  tools::Long nEdit = pHdl->GetTextSize().Width(); // in 0.01 mm
2394 
2395  const ScPatternAttr* pPattern = rDoc.GetPattern( nCol, nRow, nTab );
2396  const SvxMarginItem& rMItem = pPattern->GetItem(ATTR_MARGIN);
2397  sal_uInt16 nMargin = rMItem.GetLeftMargin() + rMItem.GetRightMargin();
2398  if ( pPattern->GetItem( ATTR_HOR_JUSTIFY ).GetValue() == SvxCellHorJustify::Left )
2399  nMargin = sal::static_int_cast<sal_uInt16>(
2400  nMargin + pPattern->GetItem(ATTR_INDENT).GetValue() );
2401 
2402  nWidth = static_cast<sal_uInt16>(nEdit * pDocSh->GetOutputFactor() / HMM_PER_TWIPS)
2403  + nMargin + STD_EXTRA_WIDTH;
2404  }
2405  }
2406  else
2407  {
2408  double nPPTX = GetViewData().GetPPTX();
2409  double nPPTY = GetViewData().GetPPTY();
2410  Fraction aZoomX = GetViewData().GetZoomX();
2411  Fraction aZoomY = GetViewData().GetZoomY();
2412 
2413  ScSizeDeviceProvider aProv(pDocSh);
2414  if (aProv.IsPrinter())
2415  {
2416  nPPTX = aProv.GetPPTX();
2417  nPPTY = aProv.GetPPTY();
2418  aZoomX = aZoomY = Fraction( 1, 1 );
2419  }
2420 
2421  tools::Long nPixel = rDoc.GetNeededSize( nCol, nRow, nTab, aProv.GetDevice(),
2422  nPPTX, nPPTY, aZoomX, aZoomY, true );
2423  sal_uInt16 nTwips = static_cast<sal_uInt16>( nPixel / nPPTX );
2424  if (nTwips != 0)
2425  nWidth = nTwips + STD_EXTRA_WIDTH;
2426  else
2427  nWidth = STD_COL_WIDTH;
2428  }
2429  }
2430  else // increment / decrement
2431  {
2432  if ( eDir == DIR_RIGHT )
2433  nWidth = sal::static_int_cast<sal_uInt16>( nWidth + nStepX );
2434  else if ( nWidth > nStepX )
2435  nWidth = sal::static_int_cast<sal_uInt16>( nWidth - nStepX );
2436  if ( nWidth < nStepX ) nWidth = nStepX;
2437  if ( nWidth > MAX_COL_WIDTH ) nWidth = MAX_COL_WIDTH;
2438  }
2439  aRange[0].mnStart = nCol;
2440  aRange[0].mnEnd = nCol;
2441  SetWidthOrHeight(true, aRange, SC_SIZE_DIRECT, nWidth);
2442 
2443  // adjust height of this row if width demands/allows this
2444 
2445  if (!bAnyEdit)
2446  {
2447  const ScPatternAttr* pPattern = rDoc.GetPattern( nCol, nRow, nTab );
2448  bool bNeedHeight =
2449  pPattern->GetItem( ATTR_LINEBREAK ).GetValue() ||
2450  pPattern->GetItem( ATTR_HOR_JUSTIFY ).GetValue() == SvxCellHorJustify::Block;
2451  if (bNeedHeight)
2452  AdjustRowHeight( nRow, nRow );
2453  }
2454  }
2455  else
2456  {
2457  ScSizeMode eMode;
2458  if (bOptimal)
2459  {
2460  eMode = SC_SIZE_OPTIMAL;
2461  nHeight = 0;
2462  }
2463  else
2464  {
2465  eMode = SC_SIZE_DIRECT;
2466  if ( eDir == DIR_BOTTOM )
2467  nHeight = sal::static_int_cast<sal_uInt16>( nHeight + nStepY );
2468  else if ( nHeight > nStepY )
2469  nHeight = sal::static_int_cast<sal_uInt16>( nHeight - nStepY );
2470  if ( nHeight < nStepY ) nHeight = nStepY;
2471  if ( nHeight > MAX_ROW_HEIGHT ) nHeight = MAX_ROW_HEIGHT;
2472  }
2473  aRange[0].mnStart = nRow;
2474  aRange[0].mnEnd = nRow;
2475  SetWidthOrHeight(false, aRange, eMode, nHeight);
2476  }
2477 
2478  if ( bAnyEdit )
2479  {
2480  UpdateEditView();
2481  if ( rDoc.HasAttrib( nCol, nRow, nTab, nCol, nRow, nTab, HasAttrFlags::NeedHeight ) )
2482  {
2483  ScInputHandler* pHdl = pScMod->GetInputHdl( GetViewData().GetViewShell() );
2484  if (pHdl)
2485  pHdl->SetModified(); // so that the height is adjusted with Enter
2486  }
2487  }
2488 
2489  ShowAllCursors();
2490 }
2491 
2492 void ScViewFunc::ProtectSheet( SCTAB nTab, const ScTableProtection& rProtect )
2493 {
2494  if (nTab == TABLEID_DOC)
2495  return;
2496 
2497  ScMarkData& rMark = GetViewData().GetMarkData();
2498  ScDocShell* pDocSh = GetViewData().GetDocShell();
2499  ScDocument& rDoc = pDocSh->GetDocument();
2500  ScDocFunc &rFunc = pDocSh->GetDocFunc();
2501  bool bUndo(rDoc.IsUndoEnabled());
2502 
2503  // modifying several tabs is handled here
2504 
2505  if (bUndo)
2506  {
2507  OUString aUndo = ScResId( STR_UNDO_PROTECT_TAB );
2508  pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo, 0, GetViewData().GetViewShell()->GetViewShellId() );
2509  }
2510 
2511  for (const auto& rTab : rMark)
2512  {
2513  rFunc.ProtectSheet(rTab, rProtect);
2514  SetTabProtectionSymbol(rTab, true);
2515  }
2516 
2517  if (bUndo)
2518  pDocSh->GetUndoManager()->LeaveListAction();
2519 
2520  UpdateLayerLocks();
2521 }
2522 
2523 void ScViewFunc::Protect( SCTAB nTab, const OUString& rPassword )
2524 {
2525  ScMarkData& rMark = GetViewData().GetMarkData();
2526  ScDocShell* pDocSh = GetViewData().GetDocShell();
2527  ScDocument& rDoc = pDocSh->GetDocument();
2528  ScDocFunc &rFunc = pDocSh->GetDocFunc();
2529  bool bUndo(rDoc.IsUndoEnabled());
2530 
2531  if ( nTab == TABLEID_DOC || rMark.GetSelectCount() <= 1 )
2532  rFunc.Protect( nTab, rPassword );
2533  else
2534  {
2535  // modifying several tabs is handled here
2536 
2537  if (bUndo)
2538  {
2539  OUString aUndo = ScResId( STR_UNDO_PROTECT_TAB );
2540  pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo, 0, GetViewData().GetViewShell()->GetViewShellId() );
2541  }
2542 
2543  for (const auto& rTab : rMark)
2544  rFunc.Protect( rTab, rPassword );
2545 
2546  if (bUndo)
2547  pDocSh->GetUndoManager()->LeaveListAction();
2548  }
2549 
2550  UpdateLayerLocks();
2551 }
2552 
2553 bool ScViewFunc::Unprotect( SCTAB nTab, const OUString& rPassword )
2554 {
2555  ScMarkData& rMark = GetViewData().GetMarkData();
2556  ScDocShell* pDocSh = GetViewData().GetDocShell();
2557  ScDocument& rDoc = pDocSh->GetDocument();
2558  ScDocFunc &rFunc = pDocSh->GetDocFunc();
2559  bool bChanged = false;
2560  bool bUndo (rDoc.IsUndoEnabled());
2561 
2562  if ( nTab == TABLEID_DOC || rMark.GetSelectCount() <= 1 )
2563  {
2564  bChanged = rFunc.Unprotect( nTab, rPassword, false );
2565  if (bChanged && nTab != TABLEID_DOC)
2566  SetTabProtectionSymbol(nTab, false);
2567  }
2568  else
2569  {
2570  // modifying several tabs is handled here
2571 
2572  if (bUndo)
2573  {
2574  OUString aUndo = ScResId( STR_UNDO_UNPROTECT_TAB );
2575  pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo, 0, GetViewData().GetViewShell()->GetViewShellId() );
2576  }
2577 
2578  for (const auto& rTab : rMark)
2579  {
2580  if ( rFunc.Unprotect( rTab, rPassword, false ) )
2581  {
2582  bChanged = true;
2583  SetTabProtectionSymbol( rTab, false);
2584  }
2585  }
2586 
2587  if (bUndo)
2588  pDocSh->GetUndoManager()->LeaveListAction();
2589  }
2590 
2591  if (bChanged)
2592  UpdateLayerLocks();
2593 
2594  return bChanged;
2595 }
2596 
2597 void ScViewFunc::SetNoteText( const ScAddress& rPos, const OUString& rNoteText )
2598 {
2599  GetViewData().GetDocShell()->GetDocFunc().SetNoteText( rPos, rNoteText, false );
2600 }
2601 
2602 void ScViewFunc::ReplaceNote( const ScAddress& rPos, const OUString& rNoteText, const OUString* pAuthor, const OUString* pDate )
2603 {
2604  GetViewData().GetDocShell()->GetDocFunc().ReplaceNote( rPos, rNoteText, pAuthor, pDate, false );
2605 }
2606 
2608 {
2609  // not editable because of matrix only? attribute OK nonetheless
2610  bool bOnlyNotBecauseOfMatrix;
2611  if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
2612  {
2613  ErrorMessage(STR_PROTECTIONERR);
2614  return;
2615  }
2616 
2617  sal_uInt32 nNumberFormat = 0;
2618  ScViewData& rViewData = GetViewData();
2619  ScDocument& rDoc = rViewData.GetDocument();
2620  SvNumberFormatter* pNumberFormatter = rDoc.GetFormatTable();
2621  LanguageType eLanguage = ScGlobal::eLnge;
2622  ScPatternAttr aNewAttrs( rDoc.GetPool() );
2623 
2624  // always take language from cursor position, even if there is a selection
2625 
2626  sal_uInt32 nCurrentNumberFormat;
2627  rDoc.GetNumberFormat( rViewData.GetCurX(),
2628  rViewData.GetCurY(),
2629  rViewData.GetTabNo(),
2630  nCurrentNumberFormat );
2631  const SvNumberformat* pEntry = pNumberFormatter->GetEntry( nCurrentNumberFormat );
2632  if (pEntry)
2633  eLanguage = pEntry->GetLanguage(); // else keep ScGlobal::eLnge
2634 
2635  nNumberFormat = pNumberFormatter->GetStandardFormat( nFormatType, eLanguage ) + nAdd;
2636 
2637  SfxItemSet& rSet = aNewAttrs.GetItemSet();
2638  rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumberFormat ) );
2639  // ATTR_LANGUAGE_FORMAT not
2640  ApplySelectionPattern( aNewAttrs );
2641 }
2642 
2643 void ScViewFunc::SetNumFmtByStr( const OUString& rCode )
2644 {
2645  // not editable because of matrix only? attribute OK nonetheless
2646  bool bOnlyNotBecauseOfMatrix;
2647  if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
2648  {
2649  ErrorMessage(STR_PROTECTIONERR);
2650  return;
2651  }
2652 
2653  ScViewData& rViewData = GetViewData();
2654  ScDocument& rDoc = rViewData.GetDocument();
2655  SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
2656 
2657  // language always from cursor position
2658 
2659  sal_uInt32 nCurrentNumberFormat;
2660  rDoc.GetNumberFormat( rViewData.GetCurX(), rViewData.GetCurY(),
2661  rViewData.GetTabNo(), nCurrentNumberFormat );
2662  const SvNumberformat* pEntry = pFormatter->GetEntry( nCurrentNumberFormat );
2663  LanguageType eLanguage = pEntry ? pEntry->GetLanguage() : ScGlobal::eLnge;
2664 
2665  // determine index for String
2666 
2667  bool bOk = true;
2668  sal_uInt32 nNumberFormat = pFormatter->GetEntryKey( rCode, eLanguage );
2669  if ( nNumberFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
2670  {
2671  // enter new
2672 
2673  OUString aFormat = rCode; // will be changed
2674  sal_Int32 nErrPos = 0;
2675  SvNumFormatType nType = SvNumFormatType::ALL;
2676  bOk = pFormatter->PutEntry( aFormat, nErrPos, nType, nNumberFormat, eLanguage );
2677  }
2678 
2679  if ( bOk ) // valid format?
2680  {
2681  ScPatternAttr aNewAttrs( rDoc.GetPool() );
2682  SfxItemSet& rSet = aNewAttrs.GetItemSet();
2683  rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumberFormat ) );
2684  rSet.Put( SvxLanguageItem( eLanguage, ATTR_LANGUAGE_FORMAT ) );
2685  ApplySelectionPattern( aNewAttrs );
2686  }
2687 
2689 }
2690 
2691 void ScViewFunc::ChangeNumFmtDecimals( bool bIncrement )
2692 {
2693  // not editable because of matrix only? attribute OK nonetheless
2694  bool bOnlyNotBecauseOfMatrix;
2695  if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
2696  {
2697  ErrorMessage(STR_PROTECTIONERR);
2698  return;
2699  }
2700 
2701  ScDocument& rDoc = GetViewData().GetDocument();
2702  SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
2703 
2704  SCCOL nCol = GetViewData().GetCurX();
2705  SCROW nRow = GetViewData().GetCurY();
2706  SCTAB nTab = GetViewData().GetTabNo();
2707 
2708  sal_uInt32 nOldFormat;
2709  rDoc.GetNumberFormat( nCol, nRow, nTab, nOldFormat );
2710  const SvNumberformat* pOldEntry = pFormatter->GetEntry( nOldFormat );
2711  if (!pOldEntry)
2712  {
2713  OSL_FAIL("numberformat not found !!!");
2714  return;
2715  }
2716 
2717  // what have we got here?
2718 
2719  sal_uInt32 nNewFormat = nOldFormat;
2720  bool bError = false;
2721 
2722  LanguageType eLanguage = pOldEntry->GetLanguage();
2723  bool bThousand, bNegRed;
2724  sal_uInt16 nPrecision, nLeading;
2725  pOldEntry->GetFormatSpecialInfo( bThousand, bNegRed, nPrecision, nLeading );
2726 
2727  SvNumFormatType nOldType = pOldEntry->GetType();
2728  if ( SvNumFormatType::ALL == ( nOldType & (
2729  SvNumFormatType::NUMBER | SvNumFormatType::CURRENCY | SvNumFormatType::PERCENT | SvNumFormatType::SCIENTIFIC | SvNumFormatType::TIME ) ) )
2730  {
2731  // date, fraction, logical, text can not be changed
2732  bError = true;
2733  }
2734 
2736  bool bWasStandard = ( nOldFormat == pFormatter->GetStandardIndex( eLanguage ) );
2737  OUString sExponentialStandardFormat = "";
2738  if (bWasStandard)
2739  {
2740  // with "Standard" the decimal places depend on cell content
2741  // 0 if empty or text -> no decimal places
2742  double nVal = rDoc.GetValue( ScAddress( nCol, nRow, nTab ) );
2743 
2744  // the ways of the Numberformatters are unfathomable, so try:
2745  OUString aOut;
2746  const Color* pCol;
2747  const_cast<SvNumberformat*>(pOldEntry)->GetOutputString( nVal, aOut, &pCol );
2748 
2749  nPrecision = 0;
2750  // 'E' for exponential is fixed in Numberformatter
2751  sal_Int32 nIndexE = aOut.indexOf('E');
2752  if ( nIndexE >= 0 )
2753  {
2754  sExponentialStandardFormat = aOut.copy( nIndexE ).replace( '-', '+' );
2755  for ( sal_Int32 i=1 ; i<sExponentialStandardFormat.getLength() ; i++ )
2756  {
2757  if ( sExponentialStandardFormat[i] >= '1' && sExponentialStandardFormat[i] <= '9' )
2758  sExponentialStandardFormat = sExponentialStandardFormat.replaceAt( i, 1, "0" );
2759  }
2760  aOut = aOut.copy( 0, nIndexE ); // remove exponential part
2761  }
2762  OUString aDecSep( pFormatter->GetFormatDecimalSep( nOldFormat ) );
2763  sal_Int32 nPos = aOut.indexOf( aDecSep );
2764  if ( nPos >= 0 )
2765  nPrecision = aOut.getLength() - nPos - aDecSep.getLength();
2766  // else keep 0
2767  }
2768  else
2769  {
2770  if ( (nOldType & SvNumFormatType::SCIENTIFIC) && !bThousand &&
2771  (pOldEntry->GetFormatIntegerDigits()%3 == 0) && pOldEntry->GetFormatIntegerDigits() > 0 )
2772  bThousand = true;
2773  }
2774 
2775  if (!bError)
2776  {
2777  if (bIncrement)
2778  {
2779  if (nPrecision<20)
2780  ++nPrecision; // increment
2781  else
2782  bError = true; // 20 is maximum
2783  }
2784  else
2785  {
2786  if (nPrecision)
2787  --nPrecision; // decrement
2788  else
2789  bError = true; // 0 is minimum
2790  }
2791  }
2792 
2793  if (!bError)
2794  {
2795  OUString aNewPicture = pFormatter->GenerateFormat(nOldFormat, eLanguage,
2796  bThousand, bNegRed,
2797  nPrecision, nLeading)
2798  + sExponentialStandardFormat;
2799 
2800  nNewFormat = pFormatter->GetEntryKey( aNewPicture, eLanguage );
2801  if ( nNewFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
2802  {
2803  sal_Int32 nErrPos = 0;
2804  SvNumFormatType nNewType = SvNumFormatType::ALL;
2805  bool bOk = pFormatter->PutEntry( aNewPicture, nErrPos,
2806  nNewType, nNewFormat, eLanguage );
2807  OSL_ENSURE( bOk, "incorrect numberformat generated" );
2808  if (!bOk)
2809  bError = true;
2810  }
2811  }
2812 
2813  if (!bError)
2814  {
2815  ScPatternAttr aNewAttrs( rDoc.GetPool() );
2816  SfxItemSet& rSet = aNewAttrs.GetItemSet();
2817  rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) );
2818  // ATTR_LANGUAGE_FORMAT not
2819  ApplySelectionPattern( aNewAttrs );
2820  }
2821 }
2822 
2823 void ScViewFunc::ChangeIndent( bool bIncrement )
2824 {
2825  ScViewData& rViewData = GetViewData();
2826  ScDocShell* pDocSh = rViewData.GetDocShell();
2827  ScMarkData& rMark = rViewData.GetMarkData();
2828 
2829  ScMarkData aWorkMark = rMark;
2830  ScViewUtil::UnmarkFiltered( aWorkMark, pDocSh->GetDocument() );
2831  aWorkMark.MarkToMulti();
2832  if (!aWorkMark.IsMultiMarked())
2833  {
2834  SCCOL nCol = rViewData.GetCurX();
2835  SCROW nRow = rViewData.GetCurY();
2836  SCTAB nTab = rViewData.GetTabNo();
2837  aWorkMark.SetMultiMarkArea( ScRange(nCol,nRow,nTab) );
2838  }
2839 
2840  bool bSuccess = pDocSh->GetDocFunc().ChangeIndent( aWorkMark, bIncrement, false );
2841  if (bSuccess)
2842  {
2843  pDocSh->UpdateOle(rViewData);
2844  StartFormatArea();
2845 
2846  // stuff for sidebar panels
2847  SfxBindings& rBindings = GetViewData().GetBindings();
2848  rBindings.Invalidate( SID_H_ALIGNCELL );
2849  rBindings.Invalidate( SID_ATTR_ALIGN_INDENT );
2850  }
2851 }
2852 
2853 bool ScViewFunc::InsertName( const OUString& rName, const OUString& rSymbol,
2854  const OUString& rType )
2855 {
2856  // Type = P,R,C,F (and combinations)
2858 
2859  bool bOk = false;
2860  ScDocShell* pDocSh = GetViewData().GetDocShell();
2861  ScDocument& rDoc = pDocSh->GetDocument();
2862  SCTAB nTab = GetViewData().GetTabNo();
2863  ScRangeName* pList = rDoc.GetRangeName();
2864 
2866  auto pNewEntry = std::make_unique<ScRangeData>(
2867  rDoc, rName, rSymbol, ScAddress( GetViewData().GetCurX(),
2868  GetViewData().GetCurY(), nTab), nType );
2869  OUString aUpType = rType.toAsciiUpperCase();
2870  if ( aUpType.indexOf( 'P' ) != -1 )
2872  if ( aUpType.indexOf( 'R' ) != -1 )
2874  if ( aUpType.indexOf( 'C' ) != -1 )
2876  if ( aUpType.indexOf( 'F' ) != -1 )
2877  nType |= ScRangeData::Type::Criteria;
2878  pNewEntry->AddType(nType);
2879 
2880  if ( pNewEntry->GetErrCode() == FormulaError::NONE ) // text valid?
2881  {
2882  ScDocShellModificator aModificator( *pDocSh );
2883 
2884  rDoc.PreprocessRangeNameUpdate();
2885 
2886  // input available yet? Then remove beforehand (=change)
2887  ScRangeData* pData = pList->findByUpperName(ScGlobal::getCharClassPtr()->uppercase(rName));
2888  if (pData)
2889  { // take old Index
2890  pNewEntry->SetIndex(pData->GetIndex());
2891  pList->erase(*pData);
2892  }
2893 
2894  // don't delete, insert took ownership, even on failure!
2895  if ( pList->insert( pNewEntry.release() ) )
2896  bOk = true;
2897 
2898  rDoc.CompileHybridFormula();
2899 
2900  aModificator.SetDocumentModified();
2901  SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreasChanged ) );
2902  }
2903 
2904  return bOk;
2905 }
2906 
2908 {
2909  bool bDone = false;
2910  ScRange aRange;
2911  if ( GetViewData().GetSimpleArea(aRange) == SC_MARK_SIMPLE )
2912  bDone = GetViewData().GetDocShell()->GetDocFunc().CreateNames( aRange, nFlags, false );
2913 
2914  if (!bDone)
2915  ErrorMessage(STR_CREATENAME_MARKERR);
2916 }
2917 
2919 {
2921 
2922  SCCOL nStartCol, nEndCol;
2923  SCROW nStartRow, nEndRow;
2924  SCTAB nDummy;
2925  if (GetViewData().GetSimpleArea(nStartCol,nStartRow,nDummy,nEndCol,nEndRow,nDummy) == SC_MARK_SIMPLE)
2926  {
2927  ScDocument& rDoc = GetViewData().GetDocument();
2928  SCTAB nTab = GetViewData().GetTabNo();
2929  bool bOk;
2930  SCCOL i;
2931  SCROW j;
2932 
2933  bOk = true;
2934  SCCOL nFirstCol = nStartCol;
2935  SCCOL nLastCol = nEndCol;
2936  if (nStartCol+1 < nEndCol) { ++nFirstCol; --nLastCol; }
2937  for (i=nFirstCol; i<=nLastCol && bOk; i++)
2938  if (!rDoc.HasStringData( i,nStartRow,nTab ))
2939  bOk = false;
2940  if (bOk)
2941  nFlags |= CreateNameFlags::Top;
2942  else // Bottom only if not Top
2943  {
2944  bOk = true;
2945  for (i=nFirstCol; i<=nLastCol && bOk; i++)
2946  if (!rDoc.HasStringData( i,nEndRow,nTab ))
2947  bOk = false;
2948  if (bOk)
2949  nFlags |= CreateNameFlags::Bottom;
2950  }
2951 
2952  bOk = true;
2953  SCROW nFirstRow = nStartRow;
2954  SCROW nLastRow = nEndRow;
2955  if (nStartRow+1 < nEndRow) { ++nFirstRow; --nLastRow; }
2956  for (j=nFirstRow; j<=nLastRow && bOk; j++)
2957  if (!rDoc.HasStringData( nStartCol,j,nTab ))
2958  bOk = false;
2959  if (bOk)
2960  nFlags |= CreateNameFlags::Left;
2961  else // Right only if not Left
2962  {
2963  bOk = true;
2964  for (j=nFirstRow; j<=nLastRow && bOk; j++)
2965  if (!rDoc.HasStringData( nEndCol,j,nTab ))
2966  bOk = false;
2967  if (bOk)
2968  nFlags |= CreateNameFlags::Right;
2969  }
2970  }
2971 
2972  if (nStartCol == nEndCol)
2974  if (nStartRow == nEndRow)
2976 
2977  return nFlags;
2978 }
2979 
2981 {
2982  ScAddress aPos( GetViewData().GetCurX(), GetViewData().GetCurY(), GetViewData().GetTabNo() );
2983  ScDocShell* pDocSh = GetViewData().GetDocShell();
2984  if ( pDocSh->GetDocFunc().InsertNameList( aPos, false ) )
2985  pDocSh->UpdateOle(GetViewData());
2986 }
2987 
2989 {
2990  ScDocShell* pDocShell = GetViewData().GetDocShell();
2991  ScRange aMarkRange;
2992  if (rSel.IsMultiMarked() )
2993  rSel.GetMultiMarkArea( aMarkRange );
2994  else
2995  rSel.GetMarkArea( aMarkRange );
2996 
2997  bool bSetLines = false;
2998  bool bSetAlign = false;
2999  if ( pAttr )
3000  {
3001  const SfxItemSet& rNewSet = pAttr->GetItemSet();
3002  bSetLines = rNewSet.GetItemState( ATTR_BORDER ) == SfxItemState::SET ||
3003  rNewSet.GetItemState( ATTR_SHADOW ) == SfxItemState::SET;
3004  bSetAlign = rNewSet.GetItemState( ATTR_HOR_JUSTIFY ) == SfxItemState::SET;
3005  }
3006 
3007  sal_uInt16 nExtFlags = 0;
3008  if ( bSetLines )
3009  nExtFlags |= SC_PF_LINES;
3010  if ( bSetAlign )
3011  nExtFlags |= SC_PF_WHOLEROWS;
3012 
3013  SCCOL nStartCol = aMarkRange.aStart.Col();
3014  SCROW nStartRow = aMarkRange.aStart.Row();
3015  SCTAB nStartTab = aMarkRange.aStart.Tab();
3016  SCCOL nEndCol = aMarkRange.aEnd.Col();
3017  SCROW nEndRow = aMarkRange.aEnd.Row();
3018  SCTAB nEndTab = aMarkRange.aEnd.Tab();
3019  pDocShell->PostPaint( nStartCol, nStartRow, nStartTab,
3020  nEndCol, nEndRow, nEndTab,
3021  PaintPartFlags::Grid, nExtFlags | SC_PF_TESTMERGE );
3022  ScTabViewShell* pTabViewShell = GetViewData().GetViewShell();
3023  pTabViewShell->AdjustBlockHeight(false, const_cast<ScMarkData*>(&rSel));
3024 }
3025 
3026 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ScMarkData & GetMarkData()
Definition: viewdata.cxx:3046
#define SC_PF_TESTMERGE
Definition: docsh.hxx:75
void BeginDrawUndo()
Definition: documen9.cxx:58
bool IsBlockEditable(SCTAB nTab, SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, bool *pOnlyNotBecauseOfMatrix=nullptr, bool bNoMatrixAtAll=false) const
Definition: document.cxx:5327
CreateNameFlags GetCreateNameFlags()
Definition: viewfunc.cxx:2918
List of spreadsheet functions.
Definition: funcdesc.hxx:242
SC_DLLPUBLIC void ShowCol(SCCOL nCol, SCTAB nTab, bool bShow)
Definition: document.cxx:4298
void DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTAB nEndTab, SCCOL nStartCol, SCSIZE nSize, ScDocument *pRefUndoDoc=nullptr, bool *pUndoOutline=nullptr, const ScMarkData *pTabMark=nullptr)
Definition: document.cxx:1586
constexpr double nPPTY
void DeleteContents(InsertDeleteFlags nFlags)
Definition: viewfunc.cxx:1936
void UpdatePageBreaks(SCTAB nTab, const ScRange *pUserArea=nullptr)
Definition: document.cxx:6221
SC_DLLPUBLIC void ApplySelectionStyle(const ScStyleSheet &rStyle, const ScMarkData &rMark)
Definition: document.cxx:4859
void ApplyStyle(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScStyleSheet &rStyle)
Definition: document.cxx:4829
void DeleteRow(SCCOL nStartCol, SCTAB nStartTab, SCCOL nEndCol, SCTAB nEndTab, SCROW nStartRow, SCSIZE nSize, ScDocument *pRefUndoDoc=nullptr, bool *pUndoOutline=nullptr, const ScMarkData *pTabMark=nullptr)
Definition: document.cxx:1367
OUString GetColRowString() const
Create a human-readable string representation of the cell address.
Definition: address.cxx:2488
void MarkToSimple()
Definition: markdata.cxx:237
sal_Int32 nIndex
double GetPPTY() const
Definition: sizedev.hxx:42
SC_DLLPUBLIC void ShowRows(SCROW nRow1, SCROW nRow2, SCTAB nTab, bool bShow)
Definition: document.cxx:4310
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:354
ScAddress aStart
Definition: address.hxx:500
bool AdjustBlockHeight(bool bPaint=true, ScMarkData *pMarkData=nullptr)
Definition: viewfun2.cxx:113
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
constexpr TypedWhichId< SvxLanguageItem > ATTR_LANGUAGE_FORMAT(147)
bool Unprotect(SCTAB nTab, const OUString &rPassword, bool bApi)
Definition: docfunc.cxx:4014
bool IsPrinter() const
Definition: sizedev.hxx:43
#define EMPTY_OUSTRING
Definition: global.hxx:215
bool CreateNames(const ScRange &rRange, CreateNameFlags nFlags, bool bApi, SCTAB nTab=-1)
Definition: docfunc.cxx:5273
SC_DLLPUBLIC void RefreshZoom()
Definition: tabview5.cxx:421
SC_DLLPUBLIC bool DeleteContents(const ScMarkData &rMark, InsertDeleteFlags nFlags, bool bRecord, bool bApi)
Definition: docfunc.cxx:567
void CreateNames(CreateNameFlags nFlags)
Definition: viewfunc.cxx:2907
constexpr TypedWhichId< SvxBoxItem > ATTR_BORDER(150)
ScAddress aFormatSource
Definition: viewfunc.hxx:74
SCROW Row() const
Definition: address.hxx:262
ScCellValue maCell
Definition: undocell.hxx:80
void MarkToMulti()
Definition: markdata.cxx:224
bool UpdateOutlineCol(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bShow)
Adapt Outline.
Definition: documen3.cxx:1403
constexpr sal_uInt16 ATTR_PATTERN_START(100)
void SetModified()
Definition: inputhdl.hxx:241
std::unique_ptr< ContentProperties > pData
void GetResultDimensions(SCSIZE &rCols, SCSIZE &rRows)
const Fraction & GetZoomX() const
Definition: viewdata.hxx:459
void SetTabProtectionSymbol(SCTAB nTab, const bool bProtect)
Definition: tabview3.cxx:523
bool SetStringCell(const ScAddress &rPos, const OUString &rStr, bool bInteraction)
Definition: docfunc.cxx:924
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const =0
void DeleteCells(DelCellCmd eCmd)
Definition: viewfunc.cxx:1653
void ApplyAttr(const SfxPoolItem &rAttrItem, bool bAdjustBlockHeight=true)
Definition: viewfunc.cxx:998
void MarkRange(const ScRange &rRange, bool bSetCursor=true, bool bContinue=false)
Definition: tabview3.cxx:1682
sheet protection state container
const SfxItemSet & GetAttribs() const
Definition: editutil.hxx:101
void PostPaintCell(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: docsh3.cxx:186
SC_DLLPUBLIC void SetDrawPageSize(SCTAB nTab)
Definition: documen9.cxx:193
SCCOL GetCurXForTab(SCTAB nTabIndex) const
Definition: viewdata.cxx:1369
void SetMultiMarkArea(const ScRange &rRange, bool bMark=true, bool bSetupMulti=false)
Definition: markdata.cxx:122
bool IsInputMode() const
Definition: inputhdl.hxx:185
int getPart() const override
See SfxViewShell::getPart().
Definition: tabvwshc.cxx:436
sal_uInt16 GetIndex() const
Definition: rangenam.hxx:117
sal_uInt16 GetLRUFuncListCount() const
Definition: appoptio.hxx:48
ScTokenArray * GetCode()
void InsertNameList()
Definition: viewfunc.cxx:2980
void SetLRUFuncList(const sal_uInt16 *pList, const sal_uInt16 nCount)
Definition: appoptio.cxx:111
sal_uIntPtr sal_uLong
long Long
constexpr TypedWhichId< SvxLanguageItem > ATTR_FONT_LANGUAGE(110)
void SetPasteMode(ScPasteFlags nFlags)
Definition: viewdata.hxx:448
SCROW GetCurY() const
Definition: viewdata.hxx:402
SC_DLLPUBLIC ScRangeName * GetRangeName(SCTAB nTab) const
Definition: documen3.cxx:168
ScDocFunc & GetDocFunc() const
Definition: viewdata.cxx:3029
double GetOutputFactor() const
Definition: docsh.hxx:352
ocOpen
sal_Int64 n
vcl::Window * GetFrameWin() const
Definition: tabview.hxx:582
ViewShellDocId GetDocId() const override
std::vector< sc::ColRowSpan > GetMarkedRowSpans() const
Definition: markdata.cxx:479
SvNumFormatType GetType(sal_uInt32 nFIndex) const
void FillRangeListWithMarks(ScRangeList *pList, bool bClear, SCTAB nForTab=-1) const
Create a range list of marks.
Definition: markdata.cxx:387
const SfxItemSet & GetItemSet() const
ScRange aFormatArea
Definition: viewfunc.hxx:75
const ContentProperties & rData
double GetPPTX() const
Definition: viewdata.hxx:468
SCTAB GetTabNo() const
Definition: viewdata.hxx:395
SC_DLLPUBLIC void GetNumberFormat(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt32 &rFormat) const
Definition: document.cxx:3641
constexpr TypedWhichId< SvxBoxInfoItem > ATTR_BORDER_INNER(151)
void Unmark()
Definition: tabview3.cxx:1718
ScAddress aEnd
Definition: address.hxx:501
void EnterValue(SCCOL nCol, SCROW nRow, SCTAB nTab, const double &rValue)
Definition: viewfunc.cxx:594
ScDocument & GetDocument() const
Definition: viewdata.hxx:380
OpCode GetOpCode() const
void OnLOKInsertDeleteRow(SCROW nStartRow, tools::Long nOffset)
Definition: viewfunc.cxx:1520
sal_Int16 GetRightMargin() const
void ProtectSheet(SCTAB nTab, const ScTableProtection &rProtect)
Definition: docfunc.cxx:3934
SC_DLLPUBLIC void SetValue(SCCOL nCol, SCROW nRow, SCTAB nTab, const double &rVal)
Definition: document.cxx:3458
constexpr TypedWhichId< ScLineBreakCell > ATTR_LINEBREAK(139)
This is very similar to ScCellValue, except that it references the original value instead of copying ...
Definition: cellvalue.hxx:104
SC_DLLPUBLIC formula::FormulaGrammar::Grammar GetGrammar() const
Definition: document.hxx:985
void EnterDataAtCursor(const OUString &rString)
Definition: viewfunc.cxx:750
void Invalidate(sal_uInt16 nId)
void Remove(const SfxPoolItem &)
CreateNameFlags
Definition: scui_def.hxx:51
SC_DLLPUBLIC void SetCursor(SCCOL nPosX, SCROW nPosY, bool bNew=false)
Definition: tabview3.cxx:358
SC_DLLPUBLIC bool HasAttrib(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, HasAttrFlags nMask) const
Definition: document.cxx:5179
bool InsertCells(const ScRange &rRange, const ScMarkData *pTabMark, InsCellCmd eCmd, bool bRecord, bool bApi, bool bPartOfPaste=false)
Definition: docfunc.cxx:1726
static void notifyAllViewsSheetGeomInvalidation(const SfxViewShell *pForViewShell, bool bColumns, bool bRows, bool bSizes, bool bHidden, bool bFiltered, bool bGroups, SCTAB nCurrentTabIndex)
Emits a LOK_CALLBACK_INVALIDATE_SHEET_GEOMETRY for all views whose current tab is equal to nCurrentTa...
Definition: tabvwshc.cxx:556
constexpr TypedWhichId< ScMergeAttr > ATTR_MERGE(144)
SC_DLLPUBLIC sal_uInt16 GetRowHeight(SCROW nRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4161
void ResetAutoSpell()
Definition: tabview.cxx:2261
SfxApplication * SfxGetpApp()
Internal use only (d&d undo): do not delete caption objects of cell notes.
constexpr TypedWhichId< ScIndentItem > ATTR_INDENT(131)
DelCellCmd
Definition: global.hxx:291
SC_DLLPUBLIC ScDocumentPool * GetPool()
Definition: document.cxx:6061
static void lcl_PostRepaintCondFormat(const ScConditionalFormat *pCondFmt, ScDocShell *pDocSh)
Definition: viewfunc.cxx:82
void GetMarkArea(ScRange &rRange) const
Definition: markdata.cxx:112
virtual SfxUndoManager * GetUndoManager() override
Definition: docsh.cxx:2805
RET_NO
bool IsInputMode()
Definition: scmod.cxx:1347
static UITestLogger & getInstance()
void UpdateCopySourceOverlay()
Definition: tabview2.cxx:978
Store arbitrary cell value of any kind.
Definition: cellvalue.hxx:36
void logEvent(const EventDescription &rDescription)
const ScStyleSheet * GetStyle(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4898
const ScRangeList & GetRange() const
Definition: conditio.hxx:560
const SfxStyleSheet * GetStyleSheetFromMarked()
Definition: viewfunc.cxx:1295
bool InsertName(const OUString &rName, const OUString &rSymbol, const OUString &rType)
Definition: viewfunc.cxx:2853
bool TestFormatArea(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bAttrChanged)
Definition: viewfunc.cxx:140
RET_YES
#define STD_COL_WIDTH
Definition: global.hxx:94
const OUString & GetName() const
bool SelectionEditable(bool *pOnlyNotBecauseOfMatrix=nullptr)
Definition: viewfunc.cxx:260
PropertiesInfo aProperties
void RemoveStyleSheetInUse(const SfxStyleSheetBase *pStyleSheet)
Definition: viewfunc.cxx:1411
const EditTextObject * mpEditText
Definition: cellvalue.hxx:110
void UpdatePaintExt(sal_uInt16 &rExtFlags, SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab)
Definition: docsh3.cxx:226
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:873
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:45
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt8 nMemberId=0) const
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:24
constexpr TypedWhichId< SvxShadowItem > ATTR_SHADOW(152)
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:314
SvtScriptType GetRangeScriptType(sc::ColumnBlockPosition &rBlockPos, const ScAddress &rPos, SCROW nLength)
Definition: documen6.cxx:183
bool Unprotect(SCTAB nTab, const OUString &rPassword)
Definition: viewfunc.cxx:2553
SC_DLLPUBLIC void SetColWidth(SCCOL nCol, SCTAB nTab, sal_uInt16 nNewWidth)
Definition: document.cxx:4083
const ScPatternAttr * GetSelectionPattern(const ScMarkData &rMark)
Definition: document.cxx:5100
SCTAB GetSelectCount() const
Definition: markdata.cxx:195
bool IsMultiMarked() const
Definition: markdata.hxx:83
bool ChangeIndent(const ScMarkData &rMark, bool bIncrement, bool bApi)
Definition: docfunc.cxx:4138
constexpr sal_uInt32 NUMBERFORMAT_ENTRY_NOT_FOUND
OpCode
sal_uInt32 GetStandardIndex(LanguageType eLnge=LANGUAGE_DONTKNOW)
void MarkDataChanged()
Definition: tabview3.cxx:1741
int nCount
static SfxViewShell * GetNext(const SfxViewShell &rPrev, bool bOnlyVisible=true, const std::function< bool(const SfxViewShell *)> &isViewShell=nullptr)
sal_uInt16 * GetLRUFuncList() const
Definition: appoptio.hxx:49
void CopyToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, InsertDeleteFlags nFlags, bool bMarked, ScDocument &rDestDoc, const ScMarkData *pMarks=nullptr, bool bColRowFlags=true)
Definition: document.cxx:2076
sal_uInt16 GetOptimalColWidth(SCCOL nCol, SCTAB nTab, OutputDevice *pDev, double nPPTX, double nPPTY, const Fraction &rZoomX, const Fraction &rZoomY, bool bFormula, const ScMarkData *pMarkData=nullptr, const ScColWidthParam *pParam=nullptr)
Definition: document.cxx:4240
#define STD_EXTRA_WIDTH
Definition: global.hxx:95
void ReplaceNote(const ScAddress &rPos, const OUString &rNoteText, const OUString *pAuthor, const OUString *pDate, bool bApi)
Definition: docfunc.cxx:1332
void push_back(const ScRange &rRange)
Definition: rangelst.cxx:1144
bool IsDocShared() const
void UpdateEditView()
Definition: tabview3.cxx:2141
Mode eMode
#define HMM_PER_TWIPS
Definition: global.hxx:92
SCTAB Tab() const
Definition: address.hxx:271
void SetRow(SCROW nRowP)
Definition: address.hxx:275
bool DeleteCells(const ScRange &rRange, const ScMarkData *pTabMark, DelCellCmd eCmd, bool bApi)
Definition: docfunc.cxx:2261
void DeleteUnchanged(const ScPatternAttr *pOldAttrs)
Definition: patattr.cxx:920
void DoneBlockMode(bool bContinue=false)
Definition: tabview2.cxx:408
ScViewFunc(vcl::Window *pParent, ScDocShell &rDocSh, ScTabViewShell *pViewShell)
Definition: viewfunc.cxx:92
void EndListAction()
Definition: docfunc.cxx:5769
bool DeleteCell(const ScAddress &rPos, const ScMarkData &rMark, InsertDeleteFlags nFlags, bool bRecord)
Definition: docfunc.cxx:660
bool SetEditCell(const ScAddress &rPos, const EditTextObject &rStr, bool bInteraction)
Definition: docfunc.cxx:961
const Fraction & GetZoomY() const
Definition: viewdata.hxx:460
SC_DLLPUBLIC const ScPatternAttr * GetPattern(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4735
bool SetNormalString(bool &o_rbNumFmtSet, const ScAddress &rPos, const OUString &rText, bool bApi)
Definition: docfunc.cxx:786
void SetCol(SCCOL nColP)
Definition: address.hxx:279
SvtScriptType GetSelectionScriptType()
Definition: viewfunc.cxx:803
ScViewData & GetViewData()
Definition: tabview.hxx:332
bool PutEntry(OUString &rString, sal_Int32 &nCheckPos, SvNumFormatType &nType, sal_uInt32 &nKey, LanguageType eLnge=LANGUAGE_DONTKNOW)
SC_DLLPUBLIC const SfxPoolItem * GetAttr(SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nWhich) const
Definition: document.cxx:4714
bool bFormatValid
Definition: viewfunc.hxx:76
bool Protect(SCTAB nTab, const OUString &rPassword)
Definition: docfunc.cxx:3959
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Definition: patattr.hxx:70
OutputDevice * GetDevice() const
Definition: sizedev.hxx:40
SC_DLLPUBLIC double GetValue(const ScAddress &rPos) const
Definition: document.cxx:3628
void PaintArea(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, ScUpdateMode eMode=ScUpdateMode::All)
Definition: tabview3.cxx:2299
ScTabViewShell * GetViewShell() const
Definition: viewdata.hxx:357
void SetNoteText(const ScAddress &rPos, const OUString &rNoteText)
Definition: viewfunc.cxx:2597
constexpr double nPPTX
bool ApplyAttributes(const ScMarkData &rMark, const ScPatternAttr &rPattern, bool bApi)
Definition: docfunc.cxx:1416
SC_DLLPUBLIC bool SetEditText(const ScAddress &rPos, std::unique_ptr< EditTextObject > pEditText)
This method manages the lifecycle of the passed edit text object.
Definition: document.cxx:3394
static SC_DLLPUBLIC sal_uInt16 nStdRowHeight
Definition: global.hxx:584
const char * GetMessageId() const
Definition: editable.cxx:152
SC_DLLPUBLIC void SetAppOptions(const ScAppOptions &rOpt)
Definition: scmod.cxx:719
void SetMarkArea(const ScRange &rRange)
Definition: markdata.cxx:97
void SetTab(SCTAB nTabP)
Definition: address.hxx:283
SC_DLLPUBLIC ScRangeData * findByUpperName(const OUString &rName)
Definition: rangenam.cxx:682
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:872
const ScStyleSheet * GetSelectionStyle(const ScMarkData &rMark) const
Definition: document.cxx:4906
virtual void AddUndoAction(std::unique_ptr< SfxUndoAction > pAction, bool bTryMerg=false)
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:438
SvNumFormatType GetType() const
SC_DLLPUBLIC bool ColHidden(SCCOL nCol, SCTAB nTab, SCCOL *pFirstCol=nullptr, SCCOL *pLastCol=nullptr) const
Definition: document.cxx:4445
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
SvtScriptType
void OnLOKSetWidthOrHeight(SCCOLROW nStart, bool bWidth)
Definition: viewfunc.cxx:1576
#define SV_MAX_COUNT_STANDARD_FORMATS
void SetTextCurrentDefaults(const EditTextObject &rTextObject)
SetText and apply defaults already set.
Definition: editutil.cxx:559
bool IsMarked() const
Definition: markdata.hxx:82
#define nPixel
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
int i
bool ApplyStyle(const ScMarkData &rMark, const OUString &rStyleName, bool bApi)
Definition: docfunc.cxx:1485
void GetSelectionCover(ScRange &rRange)
Definition: markdata.cxx:695
void SelectTable(SCTAB nTab, bool bNew)
Definition: markdata.cxx:172
void Notify(ScModelObj &rModelObj, const ScRangeList &rChangeRanges, const OUString &rType=OUString("cell-change"), const css::uno::Sequence< css::beans::PropertyValue > &rProperties=css::uno::Sequence< css::beans::PropertyValue >())
Definition: docsh.hxx:477
void invalidateByIndex(index_type nIndex)
Definition: viewdata.cxx:157
void Set(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: address.hxx:406
SfxBindings & GetBindings()
Definition: viewdata.cxx:3034
std::unique_ptr< ScDocument, o3tl::default_delete< ScDocument > > ScDocumentUniquePtr
Definition: document.hxx:2613
sal_Int16 SCCOL
Definition: types.hxx:22
InsertDeleteFlags
Definition: global.hxx:159
#define SC_MOD()
Definition: scmod.hxx:253
void UpdateStyleSheetInUse(const SfxStyleSheetBase *pStyleSheet)
Definition: viewfunc.cxx:1437
SC_DLLPUBLIC bool SetOptimalHeight(sc::RowHeightContext &rCxt, SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
Definition: document.cxx:4266
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:874
void RemoveEditTextCharAttribs(const ScAddress &rPos, const ScPatternAttr &rAttr)
Definition: document.cxx:3620
bool IsStaticDefaultItem(const SfxPoolItem *pItem)
const ScStyleSheet * GetStyleSheet() const
Definition: patattr.hxx:126
SC_DLLPUBLIC const ScAppOptions & GetAppOptions()
Definition: scmod.cxx:732
static const SfxItemPropertyMap & GetCellPropertyMap()
Definition: cellsuno.cxx:5790
SC_DLLPUBLIC SfxItemPool * GetEnginePool() const
Definition: documen2.cxx:449
SC_DLLPUBLIC void ApplyPattern(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScPatternAttr &rAttr)
Definition: document.cxx:4763
tools::Long Width() const
void SelectOneTable(SCTAB nTab)
Definition: markdata.cxx:189
OUString ScResId(const char *pId)
Definition: scdll.cxx:95
ScMarkType GetSimpleArea(SCCOL &rStartCol, SCROW &rStartRow, SCTAB &rStartTab, SCCOL &rEndCol, SCROW &rEndRow, SCTAB &rEndTab) const
Definition: viewdata.cxx:1170
void SetNumFmtByStr(const OUString &rCode)
Definition: viewfunc.cxx:2643
bool IsNumberFormat(const OUString &sString, sal_uInt32 &F_Index, double &fOutNumber, SvNumInputOptions eInputOptions=SvNumInputOptions::NONE)
void ChangeIndent(bool bIncrement)
Definition: viewfunc.cxx:2823
void EnterListAction(const char *pNameResId)
Definition: docfunc.cxx:5760
bool GetOption(ScViewOption eOpt) const
Definition: viewopti.hxx:88
#define LANGUAGE_DONTKNOW
constexpr TypedWhichId< SfxUInt32Item > ATTR_VALUE_FORMAT(146)
SvNumFormatType
SC_DLLPUBLIC void SetRowHeightRange(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, sal_uInt16 nNewHeight)
Definition: document.cxx:4101
#define LRU_MAX
Definition: funcdesc.hxx:35
void ReplaceNote(const ScAddress &rPos, const OUString &rNoteText, const OUString *pAuthor, const OUString *pDate)
Definition: viewfunc.cxx:2602
void ApplySelectionPattern(const ScPatternAttr &rAttr, bool bCursorOnly=false)
Definition: viewfunc.cxx:1108
bool IsFunction() const
SC_DLLPUBLIC const EditTextObject * GetEditText(const ScAddress &rPos) const
Definition: document.cxx:3611
bool IsEditable() const
Definition: editable.hxx:84
void DeleteObjectsInArea(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, const ScMarkData &rMark, bool bAnchored=false)
Definition: documen9.cxx:250
void InitOwnBlockMode()
Definition: tabview2.cxx:331
#define SV_COUNTRY_LANGUAGE_OFFSET
void erase(const ScRangeData &r)
Definition: rangenam.cxx:853
void SetNumberFormat(SvNumFormatType nFormatType, sal_uLong nAdd=0)
Definition: viewfunc.cxx:2607
static void UnmarkFiltered(ScMarkData &rMark, const ScDocument &rDoc)
Definition: viewutil.cxx:223
static SC_DLLPUBLIC LanguageType eLnge
Definition: global.hxx:548
const SCTAB MAXTAB
Definition: address.hxx:71
void setForceAutoSize(bool b)
void StartFormatArea()
Definition: viewfunc.cxx:118
static SfxViewShell * GetFirst(bool bOnlyVisible=true, const std::function< bool(const SfxViewShell *)> &isViewShell=nullptr)
static void notifyAllViewsHeaderInvalidation(const SfxViewShell *pForViewShell, HeaderType eHeaderType, SCTAB nCurrentTabIndex)
Emits a LOK_CALLBACK_INVALIDATE_HEADER for all views whose current tab is equal to nCurrentTabIndex...
Definition: tabvwshc.cxx:499
void PostPaint(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, sal_uInt16 nExtFlags=0)
Definition: docsh3.cxx:99
SC_DLLPUBLIC bool ExtendMerge(SCCOL nStartCol, SCROW nStartRow, SCCOL &rEndCol, SCROW &rEndRow, SCTAB nTab, bool bRefresh=false)
Definition: document.cxx:5568
SfxItemPool * GetPool() const
Size GetTextSize()
Definition: inputhdl.cxx:4231
const ScFuncDesc * GetFunction(sal_uInt32 nIndex) const
Definition: funcdesc.cxx:1015
std::vector< Value > ValuesType
Definition: undocell.hxx:85
void UpdateScrollBars(HeaderType eHeaderType=BOTH_HEADERS)
Definition: tabview4.cxx:392
ScSizeMode
Definition: global.hxx:360
const SCTAB TABLEID_DOC
Definition: address.hxx:85
FormulaError
SCCOL Col() const
Definition: address.hxx:267
static ScFunctionList * GetStarCalcFunctionList()
Definition: global.cxx:611
OUString GetFormatDecimalSep(sal_uInt32 nFormat) const
bool IsReadOnly() const
SC_DLLPUBLIC const ScPatternAttr * GetSelectionPattern()
Definition: viewfunc.cxx:829
SC_DLLPUBLIC bool HasStringData(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:3756
size_t LeaveListAction()
static bool lcl_FunctionKnown(sal_uInt16 nOpCode)
Definition: viewfunc.cxx:278
ScDBFunc * GetView() const
Definition: viewdata.cxx:852
std::vector< SfxItemPropertyNamedEntry > PropertyEntryVector_t
#define MAX_COL_WIDTH
Definition: global.hxx:101
bool IsValid(SvxBoxInfoItemValidFlags nValid) const
size_t mnStart
Definition: cellvalues.cxx:23
ScModelObj * getMustPropagateChangesModel(const ScDocShell &rDocShell)
Definition: docsh.hxx:469
void SetCurYForTab(SCCOL nNewCurY, SCTAB nTabIndex)
Definition: viewdata.cxx:1393
void EnterMatrix(const OUString &rString,::formula::FormulaGrammar::Grammar eGram)
Definition: viewfunc.cxx:759
CellType meType
Definition: cellvalue.hxx:106
bool InsertNameList(const ScAddress &rStartPos, bool bApi)
Definition: docfunc.cxx:5362
OUString GenerateFormat(sal_uInt32 nIndex, LanguageType eLnge=LANGUAGE_DONTKNOW, bool bThousand=false, bool IsRed=false, sal_uInt16 nPrecision=0, sal_uInt16 nLeadingCnt=1)
CRFlags
Definition: global.hxx:136
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
sal_Int32 SCROW
Definition: types.hxx:18
static SC_DLLPUBLIC SvtScriptType GetDefaultScriptType()
Definition: global.cxx:850
#define SC_PF_LINES
Definition: docsh.hxx:74
void ApplyPatternLines(const ScPatternAttr &rAttr, const SvxBoxItem &rNewOuter, const SvxBoxInfoItem *pNewInner)
Definition: viewfunc.cxx:1026
void SetIndex(sal_uInt16 nInd)
Definition: rangenam.hxx:116
void StyleSheetChanged(const SfxStyleSheetBase *pStyleSheet, bool bRemoved, OutputDevice *pDev, double nPPTX, double nPPTY, const Fraction &rZoomX, const Fraction &rZoomY)
Definition: document.cxx:4956
void UpdateOle(const ScViewData &rViewData, bool bSnapSize=false)
Definition: docsh6.cxx:152
bool SetFormulaCell(const ScAddress &rPos, ScFormulaCell *pCell, bool bInteraction)
Below two methods take ownership of the formula cell instance(s).
Definition: docfunc.cxx:1011
double GetPPTY() const
Definition: viewdata.hxx:469
void DoAutoAttributes(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bAttrChanged)
Definition: viewfunc.cxx:205
void HideAllCursors()
Definition: tabview3.cxx:215
PropertyEntryVector_t getPropertyEntries() const
bool AdjustRowHeight(SCROW nStartRow, SCROW nEndRow)
Definition: viewfun2.cxx:191
void SetNoteText(const ScAddress &rPos, const OUString &rNoteText, bool bApi)
Definition: docfunc.cxx:1306
sal_uInt16 GetFormatIntegerDigits(sal_uInt16 nIx=0) const
void ProtectSheet(SCTAB nTab, const ScTableProtection &rProtect)
Definition: viewfunc.cxx:2492
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
#define MAX_ROW_HEIGHT
Definition: global.hxx:102
void ErrorMessage(const char *pGlobStrId)
Definition: tabview2.cxx:1412
const SvNumberformat * GetEntry(sal_uInt32 nKey) const
SCROW GetCurYForTab(SCTAB nTabIndex) const
Definition: viewdata.cxx:1377
void assign(const ScDocument &rDoc, const ScAddress &rPos)
Take cell value from specified position in specified document.
Definition: cellvalue.cxx:330
void ChangeNumFmtDecimals(bool bIncrement)
Definition: viewfunc.cxx:2691
void MoveCursorRel(SCCOL nMovX, SCROW nMovY, ScFollowMode eMode, bool bShift, bool bKeepSel=false)
Definition: tabview3.cxx:1260
OUString aName
SCTAB GetFirstSelected() const
Definition: markdata.cxx:200
sal_uInt32 GetStandardFormat(SvNumFormatType eType, LanguageType eLnge=LANGUAGE_DONTKNOW)
void SetCurXForTab(SCCOL nNewCurX, SCTAB nTabIndex)
Definition: viewdata.cxx:1385
SC_DLLPUBLIC bool RemoveFlagsTab(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, ScMF nFlags)
Definition: document.cxx:5023
InsCellCmd
Definition: global.hxx:300
SC_DLLPUBLIC void ApplySelectionPattern(const ScPatternAttr &rAttr, const ScMarkData &rMark, ScEditDataArray *pDataArray=nullptr, bool *pIsChanged=nullptr)
Definition: document.cxx:5874
SC_DLLPUBLIC bool EnterMatrix(const ScRange &rRange, const ScMarkData *pTabMark, const ScTokenArray *pTokenArray, const OUString &rString, bool bApi, bool bEnglish, const OUString &rFormulaNmsp, const formula::FormulaGrammar::Grammar)
Definition: docfunc.cxx:4320
sal_Int16 GetLeftMargin() const
const T & Put(std::unique_ptr< T > xItem, sal_uInt16 nWhich=0)
SC_DLLPUBLIC SvtScriptType GetScriptType(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScRefCellValue *pCell=nullptr)
Definition: documen6.cxx:132
SC_DLLPUBLIC ScOutlineTable * GetOutlineTable(SCTAB nTab, bool bCreate=false)
Definition: documen3.cxx:731
bool HasItem(sal_uInt16 nWhich, const SfxPoolItem **ppItem=nullptr) const
constexpr TypedWhichId< SvxHorJustifyItem > ATTR_HOR_JUSTIFY(129)
void SetStyleSheetToMarked(const SfxStyleSheet *pStyleSheet)
Definition: viewfunc.cxx:1315
void Protect(SCTAB nTab, const OUString &rPassword)
Definition: viewfunc.cxx:2523
const ScViewOptions & GetOptions() const
Definition: viewdata.hxx:537
virtual void EnterListAction(const OUString &rComment, const OUString &rRepeatComment, sal_uInt16 nId, ViewShellId nViewShellId)
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
void OnLOKInsertDeleteColumn(SCCOL nStartCol, tools::Long nOffset)
Definition: viewfunc.cxx:1464
static SC_DLLPUBLIC const CharClass * getCharClassPtr()
Definition: global.cxx:1010
bool UpdateOutlineRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bShow)
Definition: documen3.cxx:1412
SC_DLLPUBLIC void SetManualHeight(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bManual)
Definition: document.cxx:4114
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:401
constexpr sal_uInt16 ATTR_PATTERN_END(155)
const ScDocument & GetDocument() const
Definition: docsh.hxx:216
sal_uInt16 nFIndex
Unique function index.
Definition: funcdesc.hxx:222
void SetWidthOrHeight(bool bWidth, const std::vector< sc::ColRowSpan > &rRanges, ScSizeMode eMode, sal_uInt16 nSizeTwips, bool bRecord=true, const ScMarkData *pMarkData=nullptr)
Definition: viewfunc.cxx:2022
static OUString GetSpaceDelimitedString(const EditEngine &rEngine)
Retrieves string with paragraphs delimited by spaces.
Definition: editutil.cxx:101
sal_uInt32 GetCount() const
Definition: funcdesc.hxx:248
ScPositionHelper & GetLOKWidthHelper()
Definition: viewdata.hxx:410
SC_DLLPUBLIC SfxItemPool * GetEditPool() const
Definition: documen2.cxx:444
void NotifyIfChangesListeners(const ScDocShell &rDocShell, const ScRange &rRange, const OUString &rType=OUString("cell-change"))
Definition: docsh.hxx:485
void SetMarking(bool bFlag)
Definition: markdata.hxx:103
sal_uInt32 GetEntryKey(const OUString &sStr, LanguageType eLnge=LANGUAGE_DONTKNOW)
SC_DLLPUBLIC bool RowHidden(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: document.cxx:4429
void UpdateSelectionArea(const ScMarkData &rSel, ScPatternAttr *pAttr=nullptr)
Definition: viewfunc.cxx:2988
static bool lcl_AddFunction(ScAppOptions &rAppOpt, sal_uInt16 nOpCode)
Definition: viewfunc.cxx:291
void SetDocumentModified()
Definition: docsh.cxx:3158
#define SC_PF_WHOLEROWS
Definition: docsh.hxx:76
void ApplyUserItemSet(const SfxItemSet &rItemSet)
Definition: viewfunc.cxx:1276
bool IsUndoEnabled() const
Definition: document.hxx:1531
void SetMarkedWidthOrHeight(bool bWidth, ScSizeMode eMode, sal_uInt16 nSizeTwips)
Definition: viewfunc.cxx:2328
ScDirection
Definition: global.hxx:352
void GetSelectionFrame(const ScMarkData &rMark, SvxBoxItem &rLineOuter, SvxBoxInfoItem &rLineInner)
Definition: document.cxx:5106
void ApplyAttributes(const SfxItemSet *pDialogSet, const SfxItemSet *pOldSet, bool bAdjustBlockHeight=true)
Definition: viewfunc.cxx:886
void GetMultiMarkArea(ScRange &rRange) const
Definition: markdata.cxx:117
bool NeedsCellAttr() const
Definition: editutil.hxx:100
ScInputHandler * GetInputHdl(ScTabViewShell *pViewSh=nullptr, bool bUseRef=true)
Input-Handler.
Definition: scmod.cxx:1303
SC_DLLPUBLIC ScConditionalFormat * GetCondFormat(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: documen4.cxx:834
ScDocFunc & GetDocFunc()
Definition: docsh.hxx:218
bool NeedsObject() const
Definition: editutil.hxx:99
ScPositionHelper & GetLOKHeightHelper()
Definition: viewdata.hxx:411
SC_DLLPUBLIC void SetRowFlags(SCROW nRow, SCTAB nTab, CRFlags nNewFlags)
Definition: document.cxx:4316
ScEditDataArray * GetDataArray()
Definition: undoblk3.cxx:378
std::map< OUString, OUString > aParameters
void ApplySelectionFrame(const ScMarkData &rMark, const SvxBoxItem &rLineOuter, const SvxBoxInfoItem *pLineInner)
Definition: document.cxx:5753
void UpdateLayerLocks()
Definition: tabview5.cxx:341
SC_DLLPUBLIC void ExtendOverlapped(SCCOL &rStartCol, SCROW &rStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:5478
SC_DLLPUBLIC sal_uInt16 GetColWidth(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4120
sal_uInt16 GetOptimalColWidth(SCCOL nCol, SCTAB nTab, bool bFormula)
Definition: viewfunc.cxx:236
std::vector< sc::ColRowSpan > GetMarkedColSpans() const
Definition: markdata.cxx:496
std::unique_ptr< EditTextObject > Clone() const
bool IsRemoveAdjacentCellBorder() const
void SetErrCode(FormulaError n)
const ScInputHandler * GetInputHandler() const
Definition: tabvwsh.hxx:233
void SetHyperLink(bool bVal)
void ModifyCellSize(ScDirection eDir, bool bOptimal)
Definition: viewfunc.cxx:2352
void DeleteMulti(bool bRows)
Definition: viewfunc.cxx:1741
SC_DLLPUBLIC void CellContentChanged()
Definition: tabview3.cxx:509
void SetAutoCorrection(bool bVal)
When auto correction is set, the jump command reorder must be enabled.
Definition: compiler.cxx:4018
double GetPPTX() const
Definition: sizedev.hxx:41
ocClose
SC_DLLPUBLIC bool insert(ScRangeData *p, bool bReuseFreeIndex=true)
Insert object into set.
Definition: rangenam.cxx:810
void GetSelectionFrame(std::shared_ptr< SvxBoxItem > &rLineOuter, std::shared_ptr< SvxBoxInfoItem > &rLineInner)
Definition: viewfunc.cxx:855
sal_uInt16 Which() const
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
Create before modifications of the document and destroy thereafter.
Definition: docsh.hxx:450
bool IsSelectionEditable(const ScMarkData &rMark, bool *pOnlyNotBecauseOfMatrix=nullptr) const
Definition: document.cxx:5351
LanguageType GetLanguage() const
void ForgetLastPattern()
Definition: inputhdl.cxx:2224
sal_uInt16 nPos
sal_Int16 SCTAB
Definition: types.hxx:23
SC_DLLPUBLIC CRFlags GetRowFlags(SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4336
constexpr TypedWhichId< SvxMarginItem > ATTR_MARGIN(143)
bool InsertCells(InsCellCmd eCmd, bool bRecord=true, bool bPartOfPaste=false)
Definition: viewfunc.cxx:1600
void EnterData(SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString &rString, const EditTextObject *pData=nullptr)
Definition: viewfunc.cxx:342
void GetFormatSpecialInfo(bool &bThousand, bool &IsRed, sal_uInt16 &nPrecision, sal_uInt16 &nLeadingCnt) const
void ShowAllCursors()
Definition: tabview3.cxx:229
SCCOL GetCurX() const
Definition: viewdata.hxx:401
void SetMarkData(const ScMarkData &rNew)
Definition: tabview3.cxx:1732