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