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