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