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 ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem, 1621 sal_Bool bAddUndo, sal_Bool bIsApi ) 1622 { 1623 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 1624 ScDocument* pDoc = pDocSh->GetDocument(); 1625 ScMarkData& rMark = GetViewData()->GetMarkData(); 1626 if (bAddUndo && !pDoc->IsUndoEnabled()) 1627 bAddUndo = sal_False; 1628 1629 SCCOL nCol = GetViewData()->GetCurX(); 1630 SCROW nRow = GetViewData()->GetCurY(); 1631 SCTAB nTab = GetViewData()->GetTabNo(); 1632 // sal_Bool bAttrib = pSearchItem->GetPattern(); 1633 sal_uInt16 nCommand = pSearchItem->GetCommand(); 1634 sal_Bool bAllTables = pSearchItem->IsAllTables(); 1635 sal_Bool* pOldSelectedTables = NULL; 1636 sal_uInt16 nOldSelectedCount = 0; 1637 SCTAB nOldTab = nTab; 1638 SCTAB nLastTab = pDoc->GetTableCount() - 1; 1639 SCTAB nStartTab, nEndTab; 1640 if ( bAllTables ) 1641 { 1642 nStartTab = 0; 1643 nEndTab = nLastTab; 1644 pOldSelectedTables = new sal_Bool [ nEndTab + 1 ]; 1645 for ( SCTAB j = 0; j <= nEndTab; j++ ) 1646 { 1647 pOldSelectedTables[j] = rMark.GetTableSelect( j ); 1648 if ( pOldSelectedTables[j] ) 1649 ++nOldSelectedCount; 1650 } 1651 } 1652 else 1653 { //! mindestens eine ist immer selektiert 1654 nStartTab = nEndTab = rMark.GetFirstSelected(); 1655 for ( SCTAB j = nStartTab + 1; j <= nLastTab; j++ ) 1656 { 1657 if ( rMark.GetTableSelect( j ) ) 1658 nEndTab = j; 1659 } 1660 } 1661 1662 if ( nCommand == SVX_SEARCHCMD_REPLACE 1663 || nCommand == SVX_SEARCHCMD_REPLACE_ALL ) 1664 { 1665 for ( SCTAB j = nStartTab; j <= nEndTab; j++ ) 1666 { 1667 if ( (bAllTables || rMark.GetTableSelect( j )) && 1668 pDoc->IsTabProtected( j ) ) 1669 { 1670 if ( pOldSelectedTables ) 1671 delete [] pOldSelectedTables; 1672 ErrorMessage(STR_PROTECTIONERR); 1673 //return; 1674 return sal_False; 1675 } 1676 } 1677 } 1678 1679 if ( nCommand == SVX_SEARCHCMD_FIND 1680 || nCommand == SVX_SEARCHCMD_FIND_ALL) 1681 bAddUndo = sal_False; 1682 1683 //! bAttrib bei Undo beruecksichtigen !!! 1684 1685 ScDocument* pUndoDoc = NULL; 1686 ScMarkData* pUndoMark = NULL; 1687 String aUndoStr; 1688 if (bAddUndo) 1689 { 1690 pUndoMark = new ScMarkData( rMark ); // Markierung wird veraendert 1691 if ( nCommand == SVX_SEARCHCMD_REPLACE_ALL ) 1692 { 1693 pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); 1694 pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab ); 1695 } 1696 } 1697 1698 if ( bAllTables ) 1699 { //! alles selektieren, erst nachdem pUndoMark erzeugt wurde 1700 for ( SCTAB j = nStartTab; j <= nEndTab; j++ ) 1701 { 1702 rMark.SelectTable( j, sal_True ); 1703 } 1704 } 1705 1706 DoneBlockMode(sal_True); // Markierung nicht loeschen! 1707 InitOwnBlockMode(); 1708 1709 // wenn vom Anfang an gesucht wird, nicht nochmal fragen ob vom Anfang gesucht werden soll 1710 sal_Bool bFirst = sal_True; 1711 if ( nCol == 0 && nRow == 0 && nTab == nStartTab && !pSearchItem->GetBackward() ) 1712 bFirst = sal_False; 1713 1714 sal_Bool bFound = sal_False; 1715 while (sal_True) 1716 { 1717 GetFrameWin()->EnterWait(); 1718 if (pDoc->SearchAndReplace( *pSearchItem, nCol, nRow, nTab, rMark, aUndoStr, pUndoDoc ) ) 1719 { 1720 bFound = sal_True; 1721 bFirst = sal_True; 1722 if (bAddUndo) 1723 { 1724 GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction( 1725 new ScUndoReplace( GetViewData()->GetDocShell(), *pUndoMark, 1726 nCol, nRow, nTab, 1727 aUndoStr, pUndoDoc, pSearchItem ) ); 1728 pUndoDoc = NULL; 1729 } 1730 1731 break; // Abbruch while True 1732 } 1733 else if ( bFirst && (nCommand == SVX_SEARCHCMD_FIND || 1734 nCommand == SVX_SEARCHCMD_REPLACE) ) 1735 { 1736 bFirst = sal_False; 1737 sal_uInt16 nRetVal; 1738 GetFrameWin()->LeaveWait(); 1739 if ( bIsApi ) 1740 nRetVal = RET_NO; 1741 else 1742 { 1743 // Suchen-Dialog als Parent, wenn vorhanden 1744 Window* pParent = GetParentOrChild(SID_SEARCH_DLG); 1745 sal_uInt16 nStrId; 1746 if ( pSearchItem->GetBackward() ) 1747 { 1748 if ( nStartTab == nEndTab ) 1749 nStrId = STR_MSSG_SEARCHANDREPLACE_1; 1750 else 1751 nStrId = STR_MSSG_SEARCHANDREPLACE_4; 1752 } 1753 else 1754 { 1755 if ( nStartTab == nEndTab ) 1756 nStrId = STR_MSSG_SEARCHANDREPLACE_2; 1757 else 1758 nStrId = STR_MSSG_SEARCHANDREPLACE_5; 1759 } 1760 MessBox aBox( pParent, WinBits(WB_YES_NO | WB_DEF_YES), 1761 ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_3 ), 1762 ScGlobal::GetRscString( nStrId ) ); 1763 nRetVal = aBox.Execute(); 1764 } 1765 1766 if ( nRetVal == RET_YES ) 1767 { 1768 ScDocument::GetSearchAndReplaceStart( *pSearchItem, nCol, nRow ); 1769 if (pSearchItem->GetBackward()) 1770 nTab = nEndTab; 1771 else 1772 nTab = nStartTab; 1773 } 1774 else 1775 { 1776 break; // Abbruch while True 1777 } 1778 } 1779 else // nichts gefunden 1780 { 1781 if ( nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL ) 1782 { 1783 pDocSh->PostPaintGridAll(); // Markierung 1784 } 1785 1786 GetFrameWin()->LeaveWait(); 1787 if (!bIsApi) 1788 { 1789 // Suchen-Dialog als Parent, wenn vorhanden 1790 Window* pParent = GetParentOrChild(SID_SEARCH_DLG); 1791 // "nichts gefunden" 1792 InfoBox aBox( pParent, ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_0 ) ); 1793 aBox.Execute(); 1794 } 1795 1796 break; // Abbruch while True 1797 } 1798 } // of while sal_True 1799 1800 if ( pOldSelectedTables ) 1801 { // urspruenglich selektierte Tabellen wiederherstellen 1802 for ( SCTAB j = nStartTab; j <= nEndTab; j++ ) 1803 { 1804 rMark.SelectTable( j, pOldSelectedTables[j] ); 1805 } 1806 if ( bFound ) 1807 { // durch Fundstelle neu selektierte Tabelle bleibt 1808 rMark.SelectTable( nTab, sal_True ); 1809 // wenn vorher nur eine selektiert war, ist es ein Tausch 1810 //! wenn nicht, ist jetzt evtl. eine mehr selektiert 1811 if ( nOldSelectedCount == 1 && nTab != nOldTab ) 1812 rMark.SelectTable( nOldTab, sal_False ); 1813 } 1814 delete [] pOldSelectedTables; 1815 } 1816 1817 MarkDataChanged(); 1818 1819 if ( bFound ) 1820 { 1821 if ( nTab != GetViewData()->GetTabNo() ) 1822 SetTabNo( nTab ); 1823 1824 // wenn nichts markiert ist, DoneBlockMode, damit von hier aus 1825 // direkt per Shift-Cursor markiert werden kann: 1826 if (!rMark.IsMarked() && !rMark.IsMultiMarked()) 1827 DoneBlockMode(sal_True); 1828 1829 AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP ); 1830 SetCursor( nCol, nRow, sal_True ); 1831 1832 if ( nCommand == SVX_SEARCHCMD_REPLACE 1833 || nCommand == SVX_SEARCHCMD_REPLACE_ALL ) 1834 { 1835 if ( nCommand == SVX_SEARCHCMD_REPLACE ) 1836 pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID ); 1837 else 1838 pDocSh->PostPaintGridAll(); 1839 pDocSh->SetDocumentModified(); 1840 } 1841 else if ( nCommand == SVX_SEARCHCMD_FIND_ALL ) 1842 pDocSh->PostPaintGridAll(); // Markierung 1843 GetFrameWin()->LeaveWait(); 1844 } 1845 1846 delete pUndoDoc; // loeschen wenn nicht benutzt 1847 delete pUndoMark; // kann immer geloescht werden 1848 return bFound; 1849 } 1850 1851 1852 //---------------------------------------------------------------------------- 1853 // Zielwertsuche 1854 1855 void ScViewFunc::Solve( const ScSolveParam& rParam ) 1856 { 1857 ScDocument* pDoc = GetViewData()->GetDocument(); 1858 1859 SCCOL nDestCol = rParam.aRefVariableCell.Col(); 1860 SCROW nDestRow = rParam.aRefVariableCell.Row(); 1861 SCTAB nDestTab = rParam.aRefVariableCell.Tab(); 1862 1863 ScEditableTester aTester( pDoc, nDestTab, nDestCol,nDestRow, nDestCol,nDestRow ); 1864 if (!aTester.IsEditable()) 1865 { 1866 ErrorMessage(aTester.GetMessageId()); 1867 return; 1868 } 1869 1870 if ( pDoc ) 1871 { 1872 String aTargetValStr; 1873 if ( rParam.pStrTargetVal != NULL ) 1874 aTargetValStr = *(rParam.pStrTargetVal); 1875 1876 String aMsgStr; 1877 String aResStr; 1878 double nSolveResult; 1879 1880 GetFrameWin()->EnterWait(); 1881 1882 sal_Bool bExact = 1883 pDoc->Solver( 1884 rParam.aRefFormulaCell.Col(), 1885 rParam.aRefFormulaCell.Row(), 1886 rParam.aRefFormulaCell.Tab(), 1887 nDestCol, nDestRow, nDestTab, 1888 aTargetValStr, 1889 nSolveResult ); 1890 1891 GetFrameWin()->LeaveWait(); 1892 1893 SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); 1894 sal_uLong nFormat = 0; 1895 const ScPatternAttr* pPattern = pDoc->GetPattern( nDestCol, nDestRow, nDestTab ); 1896 if ( pPattern ) 1897 nFormat = pPattern->GetNumberFormat( pFormatter ); 1898 Color* p; 1899 pFormatter->GetOutputString( nSolveResult, nFormat, aResStr, &p ); 1900 1901 if ( bExact ) 1902 { 1903 aMsgStr = ScGlobal::GetRscString( STR_MSSG_SOLVE_0 ); 1904 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_1 ); 1905 aMsgStr += String( aResStr ); 1906 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_2 ); 1907 } 1908 else 1909 { 1910 aMsgStr = ScGlobal::GetRscString( STR_MSSG_SOLVE_3 ); 1911 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_4 ); 1912 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_5 ); 1913 aMsgStr += String( aResStr ); 1914 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_6 ); 1915 } 1916 1917 MessBox aBox( GetViewData()->GetDialogParent(), 1918 WinBits(WB_YES_NO | WB_DEF_NO), 1919 ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), aMsgStr ); 1920 sal_uInt16 nRetVal = aBox.Execute(); 1921 1922 if ( RET_YES == nRetVal ) 1923 EnterValue( nDestCol, nDestRow, nDestTab, nSolveResult ); 1924 1925 GetViewData()->GetViewShell()->UpdateInputHandler( sal_True ); 1926 } 1927 } 1928 1929 1930 //---------------------------------------------------------------------------- 1931 // Mehrfachoperation 1932 1933 void ScViewFunc::TabOp( const ScTabOpParam& rParam, sal_Bool bRecord ) 1934 { 1935 ScRange aRange; 1936 if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE) 1937 { 1938 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 1939 ScMarkData& rMark = GetViewData()->GetMarkData(); 1940 pDocSh->GetDocFunc().TabOp( aRange, &rMark, rParam, bRecord, sal_False ); 1941 } 1942 else 1943 ErrorMessage(STR_NOMULTISELECT); 1944 } 1945 1946 1947 //---------------------------------------------------------------------------- 1948 1949 void ScViewFunc::MakeScenario( const String& rName, const String& rComment, 1950 const Color& rColor, sal_uInt16 nFlags ) 1951 { 1952 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 1953 ScMarkData& rMark = GetViewData()->GetMarkData(); 1954 SCTAB nTab = GetViewData()->GetTabNo(); 1955 1956 SCTAB nNewTab = pDocSh->MakeScenario( nTab, rName, rComment, rColor, nFlags, rMark ); 1957 if (nFlags & SC_SCENARIO_COPYALL) 1958 SetTabNo( nNewTab, sal_True ); // SC_SCENARIO_COPYALL -> sichtbar 1959 else 1960 { 1961 SfxBindings& rBindings = GetViewData()->GetBindings(); 1962 rBindings.Invalidate( SID_STATUS_DOCPOS ); // Statusbar 1963 rBindings.Invalidate( SID_TABLES_COUNT ); 1964 rBindings.Invalidate( SID_SELECT_SCENARIO ); 1965 rBindings.Invalidate( FID_TABLE_SHOW ); 1966 } 1967 } 1968 1969 1970 //---------------------------------------------------------------------------- 1971 1972 void ScViewFunc::ExtendScenario() 1973 { 1974 ScEditableTester aTester( this ); 1975 if (!aTester.IsEditable()) 1976 { 1977 ErrorMessage(aTester.GetMessageId()); 1978 return; 1979 } 1980 1981 // Undo: Attribute anwenden 1982 1983 ScDocument* pDoc = GetViewData()->GetDocument(); 1984 ScPatternAttr aPattern( pDoc->GetPool() ); 1985 aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) ); 1986 aPattern.GetItemSet().Put( ScProtectionAttr( sal_True ) ); 1987 ApplySelectionPattern(aPattern); 1988 } 1989 1990 1991 //---------------------------------------------------------------------------- 1992 1993 void ScViewFunc::UseScenario( const String& rName ) 1994 { 1995 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 1996 SCTAB nTab = GetViewData()->GetTabNo(); 1997 1998 DoneBlockMode(); 1999 InitOwnBlockMode(); 2000 pDocSh->UseScenario( nTab, rName ); 2001 } 2002 2003 2004 //---------------------------------------------------------------------------- 2005 // Tabelle einfuegen 2006 2007 sal_Bool ScViewFunc::InsertTable( const String& rName, SCTAB nTab, sal_Bool bRecord ) 2008 { 2009 // Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt 2010 sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc(). 2011 InsertTable( nTab, rName, bRecord, sal_False ); 2012 if (bSuccess) 2013 SetTabNo( nTab, sal_True ); 2014 2015 return bSuccess; 2016 } 2017 2018 //---------------------------------------------------------------------------- 2019 // Tabellen einfuegen 2020 2021 sal_Bool ScViewFunc::InsertTables(SvStrings *pNames, SCTAB nTab, 2022 SCTAB nCount, sal_Bool bRecord ) 2023 { 2024 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 2025 ScDocument* pDoc = pDocSh->GetDocument(); 2026 if (bRecord && !pDoc->IsUndoEnabled()) 2027 bRecord = sal_False; 2028 2029 SvStrings *pNameList= NULL; 2030 2031 WaitObject aWait( GetFrameWin() ); 2032 2033 if (bRecord) 2034 { 2035 pNameList= new SvStrings; 2036 pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage 2037 } 2038 2039 sal_Bool bFlag=sal_False; 2040 2041 String aValTabName; 2042 String *pStr; 2043 2044 for(SCTAB i=0;i<nCount;i++) 2045 { 2046 if(pNames!=NULL) 2047 { 2048 pStr=pNames->GetObject(static_cast<sal_uInt16>(i)); 2049 } 2050 else 2051 { 2052 aValTabName.Erase(); 2053 pDoc->CreateValidTabName( aValTabName); 2054 pStr=&aValTabName; 2055 } 2056 2057 if(pDoc->InsertTab( nTab+i,*pStr)) 2058 { 2059 bFlag=sal_True; 2060 pDocSh->Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab+i ) ); 2061 } 2062 else 2063 { 2064 break; 2065 } 2066 2067 if(pNameList!=NULL) 2068 pNameList->Insert(new String(*pStr),pNameList->Count()); 2069 2070 } 2071 2072 if (bFlag) 2073 { 2074 if (bRecord) 2075 pDocSh->GetUndoManager()->AddUndoAction( 2076 new ScUndoInsertTables( pDocSh, nTab, sal_False, pNameList)); 2077 2078 // Views updaten: 2079 2080 SetTabNo( nTab, sal_True ); 2081 pDocSh->PostPaintExtras(); 2082 pDocSh->SetDocumentModified(); 2083 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); 2084 return sal_True; 2085 } 2086 else 2087 { 2088 return sal_False; 2089 } 2090 } 2091 2092 2093 //---------------------------------------------------------------------------- 2094 2095 sal_Bool ScViewFunc::AppendTable( const String& rName, sal_Bool bRecord ) 2096 { 2097 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 2098 ScDocument* pDoc = pDocSh->GetDocument(); 2099 if (bRecord && !pDoc->IsUndoEnabled()) 2100 bRecord = sal_False; 2101 2102 WaitObject aWait( GetFrameWin() ); 2103 2104 if (bRecord) 2105 pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage 2106 2107 if (pDoc->InsertTab( SC_TAB_APPEND, rName )) 2108 { 2109 SCTAB nTab = pDoc->GetTableCount()-1; 2110 if (bRecord) 2111 pDocSh->GetUndoManager()->AddUndoAction( 2112 new ScUndoInsertTab( pDocSh, nTab, sal_True, rName)); 2113 GetViewData()->InsertTab( nTab ); 2114 SetTabNo( nTab, sal_True ); 2115 pDocSh->PostPaintExtras(); 2116 pDocSh->SetDocumentModified(); 2117 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); 2118 return sal_True; 2119 } 2120 else 2121 { 2122 return sal_False; 2123 } 2124 } 2125 2126 2127 //---------------------------------------------------------------------------- 2128 2129 sal_Bool ScViewFunc::DeleteTable( SCTAB nTab, sal_Bool bRecord ) 2130 { 2131 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 2132 ScDocument* pDoc = pDocSh->GetDocument(); 2133 2134 sal_Bool bSuccess = pDocSh->GetDocFunc().DeleteTable( nTab, bRecord, sal_False ); 2135 if (bSuccess) 2136 { 2137 SCTAB nNewTab = nTab; 2138 if ( nNewTab >= pDoc->GetTableCount() ) 2139 --nNewTab; 2140 SetTabNo( nNewTab, sal_True ); 2141 } 2142 return bSuccess; 2143 } 2144 2145 sal_Bool ScViewFunc::DeleteTables(const SvShorts &TheTabs, sal_Bool bRecord ) 2146 { 2147 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 2148 ScDocument* pDoc = pDocSh->GetDocument(); 2149 sal_Bool bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : sal_False; 2150 SCTAB nNewTab = TheTabs.front(); 2151 WaitObject aWait( GetFrameWin() ); 2152 if (bRecord && !pDoc->IsUndoEnabled()) 2153 bRecord = sal_False; 2154 2155 while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) ) 2156 --nNewTab; 2157 2158 sal_Bool bWasLinked = sal_False; 2159 ScDocument* pUndoDoc = NULL; 2160 ScRefUndoData* pUndoData = NULL; 2161 if (bRecord) 2162 { 2163 pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); 2164 // pUndoDoc->InitDrawLayer( pDocSh ); 2165 SCTAB nCount = pDoc->GetTableCount(); 2166 2167 // pUndoDoc->InitUndo( pDoc, 0, nCount-1 ); // incl. Ref. 2168 2169 String aOldName; 2170 for (size_t i = 0; i < TheTabs.size(); i++) 2171 { 2172 SCTAB nTab = TheTabs[i]; 2173 if (i==0) 2174 pUndoDoc->InitUndo( pDoc, nTab,nTab, sal_True,sal_True ); // incl. Spalten/Zeilenflags 2175 else 2176 pUndoDoc->AddUndoTab( nTab,nTab, sal_True,sal_True ); // incl. Spalten/Zeilenflags 2177 2178 pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,sal_False, pUndoDoc ); 2179 pDoc->GetName( nTab, aOldName ); 2180 pUndoDoc->RenameTab( nTab, aOldName, sal_False ); 2181 if (pDoc->IsLinked(nTab)) 2182 { 2183 bWasLinked = sal_True; 2184 pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab), 2185 pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab), 2186 pDoc->GetLinkTab(nTab), 2187 pDoc->GetLinkRefreshDelay(nTab) ); 2188 } 2189 if ( pDoc->IsScenario(nTab) ) 2190 { 2191 pUndoDoc->SetScenario( nTab, sal_True ); 2192 String aComment; 2193 Color aColor; 2194 sal_uInt16 nScenFlags; 2195 pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags ); 2196 pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags ); 2197 sal_Bool bActive = pDoc->IsActiveScenario( nTab ); 2198 pUndoDoc->SetActiveScenario( nTab, bActive ); 2199 } 2200 pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) ); 2201 pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) ); 2202 pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) ); 2203 2204 if ( pDoc->IsTabProtected( nTab ) ) 2205 pUndoDoc->SetTabProtection(nTab, pDoc->GetTabProtection(nTab)); 2206 2207 // Drawing-Layer muss sein Undo selbst in der Hand behalten !!! 2208 // pUndoDoc->TransferDrawPage(pDoc, nTab,nTab); 2209 } 2210 2211 pUndoDoc->AddUndoTab( 0, nCount-1 ); // alle Tabs fuer Referenzen 2212 2213 pDoc->BeginDrawUndo(); // DeleteTab erzeugt ein SdrUndoDelPage 2214 2215 pUndoData = new ScRefUndoData( pDoc ); 2216 } 2217 2218 sal_Bool bDelDone = sal_False; 2219 2220 for (size_t i = TheTabs.size(); i > 0; i--) 2221 { 2222 String sCodeName; 2223 sal_Bool bHasCodeName = pDoc->GetCodeName( TheTabs[i-1], sCodeName ); 2224 if (pDoc->DeleteTab( TheTabs[i-1], pUndoDoc )) 2225 { 2226 bDelDone = sal_True; 2227 if( bVbaEnabled ) 2228 { 2229 if( bHasCodeName ) 2230 { 2231 VBA_DeleteModule( *pDocSh, sCodeName ); 2232 } 2233 } 2234 pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[i-1] ) ); 2235 } 2236 } 2237 if (bRecord) 2238 { 2239 pDocSh->GetUndoManager()->AddUndoAction( 2240 new ScUndoDeleteTab( GetViewData()->GetDocShell(), TheTabs, 2241 pUndoDoc, pUndoData )); 2242 } 2243 2244 2245 if (bDelDone) 2246 { 2247 if ( nNewTab >= pDoc->GetTableCount() ) 2248 nNewTab = pDoc->GetTableCount() - 1; 2249 2250 SetTabNo( nNewTab, sal_True ); 2251 2252 if (bWasLinked) 2253 { 2254 pDocSh->UpdateLinks(); // Link-Manager updaten 2255 GetViewData()->GetBindings().Invalidate(SID_LINKS); 2256 } 2257 2258 pDocSh->PostPaintExtras(); 2259 pDocSh->SetDocumentModified(); 2260 2261 SfxApplication* pSfxApp = SFX_APP(); // Navigator 2262 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); 2263 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) ); 2264 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) ); 2265 } 2266 else 2267 { 2268 delete pUndoDoc; 2269 delete pUndoData; 2270 } 2271 return bDelDone; 2272 } 2273 2274 2275 //---------------------------------------------------------------------------- 2276 2277 sal_Bool ScViewFunc::RenameTable( const String& rName, SCTAB nTab ) 2278 { 2279 // Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt 2280 sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc(). 2281 RenameTable( nTab, rName, sal_True, sal_False ); 2282 if (bSuccess) 2283 { 2284 // Der Tabellenname koennte in einer Formel vorkommen... 2285 GetViewData()->GetViewShell()->UpdateInputHandler(); 2286 } 2287 return bSuccess; 2288 } 2289 2290 2291 //---------------------------------------------------------------------------- 2292 2293 bool ScViewFunc::SetTabBgColor( const Color& rColor, SCTAB nTab ) 2294 { 2295 bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( nTab, rColor, sal_True, sal_False ); 2296 if (bSuccess) 2297 { 2298 GetViewData()->GetViewShell()->UpdateInputHandler(); 2299 } 2300 return bSuccess; 2301 } 2302 2303 bool ScViewFunc::SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList ) 2304 { 2305 bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList, sal_True, sal_False ); 2306 if (bSuccess) 2307 { 2308 GetViewData()->GetViewShell()->UpdateInputHandler(); 2309 } 2310 return bSuccess; 2311 } 2312 2313 //---------------------------------------------------------------------------- 2314 2315 void ScViewFunc::InsertAreaLink( const String& rFile, 2316 const String& rFilter, const String& rOptions, 2317 const String& rSource, sal_uLong nRefresh ) 2318 { 2319 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 2320 SCCOL nPosX = GetViewData()->GetCurX(); 2321 SCROW nPosY = GetViewData()->GetCurY(); 2322 SCTAB nTab = GetViewData()->GetTabNo(); 2323 ScAddress aPos( nPosX, nPosY, nTab ); 2324 2325 pDocSh->GetDocFunc().InsertAreaLink( rFile, rFilter, rOptions, rSource, aPos, nRefresh, sal_False, sal_False ); 2326 } 2327 2328 2329 //---------------------------------------------------------------------------- 2330 2331 void ScViewFunc::InsertTableLink( const String& rFile, 2332 const String& rFilter, const String& rOptions, 2333 const String& rTabName ) 2334 { 2335 String aFilterName = rFilter; 2336 String aOpt = rOptions; 2337 ScDocumentLoader aLoader( rFile, aFilterName, aOpt ); 2338 if (!aLoader.IsError()) 2339 { 2340 ScDocShell* pSrcSh = aLoader.GetDocShell(); 2341 ScDocument* pSrcDoc = pSrcSh->GetDocument(); 2342 SCTAB nTab = MAXTAB+1; 2343 if (!rTabName.Len()) // kein Name angegeben -> erste Tabelle 2344 nTab = 0; 2345 else 2346 { 2347 String aTemp; 2348 SCTAB nCount = pSrcDoc->GetTableCount(); 2349 for (SCTAB i=0; i<nCount; i++) 2350 { 2351 pSrcDoc->GetName( i, aTemp ); 2352 if ( aTemp == rTabName ) 2353 nTab = i; 2354 } 2355 } 2356 2357 if ( nTab <= MAXTAB ) 2358 ImportTables( pSrcSh, 1, &nTab, sal_True, 2359 GetViewData()->GetTabNo() ); 2360 } 2361 } 2362 2363 2364 //---------------------------------------------------------------------------- 2365 // Tabellen aus anderem Dokument kopieren / linken 2366 2367 void ScViewFunc::ImportTables( ScDocShell* pSrcShell, 2368 SCTAB nCount, const SCTAB* pSrcTabs, sal_Bool bLink,SCTAB nTab ) 2369 { 2370 ScDocument* pSrcDoc = pSrcShell->GetDocument(); 2371 2372 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 2373 ScDocument* pDoc = pDocSh->GetDocument(); 2374 sal_Bool bUndo(pDoc->IsUndoEnabled()); 2375 //SCTAB nTab = GetViewData()->GetTabNo(); 2376 2377 sal_Bool bError = sal_False; 2378 sal_Bool bRefs = sal_False; 2379 sal_Bool bName = sal_False; 2380 2381 if (pSrcDoc->GetDrawLayer()) 2382 pDocSh->MakeDrawLayer(); 2383 2384 if (bUndo) 2385 pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions 2386 2387 SCTAB nInsCount = 0; 2388 SCTAB i; 2389 for( i=0; i<nCount; i++ ) 2390 { // #63304# insert sheets first and update all references 2391 String aName; 2392 pSrcDoc->GetName( pSrcTabs[i], aName ); 2393 pDoc->CreateValidTabName( aName ); 2394 if ( !pDoc->InsertTab( nTab+i, aName ) ) 2395 { 2396 bError = sal_True; // total error 2397 break; // for 2398 } 2399 ++nInsCount; 2400 } 2401 for (i=0; i<nCount && !bError; i++) 2402 { 2403 SCTAB nSrcTab = pSrcTabs[i]; 2404 SCTAB nDestTab1=nTab+i; 2405 sal_uLong nErrVal = pDoc->TransferTab( pSrcDoc, nSrcTab, nDestTab1, 2406 sal_False ); // no insert 2407 2408 switch (nErrVal) 2409 { 2410 case 0: // interner Fehler oder voll Fehler 2411 bError = sal_True; 2412 break; 2413 case 2: 2414 bRefs = sal_True; 2415 break; 2416 case 3: 2417 bName = sal_True; 2418 break; 2419 case 4: 2420 bRefs = bName = sal_True; 2421 break; 2422 } 2423 2424 // TransferTab doesn't copy drawing objects with bInsertNew=FALSE 2425 if ( !bError ) 2426 pDoc->TransferDrawPage( pSrcDoc, nSrcTab, nDestTab1 ); 2427 2428 if(!bError &&pSrcDoc->IsScenario(nSrcTab)) 2429 { 2430 String aComment; 2431 Color aColor; 2432 sal_uInt16 nFlags; 2433 2434 pSrcDoc->GetScenarioData(nSrcTab, aComment,aColor, nFlags); 2435 pDoc->SetScenario( nDestTab1,sal_True); 2436 pDoc->SetScenarioData( nTab+i,aComment,aColor,nFlags); 2437 sal_Bool bActive = pSrcDoc->IsActiveScenario(nSrcTab ); 2438 pDoc->SetActiveScenario( nDestTab1, bActive ); 2439 sal_Bool bVisible=pSrcDoc->IsVisible(nSrcTab); 2440 pDoc->SetVisible(nDestTab1,bVisible ); 2441 2442 } 2443 } 2444 2445 if (bLink) 2446 { 2447 sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager(); 2448 2449 SfxMedium* pMed = pSrcShell->GetMedium(); 2450 String aFileName = pMed->GetName(); 2451 String aFilterName; 2452 if (pMed->GetFilter()) 2453 aFilterName = pMed->GetFilter()->GetFilterName(); 2454 String aOptions = ScDocumentLoader::GetOptions(*pMed); 2455 2456 sal_Bool bWasThere = pDoc->HasLink( aFileName, aFilterName, aOptions ); 2457 2458 sal_uLong nRefresh = 0; 2459 String aTabStr; 2460 for (i=0; i<nInsCount; i++) 2461 { 2462 pSrcDoc->GetName( pSrcTabs[i], aTabStr ); 2463 pDoc->SetLink( nTab+i, SC_LINK_NORMAL, 2464 aFileName, aFilterName, aOptions, aTabStr, nRefresh ); 2465 } 2466 2467 if (!bWasThere) // Link pro Quelldokument nur einmal eintragen 2468 { 2469 ScTableLink* pLink = new ScTableLink( pDocSh, aFileName, aFilterName, aOptions, nRefresh ); 2470 pLink->SetInCreate( sal_True ); 2471 pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName, &aFilterName ); 2472 pLink->Update(); 2473 pLink->SetInCreate( sal_False ); 2474 2475 SfxBindings& rBindings = GetViewData()->GetBindings(); 2476 rBindings.Invalidate( SID_LINKS ); 2477 } 2478 } 2479 2480 2481 if (bUndo) 2482 { 2483 pDocSh->GetUndoManager()->AddUndoAction( 2484 new ScUndoImportTab( pDocSh, nTab, nCount, bLink ) ); 2485 } 2486 2487 for (i=0; i<nInsCount; i++) 2488 GetViewData()->InsertTab(nTab); 2489 SetTabNo(nTab,sal_True); 2490 pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, 2491 PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS ); 2492 2493 SfxApplication* pSfxApp = SFX_APP(); 2494 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); 2495 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) ); 2496 2497 pDocSh->PostPaintExtras(); 2498 pDocSh->PostPaintGridAll(); 2499 pDocSh->SetDocumentModified(); 2500 2501 if (bRefs) 2502 ErrorMessage(STR_ABSREFLOST); 2503 if (bName) 2504 ErrorMessage(STR_NAMECONFLICT); 2505 } 2506 2507 2508 //---------------------------------------------------------------------------- 2509 // Tabelle in anderes Dokument verschieben / kopieren 2510 2511 void ScViewFunc::MoveTable( sal_uInt16 nDestDocNo, SCTAB nDestTab, sal_Bool bCopy ) 2512 { 2513 ScDocument* pDoc = GetViewData()->GetDocument(); 2514 ScDocShell* pDocShell = GetViewData()->GetDocShell(); 2515 ScDocument* pDestDoc = NULL; 2516 ScDocShell* pDestShell = NULL; 2517 ScTabViewShell* pDestViewSh = NULL; 2518 sal_Bool bUndo (pDoc->IsUndoEnabled()); 2519 2520 sal_Bool bNewDoc = ( nDestDocNo == SC_DOC_NEW ); 2521 if ( bNewDoc ) 2522 { 2523 nDestTab = 0; // als erstes einfuegen 2524 2525 // ohne SFX_CALLMODE_RECORD ausfuehren, weil schon im Move-Befehl enthalten: 2526 2527 String aUrl = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("private:factory/")); 2528 aUrl.AppendAscii(RTL_CONSTASCII_STRINGPARAM( STRING_SCAPP )); // "scalc" 2529 SfxStringItem aItem( SID_FILE_NAME, aUrl ); 2530 SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") ); 2531 2532 const SfxPoolItem* pRetItem = GetViewData()->GetDispatcher().Execute( 2533 SID_OPENDOC, SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON, &aItem, &aTarget, 0L ); 2534 if ( pRetItem ) 2535 { 2536 if ( pRetItem->ISA( SfxObjectItem ) ) 2537 pDestShell = PTR_CAST( ScDocShell, ((const SfxObjectItem*)pRetItem)->GetShell() ); 2538 else if ( pRetItem->ISA( SfxViewFrameItem ) ) 2539 { 2540 SfxViewFrame* pFrm = ((const SfxViewFrameItem*)pRetItem)->GetFrame(); 2541 if (pFrm) 2542 pDestShell = PTR_CAST( ScDocShell, pFrm->GetObjectShell() ); 2543 } 2544 if (pDestShell) 2545 pDestViewSh = pDestShell->GetBestViewShell(); 2546 } 2547 } 2548 else 2549 pDestShell = ScDocShell::GetShellByNum( nDestDocNo ); 2550 2551 if (!pDestShell) 2552 { 2553 DBG_ERROR("Dest-Doc nicht gefunden !!!"); 2554 return; 2555 } 2556 2557 pDestDoc = pDestShell->GetDocument(); 2558 2559 SCTAB nTab = GetViewData()->GetTabNo(); 2560 2561 if (pDestDoc != pDoc) 2562 { 2563 if (bNewDoc) 2564 { 2565 while (pDestDoc->GetTableCount() > 1) 2566 pDestDoc->DeleteTab(0); 2567 pDestDoc->RenameTab( 0, 2568 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("______42_____")), 2569 sal_False ); 2570 } 2571 2572 ScMarkData& rMark = GetViewData()->GetMarkData(); 2573 SCTAB nTabCount = pDoc->GetTableCount(); 2574 SCTAB nTabSelCount = rMark.GetSelectCount(); 2575 2576 SvShorts TheTabs; 2577 2578 for(SCTAB i=0;i<nTabCount;i++) 2579 { 2580 if(rMark.GetTableSelect(i)) 2581 { 2582 String aTabName; 2583 pDoc->GetName( i, aTabName); 2584 TheTabs.push_back(i); 2585 for(SCTAB j=i+1;j<nTabCount;j++) 2586 { 2587 if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j))) 2588 { 2589 pDoc->GetName( j, aTabName); 2590 TheTabs.push_back(j); 2591 i=j; 2592 } 2593 else break; 2594 } 2595 } 2596 } 2597 2598 GetFrameWin()->EnterWait(); 2599 2600 if (pDoc->GetDrawLayer()) 2601 pDestShell->MakeDrawLayer(); 2602 2603 if (!bNewDoc && bUndo) 2604 pDestDoc->BeginDrawUndo(); // drawing layer must do its own undo actions 2605 2606 sal_uLong nErrVal =1; 2607 if(nDestTab==SC_TAB_APPEND) 2608 nDestTab=pDestDoc->GetTableCount(); 2609 SCTAB nDestTab1=nDestTab; 2610 for( size_t j=0; j<TheTabs.size(); j++, nDestTab1++ ) 2611 { // #63304# insert sheets first and update all references 2612 String aName; 2613 pDoc->GetName( TheTabs[j], aName ); 2614 pDestDoc->CreateValidTabName( aName ); 2615 if ( !pDestDoc->InsertTab( nDestTab1, aName ) ) 2616 { 2617 nErrVal = 0; // total error 2618 break; // for 2619 } 2620 } 2621 if ( nErrVal > 0 ) 2622 { 2623 nDestTab1 = nDestTab; 2624 for(size_t i=0;i<TheTabs.size();i++) 2625 { 2626 nErrVal = pDestDoc->TransferTab( pDoc, TheTabs[i], nDestTab1, 2627 sal_False ); // no insert 2628 2629 // TransferTab doesn't copy drawing objects with bInsertNew=FALSE 2630 if ( nErrVal > 0 ) 2631 pDestDoc->TransferDrawPage( pDoc, TheTabs[i], nDestTab1 ); 2632 2633 if(nErrVal>0 && pDoc->IsScenario(TheTabs[i])) 2634 { 2635 String aComment; 2636 Color aColor; 2637 sal_uInt16 nFlags; 2638 2639 pDoc->GetScenarioData(TheTabs[i], aComment,aColor, nFlags); 2640 pDestDoc->SetScenario(nDestTab1,sal_True); 2641 pDestDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags); 2642 sal_Bool bActive = pDoc->IsActiveScenario(TheTabs[i]); 2643 pDestDoc->SetActiveScenario(nDestTab1, bActive ); 2644 2645 sal_Bool bVisible=pDoc->IsVisible(TheTabs[i]); 2646 pDestDoc->SetVisible(nDestTab1,bVisible ); 2647 2648 } 2649 2650 if ( nErrVal > 0 && pDoc->IsTabProtected( TheTabs[i] ) ) 2651 pDestDoc->SetTabProtection(nDestTab1, pDoc->GetTabProtection(TheTabs[i])); 2652 2653 nDestTab1++; 2654 } 2655 } 2656 String sName; 2657 if (!bNewDoc && bUndo) 2658 { 2659 pDestDoc->GetName(nDestTab, sName); 2660 pDestShell->GetUndoManager()->AddUndoAction( 2661 new ScUndoImportTab( pDestShell, nDestTab, 2662 static_cast<SCTAB>(TheTabs.size()), sal_False)); 2663 2664 } 2665 else 2666 { 2667 pDestShell->GetUndoManager()->Clear(); 2668 } 2669 2670 GetFrameWin()->LeaveWait(); 2671 switch (nErrVal) 2672 { 2673 case 0: // interner Fehler oder voll Fehler 2674 { 2675 ErrorMessage(STR_TABINSERT_ERROR); 2676 return; 2677 } 2678 //break; 2679 case 2: 2680 ErrorMessage(STR_ABSREFLOST); 2681 break; 2682 case 3: 2683 ErrorMessage(STR_NAMECONFLICT); 2684 break; 2685 case 4: 2686 { 2687 ErrorMessage(STR_ABSREFLOST); 2688 ErrorMessage(STR_NAMECONFLICT); 2689 } 2690 break; 2691 default: 2692 break; 2693 } 2694 //pDestShell->GetUndoManager()->Clear(); //! Undo implementieren !!! 2695 /* 2696 String sName; 2697 pDestDoc->GetName(nDestTab, sName); 2698 pDestShell->GetUndoManager()->AddUndoAction( 2699 new ScUndoInsertTab( pDestShell, nDestTab, sal_True, sName ) ); 2700 */ 2701 if (!bCopy) 2702 { 2703 if(nTabCount!=nTabSelCount) 2704 DeleteTables(TheTabs);// incl. Paint & Undo 2705 else 2706 ErrorMessage(STR_TABREMOVE_ERROR); 2707 } 2708 2709 if (bNewDoc) 2710 { 2711 // ChartListenerCollection must be updated before DeleteTab 2712 if ( pDestDoc->IsChartListenerCollectionNeedsUpdate() ) 2713 pDestDoc->UpdateChartListenerCollection(); 2714 2715 pDestDoc->DeleteTab(static_cast<SCTAB>(TheTabs.size())); // first old table 2716 //? pDestDoc->SelectTable(0, sal_True); // neue erste Tabelle selektieren 2717 if (pDestViewSh) 2718 pDestViewSh->TabChanged(); // Pages auf dem Drawing-Layer 2719 pDestShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB, 2720 PAINT_GRID | PAINT_TOP | PAINT_LEFT | 2721 PAINT_EXTRAS | PAINT_SIZE ); 2722 // PAINT_SIZE fuer Gliederung 2723 } 2724 else 2725 { 2726 pDestShell->Broadcast( ScTablesHint( SC_TAB_INSERTED, nDestTab ) ); 2727 pDestShell->PostPaintExtras(); 2728 pDestShell->PostPaintGridAll(); 2729 } 2730 2731 TheTabs.clear(); 2732 2733 pDestShell->SetDocumentModified(); 2734 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); 2735 } 2736 else // within the documents 2737 { 2738 2739 ScMarkData& rMark = GetViewData()->GetMarkData(); 2740 SCTAB nTabCount = pDoc->GetTableCount(); 2741 2742 SvShorts TheTabs; 2743 SvShorts TheDestTabs; 2744 SvStrings TheTabNames; 2745 String aDestName; 2746 String *pString; 2747 2748 for(SCTAB i=0;i<nTabCount;i++) 2749 { 2750 if(rMark.GetTableSelect(i)) 2751 { 2752 String aTabName; 2753 pDoc->GetName( i, aTabName); 2754 TheTabNames.Insert(new String(aTabName),TheTabNames.Count()); 2755 2756 for(SCTAB j=i+1;j<nTabCount;j++) 2757 { 2758 if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j))) 2759 { 2760 pDoc->GetName( j, aTabName); 2761 TheTabNames.Insert(new String(aTabName),TheTabNames.Count()); 2762 i=j; 2763 } 2764 else break; 2765 } 2766 2767 } 2768 } 2769 2770 if (bCopy && bUndo) 2771 pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions 2772 2773 pDoc->GetName( nDestTab, aDestName); 2774 SCTAB nDestTab1=nDestTab; 2775 SCTAB nMovTab=0; 2776 for(int j=0;j<TheTabNames.Count();j++) 2777 { 2778 nTabCount = pDoc->GetTableCount(); 2779 pString=TheTabNames[sal::static_int_cast<sal_uInt16>(j)]; 2780 if(!pDoc->GetTable(*pString,nMovTab)) 2781 { 2782 nMovTab=nTabCount; 2783 } 2784 if(!pDoc->GetTable(aDestName,nDestTab1)) 2785 { 2786 nDestTab1=nTabCount; 2787 } 2788 pDocShell->MoveTable( nMovTab, nDestTab1, bCopy, sal_False ); // Undo ist hier 2789 2790 if(bCopy && pDoc->IsScenario(nMovTab)) 2791 { 2792 String aComment; 2793 Color aColor; 2794 sal_uInt16 nFlags; 2795 2796 pDoc->GetScenarioData(nMovTab, aComment,aColor, nFlags); 2797 pDoc->SetScenario(nDestTab1,sal_True); 2798 pDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags); 2799 sal_Bool bActive = pDoc->IsActiveScenario(nMovTab ); 2800 pDoc->SetActiveScenario( nDestTab1, bActive ); 2801 sal_Bool bVisible=pDoc->IsVisible(nMovTab); 2802 pDoc->SetVisible(nDestTab1,bVisible ); 2803 } 2804 2805 TheTabs.push_back(nMovTab); 2806 2807 if(!bCopy) 2808 { 2809 if(!pDoc->GetTable(*pString,nDestTab1)) 2810 { 2811 nDestTab1=nTabCount; 2812 } 2813 } 2814 2815 TheDestTabs.push_back(nDestTab1); 2816 delete pString; 2817 } 2818 2819 nTab = GetViewData()->GetTabNo(); 2820 2821 if (bUndo) 2822 { 2823 if (bCopy) 2824 { 2825 pDocShell->GetUndoManager()->AddUndoAction( 2826 new ScUndoCopyTab( pDocShell, TheTabs, TheDestTabs)); 2827 } 2828 else 2829 { 2830 pDocShell->GetUndoManager()->AddUndoAction( 2831 new ScUndoMoveTab( pDocShell, TheTabs, TheDestTabs)); 2832 } 2833 } 2834 2835 SCTAB nNewTab = nDestTab; 2836 if (nNewTab == SC_TAB_APPEND) 2837 nNewTab = pDoc->GetTableCount()-1; 2838 else if (!bCopy && nTab<nDestTab) 2839 nNewTab--; 2840 2841 SetTabNo( nNewTab, sal_True ); 2842 2843 //#i29848# adjust references to data on the copied sheet 2844 if( bCopy ) 2845 ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pDoc, pDestDoc, nTab, nNewTab ); 2846 } 2847 } 2848 2849 2850 //---------------------------------------------------------------------------- 2851 2852 void ScViewFunc::ShowTable( const String& rName ) 2853 { 2854 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 2855 ScDocument* pDoc = pDocSh->GetDocument(); 2856 sal_Bool bUndo(pDoc->IsUndoEnabled()); 2857 sal_Bool bFound = sal_False; 2858 SCTAB nPos = 0; 2859 String aTabName; 2860 SCTAB nCount = pDoc->GetTableCount(); 2861 for (SCTAB i=0; i<nCount; i++) 2862 { 2863 pDoc->GetName( i, aTabName ); 2864 if ( aTabName == rName ) 2865 { 2866 nPos = i; 2867 bFound = sal_True; 2868 } 2869 } 2870 2871 if (bFound) 2872 { 2873 pDoc->SetVisible( nPos, sal_True ); 2874 if (bUndo) 2875 { 2876 pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nPos, sal_True ) ); 2877 } 2878 SetTabNo( nPos, sal_True ); 2879 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); 2880 pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS); 2881 pDocSh->SetDocumentModified(); 2882 } 2883 else 2884 Sound::Beep(); 2885 } 2886 2887 2888 //---------------------------------------------------------------------------- 2889 2890 void ScViewFunc::HideTable( SCTAB nTab ) 2891 { 2892 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 2893 ScDocument* pDoc = pDocSh->GetDocument(); 2894 sal_Bool bUndo(pDoc->IsUndoEnabled()); 2895 SCTAB nVisible = 0; 2896 SCTAB nCount = pDoc->GetTableCount(); 2897 for (SCTAB i=0; i<nCount; i++) 2898 { 2899 if (pDoc->IsVisible(i)) 2900 ++nVisible; 2901 } 2902 2903 if (nVisible > 1) 2904 { 2905 pDoc->SetVisible( nTab, sal_False ); 2906 if (bUndo) 2907 { 2908 pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nTab, sal_False ) ); 2909 } 2910 2911 // Views updaten: 2912 pDocSh->Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) ); 2913 2914 SetTabNo( nTab, sal_True ); 2915 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); 2916 pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS); 2917 pDocSh->SetDocumentModified(); 2918 } 2919 else 2920 Sound::Beep(); 2921 } 2922 2923 2924 //---------------------------------------------------------------------------- 2925 2926 void ScViewFunc::InsertSpecialChar( const String& rStr, const Font& rFont ) 2927 { 2928 ScEditableTester aTester( this ); 2929 if (!aTester.IsEditable()) 2930 { 2931 ErrorMessage(aTester.GetMessageId()); 2932 return; 2933 } 2934 2935 const sal_Unicode* pChar = rStr.GetBuffer(); 2936 ScTabViewShell* pViewShell = GetViewData()->GetViewShell(); 2937 SvxFontItem aFontItem( rFont.GetFamily(), 2938 rFont.GetName(), 2939 rFont.GetStyleName(), 2940 rFont.GetPitch(), 2941 rFont.GetCharSet(), 2942 ATTR_FONT ); 2943 2944 // if string contains WEAK characters, set all fonts 2945 sal_uInt8 nScript; 2946 ScDocument* pDoc = GetViewData()->GetDocument(); 2947 if ( pDoc->HasStringWeakCharacters( rStr ) ) 2948 nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX; 2949 else 2950 nScript = pDoc->GetStringScriptType( rStr ); 2951 2952 SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, pViewShell->GetPool() ); 2953 aSetItem.PutItemForScriptType( nScript, aFontItem ); 2954 ApplyUserItemSet( aSetItem.GetItemSet() ); 2955 2956 while ( *pChar ) 2957 pViewShell->TabKeyInput( KeyEvent( *(pChar++), KeyCode() ) ); 2958 } 2959 2960 2961 //---------------------------------------------------------------------------- 2962 2963 void ScViewFunc::UpdateLineAttrs( SvxBorderLine& rLine, 2964 const SvxBorderLine* pDestLine, 2965 const SvxBorderLine* pSrcLine, 2966 sal_Bool bColor ) 2967 { 2968 if ( pSrcLine && pDestLine ) 2969 { 2970 if ( bColor ) 2971 { 2972 rLine.SetColor ( pSrcLine->GetColor() ); 2973 rLine.SetOutWidth ( pDestLine->GetOutWidth() ); 2974 rLine.SetInWidth ( pDestLine->GetInWidth() ); 2975 rLine.SetDistance ( pDestLine->GetDistance() ); 2976 } 2977 else 2978 { 2979 rLine.SetColor ( pDestLine->GetColor() ); 2980 rLine.SetOutWidth ( pSrcLine->GetOutWidth() ); 2981 rLine.SetInWidth ( pSrcLine->GetInWidth() ); 2982 rLine.SetDistance ( pSrcLine->GetDistance() ); 2983 } 2984 } 2985 } 2986 2987 2988 #define SET_LINE_ATTRIBUTES(LINE,BOXLINE) \ 2989 pBoxLine = aBoxItem.Get##LINE(); \ 2990 if ( pBoxLine ) \ 2991 { \ 2992 if ( pLine ) \ 2993 { \ 2994 UpdateLineAttrs( aLine, pBoxLine, pLine, bColorOnly ); \ 2995 aBoxItem.SetLine( &aLine, BOXLINE ); \ 2996 } \ 2997 else \ 2998 aBoxItem.SetLine( NULL, BOXLINE ); \ 2999 } 3000 3001 3002 //---------------------------------------------------------------------------- 3003 3004 void ScViewFunc::SetSelectionFrameLines( const SvxBorderLine* pLine, 3005 sal_Bool bColorOnly ) 3006 { 3007 // nur wegen Matrix nicht editierbar? Attribute trotzdem ok 3008 sal_Bool bOnlyNotBecauseOfMatrix; 3009 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix ) 3010 { 3011 ErrorMessage(STR_PROTECTIONERR); 3012 return; 3013 } 3014 3015 ScDocument* pDoc = GetViewData()->GetDocument(); 3016 ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered 3017 ScViewUtil::UnmarkFiltered( aFuncMark, pDoc ); 3018 ScDocShell* pDocSh = GetViewData()->GetDocShell(); 3019 const ScPatternAttr* pSelAttrs = GetSelectionPattern(); 3020 const SfxItemSet& rSelItemSet = pSelAttrs->GetItemSet(); 3021 3022 const SfxPoolItem* pBorderAttr = NULL; 3023 SfxItemState eItemState = rSelItemSet.GetItemState( ATTR_BORDER, sal_True, &pBorderAttr ); 3024 3025 const SfxPoolItem* pTLBRItem = 0; 3026 SfxItemState eTLBRState = rSelItemSet.GetItemState( ATTR_BORDER_TLBR, sal_True, &pTLBRItem ); 3027 3028 const SfxPoolItem* pBLTRItem = 0; 3029 SfxItemState eBLTRState = rSelItemSet.GetItemState( ATTR_BORDER_BLTR, sal_True, &pBLTRItem ); 3030 3031 // any of the lines visible? 3032 if( (eItemState != SFX_ITEM_DEFAULT) || (eTLBRState != SFX_ITEM_DEFAULT) || (eBLTRState != SFX_ITEM_DEFAULT) ) 3033 { 3034 // none of the lines don't care? 3035 if( (eItemState != SFX_ITEM_DONTCARE) && (eTLBRState != SFX_ITEM_DONTCARE) && (eBLTRState != SFX_ITEM_DONTCARE) ) 3036 { 3037 SfxItemSet* pOldSet = new SfxItemSet( 3038 *(pDoc->GetPool()), 3039 ATTR_PATTERN_START, 3040 ATTR_PATTERN_END ); 3041 SfxItemSet* pNewSet = new SfxItemSet( 3042 *(pDoc->GetPool()), 3043 ATTR_PATTERN_START, 3044 ATTR_PATTERN_END ); 3045 3046 //------------------------------------------------------------ 3047 const SvxBorderLine* pBoxLine = NULL; 3048 SvxBorderLine aLine; 3049 3050 // hier wird die pBoxLine benutzt: 3051 3052 if( pBorderAttr ) 3053 { 3054 SvxBoxItem aBoxItem( *(const SvxBoxItem*)pBorderAttr ); 3055 SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER ); 3056 3057 SET_LINE_ATTRIBUTES(Top,BOX_LINE_TOP) 3058 SET_LINE_ATTRIBUTES(Bottom,BOX_LINE_BOTTOM) 3059 SET_LINE_ATTRIBUTES(Left,BOX_LINE_LEFT) 3060 SET_LINE_ATTRIBUTES(Right,BOX_LINE_RIGHT) 3061 3062 aBoxInfoItem.SetLine( aBoxItem.GetTop(), BOXINFO_LINE_HORI ); 3063 aBoxInfoItem.SetLine( aBoxItem.GetLeft(), BOXINFO_LINE_VERT ); 3064 aBoxInfoItem.ResetFlags(); // Lines auf Valid setzen 3065 3066 pOldSet->Put( *pBorderAttr ); 3067 pNewSet->Put( aBoxItem ); 3068 pNewSet->Put( aBoxInfoItem ); 3069 } 3070 3071 if( pTLBRItem && ((const SvxLineItem*)pTLBRItem)->GetLine() ) 3072 { 3073 SvxLineItem aTLBRItem( *(const SvxLineItem*)pTLBRItem ); 3074 UpdateLineAttrs( aLine, aTLBRItem.GetLine(), pLine, bColorOnly ); 3075 aTLBRItem.SetLine( &aLine ); 3076 pOldSet->Put( *pTLBRItem ); 3077 pNewSet->Put( aTLBRItem ); 3078 } 3079 3080 if( pBLTRItem && ((const SvxLineItem*)pBLTRItem)->GetLine() ) 3081 { 3082 SvxLineItem aBLTRItem( *(const SvxLineItem*)pBLTRItem ); 3083 UpdateLineAttrs( aLine, aBLTRItem.GetLine(), pLine, bColorOnly ); 3084 aBLTRItem.SetLine( &aLine ); 3085 pOldSet->Put( *pBLTRItem ); 3086 pNewSet->Put( aBLTRItem ); 3087 } 3088 3089 ApplyAttributes( pNewSet, pOldSet ); 3090 3091 delete pOldSet; 3092 delete pNewSet; 3093 } 3094 else // if ( eItemState == SFX_ITEM_DONTCARE ) 3095 { 3096 aFuncMark.MarkToMulti(); 3097 pDoc->ApplySelectionLineStyle( aFuncMark, pLine, bColorOnly ); 3098 } 3099 3100 ScRange aMarkRange; 3101 aFuncMark.GetMultiMarkArea( aMarkRange ); 3102 SCCOL nStartCol = aMarkRange.aStart.Col(); 3103 SCROW nStartRow = aMarkRange.aStart.Row(); 3104 SCTAB nStartTab = aMarkRange.aStart.Tab(); 3105 SCCOL nEndCol = aMarkRange.aEnd.Col(); 3106 SCROW nEndRow = aMarkRange.aEnd.Row(); 3107 SCTAB nEndTab = aMarkRange.aEnd.Tab(); 3108 pDocSh->PostPaint( nStartCol, nStartRow, nStartTab, 3109 nEndCol, nEndRow, nEndTab, 3110 PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE ); 3111 3112 pDocSh->UpdateOle( GetViewData() ); 3113 pDocSh->SetDocumentModified(); 3114 } 3115 } 3116 3117 #undef SET_LINE_ATTRIBUTES 3118 3119 3120 //---------------------------------------------------------------------------- 3121 3122 void ScViewFunc::SetConditionalFormat( const ScConditionalFormat& rNew ) 3123 { 3124 ScDocument* pDoc = GetViewData()->GetDocument(); 3125 sal_uLong nIndex = pDoc->AddCondFormat(rNew); // dafuer gibt's kein Undo 3126 SfxUInt32Item aItem( ATTR_CONDITIONAL, nIndex ); 3127 3128 ApplyAttr( aItem ); // mit Paint und Undo... 3129 } 3130 3131 3132 //---------------------------------------------------------------------------- 3133 3134 void ScViewFunc::SetValidation( const ScValidationData& rNew ) 3135 { 3136 ScDocument* pDoc = GetViewData()->GetDocument(); 3137 sal_uLong nIndex = pDoc->AddValidationEntry(rNew); // dafuer gibt's kein Undo 3138 SfxUInt32Item aItem( ATTR_VALIDDATA, nIndex ); 3139 3140 ApplyAttr( aItem ); // mit Paint und Undo... 3141 } 3142 3143 3144