/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" // INCLUDE --------------------------------------------------------------- #include "scitems.hxx" #include #include #include #include #include #include #include #include "attrib.hxx" #include "pagedata.hxx" #include "tabview.hxx" #include "tabvwsh.hxx" #include "printfun.hxx" #include "stlpool.hxx" #include "docsh.hxx" #include "gridwin.hxx" #include "olinewin.hxx" #include "uiitems.hxx" #include "sc.hrc" #include "viewutil.hxx" #include "colrowba.hxx" #include "waitoff.hxx" #include "globstr.hrc" #include "scmod.hxx" #define SC_BLOCKMODE_NONE 0 #define SC_BLOCKMODE_NORMAL 1 #define SC_BLOCKMODE_OWN 2 // // Markier - Funktionen // void ScTabView::PaintMarks(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ) { if (!ValidCol(nStartCol)) nStartCol = MAXCOL; if (!ValidRow(nStartRow)) nStartRow = MAXROW; if (!ValidCol(nEndCol)) nEndCol = MAXCOL; if (!ValidRow(nEndRow)) nEndRow = MAXROW; sal_Bool bLeft = (nStartCol==0 && nEndCol==MAXCOL); sal_Bool bTop = (nStartRow==0 && nEndRow==MAXROW); if (bLeft) PaintLeftArea( nStartRow, nEndRow ); if (bTop) PaintTopArea( nStartCol, nEndCol ); aViewData.GetDocument()->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, aViewData.GetTabNo() ); PaintArea( nStartCol, nStartRow, nEndCol, nEndRow, SC_UPDATE_MARKS ); } sal_Bool ScTabView::IsMarking( SCCOL nCol, SCROW nRow, SCTAB nTab ) const { return bIsBlockMode && nBlockStartX == nCol && nBlockStartY == nRow && nBlockStartZ == nTab; } void ScTabView::InitOwnBlockMode() { if (!bIsBlockMode) { // Wenn keine (alte) Markierung mehr da ist, Anker in SelectionEngine loeschen: ScMarkData& rMark = aViewData.GetMarkData(); if (!rMark.IsMarked() && !rMark.IsMultiMarked()) GetSelEngine()->CursorPosChanging( sal_False, sal_False ); // bIsBlockMode = sal_True; bIsBlockMode = SC_BLOCKMODE_OWN; //! Variable umbenennen! nBlockStartX = 0; nBlockStartY = 0; nBlockStartZ = 0; nBlockEndX = 0; nBlockEndY = 0; nBlockEndZ = 0; SelectionChanged(); // Status wird mit gesetzer Markierung abgefragt } } void ScTabView::InitBlockMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ, sal_Bool bTestNeg, sal_Bool bCols, sal_Bool bRows ) { if (!bIsBlockMode) { if (!ValidCol(nCurX)) nCurX = MAXCOL; if (!ValidRow(nCurY)) nCurY = MAXROW; ScMarkData& rMark = aViewData.GetMarkData(); SCTAB nTab = aViewData.GetTabNo(); // Teil von Markierung aufheben? if (bTestNeg) { if ( bCols ) bBlockNeg = rMark.IsColumnMarked( nCurX ); else if ( bRows ) bBlockNeg = rMark.IsRowMarked( nCurY ); else bBlockNeg = rMark.IsCellMarked( nCurX, nCurY ); } else bBlockNeg = sal_False; rMark.SetMarkNegative(bBlockNeg); // bIsBlockMode = sal_True; bIsBlockMode = SC_BLOCKMODE_NORMAL; //! Variable umbenennen! bBlockCols = bCols; bBlockRows = bRows; nBlockStartX = nBlockStartXOrig = nCurX; nBlockStartY = nBlockStartYOrig = nCurY; nBlockStartZ = nCurZ; nBlockEndX = nOldCurX = nBlockStartX; nBlockEndY = nOldCurY = nBlockStartY; nBlockEndZ = nBlockStartZ; if (bBlockCols) { nBlockStartY = nBlockStartYOrig = 0; nBlockEndY = MAXROW; } if (bBlockRows) { nBlockStartX = nBlockStartXOrig = 0; nBlockEndX = MAXCOL; } rMark.SetMarkArea( ScRange( nBlockStartX,nBlockStartY, nTab, nBlockEndX,nBlockEndY, nTab ) ); #ifdef OLD_SELECTION_PAINT InvertBlockMark( nBlockStartX,nBlockStartY,nBlockEndX,nBlockEndY ); #endif UpdateSelectionOverlay(); bNewStartIfMarking = sal_False; // use only once } } void ScTabView::SetNewStartIfMarking() { bNewStartIfMarking = sal_True; } void ScTabView::DoneBlockMode( sal_Bool bContinue ) // Default FALSE { // Wenn zwischen Tabellen- und Header SelectionEngine gewechselt wird, // wird evtl. DeselectAll gerufen, weil die andere Engine keinen Anker hat. // Mit bMoveIsShift wird verhindert, dass dann die Selektion aufgehoben wird. if (bIsBlockMode && !bMoveIsShift) { ScMarkData& rMark = aViewData.GetMarkData(); sal_Bool bFlag = rMark.GetMarkingFlag(); rMark.SetMarking(sal_False); if (bBlockNeg && !bContinue) rMark.MarkToMulti(); if (bContinue) rMark.MarkToMulti(); else { // Die Tabelle kann an dieser Stelle ungueltig sein, weil DoneBlockMode // aus SetTabNo aufgerufen wird // (z.B. wenn die aktuelle Tabelle von einer anderen View aus geloescht wird) SCTAB nTab = aViewData.GetTabNo(); ScDocument* pDoc = aViewData.GetDocument(); if ( pDoc->HasTable(nTab) ) PaintBlock( sal_True ); // sal_True -> Block loeschen else rMark.ResetMark(); } // bIsBlockMode = sal_False; bIsBlockMode = SC_BLOCKMODE_NONE; //! Variable umbenennen! rMark.SetMarking(bFlag); rMark.SetMarkNegative(sal_False); } } void ScTabView::MarkCursor( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ, sal_Bool bCols, sal_Bool bRows, sal_Bool bCellSelection ) { if (!ValidCol(nCurX)) nCurX = MAXCOL; if (!ValidRow(nCurY)) nCurY = MAXROW; if (!bIsBlockMode) { DBG_ERROR( "MarkCursor nicht im BlockMode" ); InitBlockMode( nCurX, nCurY, nCurZ, sal_False, bCols, bRows ); } if (bCols) nCurY = MAXROW; if (bRows) nCurX = MAXCOL; ScMarkData& rMark = aViewData.GetMarkData(); DBG_ASSERT(rMark.IsMarked() || rMark.IsMultiMarked(), "MarkCursor, !IsMarked()"); ScRange aMarkRange; rMark.GetMarkArea(aMarkRange); if (( aMarkRange.aStart.Col() != nBlockStartX && aMarkRange.aEnd.Col() != nBlockStartX ) || ( aMarkRange.aStart.Row() != nBlockStartY && aMarkRange.aEnd.Row() != nBlockStartY ) || ( bIsBlockMode == SC_BLOCKMODE_OWN )) { // Markierung ist veraendert worden // (z.B. MarkToSimple, wenn per negativ alles bis auf ein Rechteck geloescht wurde) // oder nach InitOwnBlockMode wird mit Shift-Klick weitermarkiert... sal_Bool bOldShift = bMoveIsShift; bMoveIsShift = sal_False; // wirklich umsetzen DoneBlockMode(sal_False); //! direkt Variablen setzen? (-> kein Geflacker) bMoveIsShift = bOldShift; InitBlockMode( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nBlockStartZ, rMark.IsMarkNegative(), bCols, bRows ); } SCCOL nOldBlockEndX = nBlockEndX; SCROW nOldBlockEndY = nBlockEndY; if ( nCurX != nOldCurX || nCurY != nOldCurY ) { // Current cursor has moved SCTAB nTab = nCurZ; #ifdef OLD_SELECTION_PAINT SCCOL nDrawStartCol; SCROW nDrawStartRow; SCCOL nDrawEndCol; SCROW nDrawEndRow; #endif // Set old selection area ScUpdateRect aRect( nBlockStartX, nBlockStartY, nOldBlockEndX, nOldBlockEndY ); if ( bCellSelection ) { // Expand selection area accordingly when the current selection ends // with a merged cell. SCsCOL nCurXOffset = 0; SCsCOL nBlockStartXOffset = 0; SCsROW nCurYOffset = 0; SCsROW nBlockStartYOffset = 0; sal_Bool bBlockStartMerged = sal_False; const ScMergeAttr* pMergeAttr = NULL; ScDocument* pDocument = aViewData.GetDocument(); // The following block checks whether or not the "BlockStart" (anchor) // cell is merged. If it's merged, it'll then move the position of the // anchor cell to the corner that's diagonally opposite of the // direction of a current selection area. For instance, if a current // selection is moving in the upperleft direction, the anchor cell will // move to the lower-right corner of the merged anchor cell, and so on. pMergeAttr = static_cast( pDocument->GetAttr( nBlockStartXOrig, nBlockStartYOrig, nTab, ATTR_MERGE ) ); if ( pMergeAttr->IsMerged() ) { SCsCOL nColSpan = pMergeAttr->GetColMerge(); SCsROW nRowSpan = pMergeAttr->GetRowMerge(); if ( !( nCurX >= nBlockStartXOrig + nColSpan - 1 && nCurY >= nBlockStartYOrig + nRowSpan - 1 ) ) { nBlockStartX = nCurX >= nBlockStartXOrig ? nBlockStartXOrig : nBlockStartXOrig + nColSpan - 1; nBlockStartY = nCurY >= nBlockStartYOrig ? nBlockStartYOrig : nBlockStartYOrig + nRowSpan - 1; nCurXOffset = nCurX >= nBlockStartXOrig && nCurX < nBlockStartXOrig + nColSpan - 1 ? nBlockStartXOrig - nCurX + nColSpan - 1 : 0; nCurYOffset = nCurY >= nBlockStartYOrig && nCurY < nBlockStartYOrig + nRowSpan - 1 ? nBlockStartYOrig - nCurY + nRowSpan - 1 : 0; bBlockStartMerged = sal_True; } } // The following block checks whether or not the current cell is // merged. If it is, it'll then set the appropriate X & Y offset // values (nCurXOffset & nCurYOffset) such that the selection area will // grow by those specified offset amounts. Note that the values of // nCurXOffset/nCurYOffset may also be specified in the previous code // block, in which case whichever value is greater will take on. pMergeAttr = static_cast( pDocument->GetAttr( nCurX, nCurY, nTab, ATTR_MERGE ) ); if ( pMergeAttr->IsMerged() ) { SCsCOL nColSpan = pMergeAttr->GetColMerge(); SCsROW nRowSpan = pMergeAttr->GetRowMerge(); if ( !( nBlockStartX >= nCurX + nColSpan - 1 && nBlockStartY >= nCurY + nRowSpan - 1 ) ) { if ( nBlockStartX <= nCurX + nColSpan - 1 ) { SCsCOL nCurXOffsetTemp = nCurX < nCurX + nColSpan - 1 ? nColSpan - 1 : 0; nCurXOffset = nCurXOffset > nCurXOffsetTemp ? nCurXOffset : nCurXOffsetTemp; } if ( nBlockStartY <= nCurY + nRowSpan - 1 ) { SCsROW nCurYOffsetTemp = nCurY < nCurY + nRowSpan - 1 ? nRowSpan - 1 : 0; nCurYOffset = nCurYOffset > nCurYOffsetTemp ? nCurYOffset : nCurYOffsetTemp; } if ( !( nBlockStartX <= nCurX && nBlockStartY <= nCurY ) && !( nBlockStartX > nCurX + nColSpan - 1 && nBlockStartY > nCurY + nRowSpan - 1 ) ) { nBlockStartXOffset = nBlockStartX > nCurX && nBlockStartX <= nCurX + nColSpan - 1 ? nCurX - nBlockStartX : 0; nBlockStartYOffset = nBlockStartY > nCurY && nBlockStartY <= nCurY + nRowSpan - 1 ? nCurY - nBlockStartY : 0; } } } else { // The current cell is not merged. Move the anchor cell to its // original position. if ( !bBlockStartMerged ) { nBlockStartX = nBlockStartXOrig; nBlockStartY = nBlockStartYOrig; } } nBlockStartX = nBlockStartX + nBlockStartXOffset >= 0 ? nBlockStartX + nBlockStartXOffset : 0; nBlockStartY = nBlockStartY + nBlockStartYOffset >= 0 ? nBlockStartY + nBlockStartYOffset : 0; nBlockEndX = nCurX + nCurXOffset > MAXCOL ? MAXCOL : nCurX + nCurXOffset; nBlockEndY = nCurY + nCurYOffset > MAXROW ? MAXROW : nCurY + nCurYOffset; } else { nBlockEndX = nCurX; nBlockEndY = nCurY; } // end of "if ( bCellSelection )" // Set new selection area aRect.SetNew( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY ); rMark.SetMarkArea( ScRange( nBlockStartX, nBlockStartY, nTab, nBlockEndX, nBlockEndY, nTab ) ); #ifdef OLD_SELECTION_PAINT sal_Bool bCont; sal_Bool bDraw = aRect.GetXorDiff( nDrawStartCol, nDrawStartRow, nDrawEndCol, nDrawEndRow, bCont ); if ( bDraw ) { //? PutInOrder( nDrawStartCol, nDrawEndCol ); //? PutInOrder( nDrawStartRow, nDrawEndRow ); HideAllCursors(); InvertBlockMark( nDrawStartCol, nDrawStartRow, nDrawEndCol, nDrawEndRow ); if (bCont) { aRect.GetContDiff( nDrawStartCol, nDrawStartRow, nDrawEndCol, nDrawEndRow ); InvertBlockMark( nDrawStartCol, nDrawStartRow, nDrawEndCol, nDrawEndRow ); } ShowAllCursors(); } #endif UpdateSelectionOverlay(); nOldCurX = nCurX; nOldCurY = nCurY; aViewData.GetViewShell()->UpdateInputHandler(); // InvalidateAttribs(); } if ( !bCols && !bRows ) aHdrFunc.SetAnchorFlag( sal_False ); } void ScTabView::UpdateSelectionOverlay() { for (sal_uInt16 i=0; i<4; i++) if ( pGridWin[i] && pGridWin[i]->IsVisible() ) pGridWin[i]->UpdateSelectionOverlay(); } void ScTabView::UpdateShrinkOverlay() { for (sal_uInt16 i=0; i<4; i++) if ( pGridWin[i] && pGridWin[i]->IsVisible() ) pGridWin[i]->UpdateShrinkOverlay(); } void ScTabView::UpdateAllOverlays() { for (sal_uInt16 i=0; i<4; i++) if ( pGridWin[i] && pGridWin[i]->IsVisible() ) pGridWin[i]->UpdateAllOverlays(); } //! //! PaintBlock in zwei Methoden aufteilen: RepaintBlock und RemoveBlock o.ae. //! void ScTabView::PaintBlock( sal_Bool bReset ) { ScDocument* pDoc = aViewData.GetDocument(); ScMarkData& rMark = aViewData.GetMarkData(); SCTAB nTab = aViewData.GetTabNo(); sal_Bool bMark = rMark.IsMarked(); sal_Bool bMulti = rMark.IsMultiMarked(); if (bMark || bMulti) { ScRange aMarkRange; HideAllCursors(); if (bMulti) { sal_Bool bFlag = rMark.GetMarkingFlag(); rMark.SetMarking(sal_False); rMark.MarkToMulti(); rMark.GetMultiMarkArea(aMarkRange); rMark.MarkToSimple(); rMark.SetMarking(bFlag); bMark = rMark.IsMarked(); bMulti = rMark.IsMultiMarked(); } else rMark.GetMarkArea(aMarkRange); nBlockStartX = aMarkRange.aStart.Col(); nBlockStartY = aMarkRange.aStart.Row(); nBlockStartZ = aMarkRange.aStart.Tab(); nBlockEndX = aMarkRange.aEnd.Col(); nBlockEndY = aMarkRange.aEnd.Row(); nBlockEndZ = aMarkRange.aEnd.Tab(); sal_Bool bDidReset = sal_False; if ( nTab>=nBlockStartZ && nTab<=nBlockEndZ ) { if ( bReset ) { // Invertieren beim Loeschen nur auf aktiver View if ( aViewData.IsActive() ) { sal_uInt16 i; if ( bMulti ) { #ifdef OLD_SELECTION_PAINT for (i=0; i<4; i++) if (pGridWin[i] && pGridWin[i]->IsVisible()) pGridWin[i]->InvertSimple( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY, sal_True, sal_True ); #endif rMark.ResetMark(); UpdateSelectionOverlay(); bDidReset = sal_True; } else { #ifdef OLD_SELECTION_PAINT // (mis)use InvertBlockMark to remove all of the selection // -> set bBlockNeg (like when removing parts of a selection) // and convert everything to Multi rMark.MarkToMulti(); sal_Bool bOld = bBlockNeg; bBlockNeg = sal_True; // #73130# (negative) MarkArea must be set in case of repaint rMark.SetMarkArea( ScRange( nBlockStartX,nBlockStartY, nTab, nBlockEndX,nBlockEndY, nTab ) ); InvertBlockMark( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY ); bBlockNeg = bOld; #endif rMark.ResetMark(); UpdateSelectionOverlay(); bDidReset = sal_True; } // repaint if controls are touched (#69680# in both cases) // #i74768# Forms are rendered by DrawingLayer's EndDrawLayers() static bool bSuppressControlExtraStuff(true); if(!bSuppressControlExtraStuff) { Rectangle aMMRect = pDoc->GetMMRect(nBlockStartX,nBlockStartY,nBlockEndX,nBlockEndY, nTab); if (pDoc->HasControl( nTab, aMMRect )) { for (i=0; i<4; i++) { if (pGridWin[i] && pGridWin[i]->IsVisible()) { // MapMode muss logischer (1/100mm) sein !!! pDoc->InvalidateControls( pGridWin[i], nTab, aMMRect ); pGridWin[i]->Update(); } } } } } } else PaintMarks( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY ); } if ( bReset && !bDidReset ) rMark.ResetMark(); ShowAllCursors(); } } void ScTabView::SelectAll( sal_Bool bContinue ) { ScMarkData& rMark = aViewData.GetMarkData(); SCTAB nTab = aViewData.GetTabNo(); if (rMark.IsMarked()) { ScRange aMarkRange; rMark.GetMarkArea( aMarkRange ); if ( aMarkRange == ScRange( 0,0,nTab, MAXCOL,MAXROW,nTab ) ) return; } DoneBlockMode( bContinue ); InitBlockMode( 0,0,nTab ); MarkCursor( MAXCOL,MAXROW,nTab ); SelectionChanged(); } void ScTabView::SelectAllTables() { ScDocument* pDoc = aViewData.GetDocument(); ScMarkData& rMark = aViewData.GetMarkData(); // SCTAB nTab = aViewData.GetTabNo(); SCTAB nCount = pDoc->GetTableCount(); if (nCount>1) { for (SCTAB i=0; iExtendMarksFromTable( nTab ); aViewData.GetDocShell()->PostPaintExtras(); SfxBindings& rBind = aViewData.GetBindings(); rBind.Invalidate( FID_FILL_TAB ); rBind.Invalidate( FID_TAB_DESELECTALL ); } } void ScTabView::DeselectAllTables() { ScDocument* pDoc = aViewData.GetDocument(); ScMarkData& rMark = aViewData.GetMarkData(); SCTAB nTab = aViewData.GetTabNo(); SCTAB nCount = pDoc->GetTableCount(); for (SCTAB i=0; iPostPaintExtras(); SfxBindings& rBind = aViewData.GetBindings(); rBind.Invalidate( FID_FILL_TAB ); rBind.Invalidate( FID_TAB_DESELECTALL ); } sal_Bool lcl_FitsInWindow( double fScaleX, double fScaleY, sal_uInt16 nZoom, long nWindowX, long nWindowY, ScDocument* pDoc, SCTAB nTab, SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCCOL nFixPosX, SCROW nFixPosY ) { double fZoomFactor = (double)Fraction(nZoom,100); fScaleX *= fZoomFactor; fScaleY *= fZoomFactor; long nBlockX = 0; SCCOL nCol; for (nCol=0; nColGetColWidth( nCol, nTab ); if (nColTwips) { nBlockX += (long)(nColTwips * fScaleX); if (nBlockX > nWindowX) return sal_False; } } for (nCol=nStartCol; nCol<=nEndCol; nCol++) { sal_uInt16 nColTwips = pDoc->GetColWidth( nCol, nTab ); if (nColTwips) { nBlockX += (long)(nColTwips * fScaleX); if (nBlockX > nWindowX) return sal_False; } } long nBlockY = 0; for (SCROW nRow = 0; nRow <= nFixPosY-1; ++nRow) { if (pDoc->RowHidden(nRow, nTab)) continue; // for frozen panes, add both parts sal_uInt16 nRowTwips = pDoc->GetRowHeight(nRow, nTab); if (nRowTwips) { nBlockY += (long)(nRowTwips * fScaleY); if (nBlockY > nWindowY) return sal_False; } } for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow) { sal_uInt16 nRowTwips = pDoc->GetRowHeight(nRow, nTab); if (nRowTwips) { nBlockY += (long)(nRowTwips * fScaleY); if (nBlockY > nWindowY) return sal_False; } } return sal_True; } sal_uInt16 ScTabView::CalcZoom( SvxZoomType eType, sal_uInt16 nOldZoom ) { sal_uInt16 nZoom = 0; // Ergebnis switch ( eType ) { case SVX_ZOOM_PERCENT: // rZoom ist kein besonderer prozentualer Wert nZoom = nOldZoom; break; case SVX_ZOOM_OPTIMAL: // nZoom entspricht der optimalen Gr"o\se { ScMarkData& rMark = aViewData.GetMarkData(); ScDocument* pDoc = aViewData.GetDocument(); if (!rMark.IsMarked() && !rMark.IsMultiMarked()) nZoom = 100; // nothing selected else { SCTAB nTab = aViewData.GetTabNo(); ScRange aMarkRange; if ( aViewData.GetSimpleArea( aMarkRange ) != SC_MARK_SIMPLE ) rMark.GetMultiMarkArea( aMarkRange ); SCCOL nStartCol = aMarkRange.aStart.Col(); SCROW nStartRow = aMarkRange.aStart.Row(); SCTAB nStartTab = aMarkRange.aStart.Tab(); SCCOL nEndCol = aMarkRange.aEnd.Col(); SCROW nEndRow = aMarkRange.aEnd.Row(); SCTAB nEndTab = aMarkRange.aEnd.Tab(); if ( nTab < nStartTab && nTab > nEndTab ) nTab = nStartTab; ScSplitPos eUsedPart = aViewData.GetActivePart(); SCCOL nFixPosX = 0; SCROW nFixPosY = 0; if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX ) { // use right part eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT; nFixPosX = aViewData.GetFixPosX(); if ( nStartCol < nFixPosX ) nStartCol = nFixPosX; } if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX ) { // use bottom part eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT; nFixPosY = aViewData.GetFixPosY(); if ( nStartRow < nFixPosY ) nStartRow = nFixPosY; } if (pGridWin[eUsedPart]) { // Because scale is rounded to pixels, the only reliable way to find // the right scale is to check if a zoom fits Size aWinSize = pGridWin[eUsedPart]->GetOutputSizePixel(); // for frozen panes, use sum of both parts for calculation if ( nFixPosX != 0 ) aWinSize.Width() += GetGridWidth( SC_SPLIT_LEFT ); if ( nFixPosY != 0 ) aWinSize.Height() += GetGridHeight( SC_SPLIT_TOP ); ScDocShell* pDocSh = aViewData.GetDocShell(); double nPPTX = ScGlobal::nScreenPPTX / pDocSh->GetOutputFactor(); double nPPTY = ScGlobal::nScreenPPTY; sal_uInt16 nMin = MINZOOM; sal_uInt16 nMax = MAXZOOM; while ( nMax > nMin ) { sal_uInt16 nTest = (nMin+nMax+1)/2; if ( lcl_FitsInWindow( nPPTX, nPPTY, nTest, aWinSize.Width(), aWinSize.Height(), pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow, nFixPosX, nFixPosY ) ) nMin = nTest; else nMax = nTest-1; } DBG_ASSERT( nMin == nMax, "Schachtelung ist falsch" ); nZoom = nMin; if ( nZoom != nOldZoom ) { // scroll to block only in active split part // (the part for which the size was calculated) if ( nStartCol <= nEndCol ) aViewData.SetPosX( WhichH(eUsedPart), nStartCol ); if ( nStartRow <= nEndRow ) aViewData.SetPosY( WhichV(eUsedPart), nStartRow ); } } } } break; case SVX_ZOOM_WHOLEPAGE: // nZoom entspricht der ganzen Seite oder case SVX_ZOOM_PAGEWIDTH: // nZoom entspricht der Seitenbreite { SCTAB nCurTab = aViewData.GetTabNo(); ScDocument* pDoc = aViewData.GetDocument(); ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool(); SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nCurTab ), SFX_STYLE_FAMILY_PAGE ); DBG_ASSERT( pStyleSheet, "PageStyle not found :-/" ); if ( pStyleSheet ) { ScPrintFunc aPrintFunc( aViewData.GetDocShell(), aViewData.GetViewShell()->GetPrinter(sal_True), nCurTab ); Size aPageSize = aPrintFunc.GetDataSize(); // use the size of the largest GridWin for normal split, // or both combined for frozen panes, with the (document) size // of the frozen part added to the page size // (with frozen panes, the size of the individual parts // depends on the scale that is to be calculated) if ( !pGridWin[SC_SPLIT_BOTTOMLEFT] ) return 0; Size aWinSize = pGridWin[SC_SPLIT_BOTTOMLEFT]->GetOutputSizePixel(); ScSplitMode eHMode = aViewData.GetHSplitMode(); if ( eHMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_BOTTOMRIGHT] ) { long nOtherWidth = pGridWin[SC_SPLIT_BOTTOMRIGHT]-> GetOutputSizePixel().Width(); if ( eHMode == SC_SPLIT_FIX ) { aWinSize.Width() += nOtherWidth; for ( SCCOL nCol = aViewData.GetPosX(SC_SPLIT_LEFT); nCol < aViewData.GetFixPosX(); nCol++ ) aPageSize.Width() += pDoc->GetColWidth( nCol, nCurTab ); } else if ( nOtherWidth > aWinSize.Width() ) aWinSize.Width() = nOtherWidth; } ScSplitMode eVMode = aViewData.GetVSplitMode(); if ( eVMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_TOPLEFT] ) { long nOtherHeight = pGridWin[SC_SPLIT_TOPLEFT]-> GetOutputSizePixel().Height(); if ( eVMode == SC_SPLIT_FIX ) { aWinSize.Height() += nOtherHeight; aPageSize.Height() += pDoc->GetRowHeight( aViewData.GetPosY(SC_SPLIT_TOP), aViewData.GetFixPosY()-1, nCurTab); } else if ( nOtherHeight > aWinSize.Height() ) aWinSize.Height() = nOtherHeight; } double nPPTX = ScGlobal::nScreenPPTX / aViewData.GetDocShell()->GetOutputFactor(); double nPPTY = ScGlobal::nScreenPPTY; long nZoomX = (long) ( aWinSize.Width() * 100 / ( aPageSize.Width() * nPPTX ) ); long nZoomY = (long) ( aWinSize.Height() * 100 / ( aPageSize.Height() * nPPTY ) ); long nNew = nZoomX; if (eType == SVX_ZOOM_WHOLEPAGE && nZoomY < nNew) nNew = nZoomY; nZoom = (sal_uInt16) nNew; } } break; default: DBG_ERROR("Unknown Zoom-Revision"); nZoom = 0; } return nZoom; } // wird z.B. gerufen, wenn sich das View-Fenster verschiebt: void ScTabView::StopMarking() { ScSplitPos eActive = aViewData.GetActivePart(); if (pGridWin[eActive]) pGridWin[eActive]->StopMarking(); ScHSplitPos eH = WhichH(eActive); if (pColBar[eH]) pColBar[eH]->StopMarking(); ScVSplitPos eV = WhichV(eActive); if (pRowBar[eV]) pRowBar[eV]->StopMarking(); } void ScTabView::HideNoteMarker() { for (sal_uInt16 i=0; i<4; i++) if (pGridWin[i] && pGridWin[i]->IsVisible()) pGridWin[i]->HideNoteMarker(); } void ScTabView::MakeDrawLayer() { if (!pDrawView) { aViewData.GetDocShell()->MakeDrawLayer(); // pDrawView wird per Notify gesetzt DBG_ASSERT(pDrawView,"ScTabView::MakeDrawLayer funktioniert nicht"); // #114409# for(sal_uInt16 a(0); a < 4; a++) { if(pGridWin[a]) { pGridWin[a]->DrawLayerCreated(); } } } } void ScTabView::ErrorMessage( sal_uInt16 nGlobStrId ) { if ( SC_MOD()->IsInExecuteDrop() ) { // #i28468# don't show error message when called from Drag&Drop, silently abort instead return; } StopMarking(); // falls per Focus aus MouseButtonDown aufgerufen Window* pParent = aViewData.GetDialogParent(); ScWaitCursorOff aWaitOff( pParent ); sal_Bool bFocus = pParent && pParent->HasFocus(); if(nGlobStrId==STR_PROTECTIONERR) { if(aViewData.GetDocShell()->IsReadOnly()) { nGlobStrId=STR_READONLYERR; } } InfoBox aBox( pParent, ScGlobal::GetRscString( nGlobStrId ) ); aBox.Execute(); if (bFocus) pParent->GrabFocus(); } Window* ScTabView::GetParentOrChild( sal_uInt16 nChildId ) { SfxViewFrame* pViewFrm = aViewData.GetViewShell()->GetViewFrame(); if ( pViewFrm->HasChildWindow(nChildId) ) { SfxChildWindow* pChild = pViewFrm->GetChildWindow(nChildId); if (pChild) { Window* pWin = pChild->GetWindow(); if (pWin && pWin->IsVisible()) return pWin; } } return aViewData.GetDialogParent(); } void ScTabView::UpdatePageBreakData( sal_Bool bForcePaint ) { ScPageBreakData* pNewData = NULL; if (aViewData.IsPagebreakMode()) { ScDocShell* pDocSh = aViewData.GetDocShell(); ScDocument* pDoc = pDocSh->GetDocument(); SCTAB nTab = aViewData.GetTabNo(); sal_uInt16 nCount = pDoc->GetPrintRangeCount(nTab); if (!nCount) nCount = 1; pNewData = new ScPageBreakData(nCount); ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab, 0,0,NULL, NULL, pNewData ); // ScPrintFunc fuellt im ctor die PageBreakData if ( nCount > 1 ) { aPrintFunc.ResetBreaks(nTab); pNewData->AddPages(); } // Druckbereiche veraendert? if ( bForcePaint || ( pPageBreakData && !pPageBreakData->IsEqual( *pNewData ) ) ) PaintGrid(); } delete pPageBreakData; pPageBreakData = pNewData; }