xref: /aoo42x/main/sc/source/ui/docshell/olinefun.cxx (revision cdf0e10c)
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