LibreOffice Module sc (master)  1
dbdocfun.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <sfx2/app.hxx>
21 #include <vcl/svapp.hxx>
22 #include <vcl/weld.hxx>
24 #include <svx/svdpage.hxx>
25 #include <svx/svdoole2.hxx>
26 #include <com/sun/star/sdb/CommandType.hpp>
27 #include <unotools/charclass.hxx>
28 #include <comphelper/lok.hxx>
29 
30 #include <dbdocfun.hxx>
31 #include <dbdata.hxx>
32 #include <undodat.hxx>
33 #include <docsh.hxx>
34 #include <docfunc.hxx>
35 #include <globstr.hrc>
36 #include <scresid.hxx>
37 #include <globalnames.hxx>
38 #include <tabvwsh.hxx>
39 #include <patattr.hxx>
40 #include <rangenam.hxx>
41 #include <olinetab.hxx>
42 #include <dpobject.hxx>
43 #include <dpsave.hxx>
44 #include <dociter.hxx>
45 #include <editable.hxx>
46 #include <attrib.hxx>
47 #include <drwlayer.hxx>
48 #include <dpshttab.hxx>
49 #include <hints.hxx>
50 #include <queryentry.hxx>
51 #include <markdata.hxx>
52 #include <progress.hxx>
53 #include <undosort.hxx>
54 #include <inputopt.hxx>
55 #include <scmod.hxx>
56 
57 #include <chartlis.hxx>
58 #include <ChartTools.hxx>
59 
60 #include <memory>
61 
62 using namespace ::com::sun::star;
63 
64 bool ScDBDocFunc::AddDBRange( const OUString& rName, const ScRange& rRange )
65 {
66 
67  ScDocShellModificator aModificator( rDocShell );
68 
70  ScDBCollection* pDocColl = rDoc.GetDBCollection();
71  bool bUndo (rDoc.IsUndoEnabled());
72 
73  std::unique_ptr<ScDBCollection> pUndoColl;
74  if (bUndo)
75  pUndoColl.reset( new ScDBCollection( *pDocColl ) );
76 
77  std::unique_ptr<ScDBData> pNew(new ScDBData( rName, rRange.aStart.Tab(),
78  rRange.aStart.Col(), rRange.aStart.Row(),
79  rRange.aEnd.Col(), rRange.aEnd.Row() ));
80 
81  // #i55926# While loading XML, formula cells only have a single string token,
82  // so CompileDBFormula would never find any name (index) tokens, and would
83  // unnecessarily loop through all cells.
84  bool bCompile = !rDoc.IsImportingXML();
85  bool bOk;
86  if ( bCompile )
88  if ( rName == STR_DB_LOCAL_NONAME )
89  {
90  rDoc.SetAnonymousDBData(rRange.aStart.Tab(), std::move(pNew));
91  bOk = true;
92  }
93  else
94  {
95  bOk = pDocColl->getNamedDBs().insert(std::move(pNew));
96  }
97  if ( bCompile )
98  rDoc.CompileHybridFormula();
99 
100  if (!bOk)
101  {
102  return false;
103  }
104 
105  if (bUndo)
106  {
108  std::make_unique<ScUndoDBData>( &rDocShell, std::move(pUndoColl),
109  std::make_unique<ScDBCollection>( *pDocColl ) ) );
110  }
111 
112  aModificator.SetDocumentModified();
113  SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) );
114  return true;
115 }
116 
117 bool ScDBDocFunc::DeleteDBRange(const OUString& rName)
118 {
119  bool bDone = false;
120  ScDocument& rDoc = rDocShell.GetDocument();
121  ScDBCollection* pDocColl = rDoc.GetDBCollection();
122  bool bUndo = rDoc.IsUndoEnabled();
123 
124  ScDBCollection::NamedDBs& rDBs = pDocColl->getNamedDBs();
125  auto const iter = rDBs.findByUpperName2(ScGlobal::getCharClassPtr()->uppercase(rName));
126  if (iter != rDBs.end())
127  {
128  ScDocShellModificator aModificator( rDocShell );
129 
130  std::unique_ptr<ScDBCollection> pUndoColl;
131  if (bUndo)
132  pUndoColl.reset( new ScDBCollection( *pDocColl ) );
133 
134  rDoc.PreprocessDBDataUpdate();
135  rDBs.erase(iter);
136  rDoc.CompileHybridFormula();
137 
138  if (bUndo)
139  {
141  std::make_unique<ScUndoDBData>( &rDocShell, std::move(pUndoColl),
142  std::make_unique<ScDBCollection>( *pDocColl ) ) );
143  }
144 
145  aModificator.SetDocumentModified();
146  SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) );
147  bDone = true;
148  }
149 
150  return bDone;
151 }
152 
153 bool ScDBDocFunc::RenameDBRange( const OUString& rOld, const OUString& rNew )
154 {
155  bool bDone = false;
156  ScDocument& rDoc = rDocShell.GetDocument();
157  ScDBCollection* pDocColl = rDoc.GetDBCollection();
158  bool bUndo = rDoc.IsUndoEnabled();
159  ScDBCollection::NamedDBs& rDBs = pDocColl->getNamedDBs();
160  auto const iterOld = rDBs.findByUpperName2(ScGlobal::getCharClassPtr()->uppercase(rOld));
161  const ScDBData* pNew = rDBs.findByUpperName(ScGlobal::getCharClassPtr()->uppercase(rNew));
162  if (iterOld != rDBs.end() && !pNew)
163  {
164  ScDocShellModificator aModificator( rDocShell );
165 
166  std::unique_ptr<ScDBData> pNewData(new ScDBData(rNew, **iterOld));
167 
168  std::unique_ptr<ScDBCollection> pUndoColl( new ScDBCollection( *pDocColl ) );
169 
170  rDoc.PreprocessDBDataUpdate();
171  rDBs.erase(iterOld);
172  bool bInserted = rDBs.insert(std::move(pNewData));
173  if (!bInserted) // error -> restore old state
174  {
175  rDoc.SetDBCollection(std::move(pUndoColl)); // belongs to the document then
176  }
177 
178  rDoc.CompileHybridFormula();
179 
180  if (bInserted) // insertion worked
181  {
182  if (bUndo)
183  {
185  std::make_unique<ScUndoDBData>( &rDocShell, std::move(pUndoColl),
186  std::make_unique<ScDBCollection>( *pDocColl ) ) );
187  }
188  else
189  pUndoColl.reset();
190 
191  aModificator.SetDocumentModified();
192  SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) );
193  bDone = true;
194  }
195  }
196 
197  return bDone;
198 }
199 
200 void ScDBDocFunc::ModifyDBData( const ScDBData& rNewData )
201 {
202  ScDocument& rDoc = rDocShell.GetDocument();
203  ScDBCollection* pDocColl = rDoc.GetDBCollection();
204  bool bUndo = rDoc.IsUndoEnabled();
205 
206  ScDBData* pData = nullptr;
207  if (rNewData.GetName() == STR_DB_LOCAL_NONAME)
208  {
209  ScRange aRange;
210  rNewData.GetArea(aRange);
211  SCTAB nTab = aRange.aStart.Tab();
212  pData = rDoc.GetAnonymousDBData(nTab);
213  }
214  else
215  pData = pDocColl->getNamedDBs().findByUpperName(rNewData.GetUpperName());
216 
217  if (!pData)
218  return;
219 
220  ScDocShellModificator aModificator( rDocShell );
221  ScRange aOldRange, aNewRange;
222  pData->GetArea(aOldRange);
223  rNewData.GetArea(aNewRange);
224  bool bAreaChanged = ( aOldRange != aNewRange ); // then a recompilation is needed
225 
226  std::unique_ptr<ScDBCollection> pUndoColl;
227  if (bUndo)
228  pUndoColl.reset( new ScDBCollection( *pDocColl ) );
229 
230  *pData = rNewData;
231  if (bAreaChanged)
232  rDoc.CompileDBFormula();
233 
234  if (bUndo)
235  {
237  std::make_unique<ScUndoDBData>( &rDocShell, std::move(pUndoColl),
238  std::make_unique<ScDBCollection>( *pDocColl ) ) );
239  }
240 
241  aModificator.SetDocumentModified();
242 }
243 
244 void ScDBDocFunc::ModifyAllDBData( const ScDBCollection& rNewColl, const std::vector<ScRange>& rDelAreaList )
245 {
246  ScDocShellModificator aModificator(rDocShell);
247  ScDocument& rDoc = rDocShell.GetDocument();
248  ScDBCollection* pOldColl = rDoc.GetDBCollection();
249  std::unique_ptr<ScDBCollection> pUndoColl;
250  bool bRecord = rDoc.IsUndoEnabled();
251 
252  for (const auto& rDelArea : rDelAreaList)
253  {
254  // unregistering target in SBA no longer necessary
255  const ScAddress& rStart = rDelArea.aStart;
256  const ScAddress& rEnd = rDelArea.aEnd;
258  rStart.Tab(), rStart.Col(), rStart.Row(), rEnd.Col());
259  }
260 
261  if (bRecord)
262  pUndoColl.reset( new ScDBCollection( *pOldColl ) );
263 
264  // register target in SBA no longer necessary
265 
266  rDoc.PreprocessDBDataUpdate();
267  rDoc.SetDBCollection( std::unique_ptr<ScDBCollection>(new ScDBCollection( rNewColl )) );
268  rDoc.CompileHybridFormula();
269  pOldColl = nullptr;
270  rDocShell.PostPaint(ScRange(0, 0, 0, rDoc.MaxCol(), rDoc.MaxRow(), MAXTAB), PaintPartFlags::Grid);
271  aModificator.SetDocumentModified();
272  SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScDbAreasChanged ) );
273 
274  if (bRecord)
275  {
277  std::make_unique<ScUndoDBData>(&rDocShell, std::move(pUndoColl),
278  std::make_unique<ScDBCollection>(rNewColl)));
279  }
280 }
281 
282 bool ScDBDocFunc::RepeatDB( const OUString& rDBName, bool bApi, bool bIsUnnamed, SCTAB aTab )
283 {
285 
286  bool bDone = false;
287  ScDocument& rDoc = rDocShell.GetDocument();
288  bool bRecord = true;
289  if (!rDoc.IsUndoEnabled())
290  bRecord = false;
291  ScDBData* pDBData = nullptr;
292  if (bIsUnnamed)
293  {
294  pDBData = rDoc.GetAnonymousDBData( aTab );
295  }
296  else
297  {
298  ScDBCollection* pColl = rDoc.GetDBCollection();
299  if (pColl)
300  pDBData = pColl->getNamedDBs().findByUpperName(ScGlobal::getCharClassPtr()->uppercase(rDBName));
301  }
302 
303  if ( pDBData )
304  {
305  ScQueryParam aQueryParam;
306  pDBData->GetQueryParam( aQueryParam );
307  bool bQuery = aQueryParam.GetEntry(0).bDoQuery;
308 
309  ScSortParam aSortParam;
310  pDBData->GetSortParam( aSortParam );
311  bool bSort = aSortParam.maKeyState[0].bDoSort;
312 
313  ScSubTotalParam aSubTotalParam;
314  pDBData->GetSubTotalParam( aSubTotalParam );
315  bool bSubTotal = aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly;
316 
317  if ( bQuery || bSort || bSubTotal )
318  {
319  bool bQuerySize = false;
320  ScRange aOldQuery;
321  ScRange aNewQuery;
322  if (bQuery && !aQueryParam.bInplace)
323  {
324  ScDBData* pDest = rDoc.GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow,
325  aQueryParam.nDestTab, ScDBDataPortion::TOP_LEFT );
326  if (pDest && pDest->IsDoSize())
327  {
328  pDest->GetArea( aOldQuery );
329  bQuerySize = true;
330  }
331  }
332 
333  SCTAB nTab;
334  SCCOL nStartCol;
335  SCROW nStartRow;
336  SCCOL nEndCol;
337  SCROW nEndRow;
338  pDBData->GetArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow );
339 
341 
342  ScDocumentUniquePtr pUndoDoc;
343  std::unique_ptr<ScOutlineTable> pUndoTab;
344  std::unique_ptr<ScRangeName> pUndoRange;
345  std::unique_ptr<ScDBCollection> pUndoDB;
346 
347  if (bRecord)
348  {
349  SCTAB nTabCount = rDoc.GetTableCount();
350  pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
351  ScOutlineTable* pTable = rDoc.GetOutlineTable( nTab );
352  if (pTable)
353  {
354  pUndoTab.reset(new ScOutlineTable( *pTable ));
355 
356  // column/row state
357  SCCOLROW nOutStartCol, nOutEndCol;
358  SCCOLROW nOutStartRow, nOutEndRow;
359  pTable->GetColArray().GetRange( nOutStartCol, nOutEndCol );
360  pTable->GetRowArray().GetRange( nOutStartRow, nOutEndRow );
361 
362  pUndoDoc->InitUndo( rDoc, nTab, nTab, true, true );
363  rDoc.CopyToDocument(static_cast<SCCOL>(nOutStartCol), 0,
364  nTab, static_cast<SCCOL>(nOutEndCol), rDoc.MaxRow(), nTab,
365  InsertDeleteFlags::NONE, false, *pUndoDoc);
366  rDoc.CopyToDocument(0, static_cast<SCROW>(nOutStartRow),
367  nTab, rDoc.MaxCol(), static_cast<SCROW>(nOutEndRow), nTab,
368  InsertDeleteFlags::NONE, false, *pUndoDoc);
369  }
370  else
371  pUndoDoc->InitUndo( rDoc, nTab, nTab, false, true );
372 
373  // secure data range - incl. filtering result
374  rDoc.CopyToDocument(0, nStartRow, nTab, rDoc.MaxCol(), nEndRow, nTab, InsertDeleteFlags::ALL, false, *pUndoDoc);
375 
376  // all formulas because of references
377  rDoc.CopyToDocument(0, 0, 0, rDoc.MaxCol(), rDoc.MaxRow(), nTabCount-1, InsertDeleteFlags::FORMULA, false, *pUndoDoc);
378 
379  // ranges of DB and other
380  ScRangeName* pDocRange = rDoc.GetRangeName();
381  if (!pDocRange->empty())
382  pUndoRange.reset(new ScRangeName( *pDocRange ));
383  ScDBCollection* pDocDB = rDoc.GetDBCollection();
384  if (!pDocDB->empty())
385  pUndoDB.reset(new ScDBCollection( *pDocDB ));
386  }
387 
388  if (bSort && bSubTotal)
389  {
390  // sort without SubTotals
391 
392  aSubTotalParam.bRemoveOnly = true; // will be reset again further down
393  DoSubTotals( nTab, aSubTotalParam, false, bApi );
394  }
395 
396  if (bSort)
397  {
398  pDBData->GetSortParam( aSortParam ); // range may have changed
399  (void)Sort( nTab, aSortParam, false, false, bApi );
400  }
401  if (bQuery)
402  {
403  pDBData->GetQueryParam( aQueryParam ); // range may have changed
404  ScRange aAdvSource;
405  if (pDBData->GetAdvancedQuerySource(aAdvSource))
406  Query( nTab, aQueryParam, &aAdvSource, false, bApi );
407  else
408  Query( nTab, aQueryParam, nullptr, false, bApi );
409 
410  // at not-inplace the table may have been converted
411 // if ( !aQueryParam.bInplace && aQueryParam.nDestTab != nTab )
412 // SetTabNo( nTab );
413  }
414  if (bSubTotal)
415  {
416  pDBData->GetSubTotalParam( aSubTotalParam ); // range may have changed
417  aSubTotalParam.bRemoveOnly = false;
418  DoSubTotals( nTab, aSubTotalParam, false, bApi );
419  }
420 
421  if (bRecord)
422  {
423  SCTAB nDummyTab;
424  SCCOL nDummyCol;
425  SCROW nDummyRow;
426  SCROW nNewEndRow;
427  pDBData->GetArea( nDummyTab, nDummyCol,nDummyRow, nDummyCol,nNewEndRow );
428 
429  const ScRange* pOld = nullptr;
430  const ScRange* pNew = nullptr;
431  if (bQuerySize)
432  {
433  ScDBData* pDest = rDoc.GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow,
434  aQueryParam.nDestTab, ScDBDataPortion::TOP_LEFT );
435  if (pDest)
436  {
437  pDest->GetArea( aNewQuery );
438  pOld = &aOldQuery;
439  pNew = &aNewQuery;
440  }
441  }
442 
444  std::make_unique<ScUndoRepeatDB>( &rDocShell, nTab,
445  nStartCol, nStartRow, nEndCol, nEndRow,
446  nNewEndRow,
447  //nCurX, nCurY,
448  nStartCol, nStartRow,
449  std::move(pUndoDoc), std::move(pUndoTab),
450  std::move(pUndoRange), std::move(pUndoDB),
451  pOld, pNew ) );
452  }
453 
454  rDocShell.PostPaint(ScRange(0, 0, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab),
456  bDone = true;
457  }
458  else if (!bApi) // "Don't execute any operations"
459  rDocShell.ErrorMessage(STR_MSSG_REPEATDB_0);
460  }
461 
462  return bDone;
463 }
464 
465 bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
466  bool bRecord, bool bPaint, bool bApi )
467 {
468  ScDocShellModificator aModificator( rDocShell );
469 
470  ScDocument& rDoc = rDocShell.GetDocument();
471  if (bRecord && !rDoc.IsUndoEnabled())
472  bRecord = false;
473 
474  ScDBData* pDBData = rDoc.GetDBAtArea( nTab, rSortParam.nCol1, rSortParam.nRow1,
475  rSortParam.nCol2, rSortParam.nRow2 );
476  if (!pDBData)
477  {
478  OSL_FAIL( "Sort: no DBData" );
479  return false;
480  }
481 
482  bool bCopy = !rSortParam.bInplace;
483  if ( bCopy && rSortParam.nDestCol == rSortParam.nCol1 &&
484  rSortParam.nDestRow == rSortParam.nRow1 && rSortParam.nDestTab == nTab )
485  bCopy = false;
486 
487  ScSortParam aLocalParam( rSortParam );
488  if ( bCopy )
489  {
490  // Copy the data range to the destination then move the sort range to it.
491  ScRange aSrcRange(rSortParam.nCol1, rSortParam.nRow1, nTab, rSortParam.nCol2, rSortParam.nRow2, nTab);
492  ScAddress aDestPos(rSortParam.nDestCol,rSortParam.nDestRow,rSortParam.nDestTab);
493 
494  ScDocFunc& rDocFunc = rDocShell.GetDocFunc();
495  bool bRet = rDocFunc.MoveBlock(aSrcRange, aDestPos, false, bRecord, bPaint, bApi);
496 
497  if (!bRet)
498  return false;
499 
500  aLocalParam.MoveToDest();
501  nTab = aLocalParam.nDestTab;
502  }
503 
504  // tdf#119804: If there is a header row/column, it won't be affected by
505  // sorting; so we can exclude it from the test.
506  SCROW nStartingRowToEdit = aLocalParam.nRow1;
507  SCCOL nStartingColToEdit = aLocalParam.nCol1;
508  if ( aLocalParam.bHasHeader )
509  {
510  if ( aLocalParam.bByRow )
511  nStartingRowToEdit++;
512  else
513  nStartingColToEdit++;
514  }
515  ScEditableTester aTester( rDoc, nTab, nStartingColToEdit, nStartingRowToEdit,
516  aLocalParam.nCol2, aLocalParam.nRow2, true /*bNoMatrixAtAll*/ );
517  if (!aTester.IsEditable())
518  {
519  if (!bApi)
521  return false;
522  }
523 
524  // Adjust aLocalParam cols/rows to used data area. Keep sticky top row or
525  // column (depending on direction) in any case, not just if it has headers,
526  // so empty leading cells will be sorted to the end.
527  bool bShrunk = false;
528  rDoc.ShrinkToUsedDataArea( bShrunk, nTab, aLocalParam.nCol1, aLocalParam.nRow1,
529  aLocalParam.nCol2, aLocalParam.nRow2, false, aLocalParam.bByRow, !aLocalParam.bByRow,
530  aLocalParam.bIncludeComments, aLocalParam.bIncludeGraphicObjects );
531 
532  SCROW nStartRow = aLocalParam.nRow1;
533  if (aLocalParam.bByRow && aLocalParam.bHasHeader && nStartRow < aLocalParam.nRow2)
534  ++nStartRow;
535 
536  if ( aLocalParam.bIncludePattern && rDoc.HasAttrib(
537  aLocalParam.nCol1, nStartRow , nTab,
538  aLocalParam.nCol2, aLocalParam.nRow2, nTab,
540  {
541  // merge attributes would be mixed up during sorting
542  if (!bApi)
543  rDocShell.ErrorMessage(STR_SORT_ERR_MERGED);
544  return false;
545  }
546 
547  // execute
548 
550 
551  // Calculate the script types for all cells in the sort range beforehand.
552  // This will speed up the row height adjustment that takes place after the
553  // sort.
554  rDoc.UpdateScriptTypes(
555  ScAddress(aLocalParam.nCol1,nStartRow,nTab),
556  aLocalParam.nCol2-aLocalParam.nCol1+1,
557  aLocalParam.nRow2-nStartRow+1);
558 
559  // No point adjusting row heights after the sort when all rows have the same height.
560  bool bUniformRowHeight =
561  rDoc.HasUniformRowHeight(nTab, nStartRow, aLocalParam.nRow2);
562 
563  bool bRepeatQuery = false; // repeat existing filter?
564  ScQueryParam aQueryParam;
565  pDBData->GetQueryParam( aQueryParam );
566  if ( aQueryParam.GetEntry(0).bDoQuery )
567  bRepeatQuery = true;
568 
569  sc::ReorderParam aUndoParam;
570 
571  // don't call ScDocument::Sort with an empty SortParam (may be empty here if bCopy is set)
572  if (aLocalParam.GetSortKeyCount() && aLocalParam.maKeyState[0].bDoSort)
573  {
574  ScInputOptions aInputOption = SC_MOD()->GetInputOptions();
575  bool bUpdateRefs = aInputOption.GetSortRefUpdate();
576  ScProgress aProgress(&rDocShell, ScResId(STR_PROGRESS_SORTING), 0, true);
577  rDoc.Sort(nTab, aLocalParam, bRepeatQuery, bUpdateRefs, &aProgress, &aUndoParam);
578  }
579 
580  if (bRecord)
581  {
582  // Set up an undo object.
584  std::make_unique<sc::UndoSort>(&rDocShell, aUndoParam));
585  }
586 
587  pDBData->SetSortParam(rSortParam);
588  // Remember additional settings on anonymous database ranges.
589  if (pDBData == rDoc.GetAnonymousDBData( nTab) || rDoc.GetDBCollection()->getAnonDBs().has( pDBData))
590  pDBData->UpdateFromSortParam( rSortParam);
591 
593  {
594  SfxViewShell* pSomeViewForThisDoc = rDocShell.GetBestViewShell(false);
595  SfxViewShell* pViewShell = SfxViewShell::GetFirst();
596  while (pViewShell)
597  {
598  ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
599  if (pTabViewShell && pTabViewShell->GetDocId() == pSomeViewForThisDoc->GetDocId())
600  {
601  pTabViewShell->GetViewData().GetLOKHeightHelper(nTab)->invalidateByIndex(nStartRow);
602  }
603  pViewShell = SfxViewShell::GetNext(*pViewShell);
604  }
605 
607  pSomeViewForThisDoc, false /* bColumns */, true /* bRows */, true /* bSizes*/,
608  true /* bHidden */, true /* bFiltered */, true /* bGroups */, nTab);
609  }
610 
611  if (nStartRow <= aLocalParam.nRow2)
612  {
613  ScRange aDirtyRange(
614  aLocalParam.nCol1, nStartRow, nTab,
615  aLocalParam.nCol2, aLocalParam.nRow2, nTab);
616  rDoc.SetDirty( aDirtyRange, true );
617  }
618 
619  if (bPaint)
620  {
622  SCCOL nStartX = aLocalParam.nCol1;
623  SCROW nStartY = aLocalParam.nRow1;
624  SCCOL nEndX = aLocalParam.nCol2;
625  SCROW nEndY = aLocalParam.nRow2;
626  if ( bRepeatQuery )
627  {
628  nPaint |= PaintPartFlags::Left;
629  nStartX = 0;
630  nEndX = rDoc.MaxCol();
631  }
632  rDocShell.PostPaint(ScRange(nStartX, nStartY, nTab, nEndX, nEndY, nTab), nPaint);
633  }
634 
635  if (!bUniformRowHeight && nStartRow <= aLocalParam.nRow2)
636  rDocShell.AdjustRowHeight(nStartRow, aLocalParam.nRow2, nTab);
637 
638  aModificator.SetDocumentModified();
639 
640  return true;
641 }
642 
643 bool ScDBDocFunc::Query( SCTAB nTab, const ScQueryParam& rQueryParam,
644  const ScRange* pAdvSource, bool bRecord, bool bApi )
645 {
646  ScDocShellModificator aModificator( rDocShell );
647 
648  ScDocument& rDoc = rDocShell.GetDocument();
649 
651  if (pViewSh && ScTabViewShell::isAnyEditViewInRange(pViewSh, /*bColumns*/ false, rQueryParam.nRow1, rQueryParam.nRow2))
652  {
653  return false;
654  }
655 
656  if (bRecord && !rDoc.IsUndoEnabled())
657  bRecord = false;
658  ScDBData* pDBData = rDoc.GetDBAtArea( nTab, rQueryParam.nCol1, rQueryParam.nRow1,
659  rQueryParam.nCol2, rQueryParam.nRow2 );
660  if (!pDBData)
661  {
662  OSL_FAIL( "Query: no DBData" );
663  return false;
664  }
665 
666  // Change from Inplace to non-Inplace, only then cancel Inplace:
667  // (only if "Persistent" is selected in the dialog)
668 
669  if ( !rQueryParam.bInplace && pDBData->HasQueryParam() && rQueryParam.bDestPers )
670  {
671  ScQueryParam aOldQuery;
672  pDBData->GetQueryParam(aOldQuery);
673  if (aOldQuery.bInplace)
674  {
675  // cancel old filtering
676 
677  SCSIZE nEC = aOldQuery.GetEntryCount();
678  for (SCSIZE i=0; i<nEC; i++)
679  aOldQuery.GetEntry(i).bDoQuery = false;
680  aOldQuery.bDuplicate = true;
681  Query( nTab, aOldQuery, nullptr, bRecord, bApi );
682  }
683  }
684 
685  ScQueryParam aLocalParam( rQueryParam ); // for Paint / destination range
686  bool bCopy = !rQueryParam.bInplace; // copied in Table::Query
687  ScDBData* pDestData = nullptr; // range to be copied to
688  bool bDoSize = false; // adjust destination size (insert/delete)
689  SCCOL nFormulaCols = 0; // only at bDoSize
690  bool bKeepFmt = false;
691  ScRange aOldDest;
692  ScRange aDestTotal;
693  if ( bCopy && rQueryParam.nDestCol == rQueryParam.nCol1 &&
694  rQueryParam.nDestRow == rQueryParam.nRow1 && rQueryParam.nDestTab == nTab )
695  bCopy = false;
696  SCTAB nDestTab = nTab;
697  if ( bCopy )
698  {
699  aLocalParam.MoveToDest();
700  nDestTab = rQueryParam.nDestTab;
701  if ( !rDoc.ValidColRow( aLocalParam.nCol2, aLocalParam.nRow2 ) )
702  {
703  if (!bApi)
704  rDocShell.ErrorMessage(STR_PASTE_FULL);
705  return false;
706  }
707 
708  ScEditableTester aTester( rDoc, nDestTab, aLocalParam.nCol1,aLocalParam.nRow1,
709  aLocalParam.nCol2,aLocalParam.nRow2);
710  if (!aTester.IsEditable())
711  {
712  if (!bApi)
714  return false;
715  }
716 
717  pDestData = rDoc.GetDBAtCursor( rQueryParam.nDestCol, rQueryParam.nDestRow,
718  rQueryParam.nDestTab, ScDBDataPortion::TOP_LEFT );
719  if (pDestData)
720  {
721  pDestData->GetArea( aOldDest );
722  aDestTotal=ScRange( rQueryParam.nDestCol,
723  rQueryParam.nDestRow,
724  nDestTab,
725  rQueryParam.nDestCol + rQueryParam.nCol2 - rQueryParam.nCol1,
726  rQueryParam.nDestRow + rQueryParam.nRow2 - rQueryParam.nRow1,
727  nDestTab );
728 
729  bDoSize = pDestData->IsDoSize();
730  // test if formulas need to be filled in (nFormulaCols):
731  if ( bDoSize && aOldDest.aEnd.Col() == aDestTotal.aEnd.Col() )
732  {
733  SCCOL nTestCol = aOldDest.aEnd.Col() + 1; // next to the range
734  SCROW nTestRow = rQueryParam.nDestRow +
735  ( aLocalParam.bHasHeader ? 1 : 0 );
736  while ( nTestCol <= rDoc.MaxCol() &&
737  rDoc.GetCellType(ScAddress( nTestCol, nTestRow, nTab )) == CELLTYPE_FORMULA )
738  {
739  ++nTestCol;
740  ++nFormulaCols;
741  }
742  }
743 
744  bKeepFmt = pDestData->IsKeepFmt();
745  if ( bDoSize && !rDoc.CanFitBlock( aOldDest, aDestTotal ) )
746  {
747  if (!bApi)
748  rDocShell.ErrorMessage(STR_MSSG_DOSUBTOTALS_2); // cannot insert rows
749  return false;
750  }
751  }
752  }
753 
754  // execute
755 
757 
758  bool bKeepSub = false; // repeat existing partial results?
759  if (rQueryParam.GetEntry(0).bDoQuery) // not at cancellation
760  {
761  ScSubTotalParam aSubTotalParam;
762  pDBData->GetSubTotalParam( aSubTotalParam ); // partial results exist?
763 
764  if ( aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly )
765  bKeepSub = true;
766  }
767 
768  ScDocumentUniquePtr pUndoDoc;
769  std::unique_ptr<ScDBCollection> pUndoDB;
770  const ScRange* pOld = nullptr;
771 
772  if ( bRecord )
773  {
774  pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
775  if (bCopy)
776  {
777  pUndoDoc->InitUndo( rDoc, nDestTab, nDestTab, false, true );
778  rDoc.CopyToDocument(aLocalParam.nCol1, aLocalParam.nRow1, nDestTab,
779  aLocalParam.nCol2, aLocalParam.nRow2, nDestTab,
780  InsertDeleteFlags::ALL, false, *pUndoDoc);
781  // secure attributes in case they were copied along
782 
783  if (pDestData)
784  {
785  rDoc.CopyToDocument(aOldDest, InsertDeleteFlags::ALL, false, *pUndoDoc);
786  pOld = &aOldDest;
787  }
788  }
789  else
790  {
791  pUndoDoc->InitUndo( rDoc, nTab, nTab, false, true );
792  rDoc.CopyToDocument(0, rQueryParam.nRow1, nTab, rDoc.MaxCol(), rQueryParam.nRow2, nTab,
793  InsertDeleteFlags::NONE, false, *pUndoDoc);
794  }
795 
796  ScDBCollection* pDocDB = rDoc.GetDBCollection();
797  if (!pDocDB->empty())
798  pUndoDB.reset(new ScDBCollection( *pDocDB ));
799 
800  rDoc.BeginDrawUndo();
801  }
802 
803  std::unique_ptr<ScDocument> pAttribDoc;
804  ScRange aAttribRange;
805  if (pDestData) // delete destination range
806  {
807  if ( bKeepFmt )
808  {
809  // smaller of the end columns, header+1 row
810  aAttribRange = aOldDest;
811  if ( aAttribRange.aEnd.Col() > aDestTotal.aEnd.Col() )
812  aAttribRange.aEnd.SetCol( aDestTotal.aEnd.Col() );
813  aAttribRange.aEnd.SetRow( aAttribRange.aStart.Row() +
814  ( aLocalParam.bHasHeader ? 1 : 0 ) );
815 
816  // also for filled-in formulas
817  aAttribRange.aEnd.SetCol( aAttribRange.aEnd.Col() + nFormulaCols );
818 
819  pAttribDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
820  pAttribDoc->InitUndo( rDoc, nDestTab, nDestTab, false, true );
821  rDoc.CopyToDocument(aAttribRange, InsertDeleteFlags::ATTRIB, false, *pAttribDoc);
822  }
823 
824  if ( bDoSize )
825  rDoc.FitBlock( aOldDest, aDestTotal );
826  else
827  rDoc.DeleteAreaTab(aOldDest, InsertDeleteFlags::ALL); // simply delete
828  }
829 
830  // execute filtering on the document
831  SCSIZE nCount = rDoc.Query( nTab, rQueryParam, bKeepSub );
832  pDBData->CalcSaveFilteredCount( nCount );
833  if (bCopy)
834  {
835  aLocalParam.nRow2 = aLocalParam.nRow1 + nCount;
836  if (!aLocalParam.bHasHeader && nCount > 0)
837  --aLocalParam.nRow2;
838 
839  if ( bDoSize )
840  {
841  // adjust to the real result range
842  // (this here is always a reduction)
843 
844  ScRange aNewDest( aLocalParam.nCol1, aLocalParam.nRow1, nDestTab,
845  aLocalParam.nCol2, aLocalParam.nRow2, nDestTab );
846  rDoc.FitBlock( aDestTotal, aNewDest, false ); // sal_False - don't delete
847 
848  if ( nFormulaCols > 0 )
849  {
850  // fill in formulas
852 
853  ScRange aNewForm( aLocalParam.nCol2+1, aLocalParam.nRow1, nDestTab,
854  aLocalParam.nCol2+nFormulaCols, aLocalParam.nRow2, nDestTab );
855  ScRange aOldForm = aNewForm;
856  aOldForm.aEnd.SetRow( aOldDest.aEnd.Row() );
857  rDoc.FitBlock( aOldForm, aNewForm, false );
858 
859  ScMarkData aMark(rDoc.GetSheetLimits());
860  aMark.SelectOneTable(nDestTab);
861  SCROW nFStartY = aLocalParam.nRow1 + ( aLocalParam.bHasHeader ? 1 : 0 );
862 
863  sal_uLong nProgCount = nFormulaCols;
864  nProgCount *= aLocalParam.nRow2 - nFStartY;
865  ScProgress aProgress( rDoc.GetDocumentShell(),
866  ScResId(STR_FILL_SERIES_PROGRESS), nProgCount, true );
867 
868  rDoc.Fill( aLocalParam.nCol2+1, nFStartY,
869  aLocalParam.nCol2+nFormulaCols, nFStartY, &aProgress, aMark,
870  aLocalParam.nRow2 - nFStartY,
872  }
873  }
874 
875  if ( pAttribDoc ) // copy back the memorized attributes
876  {
877  // Header
878  if (aLocalParam.bHasHeader)
879  {
880  ScRange aHdrRange = aAttribRange;
881  aHdrRange.aEnd.SetRow( aHdrRange.aStart.Row() );
882  pAttribDoc->CopyToDocument(aHdrRange, InsertDeleteFlags::ATTRIB, false, rDoc);
883  }
884 
885  // Data
886  SCCOL nAttrEndCol = aAttribRange.aEnd.Col();
887  SCROW nAttrRow = aAttribRange.aStart.Row() + ( aLocalParam.bHasHeader ? 1 : 0 );
888  for (SCCOL nCol = aAttribRange.aStart.Col(); nCol<=nAttrEndCol; nCol++)
889  {
890  const ScPatternAttr* pSrcPattern = pAttribDoc->GetPattern(
891  nCol, nAttrRow, nDestTab );
892  OSL_ENSURE(pSrcPattern,"Pattern is 0");
893  if (pSrcPattern)
894  {
895  rDoc.ApplyPatternAreaTab( nCol, nAttrRow, nCol, aLocalParam.nRow2,
896  nDestTab, *pSrcPattern );
897  const ScStyleSheet* pStyle = pSrcPattern->GetStyleSheet();
898  if (pStyle)
899  rDoc.ApplyStyleAreaTab( nCol, nAttrRow, nCol, aLocalParam.nRow2,
900  nDestTab, *pStyle );
901  }
902  }
903  }
904  }
905 
906  // saving: Inplace always, otherwise depending on setting
907  // old Inplace-Filter may have already been removed
908 
909  bool bSave = rQueryParam.bInplace || rQueryParam.bDestPers;
910  if (bSave) // memorize
911  {
912  pDBData->SetQueryParam( rQueryParam );
913  pDBData->SetHeader( rQueryParam.bHasHeader );
914  pDBData->SetAdvancedQuerySource( pAdvSource ); // after SetQueryParam
915  }
916 
917  if (bCopy) // memorize new DB range
918  {
919  // Selection is done afterwards from outside (dbfunc).
920  // Currently through the DB area at the destination position,
921  // so a range must be created there in any case.
922 
923  ScDBData* pNewData;
924  if (pDestData)
925  pNewData = pDestData; // range exists -> adjust (always!)
926  else // create range
927  pNewData = rDocShell.GetDBData(
928  ScRange( aLocalParam.nCol1, aLocalParam.nRow1, nDestTab,
929  aLocalParam.nCol2, aLocalParam.nRow2, nDestTab ),
931 
932  if (pNewData)
933  {
934  pNewData->SetArea( nDestTab, aLocalParam.nCol1, aLocalParam.nRow1,
935  aLocalParam.nCol2, aLocalParam.nRow2 );
936 
937  // query parameter is no longer set at the destination, only leads to confusion
938  // and mistakes with the query parameter at the source range (#37187#)
939  }
940  else
941  {
942  OSL_FAIL("Target are not available");
943  }
944  }
945 
946  if (!bCopy)
947  {
948  rDoc.InvalidatePageBreaks(nTab);
949  rDoc.UpdatePageBreaks( nTab );
950  }
951 
952  // #i23299# Subtotal functions depend on cell's filtered states.
953  ScRange aDirtyRange(0 , aLocalParam.nRow1, nDestTab, rDoc.MaxCol(), aLocalParam.nRow2, nDestTab);
954  rDoc.SetSubTotalCellsDirty(aDirtyRange);
955 
956  if ( bRecord )
957  {
958  // create undo action after executing, because of drawing layer undo
960  std::make_unique<ScUndoQuery>( &rDocShell, nTab, rQueryParam, std::move(pUndoDoc), std::move(pUndoDB),
961  pOld, bDoSize, pAdvSource ) );
962  }
963 
964  if ( pViewSh )
965  {
966  // could there be horizontal autofilter ?
967  // maybe it would be better to set bColumns to !rQueryParam.bByRow ?
968  // anyway at the beginning the value of bByRow is 'false'
969  // then after the first sort action it becomes 'true'
970  pViewSh->OnLOKShowHideColRow(/*bColumns*/ false, rQueryParam.nRow1 - 1);
971  }
972 
973  if (bCopy)
974  {
975  SCCOL nEndX = aLocalParam.nCol2;
976  SCROW nEndY = aLocalParam.nRow2;
977  if (pDestData)
978  {
979  if ( aOldDest.aEnd.Col() > nEndX )
980  nEndX = aOldDest.aEnd.Col();
981  if ( aOldDest.aEnd.Row() > nEndY )
982  nEndY = aOldDest.aEnd.Row();
983  }
984  if (bDoSize)
985  nEndY = rDoc.MaxRow();
987  ScRange(aLocalParam.nCol1, aLocalParam.nRow1, nDestTab, nEndX, nEndY, nDestTab),
989  }
990  else
992  ScRange(0, rQueryParam.nRow1, nTab, rDoc.MaxCol(), rDoc.MaxRow(), nTab),
994  aModificator.SetDocumentModified();
995 
996  return true;
997 }
998 
1000  bool bRecord, bool bApi )
1001 {
1003  // then stays outside:
1004  // - mark new range (from DBData)
1005  // - SelectionChanged (?)
1006 
1007  bool bDo = !rParam.bRemoveOnly; // sal_False = only delete
1008 
1009  ScDocument& rDoc = rDocShell.GetDocument();
1010  if (bRecord && !rDoc.IsUndoEnabled())
1011  bRecord = false;
1012  ScDBData* pDBData = rDoc.GetDBAtArea( nTab, rParam.nCol1, rParam.nRow1,
1013  rParam.nCol2, rParam.nRow2 );
1014  if (!pDBData)
1015  {
1016  OSL_FAIL( "SubTotals: no DBData" );
1017  return;
1018  }
1019 
1020  ScEditableTester aTester( rDoc, nTab, 0,rParam.nRow1+1, rDoc.MaxCol(),rDoc.MaxRow() );
1021  if (!aTester.IsEditable())
1022  {
1023  if (!bApi)
1024  rDocShell.ErrorMessage(aTester.GetMessageId());
1025  return;
1026  }
1027 
1028  if (rDoc.HasAttrib( rParam.nCol1, rParam.nRow1+1, nTab,
1029  rParam.nCol2, rParam.nRow2, nTab, HasAttrFlags::Merged | HasAttrFlags::Overlapped ))
1030  {
1031  if (!bApi)
1032  rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0); // don't insert into merged
1033  return;
1034  }
1035 
1036  bool bOk = true;
1037  if (rParam.bReplace)
1038  {
1039  if (rDoc.TestRemoveSubTotals( nTab, rParam ))
1040  {
1041  std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(ScDocShell::GetActiveDialogParent(),
1042  VclMessageType::Question,
1043  VclButtonsType::YesNo, ScResId(STR_MSSG_DOSUBTOTALS_1))); // "Delete Data?"
1044  xBox->set_title(ScResId(STR_MSSG_DOSUBTOTALS_0)); // "StarCalc"
1045  bOk = xBox->run() == RET_YES;
1046  }
1047  }
1048 
1049  if (!bOk)
1050  return;
1051 
1053  ScDocShellModificator aModificator( rDocShell );
1054 
1055  ScSubTotalParam aNewParam( rParam ); // end of range is being changed
1056  ScDocumentUniquePtr pUndoDoc;
1057  std::unique_ptr<ScOutlineTable> pUndoTab;
1058  std::unique_ptr<ScRangeName> pUndoRange;
1059  std::unique_ptr<ScDBCollection> pUndoDB;
1060 
1061  if (bRecord) // secure old data
1062  {
1063  bool bOldFilter = bDo && rParam.bDoSort;
1064 
1065  SCTAB nTabCount = rDoc.GetTableCount();
1066  pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
1067  ScOutlineTable* pTable = rDoc.GetOutlineTable( nTab );
1068  if (pTable)
1069  {
1070  pUndoTab.reset(new ScOutlineTable( *pTable ));
1071 
1072  // column/row state
1073  SCCOLROW nOutStartCol, nOutEndCol;
1074  SCCOLROW nOutStartRow, nOutEndRow;
1075  pTable->GetColArray().GetRange( nOutStartCol, nOutEndCol );
1076  pTable->GetRowArray().GetRange( nOutStartRow, nOutEndRow );
1077 
1078  pUndoDoc->InitUndo( rDoc, nTab, nTab, true, true );
1079  rDoc.CopyToDocument(static_cast<SCCOL>(nOutStartCol), 0, nTab, static_cast<SCCOL>(nOutEndCol), rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false, *pUndoDoc);
1080  rDoc.CopyToDocument(0, nOutStartRow, nTab, rDoc.MaxCol(), nOutEndRow, nTab, InsertDeleteFlags::NONE, false, *pUndoDoc);
1081  }
1082  else
1083  pUndoDoc->InitUndo( rDoc, nTab, nTab, false, bOldFilter );
1084 
1085  // secure data range - incl. filtering result
1086  rDoc.CopyToDocument(0, rParam.nRow1+1,nTab, rDoc.MaxCol(),rParam.nRow2,nTab,
1087  InsertDeleteFlags::ALL, false, *pUndoDoc);
1088 
1089  // all formulas because of references
1090  rDoc.CopyToDocument(0, 0, 0, rDoc.MaxCol(),rDoc.MaxRow(),nTabCount-1,
1091  InsertDeleteFlags::FORMULA, false, *pUndoDoc);
1092 
1093  // ranges of DB and other
1094  ScRangeName* pDocRange = rDoc.GetRangeName();
1095  if (!pDocRange->empty())
1096  pUndoRange.reset(new ScRangeName( *pDocRange ));
1097  ScDBCollection* pDocDB = rDoc.GetDBCollection();
1098  if (!pDocDB->empty())
1099  pUndoDB.reset(new ScDBCollection( *pDocDB ));
1100  }
1101 
1102 // rDoc.SetOutlineTable( nTab, NULL );
1103  ScOutlineTable* pOut = rDoc.GetOutlineTable( nTab );
1104  if (pOut)
1105  pOut->GetRowArray().RemoveAll(); // only delete row outlines
1106 
1107  if (rParam.bReplace)
1108  rDoc.RemoveSubTotals( nTab, aNewParam );
1109  bool bSuccess = true;
1110  if (bDo)
1111  {
1112  // sort
1113  if ( rParam.bDoSort )
1114  {
1115  pDBData->SetArea( nTab, aNewParam.nCol1,aNewParam.nRow1, aNewParam.nCol2,aNewParam.nRow2 );
1116 
1117  // set partial result field to before the sorting
1118  // (Duplicates are omitted, so can be called again)
1119 
1120  ScSortParam aOldSort;
1121  pDBData->GetSortParam( aOldSort );
1122  ScSortParam aSortParam( aNewParam, aOldSort );
1123  Sort( nTab, aSortParam, false, false, bApi );
1124  }
1125 
1126  bSuccess = rDoc.DoSubTotals( nTab, aNewParam );
1127  rDoc.SetDrawPageSize(nTab);
1128  }
1129  ScRange aDirtyRange( aNewParam.nCol1, aNewParam.nRow1, nTab,
1130  aNewParam.nCol2, aNewParam.nRow2, nTab );
1131  rDoc.SetDirty( aDirtyRange, true );
1132 
1133  if (bRecord)
1134  {
1135 // ScDBData* pUndoDBData = pDBData ? new ScDBData( *pDBData ) : NULL;
1137  std::make_unique<ScUndoSubTotals>( &rDocShell, nTab,
1138  rParam, aNewParam.nRow2,
1139  std::move(pUndoDoc), std::move(pUndoTab), // pUndoDBData,
1140  std::move(pUndoRange), std::move(pUndoDB) ) );
1141  }
1142 
1143  if (!bSuccess)
1144  {
1145  // "Cannot insert rows"
1146  if (!bApi)
1147  rDocShell.ErrorMessage(STR_MSSG_DOSUBTOTALS_2);
1148  }
1149 
1150  // memorize
1151  pDBData->SetSubTotalParam( aNewParam );
1152  pDBData->SetArea( nTab, aNewParam.nCol1,aNewParam.nRow1, aNewParam.nCol2,aNewParam.nRow2 );
1153  rDoc.CompileDBFormula();
1154 
1155  rDocShell.PostPaint(ScRange(0, 0, nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab),
1157  aModificator.SetDocumentModified();
1158 }
1159 
1160 namespace {
1161 
1162 bool lcl_EmptyExcept( ScDocument& rDoc, const ScRange& rRange, const ScRange& rExcept )
1163 {
1164  ScCellIterator aIter( rDoc, rRange );
1165  for (bool bHasCell = aIter.first(); bHasCell; bHasCell = aIter.next())
1166  {
1167  if (!aIter.isEmpty()) // real content?
1168  {
1169  if (!rExcept.In(aIter.GetPos()))
1170  return false; // cell found
1171  }
1172  }
1173 
1174  return true; // nothing found - empty
1175 }
1176 
1177 bool isEditable(ScDocShell& rDocShell, const ScRangeList& rRanges, bool bApi)
1178 {
1179  ScDocument& rDoc = rDocShell.GetDocument();
1180  if (!rDocShell.IsEditable() || rDoc.GetChangeTrack())
1181  {
1182  // not recorded -> disallow
1183  if (!bApi)
1184  rDocShell.ErrorMessage(STR_PROTECTIONERR);
1185 
1186  return false;
1187  }
1188 
1189  for (size_t i = 0, n = rRanges.size(); i < n; ++i)
1190  {
1191  const ScRange & r = rRanges[i];
1192  ScEditableTester aTester(rDoc, r);
1193  if (!aTester.IsEditable())
1194  {
1195  if (!bApi)
1196  rDocShell.ErrorMessage(aTester.GetMessageId());
1197 
1198  return false;
1199  }
1200  }
1201 
1202  return true;
1203 }
1204 
1205 void createUndoDoc(ScDocumentUniquePtr& pUndoDoc, ScDocument& rDoc, const ScRange& rRange)
1206 {
1207  SCTAB nTab = rRange.aStart.Tab();
1208  pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
1209  pUndoDoc->InitUndo(rDoc, nTab, nTab);
1210  rDoc.CopyToDocument(rRange, InsertDeleteFlags::ALL, false, *pUndoDoc);
1211 }
1212 
1213 bool checkNewOutputRange(ScDPObject& rDPObj, ScDocShell& rDocShell, ScRange& rNewOut, bool bApi)
1214 {
1215  ScDocument& rDoc = rDocShell.GetDocument();
1216 
1217  bool bOverflow = false;
1218  rNewOut = rDPObj.GetNewOutputRange(bOverflow);
1219 
1220  // Test for overlap with source data range.
1221  // TODO: Check with other pivot tables as well.
1222  const ScSheetSourceDesc* pSheetDesc = rDPObj.GetSheetDesc();
1223  if (pSheetDesc && pSheetDesc->GetSourceRange().Intersects(rNewOut))
1224  {
1225  // New output range intersteps with the source data. Move it up to
1226  // where the old range is and see if that works.
1227  ScRange aOldRange = rDPObj.GetOutRange();
1228  SCROW nDiff = aOldRange.aStart.Row() - rNewOut.aStart.Row();
1229  rNewOut.aStart.SetRow(aOldRange.aStart.Row());
1230  rNewOut.aEnd.IncRow(nDiff);
1231  if (!rDoc.ValidRow(rNewOut.aStart.Row()) || !rDoc.ValidRow(rNewOut.aEnd.Row()))
1232  bOverflow = true;
1233  }
1234 
1235  if (bOverflow)
1236  {
1237  if (!bApi)
1238  rDocShell.ErrorMessage(STR_PIVOT_ERROR);
1239 
1240  return false;
1241  }
1242 
1243  ScEditableTester aTester(rDoc, rNewOut);
1244  if (!aTester.IsEditable())
1245  {
1246  // destination area isn't editable
1247  if (!bApi)
1248  rDocShell.ErrorMessage(aTester.GetMessageId());
1249 
1250  return false;
1251  }
1252 
1253  return true;
1254 }
1255 
1256 }
1257 
1258 bool ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewObj,
1259  bool bRecord, bool bApi, bool bAllowMove )
1260 {
1261  if (!pOldObj)
1262  {
1263  if (!pNewObj)
1264  return false;
1265 
1266  return CreatePivotTable(*pNewObj, bRecord, bApi);
1267  }
1268 
1269  if (!pNewObj)
1270  return RemovePivotTable(*pOldObj, bRecord, bApi);
1271 
1272  if (pOldObj == pNewObj)
1273  return UpdatePivotTable(*pOldObj, bRecord, bApi);
1274 
1275  OSL_ASSERT(pOldObj && pNewObj && pOldObj != pNewObj);
1276 
1277  ScDocShellModificator aModificator( rDocShell );
1279 
1280  ScRangeList aRanges;
1281  aRanges.push_back(pOldObj->GetOutRange());
1282  aRanges.push_back(pNewObj->GetOutRange().aStart); // at least one cell in the output position must be editable.
1283  if (!isEditable(rDocShell, aRanges, bApi))
1284  return false;
1285 
1286  ScDocumentUniquePtr pOldUndoDoc;
1287  ScDocumentUniquePtr pNewUndoDoc;
1288 
1289  ScDPObject aUndoDPObj(*pOldObj); // for undo or revert on failure
1290 
1291  ScDocument& rDoc = rDocShell.GetDocument();
1292  if (bRecord && !rDoc.IsUndoEnabled())
1293  bRecord = false;
1294 
1295  if (bRecord)
1296  createUndoDoc(pOldUndoDoc, rDoc, pOldObj->GetOutRange());
1297 
1298  pNewObj->WriteSourceDataTo(*pOldObj); // copy source data
1299 
1300  ScDPSaveData* pData = pNewObj->GetSaveData();
1301  OSL_ENSURE( pData, "no SaveData from living DPObject" );
1302  if (pData)
1303  pOldObj->SetSaveData(*pData); // copy SaveData
1304 
1305  pOldObj->SetAllowMove(bAllowMove);
1306  pOldObj->ReloadGroupTableData();
1307  pOldObj->SyncAllDimensionMembers();
1308  pOldObj->InvalidateData(); // before getting the new output area
1309 
1310  // make sure the table has a name (not set by dialog)
1311  if (pOldObj->GetName().isEmpty())
1312  pOldObj->SetName( rDoc.GetDPCollection()->CreateNewName() );
1313 
1314  ScRange aNewOut;
1315  if (!checkNewOutputRange(*pOldObj, rDocShell, aNewOut, bApi))
1316  {
1317  *pOldObj = aUndoDPObj;
1318  return false;
1319  }
1320 
1321  // test if new output area is empty except for old area
1322  if (!bApi)
1323  {
1324  // OutRange of pOldObj (pDestObj) is still old area
1325  if (!lcl_EmptyExcept(rDoc, aNewOut, pOldObj->GetOutRange()))
1326  {
1327  std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(ScDocShell::GetActiveDialogParent(),
1328  VclMessageType::Question, VclButtonsType::YesNo,
1329  ScResId(STR_PIVOT_NOTEMPTY)));
1330  xQueryBox->set_default_response(RET_YES);
1331  if (xQueryBox->run() == RET_NO)
1332  {
1334  *pOldObj = aUndoDPObj;
1335  return false;
1336  }
1337  }
1338  }
1339 
1340  if (bRecord)
1341  createUndoDoc(pNewUndoDoc, rDoc, aNewOut);
1342 
1343  pOldObj->Output(aNewOut.aStart);
1344  rDocShell.PostPaintGridAll();
1345 
1346  if (bRecord)
1347  {
1348  rDocShell.GetUndoManager()->AddUndoAction(
1349  std::make_unique<ScUndoDataPilot>(
1350  &rDocShell, std::move(pOldUndoDoc), std::move(pNewUndoDoc), &aUndoDPObj, pOldObj, bAllowMove));
1351  }
1352 
1353  // notify API objects
1354  rDoc.BroadcastUno( ScDataPilotModifiedHint(pOldObj->GetName()) );
1355  aModificator.SetDocumentModified();
1356 
1357  return true;
1358 }
1359 
1360 bool ScDBDocFunc::RemovePivotTable(ScDPObject& rDPObj, bool bRecord, bool bApi)
1361 {
1362  ScDocShellModificator aModificator(rDocShell);
1364 
1365  if (!isEditable(rDocShell, rDPObj.GetOutRange(), bApi))
1366  return false;
1367 
1368  ScDocument& rDoc = rDocShell.GetDocument();
1369 
1370  if (!bApi)
1371  {
1372  // If we come from GUI - ask to delete the associated pivot charts too...
1373  std::vector<SdrOle2Obj*> aListOfObjects =
1375 
1376  ScDrawLayer* pModel = rDoc.GetDrawLayer();
1377 
1378  if (pModel && !aListOfObjects.empty())
1379  {
1380  std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(ScDocShell::GetActiveDialogParent(),
1381  VclMessageType::Question, VclButtonsType::YesNo,
1382  ScResId(STR_PIVOT_REMOVE_PIVOTCHART)));
1383  xQueryBox->set_default_response(RET_YES);
1384  if (xQueryBox->run() == RET_NO)
1385  {
1386  return false;
1387  }
1388  else
1389  {
1390  for (SdrOle2Obj* pChartObject : aListOfObjects)
1391  {
1392  rDoc.GetChartListenerCollection()->removeByName(pChartObject->GetName());
1393  pModel->AddUndo(std::make_unique<SdrUndoDelObj>(*pChartObject));
1394  pChartObject->getSdrPageFromSdrObject()->RemoveObject(pChartObject->GetOrdNum());
1395  }
1396  }
1397  }
1398  }
1399 
1400  ScDocumentUniquePtr pOldUndoDoc;
1401  std::unique_ptr<ScDPObject> pUndoDPObj;
1402 
1403  if (bRecord)
1404  pUndoDPObj.reset(new ScDPObject(rDPObj)); // copy old settings for undo
1405 
1406  if (bRecord && !rDoc.IsUndoEnabled())
1407  bRecord = false;
1408 
1409  // delete table
1410 
1411  ScRange aRange = rDPObj.GetOutRange();
1412  SCTAB nTab = aRange.aStart.Tab();
1413 
1414  if (bRecord)
1415  createUndoDoc(pOldUndoDoc, rDoc, aRange);
1416 
1417  rDoc.DeleteAreaTab( aRange.aStart.Col(), aRange.aStart.Row(),
1418  aRange.aEnd.Col(), aRange.aEnd.Row(),
1419  nTab, InsertDeleteFlags::ALL );
1420  rDoc.RemoveFlagsTab( aRange.aStart.Col(), aRange.aStart.Row(),
1421  aRange.aEnd.Col(), aRange.aEnd.Row(),
1422  nTab, ScMF::Auto );
1423 
1424  rDoc.GetDPCollection()->FreeTable(&rDPObj); // object is deleted here
1425 
1426  rDocShell.PostPaintGridAll();
1427  rDocShell.PostPaint(aRange, PaintPartFlags::Grid);
1428 
1429  if (bRecord)
1430  {
1431  rDocShell.GetUndoManager()->AddUndoAction(
1432  std::make_unique<ScUndoDataPilot>(
1433  &rDocShell, std::move(pOldUndoDoc), nullptr, pUndoDPObj.get(), nullptr, false));
1434 
1435  // pUndoDPObj is copied
1436  }
1437 
1438  aModificator.SetDocumentModified();
1439  return true;
1440 }
1441 
1442 bool ScDBDocFunc::CreatePivotTable(const ScDPObject& rDPObj, bool bRecord, bool bApi)
1443 {
1444  ScDocShellModificator aModificator(rDocShell);
1446 
1447  // At least one cell in the output range should be editable. Check in advance.
1448  if (!isEditable(rDocShell, ScRange(rDPObj.GetOutRange().aStart), bApi))
1449  return false;
1450 
1451  ScDocumentUniquePtr pNewUndoDoc;
1452 
1453  ScDocument& rDoc = rDocShell.GetDocument();
1454  if (bRecord && !rDoc.IsUndoEnabled())
1455  bRecord = false;
1456 
1457  // output range must be set at pNewObj
1458  std::unique_ptr<ScDPObject> pDestObj(new ScDPObject(rDPObj));
1459 
1460  ScDPObject& rDestObj = *pDestObj;
1461 
1462  // #i94570# When changing the output position in the dialog, a new table is created
1463  // with the settings from the old table, including the name.
1464  // So we have to check for duplicate names here (before inserting).
1465  if (rDoc.GetDPCollection()->GetByName(rDestObj.GetName()))
1466  rDestObj.SetName(OUString()); // ignore the invalid name, create a new name below
1467 
1468  // Synchronize groups between linked tables
1469  {
1470  const ScDPDimensionSaveData* pGroups = nullptr;
1471  bool bRefFound = rDoc.GetDPCollection()->GetReferenceGroups(rDestObj, &pGroups);
1472  if (bRefFound)
1473  {
1474  ScDPSaveData* pSaveData = rDestObj.GetSaveData();
1475  if (pSaveData)
1476  pSaveData->SetDimensionData(pGroups);
1477  }
1478  }
1479 
1480  rDoc.GetDPCollection()->InsertNewTable(std::move(pDestObj));
1481 
1482  rDestObj.ReloadGroupTableData();
1483  rDestObj.SyncAllDimensionMembers();
1484  rDestObj.InvalidateData(); // before getting the new output area
1485 
1486  // make sure the table has a name (not set by dialog)
1487  if (rDestObj.GetName().isEmpty())
1488  rDestObj.SetName(rDoc.GetDPCollection()->CreateNewName());
1489 
1490  bool bOverflow = false;
1491  ScRange aNewOut = rDestObj.GetNewOutputRange(bOverflow);
1492 
1493  if (bOverflow)
1494  {
1495  if (!bApi)
1496  rDocShell.ErrorMessage(STR_PIVOT_ERROR);
1497 
1498  return false;
1499  }
1500 
1501  {
1502  ScEditableTester aTester(rDoc, aNewOut);
1503  if (!aTester.IsEditable())
1504  {
1505  // destination area isn't editable
1506  if (!bApi)
1507  rDocShell.ErrorMessage(aTester.GetMessageId());
1508 
1509  return false;
1510  }
1511  }
1512 
1513  // test if new output area is empty except for old area
1514  if (!bApi)
1515  {
1516  bool bEmpty = rDoc.IsBlockEmpty(
1517  aNewOut.aStart.Tab(), aNewOut.aStart.Col(), aNewOut.aStart.Row(),
1518  aNewOut.aEnd.Col(), aNewOut.aEnd.Row());
1519 
1520  if (!bEmpty)
1521  {
1522  std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(ScDocShell::GetActiveDialogParent(),
1523  VclMessageType::Question, VclButtonsType::YesNo,
1524  ScResId(STR_PIVOT_NOTEMPTY)));
1525  xQueryBox->set_default_response(RET_YES);
1526  if (xQueryBox->run() == RET_NO)
1527  {
1529  return false;
1530  }
1531  }
1532  }
1533 
1534  if (bRecord)
1535  createUndoDoc(pNewUndoDoc, rDoc, aNewOut);
1536 
1537  rDestObj.Output(aNewOut.aStart);
1538  rDocShell.PostPaintGridAll();
1539 
1540  if (bRecord)
1541  {
1542  rDocShell.GetUndoManager()->AddUndoAction(
1543  std::make_unique<ScUndoDataPilot>(&rDocShell, nullptr, std::move(pNewUndoDoc), nullptr, &rDestObj, false));
1544  }
1545 
1546  // notify API objects
1547  rDoc.BroadcastUno(ScDataPilotModifiedHint(rDestObj.GetName()));
1548  aModificator.SetDocumentModified();
1549 
1550  return true;
1551 }
1552 
1553 bool ScDBDocFunc::UpdatePivotTable(ScDPObject& rDPObj, bool bRecord, bool bApi)
1554 {
1555  ScDocShellModificator aModificator( rDocShell );
1557 
1558  if (!isEditable(rDocShell, rDPObj.GetOutRange(), bApi))
1559  return false;
1560 
1561  ScDocumentUniquePtr pOldUndoDoc;
1562  ScDocumentUniquePtr pNewUndoDoc;
1563 
1564  ScDPObject aUndoDPObj(rDPObj); // For undo or revert on failure.
1565 
1566  ScDocument& rDoc = rDocShell.GetDocument();
1567  if (bRecord && !rDoc.IsUndoEnabled())
1568  bRecord = false;
1569 
1570  if (bRecord)
1571  createUndoDoc(pOldUndoDoc, rDoc, rDPObj.GetOutRange());
1572 
1573  rDPObj.SetAllowMove(false);
1574  rDPObj.ReloadGroupTableData();
1575  if (!rDPObj.SyncAllDimensionMembers())
1576  return false;
1577 
1578  rDPObj.InvalidateData(); // before getting the new output area
1579 
1580  // make sure the table has a name (not set by dialog)
1581  if (rDPObj.GetName().isEmpty())
1582  rDPObj.SetName( rDoc.GetDPCollection()->CreateNewName() );
1583 
1584  ScRange aNewOut;
1585  if (!checkNewOutputRange(rDPObj, rDocShell, aNewOut, bApi))
1586  {
1587  rDPObj = aUndoDPObj;
1588  return false;
1589  }
1590 
1591  // test if new output area is empty except for old area
1592  if (!bApi)
1593  {
1594  if (!lcl_EmptyExcept(rDoc, aNewOut, rDPObj.GetOutRange()))
1595  {
1596  std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(ScDocShell::GetActiveDialogParent(),
1597  VclMessageType::Question, VclButtonsType::YesNo,
1598  ScResId(STR_PIVOT_NOTEMPTY)));
1599  xQueryBox->set_default_response(RET_YES);
1600  if (xQueryBox->run() == RET_NO)
1601  {
1602  rDPObj = aUndoDPObj;
1603  return false;
1604  }
1605  }
1606  }
1607 
1608  if (bRecord)
1609  createUndoDoc(pNewUndoDoc, rDoc, aNewOut);
1610 
1611  rDPObj.Output(aNewOut.aStart);
1612  rDocShell.PostPaintGridAll();
1613 
1614  if (bRecord)
1615  {
1616  rDocShell.GetUndoManager()->AddUndoAction(
1617  std::make_unique<ScUndoDataPilot>(
1618  &rDocShell, std::move(pOldUndoDoc), std::move(pNewUndoDoc), &aUndoDPObj, &rDPObj, false));
1619  }
1620 
1621  // notify API objects
1622  rDoc.BroadcastUno( ScDataPilotModifiedHint(rDPObj.GetName()) );
1623  aModificator.SetDocumentModified();
1624  return true;
1625 }
1626 
1627 void ScDBDocFunc::RefreshPivotTables(const ScDPObject* pDPObj, bool bApi)
1628 {
1629  ScDPCollection* pDPs = rDocShell.GetDocument().GetDPCollection();
1630  if (!pDPs)
1631  return;
1632 
1634  const char* pErrId = pDPs->ReloadCache(pDPObj, aRefs);
1635  if (pErrId)
1636  return;
1637 
1638  for (ScDPObject* pObj : aRefs)
1639  {
1640  // This action is intentionally not undoable since it modifies cache.
1641  UpdatePivotTable(*pObj, false, bApi);
1642  }
1643 }
1644 
1646 {
1647  if (!pDPObj)
1648  return;
1649 
1650  ScDPCollection* pDPs = rDocShell.GetDocument().GetDPCollection();
1651  if (!pDPs)
1652  return;
1653 
1654  ScDPSaveData* pSaveData = pDPObj->GetSaveData();
1655  if (!pSaveData)
1656  return;
1657 
1658  if (!pDPs->HasTable(pDPObj))
1659  {
1660  // This table is under construction so no need for a whole update (UpdatePivotTable()).
1661  pDPObj->ReloadGroupTableData();
1662  return;
1663  }
1664 
1665  // Update all linked tables, if this table is part of the cache (ScDPCollection)
1667  if (!pDPs->ReloadGroupsInCache(pDPObj, aRefs))
1668  return;
1669 
1670  // We allow pDimData being NULL.
1671  const ScDPDimensionSaveData* pDimData = pSaveData->GetExistingDimensionData();
1672  for (ScDPObject* pObj : aRefs)
1673  {
1674  if (pObj != pDPObj)
1675  {
1676  pSaveData = pObj->GetSaveData();
1677  if (pSaveData)
1678  pSaveData->SetDimensionData(pDimData);
1679  }
1680 
1681  // This action is intentionally not undoable since it modifies cache.
1682  UpdatePivotTable(*pObj, false, false);
1683  }
1684 }
1685 
1686 // database import
1687 
1688 void ScDBDocFunc::UpdateImport( const OUString& rTarget, const svx::ODataAccessDescriptor& rDescriptor )
1689 {
1690  // rTarget is the name of a database range
1691 
1692  ScDocument& rDoc = rDocShell.GetDocument();
1693  ScDBCollection& rDBColl = *rDoc.GetDBCollection();
1694  const ScDBData* pData = rDBColl.getNamedDBs().findByUpperName(ScGlobal::getCharClassPtr()->uppercase(rTarget));
1695  if (!pData)
1696  {
1697  std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(ScDocShell::GetActiveDialogParent(),
1698  VclMessageType::Info, VclButtonsType::Ok,
1699  ScResId(STR_TARGETNOTFOUND)));
1700  xInfoBox->run();
1701  return;
1702  }
1703 
1704  SCTAB nTab;
1705  SCCOL nDummyCol;
1706  SCROW nDummyRow;
1707  pData->GetArea( nTab, nDummyCol,nDummyRow,nDummyCol,nDummyRow );
1708 
1709  ScImportParam aImportParam;
1710  pData->GetImportParam( aImportParam );
1711 
1712  OUString sDBName;
1713  OUString sDBTable;
1714  sal_Int32 nCommandType = 0;
1715  sDBName = rDescriptor.getDataSource();
1716  rDescriptor[svx::DataAccessDescriptorProperty::Command] >>= sDBTable;
1717  rDescriptor[svx::DataAccessDescriptorProperty::CommandType] >>= nCommandType;
1718 
1719  aImportParam.aDBName = sDBName;
1720  aImportParam.bSql = ( nCommandType == sdb::CommandType::COMMAND );
1721  aImportParam.aStatement = sDBTable;
1722  aImportParam.bNative = false;
1723  aImportParam.nType = static_cast<sal_uInt8>( ( nCommandType == sdb::CommandType::QUERY ) ? ScDbQuery : ScDbTable );
1724  aImportParam.bImport = true;
1725 
1726  bool bContinue = DoImport( nTab, aImportParam, &rDescriptor );
1727 
1728  // repeat DB operations
1729 
1730  ScTabViewShell* pViewSh = rDocShell.GetBestViewShell();
1731  if (!pViewSh)
1732  return;
1733 
1734  ScRange aRange;
1735  pData->GetArea(aRange);
1736  pViewSh->MarkRange(aRange); // select
1737 
1738  if ( bContinue ) // error at import -> abort
1739  {
1740  // internal operations, if some are saved
1741 
1742  if ( pData->HasQueryParam() || pData->HasSortParam() || pData->HasSubTotalParam() )
1743  pViewSh->RepeatDB();
1744 
1745  // pivot tables which have the range as source data
1746 
1747  rDocShell.RefreshPivotTables(aRange);
1748  }
1749 }
1750 
1751 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::std::vector< ScSortKeyState > maKeyState
Definition: sortparam.hxx:61
bool bGroupActive[MAXSUBTOTAL]
active groups
void BeginDrawUndo()
Definition: documen9.cxx:58
const ScDPDimensionSaveData * GetExistingDimensionData() const
Definition: dpsave.hxx:349
SCROW nRow1
Definition: sortparam.hxx:44
bool CanFitBlock(const ScRange &rOld, const ScRange &rNew)
Definition: document.cxx:1829
void UpdatePageBreaks(SCTAB nTab, const ScRange *pUserArea=nullptr)
Definition: document.cxx:6214
bool insert(std::unique_ptr< ScDBData > p)
Takes ownership of p and attempts to insert it into the collection.
Definition: dbdata.cxx:1157
SC_DLLPUBLIC void ApplyStyleAreaTab(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, const ScStyleSheet &rStyle)
Definition: document.cxx:4849
void ReloadGroupTableData()
Definition: dpobject.cxx:810
void FitBlock(const ScRange &rOld, const ScRange &rNew, bool bClear=true)
Definition: document.cxx:1860
SC_DLLPUBLIC bool HasQueryParam() const
Definition: dbdata.cxx:509
SC_DLLPUBLIC ScDBCollection * GetDBCollection() const
Definition: document.hxx:813
ScAddress aStart
Definition: address.hxx:500
todo: It should be possible to have MarkArrays for each table, in order to enable "search all" across...
Definition: markdata.hxx:43
This class has to do with handling exclusively grouped dimensions? TODO: Find out what this class doe...
Definition: dpdimsave.hxx:164
SCCOL nCol2
Definition: sortparam.hxx:45
SCCOL nCol1
selected area
SC_DLLPUBLIC ScDBData * GetAnonymousDBData(SCTAB nTab)
Definition: document.cxx:305
SC_DLLPUBLIC void SetSortParam(const ScSortParam &rSortParam)
Definition: dbdata.cxx:398
SCROW Row() const
Definition: address.hxx:262
void PostPaintGridAll()
Definition: docsh3.cxx:180
bool AdjustRowHeight(SCROW nStartRow, SCROW nEndRow, SCTAB nTab)
merge with docfunc
Definition: docsh5.cxx:404
void WriteSourceDataTo(ScDPObject &rDest) const
Definition: dpobject.cxx:464
SCSIZE Query(SCTAB nTab, const ScQueryParam &rQueryParam, bool bKeepSub)
Definition: documen3.cxx:1445
OUString aDBName
Definition: global.hxx:457
std::unique_ptr< ContentProperties > pData
static weld::Window * GetActiveDialogParent()
Definition: docsh.cxx:2950
SCCOL nDestCol
Definition: sortparam.hxx:58
bool bIncludeComments
Definition: sortparam.hxx:52
SC_DLLPUBLIC void GetSortParam(ScSortParam &rSortParam) const
Definition: dbdata.cxx:386
SC_DLLPUBLIC void SetAnonymousDBData(SCTAB nTab, std::unique_ptr< ScDBData > pDBData)
Definition: document.cxx:317
void MarkRange(const ScRange &rRange, bool bSetCursor=true, bool bContinue=false)
Definition: tabview3.cxx:1683
SC_DLLPUBLIC void SetDrawPageSize(SCTAB nTab)
Definition: documen9.cxx:193
SC_DLLPUBLIC bool Intersects(const ScRange &rRange) const
Definition: address.cxx:1558
SC_DLLPUBLIC bool GetReferenceGroups(const ScDPObject &rDPObj, const ScDPDimensionSaveData **pGroups) const
Definition: dpobject.cxx:3523
sal_uIntPtr sal_uLong
SC_DLLPUBLIC void CompileHybridFormula()
Call this immediately after updating named ranges.
Definition: document10.cxx:315
#define STR_DB_LOCAL_NONAME
Definition: globalnames.hxx:13
void InvalidateData()
Definition: dpobject.cxx:785
SC_DLLPUBLIC ScRangeName * GetRangeName(SCTAB nTab) const
Definition: documen3.cxx:167
sal_Int64 n
SC_DLLPUBLIC ScDPCollection * GetDPCollection()
Definition: documen3.cxx:359
ViewShellDocId GetDocId() const override
bool DoImport(SCTAB nTab, const ScImportParam &rParam, const svx::ODataAccessDescriptor *pDescriptor)
Definition: dbdocimp.cxx:121
void RefreshPivotTables(const ScRange &rSource)
Definition: docsh5.cxx:472
void RemoveAll()
Definition: olinetab.cxx:716
SC_DLLPUBLIC const ScDBData * GetDBAtArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const
Definition: documen3.cxx:332
void SetAllowMove(bool bSet)
Definition: dpobject.cxx:381
ScAddress aEnd
Definition: address.hxx:501
bool bDoSort
presort
bool GetSortRefUpdate() const
Definition: inputopt.hxx:60
bool HasSubTotalParam() const
Definition: dbdata.cxx:527
ScDBData * GetDBData(const ScRange &rMarked, ScGetDBMode eMode, ScGetDBSelection eSel)
Definition: docsh5.cxx:114
bool DoSubTotals(SCTAB nTab, ScSubTotalParam &rParam)
Definition: documen3.cxx:771
SC_DLLPUBLIC void Fill(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScProgress *pProgress, const ScMarkData &rMark, sal_uLong nFillCount, FillDir eFillDir=FILL_TO_BOTTOM, FillCmd eFillCmd=FILL_LINEAR, FillDateCmd eFillDateCmd=FILL_DAY, double nStepValue=1.0, double nMaxValue=1E307)
Definition: documen3.cxx:1147
SC_DLLPUBLIC bool HasAttrib(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, HasAttrFlags nMask) const
Definition: document.cxx:5172
ScDPObject * GetByName(std::u16string_view rName) const
Definition: dpobject.cxx:3692
bool has(const ScDBData *p) const
Definition: dbdata.cxx:1266
bool IsDoSize() const
Definition: dbdata.hxx:136
static void notifyAllViewsSheetGeomInvalidation(const SfxViewShell *pForViewShell, bool bColumns, bool bRows, bool bSizes, bool bHidden, bool bFiltered, bool bGroups, SCTAB nCurrentTabIndex)
Emits a LOK_CALLBACK_INVALIDATE_SHEET_GEOMETRY for all views whose current tab is equal to nCurrentTa...
Definition: tabvwshc.cxx:559
SfxApplication * SfxGetpApp()
Internal use only (d&d undo): do not delete caption objects of cell notes.
bool UpdatePivotTable(ScDPObject &rDPObj, bool bRecord, bool bApi)
Definition: dbdocfun.cxx:1553
void Sort(SCTAB nTab, const ScSortParam &rSortParam, bool bKeepQuery, bool bUpdateRefs, ScProgress *pProgress, sc::ReorderParam *pUndo)
Sort a range of data.
Definition: documen3.cxx:1420
virtual SfxUndoManager * GetUndoManager() override
Definition: docsh.cxx:2806
RET_NO
OUString CreateNewName() const
Create a new name that's not yet used by any existing data pilot objects.
Definition: dpobject.cxx:3703
SCROW nRow2
Definition: sortparam.hxx:46
RET_YES
bool RepeatDB(const OUString &rDBName, bool bApi, bool bIsUnnamed, SCTAB aTab=0)
Definition: dbdocfun.cxx:282
void RefreshPivotTables(const ScDPObject *pDPObj, bool bApi)
Reload the referenced pivot cache, and refresh all pivot tables that reference the cache...
Definition: dbdocfun.cxx:1627
const ScRange & GetOutRange() const
Definition: dpobject.cxx:409
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:870
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:45
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:24
SC_DLLPUBLIC SCTAB GetTableCount() const
Definition: document.cxx:312
AnonDBs & getAnonDBs()
Definition: dbdata.hxx:318
bool empty() const
Definition: rangenam.cxx:802
int nCount
static SfxViewShell * GetNext(const SfxViewShell &rPrev, bool bOnlyVisible=true, const std::function< bool(const SfxViewShell *)> &isViewShell=nullptr)
SC_DLLPUBLIC SCSIZE GetEntryCount() const
Definition: queryparam.cxx:119
void CopyToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, InsertDeleteFlags nFlags, bool bMarked, ScDocument &rDestDoc, const ScMarkData *pMarks=nullptr, bool bColRowFlags=true)
Definition: document.cxx:2074
oslFileHandle & pOut
void push_back(const ScRange &rRange)
Definition: rangelst.cxx:1142
SC_DLLPUBLIC const ScQueryEntry & GetEntry(SCSIZE n) const
Definition: queryparam.cxx:124
void UpdateScriptTypes(const ScAddress &rPos, SCCOL nColSize, SCROW nRowSize)
Definition: document10.cxx:333
Walk through all cells in an area.
Definition: dociter.hxx:208
bool SyncAllDimensionMembers()
Remove in the save data entries for members that don't exist anymore.
Definition: dpobject.cxx:974
SCTAB Tab() const
Definition: address.hxx:271
SC_DLLPUBLIC void SetQueryParam(const ScQueryParam &rQueryParam)
Definition: dbdata.cxx:422
bool ReloadGroupsInCache(const ScDPObject *pDPObj, o3tl::sorted_vector< ScDPObject * > &rRefs)
Definition: dpobject.cxx:3435
void SetRow(SCROW nRowP)
Definition: address.hxx:275
SC_DLLPUBLIC const ScRange & GetSourceRange() const
Get the range that contains the source data.
Definition: dpshttab.cxx:229
bool DeleteDBRange(const OUString &rName)
Definition: dbdocfun.cxx:117
bool bIncludeGraphicObjects
Definition: sortparam.hxx:53
void Output(const ScAddress &rPos)
Definition: dpobject.cxx:888
void SetCol(SCCOL nColP)
Definition: address.hxx:279
ScViewData & GetViewData()
Definition: tabview.hxx:334
ScChangeTrack * GetChangeTrack() const
Definition: document.hxx:2389
void GetRange(SCCOLROW &rStart, SCCOLROW &rEnd) const
Definition: olinetab.cxx:569
create "untitled" (if necessary)
Definition: global.hxx:394
SCCOL nCol1
Definition: sortparam.hxx:43
void SetName(const OUString &rNew)
Definition: dpobject.cxx:489
void SetArea(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
Definition: dbdata.cxx:322
const char * GetMessageId() const
Definition: editable.cxx:152
void CalcSaveFilteredCount(SCSIZE nNonFilteredRowCount)
Definition: dbdata.cxx:926
OUString aStatement
Definition: global.hxx:458
SC_DLLPUBLIC ScDrawLayer * GetDrawLayer()
Definition: document.hxx:1056
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:869
void RepeatDB(bool bRecord=true)
Definition: dbfunc3.cxx:2113
bool ShrinkToUsedDataArea(bool &o_bShrunk, SCTAB nTab, SCCOL &rStartCol, SCROW &rStartRow, SCCOL &rEndCol, SCROW &rEndRow, bool bColumnsOnly, bool bStickyTopRow=false, bool bStickyLeftCol=false, bool bConsiderCellNotes=false, bool bConsiderCellDrawObjects=false) const
Shrink a range to only include used data area.
Definition: document.cxx:1069
virtual void AddUndoAction(std::unique_ptr< SfxUndoAction > pAction, bool bTryMerg=false)
void InvalidatePageBreaks(SCTAB nTab)
Definition: document.cxx:6208
void SetDBCollection(std::unique_ptr< ScDBCollection > pNewDBCollection, bool bRemoveAutoFilter=false)
Definition: documen3.cxx:269
bool IsImportingXML() const
Definition: document.hxx:2134
void DBAreaDeleted(SCTAB nTab, SCCOL nX1, SCROW nY1, SCCOL nX2)
Definition: docsh5.cxx:103
SC_DLLPUBLIC void SetDimensionData(const ScDPDimensionSaveData *pNew)
Definition: dpsave.cxx:1202
int i
bool HasUniformRowHeight(SCTAB nTab, SCROW nRow1, SCROW nRow2) const
Definition: document10.cxx:342
void UpdateFromSortParam(const ScSortParam &rSortParam)
Remember some more settings of ScSortParam, only to be called at anonymous DB ranges as it at least o...
Definition: dbdata.cxx:404
bool empty() const
Definition: dbdata.cxx:1494
bool RenameDBRange(const OUString &rOld, const OUString &rNew)
Definition: dbdocfun.cxx:153
void invalidateByIndex(index_type nIndex)
Definition: viewdata.cxx:157
std::unique_ptr< ScDocument, o3tl::default_delete< ScDocument > > ScDocumentUniquePtr
Definition: document.hxx:2610
const ScOutlineArray & GetRowArray() const
Definition: olinetab.hxx:161
sal_Int16 SCCOL
Definition: types.hxx:22
const ScOutlineArray & GetColArray() const
Definition: olinetab.hxx:159
bool DataPilotUpdate(ScDPObject *pOldObj, const ScDPObject *pNewObj, bool bRecord, bool bApi, bool bAllowMove=false)
Definition: dbdocfun.cxx:1258
void OnLOKShowHideColRow(bool bColumns, SCCOLROW nStartRow)
Definition: dbfunc3.cxx:2278
#define SC_MOD()
Definition: scmod.hxx:250
bool HasSortParam() const
Definition: dbdata.cxx:520
void SetSaveData(const ScDPSaveData &rData)
Definition: dpobject.cxx:386
SC_DLLPUBLIC void SetAdvancedQuerySource(const ScRange *pSource)
Definition: dbdata.cxx:431
ScSheetLimits & GetSheetLimits() const
Definition: document.hxx:871
const ScStyleSheet * GetStyleSheet() const
Definition: patattr.hxx:127
const OUString & GetName() const
Definition: dpobject.hxx:167
size_t size() const
Definition: rangelst.hxx:90
bool bNative
Definition: global.hxx:459
void IncRow(SCROW nDelta=1)
Definition: address.hxx:300
void SelectOneTable(SCTAB nTab)
Definition: markdata.cxx:189
OUString ScResId(const char *pId)
Definition: scdll.cxx:89
const OUString & GetName() const
Definition: dbdata.hxx:122
void GetImportParam(ScImportParam &rImportParam) const
Definition: dbdata.cxx:465
bool IsKeepFmt() const
Definition: dbdata.hxx:138
SC_DLLPUBLIC void ApplyPatternAreaTab(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, const ScPatternAttr &rAttr)
Definition: document.cxx:4784
void removeByName(const OUString &rName)
Definition: chartlis.cxx:395
ScDPSaveData * GetSaveData() const
Definition: dpobject.hxx:141
void BroadcastUno(const SfxHint &rHint)
Definition: documen3.cxx:943
SC_DLLPUBLIC ScDPObject * InsertNewTable(std::unique_ptr< ScDPObject > pDPObj)
Definition: dpobject.cxx:3731
void SetSubTotalCellsDirty(const ScRange &rDirtyRange)
Definition: document.cxx:6417
bool IsEditable() const
Definition: editable.hxx:84
bool IsBlockEmpty(SCTAB nTab, SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, bool bIgnoreNotes=false) const
Definition: document.cxx:5289
bool IsEditable() const
Definition: docsh5.cxx:95
bool In(const ScAddress &) const
is Address& in Range?
Definition: address.hxx:733
const SCTAB MAXTAB
Definition: address.hxx:71
static SfxViewShell * GetFirst(bool bOnlyVisible=true, const std::function< bool(const SfxViewShell *)> &isViewShell=nullptr)
void PostPaint(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, sal_uInt16 nExtFlags=0)
Definition: docsh3.cxx:98
void GetArea(SCTAB &rTab, SCCOL &rCol1, SCROW &rRow1, SCCOL &rCol2, SCROW &rRow2) const
Definition: dbdata.cxx:300
void SetHeader(bool bHasH)
Definition: dbdata.hxx:131
void CompileDBFormula()
Definition: documen4.cxx:556
SCCOL Col() const
Definition: address.hxx:267
void GetSubTotalParam(ScSubTotalParam &rSubTotalParam) const
Definition: dbdata.cxx:448
const char * ReloadCache(const ScDPObject *pDPObj, o3tl::sorted_vector< ScDPObject * > &rRefs)
Definition: dpobject.cxx:3371
ScDBData * findByUpperName(const OUString &rName)
Definition: dbdata.cxx:1144
void RemoveSubTotals(SCTAB nTab, ScSubTotalParam &rParam)
Definition: documen3.cxx:765
SC_DLLPUBLIC bool Query(SCTAB nTab, const ScQueryParam &rQueryParam, const ScRange *pAdvSource, bool bRecord, bool bApi)
Definition: dbdocfun.cxx:643
top left cell of area
OUString getDataSource() const
ScDocShell & rDocShell
Definition: dbdocfun.hxx:49
bool bReplace
replace existing results
bool ValidColRow(SCCOL nCol, SCROW nRow) const
Definition: document.hxx:874
std::vector< SdrOle2Obj * > getAllPivotChartsConnectedTo(std::u16string_view sPivotTableName, ScDocShell *pDocShell)
Definition: ChartTools.cxx:142
Stores global named database ranges.
Definition: dbdata.hxx:235
Behave as if the range corresponding to a ScDBData area was selected, for API use.
sal_Int32 SCROW
Definition: types.hxx:18
bool RemovePivotTable(ScDPObject &rDPObj, bool bRecord, bool bApi)
Definition: dbdocfun.cxx:1360
void erase(const iterator &itr)
Definition: dbdata.cxx:1180
SC_DLLPUBLIC bool Sort(SCTAB nTab, const ScSortParam &rSortParam, bool bRecord, bool bPaint, bool bApi)
Definition: dbdocfun.cxx:465
void SetDirty(const ScRange &, bool bIncludeEmptyCells)
Definition: document.cxx:3855
bool ValidRow(SCROW nRow) const
Definition: document.hxx:873
bool bInplace
Definition: sortparam.hxx:56
void DoSubTotals(SCTAB nTab, const ScSubTotalParam &rParam, bool bRecord, bool bApi)
Definition: dbdocfun.cxx:999
bool bHasHeader
Definition: sortparam.hxx:48
SC_DLLPUBLIC bool HasTable(const ScDPObject *pDPObj) const
Definition: dpobject.cxx:3742
sal_uInt8 nType
Definition: global.hxx:461
const OUString & GetUpperName() const
Definition: dbdata.hxx:123
unsigned char sal_uInt8
void ErrorMessage(const char *pGlobStrId)
Definition: docsh5.cxx:70
sal_uInt16 GetSortKeyCount() const
Definition: sortparam.hxx:79
SC_DLLPUBLIC bool RemoveFlagsTab(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab, ScMF nFlags)
Definition: document.cxx:5016
void ModifyAllDBData(const ScDBCollection &rNewColl, const std::vector< ScRange > &rDelAreaList)
Definition: dbdocfun.cxx:244
const ScSheetSourceDesc * GetSheetDesc() const
Definition: dpobject.hxx:156
SC_DLLPUBLIC ScOutlineTable * GetOutlineTable(SCTAB nTab, bool bCreate=false)
Definition: documen3.cxx:730
static SC_DLLPUBLIC const CharClass * getCharClassPtr()
Definition: global.cxx:1009
SC_DLLPUBLIC ScChartListenerCollection * GetChartListenerCollection() const
Definition: document.hxx:2140
const ScDocument & GetDocument() const
Definition: docsh.hxx:217
SC_DLLPUBLIC void PreprocessDBDataUpdate()
Definition: document10.cxx:303
SC_DLLPUBLIC void GetQueryParam(ScQueryParam &rQueryParam) const
Definition: dbdata.cxx:409
bool TestRemoveSubTotals(SCTAB nTab, const ScSubTotalParam &rParam)
Definition: documen3.cxx:760
bool bImport
Definition: global.hxx:456
NamedDBs & getNamedDBs()
Definition: dbdata.hxx:315
static bool isAnyEditViewInRange(const SfxViewShell *pForViewShell, bool bColumns, SCCOLROW nStart, SCCOLROW nEnd)
Definition: tabvwshc.cxx:534
void MoveToDest()
Definition: sortparam.cxx:225
iterator findByUpperName2(const OUString &rName)
Definition: dbdata.cxx:1151
void SetDocumentModified()
Definition: docsh.cxx:3159
void UpdateImport(const OUString &rTarget, const svx::ODataAccessDescriptor &rDescriptor)
Definition: dbdocfun.cxx:1688
void MoveToDest()
Definition: queryparam.cxx:398
void SetSubTotalParam(const ScSubTotalParam &rSubTotalParam)
Definition: dbdata.cxx:460
SfxObjectShell * GetDocumentShell() const
Definition: document.hxx:1055
void ModifyDBData(const ScDBData &rNewData)
Definition: dbdocfun.cxx:200
SC_DLLPUBLIC bool GetAdvancedQuerySource(ScRange &rSource) const
Definition: dbdata.cxx:442
SCROW nDestRow
Definition: sortparam.hxx:59
bool IsUndoEnabled() const
Definition: document.hxx:1528
ScDocFunc & GetDocFunc()
Definition: docsh.hxx:219
ScTabViewShell * GetBestViewShell(bool bOnlyVisible=true)
Definition: docsh4.cxx:2565
bool MoveBlock(const ScRange &rSource, const ScAddress &rDestPos, bool bCut, bool bRecord, bool bPaint, bool bApi)
Definition: docfunc.cxx:2843
ScPositionHelper & GetLOKHeightHelper()
Definition: viewdata.hxx:411
const ScDBData * GetDBAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab, ScDBDataPortion ePortion) const
Definition: documen3.cxx:316
bool bIncludePattern
Definition: sortparam.hxx:55
PaintPartFlags
Definition: global.hxx:121
void RefreshPivotTableGroups(ScDPObject *pDPObj)
Refresh the group dimensions of all pivot tables referencing the same cache.
Definition: dbdocfun.cxx:1645
SC_DLLPUBLIC void DeleteAreaTab(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, InsertDeleteFlags nDelFlag)
Definition: document.cxx:1953
bool AddDBRange(const OUString &rName, const ScRange &rRange)
Definition: dbdocfun.cxx:64
ScRange GetNewOutputRange(bool &rOverflow)
Definition: dpobject.cxx:874
This class contains authoritative information on the internal reference used as the data source for d...
Definition: dpshttab.hxx:39
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, bool bMobile=false)
Create before modifications of the document and destroy thereafter.
Definition: docsh.hxx:452
SC_DLLPUBLIC void GetCellType(SCCOL nCol, SCROW nRow, SCTAB nTab, CellType &rCellType) const
Definition: document.cxx:3745
sal_Int16 SCTAB
Definition: types.hxx:23
void FreeTable(const ScDPObject *pDPObj)
Definition: dpobject.cxx:3716
bool CreatePivotTable(const ScDPObject &rDPObj, bool bRecord, bool bApi)
Definition: dbdocfun.cxx:1442
SCTAB nDestTab
Definition: sortparam.hxx:57
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo