LibreOffice Module sc (master)  1
olinetab.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 <olinetab.hxx>
21 #include <address.hxx>
22 #include <table.hxx>
23 
24 #include <osl/diagnose.h>
25 
26 ScOutlineEntry::ScOutlineEntry( SCCOLROW nNewStart, SCCOLROW nNewSize, bool bNewHidden ) :
27  nStart ( nNewStart ),
28  nSize ( nNewSize ),
29  bHidden ( bNewHidden ),
30  bVisible( true )
31 {
32 }
33 
35  nStart ( rEntry.nStart ),
36  nSize ( rEntry.nSize ),
37  bHidden ( rEntry.bHidden ),
38  bVisible( rEntry.bVisible )
39 {
40 }
41 
43 {
44  return nStart+nSize-1;
45 }
46 
48 {
49  SCCOLROW nNewPos = nStart + nDelta;
50  if (nNewPos<0)
51  {
52  OSL_FAIL("OutlineEntry < 0");
53  nNewPos = 0;
54  }
55  nStart = nNewPos;
56 }
57 
59 {
60  if (nNewSize>0)
61  nSize = nNewSize;
62  else
63  {
64  OSL_FAIL("ScOutlineEntry Size == 0");
65  }
66 }
67 
68 void ScOutlineEntry::SetPosSize( SCCOLROW nNewPos, SCSIZE nNewSize )
69 {
70  nStart = nNewPos;
71  SetSize( nNewSize );
72 }
73 
74 void ScOutlineEntry::SetHidden( bool bNewHidden )
75 {
76  bHidden = bNewHidden;
77 }
78 
79 void ScOutlineEntry::SetVisible( bool bNewVisible )
80 {
81  bVisible = bNewVisible;
82 }
83 
85 {
86  const char* const pSep = ":";
87  return OString::number(nStart) + pSep + OString::number(nSize) +
88  pSep + (bHidden ? "1" : "0") + pSep + (bVisible ? "1" : "0");
89 }
90 
92 
94 {
95  return m_Entries.size();
96 }
97 
99 {
100  m_Entries.clear();
101 }
102 
104 {
105  SCCOLROW nStart = rEntry.GetStart();
106  m_Entries.insert(std::make_pair(nStart, rEntry));
107 }
108 
110 {
111  return m_Entries.begin();
112 }
113 
115 {
116  return m_Entries.end();
117 }
118 
120 {
121  return m_Entries.begin();
122 }
123 
125 {
126  return m_Entries.end();
127 }
128 
130 {
131  m_Entries.erase(pos);
132 }
133 
135 {
136  return m_Entries.empty();
137 }
138 
140 {
141  return m_Entries.lower_bound(nMinStart);
142 }
143 
145 {
146  OString aOutput;
147  const char* const pGroupEntrySep = ",";
148  for (const auto& rKeyValuePair : m_Entries)
149  aOutput += rKeyValuePair.second.dumpAsString() + pGroupEntrySep;
150 
151  return aOutput;
152 }
153 
155  nDepth(0) {}
156 
158  nDepth( rArray.nDepth )
159 {
160  for (size_t nLevel = 0; nLevel < nDepth; ++nLevel)
161  {
162  const ScOutlineCollection& rColl = rArray.aCollections[nLevel];
163  for (const auto& rEntry : rColl)
164  {
165  const ScOutlineEntry *const pEntry = &rEntry.second;
166  aCollections[nLevel].insert(*pEntry);
167  }
168  }
169 }
170 
172  SCCOLROW nSearchPos, size_t& rFindLevel, size_t& rFindIndex,
173  size_t nMaxLevel )
174 {
175  rFindLevel = rFindIndex = 0;
176 
177  if (nMaxLevel > nDepth)
178  nMaxLevel = nDepth;
179 
180  for (size_t nLevel = 0; nLevel < nMaxLevel; ++nLevel) //TODO: Search backwards?
181  {
182  ScOutlineCollection* pCollect = &aCollections[nLevel];
183  size_t nIndex = 0;
184  for (auto& rEntry : *pCollect)
185  {
186  ScOutlineEntry *const pEntry = &rEntry.second;
187  if (pEntry->GetStart() <= nSearchPos && pEntry->GetEnd() >= nSearchPos)
188  {
189  rFindLevel = nLevel + 1; // Next Level (for insertion)
190  rFindIndex = nIndex;
191  }
192  ++nIndex;
193  }
194  }
195 }
196 
198  SCCOLROW nStartCol, SCCOLROW nEndCol, bool& rSizeChanged, bool bHidden )
199 {
200  rSizeChanged = false;
201 
202  size_t nStartLevel, nEndLevel, nStartIndex, nEndIndex;
203  bool bFound = false;
204 
205  bool bCont;
206  sal_uInt16 nFindMax;
207  FindEntry( nStartCol, nStartLevel, nStartIndex ); // nLevel = new Level (old+1)
208  FindEntry( nEndCol, nEndLevel, nEndIndex );
209  nFindMax = std::max(nStartLevel,nEndLevel);
210  do
211  {
212  bCont = false;
213 
214  if (nStartLevel == nEndLevel && nStartIndex == nEndIndex && nStartLevel < SC_OL_MAXDEPTH)
215  bFound = true;
216 
217  if (!bFound && nFindMax>0)
218  {
219  --nFindMax;
220  if (nStartLevel)
221  {
223  std::advance(it, nStartIndex);
224  if (it->second.GetStart() == nStartCol)
225  FindEntry(nStartCol, nStartLevel, nStartIndex, nFindMax);
226  }
227 
228  if (nEndLevel)
229  {
231  std::advance(it, nEndIndex);
232  if (it->second.GetEnd() == nEndCol)
233  FindEntry(nEndCol, nEndLevel, nEndIndex, nFindMax);
234  }
235  bCont = true;
236  }
237  }
238  while ( !bFound && bCont );
239 
240  if (!bFound)
241  return false;
242 
243  size_t nLevel = nStartLevel;
244 
245  // Move the ones underneath
246  bool bNeedSize = false;
247  if (nDepth > 0)
248  {
249  for (size_t nMoveLevel = nDepth-1; nMoveLevel >= nLevel; --nMoveLevel)
250  {
251  ScOutlineCollection& rColl = aCollections[nMoveLevel];
252  ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
253  while (it != itEnd)
254  {
255  ScOutlineEntry *const pEntry = &it->second;
256  SCCOLROW nEntryStart = pEntry->GetStart();
257  if (nEntryStart >= nStartCol && nEntryStart <= nEndCol)
258  {
259  if (nMoveLevel >= SC_OL_MAXDEPTH - 1)
260  {
261  rSizeChanged = false; // No more room
262  return false;
263  }
264  aCollections[nMoveLevel+1].insert(*pEntry);
265  size_t nPos = std::distance(rColl.begin(), it);
266  rColl.erase(it);
267  it = rColl.begin();
268  std::advance(it, nPos);
269  itEnd = rColl.end();
270  if (nMoveLevel == nDepth - 1)
271  bNeedSize = true;
272  }
273  else
274  ++it;
275  }
276  if (nMoveLevel == 0)
277  break;
278  }
279  }
280 
281  if (bNeedSize)
282  {
283  ++nDepth;
284  rSizeChanged = true;
285  }
286 
287  if (nDepth <= nLevel)
288  {
289  nDepth = nLevel+1;
290  rSizeChanged = true;
291  }
292 
293  ScOutlineEntry aNewEntry(nStartCol, nEndCol+1-nStartCol, bHidden);
294  aNewEntry.SetVisible( true );
295  aCollections[nLevel].insert(aNewEntry);
296 
297  return true;
298 }
299 
301  SCCOLROW nBlockStart, SCCOLROW nBlockEnd, size_t& rFindLevel) const
302 {
303  bool bFound = false;
304  rFindLevel = 0;
305 
306  for (size_t nLevel = 0; nLevel < nDepth; ++nLevel)
307  {
308  const ScOutlineCollection* pCollect = &aCollections[nLevel];
309  for (const auto& rEntry : *pCollect)
310  {
311  const ScOutlineEntry *const pEntry = &rEntry.second;
312  SCCOLROW nStart = pEntry->GetStart();
313  SCCOLROW nEnd = pEntry->GetEnd();
314 
315  if ( ( nBlockStart>=nStart && nBlockStart<=nEnd ) ||
316  ( nBlockEnd >=nStart && nBlockEnd <=nEnd ) )
317  {
318  rFindLevel = nLevel; // Actual Level
319  bFound = true;
320  }
321  }
322  }
323 
324  return bFound;
325 }
326 
327 void ScOutlineArray::PromoteSub(SCCOLROW nStartPos, SCCOLROW nEndPos, size_t nStartLevel)
328 {
329  if (nStartLevel==0)
330  {
331  OSL_FAIL("PromoteSub with Level 0");
332  return;
333  }
334 
335  for (size_t nLevel = nStartLevel; nLevel < nDepth; ++nLevel)
336  {
337  ScOutlineCollection& rColl = aCollections[nLevel];
338  ScOutlineCollection::iterator it = rColl.begin(), itEnd = rColl.end();
339  while (it != itEnd)
340  {
341  ScOutlineEntry *const pEntry = &it->second;
342  SCCOLROW nStart = pEntry->GetStart();
343  SCCOLROW nEnd = pEntry->GetEnd();
344  if (nStart >= nStartPos && nEnd <= nEndPos)
345  {
346  aCollections[nLevel-1].insert(*pEntry);
347 
348  // Re-calc iterator positions after the tree gets invalidated
349  size_t nPos = std::distance(rColl.begin(), it);
350  rColl.erase(it);
351  it = rColl.begin();
352  std::advance(it, nPos);
353  itEnd = rColl.end();
354  }
355  else
356  ++it;
357  }
358 
359  it = rColl.begin();
360  itEnd = rColl.end();
361 
362  while (it != itEnd)
363  {
364  ScOutlineEntry *const pEntry = &it->second;
365  SCCOLROW nStart = pEntry->GetStart();
366  SCCOLROW nEnd = pEntry->GetEnd();
367  if (nStart >= nStartPos && nEnd <= nEndPos)
368  {
369  aCollections[nLevel-1].insert(*pEntry);
370 
371  // Re-calc iterator positions after the tree gets invalidated
372  size_t nPos = std::distance(rColl.begin(), it);
373  rColl.erase(it);
374  it = rColl.begin();
375  std::advance(it, nPos);
376  itEnd = rColl.end();
377  }
378  else
379  ++it;
380  }
381  }
382 }
383 
388 {
389  bool bChanged = false;
390  bool bCont;
391  do
392  {
393  bCont = false;
394  if (nDepth)
395  {
396  if (aCollections[nDepth-1].empty())
397  {
398  --nDepth;
399  bChanged = true;
400  bCont = true;
401  }
402  }
403  }
404  while (bCont);
405 
406  return bChanged;
407 }
408 
409 bool ScOutlineArray::Remove( SCCOLROW nBlockStart, SCCOLROW nBlockEnd, bool& rSizeChanged )
410 {
411  size_t nLevel;
412  FindTouchedLevel( nBlockStart, nBlockEnd, nLevel );
413 
414  ScOutlineCollection* pCollect = &aCollections[nLevel];
415  ScOutlineCollection::iterator it = pCollect->begin(), itEnd = pCollect->end();
416  bool bAny = false;
417  while (it != itEnd)
418  {
419  ScOutlineEntry *const pEntry = &it->second;
420  SCCOLROW nStart = pEntry->GetStart();
421  SCCOLROW nEnd = pEntry->GetEnd();
422  if (nBlockStart <= nEnd && nBlockEnd >= nStart)
423  {
424  // Overlaps
425  pCollect->erase(it);
426  PromoteSub( nStart, nEnd, nLevel+1 );
427  itEnd = pCollect->end();
428  it = pCollect->FindStart( nEnd+1 );
429  bAny = true;
430  }
431  else
432  ++it;
433  }
434 
435  if (bAny) // Adapt Depth
436  if (DecDepth())
437  rSizeChanged = true;
438 
439  return bAny;
440 }
441 
442 ScOutlineEntry* ScOutlineArray::GetEntry(size_t nLevel, size_t nIndex)
443 {
444  if (nLevel >= nDepth)
445  return nullptr;
446 
447  ScOutlineCollection& rColl = aCollections[nLevel];
448  if (nIndex >= rColl.size())
449  return nullptr;
450 
452  std::advance(it, nIndex);
453  return &it->second;
454 }
455 
456 const ScOutlineEntry* ScOutlineArray::GetEntry(size_t nLevel, size_t nIndex) const
457 {
458  if (nLevel >= nDepth)
459  return nullptr;
460 
461  const ScOutlineCollection& rColl = aCollections[nLevel];
462  if (nIndex >= rColl.size())
463  return nullptr;
464 
466  std::advance(it, nIndex);
467  return &it->second;
468 }
469 
470 size_t ScOutlineArray::GetCount(size_t nLevel) const
471 {
472  if (nLevel >= nDepth)
473  return 0;
474 
475  return aCollections[nLevel].size();
476 }
477 
478 const ScOutlineEntry* ScOutlineArray::GetEntryByPos(size_t nLevel, SCCOLROW nPos) const
479 {
480  if (nLevel >= nDepth)
481  return nullptr;
482 
483  const ScOutlineCollection& rColl = aCollections[nLevel];
484  ScOutlineCollection::const_iterator it = std::find_if(rColl.begin(), rColl.end(),
485  [&nPos](const auto& rEntry) {
486  const ScOutlineEntry *const pEntry = &rEntry.second;
487  return pEntry->GetStart() <= nPos && nPos <= pEntry->GetEnd();
488  });
489  if (it != rColl.end())
490  return &it->second;
491 
492  return nullptr;
493 }
494 
495 bool ScOutlineArray::GetEntryIndex(size_t nLevel, SCCOLROW nPos, size_t& rnIndex) const
496 {
497  if (nLevel >= nDepth)
498  return false;
499 
500  // Found entry contains passed position
501  const ScOutlineCollection& rColl = aCollections[nLevel];
502  ScOutlineCollection::const_iterator it = std::find_if(rColl.begin(), rColl.end(),
503  [&nPos](const auto& rEntry) {
504  const ScOutlineEntry *const p = &rEntry.second;
505  return p->GetStart() <= nPos && nPos <= p->GetEnd();
506  });
507  if (it != rColl.end())
508  {
509  rnIndex = std::distance(rColl.begin(), it);
510  return true;
511  }
512  return false;
513 }
514 
516  size_t nLevel, SCCOLROW nBlockStart, SCCOLROW nBlockEnd, size_t& rnIndex) const
517 {
518  if (nLevel >= nDepth)
519  return false;
520 
521  // Found entry will be completely inside of passed range
522  const ScOutlineCollection& rColl = aCollections[nLevel];
523  ScOutlineCollection::const_iterator it = std::find_if(rColl.begin(), rColl.end(),
524  [&nBlockStart, &nBlockEnd](const auto& rEntry) {
525  const ScOutlineEntry *const p = &rEntry.second;
526  return nBlockStart <= p->GetStart() && p->GetEnd() <= nBlockEnd;
527  });
528  if (it != rColl.end())
529  {
530  rnIndex = std::distance(rColl.begin(), it);
531  return true;
532  }
533  return false;
534 }
535 
537  size_t nLevel, size_t nEntry, bool bValue, bool bSkipHidden)
538 {
539  const ScOutlineEntry* pEntry = GetEntry( nLevel, nEntry );
540  if (!pEntry)
541  return;
542 
543  SCCOLROW nStart = pEntry->GetStart();
544  SCCOLROW nEnd = pEntry->GetEnd();
545 
546  for (size_t nSubLevel = nLevel+1; nSubLevel < nDepth; ++nSubLevel)
547  {
548  ScOutlineCollection& rColl = aCollections[nSubLevel];
549  size_t nPos = 0;
550  for (auto& rEntry : rColl)
551  {
552  ScOutlineEntry *const p = &rEntry.second;
553  if (p->GetStart() >= nStart && p->GetEnd() <= nEnd)
554  {
555  p->SetVisible(bValue);
556  if (bSkipHidden && !p->IsHidden())
557  {
558  SetVisibleBelow(nSubLevel, nPos, bValue, true);
559  }
560  }
561  ++nPos;
562  }
563 
564  if (bSkipHidden)
565  nSubLevel = nDepth; // Bail out
566  }
567 }
568 
569 void ScOutlineArray::GetRange(SCCOLROW& rStart, SCCOLROW& rEnd) const
570 {
571  const ScOutlineCollection& rColl = aCollections[0];
572  if (!rColl.empty())
573  {
575  rStart = it->second.GetStart();
576  std::advance(it, rColl.size()-1);
577  rEnd = it->second.GetEnd();
578  }
579  else
580  rStart = rEnd = 0;
581 }
582 
583 void ScOutlineArray::ExtendBlock(size_t nLevel, SCCOLROW& rBlkStart, SCCOLROW& rBlkEnd)
584 {
585  if (nLevel >= nDepth)
586  return;
587 
588  const ScOutlineCollection& rColl = aCollections[nLevel];
589  for (const auto& rEntry : rColl)
590  {
591  const ScOutlineEntry *const pEntry = &rEntry.second;
592  SCCOLROW nStart = pEntry->GetStart();
593  SCCOLROW nEnd = pEntry->GetEnd();
594 
595  if (rBlkStart <= nEnd && rBlkEnd >= nStart)
596  {
597  if (nStart < rBlkStart)
598  rBlkStart = nStart;
599  if (nEnd > rBlkEnd)
600  rBlkEnd = nEnd;
601  }
602  }
603 }
604 
606 {
607  const ScOutlineCollection& rColl = aCollections[0];
608  if (rColl.empty())
609  return true;
610 
612  std::advance(it, rColl.size()-1);
613  SCCOLROW nEnd = it->second.GetEnd();
614  return sal::static_int_cast<SCCOLROW>(nEnd+nSize) <= nMaxVal;
615 }
616 
618 {
619  ScSubOutlineIterator aIter( this );
620  ScOutlineEntry* pEntry;
621  while ((pEntry = aIter.GetNext()) != nullptr)
622  {
623  if ( pEntry->GetStart() >= nStartPos )
624  pEntry->Move(static_cast<SCCOLROW>(nSize));
625  else
626  {
627  SCCOLROW nEnd = pEntry->GetEnd();
628  // Always expand if inserted within the group
629  // When inserting at the end, only if the group is not hidden
630  if ( nEnd >= nStartPos || ( nEnd+1 >= nStartPos && !pEntry->IsHidden() ) )
631  {
632  SCSIZE nEntrySize = pEntry->GetSize();
633  nEntrySize += nSize;
634  pEntry->SetSize( nEntrySize );
635  }
636  }
637  }
638 }
639 
641 {
642  SCCOLROW nEndPos = nStartPos + nSize - 1;
643  bool bNeedSave = false; // Do we need the original one for Undo?
644  bool bChanged = false; // For Level test
645 
646  ScSubOutlineIterator aIter( this );
647  ScOutlineEntry* pEntry;
648  while((pEntry=aIter.GetNext())!=nullptr)
649  {
650  SCCOLROW nEntryStart = pEntry->GetStart();
651  SCCOLROW nEntryEnd = pEntry->GetEnd();
652  SCSIZE nEntrySize = pEntry->GetSize();
653 
654  if ( nEntryEnd >= nStartPos )
655  {
656  if ( nEntryStart > nEndPos ) // Right
657  pEntry->Move(-static_cast<SCCOLROW>(nSize));
658  else if ( nEntryStart < nStartPos && nEntryEnd >= nEndPos ) // Outside
659  pEntry->SetSize( nEntrySize-nSize );
660  else
661  {
662  bNeedSave = true;
663  if ( nEntryStart >= nStartPos && nEntryEnd <= nEndPos ) // Inside
664  {
665  aIter.DeleteLast();
666  bChanged = true;
667  }
668  else if ( nEntryStart >= nStartPos ) // Top right
669  pEntry->SetPosSize( nStartPos, static_cast<SCSIZE>(nEntryEnd-nEndPos) );
670  else // Top left
671  pEntry->SetSize( static_cast<SCSIZE>(nStartPos-nEntryStart) );
672  }
673  }
674  }
675 
676  if (bChanged)
677  DecDepth();
678 
679  return bNeedSave;
680 }
681 
683  SCCOLROW nStartPos, SCCOLROW nEndPos, bool bShow, const ScTable& rTable, bool bCol)
684 {
685  bool bModified = false;
686  ScSubOutlineIterator aIter( this );
687  ScOutlineEntry* pEntry;
688  while((pEntry=aIter.GetNext())!=nullptr)
689  {
690  SCCOLROW nEntryStart = pEntry->GetStart();
691  SCCOLROW nEntryEnd = pEntry->GetEnd();
692 
693  if (nEntryEnd>=nStartPos && nEntryStart<=nEndPos)
694  {
695  if ( pEntry->IsHidden() == bShow )
696  {
697  // #i12341# hide if all columns/rows are hidden, show if at least one
698  // is visible
699  SCCOLROW nEnd = rTable.LastHiddenColRow(nEntryStart, bCol);
700  bool bAllHidden = (nEntryEnd <= nEnd && nEnd <
701  ::std::numeric_limits<SCCOLROW>::max());
702 
703  bool bToggle = ( bShow != bAllHidden );
704  if ( bToggle )
705  {
706  pEntry->SetHidden( !bShow );
707  SetVisibleBelow( aIter.LastLevel(), aIter.LastEntry(), bShow, bShow );
708  bModified = true;
709  }
710  }
711  }
712  }
713  return bModified;
714 }
715 
717 {
718  for (size_t nLevel = 0; nLevel < nDepth; ++nLevel)
719  aCollections[nLevel].clear();
720 
721  nDepth = 0;
722 }
723 
725 {
726  ScSubOutlineIterator aIter( this );
727  ScOutlineEntry* pEntry;
728  while((pEntry=aIter.GetNext())!=nullptr)
729  {
730 
731  if (!pEntry->IsHidden())
732  continue;
733 
734  SCCOLROW nEntryStart = pEntry->GetStart();
735  SCCOLROW nEntryEnd = pEntry->GetEnd();
736  SCCOLROW nEnd = rTable.LastHiddenColRow(nEntryStart, false/*bCol*/);
737  bool bAllHidden = (nEntryEnd <= nEnd && nEnd <
738  ::std::numeric_limits<SCCOLROW>::max());
739 
740  pEntry->SetHidden(bAllHidden);
741  SetVisibleBelow(aIter.LastLevel(), aIter.LastEntry(), !bAllHidden, !bAllHidden);
742  }
743 }
744 
746 {
747  OString aOutput;
748  const char* const pLevelSep = " ";
749  for (const auto& rCollection : aCollections)
750  {
751  if (rCollection.empty())
752  continue;
753  aOutput += rCollection.dumpAsString() + pLevelSep;
754  }
755 
756  return aOutput;
757 }
758 
760 {
761 }
762 
764  aColOutline( rOutline.aColOutline ),
765  aRowOutline( rOutline.aRowOutline )
766 {
767 }
768 
770 {
771  return aColOutline.TestInsertSpace( nSize, MAXCOL );
772 }
773 
774 void ScOutlineTable::InsertCol( SCCOL nStartCol, SCSIZE nSize )
775 {
776  aColOutline.InsertSpace( nStartCol, nSize );
777 }
778 
779 bool ScOutlineTable::DeleteCol( SCCOL nStartCol, SCSIZE nSize )
780 {
781  return aColOutline.DeleteSpace( nStartCol, nSize );
782 }
783 
785 {
786  return aRowOutline.TestInsertSpace( nSize, MAXROW );
787 }
788 
789 void ScOutlineTable::InsertRow( SCROW nStartRow, SCSIZE nSize )
790 {
791  aRowOutline.InsertSpace( nStartRow, nSize );
792 }
793 
794 bool ScOutlineTable::DeleteRow( SCROW nStartRow, SCSIZE nSize )
795 {
796  return aRowOutline.DeleteSpace( nStartRow, nSize );
797 }
798 
800  pArray( pOutlineArray ),
801  nStart( 0 ),
802  nEnd( SCCOLROW_MAX ), // Iterate over all of them
803  nSubLevel( 0 ),
804  nSubEntry( 0 )
805 {
806  nDepth = pArray->nDepth;
807 }
808 
810  ScOutlineArray* pOutlineArray, size_t nLevel, size_t nEntry ) :
811  pArray( pOutlineArray )
812 {
813  const ScOutlineCollection& rColl = pArray->aCollections[nLevel];
815  std::advance(it, nEntry);
816  const ScOutlineEntry* pEntry = &it->second;
817  nStart = pEntry->GetStart();
818  nEnd = pEntry->GetEnd();
819  nSubLevel = nLevel + 1;
820  nSubEntry = 0;
821  nDepth = pArray->nDepth;
822 }
823 
825 {
826  ScOutlineEntry* pEntry = nullptr;
827  bool bFound = false;
828  do
829  {
830  if (nSubLevel >= nDepth)
831  return nullptr;
832 
834  if (nSubEntry < rColl.size())
835  {
837  std::advance(it, nSubEntry);
838  pEntry = &it->second;
839 
840  if (pEntry->GetStart() >= nStart && pEntry->GetEnd() <= nEnd)
841  bFound = true;
842 
843  ++nSubEntry;
844  }
845  else
846  {
847  // Go to the next sub-level
848  nSubEntry = 0;
849  ++nSubLevel;
850  }
851  }
852  while (!bFound);
853  return pEntry; // nSubLevel valid, if pEntry != 0
854 }
855 
857 {
858  if (nSubEntry == 0)
859  {
860  OSL_FAIL("ScSubOutlineIterator::LastEntry before GetNext");
861  return 0;
862  }
863  return nSubEntry-1;
864 }
865 
867 {
868  if (nSubLevel >= nDepth)
869  {
870  OSL_FAIL("ScSubOutlineIterator::DeleteLast after End");
871  return;
872  }
873  if (nSubEntry == 0)
874  {
875  OSL_FAIL("ScSubOutlineIterator::DeleteLast before GetNext");
876  return;
877  }
878 
879  --nSubEntry;
881  assert(nSubEntry < rColl.size());
883  std::advance(it, nSubEntry);
884  rColl.erase(it);
885 }
886 
887 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void ExtendBlock(size_t nLevel, SCCOLROW &rBlkStart, SCCOLROW &rBlkEnd)
Definition: olinetab.cxx:583
void InsertRow(SCROW nStartRow, SCSIZE nSize)
Definition: olinetab.cxx:789
sal_Int32 nIndex
bool bVisible
size_t nDepth
Definition: olinetab.hxx:97
SC_DLLPUBLIC bool IsHidden() const
Definition: olinetab.hxx:50
void Move(SCCOLROW nDelta)
Definition: olinetab.cxx:47
const SCCOLROW SCCOLROW_MAX
Definition: address.hxx:59
bool TestInsertRow(SCSIZE nSize)
Definition: olinetab.cxx:784
ScOutlineEntry(SCCOLROW nNewStart, SCCOLROW nNewSize, bool bNewHidden)
Definition: olinetab.cxx:26
void FindEntry(SCCOLROW nSearchPos, size_t &rFindLevel, size_t &rFindIndex, size_t nMaxLevel=SC_OL_MAXDEPTH)
Definition: olinetab.cxx:171
SC_DLLPUBLIC SCCOLROW GetEnd() const
Definition: olinetab.cxx:42
OString dumpAsString() const
Definition: olinetab.cxx:84
OString dumpAsString() const
Definition: olinetab.cxx:144
ScOutlineArray * pArray
Definition: olinetab.hxx:175
void RemoveAll()
Definition: olinetab.cxx:716
ScOutlineEntry * GetEntry(size_t nLevel, size_t nIndex)
Definition: olinetab.cxx:442
SCCOLROW LastHiddenColRow(SCCOLROW nPos, bool bCol) const
Definition: table5.cxx:766
void SetSize(SCSIZE nNewSize)
Definition: olinetab.cxx:58
void finalizeImport(const ScTable &rTable)
Definition: olinetab.cxx:724
void erase(const iterator &pos)
Definition: olinetab.cxx:129
const ScOutlineEntry * GetEntryByPos(size_t nLevel, SCCOLROW nPos) const
Definition: olinetab.cxx:478
size_t LastEntry() const
Definition: olinetab.cxx:856
ScOutlineCollection aCollections[SC_OL_MAXDEPTH]
Definition: olinetab.hxx:98
void SetVisible(bool bNewVisible)
Definition: olinetab.cxx:79
bool GetEntryIndex(size_t nLevel, SCCOLROW nPos, size_t &rnIndex) const
Definition: olinetab.cxx:495
bool DeleteSpace(SCCOLROW nStartPos, SCSIZE nSize)
Definition: olinetab.cxx:640
bool TestInsertSpace(SCSIZE nSize, SCCOLROW nMaxVal) const
Definition: olinetab.cxx:605
OString dumpAsString() const
Definition: olinetab.cxx:745
bool GetEntryIndexInRange(size_t nLevel, SCCOLROW nBlockStart, SCCOLROW nBlockEnd, size_t &rnIndex) const
Definition: olinetab.cxx:515
size_t SCSIZE
size_t typedef to be able to find places where code was changed from USHORT to size_t and is used to ...
Definition: address.hxx:45
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
sal_Int32 SCCOLROW
a type capable of holding either SCCOL or SCROW
Definition: types.hxx:24
const SCROW MAXROW
Definition: address.hxx:69
iterator begin()
Definition: olinetab.cxx:109
void InsertSpace(SCCOLROW nStartPos, SCSIZE nSize)
Definition: olinetab.cxx:617
bool DecDepth()
Adapt nDepth for empty Levels.
Definition: olinetab.cxx:387
void GetRange(SCCOLROW &rStart, SCCOLROW &rEnd) const
Definition: olinetab.cxx:569
SCSIZE GetSize() const
Definition: olinetab.hxx:44
MapType::iterator iterator
Definition: olinetab.hxx:72
void PromoteSub(SCCOLROW nStartPos, SCCOLROW nEndPos, size_t nStartLevel)
Definition: olinetab.cxx:327
SC_DLLPUBLIC SCCOLROW GetStart() const
Definition: olinetab.hxx:43
ScOutlineArray aColOutline
Definition: olinetab.hxx:152
ScSubOutlineIterator(ScOutlineArray *pOutlineArray)
Definition: olinetab.cxx:799
sal_Int16 SCCOL
Definition: types.hxx:22
size_t GetCount(size_t nLevel) const
Definition: olinetab.cxx:470
const SCCOL MAXCOL
Definition: address.hxx:70
ScOutlineArray aRowOutline
Definition: olinetab.hxx:153
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
bool DeleteCol(SCCOL nStartCol, SCSIZE nSize)
Definition: olinetab.cxx:779
iterator FindStart(SCCOLROW nMinStart)
Definition: olinetab.cxx:139
SCCOLROW nStart
Definition: olinetab.hxx:34
bool DeleteRow(SCROW nStartRow, SCSIZE nSize)
Definition: olinetab.cxx:794
sal_Int32 SCROW
Definition: types.hxx:18
void insert(ScOutlineEntry const &rEntry)
Definition: olinetab.cxx:103
ScOutlineEntry * GetNext()
Definition: olinetab.cxx:824
void InsertCol(SCCOL nStartCol, SCSIZE nSize)
Definition: olinetab.cxx:774
size_t LastLevel() const
Definition: olinetab.hxx:187
bool TestInsertCol(SCSIZE nSize)
Definition: olinetab.cxx:769
void SetPosSize(SCCOLROW nNewPos, SCSIZE nNewSize)
Definition: olinetab.cxx:68
void * p
bool ManualAction(SCCOLROW nStartPos, SCCOLROW nEndPos, bool bShow, const ScTable &rTable, bool bCol)
Definition: olinetab.cxx:682
MapType::const_iterator const_iterator
Definition: olinetab.hxx:73
bool empty() const
Definition: olinetab.cxx:134
bool FindTouchedLevel(SCCOLROW nBlockStart, SCCOLROW nBlockEnd, size_t &rFindLevel) const
Definition: olinetab.cxx:300
SCSIZE nSize
Definition: olinetab.hxx:35
size_t size() const
Definition: olinetab.cxx:93
bool Insert(SCCOLROW nStartPos, SCCOLROW nEndPos, bool &rSizeChanged, bool bHidden=false)
Definition: olinetab.cxx:197
#define SC_OL_MAXDEPTH
Definition: olinetab.hxx:28
sal_uInt16 nPos