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