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