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