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