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