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/justifyitem.hxx>
30 #include <sfx2/bindings.hxx>
31 #include <svl/zforlist.hxx>
32 #include <svl/zformat.hxx>
33 #include <vcl/svapp.hxx>
34 #include <vcl/weld.hxx>
35 #include <vcl/virdev.hxx>
36 #include <vcl/waitobj.hxx>
37 #include <stdlib.h>
38 #include <unotools/charclass.hxx>
39 #include <vcl/uitest/logger.hxx>
41 
42 #include <viewfunc.hxx>
43 #include <tabvwsh.hxx>
44 #include <docsh.hxx>
45 #include <attrib.hxx>
46 #include <patattr.hxx>
47 #include <docpool.hxx>
48 #include <sc.hrc>
49 #include <strings.hrc>
50 #include <undocell.hxx>
51 #include <undoblk.hxx>
52 #include <refundo.hxx>
53 #include <olinetab.hxx>
54 #include <rangenam.hxx>
55 #include <globstr.hrc>
56 #include <global.hxx>
57 #include <stlsheet.hxx>
58 #include <editutil.hxx>
59 #include <formulacell.hxx>
60 #include <scresid.hxx>
61 #include <inputhdl.hxx>
62 #include <scmod.hxx>
63 #include <inputopt.hxx>
64 #include <compiler.hxx>
65 #include <docfunc.hxx>
66 #include <appoptio.hxx>
67 #include <sizedev.hxx>
68 #include <editable.hxx>
69 #include <scui_def.hxx>
70 #include <funcdesc.hxx>
71 #include <docuno.hxx>
72 #include <cellsuno.hxx>
73 #include <tokenarray.hxx>
74 #include <rowheightcontext.hxx>
75 #include <comphelper/lok.hxx>
76 #include <conditio.hxx>
77 #include <columnspanset.hxx>
78 
79 #include <memory>
80 
81 static void lcl_PostRepaintCondFormat( const ScConditionalFormat *pCondFmt, ScDocShell *pDocSh )
82 {
83  if( pCondFmt )
84  {
85  const ScRangeList& rRanges = pCondFmt->GetRange();
86 
87  pDocSh->PostPaint( rRanges, PaintPartFlags::All );
88  }
89 }
90 
91 ScViewFunc::ScViewFunc( vcl::Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
92  ScTabView( pParent, rDocSh, pViewShell ),
93  bFormatValid( false )
94 {
95 }
96 
98 {
99 }
100 
101 namespace {
102 
103 void collectUIInformation(const std::map<OUString, OUString>& aParameters, const OUString& rAction)
104 {
105  EventDescription aDescription;
106  aDescription.aID = "grid_window";
107  aDescription.aAction = rAction;
108  aDescription.aParameters = aParameters;
109  aDescription.aParent = "MainWindow";
110  aDescription.aKeyWord = "ScGridWinUIObject";
111 
112  UITestLogger::getInstance().logEvent(aDescription);
113 }
114 
115 }
116 
118 {
119  // anything to do?
120  if ( !SC_MOD()->GetInputOptions().GetExtendFormat() )
121  return;
122 
123  // start only with single cell (marked or cursor position)
124  ScRange aMarkRange;
125  bool bOk = (GetViewData().GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE);
126  if ( bOk && aMarkRange.aStart != aMarkRange.aEnd )
127  bOk = false;
128 
129  if (bOk)
130  {
131  bFormatValid = true;
132  aFormatSource = aMarkRange.aStart;
134  }
135  else
136  bFormatValid = false; // discard old range
137 }
138 
139 bool ScViewFunc::TestFormatArea( SCCOL nCol, SCROW nRow, SCTAB nTab, bool bAttrChanged )
140 {
141  // anything to do?
142  if ( !SC_MOD()->GetInputOptions().GetExtendFormat() )
143  return false;
144 
145  // Test: treat input with numberformat (bAttrChanged) always as new Attribute
146  // (discard old Area ). If not wanted, discard if-statement
147  if ( bAttrChanged )
148  {
149  StartFormatArea();
150  return false;
151  }
152 
154 
155  bool bFound = false;
156  ScRange aNewRange = aFormatArea;
157  if ( bFormatValid && nTab == aFormatSource.Tab() )
158  {
159  if ( nRow >= aFormatArea.aStart.Row() && nRow <= aFormatArea.aEnd.Row() )
160  {
161  // within range?
162  if ( nCol >= aFormatArea.aStart.Col() && nCol <= aFormatArea.aEnd.Col() )
163  {
164  bFound = true; // do not change range
165  }
166  // left ?
167  if ( nCol+1 == aFormatArea.aStart.Col() )
168  {
169  bFound = true;
170  aNewRange.aStart.SetCol( nCol );
171  }
172  // right ?
173  if ( nCol == aFormatArea.aEnd.Col()+1 )
174  {
175  bFound = true;
176  aNewRange.aEnd.SetCol( nCol );
177  }
178  }
179  if ( nCol >= aFormatArea.aStart.Col() && nCol <= aFormatArea.aEnd.Col() )
180  {
181  // top ?
182  if ( nRow+1 == aFormatArea.aStart.Row() )
183  {
184  bFound = true;
185  aNewRange.aStart.SetRow( nRow );
186  }
187  // bottom ?
188  if ( nRow == aFormatArea.aEnd.Row()+1 )
189  {
190  bFound = true;
191  aNewRange.aEnd.SetRow( nRow );
192  }
193  }
194  }
195 
196  if (bFound)
197  aFormatArea = aNewRange; // extend
198  else
199  bFormatValid = false; // outside of range -> break
200 
201  return bFound;
202 }
203 
205  bool bAttrChanged )
206 {
207  ScDocShell* pDocSh = GetViewData().GetDocShell();
208  ScDocument& rDoc = pDocSh->GetDocument();
209 
210  const ScPatternAttr* pSource = rDoc.GetPattern(
211  aFormatSource.Col(), aFormatSource.Row(), nTab );
212  if ( !pSource->GetItem(ATTR_MERGE).IsMerged() )
213  {
214  ScRange aRange( nCol, nRow, nTab, nCol, nRow, nTab );
215  ScMarkData aMark(rDoc.GetSheetLimits());
216  aMark.SetMarkArea( aRange );
217 
218  ScDocFunc &rFunc = GetViewData().GetDocFunc();
219 
220  // pOldPattern is only valid until call to ApplyAttributes!
221  const ScPatternAttr* pOldPattern = rDoc.GetPattern( nCol, nRow, nTab );
222  const ScStyleSheet* pSrcStyle = pSource->GetStyleSheet();
223  if ( pSrcStyle && pSrcStyle != pOldPattern->GetStyleSheet() )
224  rFunc.ApplyStyle( aMark, pSrcStyle->GetName(), false );
225 
226  rFunc.ApplyAttributes( aMark, *pSource, false );
227  }
228 
229  if ( bAttrChanged ) // value entered with number format?
230  aFormatSource.Set( nCol, nRow, nTab ); // then set a new source
231 }
232 
233 // additional routines
234 
235 sal_uInt16 ScViewFunc::GetOptimalColWidth( SCCOL nCol, SCTAB nTab, bool bFormula )
236 {
237  ScDocShell* pDocSh = GetViewData().GetDocShell();
238  ScDocument& rDoc = pDocSh->GetDocument();
239  ScMarkData& rMark = GetViewData().GetMarkData();
240 
241  double nPPTX = GetViewData().GetPPTX();
242  double nPPTY = GetViewData().GetPPTY();
243  Fraction aZoomX = GetViewData().GetZoomX();
244  Fraction aZoomY = GetViewData().GetZoomY();
245 
246  ScSizeDeviceProvider aProv(pDocSh);
247  if (aProv.IsPrinter())
248  {
249  nPPTX = aProv.GetPPTX();
250  nPPTY = aProv.GetPPTY();
251  aZoomX = aZoomY = Fraction( 1, 1 );
252  }
253 
254  sal_uInt16 nTwips = rDoc.GetOptimalColWidth( nCol, nTab, aProv.GetDevice(),
255  nPPTX, nPPTY, aZoomX, aZoomY, bFormula, &rMark );
256  return nTwips;
257 }
258 
259 bool ScViewFunc::SelectionEditable( bool* pOnlyNotBecauseOfMatrix /* = NULL */ )
260 {
261  bool bRet;
262  ScDocument& rDoc = GetViewData().GetDocument();
263  ScMarkData& rMark = GetViewData().GetMarkData();
264  if (rMark.IsMarked() || rMark.IsMultiMarked())
265  bRet = rDoc.IsSelectionEditable( rMark, pOnlyNotBecauseOfMatrix );
266  else
267  {
268  SCCOL nCol = GetViewData().GetCurX();
269  SCROW nRow = GetViewData().GetCurY();
270  SCTAB nTab = GetViewData().GetTabNo();
271  bRet = rDoc.IsBlockEditable( nTab, nCol, nRow, nCol, nRow,
272  pOnlyNotBecauseOfMatrix );
273  }
274  return bRet;
275 }
276 
277 static bool lcl_FunctionKnown( sal_uInt16 nOpCode )
278 {
280  if ( pFuncList )
281  {
282  sal_uLong nCount = pFuncList->GetCount();
283  for (sal_uLong i=0; i<nCount; i++)
284  if ( pFuncList->GetFunction(i)->nFIndex == nOpCode )
285  return true;
286  }
287  return false;
288 }
289 
290 static bool lcl_AddFunction( ScAppOptions& rAppOpt, sal_uInt16 nOpCode )
291 {
292  sal_uInt16 nOldCount = rAppOpt.GetLRUFuncListCount();
293  sal_uInt16* pOldList = rAppOpt.GetLRUFuncList();
294  sal_uInt16 nPos;
295  for (nPos=0; nPos<nOldCount; nPos++)
296  if (pOldList[nPos] == nOpCode) // is the function already in the list?
297  {
298  if ( nPos == 0 )
299  return false; // already at the top -> no change
300 
301  // count doesn't change, so the original array is modified
302 
303  for (sal_uInt16 nCopy=nPos; nCopy>0; nCopy--)
304  pOldList[nCopy] = pOldList[nCopy-1];
305  pOldList[0] = nOpCode;
306 
307  return true; // list has changed
308  }
309 
310  if ( !lcl_FunctionKnown( nOpCode ) )
311  return false; // not in function list -> no change
312 
313  sal_uInt16 nNewCount = std::min( static_cast<sal_uInt16>(nOldCount + 1), sal_uInt16(LRU_MAX) );
314  sal_uInt16 nNewList[LRU_MAX];
315  nNewList[0] = nOpCode;
316  for (nPos=1; nPos<nNewCount; nPos++)
317  nNewList[nPos] = pOldList[nPos-1];
318  rAppOpt.SetLRUFuncList( nNewList, nNewCount );
319 
320  return true; // list has changed
321 }
322 
323 namespace HelperNotifyChanges
324 {
325  static void NotifyIfChangesListeners(const ScDocShell &rDocShell, ScMarkData& rMark, SCCOL nCol, SCROW nRow)
326  {
327  if (ScModelObj *pModelObj = getMustPropagateChangesModel(rDocShell))
328  {
329  ScRangeList aChangeRanges;
330  for (const auto& rTab : rMark)
331  aChangeRanges.push_back( ScRange( nCol, nRow, rTab ) );
332 
333  HelperNotifyChanges::Notify(*pModelObj, aChangeRanges, "cell-change");
334  }
335  }
336 }
337 
338 // actual functions
339 
340 // input - undo OK
341 void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab,
342  const OUString& rString,
343  const EditTextObject* pData )
344 {
345  ScDocument& rDoc = GetViewData().GetDocument();
346  ScMarkData rMark(GetViewData().GetMarkData());
347  bool bRecord = rDoc.IsUndoEnabled();
348  SCTAB i;
349 
350  ScDocShell* pDocSh = GetViewData().GetDocShell();
351  ScDocFunc &rFunc = GetViewData().GetDocFunc();
352  ScDocShellModificator aModificator( *pDocSh );
353 
354  ScEditableTester aTester( rDoc, nCol,nRow, nCol,nRow, rMark );
355  if (!aTester.IsEditable())
356  {
357  ErrorMessage(aTester.GetMessageId());
358  PaintArea(nCol, nRow, nCol, nRow); // possibly the edit-engine is still painted there
359  return;
360  }
361 
362  if ( bRecord )
363  rFunc.EnterListAction( STR_UNDO_ENTERDATA );
364 
365  bool bFormula = false;
366 
367  // a single '=' character is handled as string (needed for special filters)
368  if ( rString.getLength() > 1 )
369  {
370  if ( rString[0] == '=' )
371  {
372  // handle as formula
373  bFormula = true;
374  }
375  else if ( rString[0] == '+' || rString[0] == '-' )
376  {
377  // if there is more than one leading '+' or '-' character, remove the additional ones
378  sal_Int32 nIndex = 1;
379  sal_Int32 nLen = rString.getLength();
380  while ( nIndex < nLen && ( rString[ nIndex ] == '+' || rString[ nIndex ] == '-' ) )
381  {
382  ++nIndex;
383  }
384  OUString aString = rString.replaceAt( 1, nIndex - 1, "" );
385 
386  // if the remaining part without the leading '+' or '-' character
387  // is non-empty and not a number, handle as formula
388  if ( aString.getLength() > 1 )
389  {
390  sal_uInt32 nFormat = 0;
391  rDoc.GetNumberFormat( nCol, nRow, nTab, nFormat );
392  SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
393  double fNumber = 0;
394  if ( !pFormatter->IsNumberFormat( aString, nFormat, fNumber ) )
395  {
396  bFormula = true;
397  }
398  }
399  }
400  }
401 
402  bool bNumFmtChanged = false;
403  if ( bFormula )
404  { // formula, compile with autoCorrection
405  i = rMark.GetFirstSelected();
406  ScAddress aPos( nCol, nRow, i );
407  ScCompiler aComp( rDoc, aPos, rDoc.GetGrammar(), true, false );
408 //2do: enable/disable autoCorrection via calcoptions
409  aComp.SetAutoCorrection( true );
410  if ( rString[0] == '+' || rString[0] == '-' )
411  {
412  aComp.SetExtendedErrorDetection( ScCompiler::EXTENDED_ERROR_DETECTION_NAME_BREAK );
413  }
414  OUString aFormula( rString );
415  std::unique_ptr< ScTokenArray > pArr;
416  bool bAgain;
417  do
418  {
419  bAgain = false;
420  bool bAddEqual = false;
421  pArr = aComp.CompileString( aFormula );
422  bool bCorrected = aComp.IsCorrected();
423  std::unique_ptr< ScTokenArray > pArrFirst;
424  if ( bCorrected )
425  { // try to parse with first parser-correction
426  pArrFirst = std::move( pArr );
427  pArr = aComp.CompileString( aComp.GetCorrectedFormula() );
428  }
429  if ( pArr->GetCodeError() == FormulaError::NONE )
430  {
431  bAddEqual = true;
432  aComp.CompileTokenArray();
433  bCorrected |= aComp.IsCorrected();
434  }
435  if ( bCorrected )
436  {
437  OUString aCorrectedFormula;
438  if ( bAddEqual )
439  {
440  aCorrectedFormula = "=" + aComp.GetCorrectedFormula();
441  }
442  else
443  aCorrectedFormula = aComp.GetCorrectedFormula();
444  short nResult;
445  if ( aCorrectedFormula.getLength() == 1 )
446  nResult = RET_NO; // empty formula, just '='
447  else
448  {
449  OUString aMessage = ScResId( SCSTR_FORMULA_AUTOCORRECTION ) + aCorrectedFormula;
450 
451  std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetViewData().GetDialogParent(),
452  VclMessageType::Question, VclButtonsType::YesNo,
453  aMessage));
454  xQueryBox->set_default_response(RET_YES);
455  nResult = xQueryBox->run();
456  }
457  if ( nResult == RET_YES )
458  {
459  aFormula = aCorrectedFormula;
460  bAgain = true;
461  }
462  else
463  {
464  if ( pArrFirst )
465  pArr = std::move( pArrFirst );
466  }
467  }
468  } while ( bAgain );
469  // to be used in multiple tabs, the formula must be compiled anew
470  // via ScFormulaCell copy-ctor because of RangeNames,
471  // the same code-array for all cells is not possible.
472  // If the array has an error, (it) must be RPN-erased in the newly generated
473  // cells and the error be set explicitly, so that
474  // via FormulaCell copy-ctor and Interpreter it will be, when possible,
475  // ironed out again, too intelligent... e.g.: =1))
476  FormulaError nError = pArr->GetCodeError();
477  if ( nError == FormulaError::NONE )
478  {
479  // update list of recent functions with all functions that
480  // are not within parentheses
481 
482  ScModule* pScMod = SC_MOD();
483  ScAppOptions aAppOpt = pScMod->GetAppOptions();
484  bool bOptChanged = false;
485 
486  formula::FormulaToken** ppToken = pArr->GetArray();
487  sal_uInt16 nTokens = pArr->GetLen();
488  sal_uInt16 nLevel = 0;
489  for (sal_uInt16 nTP=0; nTP<nTokens; nTP++)
490  {
491  formula::FormulaToken* pTok = ppToken[nTP];
492  OpCode eOp = pTok->GetOpCode();
493  if ( eOp == ocOpen )
494  ++nLevel;
495  else if ( eOp == ocClose && nLevel )
496  --nLevel;
497  if ( nLevel == 0 && pTok->IsFunction() &&
498  lcl_AddFunction( aAppOpt, sal::static_int_cast<sal_uInt16>( eOp ) ) )
499  bOptChanged = true;
500  }
501 
502  if ( bOptChanged )
503  {
504  pScMod->SetAppOptions(aAppOpt);
505  }
506  }
507 
508  ScFormulaCell aCell(rDoc, aPos, std::move( pArr ), formula::FormulaGrammar::GRAM_DEFAULT, ScMatrixMode::NONE);
509 
510  SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
511  for (const auto& rTab : rMark)
512  {
513  i = rTab;
514  aPos.SetTab( i );
515  const sal_uInt32 nIndex = rDoc.GetAttr(
516  nCol, nRow, i, ATTR_VALUE_FORMAT )->GetValue();
517  const SvNumFormatType nType = pFormatter->GetType( nIndex);
518  if (nType == SvNumFormatType::TEXT ||
519  ((rString[0] == '+' || rString[0] == '-') && nError != FormulaError::NONE && rString == aFormula))
520  {
521  if ( pData )
522  {
523  // A clone of pData will be stored in the cell.
524  rFunc.SetEditCell(aPos, *pData, true);
525  }
526  else
527  rFunc.SetStringCell(aPos, aFormula, true);
528  }
529  else
530  {
531  ScFormulaCell* pCell = new ScFormulaCell( aCell, rDoc, aPos );
532  if ( nError != FormulaError::NONE )
533  {
534  pCell->GetCode()->DelRPN();
535  pCell->SetErrCode( nError );
536  if(pCell->GetCode()->IsHyperLink())
537  pCell->GetCode()->SetHyperLink(false);
538  }
539  if (nType == SvNumFormatType::LOGICAL)
540  {
541  // Reset to General so the actual format can be determined
542  // after the cell has been interpreted. A sticky boolean
543  // number format is highly likely unwanted... see tdf#75650.
544  // General of same locale as current number format.
545  const SvNumberformat* pEntry = pFormatter->GetEntry( nIndex);
546  const LanguageType nLang = (pEntry ? pEntry->GetLanguage() : ScGlobal::eLnge);
547  const sal_uInt32 nFormat = pFormatter->GetStandardFormat( SvNumFormatType::NUMBER, nLang);
548  ScPatternAttr aPattern( rDoc.GetPool());
549  aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nFormat));
550  ScMarkData aMark(rDoc.GetSheetLimits());
551  aMark.SelectTable( i, true);
552  aMark.SetMarkArea( ScRange( aPos));
553  rFunc.ApplyAttributes( aMark, aPattern, false);
554  bNumFmtChanged = true;
555  }
556  rFunc.SetFormulaCell(aPos, pCell, true);
557  }
558  }
559  }
560  else
561  {
562  for (const auto& rTab : rMark)
563  {
564  bool bNumFmtSet = false;
565  rFunc.SetNormalString( bNumFmtSet, ScAddress( nCol, nRow, rTab ), rString, false );
566  if (bNumFmtSet)
567  {
568  /* FIXME: if set on any sheet results in changed only on
569  * sheet nTab for TestFormatArea() and DoAutoAttributes() */
570  bNumFmtChanged = true;
571  }
572  }
573  }
574 
575  bool bAutoFormat = TestFormatArea(nCol, nRow, nTab, bNumFmtChanged);
576 
577  if (bAutoFormat)
578  DoAutoAttributes(nCol, nRow, nTab, bNumFmtChanged);
579 
580  pDocSh->UpdateOle(GetViewData());
581 
582  HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh, rMark, nCol, nRow);
583 
584  if ( bRecord )
585  rFunc.EndListAction();
586 
587  aModificator.SetDocumentModified();
588  lcl_PostRepaintCondFormat( rDoc.GetCondFormat( nCol, nRow, nTab ), pDocSh );
589 }
590 
591 // enter value in single cell (on nTab only)
592 
593 void ScViewFunc::EnterValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rValue )
594 {
595  ScDocument& rDoc = GetViewData().GetDocument();
596  ScDocShell* pDocSh = GetViewData().GetDocShell();
597 
598  if (!pDocSh)
599  return;
600 
601  bool bUndo(rDoc.IsUndoEnabled());
602  ScDocShellModificator aModificator( *pDocSh );
603 
604  ScEditableTester aTester( rDoc, nTab, nCol,nRow, nCol,nRow );
605  if (aTester.IsEditable())
606  {
607  ScAddress aPos( nCol, nRow, nTab );
608  ScCellValue aUndoCell;
609  if (bUndo)
610  aUndoCell.assign(rDoc, aPos);
611 
612  rDoc.SetValue( nCol, nRow, nTab, rValue );
613 
614  // because of ChangeTrack after change in document
615  if (bUndo)
616  {
617  pDocSh->GetUndoManager()->AddUndoAction(
618  std::make_unique<ScUndoEnterValue>(pDocSh, aPos, aUndoCell, rValue));
619  }
620 
621  pDocSh->PostPaintCell( aPos );
622  pDocSh->UpdateOle(GetViewData());
623  aModificator.SetDocumentModified();
624  }
625  else
626  ErrorMessage(aTester.GetMessageId());
627 }
628 
629 void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab,
630  const EditTextObject& rData, bool bTestSimple )
631 {
632  ScDocShell* pDocSh = GetViewData().GetDocShell();
633  ScMarkData& rMark = GetViewData().GetMarkData();
634  ScDocument& rDoc = pDocSh->GetDocument();
635  bool bRecord = rDoc.IsUndoEnabled();
636 
637  ScDocShellModificator aModificator( *pDocSh );
638 
639  ScEditableTester aTester( rDoc, nTab, nCol,nRow, nCol,nRow );
640  if (aTester.IsEditable())
641  {
642 
643  // test for attribute
644 
645  bool bSimple = false;
646  bool bCommon = false;
647  std::unique_ptr<ScPatternAttr> pCellAttrs;
648  OUString aString;
649 
650  const ScPatternAttr* pOldPattern = rDoc.GetPattern( nCol, nRow, nTab );
651  ScTabEditEngine aEngine( *pOldPattern, rDoc.GetEnginePool(), &rDoc );
652  aEngine.SetTextCurrentDefaults(rData);
653 
654  if (bTestSimple) // test, if simple string without attribute
655  {
656  ScEditAttrTester aAttrTester( &aEngine );
657  bSimple = !aAttrTester.NeedsObject();
658  bCommon = aAttrTester.NeedsCellAttr();
659 
660  // formulas have to be recognized even if they're formatted
661  // (but common attributes are still collected)
662 
663  if ( !bSimple && aEngine.GetParagraphCount() == 1 )
664  {
665  OUString aParStr(aEngine.GetText( 0 ));
666  if ( aParStr[0] == '=' )
667  bSimple = true;
668  }
669 
670  if (bCommon) // attribute for tab
671  {
672  pCellAttrs.reset(new ScPatternAttr( *pOldPattern ));
673  pCellAttrs->GetFromEditItemSet( &aAttrTester.GetAttribs() );
675  }
676  }
677 
678  // #i97726# always get text for "repeat" of undo action
679  aString = ScEditUtil::GetSpaceDelimitedString(aEngine);
680 
681  // undo
682 
683  std::unique_ptr<EditTextObject> pUndoData;
684  ScUndoEnterData::ValuesType aOldValues;
685 
686  if (bRecord && !bSimple)
687  {
688  for (const auto& rTab : rMark)
689  {
690  ScUndoEnterData::Value aOldValue;
691  aOldValue.mnTab = rTab;
692  aOldValue.maCell.assign(rDoc, ScAddress(nCol, nRow, rTab));
693  aOldValues.push_back(aOldValue);
694  }
695 
696  pUndoData = rData.Clone();
697  }
698 
699  // enter data
700 
701  if (bCommon)
702  rDoc.ApplyPattern(nCol,nRow,nTab,*pCellAttrs);
703 
704  if (bSimple)
705  {
706  if (bCommon)
707  AdjustRowHeight(nRow,nRow);
708 
709  EnterData(nCol,nRow,nTab,aString);
710  }
711  else
712  {
713  for (const auto& rTab : rMark)
714  {
715  ScAddress aPos(nCol, nRow, rTab);
716  rDoc.SetEditText(aPos, rData, rDoc.GetEditPool());
717  }
718 
719  if ( bRecord )
720  { // because of ChangeTrack current first
721  pDocSh->GetUndoManager()->AddUndoAction(
722  std::make_unique<ScUndoEnterData>(pDocSh, ScAddress(nCol,nRow,nTab), aOldValues, aString, std::move(pUndoData)));
723  }
724 
725  HideAllCursors();
726 
727  AdjustRowHeight(nRow,nRow);
728 
729  for (const auto& rTab : rMark)
730  pDocSh->PostPaintCell( nCol, nRow, rTab );
731 
732  ShowAllCursors();
733 
734  pDocSh->UpdateOle(GetViewData());
735 
736  HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh, rMark, nCol, nRow);
737 
738  aModificator.SetDocumentModified();
739  }
740  lcl_PostRepaintCondFormat( rDoc.GetCondFormat( nCol, nRow, nTab ), pDocSh );
741  }
742  else
743  {
744  ErrorMessage(aTester.GetMessageId());
745  PaintArea( nCol, nRow, nCol, nRow ); // possibly the edit-engine is still painted there
746  }
747 }
748 
749 void ScViewFunc::EnterDataAtCursor( const OUString& rString )
750 {
751  SCCOL nPosX = GetViewData().GetCurX();
752  SCROW nPosY = GetViewData().GetCurY();
753  SCTAB nTab = GetViewData().GetTabNo();
754 
755  EnterData( nPosX, nPosY, nTab, rString );
756 }
757 
758 void ScViewFunc::EnterMatrix( const OUString& rString, ::formula::FormulaGrammar::Grammar eGram )
759 {
761  const SCCOL nCol = rData.GetCurX();
762  const SCROW nRow = rData.GetCurY();
763  const ScMarkData& rMark = rData.GetMarkData();
764  if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
765  {
766  // nothing marked -> temporarily calculate block
767  // with size of result formula to get the size
768 
769  ScDocument& rDoc = rData.GetDocument();
770  SCTAB nTab = rData.GetTabNo();
771  ScFormulaCell aFormCell( rDoc, ScAddress(nCol,nRow,nTab), rString, eGram, ScMatrixMode::Formula );
772 
773  SCSIZE nSizeX;
774  SCSIZE nSizeY;
775  aFormCell.GetResultDimensions( nSizeX, nSizeY );
776  if ( nSizeX != 0 && nSizeY != 0 &&
777  nCol+nSizeX-1 <= sal::static_int_cast<SCSIZE>(rDoc.MaxCol()) &&
778  nRow+nSizeY-1 <= sal::static_int_cast<SCSIZE>(rDoc.MaxRow()) )
779  {
780  ScRange aResult( nCol, nRow, nTab,
781  sal::static_int_cast<SCCOL>(nCol+nSizeX-1),
782  sal::static_int_cast<SCROW>(nRow+nSizeY-1), nTab );
783  MarkRange( aResult, false );
784  }
785  }
786 
787  ScRange aRange;
788  if (rData.GetSimpleArea(aRange) == SC_MARK_SIMPLE)
789  {
790  ScDocShell* pDocSh = rData.GetDocShell();
791  bool bSuccess = pDocSh->GetDocFunc().EnterMatrix(
792  aRange, &rMark, nullptr, rString, false, false, EMPTY_OUSTRING, eGram );
793  if (bSuccess)
794  pDocSh->UpdateOle(GetViewData());
795  else
796  PaintArea(nCol, nRow, nCol, nRow); // possibly the edit-engine is still painted there
797  }
798  else
799  ErrorMessage(STR_NOMULTISELECT);
800 }
801 
803 {
804  SvtScriptType nScript = SvtScriptType::NONE;
805 
806  ScDocument& rDoc = GetViewData().GetDocument();
807  const ScMarkData& rMark = GetViewData().GetMarkData();
808  if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
809  {
810  // no selection -> cursor
811 
812  nScript = rDoc.GetScriptType( GetViewData().GetCurX(),
813  GetViewData().GetCurY(), GetViewData().GetTabNo());
814  }
815  else
816  {
817  ScRangeList aRanges;
818  rMark.FillRangeListWithMarks( &aRanges, false );
819  nScript = rDoc.GetRangeScriptType(aRanges);
820  }
821 
822  if (nScript == SvtScriptType::NONE)
823  nScript = ScGlobal::GetDefaultScriptType();
824 
825  return nScript;
826 }
827 
829 {
830  // Don't use UnmarkFiltered in slot state functions, for performance reasons.
831  // The displayed state is always that of the whole selection including filtered rows.
832 
833  const ScMarkData& rMark = GetViewData().GetMarkData();
834  ScDocument& rDoc = GetViewData().GetDocument();
835  if ( rMark.IsMarked() || rMark.IsMultiMarked() )
836  {
837  // MarkToMulti is no longer necessary for rDoc.GetSelectionPattern
838  const ScPatternAttr* pAttr = rDoc.GetSelectionPattern( rMark );
839  return pAttr;
840  }
841  else
842  {
843  SCCOL nCol = GetViewData().GetCurX();
844  SCROW nRow = GetViewData().GetCurY();
845  SCTAB nTab = GetViewData().GetTabNo();
846 
847  ScMarkData aTempMark( rMark ); // copy sheet selection
848  aTempMark.SetMarkArea( ScRange( nCol, nRow, nTab ) );
849  const ScPatternAttr* pAttr = rDoc.GetSelectionPattern( aTempMark );
850  return pAttr;
851  }
852 }
853 
855  std::shared_ptr<SvxBoxItem>& rLineOuter,
856  std::shared_ptr<SvxBoxInfoItem>& rLineInner )
857 {
858  ScDocument& rDoc = GetViewData().GetDocument();
859  const ScMarkData& rMark = GetViewData().GetMarkData();
860 
861  if ( rMark.IsMarked() || rMark.IsMultiMarked() )
862  {
863  rDoc.GetSelectionFrame( rMark, *rLineOuter, *rLineInner );
864  }
865  else
866  {
867  const ScPatternAttr* pAttrs =
868  rDoc.GetPattern( GetViewData().GetCurX(),
869  GetViewData().GetCurY(),
870  GetViewData().GetTabNo() );
871 
872  rLineOuter.reset(pAttrs->GetItem(ATTR_BORDER).Clone());
873  rLineInner.reset(pAttrs->GetItem(ATTR_BORDER_INNER).Clone());
874 
875  rLineInner->SetTable(false);
876  rLineInner->SetDist(true);
877  rLineInner->SetMinDist(false);
878  }
879 }
880 
881 // apply attribute - undo OK
882 //
883 // complete set ( ATTR_STARTINDEX, ATTR_ENDINDEX )
884 
885 void ScViewFunc::ApplyAttributes( const SfxItemSet* pDialogSet,
886  const SfxItemSet* pOldSet,
887  bool bAdjustBlockHeight)
888 {
889  // not editable because of matrix only? attribute OK nonetheless
890  bool bOnlyNotBecauseOfMatrix;
891  if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
892  {
893  ErrorMessage(STR_PROTECTIONERR);
894  return;
895  }
896 
897  ScPatternAttr aOldAttrs( std::make_unique<SfxItemSet>(*pOldSet) );
898  ScPatternAttr aNewAttrs( std::make_unique<SfxItemSet>(*pDialogSet) );
899  aNewAttrs.DeleteUnchanged( &aOldAttrs );
900 
901  if ( pDialogSet->GetItemState( ATTR_VALUE_FORMAT ) == SfxItemState::SET )
902  { // don't reset to default SYSTEM GENERAL if not intended
903  sal_uInt32 nOldFormat =
904  pOldSet->Get( ATTR_VALUE_FORMAT ).GetValue();
905  sal_uInt32 nNewFormat =
906  pDialogSet->Get( ATTR_VALUE_FORMAT ).GetValue();
907  if ( nNewFormat != nOldFormat )
908  {
909  SvNumberFormatter* pFormatter =
911  const SvNumberformat* pOldEntry = pFormatter->GetEntry( nOldFormat );
912  LanguageType eOldLang =
913  pOldEntry ? pOldEntry->GetLanguage() : LANGUAGE_DONTKNOW;
914  const SvNumberformat* pNewEntry = pFormatter->GetEntry( nNewFormat );
915  LanguageType eNewLang =
916  pNewEntry ? pNewEntry->GetLanguage() : LANGUAGE_DONTKNOW;
917  if ( eNewLang != eOldLang )
918  {
919  aNewAttrs.GetItemSet().Put(
920  SvxLanguageItem( eNewLang, ATTR_LANGUAGE_FORMAT ) );
921 
922  // only the language has changed -> do not touch numberformat-attribute
923  sal_uInt32 nNewMod = nNewFormat % SV_COUNTRY_LANGUAGE_OFFSET;
924  if ( nNewMod == ( nOldFormat % SV_COUNTRY_LANGUAGE_OFFSET ) &&
925  nNewMod <= SV_MAX_COUNT_STANDARD_FORMATS )
926  aNewAttrs.GetItemSet().ClearItem( ATTR_VALUE_FORMAT );
927  }
928  }
929  }
930 
931  if (pDialogSet->HasItem(ATTR_FONT_LANGUAGE))
932  // font language has changed. Redo the online spelling.
933  ResetAutoSpell();
934 
935  const SvxBoxItem& rOldOuter = pOldSet->Get(ATTR_BORDER);
936  const SvxBoxItem& rNewOuter = pDialogSet->Get(ATTR_BORDER);
937  const SvxBoxInfoItem& rOldInner = pOldSet->Get(ATTR_BORDER_INNER);
938  const SvxBoxInfoItem& rNewInner = pDialogSet->Get(ATTR_BORDER_INNER);
939  SfxItemSet& rNewSet = aNewAttrs.GetItemSet();
940  SfxItemPool* pNewPool = rNewSet.GetPool();
941 
942  pNewPool->Put(rNewOuter); // don't delete yet
943  pNewPool->Put(rNewInner);
944  rNewSet.ClearItem( ATTR_BORDER );
945  rNewSet.ClearItem( ATTR_BORDER_INNER );
946 
947  /*
948  * establish whether border attribute is to be set:
949  * 1. new != old
950  * 2. is one of the borders not-DontCare (since 238.f: IsxxValid())
951  *
952  */
953 
954  bool bFrame = (pDialogSet->GetItemState( ATTR_BORDER ) != SfxItemState::DEFAULT)
955  || (pDialogSet->GetItemState( ATTR_BORDER_INNER ) != SfxItemState::DEFAULT);
956 
957  if (&rNewOuter == &rOldOuter && &rNewInner == &rOldInner)
958  bFrame = false;
959 
960  // this should be intercepted by the pool: ?!??!??
961 
962  if (bFrame && rNewOuter == rOldOuter && rNewInner == rOldInner)
963  bFrame = false;
964 
965  bFrame = bFrame
966  && ( rNewInner.IsValid(SvxBoxInfoItemValidFlags::LEFT)
967  || rNewInner.IsValid(SvxBoxInfoItemValidFlags::RIGHT)
968  || rNewInner.IsValid(SvxBoxInfoItemValidFlags::TOP)
969  || rNewInner.IsValid(SvxBoxInfoItemValidFlags::BOTTOM)
970  || rNewInner.IsValid(SvxBoxInfoItemValidFlags::HORI)
971  || rNewInner.IsValid(SvxBoxInfoItemValidFlags::VERT) );
972 
973  if (!bFrame)
974  ApplySelectionPattern( aNewAttrs ); // standard only
975  else
976  {
977  // if new items are default-items, overwrite the old items:
978 
979  bool bDefNewOuter = IsStaticDefaultItem(&rNewOuter);
980  bool bDefNewInner = IsStaticDefaultItem(&rNewInner);
981 
982  ApplyPatternLines( aNewAttrs,
983  bDefNewOuter ? rOldOuter : rNewOuter,
984  bDefNewInner ? &rOldInner : &rNewInner );
985  }
986 
987  pNewPool->Remove(rNewOuter); // release
988  pNewPool->Remove(rNewInner);
989 
990  // adjust height only if needed
991  if (bAdjustBlockHeight)
993 
994  // CellContentChanged is called in ApplySelectionPattern / ApplyPatternLines
995 }
996 
997 void ScViewFunc::ApplyAttr( const SfxPoolItem& rAttrItem, bool bAdjustBlockHeight )
998 {
999  // not editable because of matrix only? attribute OK nonetheless
1000  bool bOnlyNotBecauseOfMatrix;
1001  if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
1002  {
1003  ErrorMessage(STR_PROTECTIONERR);
1004  return;
1005  }
1006 
1007  ScPatternAttr aNewAttrs( std::make_unique<SfxItemSet>( *GetViewData().GetDocument().GetPool(),
1009 
1010  aNewAttrs.GetItemSet().Put( rAttrItem );
1011  // if justify is set (with Buttons), always indentation 0
1012  if ( rAttrItem.Which() == ATTR_HOR_JUSTIFY )
1013  aNewAttrs.GetItemSet().Put( ScIndentItem( 0 ) );
1014  ApplySelectionPattern( aNewAttrs );
1015 
1016  // Prevent useless compute
1017  if (bAdjustBlockHeight)
1019 
1020  // CellContentChanged is called in ApplySelectionPattern
1021 }
1022 
1023 // patterns and borders
1024 
1025 void ScViewFunc::ApplyPatternLines( const ScPatternAttr& rAttr, const SvxBoxItem& rNewOuter,
1026  const SvxBoxInfoItem* pNewInner )
1027 {
1028  ScDocument& rDoc = GetViewData().GetDocument();
1029  ScMarkData aFuncMark( GetViewData().GetMarkData() ); // local copy for UnmarkFiltered
1030  ScViewUtil::UnmarkFiltered( aFuncMark, rDoc );
1031  bool bRecord = true;
1032  if (!rDoc.IsUndoEnabled())
1033  bRecord = false;
1034 
1035  bool bRemoveAdjCellBorder = rNewOuter.IsRemoveAdjacentCellBorder();
1036  ScRange aMarkRange, aMarkRangeWithEnvelope;
1037  aFuncMark.MarkToSimple();
1038  bool bMulti = aFuncMark.IsMultiMarked();
1039  if (bMulti)
1040  aFuncMark.GetMultiMarkArea( aMarkRange );
1041  else if (aFuncMark.IsMarked())
1042  aFuncMark.GetMarkArea( aMarkRange );
1043  else
1044  {
1045  aMarkRange = ScRange( GetViewData().GetCurX(),
1046  GetViewData().GetCurY(), GetViewData().GetTabNo() );
1047  DoneBlockMode();
1048  InitOwnBlockMode();
1049  aFuncMark.SetMarkArea(aMarkRange);
1050  MarkDataChanged();
1051  }
1052  if( bRemoveAdjCellBorder )
1053  aFuncMark.GetSelectionCover( aMarkRangeWithEnvelope );
1054  else
1055  aMarkRangeWithEnvelope = aMarkRange;
1056 
1057  ScDocShell* pDocSh = GetViewData().GetDocShell();
1058 
1059  ScDocShellModificator aModificator( *pDocSh );
1060 
1061  if (bRecord)
1062  {
1064  SCTAB nStartTab = aMarkRange.aStart.Tab();
1065  SCTAB nTabCount = rDoc.GetTableCount();
1066  bool bCopyOnlyMarked = false;
1067  if( !bRemoveAdjCellBorder )
1068  bCopyOnlyMarked = bMulti;
1069  pUndoDoc->InitUndo( rDoc, nStartTab, nStartTab );
1070  for (const auto& rTab : aFuncMark)
1071  if (rTab != nStartTab)
1072  pUndoDoc->AddUndoTab( rTab, rTab );
1073 
1074  ScRange aCopyRange = aMarkRangeWithEnvelope;
1075  aCopyRange.aStart.SetTab(0);
1076  aCopyRange.aEnd.SetTab(nTabCount-1);
1077  rDoc.CopyToDocument( aCopyRange, InsertDeleteFlags::ATTRIB, bCopyOnlyMarked, *pUndoDoc, &aFuncMark );
1078 
1079  pDocSh->GetUndoManager()->AddUndoAction(
1080  std::make_unique<ScUndoSelectionAttr>(
1081  pDocSh, aFuncMark,
1082  aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), aMarkRange.aStart.Tab(),
1083  aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), aMarkRange.aEnd.Tab(),
1084  std::move(pUndoDoc), bCopyOnlyMarked, &rAttr, &rNewOuter, pNewInner, &aMarkRangeWithEnvelope ) );
1085  }
1086 
1087  sal_uInt16 nExt = SC_PF_TESTMERGE;
1088  pDocSh->UpdatePaintExt( nExt, aMarkRangeWithEnvelope ); // content before the change
1089 
1090  rDoc.ApplySelectionFrame(aFuncMark, rNewOuter, pNewInner);
1091 
1092  pDocSh->UpdatePaintExt( nExt, aMarkRangeWithEnvelope ); // content after the change
1093 
1094  aFuncMark.MarkToMulti();
1095  rDoc.ApplySelectionPattern( rAttr, aFuncMark );
1096 
1097  pDocSh->PostPaint( aMarkRange, PaintPartFlags::Grid, nExt );
1098  pDocSh->UpdateOle(GetViewData());
1099  aModificator.SetDocumentModified();
1101 
1102  StartFormatArea();
1103 }
1104 
1105 // pattern only
1106 
1107 void ScViewFunc::ApplySelectionPattern( const ScPatternAttr& rAttr, bool bCursorOnly )
1108 {
1109  ScViewData& rViewData = GetViewData();
1110  ScDocShell* pDocSh = rViewData.GetDocShell();
1111  ScDocument& rDoc = pDocSh->GetDocument();
1112  ScMarkData aFuncMark( rViewData.GetMarkData() ); // local copy for UnmarkFiltered
1113  ScViewUtil::UnmarkFiltered( aFuncMark, rDoc );
1114 
1115  bool bRecord = true;
1116  if (!rDoc.IsUndoEnabled())
1117  bRecord = false;
1118 
1119  // State from old ItemSet doesn't matter for paint flags, as any change will be
1120  // from SfxItemState::SET in the new ItemSet (default is ignored in ApplyPattern).
1121  // New alignment is checked (check in PostPaint isn't enough) in case a right
1122  // alignment is changed to left.
1123  const SfxItemSet& rNewSet = rAttr.GetItemSet();
1124  bool bSetLines = rNewSet.GetItemState( ATTR_BORDER ) == SfxItemState::SET ||
1125  rNewSet.GetItemState( ATTR_SHADOW ) == SfxItemState::SET;
1126  bool bSetAlign = rNewSet.GetItemState( ATTR_HOR_JUSTIFY ) == SfxItemState::SET;
1127 
1128  sal_uInt16 nExtFlags = 0;
1129  if ( bSetLines )
1130  nExtFlags |= SC_PF_LINES;
1131  if ( bSetAlign )
1132  nExtFlags |= SC_PF_WHOLEROWS;
1133 
1134  ScDocShellModificator aModificator( *pDocSh );
1135 
1136  bool bMulti = aFuncMark.IsMultiMarked();
1137  aFuncMark.MarkToMulti();
1138  bool bOnlyTab = (!aFuncMark.IsMultiMarked() && !bCursorOnly && aFuncMark.GetSelectCount() > 1);
1139  if (bOnlyTab)
1140  {
1141  SCCOL nCol = rViewData.GetCurX();
1142  SCROW nRow = rViewData.GetCurY();
1143  SCTAB nTab = rViewData.GetTabNo();
1144  aFuncMark.SetMarkArea(ScRange(nCol,nRow,nTab));
1145  aFuncMark.MarkToMulti();
1146  }
1147 
1148  ScRangeList aChangeRanges;
1149 
1150  if (aFuncMark.IsMultiMarked() && !bCursorOnly)
1151  {
1152  ScRange aMarkRange;
1153  aFuncMark.GetMultiMarkArea( aMarkRange );
1154  SCTAB nTabCount = rDoc.GetTableCount();
1155  for (const auto& rTab : aFuncMark)
1156  {
1157  ScRange aChangeRange( aMarkRange );
1158  aChangeRange.aStart.SetTab( rTab );
1159  aChangeRange.aEnd.SetTab( rTab );
1160  aChangeRanges.push_back( aChangeRange );
1161  }
1162 
1163  SCCOL nStartCol = aMarkRange.aStart.Col();
1164  SCROW nStartRow = aMarkRange.aStart.Row();
1165  SCTAB nStartTab = aMarkRange.aStart.Tab();
1166  SCCOL nEndCol = aMarkRange.aEnd.Col();
1167  SCROW nEndRow = aMarkRange.aEnd.Row();
1168  SCTAB nEndTab = aMarkRange.aEnd.Tab();
1169 
1170  ScEditDataArray* pEditDataArray = nullptr;
1171  if (bRecord)
1172  {
1173  ScRange aCopyRange = aMarkRange;
1174  aCopyRange.aStart.SetTab(0);
1175  aCopyRange.aEnd.SetTab(nTabCount-1);
1176 
1178  pUndoDoc->InitUndo( rDoc, nStartTab, nStartTab );
1179  for (const auto& rTab : aFuncMark)
1180  if (rTab != nStartTab)
1181  pUndoDoc->AddUndoTab( rTab, rTab );
1182  rDoc.CopyToDocument( aCopyRange, InsertDeleteFlags::ATTRIB, bMulti, *pUndoDoc, &aFuncMark );
1183 
1184  aFuncMark.MarkToMulti();
1185 
1186  ScUndoSelectionAttr* pUndoAttr = new ScUndoSelectionAttr(
1187  pDocSh, aFuncMark, nStartCol, nStartRow, nStartTab,
1188  nEndCol, nEndRow, nEndTab, std::move(pUndoDoc), bMulti, &rAttr );
1189  pDocSh->GetUndoManager()->AddUndoAction(std::unique_ptr<ScUndoSelectionAttr>(pUndoAttr));
1190  pEditDataArray = pUndoAttr->GetDataArray();
1191  }
1192 
1193  rDoc.ApplySelectionPattern( rAttr, aFuncMark, pEditDataArray );
1194 
1195  pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
1196  nEndCol, nEndRow, nEndTab,
1197  PaintPartFlags::Grid, nExtFlags | SC_PF_TESTMERGE );
1198  pDocSh->UpdateOle(GetViewData());
1199  aModificator.SetDocumentModified();
1201  }
1202  else // single cell - simpler undo
1203  {
1204  SCCOL nCol = rViewData.GetCurX();
1205  SCROW nRow = rViewData.GetCurY();
1206  SCTAB nTab = rViewData.GetTabNo();
1207 
1208  std::unique_ptr<EditTextObject> pOldEditData;
1209  std::unique_ptr<EditTextObject> pNewEditData;
1210  ScAddress aPos(nCol, nRow, nTab);
1211  ScRefCellValue aCell(rDoc, aPos);
1212  if (aCell.meType == CELLTYPE_EDIT)
1213  {
1214  const EditTextObject* pEditObj = aCell.mpEditText;
1215  pOldEditData = pEditObj->Clone();
1216  rDoc.RemoveEditTextCharAttribs(aPos, rAttr);
1217  pEditObj = rDoc.GetEditText(aPos);
1218  pNewEditData = pEditObj->Clone();
1219  }
1220 
1221  aChangeRanges.push_back(aPos);
1222  std::unique_ptr<ScPatternAttr> pOldPat(new ScPatternAttr(*rDoc.GetPattern( nCol, nRow, nTab )));
1223 
1224  rDoc.ApplyPattern( nCol, nRow, nTab, rAttr );
1225 
1226  const ScPatternAttr* pNewPat = rDoc.GetPattern( nCol, nRow, nTab );
1227 
1228  if (bRecord)
1229  {
1230  std::unique_ptr<ScUndoCursorAttr> pUndo(new ScUndoCursorAttr(
1231  pDocSh, nCol, nRow, nTab, pOldPat.get(), pNewPat, &rAttr ));
1232  pUndo->SetEditData(std::move(pOldEditData), std::move(pNewEditData));
1233  pDocSh->GetUndoManager()->AddUndoAction(std::move(pUndo));
1234  }
1235  pOldPat.reset(); // is copied in undo (Pool)
1236 
1237  pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PaintPartFlags::Grid, nExtFlags | SC_PF_TESTMERGE );
1238  pDocSh->UpdateOle(GetViewData());
1239  aModificator.SetDocumentModified();
1241  }
1242 
1244  if (pModelObj)
1245  {
1246  css::uno::Sequence< css::beans::PropertyValue > aProperties;
1247  sal_Int32 nCount = 0;
1249  PropertyEntryVector_t aPropVector = rMap.getPropertyEntries();
1250  for ( sal_uInt16 nWhich = ATTR_PATTERN_START; nWhich <= ATTR_PATTERN_END; ++nWhich )
1251  {
1252  const SfxPoolItem* pItem = nullptr;
1253  if ( rNewSet.GetItemState( nWhich, true, &pItem ) == SfxItemState::SET && pItem )
1254  {
1255  for ( const auto& rProp : aPropVector)
1256  {
1257  if ( rProp.nWID == nWhich )
1258  {
1259  css::uno::Any aVal;
1260  pItem->QueryValue( aVal, rProp.nMemberId );
1261  aProperties.realloc( nCount + 1 );
1262  aProperties[ nCount ].Name = rProp.sName;
1263  aProperties[ nCount ].Value = aVal;
1264  ++nCount;
1265  }
1266  }
1267  }
1268  }
1269  HelperNotifyChanges::Notify(*pModelObj, aChangeRanges, "attribute", aProperties);
1270  }
1271 
1272  StartFormatArea();
1273 }
1274 
1276 {
1277  // ItemSet from UI, may have different pool
1278 
1279  bool bOnlyNotBecauseOfMatrix;
1280  if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
1281  {
1282  ErrorMessage(STR_PROTECTIONERR);
1283  return;
1284  }
1285 
1286  ScPatternAttr aNewAttrs( GetViewData().GetDocument().GetPool() );
1287  SfxItemSet& rNewSet = aNewAttrs.GetItemSet();
1288  rNewSet.Put( rItemSet, false );
1289  ApplySelectionPattern( aNewAttrs );
1290 
1292 }
1293 
1295 {
1296  // Don't use UnmarkFiltered in slot state functions, for performance reasons.
1297  // The displayed state is always that of the whole selection including filtered rows.
1298 
1299  const ScStyleSheet* pSheet = nullptr;
1300  ScViewData& rViewData = GetViewData();
1301  ScDocument& rDoc = rViewData.GetDocument();
1302  ScMarkData& rMark = rViewData.GetMarkData();
1303 
1304  if ( rMark.IsMarked() || rMark.IsMultiMarked() )
1305  pSheet = rDoc.GetSelectionStyle( rMark ); // MarkToMulti isn't necessary
1306  else
1307  pSheet = rDoc.GetStyle( rViewData.GetCurX(),
1308  rViewData.GetCurY(),
1309  rViewData.GetTabNo() );
1310 
1311  return pSheet;
1312 }
1313 
1315 {
1316  // not editable because of matrix only? attribute OK nonetheless
1317  bool bOnlyNotBecauseOfMatrix;
1318  if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
1319  {
1320  ErrorMessage(STR_PROTECTIONERR);
1321  return;
1322  }
1323 
1324  if ( !pStyleSheet) return;
1325 
1326  ScViewData& rViewData = GetViewData();
1327  ScDocShell* pDocSh = rViewData.GetDocShell();
1328  ScDocument& rDoc = pDocSh->GetDocument();
1329  ScMarkData aFuncMark( rViewData.GetMarkData() ); // local copy for UnmarkFiltered
1330  ScViewUtil::UnmarkFiltered( aFuncMark, rDoc );
1331  SCTAB nTabCount = rDoc.GetTableCount();
1332  bool bRecord = true;
1333  if (!rDoc.IsUndoEnabled())
1334  bRecord = false;
1335 
1336  ScDocShellModificator aModificator( *pDocSh );
1337 
1338  if ( aFuncMark.IsMarked() || aFuncMark.IsMultiMarked() )
1339  {
1340  ScRange aMarkRange;
1341  aFuncMark.MarkToMulti();
1342  aFuncMark.GetMultiMarkArea( aMarkRange );
1343 
1344  if ( bRecord )
1345  {
1346  SCTAB nTab = rViewData.GetTabNo();
1348  pUndoDoc->InitUndo( rDoc, nTab, nTab );
1349  for (const auto& rTab : aFuncMark)
1350  if (rTab != nTab)
1351  pUndoDoc->AddUndoTab( rTab, rTab );
1352 
1353  ScRange aCopyRange = aMarkRange;
1354  aCopyRange.aStart.SetTab(0);
1355  aCopyRange.aEnd.SetTab(nTabCount-1);
1356  rDoc.CopyToDocument( aCopyRange, InsertDeleteFlags::ATTRIB, true, *pUndoDoc, &aFuncMark );
1357  aFuncMark.MarkToMulti();
1358 
1359  OUString aName = pStyleSheet->GetName();
1360  pDocSh->GetUndoManager()->AddUndoAction(
1361  std::make_unique<ScUndoSelectionStyle>( pDocSh, aFuncMark, aMarkRange, aName, std::move(pUndoDoc) ) );
1362  }
1363 
1364  rDoc.ApplySelectionStyle( static_cast<const ScStyleSheet&>(*pStyleSheet), aFuncMark );
1365 
1366  if (!AdjustBlockHeight())
1367  rViewData.GetDocShell()->PostPaint( aMarkRange, PaintPartFlags::Grid );
1368 
1369  aFuncMark.MarkToSimple();
1370  }
1371  else
1372  {
1373  SCCOL nCol = rViewData.GetCurX();
1374  SCROW nRow = rViewData.GetCurY();
1375  SCTAB nTab = rViewData.GetTabNo();
1376 
1377  if ( bRecord )
1378  {
1380  pUndoDoc->InitUndo( rDoc, nTab, nTab );
1381  for (const auto& rTab : aFuncMark)
1382  if (rTab != nTab)
1383  pUndoDoc->AddUndoTab( rTab, rTab );
1384 
1385  ScRange aCopyRange( nCol, nRow, 0, nCol, nRow, nTabCount-1 );
1386  rDoc.CopyToDocument( aCopyRange, InsertDeleteFlags::ATTRIB, false, *pUndoDoc );
1387 
1388  ScRange aMarkRange ( nCol, nRow, nTab );
1389  ScMarkData aUndoMark = aFuncMark;
1390  aUndoMark.SetMultiMarkArea( aMarkRange );
1391 
1392  OUString aName = pStyleSheet->GetName();
1393  pDocSh->GetUndoManager()->AddUndoAction(
1394  std::make_unique<ScUndoSelectionStyle>( pDocSh, aUndoMark, aMarkRange, aName, std::move(pUndoDoc) ) );
1395  }
1396 
1397  for (const auto& rTab : aFuncMark)
1398  rDoc.ApplyStyle( nCol, nRow, rTab, static_cast<const ScStyleSheet&>(*pStyleSheet) );
1399 
1400  if (!AdjustBlockHeight())
1401  rViewData.GetDocShell()->PostPaintCell( nCol, nRow, nTab );
1402 
1403  }
1404 
1405  aModificator.SetDocumentModified();
1406 
1407  StartFormatArea();
1408 }
1409 
1411 {
1412  if ( !pStyleSheet) return;
1413 
1414  ScViewData& rViewData = GetViewData();
1415  ScDocument& rDoc = rViewData.GetDocument();
1416  ScDocShell* pDocSh = rViewData.GetDocShell();
1417 
1418  ScDocShellModificator aModificator( *pDocSh );
1419 
1421  pVirtDev->SetMapMode(MapMode(MapUnit::MapPixel));
1422  rDoc.StyleSheetChanged( pStyleSheet, true, pVirtDev,
1423  rViewData.GetPPTX(),
1424  rViewData.GetPPTY(),
1425  rViewData.GetZoomX(),
1426  rViewData.GetZoomY() );
1427 
1428  pDocSh->PostPaint( 0,0,0, rDoc.MaxCol(), rDoc.MaxRow(), MAXTAB, PaintPartFlags::Grid|PaintPartFlags::Left );
1429  aModificator.SetDocumentModified();
1430 
1431  ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
1432  if (pHdl)
1433  pHdl->ForgetLastPattern();
1434 }
1435 
1437 {
1438  if ( !pStyleSheet) return;
1439 
1440  ScViewData& rViewData = GetViewData();
1441  ScDocument& rDoc = rViewData.GetDocument();
1442  ScDocShell* pDocSh = rViewData.GetDocShell();
1443 
1444  ScDocShellModificator aModificator( *pDocSh );
1445 
1447  pVirtDev->SetMapMode(MapMode(MapUnit::MapPixel));
1448  rDoc.StyleSheetChanged( pStyleSheet, false, pVirtDev,
1449  rViewData.GetPPTX(),
1450  rViewData.GetPPTY(),
1451  rViewData.GetZoomX(),
1452  rViewData.GetZoomY() );
1453 
1454  pDocSh->PostPaint( 0,0,0, rDoc.MaxCol(), rDoc.MaxRow(), MAXTAB, PaintPartFlags::Grid|PaintPartFlags::Left );
1455  aModificator.SetDocumentModified();
1456 
1457  ScInputHandler* pHdl = SC_MOD()->GetInputHdl();
1458  if (pHdl)
1459  pHdl->ForgetLastPattern();
1460 }
1461 
1462 
1464 {
1465  if (!comphelper::LibreOfficeKit::isActive() || nOffset == 0)
1466  return;
1467 
1468  SCTAB nCurrentTabIndex = GetViewData().GetTabNo();
1469  SfxViewShell* pCurrentViewShell = GetViewData().GetViewShell();
1470  SfxViewShell* pViewShell = SfxViewShell::GetFirst();
1471  while (pViewShell)
1472  {
1473  ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
1474  if (pTabViewShell && pTabViewShell->GetDocId() == pCurrentViewShell->GetDocId())
1475  {
1476  pTabViewShell->GetViewData().GetLOKWidthHelper(nCurrentTabIndex)->invalidateByIndex(nStartCol);
1477 
1478  // if we remove a column the cursor position and the current selection
1479  // in other views could need to be moved on the left by one column.
1480  if (pTabViewShell != this)
1481  {
1482  if (pTabViewShell->getPart() == nCurrentTabIndex)
1483  {
1484  SCCOL nX = pTabViewShell->GetViewData().GetCurX();
1485  if (nX > nStartCol || (nX == nStartCol && nOffset > 0))
1486  {
1487  ScInputHandler* pInputHdl = pTabViewShell->GetInputHandler();
1488  SCROW nY = pTabViewShell->GetViewData().GetCurY();
1489  pTabViewShell->SetCursor(nX + nOffset, nY);
1490  if (pInputHdl && pInputHdl->IsInputMode())
1491  {
1492  pInputHdl->SetModified();
1493  }
1494  }
1495 
1496  ScMarkData aMultiMark( pTabViewShell->GetViewData().GetMarkData() );
1497  aMultiMark.SetMarking( false );
1498  aMultiMark.MarkToMulti();
1499  if (aMultiMark.IsMultiMarked())
1500  {
1501  aMultiMark.ShiftCols(pTabViewShell->GetViewData().GetDocument(), nStartCol, nOffset);
1502  pTabViewShell->SetMarkData(aMultiMark);
1503  }
1504  }
1505  else
1506  {
1507  SCROW nX = pTabViewShell->GetViewData().GetCurXForTab(nCurrentTabIndex);
1508  if (nX > nStartCol || (nX == nStartCol && nOffset > 0))
1509  {
1510  pTabViewShell->GetViewData().SetCurXForTab(nX + nOffset, nCurrentTabIndex);
1511  }
1512  }
1513  }
1514  }
1515  pViewShell = SfxViewShell::GetNext(*pViewShell);
1516  }
1517 }
1518 
1520 {
1521  if (!comphelper::LibreOfficeKit::isActive() || nOffset == 0)
1522  return;
1523 
1524  SCTAB nCurrentTabIndex = GetViewData().GetTabNo();
1525  SfxViewShell* pCurrentViewShell = GetViewData().GetViewShell();
1526  SfxViewShell* pViewShell = SfxViewShell::GetFirst();
1527  while (pViewShell)
1528  {
1529  ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
1530  if (pTabViewShell && pTabViewShell->GetDocId() == pCurrentViewShell->GetDocId())
1531  {
1532  pTabViewShell->GetViewData().GetLOKHeightHelper(nCurrentTabIndex)->invalidateByIndex(nStartRow);
1533 
1534  // if we remove a row the cursor position and the current selection
1535  // in other views could need to be moved up by one row.
1536  if (pTabViewShell != this)
1537  {
1538  if (pTabViewShell->getPart() == nCurrentTabIndex)
1539  {
1540  SCROW nY = pTabViewShell->GetViewData().GetCurY();
1541  if (nY > nStartRow || (nY == nStartRow && nOffset > 0))
1542  {
1543  ScInputHandler* pInputHdl = pTabViewShell->GetInputHandler();
1544  SCCOL nX = pTabViewShell->GetViewData().GetCurX();
1545  pTabViewShell->SetCursor(nX, nY + nOffset);
1546  if (pInputHdl && pInputHdl->IsInputMode())
1547  {
1548  pInputHdl->SetModified();
1549  }
1550  }
1551 
1552  ScMarkData aMultiMark( pTabViewShell->GetViewData().GetMarkData() );
1553  aMultiMark.SetMarking( false );
1554  aMultiMark.MarkToMulti();
1555  if (aMultiMark.IsMultiMarked())
1556  {
1557  aMultiMark.ShiftRows(pTabViewShell->GetViewData().GetDocument(), nStartRow, nOffset);
1558  pTabViewShell->SetMarkData(aMultiMark);
1559  }
1560  }
1561  else
1562  {
1563  SCROW nY = pTabViewShell->GetViewData().GetCurYForTab(nCurrentTabIndex);
1564  if (nY > nStartRow || (nY == nStartRow && nOffset > 0))
1565  {
1566  pTabViewShell->GetViewData().SetCurYForTab(nY + nOffset, nCurrentTabIndex);
1567  }
1568  }
1569  }
1570  }
1571  pViewShell = SfxViewShell::GetNext(*pViewShell);
1572  }
1573 }
1574 
1576 {
1578  return;
1579 
1580  SCTAB nCurTab = GetViewData().GetTabNo();
1581  SfxViewShell* pCurrentViewShell = GetViewData().GetViewShell();
1582  SfxViewShell* pViewShell = SfxViewShell::GetFirst();
1583  while (pViewShell)
1584  {
1585  ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
1586  if (pTabViewShell && pTabViewShell->GetDocId() == pCurrentViewShell->GetDocId())
1587  {
1588  if (bWidth)
1589  pTabViewShell->GetViewData().GetLOKWidthHelper(nCurTab)->invalidateByIndex(nStart);
1590  else
1591  pTabViewShell->GetViewData().GetLOKHeightHelper(nCurTab)->invalidateByIndex(nStart);
1592  }
1593  pViewShell = SfxViewShell::GetNext(*pViewShell);
1594  }
1595 }
1596 
1597 // insert cells - undo OK
1598 
1599 bool ScViewFunc::InsertCells( InsCellCmd eCmd, bool bRecord, bool bPartOfPaste )
1600 {
1601  ScRange aRange;
1602  if (GetViewData().GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1603  {
1604  ScDocShell* pDocSh = GetViewData().GetDocShell();
1605  const ScMarkData& rMark = GetViewData().GetMarkData();
1606  bool bSuccess = pDocSh->GetDocFunc().InsertCells( aRange, &rMark, eCmd, bRecord, false, bPartOfPaste );
1607  if (bSuccess)
1608  {
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 
1616  if ( bInsertCols || bInsertRows )
1617  {
1618  OUString aOperation = bInsertRows ?
1619  OUString("insert-rows"):
1620  OUString("insert-columns");
1621  HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh, aRange, aOperation);
1622  }
1623 
1625  {
1626  if (bInsertCols)
1628 
1629  if (bInsertRows)
1631 
1633  bInsertCols, bInsertRows, true /* bSizes*/,
1634  true /* bHidden */, true /* bFiltered */,
1635  true /* bGroups */, GetViewData().GetTabNo());
1636  }
1637  }
1638  OUString aStartAddress = aRange.aStart.GetColRowString();
1639  OUString aEndAddress = aRange.aEnd.GetColRowString();
1640  collectUIInformation({{"RANGE", aStartAddress + ":" + aEndAddress}}, "INSERT_CELLS");
1641  return bSuccess;
1642  }
1643  else
1644  {
1645  ErrorMessage(STR_NOMULTISELECT);
1646  return false;
1647  }
1648 }
1649 
1650 // delete cells - undo OK
1651 
1653 {
1654  ScRange aRange;
1655  if ( GetViewData().GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
1656  {
1657  ScDocShell* pDocSh = GetViewData().GetDocShell();
1658  const ScMarkData& rMark = GetViewData().GetMarkData();
1659 
1660 #if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
1661  // #i94841# [Collaboration] if deleting rows is rejected, the content is sometimes wrong
1662  if ( pDocSh->IsDocShared() && ( eCmd == DelCellCmd::Rows || eCmd == DelCellCmd::Cols ) )
1663  {
1664  ScRange aDelRange( aRange.aStart );
1665  SCCOLROW nCount = 0;
1666  if ( eCmd == DelCellCmd::Rows )
1667  {
1668  nCount = sal::static_int_cast< SCCOLROW >( aRange.aEnd.Row() - aRange.aStart.Row() + 1 );
1669  }
1670  else
1671  {
1672  nCount = sal::static_int_cast< SCCOLROW >( aRange.aEnd.Col() - aRange.aStart.Col() + 1 );
1673  }
1674  while ( nCount > 0 )
1675  {
1676  pDocSh->GetDocFunc().DeleteCells( aDelRange, &rMark, eCmd, false );
1677  --nCount;
1678  }
1679  }
1680  else
1681 #endif
1682  {
1683  pDocSh->GetDocFunc().DeleteCells( aRange, &rMark, eCmd, false );
1684  }
1685 
1687  pDocSh->UpdateOle(GetViewData());
1689 
1690  if ( eCmd == DelCellCmd::Rows || eCmd == DelCellCmd::Cols )
1691  {
1692  OUString aOperation = ( eCmd == DelCellCmd::Rows) ?
1693  OUString("delete-rows"):
1694  OUString("delete-columns");
1695  HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh, aRange, aOperation);
1696  }
1697 
1698  // put cursor directly behind deleted range
1699  SCCOL nCurX = GetViewData().GetCurX();
1700  SCROW nCurY = GetViewData().GetCurY();
1701  if ( eCmd==DelCellCmd::CellsLeft || eCmd==DelCellCmd::Cols )
1702  nCurX = aRange.aStart.Col();
1703  else
1704  nCurY = aRange.aStart.Row();
1705  SetCursor( nCurX, nCurY );
1706 
1708  {
1709  bool bColsDeleted = (eCmd == DelCellCmd::Cols);
1710  bool bRowsDeleted = (eCmd == DelCellCmd::Rows);
1711  if (bColsDeleted)
1713 
1714  if (bRowsDeleted)
1716 
1718  bColsDeleted, bRowsDeleted, true /* bSizes*/,
1719  true /* bHidden */, true /* bFiltered */,
1720  true /* bGroups */, GetViewData().GetTabNo());
1721  }
1722  }
1723  else
1724  {
1725  if (eCmd == DelCellCmd::Cols)
1726  DeleteMulti( false );
1727  else if (eCmd == DelCellCmd::Rows)
1728  DeleteMulti( true );
1729  else
1730  ErrorMessage(STR_NOMULTISELECT);
1731  }
1732 
1733  OUString aStartAddress = aRange.aStart.GetColRowString();
1734  OUString aEndAddress = aRange.aEnd.GetColRowString();
1735  collectUIInformation({{"RANGE", aStartAddress + ":" + aEndAddress}}, "DELETE_CELLS");
1736 
1737  Unmark();
1738 }
1739 
1740 void ScViewFunc::DeleteMulti( bool bRows )
1741 {
1742  ScDocShell* pDocSh = GetViewData().GetDocShell();
1743  ScDocShellModificator aModificator( *pDocSh );
1744  SCTAB nTab = GetViewData().GetTabNo();
1745  ScDocument& rDoc = pDocSh->GetDocument();
1746  ScMarkData aFuncMark( GetViewData().GetMarkData() ); // local copy for UnmarkFiltered
1747  ScViewUtil::UnmarkFiltered( aFuncMark, rDoc );
1748 
1749  bool bRecord = true;
1750  if (!rDoc.IsUndoEnabled())
1751  bRecord = false;
1752 
1753  std::vector<sc::ColRowSpan> aSpans;
1754  if (bRows)
1755  aSpans = aFuncMark.GetMarkedRowSpans();
1756  else
1757  aSpans = aFuncMark.GetMarkedColSpans();
1758 
1759  if (aSpans.empty())
1760  {
1761  SCCOLROW nCurPos = bRows ? GetViewData().GetCurY() : GetViewData().GetCurX();
1762  aSpans.emplace_back(nCurPos, nCurPos);
1763  }
1764 
1765  // test if allowed
1766 
1767  const char* pErrorId = nullptr;
1768  bool bNeedRefresh = false;
1769  for (size_t i = 0, n = aSpans.size(); i < n && !pErrorId; ++i)
1770  {
1771  SCCOLROW nStart = aSpans[i].mnStart;
1772  SCCOLROW nEnd = aSpans[i].mnEnd;
1773 
1774  SCCOL nStartCol, nEndCol;
1775  SCROW nStartRow, nEndRow;
1776  if ( bRows )
1777  {
1778  nStartCol = 0;
1779  nEndCol = rDoc.MaxCol();
1780  nStartRow = static_cast<SCROW>(nStart);
1781  nEndRow = static_cast<SCROW>(nEnd);
1782  }
1783  else
1784  {
1785  nStartCol = static_cast<SCCOL>(nStart);
1786  nEndCol = static_cast<SCCOL>(nEnd);
1787  nStartRow = 0;
1788  nEndRow = rDoc.MaxRow();
1789  }
1790 
1791  // cell protection (only needed for first range, as all following cells are moved)
1792  if (i == 0)
1793  {
1794  // test to the end of the sheet
1795  ScEditableTester aTester( rDoc, nTab, nStartCol, nStartRow, rDoc.MaxCol(), rDoc.MaxRow() );
1796  if (!aTester.IsEditable())
1797  pErrorId = aTester.GetMessageId();
1798  }
1799 
1800  // merged cells
1801  SCCOL nMergeStartX = nStartCol;
1802  SCROW nMergeStartY = nStartRow;
1803  SCCOL nMergeEndX = nEndCol;
1804  SCROW nMergeEndY = nEndRow;
1805  rDoc.ExtendMerge( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, nTab );
1806  rDoc.ExtendOverlapped( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, nTab );
1807 
1808  if ( nMergeStartX != nStartCol || nMergeStartY != nStartRow )
1809  {
1810  // Disallow deleting parts of a merged cell.
1811  // Deleting the start is allowed (merge is removed), so the end doesn't have to be checked.
1812 
1813  pErrorId = STR_MSSG_DELETECELLS_0;
1814  }
1815  if ( nMergeEndX != nEndCol || nMergeEndY != nEndRow )
1816  {
1817  // detect if the start of a merged cell is deleted, so the merge flags can be refreshed
1818 
1819  bNeedRefresh = true;
1820  }
1821  }
1822 
1823  if (pErrorId)
1824  {
1825  ErrorMessage(pErrorId);
1826  return;
1827  }
1828 
1829  // proceed
1830 
1831  WaitObject aWait( GetFrameWin() ); // important for TrackFormulas in UpdateReference
1832 
1834 
1835  ScDocumentUniquePtr pUndoDoc;
1836  std::unique_ptr<ScRefUndoData> pUndoData;
1837  if (bRecord)
1838  {
1839  pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
1840  pUndoDoc->InitUndo( rDoc, nTab, nTab, !bRows, bRows ); // row height
1841 
1842  for (const sc::ColRowSpan & rSpan : aSpans)
1843  {
1844  SCCOLROW nStart = rSpan.mnStart;
1845  SCCOLROW nEnd = rSpan.mnEnd;
1846  if (bRows)
1847  rDoc.CopyToDocument( 0,nStart,nTab, rDoc.MaxCol(), nEnd,nTab, InsertDeleteFlags::ALL,false,*pUndoDoc );
1848  else
1849  rDoc.CopyToDocument( static_cast<SCCOL>(nStart),0,nTab,
1850  static_cast<SCCOL>(nEnd), rDoc.MaxRow(), nTab,
1851  InsertDeleteFlags::ALL,false,*pUndoDoc );
1852  }
1853 
1854  // all Formulas because of references
1855  SCTAB nTabCount = rDoc.GetTableCount();
1856  pUndoDoc->AddUndoTab( 0, nTabCount-1 );
1857  rDoc.CopyToDocument( 0,0,0, rDoc.MaxCol(), rDoc.MaxRow(), MAXTAB, InsertDeleteFlags::FORMULA,false,*pUndoDoc );
1858 
1859  pUndoData.reset(new ScRefUndoData( &rDoc ));
1860 
1861  rDoc.BeginDrawUndo();
1862  }
1863 
1864  std::vector<sc::ColRowSpan>::const_reverse_iterator ri = aSpans.rbegin(), riEnd = aSpans.rend();
1865  aFuncMark.SelectOneTable(nTab);
1866  for (; ri != riEnd; ++ri)
1867  {
1868  SCCOLROW nEnd = ri->mnEnd;
1869  SCCOLROW nStart = ri->mnStart;
1870 
1871  if (bRows)
1872  {
1873  rDoc.DeleteObjectsInArea(0, nStart, rDoc.MaxCol(), nEnd, aFuncMark, true);
1874  rDoc.DeleteRow(0, nTab, rDoc.MaxCol(), nTab, nStart, static_cast<SCSIZE>(nEnd - nStart + 1));
1875  }
1876  else
1877  {
1878  rDoc.DeleteObjectsInArea(nStart, 0, nEnd, rDoc.MaxRow(), aFuncMark, true);
1879  rDoc.DeleteCol(0, nTab, rDoc.MaxRow(), nTab, static_cast<SCCOL>(nStart), static_cast<SCSIZE>(nEnd - nStart + 1));
1880  }
1881  }
1882 
1883  if (bNeedRefresh)
1884  {
1885  SCCOLROW nFirstStart = aSpans[0].mnStart;
1886  SCCOL nStartCol = bRows ? 0 : static_cast<SCCOL>(nFirstStart);
1887  SCROW nStartRow = bRows ? static_cast<SCROW>(nFirstStart) : 0;
1888  SCCOL nEndCol = rDoc.MaxCol();
1889  SCROW nEndRow = rDoc.MaxRow();
1890 
1891  rDoc.RemoveFlagsTab( nStartCol, nStartRow, nEndCol, nEndRow, nTab, ScMF::Hor | ScMF::Ver );
1892  rDoc.ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab, true );
1893  }
1894 
1895  if (bRecord)
1896  {
1897  pDocSh->GetUndoManager()->AddUndoAction(
1898  std::make_unique<ScUndoDeleteMulti>(
1899  pDocSh, bRows, bNeedRefresh, nTab, aSpans, std::move(pUndoDoc), std::move(pUndoData)));
1900  }
1901 
1902  if (!AdjustRowHeight(0, rDoc.MaxRow()))
1903  {
1904  if (bRows)
1905  {
1906  pDocSh->PostPaint(
1907  0, aSpans[0].mnStart, nTab,
1908  rDoc.MaxCol(), rDoc.MaxRow(), nTab, (PaintPartFlags::Grid | PaintPartFlags::Left));
1909  }
1910  else
1911  {
1912  pDocSh->PostPaint(
1913  static_cast<SCCOL>(aSpans[0].mnStart), 0, nTab,
1914  rDoc.MaxCol(), rDoc.MaxRow(), nTab, (PaintPartFlags::Grid | PaintPartFlags::Top));
1915  }
1916  }
1917 
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  }
2515 
2516  if (bUndo)
2517  pDocSh->GetUndoManager()->LeaveListAction();
2518 
2519  UpdateLayerLocks();
2520 }
2521 
2522 void ScViewFunc::Protect( SCTAB nTab, const OUString& rPassword )
2523 {
2524  ScMarkData& rMark = GetViewData().GetMarkData();
2525  ScDocShell* pDocSh = GetViewData().GetDocShell();
2526  ScDocument& rDoc = pDocSh->GetDocument();
2527  ScDocFunc &rFunc = pDocSh->GetDocFunc();
2528  bool bUndo(rDoc.IsUndoEnabled());
2529 
2530  if ( nTab == TABLEID_DOC || rMark.GetSelectCount() <= 1 )
2531  rFunc.Protect( nTab, rPassword );
2532  else
2533  {
2534  // modifying several tabs is handled here
2535 
2536  if (bUndo)
2537  {
2538  OUString aUndo = ScResId( STR_UNDO_PROTECT_TAB );
2539  pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo, 0, GetViewData().GetViewShell()->GetViewShellId() );
2540  }
2541 
2542  for (const auto& rTab : rMark)
2543  rFunc.Protect( rTab, rPassword );
2544 
2545  if (bUndo)
2546  pDocSh->GetUndoManager()->LeaveListAction();
2547  }
2548 
2549  UpdateLayerLocks();
2550 }
2551 
2552 bool ScViewFunc::Unprotect( SCTAB nTab, const OUString& rPassword )
2553 {
2554  ScMarkData& rMark = GetViewData().GetMarkData();
2555  ScDocShell* pDocSh = GetViewData().GetDocShell();
2556  ScDocument& rDoc = pDocSh->GetDocument();
2557  ScDocFunc &rFunc = pDocSh->GetDocFunc();
2558  bool bChanged = false;
2559  bool bUndo (rDoc.IsUndoEnabled());
2560 
2561  if ( nTab == TABLEID_DOC || rMark.GetSelectCount() <= 1 )
2562  {
2563  bChanged = rFunc.Unprotect( nTab, rPassword, false );
2564  if (bChanged && nTab != TABLEID_DOC)
2565  SetTabProtectionSymbol(nTab, false);
2566  }
2567  else
2568  {
2569  // modifying several tabs is handled here
2570 
2571  if (bUndo)
2572  {
2573  OUString aUndo = ScResId( STR_UNDO_UNPROTECT_TAB );
2574  pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo, 0, GetViewData().GetViewShell()->GetViewShellId() );
2575  }
2576 
2577  for (const auto& rTab : rMark)
2578  {
2579  if ( rFunc.Unprotect( rTab, rPassword, false ) )
2580  {
2581  bChanged = true;
2582  SetTabProtectionSymbol( rTab, false);
2583  }
2584  }
2585 
2586  if (bUndo)
2587  pDocSh->GetUndoManager()->LeaveListAction();
2588  }
2589 
2590  if (bChanged)
2591  UpdateLayerLocks();
2592 
2593  return bChanged;
2594 }
2595 
2596 void ScViewFunc::SetNoteText( const ScAddress& rPos, const OUString& rNoteText )
2597 {
2598  GetViewData().GetDocShell()->GetDocFunc().SetNoteText( rPos, rNoteText, false );
2599 }
2600 
2601 void ScViewFunc::ReplaceNote( const ScAddress& rPos, const OUString& rNoteText, const OUString* pAuthor, const OUString* pDate )
2602 {
2603  GetViewData().GetDocShell()->GetDocFunc().ReplaceNote( rPos, rNoteText, pAuthor, pDate, false );
2604 }
2605 
2607 {
2608  // not editable because of matrix only? attribute OK nonetheless
2609  bool bOnlyNotBecauseOfMatrix;
2610  if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
2611  {
2612  ErrorMessage(STR_PROTECTIONERR);
2613  return;
2614  }
2615 
2616  sal_uInt32 nNumberFormat = 0;
2617  ScViewData& rViewData = GetViewData();
2618  ScDocument& rDoc = rViewData.GetDocument();
2619  SvNumberFormatter* pNumberFormatter = rDoc.GetFormatTable();
2620  LanguageType eLanguage = ScGlobal::eLnge;
2621  ScPatternAttr aNewAttrs( rDoc.GetPool() );
2622 
2623  // always take language from cursor position, even if there is a selection
2624 
2625  sal_uInt32 nCurrentNumberFormat;
2626  rDoc.GetNumberFormat( rViewData.GetCurX(),
2627  rViewData.GetCurY(),
2628  rViewData.GetTabNo(),
2629  nCurrentNumberFormat );
2630  const SvNumberformat* pEntry = pNumberFormatter->GetEntry( nCurrentNumberFormat );
2631  if (pEntry)
2632  eLanguage = pEntry->GetLanguage(); // else keep ScGlobal::eLnge
2633 
2634  nNumberFormat = pNumberFormatter->GetStandardFormat( nFormatType, eLanguage ) + nAdd;
2635 
2636  SfxItemSet& rSet = aNewAttrs.GetItemSet();
2637  rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumberFormat ) );
2638  // ATTR_LANGUAGE_FORMAT not
2639  ApplySelectionPattern( aNewAttrs );
2640 }
2641 
2642 void ScViewFunc::SetNumFmtByStr( const OUString& rCode )
2643 {
2644  // not editable because of matrix only? attribute OK nonetheless
2645  bool bOnlyNotBecauseOfMatrix;
2646  if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
2647  {
2648  ErrorMessage(STR_PROTECTIONERR);
2649  return;
2650  }
2651 
2652  ScViewData& rViewData = GetViewData();
2653  ScDocument& rDoc = rViewData.GetDocument();
2654  SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
2655 
2656  // language always from cursor position
2657 
2658  sal_uInt32 nCurrentNumberFormat;
2659  rDoc.GetNumberFormat( rViewData.GetCurX(), rViewData.GetCurY(),
2660  rViewData.GetTabNo(), nCurrentNumberFormat );
2661  const SvNumberformat* pEntry = pFormatter->GetEntry( nCurrentNumberFormat );
2662  LanguageType eLanguage = pEntry ? pEntry->GetLanguage() : ScGlobal::eLnge;
2663 
2664  // determine index for String
2665 
2666  bool bOk = true;
2667  sal_uInt32 nNumberFormat = pFormatter->GetEntryKey( rCode, eLanguage );
2668  if ( nNumberFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
2669  {
2670  // enter new
2671 
2672  OUString aFormat = rCode; // will be changed
2673  sal_Int32 nErrPos = 0;
2674  SvNumFormatType nType = SvNumFormatType::ALL;
2675  bOk = pFormatter->PutEntry( aFormat, nErrPos, nType, nNumberFormat, eLanguage );
2676  }
2677 
2678  if ( bOk ) // valid format?
2679  {
2680  ScPatternAttr aNewAttrs( rDoc.GetPool() );
2681  SfxItemSet& rSet = aNewAttrs.GetItemSet();
2682  rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNumberFormat ) );
2683  rSet.Put( SvxLanguageItem( eLanguage, ATTR_LANGUAGE_FORMAT ) );
2684  ApplySelectionPattern( aNewAttrs );
2685  }
2686 
2688 }
2689 
2690 void ScViewFunc::ChangeNumFmtDecimals( bool bIncrement )
2691 {
2692  // not editable because of matrix only? attribute OK nonetheless
2693  bool bOnlyNotBecauseOfMatrix;
2694  if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
2695  {
2696  ErrorMessage(STR_PROTECTIONERR);
2697  return;
2698  }
2699 
2700  ScDocument& rDoc = GetViewData().GetDocument();
2701  SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
2702 
2703  SCCOL nCol = GetViewData().GetCurX();
2704  SCROW nRow = GetViewData().GetCurY();
2705  SCTAB nTab = GetViewData().GetTabNo();
2706 
2707  sal_uInt32 nOldFormat;
2708  rDoc.GetNumberFormat( nCol, nRow, nTab, nOldFormat );
2709  const SvNumberformat* pOldEntry = pFormatter->GetEntry( nOldFormat );
2710  if (!pOldEntry)
2711  {
2712  OSL_FAIL("numberformat not found !!!");
2713  return;
2714  }
2715 
2716  // what have we got here?
2717 
2718  sal_uInt32 nNewFormat = nOldFormat;
2719  bool bError = false;
2720 
2721  LanguageType eLanguage = pOldEntry->GetLanguage();
2722  bool bThousand, bNegRed;
2723  sal_uInt16 nPrecision, nLeading;
2724  pOldEntry->GetFormatSpecialInfo( bThousand, bNegRed, nPrecision, nLeading );
2725 
2726  SvNumFormatType nOldType = pOldEntry->GetType();
2727  if ( SvNumFormatType::ALL == ( nOldType & (
2728  SvNumFormatType::NUMBER | SvNumFormatType::CURRENCY | SvNumFormatType::PERCENT | SvNumFormatType::SCIENTIFIC | SvNumFormatType::TIME ) ) )
2729  {
2730  // date, fraction, logical, text can not be changed
2731  bError = true;
2732  }
2733 
2735  bool bWasStandard = ( nOldFormat == pFormatter->GetStandardIndex( eLanguage ) );
2736  OUString sExponentialStandardFormat = "";
2737  if (bWasStandard)
2738  {
2739  // with "Standard" the decimal places depend on cell content
2740  // 0 if empty or text -> no decimal places
2741  double nVal = rDoc.GetValue( ScAddress( nCol, nRow, nTab ) );
2742 
2743  // the ways of the Numberformatters are unfathomable, so try:
2744  OUString aOut;
2745  const Color* pCol;
2746  const_cast<SvNumberformat*>(pOldEntry)->GetOutputString( nVal, aOut, &pCol );
2747 
2748  nPrecision = 0;
2749  // 'E' for exponential is fixed in Numberformatter
2750  sal_Int32 nIndexE = aOut.indexOf('E');
2751  if ( nIndexE >= 0 )
2752  {
2753  sExponentialStandardFormat = aOut.copy( nIndexE ).replace( '-', '+' );
2754  for ( sal_Int32 i=1 ; i<sExponentialStandardFormat.getLength() ; i++ )
2755  {
2756  if ( sExponentialStandardFormat[i] >= '1' && sExponentialStandardFormat[i] <= '9' )
2757  sExponentialStandardFormat = sExponentialStandardFormat.replaceAt( i, 1, "0" );
2758  }
2759  aOut = aOut.copy( 0, nIndexE ); // remove exponential part
2760  }
2761  OUString aDecSep( pFormatter->GetFormatDecimalSep( nOldFormat ) );
2762  sal_Int32 nPos = aOut.indexOf( aDecSep );
2763  if ( nPos >= 0 )
2764  nPrecision = aOut.getLength() - nPos - aDecSep.getLength();
2765  // else keep 0
2766  }
2767  else
2768  {
2769  if ( (nOldType & SvNumFormatType::SCIENTIFIC) && !bThousand &&
2770  (pOldEntry->GetFormatIntegerDigits()%3 == 0) && pOldEntry->GetFormatIntegerDigits() > 0 )
2771  bThousand = true;
2772  }
2773 
2774  if (!bError)
2775  {
2776  if (bIncrement)
2777  {
2778  if (nPrecision<20)
2779  ++nPrecision; // increment
2780  else
2781  bError = true; // 20 is maximum
2782  }
2783  else
2784  {
2785  if (nPrecision)
2786  --nPrecision; // decrement
2787  else
2788  bError = true; // 0 is minimum
2789  }
2790  }
2791 
2792  if (!bError)
2793  {
2794  OUString aNewPicture = pFormatter->GenerateFormat(nOldFormat, eLanguage,
2795  bThousand, bNegRed,
2796  nPrecision, nLeading)
2797  + sExponentialStandardFormat;
2798 
2799  nNewFormat = pFormatter->GetEntryKey( aNewPicture, eLanguage );
2800  if ( nNewFormat == NUMBERFORMAT_ENTRY_NOT_FOUND )
2801  {
2802  sal_Int32 nErrPos = 0;
2803  SvNumFormatType nNewType = SvNumFormatType::ALL;
2804  bool bOk = pFormatter->PutEntry( aNewPicture, nErrPos,
2805  nNewType, nNewFormat, eLanguage );
2806  OSL_ENSURE( bOk, "incorrect numberformat generated" );
2807  if (!bOk)
2808  bError = true;
2809  }
2810  }
2811 
2812  if (!bError)
2813  {
2814  ScPatternAttr aNewAttrs( rDoc.GetPool() );
2815  SfxItemSet& rSet = aNewAttrs.GetItemSet();
2816  rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) );
2817  // ATTR_LANGUAGE_FORMAT not
2818  ApplySelectionPattern( aNewAttrs );
2819  }
2820 }
2821 
2822 void ScViewFunc::ChangeIndent( bool bIncrement )
2823 {
2824  ScViewData& rViewData = GetViewData();
2825  ScDocShell* pDocSh = rViewData.GetDocShell();
2826  ScMarkData& rMark = rViewData.GetMarkData();
2827 
2828  ScMarkData aWorkMark = rMark;
2829  ScViewUtil::UnmarkFiltered( aWorkMark, pDocSh->GetDocument() );
2830  aWorkMark.MarkToMulti();
2831  if (!aWorkMark.IsMultiMarked())
2832  {
2833  SCCOL nCol = rViewData.GetCurX();
2834  SCROW nRow = rViewData.GetCurY();
2835  SCTAB nTab = rViewData.GetTabNo();
2836  aWorkMark.SetMultiMarkArea( ScRange(nCol,nRow,nTab) );
2837  }
2838 
2839  bool bSuccess = pDocSh->GetDocFunc().ChangeIndent( aWorkMark, bIncrement, false );
2840  if (bSuccess)
2841  {
2842  pDocSh->UpdateOle(rViewData);
2843  StartFormatArea();
2844 
2845  // stuff for sidebar panels
2846  SfxBindings& rBindings = GetViewData().GetBindings();
2847  rBindings.Invalidate( SID_H_ALIGNCELL );
2848  rBindings.Invalidate( SID_ATTR_ALIGN_INDENT );
2849  }
2850 }
2851 
2852 bool ScViewFunc::InsertName( const OUString& rName, const OUString& rSymbol,
2853  const OUString& rType )
2854 {
2855  // Type = P,R,C,F (and combinations)
2857 
2858  bool bOk = false;
2859  ScDocShell* pDocSh = GetViewData().GetDocShell();
2860  ScDocument& rDoc = pDocSh->GetDocument();
2861  SCTAB nTab = GetViewData().GetTabNo();
2862  ScRangeName* pList = rDoc.GetRangeName();
2863 
2865  auto pNewEntry = std::make_unique<ScRangeData>(
2866  rDoc, rName, rSymbol, ScAddress( GetViewData().GetCurX(),
2867  GetViewData().GetCurY(), nTab), nType );
2868  OUString aUpType = rType.toAsciiUpperCase();
2869  if ( aUpType.indexOf( 'P' ) != -1 )
2871  if ( aUpType.indexOf( 'R' ) != -1 )
2873  if ( aUpType.indexOf( 'C' ) != -1 )
2875  if ( aUpType.indexOf( 'F' ) != -1 )
2876  nType |= ScRangeData::Type::Criteria;
2877  pNewEntry->AddType(nType);
2878 
2879  if ( pNewEntry->GetErrCode() == FormulaError::NONE ) // text valid?
2880  {
2881  ScDocShellModificator aModificator( *pDocSh );
2882 
2883  rDoc.PreprocessRangeNameUpdate();
2884 
2885  // input available yet? Then remove beforehand (=change)
2886  ScRangeData* pData = pList->findByUpperName(ScGlobal::getCharClassPtr()->uppercase(rName));
2887  if (pData)
2888  { // take old Index
2889  pNewEntry->SetIndex(pData->GetIndex());
2890  pList->erase(*pData);
2891  }
2892 
2893  // don't delete, insert took ownership, even on failure!
2894  if ( pList->insert( pNewEntry.release() ) )
2895  bOk = true;
2896 
2897  rDoc.CompileHybridFormula();
2898 
2899  aModificator.SetDocumentModified();
2900  SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScAreasChanged ) );
2901  }
2902 
2903  return bOk;
2904 }
2905 
2907 {
2908  bool bDone = false;
2909  ScRange aRange;
2910  if ( GetViewData().GetSimpleArea(aRange) == SC_MARK_SIMPLE )
2911  bDone = GetViewData().GetDocShell()->GetDocFunc().CreateNames( aRange, nFlags, false );
2912 
2913  if (!bDone)
2914  ErrorMessage(STR_CREATENAME_MARKERR);
2915 }
2916 
2918 {
2920 
2921  SCCOL nStartCol, nEndCol;
2922  SCROW nStartRow, nEndRow;
2923  SCTAB nDummy;
2924  if (GetViewData().GetSimpleArea(nStartCol,nStartRow,nDummy,nEndCol,nEndRow,nDummy) == SC_MARK_SIMPLE)
2925  {
2926  ScDocument& rDoc = GetViewData().GetDocument();
2927  SCTAB nTab = GetViewData().GetTabNo();
2928  bool bOk;
2929  SCCOL i;
2930  SCROW j;
2931 
2932  bOk = true;
2933  SCCOL nFirstCol = nStartCol;
2934  SCCOL nLastCol = nEndCol;
2935  if (nStartCol+1 < nEndCol) { ++nFirstCol; --nLastCol; }
2936  for (i=nFirstCol; i<=nLastCol && bOk; i++)
2937  if (!rDoc.HasStringData( i,nStartRow,nTab ))
2938  bOk = false;
2939  if (bOk)
2940  nFlags |= CreateNameFlags::Top;
2941  else // Bottom only if not Top
2942  {
2943  bOk = true;
2944  for (i=nFirstCol; i<=nLastCol && bOk; i++)
2945  if (!rDoc.HasStringData( i,nEndRow,nTab ))
2946  bOk = false;
2947  if (bOk)
2948  nFlags |= CreateNameFlags::Bottom;
2949  }
2950 
2951  bOk = true;
2952  SCROW nFirstRow = nStartRow;
2953  SCROW nLastRow = nEndRow;
2954  if (nStartRow+1 < nEndRow) { ++nFirstRow; --nLastRow; }
2955  for (j=nFirstRow; j<=nLastRow && bOk; j++)
2956  if (!rDoc.HasStringData( nStartCol,j,nTab ))
2957  bOk = false;
2958  if (bOk)
2959  nFlags |= CreateNameFlags::Left;
2960  else // Right only if not Left
2961  {
2962  bOk = true;
2963  for (j=nFirstRow; j<=nLastRow && bOk; j++)
2964  if (!rDoc.HasStringData( nEndCol,j,nTab ))
2965  bOk = false;
2966  if (bOk)
2967  nFlags |= CreateNameFlags::Right;
2968  }
2969  }
2970 
2971  if (nStartCol == nEndCol)
2973  if (nStartRow == nEndRow)
2975 
2976  return nFlags;
2977 }
2978 
2980 {
2981  ScAddress aPos( GetViewData().GetCurX(), GetViewData().GetCurY(), GetViewData().GetTabNo() );
2982  ScDocShell* pDocSh = GetViewData().GetDocShell();
2983  if ( pDocSh->GetDocFunc().InsertNameList( aPos, false ) )
2984  pDocSh->UpdateOle(GetViewData());
2985 }
2986 
2988 {
2989  ScDocShell* pDocShell = GetViewData().GetDocShell();
2990  ScRange aMarkRange;
2991  if (rSel.IsMultiMarked() )
2992  rSel.GetMultiMarkArea( aMarkRange );
2993  else
2994  rSel.GetMarkArea( aMarkRange );
2995 
2996  bool bSetLines = false;
2997  bool bSetAlign = false;
2998  if ( pAttr )
2999  {
3000  const SfxItemSet& rNewSet = pAttr->GetItemSet();
3001  bSetLines = rNewSet.GetItemState( ATTR_BORDER ) == SfxItemState::SET ||
3002  rNewSet.GetItemState( ATTR_SHADOW ) == SfxItemState::SET;
3003  bSetAlign = rNewSet.GetItemState( ATTR_HOR_JUSTIFY ) == SfxItemState::SET;
3004  }
3005 
3006  sal_uInt16 nExtFlags = 0;
3007  if ( bSetLines )
3008  nExtFlags |= SC_PF_LINES;
3009  if ( bSetAlign )
3010  nExtFlags |= SC_PF_WHOLEROWS;
3011 
3012  SCCOL nStartCol = aMarkRange.aStart.Col();
3013  SCROW nStartRow = aMarkRange.aStart.Row();
3014  SCTAB nStartTab = aMarkRange.aStart.Tab();
3015  SCCOL nEndCol = aMarkRange.aEnd.Col();
3016  SCROW nEndRow = aMarkRange.aEnd.Row();
3017  SCTAB nEndTab = aMarkRange.aEnd.Tab();
3018  pDocShell->PostPaint( nStartCol, nStartRow, nStartTab,
3019  nEndCol, nEndRow, nEndTab,
3020  PaintPartFlags::Grid, nExtFlags | SC_PF_TESTMERGE );
3021  ScTabViewShell* pTabViewShell = GetViewData().GetViewShell();
3022  pTabViewShell->AdjustBlockHeight(false, const_cast<ScMarkData*>(&rSel));
3023 }
3024 
3025 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ScMarkData & GetMarkData()
Definition: viewdata.cxx:3046
#define SC_PF_TESTMERGE
Definition: docsh.hxx:76
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:5320
CreateNameFlags GetCreateNameFlags()
Definition: viewfunc.cxx:2917
List of spreadsheet functions.
Definition: funcdesc.hxx:242
SC_DLLPUBLIC void ShowCol(SCCOL nCol, SCTAB nTab, bool bShow)
Definition: document.cxx:4296
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:1584
constexpr double nPPTY
void DeleteContents(InsertDeleteFlags nFlags)
Definition: viewfunc.cxx:1936
void UpdatePageBreaks(SCTAB nTab, const ScRange *pUserArea=nullptr)
Definition: document.cxx:6214
SC_DLLPUBLIC void ApplySelectionStyle(const ScStyleSheet &rStyle, const ScMarkData &rMark)
Definition: document.cxx:4857
void ApplyStyle(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScStyleSheet &rStyle)
Definition: document.cxx:4827
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:1365
OUString GetColRowString() const
Create a human-readable string representation of the cell address.
Definition: address.cxx:2497
void MarkToSimple()
Definition: markdata.cxx:237
sal_Int32 nIndex
double GetPPTY() const
Definition: sizedev.hxx:43
SC_DLLPUBLIC void ShowRows(SCROW nRow1, SCROW nRow2, SCTAB nTab, bool bShow)
Definition: document.cxx:4308
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:4020
bool IsPrinter() const
Definition: sizedev.hxx:44
#define EMPTY_OUSTRING
Definition: global.hxx:216
bool CreateNames(const ScRange &rRange, CreateNameFlags nFlags, bool bApi, SCTAB nTab=-1)
Definition: docfunc.cxx:5267
SC_DLLPUBLIC void RefreshZoom()
Definition: tabview5.cxx:426
SC_DLLPUBLIC bool DeleteContents(const ScMarkData &rMark, InsertDeleteFlags nFlags, bool bRecord, bool bApi)
Definition: docfunc.cxx:568
void CreateNames(CreateNameFlags nFlags)
Definition: viewfunc.cxx:2906
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:1402
constexpr sal_uInt16 ATTR_PATTERN_START(100)
void SetModified()
Definition: inputhdl.hxx:245
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:524
bool SetStringCell(const ScAddress &rPos, const OUString &rStr, bool bInteraction)
Definition: docfunc.cxx:925
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const =0
void DeleteCells(DelCellCmd eCmd)
Definition: viewfunc.cxx:1652
void ApplyAttr(const SfxPoolItem &rAttrItem, bool bAdjustBlockHeight=true)
Definition: viewfunc.cxx:997
void MarkRange(const ScRange &rRange, bool bSetCursor=true, bool bContinue=false)
Definition: tabview3.cxx:1683
sheet protection state container
const SfxItemSet & GetAttribs() const
Definition: editutil.hxx:101
void PostPaintCell(SCCOL nCol, SCROW nRow, SCTAB nTab)
Definition: docsh3.cxx:185
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:438
sal_uInt16 GetIndex() const
Definition: rangenam.hxx:117
sal_uInt16 GetLRUFuncListCount() const
Definition: appoptio.hxx:48
ScTokenArray * GetCode()
void InsertNameList()
Definition: viewfunc.cxx:2979
void SetLRUFuncList(const sal_uInt16 *pList, const sal_uInt16 nCount)
Definition: appoptio.cxx:107
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:167
ScDocFunc & GetDocFunc() const
Definition: viewdata.cxx:3029
double GetOutputFactor() const
Definition: docsh.hxx:354
ocOpen
sal_Int64 n
vcl::Window * GetFrameWin() const
Definition: tabview.hxx:584
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:3639
constexpr TypedWhichId< SvxBoxInfoItem > ATTR_BORDER_INNER(151)
void Unmark()
Definition: tabview3.cxx:1719
ScAddress aEnd
Definition: address.hxx:501
void EnterValue(SCCOL nCol, SCROW nRow, SCTAB nTab, const double &rValue)
Definition: viewfunc.cxx:593
ScDocument & GetDocument() const
Definition: viewdata.hxx:380
OpCode GetOpCode() const
void OnLOKInsertDeleteRow(SCROW nStartRow, tools::Long nOffset)
Definition: viewfunc.cxx:1519
sal_Int16 GetRightMargin() const
void ProtectSheet(SCTAB nTab, const ScTableProtection &rProtect)
Definition: docfunc.cxx:3935
SC_DLLPUBLIC void SetValue(SCCOL nCol, SCROW nRow, SCTAB nTab, const double &rVal)
Definition: document.cxx:3456
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:982
void EnterDataAtCursor(const OUString &rString)
Definition: viewfunc.cxx:749
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:359
SC_DLLPUBLIC bool HasAttrib(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, HasAttrFlags nMask) const
Definition: document.cxx:5172
bool InsertCells(const ScRange &rRange, const ScMarkData *pTabMark, InsCellCmd eCmd, bool bRecord, bool bApi, bool bPartOfPaste=false)
Definition: docfunc.cxx:1727
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:559
constexpr TypedWhichId< ScMergeAttr > ATTR_MERGE(144)
SC_DLLPUBLIC sal_uInt16 GetRowHeight(SCROW nRow, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4159
void ResetAutoSpell()
Definition: tabview.cxx:2257
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:292
SC_DLLPUBLIC ScDocumentPool * GetPool()
Definition: document.cxx:6054
static void lcl_PostRepaintCondFormat(const ScConditionalFormat *pCondFmt, ScDocShell *pDocSh)
Definition: viewfunc.cxx:81
void GetMarkArea(ScRange &rRange) const
Definition: markdata.cxx:112
virtual SfxUndoManager * GetUndoManager() override
Definition: docsh.cxx:2806
RET_NO
bool IsInputMode()
Definition: scmod.cxx:1348
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:4896
const ScRangeList & GetRange() const
Definition: conditio.hxx:560
const SfxStyleSheet * GetStyleSheetFromMarked()
Definition: viewfunc.cxx:1294
bool InsertName(const OUString &rName, const OUString &rSymbol, const OUString &rType)
Definition: viewfunc.cxx:2852
bool TestFormatArea(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bAttrChanged)
Definition: viewfunc.cxx:139
RET_YES
#define STD_COL_WIDTH
Definition: global.hxx:95
const OUString & GetName() const
bool SelectionEditable(bool *pOnlyNotBecauseOfMatrix=nullptr)
Definition: viewfunc.cxx:259
PropertiesInfo aProperties
void RemoveStyleSheetInUse(const SfxStyleSheetBase *pStyleSheet)
Definition: viewfunc.cxx:1410
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:225
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:870
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:312
SvtScriptType GetRangeScriptType(sc::ColumnBlockPosition &rBlockPos, const ScAddress &rPos, SCROW nLength)
Definition: documen6.cxx:183
bool Unprotect(SCTAB nTab, const OUString &rPassword)
Definition: viewfunc.cxx:2552
SC_DLLPUBLIC void SetColWidth(SCCOL nCol, SCTAB nTab, sal_uInt16 nNewWidth)
Definition: document.cxx:4081
const ScPatternAttr * GetSelectionPattern(const ScMarkData &rMark)
Definition: document.cxx:5093
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:4123
constexpr sal_uInt32 NUMBERFORMAT_ENTRY_NOT_FOUND
OpCode
sal_uInt32 GetStandardIndex(LanguageType eLnge=LANGUAGE_DONTKNOW)
void MarkDataChanged()
Definition: tabview3.cxx:1742
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:2074
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:4238
#define STD_EXTRA_WIDTH
Definition: global.hxx:96
void ReplaceNote(const ScAddress &rPos, const OUString &rNoteText, const OUString *pAuthor, const OUString *pDate, bool bApi)
Definition: docfunc.cxx:1333
void push_back(const ScRange &rRange)
Definition: rangelst.cxx:1142
bool IsDocShared() const
void UpdateEditView()
Definition: tabview3.cxx:2144
Mode eMode
#define HMM_PER_TWIPS
Definition: global.hxx:93
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:2262
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:91
void EndListAction()
Definition: docfunc.cxx:5763
bool DeleteCell(const ScAddress &rPos, const ScMarkData &rMark, InsertDeleteFlags nFlags, bool bRecord)
Definition: docfunc.cxx:661
bool SetEditCell(const ScAddress &rPos, const EditTextObject &rStr, bool bInteraction)
Definition: docfunc.cxx:962
const Fraction & GetZoomY() const
Definition: viewdata.hxx:460
SC_DLLPUBLIC const ScPatternAttr * GetPattern(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4733
bool SetNormalString(bool &o_rbNumFmtSet, const ScAddress &rPos, const OUString &rText, bool bApi)
Definition: docfunc.cxx:787
void SetCol(SCCOL nColP)
Definition: address.hxx:279
SvtScriptType GetSelectionScriptType()
Definition: viewfunc.cxx:802
ScViewData & GetViewData()
Definition: tabview.hxx:334
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:4712
bool bFormatValid
Definition: viewfunc.hxx:76
bool Protect(SCTAB nTab, const OUString &rPassword)
Definition: docfunc.cxx:3996
const SfxPoolItem & GetItem(sal_uInt16 nWhichP) const
Definition: patattr.hxx:71
OutputDevice * GetDevice() const
Definition: sizedev.hxx:41
SC_DLLPUBLIC double GetValue(const ScAddress &rPos) const
Definition: document.cxx:3626
void PaintArea(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, ScUpdateMode eMode=ScUpdateMode::All)
Definition: tabview3.cxx:2302
ScTabViewShell * GetViewShell() const
Definition: viewdata.hxx:357
void SetNoteText(const ScAddress &rPos, const OUString &rNoteText)
Definition: viewfunc.cxx:2596
constexpr double nPPTX
bool ApplyAttributes(const ScMarkData &rMark, const ScPatternAttr &rPattern, bool bApi)
Definition: docfunc.cxx:1417
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:3392
static SC_DLLPUBLIC sal_uInt16 nStdRowHeight
Definition: global.hxx:585
const char * GetMessageId() const
Definition: editable.cxx:152
SC_DLLPUBLIC void SetAppOptions(const ScAppOptions &rOpt)
Definition: scmod.cxx:715
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:679
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:869
const ScStyleSheet * GetSelectionStyle(const ScMarkData &rMark) const
Definition: document.cxx:4904
virtual void AddUndoAction(std::unique_ptr< SfxUndoAction > pAction, bool bTryMerg=false)
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
Definition: documen2.cxx:437
SvNumFormatType GetType() const
SC_DLLPUBLIC bool ColHidden(SCCOL nCol, SCTAB nTab, SCCOL *pFirstCol=nullptr, SCCOL *pLastCol=nullptr) const
Definition: document.cxx:4443
sal_uInt16 ClearItem(sal_uInt16 nWhich=0)
SvtScriptType
void OnLOKSetWidthOrHeight(SCCOLROW nStart, bool bWidth)
Definition: viewfunc.cxx:1575
#define SV_MAX_COUNT_STANDARD_FORMATS
void SetTextCurrentDefaults(const EditTextObject &rTextObject)
SetText and apply defaults already set.
Definition: editutil.cxx:555
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:1486
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:479
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:2610
sal_Int16 SCCOL
Definition: types.hxx:22
InsertDeleteFlags
Definition: global.hxx:160
#define SC_MOD()
Definition: scmod.hxx:250
void UpdateStyleSheetInUse(const SfxStyleSheetBase *pStyleSheet)
Definition: viewfunc.cxx:1436
SC_DLLPUBLIC bool SetOptimalHeight(sc::RowHeightContext &rCxt, SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
Definition: document.cxx:4264
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:871
void RemoveEditTextCharAttribs(const ScAddress &rPos, const ScPatternAttr &rAttr)
Definition: document.cxx:3618
bool IsStaticDefaultItem(const SfxPoolItem *pItem)
const ScStyleSheet * GetStyleSheet() const
Definition: patattr.hxx:127
SC_DLLPUBLIC const ScAppOptions & GetAppOptions()
Definition: scmod.cxx:728
static const SfxItemPropertyMap & GetCellPropertyMap()
Definition: cellsuno.cxx:5789
SC_DLLPUBLIC SfxItemPool * GetEnginePool() const
Definition: documen2.cxx:448
SC_DLLPUBLIC void ApplyPattern(SCCOL nCol, SCROW nRow, SCTAB nTab, const ScPatternAttr &rAttr)
Definition: document.cxx:4761
tools::Long Width() const
void SelectOneTable(SCTAB nTab)
Definition: markdata.cxx:189
OUString ScResId(const char *pId)
Definition: scdll.cxx:89
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:2642
bool IsNumberFormat(const OUString &sString, sal_uInt32 &F_Index, double &fOutNumber, SvNumInputOptions eInputOptions=SvNumInputOptions::NONE)
void ChangeIndent(bool bIncrement)
Definition: viewfunc.cxx:2822
void EnterListAction(const char *pNameResId)
Definition: docfunc.cxx:5754
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:4099
#define LRU_MAX
Definition: funcdesc.hxx:35
void ReplaceNote(const ScAddress &rPos, const OUString &rNoteText, const OUString *pAuthor, const OUString *pDate)
Definition: viewfunc.cxx:2601
void ApplySelectionPattern(const ScPatternAttr &rAttr, bool bCursorOnly=false)
Definition: viewfunc.cxx:1107
bool IsFunction() const
SC_DLLPUBLIC const EditTextObject * GetEditText(const ScAddress &rPos) const
Definition: document.cxx:3609
sal_uInt32 GetEntryKey(std::u16string_view sStr, LanguageType eLnge=LANGUAGE_DONTKNOW)
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:850
void SetNumberFormat(SvNumFormatType nFormatType, sal_uLong nAdd=0)
Definition: viewfunc.cxx:2606
static void UnmarkFiltered(ScMarkData &rMark, const ScDocument &rDoc)
Definition: viewutil.cxx:223
static SC_DLLPUBLIC LanguageType eLnge
Definition: global.hxx:549
const SCTAB MAXTAB
Definition: address.hxx:71
void setForceAutoSize(bool b)
void StartFormatArea()
Definition: viewfunc.cxx:117
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:501
void PostPaint(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, sal_uInt16 nExtFlags=0)
Definition: docsh3.cxx:98
SC_DLLPUBLIC bool ExtendMerge(SCCOL nStartCol, SCROW nStartRow, SCCOL &rEndCol, SCROW &rEndRow, SCTAB nTab, bool bRefresh=false)
Definition: document.cxx:5561
SfxItemPool * GetPool() const
Size GetTextSize()
Definition: inputhdl.cxx:4282
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:390
ScSizeMode
Definition: global.hxx:361
const SCTAB TABLEID_DOC
Definition: address.hxx:85
FormulaError
SCCOL Col() const
Definition: address.hxx:267
static ScFunctionList * GetStarCalcFunctionList()
Definition: global.cxx:609
OUString GetFormatDecimalSep(sal_uInt32 nFormat) const
bool IsReadOnly() const
SC_DLLPUBLIC const ScPatternAttr * GetSelectionPattern()
Definition: viewfunc.cxx:828
SC_DLLPUBLIC bool HasStringData(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: document.cxx:3754
size_t LeaveListAction()
static bool lcl_FunctionKnown(sal_uInt16 nOpCode)
Definition: viewfunc.cxx:277
ScDBFunc * GetView() const
Definition: viewdata.cxx:852
std::vector< SfxItemPropertyNamedEntry > PropertyEntryVector_t
#define MAX_COL_WIDTH
Definition: global.hxx:102
bool IsValid(SvxBoxInfoItemValidFlags nValid) const
size_t mnStart
Definition: cellvalues.cxx:23
ScModelObj * getMustPropagateChangesModel(const ScDocShell &rDocShell)
Definition: docsh.hxx:471
void SetCurYForTab(SCCOL nNewCurY, SCTAB nTabIndex)
Definition: viewdata.cxx:1393
void EnterMatrix(const OUString &rString,::formula::FormulaGrammar::Grammar eGram)
Definition: viewfunc.cxx:758
CellType meType
Definition: cellvalue.hxx:106
bool InsertNameList(const ScAddress &rStartPos, bool bApi)
Definition: docfunc.cxx:5356
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:137
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
sal_Int32 SCROW
Definition: types.hxx:18
static SC_DLLPUBLIC SvtScriptType GetDefaultScriptType()
Definition: global.cxx:849
#define SC_PF_LINES
Definition: docsh.hxx:75
void ApplyPatternLines(const ScPatternAttr &rAttr, const SvxBoxItem &rNewOuter, const SvxBoxInfoItem *pNewInner)
Definition: viewfunc.cxx:1025
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:4954
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:1012
double GetPPTY() const
Definition: viewdata.hxx:469
void ResetAutoSpellForContentChange()
Definition: tabview.cxx:2268
void DoAutoAttributes(SCCOL nCol, SCROW nRow, SCTAB nTab, bool bAttrChanged)
Definition: viewfunc.cxx:204
void HideAllCursors()
Definition: tabview3.cxx:216
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:1307
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:103
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:2690
void MoveCursorRel(SCCOL nMovX, SCROW nMovY, ScFollowMode eMode, bool bShift, bool bKeepSel=false)
Definition: tabview3.cxx:1261
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:5016
InsCellCmd
Definition: global.hxx:301
SC_DLLPUBLIC void ApplySelectionPattern(const ScPatternAttr &rAttr, const ScMarkData &rMark, ScEditDataArray *pDataArray=nullptr, bool *pIsChanged=nullptr)
Definition: document.cxx:5867
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:4305
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:730
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:1314
void Protect(SCTAB nTab, const OUString &rPassword)
Definition: viewfunc.cxx:2522
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:4251
void OnLOKInsertDeleteColumn(SCCOL nStartCol, tools::Long nOffset)
Definition: viewfunc.cxx:1463
static SC_DLLPUBLIC const CharClass * getCharClassPtr()
Definition: global.cxx:1009
bool UpdateOutlineRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bShow)
Definition: documen3.cxx:1411
SC_DLLPUBLIC void SetManualHeight(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bManual)
Definition: document.cxx:4112
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:400
constexpr sal_uInt16 ATTR_PATTERN_END(155)
const ScDocument & GetDocument() const
Definition: docsh.hxx:217
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:97
sal_uInt32 GetCount() const
Definition: funcdesc.hxx:248
ScPositionHelper & GetLOKWidthHelper()
Definition: viewdata.hxx:410
SC_DLLPUBLIC SfxItemPool * GetEditPool() const
Definition: documen2.cxx:443
void NotifyIfChangesListeners(const ScDocShell &rDocShell, const ScRange &rRange, const OUString &rType=OUString("cell-change"))
Definition: docsh.hxx:487
void SetMarking(bool bFlag)
Definition: markdata.hxx:103
SC_DLLPUBLIC bool RowHidden(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: document.cxx:4427
void UpdateSelectionArea(const ScMarkData &rSel, ScPatternAttr *pAttr=nullptr)
Definition: viewfunc.cxx:2987
static bool lcl_AddFunction(ScAppOptions &rAppOpt, sal_uInt16 nOpCode)
Definition: viewfunc.cxx:290
void SetDocumentModified()
Definition: docsh.cxx:3159
#define SC_PF_WHOLEROWS
Definition: docsh.hxx:77
void ApplyUserItemSet(const SfxItemSet &rItemSet)
Definition: viewfunc.cxx:1275
bool IsUndoEnabled() const
Definition: document.hxx:1528
void SetMarkedWidthOrHeight(bool bWidth, ScSizeMode eMode, sal_uInt16 nSizeTwips)
Definition: viewfunc.cxx:2328
ScDirection
Definition: global.hxx:353
void GetSelectionFrame(const ScMarkData &rMark, SvxBoxItem &rLineOuter, SvxBoxInfoItem &rLineInner)
Definition: document.cxx:5099
void ApplyAttributes(const SfxItemSet *pDialogSet, const SfxItemSet *pOldSet, bool bAdjustBlockHeight=true)
Definition: viewfunc.cxx:885
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:1304
SC_DLLPUBLIC ScConditionalFormat * GetCondFormat(SCCOL nCol, SCROW nRow, SCTAB nTab) const
Definition: documen4.cxx:834
ScDocFunc & GetDocFunc()
Definition: docsh.hxx:219
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:4314
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:5746
void UpdateLayerLocks()
Definition: tabview5.cxx:346
SC_DLLPUBLIC void ExtendOverlapped(SCCOL &rStartCol, SCROW &rStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab) const
Definition: document.cxx:5471
SC_DLLPUBLIC sal_uInt16 GetColWidth(SCCOL nCol, SCTAB nTab, bool bHiddenAsZero=true) const
Definition: document.cxx:4118
sal_uInt16 GetOptimalColWidth(SCCOL nCol, SCTAB nTab, bool bFormula)
Definition: viewfunc.cxx:235
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:232
void SetHyperLink(bool bVal)
void ModifyCellSize(ScDirection eDir, bool bOptimal)
Definition: viewfunc.cxx:2352
void DeleteMulti(bool bRows)
Definition: viewfunc.cxx:1740
SC_DLLPUBLIC void CellContentChanged()
Definition: tabview3.cxx:510
void SetAutoCorrection(bool bVal)
When auto correction is set, the jump command reorder must be enabled.
Definition: compiler.cxx:4014
double GetPPTX() const
Definition: sizedev.hxx:42
ocClose
SC_DLLPUBLIC bool insert(ScRangeData *p, bool bReuseFreeIndex=true)
Insert object into set.
Definition: rangenam.cxx:807
void GetSelectionFrame(std::shared_ptr< SvxBoxItem > &rLineOuter, std::shared_ptr< SvxBoxInfoItem > &rLineInner)
Definition: viewfunc.cxx:854
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:452
bool IsSelectionEditable(const ScMarkData &rMark, bool *pOnlyNotBecauseOfMatrix=nullptr) const
Definition: document.cxx:5344
LanguageType GetLanguage() const
void ForgetLastPattern()
Definition: inputhdl.cxx:2226
sal_uInt16 nPos
sal_Int16 SCTAB
Definition: types.hxx:23
SC_DLLPUBLIC CRFlags GetRowFlags(SCROW nRow, SCTAB nTab) const
Definition: document.cxx:4334
constexpr TypedWhichId< SvxMarginItem > ATTR_MARGIN(143)
bool InsertCells(InsCellCmd eCmd, bool bRecord=true, bool bPartOfPaste=false)
Definition: viewfunc.cxx:1599
void EnterData(SCCOL nCol, SCROW nRow, SCTAB nTab, const OUString &rString, const EditTextObject *pData=nullptr)
Definition: viewfunc.cxx:341
void GetFormatSpecialInfo(bool &bThousand, bool &IsRed, sal_uInt16 &nPrecision, sal_uInt16 &nLeadingCnt) const
void ShowAllCursors()
Definition: tabview3.cxx:230
SCCOL GetCurX() const
Definition: viewdata.hxx:401
void SetMarkData(const ScMarkData &rNew)
Definition: tabview3.cxx:1733