summaryrefslogtreecommitdiff
path: root/sc/source/ui/view/tabview2.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/view/tabview2.cxx')
-rw-r--r--sc/source/ui/view/tabview2.cxx982
1 files changed, 982 insertions, 0 deletions
diff --git a/sc/source/ui/view/tabview2.cxx b/sc/source/ui/view/tabview2.cxx
new file mode 100644
index 000000000000..4fc575942feb
--- /dev/null
+++ b/sc/source/ui/view/tabview2.cxx
@@ -0,0 +1,982 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+
+
+#include <vcl/timer.hxx>
+#include <vcl/msgbox.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/childwin.hxx>
+
+#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<const ScMergeAttr*>(
+ 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<const ScMergeAttr*>(
+ 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; i<nCount; i++)
+ rMark.SelectTable( i, sal_True );
+
+ // Markierungen werden per Default nicht pro Tabelle gehalten
+// pDoc->ExtendMarksFromTable( 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; i<nCount; i++)
+ rMark.SelectTable( i, ( i == nTab ) );
+
+ aViewData.GetDocShell()->PostPaintExtras();
+ 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; nCol<nFixPosX; nCol++)
+ {
+ // for frozen panes, add both parts
+ sal_uInt16 nColTwips = pDoc->GetColWidth( 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;
+}
+
+
+