merge the formfield patch from ooo-build
[ooovba.git] / sc / source / ui / view / tabview2.cxx
blob9d56ebff4e2de0eba3fffa455525960ca05c96a6
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tabview2.cxx,v $
10 * $Revision: 1.21 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
38 #include "scitems.hxx"
39 #include <svx/eeitem.hxx>
42 #include <vcl/timer.hxx>
43 #include <vcl/msgbox.hxx>
44 #include <sfx2/app.hxx>
45 #include <sfx2/viewfrm.hxx>
46 #include <sfx2/bindings.hxx>
47 #include <sfx2/childwin.hxx>
49 #include "attrib.hxx"
50 #include "pagedata.hxx"
51 #include "tabview.hxx"
52 #include "tabvwsh.hxx"
53 #include "printfun.hxx"
54 #include "stlpool.hxx"
55 #include "docsh.hxx"
56 #include "gridwin.hxx"
57 #include "olinewin.hxx"
58 #include "uiitems.hxx"
59 #include "sc.hrc"
60 #include "viewutil.hxx"
61 #include "colrowba.hxx"
62 #include "waitoff.hxx"
63 #include "globstr.hrc"
64 #include "scmod.hxx"
65 #include "tabprotection.hxx"
67 #define SC_BLOCKMODE_NONE 0
68 #define SC_BLOCKMODE_NORMAL 1
69 #define SC_BLOCKMODE_OWN 2
74 // Markier - Funktionen
77 void ScTabView::PaintMarks(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
79 if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
80 if (!ValidRow(nStartRow)) nStartRow = MAXROW;
81 if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
82 if (!ValidRow(nEndRow)) nEndRow = MAXROW;
84 BOOL bLeft = (nStartCol==0 && nEndCol==MAXCOL);
85 BOOL bTop = (nStartRow==0 && nEndRow==MAXROW);
87 if (bLeft)
88 PaintLeftArea( nStartRow, nEndRow );
89 if (bTop)
90 PaintTopArea( nStartCol, nEndCol );
92 aViewData.GetDocument()->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow,
93 aViewData.GetTabNo() );
94 PaintArea( nStartCol, nStartRow, nEndCol, nEndRow, SC_UPDATE_MARKS );
97 BOOL ScTabView::IsMarking( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
99 return bIsBlockMode
100 && nBlockStartX == nCol
101 && nBlockStartY == nRow
102 && nBlockStartZ == nTab;
105 void ScTabView::InitOwnBlockMode()
107 if (!bIsBlockMode)
109 // Wenn keine (alte) Markierung mehr da ist, Anker in SelectionEngine loeschen:
111 ScMarkData& rMark = aViewData.GetMarkData();
112 if (!rMark.IsMarked() && !rMark.IsMultiMarked())
113 GetSelEngine()->CursorPosChanging( FALSE, FALSE );
115 // bIsBlockMode = TRUE;
116 bIsBlockMode = SC_BLOCKMODE_OWN; //! Variable umbenennen!
117 nBlockStartX = 0;
118 nBlockStartY = 0;
119 nBlockStartZ = 0;
120 nBlockEndX = 0;
121 nBlockEndY = 0;
122 nBlockEndZ = 0;
124 SelectionChanged(); // Status wird mit gesetzer Markierung abgefragt
128 void ScTabView::InitBlockMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
129 BOOL bTestNeg, BOOL bCols, BOOL bRows )
131 if (!bIsBlockMode)
133 if (!ValidCol(nCurX)) nCurX = MAXCOL;
134 if (!ValidRow(nCurY)) nCurY = MAXROW;
136 ScMarkData& rMark = aViewData.GetMarkData();
137 SCTAB nTab = aViewData.GetTabNo();
139 // Teil von Markierung aufheben?
140 if (bTestNeg)
142 if ( bCols )
143 bBlockNeg = rMark.IsColumnMarked( nCurX );
144 else if ( bRows )
145 bBlockNeg = rMark.IsRowMarked( nCurY );
146 else
147 bBlockNeg = rMark.IsCellMarked( nCurX, nCurY );
149 else
150 bBlockNeg = FALSE;
151 rMark.SetMarkNegative(bBlockNeg);
153 // bIsBlockMode = TRUE;
154 bIsBlockMode = SC_BLOCKMODE_NORMAL; //! Variable umbenennen!
155 bBlockCols = bCols;
156 bBlockRows = bRows;
157 nBlockStartX = nBlockStartXOrig = nCurX;
158 nBlockStartY = nBlockStartYOrig = nCurY;
159 nBlockStartZ = nCurZ;
160 nBlockEndX = nOldCurX = nBlockStartX;
161 nBlockEndY = nOldCurY = nBlockStartY;
162 nBlockEndZ = nBlockStartZ;
164 if (bBlockCols)
166 nBlockStartY = nBlockStartYOrig = 0;
167 nBlockEndY = MAXROW;
170 if (bBlockRows)
172 nBlockStartX = nBlockStartXOrig = 0;
173 nBlockEndX = MAXCOL;
176 rMark.SetMarkArea( ScRange( nBlockStartX,nBlockStartY, nTab, nBlockEndX,nBlockEndY, nTab ) );
178 #ifdef OLD_SELECTION_PAINT
179 InvertBlockMark( nBlockStartX,nBlockStartY,nBlockEndX,nBlockEndY );
180 #endif
181 UpdateSelectionOverlay();
185 void ScTabView::DoneBlockMode( BOOL bContinue ) // Default FALSE
187 // Wenn zwischen Tabellen- und Header SelectionEngine gewechselt wird,
188 // wird evtl. DeselectAll gerufen, weil die andere Engine keinen Anker hat.
189 // Mit bMoveIsShift wird verhindert, dass dann die Selektion aufgehoben wird.
191 if (bIsBlockMode && !bMoveIsShift)
193 ScMarkData& rMark = aViewData.GetMarkData();
194 BOOL bFlag = rMark.GetMarkingFlag();
195 rMark.SetMarking(FALSE);
197 if (bBlockNeg && !bContinue)
198 rMark.MarkToMulti();
200 if (bContinue)
201 rMark.MarkToMulti();
202 else
204 // Die Tabelle kann an dieser Stelle ungueltig sein, weil DoneBlockMode
205 // aus SetTabNo aufgerufen wird
206 // (z.B. wenn die aktuelle Tabelle von einer anderen View aus geloescht wird)
208 SCTAB nTab = aViewData.GetTabNo();
209 ScDocument* pDoc = aViewData.GetDocument();
210 if ( pDoc->HasTable(nTab) )
211 PaintBlock( TRUE ); // TRUE -> Block loeschen
212 else
213 rMark.ResetMark();
215 // bIsBlockMode = FALSE;
216 bIsBlockMode = SC_BLOCKMODE_NONE; //! Variable umbenennen!
218 rMark.SetMarking(bFlag);
219 rMark.SetMarkNegative(FALSE);
223 void ScTabView::MarkCursor( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
224 BOOL bCols, BOOL bRows, BOOL bCellSelection )
226 if (!ValidCol(nCurX)) nCurX = MAXCOL;
227 if (!ValidRow(nCurY)) nCurY = MAXROW;
229 if (!bIsBlockMode)
231 DBG_ERROR( "MarkCursor nicht im BlockMode" );
232 InitBlockMode( nCurX, nCurY, nCurZ, FALSE, bCols, bRows );
235 if (bCols)
236 nCurY = MAXROW;
237 if (bRows)
238 nCurX = MAXCOL;
240 ScMarkData& rMark = aViewData.GetMarkData();
241 DBG_ASSERT(rMark.IsMarked() || rMark.IsMultiMarked(), "MarkCursor, !IsMarked()");
242 ScRange aMarkRange;
243 rMark.GetMarkArea(aMarkRange);
244 if (( aMarkRange.aStart.Col() != nBlockStartX && aMarkRange.aEnd.Col() != nBlockStartX ) ||
245 ( aMarkRange.aStart.Row() != nBlockStartY && aMarkRange.aEnd.Row() != nBlockStartY ) ||
246 ( bIsBlockMode == SC_BLOCKMODE_OWN ))
248 // Markierung ist veraendert worden
249 // (z.B. MarkToSimple, wenn per negativ alles bis auf ein Rechteck geloescht wurde)
250 // oder nach InitOwnBlockMode wird mit Shift-Klick weitermarkiert...
252 BOOL bOldShift = bMoveIsShift;
253 bMoveIsShift = FALSE; // wirklich umsetzen
254 DoneBlockMode(FALSE); //! direkt Variablen setzen? (-> kein Geflacker)
255 bMoveIsShift = bOldShift;
257 InitBlockMode( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
258 nBlockStartZ, rMark.IsMarkNegative(), bCols, bRows );
261 SCCOL nOldBlockEndX = nBlockEndX;
262 SCROW nOldBlockEndY = nBlockEndY;
264 if ( nCurX != nOldCurX || nCurY != nOldCurY )
266 // Current cursor has moved
268 SCTAB nTab = nCurZ;
270 #ifdef OLD_SELECTION_PAINT
271 SCCOL nDrawStartCol;
272 SCROW nDrawStartRow;
273 SCCOL nDrawEndCol;
274 SCROW nDrawEndRow;
275 #endif
277 // Set old selection area
278 ScUpdateRect aRect( nBlockStartX, nBlockStartY, nOldBlockEndX, nOldBlockEndY );
280 if ( bCellSelection )
282 // Expand selection area accordingly when the current selection ends
283 // with a merged cell.
284 SCsCOL nCurXOffset = 0;
285 SCsCOL nBlockStartXOffset = 0;
286 SCsROW nCurYOffset = 0;
287 SCsROW nBlockStartYOffset = 0;
288 BOOL bBlockStartMerged = FALSE;
289 const ScMergeAttr* pMergeAttr = NULL;
290 ScDocument* pDocument = aViewData.GetDocument();
292 // The following block checks whether or not the "BlockStart" (anchor)
293 // cell is merged. If it's merged, it'll then move the position of the
294 // anchor cell to the corner that's diagonally opposite of the
295 // direction of a current selection area. For instance, if a current
296 // selection is moving in the upperleft direction, the anchor cell will
297 // move to the lower-right corner of the merged anchor cell, and so on.
299 pMergeAttr = static_cast<const ScMergeAttr*>(
300 pDocument->GetAttr( nBlockStartXOrig, nBlockStartYOrig, nTab, ATTR_MERGE ) );
301 if ( pMergeAttr->IsMerged() )
303 SCsCOL nColSpan = pMergeAttr->GetColMerge();
304 SCsROW nRowSpan = pMergeAttr->GetRowMerge();
306 if ( !( nCurX >= nBlockStartXOrig + nColSpan - 1 && nCurY >= nBlockStartYOrig + nRowSpan - 1 ) )
308 nBlockStartX = nCurX >= nBlockStartXOrig ? nBlockStartXOrig : nBlockStartXOrig + nColSpan - 1;
309 nBlockStartY = nCurY >= nBlockStartYOrig ? nBlockStartYOrig : nBlockStartYOrig + nRowSpan - 1;
310 nCurXOffset = nCurX >= nBlockStartXOrig && nCurX < nBlockStartXOrig + nColSpan - 1 ?
311 nBlockStartXOrig - nCurX + nColSpan - 1 : 0;
312 nCurYOffset = nCurY >= nBlockStartYOrig && nCurY < nBlockStartYOrig + nRowSpan - 1 ?
313 nBlockStartYOrig - nCurY + nRowSpan - 1 : 0;
314 bBlockStartMerged = TRUE;
318 // The following block checks whether or not the current cell is
319 // merged. If it is, it'll then set the appropriate X & Y offset
320 // values (nCurXOffset & nCurYOffset) such that the selection area will
321 // grow by those specified offset amounts. Note that the values of
322 // nCurXOffset/nCurYOffset may also be specified in the previous code
323 // block, in which case whichever value is greater will take on.
325 pMergeAttr = static_cast<const ScMergeAttr*>(
326 pDocument->GetAttr( nCurX, nCurY, nTab, ATTR_MERGE ) );
327 if ( pMergeAttr->IsMerged() )
329 SCsCOL nColSpan = pMergeAttr->GetColMerge();
330 SCsROW nRowSpan = pMergeAttr->GetRowMerge();
332 if ( !( nBlockStartX >= nCurX + nColSpan - 1 && nBlockStartY >= nCurY + nRowSpan - 1 ) )
334 if ( nBlockStartX <= nCurX + nColSpan - 1 )
336 SCsCOL nCurXOffsetTemp = nCurX < nCurX + nColSpan - 1 ? nColSpan - 1 : 0;
337 nCurXOffset = nCurXOffset > nCurXOffsetTemp ? nCurXOffset : nCurXOffsetTemp;
339 if ( nBlockStartY <= nCurY + nRowSpan - 1 )
341 SCsROW nCurYOffsetTemp = nCurY < nCurY + nRowSpan - 1 ? nRowSpan - 1 : 0;
342 nCurYOffset = nCurYOffset > nCurYOffsetTemp ? nCurYOffset : nCurYOffsetTemp;
344 if ( !( nBlockStartX <= nCurX && nBlockStartY <= nCurY ) &&
345 !( nBlockStartX > nCurX + nColSpan - 1 && nBlockStartY > nCurY + nRowSpan - 1 ) )
347 nBlockStartXOffset = nBlockStartX > nCurX && nBlockStartX <= nCurX + nColSpan - 1 ? nCurX - nBlockStartX : 0;
348 nBlockStartYOffset = nBlockStartY > nCurY && nBlockStartY <= nCurY + nRowSpan - 1 ? nCurY - nBlockStartY : 0;
352 else
354 // The current cell is not merged. Move the anchor cell to its
355 // original position.
356 if ( !bBlockStartMerged )
358 nBlockStartX = nBlockStartXOrig;
359 nBlockStartY = nBlockStartYOrig;
363 nBlockStartX = nBlockStartX + nBlockStartXOffset >= 0 ? nBlockStartX + nBlockStartXOffset : 0;
364 nBlockStartY = nBlockStartY + nBlockStartYOffset >= 0 ? nBlockStartY + nBlockStartYOffset : 0;
365 nBlockEndX = nCurX + nCurXOffset > MAXCOL ? MAXCOL : nCurX + nCurXOffset;
366 nBlockEndY = nCurY + nCurYOffset > MAXROW ? MAXROW : nCurY + nCurYOffset;
368 else
370 nBlockEndX = nCurX;
371 nBlockEndY = nCurY;
373 // end of "if ( bCellSelection )"
375 // Set new selection area
376 aRect.SetNew( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY );
377 rMark.SetMarkArea( ScRange( nBlockStartX, nBlockStartY, nTab, nBlockEndX, nBlockEndY, nTab ) );
379 #ifdef OLD_SELECTION_PAINT
380 BOOL bCont;
381 BOOL bDraw = aRect.GetXorDiff( nDrawStartCol, nDrawStartRow,
382 nDrawEndCol, nDrawEndRow, bCont );
383 if ( bDraw )
385 //? PutInOrder( nDrawStartCol, nDrawEndCol );
386 //? PutInOrder( nDrawStartRow, nDrawEndRow );
388 HideAllCursors();
389 InvertBlockMark( nDrawStartCol, nDrawStartRow, nDrawEndCol, nDrawEndRow );
390 if (bCont)
392 aRect.GetContDiff( nDrawStartCol, nDrawStartRow, nDrawEndCol, nDrawEndRow );
393 InvertBlockMark( nDrawStartCol, nDrawStartRow, nDrawEndCol, nDrawEndRow );
395 ShowAllCursors();
397 #endif
398 UpdateSelectionOverlay();
400 nOldCurX = nCurX;
401 nOldCurY = nCurY;
403 aViewData.GetViewShell()->UpdateInputHandler();
404 // InvalidateAttribs();
407 if ( !bCols && !bRows )
408 aHdrFunc.SetAnchorFlag( FALSE );
411 void ScTabView::UpdateCopySourceOverlay()
413 for (sal_uInt8 i = 0; i < 4; ++i)
414 if (pGridWin[i] && pGridWin[i]->IsVisible())
415 pGridWin[i]->UpdateCopySourceOverlay();
418 void ScTabView::GetPageMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, SCsCOL& rPageX, SCsROW& rPageY)
420 SCCOL nCurX;
421 SCROW nCurY;
422 aViewData.GetMoveCursor( nCurX,nCurY );
424 ScSplitPos eWhich = aViewData.GetActivePart();
425 ScHSplitPos eWhichX = WhichH( eWhich );
426 ScVSplitPos eWhichY = WhichV( eWhich );
428 SCsCOL nPageX;
429 SCsROW nPageY;
430 if (nMovX >= 0)
431 nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, 1, eWhichX )) * nMovX;
432 else
433 nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, -1, eWhichX )) * nMovX;
435 if (nMovY >= 0)
436 nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, 1, eWhichY )) * nMovY;
437 else
438 nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, -1, eWhichY )) * nMovY;
440 if (nMovX != 0 && nPageX == 0) nPageX = (nMovX>0) ? 1 : -1;
441 if (nMovY != 0 && nPageY == 0) nPageY = (nMovY>0) ? 1 : -1;
443 rPageX = nPageX;
444 rPageY = nPageY;
447 void ScTabView::GetAreaMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
448 SCsCOL& rAreaX, SCsROW& rAreaY, ScFollowMode& rMode)
450 SCCOL nNewX = -1;
451 SCROW nNewY = -1;
452 SCCOL nCurX = -1;
453 SCROW nCurY = -1;
455 if (aViewData.IsRefMode())
457 nNewX = aViewData.GetRefEndX();
458 nNewY = aViewData.GetRefEndY();
460 else if (IsBlockMode())
462 nNewX = nBlockEndX;
463 nNewY = nBlockEndY;
465 else
467 nNewX = nCurX = aViewData.GetCurX();
468 nNewY = nCurY = aViewData.GetCurY();
471 ScDocument* pDoc = aViewData.GetDocument();
472 SCTAB nTab = aViewData.GetTabNo();
474 // FindAreaPos kennt nur -1 oder 1 als Richtung
476 SCsCOLROW i;
477 if ( nMovX > 0 )
478 for ( i=0; i<nMovX; i++ )
479 pDoc->FindAreaPos( nNewX, nNewY, nTab, 1, 0 );
480 if ( nMovX < 0 )
481 for ( i=0; i<-nMovX; i++ )
482 pDoc->FindAreaPos( nNewX, nNewY, nTab, -1, 0 );
483 if ( nMovY > 0 )
484 for ( i=0; i<nMovY; i++ )
485 pDoc->FindAreaPos( nNewX, nNewY, nTab, 0, 1 );
486 if ( nMovY < 0 )
487 for ( i=0; i<-nMovY; i++ )
488 pDoc->FindAreaPos( nNewX, nNewY, nTab, 0, -1 );
490 if (eMode==SC_FOLLOW_JUMP) // unten/rechts nicht zuviel grau anzeigen
492 if (nMovX != 0 && nNewX == MAXCOL)
493 eMode = SC_FOLLOW_LINE;
494 if (nMovY != 0 && nNewY == MAXROW)
495 eMode = SC_FOLLOW_LINE;
498 if (aViewData.IsRefMode())
500 rAreaX = nNewX - aViewData.GetRefEndX();
501 rAreaY = nNewY - aViewData.GetRefEndY();
503 else if (IsBlockMode())
505 rAreaX = nNewX - nBlockEndX;
506 rAreaY = nNewY - nBlockEndY;
508 else
510 rAreaX = nNewX - nCurX;
511 rAreaY = nNewY - nCurY;
513 rMode = eMode;
516 namespace {
518 bool lcl_isCellQualified(ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, bool bSelectLocked, bool bSelectUnlocked)
520 bool bCellProtected = pDoc->HasAttrib(
521 nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_PROTECTED);
523 if (bCellProtected && !bSelectLocked)
524 return false;
526 if (!bCellProtected && !bSelectUnlocked)
527 return false;
529 return true;
532 void lcl_moveCursorByProtRule(
533 SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY, SCTAB nTab, ScDocument* pDoc)
535 bool bSelectLocked = true;
536 bool bSelectUnlocked = true;
537 ScTableProtection* pTabProtection = pDoc->GetTabProtection(nTab);
538 if (pTabProtection && pTabProtection->isProtected())
540 bSelectLocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
541 bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
544 if (nMovX > 0)
546 if (rCol < MAXCOL)
548 for (SCCOL i = 0; i < nMovX; ++i)
550 if (!lcl_isCellQualified(pDoc, rCol+1, rRow, nTab, bSelectLocked, bSelectUnlocked))
551 break;
552 ++rCol;
556 else if (nMovX < 0)
558 if (rCol > 0)
560 nMovX = -nMovX;
561 for (SCCOL i = 0; i < nMovX; ++i)
563 if (!lcl_isCellQualified(pDoc, rCol-1, rRow, nTab, bSelectLocked, bSelectUnlocked))
564 break;
565 --rCol;
570 if (nMovY > 0)
572 if (rRow < MAXROW)
574 for (SCROW i = 0; i < nMovY; ++i)
576 if (!lcl_isCellQualified(pDoc, rCol, rRow+1, nTab, bSelectLocked, bSelectUnlocked))
577 break;
578 ++rRow;
582 else if (nMovY < 0)
584 if (rRow > 0)
586 nMovY = -nMovY;
587 for (SCROW i = 0; i < nMovY; ++i)
589 if (!lcl_isCellQualified(pDoc, rCol, rRow-1, nTab, bSelectLocked, bSelectUnlocked))
590 break;
591 --rRow;
599 void ScTabView::ExpandBlock(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode)
601 if (!nMovX && !nMovY)
602 // Nothing to do. Bail out.
603 return;
605 ScTabViewShell* pViewShell = aViewData.GetViewShell();
606 bool bRefInputMode = pViewShell && pViewShell->IsRefInputMode();
607 if (bRefInputMode && !aViewData.IsRefMode())
608 // initialize formula reference mode if it hasn't already.
609 InitRefMode(aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo(), SC_REFTYPE_REF);
611 ScDocument* pDoc = aViewData.GetDocument();
613 if (aViewData.IsRefMode())
615 // formula reference mode
617 SCCOL nNewX = aViewData.GetRefEndX();
618 SCROW nNewY = aViewData.GetRefEndY();
619 SCTAB nRefTab = aViewData.GetRefEndZ();
621 bool bSelectLocked = true;
622 bool bSelectUnlocked = true;
623 ScTableProtection* pTabProtection = pDoc->GetTabProtection(nRefTab);
624 if (pTabProtection && pTabProtection->isProtected())
626 bSelectLocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
627 bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
630 lcl_moveCursorByProtRule(nNewX, nNewY, nMovX, nMovY, nRefTab, pDoc);
632 if (nMovX)
634 SCCOL nTempX = nNewX;
635 while (pDoc->IsHorOverlapped(nTempX, nNewY, nRefTab))
637 if (nMovX > 0)
638 ++nTempX;
639 else
640 --nTempX;
642 if (lcl_isCellQualified(pDoc, nTempX, nNewY, nRefTab, bSelectLocked, bSelectUnlocked))
643 nNewX = nTempX;
646 if (nMovY)
648 SCROW nTempY = nNewY;
649 while (pDoc->IsVerOverlapped(nNewX, nTempY, nRefTab))
651 if (nMovY > 0)
652 ++nTempY;
653 else
654 --nTempY;
656 if (lcl_isCellQualified(pDoc, nNewX, nTempY, nRefTab, bSelectLocked, bSelectUnlocked))
657 nNewY = nTempY;
660 pDoc->SkipOverlapped(nNewX, nNewY, nRefTab);
661 UpdateRef(nNewX, nNewY, nRefTab);
662 AlignToCursor(nNewX, nNewY, eMode);
664 else
666 // normal selection mode
668 SCTAB nTab = aViewData.GetTabNo();
670 if (!IsBlockMode())
671 InitBlockMode(aViewData.GetCurX(), aViewData.GetCurY(), nTab, true);
673 lcl_moveCursorByProtRule(nBlockEndX, nBlockEndY, nMovX, nMovY, nTab, pDoc);
675 if (nBlockEndX < 0)
676 nBlockEndX = 0;
677 else if (nBlockEndX > MAXCOL)
678 nBlockEndX = MAXCOL;
680 if (nBlockEndY < 0)
681 nBlockEndY = 0;
682 else if (nBlockEndY > MAXROW)
683 nBlockEndY = MAXROW;
685 pDoc->SkipOverlapped(nBlockEndX, nBlockEndY, nTab);
686 MarkCursor(nBlockEndX, nBlockEndY, nTab, false, false, true);
688 // Check if the entire row(s) or column(s) are selected.
689 ScSplitPos eActive = aViewData.GetActivePart();
690 bool bRowSelected = (nBlockStartX == 0 && nBlockEndX == MAXCOL);
691 bool bColSelected = (nBlockStartY == 0 && nBlockEndY == MAXROW);
692 SCsCOL nAlignX = bRowSelected ? aViewData.GetPosX(WhichH(eActive)) : nBlockEndX;
693 SCsROW nAlignY = bColSelected ? aViewData.GetPosY(WhichV(eActive)) : nBlockEndY;
694 AlignToCursor(nAlignX, nAlignY, eMode);
696 UpdateAutoFillMark();
700 void ScTabView::ExpandBlockPage(SCsCOL nMovX, SCsROW nMovY)
702 SCsCOL nPageX;
703 SCsROW nPageY;
704 GetPageMoveEndPosition(nMovX, nMovY, nPageX, nPageY);
705 ExpandBlock(nPageX, nPageY, SC_FOLLOW_FIX);
708 void ScTabView::ExpandBlockArea(SCsCOL nMovX, SCsROW nMovY)
710 SCsCOL nAreaX;
711 SCsROW nAreaY;
712 ScFollowMode eMode;
713 GetAreaMoveEndPosition(nMovX, nMovY, SC_FOLLOW_JUMP, nAreaX, nAreaY, eMode);
714 ExpandBlock(nAreaX, nAreaY, eMode);
717 void ScTabView::UpdateSelectionOverlay()
719 for (USHORT i=0; i<4; i++)
720 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
721 pGridWin[i]->UpdateSelectionOverlay();
724 void ScTabView::UpdateShrinkOverlay()
726 for (USHORT i=0; i<4; i++)
727 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
728 pGridWin[i]->UpdateShrinkOverlay();
731 void ScTabView::UpdateAllOverlays()
733 for (USHORT i=0; i<4; i++)
734 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
735 pGridWin[i]->UpdateAllOverlays();
739 //! PaintBlock in zwei Methoden aufteilen: RepaintBlock und RemoveBlock o.ae.
742 void ScTabView::PaintBlock( BOOL bReset )
744 ScDocument* pDoc = aViewData.GetDocument();
745 ScMarkData& rMark = aViewData.GetMarkData();
746 SCTAB nTab = aViewData.GetTabNo();
747 BOOL bMark = rMark.IsMarked();
748 BOOL bMulti = rMark.IsMultiMarked();
749 if (bMark || bMulti)
751 ScRange aMarkRange;
752 HideAllCursors();
753 if (bMulti)
755 BOOL bFlag = rMark.GetMarkingFlag();
756 rMark.SetMarking(FALSE);
757 rMark.MarkToMulti();
758 rMark.GetMultiMarkArea(aMarkRange);
759 rMark.MarkToSimple();
760 rMark.SetMarking(bFlag);
762 bMark = rMark.IsMarked();
763 bMulti = rMark.IsMultiMarked();
765 else
766 rMark.GetMarkArea(aMarkRange);
768 nBlockStartX = aMarkRange.aStart.Col();
769 nBlockStartY = aMarkRange.aStart.Row();
770 nBlockStartZ = aMarkRange.aStart.Tab();
771 nBlockEndX = aMarkRange.aEnd.Col();
772 nBlockEndY = aMarkRange.aEnd.Row();
773 nBlockEndZ = aMarkRange.aEnd.Tab();
775 BOOL bDidReset = FALSE;
777 if ( nTab>=nBlockStartZ && nTab<=nBlockEndZ )
779 if ( bReset )
781 // Invertieren beim Loeschen nur auf aktiver View
782 if ( aViewData.IsActive() )
784 USHORT i;
785 if ( bMulti )
787 #ifdef OLD_SELECTION_PAINT
788 for (i=0; i<4; i++)
789 if (pGridWin[i] && pGridWin[i]->IsVisible())
790 pGridWin[i]->InvertSimple( nBlockStartX, nBlockStartY,
791 nBlockEndX, nBlockEndY,
792 TRUE, TRUE );
793 #endif
794 rMark.ResetMark();
795 UpdateSelectionOverlay();
796 bDidReset = TRUE;
798 else
800 #ifdef OLD_SELECTION_PAINT
801 // (mis)use InvertBlockMark to remove all of the selection
802 // -> set bBlockNeg (like when removing parts of a selection)
803 // and convert everything to Multi
805 rMark.MarkToMulti();
806 BOOL bOld = bBlockNeg;
807 bBlockNeg = TRUE;
808 // #73130# (negative) MarkArea must be set in case of repaint
809 rMark.SetMarkArea( ScRange( nBlockStartX,nBlockStartY, nTab,
810 nBlockEndX,nBlockEndY, nTab ) );
812 InvertBlockMark( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY );
814 bBlockNeg = bOld;
815 #endif
816 rMark.ResetMark();
817 UpdateSelectionOverlay();
818 bDidReset = TRUE;
821 // repaint if controls are touched (#69680# in both cases)
822 // #i74768# Forms are rendered by DrawingLayer's EndDrawLayers()
823 static bool bSuppressControlExtraStuff(true);
825 if(!bSuppressControlExtraStuff)
827 Rectangle aMMRect = pDoc->GetMMRect(nBlockStartX,nBlockStartY,nBlockEndX,nBlockEndY, nTab);
828 if (pDoc->HasControl( nTab, aMMRect ))
830 for (i=0; i<4; i++)
832 if (pGridWin[i] && pGridWin[i]->IsVisible())
834 // MapMode muss logischer (1/100mm) sein !!!
835 pDoc->InvalidateControls( pGridWin[i], nTab, aMMRect );
836 pGridWin[i]->Update();
843 else
844 PaintMarks( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY );
847 if ( bReset && !bDidReset )
848 rMark.ResetMark();
850 ShowAllCursors();
854 void ScTabView::SelectAll( BOOL bContinue )
856 ScMarkData& rMark = aViewData.GetMarkData();
857 SCTAB nTab = aViewData.GetTabNo();
859 if (rMark.IsMarked())
861 ScRange aMarkRange;
862 rMark.GetMarkArea( aMarkRange );
863 if ( aMarkRange == ScRange( 0,0,nTab, MAXCOL,MAXROW,nTab ) )
864 return;
867 DoneBlockMode( bContinue );
868 InitBlockMode( 0,0,nTab );
869 MarkCursor( MAXCOL,MAXROW,nTab );
871 SelectionChanged();
874 void ScTabView::SelectAllTables()
876 ScDocument* pDoc = aViewData.GetDocument();
877 ScMarkData& rMark = aViewData.GetMarkData();
878 // SCTAB nTab = aViewData.GetTabNo();
879 SCTAB nCount = pDoc->GetTableCount();
881 if (nCount>1)
883 for (SCTAB i=0; i<nCount; i++)
884 rMark.SelectTable( i, TRUE );
886 // Markierungen werden per Default nicht pro Tabelle gehalten
887 // pDoc->ExtendMarksFromTable( nTab );
889 aViewData.GetDocShell()->PostPaintExtras();
890 SfxBindings& rBind = aViewData.GetBindings();
891 rBind.Invalidate( FID_FILL_TAB );
892 rBind.Invalidate( FID_TAB_DESELECTALL );
896 void ScTabView::DeselectAllTables()
898 ScDocument* pDoc = aViewData.GetDocument();
899 ScMarkData& rMark = aViewData.GetMarkData();
900 SCTAB nTab = aViewData.GetTabNo();
901 SCTAB nCount = pDoc->GetTableCount();
903 for (SCTAB i=0; i<nCount; i++)
904 rMark.SelectTable( i, ( i == nTab ) );
906 aViewData.GetDocShell()->PostPaintExtras();
907 SfxBindings& rBind = aViewData.GetBindings();
908 rBind.Invalidate( FID_FILL_TAB );
909 rBind.Invalidate( FID_TAB_DESELECTALL );
912 BOOL lcl_FitsInWindow( double fScaleX, double fScaleY, USHORT nZoom,
913 long nWindowX, long nWindowY, ScDocument* pDoc, SCTAB nTab,
914 SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
915 SCCOL nFixPosX, SCROW nFixPosY )
917 double fZoomFactor = (double)Fraction(nZoom,100);
918 fScaleX *= fZoomFactor;
919 fScaleY *= fZoomFactor;
921 long nBlockX = 0;
922 SCCOL nCol;
923 for (nCol=0; nCol<nFixPosX; nCol++)
925 // for frozen panes, add both parts
926 USHORT nColTwips = pDoc->GetColWidth( nCol, nTab );
927 if (nColTwips)
929 nBlockX += (long)(nColTwips * fScaleX);
930 if (nBlockX > nWindowX)
931 return FALSE;
934 for (nCol=nStartCol; nCol<=nEndCol; nCol++)
936 USHORT nColTwips = pDoc->GetColWidth( nCol, nTab );
937 if (nColTwips)
939 nBlockX += (long)(nColTwips * fScaleX);
940 if (nBlockX > nWindowX)
941 return FALSE;
945 long nBlockY = 0;
946 for (SCROW nRow = 0; nRow <= nFixPosY-1; ++nRow)
948 if (pDoc->RowHidden(nRow, nTab))
949 continue;
951 // for frozen panes, add both parts
952 USHORT nRowTwips = pDoc->GetRowHeight(nRow, nTab);
953 if (nRowTwips)
955 nBlockY += (long)(nRowTwips * fScaleY);
956 if (nBlockY > nWindowY)
957 return FALSE;
960 for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
962 USHORT nRowTwips = pDoc->GetRowHeight(nRow, nTab);
963 if (nRowTwips)
965 nBlockY += (long)(nRowTwips * fScaleY);
966 if (nBlockY > nWindowY)
967 return FALSE;
971 return TRUE;
974 USHORT ScTabView::CalcZoom( SvxZoomType eType, USHORT nOldZoom )
976 USHORT nZoom = 0; // Ergebnis
978 switch ( eType )
980 case SVX_ZOOM_PERCENT: // rZoom ist kein besonderer prozentualer Wert
981 nZoom = nOldZoom;
982 break;
984 case SVX_ZOOM_OPTIMAL: // nZoom entspricht der optimalen Gr"o\se
986 ScMarkData& rMark = aViewData.GetMarkData();
987 ScDocument* pDoc = aViewData.GetDocument();
989 if (!rMark.IsMarked() && !rMark.IsMultiMarked())
990 nZoom = 100; // nothing selected
991 else
993 SCTAB nTab = aViewData.GetTabNo();
994 ScRange aMarkRange;
995 if ( aViewData.GetSimpleArea( aMarkRange ) != SC_MARK_SIMPLE )
996 rMark.GetMultiMarkArea( aMarkRange );
998 SCCOL nStartCol = aMarkRange.aStart.Col();
999 SCROW nStartRow = aMarkRange.aStart.Row();
1000 SCTAB nStartTab = aMarkRange.aStart.Tab();
1001 SCCOL nEndCol = aMarkRange.aEnd.Col();
1002 SCROW nEndRow = aMarkRange.aEnd.Row();
1003 SCTAB nEndTab = aMarkRange.aEnd.Tab();
1005 if ( nTab < nStartTab && nTab > nEndTab )
1006 nTab = nStartTab;
1008 ScSplitPos eUsedPart = aViewData.GetActivePart();
1010 SCCOL nFixPosX = 0;
1011 SCROW nFixPosY = 0;
1012 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
1014 // use right part
1015 eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
1016 nFixPosX = aViewData.GetFixPosX();
1017 if ( nStartCol < nFixPosX )
1018 nStartCol = nFixPosX;
1020 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1022 // use bottom part
1023 eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
1024 nFixPosY = aViewData.GetFixPosY();
1025 if ( nStartRow < nFixPosY )
1026 nStartRow = nFixPosY;
1029 if (pGridWin[eUsedPart])
1031 // Because scale is rounded to pixels, the only reliable way to find
1032 // the right scale is to check if a zoom fits
1034 Size aWinSize = pGridWin[eUsedPart]->GetOutputSizePixel();
1036 // for frozen panes, use sum of both parts for calculation
1038 if ( nFixPosX != 0 )
1039 aWinSize.Width() += GetGridWidth( SC_SPLIT_LEFT );
1040 if ( nFixPosY != 0 )
1041 aWinSize.Height() += GetGridHeight( SC_SPLIT_TOP );
1043 ScDocShell* pDocSh = aViewData.GetDocShell();
1044 double nPPTX = ScGlobal::nScreenPPTX / pDocSh->GetOutputFactor();
1045 double nPPTY = ScGlobal::nScreenPPTY;
1047 USHORT nMin = MINZOOM;
1048 USHORT nMax = MAXZOOM;
1049 while ( nMax > nMin )
1051 USHORT nTest = (nMin+nMax+1)/2;
1052 if ( lcl_FitsInWindow(
1053 nPPTX, nPPTY, nTest, aWinSize.Width(), aWinSize.Height(),
1054 pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow,
1055 nFixPosX, nFixPosY ) )
1056 nMin = nTest;
1057 else
1058 nMax = nTest-1;
1060 DBG_ASSERT( nMin == nMax, "Schachtelung ist falsch" );
1061 nZoom = nMin;
1063 if ( nZoom != nOldZoom )
1065 // scroll to block only in active split part
1066 // (the part for which the size was calculated)
1068 if ( nStartCol <= nEndCol )
1069 aViewData.SetPosX( WhichH(eUsedPart), nStartCol );
1070 if ( nStartRow <= nEndRow )
1071 aViewData.SetPosY( WhichV(eUsedPart), nStartRow );
1076 break;
1078 case SVX_ZOOM_WHOLEPAGE: // nZoom entspricht der ganzen Seite oder
1079 case SVX_ZOOM_PAGEWIDTH: // nZoom entspricht der Seitenbreite
1081 SCTAB nCurTab = aViewData.GetTabNo();
1082 ScDocument* pDoc = aViewData.GetDocument();
1083 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
1084 SfxStyleSheetBase* pStyleSheet =
1085 pStylePool->Find( pDoc->GetPageStyle( nCurTab ),
1086 SFX_STYLE_FAMILY_PAGE );
1088 DBG_ASSERT( pStyleSheet, "PageStyle not found :-/" );
1090 if ( pStyleSheet )
1092 ScPrintFunc aPrintFunc( aViewData.GetDocShell(),
1093 aViewData.GetViewShell()->GetPrinter(TRUE),
1094 nCurTab );
1096 Size aPageSize = aPrintFunc.GetDataSize();
1098 // use the size of the largest GridWin for normal split,
1099 // or both combined for frozen panes, with the (document) size
1100 // of the frozen part added to the page size
1101 // (with frozen panes, the size of the individual parts
1102 // depends on the scale that is to be calculated)
1104 if ( !pGridWin[SC_SPLIT_BOTTOMLEFT] ) return 0;
1105 Size aWinSize = pGridWin[SC_SPLIT_BOTTOMLEFT]->GetOutputSizePixel();
1106 ScSplitMode eHMode = aViewData.GetHSplitMode();
1107 if ( eHMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_BOTTOMRIGHT] )
1109 long nOtherWidth = pGridWin[SC_SPLIT_BOTTOMRIGHT]->
1110 GetOutputSizePixel().Width();
1111 if ( eHMode == SC_SPLIT_FIX )
1113 aWinSize.Width() += nOtherWidth;
1114 for ( SCCOL nCol = aViewData.GetPosX(SC_SPLIT_LEFT);
1115 nCol < aViewData.GetFixPosX(); nCol++ )
1116 aPageSize.Width() += pDoc->GetColWidth( nCol, nCurTab );
1118 else if ( nOtherWidth > aWinSize.Width() )
1119 aWinSize.Width() = nOtherWidth;
1121 ScSplitMode eVMode = aViewData.GetVSplitMode();
1122 if ( eVMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_TOPLEFT] )
1124 long nOtherHeight = pGridWin[SC_SPLIT_TOPLEFT]->
1125 GetOutputSizePixel().Height();
1126 if ( eVMode == SC_SPLIT_FIX )
1128 aWinSize.Height() += nOtherHeight;
1129 aPageSize.Height() += pDoc->GetRowHeight(
1130 aViewData.GetPosY(SC_SPLIT_TOP),
1131 aViewData.GetFixPosY()-1, nCurTab);
1133 else if ( nOtherHeight > aWinSize.Height() )
1134 aWinSize.Height() = nOtherHeight;
1137 double nPPTX = ScGlobal::nScreenPPTX / aViewData.GetDocShell()->GetOutputFactor();
1138 double nPPTY = ScGlobal::nScreenPPTY;
1140 long nZoomX = (long) ( aWinSize.Width() * 100 /
1141 ( aPageSize.Width() * nPPTX ) );
1142 long nZoomY = (long) ( aWinSize.Height() * 100 /
1143 ( aPageSize.Height() * nPPTY ) );
1144 long nNew = nZoomX;
1146 if (eType == SVX_ZOOM_WHOLEPAGE && nZoomY < nNew)
1147 nNew = nZoomY;
1149 nZoom = (USHORT) nNew;
1152 break;
1154 default:
1155 DBG_ERROR("Unknown Zoom-Revision");
1156 nZoom = 0;
1159 return nZoom;
1162 // wird z.B. gerufen, wenn sich das View-Fenster verschiebt:
1164 void ScTabView::StopMarking()
1166 ScSplitPos eActive = aViewData.GetActivePart();
1167 if (pGridWin[eActive])
1168 pGridWin[eActive]->StopMarking();
1170 ScHSplitPos eH = WhichH(eActive);
1171 if (pColBar[eH])
1172 pColBar[eH]->StopMarking();
1174 ScVSplitPos eV = WhichV(eActive);
1175 if (pRowBar[eV])
1176 pRowBar[eV]->StopMarking();
1179 void ScTabView::HideNoteMarker()
1181 for (USHORT i=0; i<4; i++)
1182 if (pGridWin[i] && pGridWin[i]->IsVisible())
1183 pGridWin[i]->HideNoteMarker();
1186 void ScTabView::MakeDrawLayer()
1188 if (!pDrawView)
1190 aViewData.GetDocShell()->MakeDrawLayer();
1192 // pDrawView wird per Notify gesetzt
1193 DBG_ASSERT(pDrawView,"ScTabView::MakeDrawLayer funktioniert nicht");
1195 // #114409#
1196 for(sal_uInt16 a(0); a < 4; a++)
1198 if(pGridWin[a])
1200 pGridWin[a]->DrawLayerCreated();
1206 void ScTabView::ErrorMessage( USHORT nGlobStrId )
1208 if ( SC_MOD()->IsInExecuteDrop() )
1210 // #i28468# don't show error message when called from Drag&Drop, silently abort instead
1211 return;
1214 StopMarking(); // falls per Focus aus MouseButtonDown aufgerufen
1216 Window* pParent = aViewData.GetDialogParent();
1217 ScWaitCursorOff aWaitOff( pParent );
1218 BOOL bFocus = pParent && pParent->HasFocus();
1220 if(nGlobStrId==STR_PROTECTIONERR)
1222 if(aViewData.GetDocShell()->IsReadOnly())
1224 nGlobStrId=STR_READONLYERR;
1228 InfoBox aBox( pParent, ScGlobal::GetRscString( nGlobStrId ) );
1229 aBox.Execute();
1230 if (bFocus)
1231 pParent->GrabFocus();
1234 Window* ScTabView::GetParentOrChild( USHORT nChildId )
1236 SfxViewFrame* pViewFrm = aViewData.GetViewShell()->GetViewFrame();
1238 if ( pViewFrm->HasChildWindow(nChildId) )
1240 SfxChildWindow* pChild = pViewFrm->GetChildWindow(nChildId);
1241 if (pChild)
1243 Window* pWin = pChild->GetWindow();
1244 if (pWin && pWin->IsVisible())
1245 return pWin;
1249 return aViewData.GetDialogParent();
1252 void ScTabView::UpdatePageBreakData( BOOL bForcePaint )
1254 ScPageBreakData* pNewData = NULL;
1256 if (aViewData.IsPagebreakMode())
1258 ScDocShell* pDocSh = aViewData.GetDocShell();
1259 ScDocument* pDoc = pDocSh->GetDocument();
1260 SCTAB nTab = aViewData.GetTabNo();
1262 USHORT nCount = pDoc->GetPrintRangeCount(nTab);
1263 if (!nCount)
1264 nCount = 1;
1265 pNewData = new ScPageBreakData(nCount);
1267 ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab, 0,0,NULL, NULL, pNewData );
1268 // ScPrintFunc fuellt im ctor die PageBreakData
1269 if ( nCount > 1 )
1271 aPrintFunc.ResetBreaks(nTab);
1272 pNewData->AddPages();
1275 // Druckbereiche veraendert?
1276 if ( bForcePaint || ( pPageBreakData && !pPageBreakData->IsEqual( *pNewData ) ) )
1277 PaintGrid();
1280 delete pPageBreakData;
1281 pPageBreakData = pNewData;