1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sc.hxx" 30 31 32 33 // INCLUDE --------------------------------------------------------------- 34 35 #include "scitems.hxx" 36 #include <editeng/eeitem.hxx> 37 38 39 #include <svtools/colorcfg.hxx> 40 #include <editeng/colritem.hxx> 41 #include <editeng/editview.hxx> 42 #include <editeng/fhgtitem.hxx> 43 #include <editeng/scripttypeitem.hxx> 44 #include <sfx2/bindings.hxx> 45 #include <sfx2/printer.hxx> 46 47 #include <svx/svdview.hxx> 48 #include "tabvwsh.hxx" 49 50 #include "gridwin.hxx" 51 #include "viewdata.hxx" 52 #include "output.hxx" 53 #include "document.hxx" 54 #include "attrib.hxx" 55 #include "patattr.hxx" // InvertSimple 56 #include "dbcolect.hxx" 57 #include "docoptio.hxx" 58 #include "notemark.hxx" 59 #include "dbfunc.hxx" // oder GetPageBreakData an die ViewData 60 #include "scmod.hxx" 61 #include "inputhdl.hxx" 62 #include "rfindlst.hxx" 63 #include "hiranges.hxx" 64 #include "pagedata.hxx" 65 #include "docpool.hxx" 66 #include "globstr.hrc" 67 #include "docsh.hxx" // oder GetSfxInPlaceObject 68 #include "cbutton.hxx" 69 #include "invmerge.hxx" 70 #include "editutil.hxx" 71 #include "inputopt.hxx" 72 #include "fillinfo.hxx" 73 #include "dpcontrol.hxx" 74 #include "queryparam.hxx" 75 #include "sc.hrc" 76 #include <vcl/virdev.hxx> 77 78 // #i74769# 79 #include <svx/sdrpaintwindow.hxx> 80 81 //#include "tabvwsh.hxx" //! Test !!!! 82 83 //------------------------------------------------------------------------ 84 85 void lcl_LimitRect( Rectangle& rRect, const Rectangle& rVisible ) 86 { 87 if ( rRect.Top() < rVisible.Top()-1 ) rRect.Top() = rVisible.Top()-1; 88 // if ( rRect.Left() < rVisible.Left()-1 ) rRect.Left() = rVisible.Left()-1; 89 if ( rRect.Bottom() > rVisible.Bottom()+1 ) rRect.Bottom() = rVisible.Bottom()+1; 90 // if ( rRect.Right() > rVisible.Right()+1 ) rRect.Right() = rVisible.Right()+1; 91 92 // #51122# auch wenn das inner-Rectangle nicht sichtbar ist, muss evtl. 93 // die Titelzeile gezeichnet werden, darum kein Rueckgabewert mehr. 94 // Wenn's weit daneben liegt, wird lcl_DrawOneFrame erst gar nicht gerufen. 95 } 96 97 void lcl_DrawOneFrame( OutputDevice* pDev, const Rectangle& rInnerPixel, 98 const String& rTitle, const Color& rColor, sal_Bool bTextBelow, 99 double nPPTX, double nPPTY, const Fraction& rZoomY, 100 ScDocument* pDoc, ScViewData* pButtonViewData, sal_Bool bLayoutRTL ) 101 { 102 // pButtonViewData wird nur benutzt, um die Button-Groesse zu setzen, 103 // darf ansonsten NULL sein! 104 105 Rectangle aInner = rInnerPixel; 106 if ( bLayoutRTL ) 107 { 108 aInner.Left() = rInnerPixel.Right(); 109 aInner.Right() = rInnerPixel.Left(); 110 } 111 112 Rectangle aVisible( Point(0,0), pDev->GetOutputSizePixel() ); 113 lcl_LimitRect( aInner, aVisible ); 114 115 Rectangle aOuter = aInner; 116 long nHor = (long) ( SC_SCENARIO_HSPACE * nPPTX ); 117 long nVer = (long) ( SC_SCENARIO_VSPACE * nPPTY ); 118 aOuter.Left() -= nHor; 119 aOuter.Right() += nHor; 120 aOuter.Top() -= nVer; 121 aOuter.Bottom() += nVer; 122 123 // use ScPatternAttr::GetFont only for font size 124 Font aAttrFont; 125 ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)). 126 GetFont(aAttrFont,SC_AUTOCOL_BLACK,pDev,&rZoomY); 127 128 // everything else from application font 129 Font aAppFont = pDev->GetSettings().GetStyleSettings().GetAppFont(); 130 aAppFont.SetSize( aAttrFont.GetSize() ); 131 132 aAppFont.SetAlign( ALIGN_TOP ); 133 pDev->SetFont( aAppFont ); 134 135 Size aTextSize( pDev->GetTextWidth( rTitle ), pDev->GetTextHeight() ); 136 137 if ( bTextBelow ) 138 aOuter.Bottom() += aTextSize.Height(); 139 else 140 aOuter.Top() -= aTextSize.Height(); 141 142 pDev->SetLineColor(); 143 pDev->SetFillColor( rColor ); 144 // links, oben, rechts, unten 145 pDev->DrawRect( Rectangle( aOuter.Left(), aOuter.Top(), aInner.Left(), aOuter.Bottom() ) ); 146 pDev->DrawRect( Rectangle( aOuter.Left(), aOuter.Top(), aOuter.Right(), aInner.Top() ) ); 147 pDev->DrawRect( Rectangle( aInner.Right(), aOuter.Top(), aOuter.Right(), aOuter.Bottom() ) ); 148 pDev->DrawRect( Rectangle( aOuter.Left(), aInner.Bottom(), aOuter.Right(), aOuter.Bottom() ) ); 149 150 long nButtonY = bTextBelow ? aInner.Bottom() : aOuter.Top(); 151 152 ScDDComboBoxButton aComboButton((Window*)pDev); 153 aComboButton.SetOptSizePixel(); 154 long nBWidth = ( aComboButton.GetSizePixel().Width() * rZoomY.GetNumerator() ) 155 / rZoomY.GetDenominator(); 156 long nBHeight = nVer + aTextSize.Height() + 1; 157 Size aButSize( nBWidth, nBHeight ); 158 long nButtonPos = bLayoutRTL ? aOuter.Left() : aOuter.Right()-nBWidth+1; 159 aComboButton.Draw( Point(nButtonPos, nButtonY), aButSize, sal_False ); 160 if (pButtonViewData) 161 pButtonViewData->SetScenButSize( aButSize ); 162 163 long nTextStart = bLayoutRTL ? aInner.Right() - aTextSize.Width() + 1 : aInner.Left(); 164 165 sal_Bool bWasClip = sal_False; 166 Region aOldClip; 167 sal_Bool bClip = ( aTextSize.Width() > aOuter.Right() - nBWidth - aInner.Left() ); 168 if ( bClip ) 169 { 170 if (pDev->IsClipRegion()) 171 { 172 bWasClip = sal_True; 173 aOldClip = pDev->GetActiveClipRegion(); 174 } 175 long nClipStartX = bLayoutRTL ? aOuter.Left() + nBWidth : aInner.Left(); 176 long nClipEndX = bLayoutRTL ? aInner.Right() : aOuter.Right() - nBWidth; 177 pDev->SetClipRegion( Rectangle( nClipStartX, nButtonY + nVer/2, 178 nClipEndX, nButtonY + nVer/2 + aTextSize.Height() ) ); 179 } 180 181 pDev->DrawText( Point( nTextStart, nButtonY + nVer/2 ), rTitle ); 182 183 if ( bClip ) 184 { 185 if ( bWasClip ) 186 pDev->SetClipRegion(aOldClip); 187 else 188 pDev->SetClipRegion(); 189 } 190 191 pDev->SetFillColor(); 192 pDev->SetLineColor( COL_BLACK ); 193 pDev->DrawRect( aInner ); 194 pDev->DrawRect( aOuter ); 195 } 196 197 void lcl_DrawScenarioFrames( OutputDevice* pDev, ScViewData* pViewData, ScSplitPos eWhich, 198 SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 ) 199 { 200 ScDocument* pDoc = pViewData->GetDocument(); 201 SCTAB nTab = pViewData->GetTabNo(); 202 SCTAB nTabCount = pDoc->GetTableCount(); 203 if ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) ) 204 { 205 if ( nX1 > 0 ) --nX1; 206 if ( nY1>=2 ) nY1 -= 2; // Hack: Titelzeile beruehrt zwei Zellen 207 else if ( nY1 > 0 ) --nY1; 208 if ( nX2 < MAXCOL ) ++nX2; 209 if ( nY2 < MAXROW-1 ) nY2 += 2; // Hack: Titelzeile beruehrt zwei Zellen 210 else if ( nY2 < MAXROW ) ++nY2; 211 ScRange aViewRange( nX1,nY1,nTab, nX2,nY2,nTab ); 212 213 //! Ranges an der Table cachen!!!! 214 215 ScMarkData aMarks; 216 for (SCTAB i=nTab+1; i<nTabCount && pDoc->IsScenario(i); i++) 217 pDoc->MarkScenario( i, nTab, aMarks, sal_False, SC_SCENARIO_SHOWFRAME ); 218 ScRangeListRef xRanges = new ScRangeList; 219 aMarks.FillRangeListWithMarks( xRanges, sal_False ); 220 221 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 222 long nLayoutSign = bLayoutRTL ? -1 : 1; 223 224 sal_uInt16 nRangeCount = (sal_uInt16)xRanges->Count(); 225 for (sal_uInt16 j=0; j<nRangeCount; j++) 226 { 227 ScRange aRange = *xRanges->GetObject(j); 228 // Szenario-Rahmen immer dann auf zusammengefasste Zellen erweitern, wenn 229 // dadurch keine neuen nicht-ueberdeckten Zellen mit umrandet werden 230 pDoc->ExtendTotalMerge( aRange ); 231 232 //! -> Repaint beim Zusammenfassen erweitern !!! 233 234 if ( aRange.Intersects( aViewRange ) ) //! Platz fuer Text/Button? 235 { 236 Point aStartPos = pViewData->GetScrPos( 237 aRange.aStart.Col(), aRange.aStart.Row(), eWhich, sal_True ); 238 Point aEndPos = pViewData->GetScrPos( 239 aRange.aEnd.Col()+1, aRange.aEnd.Row()+1, eWhich, sal_True ); 240 // on the grid: 241 aStartPos.X() -= nLayoutSign; 242 aStartPos.Y() -= 1; 243 aEndPos.X() -= nLayoutSign; 244 aEndPos.Y() -= 1; 245 246 sal_Bool bTextBelow = ( aRange.aStart.Row() == 0 ); 247 248 String aCurrent; 249 Color aColor( COL_LIGHTGRAY ); 250 for (SCTAB nAct=nTab+1; nAct<nTabCount && pDoc->IsScenario(nAct); nAct++) 251 if ( pDoc->IsActiveScenario(nAct) && pDoc->HasScenarioRange(nAct,aRange) ) 252 { 253 String aDummyComment; 254 sal_uInt16 nDummyFlags; 255 pDoc->GetName( nAct, aCurrent ); 256 pDoc->GetScenarioData( nAct, aDummyComment, aColor, nDummyFlags ); 257 } 258 259 if (!aCurrent.Len()) 260 aCurrent = ScGlobal::GetRscString( STR_EMPTYDATA ); 261 262 //! eigener Text "(keins)" statt "(leer)" ??? 263 264 lcl_DrawOneFrame( pDev, Rectangle( aStartPos, aEndPos ), 265 aCurrent, aColor, bTextBelow, 266 pViewData->GetPPTX(), pViewData->GetPPTY(), pViewData->GetZoomY(), 267 pDoc, pViewData, bLayoutRTL ); 268 } 269 } 270 } 271 } 272 273 //------------------------------------------------------------------------ 274 275 void lcl_DrawHighlight( ScOutputData& rOutputData, ScViewData* pViewData, 276 ScHighlightRanges& rHighlightRanges ) 277 { 278 SCTAB nTab = pViewData->GetTabNo(); 279 sal_uLong nCount = rHighlightRanges.Count(); 280 for (sal_uLong i=0; i<nCount; i++) 281 { 282 ScHighlightEntry* pEntry = rHighlightRanges.GetObject( i ); 283 if (pEntry) 284 { 285 ScRange aRange = pEntry->aRef; 286 if ( nTab >= aRange.aStart.Tab() && nTab <= aRange.aEnd.Tab() ) 287 { 288 rOutputData.DrawRefMark( 289 aRange.aStart.Col(), aRange.aStart.Row(), 290 aRange.aEnd.Col(), aRange.aEnd.Row(), 291 pEntry->aColor, sal_False ); 292 } 293 } 294 } 295 } 296 297 //------------------------------------------------------------------------ 298 299 void ScGridWindow::DoInvertRect( const Rectangle& rPixel ) 300 { 301 // Invert( PixelToLogic(rPixel) ); 302 303 if ( rPixel == aInvertRect ) 304 aInvertRect = Rectangle(); // aufheben 305 else 306 { 307 DBG_ASSERT( aInvertRect.IsEmpty(), "DoInvertRect nicht paarig" ); 308 309 aInvertRect = rPixel; // neues Rechteck merken 310 } 311 312 UpdateHeaderOverlay(); // uses aInvertRect 313 } 314 315 //------------------------------------------------------------------------ 316 317 void __EXPORT ScGridWindow::PrePaint() 318 { 319 // forward PrePaint to DrawingLayer 320 ScTabViewShell* pTabViewShell = pViewData->GetViewShell(); 321 322 if(pTabViewShell) 323 { 324 SdrView* pDrawView = pTabViewShell->GetSdrView(); 325 326 if(pDrawView) 327 { 328 pDrawView->PrePaint(); 329 } 330 } 331 } 332 333 //------------------------------------------------------------------------ 334 335 void __EXPORT ScGridWindow::Paint( const Rectangle& rRect ) 336 { 337 //TODO/LATER: how to get environment? Do we need that?! 338 /* 339 ScDocShell* pDocSh = pViewData->GetDocShell(); 340 SvInPlaceEnvironment* pEnv = pDocSh->GetIPEnv(); 341 if (pEnv && pEnv->GetRectsChangedLockCount()) 342 { 343 Invalidate(rRect); 344 return; 345 }*/ 346 347 ScDocument* pDoc = pViewData->GetDocument(); 348 if ( pDoc->IsInInterpreter() ) 349 { 350 // via Reschedule, interpretierende Zellen nicht nochmal anstossen 351 // hier kein Invalidate, sonst kommt z.B. eine Error-Box nie an die Reihe 352 // (Bug 36381). Durch bNeedsRepaint wird spaeter alles nochmal gemalt. 353 354 if ( bNeedsRepaint ) 355 { 356 //! Rechtecke zusammenfassen? 357 aRepaintPixel = Rectangle(); // mehrfach -> alles painten 358 } 359 else 360 { 361 bNeedsRepaint = sal_True; 362 aRepaintPixel = LogicToPixel(rRect); // nur betroffenen Bereich 363 } 364 return; 365 } 366 367 if (bIsInPaint) 368 return; 369 370 bIsInPaint = sal_True; 371 372 Rectangle aPixRect = LogicToPixel( rRect ); 373 374 SCCOL nX1 = pViewData->GetPosX(eHWhich); 375 SCROW nY1 = pViewData->GetPosY(eVWhich); 376 377 SCTAB nTab = pViewData->GetTabNo(); 378 379 double nPPTX = pViewData->GetPPTX(); 380 double nPPTY = pViewData->GetPPTY(); 381 382 Rectangle aMirroredPixel = aPixRect; 383 if ( pDoc->IsLayoutRTL( nTab ) ) 384 { 385 // mirror and swap 386 long nWidth = GetSizePixel().Width(); 387 aMirroredPixel.Left() = nWidth - 1 - aPixRect.Right(); 388 aMirroredPixel.Right() = nWidth - 1 - aPixRect.Left(); 389 } 390 391 long nScrX = ScViewData::ToPixel( pDoc->GetColWidth( nX1, nTab ), nPPTX ); 392 while ( nScrX <= aMirroredPixel.Left() && nX1 < MAXCOL ) 393 { 394 ++nX1; 395 nScrX += ScViewData::ToPixel( pDoc->GetColWidth( nX1, nTab ), nPPTX ); 396 } 397 SCCOL nX2 = nX1; 398 while ( nScrX <= aMirroredPixel.Right() && nX2 < MAXCOL ) 399 { 400 ++nX2; 401 nScrX += ScViewData::ToPixel( pDoc->GetColWidth( nX2, nTab ), nPPTX ); 402 } 403 404 long nScrY = 0; 405 ScViewData::AddPixelsWhile( nScrY, aPixRect.Top(), nY1, MAXROW, nPPTY, pDoc, nTab); 406 SCROW nY2 = nY1; 407 if (nScrY <= aPixRect.Bottom() && nY2 < MAXROW) 408 { 409 ++nY2; 410 ScViewData::AddPixelsWhile( nScrY, aPixRect.Bottom(), nY2, MAXROW, nPPTY, pDoc, nTab); 411 } 412 413 Draw( nX1,nY1,nX2,nY2, SC_UPDATE_MARKS ); // nicht weiterzeichnen 414 415 bIsInPaint = sal_False; 416 } 417 418 // 419 // Draw ---------------------------------------------------------------- 420 // 421 422 void ScGridWindow::Draw( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, ScUpdateMode eMode ) 423 { 424 ScModule* pScMod = SC_MOD(); 425 sal_Bool bTextWysiwyg = pScMod->GetInputOptions().GetTextWysiwyg(); 426 sal_Bool bGridFirst = sal_True; //! entscheiden!!! 427 428 if (pViewData->IsMinimized()) 429 return; 430 431 PutInOrder( nX1, nX2 ); 432 PutInOrder( nY1, nY2 ); 433 434 DBG_ASSERT( ValidCol(nX2) && ValidRow(nY2), "GridWin Draw Bereich zu gross" ); 435 436 SCCOL nPosX = pViewData->GetPosX( eHWhich ); 437 SCROW nPosY = pViewData->GetPosY( eVWhich ); 438 if (nX2 < nPosX || nY2 < nPosY) 439 return; // unsichtbar 440 if (nX1 < nPosX) nX1 = nPosX; 441 if (nY1 < nPosY) nY1 = nPosY; 442 443 SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich); 444 if (nXRight > MAXCOL) nXRight = MAXCOL; 445 SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich); 446 if (nYBottom > MAXROW) nYBottom = MAXROW; 447 448 // Store the current visible range. 449 maVisibleRange.mnCol1 = nPosX; 450 maVisibleRange.mnCol2 = nXRight; 451 maVisibleRange.mnRow1 = nPosY; 452 maVisibleRange.mnRow2 = nYBottom; 453 454 if (nX1 > nXRight || nY1 > nYBottom) 455 return; // unsichtbar 456 if (nX2 > nXRight) nX2 = nXRight; 457 if (nY2 > nYBottom) nY2 = nYBottom; 458 459 if ( eMode != SC_UPDATE_MARKS ) 460 if (nX2 < nXRight) 461 nX2 = nXRight; // zum Weiterzeichnen 462 463 // ab hier kein return mehr 464 465 ++nPaintCount; // merken, dass gemalt wird (wichtig beim Invertieren) 466 467 ScDocShell* pDocSh = pViewData->GetDocShell(); 468 ScDocument* pDoc = pDocSh->GetDocument(); 469 SCTAB nTab = pViewData->GetTabNo(); 470 471 pDoc->ExtendHidden( nX1, nY1, nX2, nY2, nTab ); 472 473 Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich ); 474 long nMirrorWidth = GetSizePixel().Width(); 475 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 476 long nLayoutSign = bLayoutRTL ? -1 : 1; 477 if ( bLayoutRTL ) 478 { 479 long nEndPixel = pViewData->GetScrPos( nX2+1, nPosY, eWhich ).X(); 480 nMirrorWidth = aScrPos.X() - nEndPixel; 481 aScrPos.X() = nEndPixel + 1; 482 } 483 484 long nScrX = aScrPos.X(); 485 long nScrY = aScrPos.Y(); 486 487 SCCOL nCurX = pViewData->GetCurX(); 488 SCROW nCurY = pViewData->GetCurY(); 489 SCCOL nCurEndX = nCurX; 490 SCROW nCurEndY = nCurY; 491 pDoc->ExtendMerge( nCurX, nCurY, nCurEndX, nCurEndY, nTab ); 492 sal_Bool bCurVis = nCursorHideCount==0 && 493 ( nCurEndX+1 >= nX1 && nCurX <= nX2+1 && nCurEndY+1 >= nY1 && nCurY <= nY2+1 ); 494 495 // AutoFill-Anfasser 496 if ( !bCurVis && nCursorHideCount==0 && bAutoMarkVisible && aAutoMarkPos.Tab() == nTab && 497 ( aAutoMarkPos.Col() != nCurX || aAutoMarkPos.Row() != nCurY ) ) 498 { 499 SCCOL nHdlX = aAutoMarkPos.Col(); 500 SCROW nHdlY = aAutoMarkPos.Row(); 501 pDoc->ExtendMerge( nHdlX, nHdlY, nHdlX, nHdlY, nTab ); 502 bCurVis = ( nHdlX+1 >= nX1 && nHdlX <= nX2 && nHdlY+1 >= nY1 && nHdlY <= nY2 ); 503 // links und oben ist nicht betroffen 504 505 //! AutoFill-Anfasser alleine (ohne Cursor) zeichnen ??? 506 } 507 508 double nPPTX = pViewData->GetPPTX(); 509 double nPPTY = pViewData->GetPPTY(); 510 511 const ScViewOptions& rOpts = pViewData->GetOptions(); 512 sal_Bool bFormulaMode = rOpts.GetOption( VOPT_FORMULAS ); 513 sal_Bool bMarkClipped = rOpts.GetOption( VOPT_CLIPMARKS ); 514 515 // Datenblock 516 517 ScTableInfo aTabInfo; 518 pDoc->FillInfo( aTabInfo, nX1, nY1, nX2, nY2, nTab, 519 nPPTX, nPPTY, sal_False, bFormulaMode, 520 &pViewData->GetMarkData() ); 521 522 //-------------------------------------------------------------------- 523 524 Fraction aZoomX = pViewData->GetZoomX(); 525 Fraction aZoomY = pViewData->GetZoomY(); 526 ScOutputData aOutputData( this, OUTTYPE_WINDOW, aTabInfo, pDoc, nTab, 527 nScrX, nScrY, nX1, nY1, nX2, nY2, nPPTX, nPPTY, 528 &aZoomX, &aZoomY ); 529 530 aOutputData.SetMirrorWidth( nMirrorWidth ); // needed for RTL 531 532 std::auto_ptr< VirtualDevice > xFmtVirtDev; 533 sal_Bool bLogicText = bTextWysiwyg; // call DrawStrings in logic MapMode? 534 535 if ( bTextWysiwyg ) 536 { 537 // use printer for text formatting 538 539 OutputDevice* pFmtDev = pDoc->GetPrinter(); 540 pFmtDev->SetMapMode( pViewData->GetLogicMode(eWhich) ); 541 aOutputData.SetFmtDevice( pFmtDev ); 542 } 543 else if ( aZoomX != aZoomY && pViewData->IsOle() ) 544 { 545 // #i45033# For OLE inplace editing with different zoom factors, 546 // use a virtual device with 1/100th mm as text formatting reference 547 548 xFmtVirtDev.reset( new VirtualDevice ); 549 xFmtVirtDev->SetMapMode( MAP_100TH_MM ); 550 aOutputData.SetFmtDevice( xFmtVirtDev.get() ); 551 552 bLogicText = sal_True; // use logic MapMode 553 } 554 555 const svtools::ColorConfig& rColorCfg = pScMod->GetColorConfig(); 556 Color aGridColor( rColorCfg.GetColorValue( svtools::CALCGRID, sal_False ).nColor ); 557 if ( aGridColor.GetColor() == COL_TRANSPARENT ) 558 { 559 // use view options' grid color only if color config has "automatic" color 560 aGridColor = rOpts.GetGridColor(); 561 } 562 563 aOutputData.SetSyntaxMode ( pViewData->IsSyntaxMode() ); 564 aOutputData.SetGridColor ( aGridColor ); 565 aOutputData.SetShowNullValues ( rOpts.GetOption( VOPT_NULLVALS ) ); 566 aOutputData.SetShowFormulas ( bFormulaMode ); 567 aOutputData.SetShowSpellErrors ( pDoc->GetDocOptions().IsAutoSpell() ); 568 aOutputData.SetMarkClipped ( bMarkClipped ); 569 570 aOutputData.SetUseStyleColor( sal_True ); // always set in table view 571 572 aOutputData.SetEditObject( GetEditObject() ); 573 aOutputData.SetViewShell( pViewData->GetViewShell() ); 574 575 sal_Bool bGrid = rOpts.GetOption( VOPT_GRID ); 576 sal_Bool bPage = rOpts.GetOption( VOPT_PAGEBREAKS ); 577 578 if ( eMode == SC_UPDATE_CHANGED ) 579 { 580 aOutputData.FindChanged(); 581 aOutputData.SetSingleGrid(sal_True); 582 } 583 584 sal_Bool bPageMode = pViewData->IsPagebreakMode(); 585 if (bPageMode) // nach FindChanged 586 { 587 // SetPagebreakMode initialisiert auch bPrinted Flags 588 aOutputData.SetPagebreakMode( pViewData->GetView()->GetPageBreakData() ); 589 } 590 591 EditView* pEditView = NULL; 592 sal_Bool bEditMode = pViewData->HasEditView(eWhich); 593 if ( bEditMode && pViewData->GetRefTabNo() == nTab ) 594 { 595 SCCOL nEditCol; 596 SCROW nEditRow; 597 pViewData->GetEditView( eWhich, pEditView, nEditCol, nEditRow ); 598 SCCOL nEditEndCol = pViewData->GetEditEndCol(); 599 SCROW nEditEndRow = pViewData->GetEditEndRow(); 600 601 if ( nEditEndCol >= nX1 && nEditCol <= nX2 && nEditEndRow >= nY1 && nEditRow <= nY2 ) 602 aOutputData.SetEditCell( nEditCol, nEditRow ); 603 else 604 bEditMode = sal_False; 605 606 // nur Edit-Area zu zeichnen? 607 //! dann muss trotzdem noch der Rand / das Gitter gemalt werden! 608 609 // if ( nEditCol <= nX1 && nEditEndCol >= nX2 && nEditRow <= nY1 && nEditEndRow >= nY2 ) 610 // bOnlyEdit = sal_True; 611 } 612 613 // define drawing layer map mode and paint rectangle 614 const MapMode aDrawMode = GetDrawMapMode(); 615 Rectangle aDrawingRectLogic; 616 617 { 618 // get drawing pixel rect 619 Rectangle aDrawingRectPixel(Point(nScrX, nScrY), Size(aOutputData.GetScrW(), aOutputData.GetScrH())); 620 621 // correct for border (left/right) 622 if(MAXCOL == nX2) 623 { 624 if(bLayoutRTL) 625 { 626 aDrawingRectPixel.Left() = 0L; 627 } 628 else 629 { 630 aDrawingRectPixel.Right() = GetOutputSizePixel().getWidth(); 631 } 632 } 633 634 // correct for border (bottom) 635 if(MAXROW == nY2) 636 { 637 aDrawingRectPixel.Bottom() = GetOutputSizePixel().getHeight(); 638 } 639 640 // get logic positions 641 aDrawingRectLogic = PixelToLogic(aDrawingRectPixel, aDrawMode); 642 } 643 644 // not necessary with overlay 645 // if (bCurVis) 646 // HideCursor(); 647 648 OutputDevice* pContentDev = this; // device for document content, used by overlay manager 649 SdrPaintWindow* pTargetPaintWindow = 0; // #i74769# work with SdrPaintWindow directly 650 651 { 652 // init redraw 653 ScTabViewShell* pTabViewShell = pViewData->GetViewShell(); 654 655 if(pTabViewShell) 656 { 657 MapMode aCurrentMapMode(pContentDev->GetMapMode()); 658 pContentDev->SetMapMode(aDrawMode); 659 SdrView* pDrawView = pTabViewShell->GetSdrView(); 660 661 if(pDrawView) 662 { 663 // #i74769# Use new BeginDrawLayers() interface 664 Region aDrawingRegion(aDrawingRectLogic); 665 pTargetPaintWindow = pDrawView->BeginDrawLayers(this, aDrawingRegion); 666 OSL_ENSURE(pTargetPaintWindow, "BeginDrawLayers: Got no SdrPaintWindow (!)"); 667 668 // #i74769# get target device from SdrPaintWindow, this may be the prerender 669 // device now, too. 670 pContentDev = &(pTargetPaintWindow->GetTargetOutputDevice()); 671 aOutputData.SetContentDevice( pContentDev ); 672 } 673 674 pContentDev->SetMapMode(aCurrentMapMode); 675 } 676 } 677 678 // Rand (Wiese) (Pixel) 679 if ( nX2==MAXCOL || nY2==MAXROW ) 680 { 681 // save MapMode and set to pixel 682 MapMode aCurrentMapMode(pContentDev->GetMapMode()); 683 pContentDev->SetMapMode(MAP_PIXEL); 684 685 Rectangle aPixRect = Rectangle( Point(), GetOutputSizePixel() ); 686 pContentDev->SetFillColor( rColorCfg.GetColorValue(svtools::APPBACKGROUND).nColor ); 687 pContentDev->SetLineColor(); 688 if ( nX2==MAXCOL ) 689 { 690 Rectangle aDrawRect( aPixRect ); 691 if ( bLayoutRTL ) 692 aDrawRect.Right() = nScrX - 1; 693 else 694 aDrawRect.Left() = nScrX + aOutputData.GetScrW(); 695 if (aDrawRect.Right() >= aDrawRect.Left()) 696 pContentDev->DrawRect( aDrawRect ); 697 } 698 if ( nY2==MAXROW ) 699 { 700 Rectangle aDrawRect( aPixRect ); 701 aDrawRect.Top() = nScrY + aOutputData.GetScrH(); 702 if ( nX2==MAXCOL ) 703 { 704 // no double painting of the corner 705 if ( bLayoutRTL ) 706 aDrawRect.Left() = nScrX; 707 else 708 aDrawRect.Right() = nScrX + aOutputData.GetScrW() - 1; 709 } 710 if (aDrawRect.Bottom() >= aDrawRect.Top()) 711 pContentDev->DrawRect( aDrawRect ); 712 } 713 714 // restore MapMode 715 pContentDev->SetMapMode(aCurrentMapMode); 716 } 717 718 if ( pDoc->HasBackgroundDraw( nTab, aDrawingRectLogic ) ) 719 { 720 pContentDev->SetMapMode(MAP_PIXEL); 721 aOutputData.DrawClear(); 722 723 // Drawing Hintergrund 724 725 pContentDev->SetMapMode(aDrawMode); 726 DrawRedraw( aOutputData, eMode, SC_LAYER_BACK ); 727 } 728 else 729 aOutputData.SetSolidBackground(sal_True); 730 731 pContentDev->SetMapMode(MAP_PIXEL); 732 aOutputData.DrawBackground(); 733 if ( bGridFirst && ( bGrid || bPage ) ) 734 aOutputData.DrawGrid( bGrid, bPage ); 735 if ( bPageMode ) 736 { 737 // #87655# DrawPagePreview draws complete lines/page numbers, must always be clipped 738 if ( aOutputData.SetChangedClip() ) 739 { 740 DrawPagePreview(nX1,nY1,nX2,nY2, pContentDev); 741 pContentDev->SetClipRegion(); 742 } 743 } 744 aOutputData.DrawShadow(); 745 aOutputData.DrawFrame(); 746 if ( !bLogicText ) 747 aOutputData.DrawStrings(sal_False); // in pixel MapMode 748 749 // edit cells and printer-metrics text must be before the buttons 750 // (DataPilot buttons contain labels in UI font) 751 752 pContentDev->SetMapMode(pViewData->GetLogicMode(eWhich)); 753 if ( bLogicText ) 754 aOutputData.DrawStrings(sal_True); // in logic MapMode if bTextWysiwyg is set 755 aOutputData.DrawEdit(sal_True); 756 pContentDev->SetMapMode(MAP_PIXEL); 757 758 // Autofilter- und Pivot-Buttons 759 760 DrawButtons( nX1, nY1, nX2, nY2, aTabInfo, pContentDev ); // Pixel 761 762 // Notiz-Anzeiger 763 764 if ( rOpts.GetOption( VOPT_NOTES ) ) 765 aOutputData.DrawNoteMarks(); 766 767 if ( !bGridFirst && ( bGrid || bPage ) ) 768 { 769 aOutputData.DrawGrid( bGrid, bPage ); 770 } 771 aOutputData.DrawClipMarks(); 772 773 // Szenario / ChangeTracking muss auf jeden Fall nach DrawGrid sein, auch bei !bGridFirst 774 775 //! Test, ob ChangeTrack-Anzeige aktiv ist 776 //! Szenario-Rahmen per View-Optionen abschaltbar? 777 778 SCTAB nTabCount = pDoc->GetTableCount(); 779 ScHighlightRanges* pHigh = pViewData->GetView()->GetHighlightRanges(); 780 sal_Bool bHasScenario = ( nTab+1<nTabCount && pDoc->IsScenario(nTab+1) && !pDoc->IsScenario(nTab) ); 781 sal_Bool bHasChange = ( pDoc->GetChangeTrack() != NULL ); 782 783 if ( bHasChange || bHasScenario || pHigh != NULL ) 784 { 785 786 //! SetChangedClip() mit DrawMarks() zusammenfassen?? (anderer MapMode!) 787 788 sal_Bool bAny = sal_True; 789 if (eMode == SC_UPDATE_CHANGED) 790 bAny = aOutputData.SetChangedClip(); 791 if (bAny) 792 { 793 if ( bHasChange ) 794 aOutputData.DrawChangeTrack(); 795 796 if ( bHasScenario ) 797 lcl_DrawScenarioFrames( pContentDev, pViewData, eWhich, nX1,nY1,nX2,nY2 ); 798 799 if ( pHigh ) 800 lcl_DrawHighlight( aOutputData, pViewData, *pHigh ); 801 802 if (eMode == SC_UPDATE_CHANGED) 803 pContentDev->SetClipRegion(); 804 } 805 } 806 807 // Drawing Vordergrund 808 809 pContentDev->SetMapMode(aDrawMode); 810 811 DrawRedraw( aOutputData, eMode, SC_LAYER_FRONT ); 812 DrawRedraw( aOutputData, eMode, SC_LAYER_INTERN ); 813 DrawSdrGrid( aDrawingRectLogic, pContentDev ); 814 815 if (!bIsInScroll) // Drawing Markierungen 816 { 817 if(eMode == SC_UPDATE_CHANGED && aOutputData.SetChangedClip()) 818 { 819 pContentDev->SetClipRegion(); 820 } 821 822 //sal_Bool bDraw = sal_True; 823 //if (eMode == SC_UPDATE_CHANGED) 824 // bDraw = NeedDrawMarks() && aOutputData.SetChangedClip(); 825 //if (bDraw) 826 //{ 827 // DrawMarks(); 828 // if (eMode == SC_UPDATE_CHANGED) 829 // pContentDev->SetClipRegion(); 830 //} 831 } 832 833 pContentDev->SetMapMode(MAP_PIXEL); 834 835 #ifdef OLD_SELECTION_PAINT 836 if (pViewData->IsActive()) 837 aOutputData.DrawMark( this ); 838 #endif 839 840 if ( pViewData->IsRefMode() && nTab >= pViewData->GetRefStartZ() && nTab <= pViewData->GetRefEndZ() ) 841 { 842 // The AutoFill shrink area has an own overlay now 843 #if 0 844 // Schraffur beim Loeschen per AutoFill 845 if ( pViewData->GetRefType() == SC_REFTYPE_FILL ) 846 { 847 ScRange aRange; 848 if ( pViewData->GetDelMark( aRange ) ) 849 { 850 if ( aRange.aStart.Col() < nX1 ) aRange.aStart.SetCol(nX1); 851 if ( aRange.aEnd.Col() > nX2 ) aRange.aEnd.SetCol(nX2); 852 if ( aRange.aStart.Row() < nY1 ) aRange.aStart.SetRow(nY1); 853 if ( aRange.aEnd.Row() > nY2 ) aRange.aEnd.SetRow(nY2); 854 if ( aRange.aStart.Col() <= aRange.aEnd.Col() && 855 aRange.aStart.Row() <= aRange.aEnd.Row() ) 856 { 857 Point aStart = pViewData->GetScrPos( aRange.aStart.Col(), 858 aRange.aStart.Row(), eWhich ); 859 Point aEnd = pViewData->GetScrPos( aRange.aEnd.Col()+1, 860 aRange.aEnd.Row()+1, eWhich ); 861 aEnd.X() -= 1; 862 aEnd.Y() -= 1; 863 864 // Markierung aufheben - roter Rahmen bleibt stehen 865 Rectangle aRect( aStart,aEnd ); 866 Invert( aRect, INVERT_HIGHLIGHT ); 867 868 //! Delete-Bereich extra kennzeichnen?!?!? 869 } 870 } 871 } 872 #endif 873 874 Color aRefColor( rColorCfg.GetColorValue(svtools::CALCREFERENCE).nColor ); 875 aOutputData.DrawRefMark( pViewData->GetRefStartX(), pViewData->GetRefStartY(), 876 pViewData->GetRefEndX(), pViewData->GetRefEndY(), 877 aRefColor, sal_False ); 878 } 879 880 // Range-Finder 881 882 ScInputHandler* pHdl = pScMod->GetInputHdl( pViewData->GetViewShell() ); 883 if (pHdl) 884 { 885 ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList(); 886 if ( pRangeFinder && !pRangeFinder->IsHidden() && 887 pRangeFinder->GetDocName() == pDocSh->GetTitle() ) 888 { 889 sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count(); 890 for (sal_uInt16 i=0; i<nCount; i++) 891 { 892 ScRangeFindData* pData = pRangeFinder->GetObject(i); 893 if (pData) 894 { 895 ScRange aRef = pData->aRef; 896 aRef.Justify(); 897 if ( aRef.aStart.Tab() >= nTab && aRef.aEnd.Tab() <= nTab ) 898 aOutputData.DrawRefMark( aRef.aStart.Col(), aRef.aStart.Row(), 899 aRef.aEnd.Col(), aRef.aEnd.Row(), 900 Color( ScRangeFindList::GetColorName( i ) ), 901 sal_True ); 902 } 903 } 904 } 905 } 906 907 { 908 // end redraw 909 ScTabViewShell* pTabViewShell = pViewData->GetViewShell(); 910 911 if(pTabViewShell) 912 { 913 MapMode aCurrentMapMode(pContentDev->GetMapMode()); 914 pContentDev->SetMapMode(aDrawMode); 915 SdrView* pDrawView = pTabViewShell->GetSdrView(); 916 917 if(pDrawView) 918 { 919 // #i74769# work with SdrPaintWindow directly 920 pDrawView->EndDrawLayers(*pTargetPaintWindow, true); 921 } 922 923 pContentDev->SetMapMode(aCurrentMapMode); 924 } 925 } 926 927 // InPlace Edit-View 928 // moved after EndDrawLayers() to get it outside the overlay buffer and 929 // on top of everything 930 if ( bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()) ) 931 { 932 //! use pContentDev for EditView? 933 SetMapMode(MAP_PIXEL); 934 SCCOL nCol1 = pViewData->GetEditStartCol(); 935 SCROW nRow1 = pViewData->GetEditStartRow(); 936 SCCOL nCol2 = pViewData->GetEditEndCol(); 937 SCROW nRow2 = pViewData->GetEditEndRow(); 938 SetLineColor(); 939 SetFillColor( pEditView->GetBackgroundColor() ); 940 Point aStart = pViewData->GetScrPos( nCol1, nRow1, eWhich ); 941 Point aEnd = pViewData->GetScrPos( nCol2+1, nRow2+1, eWhich ); 942 aEnd.X() -= 2 * nLayoutSign; // don't overwrite grid 943 aEnd.Y() -= 2; 944 DrawRect( Rectangle( aStart,aEnd ) ); 945 946 SetMapMode(pViewData->GetLogicMode()); 947 pEditView->Paint( PixelToLogic( Rectangle( Point( nScrX, nScrY ), 948 Size( aOutputData.GetScrW(), aOutputData.GetScrH() ) ) ) ); 949 SetMapMode(MAP_PIXEL); 950 } 951 952 if (pViewData->HasEditView(eWhich)) 953 { 954 // flush OverlayManager before changing the MapMode 955 flushOverlayManager(); 956 957 // set MapMode for text edit 958 SetMapMode(pViewData->GetLogicMode()); 959 } 960 else 961 SetMapMode(aDrawMode); 962 963 if ( pNoteMarker ) 964 pNoteMarker->Draw(); // ueber den Cursor, im Drawing-MapMode 965 966 //DrawStartTimer(); // fuer bunte Handles ohne System-Clipping 967 968 // 969 // Wenn waehrend des Paint etwas invertiert wurde (Selektion geaendert aus Basic-Macro), 970 // ist das jetzt durcheinandergekommen und es muss neu gemalt werden 971 // 972 973 DBG_ASSERT(nPaintCount, "nPaintCount falsch"); 974 --nPaintCount; 975 if (!nPaintCount) 976 CheckNeedsRepaint(); 977 } 978 979 void ScGridWindow::CheckNeedsRepaint() 980 { 981 // called at the end of painting, and from timer after background text width calculation 982 983 if (bNeedsRepaint) 984 { 985 bNeedsRepaint = sal_False; 986 if (aRepaintPixel.IsEmpty()) 987 Invalidate(); 988 else 989 Invalidate(PixelToLogic(aRepaintPixel)); 990 aRepaintPixel = Rectangle(); 991 992 // selection function in status bar might also be invalid 993 SfxBindings& rBindings = pViewData->GetBindings(); 994 rBindings.Invalidate( SID_STATUS_SUM ); 995 rBindings.Invalidate( SID_ATTR_SIZE ); 996 rBindings.Invalidate( SID_TABLE_CELL ); 997 } 998 } 999 1000 void ScGridWindow::DrawPagePreview( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, OutputDevice* pContentDev ) 1001 { 1002 ScPageBreakData* pPageData = pViewData->GetView()->GetPageBreakData(); 1003 if (pPageData) 1004 { 1005 ScDocument* pDoc = pViewData->GetDocument(); 1006 SCTAB nTab = pViewData->GetTabNo(); 1007 Size aWinSize = GetOutputSizePixel(); 1008 const svtools::ColorConfig& rColorCfg = SC_MOD()->GetColorConfig(); 1009 Color aManual( rColorCfg.GetColorValue(svtools::CALCPAGEBREAKMANUAL).nColor ); 1010 Color aAutomatic( rColorCfg.GetColorValue(svtools::CALCPAGEBREAK).nColor ); 1011 1012 String aPageText = ScGlobal::GetRscString( STR_PAGE ); 1013 if ( nPageScript == 0 ) 1014 { 1015 // get script type of translated "Page" string only once 1016 nPageScript = pDoc->GetStringScriptType( aPageText ); 1017 if (nPageScript == 0) 1018 nPageScript = ScGlobal::GetDefaultScriptType(); 1019 } 1020 aPageText += ' '; 1021 1022 Font aFont; 1023 ScEditEngineDefaulter* pEditEng = NULL; 1024 const ScPatternAttr& rDefPattern = ((const ScPatternAttr&)pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)); 1025 if ( nPageScript == SCRIPTTYPE_LATIN ) 1026 { 1027 // use single font and call DrawText directly 1028 rDefPattern.GetFont( aFont, SC_AUTOCOL_BLACK ); 1029 aFont.SetColor( Color( COL_LIGHTGRAY ) ); 1030 // font size is set as needed 1031 } 1032 else 1033 { 1034 // use EditEngine to draw mixed-script string 1035 pEditEng = new ScEditEngineDefaulter( EditEngine::CreatePool(), sal_True ); 1036 pEditEng->SetRefMapMode( pContentDev->GetMapMode() ); 1037 SfxItemSet* pEditDefaults = new SfxItemSet( pEditEng->GetEmptyItemSet() ); 1038 rDefPattern.FillEditItemSet( pEditDefaults ); 1039 pEditDefaults->Put( SvxColorItem( Color( COL_LIGHTGRAY ), EE_CHAR_COLOR ) ); 1040 pEditEng->SetDefaults( pEditDefaults ); 1041 } 1042 1043 sal_uInt16 nCount = sal::static_int_cast<sal_uInt16>( pPageData->GetCount() ); 1044 for (sal_uInt16 nPos=0; nPos<nCount; nPos++) 1045 { 1046 ScPrintRangeData& rData = pPageData->GetData(nPos); 1047 ScRange aRange = rData.GetPrintRange(); 1048 if ( aRange.aStart.Col() <= nX2+1 && aRange.aEnd.Col()+1 >= nX1 && 1049 aRange.aStart.Row() <= nY2+1 && aRange.aEnd.Row()+1 >= nY1 ) 1050 { 1051 // 3 Pixel Rahmen um den Druckbereich 1052 // (mittlerer Pixel auf den Gitterlinien) 1053 1054 pContentDev->SetLineColor(); 1055 if (rData.IsAutomatic()) 1056 pContentDev->SetFillColor( aAutomatic ); 1057 else 1058 pContentDev->SetFillColor( aManual ); 1059 1060 Point aStart = pViewData->GetScrPos( 1061 aRange.aStart.Col(), aRange.aStart.Row(), eWhich, sal_True ); 1062 Point aEnd = pViewData->GetScrPos( 1063 aRange.aEnd.Col() + 1, aRange.aEnd.Row() + 1, eWhich, sal_True ); 1064 aStart.X() -= 2; 1065 aStart.Y() -= 2; 1066 1067 // Ueberlaeufe verhindern: 1068 if ( aStart.X() < -10 ) aStart.X() = -10; 1069 if ( aStart.Y() < -10 ) aStart.Y() = -10; 1070 if ( aEnd.X() > aWinSize.Width() + 10 ) 1071 aEnd.X() = aWinSize.Width() + 10; 1072 if ( aEnd.Y() > aWinSize.Height() + 10 ) 1073 aEnd.Y() = aWinSize.Height() + 10; 1074 1075 pContentDev->DrawRect( Rectangle( aStart, Point(aEnd.X(),aStart.Y()+2) ) ); 1076 pContentDev->DrawRect( Rectangle( aStart, Point(aStart.X()+2,aEnd.Y()) ) ); 1077 pContentDev->DrawRect( Rectangle( Point(aStart.X(),aEnd.Y()-2), aEnd ) ); 1078 pContentDev->DrawRect( Rectangle( Point(aEnd.X()-2,aStart.Y()), aEnd ) ); 1079 1080 // Seitenumbrueche 1081 //! anders darstellen (gestrichelt ????) 1082 1083 size_t nColBreaks = rData.GetPagesX(); 1084 const SCCOL* pColEnd = rData.GetPageEndX(); 1085 size_t nColPos; 1086 for (nColPos=0; nColPos+1<nColBreaks; nColPos++) 1087 { 1088 SCCOL nBreak = pColEnd[nColPos]+1; 1089 if ( nBreak >= nX1 && nBreak <= nX2+1 ) 1090 { 1091 //! hidden suchen 1092 if (pDoc->HasColBreak(nBreak, nTab) & BREAK_MANUAL) 1093 pContentDev->SetFillColor( aManual ); 1094 else 1095 pContentDev->SetFillColor( aAutomatic ); 1096 Point aBreak = pViewData->GetScrPos( 1097 nBreak, aRange.aStart.Row(), eWhich, sal_True ); 1098 pContentDev->DrawRect( Rectangle( aBreak.X()-1, aStart.Y(), aBreak.X(), aEnd.Y() ) ); 1099 } 1100 } 1101 1102 size_t nRowBreaks = rData.GetPagesY(); 1103 const SCROW* pRowEnd = rData.GetPageEndY(); 1104 size_t nRowPos; 1105 for (nRowPos=0; nRowPos+1<nRowBreaks; nRowPos++) 1106 { 1107 SCROW nBreak = pRowEnd[nRowPos]+1; 1108 if ( nBreak >= nY1 && nBreak <= nY2+1 ) 1109 { 1110 //! hidden suchen 1111 if (pDoc->HasRowBreak(nBreak, nTab) & BREAK_MANUAL) 1112 pContentDev->SetFillColor( aManual ); 1113 else 1114 pContentDev->SetFillColor( aAutomatic ); 1115 Point aBreak = pViewData->GetScrPos( 1116 aRange.aStart.Col(), nBreak, eWhich, sal_True ); 1117 pContentDev->DrawRect( Rectangle( aStart.X(), aBreak.Y()-1, aEnd.X(), aBreak.Y() ) ); 1118 } 1119 } 1120 1121 // Seitenzahlen 1122 1123 SCROW nPrStartY = aRange.aStart.Row(); 1124 for (nRowPos=0; nRowPos<nRowBreaks; nRowPos++) 1125 { 1126 SCROW nPrEndY = pRowEnd[nRowPos]; 1127 if ( nPrEndY >= nY1 && nPrStartY <= nY2 ) 1128 { 1129 SCCOL nPrStartX = aRange.aStart.Col(); 1130 for (nColPos=0; nColPos<nColBreaks; nColPos++) 1131 { 1132 SCCOL nPrEndX = pColEnd[nColPos]; 1133 if ( nPrEndX >= nX1 && nPrStartX <= nX2 ) 1134 { 1135 Point aPageStart = pViewData->GetScrPos( 1136 nPrStartX, nPrStartY, eWhich, sal_True ); 1137 Point aPageEnd = pViewData->GetScrPos( 1138 nPrEndX+1,nPrEndY+1, eWhich, sal_True ); 1139 1140 long nPageNo = rData.GetFirstPage(); 1141 if ( rData.IsTopDown() ) 1142 nPageNo += ((long)nColPos)*nRowBreaks+nRowPos; 1143 else 1144 nPageNo += ((long)nRowPos)*nColBreaks+nColPos; 1145 String aPageStr = aPageText; 1146 aPageStr += String::CreateFromInt32(nPageNo); 1147 1148 if ( pEditEng ) 1149 { 1150 // find right font size with EditEngine 1151 long nHeight = 100; 1152 pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) ); 1153 pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) ); 1154 pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) ); 1155 pEditEng->SetText( aPageStr ); 1156 Size aSize100( pEditEng->CalcTextWidth(), pEditEng->GetTextHeight() ); 1157 1158 // 40% of width or 60% of height 1159 long nSizeX = 40 * ( aPageEnd.X() - aPageStart.X() ) / aSize100.Width(); 1160 long nSizeY = 60 * ( aPageEnd.Y() - aPageStart.Y() ) / aSize100.Height(); 1161 nHeight = Min(nSizeX,nSizeY); 1162 pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT ) ); 1163 pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CJK ) ); 1164 pEditEng->SetDefaultItem( SvxFontHeightItem( nHeight, 100, EE_CHAR_FONTHEIGHT_CTL ) ); 1165 1166 // centered output with EditEngine 1167 Size aTextSize( pEditEng->CalcTextWidth(), pEditEng->GetTextHeight() ); 1168 Point aPos( (aPageStart.X()+aPageEnd.X()-aTextSize.Width())/2, 1169 (aPageStart.Y()+aPageEnd.Y()-aTextSize.Height())/2 ); 1170 pEditEng->Draw( pContentDev, aPos ); 1171 } 1172 else 1173 { 1174 // find right font size for DrawText 1175 aFont.SetSize( Size( 0,100 ) ); 1176 pContentDev->SetFont( aFont ); 1177 Size aSize100( pContentDev->GetTextWidth( aPageStr ), pContentDev->GetTextHeight() ); 1178 1179 // 40% of width or 60% of height 1180 long nSizeX = 40 * ( aPageEnd.X() - aPageStart.X() ) / aSize100.Width(); 1181 long nSizeY = 60 * ( aPageEnd.Y() - aPageStart.Y() ) / aSize100.Height(); 1182 aFont.SetSize( Size( 0,Min(nSizeX,nSizeY) ) ); 1183 pContentDev->SetFont( aFont ); 1184 1185 // centered output with DrawText 1186 Size aTextSize( pContentDev->GetTextWidth( aPageStr ), pContentDev->GetTextHeight() ); 1187 Point aPos( (aPageStart.X()+aPageEnd.X()-aTextSize.Width())/2, 1188 (aPageStart.Y()+aPageEnd.Y()-aTextSize.Height())/2 ); 1189 pContentDev->DrawText( aPos, aPageStr ); 1190 } 1191 } 1192 nPrStartX = nPrEndX + 1; 1193 } 1194 } 1195 nPrStartY = nPrEndY + 1; 1196 } 1197 } 1198 } 1199 1200 delete pEditEng; 1201 } 1202 } 1203 1204 void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2*/, ScTableInfo& rTabInfo, OutputDevice* pContentDev ) 1205 { 1206 aComboButton.SetOutputDevice( pContentDev ); 1207 1208 ScDocument* pDoc = pViewData->GetDocument(); 1209 ScDPFieldButton aCellBtn(pContentDev, &GetSettings().GetStyleSettings(), &pViewData->GetZoomX(), &pViewData->GetZoomY(), pDoc); 1210 1211 SCCOL nCol; 1212 SCROW nRow; 1213 SCSIZE nArrY; 1214 SCSIZE nQuery; 1215 SCTAB nTab = pViewData->GetTabNo(); 1216 ScDBData* pDBData = NULL; 1217 ScQueryParam* pQueryParam = NULL; 1218 1219 RowInfo* pRowInfo = rTabInfo.mpRowInfo; 1220 sal_uInt16 nArrCount = rTabInfo.mnArrCount; 1221 1222 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 1223 1224 Point aOldPos = aComboButton.GetPosPixel(); // Zustand fuer MouseDown/Up 1225 Size aOldSize = aComboButton.GetSizePixel(); // merken 1226 1227 for (nArrY=1; nArrY+1<nArrCount; nArrY++) 1228 { 1229 if ( pRowInfo[nArrY].bAutoFilter && pRowInfo[nArrY].bChanged ) 1230 { 1231 RowInfo* pThisRowInfo = &pRowInfo[nArrY]; 1232 1233 nRow = pThisRowInfo->nRowNo; 1234 1235 1236 for (nCol=nX1; nCol<=nX2; nCol++) 1237 { 1238 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nCol+1]; 1239 if ( pInfo->bAutoFilter && !pInfo->bHOverlapped && !pInfo->bVOverlapped ) 1240 { 1241 if (!pQueryParam) 1242 pQueryParam = new ScQueryParam; 1243 1244 sal_Bool bNewData = sal_True; 1245 if (pDBData) 1246 { 1247 SCCOL nStartCol; 1248 SCROW nStartRow; 1249 SCCOL nEndCol; 1250 SCROW nEndRow; 1251 SCTAB nAreaTab; 1252 pDBData->GetArea( nAreaTab, nStartCol, nStartRow, nEndCol, nEndRow ); 1253 if ( nCol >= nStartCol && nCol <= nEndCol && 1254 nRow >= nStartRow && nRow <= nEndRow ) 1255 bNewData = sal_False; 1256 } 1257 if (bNewData) 1258 { 1259 pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab ); 1260 if (pDBData) 1261 pDBData->GetQueryParam( *pQueryParam ); 1262 else 1263 { 1264 // can also be part of DataPilot table 1265 // DBG_ERROR("Auto-Filter-Button ohne DBData"); 1266 } 1267 } 1268 1269 // pQueryParam kann nur MAXQUERY Eintraege enthalten 1270 1271 sal_Bool bSimpleQuery = sal_True; 1272 sal_Bool bColumnFound = sal_False; 1273 if (!pQueryParam->bInplace) 1274 bSimpleQuery = sal_False; 1275 for (nQuery=0; nQuery<MAXQUERY && bSimpleQuery; nQuery++) 1276 if (pQueryParam->GetEntry(nQuery).bDoQuery) 1277 { 1278 // hier nicht auf EQUAL beschraenken 1279 // (auch bei ">1" soll der Spaltenkopf blau werden) 1280 1281 if (pQueryParam->GetEntry(nQuery).nField == nCol) 1282 bColumnFound = sal_True; 1283 if (nQuery > 0) 1284 if (pQueryParam->GetEntry(nQuery).eConnect != SC_AND) 1285 bSimpleQuery = sal_False; 1286 } 1287 1288 bool bArrowState = bSimpleQuery && bColumnFound; 1289 long nSizeX; 1290 long nSizeY; 1291 pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY ); 1292 Point aScrPos = pViewData->GetScrPos( nCol, nRow, eWhich ); 1293 1294 aCellBtn.setBoundingBox(aScrPos, Size(nSizeX-1, nSizeY-1), bLayoutRTL); 1295 aCellBtn.setPopupLeft(bLayoutRTL); // #i114944# AutoFilter button is left-aligned in RTL 1296 aCellBtn.setDrawBaseButton(false); 1297 aCellBtn.setDrawPopupButton(true); 1298 aCellBtn.setHasHiddenMember(bArrowState); 1299 aCellBtn.draw(); 1300 } 1301 } 1302 } 1303 1304 if ( pRowInfo[nArrY].bPushButton && pRowInfo[nArrY].bChanged ) 1305 { 1306 RowInfo* pThisRowInfo = &pRowInfo[nArrY]; 1307 nRow = pThisRowInfo->nRowNo; 1308 for (nCol=nX1; nCol<=nX2; nCol++) 1309 { 1310 CellInfo* pInfo = &pThisRowInfo->pCellInfo[nCol+1]; 1311 if ( pInfo->bPushButton && !pInfo->bHOverlapped && !pInfo->bVOverlapped ) 1312 { 1313 Point aScrPos = pViewData->GetScrPos( nCol, nRow, eWhich ); 1314 long nSizeX; 1315 long nSizeY; 1316 pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY ); 1317 long nPosX = aScrPos.X(); 1318 long nPosY = aScrPos.Y(); 1319 // bLayoutRTL is handled in setBoundingBox 1320 1321 String aStr; 1322 pDoc->GetString(nCol, nRow, nTab, aStr); 1323 aCellBtn.setText(aStr); 1324 aCellBtn.setBoundingBox(Point(nPosX, nPosY), Size(nSizeX-1, nSizeY-1), bLayoutRTL); 1325 aCellBtn.setPopupLeft(false); // DataPilot popup is always right-aligned for now 1326 aCellBtn.setDrawBaseButton(true); 1327 aCellBtn.setDrawPopupButton(pInfo->bPopupButton); 1328 aCellBtn.setHasHiddenMember(pInfo->bFilterActive); 1329 aCellBtn.draw(); 1330 } 1331 } 1332 } 1333 1334 if ( bListValButton && pRowInfo[nArrY].nRowNo == aListValPos.Row() && pRowInfo[nArrY].bChanged ) 1335 { 1336 Rectangle aRect = GetListValButtonRect( aListValPos ); 1337 aComboButton.SetPosPixel( aRect.TopLeft() ); 1338 aComboButton.SetSizePixel( aRect.GetSize() ); 1339 pContentDev->SetClipRegion( aRect ); 1340 aComboButton.Draw( sal_False, sal_False ); 1341 pContentDev->SetClipRegion(); // always called from Draw() without clip region 1342 aComboButton.SetPosPixel( aOldPos ); // restore old state 1343 aComboButton.SetSizePixel( aOldSize ); // for MouseUp/Down (AutoFilter) 1344 } 1345 } 1346 1347 delete pQueryParam; 1348 aComboButton.SetOutputDevice( this ); 1349 } 1350 1351 Rectangle ScGridWindow::GetListValButtonRect( const ScAddress& rButtonPos ) 1352 { 1353 ScDocument* pDoc = pViewData->GetDocument(); 1354 SCTAB nTab = pViewData->GetTabNo(); 1355 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 1356 long nLayoutSign = bLayoutRTL ? -1 : 1; 1357 1358 ScDDComboBoxButton aButton( this ); // for optimal size 1359 Size aBtnSize = aButton.GetSizePixel(); 1360 1361 SCCOL nCol = rButtonPos.Col(); 1362 SCROW nRow = rButtonPos.Row(); 1363 1364 long nCellSizeX; // width of this cell, including merged 1365 long nDummy; 1366 pViewData->GetMergeSizePixel( nCol, nRow, nCellSizeX, nDummy ); 1367 1368 // for height, only the cell's row is used, excluding merged cells 1369 long nCellSizeY = ScViewData::ToPixel( pDoc->GetRowHeight( nRow, nTab ), pViewData->GetPPTY() ); 1370 long nAvailable = nCellSizeX; 1371 1372 // left edge of next cell if there is a non-hidden next column 1373 SCCOL nNextCol = nCol + 1; 1374 const ScMergeAttr* pMerge = static_cast<const ScMergeAttr*>(pDoc->GetAttr( nCol,nRow,nTab, ATTR_MERGE )); 1375 if ( pMerge->GetColMerge() > 1 ) 1376 nNextCol = nCol + pMerge->GetColMerge(); // next cell after the merged area 1377 while ( nNextCol <= MAXCOL && pDoc->ColHidden(nNextCol, nTab) ) 1378 ++nNextCol; 1379 sal_Bool bNextCell = ( nNextCol <= MAXCOL ); 1380 if ( bNextCell ) 1381 nAvailable = ScViewData::ToPixel( pDoc->GetColWidth( nNextCol, nTab ), pViewData->GetPPTX() ); 1382 1383 if ( nAvailable < aBtnSize.Width() ) 1384 aBtnSize.Width() = nAvailable; 1385 if ( nCellSizeY < aBtnSize.Height() ) 1386 aBtnSize.Height() = nCellSizeY; 1387 1388 Point aPos = pViewData->GetScrPos( nCol, nRow, eWhich, sal_True ); 1389 aPos.X() += nCellSizeX * nLayoutSign; // start of next cell 1390 if (!bNextCell) 1391 aPos.X() -= aBtnSize.Width() * nLayoutSign; // right edge of cell if next cell not available 1392 aPos.Y() += nCellSizeY - aBtnSize.Height(); 1393 // X remains at the left edge 1394 1395 if ( bLayoutRTL ) 1396 aPos.X() -= aBtnSize.Width()-1; // align right edge of button with cell border 1397 1398 return Rectangle( aPos, aBtnSize ); 1399 } 1400 1401 sal_Bool ScGridWindow::IsAutoFilterActive( SCCOL nCol, SCROW nRow, SCTAB nTab ) 1402 { 1403 ScDocument* pDoc = pViewData->GetDocument(); 1404 ScDBData* pDBData = pDoc->GetDBAtCursor( nCol, nRow, nTab ); 1405 ScQueryParam aQueryParam; 1406 1407 if ( pDBData ) 1408 pDBData->GetQueryParam( aQueryParam ); 1409 else 1410 { 1411 DBG_ERROR("Auto-Filter-Button ohne DBData"); 1412 } 1413 1414 sal_Bool bSimpleQuery = sal_True; 1415 sal_Bool bColumnFound = sal_False; 1416 SCSIZE nQuery; 1417 1418 if ( !aQueryParam.bInplace ) 1419 bSimpleQuery = sal_False; 1420 1421 // aQueryParam kann nur MAXQUERY Eintraege enthalten 1422 1423 for ( nQuery=0; nQuery<MAXQUERY && bSimpleQuery; nQuery++ ) 1424 if ( aQueryParam.GetEntry(nQuery).bDoQuery ) 1425 { 1426 if (aQueryParam.GetEntry(nQuery).nField == nCol) 1427 bColumnFound = sal_True; 1428 1429 if (nQuery > 0) 1430 if (aQueryParam.GetEntry(nQuery).eConnect != SC_AND) 1431 bSimpleQuery = sal_False; 1432 } 1433 1434 return ( bSimpleQuery && bColumnFound ); 1435 } 1436 1437 void ScGridWindow::DrawComboButton( const Point& rCellPos, 1438 long nCellSizeX, 1439 long nCellSizeY, 1440 sal_Bool bArrowState, 1441 sal_Bool bBtnIn ) 1442 { 1443 Point aScrPos = rCellPos; 1444 Size aBtnSize = aComboButton.GetSizePixel(); 1445 1446 if ( nCellSizeX < aBtnSize.Width() || nCellSizeY < aBtnSize.Height() ) 1447 { 1448 if ( nCellSizeX < aBtnSize.Width() ) 1449 aBtnSize.Width() = nCellSizeX; 1450 1451 if ( nCellSizeY < aBtnSize.Height() ) 1452 aBtnSize.Height() = nCellSizeY; 1453 1454 aComboButton.SetSizePixel( aBtnSize ); 1455 } 1456 1457 sal_Bool bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() ); 1458 1459 if ( bLayoutRTL ) 1460 aScrPos.X() -= nCellSizeX - 1; 1461 else 1462 aScrPos.X() += nCellSizeX - aBtnSize.Width(); 1463 aScrPos.Y() += nCellSizeY - aBtnSize.Height(); 1464 1465 aComboButton.SetPosPixel( aScrPos ); 1466 1467 HideCursor(); 1468 aComboButton.Draw( bArrowState, bBtnIn ); 1469 ShowCursor(); 1470 } 1471 1472 void ScGridWindow::InvertSimple( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, 1473 sal_Bool bTestMerge, sal_Bool bRepeat ) 1474 { 1475 //! if INVERT_HIGHLIGHT swaps foreground and background (like on Mac), 1476 //! use INVERT_HIGHLIGHT only for cells that have no background color set 1477 //! (here and in ScOutputData::DrawMark) 1478 1479 PutInOrder( nX1, nX2 ); 1480 PutInOrder( nY1, nY2 ); 1481 1482 ScMarkData& rMark = pViewData->GetMarkData(); 1483 ScDocument* pDoc = pViewData->GetDocument(); 1484 SCTAB nTab = pViewData->GetTabNo(); 1485 1486 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 1487 long nLayoutSign = bLayoutRTL ? -1 : 1; 1488 1489 SCCOL nTestX2 = nX2; 1490 SCROW nTestY2 = nY2; 1491 if (bTestMerge) 1492 pDoc->ExtendMerge( nX1,nY1, nTestX2,nTestY2, nTab ); 1493 1494 SCCOL nPosX = pViewData->GetPosX( eHWhich ); 1495 SCROW nPosY = pViewData->GetPosY( eVWhich ); 1496 if (nTestX2 < nPosX || nTestY2 < nPosY) 1497 return; // unsichtbar 1498 SCCOL nRealX1 = nX1; 1499 if (nX1 < nPosX) 1500 nX1 = nPosX; 1501 if (nY1 < nPosY) 1502 nY1 = nPosY; 1503 1504 SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich); 1505 if (nXRight > MAXCOL) nXRight = MAXCOL; 1506 SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich); 1507 if (nYBottom > MAXROW) nYBottom = MAXROW; 1508 1509 if (nX1 > nXRight || nY1 > nYBottom) 1510 return; // unsichtbar 1511 if (nX2 > nXRight) nX2 = nXRight; 1512 if (nY2 > nYBottom) nY2 = nYBottom; 1513 1514 MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL); // erst nach den return's !!! 1515 1516 double nPPTX = pViewData->GetPPTX(); 1517 double nPPTY = pViewData->GetPPTY(); 1518 1519 ScInvertMerger aInvert( this ); 1520 1521 Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich ); 1522 long nScrY = aScrPos.Y(); 1523 sal_Bool bWasHidden = sal_False; 1524 for (SCROW nY=nY1; nY<=nY2; nY++) 1525 { 1526 sal_Bool bFirstRow = ( nY == nPosY ); // first visible row? 1527 sal_Bool bDoHidden = sal_False; // versteckte nachholen ? 1528 sal_uInt16 nHeightTwips = pDoc->GetRowHeight( nY,nTab ); 1529 sal_Bool bDoRow = ( nHeightTwips != 0 ); 1530 if (bDoRow) 1531 { 1532 if (bTestMerge) 1533 if (bWasHidden) // auf versteckte zusammengefasste testen 1534 { 1535 // --nY; // nY geaendert -> vorherige zeichnen 1536 bDoHidden = sal_True; 1537 bDoRow = sal_True; 1538 } 1539 1540 bWasHidden = sal_False; 1541 } 1542 else 1543 { 1544 bWasHidden = sal_True; 1545 if (bTestMerge) 1546 if (nY==nY2) 1547 bDoRow = sal_True; // letzte Zeile aus Block 1548 } 1549 1550 if ( bDoRow ) 1551 { 1552 SCCOL nLoopEndX = nX2; 1553 if (nX2 < nX1) // Rest von zusammengefasst 1554 { 1555 SCCOL nStartX = nX1; 1556 while ( ((const ScMergeFlagAttr*)pDoc-> 1557 GetAttr(nStartX,nY,nTab,ATTR_MERGE_FLAG))->IsHorOverlapped() ) 1558 --nStartX; 1559 if (nStartX <= nX2) 1560 nLoopEndX = nX1; 1561 } 1562 1563 long nEndY = nScrY + ScViewData::ToPixel( nHeightTwips, nPPTY ) - 1; 1564 long nScrX = aScrPos.X(); 1565 for (SCCOL nX=nX1; nX<=nLoopEndX; nX++) 1566 { 1567 long nWidth = ScViewData::ToPixel( pDoc->GetColWidth( nX,nTab ), nPPTX ); 1568 if ( nWidth > 0 ) 1569 { 1570 long nEndX = nScrX + ( nWidth - 1 ) * nLayoutSign; 1571 if (bTestMerge) 1572 { 1573 SCROW nThisY = nY; 1574 const ScPatternAttr* pPattern = pDoc->GetPattern( nX, nY, nTab ); 1575 const ScMergeFlagAttr* pMergeFlag = (const ScMergeFlagAttr*) &pPattern-> 1576 GetItem(ATTR_MERGE_FLAG); 1577 if ( pMergeFlag->IsVerOverlapped() && ( bDoHidden || bFirstRow ) ) 1578 { 1579 while ( pMergeFlag->IsVerOverlapped() && nThisY > 0 && 1580 (pDoc->RowHidden(nThisY-1, nTab) || bFirstRow) ) 1581 { 1582 --nThisY; 1583 pPattern = pDoc->GetPattern( nX, nThisY, nTab ); 1584 pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG); 1585 } 1586 } 1587 1588 // nur Rest von zusammengefasster zu sehen ? 1589 SCCOL nThisX = nX; 1590 if ( pMergeFlag->IsHorOverlapped() && nX == nPosX && nX > nRealX1 ) 1591 { 1592 while ( pMergeFlag->IsHorOverlapped() ) 1593 { 1594 --nThisX; 1595 pPattern = pDoc->GetPattern( nThisX, nThisY, nTab ); 1596 pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG); 1597 } 1598 } 1599 1600 if ( rMark.IsCellMarked( nThisX, nThisY, sal_True ) == bRepeat ) 1601 { 1602 if ( !pMergeFlag->IsOverlapped() ) 1603 { 1604 ScMergeAttr* pMerge = (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE); 1605 if (pMerge->GetColMerge() > 0 || pMerge->GetRowMerge() > 0) 1606 { 1607 Point aEndPos = pViewData->GetScrPos( 1608 nThisX + pMerge->GetColMerge(), 1609 nThisY + pMerge->GetRowMerge(), eWhich ); 1610 if ( aEndPos.X() * nLayoutSign > nScrX * nLayoutSign && aEndPos.Y() > nScrY ) 1611 { 1612 aInvert.AddRect( Rectangle( nScrX,nScrY, 1613 aEndPos.X()-nLayoutSign,aEndPos.Y()-1 ) ); 1614 } 1615 } 1616 else if ( nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY ) 1617 { 1618 aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) ); 1619 } 1620 } 1621 } 1622 } 1623 else // !bTestMerge 1624 { 1625 if ( rMark.IsCellMarked( nX, nY, sal_True ) == bRepeat && 1626 nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY ) 1627 { 1628 aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) ); 1629 } 1630 } 1631 1632 nScrX = nEndX + nLayoutSign; 1633 } 1634 } 1635 nScrY = nEndY + 1; 1636 } 1637 } 1638 1639 aInvert.Flush(); // before restoring MapMode 1640 1641 SetMapMode(aOld); 1642 1643 CheckInverted(); 1644 } 1645 1646 void ScGridWindow::GetSelectionRects( ::std::vector< Rectangle >& rPixelRects ) 1647 { 1648 // transformed from ScGridWindow::InvertSimple 1649 1650 // ScMarkData& rMark = pViewData->GetMarkData(); 1651 ScMarkData aMultiMark( pViewData->GetMarkData() ); 1652 aMultiMark.SetMarking( sal_False ); 1653 aMultiMark.MarkToMulti(); 1654 1655 ScDocument* pDoc = pViewData->GetDocument(); 1656 SCTAB nTab = pViewData->GetTabNo(); 1657 1658 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 1659 long nLayoutSign = bLayoutRTL ? -1 : 1; 1660 1661 if ( !aMultiMark.IsMultiMarked() ) 1662 return; 1663 1664 ScRange aMultiRange; 1665 aMultiMark.GetMultiMarkArea( aMultiRange ); 1666 SCCOL nX1 = aMultiRange.aStart.Col(); 1667 SCROW nY1 = aMultiRange.aStart.Row(); 1668 SCCOL nX2 = aMultiRange.aEnd.Col(); 1669 SCROW nY2 = aMultiRange.aEnd.Row(); 1670 1671 PutInOrder( nX1, nX2 ); 1672 PutInOrder( nY1, nY2 ); 1673 1674 sal_Bool bTestMerge = sal_True; 1675 sal_Bool bRepeat = sal_True; 1676 1677 SCCOL nTestX2 = nX2; 1678 SCROW nTestY2 = nY2; 1679 if (bTestMerge) 1680 pDoc->ExtendMerge( nX1,nY1, nTestX2,nTestY2, nTab ); 1681 1682 SCCOL nPosX = pViewData->GetPosX( eHWhich ); 1683 SCROW nPosY = pViewData->GetPosY( eVWhich ); 1684 if (nTestX2 < nPosX || nTestY2 < nPosY) 1685 return; // unsichtbar 1686 SCCOL nRealX1 = nX1; 1687 if (nX1 < nPosX) 1688 nX1 = nPosX; 1689 if (nY1 < nPosY) 1690 nY1 = nPosY; 1691 1692 SCCOL nXRight = nPosX + pViewData->VisibleCellsX(eHWhich); 1693 if (nXRight > MAXCOL) nXRight = MAXCOL; 1694 SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich); 1695 if (nYBottom > MAXROW) nYBottom = MAXROW; 1696 1697 if (nX1 > nXRight || nY1 > nYBottom) 1698 return; // unsichtbar 1699 if (nX2 > nXRight) nX2 = nXRight; 1700 if (nY2 > nYBottom) nY2 = nYBottom; 1701 1702 // MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL); // erst nach den return's !!! 1703 1704 double nPPTX = pViewData->GetPPTX(); 1705 double nPPTY = pViewData->GetPPTY(); 1706 1707 ScInvertMerger aInvert( &rPixelRects ); 1708 1709 Point aScrPos = pViewData->GetScrPos( nX1, nY1, eWhich ); 1710 long nScrY = aScrPos.Y(); 1711 sal_Bool bWasHidden = sal_False; 1712 for (SCROW nY=nY1; nY<=nY2; nY++) 1713 { 1714 sal_Bool bFirstRow = ( nY == nPosY ); // first visible row? 1715 sal_Bool bDoHidden = sal_False; // versteckte nachholen ? 1716 sal_uInt16 nHeightTwips = pDoc->GetRowHeight( nY,nTab ); 1717 sal_Bool bDoRow = ( nHeightTwips != 0 ); 1718 if (bDoRow) 1719 { 1720 if (bTestMerge) 1721 if (bWasHidden) // auf versteckte zusammengefasste testen 1722 { 1723 bDoHidden = sal_True; 1724 bDoRow = sal_True; 1725 } 1726 1727 bWasHidden = sal_False; 1728 } 1729 else 1730 { 1731 bWasHidden = sal_True; 1732 if (bTestMerge) 1733 if (nY==nY2) 1734 bDoRow = sal_True; // letzte Zeile aus Block 1735 } 1736 1737 if ( bDoRow ) 1738 { 1739 SCCOL nLoopEndX = nX2; 1740 if (nX2 < nX1) // Rest von zusammengefasst 1741 { 1742 SCCOL nStartX = nX1; 1743 while ( ((const ScMergeFlagAttr*)pDoc-> 1744 GetAttr(nStartX,nY,nTab,ATTR_MERGE_FLAG))->IsHorOverlapped() ) 1745 --nStartX; 1746 if (nStartX <= nX2) 1747 nLoopEndX = nX1; 1748 } 1749 1750 long nEndY = nScrY + ScViewData::ToPixel( nHeightTwips, nPPTY ) - 1; 1751 long nScrX = aScrPos.X(); 1752 for (SCCOL nX=nX1; nX<=nLoopEndX; nX++) 1753 { 1754 long nWidth = ScViewData::ToPixel( pDoc->GetColWidth( nX,nTab ), nPPTX ); 1755 if ( nWidth > 0 ) 1756 { 1757 long nEndX = nScrX + ( nWidth - 1 ) * nLayoutSign; 1758 if (bTestMerge) 1759 { 1760 SCROW nThisY = nY; 1761 const ScPatternAttr* pPattern = pDoc->GetPattern( nX, nY, nTab ); 1762 const ScMergeFlagAttr* pMergeFlag = (const ScMergeFlagAttr*) &pPattern-> 1763 GetItem(ATTR_MERGE_FLAG); 1764 if ( pMergeFlag->IsVerOverlapped() && ( bDoHidden || bFirstRow ) ) 1765 { 1766 while ( pMergeFlag->IsVerOverlapped() && nThisY > 0 && 1767 (pDoc->RowHidden(nThisY-1, nTab) || bFirstRow) ) 1768 { 1769 --nThisY; 1770 pPattern = pDoc->GetPattern( nX, nThisY, nTab ); 1771 pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG); 1772 } 1773 } 1774 1775 // nur Rest von zusammengefasster zu sehen ? 1776 SCCOL nThisX = nX; 1777 if ( pMergeFlag->IsHorOverlapped() && nX == nPosX && nX > nRealX1 ) 1778 { 1779 while ( pMergeFlag->IsHorOverlapped() ) 1780 { 1781 --nThisX; 1782 pPattern = pDoc->GetPattern( nThisX, nThisY, nTab ); 1783 pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG); 1784 } 1785 } 1786 1787 if ( aMultiMark.IsCellMarked( nThisX, nThisY, sal_True ) == bRepeat ) 1788 { 1789 if ( !pMergeFlag->IsOverlapped() ) 1790 { 1791 ScMergeAttr* pMerge = (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE); 1792 if (pMerge->GetColMerge() > 0 || pMerge->GetRowMerge() > 0) 1793 { 1794 Point aEndPos = pViewData->GetScrPos( 1795 nThisX + pMerge->GetColMerge(), 1796 nThisY + pMerge->GetRowMerge(), eWhich ); 1797 if ( aEndPos.X() * nLayoutSign > nScrX * nLayoutSign && aEndPos.Y() > nScrY ) 1798 { 1799 aInvert.AddRect( Rectangle( nScrX,nScrY, 1800 aEndPos.X()-nLayoutSign,aEndPos.Y()-1 ) ); 1801 } 1802 } 1803 else if ( nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY ) 1804 { 1805 aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) ); 1806 } 1807 } 1808 } 1809 } 1810 else // !bTestMerge 1811 { 1812 if ( aMultiMark.IsCellMarked( nX, nY, sal_True ) == bRepeat && 1813 nEndX * nLayoutSign >= nScrX * nLayoutSign && nEndY >= nScrY ) 1814 { 1815 aInvert.AddRect( Rectangle( nScrX,nScrY,nEndX,nEndY ) ); 1816 } 1817 } 1818 1819 nScrX = nEndX + nLayoutSign; 1820 } 1821 } 1822 nScrY = nEndY + 1; 1823 } 1824 } 1825 1826 // aInvert.Flush(); // before restoring MapMode 1827 } 1828 1829 // ------------------------------------------------------------------------- 1830 1831 //UNUSED2008-05 void ScGridWindow::DrawDragRect( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2 ) 1832 //UNUSED2008-05 { 1833 //UNUSED2008-05 if ( nX2 < pViewData->GetPosX(eHWhich) || nY2 < pViewData->GetPosY(eVWhich) ) 1834 //UNUSED2008-05 return; 1835 //UNUSED2008-05 1836 //UNUSED2008-05 Update(); // wegen XOR 1837 //UNUSED2008-05 1838 //UNUSED2008-05 MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL); 1839 //UNUSED2008-05 1840 //UNUSED2008-05 SCTAB nTab = pViewData->GetTabNo(); 1841 //UNUSED2008-05 1842 //UNUSED2008-05 SCCOL nPosX = pViewData->GetPosX(WhichH(eWhich)); 1843 //UNUSED2008-05 SCROW nPosY = pViewData->GetPosY(WhichV(eWhich)); 1844 //UNUSED2008-05 if (nX1 < nPosX) nX1 = nPosX; 1845 //UNUSED2008-05 if (nX2 < nPosX) nX2 = nPosX; 1846 //UNUSED2008-05 if (nY1 < nPosY) nY1 = nPosY; 1847 //UNUSED2008-05 if (nY2 < nPosY) nY2 = nPosY; 1848 //UNUSED2008-05 1849 //UNUSED2008-05 Point aScrPos( pViewData->GetScrPos( nX1, nY1, eWhich ) ); 1850 //UNUSED2008-05 1851 //UNUSED2008-05 long nSizeXPix=0; 1852 //UNUSED2008-05 long nSizeYPix=0; 1853 //UNUSED2008-05 ScDocument* pDoc = pViewData->GetDocument(); 1854 //UNUSED2008-05 double nPPTX = pViewData->GetPPTX(); 1855 //UNUSED2008-05 double nPPTY = pViewData->GetPPTY(); 1856 //UNUSED2008-05 SCCOLROW i; 1857 //UNUSED2008-05 1858 //UNUSED2008-05 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 1859 //UNUSED2008-05 long nLayoutSign = bLayoutRTL ? -1 : 1; 1860 //UNUSED2008-05 1861 //UNUSED2008-05 if (ValidCol(nX2) && nX2>=nX1) 1862 //UNUSED2008-05 for (i=nX1; i<=nX2; i++) 1863 //UNUSED2008-05 nSizeXPix += ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(i), nTab ), nPPTX ); 1864 //UNUSED2008-05 else 1865 //UNUSED2008-05 { 1866 //UNUSED2008-05 aScrPos.X() -= nLayoutSign; 1867 //UNUSED2008-05 nSizeXPix += 2; 1868 //UNUSED2008-05 } 1869 //UNUSED2008-05 1870 //UNUSED2008-05 if (ValidRow(nY2) && nY2>=nY1) 1871 //UNUSED2008-05 for (i=nY1; i<=nY2; i++) 1872 //UNUSED2008-05 nSizeYPix += ScViewData::ToPixel( pDoc->GetRowHeight( i, nTab ), nPPTY ); 1873 //UNUSED2008-05 else 1874 //UNUSED2008-05 { 1875 //UNUSED2008-05 aScrPos.Y() -= 1; 1876 //UNUSED2008-05 nSizeYPix += 2; 1877 //UNUSED2008-05 } 1878 //UNUSED2008-05 1879 //UNUSED2008-05 aScrPos.X() -= 2 * nLayoutSign; 1880 //UNUSED2008-05 aScrPos.Y() -= 2; 1881 //UNUSED2008-05 // Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) ); 1882 //UNUSED2008-05 Rectangle aRect( aScrPos.X(), aScrPos.Y(), 1883 //UNUSED2008-05 aScrPos.X() + ( nSizeXPix + 2 ) * nLayoutSign, aScrPos.Y() + nSizeYPix + 2 ); 1884 //UNUSED2008-05 if ( bLayoutRTL ) 1885 //UNUSED2008-05 { 1886 //UNUSED2008-05 aRect.Left() = aRect.Right(); // end position is left 1887 //UNUSED2008-05 aRect.Right() = aScrPos.X(); 1888 //UNUSED2008-05 } 1889 //UNUSED2008-05 1890 //UNUSED2008-05 Invert(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() )); 1891 //UNUSED2008-05 Invert(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() )); 1892 //UNUSED2008-05 Invert(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 )); 1893 //UNUSED2008-05 Invert(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() )); 1894 //UNUSED2008-05 1895 //UNUSED2008-05 SetMapMode(aOld); 1896 //UNUSED2008-05 } 1897 1898 // ------------------------------------------------------------------------- 1899 1900 void ScGridWindow::DrawCursor() 1901 { 1902 // #114409# 1903 // SCTAB nTab = pViewData->GetTabNo(); 1904 // SCCOL nX = pViewData->GetCurX(); 1905 // SCROW nY = pViewData->GetCurY(); 1906 // 1907 // // in verdeckten Zellen nicht zeichnen 1908 // 1909 // ScDocument* pDoc = pViewData->GetDocument(); 1910 // const ScPatternAttr* pPattern = pDoc->GetPattern(nX,nY,nTab); 1911 // const ScMergeFlagAttr& rMerge = (const ScMergeFlagAttr&) pPattern->GetItem(ATTR_MERGE_FLAG); 1912 // if (rMerge.IsOverlapped()) 1913 // return; 1914 // 1915 // // links/oben ausserhalb des Bildschirms ? 1916 // 1917 // sal_Bool bVis = ( nX>=pViewData->GetPosX(eHWhich) && nY>=pViewData->GetPosY(eVWhich) ); 1918 // if (!bVis) 1919 // { 1920 // SCCOL nEndX = nX; 1921 // SCROW nEndY = nY; 1922 // ScDocument* pDoc = pViewData->GetDocument(); 1923 // const ScMergeAttr& rMerge = (const ScMergeAttr&) pPattern->GetItem(ATTR_MERGE); 1924 // if (rMerge.GetColMerge() > 1) 1925 // nEndX += rMerge.GetColMerge()-1; 1926 // if (rMerge.GetRowMerge() > 1) 1927 // nEndY += rMerge.GetRowMerge()-1; 1928 // bVis = ( nEndX>=pViewData->GetPosX(eHWhich) && nEndY>=pViewData->GetPosY(eVWhich) ); 1929 // } 1930 // 1931 // if ( bVis ) 1932 // { 1933 // // hier kein Update, da aus Paint gerufen und laut Zaehler Cursor schon da 1934 // // wenn Update noetig, dann bei Hide/Showcursor vor dem Hoch-/Runterzaehlen 1935 // 1936 // MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL); 1937 // 1938 // Point aScrPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True ); 1939 // sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 1940 // 1941 // // completely right of/below the screen? 1942 // // (test with logical start position in aScrPos) 1943 // sal_Bool bMaybeVisible; 1944 // if ( bLayoutRTL ) 1945 // bMaybeVisible = ( aScrPos.X() >= -2 && aScrPos.Y() >= -2 ); 1946 // else 1947 // { 1948 // Size aOutSize = GetOutputSizePixel(); 1949 // bMaybeVisible = ( aScrPos.X() <= aOutSize.Width() + 2 && aScrPos.Y() <= aOutSize.Height() + 2 ); 1950 // } 1951 // if ( bMaybeVisible ) 1952 // { 1953 // long nSizeXPix; 1954 // long nSizeYPix; 1955 // pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix ); 1956 // 1957 // if ( bLayoutRTL ) 1958 // aScrPos.X() -= nSizeXPix - 2; // move instead of mirroring 1959 // 1960 // sal_Bool bFix = ( pViewData->GetHSplitMode() == SC_SPLIT_FIX || 1961 // pViewData->GetVSplitMode() == SC_SPLIT_FIX ); 1962 // if ( pViewData->GetActivePart()==eWhich || bFix ) 1963 // { 1964 // // old UNX version with two Invert calls causes flicker. 1965 // // if optimization is needed, a new flag should be added 1966 // // to InvertTracking 1967 // 1968 // aScrPos.X() -= 2; 1969 // aScrPos.Y() -= 2; 1970 // Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) ); 1971 // 1972 // Invert(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() )); 1973 // Invert(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() )); 1974 // Invert(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 )); 1975 // Invert(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() )); 1976 // } 1977 // else 1978 // { 1979 // Rectangle aRect( aScrPos, Size( nSizeXPix - 1, nSizeYPix - 1 ) ); 1980 // Invert( aRect ); 1981 // } 1982 // } 1983 // 1984 // SetMapMode(aOld); 1985 // } 1986 } 1987 1988 // AutoFill-Anfasser: 1989 1990 void ScGridWindow::DrawAutoFillMark() 1991 { 1992 // #114409# 1993 // if ( bAutoMarkVisible && aAutoMarkPos.Tab() == pViewData->GetTabNo() ) 1994 // { 1995 // SCCOL nX = aAutoMarkPos.Col(); 1996 // SCROW nY = aAutoMarkPos.Row(); 1997 // SCTAB nTab = pViewData->GetTabNo(); 1998 // ScDocument* pDoc = pViewData->GetDocument(); 1999 // sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab ); 2000 // 2001 // Point aFillPos = pViewData->GetScrPos( nX, nY, eWhich, sal_True ); 2002 // long nSizeXPix; 2003 // long nSizeYPix; 2004 // pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix ); 2005 // if ( bLayoutRTL ) 2006 // aFillPos.X() -= nSizeXPix + 3; 2007 // else 2008 // aFillPos.X() += nSizeXPix - 2; 2009 // 2010 // aFillPos.Y() += nSizeYPix; 2011 // aFillPos.Y() -= 2; 2012 // Rectangle aFillRect( aFillPos, Size(6,6) ); 2013 // // Anfasser von Zeichenobjekten sind 7*7 2014 // 2015 // MapMode aOld = GetMapMode(); SetMapMode(MAP_PIXEL); 2016 // Invert( aFillRect ); 2017 // SetMapMode(aOld); 2018 // } 2019 } 2020 2021 // ------------------------------------------------------------------------- 2022 2023 void ScGridWindow::DataChanged( const DataChangedEvent& rDCEvt ) 2024 { 2025 Window::DataChanged(rDCEvt); 2026 2027 if ( (rDCEvt.GetType() == DATACHANGED_PRINTER) || 2028 (rDCEvt.GetType() == DATACHANGED_DISPLAY) || 2029 (rDCEvt.GetType() == DATACHANGED_FONTS) || 2030 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) || 2031 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) && 2032 (rDCEvt.GetFlags() & SETTINGS_STYLE)) ) 2033 { 2034 if ( rDCEvt.GetType() == DATACHANGED_FONTS && eWhich == pViewData->GetActivePart() ) 2035 pViewData->GetDocShell()->UpdateFontList(); 2036 2037 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && 2038 (rDCEvt.GetFlags() & SETTINGS_STYLE) ) 2039 { 2040 if ( eWhich == pViewData->GetActivePart() ) // only once for the view 2041 { 2042 ScTabView* pView = pViewData->GetView(); 2043 2044 // update scale in case the UI ScreenZoom has changed 2045 ScGlobal::UpdatePPT(this); 2046 pView->RecalcPPT(); 2047 2048 // RepeatResize in case scroll bar sizes have changed 2049 pView->RepeatResize(); 2050 pView->UpdateAllOverlays(); 2051 2052 // invalidate cell attribs in input handler, in case the 2053 // EditEngine BackgroundColor has to be changed 2054 if ( pViewData->IsActive() ) 2055 { 2056 ScInputHandler* pHdl = SC_MOD()->GetInputHdl(); 2057 if (pHdl) 2058 pHdl->ForgetLastPattern(); 2059 } 2060 } 2061 } 2062 2063 Invalidate(); 2064 } 2065 } 2066 2067 2068 2069 2070