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 // INCLUDE --------------------------------------------------------------- 32 33 #include "scitems.hxx" 34 #include <editeng/eeitem.hxx> 35 36 #include <sfx2/app.hxx> 37 #define _SVSTDARR_STRINGS 38 #include <editeng/boxitem.hxx> 39 #include <editeng/fontitem.hxx> 40 #include <editeng/scripttypeitem.hxx> 41 #include <svl/srchitem.hxx> 42 #include <sfx2/linkmgr.hxx> 43 #include <sfx2/dispatch.hxx> 44 #include <sfx2/docfilt.hxx> 45 #include <sfx2/docfile.hxx> 46 #include <sfx2/objitem.hxx> 47 #include <sfx2/viewfrm.hxx> 48 #include <svl/stritem.hxx> 49 #include <svl/zforlist.hxx> 50 #include <svl/svstdarr.hxx> 51 #include <vcl/msgbox.hxx> 52 #include <vcl/sound.hxx> 53 #include <vcl/waitobj.hxx> 54 55 #include "viewfunc.hxx" 56 57 #include "sc.hrc" 58 #include "globstr.hrc" 59 60 #include "attrib.hxx" 61 #include "autoform.hxx" 62 #include "cell.hxx" // EnterAutoSum 63 #include "compiler.hxx" 64 #include "docfunc.hxx" 65 #include "docpool.hxx" 66 #include "docsh.hxx" 67 #include "global.hxx" 68 #include "patattr.hxx" 69 #include "printfun.hxx" 70 #include "rangenam.hxx" 71 #include "rangeutl.hxx" 72 #include "refundo.hxx" 73 #include "tablink.hxx" 74 #include "tabvwsh.hxx" 75 #include "uiitems.hxx" 76 #include "undoblk.hxx" 77 #include "undocell.hxx" 78 #include "undotab.hxx" 79 #include "sizedev.hxx" 80 #include "editable.hxx" 81 #include "scmod.hxx" 82 #include "inputhdl.hxx" 83 #include "inputwin.hxx" 84 #include "funcdesc.hxx" 85 #include "docuno.hxx" 86 #include "charthelper.hxx" 87 #include "tabbgcolor.hxx" 88 89 #include <basic/sbstar.hxx> 90 #include <com/sun/star/container/XNameContainer.hpp> 91 #include <com/sun/star/script/XLibraryContainer.hpp> 92 using namespace com::sun::star; 93 94 // helper func defined in docfunc.cxx 95 void VBA_DeleteModule( ScDocShell& rDocSh, String& sModuleName ); 96 97 // STATIC DATA --------------------------------------------------------------- 98 99 100 //---------------------------------------------------------------------------- 101 102 sal_Bool ScViewFunc::AdjustBlockHeight( sal_Bool bPaint, ScMarkData* pMarkData ) 103 { 104 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 105 if (!pMarkData) 106 pMarkData = &GetViewData()->GetMarkData(); 107 108 ScDocument* pDoc = pDocSh->GetDocument(); 109 SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT]; 110 SCCOLROW nRangeCnt = pMarkData->GetMarkRowRanges( pRanges ); 111 if (nRangeCnt == 0) 112 { 113 pRanges[0] = pRanges[1] = GetViewData()->GetCurY(); 114 nRangeCnt = 1; 115 } 116 117 double nPPTX = GetViewData()->GetPPTX(); 118 double nPPTY = GetViewData()->GetPPTY(); 119 Fraction aZoomX = GetViewData()->GetZoomX(); 120 Fraction aZoomY = GetViewData()->GetZoomY(); 121 122 ScSizeDeviceProvider aProv(pDocSh); 123 if (aProv.IsPrinter()) 124 { 125 nPPTX = aProv.GetPPTX(); 126 nPPTY = aProv.GetPPTY(); 127 aZoomX = aZoomY = Fraction( 1, 1 ); 128 } 129 130 sal_Bool bAnyChanged = sal_False; 131 SCTAB nTabCount = pDoc->GetTableCount(); 132 for (SCTAB nTab=0; nTab<nTabCount; nTab++) 133 { 134 if (pMarkData->GetTableSelect(nTab)) 135 { 136 SCCOLROW* pOneRange = pRanges; 137 sal_Bool bChanged = sal_False; 138 SCROW nPaintY = 0; 139 for (SCROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++) 140 { 141 SCROW nStartNo = *(pOneRange++); 142 SCROW nEndNo = *(pOneRange++); 143 if (pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, 0, aProv.GetDevice(), 144 nPPTX, nPPTY, aZoomX, aZoomY, sal_False )) 145 { 146 if (!bChanged) 147 nPaintY = nStartNo; 148 bAnyChanged = bChanged = sal_True; 149 } 150 } 151 if ( bPaint && bChanged ) 152 pDocSh->PostPaint( 0, nPaintY, nTab, MAXCOL, MAXROW, nTab, 153 PAINT_GRID | PAINT_LEFT ); 154 } 155 } 156 delete[] pRanges; 157 158 if ( bPaint && bAnyChanged ) 159 pDocSh->UpdateOle(GetViewData()); 160 161 return bAnyChanged; 162 } 163 164 165 //---------------------------------------------------------------------------- 166 167 sal_Bool ScViewFunc::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, sal_Bool bPaint ) 168 { 169 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 170 ScDocument* pDoc = pDocSh->GetDocument(); 171 SCTAB nTab = GetViewData()->GetTabNo(); 172 double nPPTX = GetViewData()->GetPPTX(); 173 double nPPTY = GetViewData()->GetPPTY(); 174 Fraction aZoomX = GetViewData()->GetZoomX(); 175 Fraction aZoomY = GetViewData()->GetZoomY(); 176 sal_uInt16 nOldPixel = 0; 177 if (nStartRow == nEndRow) 178 nOldPixel = (sal_uInt16) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY); 179 180 ScSizeDeviceProvider aProv(pDocSh); 181 if (aProv.IsPrinter()) 182 { 183 nPPTX = aProv.GetPPTX(); 184 nPPTY = aProv.GetPPTY(); 185 aZoomX = aZoomY = Fraction( 1, 1 ); 186 } 187 sal_Bool bChanged = pDoc->SetOptimalHeight( nStartRow, nEndRow, nTab, 0, aProv.GetDevice(), 188 nPPTX, nPPTY, aZoomX, aZoomY, sal_False ); 189 190 if (bChanged && ( nStartRow == nEndRow )) 191 { 192 sal_uInt16 nNewPixel = (sal_uInt16) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY); 193 if ( nNewPixel == nOldPixel ) 194 bChanged = sal_False; 195 } 196 197 if ( bPaint && bChanged ) 198 pDocSh->PostPaint( 0, nStartRow, nTab, MAXCOL, MAXROW, nTab, 199 PAINT_GRID | PAINT_LEFT ); 200 201 return bChanged; 202 } 203 204 205 //---------------------------------------------------------------------------- 206 207 enum ScAutoSum 208 { 209 ScAutoSumNone = 0, 210 ScAutoSumData, 211 ScAutoSumSum 212 }; 213 214 215 ScAutoSum lcl_IsAutoSumData( ScDocument* pDoc, SCCOL nCol, SCROW nRow, 216 SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend ) 217 { 218 ScBaseCell* pCell; 219 pDoc->GetCell( nCol, nRow, nTab, pCell ); 220 if ( pCell && pCell->HasValueData() ) 221 { 222 if ( pCell->GetCellType() == CELLTYPE_FORMULA ) 223 { 224 ScTokenArray* pCode = ((ScFormulaCell*)pCell)->GetCode(); 225 if ( pCode && pCode->GetOuterFuncOpCode() == ocSum ) 226 { 227 if ( pCode->GetAdjacentExtendOfOuterFuncRefs( nExtend, 228 ScAddress( nCol, nRow, nTab ), eDir ) ) 229 return ScAutoSumSum; 230 } 231 } 232 return ScAutoSumData; 233 } 234 return ScAutoSumNone; 235 } 236 237 238 //---------------------------------------------------------------------------- 239 240 #define SC_AUTOSUM_MAXCOUNT 20 241 242 ScAutoSum lcl_SeekAutoSumData( ScDocument* pDoc, SCCOL& nCol, SCROW& nRow, 243 SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend ) 244 { 245 sal_uInt16 nCount = 0; 246 while (nCount < SC_AUTOSUM_MAXCOUNT) 247 { 248 if ( eDir == DIR_TOP ) 249 { 250 if (nRow > 0) 251 --nRow; 252 else 253 return ScAutoSumNone; 254 } 255 else 256 { 257 if (nCol > 0) 258 --nCol; 259 else 260 return ScAutoSumNone; 261 } 262 ScAutoSum eSum; 263 if ( (eSum = lcl_IsAutoSumData( 264 pDoc, nCol, nRow, nTab, eDir, nExtend )) != ScAutoSumNone ) 265 return eSum; 266 ++nCount; 267 } 268 return ScAutoSumNone; 269 } 270 271 #undef SC_AUTOSUM_MAXCOUNT 272 273 //---------------------------------------------------------------------------- 274 275 bool lcl_FindNextSumEntryInColumn( ScDocument* pDoc, SCCOL nCol, SCROW& nRow, 276 SCTAB nTab, SCCOLROW& nExtend, SCROW nMinRow ) 277 { 278 const SCROW nTmp = nRow; 279 ScAutoSum eSkip = ScAutoSumNone; 280 while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) ) == ScAutoSumData && 281 nRow > nMinRow ) 282 { 283 --nRow; 284 } 285 if ( eSkip == ScAutoSumSum && nRow < nTmp ) 286 { 287 return true; 288 } 289 return false; 290 } 291 292 //---------------------------------------------------------------------------- 293 294 bool lcl_FindNextSumEntryInRow( ScDocument* pDoc, SCCOL& nCol, SCROW nRow, 295 SCTAB nTab, SCCOLROW& nExtend, SCROW nMinCol ) 296 { 297 const SCCOL nTmp = nCol; 298 ScAutoSum eSkip = ScAutoSumNone; 299 while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) ) == ScAutoSumData && 300 nCol > nMinCol ) 301 { 302 --nCol; 303 } 304 if ( eSkip == ScAutoSumSum && nCol < nTmp ) 305 { 306 return true; 307 } 308 return false; 309 } 310 311 //---------------------------------------------------------------------------- 312 313 bool lcl_GetAutoSumForColumnRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange ) 314 { 315 const ScAddress aStart = rRange.aStart; 316 const ScAddress aEnd = rRange.aEnd; 317 if ( aStart.Col() != aEnd.Col() ) 318 { 319 return false; 320 } 321 322 const SCTAB nTab = aEnd.Tab(); 323 const SCCOL nCol = aEnd.Col(); 324 SCROW nEndRow = aEnd.Row(); 325 SCROW nStartRow = nEndRow; 326 SCCOLROW nExtend = 0; 327 const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nCol, nEndRow, nTab, DIR_TOP, nExtend /*out*/ ); 328 329 if ( eSum == ScAutoSumSum ) 330 { 331 bool bContinue = false; 332 do 333 { 334 rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) ); 335 nEndRow = static_cast< SCROW >( nExtend ); 336 if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, aStart.Row() ) ) == true ) 337 { 338 nStartRow = nEndRow; 339 } 340 } while ( bContinue ); 341 } 342 else 343 { 344 while ( nStartRow > aStart.Row() && 345 lcl_IsAutoSumData( pDoc, nCol, nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) != ScAutoSumSum ) 346 { 347 --nStartRow; 348 } 349 rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) ); 350 } 351 352 return true; 353 } 354 355 //---------------------------------------------------------------------------- 356 357 bool lcl_GetAutoSumForRowRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange ) 358 { 359 const ScAddress aStart = rRange.aStart; 360 const ScAddress aEnd = rRange.aEnd; 361 if ( aStart.Row() != aEnd.Row() ) 362 { 363 return false; 364 } 365 366 const SCTAB nTab = aEnd.Tab(); 367 const SCROW nRow = aEnd.Row(); 368 SCCOL nEndCol = aEnd.Col(); 369 SCCOL nStartCol = nEndCol; 370 SCCOLROW nExtend = 0; 371 const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nEndCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ ); 372 373 if ( eSum == ScAutoSumSum ) 374 { 375 bool bContinue = false; 376 do 377 { 378 rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) ); 379 nEndCol = static_cast< SCCOL >( nExtend ); 380 if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, aStart.Col() ) ) == true ) 381 { 382 nStartCol = nEndCol; 383 } 384 } while ( bContinue ); 385 } 386 else 387 { 388 while ( nStartCol > aStart.Col() && 389 lcl_IsAutoSumData( pDoc, nStartCol-1, nRow, nTab, DIR_LEFT, nExtend /*out*/ ) != ScAutoSumSum ) 390 { 391 --nStartCol; 392 } 393 rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) ); 394 } 395 396 return true; 397 } 398 399 //---------------------------------------------------------------------------- 400 401 sal_Bool ScViewFunc::GetAutoSumArea( ScRangeList& rRangeList ) 402 { 403 ScDocument* pDoc = GetViewData()->GetDocument(); 404 SCTAB nTab = GetViewData()->GetTabNo(); 405 406 SCCOL nCol = GetViewData()->GetCurX(); 407 SCROW nRow = GetViewData()->GetCurY(); 408 409 SCCOL nStartCol = nCol; 410 SCROW nStartRow = nRow; 411 SCCOL nEndCol = nCol; 412 SCROW nEndRow = nRow; 413 SCCOL nSeekCol = nCol; 414 SCROW nSeekRow = nRow; 415 SCCOLROW nExtend; // wird per Reference gueltig bei ScAutoSumSum 416 417 sal_Bool bCol = sal_False; 418 sal_Bool bRow = sal_False; 419 420 ScAutoSum eSum; 421 if ( nRow != 0 422 && ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab, 423 DIR_TOP, nExtend /*out*/ )) == ScAutoSumData ) 424 && ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab, 425 DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData ) 426 ) 427 { 428 bRow = sal_True; 429 nSeekRow = nRow - 1; 430 } 431 else if ( nCol != 0 && (eSum = lcl_IsAutoSumData( pDoc, nCol-1, nRow, nTab, 432 DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData ) 433 { 434 bCol = sal_True; 435 nSeekCol = nCol - 1; 436 } 437 else if ( (eSum = lcl_SeekAutoSumData( pDoc, nCol, nSeekRow, nTab, DIR_TOP, nExtend /*out*/ )) != ScAutoSumNone ) 438 bRow = sal_True; 439 else if (( eSum = lcl_SeekAutoSumData( pDoc, nSeekCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ )) != ScAutoSumNone ) 440 bCol = sal_True; 441 442 if ( bCol || bRow ) 443 { 444 if ( bRow ) 445 { 446 nStartRow = nSeekRow; // nSeekRow evtl. per Reference angepasst 447 if ( eSum == ScAutoSumSum ) 448 nEndRow = nStartRow; // nur Summen summieren 449 else 450 nEndRow = nRow - 1; // Datenbereich evtl. nach unten erweitern 451 } 452 else 453 { 454 nStartCol = nSeekCol; // nSeekCol evtl. per Reference angepasst 455 if ( eSum == ScAutoSumSum ) 456 nEndCol = nStartCol; // nur Summen summieren 457 else 458 nEndCol = nCol - 1; // Datenbereich evtl. nach rechts erweitern 459 } 460 sal_Bool bContinue = sal_False; 461 do 462 { 463 if ( eSum == ScAutoSumData ) 464 { 465 if ( bRow ) 466 { 467 while ( nStartRow != 0 && lcl_IsAutoSumData( pDoc, nCol, 468 nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) == eSum ) 469 --nStartRow; 470 } 471 else 472 { 473 while ( nStartCol != 0 && lcl_IsAutoSumData( pDoc, nStartCol-1, 474 nRow, nTab, DIR_LEFT, nExtend /*out*/ ) == eSum ) 475 --nStartCol; 476 } 477 } 478 rRangeList.Append( 479 ScRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ) ); 480 if ( eSum == ScAutoSumSum ) 481 { 482 if ( bRow ) 483 { 484 nEndRow = static_cast< SCROW >( nExtend ); 485 if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, 0 ) ) == true ) 486 { 487 nStartRow = nEndRow; 488 } 489 } 490 else 491 { 492 nEndCol = static_cast< SCCOL >( nExtend ); 493 if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, 0 ) ) == true ) 494 { 495 nStartCol = nEndCol; 496 } 497 } 498 } 499 } while ( bContinue ); 500 return sal_True; 501 } 502 return sal_False; 503 } 504 505 //---------------------------------------------------------------------------- 506 507 void ScViewFunc::EnterAutoSum(const ScRangeList& rRangeList, sal_Bool bSubTotal) // Block mit Summen fuellen 508 { 509 String aFormula = GetAutoSumFormula( rRangeList, bSubTotal ); 510 EnterBlock( aFormula, NULL ); 511 } 512 513 //---------------------------------------------------------------------------- 514 515 bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor, bool bContinue ) 516 { 517 ScDocument* pDoc = GetViewData()->GetDocument(); 518 const SCTAB nTab = rRange.aStart.Tab(); 519 SCCOL nStartCol = rRange.aStart.Col(); 520 SCROW nStartRow = rRange.aStart.Row(); 521 const SCCOL nEndCol = rRange.aEnd.Col(); 522 const SCROW nEndRow = rRange.aEnd.Row(); 523 SCCOLROW nExtend = 0; // out parameter for lcl_IsAutoSumData 524 525 // ignore rows at the top of the given range which don't contain autosum data 526 bool bRowData = false; 527 for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow ) 528 { 529 for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol ) 530 { 531 if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) != ScAutoSumNone ) 532 { 533 bRowData = true; 534 break; 535 } 536 } 537 if ( bRowData ) 538 { 539 nStartRow = nRow; 540 break; 541 } 542 } 543 if ( !bRowData ) 544 { 545 return false; 546 } 547 548 // ignore columns at the left of the given range which don't contain autosum data 549 bool bColData = false; 550 for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol ) 551 { 552 for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow ) 553 { 554 if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) != ScAutoSumNone ) 555 { 556 bColData = true; 557 break; 558 } 559 } 560 if ( bColData ) 561 { 562 nStartCol = nCol; 563 break; 564 } 565 } 566 if ( !bColData ) 567 { 568 return false; 569 } 570 571 const bool bEndRowEmpty = pDoc->IsBlockEmpty( nTab, nStartCol, nEndRow, nEndCol, nEndRow ); 572 const bool bEndColEmpty = pDoc->IsBlockEmpty( nTab, nEndCol, nStartRow, nEndCol, nEndRow ); 573 bool bRow = ( ( nStartRow != nEndRow ) && ( bEndRowEmpty || ( !bEndRowEmpty && !bEndColEmpty ) ) ); 574 bool bCol = ( ( nStartCol != nEndCol ) && ( bEndColEmpty || nStartRow == nEndRow ) ); 575 576 // find an empty row for entering the result 577 SCROW nInsRow = nEndRow; 578 if ( bRow && !bEndRowEmpty ) 579 { 580 if ( nInsRow < MAXROW ) 581 { 582 ++nInsRow; 583 while ( !pDoc->IsBlockEmpty( nTab, nStartCol, nInsRow, nEndCol, nInsRow ) ) 584 { 585 if ( nInsRow < MAXROW ) 586 { 587 ++nInsRow; 588 } 589 else 590 { 591 bRow = false; 592 break; 593 } 594 } 595 } 596 else 597 { 598 bRow = false; 599 } 600 } 601 602 // find an empty column for entering the result 603 SCCOL nInsCol = nEndCol; 604 if ( bCol && !bEndColEmpty ) 605 { 606 if ( nInsCol < MAXCOL ) 607 { 608 ++nInsCol; 609 while ( !pDoc->IsBlockEmpty( nTab, nInsCol, nStartRow, nInsCol, nEndRow ) ) 610 { 611 if ( nInsCol < MAXCOL ) 612 { 613 ++nInsCol; 614 } 615 else 616 { 617 bCol = false; 618 break; 619 } 620 } 621 } 622 else 623 { 624 bCol = false; 625 } 626 } 627 628 if ( !bRow && !bCol ) 629 { 630 return false; 631 } 632 633 SCCOL nMarkEndCol = nEndCol; 634 SCROW nMarkEndRow = nEndRow; 635 636 if ( bRow ) 637 { 638 // calculate the row sums for all columns of the given range 639 640 SCROW nSumEndRow = nEndRow; 641 642 if ( bEndRowEmpty ) 643 { 644 // the last row of the given range is empty; 645 // don't take into account for calculating the autosum 646 --nSumEndRow; 647 } 648 else 649 { 650 // increase mark range 651 ++nMarkEndRow; 652 } 653 654 for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol ) 655 { 656 if ( !pDoc->IsBlockEmpty( nTab, nCol, nStartRow, nCol, nSumEndRow ) ) 657 { 658 ScRangeList aRangeList; 659 const ScRange aRange( nCol, nStartRow, nTab, nCol, nSumEndRow, nTab ); 660 if ( lcl_GetAutoSumForColumnRange( pDoc, aRangeList, aRange ) ) 661 { 662 const String aFormula = GetAutoSumFormula( aRangeList, bSubTotal ); 663 EnterData( nCol, nInsRow, nTab, aFormula ); 664 } 665 } 666 } 667 } 668 669 if ( bCol ) 670 { 671 // calculate the column sums for all rows of the given range 672 673 SCCOL nSumEndCol = nEndCol; 674 675 if ( bEndColEmpty ) 676 { 677 // the last column of the given range is empty; 678 // don't take into account for calculating the autosum 679 --nSumEndCol; 680 } 681 else 682 { 683 // increase mark range 684 ++nMarkEndCol; 685 } 686 687 for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow ) 688 { 689 if ( !pDoc->IsBlockEmpty( nTab, nStartCol, nRow, nSumEndCol, nRow ) ) 690 { 691 ScRangeList aRangeList; 692 const ScRange aRange( nStartCol, nRow, nTab, nSumEndCol, nRow, nTab ); 693 if ( lcl_GetAutoSumForRowRange( pDoc, aRangeList, aRange ) ) 694 { 695 const String aFormula = GetAutoSumFormula( aRangeList, bSubTotal ); 696 EnterData( nInsCol, nRow, nTab, aFormula ); 697 } 698 } 699 } 700 } 701 702 // set new mark range and cursor position 703 const ScRange aMarkRange( nStartCol, nStartRow, nTab, nMarkEndCol, nMarkEndRow, nTab ); 704 MarkRange( aMarkRange, sal_False, bContinue ); 705 if ( bSetCursor ) 706 { 707 SetCursor( nMarkEndCol, nMarkEndRow ); 708 } 709 710 return true; 711 } 712 713 //---------------------------------------------------------------------------- 714 715 String ScViewFunc::GetAutoSumFormula( const ScRangeList& rRangeList, bool bSubTotal ) 716 { 717 String aFormula = '='; 718 ScFunctionMgr* pFuncMgr = ScGlobal::GetStarCalcFunctionMgr(); 719 const ScFuncDesc* pDesc = NULL; 720 if ( bSubTotal ) 721 { 722 pDesc = pFuncMgr->Get( SC_OPCODE_SUB_TOTAL ); 723 } 724 else 725 { 726 pDesc = pFuncMgr->Get( SC_OPCODE_SUM ); 727 } 728 if ( pDesc && pDesc->pFuncName ) 729 { 730 aFormula += *pDesc->pFuncName; 731 if ( bSubTotal ) 732 { 733 aFormula.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "(9;" ) ); 734 } 735 else 736 { 737 aFormula += '('; 738 } 739 ScDocument* pDoc = GetViewData()->GetDocument(); 740 String aRef; 741 rRangeList.Format( aRef, SCA_VALID, pDoc ); 742 aFormula += aRef; 743 aFormula += ')'; 744 } 745 return aFormula; 746 } 747 748 //---------------------------------------------------------------------------- 749 750 void ScViewFunc::EnterBlock( const String& rString, const EditTextObject* pData ) 751 { 752 // Mehrfachselektion vorher abfragen... 753 754 SCCOL nCol = GetViewData()->GetCurX(); 755 SCROW nRow = GetViewData()->GetCurY(); 756 SCTAB nTab = GetViewData()->GetTabNo(); 757 ScMarkData& rMark = GetViewData()->GetMarkData(); 758 if ( rMark.IsMultiMarked() ) 759 { 760 rMark.MarkToSimple(); 761 if ( rMark.IsMultiMarked() ) 762 { // "Einfuegen auf Mehrfachselektion nicht moeglich" 763 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0); 764 765 // insert into single cell 766 if ( pData ) 767 EnterData( nCol, nRow, nTab, pData ); 768 else 769 EnterData( nCol, nRow, nTab, rString ); 770 return; 771 } 772 } 773 774 ScDocument* pDoc = GetViewData()->GetDocument(); 775 String aNewStr = rString; 776 if ( pData ) 777 { 778 const ScPatternAttr* pOldPattern = pDoc->GetPattern( nCol, nRow, nTab ); 779 ScTabEditEngine aEngine( *pOldPattern, pDoc->GetEnginePool() ); 780 aEngine.SetText(*pData); 781 782 ScEditAttrTester aTester( &aEngine ); 783 if (!aTester.NeedsObject()) 784 { 785 aNewStr = aEngine.GetText(); 786 pData = NULL; 787 } 788 } 789 790 // Einfuegen per PasteFromClip 791 792 WaitObject aWait( GetFrameWin() ); 793 794 ScAddress aPos( nCol, nRow, nTab ); 795 796 ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP ); 797 pInsDoc->ResetClip( pDoc, nTab ); 798 799 if (aNewStr.GetChar(0) == '=') // Formel ? 800 { 801 // SetString geht nicht, weil in Clipboard-Dokumenten nicht kompiliert wird! 802 ScFormulaCell* pFCell = new ScFormulaCell( pDoc, aPos, aNewStr ); 803 pInsDoc->PutCell( nCol, nRow, nTab, pFCell ); 804 } 805 else if ( pData ) 806 pInsDoc->PutCell( nCol, nRow, nTab, new ScEditCell( pData, pDoc, NULL ) ); 807 else 808 pInsDoc->SetString( nCol, nRow, nTab, aNewStr ); 809 810 pInsDoc->SetClipArea( ScRange(aPos) ); 811 // auf Block einfuegen, mit Undo etc. 812 if ( PasteFromClip( IDF_CONTENTS, pInsDoc, PASTE_NOFUNC, sal_False, sal_False, 813 sal_False, INS_NONE, IDF_ATTRIB ) ) 814 { 815 const SfxUInt32Item* pItem = (SfxUInt32Item*) pInsDoc->GetAttr( 816 nCol, nRow, nTab, ATTR_VALUE_FORMAT ); 817 if ( pItem ) 818 { // Numberformat setzen wenn inkompatibel 819 // MarkData wurde bereits in PasteFromClip MarkToSimple'ed 820 ScRange aRange; 821 rMark.GetMarkArea( aRange ); 822 ScPatternAttr* pPattern = new ScPatternAttr( pDoc->GetPool() ); 823 pPattern->GetItemSet().Put( *pItem ); 824 short nNewType = pDoc->GetFormatTable()->GetType( pItem->GetValue() ); 825 pDoc->ApplyPatternIfNumberformatIncompatible( aRange, rMark, 826 *pPattern, nNewType ); 827 delete pPattern; 828 } 829 } 830 831 delete pInsDoc; 832 } 833 834 835 //---------------------------------------------------------------------------- 836 837 //UNUSED2008-05 void ScViewFunc::PaintWidthHeight( sal_Bool bColumns, SCCOLROW nStart, SCCOLROW nEnd ) 838 //UNUSED2008-05 { 839 //UNUSED2008-05 SCTAB nTab = GetViewData()->GetTabNo(); 840 //UNUSED2008-05 ScDocument* pDoc = GetViewData()->GetDocument(); 841 //UNUSED2008-05 842 //UNUSED2008-05 sal_uInt16 nParts = PAINT_GRID; 843 //UNUSED2008-05 SCCOL nStartCol = 0; 844 //UNUSED2008-05 SCROW nStartRow = 0; 845 //UNUSED2008-05 SCCOL nEndCol = MAXCOL; // fuer Test auf Merge 846 //UNUSED2008-05 SCROW nEndRow = MAXROW; 847 //UNUSED2008-05 if ( bColumns ) 848 //UNUSED2008-05 { 849 //UNUSED2008-05 nParts |= PAINT_TOP; 850 //UNUSED2008-05 nStartCol = static_cast<SCCOL>(nStart); 851 //UNUSED2008-05 nEndCol = static_cast<SCCOL>(nEnd); 852 //UNUSED2008-05 } 853 //UNUSED2008-05 else 854 //UNUSED2008-05 { 855 //UNUSED2008-05 nParts |= PAINT_LEFT; 856 //UNUSED2008-05 nStartRow = nStart; 857 //UNUSED2008-05 nEndRow = nEnd; 858 //UNUSED2008-05 } 859 //UNUSED2008-05 if (pDoc->HasAttrib( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab, 860 //UNUSED2008-05 HASATTR_MERGED | HASATTR_OVERLAPPED )) 861 //UNUSED2008-05 { 862 //UNUSED2008-05 nStartCol = 0; 863 //UNUSED2008-05 nStartRow = 0; 864 //UNUSED2008-05 } 865 //UNUSED2008-05 GetViewData()->GetDocShell()->PostPaint( nStartCol,nStartRow,nTab, MAXCOL,MAXROW,nTab, nParts ); 866 //UNUSED2008-05 } 867 868 869 //---------------------------------------------------------------------------- 870 // manueller Seitenumbruch 871 872 void ScViewFunc::InsertPageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos, 873 sal_Bool bSetModified ) 874 { 875 SCTAB nTab = GetViewData()->GetTabNo(); 876 ScAddress aCursor; 877 if (pPos) 878 aCursor = *pPos; 879 else 880 aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab ); 881 882 sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc(). 883 InsertPageBreak( bColumn, aCursor, bRecord, bSetModified, sal_False ); 884 885 if ( bSuccess && bSetModified ) 886 UpdatePageBreakData( sal_True ); // fuer PageBreak-Modus 887 } 888 889 890 //---------------------------------------------------------------------------- 891 892 void ScViewFunc::DeletePageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos, 893 sal_Bool bSetModified ) 894 { 895 SCTAB nTab = GetViewData()->GetTabNo(); 896 ScAddress aCursor; 897 if (pPos) 898 aCursor = *pPos; 899 else 900 aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab ); 901 902 sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc(). 903 RemovePageBreak( bColumn, aCursor, bRecord, bSetModified, sal_False ); 904 905 if ( bSuccess && bSetModified ) 906 UpdatePageBreakData( sal_True ); // fuer PageBreak-Modus 907 } 908 909 //---------------------------------------------------------------------------- 910 911 void ScViewFunc::RemoveManualBreaks() 912 { 913 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 914 ScDocument* pDoc = pDocSh->GetDocument(); 915 SCTAB nTab = GetViewData()->GetTabNo(); 916 sal_Bool bUndo(pDoc->IsUndoEnabled()); 917 918 if (bUndo) 919 { 920 ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); 921 pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True ); 922 pDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, sal_False, pUndoDoc ); 923 pDocSh->GetUndoManager()->AddUndoAction( 924 new ScUndoRemoveBreaks( pDocSh, nTab, pUndoDoc ) ); 925 } 926 927 pDoc->RemoveManualBreaks(nTab); 928 pDoc->UpdatePageBreaks(nTab); 929 930 UpdatePageBreakData( sal_True ); 931 pDocSh->SetDocumentModified(); 932 pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID ); 933 } 934 935 //---------------------------------------------------------------------------- 936 937 void ScViewFunc::SetPrintZoom(sal_uInt16 nScale, sal_uInt16 nPages) 938 { 939 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 940 SCTAB nTab = GetViewData()->GetTabNo(); 941 pDocSh->SetPrintZoom( nTab, nScale, nPages ); 942 } 943 944 void ScViewFunc::AdjustPrintZoom() 945 { 946 ScRange aRange; 947 if ( GetViewData()->GetSimpleArea( aRange ) != SC_MARK_SIMPLE ) 948 GetViewData()->GetMarkData().GetMultiMarkArea( aRange ); 949 GetViewData()->GetDocShell()->AdjustPrintZoom( aRange ); 950 } 951 952 //---------------------------------------------------------------------------- 953 954 void ScViewFunc::SetPrintRanges( sal_Bool bEntireSheet, const String* pPrint, 955 const String* pRepCol, const String* pRepRow, 956 sal_Bool bAddPrint ) 957 { 958 // on all selected tables 959 960 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 961 ScDocument* pDoc = pDocSh->GetDocument(); 962 SCTAB nTabCount = pDoc->GetTableCount(); 963 ScMarkData& rMark = GetViewData()->GetMarkData(); 964 SCTAB nTab; 965 sal_Bool bUndo (pDoc->IsUndoEnabled()); 966 967 ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver(); 968 969 ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0); 970 971 for (nTab=0; nTab<nTabCount; nTab++) 972 if (rMark.GetTableSelect(nTab)) 973 { 974 ScRange aRange( 0,0,nTab ); 975 976 // print ranges 977 978 if( !bAddPrint ) 979 pDoc->ClearPrintRanges( nTab ); 980 981 if( bEntireSheet ) 982 { 983 pDoc->SetPrintEntireSheet( nTab ); 984 } 985 else if ( pPrint ) 986 { 987 if ( pPrint->Len() ) 988 { 989 const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0); 990 sal_uInt16 nTCount = pPrint->GetTokenCount(sep); 991 for (sal_uInt16 i=0; i<nTCount; i++) 992 { 993 String aToken = pPrint->GetToken(i, sep); 994 if ( aRange.ParseAny( aToken, pDoc, aDetails ) & SCA_VALID ) 995 pDoc->AddPrintRange( nTab, aRange ); 996 } 997 } 998 } 999 else // NULL = use selection (print range is always set), use empty string to delete all ranges 1000 { 1001 if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE ) 1002 { 1003 pDoc->AddPrintRange( nTab, aRange ); 1004 } 1005 else if ( rMark.IsMultiMarked() ) 1006 { 1007 rMark.MarkToMulti(); 1008 ScRangeListRef aList( new ScRangeList ); 1009 rMark.FillRangeListWithMarks( aList, sal_False ); 1010 sal_uInt16 nCnt = (sal_uInt16) aList->Count(); 1011 if ( nCnt ) 1012 { 1013 ScRangePtr pR; 1014 sal_uInt16 i; 1015 for ( pR = aList->First(), i=0; i < nCnt; 1016 pR = aList->Next(), i++ ) 1017 { 1018 pDoc->AddPrintRange( nTab, *pR ); 1019 } 1020 } 1021 } 1022 } 1023 1024 // repeat columns 1025 1026 if ( pRepCol ) 1027 { 1028 if ( !pRepCol->Len() ) 1029 pDoc->SetRepeatColRange( nTab, NULL ); 1030 else 1031 if ( aRange.ParseAny( *pRepCol, pDoc, aDetails ) & SCA_VALID ) 1032 pDoc->SetRepeatColRange( nTab, &aRange ); 1033 } 1034 1035 // repeat rows 1036 1037 if ( pRepRow ) 1038 { 1039 if ( !pRepRow->Len() ) 1040 pDoc->SetRepeatRowRange( nTab, NULL ); 1041 else 1042 if ( aRange.ParseAny( *pRepRow, pDoc, aDetails ) & SCA_VALID ) 1043 pDoc->SetRepeatRowRange( nTab, &aRange ); 1044 } 1045 } 1046 1047 // undo (for all tables) 1048 if (bUndo) 1049 { 1050 SCTAB nCurTab = GetViewData()->GetTabNo(); 1051 ScPrintRangeSaver* pNewRanges = pDoc->CreatePrintRangeSaver(); 1052 pDocSh->GetUndoManager()->AddUndoAction( 1053 new ScUndoPrintRange( pDocSh, nCurTab, pOldRanges, pNewRanges ) ); 1054 } 1055 1056 // update page breaks 1057 1058 for (nTab=0; nTab<nTabCount; nTab++) 1059 if (rMark.GetTableSelect(nTab)) 1060 ScPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ).UpdatePages(); 1061 1062 SfxBindings& rBindings = GetViewData()->GetBindings(); 1063 rBindings.Invalidate( SID_DELETE_PRINTAREA ); 1064 1065 pDocSh->SetDocumentModified(); 1066 } 1067 1068 //---------------------------------------------------------------------------- 1069 // Zellen zusammenfassen 1070 1071 sal_Bool ScViewFunc::TestMergeCells() // Vorab-Test (fuer Menue) 1072 { 1073 // simple test: sal_True if there's a selection but no multi selection and not filtered 1074 1075 const ScMarkData& rMark = GetViewData()->GetMarkData(); 1076 if ( rMark.IsMarked() || rMark.IsMultiMarked() ) 1077 { 1078 ScRange aDummy; 1079 return GetViewData()->GetSimpleArea( aDummy) == SC_MARK_SIMPLE; 1080 } 1081 else 1082 return sal_False; 1083 } 1084 1085 1086 //---------------------------------------------------------------------------- 1087 1088 sal_Bool ScViewFunc::MergeCells( sal_Bool bApi, sal_Bool& rDoContents, sal_Bool bRecord ) 1089 { 1090 // Editable- und Verschachtelungs-Abfrage muss vorneweg sein (auch in DocFunc), 1091 // damit dann nicht die Inhalte-QueryBox kommt 1092 ScEditableTester aTester( this ); 1093 if (!aTester.IsEditable()) 1094 { 1095 ErrorMessage(aTester.GetMessageId()); 1096 return sal_False; 1097 } 1098 1099 ScMarkData& rMark = GetViewData()->GetMarkData(); 1100 rMark.MarkToSimple(); 1101 if (!rMark.IsMarked()) 1102 { 1103 ErrorMessage(STR_NOMULTISELECT); 1104 return sal_False; 1105 } 1106 1107 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 1108 ScDocument* pDoc = pDocSh->GetDocument(); 1109 1110 ScRange aMarkRange; 1111 rMark.GetMarkArea( aMarkRange ); 1112 SCCOL nStartCol = aMarkRange.aStart.Col(); 1113 SCROW nStartRow = aMarkRange.aStart.Row(); 1114 SCTAB nStartTab = aMarkRange.aStart.Tab(); 1115 SCCOL nEndCol = aMarkRange.aEnd.Col(); 1116 SCROW nEndRow = aMarkRange.aEnd.Row(); 1117 SCTAB nEndTab = aMarkRange.aEnd.Tab(); 1118 if ( nStartCol == nEndCol && nStartRow == nEndRow ) 1119 { 1120 // nichts zu tun 1121 return sal_True; 1122 } 1123 1124 if ( pDoc->HasAttrib( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab, 1125 HASATTR_MERGED | HASATTR_OVERLAPPED ) ) 1126 { // "Zusammenfassen nicht verschachteln !" 1127 ErrorMessage(STR_MSSG_MERGECELLS_0); 1128 return sal_False; 1129 } 1130 1131 sal_Bool bOk = sal_True; 1132 1133 if ( !pDoc->IsBlockEmpty( nStartTab, nStartCol,nStartRow+1, nStartCol,nEndRow, true ) || 1134 !pDoc->IsBlockEmpty( nStartTab, nStartCol+1,nStartRow, nEndCol,nEndRow, true ) ) 1135 { 1136 if (!bApi) 1137 { 1138 MessBox aBox( GetViewData()->GetDialogParent(), 1139 WinBits(WB_YES_NO_CANCEL | WB_DEF_NO), 1140 ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), 1141 ScGlobal::GetRscString( STR_MERGE_NOTEMPTY ) ); 1142 sal_uInt16 nRetVal = aBox.Execute(); 1143 1144 if ( nRetVal == RET_YES ) 1145 rDoContents = sal_True; 1146 else if ( nRetVal == RET_CANCEL ) 1147 bOk = sal_False; 1148 } 1149 } 1150 1151 if (bOk) 1152 { 1153 HideCursor(); 1154 bOk = pDocSh->GetDocFunc().MergeCells( aMarkRange, rDoContents, bRecord, bApi ); 1155 ShowCursor(); 1156 1157 if (bOk) 1158 { 1159 SetCursor( nStartCol, nStartRow ); 1160 //DoneBlockMode( sal_False); 1161 Unmark(); 1162 1163 pDocSh->UpdateOle(GetViewData()); 1164 UpdateInputLine(); 1165 } 1166 } 1167 1168 return bOk; 1169 } 1170 1171 1172 //---------------------------------------------------------------------------- 1173 1174 sal_Bool ScViewFunc::TestRemoveMerge() 1175 { 1176 sal_Bool bMerged = sal_False; 1177 ScRange aRange; 1178 if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE) 1179 { 1180 ScDocument* pDoc = GetViewData()->GetDocument(); 1181 if ( pDoc->HasAttrib( aRange, HASATTR_MERGED ) ) 1182 bMerged = sal_True; 1183 } 1184 return bMerged; 1185 } 1186 1187 1188 //---------------------------------------------------------------------------- 1189 1190 sal_Bool ScViewFunc::RemoveMerge( sal_Bool bRecord ) 1191 { 1192 ScRange aRange; 1193 ScEditableTester aTester( this ); 1194 if (!aTester.IsEditable()) 1195 { 1196 ErrorMessage(aTester.GetMessageId()); 1197 return sal_False; 1198 } 1199 else if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE) 1200 { 1201 ScRange aExtended( aRange ); 1202 GetViewData()->GetDocument()->ExtendMerge( aExtended ); 1203 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 1204 1205 HideCursor(); 1206 sal_Bool bOk = pDocSh->GetDocFunc().UnmergeCells( aRange, bRecord, sal_False ); 1207 MarkRange( aExtended ); 1208 ShowCursor(); 1209 1210 if (bOk) 1211 pDocSh->UpdateOle(GetViewData()); 1212 } 1213 return sal_True; //! bOk ?? 1214 } 1215 1216 //---------------------------------------------------------------------------- 1217 1218 void ScViewFunc::FillSimple( FillDir eDir, sal_Bool bRecord ) 1219 { 1220 ScRange aRange; 1221 if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE) 1222 { 1223 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 1224 const ScMarkData& rMark = GetViewData()->GetMarkData(); 1225 sal_Bool bSuccess = pDocSh->GetDocFunc().FillSimple( aRange, &rMark, eDir, bRecord, sal_False ); 1226 if (bSuccess) 1227 { 1228 pDocSh->UpdateOle(GetViewData()); 1229 UpdateScrollBars(); 1230 } 1231 } 1232 else 1233 ErrorMessage(STR_NOMULTISELECT); 1234 } 1235 1236 //---------------------------------------------------------------------------- 1237 1238 void ScViewFunc::FillSeries( FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd, 1239 double fStart, double fStep, double fMax, sal_Bool bRecord ) 1240 { 1241 ScRange aRange; 1242 if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE) 1243 { 1244 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 1245 const ScMarkData& rMark = GetViewData()->GetMarkData(); 1246 sal_Bool bSuccess = pDocSh->GetDocFunc(). 1247 FillSeries( aRange, &rMark, eDir, eCmd, eDateCmd, 1248 fStart, fStep, fMax, bRecord, sal_False ); 1249 if (bSuccess) 1250 { 1251 pDocSh->UpdateOle(GetViewData()); 1252 UpdateScrollBars(); 1253 1254 // #i97876# Spreadsheet data changes are not notified 1255 ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() ); 1256 if ( pModelObj && pModelObj->HasChangesListeners() ) 1257 { 1258 ScRangeList aChangeRanges; 1259 aChangeRanges.Append( aRange ); 1260 pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges ); 1261 } 1262 } 1263 } 1264 else 1265 ErrorMessage(STR_NOMULTISELECT); 1266 } 1267 1268 //---------------------------------------------------------------------------- 1269 1270 void ScViewFunc::FillAuto( FillDir eDir, SCCOL nStartCol, SCROW nStartRow, 1271 SCCOL nEndCol, SCROW nEndRow, sal_uLong nCount, sal_Bool bRecord ) 1272 { 1273 SCTAB nTab = GetViewData()->GetTabNo(); 1274 ScRange aRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab ); 1275 ScRange aSourceRange( aRange ); 1276 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 1277 const ScMarkData& rMark = GetViewData()->GetMarkData(); 1278 sal_Bool bSuccess = pDocSh->GetDocFunc(). 1279 FillAuto( aRange, &rMark, eDir, nCount, bRecord, sal_False ); 1280 if (bSuccess) 1281 { 1282 MarkRange( aRange, sal_False ); // aRange ist in FillAuto veraendert worden 1283 pDocSh->UpdateOle(GetViewData()); 1284 UpdateScrollBars(); 1285 1286 // #i97876# Spreadsheet data changes are not notified 1287 ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() ); 1288 if ( pModelObj && pModelObj->HasChangesListeners() ) 1289 { 1290 ScRangeList aChangeRanges; 1291 ScRange aChangeRange( aRange ); 1292 switch ( eDir ) 1293 { 1294 case FILL_TO_BOTTOM: 1295 { 1296 aChangeRange.aStart.SetRow( aSourceRange.aEnd.Row() + 1 ); 1297 } 1298 break; 1299 case FILL_TO_TOP: 1300 { 1301 aChangeRange.aEnd.SetRow( aSourceRange.aStart.Row() - 1 ); 1302 } 1303 break; 1304 case FILL_TO_RIGHT: 1305 { 1306 aChangeRange.aStart.SetCol( aSourceRange.aEnd.Col() + 1 ); 1307 } 1308 break; 1309 case FILL_TO_LEFT: 1310 { 1311 aChangeRange.aEnd.SetCol( aSourceRange.aStart.Col() - 1 ); 1312 } 1313 break; 1314 default: 1315 { 1316 1317 } 1318 break; 1319 } 1320 aChangeRanges.Append( aChangeRange ); 1321 pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges ); 1322 } 1323 } 1324 } 1325 1326 //---------------------------------------------------------------------------- 1327 1328 void ScViewFunc::FillTab( sal_uInt16 nFlags, sal_uInt16 nFunction, sal_Bool bSkipEmpty, sal_Bool bAsLink ) 1329 { 1330 //! allow source sheet to be protected 1331 ScEditableTester aTester( this ); 1332 if (!aTester.IsEditable()) 1333 { 1334 ErrorMessage(aTester.GetMessageId()); 1335 return; 1336 } 1337 1338 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 1339 ScDocument* pDoc = pDocSh->GetDocument(); 1340 ScMarkData& rMark = GetViewData()->GetMarkData(); 1341 SCTAB nTab = GetViewData()->GetTabNo(); 1342 sal_Bool bUndo(pDoc->IsUndoEnabled()); 1343 1344 ScRange aMarkRange; 1345 rMark.MarkToSimple(); 1346 sal_Bool bMulti = rMark.IsMultiMarked(); 1347 if (bMulti) 1348 rMark.GetMultiMarkArea( aMarkRange ); 1349 else if (rMark.IsMarked()) 1350 rMark.GetMarkArea( aMarkRange ); 1351 else 1352 aMarkRange = ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab ); 1353 1354 ScDocument* pUndoDoc = NULL; 1355 // if ( bRecord ) 1356 if (bUndo) 1357 { 1358 pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); 1359 pUndoDoc->InitUndo( pDoc, nTab, nTab ); 1360 // pUndoDoc->SelectTable( nTab, sal_True ); // nur fuer Markierung 1361 1362 SCTAB nTabCount = pDoc->GetTableCount(); 1363 for (SCTAB i=0; i<nTabCount; i++) 1364 if (i != nTab && rMark.GetTableSelect(i)) 1365 { 1366 pUndoDoc->AddUndoTab( i, i ); 1367 aMarkRange.aStart.SetTab( i ); 1368 aMarkRange.aEnd.SetTab( i ); 1369 pDoc->CopyToDocument( aMarkRange, IDF_ALL, bMulti, pUndoDoc ); 1370 // pUndoDoc->SelectTable( i, sal_True ); 1371 } 1372 } 1373 1374 if (bMulti) 1375 pDoc->FillTabMarked( nTab, rMark, nFlags, nFunction, bSkipEmpty, bAsLink ); 1376 else 1377 { 1378 aMarkRange.aStart.SetTab( nTab ); 1379 aMarkRange.aEnd.SetTab( nTab ); 1380 pDoc->FillTab( aMarkRange, rMark, nFlags, nFunction, bSkipEmpty, bAsLink ); 1381 } 1382 1383 // if ( bRecord ) 1384 if (bUndo) 1385 { //! fuer ChangeTrack erst zum Schluss 1386 pDocSh->GetUndoManager()->AddUndoAction( 1387 new ScUndoFillTable( pDocSh, rMark, 1388 aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nTab, 1389 aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), nTab, 1390 pUndoDoc, bMulti, nTab, nFlags, nFunction, bSkipEmpty, bAsLink ) ); 1391 } 1392 1393 pDocSh->PostPaintGridAll(); 1394 pDocSh->PostDataChanged(); 1395 } 1396 1397 //---------------------------------------------------------------------------- 1398 1399 /** Downward fill of selected cell(s) by double-clicking cross-hair cursor 1400 1401 Extends a current selection down to the last non-empty cell of an adjacent 1402 column when the lower-right corner of the selection is double-clicked. It 1403 uses a left-adjoining non-empty column as a guide if such is available, 1404 otherwise a right-adjoining non-empty column is used. 1405 1406 @author Kohei Yoshida (kohei@openoffice.org) 1407 1408 @return No return value 1409 1410 @see #i12313# 1411 */ 1412 void ScViewFunc::FillCrossDblClick() 1413 { 1414 ScRange aRange; 1415 GetViewData()->GetSimpleArea( aRange ); 1416 aRange.Justify(); 1417 1418 SCTAB nTab = GetViewData()->GetCurPos().Tab(); 1419 SCCOL nStartX = aRange.aStart.Col(); 1420 SCROW nStartY = aRange.aStart.Row(); 1421 SCCOL nEndX = aRange.aEnd.Col(); 1422 SCROW nEndY = aRange.aEnd.Row(); 1423 1424 ScDocument* pDoc = GetViewData()->GetDocument(); 1425 1426 // Make sure the selection is not empty 1427 if ( pDoc->IsBlockEmpty( nTab, nStartX, nStartY, nEndX, nEndY ) ) 1428 return; 1429 1430 if ( nEndY < MAXROW ) 1431 { 1432 if ( nStartX > 0 ) 1433 { 1434 SCCOL nMovX = nStartX - 1; 1435 SCROW nMovY = nStartY; 1436 1437 if ( pDoc->HasData( nMovX, nStartY, nTab ) && 1438 pDoc->HasData( nMovX, nStartY + 1, nTab ) ) 1439 { 1440 pDoc->FindAreaPos( nMovX, nMovY, nTab, 0, 1 ); 1441 1442 if ( nMovY > nEndY ) 1443 { 1444 FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY, 1445 nMovY - nEndY ); 1446 return; 1447 } 1448 } 1449 } 1450 1451 if ( nEndX < MAXCOL ) 1452 { 1453 SCCOL nMovX = nEndX + 1; 1454 SCROW nMovY = nStartY; 1455 1456 if ( pDoc->HasData( nMovX, nStartY, nTab ) && 1457 pDoc->HasData( nMovX, nStartY + 1, nTab ) ) 1458 { 1459 pDoc->FindAreaPos( nMovX, nMovY, nTab, 0, 1 ); 1460 1461 if ( nMovY > nEndY ) 1462 { 1463 FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY, 1464 nMovY - nEndY ); 1465 return; 1466 } 1467 } 1468 } 1469 } 1470 } 1471 1472 //---------------------------------------------------------------------------- 1473 1474 void ScViewFunc::TransliterateText( sal_Int32 nType ) 1475 { 1476 ScMarkData aFuncMark = GetViewData()->GetMarkData(); 1477 if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() ) 1478 { 1479 // no selection -> use cursor position 1480 1481 ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() ); 1482 aFuncMark.SetMarkArea( ScRange( aCursor ) ); 1483 } 1484 1485 sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc(). 1486 TransliterateText( aFuncMark, nType, sal_True, sal_False ); 1487 if (bSuccess) 1488 { 1489 GetViewData()->GetViewShell()->UpdateInputHandler(); 1490 } 1491 } 1492 1493 //---------------------------------------------------------------------------- 1494 // AutoFormat 1495 1496 ScAutoFormatData* ScViewFunc::CreateAutoFormatData() 1497 { 1498 ScAutoFormatData* pData = NULL; 1499 SCCOL nStartCol; 1500 SCROW nStartRow; 1501 SCTAB nStartTab; 1502 SCCOL nEndCol; 1503 SCROW nEndRow; 1504 SCTAB nEndTab; 1505 if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE) 1506 { 1507 if ( nEndCol-nStartCol >= 3 && nEndRow-nStartRow >= 3 ) 1508 { 1509 ScDocument* pDoc = GetViewData()->GetDocument(); 1510 pData = new ScAutoFormatData; 1511 pDoc->GetAutoFormatData( nStartTab, nStartCol,nStartRow,nEndCol,nEndRow, *pData ); 1512 } 1513 } 1514 return pData; 1515 } 1516 1517 1518 //---------------------------------------------------------------------------- 1519 1520 void ScViewFunc::AutoFormat( sal_uInt16 nFormatNo, sal_Bool bRecord ) 1521 { 1522 #if 1 1523 1524 ScRange aRange; 1525 if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE) 1526 { 1527 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 1528 ScMarkData& rMark = GetViewData()->GetMarkData(); 1529 1530 sal_Bool bSuccess = pDocSh->GetDocFunc().AutoFormat( aRange, &rMark, nFormatNo, bRecord, sal_False ); 1531 if (bSuccess) 1532 pDocSh->UpdateOle(GetViewData()); 1533 } 1534 else 1535 ErrorMessage(STR_NOMULTISELECT); 1536 1537 #else 1538 1539 // nur wegen Matrix nicht editierbar? Attribute trotzdem ok 1540 sal_Bool bOnlyNotBecauseOfMatrix; 1541 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix ) 1542 { 1543 ErrorMessage(STR_PROTECTIONERR); 1544 return; 1545 } 1546 1547 SCCOL nStartCol; 1548 SCROW nStartRow; 1549 SCTAB nStartTab; 1550 SCCOL nEndCol; 1551 SCROW nEndRow; 1552 SCTAB nEndTab; 1553 1554 if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE) 1555 { 1556 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 1557 ScDocument* pDoc = pDocSh->GetDocument(); 1558 ScMarkData& rMark = GetViewData()->GetMarkData(); 1559 sal_Bool bSize = (*ScGlobal::GetAutoFormat())[nFormatNo]->GetIncludeWidthHeight(); 1560 if (bRecord && !pDoc->IsUndoEnabled()) 1561 bRecord = sal_False; 1562 1563 ScDocument* pUndoDoc = NULL; 1564 if ( bRecord ) 1565 { 1566 pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); 1567 pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab, bSize, bSize ); 1568 pDoc->CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab, 1569 IDF_ATTRIB, sal_False, pUndoDoc ); 1570 if (bSize) 1571 { 1572 pDoc->CopyToDocument( nStartCol,0,nStartTab, nEndCol,MAXROW,nEndTab, 1573 IDF_NONE, sal_False, pUndoDoc ); 1574 pDoc->CopyToDocument( 0,nStartRow,nStartTab, MAXCOL,nEndRow,nEndTab, 1575 IDF_NONE, sal_False, pUndoDoc ); 1576 } 1577 pDoc->BeginDrawUndo(); 1578 } 1579 1580 GetFrameWin()->EnterWait(); 1581 pDoc->AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo, rMark ); 1582 GetFrameWin()->LeaveWait(); 1583 1584 if (bSize) 1585 { 1586 SetMarkedWidthOrHeight( sal_True, SC_SIZE_VISOPT, STD_EXTRA_WIDTH, sal_False, sal_False ); 1587 SetMarkedWidthOrHeight( sal_False, SC_SIZE_VISOPT, 0, sal_False, sal_False ); 1588 pDocSh->PostPaint( 0,0,nStartTab, MAXCOL,MAXROW,nStartTab, 1589 PAINT_GRID | PAINT_LEFT | PAINT_TOP ); 1590 } 1591 else 1592 { 1593 sal_Bool bAdj = AdjustBlockHeight( sal_False ); 1594 if (bAdj) 1595 pDocSh->PostPaint( 0,nStartRow,nStartTab, MAXCOL,MAXROW,nStartTab, 1596 PAINT_GRID | PAINT_LEFT ); 1597 else 1598 pDocSh->PostPaint( nStartCol, nStartRow, nStartTab, 1599 nEndCol, nEndRow, nEndTab, PAINT_GRID ); 1600 } 1601 1602 if ( bRecord ) // Draw-Undo erst jetzt verfuegbar 1603 { 1604 pDocSh->GetUndoManager()->AddUndoAction( 1605 new ScUndoAutoFormat( pDocSh, 1606 ScRange(nStartCol,nStartRow,nStartTab, nEndCol,nEndRow,nEndTab), 1607 pUndoDoc, rMark, bSize, nFormatNo ) ); 1608 } 1609 1610 pDocSh->UpdateOle(GetViewData()); 1611 pDocSh->SetDocumentModified(); 1612 } 1613 else 1614 ErrorMessage(STR_NOMULTISELECT); 1615 1616 #endif 1617 } 1618 1619 1620 //---------------------------------------------------------------------------- 1621 // Suchen & Ersetzen 1622 1623 void ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem, 1624 sal_Bool bAddUndo, sal_Bool bIsApi ) 1625 { 1626 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 1627 ScDocument* pDoc = pDocSh->GetDocument(); 1628 ScMarkData& rMark = GetViewData()->GetMarkData(); 1629 if (bAddUndo && !pDoc->IsUndoEnabled()) 1630 bAddUndo = sal_False; 1631 1632 SCCOL nCol = GetViewData()->GetCurX(); 1633 SCROW nRow = GetViewData()->GetCurY(); 1634 SCTAB nTab = GetViewData()->GetTabNo(); 1635 // sal_Bool bAttrib = pSearchItem->GetPattern(); 1636 sal_uInt16 nCommand = pSearchItem->GetCommand(); 1637 sal_Bool bAllTables = pSearchItem->IsAllTables(); 1638 sal_Bool* pOldSelectedTables = NULL; 1639 sal_uInt16 nOldSelectedCount = 0; 1640 SCTAB nOldTab = nTab; 1641 SCTAB nLastTab = pDoc->GetTableCount() - 1; 1642 SCTAB nStartTab, nEndTab; 1643 if ( bAllTables ) 1644 { 1645 nStartTab = 0; 1646 nEndTab = nLastTab; 1647 pOldSelectedTables = new sal_Bool [ nEndTab + 1 ]; 1648 for ( SCTAB j = 0; j <= nEndTab; j++ ) 1649 { 1650 pOldSelectedTables[j] = rMark.GetTableSelect( j ); 1651 if ( pOldSelectedTables[j] ) 1652 ++nOldSelectedCount; 1653 } 1654 } 1655 else 1656 { //! mindestens eine ist immer selektiert 1657 nStartTab = nEndTab = rMark.GetFirstSelected(); 1658 for ( SCTAB j = nStartTab + 1; j <= nLastTab; j++ ) 1659 { 1660 if ( rMark.GetTableSelect( j ) ) 1661 nEndTab = j; 1662 } 1663 } 1664 1665 if ( nCommand == SVX_SEARCHCMD_REPLACE 1666 || nCommand == SVX_SEARCHCMD_REPLACE_ALL ) 1667 { 1668 for ( SCTAB j = nStartTab; j <= nEndTab; j++ ) 1669 { 1670 if ( (bAllTables || rMark.GetTableSelect( j )) && 1671 pDoc->IsTabProtected( j ) ) 1672 { 1673 if ( pOldSelectedTables ) 1674 delete [] pOldSelectedTables; 1675 ErrorMessage(STR_PROTECTIONERR); 1676 return; 1677 } 1678 } 1679 } 1680 1681 if ( nCommand == SVX_SEARCHCMD_FIND 1682 || nCommand == SVX_SEARCHCMD_FIND_ALL) 1683 bAddUndo = sal_False; 1684 1685 //! bAttrib bei Undo beruecksichtigen !!! 1686 1687 ScDocument* pUndoDoc = NULL; 1688 ScMarkData* pUndoMark = NULL; 1689 String aUndoStr; 1690 if (bAddUndo) 1691 { 1692 pUndoMark = new ScMarkData( rMark ); // Markierung wird veraendert 1693 if ( nCommand == SVX_SEARCHCMD_REPLACE_ALL ) 1694 { 1695 pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); 1696 pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab ); 1697 } 1698 } 1699 1700 if ( bAllTables ) 1701 { //! alles selektieren, erst nachdem pUndoMark erzeugt wurde 1702 for ( SCTAB j = nStartTab; j <= nEndTab; j++ ) 1703 { 1704 rMark.SelectTable( j, sal_True ); 1705 } 1706 } 1707 1708 DoneBlockMode(sal_True); // Markierung nicht loeschen! 1709 InitOwnBlockMode(); 1710 1711 // wenn vom Anfang an gesucht wird, nicht nochmal fragen ob vom Anfang gesucht werden soll 1712 sal_Bool bFirst = sal_True; 1713 if ( nCol == 0 && nRow == 0 && nTab == nStartTab && !pSearchItem->GetBackward() ) 1714 bFirst = sal_False; 1715 1716 sal_Bool bFound = sal_False; 1717 while (sal_True) 1718 { 1719 GetFrameWin()->EnterWait(); 1720 if (pDoc->SearchAndReplace( *pSearchItem, nCol, nRow, nTab, rMark, aUndoStr, pUndoDoc ) ) 1721 { 1722 bFound = sal_True; 1723 bFirst = sal_True; 1724 if (bAddUndo) 1725 { 1726 GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction( 1727 new ScUndoReplace( GetViewData()->GetDocShell(), *pUndoMark, 1728 nCol, nRow, nTab, 1729 aUndoStr, pUndoDoc, pSearchItem ) ); 1730 pUndoDoc = NULL; 1731 } 1732 1733 break; // Abbruch while True 1734 } 1735 else if ( bFirst && (nCommand == SVX_SEARCHCMD_FIND || 1736 nCommand == SVX_SEARCHCMD_REPLACE) ) 1737 { 1738 bFirst = sal_False; 1739 sal_uInt16 nRetVal; 1740 GetFrameWin()->LeaveWait(); 1741 if ( bIsApi ) 1742 nRetVal = RET_NO; 1743 else 1744 { 1745 // Suchen-Dialog als Parent, wenn vorhanden 1746 Window* pParent = GetParentOrChild(SID_SEARCH_DLG); 1747 sal_uInt16 nStrId; 1748 if ( pSearchItem->GetBackward() ) 1749 { 1750 if ( nStartTab == nEndTab ) 1751 nStrId = STR_MSSG_SEARCHANDREPLACE_1; 1752 else 1753 nStrId = STR_MSSG_SEARCHANDREPLACE_4; 1754 } 1755 else 1756 { 1757 if ( nStartTab == nEndTab ) 1758 nStrId = STR_MSSG_SEARCHANDREPLACE_2; 1759 else 1760 nStrId = STR_MSSG_SEARCHANDREPLACE_5; 1761 } 1762 MessBox aBox( pParent, WinBits(WB_YES_NO | WB_DEF_YES), 1763 ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_3 ), 1764 ScGlobal::GetRscString( nStrId ) ); 1765 nRetVal = aBox.Execute(); 1766 } 1767 1768 if ( nRetVal == RET_YES ) 1769 { 1770 ScDocument::GetSearchAndReplaceStart( *pSearchItem, nCol, nRow ); 1771 if (pSearchItem->GetBackward()) 1772 nTab = nEndTab; 1773 else 1774 nTab = nStartTab; 1775 } 1776 else 1777 { 1778 break; // Abbruch while True 1779 } 1780 } 1781 else // nichts gefunden 1782 { 1783 if ( nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL ) 1784 { 1785 pDocSh->PostPaintGridAll(); // Markierung 1786 } 1787 1788 GetFrameWin()->LeaveWait(); 1789 if (!bIsApi) 1790 { 1791 // Suchen-Dialog als Parent, wenn vorhanden 1792 Window* pParent = GetParentOrChild(SID_SEARCH_DLG); 1793 // "nichts gefunden" 1794 InfoBox aBox( pParent, ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_0 ) ); 1795 aBox.Execute(); 1796 } 1797 1798 break; // Abbruch while True 1799 } 1800 } // of while sal_True 1801 1802 if ( pOldSelectedTables ) 1803 { // urspruenglich selektierte Tabellen wiederherstellen 1804 for ( SCTAB j = nStartTab; j <= nEndTab; j++ ) 1805 { 1806 rMark.SelectTable( j, pOldSelectedTables[j] ); 1807 } 1808 if ( bFound ) 1809 { // durch Fundstelle neu selektierte Tabelle bleibt 1810 rMark.SelectTable( nTab, sal_True ); 1811 // wenn vorher nur eine selektiert war, ist es ein Tausch 1812 //! wenn nicht, ist jetzt evtl. eine mehr selektiert 1813 if ( nOldSelectedCount == 1 && nTab != nOldTab ) 1814 rMark.SelectTable( nOldTab, sal_False ); 1815 } 1816 delete [] pOldSelectedTables; 1817 } 1818 1819 MarkDataChanged(); 1820 1821 if ( bFound ) 1822 { 1823 if ( nTab != GetViewData()->GetTabNo() ) 1824 SetTabNo( nTab ); 1825 1826 // wenn nichts markiert ist, DoneBlockMode, damit von hier aus 1827 // direkt per Shift-Cursor markiert werden kann: 1828 if (!rMark.IsMarked() && !rMark.IsMultiMarked()) 1829 DoneBlockMode(sal_True); 1830 1831 AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP ); 1832 SetCursor( nCol, nRow, sal_True ); 1833 1834 if ( nCommand == SVX_SEARCHCMD_REPLACE 1835 || nCommand == SVX_SEARCHCMD_REPLACE_ALL ) 1836 { 1837 if ( nCommand == SVX_SEARCHCMD_REPLACE ) 1838 pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID ); 1839 else 1840 pDocSh->PostPaintGridAll(); 1841 pDocSh->SetDocumentModified(); 1842 } 1843 else if ( nCommand == SVX_SEARCHCMD_FIND_ALL ) 1844 pDocSh->PostPaintGridAll(); // Markierung 1845 GetFrameWin()->LeaveWait(); 1846 } 1847 1848 delete pUndoDoc; // loeschen wenn nicht benutzt 1849 delete pUndoMark; // kann immer geloescht werden 1850 } 1851 1852 1853 //---------------------------------------------------------------------------- 1854 // Zielwertsuche 1855 1856 void ScViewFunc::Solve( const ScSolveParam& rParam ) 1857 { 1858 ScDocument* pDoc = GetViewData()->GetDocument(); 1859 1860 SCCOL nDestCol = rParam.aRefVariableCell.Col(); 1861 SCROW nDestRow = rParam.aRefVariableCell.Row(); 1862 SCTAB nDestTab = rParam.aRefVariableCell.Tab(); 1863 1864 ScEditableTester aTester( pDoc, nDestTab, nDestCol,nDestRow, nDestCol,nDestRow ); 1865 if (!aTester.IsEditable()) 1866 { 1867 ErrorMessage(aTester.GetMessageId()); 1868 return; 1869 } 1870 1871 if ( pDoc ) 1872 { 1873 String aTargetValStr; 1874 if ( rParam.pStrTargetVal != NULL ) 1875 aTargetValStr = *(rParam.pStrTargetVal); 1876 1877 String aMsgStr; 1878 String aResStr; 1879 double nSolveResult; 1880 1881 GetFrameWin()->EnterWait(); 1882 1883 sal_Bool bExact = 1884 pDoc->Solver( 1885 rParam.aRefFormulaCell.Col(), 1886 rParam.aRefFormulaCell.Row(), 1887 rParam.aRefFormulaCell.Tab(), 1888 nDestCol, nDestRow, nDestTab, 1889 aTargetValStr, 1890 nSolveResult ); 1891 1892 GetFrameWin()->LeaveWait(); 1893 1894 SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); 1895 sal_uLong nFormat = 0; 1896 const ScPatternAttr* pPattern = pDoc->GetPattern( nDestCol, nDestRow, nDestTab ); 1897 if ( pPattern ) 1898 nFormat = pPattern->GetNumberFormat( pFormatter ); 1899 Color* p; 1900 pFormatter->GetOutputString( nSolveResult, nFormat, aResStr, &p ); 1901 1902 if ( bExact ) 1903 { 1904 aMsgStr = ScGlobal::GetRscString( STR_MSSG_SOLVE_0 ); 1905 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_1 ); 1906 aMsgStr += String( aResStr ); 1907 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_2 ); 1908 } 1909 else 1910 { 1911 aMsgStr = ScGlobal::GetRscString( STR_MSSG_SOLVE_3 ); 1912 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_4 ); 1913 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_5 ); 1914 aMsgStr += String( aResStr ); 1915 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_6 ); 1916 } 1917 1918 MessBox aBox( GetViewData()->GetDialogParent(), 1919 WinBits(WB_YES_NO | WB_DEF_NO), 1920 ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), aMsgStr ); 1921 sal_uInt16 nRetVal = aBox.Execute(); 1922 1923 if ( RET_YES == nRetVal ) 1924 EnterValue( nDestCol, nDestRow, nDestTab, nSolveResult ); 1925 1926 GetViewData()->GetViewShell()->UpdateInputHandler( sal_True ); 1927 } 1928 } 1929 1930 1931 //---------------------------------------------------------------------------- 1932 // Mehrfachoperation 1933 1934 void ScViewFunc::TabOp( const ScTabOpParam& rParam, sal_Bool bRecord ) 1935 { 1936 ScRange aRange; 1937 if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE) 1938 { 1939 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 1940 ScMarkData& rMark = GetViewData()->GetMarkData(); 1941 pDocSh->GetDocFunc().TabOp( aRange, &rMark, rParam, bRecord, sal_False ); 1942 } 1943 else 1944 ErrorMessage(STR_NOMULTISELECT); 1945 } 1946 1947 1948 //---------------------------------------------------------------------------- 1949 1950 void ScViewFunc::MakeScenario( const String& rName, const String& rComment, 1951 const Color& rColor, sal_uInt16 nFlags ) 1952 { 1953 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 1954 ScMarkData& rMark = GetViewData()->GetMarkData(); 1955 SCTAB nTab = GetViewData()->GetTabNo(); 1956 1957 SCTAB nNewTab = pDocSh->MakeScenario( nTab, rName, rComment, rColor, nFlags, rMark ); 1958 if (nFlags & SC_SCENARIO_COPYALL) 1959 SetTabNo( nNewTab, sal_True ); // SC_SCENARIO_COPYALL -> sichtbar 1960 else 1961 { 1962 SfxBindings& rBindings = GetViewData()->GetBindings(); 1963 rBindings.Invalidate( SID_STATUS_DOCPOS ); // Statusbar 1964 rBindings.Invalidate( SID_TABLES_COUNT ); 1965 rBindings.Invalidate( SID_SELECT_SCENARIO ); 1966 rBindings.Invalidate( FID_TABLE_SHOW ); 1967 } 1968 } 1969 1970 1971 //---------------------------------------------------------------------------- 1972 1973 void ScViewFunc::ExtendScenario() 1974 { 1975 ScEditableTester aTester( this ); 1976 if (!aTester.IsEditable()) 1977 { 1978 ErrorMessage(aTester.GetMessageId()); 1979 return; 1980 } 1981 1982 // Undo: Attribute anwenden 1983 1984 ScDocument* pDoc = GetViewData()->GetDocument(); 1985 ScPatternAttr aPattern( pDoc->GetPool() ); 1986 aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) ); 1987 aPattern.GetItemSet().Put( ScProtectionAttr( sal_True ) ); 1988 ApplySelectionPattern(aPattern); 1989 } 1990 1991 1992 //---------------------------------------------------------------------------- 1993 1994 void ScViewFunc::UseScenario( const String& rName ) 1995 { 1996 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 1997 SCTAB nTab = GetViewData()->GetTabNo(); 1998 1999 DoneBlockMode(); 2000 InitOwnBlockMode(); 2001 pDocSh->UseScenario( nTab, rName ); 2002 } 2003 2004 2005 //---------------------------------------------------------------------------- 2006 // Tabelle einfuegen 2007 2008 sal_Bool ScViewFunc::InsertTable( const String& rName, SCTAB nTab, sal_Bool bRecord ) 2009 { 2010 // Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt 2011 sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc(). 2012 InsertTable( nTab, rName, bRecord, sal_False ); 2013 if (bSuccess) 2014 SetTabNo( nTab, sal_True ); 2015 2016 return bSuccess; 2017 } 2018 2019 //---------------------------------------------------------------------------- 2020 // Tabellen einfuegen 2021 2022 sal_Bool ScViewFunc::InsertTables(SvStrings *pNames, SCTAB nTab, 2023 SCTAB nCount, sal_Bool bRecord ) 2024 { 2025 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 2026 ScDocument* pDoc = pDocSh->GetDocument(); 2027 if (bRecord && !pDoc->IsUndoEnabled()) 2028 bRecord = sal_False; 2029 2030 SvStrings *pNameList= NULL; 2031 2032 WaitObject aWait( GetFrameWin() ); 2033 2034 if (bRecord) 2035 { 2036 pNameList= new SvStrings; 2037 pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage 2038 } 2039 2040 sal_Bool bFlag=sal_False; 2041 2042 String aValTabName; 2043 String *pStr; 2044 2045 for(SCTAB i=0;i<nCount;i++) 2046 { 2047 if(pNames!=NULL) 2048 { 2049 pStr=pNames->GetObject(static_cast<sal_uInt16>(i)); 2050 } 2051 else 2052 { 2053 aValTabName.Erase(); 2054 pDoc->CreateValidTabName( aValTabName); 2055 pStr=&aValTabName; 2056 } 2057 2058 if(pDoc->InsertTab( nTab+i,*pStr)) 2059 { 2060 bFlag=sal_True; 2061 pDocSh->Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab+i ) ); 2062 } 2063 else 2064 { 2065 break; 2066 } 2067 2068 if(pNameList!=NULL) 2069 pNameList->Insert(new String(*pStr),pNameList->Count()); 2070 2071 } 2072 2073 if (bFlag) 2074 { 2075 if (bRecord) 2076 pDocSh->GetUndoManager()->AddUndoAction( 2077 new ScUndoInsertTables( pDocSh, nTab, sal_False, pNameList)); 2078 2079 // Views updaten: 2080 2081 SetTabNo( nTab, sal_True ); 2082 pDocSh->PostPaintExtras(); 2083 pDocSh->SetDocumentModified(); 2084 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); 2085 return sal_True; 2086 } 2087 else 2088 { 2089 return sal_False; 2090 } 2091 } 2092 2093 2094 //---------------------------------------------------------------------------- 2095 2096 sal_Bool ScViewFunc::AppendTable( const String& rName, sal_Bool bRecord ) 2097 { 2098 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 2099 ScDocument* pDoc = pDocSh->GetDocument(); 2100 if (bRecord && !pDoc->IsUndoEnabled()) 2101 bRecord = sal_False; 2102 2103 WaitObject aWait( GetFrameWin() ); 2104 2105 if (bRecord) 2106 pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage 2107 2108 if (pDoc->InsertTab( SC_TAB_APPEND, rName )) 2109 { 2110 SCTAB nTab = pDoc->GetTableCount()-1; 2111 if (bRecord) 2112 pDocSh->GetUndoManager()->AddUndoAction( 2113 new ScUndoInsertTab( pDocSh, nTab, sal_True, rName)); 2114 GetViewData()->InsertTab( nTab ); 2115 SetTabNo( nTab, sal_True ); 2116 pDocSh->PostPaintExtras(); 2117 pDocSh->SetDocumentModified(); 2118 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); 2119 return sal_True; 2120 } 2121 else 2122 { 2123 return sal_False; 2124 } 2125 } 2126 2127 2128 //---------------------------------------------------------------------------- 2129 2130 sal_Bool ScViewFunc::DeleteTable( SCTAB nTab, sal_Bool bRecord ) 2131 { 2132 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 2133 ScDocument* pDoc = pDocSh->GetDocument(); 2134 2135 sal_Bool bSuccess = pDocSh->GetDocFunc().DeleteTable( nTab, bRecord, sal_False ); 2136 if (bSuccess) 2137 { 2138 SCTAB nNewTab = nTab; 2139 if ( nNewTab >= pDoc->GetTableCount() ) 2140 --nNewTab; 2141 SetTabNo( nNewTab, sal_True ); 2142 } 2143 return bSuccess; 2144 } 2145 2146 sal_Bool ScViewFunc::DeleteTables(const SvShorts &TheTabs, sal_Bool bRecord ) 2147 { 2148 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 2149 ScDocument* pDoc = pDocSh->GetDocument(); 2150 sal_Bool bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : sal_False; 2151 SCTAB nNewTab = TheTabs.front(); 2152 WaitObject aWait( GetFrameWin() ); 2153 if (bRecord && !pDoc->IsUndoEnabled()) 2154 bRecord = sal_False; 2155 2156 while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) ) 2157 --nNewTab; 2158 2159 sal_Bool bWasLinked = sal_False; 2160 ScDocument* pUndoDoc = NULL; 2161 ScRefUndoData* pUndoData = NULL; 2162 if (bRecord) 2163 { 2164 pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); 2165 // pUndoDoc->InitDrawLayer( pDocSh ); 2166 SCTAB nCount = pDoc->GetTableCount(); 2167 2168 // pUndoDoc->InitUndo( pDoc, 0, nCount-1 ); // incl. Ref. 2169 2170 String aOldName; 2171 for (size_t i = 0; i < TheTabs.size(); i++) 2172 { 2173 SCTAB nTab = TheTabs[i]; 2174 if (i==0) 2175 pUndoDoc->InitUndo( pDoc, nTab,nTab, sal_True,sal_True ); // incl. Spalten/Zeilenflags 2176 else 2177 pUndoDoc->AddUndoTab( nTab,nTab, sal_True,sal_True ); // incl. Spalten/Zeilenflags 2178 2179 pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,sal_False, pUndoDoc ); 2180 pDoc->GetName( nTab, aOldName ); 2181 pUndoDoc->RenameTab( nTab, aOldName, sal_False ); 2182 if (pDoc->IsLinked(nTab)) 2183 { 2184 bWasLinked = sal_True; 2185 pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab), 2186 pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab), 2187 pDoc->GetLinkTab(nTab), 2188 pDoc->GetLinkRefreshDelay(nTab) ); 2189 } 2190 if ( pDoc->IsScenario(nTab) ) 2191 { 2192 pUndoDoc->SetScenario( nTab, sal_True ); 2193 String aComment; 2194 Color aColor; 2195 sal_uInt16 nScenFlags; 2196 pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags ); 2197 pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags ); 2198 sal_Bool bActive = pDoc->IsActiveScenario( nTab ); 2199 pUndoDoc->SetActiveScenario( nTab, bActive ); 2200 } 2201 pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) ); 2202 pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) ); 2203 pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) ); 2204 2205 if ( pDoc->IsTabProtected( nTab ) ) 2206 pUndoDoc->SetTabProtection(nTab, pDoc->GetTabProtection(nTab)); 2207 2208 // Drawing-Layer muss sein Undo selbst in der Hand behalten !!! 2209 // pUndoDoc->TransferDrawPage(pDoc, nTab,nTab); 2210 } 2211 2212 pUndoDoc->AddUndoTab( 0, nCount-1 ); // alle Tabs fuer Referenzen 2213 2214 pDoc->BeginDrawUndo(); // DeleteTab erzeugt ein SdrUndoDelPage 2215 2216 pUndoData = new ScRefUndoData( pDoc ); 2217 } 2218 2219 sal_Bool bDelDone = sal_False; 2220 2221 for (size_t i = TheTabs.size(); i > 0; i--) 2222 { 2223 String sCodeName; 2224 sal_Bool bHasCodeName = pDoc->GetCodeName( TheTabs[i-1], sCodeName ); 2225 if (pDoc->DeleteTab( TheTabs[i-1], pUndoDoc )) 2226 { 2227 bDelDone = sal_True; 2228 if( bVbaEnabled ) 2229 { 2230 if( bHasCodeName ) 2231 { 2232 VBA_DeleteModule( *pDocSh, sCodeName ); 2233 } 2234 } 2235 pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[i-1] ) ); 2236 } 2237 } 2238 if (bRecord) 2239 { 2240 pDocSh->GetUndoManager()->AddUndoAction( 2241 new ScUndoDeleteTab( GetViewData()->GetDocShell(), TheTabs, 2242 pUndoDoc, pUndoData )); 2243 } 2244 2245 2246 if (bDelDone) 2247 { 2248 if ( nNewTab >= pDoc->GetTableCount() ) 2249 nNewTab = pDoc->GetTableCount() - 1; 2250 2251 SetTabNo( nNewTab, sal_True ); 2252 2253 if (bWasLinked) 2254 { 2255 pDocSh->UpdateLinks(); // Link-Manager updaten 2256 GetViewData()->GetBindings().Invalidate(SID_LINKS); 2257 } 2258 2259 pDocSh->PostPaintExtras(); 2260 pDocSh->SetDocumentModified(); 2261 2262 SfxApplication* pSfxApp = SFX_APP(); // Navigator 2263 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); 2264 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) ); 2265 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); 2266 } 2267 else 2268 { 2269 delete pUndoDoc; 2270 delete pUndoData; 2271 } 2272 return bDelDone; 2273 } 2274 2275 2276 //---------------------------------------------------------------------------- 2277 2278 sal_Bool ScViewFunc::RenameTable( const String& rName, SCTAB nTab ) 2279 { 2280 // Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt 2281 sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc(). 2282 RenameTable( nTab, rName, sal_True, sal_False ); 2283 if (bSuccess) 2284 { 2285 // Der Tabellenname koennte in einer Formel vorkommen... 2286 GetViewData()->GetViewShell()->UpdateInputHandler(); 2287 } 2288 return bSuccess; 2289 } 2290 2291 2292 //---------------------------------------------------------------------------- 2293 2294 bool ScViewFunc::SetTabBgColor( const Color& rColor, SCTAB nTab ) 2295 { 2296 bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( nTab, rColor, sal_True, sal_False ); 2297 if (bSuccess) 2298 { 2299 GetViewData()->GetViewShell()->UpdateInputHandler(); 2300 } 2301 return bSuccess; 2302 } 2303 2304 bool ScViewFunc::SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList ) 2305 { 2306 bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList, sal_True, sal_False ); 2307 if (bSuccess) 2308 { 2309 GetViewData()->GetViewShell()->UpdateInputHandler(); 2310 } 2311 return bSuccess; 2312 } 2313 2314 //---------------------------------------------------------------------------- 2315 2316 void ScViewFunc::InsertAreaLink( const String& rFile, 2317 const String& rFilter, const String& rOptions, 2318 const String& rSource, sal_uLong nRefresh ) 2319 { 2320 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 2321 SCCOL nPosX = GetViewData()->GetCurX(); 2322 SCROW nPosY = GetViewData()->GetCurY(); 2323 SCTAB nTab = GetViewData()->GetTabNo(); 2324 ScAddress aPos( nPosX, nPosY, nTab ); 2325 2326 pDocSh->GetDocFunc().InsertAreaLink( rFile, rFilter, rOptions, rSource, aPos, nRefresh, sal_False, sal_False ); 2327 } 2328 2329 2330 //---------------------------------------------------------------------------- 2331 2332 void ScViewFunc::InsertTableLink( const String& rFile, 2333 const String& rFilter, const String& rOptions, 2334 const String& rTabName ) 2335 { 2336 String aFilterName = rFilter; 2337 String aOpt = rOptions; 2338 ScDocumentLoader aLoader( rFile, aFilterName, aOpt ); 2339 if (!aLoader.IsError()) 2340 { 2341 ScDocShell* pSrcSh = aLoader.GetDocShell(); 2342 ScDocument* pSrcDoc = pSrcSh->GetDocument(); 2343 SCTAB nTab = MAXTAB+1; 2344 if (!rTabName.Len()) // kein Name angegeben -> erste Tabelle 2345 nTab = 0; 2346 else 2347 { 2348 String aTemp; 2349 SCTAB nCount = pSrcDoc->GetTableCount(); 2350 for (SCTAB i=0; i<nCount; i++) 2351 { 2352 pSrcDoc->GetName( i, aTemp ); 2353 if ( aTemp == rTabName ) 2354 nTab = i; 2355 } 2356 } 2357 2358 if ( nTab <= MAXTAB ) 2359 ImportTables( pSrcSh, 1, &nTab, sal_True, 2360 GetViewData()->GetTabNo() ); 2361 } 2362 } 2363 2364 2365 //---------------------------------------------------------------------------- 2366 // Tabellen aus anderem Dokument kopieren / linken 2367 2368 void ScViewFunc::ImportTables( ScDocShell* pSrcShell, 2369 SCTAB nCount, const SCTAB* pSrcTabs, sal_Bool bLink,SCTAB nTab ) 2370 { 2371 ScDocument* pSrcDoc = pSrcShell->GetDocument(); 2372 2373 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 2374 ScDocument* pDoc = pDocSh->GetDocument(); 2375 sal_Bool bUndo(pDoc->IsUndoEnabled()); 2376 //SCTAB nTab = GetViewData()->GetTabNo(); 2377 2378 sal_Bool bError = sal_False; 2379 sal_Bool bRefs = sal_False; 2380 sal_Bool bName = sal_False; 2381 2382 if (pSrcDoc->GetDrawLayer()) 2383 pDocSh->MakeDrawLayer(); 2384 2385 if (bUndo) 2386 pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions 2387 2388 SCTAB nInsCount = 0; 2389 SCTAB i; 2390 for( i=0; i<nCount; i++ ) 2391 { // #63304# insert sheets first and update all references 2392 String aName; 2393 pSrcDoc->GetName( pSrcTabs[i], aName ); 2394 pDoc->CreateValidTabName( aName ); 2395 if ( !pDoc->InsertTab( nTab+i, aName ) ) 2396 { 2397 bError = sal_True; // total error 2398 break; // for 2399 } 2400 ++nInsCount; 2401 } 2402 for (i=0; i<nCount && !bError; i++) 2403 { 2404 SCTAB nSrcTab = pSrcTabs[i]; 2405 SCTAB nDestTab1=nTab+i; 2406 sal_uLong nErrVal = pDoc->TransferTab( pSrcDoc, nSrcTab, nDestTab1, 2407 sal_False ); // no insert 2408 2409 switch (nErrVal) 2410 { 2411 case 0: // interner Fehler oder voll Fehler 2412 bError = sal_True; 2413 break; 2414 case 2: 2415 bRefs = sal_True; 2416 break; 2417 case 3: 2418 bName = sal_True; 2419 break; 2420 case 4: 2421 bRefs = bName = sal_True; 2422 break; 2423 } 2424 2425 // TransferTab doesn't copy drawing objects with bInsertNew=FALSE 2426 if ( !bError ) 2427 pDoc->TransferDrawPage( pSrcDoc, nSrcTab, nDestTab1 ); 2428 2429 if(!bError &&pSrcDoc->IsScenario(nSrcTab)) 2430 { 2431 String aComment; 2432 Color aColor; 2433 sal_uInt16 nFlags; 2434 2435 pSrcDoc->GetScenarioData(nSrcTab, aComment,aColor, nFlags); 2436 pDoc->SetScenario( nDestTab1,sal_True); 2437 pDoc->SetScenarioData( nTab+i,aComment,aColor,nFlags); 2438 sal_Bool bActive = pSrcDoc->IsActiveScenario(nSrcTab ); 2439 pDoc->SetActiveScenario( nDestTab1, bActive ); 2440 sal_Bool bVisible=pSrcDoc->IsVisible(nSrcTab); 2441 pDoc->SetVisible(nDestTab1,bVisible ); 2442 2443 } 2444 } 2445 2446 if (bLink) 2447 { 2448 sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager(); 2449 2450 SfxMedium* pMed = pSrcShell->GetMedium(); 2451 String aFileName = pMed->GetName(); 2452 String aFilterName; 2453 if (pMed->GetFilter()) 2454 aFilterName = pMed->GetFilter()->GetFilterName(); 2455 String aOptions = ScDocumentLoader::GetOptions(*pMed); 2456 2457 sal_Bool bWasThere = pDoc->HasLink( aFileName, aFilterName, aOptions ); 2458 2459 sal_uLong nRefresh = 0; 2460 String aTabStr; 2461 for (i=0; i<nInsCount; i++) 2462 { 2463 pSrcDoc->GetName( pSrcTabs[i], aTabStr ); 2464 pDoc->SetLink( nTab+i, SC_LINK_NORMAL, 2465 aFileName, aFilterName, aOptions, aTabStr, nRefresh ); 2466 } 2467 2468 if (!bWasThere) // Link pro Quelldokument nur einmal eintragen 2469 { 2470 ScTableLink* pLink = new ScTableLink( pDocSh, aFileName, aFilterName, aOptions, nRefresh ); 2471 pLink->SetInCreate( sal_True ); 2472 pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName, &aFilterName ); 2473 pLink->Update(); 2474 pLink->SetInCreate( sal_False ); 2475 2476 SfxBindings& rBindings = GetViewData()->GetBindings(); 2477 rBindings.Invalidate( SID_LINKS ); 2478 } 2479 } 2480 2481 2482 if (bUndo) 2483 { 2484 pDocSh->GetUndoManager()->AddUndoAction( 2485 new ScUndoImportTab( pDocSh, nTab, nCount, bLink ) ); 2486 } 2487 2488 for (i=0; i<nInsCount; i++) 2489 GetViewData()->InsertTab(nTab); 2490 SetTabNo(nTab,sal_True); 2491 pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, 2492 PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS ); 2493 2494 SfxApplication* pSfxApp = SFX_APP(); 2495 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); 2496 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) ); 2497 2498 pDocSh->PostPaintExtras(); 2499 pDocSh->PostPaintGridAll(); 2500 pDocSh->SetDocumentModified(); 2501 2502 if (bRefs) 2503 ErrorMessage(STR_ABSREFLOST); 2504 if (bName) 2505 ErrorMessage(STR_NAMECONFLICT); 2506 } 2507 2508 2509 //---------------------------------------------------------------------------- 2510 // Tabelle in anderes Dokument verschieben / kopieren 2511 2512 void ScViewFunc::MoveTable( sal_uInt16 nDestDocNo, SCTAB nDestTab, sal_Bool bCopy ) 2513 { 2514 ScDocument* pDoc = GetViewData()->GetDocument(); 2515 ScDocShell* pDocShell = GetViewData()->GetDocShell(); 2516 ScDocument* pDestDoc = NULL; 2517 ScDocShell* pDestShell = NULL; 2518 ScTabViewShell* pDestViewSh = NULL; 2519 sal_Bool bUndo (pDoc->IsUndoEnabled()); 2520 2521 sal_Bool bNewDoc = ( nDestDocNo == SC_DOC_NEW ); 2522 if ( bNewDoc ) 2523 { 2524 nDestTab = 0; // als erstes einfuegen 2525 2526 // ohne SFX_CALLMODE_RECORD ausfuehren, weil schon im Move-Befehl enthalten: 2527 2528 String aUrl = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("private:factory/")); 2529 aUrl.AppendAscii(RTL_CONSTASCII_STRINGPARAM( STRING_SCAPP )); // "scalc" 2530 SfxStringItem aItem( SID_FILE_NAME, aUrl ); 2531 SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") ); 2532 2533 const SfxPoolItem* pRetItem = GetViewData()->GetDispatcher().Execute( 2534 SID_OPENDOC, SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON, &aItem, &aTarget, 0L ); 2535 if ( pRetItem ) 2536 { 2537 if ( pRetItem->ISA( SfxObjectItem ) ) 2538 pDestShell = PTR_CAST( ScDocShell, ((const SfxObjectItem*)pRetItem)->GetShell() ); 2539 else if ( pRetItem->ISA( SfxViewFrameItem ) ) 2540 { 2541 SfxViewFrame* pFrm = ((const SfxViewFrameItem*)pRetItem)->GetFrame(); 2542 if (pFrm) 2543 pDestShell = PTR_CAST( ScDocShell, pFrm->GetObjectShell() ); 2544 } 2545 if (pDestShell) 2546 pDestViewSh = pDestShell->GetBestViewShell(); 2547 } 2548 } 2549 else 2550 pDestShell = ScDocShell::GetShellByNum( nDestDocNo ); 2551 2552 if (!pDestShell) 2553 { 2554 DBG_ERROR("Dest-Doc nicht gefunden !!!"); 2555 return; 2556 } 2557 2558 pDestDoc = pDestShell->GetDocument(); 2559 2560 SCTAB nTab = GetViewData()->GetTabNo(); 2561 2562 if (pDestDoc != pDoc) 2563 { 2564 if (bNewDoc) 2565 { 2566 while (pDestDoc->GetTableCount() > 1) 2567 pDestDoc->DeleteTab(0); 2568 pDestDoc->RenameTab( 0, 2569 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("______42_____")), 2570 sal_False ); 2571 } 2572 2573 ScMarkData& rMark = GetViewData()->GetMarkData(); 2574 SCTAB nTabCount = pDoc->GetTableCount(); 2575 SCTAB nTabSelCount = rMark.GetSelectCount(); 2576 2577 SvShorts TheTabs; 2578 2579 for(SCTAB i=0;i<nTabCount;i++) 2580 { 2581 if(rMark.GetTableSelect(i)) 2582 { 2583 String aTabName; 2584 pDoc->GetName( i, aTabName); 2585 TheTabs.push_back(i); 2586 for(SCTAB j=i+1;j<nTabCount;j++) 2587 { 2588 if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j))) 2589 { 2590 pDoc->GetName( j, aTabName); 2591 TheTabs.push_back(j); 2592 i=j; 2593 } 2594 else break; 2595 } 2596 } 2597 } 2598 2599 GetFrameWin()->EnterWait(); 2600 2601 if (pDoc->GetDrawLayer()) 2602 pDestShell->MakeDrawLayer(); 2603 2604 if (!bNewDoc && bUndo) 2605 pDestDoc->BeginDrawUndo(); // drawing layer must do its own undo actions 2606 2607 sal_uLong nErrVal =1; 2608 if(nDestTab==SC_TAB_APPEND) 2609 nDestTab=pDestDoc->GetTableCount(); 2610 SCTAB nDestTab1=nDestTab; 2611 for( size_t j=0; j<TheTabs.size(); j++, nDestTab1++ ) 2612 { // #63304# insert sheets first and update all references 2613 String aName; 2614 pDoc->GetName( TheTabs[j], aName ); 2615 pDestDoc->CreateValidTabName( aName ); 2616 if ( !pDestDoc->InsertTab( nDestTab1, aName ) ) 2617 { 2618 nErrVal = 0; // total error 2619 break; // for 2620 } 2621 } 2622 if ( nErrVal > 0 ) 2623 { 2624 nDestTab1 = nDestTab; 2625 for(size_t i=0;i<TheTabs.size();i++) 2626 { 2627 nErrVal = pDestDoc->TransferTab( pDoc, TheTabs[i], nDestTab1, 2628 sal_False ); // no insert 2629 2630 // TransferTab doesn't copy drawing objects with bInsertNew=FALSE 2631 if ( nErrVal > 0 ) 2632 pDestDoc->TransferDrawPage( pDoc, TheTabs[i], nDestTab1 ); 2633 2634 if(nErrVal>0 && pDoc->IsScenario(TheTabs[i])) 2635 { 2636 String aComment; 2637 Color aColor; 2638 sal_uInt16 nFlags; 2639 2640 pDoc->GetScenarioData(TheTabs[i], aComment,aColor, nFlags); 2641 pDestDoc->SetScenario(nDestTab1,sal_True); 2642 pDestDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags); 2643 sal_Bool bActive = pDoc->IsActiveScenario(TheTabs[i]); 2644 pDestDoc->SetActiveScenario(nDestTab1, bActive ); 2645 2646 sal_Bool bVisible=pDoc->IsVisible(TheTabs[i]); 2647 pDestDoc->SetVisible(nDestTab1,bVisible ); 2648 2649 } 2650 2651 if ( nErrVal > 0 && pDoc->IsTabProtected( TheTabs[i] ) ) 2652 pDestDoc->SetTabProtection(nDestTab1, pDoc->GetTabProtection(TheTabs[i])); 2653 2654 nDestTab1++; 2655 } 2656 } 2657 String sName; 2658 if (!bNewDoc && bUndo) 2659 { 2660 pDestDoc->GetName(nDestTab, sName); 2661 pDestShell->GetUndoManager()->AddUndoAction( 2662 new ScUndoImportTab( pDestShell, nDestTab, 2663 static_cast<SCTAB>(TheTabs.size()), sal_False)); 2664 2665 } 2666 else 2667 { 2668 pDestShell->GetUndoManager()->Clear(); 2669 } 2670 2671 GetFrameWin()->LeaveWait(); 2672 switch (nErrVal) 2673 { 2674 case 0: // interner Fehler oder voll Fehler 2675 { 2676 ErrorMessage(STR_TABINSERT_ERROR); 2677 return; 2678 } 2679 //break; 2680 case 2: 2681 ErrorMessage(STR_ABSREFLOST); 2682 break; 2683 case 3: 2684 ErrorMessage(STR_NAMECONFLICT); 2685 break; 2686 case 4: 2687 { 2688 ErrorMessage(STR_ABSREFLOST); 2689 ErrorMessage(STR_NAMECONFLICT); 2690 } 2691 break; 2692 default: 2693 break; 2694 } 2695 //pDestShell->GetUndoManager()->Clear(); //! Undo implementieren !!! 2696 /* 2697 String sName; 2698 pDestDoc->GetName(nDestTab, sName); 2699 pDestShell->GetUndoManager()->AddUndoAction( 2700 new ScUndoInsertTab( pDestShell, nDestTab, sal_True, sName ) ); 2701 */ 2702 if (!bCopy) 2703 { 2704 if(nTabCount!=nTabSelCount) 2705 DeleteTables(TheTabs);// incl. Paint & Undo 2706 else 2707 ErrorMessage(STR_TABREMOVE_ERROR); 2708 } 2709 2710 if (bNewDoc) 2711 { 2712 // ChartListenerCollection must be updated before DeleteTab 2713 if ( pDestDoc->IsChartListenerCollectionNeedsUpdate() ) 2714 pDestDoc->UpdateChartListenerCollection(); 2715 2716 pDestDoc->DeleteTab(static_cast<SCTAB>(TheTabs.size())); // first old table 2717 //? pDestDoc->SelectTable(0, sal_True); // neue erste Tabelle selektieren 2718 if (pDestViewSh) 2719 pDestViewSh->TabChanged(); // Pages auf dem Drawing-Layer 2720 pDestShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, 2721 PAINT_GRID | PAINT_TOP | PAINT_LEFT | 2722 PAINT_EXTRAS | PAINT_SIZE ); 2723 // PAINT_SIZE fuer Gliederung 2724 } 2725 else 2726 { 2727 pDestShell->Broadcast( ScTablesHint( SC_TAB_INSERTED, nDestTab ) ); 2728 pDestShell->PostPaintExtras(); 2729 pDestShell->PostPaintGridAll(); 2730 } 2731 2732 TheTabs.clear(); 2733 2734 pDestShell->SetDocumentModified(); 2735 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); 2736 } 2737 else // within the documents 2738 { 2739 2740 ScMarkData& rMark = GetViewData()->GetMarkData(); 2741 SCTAB nTabCount = pDoc->GetTableCount(); 2742 2743 SvShorts TheTabs; 2744 SvShorts TheDestTabs; 2745 SvStrings TheTabNames; 2746 String aDestName; 2747 String *pString; 2748 2749 for(SCTAB i=0;i<nTabCount;i++) 2750 { 2751 if(rMark.GetTableSelect(i)) 2752 { 2753 String aTabName; 2754 pDoc->GetName( i, aTabName); 2755 TheTabNames.Insert(new String(aTabName),TheTabNames.Count()); 2756 2757 for(SCTAB j=i+1;j<nTabCount;j++) 2758 { 2759 if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j))) 2760 { 2761 pDoc->GetName( j, aTabName); 2762 TheTabNames.Insert(new String(aTabName),TheTabNames.Count()); 2763 i=j; 2764 } 2765 else break; 2766 } 2767 2768 } 2769 } 2770 2771 if (bCopy && bUndo) 2772 pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions 2773 2774 pDoc->GetName( nDestTab, aDestName); 2775 SCTAB nDestTab1=nDestTab; 2776 SCTAB nMovTab=0; 2777 for(int j=0;j<TheTabNames.Count();j++) 2778 { 2779 nTabCount = pDoc->GetTableCount(); 2780 pString=TheTabNames[sal::static_int_cast<sal_uInt16>(j)]; 2781 if(!pDoc->GetTable(*pString,nMovTab)) 2782 { 2783 nMovTab=nTabCount; 2784 } 2785 if(!pDoc->GetTable(aDestName,nDestTab1)) 2786 { 2787 nDestTab1=nTabCount; 2788 } 2789 pDocShell->MoveTable( nMovTab, nDestTab1, bCopy, sal_False ); // Undo ist hier 2790 2791 if(bCopy && pDoc->IsScenario(nMovTab)) 2792 { 2793 String aComment; 2794 Color aColor; 2795 sal_uInt16 nFlags; 2796 2797 pDoc->GetScenarioData(nMovTab, aComment,aColor, nFlags); 2798 pDoc->SetScenario(nDestTab1,sal_True); 2799 pDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags); 2800 sal_Bool bActive = pDoc->IsActiveScenario(nMovTab ); 2801 pDoc->SetActiveScenario( nDestTab1, bActive ); 2802 sal_Bool bVisible=pDoc->IsVisible(nMovTab); 2803 pDoc->SetVisible(nDestTab1,bVisible ); 2804 } 2805 2806 TheTabs.push_back(nMovTab); 2807 2808 if(!bCopy) 2809 { 2810 if(!pDoc->GetTable(*pString,nDestTab1)) 2811 { 2812 nDestTab1=nTabCount; 2813 } 2814 } 2815 2816 TheDestTabs.push_back(nDestTab1); 2817 delete pString; 2818 } 2819 2820 nTab = GetViewData()->GetTabNo(); 2821 2822 if (bUndo) 2823 { 2824 if (bCopy) 2825 { 2826 pDocShell->GetUndoManager()->AddUndoAction( 2827 new ScUndoCopyTab( pDocShell, TheTabs, TheDestTabs)); 2828 } 2829 else 2830 { 2831 pDocShell->GetUndoManager()->AddUndoAction( 2832 new ScUndoMoveTab( pDocShell, TheTabs, TheDestTabs)); 2833 } 2834 } 2835 2836 SCTAB nNewTab = nDestTab; 2837 if (nNewTab == SC_TAB_APPEND) 2838 nNewTab = pDoc->GetTableCount()-1; 2839 else if (!bCopy && nTab<nDestTab) 2840 nNewTab--; 2841 2842 SetTabNo( nNewTab, sal_True ); 2843 2844 //#i29848# adjust references to data on the copied sheet 2845 if( bCopy ) 2846 ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pDoc, pDestDoc, nTab, nNewTab ); 2847 } 2848 } 2849 2850 2851 //---------------------------------------------------------------------------- 2852 2853 void ScViewFunc::ShowTable( const String& rName ) 2854 { 2855 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 2856 ScDocument* pDoc = pDocSh->GetDocument(); 2857 sal_Bool bUndo(pDoc->IsUndoEnabled()); 2858 sal_Bool bFound = sal_False; 2859 SCTAB nPos = 0; 2860 String aTabName; 2861 SCTAB nCount = pDoc->GetTableCount(); 2862 for (SCTAB i=0; i<nCount; i++) 2863 { 2864 pDoc->GetName( i, aTabName ); 2865 if ( aTabName == rName ) 2866 { 2867 nPos = i; 2868 bFound = sal_True; 2869 } 2870 } 2871 2872 if (bFound) 2873 { 2874 pDoc->SetVisible( nPos, sal_True ); 2875 if (bUndo) 2876 { 2877 pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nPos, sal_True ) ); 2878 } 2879 SetTabNo( nPos, sal_True ); 2880 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); 2881 pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS); 2882 pDocSh->SetDocumentModified(); 2883 } 2884 else 2885 Sound::Beep(); 2886 } 2887 2888 2889 //---------------------------------------------------------------------------- 2890 2891 void ScViewFunc::HideTable( SCTAB nTab ) 2892 { 2893 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 2894 ScDocument* pDoc = pDocSh->GetDocument(); 2895 sal_Bool bUndo(pDoc->IsUndoEnabled()); 2896 SCTAB nVisible = 0; 2897 SCTAB nCount = pDoc->GetTableCount(); 2898 for (SCTAB i=0; i<nCount; i++) 2899 { 2900 if (pDoc->IsVisible(i)) 2901 ++nVisible; 2902 } 2903 2904 if (nVisible > 1) 2905 { 2906 pDoc->SetVisible( nTab, sal_False ); 2907 if (bUndo) 2908 { 2909 pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nTab, sal_False ) ); 2910 } 2911 2912 // Views updaten: 2913 pDocSh->Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) ); 2914 2915 SetTabNo( nTab, sal_True ); 2916 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); 2917 pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS); 2918 pDocSh->SetDocumentModified(); 2919 } 2920 else 2921 Sound::Beep(); 2922 } 2923 2924 2925 //---------------------------------------------------------------------------- 2926 2927 void ScViewFunc::InsertSpecialChar( const String& rStr, const Font& rFont ) 2928 { 2929 ScEditableTester aTester( this ); 2930 if (!aTester.IsEditable()) 2931 { 2932 ErrorMessage(aTester.GetMessageId()); 2933 return; 2934 } 2935 2936 const sal_Unicode* pChar = rStr.GetBuffer(); 2937 ScTabViewShell* pViewShell = GetViewData()->GetViewShell(); 2938 SvxFontItem aFontItem( rFont.GetFamily(), 2939 rFont.GetName(), 2940 rFont.GetStyleName(), 2941 rFont.GetPitch(), 2942 rFont.GetCharSet(), 2943 ATTR_FONT ); 2944 2945 // if string contains WEAK characters, set all fonts 2946 sal_uInt8 nScript; 2947 ScDocument* pDoc = GetViewData()->GetDocument(); 2948 if ( pDoc->HasStringWeakCharacters( rStr ) ) 2949 nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX; 2950 else 2951 nScript = pDoc->GetStringScriptType( rStr ); 2952 2953 SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, pViewShell->GetPool() ); 2954 aSetItem.PutItemForScriptType( nScript, aFontItem ); 2955 ApplyUserItemSet( aSetItem.GetItemSet() ); 2956 2957 while ( *pChar ) 2958 pViewShell->TabKeyInput( KeyEvent( *(pChar++), KeyCode() ) ); 2959 } 2960 2961 2962 //---------------------------------------------------------------------------- 2963 2964 void ScViewFunc::UpdateLineAttrs( SvxBorderLine& rLine, 2965 const SvxBorderLine* pDestLine, 2966 const SvxBorderLine* pSrcLine, 2967 sal_Bool bColor ) 2968 { 2969 if ( pSrcLine && pDestLine ) 2970 { 2971 if ( bColor ) 2972 { 2973 rLine.SetColor ( pSrcLine->GetColor() ); 2974 rLine.SetOutWidth ( pDestLine->GetOutWidth() ); 2975 rLine.SetInWidth ( pDestLine->GetInWidth() ); 2976 rLine.SetDistance ( pDestLine->GetDistance() ); 2977 } 2978 else 2979 { 2980 rLine.SetColor ( pDestLine->GetColor() ); 2981 rLine.SetOutWidth ( pSrcLine->GetOutWidth() ); 2982 rLine.SetInWidth ( pSrcLine->GetInWidth() ); 2983 rLine.SetDistance ( pSrcLine->GetDistance() ); 2984 } 2985 } 2986 } 2987 2988 2989 #define SET_LINE_ATTRIBUTES(LINE,BOXLINE) \ 2990 pBoxLine = aBoxItem.Get##LINE(); \ 2991 if ( pBoxLine ) \ 2992 { \ 2993 if ( pLine ) \ 2994 { \ 2995 UpdateLineAttrs( aLine, pBoxLine, pLine, bColorOnly ); \ 2996 aBoxItem.SetLine( &aLine, BOXLINE ); \ 2997 } \ 2998 else \ 2999 aBoxItem.SetLine( NULL, BOXLINE ); \ 3000 } 3001 3002 3003 //---------------------------------------------------------------------------- 3004 3005 void ScViewFunc::SetSelectionFrameLines( const SvxBorderLine* pLine, 3006 sal_Bool bColorOnly ) 3007 { 3008 // nur wegen Matrix nicht editierbar? Attribute trotzdem ok 3009 sal_Bool bOnlyNotBecauseOfMatrix; 3010 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix ) 3011 { 3012 ErrorMessage(STR_PROTECTIONERR); 3013 return; 3014 } 3015 3016 ScDocument* pDoc = GetViewData()->GetDocument(); 3017 ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered 3018 ScViewUtil::UnmarkFiltered( aFuncMark, pDoc ); 3019 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 3020 const ScPatternAttr* pSelAttrs = GetSelectionPattern(); 3021 const SfxItemSet& rSelItemSet = pSelAttrs->GetItemSet(); 3022 3023 const SfxPoolItem* pBorderAttr = NULL; 3024 SfxItemState eItemState = rSelItemSet.GetItemState( ATTR_BORDER, sal_True, &pBorderAttr ); 3025 3026 const SfxPoolItem* pTLBRItem = 0; 3027 SfxItemState eTLBRState = rSelItemSet.GetItemState( ATTR_BORDER_TLBR, sal_True, &pTLBRItem ); 3028 3029 const SfxPoolItem* pBLTRItem = 0; 3030 SfxItemState eBLTRState = rSelItemSet.GetItemState( ATTR_BORDER_BLTR, sal_True, &pBLTRItem ); 3031 3032 // any of the lines visible? 3033 if( (eItemState != SFX_ITEM_DEFAULT) || (eTLBRState != SFX_ITEM_DEFAULT) || (eBLTRState != SFX_ITEM_DEFAULT) ) 3034 { 3035 // none of the lines don't care? 3036 if( (eItemState != SFX_ITEM_DONTCARE) && (eTLBRState != SFX_ITEM_DONTCARE) && (eBLTRState != SFX_ITEM_DONTCARE) ) 3037 { 3038 SfxItemSet* pOldSet = new SfxItemSet( 3039 *(pDoc->GetPool()), 3040 ATTR_PATTERN_START, 3041 ATTR_PATTERN_END ); 3042 SfxItemSet* pNewSet = new SfxItemSet( 3043 *(pDoc->GetPool()), 3044 ATTR_PATTERN_START, 3045 ATTR_PATTERN_END ); 3046 3047 //------------------------------------------------------------ 3048 const SvxBorderLine* pBoxLine = NULL; 3049 SvxBorderLine aLine; 3050 3051 // hier wird die pBoxLine benutzt: 3052 3053 if( pBorderAttr ) 3054 { 3055 SvxBoxItem aBoxItem( *(const SvxBoxItem*)pBorderAttr ); 3056 SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER ); 3057 3058 SET_LINE_ATTRIBUTES(Top,BOX_LINE_TOP) 3059 SET_LINE_ATTRIBUTES(Bottom,BOX_LINE_BOTTOM) 3060 SET_LINE_ATTRIBUTES(Left,BOX_LINE_LEFT) 3061 SET_LINE_ATTRIBUTES(Right,BOX_LINE_RIGHT) 3062 3063 aBoxInfoItem.SetLine( aBoxItem.GetTop(), BOXINFO_LINE_HORI ); 3064 aBoxInfoItem.SetLine( aBoxItem.GetLeft(), BOXINFO_LINE_VERT ); 3065 aBoxInfoItem.ResetFlags(); // Lines auf Valid setzen 3066 3067 pOldSet->Put( *pBorderAttr ); 3068 pNewSet->Put( aBoxItem ); 3069 pNewSet->Put( aBoxInfoItem ); 3070 } 3071 3072 if( pTLBRItem && ((const SvxLineItem*)pTLBRItem)->GetLine() ) 3073 { 3074 SvxLineItem aTLBRItem( *(const SvxLineItem*)pTLBRItem ); 3075 UpdateLineAttrs( aLine, aTLBRItem.GetLine(), pLine, bColorOnly ); 3076 aTLBRItem.SetLine( &aLine ); 3077 pOldSet->Put( *pTLBRItem ); 3078 pNewSet->Put( aTLBRItem ); 3079 } 3080 3081 if( pBLTRItem && ((const SvxLineItem*)pBLTRItem)->GetLine() ) 3082 { 3083 SvxLineItem aBLTRItem( *(const SvxLineItem*)pBLTRItem ); 3084 UpdateLineAttrs( aLine, aBLTRItem.GetLine(), pLine, bColorOnly ); 3085 aBLTRItem.SetLine( &aLine ); 3086 pOldSet->Put( *pBLTRItem ); 3087 pNewSet->Put( aBLTRItem ); 3088 } 3089 3090 ApplyAttributes( pNewSet, pOldSet ); 3091 3092 delete pOldSet; 3093 delete pNewSet; 3094 } 3095 else // if ( eItemState == SFX_ITEM_DONTCARE ) 3096 { 3097 aFuncMark.MarkToMulti(); 3098 pDoc->ApplySelectionLineStyle( aFuncMark, pLine, bColorOnly ); 3099 } 3100 3101 ScRange aMarkRange; 3102 aFuncMark.GetMultiMarkArea( aMarkRange ); 3103 SCCOL nStartCol = aMarkRange.aStart.Col(); 3104 SCROW nStartRow = aMarkRange.aStart.Row(); 3105 SCTAB nStartTab = aMarkRange.aStart.Tab(); 3106 SCCOL nEndCol = aMarkRange.aEnd.Col(); 3107 SCROW nEndRow = aMarkRange.aEnd.Row(); 3108 SCTAB nEndTab = aMarkRange.aEnd.Tab(); 3109 pDocSh->PostPaint( nStartCol, nStartRow, nStartTab, 3110 nEndCol, nEndRow, nEndTab, 3111 PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE ); 3112 3113 pDocSh->UpdateOle( GetViewData() ); 3114 pDocSh->SetDocumentModified(); 3115 } 3116 } 3117 3118 #undef SET_LINE_ATTRIBUTES 3119 3120 3121 //---------------------------------------------------------------------------- 3122 3123 void ScViewFunc::SetConditionalFormat( const ScConditionalFormat& rNew ) 3124 { 3125 ScDocument* pDoc = GetViewData()->GetDocument(); 3126 sal_uLong nIndex = pDoc->AddCondFormat(rNew); // dafuer gibt's kein Undo 3127 SfxUInt32Item aItem( ATTR_CONDITIONAL, nIndex ); 3128 3129 ApplyAttr( aItem ); // mit Paint und Undo... 3130 } 3131 3132 3133 //---------------------------------------------------------------------------- 3134 3135 void ScViewFunc::SetValidation( const ScValidationData& rNew ) 3136 { 3137 ScDocument* pDoc = GetViewData()->GetDocument(); 3138 sal_uLong nIndex = pDoc->AddValidationEntry(rNew); // dafuer gibt's kein Undo 3139 SfxUInt32Item aItem( ATTR_VALIDDATA, nIndex ); 3140 3141 ApplyAttr( aItem ); // mit Paint und Undo... 3142 } 3143 3144 3145