xref: /aoo41x/main/sc/source/ui/view/tabview2.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_sc.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir #include "scitems.hxx"
36*cdf0e10cSrcweir #include <editeng/eeitem.hxx>
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir #include <vcl/timer.hxx>
40*cdf0e10cSrcweir #include <vcl/msgbox.hxx>
41*cdf0e10cSrcweir #include <sfx2/app.hxx>
42*cdf0e10cSrcweir #include <sfx2/viewfrm.hxx>
43*cdf0e10cSrcweir #include <sfx2/bindings.hxx>
44*cdf0e10cSrcweir #include <sfx2/childwin.hxx>
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir #include "attrib.hxx"
47*cdf0e10cSrcweir #include "pagedata.hxx"
48*cdf0e10cSrcweir #include "tabview.hxx"
49*cdf0e10cSrcweir #include "tabvwsh.hxx"
50*cdf0e10cSrcweir #include "printfun.hxx"
51*cdf0e10cSrcweir #include "stlpool.hxx"
52*cdf0e10cSrcweir #include "docsh.hxx"
53*cdf0e10cSrcweir #include "gridwin.hxx"
54*cdf0e10cSrcweir #include "olinewin.hxx"
55*cdf0e10cSrcweir #include "uiitems.hxx"
56*cdf0e10cSrcweir #include "sc.hrc"
57*cdf0e10cSrcweir #include "viewutil.hxx"
58*cdf0e10cSrcweir #include "colrowba.hxx"
59*cdf0e10cSrcweir #include "waitoff.hxx"
60*cdf0e10cSrcweir #include "globstr.hrc"
61*cdf0e10cSrcweir #include "scmod.hxx"
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir #define SC_BLOCKMODE_NONE		0
64*cdf0e10cSrcweir #define SC_BLOCKMODE_NORMAL		1
65*cdf0e10cSrcweir #define SC_BLOCKMODE_OWN		2
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir //
70*cdf0e10cSrcweir //          Markier - Funktionen
71*cdf0e10cSrcweir //
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir void ScTabView::PaintMarks(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
74*cdf0e10cSrcweir {
75*cdf0e10cSrcweir 	if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
76*cdf0e10cSrcweir 	if (!ValidRow(nStartRow)) nStartRow = MAXROW;
77*cdf0e10cSrcweir 	if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
78*cdf0e10cSrcweir 	if (!ValidRow(nEndRow)) nEndRow = MAXROW;
79*cdf0e10cSrcweir 
80*cdf0e10cSrcweir 	sal_Bool bLeft = (nStartCol==0 && nEndCol==MAXCOL);
81*cdf0e10cSrcweir 	sal_Bool bTop = (nStartRow==0 && nEndRow==MAXROW);
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir 	if (bLeft)
84*cdf0e10cSrcweir 		PaintLeftArea( nStartRow, nEndRow );
85*cdf0e10cSrcweir 	if (bTop)
86*cdf0e10cSrcweir 		PaintTopArea( nStartCol, nEndCol );
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir 	aViewData.GetDocument()->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow,
89*cdf0e10cSrcweir 											aViewData.GetTabNo() );
90*cdf0e10cSrcweir 	PaintArea( nStartCol, nStartRow, nEndCol, nEndRow, SC_UPDATE_MARKS );
91*cdf0e10cSrcweir }
92*cdf0e10cSrcweir 
93*cdf0e10cSrcweir sal_Bool ScTabView::IsMarking( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
94*cdf0e10cSrcweir {
95*cdf0e10cSrcweir 	return bIsBlockMode
96*cdf0e10cSrcweir 		&& nBlockStartX == nCol
97*cdf0e10cSrcweir 		&& nBlockStartY == nRow
98*cdf0e10cSrcweir 		&& nBlockStartZ == nTab;
99*cdf0e10cSrcweir }
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir void ScTabView::InitOwnBlockMode()
102*cdf0e10cSrcweir {
103*cdf0e10cSrcweir 	if (!bIsBlockMode)
104*cdf0e10cSrcweir 	{
105*cdf0e10cSrcweir 		//	Wenn keine (alte) Markierung mehr da ist, Anker in SelectionEngine loeschen:
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir 		ScMarkData& rMark = aViewData.GetMarkData();
108*cdf0e10cSrcweir 		if (!rMark.IsMarked() && !rMark.IsMultiMarked())
109*cdf0e10cSrcweir 			GetSelEngine()->CursorPosChanging( sal_False, sal_False );
110*cdf0e10cSrcweir 
111*cdf0e10cSrcweir //		bIsBlockMode = sal_True;
112*cdf0e10cSrcweir 		bIsBlockMode = SC_BLOCKMODE_OWN;			//! Variable umbenennen!
113*cdf0e10cSrcweir 		nBlockStartX = 0;
114*cdf0e10cSrcweir 		nBlockStartY = 0;
115*cdf0e10cSrcweir 		nBlockStartZ = 0;
116*cdf0e10cSrcweir 		nBlockEndX = 0;
117*cdf0e10cSrcweir 		nBlockEndY = 0;
118*cdf0e10cSrcweir 		nBlockEndZ = 0;
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir 		SelectionChanged();		// Status wird mit gesetzer Markierung abgefragt
121*cdf0e10cSrcweir 	}
122*cdf0e10cSrcweir }
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir void ScTabView::InitBlockMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
125*cdf0e10cSrcweir 								sal_Bool bTestNeg, sal_Bool bCols, sal_Bool bRows )
126*cdf0e10cSrcweir {
127*cdf0e10cSrcweir 	if (!bIsBlockMode)
128*cdf0e10cSrcweir 	{
129*cdf0e10cSrcweir 		if (!ValidCol(nCurX)) nCurX = MAXCOL;
130*cdf0e10cSrcweir 		if (!ValidRow(nCurY)) nCurY = MAXROW;
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir 		ScMarkData& rMark = aViewData.GetMarkData();
133*cdf0e10cSrcweir 		SCTAB nTab = aViewData.GetTabNo();
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir 		//	Teil von Markierung aufheben?
136*cdf0e10cSrcweir 		if (bTestNeg)
137*cdf0e10cSrcweir 		{
138*cdf0e10cSrcweir 			if ( bCols )
139*cdf0e10cSrcweir 				bBlockNeg = rMark.IsColumnMarked( nCurX );
140*cdf0e10cSrcweir 			else if ( bRows )
141*cdf0e10cSrcweir 				bBlockNeg = rMark.IsRowMarked( nCurY );
142*cdf0e10cSrcweir 			else
143*cdf0e10cSrcweir 				bBlockNeg = rMark.IsCellMarked( nCurX, nCurY );
144*cdf0e10cSrcweir 		}
145*cdf0e10cSrcweir 		else
146*cdf0e10cSrcweir 			bBlockNeg = sal_False;
147*cdf0e10cSrcweir 		rMark.SetMarkNegative(bBlockNeg);
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir //		bIsBlockMode = sal_True;
150*cdf0e10cSrcweir 		bIsBlockMode = SC_BLOCKMODE_NORMAL;			//! Variable umbenennen!
151*cdf0e10cSrcweir 		bBlockCols = bCols;
152*cdf0e10cSrcweir 		bBlockRows = bRows;
153*cdf0e10cSrcweir 		nBlockStartX = nBlockStartXOrig = nCurX;
154*cdf0e10cSrcweir 		nBlockStartY = nBlockStartYOrig = nCurY;
155*cdf0e10cSrcweir 		nBlockStartZ = nCurZ;
156*cdf0e10cSrcweir 		nBlockEndX = nOldCurX = nBlockStartX;
157*cdf0e10cSrcweir 		nBlockEndY = nOldCurY = nBlockStartY;
158*cdf0e10cSrcweir 		nBlockEndZ = nBlockStartZ;
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir 		if (bBlockCols)
161*cdf0e10cSrcweir 		{
162*cdf0e10cSrcweir 			nBlockStartY = nBlockStartYOrig = 0;
163*cdf0e10cSrcweir 			nBlockEndY = MAXROW;
164*cdf0e10cSrcweir 		}
165*cdf0e10cSrcweir 
166*cdf0e10cSrcweir 		if (bBlockRows)
167*cdf0e10cSrcweir 		{
168*cdf0e10cSrcweir 			nBlockStartX = nBlockStartXOrig = 0;
169*cdf0e10cSrcweir 			nBlockEndX = MAXCOL;
170*cdf0e10cSrcweir 		}
171*cdf0e10cSrcweir 
172*cdf0e10cSrcweir 		rMark.SetMarkArea( ScRange( nBlockStartX,nBlockStartY, nTab, nBlockEndX,nBlockEndY, nTab ) );
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir #ifdef OLD_SELECTION_PAINT
175*cdf0e10cSrcweir 		InvertBlockMark( nBlockStartX,nBlockStartY,nBlockEndX,nBlockEndY );
176*cdf0e10cSrcweir #endif
177*cdf0e10cSrcweir 		UpdateSelectionOverlay();
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir 		bNewStartIfMarking = sal_False;		// use only once
180*cdf0e10cSrcweir 	}
181*cdf0e10cSrcweir }
182*cdf0e10cSrcweir 
183*cdf0e10cSrcweir void ScTabView::SetNewStartIfMarking()
184*cdf0e10cSrcweir {
185*cdf0e10cSrcweir 	bNewStartIfMarking = sal_True;
186*cdf0e10cSrcweir }
187*cdf0e10cSrcweir 
188*cdf0e10cSrcweir void ScTabView::DoneBlockMode( sal_Bool bContinue )            // Default FALSE
189*cdf0e10cSrcweir {
190*cdf0e10cSrcweir 	//	Wenn zwischen Tabellen- und Header SelectionEngine gewechselt wird,
191*cdf0e10cSrcweir 	//	wird evtl. DeselectAll gerufen, weil die andere Engine keinen Anker hat.
192*cdf0e10cSrcweir 	//	Mit bMoveIsShift wird verhindert, dass dann die Selektion aufgehoben wird.
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir 	if (bIsBlockMode && !bMoveIsShift)
195*cdf0e10cSrcweir 	{
196*cdf0e10cSrcweir 		ScMarkData& rMark = aViewData.GetMarkData();
197*cdf0e10cSrcweir 		sal_Bool bFlag = rMark.GetMarkingFlag();
198*cdf0e10cSrcweir 		rMark.SetMarking(sal_False);
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir 		if (bBlockNeg && !bContinue)
201*cdf0e10cSrcweir 			rMark.MarkToMulti();
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir 		if (bContinue)
204*cdf0e10cSrcweir 			rMark.MarkToMulti();
205*cdf0e10cSrcweir 		else
206*cdf0e10cSrcweir 		{
207*cdf0e10cSrcweir 			//	Die Tabelle kann an dieser Stelle ungueltig sein, weil DoneBlockMode
208*cdf0e10cSrcweir 			//	aus SetTabNo aufgerufen wird
209*cdf0e10cSrcweir 			//	(z.B. wenn die aktuelle Tabelle von einer anderen View aus geloescht wird)
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir 			SCTAB nTab = aViewData.GetTabNo();
212*cdf0e10cSrcweir 			ScDocument* pDoc = aViewData.GetDocument();
213*cdf0e10cSrcweir 			if ( pDoc->HasTable(nTab) )
214*cdf0e10cSrcweir 				PaintBlock( sal_True );								// sal_True -> Block loeschen
215*cdf0e10cSrcweir 			else
216*cdf0e10cSrcweir 				rMark.ResetMark();
217*cdf0e10cSrcweir 		}
218*cdf0e10cSrcweir //		bIsBlockMode = sal_False;
219*cdf0e10cSrcweir 		bIsBlockMode = SC_BLOCKMODE_NONE;			//! Variable umbenennen!
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir 		rMark.SetMarking(bFlag);
222*cdf0e10cSrcweir 		rMark.SetMarkNegative(sal_False);
223*cdf0e10cSrcweir 	}
224*cdf0e10cSrcweir }
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir void ScTabView::MarkCursor( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
227*cdf0e10cSrcweir                             sal_Bool bCols, sal_Bool bRows, sal_Bool bCellSelection )
228*cdf0e10cSrcweir {
229*cdf0e10cSrcweir 	if (!ValidCol(nCurX)) nCurX = MAXCOL;
230*cdf0e10cSrcweir 	if (!ValidRow(nCurY)) nCurY = MAXROW;
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir 	if (!bIsBlockMode)
233*cdf0e10cSrcweir 	{
234*cdf0e10cSrcweir 		DBG_ERROR( "MarkCursor nicht im BlockMode" );
235*cdf0e10cSrcweir 		InitBlockMode( nCurX, nCurY, nCurZ, sal_False, bCols, bRows );
236*cdf0e10cSrcweir 	}
237*cdf0e10cSrcweir 
238*cdf0e10cSrcweir 	if (bCols)
239*cdf0e10cSrcweir 		nCurY = MAXROW;
240*cdf0e10cSrcweir 	if (bRows)
241*cdf0e10cSrcweir 		nCurX = MAXCOL;
242*cdf0e10cSrcweir 
243*cdf0e10cSrcweir 	ScMarkData& rMark = aViewData.GetMarkData();
244*cdf0e10cSrcweir 	DBG_ASSERT(rMark.IsMarked() || rMark.IsMultiMarked(), "MarkCursor, !IsMarked()");
245*cdf0e10cSrcweir 	ScRange aMarkRange;
246*cdf0e10cSrcweir 	rMark.GetMarkArea(aMarkRange);
247*cdf0e10cSrcweir 	if (( aMarkRange.aStart.Col() != nBlockStartX && aMarkRange.aEnd.Col() != nBlockStartX ) ||
248*cdf0e10cSrcweir 		( aMarkRange.aStart.Row() != nBlockStartY && aMarkRange.aEnd.Row() != nBlockStartY ) ||
249*cdf0e10cSrcweir 		( bIsBlockMode == SC_BLOCKMODE_OWN ))
250*cdf0e10cSrcweir 	{
251*cdf0e10cSrcweir 		//	Markierung ist veraendert worden
252*cdf0e10cSrcweir 		//	(z.B. MarkToSimple, wenn per negativ alles bis auf ein Rechteck geloescht wurde)
253*cdf0e10cSrcweir 		//	oder nach InitOwnBlockMode wird mit Shift-Klick weitermarkiert...
254*cdf0e10cSrcweir 
255*cdf0e10cSrcweir 		sal_Bool bOldShift = bMoveIsShift;
256*cdf0e10cSrcweir 		bMoveIsShift = sal_False;				//	wirklich umsetzen
257*cdf0e10cSrcweir 		DoneBlockMode(sal_False);				//!	direkt Variablen setzen? (-> kein Geflacker)
258*cdf0e10cSrcweir 		bMoveIsShift = bOldShift;
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir 		InitBlockMode( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
261*cdf0e10cSrcweir 						nBlockStartZ, rMark.IsMarkNegative(), bCols, bRows );
262*cdf0e10cSrcweir 	}
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir 	SCCOL nOldBlockEndX = nBlockEndX;
265*cdf0e10cSrcweir 	SCROW nOldBlockEndY = nBlockEndY;
266*cdf0e10cSrcweir 
267*cdf0e10cSrcweir 	if ( nCurX != nOldCurX || nCurY != nOldCurY )
268*cdf0e10cSrcweir 	{
269*cdf0e10cSrcweir         // Current cursor has moved
270*cdf0e10cSrcweir 
271*cdf0e10cSrcweir 		SCTAB		nTab = nCurZ;
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir #ifdef OLD_SELECTION_PAINT
274*cdf0e10cSrcweir 		SCCOL		nDrawStartCol;
275*cdf0e10cSrcweir 		SCROW		nDrawStartRow;
276*cdf0e10cSrcweir 		SCCOL		nDrawEndCol;
277*cdf0e10cSrcweir 		SCROW		nDrawEndRow;
278*cdf0e10cSrcweir #endif
279*cdf0e10cSrcweir 
280*cdf0e10cSrcweir         // Set old selection area
281*cdf0e10cSrcweir 		ScUpdateRect aRect( nBlockStartX, nBlockStartY, nOldBlockEndX, nOldBlockEndY );
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir         if ( bCellSelection )
284*cdf0e10cSrcweir         {
285*cdf0e10cSrcweir             // Expand selection area accordingly when the current selection ends
286*cdf0e10cSrcweir             // with a merged cell.
287*cdf0e10cSrcweir             SCsCOL nCurXOffset = 0;
288*cdf0e10cSrcweir             SCsCOL nBlockStartXOffset = 0;
289*cdf0e10cSrcweir             SCsROW nCurYOffset = 0;
290*cdf0e10cSrcweir             SCsROW nBlockStartYOffset = 0;
291*cdf0e10cSrcweir             sal_Bool bBlockStartMerged = sal_False;
292*cdf0e10cSrcweir             const ScMergeAttr* pMergeAttr = NULL;
293*cdf0e10cSrcweir             ScDocument* pDocument = aViewData.GetDocument();
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir             // The following block checks whether or not the "BlockStart" (anchor)
296*cdf0e10cSrcweir             // cell is merged.  If it's merged, it'll then move the position of the
297*cdf0e10cSrcweir             // anchor cell to the corner that's diagonally opposite of the
298*cdf0e10cSrcweir             // direction of a current selection area.  For instance, if a current
299*cdf0e10cSrcweir             // selection is moving in the upperleft direction, the anchor cell will
300*cdf0e10cSrcweir             // move to the lower-right corner of the merged anchor cell, and so on.
301*cdf0e10cSrcweir 
302*cdf0e10cSrcweir             pMergeAttr = static_cast<const ScMergeAttr*>(
303*cdf0e10cSrcweir                 pDocument->GetAttr( nBlockStartXOrig, nBlockStartYOrig, nTab, ATTR_MERGE ) );
304*cdf0e10cSrcweir             if ( pMergeAttr->IsMerged() )
305*cdf0e10cSrcweir             {
306*cdf0e10cSrcweir                 SCsCOL nColSpan = pMergeAttr->GetColMerge();
307*cdf0e10cSrcweir                 SCsROW nRowSpan = pMergeAttr->GetRowMerge();
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir                 if ( !( nCurX >= nBlockStartXOrig + nColSpan - 1 && nCurY >= nBlockStartYOrig + nRowSpan - 1 ) )
310*cdf0e10cSrcweir                 {
311*cdf0e10cSrcweir                     nBlockStartX = nCurX >= nBlockStartXOrig ? nBlockStartXOrig : nBlockStartXOrig + nColSpan - 1;
312*cdf0e10cSrcweir                     nBlockStartY = nCurY >= nBlockStartYOrig ? nBlockStartYOrig : nBlockStartYOrig + nRowSpan - 1;
313*cdf0e10cSrcweir                     nCurXOffset  = nCurX >= nBlockStartXOrig && nCurX < nBlockStartXOrig + nColSpan - 1 ?
314*cdf0e10cSrcweir                         nBlockStartXOrig - nCurX + nColSpan - 1 : 0;
315*cdf0e10cSrcweir                     nCurYOffset  = nCurY >= nBlockStartYOrig && nCurY < nBlockStartYOrig + nRowSpan - 1 ?
316*cdf0e10cSrcweir                         nBlockStartYOrig - nCurY + nRowSpan - 1 : 0;
317*cdf0e10cSrcweir                     bBlockStartMerged = sal_True;
318*cdf0e10cSrcweir                 }
319*cdf0e10cSrcweir             }
320*cdf0e10cSrcweir 
321*cdf0e10cSrcweir             // The following block checks whether or not the current cell is
322*cdf0e10cSrcweir             // merged.  If it is, it'll then set the appropriate X & Y offset
323*cdf0e10cSrcweir             // values (nCurXOffset & nCurYOffset) such that the selection area will
324*cdf0e10cSrcweir             // grow by those specified offset amounts.  Note that the values of
325*cdf0e10cSrcweir             // nCurXOffset/nCurYOffset may also be specified in the previous code
326*cdf0e10cSrcweir             // block, in which case whichever value is greater will take on.
327*cdf0e10cSrcweir 
328*cdf0e10cSrcweir             pMergeAttr = static_cast<const ScMergeAttr*>(
329*cdf0e10cSrcweir                 pDocument->GetAttr( nCurX, nCurY, nTab, ATTR_MERGE ) );
330*cdf0e10cSrcweir             if ( pMergeAttr->IsMerged() )
331*cdf0e10cSrcweir             {
332*cdf0e10cSrcweir                 SCsCOL nColSpan = pMergeAttr->GetColMerge();
333*cdf0e10cSrcweir                 SCsROW nRowSpan = pMergeAttr->GetRowMerge();
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir                 if ( !( nBlockStartX >= nCurX + nColSpan - 1 && nBlockStartY >= nCurY + nRowSpan - 1 ) )
336*cdf0e10cSrcweir                 {
337*cdf0e10cSrcweir                     if ( nBlockStartX <= nCurX + nColSpan - 1 )
338*cdf0e10cSrcweir                     {
339*cdf0e10cSrcweir                         SCsCOL nCurXOffsetTemp = nCurX < nCurX + nColSpan - 1 ? nColSpan - 1 : 0;
340*cdf0e10cSrcweir                         nCurXOffset = nCurXOffset > nCurXOffsetTemp ? nCurXOffset : nCurXOffsetTemp;
341*cdf0e10cSrcweir                     }
342*cdf0e10cSrcweir                     if ( nBlockStartY <= nCurY + nRowSpan - 1 )
343*cdf0e10cSrcweir                     {
344*cdf0e10cSrcweir                         SCsROW nCurYOffsetTemp = nCurY < nCurY + nRowSpan - 1 ? nRowSpan - 1 : 0;
345*cdf0e10cSrcweir                         nCurYOffset = nCurYOffset > nCurYOffsetTemp ? nCurYOffset : nCurYOffsetTemp;
346*cdf0e10cSrcweir                     }
347*cdf0e10cSrcweir                     if ( !( nBlockStartX <= nCurX && nBlockStartY <= nCurY ) &&
348*cdf0e10cSrcweir                          !( nBlockStartX > nCurX + nColSpan - 1 && nBlockStartY > nCurY + nRowSpan - 1 ) )
349*cdf0e10cSrcweir                     {
350*cdf0e10cSrcweir                         nBlockStartXOffset = nBlockStartX > nCurX && nBlockStartX <= nCurX + nColSpan - 1 ? nCurX - nBlockStartX : 0;
351*cdf0e10cSrcweir                         nBlockStartYOffset = nBlockStartY > nCurY && nBlockStartY <= nCurY + nRowSpan - 1 ? nCurY - nBlockStartY : 0;
352*cdf0e10cSrcweir                     }
353*cdf0e10cSrcweir                 }
354*cdf0e10cSrcweir             }
355*cdf0e10cSrcweir             else
356*cdf0e10cSrcweir             {
357*cdf0e10cSrcweir                 // The current cell is not merged.  Move the anchor cell to its
358*cdf0e10cSrcweir                 // original position.
359*cdf0e10cSrcweir                 if ( !bBlockStartMerged )
360*cdf0e10cSrcweir                 {
361*cdf0e10cSrcweir                     nBlockStartX = nBlockStartXOrig;
362*cdf0e10cSrcweir                     nBlockStartY = nBlockStartYOrig;
363*cdf0e10cSrcweir                 }
364*cdf0e10cSrcweir             }
365*cdf0e10cSrcweir 
366*cdf0e10cSrcweir             nBlockStartX = nBlockStartX + nBlockStartXOffset >= 0 ? nBlockStartX + nBlockStartXOffset : 0;
367*cdf0e10cSrcweir             nBlockStartY = nBlockStartY + nBlockStartYOffset >= 0 ? nBlockStartY + nBlockStartYOffset : 0;
368*cdf0e10cSrcweir             nBlockEndX = nCurX + nCurXOffset > MAXCOL ? MAXCOL : nCurX + nCurXOffset;
369*cdf0e10cSrcweir             nBlockEndY = nCurY + nCurYOffset > MAXROW ? MAXROW : nCurY + nCurYOffset;
370*cdf0e10cSrcweir         }
371*cdf0e10cSrcweir         else
372*cdf0e10cSrcweir         {
373*cdf0e10cSrcweir             nBlockEndX = nCurX;
374*cdf0e10cSrcweir             nBlockEndY = nCurY;
375*cdf0e10cSrcweir         }
376*cdf0e10cSrcweir         // end of "if ( bCellSelection )"
377*cdf0e10cSrcweir 
378*cdf0e10cSrcweir         // Set new selection area
379*cdf0e10cSrcweir 		aRect.SetNew( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY );
380*cdf0e10cSrcweir 		rMark.SetMarkArea( ScRange( nBlockStartX, nBlockStartY, nTab, nBlockEndX, nBlockEndY, nTab ) );
381*cdf0e10cSrcweir 
382*cdf0e10cSrcweir #ifdef OLD_SELECTION_PAINT
383*cdf0e10cSrcweir 		sal_Bool bCont;
384*cdf0e10cSrcweir 		sal_Bool bDraw = aRect.GetXorDiff( nDrawStartCol, nDrawStartRow,
385*cdf0e10cSrcweir 										nDrawEndCol, nDrawEndRow, bCont );
386*cdf0e10cSrcweir 		if ( bDraw )
387*cdf0e10cSrcweir 		{
388*cdf0e10cSrcweir //?			PutInOrder( nDrawStartCol, nDrawEndCol );
389*cdf0e10cSrcweir //?			PutInOrder( nDrawStartRow, nDrawEndRow );
390*cdf0e10cSrcweir 
391*cdf0e10cSrcweir 			HideAllCursors();
392*cdf0e10cSrcweir 			InvertBlockMark( nDrawStartCol, nDrawStartRow, nDrawEndCol, nDrawEndRow );
393*cdf0e10cSrcweir 			if (bCont)
394*cdf0e10cSrcweir 			{
395*cdf0e10cSrcweir 				aRect.GetContDiff( nDrawStartCol, nDrawStartRow, nDrawEndCol, nDrawEndRow );
396*cdf0e10cSrcweir 				InvertBlockMark( nDrawStartCol, nDrawStartRow, nDrawEndCol, nDrawEndRow );
397*cdf0e10cSrcweir 			}
398*cdf0e10cSrcweir 			ShowAllCursors();
399*cdf0e10cSrcweir 		}
400*cdf0e10cSrcweir #endif
401*cdf0e10cSrcweir         UpdateSelectionOverlay();
402*cdf0e10cSrcweir 
403*cdf0e10cSrcweir         nOldCurX = nCurX;
404*cdf0e10cSrcweir         nOldCurY = nCurY;
405*cdf0e10cSrcweir 
406*cdf0e10cSrcweir 		aViewData.GetViewShell()->UpdateInputHandler();
407*cdf0e10cSrcweir //		InvalidateAttribs();
408*cdf0e10cSrcweir 	}
409*cdf0e10cSrcweir 
410*cdf0e10cSrcweir 	if ( !bCols && !bRows )
411*cdf0e10cSrcweir 		aHdrFunc.SetAnchorFlag( sal_False );
412*cdf0e10cSrcweir }
413*cdf0e10cSrcweir 
414*cdf0e10cSrcweir void ScTabView::UpdateSelectionOverlay()
415*cdf0e10cSrcweir {
416*cdf0e10cSrcweir     for (sal_uInt16 i=0; i<4; i++)
417*cdf0e10cSrcweir         if ( pGridWin[i] && pGridWin[i]->IsVisible() )
418*cdf0e10cSrcweir             pGridWin[i]->UpdateSelectionOverlay();
419*cdf0e10cSrcweir }
420*cdf0e10cSrcweir 
421*cdf0e10cSrcweir void ScTabView::UpdateShrinkOverlay()
422*cdf0e10cSrcweir {
423*cdf0e10cSrcweir     for (sal_uInt16 i=0; i<4; i++)
424*cdf0e10cSrcweir         if ( pGridWin[i] && pGridWin[i]->IsVisible() )
425*cdf0e10cSrcweir             pGridWin[i]->UpdateShrinkOverlay();
426*cdf0e10cSrcweir }
427*cdf0e10cSrcweir 
428*cdf0e10cSrcweir void ScTabView::UpdateAllOverlays()
429*cdf0e10cSrcweir {
430*cdf0e10cSrcweir     for (sal_uInt16 i=0; i<4; i++)
431*cdf0e10cSrcweir         if ( pGridWin[i] && pGridWin[i]->IsVisible() )
432*cdf0e10cSrcweir             pGridWin[i]->UpdateAllOverlays();
433*cdf0e10cSrcweir }
434*cdf0e10cSrcweir 
435*cdf0e10cSrcweir //!
436*cdf0e10cSrcweir //!	PaintBlock in zwei Methoden aufteilen: RepaintBlock und RemoveBlock o.ae.
437*cdf0e10cSrcweir //!
438*cdf0e10cSrcweir 
439*cdf0e10cSrcweir void ScTabView::PaintBlock( sal_Bool bReset )
440*cdf0e10cSrcweir {
441*cdf0e10cSrcweir 	ScDocument* pDoc = aViewData.GetDocument();
442*cdf0e10cSrcweir 	ScMarkData& rMark = aViewData.GetMarkData();
443*cdf0e10cSrcweir 	SCTAB nTab = aViewData.GetTabNo();
444*cdf0e10cSrcweir 	sal_Bool bMark = rMark.IsMarked();
445*cdf0e10cSrcweir 	sal_Bool bMulti = rMark.IsMultiMarked();
446*cdf0e10cSrcweir 	if (bMark || bMulti)
447*cdf0e10cSrcweir 	{
448*cdf0e10cSrcweir 		ScRange aMarkRange;
449*cdf0e10cSrcweir 		HideAllCursors();
450*cdf0e10cSrcweir 		if (bMulti)
451*cdf0e10cSrcweir 		{
452*cdf0e10cSrcweir 			sal_Bool bFlag = rMark.GetMarkingFlag();
453*cdf0e10cSrcweir 			rMark.SetMarking(sal_False);
454*cdf0e10cSrcweir 			rMark.MarkToMulti();
455*cdf0e10cSrcweir 			rMark.GetMultiMarkArea(aMarkRange);
456*cdf0e10cSrcweir 			rMark.MarkToSimple();
457*cdf0e10cSrcweir 			rMark.SetMarking(bFlag);
458*cdf0e10cSrcweir 
459*cdf0e10cSrcweir 			bMark = rMark.IsMarked();
460*cdf0e10cSrcweir 			bMulti = rMark.IsMultiMarked();
461*cdf0e10cSrcweir 		}
462*cdf0e10cSrcweir 		else
463*cdf0e10cSrcweir 			rMark.GetMarkArea(aMarkRange);
464*cdf0e10cSrcweir 
465*cdf0e10cSrcweir 		nBlockStartX = aMarkRange.aStart.Col();
466*cdf0e10cSrcweir 		nBlockStartY = aMarkRange.aStart.Row();
467*cdf0e10cSrcweir 		nBlockStartZ = aMarkRange.aStart.Tab();
468*cdf0e10cSrcweir 		nBlockEndX = aMarkRange.aEnd.Col();
469*cdf0e10cSrcweir 		nBlockEndY = aMarkRange.aEnd.Row();
470*cdf0e10cSrcweir 		nBlockEndZ = aMarkRange.aEnd.Tab();
471*cdf0e10cSrcweir 
472*cdf0e10cSrcweir 		sal_Bool bDidReset = sal_False;
473*cdf0e10cSrcweir 
474*cdf0e10cSrcweir 		if ( nTab>=nBlockStartZ && nTab<=nBlockEndZ )
475*cdf0e10cSrcweir 		{
476*cdf0e10cSrcweir 			if ( bReset )
477*cdf0e10cSrcweir 			{
478*cdf0e10cSrcweir 				// Invertieren beim Loeschen nur auf aktiver View
479*cdf0e10cSrcweir 				if ( aViewData.IsActive() )
480*cdf0e10cSrcweir 				{
481*cdf0e10cSrcweir 					sal_uInt16 i;
482*cdf0e10cSrcweir 					if ( bMulti )
483*cdf0e10cSrcweir 					{
484*cdf0e10cSrcweir #ifdef OLD_SELECTION_PAINT
485*cdf0e10cSrcweir 						for (i=0; i<4; i++)
486*cdf0e10cSrcweir 							if (pGridWin[i] && pGridWin[i]->IsVisible())
487*cdf0e10cSrcweir 								pGridWin[i]->InvertSimple( nBlockStartX, nBlockStartY,
488*cdf0e10cSrcweir 															nBlockEndX, nBlockEndY,
489*cdf0e10cSrcweir 															sal_True, sal_True );
490*cdf0e10cSrcweir #endif
491*cdf0e10cSrcweir 						rMark.ResetMark();
492*cdf0e10cSrcweir                         UpdateSelectionOverlay();
493*cdf0e10cSrcweir 						bDidReset = sal_True;
494*cdf0e10cSrcweir 					}
495*cdf0e10cSrcweir 					else
496*cdf0e10cSrcweir 					{
497*cdf0e10cSrcweir #ifdef OLD_SELECTION_PAINT
498*cdf0e10cSrcweir 						// (mis)use InvertBlockMark to remove all of the selection
499*cdf0e10cSrcweir 						// -> set bBlockNeg (like when removing parts of a selection)
500*cdf0e10cSrcweir 						//	  and convert everything to Multi
501*cdf0e10cSrcweir 
502*cdf0e10cSrcweir 						rMark.MarkToMulti();
503*cdf0e10cSrcweir 						sal_Bool bOld = bBlockNeg;
504*cdf0e10cSrcweir 						bBlockNeg = sal_True;
505*cdf0e10cSrcweir 						// #73130# (negative) MarkArea must be set in case of repaint
506*cdf0e10cSrcweir 						rMark.SetMarkArea( ScRange( nBlockStartX,nBlockStartY, nTab,
507*cdf0e10cSrcweir 													nBlockEndX,nBlockEndY, nTab ) );
508*cdf0e10cSrcweir 
509*cdf0e10cSrcweir 						InvertBlockMark( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY );
510*cdf0e10cSrcweir 
511*cdf0e10cSrcweir 						bBlockNeg = bOld;
512*cdf0e10cSrcweir #endif
513*cdf0e10cSrcweir 						rMark.ResetMark();
514*cdf0e10cSrcweir                         UpdateSelectionOverlay();
515*cdf0e10cSrcweir 						bDidReset = sal_True;
516*cdf0e10cSrcweir 					}
517*cdf0e10cSrcweir 
518*cdf0e10cSrcweir 					//	repaint if controls are touched (#69680# in both cases)
519*cdf0e10cSrcweir 					// #i74768# Forms are rendered by DrawingLayer's EndDrawLayers()
520*cdf0e10cSrcweir 					static bool bSuppressControlExtraStuff(true);
521*cdf0e10cSrcweir 
522*cdf0e10cSrcweir 					if(!bSuppressControlExtraStuff)
523*cdf0e10cSrcweir 					{
524*cdf0e10cSrcweir 						Rectangle aMMRect = pDoc->GetMMRect(nBlockStartX,nBlockStartY,nBlockEndX,nBlockEndY, nTab);
525*cdf0e10cSrcweir 						if (pDoc->HasControl( nTab, aMMRect ))
526*cdf0e10cSrcweir 						{
527*cdf0e10cSrcweir 							for (i=0; i<4; i++)
528*cdf0e10cSrcweir 							{
529*cdf0e10cSrcweir 								if (pGridWin[i] && pGridWin[i]->IsVisible())
530*cdf0e10cSrcweir 								{
531*cdf0e10cSrcweir 									//	MapMode muss logischer (1/100mm) sein !!!
532*cdf0e10cSrcweir 									pDoc->InvalidateControls( pGridWin[i], nTab, aMMRect );
533*cdf0e10cSrcweir 									pGridWin[i]->Update();
534*cdf0e10cSrcweir 								}
535*cdf0e10cSrcweir 							}
536*cdf0e10cSrcweir 						}
537*cdf0e10cSrcweir 					}
538*cdf0e10cSrcweir 				}
539*cdf0e10cSrcweir 			}
540*cdf0e10cSrcweir 			else
541*cdf0e10cSrcweir 				PaintMarks( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY );
542*cdf0e10cSrcweir 		}
543*cdf0e10cSrcweir 
544*cdf0e10cSrcweir 		if ( bReset && !bDidReset )
545*cdf0e10cSrcweir 			rMark.ResetMark();
546*cdf0e10cSrcweir 
547*cdf0e10cSrcweir 		ShowAllCursors();
548*cdf0e10cSrcweir 	}
549*cdf0e10cSrcweir }
550*cdf0e10cSrcweir 
551*cdf0e10cSrcweir void ScTabView::SelectAll( sal_Bool bContinue )
552*cdf0e10cSrcweir {
553*cdf0e10cSrcweir 	ScMarkData& rMark = aViewData.GetMarkData();
554*cdf0e10cSrcweir 	SCTAB nTab = aViewData.GetTabNo();
555*cdf0e10cSrcweir 
556*cdf0e10cSrcweir 	if (rMark.IsMarked())
557*cdf0e10cSrcweir 	{
558*cdf0e10cSrcweir 		ScRange aMarkRange;
559*cdf0e10cSrcweir 		rMark.GetMarkArea( aMarkRange );
560*cdf0e10cSrcweir 		if ( aMarkRange == ScRange( 0,0,nTab, MAXCOL,MAXROW,nTab ) )
561*cdf0e10cSrcweir 			return;
562*cdf0e10cSrcweir 	}
563*cdf0e10cSrcweir 
564*cdf0e10cSrcweir 	DoneBlockMode( bContinue );
565*cdf0e10cSrcweir 	InitBlockMode( 0,0,nTab );
566*cdf0e10cSrcweir 	MarkCursor( MAXCOL,MAXROW,nTab );
567*cdf0e10cSrcweir 
568*cdf0e10cSrcweir 	SelectionChanged();
569*cdf0e10cSrcweir }
570*cdf0e10cSrcweir 
571*cdf0e10cSrcweir void ScTabView::SelectAllTables()
572*cdf0e10cSrcweir {
573*cdf0e10cSrcweir 	ScDocument* pDoc = aViewData.GetDocument();
574*cdf0e10cSrcweir 	ScMarkData& rMark = aViewData.GetMarkData();
575*cdf0e10cSrcweir //    SCTAB nTab = aViewData.GetTabNo();
576*cdf0e10cSrcweir 	SCTAB nCount = pDoc->GetTableCount();
577*cdf0e10cSrcweir 
578*cdf0e10cSrcweir 	if (nCount>1)
579*cdf0e10cSrcweir 	{
580*cdf0e10cSrcweir 		for (SCTAB i=0; i<nCount; i++)
581*cdf0e10cSrcweir 			rMark.SelectTable( i, sal_True );
582*cdf0e10cSrcweir 
583*cdf0e10cSrcweir 		//		Markierungen werden per Default nicht pro Tabelle gehalten
584*cdf0e10cSrcweir //		pDoc->ExtendMarksFromTable( nTab );
585*cdf0e10cSrcweir 
586*cdf0e10cSrcweir 		aViewData.GetDocShell()->PostPaintExtras();
587*cdf0e10cSrcweir         SfxBindings& rBind = aViewData.GetBindings();
588*cdf0e10cSrcweir         rBind.Invalidate( FID_FILL_TAB );
589*cdf0e10cSrcweir         rBind.Invalidate( FID_TAB_DESELECTALL );
590*cdf0e10cSrcweir 	}
591*cdf0e10cSrcweir }
592*cdf0e10cSrcweir 
593*cdf0e10cSrcweir void ScTabView::DeselectAllTables()
594*cdf0e10cSrcweir {
595*cdf0e10cSrcweir     ScDocument* pDoc = aViewData.GetDocument();
596*cdf0e10cSrcweir     ScMarkData& rMark = aViewData.GetMarkData();
597*cdf0e10cSrcweir     SCTAB nTab = aViewData.GetTabNo();
598*cdf0e10cSrcweir     SCTAB nCount = pDoc->GetTableCount();
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir     for (SCTAB i=0; i<nCount; i++)
601*cdf0e10cSrcweir         rMark.SelectTable( i, ( i == nTab ) );
602*cdf0e10cSrcweir 
603*cdf0e10cSrcweir     aViewData.GetDocShell()->PostPaintExtras();
604*cdf0e10cSrcweir     SfxBindings& rBind = aViewData.GetBindings();
605*cdf0e10cSrcweir     rBind.Invalidate( FID_FILL_TAB );
606*cdf0e10cSrcweir     rBind.Invalidate( FID_TAB_DESELECTALL );
607*cdf0e10cSrcweir }
608*cdf0e10cSrcweir 
609*cdf0e10cSrcweir sal_Bool lcl_FitsInWindow( double fScaleX, double fScaleY, sal_uInt16 nZoom,
610*cdf0e10cSrcweir 						long nWindowX, long nWindowY, ScDocument* pDoc, SCTAB nTab,
611*cdf0e10cSrcweir 						SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
612*cdf0e10cSrcweir 						SCCOL nFixPosX, SCROW nFixPosY )
613*cdf0e10cSrcweir {
614*cdf0e10cSrcweir 	double fZoomFactor = (double)Fraction(nZoom,100);
615*cdf0e10cSrcweir 	fScaleX *= fZoomFactor;
616*cdf0e10cSrcweir 	fScaleY *= fZoomFactor;
617*cdf0e10cSrcweir 
618*cdf0e10cSrcweir 	long nBlockX = 0;
619*cdf0e10cSrcweir 	SCCOL nCol;
620*cdf0e10cSrcweir 	for (nCol=0; nCol<nFixPosX; nCol++)
621*cdf0e10cSrcweir 	{
622*cdf0e10cSrcweir 		//	for frozen panes, add both parts
623*cdf0e10cSrcweir 		sal_uInt16 nColTwips = pDoc->GetColWidth( nCol, nTab );
624*cdf0e10cSrcweir 		if (nColTwips)
625*cdf0e10cSrcweir 		{
626*cdf0e10cSrcweir 			nBlockX += (long)(nColTwips * fScaleX);
627*cdf0e10cSrcweir 			if (nBlockX > nWindowX)
628*cdf0e10cSrcweir 				return sal_False;
629*cdf0e10cSrcweir 		}
630*cdf0e10cSrcweir 	}
631*cdf0e10cSrcweir 	for (nCol=nStartCol; nCol<=nEndCol; nCol++)
632*cdf0e10cSrcweir 	{
633*cdf0e10cSrcweir 		sal_uInt16 nColTwips = pDoc->GetColWidth( nCol, nTab );
634*cdf0e10cSrcweir 		if (nColTwips)
635*cdf0e10cSrcweir 		{
636*cdf0e10cSrcweir 			nBlockX += (long)(nColTwips * fScaleX);
637*cdf0e10cSrcweir 			if (nBlockX > nWindowX)
638*cdf0e10cSrcweir 				return sal_False;
639*cdf0e10cSrcweir 		}
640*cdf0e10cSrcweir 	}
641*cdf0e10cSrcweir 
642*cdf0e10cSrcweir 	long nBlockY = 0;
643*cdf0e10cSrcweir     for (SCROW nRow = 0; nRow <= nFixPosY-1; ++nRow)
644*cdf0e10cSrcweir 	{
645*cdf0e10cSrcweir         if (pDoc->RowHidden(nRow, nTab))
646*cdf0e10cSrcweir             continue;
647*cdf0e10cSrcweir 
648*cdf0e10cSrcweir 		//	for frozen panes, add both parts
649*cdf0e10cSrcweir         sal_uInt16 nRowTwips = pDoc->GetRowHeight(nRow, nTab);
650*cdf0e10cSrcweir 		if (nRowTwips)
651*cdf0e10cSrcweir 		{
652*cdf0e10cSrcweir 			nBlockY += (long)(nRowTwips * fScaleY);
653*cdf0e10cSrcweir 			if (nBlockY > nWindowY)
654*cdf0e10cSrcweir 				return sal_False;
655*cdf0e10cSrcweir 		}
656*cdf0e10cSrcweir 	}
657*cdf0e10cSrcweir     for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
658*cdf0e10cSrcweir 	{
659*cdf0e10cSrcweir         sal_uInt16 nRowTwips = pDoc->GetRowHeight(nRow, nTab);
660*cdf0e10cSrcweir 		if (nRowTwips)
661*cdf0e10cSrcweir 		{
662*cdf0e10cSrcweir 			nBlockY += (long)(nRowTwips * fScaleY);
663*cdf0e10cSrcweir 			if (nBlockY > nWindowY)
664*cdf0e10cSrcweir 				return sal_False;
665*cdf0e10cSrcweir 		}
666*cdf0e10cSrcweir 	}
667*cdf0e10cSrcweir 
668*cdf0e10cSrcweir 	return sal_True;
669*cdf0e10cSrcweir }
670*cdf0e10cSrcweir 
671*cdf0e10cSrcweir sal_uInt16 ScTabView::CalcZoom( SvxZoomType eType, sal_uInt16 nOldZoom )
672*cdf0e10cSrcweir {
673*cdf0e10cSrcweir 	sal_uInt16 nZoom = 0; // Ergebnis
674*cdf0e10cSrcweir 
675*cdf0e10cSrcweir 	switch ( eType )
676*cdf0e10cSrcweir 	{
677*cdf0e10cSrcweir 		case SVX_ZOOM_PERCENT: // rZoom ist kein besonderer prozentualer Wert
678*cdf0e10cSrcweir 			nZoom = nOldZoom;
679*cdf0e10cSrcweir 			break;
680*cdf0e10cSrcweir 
681*cdf0e10cSrcweir 		case SVX_ZOOM_OPTIMAL:	// nZoom entspricht der optimalen Gr"o\se
682*cdf0e10cSrcweir 			{
683*cdf0e10cSrcweir 				ScMarkData& rMark = aViewData.GetMarkData();
684*cdf0e10cSrcweir 				ScDocument* pDoc = aViewData.GetDocument();
685*cdf0e10cSrcweir 
686*cdf0e10cSrcweir 				if (!rMark.IsMarked() && !rMark.IsMultiMarked())
687*cdf0e10cSrcweir 					nZoom = 100;				// nothing selected
688*cdf0e10cSrcweir 				else
689*cdf0e10cSrcweir 				{
690*cdf0e10cSrcweir 					SCTAB	nTab = aViewData.GetTabNo();
691*cdf0e10cSrcweir 					ScRange aMarkRange;
692*cdf0e10cSrcweir 					if ( aViewData.GetSimpleArea( aMarkRange ) != SC_MARK_SIMPLE )
693*cdf0e10cSrcweir 						rMark.GetMultiMarkArea( aMarkRange );
694*cdf0e10cSrcweir 
695*cdf0e10cSrcweir 					SCCOL	nStartCol = aMarkRange.aStart.Col();
696*cdf0e10cSrcweir 					SCROW	nStartRow = aMarkRange.aStart.Row();
697*cdf0e10cSrcweir 					SCTAB	nStartTab = aMarkRange.aStart.Tab();
698*cdf0e10cSrcweir 					SCCOL	nEndCol = aMarkRange.aEnd.Col();
699*cdf0e10cSrcweir 					SCROW	nEndRow = aMarkRange.aEnd.Row();
700*cdf0e10cSrcweir 					SCTAB	nEndTab = aMarkRange.aEnd.Tab();
701*cdf0e10cSrcweir 
702*cdf0e10cSrcweir 					if ( nTab < nStartTab && nTab > nEndTab )
703*cdf0e10cSrcweir 						nTab = nStartTab;
704*cdf0e10cSrcweir 
705*cdf0e10cSrcweir 					ScSplitPos eUsedPart = aViewData.GetActivePart();
706*cdf0e10cSrcweir 
707*cdf0e10cSrcweir 					SCCOL nFixPosX = 0;
708*cdf0e10cSrcweir 					SCROW nFixPosY = 0;
709*cdf0e10cSrcweir 					if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
710*cdf0e10cSrcweir 					{
711*cdf0e10cSrcweir 						//	use right part
712*cdf0e10cSrcweir 						eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
713*cdf0e10cSrcweir 						nFixPosX = aViewData.GetFixPosX();
714*cdf0e10cSrcweir 						if ( nStartCol < nFixPosX )
715*cdf0e10cSrcweir 							nStartCol = nFixPosX;
716*cdf0e10cSrcweir 					}
717*cdf0e10cSrcweir 					if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
718*cdf0e10cSrcweir 					{
719*cdf0e10cSrcweir 						//	use bottom part
720*cdf0e10cSrcweir 						eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
721*cdf0e10cSrcweir 						nFixPosY = aViewData.GetFixPosY();
722*cdf0e10cSrcweir 						if ( nStartRow < nFixPosY )
723*cdf0e10cSrcweir 							nStartRow = nFixPosY;
724*cdf0e10cSrcweir 					}
725*cdf0e10cSrcweir 
726*cdf0e10cSrcweir 					if (pGridWin[eUsedPart])
727*cdf0e10cSrcweir 					{
728*cdf0e10cSrcweir 						//	Because scale is rounded to pixels, the only reliable way to find
729*cdf0e10cSrcweir 						//	the right scale is to check if a zoom fits
730*cdf0e10cSrcweir 
731*cdf0e10cSrcweir 						Size aWinSize = pGridWin[eUsedPart]->GetOutputSizePixel();
732*cdf0e10cSrcweir 
733*cdf0e10cSrcweir 						//	for frozen panes, use sum of both parts for calculation
734*cdf0e10cSrcweir 
735*cdf0e10cSrcweir 						if ( nFixPosX != 0 )
736*cdf0e10cSrcweir 							aWinSize.Width() += GetGridWidth( SC_SPLIT_LEFT );
737*cdf0e10cSrcweir 						if ( nFixPosY != 0 )
738*cdf0e10cSrcweir 							aWinSize.Height() += GetGridHeight( SC_SPLIT_TOP );
739*cdf0e10cSrcweir 
740*cdf0e10cSrcweir 						ScDocShell* pDocSh = aViewData.GetDocShell();
741*cdf0e10cSrcweir 						double nPPTX = ScGlobal::nScreenPPTX / pDocSh->GetOutputFactor();
742*cdf0e10cSrcweir 						double nPPTY = ScGlobal::nScreenPPTY;
743*cdf0e10cSrcweir 
744*cdf0e10cSrcweir 						sal_uInt16 nMin = MINZOOM;
745*cdf0e10cSrcweir 						sal_uInt16 nMax = MAXZOOM;
746*cdf0e10cSrcweir 						while ( nMax > nMin )
747*cdf0e10cSrcweir 						{
748*cdf0e10cSrcweir 							sal_uInt16 nTest = (nMin+nMax+1)/2;
749*cdf0e10cSrcweir 							if ( lcl_FitsInWindow(
750*cdf0e10cSrcweir 										nPPTX, nPPTY, nTest, aWinSize.Width(), aWinSize.Height(),
751*cdf0e10cSrcweir 										pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow,
752*cdf0e10cSrcweir 										nFixPosX, nFixPosY ) )
753*cdf0e10cSrcweir 								nMin = nTest;
754*cdf0e10cSrcweir 							else
755*cdf0e10cSrcweir 								nMax = nTest-1;
756*cdf0e10cSrcweir 						}
757*cdf0e10cSrcweir 						DBG_ASSERT( nMin == nMax, "Schachtelung ist falsch" );
758*cdf0e10cSrcweir 						nZoom = nMin;
759*cdf0e10cSrcweir 
760*cdf0e10cSrcweir 						if ( nZoom != nOldZoom )
761*cdf0e10cSrcweir 						{
762*cdf0e10cSrcweir 							// scroll to block only in active split part
763*cdf0e10cSrcweir 							// (the part for which the size was calculated)
764*cdf0e10cSrcweir 
765*cdf0e10cSrcweir 							if ( nStartCol <= nEndCol )
766*cdf0e10cSrcweir 								aViewData.SetPosX( WhichH(eUsedPart), nStartCol );
767*cdf0e10cSrcweir 							if ( nStartRow <= nEndRow )
768*cdf0e10cSrcweir 								aViewData.SetPosY( WhichV(eUsedPart), nStartRow );
769*cdf0e10cSrcweir 						}
770*cdf0e10cSrcweir 					}
771*cdf0e10cSrcweir 				}
772*cdf0e10cSrcweir 			}
773*cdf0e10cSrcweir 			break;
774*cdf0e10cSrcweir 
775*cdf0e10cSrcweir 			case SVX_ZOOM_WHOLEPAGE:	// nZoom entspricht der ganzen Seite oder
776*cdf0e10cSrcweir 			case SVX_ZOOM_PAGEWIDTH:	// nZoom entspricht der Seitenbreite
777*cdf0e10cSrcweir 				{
778*cdf0e10cSrcweir 					SCTAB				nCurTab		= aViewData.GetTabNo();
779*cdf0e10cSrcweir 					ScDocument*			pDoc		= aViewData.GetDocument();
780*cdf0e10cSrcweir 					ScStyleSheetPool*	pStylePool  = pDoc->GetStyleSheetPool();
781*cdf0e10cSrcweir 					SfxStyleSheetBase*	pStyleSheet =
782*cdf0e10cSrcweir 											pStylePool->Find( pDoc->GetPageStyle( nCurTab ),
783*cdf0e10cSrcweir 															  SFX_STYLE_FAMILY_PAGE );
784*cdf0e10cSrcweir 
785*cdf0e10cSrcweir 					DBG_ASSERT( pStyleSheet, "PageStyle not found :-/" );
786*cdf0e10cSrcweir 
787*cdf0e10cSrcweir 					if ( pStyleSheet )
788*cdf0e10cSrcweir 					{
789*cdf0e10cSrcweir 						ScPrintFunc aPrintFunc( aViewData.GetDocShell(),
790*cdf0e10cSrcweir 												aViewData.GetViewShell()->GetPrinter(sal_True),
791*cdf0e10cSrcweir 												nCurTab );
792*cdf0e10cSrcweir 
793*cdf0e10cSrcweir 						Size aPageSize = aPrintFunc.GetDataSize();
794*cdf0e10cSrcweir 
795*cdf0e10cSrcweir 						//	use the size of the largest GridWin for normal split,
796*cdf0e10cSrcweir 						//	or both combined for frozen panes, with the (document) size
797*cdf0e10cSrcweir 						//	of the frozen part added to the page size
798*cdf0e10cSrcweir 						//	(with frozen panes, the size of the individual parts
799*cdf0e10cSrcweir 						//	depends on the scale that is to be calculated)
800*cdf0e10cSrcweir 
801*cdf0e10cSrcweir 						if ( !pGridWin[SC_SPLIT_BOTTOMLEFT] ) return 0;
802*cdf0e10cSrcweir 						Size aWinSize = pGridWin[SC_SPLIT_BOTTOMLEFT]->GetOutputSizePixel();
803*cdf0e10cSrcweir 						ScSplitMode eHMode = aViewData.GetHSplitMode();
804*cdf0e10cSrcweir 						if ( eHMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_BOTTOMRIGHT] )
805*cdf0e10cSrcweir 						{
806*cdf0e10cSrcweir 							long nOtherWidth = pGridWin[SC_SPLIT_BOTTOMRIGHT]->
807*cdf0e10cSrcweir 														GetOutputSizePixel().Width();
808*cdf0e10cSrcweir 							if ( eHMode == SC_SPLIT_FIX )
809*cdf0e10cSrcweir 							{
810*cdf0e10cSrcweir 								aWinSize.Width() += nOtherWidth;
811*cdf0e10cSrcweir 								for ( SCCOL nCol = aViewData.GetPosX(SC_SPLIT_LEFT);
812*cdf0e10cSrcweir 										nCol < aViewData.GetFixPosX(); nCol++ )
813*cdf0e10cSrcweir 									aPageSize.Width() += pDoc->GetColWidth( nCol, nCurTab );
814*cdf0e10cSrcweir 							}
815*cdf0e10cSrcweir 							else if ( nOtherWidth > aWinSize.Width() )
816*cdf0e10cSrcweir 								aWinSize.Width() = nOtherWidth;
817*cdf0e10cSrcweir 						}
818*cdf0e10cSrcweir 						ScSplitMode eVMode = aViewData.GetVSplitMode();
819*cdf0e10cSrcweir 						if ( eVMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_TOPLEFT] )
820*cdf0e10cSrcweir 						{
821*cdf0e10cSrcweir 							long nOtherHeight = pGridWin[SC_SPLIT_TOPLEFT]->
822*cdf0e10cSrcweir 														GetOutputSizePixel().Height();
823*cdf0e10cSrcweir 							if ( eVMode == SC_SPLIT_FIX )
824*cdf0e10cSrcweir 							{
825*cdf0e10cSrcweir 								aWinSize.Height() += nOtherHeight;
826*cdf0e10cSrcweir                                 aPageSize.Height() += pDoc->GetRowHeight(
827*cdf0e10cSrcweir                                         aViewData.GetPosY(SC_SPLIT_TOP),
828*cdf0e10cSrcweir                                         aViewData.GetFixPosY()-1, nCurTab);
829*cdf0e10cSrcweir 							}
830*cdf0e10cSrcweir 							else if ( nOtherHeight > aWinSize.Height() )
831*cdf0e10cSrcweir 								aWinSize.Height() = nOtherHeight;
832*cdf0e10cSrcweir 						}
833*cdf0e10cSrcweir 
834*cdf0e10cSrcweir 						double nPPTX = ScGlobal::nScreenPPTX / aViewData.GetDocShell()->GetOutputFactor();
835*cdf0e10cSrcweir 						double nPPTY = ScGlobal::nScreenPPTY;
836*cdf0e10cSrcweir 
837*cdf0e10cSrcweir 						long nZoomX = (long) ( aWinSize.Width() * 100 /
838*cdf0e10cSrcweir 											   ( aPageSize.Width() * nPPTX ) );
839*cdf0e10cSrcweir 						long nZoomY = (long) ( aWinSize.Height() * 100 /
840*cdf0e10cSrcweir 											   ( aPageSize.Height() * nPPTY ) );
841*cdf0e10cSrcweir 						long nNew = nZoomX;
842*cdf0e10cSrcweir 
843*cdf0e10cSrcweir 						if (eType == SVX_ZOOM_WHOLEPAGE && nZoomY < nNew)
844*cdf0e10cSrcweir 							nNew = nZoomY;
845*cdf0e10cSrcweir 
846*cdf0e10cSrcweir 						nZoom = (sal_uInt16) nNew;
847*cdf0e10cSrcweir 					}
848*cdf0e10cSrcweir 				}
849*cdf0e10cSrcweir 				break;
850*cdf0e10cSrcweir 
851*cdf0e10cSrcweir 		default:
852*cdf0e10cSrcweir 			DBG_ERROR("Unknown Zoom-Revision");
853*cdf0e10cSrcweir 			nZoom = 0;
854*cdf0e10cSrcweir 	}
855*cdf0e10cSrcweir 
856*cdf0e10cSrcweir 	return nZoom;
857*cdf0e10cSrcweir }
858*cdf0e10cSrcweir 
859*cdf0e10cSrcweir //	wird z.B. gerufen, wenn sich das View-Fenster verschiebt:
860*cdf0e10cSrcweir 
861*cdf0e10cSrcweir void ScTabView::StopMarking()
862*cdf0e10cSrcweir {
863*cdf0e10cSrcweir 	ScSplitPos eActive = aViewData.GetActivePart();
864*cdf0e10cSrcweir 	if (pGridWin[eActive])
865*cdf0e10cSrcweir 		pGridWin[eActive]->StopMarking();
866*cdf0e10cSrcweir 
867*cdf0e10cSrcweir 	ScHSplitPos eH = WhichH(eActive);
868*cdf0e10cSrcweir 	if (pColBar[eH])
869*cdf0e10cSrcweir 		pColBar[eH]->StopMarking();
870*cdf0e10cSrcweir 
871*cdf0e10cSrcweir 	ScVSplitPos eV = WhichV(eActive);
872*cdf0e10cSrcweir 	if (pRowBar[eV])
873*cdf0e10cSrcweir 		pRowBar[eV]->StopMarking();
874*cdf0e10cSrcweir }
875*cdf0e10cSrcweir 
876*cdf0e10cSrcweir void ScTabView::HideNoteMarker()
877*cdf0e10cSrcweir {
878*cdf0e10cSrcweir 	for (sal_uInt16 i=0; i<4; i++)
879*cdf0e10cSrcweir 		if (pGridWin[i] && pGridWin[i]->IsVisible())
880*cdf0e10cSrcweir 			pGridWin[i]->HideNoteMarker();
881*cdf0e10cSrcweir }
882*cdf0e10cSrcweir 
883*cdf0e10cSrcweir void ScTabView::MakeDrawLayer()
884*cdf0e10cSrcweir {
885*cdf0e10cSrcweir 	if (!pDrawView)
886*cdf0e10cSrcweir 	{
887*cdf0e10cSrcweir 		aViewData.GetDocShell()->MakeDrawLayer();
888*cdf0e10cSrcweir 
889*cdf0e10cSrcweir 		//	pDrawView wird per Notify gesetzt
890*cdf0e10cSrcweir 		DBG_ASSERT(pDrawView,"ScTabView::MakeDrawLayer funktioniert nicht");
891*cdf0e10cSrcweir 
892*cdf0e10cSrcweir 		// #114409#
893*cdf0e10cSrcweir 		for(sal_uInt16 a(0); a < 4; a++)
894*cdf0e10cSrcweir 		{
895*cdf0e10cSrcweir 			if(pGridWin[a])
896*cdf0e10cSrcweir 			{
897*cdf0e10cSrcweir 				pGridWin[a]->DrawLayerCreated();
898*cdf0e10cSrcweir 			}
899*cdf0e10cSrcweir 		}
900*cdf0e10cSrcweir 	}
901*cdf0e10cSrcweir }
902*cdf0e10cSrcweir 
903*cdf0e10cSrcweir void ScTabView::ErrorMessage( sal_uInt16 nGlobStrId )
904*cdf0e10cSrcweir {
905*cdf0e10cSrcweir     if ( SC_MOD()->IsInExecuteDrop() )
906*cdf0e10cSrcweir     {
907*cdf0e10cSrcweir         // #i28468# don't show error message when called from Drag&Drop, silently abort instead
908*cdf0e10cSrcweir         return;
909*cdf0e10cSrcweir     }
910*cdf0e10cSrcweir 
911*cdf0e10cSrcweir 	StopMarking();		// falls per Focus aus MouseButtonDown aufgerufen
912*cdf0e10cSrcweir 
913*cdf0e10cSrcweir 	Window* pParent = aViewData.GetDialogParent();
914*cdf0e10cSrcweir 	ScWaitCursorOff aWaitOff( pParent );
915*cdf0e10cSrcweir 	sal_Bool bFocus = pParent && pParent->HasFocus();
916*cdf0e10cSrcweir 
917*cdf0e10cSrcweir 	if(nGlobStrId==STR_PROTECTIONERR)
918*cdf0e10cSrcweir 	{
919*cdf0e10cSrcweir 		if(aViewData.GetDocShell()->IsReadOnly())
920*cdf0e10cSrcweir 		{
921*cdf0e10cSrcweir 			nGlobStrId=STR_READONLYERR;
922*cdf0e10cSrcweir 		}
923*cdf0e10cSrcweir 	}
924*cdf0e10cSrcweir 
925*cdf0e10cSrcweir 	InfoBox aBox( pParent, ScGlobal::GetRscString( nGlobStrId ) );
926*cdf0e10cSrcweir 	aBox.Execute();
927*cdf0e10cSrcweir 	if (bFocus)
928*cdf0e10cSrcweir 		pParent->GrabFocus();
929*cdf0e10cSrcweir }
930*cdf0e10cSrcweir 
931*cdf0e10cSrcweir Window* ScTabView::GetParentOrChild( sal_uInt16 nChildId )
932*cdf0e10cSrcweir {
933*cdf0e10cSrcweir 	SfxViewFrame* pViewFrm = aViewData.GetViewShell()->GetViewFrame();
934*cdf0e10cSrcweir 
935*cdf0e10cSrcweir 	if ( pViewFrm->HasChildWindow(nChildId) )
936*cdf0e10cSrcweir 	{
937*cdf0e10cSrcweir 		SfxChildWindow* pChild = pViewFrm->GetChildWindow(nChildId);
938*cdf0e10cSrcweir 		if (pChild)
939*cdf0e10cSrcweir 		{
940*cdf0e10cSrcweir 			Window* pWin = pChild->GetWindow();
941*cdf0e10cSrcweir 			if (pWin && pWin->IsVisible())
942*cdf0e10cSrcweir 				return pWin;
943*cdf0e10cSrcweir 		}
944*cdf0e10cSrcweir 	}
945*cdf0e10cSrcweir 
946*cdf0e10cSrcweir 	return aViewData.GetDialogParent();
947*cdf0e10cSrcweir }
948*cdf0e10cSrcweir 
949*cdf0e10cSrcweir void ScTabView::UpdatePageBreakData( sal_Bool bForcePaint )
950*cdf0e10cSrcweir {
951*cdf0e10cSrcweir 	ScPageBreakData* pNewData = NULL;
952*cdf0e10cSrcweir 
953*cdf0e10cSrcweir 	if (aViewData.IsPagebreakMode())
954*cdf0e10cSrcweir 	{
955*cdf0e10cSrcweir 		ScDocShell* pDocSh = aViewData.GetDocShell();
956*cdf0e10cSrcweir 		ScDocument* pDoc = pDocSh->GetDocument();
957*cdf0e10cSrcweir 		SCTAB nTab = aViewData.GetTabNo();
958*cdf0e10cSrcweir 
959*cdf0e10cSrcweir 		sal_uInt16 nCount = pDoc->GetPrintRangeCount(nTab);
960*cdf0e10cSrcweir 		if (!nCount)
961*cdf0e10cSrcweir 			nCount = 1;
962*cdf0e10cSrcweir 		pNewData = new ScPageBreakData(nCount);
963*cdf0e10cSrcweir 
964*cdf0e10cSrcweir 		ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab, 0,0,NULL, NULL, pNewData );
965*cdf0e10cSrcweir 		//	ScPrintFunc fuellt im ctor die PageBreakData
966*cdf0e10cSrcweir 		if ( nCount > 1 )
967*cdf0e10cSrcweir 		{
968*cdf0e10cSrcweir 			aPrintFunc.ResetBreaks(nTab);
969*cdf0e10cSrcweir 			pNewData->AddPages();
970*cdf0e10cSrcweir 		}
971*cdf0e10cSrcweir 
972*cdf0e10cSrcweir 		//	Druckbereiche veraendert?
973*cdf0e10cSrcweir 		if ( bForcePaint || ( pPageBreakData && !pPageBreakData->IsEqual( *pNewData ) ) )
974*cdf0e10cSrcweir 			PaintGrid();
975*cdf0e10cSrcweir 	}
976*cdf0e10cSrcweir 
977*cdf0e10cSrcweir 	delete pPageBreakData;
978*cdf0e10cSrcweir 	pPageBreakData = pNewData;
979*cdf0e10cSrcweir }
980*cdf0e10cSrcweir 
981*cdf0e10cSrcweir 
982*cdf0e10cSrcweir 
983