xref: /AOO41X/main/sc/source/ui/docshell/olinefun.cxx (revision b3f79822e811ac3493b185030a72c3c5a51f32d8)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 
28 
29 // INCLUDE ---------------------------------------------------------------
30 
31 #include <vcl/sound.hxx>
32 #include <sfx2/bindings.hxx>
33 
34 #include "olinefun.hxx"
35 
36 #include "docsh.hxx"
37 #include "olinetab.hxx"
38 #include "undodat.hxx"
39 #include "globstr.hrc"
40 #include "sc.hrc"
41 
42 
43 //========================================================================
44 
lcl_InvalidateOutliner(SfxBindings * pBindings)45 void lcl_InvalidateOutliner( SfxBindings* pBindings )
46 {
47     if ( pBindings )
48     {
49         pBindings->Invalidate( SID_OUTLINE_SHOW );
50         pBindings->Invalidate( SID_OUTLINE_HIDE );
51         pBindings->Invalidate( SID_OUTLINE_REMOVE );
52 
53         pBindings->Invalidate( SID_STATUS_SUM );            // wegen ein-/ausblenden
54         pBindings->Invalidate( SID_ATTR_SIZE );
55     }
56 }
57 
58 //------------------------------------------------------------------------
59 
60 //! PaintWidthHeight zur DocShell verschieben?
61 
lcl_PaintWidthHeight(ScDocShell & rDocShell,SCTAB nTab,sal_Bool bColumns,SCCOLROW nStart,SCCOLROW nEnd)62 void lcl_PaintWidthHeight( ScDocShell& rDocShell, SCTAB nTab,
63                                     sal_Bool bColumns, SCCOLROW nStart, SCCOLROW nEnd )
64 {
65     ScDocument* pDoc = rDocShell.GetDocument();
66 
67     sal_uInt16 nParts = PAINT_GRID;
68     SCCOL nStartCol = 0;
69     SCROW nStartRow = 0;
70     SCCOL nEndCol = MAXCOL;         // fuer Test auf Merge
71     SCROW nEndRow = MAXROW;
72     if ( bColumns )
73     {
74         nParts |= PAINT_TOP;
75         nStartCol = static_cast<SCCOL>(nStart);
76         nEndCol = static_cast<SCCOL>(nEnd);
77     }
78     else
79     {
80         nParts |= PAINT_LEFT;
81         nStartRow = nStart;
82         nEndRow = nEnd;
83     }
84     if (pDoc->HasAttrib( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
85                             HASATTR_MERGED | HASATTR_OVERLAPPED ))
86     {
87         nStartCol = 0;
88         nStartRow = 0;
89     }
90     rDocShell.PostPaint( nStartCol,nStartRow,nTab, MAXCOL,MAXROW,nTab, nParts );
91 }
92 
93 //------------------------------------------------------------------------
94 
MakeOutline(const ScRange & rRange,sal_Bool bColumns,sal_Bool bRecord,sal_Bool bApi)95 sal_Bool ScOutlineDocFunc::MakeOutline( const ScRange& rRange, sal_Bool bColumns, sal_Bool bRecord, sal_Bool bApi )
96 {
97     sal_Bool bSuccess = sal_False;
98     SCCOL nStartCol = rRange.aStart.Col();
99     SCROW nStartRow = rRange.aStart.Row();
100     SCCOL nEndCol = rRange.aEnd.Col();
101     SCROW nEndRow = rRange.aEnd.Row();
102     SCTAB nTab = rRange.aStart.Tab();
103 
104     ScDocument* pDoc = rDocShell.GetDocument();
105     ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab, sal_True );
106     ScOutlineTable* pUndoTab = NULL;
107 
108     if (bRecord && !pDoc->IsUndoEnabled())
109         bRecord = sal_False;
110 
111     if (bRecord)
112         pUndoTab = new ScOutlineTable( *pTable );
113 
114     ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
115 
116     sal_Bool bRes;
117     sal_Bool bSize = sal_False;
118     if ( bColumns )
119         bRes = pArray->Insert( nStartCol, nEndCol, bSize );
120     else
121         bRes = pArray->Insert( nStartRow, nEndRow, bSize );
122 
123     if ( bRes )
124     {
125         if (bRecord)
126         {
127             rDocShell.GetUndoManager()->AddUndoAction(
128                 new ScUndoMakeOutline( &rDocShell,
129                                         nStartCol,nStartRow,nTab,nEndCol,nEndRow,nTab,
130                                         pUndoTab, bColumns, sal_True ) );
131         }
132 
133         if (pDoc->IsStreamValid(nTab))
134             pDoc->SetStreamValid(nTab, sal_False);
135 
136         sal_uInt16 nParts = 0;              // Datenbereich nicht geaendert
137         if ( bColumns )
138             nParts |= PAINT_TOP;
139         else
140             nParts |= PAINT_LEFT;
141         if ( bSize )
142             nParts |= PAINT_SIZE;
143 
144         rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, nParts );
145         rDocShell.SetDocumentModified();
146         lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
147         bSuccess = sal_True;
148     }
149     else
150     {
151         if (!bApi)
152             rDocShell.ErrorMessage(STR_MSSG_MAKEOUTLINE_0); // "Gruppierung nicht moeglich"
153         delete pUndoTab;
154     }
155 
156     return bSuccess;
157 }
158 
RemoveOutline(const ScRange & rRange,sal_Bool bColumns,sal_Bool bRecord,sal_Bool bApi)159 sal_Bool ScOutlineDocFunc::RemoveOutline( const ScRange& rRange, sal_Bool bColumns, sal_Bool bRecord, sal_Bool bApi )
160 {
161     sal_Bool bDone = sal_False;
162 
163     SCCOL nStartCol = rRange.aStart.Col();
164     SCROW nStartRow = rRange.aStart.Row();
165     SCCOL nEndCol = rRange.aEnd.Col();
166     SCROW nEndRow = rRange.aEnd.Row();
167     SCTAB nTab = rRange.aStart.Tab();
168 
169     ScDocument* pDoc = rDocShell.GetDocument();
170 
171     if (bRecord && !pDoc->IsUndoEnabled())
172         bRecord = sal_False;
173     ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
174     if (pTable)
175     {
176         ScOutlineTable* pUndoTab = NULL;
177         if (bRecord)
178             pUndoTab = new ScOutlineTable( *pTable );
179 
180         ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
181 
182         sal_Bool bRes;
183         sal_Bool bSize = sal_False;
184         if ( bColumns )
185             bRes = pArray->Remove( nStartCol, nEndCol, bSize );
186         else
187             bRes = pArray->Remove( nStartRow, nEndRow, bSize );
188 
189         if ( bRes )
190         {
191             if (bRecord)
192             {
193                 rDocShell.GetUndoManager()->AddUndoAction(
194                     new ScUndoMakeOutline( &rDocShell,
195                                             nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
196                                             pUndoTab, bColumns, sal_False ) );
197             }
198 
199             if (pDoc->IsStreamValid(nTab))
200                 pDoc->SetStreamValid(nTab, sal_False);
201 
202             sal_uInt16 nParts = 0;              // Datenbereich nicht geaendert
203             if ( bColumns )
204                 nParts |= PAINT_TOP;
205             else
206                 nParts |= PAINT_LEFT;
207             if ( bSize )
208                 nParts |= PAINT_SIZE;
209 
210             rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, nParts );
211             rDocShell.SetDocumentModified();
212             bDone = sal_True;
213             lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
214 
215             // es wird nicht wieder eingeblendet -> kein UpdatePageBreaks
216         }
217         else
218             delete pUndoTab;
219     }
220 
221     if (!bDone && !bApi)
222         rDocShell.ErrorMessage(STR_MSSG_REMOVEOUTLINE_0);   // "Aufheben nicht moeglich"
223 
224     return bDone;
225 }
226 
RemoveAllOutlines(SCTAB nTab,sal_Bool bRecord,sal_Bool bApi)227 sal_Bool ScOutlineDocFunc::RemoveAllOutlines( SCTAB nTab, sal_Bool bRecord, sal_Bool bApi )
228 {
229     sal_Bool bSuccess = sal_False;
230     ScDocument* pDoc = rDocShell.GetDocument();
231 
232     if (bRecord && !pDoc->IsUndoEnabled())
233         bRecord = sal_False;
234     ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
235     if (pTable)
236     {
237         if (bRecord)
238         {
239             SCCOLROW nCol1, nCol2, nRow1, nRow2;
240             pTable->GetColArray()->GetRange( nCol1, nCol2 );
241             pTable->GetRowArray()->GetRange( nRow1, nRow2 );
242             SCCOL nStartCol = static_cast<SCCOL>(nCol1);
243             SCROW nStartRow = nRow1;
244             SCCOL nEndCol = static_cast<SCCOL>(nCol2);
245             SCROW nEndRow = nRow2;
246 
247             ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
248             pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
249             pDoc->CopyToDocument( nStartCol, 0, nTab, nEndCol, MAXROW, nTab, IDF_NONE, sal_False, pUndoDoc );
250             pDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, sal_False, pUndoDoc );
251 
252             ScOutlineTable* pUndoTab = new ScOutlineTable( *pTable );
253 
254             rDocShell.GetUndoManager()->AddUndoAction(
255                 new ScUndoRemoveAllOutlines( &rDocShell,
256                                                 nStartCol, nStartRow, nTab,
257                                                 nEndCol, nEndRow, nTab,
258                                                 pUndoDoc, pUndoTab ) );
259         }
260 
261         SelectLevel( nTab, sal_True,  pTable->GetColArray()->GetDepth(), sal_False, sal_False, bApi );
262         SelectLevel( nTab, sal_False, pTable->GetRowArray()->GetDepth(), sal_False, sal_False, bApi );
263         pDoc->SetOutlineTable( nTab, NULL );
264 
265         pDoc->UpdatePageBreaks( nTab );
266 
267         if (pDoc->IsStreamValid(nTab))
268             pDoc->SetStreamValid(nTab, sal_False);
269 
270         rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab,
271                                     PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE );
272         rDocShell.SetDocumentModified();
273         lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
274         bSuccess = sal_True;
275     }
276     else if (!bApi)
277         Sound::Beep();
278 
279     return bSuccess;
280 }
281 
282 //------------------------------------------------------------------------
283 
AutoOutline(const ScRange & rRange,sal_Bool bRecord,sal_Bool bApi)284 sal_Bool ScOutlineDocFunc::AutoOutline( const ScRange& rRange, sal_Bool bRecord, sal_Bool bApi )
285 {
286     SCCOL nStartCol = rRange.aStart.Col();
287     SCROW nStartRow = rRange.aStart.Row();
288     SCCOL nEndCol = rRange.aEnd.Col();
289     SCROW nEndRow = rRange.aEnd.Row();
290     SCTAB nTab = rRange.aStart.Tab();
291 
292     ScDocument* pDoc = rDocShell.GetDocument();
293 
294     if (bRecord && !pDoc->IsUndoEnabled())
295         bRecord = sal_False;
296     ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
297 
298     ScDocument* pUndoDoc = NULL;
299     ScOutlineTable* pUndoTab = NULL;
300 
301     if ( pTable )
302     {
303         if ( bRecord )
304         {
305             pUndoTab = new ScOutlineTable( *pTable );
306 
307             SCCOLROW nCol1, nCol2, nRow1, nRow2;
308             pTable->GetColArray()->GetRange( nCol1, nCol2 );
309             pTable->GetRowArray()->GetRange( nRow1, nRow2 );
310             SCCOL nOutStartCol = static_cast<SCCOL>(nCol1);;
311             SCROW nOutStartRow = nRow1;
312             SCCOL nOutEndCol = static_cast<SCCOL>(nCol2);;
313             SCROW nOutEndRow = nRow2;
314 
315             pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
316             pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
317             pDoc->CopyToDocument( nOutStartCol, 0, nTab, nOutEndCol, MAXROW, nTab, IDF_NONE, sal_False, pUndoDoc );
318             pDoc->CopyToDocument( 0, nOutStartRow, nTab, MAXCOL, nOutEndRow, nTab, IDF_NONE, sal_False, pUndoDoc );
319         }
320 
321         // einblenden
322         SelectLevel( nTab, sal_True,  pTable->GetColArray()->GetDepth(), sal_False, sal_False, bApi );
323         SelectLevel( nTab, sal_False, pTable->GetRowArray()->GetDepth(), sal_False, sal_False, bApi );
324         pDoc->SetOutlineTable( nTab, NULL );
325     }
326 
327     pDoc->DoAutoOutline( nStartCol,nStartRow, nEndCol,nEndRow, nTab );
328 
329     if (bRecord)
330     {
331         rDocShell.GetUndoManager()->AddUndoAction(
332             new ScUndoAutoOutline( &rDocShell,
333                                     nStartCol, nStartRow, nTab,
334                                     nEndCol, nEndRow, nTab,
335                                     pUndoDoc, pUndoTab ) );
336     }
337 
338     if (pDoc->IsStreamValid(nTab))
339         pDoc->SetStreamValid(nTab, sal_False);
340 
341     rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_LEFT | PAINT_TOP | PAINT_SIZE );
342     rDocShell.SetDocumentModified();
343     lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
344 
345     return sal_True;
346 }
347 
348 //------------------------------------------------------------------------
349 
SelectLevel(SCTAB nTab,sal_Bool bColumns,sal_uInt16 nLevel,sal_Bool bRecord,sal_Bool bPaint,sal_Bool)350 sal_Bool ScOutlineDocFunc::SelectLevel( SCTAB nTab, sal_Bool bColumns, sal_uInt16 nLevel,
351                                     sal_Bool bRecord, sal_Bool bPaint, sal_Bool /* bApi */ )
352 {
353     ScDocument* pDoc = rDocShell.GetDocument();
354 
355     if (bRecord && !pDoc->IsUndoEnabled())
356         bRecord = sal_False;
357     ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );             // ist schon da
358     if (!pTable)
359         return sal_False;
360     ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
361     if (!pArray)
362         return sal_False;
363 
364     SCCOLROW nStart, nEnd;
365     pArray->GetRange( nStart, nEnd );
366 
367     if ( bRecord )
368     {
369         ScOutlineTable* pUndoTab = new ScOutlineTable( *pTable );
370         ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
371         if (bColumns)
372         {
373             pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_False );
374             pDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab,
375                     static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, sal_False,
376                     pUndoDoc );
377         }
378         else
379         {
380             pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, sal_True );
381             pDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, sal_False, pUndoDoc );
382         }
383 
384         rDocShell.GetUndoManager()->AddUndoAction(
385             new ScUndoOutlineLevel( &rDocShell,
386                                     nStart, nEnd, nTab,             //! start und end berechnen
387                                     pUndoDoc, pUndoTab,
388                                     bColumns, nLevel ) );
389     }
390 
391     pDoc->IncSizeRecalcLevel( nTab );
392 
393     ScSubOutlineIterator aIter( pArray );                   // alle Eintraege
394     ScOutlineEntry* pEntry;
395     while ((pEntry=aIter.GetNext()) != NULL)
396     {
397         sal_uInt16 nThisLevel = aIter.LastLevel();
398         sal_Bool bShow = (nThisLevel < nLevel);
399         if (bShow)                                          // einblenden
400         {
401             pEntry->SetHidden( sal_False );
402             pEntry->SetVisible( sal_True );
403         }
404         else if ( nThisLevel == nLevel )                    // ausblenden
405         {
406             pEntry->SetHidden( sal_True );
407             pEntry->SetVisible( sal_True );
408         }
409         else                                                // verdeckt
410         {
411             pEntry->SetVisible( sal_False );
412         }
413 
414         SCCOLROW nThisStart = pEntry->GetStart();
415         SCCOLROW nThisEnd   = pEntry->GetEnd();
416         for (SCCOLROW i=nThisStart; i<=nThisEnd; i++)
417         {
418             if ( bColumns )
419                 pDoc->ShowCol( static_cast<SCCOL>(i), nTab, bShow );
420             else
421             {
422                 // show several rows together, don't show filtered rows
423                 SCROW nFilterEnd = i;
424                 bool bFiltered = pDoc->RowFiltered( i, nTab, NULL, &nFilterEnd );
425                 nFilterEnd = std::min( nThisEnd, nFilterEnd );
426                 if ( !bShow || !bFiltered )
427                     pDoc->ShowRows( i, nFilterEnd, nTab, bShow );
428                 i = nFilterEnd;
429             }
430         }
431     }
432 
433     pDoc->DecSizeRecalcLevel( nTab );
434     pDoc->UpdatePageBreaks( nTab );
435 
436     if (bPaint)
437         lcl_PaintWidthHeight( rDocShell, nTab, bColumns, nStart, nEnd );
438 
439     rDocShell.SetDocumentModified();
440     lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
441 
442     return sal_True;
443 }
444 
445 //------------------------------------------------------------------------
446 
ShowMarkedOutlines(const ScRange & rRange,sal_Bool bRecord,sal_Bool bApi)447 sal_Bool ScOutlineDocFunc::ShowMarkedOutlines( const ScRange& rRange, sal_Bool bRecord, sal_Bool bApi )
448 {
449     sal_Bool bDone = sal_False;
450 
451     SCCOL nStartCol = rRange.aStart.Col();
452     SCROW nStartRow = rRange.aStart.Row();
453     SCCOL nEndCol = rRange.aEnd.Col();
454     SCROW nEndRow = rRange.aEnd.Row();
455     SCTAB nTab = rRange.aStart.Tab();
456 
457     ScDocument* pDoc = rDocShell.GetDocument();
458 
459     if (bRecord && !pDoc->IsUndoEnabled())
460         bRecord = sal_False;
461     ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
462 
463     if (pTable)
464     {
465         ScOutlineArray* pArray;
466         ScOutlineEntry* pEntry;
467         SCCOLROW nStart;
468         SCCOLROW nEnd;
469         SCCOLROW nMin;
470         SCCOLROW nMax;
471         SCCOLROW i;
472 
473         if ( bRecord )
474         {
475             ScOutlineTable* pUndoTab = new ScOutlineTable( *pTable );
476             ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
477             pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
478             pDoc->CopyToDocument( nStartCol, 0, nTab, nEndCol, MAXROW, nTab, IDF_NONE, sal_False, pUndoDoc );
479             pDoc->CopyToDocument( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab, IDF_NONE, sal_False, pUndoDoc );
480 
481             rDocShell.GetUndoManager()->AddUndoAction(
482                 new ScUndoOutlineBlock( &rDocShell,
483                                         nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
484                                         pUndoDoc, pUndoTab, sal_True ) );
485         }
486 
487         pDoc->IncSizeRecalcLevel( nTab );
488 
489         //  Spalten
490 
491         nMin=MAXCOL;
492         nMax=0;
493         pArray = pTable->GetColArray();
494         ScSubOutlineIterator aColIter( pArray );
495         while ((pEntry=aColIter.GetNext()) != NULL)
496         {
497             nStart = pEntry->GetStart();
498             nEnd   = pEntry->GetEnd();
499             if ( nStart>=nStartCol && nEnd<=nEndCol )
500             {
501                 pEntry->SetHidden( sal_False );
502                 pEntry->SetVisible( sal_True );
503                 if (nStart<nMin) nMin=nStart;
504                 if (nEnd>nMax) nMax=nEnd;
505             }
506         }
507         for ( i=nMin; i<=nMax; i++ )
508             pDoc->ShowCol( static_cast<SCCOL>(i), nTab, sal_True );
509 
510         //  Zeilen
511 
512         nMin=MAXROW;
513         nMax=0;
514         pArray = pTable->GetRowArray();
515         ScSubOutlineIterator aRowIter( pArray );
516         while ((pEntry=aRowIter.GetNext()) != NULL)
517         {
518             nStart = pEntry->GetStart();
519             nEnd   = pEntry->GetEnd();
520             if ( nStart>=nStartRow && nEnd<=nEndRow )
521             {
522                 pEntry->SetHidden( sal_False );
523                 pEntry->SetVisible( sal_True );
524                 if (nStart<nMin) nMin=nStart;
525                 if (nEnd>nMax) nMax=nEnd;
526             }
527         }
528         for ( i=nMin; i<=nMax; i++ )
529         {
530             // show several rows together, don't show filtered rows
531             SCROW nFilterEnd = i;
532             bool bFiltered = pDoc->RowFiltered( i, nTab, NULL, &nFilterEnd );
533             nFilterEnd = std::min( nMax, nFilterEnd );
534             if ( !bFiltered )
535                 pDoc->ShowRows( i, nFilterEnd, nTab, sal_True );
536             i = nFilterEnd;
537         }
538 
539         pDoc->DecSizeRecalcLevel( nTab );
540         pDoc->UpdatePageBreaks( nTab );
541 
542         rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_LEFT | PAINT_TOP );
543 
544         rDocShell.SetDocumentModified();
545         bDone = sal_True;
546 
547         lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
548     }
549 
550     if (!bDone && !bApi)
551         Sound::Beep();
552 
553     return bDone;
554 }
555 
HideMarkedOutlines(const ScRange & rRange,sal_Bool bRecord,sal_Bool bApi)556 sal_Bool ScOutlineDocFunc::HideMarkedOutlines( const ScRange& rRange, sal_Bool bRecord, sal_Bool bApi )
557 {
558     sal_Bool bDone = sal_False;
559 
560     SCCOL nStartCol = rRange.aStart.Col();
561     SCROW nStartRow = rRange.aStart.Row();
562     SCCOL nEndCol = rRange.aEnd.Col();
563     SCROW nEndRow = rRange.aEnd.Row();
564     SCTAB nTab = rRange.aStart.Tab();
565 
566     ScDocument* pDoc = rDocShell.GetDocument();
567 
568     if (bRecord && !pDoc->IsUndoEnabled())
569         bRecord = sal_False;
570     ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
571 
572     if (pTable)
573     {
574         ScOutlineEntry* pEntry;
575         sal_uInt16 nColLevel;
576         sal_uInt16 nRowLevel;
577         sal_uInt16 nCount;
578         SCCOLROW nStart;
579         SCCOLROW nEnd;
580         sal_uInt16 i;
581 
582         SCCOLROW nEffStartCol = nStartCol;
583         SCCOLROW nEffEndCol   = nEndCol;
584         ScOutlineArray* pColArray = pTable->GetColArray();
585         pColArray->FindTouchedLevel( nStartCol, nEndCol, nColLevel );
586         pColArray->ExtendBlock( nColLevel, nEffStartCol, nEffEndCol );
587         SCCOLROW nEffStartRow = nStartRow;
588         SCCOLROW nEffEndRow   = nEndRow;
589         ScOutlineArray* pRowArray = pTable->GetRowArray();
590         pRowArray->FindTouchedLevel( nStartRow, nEndRow, nRowLevel );
591         pRowArray->ExtendBlock( nRowLevel, nEffStartRow, nEffEndRow );
592 
593         if ( bRecord )
594         {
595             ScOutlineTable* pUndoTab = new ScOutlineTable( *pTable );
596             ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
597             pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
598             pDoc->CopyToDocument( static_cast<SCCOL>(nEffStartCol), 0, nTab,
599                     static_cast<SCCOL>(nEffEndCol), MAXROW, nTab, IDF_NONE,
600                     sal_False, pUndoDoc );
601             pDoc->CopyToDocument( 0, nEffStartRow, nTab, MAXCOL, nEffEndRow, nTab, IDF_NONE, sal_False, pUndoDoc );
602 
603             rDocShell.GetUndoManager()->AddUndoAction(
604                 new ScUndoOutlineBlock( &rDocShell,
605                                         nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
606                                         pUndoDoc, pUndoTab, sal_False ) );
607         }
608 
609         pDoc->IncSizeRecalcLevel( nTab );
610 
611         //  Spalten
612 
613         nCount = pColArray->GetCount(nColLevel);
614         for ( i=0; i<nCount; i++ )
615         {
616             pEntry = pColArray->GetEntry(nColLevel,i);
617             nStart = pEntry->GetStart();
618             nEnd   = pEntry->GetEnd();
619 
620             if ( static_cast<SCCOLROW>(nStartCol)<=nEnd && static_cast<SCCOLROW>(nEndCol)>=nStart )
621                 HideOutline( nTab, sal_True, nColLevel, i, sal_False, sal_False, bApi );
622         }
623 
624         //  Zeilen
625 
626         nCount = pRowArray->GetCount(nRowLevel);
627         for ( i=0; i<nCount; i++ )
628         {
629             pEntry = pRowArray->GetEntry(nRowLevel,i);
630             nStart = pEntry->GetStart();
631             nEnd   = pEntry->GetEnd();
632 
633             if ( nStartRow<=nEnd && nEndRow>=nStart )
634                 HideOutline( nTab, sal_False, nRowLevel, i, sal_False, sal_False, bApi );
635         }
636 
637         pDoc->DecSizeRecalcLevel( nTab );
638         pDoc->UpdatePageBreaks( nTab );
639 
640         rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID | PAINT_LEFT | PAINT_TOP );
641 
642         rDocShell.SetDocumentModified();
643         bDone = sal_True;
644 
645         lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
646     }
647 
648     if (!bDone && !bApi)
649         Sound::Beep();
650 
651     return bDone;
652 }
653 
654 //------------------------------------------------------------------------
655 
ShowOutline(SCTAB nTab,sal_Bool bColumns,sal_uInt16 nLevel,sal_uInt16 nEntry,sal_Bool bRecord,sal_Bool bPaint,sal_Bool)656 sal_Bool ScOutlineDocFunc::ShowOutline( SCTAB nTab, sal_Bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry,
657                                     sal_Bool bRecord, sal_Bool bPaint, sal_Bool /* bApi */ )
658 {
659     ScDocument* pDoc = rDocShell.GetDocument();
660     if (bRecord && !pDoc->IsUndoEnabled())
661         bRecord = sal_False;
662 
663     ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
664     ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
665     ScOutlineEntry* pEntry = pArray->GetEntry( nLevel, nEntry );
666     SCCOLROW nStart = pEntry->GetStart();
667     SCCOLROW nEnd   = pEntry->GetEnd();
668 
669     if ( bRecord )
670     {
671         ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
672         if (bColumns)
673         {
674             pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_False );
675             pDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab,
676                     static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, sal_False,
677                     pUndoDoc );
678         }
679         else
680         {
681             pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, sal_True );
682             pDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, sal_False, pUndoDoc );
683         }
684 
685         rDocShell.GetUndoManager()->AddUndoAction(
686             new ScUndoDoOutline( &rDocShell,
687                                     nStart, nEnd, nTab, pUndoDoc,       //! start und end berechnen
688                                     bColumns, nLevel, nEntry, sal_True ) );
689     }
690 
691 //! HideCursor();
692 
693     pDoc->IncSizeRecalcLevel( nTab );
694 
695     pEntry->SetHidden(sal_False);
696     SCCOLROW i;
697     for ( i = nStart; i <= nEnd; i++ )
698     {
699         if ( bColumns )
700             pDoc->ShowCol( static_cast<SCCOL>(i), nTab, sal_True );
701         else
702         {
703             // show several rows together, don't show filtered rows
704             SCROW nFilterEnd = i;
705             bool bFiltered = pDoc->RowFiltered( i, nTab, NULL, &nFilterEnd );
706             nFilterEnd = std::min( nEnd, nFilterEnd );
707             if ( !bFiltered )
708                 pDoc->ShowRows( i, nFilterEnd, nTab, sal_True );
709             i = nFilterEnd;
710         }
711     }
712 
713     ScSubOutlineIterator aIter( pArray, nLevel, nEntry );
714     while ((pEntry=aIter.GetNext()) != NULL)
715     {
716         if ( pEntry->IsHidden() )
717         {
718             SCCOLROW nSubStart = pEntry->GetStart();
719             SCCOLROW nSubEnd   = pEntry->GetEnd();
720             if ( bColumns )
721                 for ( i = nSubStart; i <= nSubEnd; i++ )
722                     pDoc->ShowCol( static_cast<SCCOL>(i), nTab, sal_False );
723             else
724                 pDoc->ShowRows( nSubStart, nSubEnd, nTab, sal_False );
725         }
726     }
727 
728     pArray->SetVisibleBelow( nLevel, nEntry, sal_True, sal_True );
729 
730     pDoc->DecSizeRecalcLevel( nTab );
731     pDoc->InvalidatePageBreaks(nTab);
732     pDoc->UpdatePageBreaks( nTab );
733 
734     if (bPaint)
735         lcl_PaintWidthHeight( rDocShell, nTab, bColumns, nStart, nEnd );
736 
737 //! ShowCursor();
738     rDocShell.SetDocumentModified();
739 
740 //! if (bPaint)
741 //!     UpdateScrollBars();
742 
743     lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
744 
745     return sal_True;        //! immer ???
746 }
747 
HideOutline(SCTAB nTab,sal_Bool bColumns,sal_uInt16 nLevel,sal_uInt16 nEntry,sal_Bool bRecord,sal_Bool bPaint,sal_Bool)748 sal_Bool ScOutlineDocFunc::HideOutline( SCTAB nTab, sal_Bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry,
749                                     sal_Bool bRecord, sal_Bool bPaint, sal_Bool /* bApi */ )
750 {
751     ScDocument* pDoc = rDocShell.GetDocument();
752     if (bRecord && !pDoc->IsUndoEnabled())
753         bRecord = sal_False;
754 
755     ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
756     ScOutlineArray* pArray = bColumns ? pTable->GetColArray() : pTable->GetRowArray();
757     ScOutlineEntry* pEntry = pArray->GetEntry( nLevel, nEntry );
758     SCCOLROW nStart = pEntry->GetStart();
759     SCCOLROW nEnd   = pEntry->GetEnd();
760 
761     if ( bRecord )
762     {
763         ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
764         if (bColumns)
765         {
766             pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_False );
767             pDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab,
768                     static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, sal_False,
769                     pUndoDoc );
770         }
771         else
772         {
773             pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, sal_True );
774             pDoc->CopyToDocument( 0, nStart, nTab, MAXCOL, nEnd, nTab, IDF_NONE, sal_False, pUndoDoc );
775         }
776 
777         rDocShell.GetUndoManager()->AddUndoAction(
778             new ScUndoDoOutline( &rDocShell,
779                                     nStart, nEnd, nTab, pUndoDoc,
780                                     bColumns, nLevel, nEntry, sal_False ) );
781     }
782 
783 //! HideCursor();
784 
785     pDoc->IncSizeRecalcLevel( nTab );
786 
787     pEntry->SetHidden(sal_True);
788     SCCOLROW i;
789     if ( bColumns )
790         for ( i = nStart; i <= nEnd; i++ )
791             pDoc->ShowCol( static_cast<SCCOL>(i), nTab, sal_False );
792     else
793         pDoc->ShowRows( nStart, nEnd, nTab, sal_False );
794 
795     pArray->SetVisibleBelow( nLevel, nEntry, sal_False );
796 
797     pDoc->DecSizeRecalcLevel( nTab );
798     pDoc->InvalidatePageBreaks(nTab);
799     pDoc->UpdatePageBreaks( nTab );
800 
801     if (bPaint)
802         lcl_PaintWidthHeight( rDocShell, nTab, bColumns, nStart, nEnd );
803 
804 //! ShowCursor();
805     rDocShell.SetDocumentModified();
806 
807 //! if (bPaint)
808 //!     UpdateScrollBars();
809 
810     lcl_InvalidateOutliner( rDocShell.GetViewBindings() );
811 
812     return sal_True;        //! immer ???
813 }
814 
815 
816 
817 
818 
819