LibreOffice Module sc (master)  1
olinefun.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/bindings.hxx>
21 
22 #include <olinefun.hxx>
23 
24 #include <docsh.hxx>
25 #include <olinetab.hxx>
26 #include <tabvwsh.hxx>
27 #include <undodat.hxx>
28 #include <globstr.hrc>
29 #include <sc.hrc>
30 
31 #include <comphelper/lok.hxx>
32 
33 
34 static void lcl_InvalidateOutliner( SfxBindings* pBindings )
35 {
36  if ( pBindings )
37  {
38  pBindings->Invalidate( SID_OUTLINE_SHOW );
39  pBindings->Invalidate( SID_OUTLINE_HIDE );
40  pBindings->Invalidate( SID_OUTLINE_REMOVE );
41 
42  pBindings->Invalidate( SID_STATUS_SUM ); // because of enabling/disabling
43  pBindings->Invalidate( SID_ATTR_SIZE );
44  }
45 }
46 
48 
49 static void lcl_PaintWidthHeight( ScDocShell& rDocShell, SCTAB nTab,
50  bool bColumns, SCCOLROW nStart, SCCOLROW nEnd )
51 {
52  ScDocument& rDoc = rDocShell.GetDocument();
53 
55  SCCOL nStartCol = 0;
56  SCROW nStartRow = 0;
57  SCCOL nEndCol = rDoc.MaxCol(); // for testing if merged
58  SCROW nEndRow = rDoc.MaxRow();
59  if ( bColumns )
60  {
61  nParts |= PaintPartFlags::Top;
62  nStartCol = static_cast<SCCOL>(nStart);
63  nEndCol = static_cast<SCCOL>(nEnd);
64  }
65  else
66  {
67  nParts |= PaintPartFlags::Left;
68  nStartRow = nStart;
69  nEndRow = nEnd;
70  }
71  if (rDoc.HasAttrib( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
73  {
74  nStartCol = 0;
75  nStartRow = 0;
76  }
77  rDocShell.PostPaint( nStartCol,nStartRow,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab, nParts );
78 }
79 
80 void ScOutlineDocFunc::MakeOutline( const ScRange& rRange, bool bColumns, bool bRecord, bool bApi )
81 {
82  SCCOL nStartCol = rRange.aStart.Col();
83  SCROW nStartRow = rRange.aStart.Row();
84  SCCOL nEndCol = rRange.aEnd.Col();
85  SCROW nEndRow = rRange.aEnd.Row();
86  SCTAB nTab = rRange.aStart.Tab();
87 
89  ScOutlineTable* pTable = rDoc.GetOutlineTable( nTab, true );
90  std::unique_ptr<ScOutlineTable> pUndoTab;
91 
92  if (bRecord && !rDoc.IsUndoEnabled())
93  bRecord = false;
94 
95  if (bRecord)
96  pUndoTab.reset(new ScOutlineTable( *pTable ));
97 
98  ScOutlineArray& rArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
99 
100  bool bRes;
101  bool bSize = false;
102  if ( bColumns )
103  bRes = rArray.Insert( nStartCol, nEndCol, bSize );
104  else
105  bRes = rArray.Insert( nStartRow, nEndRow, bSize );
106 
107  if ( bRes )
108  {
109  if (bRecord)
110  {
112  std::make_unique<ScUndoMakeOutline>( &rDocShell,
113  nStartCol,nStartRow,nTab,nEndCol,nEndRow,nTab,
114  std::move(pUndoTab), bColumns, true ) );
115  }
116 
117  rDoc.SetStreamValid(nTab, false);
118 
119  PaintPartFlags nParts = PaintPartFlags::NONE; // Data range hasn't been changed
120  if ( bColumns )
121  nParts |= PaintPartFlags::Top;
122  else
123  nParts |= PaintPartFlags::Left;
124  if ( bSize )
125  nParts |= PaintPartFlags::Size;
126 
127  rDocShell.PostPaint( 0,0,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab, nParts );
130  }
131  else
132  {
133  if (!bApi)
134  rDocShell.ErrorMessage(STR_MSSG_MAKEOUTLINE_0); // "Grouping not possible"
135  }
136 }
137 
138 void ScOutlineDocFunc::RemoveOutline( const ScRange& rRange, bool bColumns, bool bRecord, bool bApi )
139 {
140  bool bDone = false;
141 
142  SCCOL nStartCol = rRange.aStart.Col();
143  SCROW nStartRow = rRange.aStart.Row();
144  SCCOL nEndCol = rRange.aEnd.Col();
145  SCROW nEndRow = rRange.aEnd.Row();
146  SCTAB nTab = rRange.aStart.Tab();
147 
148  ScDocument& rDoc = rDocShell.GetDocument();
149 
150  if (bRecord && !rDoc.IsUndoEnabled())
151  bRecord = false;
152  ScOutlineTable* pTable = rDoc.GetOutlineTable( nTab );
153  if (pTable)
154  {
155  std::unique_ptr<ScOutlineTable> pUndoTab;
156  if (bRecord)
157  pUndoTab.reset(new ScOutlineTable( *pTable ));
158 
159  ScOutlineArray& rArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
160 
161  bool bRes;
162  bool bSize = false;
163  if ( bColumns )
164  bRes = rArray.Remove( nStartCol, nEndCol, bSize );
165  else
166  bRes = rArray.Remove( nStartRow, nEndRow, bSize );
167 
168  if ( bRes )
169  {
170  if (bRecord)
171  {
173  std::make_unique<ScUndoMakeOutline>( &rDocShell,
174  nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
175  std::move(pUndoTab), bColumns, false ) );
176  }
177 
178  rDoc.SetStreamValid(nTab, false);
179 
180  PaintPartFlags nParts = PaintPartFlags::NONE; // Data range hasn't been changed
181  if ( bColumns )
182  nParts |= PaintPartFlags::Top;
183  else
184  nParts |= PaintPartFlags::Left;
185  if ( bSize )
186  nParts |= PaintPartFlags::Size;
187 
188  rDocShell.PostPaint( 0,0,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab, nParts );
190  bDone = true;
192 
193  // we are not enabling again -> no UpdatePageBreaks
194  }
195  }
196 
197  if (!bDone && !bApi)
198  rDocShell.ErrorMessage(STR_MSSG_REMOVEOUTLINE_0); // "Ungrouping not possible"
199 }
200 
201 bool ScOutlineDocFunc::RemoveAllOutlines( SCTAB nTab, bool bRecord )
202 {
203  bool bSuccess = false;
204  ScDocument& rDoc = rDocShell.GetDocument();
205 
206  if (bRecord && !rDoc.IsUndoEnabled())
207  bRecord = false;
208  ScOutlineTable* pTable = rDoc.GetOutlineTable( nTab );
209  if (pTable)
210  {
211  if (bRecord)
212  {
213  SCCOLROW nCol1, nCol2, nRow1, nRow2;
214  pTable->GetColArray().GetRange( nCol1, nCol2 );
215  pTable->GetRowArray().GetRange( nRow1, nRow2 );
216  SCCOL nStartCol = static_cast<SCCOL>(nCol1);
217  SCROW nStartRow = nRow1;
218  SCCOL nEndCol = static_cast<SCCOL>(nCol2);
219  SCROW nEndRow = nRow2;
220 
222  pUndoDoc->InitUndo( rDoc, nTab, nTab, true, true );
223  rDoc.CopyToDocument(nStartCol, 0, nTab, nEndCol, rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false, *pUndoDoc);
224  rDoc.CopyToDocument(0, nStartRow, nTab, rDoc.MaxCol(), nEndRow, nTab, InsertDeleteFlags::NONE, false, *pUndoDoc);
225 
226  std::unique_ptr<ScOutlineTable> pUndoTab(new ScOutlineTable( *pTable ));
227 
229  std::make_unique<ScUndoRemoveAllOutlines>( &rDocShell,
230  nStartCol, nStartRow, nTab,
231  nEndCol, nEndRow, nTab,
232  std::move(pUndoDoc), std::move(pUndoTab) ) );
233  }
234 
235  SelectLevel( nTab, true, pTable->GetColArray().GetDepth(), false, false );
236  SelectLevel( nTab, false, pTable->GetRowArray().GetDepth(), false, false );
237  rDoc.SetOutlineTable( nTab, nullptr );
238 
239  rDoc.UpdatePageBreaks( nTab );
240 
241  rDoc.SetStreamValid(nTab, false);
242 
243  rDocShell.PostPaint( 0,0,nTab, rDoc.MaxCol(),rDoc.MaxRow(),nTab,
247  bSuccess = true;
248  }
249 
250  return bSuccess;
251 }
252 
253 void ScOutlineDocFunc::AutoOutline( const ScRange& rRange, bool bRecord )
254 {
255  SCCOL nStartCol = rRange.aStart.Col();
256  SCROW nStartRow = rRange.aStart.Row();
257  SCCOL nEndCol = rRange.aEnd.Col();
258  SCROW nEndRow = rRange.aEnd.Row();
259  SCTAB nTab = rRange.aStart.Tab();
260 
261  ScDocument& rDoc = rDocShell.GetDocument();
262 
263  if (bRecord && !rDoc.IsUndoEnabled())
264  bRecord = false;
265  ScOutlineTable* pTable = rDoc.GetOutlineTable( nTab );
266 
267  ScDocumentUniquePtr pUndoDoc;
268  std::unique_ptr<ScOutlineTable> pUndoTab;
269 
270  if ( pTable )
271  {
272  if ( bRecord )
273  {
274  pUndoTab.reset(new ScOutlineTable( *pTable ));
275 
276  SCCOLROW nCol1, nCol2, nRow1, nRow2;
277  pTable->GetColArray().GetRange( nCol1, nCol2 );
278  pTable->GetRowArray().GetRange( nRow1, nRow2 );
279  SCCOL nOutStartCol = static_cast<SCCOL>(nCol1);
280  SCROW nOutStartRow = nRow1;
281  SCCOL nOutEndCol = static_cast<SCCOL>(nCol2);
282  SCROW nOutEndRow = nRow2;
283 
284  pUndoDoc.reset(new ScDocument( SCDOCMODE_UNDO ));
285  pUndoDoc->InitUndo( rDoc, nTab, nTab, true, true );
286  rDoc.CopyToDocument(nOutStartCol, 0, nTab, nOutEndCol, rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false, *pUndoDoc);
287  rDoc.CopyToDocument(0, nOutStartRow, nTab, rDoc.MaxCol(), nOutEndRow, nTab, InsertDeleteFlags::NONE, false, *pUndoDoc);
288  }
289 
290  // enable
291  SelectLevel( nTab, true, pTable->GetColArray().GetDepth(), false, false );
292  SelectLevel( nTab, false, pTable->GetRowArray().GetDepth(), false, false );
293  rDoc.SetOutlineTable( nTab, nullptr );
294  }
295 
296  rDoc.DoAutoOutline( nStartCol,nStartRow, nEndCol,nEndRow, nTab );
297 
298  if (bRecord)
299  {
301  std::make_unique<ScUndoAutoOutline>( &rDocShell,
302  nStartCol, nStartRow, nTab,
303  nEndCol, nEndRow, nTab,
304  std::move(pUndoDoc), std::move(pUndoTab) ) );
305  }
306 
307  rDoc.SetStreamValid(nTab, false);
308 
312 }
313 
314 bool ScOutlineDocFunc::SelectLevel( SCTAB nTab, bool bColumns, sal_uInt16 nLevel,
315  bool bRecord, bool bPaint )
316 {
317  ScDocument& rDoc = rDocShell.GetDocument();
319 
320  if (bRecord && !rDoc.IsUndoEnabled())
321  bRecord = false;
322  ScOutlineTable* pTable = rDoc.GetOutlineTable( nTab ); // already there
323  if (!pTable)
324  return false;
325  ScOutlineArray& rArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
326 
327  SCCOLROW nStart, nEnd;
328  rArray.GetRange( nStart, nEnd );
329 
330  // TODO undo can mess things up when another view is editing a cell in the range of group entry
331  // this is a temporarily workaround
332  if (!comphelper::LibreOfficeKit::isActive() && bRecord )
333  {
334  std::unique_ptr<ScOutlineTable> pUndoTab(new ScOutlineTable( *pTable ));
336  if (bColumns)
337  {
338  pUndoDoc->InitUndo( rDoc, nTab, nTab, true );
339  rDoc.CopyToDocument(static_cast<SCCOL>(nStart), 0, nTab,
340  static_cast<SCCOL>(nEnd), rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false,
341  *pUndoDoc);
342  }
343  else
344  {
345  pUndoDoc->InitUndo( rDoc, nTab, nTab, false, true );
346  rDoc.CopyToDocument(0, nStart, nTab, rDoc.MaxCol(), nEnd, nTab, InsertDeleteFlags::NONE, false, *pUndoDoc);
347  }
348 
350  std::make_unique<ScUndoOutlineLevel>( &rDocShell,
351  nStart, nEnd, nTab,
352  std::move(pUndoDoc), std::move(pUndoTab),
353  bColumns, nLevel ) );
354  }
355 
356  ScSubOutlineIterator aIter( &rArray ); // all entries
357  ScOutlineEntry* pEntry;
358  while ((pEntry=aIter.GetNext()) != nullptr)
359  {
360  SCCOLROW nThisStart = pEntry->GetStart();
361  SCCOLROW nThisEnd = pEntry->GetEnd();
362 
363  sal_uInt16 nThisLevel = aIter.LastLevel();
364  bool bShow = (nThisLevel < nLevel);
365 
366  if (!bShow && pViewSh && ScTabViewShell::isAnyEditViewInRange(pViewSh, bColumns, nThisStart, nThisEnd))
367  continue;
368 
369  if (bShow) // enable
370  {
371  pEntry->SetHidden( false );
372  pEntry->SetVisible( true );
373  }
374  else if ( nThisLevel == nLevel ) // disable
375  {
376  pEntry->SetHidden( true );
377  pEntry->SetVisible( true );
378  }
379  else // hidden below
380  {
381  if (comphelper::LibreOfficeKit::isActive() && nThisLevel > 0)
382  {
383  pEntry->SetHidden( true );
384  const ScOutlineEntry* pParentEntry = rArray.GetEntryByPos(nThisLevel - 1, nThisStart);
385  if (pParentEntry && pParentEntry->IsHidden())
386  pEntry->SetVisible( false );
387  }
388  else
389  {
390  pEntry->SetVisible( false );
391  }
392  }
393 
394  for (SCCOLROW i=nThisStart; i<=nThisEnd; i++)
395  {
396  if ( bColumns )
397  rDoc.ShowCol( static_cast<SCCOL>(i), nTab, bShow );
398  else
399  {
400  // show several rows together, don't show filtered rows
401  SCROW nFilterEnd = i;
402  bool bFiltered = rDoc.RowFiltered( i, nTab, nullptr, &nFilterEnd );
403  nFilterEnd = std::min( nThisEnd, nFilterEnd );
404  if ( !bShow || !bFiltered )
405  rDoc.ShowRows( i, nFilterEnd, nTab, bShow );
406  i = nFilterEnd;
407  }
408  }
409  }
410 
411  rDoc.SetDrawPageSize(nTab);
412  rDoc.UpdatePageBreaks( nTab );
413 
414  if ( pViewSh )
415  pViewSh->OnLOKShowHideColRow(bColumns, nStart - 1);
416 
417  if (bPaint)
418  lcl_PaintWidthHeight( rDocShell, nTab, bColumns, nStart, nEnd );
419 
422 
423  return true;
424 }
425 
426 bool ScOutlineDocFunc::ShowMarkedOutlines( const ScRange& rRange, bool bRecord )
427 {
428  bool bDone = false;
429 
430  SCCOL nStartCol = rRange.aStart.Col();
431  SCROW nStartRow = rRange.aStart.Row();
432  SCCOL nEndCol = rRange.aEnd.Col();
433  SCROW nEndRow = rRange.aEnd.Row();
434  SCTAB nTab = rRange.aStart.Tab();
435 
436  ScDocument& rDoc = rDocShell.GetDocument();
437 
438  if (bRecord && !rDoc.IsUndoEnabled())
439  bRecord = false;
440  ScOutlineTable* pTable = rDoc.GetOutlineTable( nTab );
441 
442  if (pTable)
443  {
444  ScOutlineEntry* pEntry;
445  SCCOLROW nStart;
446  SCCOLROW nEnd;
447  SCCOLROW nMin;
448  SCCOLROW nMax;
449  SCCOLROW i;
450 
451  // TODO undo can mess things up when another view is editing a cell in the range of group entry
452  // this is a temporarily workaround
453  if ( !comphelper::LibreOfficeKit::isActive() && bRecord )
454  {
455  std::unique_ptr<ScOutlineTable> pUndoTab(new ScOutlineTable( *pTable ));
457  pUndoDoc->InitUndo( rDoc, nTab, nTab, true, true );
458  rDoc.CopyToDocument(nStartCol, 0, nTab, nEndCol, rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false, *pUndoDoc);
459  rDoc.CopyToDocument(0, nStartRow, nTab, rDoc.MaxCol(), nEndRow, nTab, InsertDeleteFlags::NONE, false, *pUndoDoc);
460 
462  std::make_unique<ScUndoOutlineBlock>( &rDocShell,
463  nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
464  std::move(pUndoDoc), std::move(pUndoTab), true ) );
465  }
466 
467  // Columns
468 
469  nMin=rDoc.MaxCol();
470  nMax=0;
471  ScOutlineArray& rColArray = pTable->GetColArray();
472  ScSubOutlineIterator aColIter( &rColArray );
473  while ((pEntry=aColIter.GetNext()) != nullptr)
474  {
475  nStart = pEntry->GetStart();
476  nEnd = pEntry->GetEnd();
477  if ( nStart>=nStartCol && nEnd<=nEndCol )
478  {
479  pEntry->SetHidden( false );
480  pEntry->SetVisible( true );
481  if (nStart<nMin) nMin=nStart;
482  if (nEnd>nMax) nMax=nEnd;
483  }
484  }
485  const SCCOLROW nMinStartCol = nMin;
486  for ( i=nMin; i<=nMax; i++ )
487  rDoc.ShowCol( static_cast<SCCOL>(i), nTab, true );
488 
489  // Rows
490 
491  nMin=rDoc.MaxRow();
492  nMax=0;
493  ScOutlineArray& rRowArray = pTable->GetRowArray();
494  ScSubOutlineIterator aRowIter( &rRowArray );
495  while ((pEntry=aRowIter.GetNext()) != nullptr)
496  {
497  nStart = pEntry->GetStart();
498  nEnd = pEntry->GetEnd();
499  if ( nStart>=nStartRow && nEnd<=nEndRow )
500  {
501  pEntry->SetHidden( false );
502  pEntry->SetVisible( true );
503  if (nStart<nMin) nMin=nStart;
504  if (nEnd>nMax) nMax=nEnd;
505  }
506  }
507  const SCCOLROW nMinStartRow = nMin;
508  for ( i=nMin; i<=nMax; i++ )
509  {
510  // show several rows together, don't show filtered rows
511  SCROW nFilterEnd = i;
512  bool bFiltered = rDoc.RowFiltered( i, nTab, nullptr, &nFilterEnd );
513  nFilterEnd = std::min( nMax, nFilterEnd );
514  if ( !bFiltered )
515  rDoc.ShowRows( i, nFilterEnd, nTab, true );
516  i = nFilterEnd;
517  }
518 
519 
520  rDoc.SetDrawPageSize(nTab);
521  rDoc.UpdatePageBreaks( nTab );
522 
524  if ( pViewSh )
525  {
526  pViewSh->OnLOKShowHideColRow(/*columns: */ true, nMinStartCol - 1);
527  pViewSh->OnLOKShowHideColRow(/*columns: */ false, nMinStartRow - 1);
528  }
529 
532  bDone = true;
533 
535  }
536 
537  return bDone;
538 }
539 
540 bool ScOutlineDocFunc::HideMarkedOutlines( const ScRange& rRange, bool bRecord )
541 {
542  bool bDone = false;
543 
544  SCCOL nStartCol = rRange.aStart.Col();
545  SCROW nStartRow = rRange.aStart.Row();
546  SCCOL nEndCol = rRange.aEnd.Col();
547  SCROW nEndRow = rRange.aEnd.Row();
548  SCTAB nTab = rRange.aStart.Tab();
549 
550  ScDocument& rDoc = rDocShell.GetDocument();
551 
552  if (bRecord && !rDoc.IsUndoEnabled())
553  bRecord = false;
554  ScOutlineTable* pTable = rDoc.GetOutlineTable( nTab );
555 
556  if (pTable)
557  {
558  const ScOutlineEntry* pEntry;
559  size_t nColLevel;
560  size_t nRowLevel;
561  sal_uInt16 nCount;
562  SCCOLROW nStart;
563  SCCOLROW nEnd;
564  sal_uInt16 i;
565 
566  SCCOLROW nEffStartCol = nStartCol;
567  SCCOLROW nEffEndCol = nEndCol;
568  ScOutlineArray& rColArray = pTable->GetColArray();
569  rColArray.FindTouchedLevel( nStartCol, nEndCol, nColLevel );
570  rColArray.ExtendBlock( nColLevel, nEffStartCol, nEffEndCol );
571  SCCOLROW nEffStartRow = nStartRow;
572  SCCOLROW nEffEndRow = nEndRow;
573  ScOutlineArray& rRowArray = pTable->GetRowArray();
574  rRowArray.FindTouchedLevel( nStartRow, nEndRow, nRowLevel );
575  rRowArray.ExtendBlock( nRowLevel, nEffStartRow, nEffEndRow );
576 
577  // TODO undo can mess things up when another view is editing a cell in the range of group entry
578  // this is a temporarily workaround
579  if ( !comphelper::LibreOfficeKit::isActive() && bRecord )
580  {
581  std::unique_ptr<ScOutlineTable> pUndoTab(new ScOutlineTable( *pTable ));
583  pUndoDoc->InitUndo( rDoc, nTab, nTab, true, true );
584  rDoc.CopyToDocument(static_cast<SCCOL>(nEffStartCol), 0, nTab,
585  static_cast<SCCOL>(nEffEndCol), rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE,
586  false, *pUndoDoc);
587  rDoc.CopyToDocument(0, nEffStartRow, nTab, rDoc.MaxCol(), nEffEndRow, nTab, InsertDeleteFlags::NONE, false, *pUndoDoc);
588 
590  std::make_unique<ScUndoOutlineBlock>( &rDocShell,
591  nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
592  std::move(pUndoDoc), std::move(pUndoTab), false ) );
593  }
594 
595  // Columns
596 
597  nCount = rColArray.GetCount(nColLevel);
598  for ( i=0; i<nCount; i++ )
599  {
600  pEntry = rColArray.GetEntry(nColLevel,i);
601  nStart = pEntry->GetStart();
602  nEnd = pEntry->GetEnd();
603 
604  if ( static_cast<SCCOLROW>(nStartCol)<=nEnd && static_cast<SCCOLROW>(nEndCol)>=nStart )
605  HideOutline( nTab, true, nColLevel, i, false, false );
606  }
607 
608  // Rows
609 
610  nCount = rRowArray.GetCount(nRowLevel);
611  for ( i=0; i<nCount; i++ )
612  {
613  pEntry = rRowArray.GetEntry(nRowLevel,i);
614  nStart = pEntry->GetStart();
615  nEnd = pEntry->GetEnd();
616 
617  if ( nStartRow<=nEnd && nEndRow>=nStart )
618  HideOutline( nTab, false, nRowLevel, i, false, false );
619  }
620 
621  rDoc.SetDrawPageSize(nTab);
622  rDoc.UpdatePageBreaks( nTab );
623 
625 
627  bDone = true;
628 
630  }
631 
632  return bDone;
633 }
634 
635 void ScOutlineDocFunc::ShowOutline( SCTAB nTab, bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry,
636  bool bRecord, bool bPaint )
637 {
638  ScDocument& rDoc = rDocShell.GetDocument();
639  if (bRecord && !rDoc.IsUndoEnabled())
640  bRecord = false;
641 
642  ScOutlineTable* pTable = rDoc.GetOutlineTable( nTab );
643  ScOutlineArray& rArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
644  ScOutlineEntry* pEntry = rArray.GetEntry( nLevel, nEntry );
645  SCCOLROW nStart = pEntry->GetStart();
646  SCCOLROW nEnd = pEntry->GetEnd();
647 
648  // TODO undo can mess things up when another view is editing a cell in the range of group entry
649  // this is a temporarily workaround
650  if ( !comphelper::LibreOfficeKit::isActive() && bRecord )
651  {
653  if (bColumns)
654  {
655  pUndoDoc->InitUndo( rDoc, nTab, nTab, true );
656  rDoc.CopyToDocument(static_cast<SCCOL>(nStart), 0, nTab,
657  static_cast<SCCOL>(nEnd), rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false,
658  *pUndoDoc);
659  }
660  else
661  {
662  pUndoDoc->InitUndo( rDoc, nTab, nTab, false, true );
663  rDoc.CopyToDocument(0, nStart, nTab, rDoc.MaxCol(), nEnd, nTab, InsertDeleteFlags::NONE, false, *pUndoDoc);
664  }
665 
667  std::make_unique<ScUndoDoOutline>( &rDocShell,
668  nStart, nEnd, nTab, std::move(pUndoDoc),
669  bColumns, nLevel, nEntry, true ) );
670  }
671 
672  pEntry->SetHidden(false);
673  SCCOLROW i;
674  for ( i = nStart; i <= nEnd; i++ )
675  {
676  if ( bColumns )
677  rDoc.ShowCol( static_cast<SCCOL>(i), nTab, true );
678  else
679  {
680  // show several rows together, don't show filtered rows
681  SCROW nFilterEnd = i;
682  bool bFiltered = rDoc.RowFiltered( i, nTab, nullptr, &nFilterEnd );
683  nFilterEnd = std::min( nEnd, nFilterEnd );
684  if ( !bFiltered )
685  rDoc.ShowRows( i, nFilterEnd, nTab, true );
686  i = nFilterEnd;
687  }
688  }
689 
690  ScSubOutlineIterator aIter( &rArray, nLevel, nEntry );
691  while ((pEntry=aIter.GetNext()) != nullptr)
692  {
693  if ( pEntry->IsHidden() )
694  {
695  SCCOLROW nSubStart = pEntry->GetStart();
696  SCCOLROW nSubEnd = pEntry->GetEnd();
697  if ( bColumns )
698  for ( i = nSubStart; i <= nSubEnd; i++ )
699  rDoc.ShowCol( static_cast<SCCOL>(i), nTab, false );
700  else
701  rDoc.ShowRows( nSubStart, nSubEnd, nTab, false );
702  }
703  }
704 
705  rArray.SetVisibleBelow( nLevel, nEntry, true, true );
706 
707  rDoc.SetDrawPageSize(nTab);
708  rDoc.InvalidatePageBreaks(nTab);
709  rDoc.UpdatePageBreaks( nTab );
710 
712  if ( pViewSh )
713  pViewSh->OnLOKShowHideColRow(bColumns, nStart - 1);
714 
715  if (bPaint)
716  lcl_PaintWidthHeight( rDocShell, nTab, bColumns, nStart, nEnd );
717 
719 
721 }
722 
723 bool ScOutlineDocFunc::HideOutline( SCTAB nTab, bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry,
724  bool bRecord, bool bPaint )
725 {
726  ScDocument& rDoc = rDocShell.GetDocument();
727  if (bRecord && !rDoc.IsUndoEnabled())
728  bRecord = false;
729 
730  ScOutlineTable* pTable = rDoc.GetOutlineTable( nTab );
731  ScOutlineArray& rArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
732  ScOutlineEntry* pEntry = rArray.GetEntry( nLevel, nEntry );
733  SCCOLROW nStart = pEntry->GetStart();
734  SCCOLROW nEnd = pEntry->GetEnd();
735 
737  if (pViewSh && ScTabViewShell::isAnyEditViewInRange(pViewSh, bColumns, nStart, nEnd))
738  return false;
739 
740  // TODO undo can mess things up when another view is editing a cell in the range of group entry
741  // this is a temporarily workaround
742  if ( !comphelper::LibreOfficeKit::isActive() && bRecord )
743  {
745  if (bColumns)
746  {
747  pUndoDoc->InitUndo( rDoc, nTab, nTab, true );
748  rDoc.CopyToDocument(static_cast<SCCOL>(nStart), 0, nTab,
749  static_cast<SCCOL>(nEnd), rDoc.MaxRow(), nTab, InsertDeleteFlags::NONE, false,
750  *pUndoDoc);
751  }
752  else
753  {
754  pUndoDoc->InitUndo( rDoc, nTab, nTab, false, true );
755  rDoc.CopyToDocument(0, nStart, nTab, rDoc.MaxCol(), nEnd, nTab, InsertDeleteFlags::NONE, false, *pUndoDoc);
756  }
757 
759  std::make_unique<ScUndoDoOutline>( &rDocShell,
760  nStart, nEnd, nTab, std::move(pUndoDoc),
761  bColumns, nLevel, nEntry, false ) );
762  }
763 
764  pEntry->SetHidden(true);
765  SCCOLROW i;
766  if ( bColumns )
767  for ( i = nStart; i <= nEnd; i++ )
768  rDoc.ShowCol( static_cast<SCCOL>(i), nTab, false );
769  else
770  rDoc.ShowRows( nStart, nEnd, nTab, false );
771 
772  rArray.SetVisibleBelow( nLevel, nEntry, false );
773 
774  rDoc.SetDrawPageSize(nTab);
775  rDoc.InvalidatePageBreaks(nTab);
776  rDoc.UpdatePageBreaks( nTab );
777 
778  if ( pViewSh )
779  pViewSh->OnLOKShowHideColRow(bColumns, nStart - 1);
780 
781  if (bPaint)
782  lcl_PaintWidthHeight( rDocShell, nTab, bColumns, nStart, nEnd );
783 
785 
787 
788 
789  return true;
790 }
791 
792 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void ExtendBlock(size_t nLevel, SCCOLROW &rBlkStart, SCCOLROW &rBlkEnd)
Definition: olinetab.cxx:583
SC_DLLPUBLIC void ShowCol(SCCOL nCol, SCTAB nTab, bool bShow)
Definition: document.cxx:4298
void UpdatePageBreaks(SCTAB nTab, const ScRange *pUserArea=nullptr)
Definition: document.cxx:6221
static void lcl_PaintWidthHeight(ScDocShell &rDocShell, SCTAB nTab, bool bColumns, SCCOLROW nStart, SCCOLROW nEnd)
Move PaintWidthHeight to DocShell ?
Definition: olinefun.cxx:49
SC_DLLPUBLIC void ShowRows(SCROW nRow1, SCROW nRow2, SCTAB nTab, bool bShow)
Definition: document.cxx:4310
ScAddress aStart
Definition: address.hxx:500
SC_DLLPUBLIC bool IsHidden() const
Definition: olinetab.hxx:50
SCROW Row() const
Definition: address.hxx:262
bool RemoveAllOutlines(SCTAB nTab, bool bRecord)
Definition: olinefun.cxx:201
SfxBindings * GetViewBindings()
Definition: docsh4.cxx:2575
SC_DLLPUBLIC void SetDrawPageSize(SCTAB nTab)
Definition: documen9.cxx:193
SC_DLLPUBLIC SCCOLROW GetEnd() const
Definition: olinetab.cxx:42
ScDocShell & rDocShell
Definition: olinefun.hxx:31
void SetDocumentModified()
Definition: docsh.cxx:2819
ScOutlineEntry * GetEntry(size_t nLevel, size_t nIndex)
Definition: olinetab.cxx:442
ScAddress aEnd
Definition: address.hxx:501
void Invalidate(sal_uInt16 nId)
const ScOutlineEntry * GetEntryByPos(size_t nLevel, SCCOLROW nPos) const
Definition: olinetab.cxx:478
SC_DLLPUBLIC bool HasAttrib(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, HasAttrFlags nMask) const
Definition: document.cxx:5179
void SetVisible(bool bNewVisible)
Definition: olinetab.cxx:79
virtual SfxUndoManager * GetUndoManager() override
Definition: docsh.cxx:2805
void DoAutoOutline(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab)
Definition: documen3.cxx:754
SC_DLLPUBLIC SCROW MaxRow() const
Definition: document.hxx:873
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:24
size_t GetDepth() const
Definition: olinetab.hxx:111
int nCount
void CopyToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, InsertDeleteFlags nFlags, bool bMarked, ScDocument &rDestDoc, const ScMarkData *pMarks=nullptr, bool bColRowFlags=true)
Definition: document.cxx:2076
SCTAB Tab() const
Definition: address.hxx:271
void MakeOutline(const ScRange &rRange, bool bColumns, bool bRecord, bool bApi)
Definition: olinefun.cxx:80
bool SetOutlineTable(SCTAB nTab, const ScOutlineTable *pNewOutline)
Definition: documen3.cxx:749
void GetRange(SCCOLROW &rStart, SCCOLROW &rEnd) const
Definition: olinetab.cxx:569
SC_DLLPUBLIC SCCOL MaxCol() const
Definition: document.hxx:872
virtual void AddUndoAction(std::unique_ptr< SfxUndoAction > pAction, bool bTryMerg=false)
void InvalidatePageBreaks(SCTAB nTab)
Definition: document.cxx:6215
void RemoveOutline(const ScRange &rRange, bool bColumns, bool bRecord, bool bApi)
Definition: olinefun.cxx:138
bool HideMarkedOutlines(const ScRange &rRange, bool bRecord)
Definition: olinefun.cxx:540
int i
SC_DLLPUBLIC SCCOLROW GetStart() const
Definition: olinetab.hxx:43
bool RowFiltered(SCROW nRow, SCTAB nTab, SCROW *pFirstRow=nullptr, SCROW *pLastRow=nullptr) const
Definition: document.cxx:4499
std::unique_ptr< ScDocument, o3tl::default_delete< ScDocument > > ScDocumentUniquePtr
Definition: document.hxx:2613
const ScOutlineArray & GetRowArray() const
Definition: olinetab.hxx:161
sal_Int16 SCCOL
Definition: types.hxx:22
const ScOutlineArray & GetColArray() const
Definition: olinetab.hxx:159
void OnLOKShowHideColRow(bool bColumns, SCCOLROW nStartRow)
Definition: dbfunc3.cxx:2278
size_t GetCount(size_t nLevel) const
Definition: olinetab.cxx:470
void SetHidden(bool bNewHidden)
Definition: olinetab.cxx:74
void SetVisibleBelow(size_t nLevel, size_t nEntry, bool bValue, bool bSkipHidden=false)
Definition: olinetab.cxx:536
bool Remove(SCCOLROW nBlockStart, SCCOLROW nBlockEnd, bool &rSizeChanged)
Definition: olinetab.cxx:409
void AutoOutline(const ScRange &rRange, bool bRecord)
Definition: olinefun.cxx:253
void PostPaint(SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, PaintPartFlags nPart, sal_uInt16 nExtFlags=0)
Definition: docsh3.cxx:99
SCCOL Col() const
Definition: address.hxx:267
bool SelectLevel(SCTAB nTab, bool bColumns, sal_uInt16 nLevel, bool bRecord, bool bPaint)
Definition: olinefun.cxx:314
sal_Int32 SCROW
Definition: types.hxx:18
void SetStreamValid(SCTAB nTab, bool bSet, bool bIgnoreLock=false)
Definition: document.cxx:925
ScOutlineEntry * GetNext()
Definition: olinetab.cxx:824
bool ShowMarkedOutlines(const ScRange &rRange, bool bRecord)
Definition: olinefun.cxx:426
size_t LastLevel() const
Definition: olinetab.hxx:187
void ErrorMessage(const char *pGlobStrId)
Definition: docsh5.cxx:71
SC_DLLPUBLIC ScOutlineTable * GetOutlineTable(SCTAB nTab, bool bCreate=false)
Definition: documen3.cxx:731
const ScDocument & GetDocument() const
Definition: docsh.hxx:216
static bool isAnyEditViewInRange(const SfxViewShell *pForViewShell, bool bColumns, SCCOLROW nStart, SCCOLROW nEnd)
Definition: tabvwshc.cxx:531
bool IsUndoEnabled() const
Definition: document.hxx:1531
bool FindTouchedLevel(SCCOLROW nBlockStart, SCCOLROW nBlockEnd, size_t &rFindLevel) const
Definition: olinetab.cxx:300
void ShowOutline(SCTAB nTab, bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry, bool bRecord, bool bPaint)
Definition: olinefun.cxx:635
ScTabViewShell * GetBestViewShell(bool bOnlyVisible=true)
Definition: docsh4.cxx:2556
PaintPartFlags
Definition: global.hxx:120
bool Insert(SCCOLROW nStartPos, SCCOLROW nEndPos, bool &rSizeChanged, bool bHidden=false)
Definition: olinetab.cxx:197
sal_Int16 SCTAB
Definition: types.hxx:23
bool HideOutline(SCTAB nTab, bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry, bool bRecord, bool bPaint)
Definition: olinefun.cxx:723
static void lcl_InvalidateOutliner(SfxBindings *pBindings)
Definition: olinefun.cxx:34