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