Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / sc / source / ui / view / tabview2.cxx
blob59eec9b2b89473e0978ce52994b821c910d9489b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "scitems.hxx"
22 #include <editeng/eeitem.hxx>
23 #include <vcl/timer.hxx>
24 #include <vcl/msgbox.hxx>
25 #include <sfx2/app.hxx>
26 #include <sfx2/viewfrm.hxx>
27 #include <sfx2/bindings.hxx>
28 #include <sfx2/childwin.hxx>
30 #include "attrib.hxx"
31 #include "pagedata.hxx"
32 #include "tabview.hxx"
33 #include "tabvwsh.hxx"
34 #include "printfun.hxx"
35 #include "stlpool.hxx"
36 #include "docsh.hxx"
37 #include "gridwin.hxx"
38 #include "olinewin.hxx"
39 #include "uiitems.hxx"
40 #include "sc.hrc"
41 #include "viewutil.hxx"
42 #include "colrowba.hxx"
43 #include "waitoff.hxx"
44 #include "globstr.hrc"
45 #include "scmod.hxx"
46 #include "tabprotection.hxx"
47 #include "markdata.hxx"
49 namespace {
51 bool isCellQualified(ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, bool bSelectLocked, bool bSelectUnlocked)
53 bool bCellProtected = pDoc->HasAttrib(
54 nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_PROTECTED);
56 if (bCellProtected && !bSelectLocked)
57 return false;
59 if (!bCellProtected && !bSelectUnlocked)
60 return false;
62 return true;
65 void moveCursorByProtRule(
66 SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY, SCTAB nTab, ScDocument* pDoc)
68 bool bSelectLocked = true;
69 bool bSelectUnlocked = true;
70 ScTableProtection* pTabProtection = pDoc->GetTabProtection(nTab);
71 if (pTabProtection && pTabProtection->isProtected())
73 bSelectLocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
74 bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
77 if (nMovX > 0)
79 for (SCCOL i = 0; i < nMovX && rCol < MAXCOL; ++i)
81 if (!isCellQualified(pDoc, rCol+1, rRow, nTab, bSelectLocked, bSelectUnlocked))
82 break;
83 ++rCol;
86 else if (nMovX < 0)
88 for (SCCOL i = 0; i > nMovX && rCol > 0; --i)
90 if (!isCellQualified(pDoc, rCol-1, rRow, nTab, bSelectLocked, bSelectUnlocked))
91 break;
92 --rCol;
96 if (nMovY > 0)
98 for (SCROW i = 0; i < nMovY && rRow < MAXROW; ++i)
100 if (!isCellQualified(pDoc, rCol, rRow+1, nTab, bSelectLocked, bSelectUnlocked))
101 break;
102 ++rRow;
105 else if (nMovY < 0)
107 for (SCROW i = 0; i > nMovY && rRow > 0; --i)
109 if (!isCellQualified(pDoc, rCol, rRow-1, nTab, bSelectLocked, bSelectUnlocked))
110 break;
111 --rRow;
116 bool checkBoundary(SCCOL& rCol, SCROW& rRow)
118 bool bGood = true;
119 if (rCol < 0)
121 rCol = 0;
122 bGood = false;
124 else if (rCol > MAXCOL)
126 rCol = MAXCOL;
127 bGood = false;
130 if (rRow < 0)
132 rRow = 0;
133 bGood = false;
135 else if (rRow > MAXROW)
137 rRow = MAXROW;
138 bGood = false;
140 return bGood;
143 void moveCursorByMergedCell(
144 SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY, SCTAB nTab,
145 ScDocument* pDoc, const ScViewData& rViewData)
147 SCCOL nOrigX = rViewData.GetCurX();
148 SCROW nOrigY = rViewData.GetCurY();
150 ScTableProtection* pTabProtection = pDoc->GetTabProtection(nTab);
151 bool bSelectLocked = true;
152 bool bSelectUnlocked = true;
153 if (pTabProtection && pTabProtection->isProtected())
155 bSelectLocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
156 bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
159 const ScMergeAttr* pMergeAttr = static_cast<const ScMergeAttr*>(
160 pDoc->GetAttr(nOrigX, nOrigY, nTab, ATTR_MERGE));
162 bool bOriginMerged = false;
163 SCsCOL nColSpan = 1;
164 SCsROW nRowSpan = 1;
165 if (pMergeAttr && pMergeAttr->IsMerged())
167 nColSpan = pMergeAttr->GetColMerge();
168 nRowSpan = pMergeAttr->GetRowMerge();
169 bOriginMerged = true;
172 if (nMovX > 0)
174 SCCOL nOld = rCol;
175 if (bOriginMerged)
177 // Original cell is merged. Push the block end outside the merged region.
178 if (nOrigX < MAXCOL && nOrigX < rCol && rCol <= nOrigX + nColSpan - 1)
179 rCol = nOrigX + nColSpan;
181 else
183 pDoc->SkipOverlapped(rCol, rRow, nTab);
186 if (nOld < rCol)
188 // The block end has moved. Check the protection setting and move back if needed.
189 checkBoundary(rCol, rRow);
190 if (!isCellQualified(pDoc, rCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
191 --rCol;
194 if (nMovX < 0)
196 SCCOL nOld = rCol;
197 if (bOriginMerged)
199 if (nOrigX > 0 && nOrigX <= rCol && rCol < nOrigX + nColSpan - 1)
200 // Block end is still within the merged region. Push it outside.
201 rCol = nOrigX - 1;
203 else
205 pDoc->SkipOverlapped(rCol, rRow, nTab);
208 if (nOld > rCol)
210 // The block end has moved. Check the protection setting and move back if needed.
211 checkBoundary(rCol, rRow);
212 if (!isCellQualified(pDoc, rCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
213 ++rCol;
216 if (nMovY > 0)
218 SCROW nOld = rRow;
219 if (bOriginMerged)
221 // Original cell is merged. Push the block end outside the merged region.
222 if (nOrigY < MAXROW && nOrigY < rRow && rRow <= nOrigY + nRowSpan - 1)
223 rRow = nOrigY + nRowSpan;
225 else
227 pDoc->SkipOverlapped(rCol, rRow, nTab);
230 if (nOld < rRow)
232 // The block end has moved. Check the protection setting and move back if needed.
233 checkBoundary(rCol, rRow);
234 if (!isCellQualified(pDoc, rCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
235 --rRow;
238 if (nMovY < 0)
240 SCROW nOld = rRow;
241 if (bOriginMerged)
243 if (nOrigY > 0 && nOrigY <= rRow && rRow < nOrigY + nRowSpan - 1)
244 // Block end is still within the merged region. Push it outside.
245 rRow = nOrigY - 1;
247 else
249 pDoc->SkipOverlapped(rCol, rRow, nTab);
252 if (nOld > rRow)
254 // The block end has moved. Check the protection setting and move back if needed.
255 checkBoundary(rCol, rRow);
256 if (!isCellQualified(pDoc, rCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
257 ++rRow;
264 void ScTabView::PaintMarks(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
266 if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
267 if (!ValidRow(nStartRow)) nStartRow = MAXROW;
268 if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
269 if (!ValidRow(nEndRow)) nEndRow = MAXROW;
271 bool bLeft = (nStartCol==0 && nEndCol==MAXCOL);
272 bool bTop = (nStartRow==0 && nEndRow==MAXROW);
274 if (bLeft)
275 PaintLeftArea( nStartRow, nEndRow );
276 if (bTop)
277 PaintTopArea( nStartCol, nEndCol );
279 aViewData.GetDocument()->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow,
280 aViewData.GetTabNo() );
281 PaintArea( nStartCol, nStartRow, nEndCol, nEndRow, SC_UPDATE_MARKS );
284 bool ScTabView::IsMarking( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
286 return IsBlockMode()
287 && nBlockStartX == nCol
288 && nBlockStartY == nRow
289 && nBlockStartZ == nTab;
292 void ScTabView::InitOwnBlockMode()
294 if (!IsBlockMode())
296 // Wenn keine (alte) Markierung mehr da ist, Anker in SelectionEngine loeschen:
298 ScMarkData& rMark = aViewData.GetMarkData();
299 if (!rMark.IsMarked() && !rMark.IsMultiMarked())
300 GetSelEngine()->CursorPosChanging( false, false );
302 meBlockMode = Own;
303 nBlockStartX = 0;
304 nBlockStartY = 0;
305 nBlockStartZ = 0;
306 nBlockEndX = 0;
307 nBlockEndY = 0;
308 nBlockEndZ = 0;
310 SelectionChanged(); // Status wird mit gesetzer Markierung abgefragt
314 void ScTabView::InitBlockMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
315 bool bTestNeg, bool bCols, bool bRows )
317 if (!IsBlockMode())
319 if (!ValidCol(nCurX)) nCurX = MAXCOL;
320 if (!ValidRow(nCurY)) nCurY = MAXROW;
322 ScMarkData& rMark = aViewData.GetMarkData();
323 SCTAB nTab = aViewData.GetTabNo();
325 // Teil von Markierung aufheben?
326 if (bTestNeg)
328 if ( bCols )
329 bBlockNeg = rMark.IsColumnMarked( nCurX );
330 else if ( bRows )
331 bBlockNeg = rMark.IsRowMarked( nCurY );
332 else
333 bBlockNeg = rMark.IsCellMarked( nCurX, nCurY );
335 else
336 bBlockNeg = false;
337 rMark.SetMarkNegative(bBlockNeg);
339 meBlockMode = Normal;
340 bBlockCols = bCols;
341 bBlockRows = bRows;
342 nBlockStartX = nBlockStartXOrig = nCurX;
343 nBlockStartY = nBlockStartYOrig = nCurY;
344 nBlockStartZ = nCurZ;
345 nBlockEndX = nOldCurX = nBlockStartX;
346 nBlockEndY = nOldCurY = nBlockStartY;
347 nBlockEndZ = nBlockStartZ;
349 if (bBlockCols)
351 nBlockStartY = nBlockStartYOrig = 0;
352 nBlockEndY = MAXROW;
355 if (bBlockRows)
357 nBlockStartX = nBlockStartXOrig = 0;
358 nBlockEndX = MAXCOL;
361 rMark.SetMarkArea( ScRange( nBlockStartX,nBlockStartY, nTab, nBlockEndX,nBlockEndY, nTab ) );
363 UpdateSelectionOverlay();
367 void ScTabView::DoneBlockMode( bool bContinue )
369 // Wenn zwischen Tabellen- und Header SelectionEngine gewechselt wird,
370 // wird evtl. DeselectAll gerufen, weil die andere Engine keinen Anker hat.
371 // Mit bMoveIsShift wird verhindert, dass dann die Selektion aufgehoben wird.
373 if (IsBlockMode() && !bMoveIsShift)
375 ScMarkData& rMark = aViewData.GetMarkData();
376 bool bFlag = rMark.GetMarkingFlag();
377 rMark.SetMarking(false);
379 if (bBlockNeg && !bContinue)
380 rMark.MarkToMulti();
382 if (bContinue)
383 rMark.MarkToMulti();
384 else
386 // Die Tabelle kann an dieser Stelle ungueltig sein, weil DoneBlockMode
387 // aus SetTabNo aufgerufen wird
388 // (z.B. wenn die aktuelle Tabelle von einer anderen View aus geloescht wird)
390 SCTAB nTab = aViewData.GetTabNo();
391 ScDocument* pDoc = aViewData.GetDocument();
392 if ( pDoc->HasTable(nTab) )
393 PaintBlock( true ); // true -> Block loeschen
394 else
395 rMark.ResetMark();
397 meBlockMode = None;
399 rMark.SetMarking(bFlag);
400 rMark.SetMarkNegative(false);
404 bool ScTabView::IsBlockMode() const
406 return meBlockMode != None;
409 void ScTabView::MarkCursor( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
410 bool bCols, bool bRows, bool bCellSelection )
412 if (!ValidCol(nCurX)) nCurX = MAXCOL;
413 if (!ValidRow(nCurY)) nCurY = MAXROW;
415 if (!IsBlockMode())
417 OSL_FAIL( "MarkCursor nicht im BlockMode" );
418 InitBlockMode( nCurX, nCurY, nCurZ, false, bCols, bRows );
421 if (bCols)
422 nCurY = MAXROW;
423 if (bRows)
424 nCurX = MAXCOL;
426 ScMarkData& rMark = aViewData.GetMarkData();
427 OSL_ENSURE(rMark.IsMarked() || rMark.IsMultiMarked(), "MarkCursor, !IsMarked()");
428 ScRange aMarkRange;
429 rMark.GetMarkArea(aMarkRange);
430 if (( aMarkRange.aStart.Col() != nBlockStartX && aMarkRange.aEnd.Col() != nBlockStartX ) ||
431 ( aMarkRange.aStart.Row() != nBlockStartY && aMarkRange.aEnd.Row() != nBlockStartY ) ||
432 ( meBlockMode == Own ))
434 // Markierung ist veraendert worden
435 // (z.B. MarkToSimple, wenn per negativ alles bis auf ein Rechteck geloescht wurde)
436 // oder nach InitOwnBlockMode wird mit Shift-Klick weitermarkiert...
438 bool bOldShift = bMoveIsShift;
439 bMoveIsShift = false; // wirklich umsetzen
440 DoneBlockMode(false); //! direkt Variablen setzen? (-> kein Geflacker)
441 bMoveIsShift = bOldShift;
443 InitBlockMode( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
444 nBlockStartZ, rMark.IsMarkNegative(), bCols, bRows );
447 if ( nCurX != nOldCurX || nCurY != nOldCurY )
449 // Current cursor has moved
451 SCTAB nTab = nCurZ;
453 if ( bCellSelection )
455 // Expand selection area accordingly when the current selection ends
456 // with a merged cell.
457 SCsCOL nCurXOffset = 0;
458 SCsCOL nBlockStartXOffset = 0;
459 SCsROW nCurYOffset = 0;
460 SCsROW nBlockStartYOffset = 0;
461 bool bBlockStartMerged = false;
462 const ScMergeAttr* pMergeAttr = NULL;
463 ScDocument* pDocument = aViewData.GetDocument();
465 // The following block checks whether or not the "BlockStart" (anchor)
466 // cell is merged. If it's merged, it'll then move the position of the
467 // anchor cell to the corner that's diagonally opposite of the
468 // direction of a current selection area. For instance, if a current
469 // selection is moving in the upperleft direction, the anchor cell will
470 // move to the lower-right corner of the merged anchor cell, and so on.
472 pMergeAttr = static_cast<const ScMergeAttr*>(
473 pDocument->GetAttr( nBlockStartXOrig, nBlockStartYOrig, nTab, ATTR_MERGE ) );
474 if ( pMergeAttr->IsMerged() )
476 SCsCOL nColSpan = pMergeAttr->GetColMerge();
477 SCsROW nRowSpan = pMergeAttr->GetRowMerge();
479 if ( !( nCurX >= nBlockStartXOrig + nColSpan - 1 && nCurY >= nBlockStartYOrig + nRowSpan - 1 ) )
481 nBlockStartX = nCurX >= nBlockStartXOrig ? nBlockStartXOrig : nBlockStartXOrig + nColSpan - 1;
482 nBlockStartY = nCurY >= nBlockStartYOrig ? nBlockStartYOrig : nBlockStartYOrig + nRowSpan - 1;
483 nCurXOffset = (nCurX >= nBlockStartXOrig && nCurX < nBlockStartXOrig + nColSpan - 1) ?
484 nBlockStartXOrig - nCurX + nColSpan - 1 : 0;
485 nCurYOffset = (nCurY >= nBlockStartYOrig && nCurY < nBlockStartYOrig + nRowSpan - 1) ?
486 nBlockStartYOrig - nCurY + nRowSpan - 1 : 0;
487 bBlockStartMerged = sal_True;
491 // The following block checks whether or not the current cell is
492 // merged. If it is, it'll then set the appropriate X & Y offset
493 // values (nCurXOffset & nCurYOffset) such that the selection area will
494 // grow by those specified offset amounts. Note that the values of
495 // nCurXOffset/nCurYOffset may also be specified in the previous code
496 // block, in which case whichever value is greater will take on.
498 pMergeAttr = static_cast<const ScMergeAttr*>(
499 pDocument->GetAttr( nCurX, nCurY, nTab, ATTR_MERGE ) );
500 if ( pMergeAttr->IsMerged() )
502 SCsCOL nColSpan = pMergeAttr->GetColMerge();
503 SCsROW nRowSpan = pMergeAttr->GetRowMerge();
505 if ( !( nBlockStartX >= nCurX + nColSpan - 1 && nBlockStartY >= nCurY + nRowSpan - 1 ) )
507 if ( nBlockStartX <= nCurX + nColSpan - 1 )
509 SCsCOL nCurXOffsetTemp = (nCurX < nCurX + nColSpan - 1) ? nColSpan - 1 : 0;
510 nCurXOffset = nCurXOffset > nCurXOffsetTemp ? nCurXOffset : nCurXOffsetTemp;
512 if ( nBlockStartY <= nCurY + nRowSpan - 1 )
514 SCsROW nCurYOffsetTemp = (nCurY < nCurY + nRowSpan - 1) ? nRowSpan - 1 : 0;
515 nCurYOffset = nCurYOffset > nCurYOffsetTemp ? nCurYOffset : nCurYOffsetTemp;
517 if ( !( nBlockStartX <= nCurX && nBlockStartY <= nCurY ) &&
518 !( nBlockStartX > nCurX + nColSpan - 1 && nBlockStartY > nCurY + nRowSpan - 1 ) )
520 nBlockStartXOffset = (nBlockStartX > nCurX && nBlockStartX <= nCurX + nColSpan - 1) ? nCurX - nBlockStartX : 0;
521 nBlockStartYOffset = (nBlockStartY > nCurY && nBlockStartY <= nCurY + nRowSpan - 1) ? nCurY - nBlockStartY : 0;
525 else
527 // The current cell is not merged. Move the anchor cell to its
528 // original position.
529 if ( !bBlockStartMerged )
531 nBlockStartX = nBlockStartXOrig;
532 nBlockStartY = nBlockStartYOrig;
536 nBlockStartX = nBlockStartX + nBlockStartXOffset >= 0 ? nBlockStartX + nBlockStartXOffset : 0;
537 nBlockStartY = nBlockStartY + nBlockStartYOffset >= 0 ? nBlockStartY + nBlockStartYOffset : 0;
538 nBlockEndX = nCurX + nCurXOffset > MAXCOL ? MAXCOL : nCurX + nCurXOffset;
539 nBlockEndY = nCurY + nCurYOffset > MAXROW ? MAXROW : nCurY + nCurYOffset;
541 else
543 nBlockEndX = nCurX;
544 nBlockEndY = nCurY;
547 // Set new selection area
548 rMark.SetMarkArea( ScRange( nBlockStartX, nBlockStartY, nTab, nBlockEndX, nBlockEndY, nTab ) );
550 UpdateSelectionOverlay();
551 SelectionChanged();
553 nOldCurX = nCurX;
554 nOldCurY = nCurY;
556 aViewData.GetViewShell()->UpdateInputHandler();
559 if ( !bCols && !bRows )
560 aHdrFunc.SetAnchorFlag( false );
563 void ScTabView::GetPageMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, SCsCOL& rPageX, SCsROW& rPageY)
565 SCCOL nCurX;
566 SCROW nCurY;
567 if (aViewData.IsRefMode())
569 nCurX = aViewData.GetRefEndX();
570 nCurY = aViewData.GetRefEndY();
572 else if (IsBlockMode())
574 // block end position.
575 nCurX = nBlockEndX;
576 nCurY = nBlockEndY;
578 else
580 // cursor position
581 nCurX = aViewData.GetCurX();
582 nCurY = aViewData.GetCurY();
585 ScSplitPos eWhich = aViewData.GetActivePart();
586 ScHSplitPos eWhichX = WhichH( eWhich );
587 ScVSplitPos eWhichY = WhichV( eWhich );
589 SCsCOL nPageX;
590 SCsROW nPageY;
591 if (nMovX >= 0)
592 nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, 1, eWhichX )) * nMovX;
593 else
594 nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, -1, eWhichX )) * nMovX;
596 if (nMovY >= 0)
597 nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, 1, eWhichY )) * nMovY;
598 else
599 nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, -1, eWhichY )) * nMovY;
601 if (nMovX != 0 && nPageX == 0) nPageX = (nMovX>0) ? 1 : -1;
602 if (nMovY != 0 && nPageY == 0) nPageY = (nMovY>0) ? 1 : -1;
604 rPageX = nPageX;
605 rPageY = nPageY;
608 void ScTabView::GetAreaMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
609 SCsCOL& rAreaX, SCsROW& rAreaY, ScFollowMode& rMode)
611 SCCOL nNewX = -1;
612 SCROW nNewY = -1;
613 // current cursor position.
614 SCCOL nCurX = aViewData.GetCurX();
615 SCROW nCurY = aViewData.GetCurY();
617 if (aViewData.IsRefMode())
619 nNewX = aViewData.GetRefEndX();
620 nNewY = aViewData.GetRefEndY();
621 nCurX = aViewData.GetRefStartX();
622 nCurY = aViewData.GetRefStartY();
624 else if (IsBlockMode())
626 // block end position.
627 nNewX = nBlockEndX;
628 nNewY = nBlockEndY;
630 else
632 nNewX = nCurX;
633 nNewY = nCurY;
636 ScDocument* pDoc = aViewData.GetDocument();
637 SCTAB nTab = aViewData.GetTabNo();
639 // FindAreaPos kennt nur -1 oder 1 als Richtung
641 SCsCOLROW i;
642 if ( nMovX > 0 )
643 for ( i=0; i<nMovX; i++ )
644 pDoc->FindAreaPos( nNewX, nCurY, nTab, SC_MOVE_RIGHT );
645 if ( nMovX < 0 )
646 for ( i=0; i<-nMovX; i++ )
647 pDoc->FindAreaPos( nNewX, nCurY, nTab, SC_MOVE_LEFT );
648 if ( nMovY > 0 )
649 for ( i=0; i<nMovY; i++ )
650 pDoc->FindAreaPos( nCurX, nNewY, nTab, SC_MOVE_DOWN );
651 if ( nMovY < 0 )
652 for ( i=0; i<-nMovY; i++ )
653 pDoc->FindAreaPos( nCurX, nNewY, nTab, SC_MOVE_UP );
655 if (eMode==SC_FOLLOW_JUMP) // unten/rechts nicht zuviel grau anzeigen
657 if (nMovX != 0 && nNewX == MAXCOL)
658 eMode = SC_FOLLOW_LINE;
659 if (nMovY != 0 && nNewY == MAXROW)
660 eMode = SC_FOLLOW_LINE;
663 if (aViewData.IsRefMode())
665 rAreaX = nNewX - aViewData.GetRefEndX();
666 rAreaY = nNewY - aViewData.GetRefEndY();
668 else if (IsBlockMode())
670 rAreaX = nNewX - nBlockEndX;
671 rAreaY = nNewY - nBlockEndY;
673 else
675 rAreaX = nNewX - nCurX;
676 rAreaY = nNewY - nCurY;
678 rMode = eMode;
681 void ScTabView::SkipCursorHorizontal(SCsCOL& rCurX, SCsROW& rCurY, SCsCOL nOldX, SCsROW nMovX)
683 ScDocument* pDoc = aViewData.GetDocument();
684 SCTAB nTab = aViewData.GetTabNo();
686 bool bSkipProtected = false, bSkipUnprotected = false;
687 ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
688 if (pProtect && pProtect->isProtected())
690 bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
691 bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
694 bool bSkipCell = false;
695 bool bHFlip = false;
698 bSkipCell = pDoc->ColHidden(rCurX, nTab) || pDoc->IsHorOverlapped(rCurX, rCurY, nTab);
699 if (bSkipProtected && !bSkipCell)
700 bSkipCell = pDoc->HasAttrib(rCurX, rCurY, nTab, rCurX, rCurY, nTab, HASATTR_PROTECTED);
701 if (bSkipUnprotected && !bSkipCell)
702 bSkipCell = !pDoc->HasAttrib(rCurX, rCurY, nTab, rCurX, rCurY, nTab, HASATTR_PROTECTED);
704 if (bSkipCell)
706 if (rCurX <= 0 || rCurX >= MAXCOL)
708 if (bHFlip)
710 rCurX = nOldX;
711 bSkipCell = false;
713 else
715 nMovX = -nMovX;
716 if (nMovX > 0)
717 ++rCurX;
718 else
719 --rCurX;
720 bHFlip = true;
723 else
724 if (nMovX > 0)
725 ++rCurX;
726 else
727 --rCurX;
730 while (bSkipCell);
732 if (pDoc->IsVerOverlapped(rCurX, rCurY, nTab))
734 aViewData.SetOldCursor(rCurX, rCurY);
735 while (pDoc->IsVerOverlapped(rCurX, rCurY, nTab))
736 --rCurY;
740 void ScTabView::SkipCursorVertical(SCsCOL& rCurX, SCsROW& rCurY, SCsROW nOldY, SCsROW nMovY)
742 ScDocument* pDoc = aViewData.GetDocument();
743 SCTAB nTab = aViewData.GetTabNo();
745 bool bSkipProtected = false, bSkipUnprotected = false;
746 ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
747 if (pProtect && pProtect->isProtected())
749 bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
750 bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
753 bool bSkipCell = false;
754 bool bVFlip = false;
757 SCROW nLastRow = -1;
758 bSkipCell = pDoc->RowHidden(rCurY, nTab, NULL, &nLastRow) || pDoc->IsVerOverlapped( rCurX, rCurY, nTab );
759 if (bSkipProtected && !bSkipCell)
760 bSkipCell = pDoc->HasAttrib(rCurX, rCurY, nTab, rCurX, rCurY, nTab, HASATTR_PROTECTED);
761 if (bSkipUnprotected && !bSkipCell)
762 bSkipCell = !pDoc->HasAttrib(rCurX, rCurY, nTab, rCurX, rCurY, nTab, HASATTR_PROTECTED);
764 if (bSkipCell)
766 if (rCurY <= 0 || rCurY >= MAXROW)
768 if (bVFlip)
770 rCurY = nOldY;
771 bSkipCell = false;
773 else
775 nMovY = -nMovY;
776 if (nMovY > 0)
777 ++rCurY;
778 else
779 --rCurY;
780 bVFlip = true;
783 else
784 if (nMovY > 0)
785 ++rCurY;
786 else
787 --rCurY;
790 while (bSkipCell);
792 if (pDoc->IsHorOverlapped(rCurX, rCurY, nTab))
794 aViewData.SetOldCursor(rCurX, rCurY);
795 while (pDoc->IsHorOverlapped(rCurX, rCurY, nTab))
796 --rCurX;
800 void ScTabView::ExpandBlock(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode)
802 if (!nMovX && !nMovY)
803 // Nothing to do. Bail out.
804 return;
806 ScTabViewShell* pViewShell = aViewData.GetViewShell();
807 bool bRefInputMode = pViewShell && pViewShell->IsRefInputMode();
808 if (bRefInputMode && !aViewData.IsRefMode())
809 // initialize formula reference mode if it hasn't already.
810 InitRefMode(aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo(), SC_REFTYPE_REF);
812 ScDocument* pDoc = aViewData.GetDocument();
814 if (aViewData.IsRefMode())
816 // formula reference mode
818 SCCOL nNewX = aViewData.GetRefEndX();
819 SCROW nNewY = aViewData.GetRefEndY();
820 SCTAB nRefTab = aViewData.GetRefEndZ();
822 bool bSelectLocked = true;
823 bool bSelectUnlocked = true;
824 ScTableProtection* pTabProtection = pDoc->GetTabProtection(nRefTab);
825 if (pTabProtection && pTabProtection->isProtected())
827 bSelectLocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
828 bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
831 moveCursorByProtRule(nNewX, nNewY, nMovX, nMovY, nRefTab, pDoc);
832 checkBoundary(nNewX, nNewY);
834 if (nMovX)
836 SCCOL nTempX = nNewX;
837 while (pDoc->IsHorOverlapped(nTempX, nNewY, nRefTab))
839 if (nMovX > 0)
840 ++nTempX;
841 else
842 --nTempX;
843 if (!checkBoundary(nTempX, nNewY))
844 break;
846 if (isCellQualified(pDoc, nTempX, nNewY, nRefTab, bSelectLocked, bSelectUnlocked))
847 nNewX = nTempX;
850 if (nMovY)
852 SCROW nTempY = nNewY;
853 while (pDoc->IsVerOverlapped(nNewX, nTempY, nRefTab))
855 if (nMovY > 0)
856 ++nTempY;
857 else
858 --nTempY;
859 if (!checkBoundary(nNewX, nTempY))
860 break;
862 if (isCellQualified(pDoc, nNewX, nTempY, nRefTab, bSelectLocked, bSelectUnlocked))
863 nNewY = nTempY;
866 pDoc->SkipOverlapped(nNewX, nNewY, nRefTab);
867 UpdateRef(nNewX, nNewY, nRefTab);
868 AlignToCursor(nNewX, nNewY, eMode);
870 else
872 // normal selection mode
874 SCTAB nTab = aViewData.GetTabNo();
875 SCCOL nOrigX = aViewData.GetCurX();
876 SCROW nOrigY = aViewData.GetCurY();
878 // Note that the origin position *never* moves during selection.
880 if (!IsBlockMode())
881 InitBlockMode(nOrigX, nOrigY, nTab, true);
883 moveCursorByProtRule(nBlockEndX, nBlockEndY, nMovX, nMovY, nTab, pDoc);
884 checkBoundary(nBlockEndX, nBlockEndY);
885 moveCursorByMergedCell(nBlockEndX, nBlockEndY, nMovX, nMovY, nTab, pDoc, aViewData);
886 checkBoundary(nBlockEndX, nBlockEndY);
888 MarkCursor(nBlockEndX, nBlockEndY, nTab, false, false, true);
890 // Check if the entire row(s) or column(s) are selected.
891 ScSplitPos eActive = aViewData.GetActivePart();
892 bool bRowSelected = (nBlockStartX == 0 && nBlockEndX == MAXCOL);
893 bool bColSelected = (nBlockStartY == 0 && nBlockEndY == MAXROW);
894 SCsCOL nAlignX = bRowSelected ? aViewData.GetPosX(WhichH(eActive)) : nBlockEndX;
895 SCsROW nAlignY = bColSelected ? aViewData.GetPosY(WhichV(eActive)) : nBlockEndY;
896 AlignToCursor(nAlignX, nAlignY, eMode);
898 SelectionChanged();
902 void ScTabView::ExpandBlockPage(SCsCOL nMovX, SCsROW nMovY)
904 SCsCOL nPageX;
905 SCsROW nPageY;
906 GetPageMoveEndPosition(nMovX, nMovY, nPageX, nPageY);
907 ExpandBlock(nPageX, nPageY, SC_FOLLOW_FIX);
910 void ScTabView::ExpandBlockArea(SCsCOL nMovX, SCsROW nMovY)
912 SCsCOL nAreaX;
913 SCsROW nAreaY;
914 ScFollowMode eMode;
915 GetAreaMoveEndPosition(nMovX, nMovY, SC_FOLLOW_JUMP, nAreaX, nAreaY, eMode);
916 ExpandBlock(nAreaX, nAreaY, eMode);
919 void ScTabView::UpdateCopySourceOverlay()
921 for (sal_uInt8 i = 0; i < 4; ++i)
922 if (pGridWin[i] && pGridWin[i]->IsVisible())
923 pGridWin[i]->UpdateCopySourceOverlay();
926 void ScTabView::UpdateSelectionOverlay()
928 for (sal_uInt16 i=0; i<4; i++)
929 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
930 pGridWin[i]->UpdateSelectionOverlay();
933 void ScTabView::UpdateShrinkOverlay()
935 for (sal_uInt16 i=0; i<4; i++)
936 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
937 pGridWin[i]->UpdateShrinkOverlay();
940 void ScTabView::UpdateAllOverlays()
942 for (sal_uInt16 i=0; i<4; i++)
943 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
944 pGridWin[i]->UpdateAllOverlays();
948 //! PaintBlock in zwei Methoden aufteilen: RepaintBlock und RemoveBlock o.ae.
951 void ScTabView::PaintBlock( bool bReset )
953 ScMarkData& rMark = aViewData.GetMarkData();
954 SCTAB nTab = aViewData.GetTabNo();
955 bool bMark = rMark.IsMarked();
956 bool bMulti = rMark.IsMultiMarked();
957 if (bMark || bMulti)
959 ScRange aMarkRange;
960 HideAllCursors();
961 if (bMulti)
963 bool bFlag = rMark.GetMarkingFlag();
964 rMark.SetMarking(false);
965 rMark.MarkToMulti();
966 rMark.GetMultiMarkArea(aMarkRange);
967 rMark.MarkToSimple();
968 rMark.SetMarking(bFlag);
970 bMark = rMark.IsMarked();
972 else
973 rMark.GetMarkArea(aMarkRange);
975 nBlockStartX = aMarkRange.aStart.Col();
976 nBlockStartY = aMarkRange.aStart.Row();
977 nBlockStartZ = aMarkRange.aStart.Tab();
978 nBlockEndX = aMarkRange.aEnd.Col();
979 nBlockEndY = aMarkRange.aEnd.Row();
980 nBlockEndZ = aMarkRange.aEnd.Tab();
982 bool bDidReset = false;
984 if ( nTab>=nBlockStartZ && nTab<=nBlockEndZ )
986 if ( bReset )
988 // Invertieren beim Loeschen nur auf aktiver View
989 if ( aViewData.IsActive() )
991 rMark.ResetMark();
992 UpdateSelectionOverlay();
993 bDidReset = true;
996 else
997 PaintMarks( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY );
1000 if ( bReset && !bDidReset )
1001 rMark.ResetMark();
1003 ShowAllCursors();
1007 void ScTabView::SelectAll( bool bContinue )
1009 ScMarkData& rMark = aViewData.GetMarkData();
1010 SCTAB nTab = aViewData.GetTabNo();
1012 if (rMark.IsMarked())
1014 ScRange aMarkRange;
1015 rMark.GetMarkArea( aMarkRange );
1016 if ( aMarkRange == ScRange( 0,0,nTab, MAXCOL,MAXROW,nTab ) )
1017 return;
1020 DoneBlockMode( bContinue );
1021 InitBlockMode( 0,0,nTab );
1022 MarkCursor( MAXCOL,MAXROW,nTab );
1024 SelectionChanged();
1027 void ScTabView::SelectAllTables()
1029 ScDocument* pDoc = aViewData.GetDocument();
1030 ScMarkData& rMark = aViewData.GetMarkData();
1031 SCTAB nCount = pDoc->GetTableCount();
1033 if (nCount>1)
1035 for (SCTAB i=0; i<nCount; i++)
1036 rMark.SelectTable( i, true );
1038 aViewData.GetDocShell()->PostPaintExtras();
1039 SfxBindings& rBind = aViewData.GetBindings();
1040 rBind.Invalidate( FID_FILL_TAB );
1041 rBind.Invalidate( FID_TAB_DESELECTALL );
1045 void ScTabView::DeselectAllTables()
1047 ScDocument* pDoc = aViewData.GetDocument();
1048 ScMarkData& rMark = aViewData.GetMarkData();
1049 SCTAB nTab = aViewData.GetTabNo();
1050 SCTAB nCount = pDoc->GetTableCount();
1052 for (SCTAB i=0; i<nCount; i++)
1053 rMark.SelectTable( i, ( i == nTab ) );
1055 aViewData.GetDocShell()->PostPaintExtras();
1056 SfxBindings& rBind = aViewData.GetBindings();
1057 rBind.Invalidate( FID_FILL_TAB );
1058 rBind.Invalidate( FID_TAB_DESELECTALL );
1061 static bool lcl_FitsInWindow( double fScaleX, double fScaleY, sal_uInt16 nZoom,
1062 long nWindowX, long nWindowY, ScDocument* pDoc, SCTAB nTab,
1063 SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1064 SCCOL nFixPosX, SCROW nFixPosY )
1066 double fZoomFactor = (double)Fraction(nZoom,100);
1067 fScaleX *= fZoomFactor;
1068 fScaleY *= fZoomFactor;
1070 long nBlockX = 0;
1071 SCCOL nCol;
1072 for (nCol=0; nCol<nFixPosX; nCol++)
1074 // for frozen panes, add both parts
1075 sal_uInt16 nColTwips = pDoc->GetColWidth( nCol, nTab );
1076 if (nColTwips)
1078 nBlockX += (long)(nColTwips * fScaleX);
1079 if (nBlockX > nWindowX)
1080 return false;
1083 for (nCol=nStartCol; nCol<=nEndCol; nCol++)
1085 sal_uInt16 nColTwips = pDoc->GetColWidth( nCol, nTab );
1086 if (nColTwips)
1088 nBlockX += (long)(nColTwips * fScaleX);
1089 if (nBlockX > nWindowX)
1090 return false;
1094 long nBlockY = 0;
1095 for (SCROW nRow = 0; nRow <= nFixPosY-1; ++nRow)
1097 if (pDoc->RowHidden(nRow, nTab))
1098 continue;
1100 // for frozen panes, add both parts
1101 sal_uInt16 nRowTwips = pDoc->GetRowHeight(nRow, nTab);
1102 if (nRowTwips)
1104 nBlockY += (long)(nRowTwips * fScaleY);
1105 if (nBlockY > nWindowY)
1106 return false;
1109 for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
1111 sal_uInt16 nRowTwips = pDoc->GetRowHeight(nRow, nTab);
1112 if (nRowTwips)
1114 nBlockY += (long)(nRowTwips * fScaleY);
1115 if (nBlockY > nWindowY)
1116 return false;
1120 return true;
1123 sal_uInt16 ScTabView::CalcZoom( SvxZoomType eType, sal_uInt16 nOldZoom )
1125 sal_uInt16 nZoom = 0; // Ergebnis
1127 switch ( eType )
1129 case SVX_ZOOM_PERCENT: // rZoom ist kein besonderer prozentualer Wert
1130 nZoom = nOldZoom;
1131 break;
1133 case SVX_ZOOM_OPTIMAL: // nZoom entspricht der optimalen Gr"o\se
1135 ScMarkData& rMark = aViewData.GetMarkData();
1136 ScDocument* pDoc = aViewData.GetDocument();
1138 if (!rMark.IsMarked() && !rMark.IsMultiMarked())
1139 nZoom = 100; // nothing selected
1140 else
1142 SCTAB nTab = aViewData.GetTabNo();
1143 ScRange aMarkRange;
1144 if ( aViewData.GetSimpleArea( aMarkRange ) != SC_MARK_SIMPLE )
1145 rMark.GetMultiMarkArea( aMarkRange );
1147 SCCOL nStartCol = aMarkRange.aStart.Col();
1148 SCROW nStartRow = aMarkRange.aStart.Row();
1149 SCTAB nStartTab = aMarkRange.aStart.Tab();
1150 SCCOL nEndCol = aMarkRange.aEnd.Col();
1151 SCROW nEndRow = aMarkRange.aEnd.Row();
1152 SCTAB nEndTab = aMarkRange.aEnd.Tab();
1154 if ( nTab < nStartTab && nTab > nEndTab )
1155 nTab = nStartTab;
1157 ScSplitPos eUsedPart = aViewData.GetActivePart();
1159 SCCOL nFixPosX = 0;
1160 SCROW nFixPosY = 0;
1161 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
1163 // use right part
1164 eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
1165 nFixPosX = aViewData.GetFixPosX();
1166 if ( nStartCol < nFixPosX )
1167 nStartCol = nFixPosX;
1169 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1171 // use bottom part
1172 eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
1173 nFixPosY = aViewData.GetFixPosY();
1174 if ( nStartRow < nFixPosY )
1175 nStartRow = nFixPosY;
1178 if (pGridWin[eUsedPart])
1180 // Because scale is rounded to pixels, the only reliable way to find
1181 // the right scale is to check if a zoom fits
1183 Size aWinSize = pGridWin[eUsedPart]->GetOutputSizePixel();
1185 // for frozen panes, use sum of both parts for calculation
1187 if ( nFixPosX != 0 )
1188 aWinSize.Width() += GetGridWidth( SC_SPLIT_LEFT );
1189 if ( nFixPosY != 0 )
1190 aWinSize.Height() += GetGridHeight( SC_SPLIT_TOP );
1192 ScDocShell* pDocSh = aViewData.GetDocShell();
1193 double nPPTX = ScGlobal::nScreenPPTX / pDocSh->GetOutputFactor();
1194 double nPPTY = ScGlobal::nScreenPPTY;
1196 sal_uInt16 nMin = MINZOOM;
1197 sal_uInt16 nMax = MAXZOOM;
1198 while ( nMax > nMin )
1200 sal_uInt16 nTest = (nMin+nMax+1)/2;
1201 if ( lcl_FitsInWindow(
1202 nPPTX, nPPTY, nTest, aWinSize.Width(), aWinSize.Height(),
1203 pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow,
1204 nFixPosX, nFixPosY ) )
1205 nMin = nTest;
1206 else
1207 nMax = nTest-1;
1209 OSL_ENSURE( nMin == nMax, "Schachtelung ist falsch" );
1210 nZoom = nMin;
1212 if ( nZoom != nOldZoom )
1214 // scroll to block only in active split part
1215 // (the part for which the size was calculated)
1217 if ( nStartCol <= nEndCol )
1218 aViewData.SetPosX( WhichH(eUsedPart), nStartCol );
1219 if ( nStartRow <= nEndRow )
1220 aViewData.SetPosY( WhichV(eUsedPart), nStartRow );
1225 break;
1227 case SVX_ZOOM_WHOLEPAGE: // nZoom entspricht der ganzen Seite oder
1228 case SVX_ZOOM_PAGEWIDTH: // nZoom entspricht der Seitenbreite
1230 SCTAB nCurTab = aViewData.GetTabNo();
1231 ScDocument* pDoc = aViewData.GetDocument();
1232 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
1233 SfxStyleSheetBase* pStyleSheet =
1234 pStylePool->Find( pDoc->GetPageStyle( nCurTab ),
1235 SFX_STYLE_FAMILY_PAGE );
1237 OSL_ENSURE( pStyleSheet, "PageStyle not found :-/" );
1239 if ( pStyleSheet )
1241 ScPrintFunc aPrintFunc( aViewData.GetDocShell(),
1242 aViewData.GetViewShell()->GetPrinter(true),
1243 nCurTab );
1245 Size aPageSize = aPrintFunc.GetDataSize();
1247 // use the size of the largest GridWin for normal split,
1248 // or both combined for frozen panes, with the (document) size
1249 // of the frozen part added to the page size
1250 // (with frozen panes, the size of the individual parts
1251 // depends on the scale that is to be calculated)
1253 if ( !pGridWin[SC_SPLIT_BOTTOMLEFT] ) return 0;
1254 Size aWinSize = pGridWin[SC_SPLIT_BOTTOMLEFT]->GetOutputSizePixel();
1255 ScSplitMode eHMode = aViewData.GetHSplitMode();
1256 if ( eHMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_BOTTOMRIGHT] )
1258 long nOtherWidth = pGridWin[SC_SPLIT_BOTTOMRIGHT]->
1259 GetOutputSizePixel().Width();
1260 if ( eHMode == SC_SPLIT_FIX )
1262 aWinSize.Width() += nOtherWidth;
1263 for ( SCCOL nCol = aViewData.GetPosX(SC_SPLIT_LEFT);
1264 nCol < aViewData.GetFixPosX(); nCol++ )
1265 aPageSize.Width() += pDoc->GetColWidth( nCol, nCurTab );
1267 else if ( nOtherWidth > aWinSize.Width() )
1268 aWinSize.Width() = nOtherWidth;
1270 ScSplitMode eVMode = aViewData.GetVSplitMode();
1271 if ( eVMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_TOPLEFT] )
1273 long nOtherHeight = pGridWin[SC_SPLIT_TOPLEFT]->
1274 GetOutputSizePixel().Height();
1275 if ( eVMode == SC_SPLIT_FIX )
1277 aWinSize.Height() += nOtherHeight;
1278 aPageSize.Height() += pDoc->GetRowHeight(
1279 aViewData.GetPosY(SC_SPLIT_TOP),
1280 aViewData.GetFixPosY()-1, nCurTab);
1282 else if ( nOtherHeight > aWinSize.Height() )
1283 aWinSize.Height() = nOtherHeight;
1286 double nPPTX = ScGlobal::nScreenPPTX / aViewData.GetDocShell()->GetOutputFactor();
1287 double nPPTY = ScGlobal::nScreenPPTY;
1289 long nZoomX = (long) ( aWinSize.Width() * 100 /
1290 ( aPageSize.Width() * nPPTX ) );
1291 long nZoomY = (long) ( aWinSize.Height() * 100 /
1292 ( aPageSize.Height() * nPPTY ) );
1293 long nNew = nZoomX;
1295 if (eType == SVX_ZOOM_WHOLEPAGE && nZoomY < nNew)
1296 nNew = nZoomY;
1298 nZoom = (sal_uInt16) nNew;
1301 break;
1303 default:
1304 OSL_FAIL("Unknown Zoom-Revision");
1305 nZoom = 0;
1308 return nZoom;
1311 // wird z.B. gerufen, wenn sich das View-Fenster verschiebt:
1313 void ScTabView::StopMarking()
1315 ScSplitPos eActive = aViewData.GetActivePart();
1316 if (pGridWin[eActive])
1317 pGridWin[eActive]->StopMarking();
1319 ScHSplitPos eH = WhichH(eActive);
1320 if (pColBar[eH])
1321 pColBar[eH]->StopMarking();
1323 ScVSplitPos eV = WhichV(eActive);
1324 if (pRowBar[eV])
1325 pRowBar[eV]->StopMarking();
1328 void ScTabView::HideNoteMarker()
1330 for (sal_uInt16 i=0; i<4; i++)
1331 if (pGridWin[i] && pGridWin[i]->IsVisible())
1332 pGridWin[i]->HideNoteMarker();
1335 void ScTabView::MakeDrawLayer()
1337 if (!pDrawView)
1339 aViewData.GetDocShell()->MakeDrawLayer();
1341 // pDrawView wird per Notify gesetzt
1342 OSL_ENSURE(pDrawView,"ScTabView::MakeDrawLayer funktioniert nicht");
1344 // #114409#
1345 for(sal_uInt16 a(0); a < 4; a++)
1347 if(pGridWin[a])
1349 pGridWin[a]->DrawLayerCreated();
1355 void ScTabView::ErrorMessage( sal_uInt16 nGlobStrId )
1357 if ( SC_MOD()->IsInExecuteDrop() )
1359 // #i28468# don't show error message when called from Drag&Drop, silently abort instead
1360 return;
1363 StopMarking(); // falls per Focus aus MouseButtonDown aufgerufen
1365 Window* pParent = aViewData.GetDialogParent();
1366 ScWaitCursorOff aWaitOff( pParent );
1367 bool bFocus = pParent && pParent->HasFocus();
1369 if(nGlobStrId==STR_PROTECTIONERR)
1371 if(aViewData.GetDocShell()->IsReadOnly())
1373 nGlobStrId=STR_READONLYERR;
1377 InfoBox aBox( pParent, ScGlobal::GetRscString( nGlobStrId ) );
1378 aBox.Execute();
1379 if (bFocus)
1380 pParent->GrabFocus();
1383 Window* ScTabView::GetParentOrChild( sal_uInt16 nChildId )
1385 SfxViewFrame* pViewFrm = aViewData.GetViewShell()->GetViewFrame();
1387 if ( pViewFrm->HasChildWindow(nChildId) )
1389 SfxChildWindow* pChild = pViewFrm->GetChildWindow(nChildId);
1390 if (pChild)
1392 Window* pWin = pChild->GetWindow();
1393 if (pWin && pWin->IsVisible())
1394 return pWin;
1398 return aViewData.GetDialogParent();
1401 void ScTabView::UpdatePageBreakData( bool bForcePaint )
1403 ScPageBreakData* pNewData = NULL;
1405 if (aViewData.IsPagebreakMode())
1407 ScDocShell* pDocSh = aViewData.GetDocShell();
1408 ScDocument* pDoc = pDocSh->GetDocument();
1409 SCTAB nTab = aViewData.GetTabNo();
1411 sal_uInt16 nCount = pDoc->GetPrintRangeCount(nTab);
1412 if (!nCount)
1413 nCount = 1;
1414 pNewData = new ScPageBreakData(nCount);
1416 ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab, 0,0,NULL, NULL, pNewData );
1417 // ScPrintFunc fuellt im ctor die PageBreakData
1418 if ( nCount > 1 )
1420 aPrintFunc.ResetBreaks(nTab);
1421 pNewData->AddPages();
1424 // Druckbereiche veraendert?
1425 if ( bForcePaint || ( pPageBreakData && !pPageBreakData->IsEqual( *pNewData ) ) )
1426 PaintGrid();
1429 delete pPageBreakData;
1430 pPageBreakData = pNewData;
1435 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */