Bump version to 4.3-4
[LibreOffice.git] / sc / source / ui / view / tabview2.cxx
blob501459f3211af5995fcf9a26ce1dff79a6be5698
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"
48 #include "inputopt.hxx"
50 namespace {
52 bool isCellQualified(ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, bool bSelectLocked, bool bSelectUnlocked)
54 bool bCellProtected = pDoc->HasAttrib(
55 nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_PROTECTED);
57 if (bCellProtected && !bSelectLocked)
58 return false;
60 if (!bCellProtected && !bSelectUnlocked)
61 return false;
63 return true;
66 void moveCursorByProtRule(
67 SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY, SCTAB nTab, ScDocument* pDoc)
69 bool bSelectLocked = true;
70 bool bSelectUnlocked = true;
71 ScTableProtection* pTabProtection = pDoc->GetTabProtection(nTab);
72 if (pTabProtection && pTabProtection->isProtected())
74 bSelectLocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
75 bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
78 if (nMovX > 0)
80 for (SCCOL i = 0; i < nMovX && rCol < MAXCOL; ++i)
82 SCCOL nNewUnhiddenCol = rCol + 1;
83 SCCOL nEndCol = 0;
84 while(pDoc->ColHidden(nNewUnhiddenCol, nTab, NULL, &nEndCol))
86 if(nNewUnhiddenCol >= MAXCOL)
87 return;
89 i += nEndCol - nNewUnhiddenCol + 1;
90 nNewUnhiddenCol = nEndCol +1;
93 if (!isCellQualified(pDoc, nNewUnhiddenCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
94 break;
95 rCol = nNewUnhiddenCol;
98 else if (nMovX < 0)
100 for (SCCOL i = 0; i > nMovX && rCol > 0; --i)
102 SCCOL nNewUnhiddenCol = rCol - 1;
103 SCCOL nStartCol = 0;
104 while(pDoc->ColHidden(nNewUnhiddenCol, nTab, &nStartCol))
106 if(nNewUnhiddenCol <= 0)
107 return;
109 i -= nNewUnhiddenCol - nStartCol + 1;
110 nNewUnhiddenCol = nStartCol - 1;
113 if (!isCellQualified(pDoc, nNewUnhiddenCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
114 break;
115 rCol = nNewUnhiddenCol;
119 if (nMovY > 0)
121 for (SCROW i = 0; i < nMovY && rRow < MAXROW; ++i)
123 SCROW nNewUnhiddenRow = rRow + 1;
124 SCROW nEndRow = 0;
125 while(pDoc->RowHidden(nNewUnhiddenRow, nTab, NULL, &nEndRow))
127 if(nNewUnhiddenRow >= MAXROW)
128 return;
130 i += nEndRow - nNewUnhiddenRow + 1;
131 nNewUnhiddenRow = nEndRow + 1;
134 if (!isCellQualified(pDoc, rCol, nNewUnhiddenRow, nTab, bSelectLocked, bSelectUnlocked))
135 break;
136 rRow = nNewUnhiddenRow;
139 else if (nMovY < 0)
141 for (SCROW i = 0; i > nMovY && rRow > 0; --i)
143 SCROW nNewUnhiddenRow = rRow - 1;
144 SCROW nStartRow = 0;
145 while(pDoc->RowHidden(nNewUnhiddenRow, nTab, &nStartRow))
147 if(nNewUnhiddenRow <= 0)
148 return;
150 i -= nNewUnhiddenRow - nStartRow + 1;
151 nNewUnhiddenRow = nStartRow - 1;
154 if (!isCellQualified(pDoc, rCol, nNewUnhiddenRow, nTab, bSelectLocked, bSelectUnlocked))
155 break;
156 rRow = nNewUnhiddenRow;
161 bool checkBoundary(SCCOL& rCol, SCROW& rRow)
163 bool bGood = true;
164 if (rCol < 0)
166 rCol = 0;
167 bGood = false;
169 else if (rCol > MAXCOL)
171 rCol = MAXCOL;
172 bGood = false;
175 if (rRow < 0)
177 rRow = 0;
178 bGood = false;
180 else if (rRow > MAXROW)
182 rRow = MAXROW;
183 bGood = false;
185 return bGood;
188 void moveCursorByMergedCell(
189 SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY, SCTAB nTab,
190 ScDocument* pDoc, const ScViewData& rViewData)
192 SCCOL nOrigX = rViewData.GetCurX();
193 SCROW nOrigY = rViewData.GetCurY();
195 ScTableProtection* pTabProtection = pDoc->GetTabProtection(nTab);
196 bool bSelectLocked = true;
197 bool bSelectUnlocked = true;
198 if (pTabProtection && pTabProtection->isProtected())
200 bSelectLocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
201 bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
204 const ScMergeAttr* pMergeAttr = static_cast<const ScMergeAttr*>(
205 pDoc->GetAttr(nOrigX, nOrigY, nTab, ATTR_MERGE));
207 bool bOriginMerged = false;
208 SCsCOL nColSpan = 1;
209 SCsROW nRowSpan = 1;
210 if (pMergeAttr && pMergeAttr->IsMerged())
212 nColSpan = pMergeAttr->GetColMerge();
213 nRowSpan = pMergeAttr->GetRowMerge();
214 bOriginMerged = true;
217 if (nMovX > 0)
219 SCCOL nOld = rCol;
220 if (bOriginMerged)
222 // Original cell is merged. Push the block end outside the merged region.
223 if (nOrigX < MAXCOL && nOrigX < rCol && rCol <= nOrigX + nColSpan - 1)
224 rCol = nOrigX + nColSpan;
226 else
228 pDoc->SkipOverlapped(rCol, rRow, nTab);
231 if (nOld < rCol)
233 // The block end has moved. Check the protection setting and move back if needed.
234 checkBoundary(rCol, rRow);
235 if (!isCellQualified(pDoc, rCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
236 --rCol;
239 if (nMovX < 0)
241 SCCOL nOld = rCol;
242 if (bOriginMerged)
244 if (nOrigX > 0 && nOrigX <= rCol && rCol < nOrigX + nColSpan - 1)
245 // Block end is still within the merged region. Push it outside.
246 rCol = nOrigX - 1;
248 else
250 pDoc->SkipOverlapped(rCol, rRow, nTab);
253 if (nOld > rCol)
255 // The block end has moved. Check the protection setting and move back if needed.
256 checkBoundary(rCol, rRow);
257 if (!isCellQualified(pDoc, rCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
258 ++rCol;
261 if (nMovY > 0)
263 SCROW nOld = rRow;
264 if (bOriginMerged)
266 // Original cell is merged. Push the block end outside the merged region.
267 if (nOrigY < MAXROW && nOrigY < rRow && rRow <= nOrigY + nRowSpan - 1)
268 rRow = nOrigY + nRowSpan;
270 else
272 pDoc->SkipOverlapped(rCol, rRow, nTab);
275 if (nOld < rRow)
277 // The block end has moved. Check the protection setting and move back if needed.
278 checkBoundary(rCol, rRow);
279 if (!isCellQualified(pDoc, rCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
280 --rRow;
283 if (nMovY < 0)
285 SCROW nOld = rRow;
286 if (bOriginMerged)
288 if (nOrigY > 0 && nOrigY <= rRow && rRow < nOrigY + nRowSpan - 1)
289 // Block end is still within the merged region. Push it outside.
290 rRow = nOrigY - 1;
292 else
294 pDoc->SkipOverlapped(rCol, rRow, nTab);
297 if (nOld > rRow)
299 // The block end has moved. Check the protection setting and move back if needed.
300 checkBoundary(rCol, rRow);
301 if (!isCellQualified(pDoc, rCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
302 ++rRow;
309 void ScTabView::PaintMarks(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
311 if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
312 if (!ValidRow(nStartRow)) nStartRow = MAXROW;
313 if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
314 if (!ValidRow(nEndRow)) nEndRow = MAXROW;
316 bool bLeft = (nStartCol==0 && nEndCol==MAXCOL);
317 bool bTop = (nStartRow==0 && nEndRow==MAXROW);
319 if (bLeft)
320 PaintLeftArea( nStartRow, nEndRow );
321 if (bTop)
322 PaintTopArea( nStartCol, nEndCol );
324 aViewData.GetDocument()->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow,
325 aViewData.GetTabNo() );
326 PaintArea( nStartCol, nStartRow, nEndCol, nEndRow, SC_UPDATE_MARKS );
329 bool ScTabView::IsMarking( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
331 return IsBlockMode()
332 && nBlockStartX == nCol
333 && nBlockStartY == nRow
334 && nBlockStartZ == nTab;
337 void ScTabView::InitOwnBlockMode()
339 if (!IsBlockMode())
341 // Wenn keine (alte) Markierung mehr da ist, Anker in SelectionEngine loeschen:
343 ScMarkData& rMark = aViewData.GetMarkData();
344 if (!rMark.IsMarked() && !rMark.IsMultiMarked())
345 GetSelEngine()->CursorPosChanging( false, false );
347 meBlockMode = Own;
348 nBlockStartX = 0;
349 nBlockStartY = 0;
350 nBlockStartZ = 0;
351 nBlockEndX = 0;
352 nBlockEndY = 0;
353 nBlockEndZ = 0;
355 SelectionChanged(); // Status wird mit gesetzer Markierung abgefragt
359 void ScTabView::InitBlockMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
360 bool bTestNeg, bool bCols, bool bRows, bool bForceNeg )
362 if (!IsBlockMode())
364 if (!ValidCol(nCurX)) nCurX = MAXCOL;
365 if (!ValidRow(nCurY)) nCurY = MAXROW;
367 ScMarkData& rMark = aViewData.GetMarkData();
368 SCTAB nTab = aViewData.GetTabNo();
370 // Teil von Markierung aufheben?
371 if (bForceNeg)
372 bBlockNeg = true;
373 else if (bTestNeg)
375 if ( bCols )
376 bBlockNeg = rMark.IsColumnMarked( nCurX );
377 else if ( bRows )
378 bBlockNeg = rMark.IsRowMarked( nCurY );
379 else
380 bBlockNeg = rMark.IsCellMarked( nCurX, nCurY );
382 else
383 bBlockNeg = false;
384 rMark.SetMarkNegative(bBlockNeg);
386 meBlockMode = Normal;
387 bBlockCols = bCols;
388 bBlockRows = bRows;
389 nBlockStartX = nBlockStartXOrig = nCurX;
390 nBlockStartY = nBlockStartYOrig = nCurY;
391 nBlockStartZ = nCurZ;
392 nBlockEndX = nOldCurX = nBlockStartX;
393 nBlockEndY = nOldCurY = nBlockStartY;
394 nBlockEndZ = nBlockStartZ;
396 if (bBlockCols)
398 nBlockStartY = nBlockStartYOrig = 0;
399 nBlockEndY = MAXROW;
402 if (bBlockRows)
404 nBlockStartX = nBlockStartXOrig = 0;
405 nBlockEndX = MAXCOL;
408 rMark.SetMarkArea( ScRange( nBlockStartX,nBlockStartY, nTab, nBlockEndX,nBlockEndY, nTab ) );
410 UpdateSelectionOverlay();
414 void ScTabView::DoneBlockMode( bool bContinue )
416 // Wenn zwischen Tabellen- und Header SelectionEngine gewechselt wird,
417 // wird evtl. DeselectAll gerufen, weil die andere Engine keinen Anker hat.
418 // Mit bMoveIsShift wird verhindert, dass dann die Selektion aufgehoben wird.
420 if (IsBlockMode() && !bMoveIsShift)
422 ScMarkData& rMark = aViewData.GetMarkData();
423 bool bFlag = rMark.GetMarkingFlag();
424 rMark.SetMarking(false);
426 if (bBlockNeg && !bContinue)
427 rMark.MarkToMulti();
429 if (bContinue)
430 rMark.MarkToMulti();
431 else
433 // Die Tabelle kann an dieser Stelle ungueltig sein, weil DoneBlockMode
434 // aus SetTabNo aufgerufen wird
435 // (z.B. wenn die aktuelle Tabelle von einer anderen View aus geloescht wird)
437 SCTAB nTab = aViewData.GetTabNo();
438 ScDocument* pDoc = aViewData.GetDocument();
439 if ( pDoc->HasTable(nTab) )
440 PaintBlock( true ); // true -> Block loeschen
441 else
442 rMark.ResetMark();
444 meBlockMode = None;
446 rMark.SetMarking(bFlag);
447 rMark.SetMarkNegative(false);
451 bool ScTabView::IsBlockMode() const
453 return meBlockMode != None;
456 void ScTabView::MarkCursor( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
457 bool bCols, bool bRows, bool bCellSelection )
459 if (!ValidCol(nCurX)) nCurX = MAXCOL;
460 if (!ValidRow(nCurY)) nCurY = MAXROW;
462 if (!IsBlockMode())
464 OSL_FAIL( "MarkCursor nicht im BlockMode" );
465 InitBlockMode( nCurX, nCurY, nCurZ, false, bCols, bRows );
468 if (bCols)
469 nCurY = MAXROW;
470 if (bRows)
471 nCurX = MAXCOL;
473 ScMarkData& rMark = aViewData.GetMarkData();
474 OSL_ENSURE(rMark.IsMarked() || rMark.IsMultiMarked(), "MarkCursor, !IsMarked()");
475 ScRange aMarkRange;
476 rMark.GetMarkArea(aMarkRange);
477 if (( aMarkRange.aStart.Col() != nBlockStartX && aMarkRange.aEnd.Col() != nBlockStartX ) ||
478 ( aMarkRange.aStart.Row() != nBlockStartY && aMarkRange.aEnd.Row() != nBlockStartY ) ||
479 ( meBlockMode == Own ))
481 // Markierung ist veraendert worden
482 // (z.B. MarkToSimple, wenn per negativ alles bis auf ein Rechteck geloescht wurde)
483 // oder nach InitOwnBlockMode wird mit Shift-Klick weitermarkiert...
485 bool bOldShift = bMoveIsShift;
486 bMoveIsShift = false; // wirklich umsetzen
487 DoneBlockMode(false); //! direkt Variablen setzen? (-> kein Geflacker)
488 bMoveIsShift = bOldShift;
490 InitBlockMode( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
491 nBlockStartZ, rMark.IsMarkNegative(), bCols, bRows );
494 if ( nCurX != nOldCurX || nCurY != nOldCurY )
496 // Current cursor has moved
498 SCTAB nTab = nCurZ;
500 if ( bCellSelection )
502 // Expand selection area accordingly when the current selection ends
503 // with a merged cell.
504 SCsCOL nCurXOffset = 0;
505 SCsCOL nBlockStartXOffset = 0;
506 SCsROW nCurYOffset = 0;
507 SCsROW nBlockStartYOffset = 0;
508 bool bBlockStartMerged = false;
509 const ScMergeAttr* pMergeAttr = NULL;
510 ScDocument* pDocument = aViewData.GetDocument();
512 // The following block checks whether or not the "BlockStart" (anchor)
513 // cell is merged. If it's merged, it'll then move the position of the
514 // anchor cell to the corner that's diagonally opposite of the
515 // direction of a current selection area. For instance, if a current
516 // selection is moving in the upperleft direction, the anchor cell will
517 // move to the lower-right corner of the merged anchor cell, and so on.
519 pMergeAttr = static_cast<const ScMergeAttr*>(
520 pDocument->GetAttr( nBlockStartXOrig, nBlockStartYOrig, nTab, ATTR_MERGE ) );
521 if ( pMergeAttr->IsMerged() )
523 SCsCOL nColSpan = pMergeAttr->GetColMerge();
524 SCsROW nRowSpan = pMergeAttr->GetRowMerge();
526 if ( !( nCurX >= nBlockStartXOrig + nColSpan - 1 && nCurY >= nBlockStartYOrig + nRowSpan - 1 ) )
528 nBlockStartX = nCurX >= nBlockStartXOrig ? nBlockStartXOrig : nBlockStartXOrig + nColSpan - 1;
529 nBlockStartY = nCurY >= nBlockStartYOrig ? nBlockStartYOrig : nBlockStartYOrig + nRowSpan - 1;
530 nCurXOffset = (nCurX >= nBlockStartXOrig && nCurX < nBlockStartXOrig + nColSpan - 1) ?
531 nBlockStartXOrig - nCurX + nColSpan - 1 : 0;
532 nCurYOffset = (nCurY >= nBlockStartYOrig && nCurY < nBlockStartYOrig + nRowSpan - 1) ?
533 nBlockStartYOrig - nCurY + nRowSpan - 1 : 0;
534 bBlockStartMerged = true;
538 // The following block checks whether or not the current cell is
539 // merged. If it is, it'll then set the appropriate X & Y offset
540 // values (nCurXOffset & nCurYOffset) such that the selection area will
541 // grow by those specified offset amounts. Note that the values of
542 // nCurXOffset/nCurYOffset may also be specified in the previous code
543 // block, in which case whichever value is greater will take on.
545 pMergeAttr = static_cast<const ScMergeAttr*>(
546 pDocument->GetAttr( nCurX, nCurY, nTab, ATTR_MERGE ) );
547 if ( pMergeAttr->IsMerged() )
549 SCsCOL nColSpan = pMergeAttr->GetColMerge();
550 SCsROW nRowSpan = pMergeAttr->GetRowMerge();
552 if ( !( nBlockStartX >= nCurX + nColSpan - 1 && nBlockStartY >= nCurY + nRowSpan - 1 ) )
554 if ( nBlockStartX <= nCurX + nColSpan - 1 )
556 SCsCOL nCurXOffsetTemp = (nCurX < nCurX + nColSpan - 1) ? nColSpan - 1 : 0;
557 nCurXOffset = nCurXOffset > nCurXOffsetTemp ? nCurXOffset : nCurXOffsetTemp;
559 if ( nBlockStartY <= nCurY + nRowSpan - 1 )
561 SCsROW nCurYOffsetTemp = (nCurY < nCurY + nRowSpan - 1) ? nRowSpan - 1 : 0;
562 nCurYOffset = nCurYOffset > nCurYOffsetTemp ? nCurYOffset : nCurYOffsetTemp;
564 if ( !( nBlockStartX <= nCurX && nBlockStartY <= nCurY ) &&
565 !( nBlockStartX > nCurX + nColSpan - 1 && nBlockStartY > nCurY + nRowSpan - 1 ) )
567 nBlockStartXOffset = (nBlockStartX > nCurX && nBlockStartX <= nCurX + nColSpan - 1) ? nCurX - nBlockStartX : 0;
568 nBlockStartYOffset = (nBlockStartY > nCurY && nBlockStartY <= nCurY + nRowSpan - 1) ? nCurY - nBlockStartY : 0;
572 else
574 // The current cell is not merged. Move the anchor cell to its
575 // original position.
576 if ( !bBlockStartMerged )
578 nBlockStartX = nBlockStartXOrig;
579 nBlockStartY = nBlockStartYOrig;
583 nBlockStartX = nBlockStartX + nBlockStartXOffset >= 0 ? nBlockStartX + nBlockStartXOffset : 0;
584 nBlockStartY = nBlockStartY + nBlockStartYOffset >= 0 ? nBlockStartY + nBlockStartYOffset : 0;
585 nBlockEndX = nCurX + nCurXOffset > MAXCOL ? MAXCOL : nCurX + nCurXOffset;
586 nBlockEndY = nCurY + nCurYOffset > MAXROW ? MAXROW : nCurY + nCurYOffset;
588 else
590 nBlockEndX = nCurX;
591 nBlockEndY = nCurY;
594 // Set new selection area
595 rMark.SetMarkArea( ScRange( nBlockStartX, nBlockStartY, nTab, nBlockEndX, nBlockEndY, nTab ) );
597 UpdateSelectionOverlay();
598 SelectionChanged();
600 nOldCurX = nCurX;
601 nOldCurY = nCurY;
603 aViewData.GetViewShell()->UpdateInputHandler();
606 if ( !bCols && !bRows )
607 aHdrFunc.SetAnchorFlag( false );
610 void ScTabView::GetPageMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, SCsCOL& rPageX, SCsROW& rPageY)
612 SCCOL nCurX;
613 SCROW nCurY;
614 if (aViewData.IsRefMode())
616 nCurX = aViewData.GetRefEndX();
617 nCurY = aViewData.GetRefEndY();
619 else if (IsBlockMode())
621 // block end position.
622 nCurX = nBlockEndX;
623 nCurY = nBlockEndY;
625 else
627 // cursor position
628 nCurX = aViewData.GetCurX();
629 nCurY = aViewData.GetCurY();
632 ScSplitPos eWhich = aViewData.GetActivePart();
633 ScHSplitPos eWhichX = WhichH( eWhich );
634 ScVSplitPos eWhichY = WhichV( eWhich );
636 SCsCOL nPageX;
637 SCsROW nPageY;
638 if (nMovX >= 0)
639 nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, 1, eWhichX )) * nMovX;
640 else
641 nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, -1, eWhichX )) * nMovX;
643 if (nMovY >= 0)
644 nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, 1, eWhichY )) * nMovY;
645 else
646 nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, -1, eWhichY )) * nMovY;
648 if (nMovX != 0 && nPageX == 0) nPageX = (nMovX>0) ? 1 : -1;
649 if (nMovY != 0 && nPageY == 0) nPageY = (nMovY>0) ? 1 : -1;
651 rPageX = nPageX;
652 rPageY = nPageY;
655 void ScTabView::GetAreaMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
656 SCsCOL& rAreaX, SCsROW& rAreaY, ScFollowMode& rMode)
658 SCCOL nNewX = -1;
659 SCROW nNewY = -1;
661 // current cursor position.
662 SCCOL nCurX = aViewData.GetCurX();
663 SCROW nCurY = aViewData.GetCurY();
665 if (aViewData.IsRefMode())
667 nNewX = aViewData.GetRefEndX();
668 nNewY = aViewData.GetRefEndY();
669 nCurX = aViewData.GetRefStartX();
670 nCurY = aViewData.GetRefStartY();
672 else if (IsBlockMode())
674 // block end position.
675 nNewX = nBlockEndX;
676 nNewY = nBlockEndY;
678 else
680 nNewX = nCurX;
681 nNewY = nCurY;
684 ScDocument* pDoc = aViewData.GetDocument();
685 SCTAB nTab = aViewData.GetTabNo();
687 // FindAreaPos kennt nur -1 oder 1 als Richtung
688 ScModule* pScModule = SC_MOD();
689 bool bLegacyCellSelection = pScModule->GetInputOptions().GetLegacyCellSelection();
690 SCCOL nVirtualX = bLegacyCellSelection ? nNewX : nCurX;
691 SCROW nVirtualY = bLegacyCellSelection ? nNewY : nCurY;
693 SCsCOLROW i;
694 if ( nMovX > 0 )
695 for ( i=0; i<nMovX; i++ )
696 pDoc->FindAreaPos( nNewX, nVirtualY, nTab, SC_MOVE_RIGHT );
697 if ( nMovX < 0 )
698 for ( i=0; i<-nMovX; i++ )
699 pDoc->FindAreaPos( nNewX, nVirtualY, nTab, SC_MOVE_LEFT );
700 if ( nMovY > 0 )
701 for ( i=0; i<nMovY; i++ )
702 pDoc->FindAreaPos( nVirtualX, nNewY, nTab, SC_MOVE_DOWN );
703 if ( nMovY < 0 )
704 for ( i=0; i<-nMovY; i++ )
705 pDoc->FindAreaPos( nVirtualX, nNewY, nTab, SC_MOVE_UP );
707 if (eMode==SC_FOLLOW_JUMP) // unten/rechts nicht zuviel grau anzeigen
709 if (nMovX != 0 && nNewX == MAXCOL)
710 eMode = SC_FOLLOW_LINE;
711 if (nMovY != 0 && nNewY == MAXROW)
712 eMode = SC_FOLLOW_LINE;
715 if (aViewData.IsRefMode())
717 rAreaX = nNewX - aViewData.GetRefEndX();
718 rAreaY = nNewY - aViewData.GetRefEndY();
720 else if (IsBlockMode())
722 rAreaX = nNewX - nBlockEndX;
723 rAreaY = nNewY - nBlockEndY;
725 else
727 rAreaX = nNewX - nCurX;
728 rAreaY = nNewY - nCurY;
730 rMode = eMode;
733 void ScTabView::SkipCursorHorizontal(SCsCOL& rCurX, SCsROW& rCurY, SCsCOL nOldX, SCsROW nMovX)
735 ScDocument* pDoc = aViewData.GetDocument();
736 SCTAB nTab = aViewData.GetTabNo();
738 bool bSkipProtected = false, bSkipUnprotected = false;
739 ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
740 if (pProtect && pProtect->isProtected())
742 bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
743 bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
746 bool bSkipCell = false;
747 bool bHFlip = false;
750 bSkipCell = pDoc->ColHidden(rCurX, nTab) || pDoc->IsHorOverlapped(rCurX, rCurY, nTab);
751 if (bSkipProtected && !bSkipCell)
752 bSkipCell = pDoc->HasAttrib(rCurX, rCurY, nTab, rCurX, rCurY, nTab, HASATTR_PROTECTED);
753 if (bSkipUnprotected && !bSkipCell)
754 bSkipCell = !pDoc->HasAttrib(rCurX, rCurY, nTab, rCurX, rCurY, nTab, HASATTR_PROTECTED);
756 if (bSkipCell)
758 if (rCurX <= 0 || rCurX >= MAXCOL)
760 if (bHFlip)
762 rCurX = nOldX;
763 bSkipCell = false;
765 else
767 nMovX = -nMovX;
768 if (nMovX > 0)
769 ++rCurX;
770 else
771 --rCurX;
772 bHFlip = true;
775 else
776 if (nMovX > 0)
777 ++rCurX;
778 else
779 --rCurX;
782 while (bSkipCell);
784 if (pDoc->IsVerOverlapped(rCurX, rCurY, nTab))
786 aViewData.SetOldCursor(rCurX, rCurY);
787 while (pDoc->IsVerOverlapped(rCurX, rCurY, nTab))
788 --rCurY;
792 void ScTabView::SkipCursorVertical(SCsCOL& rCurX, SCsROW& rCurY, SCsROW nOldY, SCsROW nMovY)
794 ScDocument* pDoc = aViewData.GetDocument();
795 SCTAB nTab = aViewData.GetTabNo();
797 bool bSkipProtected = false, bSkipUnprotected = false;
798 ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
799 if (pProtect && pProtect->isProtected())
801 bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
802 bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
805 bool bSkipCell = false;
806 bool bVFlip = false;
809 SCROW nLastRow = -1;
810 bSkipCell = pDoc->RowHidden(rCurY, nTab, NULL, &nLastRow) || pDoc->IsVerOverlapped( rCurX, rCurY, nTab );
811 if (bSkipProtected && !bSkipCell)
812 bSkipCell = pDoc->HasAttrib(rCurX, rCurY, nTab, rCurX, rCurY, nTab, HASATTR_PROTECTED);
813 if (bSkipUnprotected && !bSkipCell)
814 bSkipCell = !pDoc->HasAttrib(rCurX, rCurY, nTab, rCurX, rCurY, nTab, HASATTR_PROTECTED);
816 if (bSkipCell)
818 if (rCurY <= 0 || rCurY >= MAXROW)
820 if (bVFlip)
822 rCurY = nOldY;
823 bSkipCell = false;
825 else
827 nMovY = -nMovY;
828 if (nMovY > 0)
829 ++rCurY;
830 else
831 --rCurY;
832 bVFlip = true;
835 else
836 if (nMovY > 0)
837 ++rCurY;
838 else
839 --rCurY;
842 while (bSkipCell);
844 if (pDoc->IsHorOverlapped(rCurX, rCurY, nTab))
846 aViewData.SetOldCursor(rCurX, rCurY);
847 while (pDoc->IsHorOverlapped(rCurX, rCurY, nTab))
848 --rCurX;
852 void ScTabView::ExpandBlock(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode)
854 if (!nMovX && !nMovY)
855 // Nothing to do. Bail out.
856 return;
858 ScTabViewShell* pViewShell = aViewData.GetViewShell();
859 bool bRefInputMode = pViewShell && pViewShell->IsRefInputMode();
860 if (bRefInputMode && !aViewData.IsRefMode())
861 // initialize formula reference mode if it hasn't already.
862 InitRefMode(aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo(), SC_REFTYPE_REF);
864 ScDocument* pDoc = aViewData.GetDocument();
866 if (aViewData.IsRefMode())
868 // formula reference mode
870 SCCOL nNewX = aViewData.GetRefEndX();
871 SCROW nNewY = aViewData.GetRefEndY();
872 SCTAB nRefTab = aViewData.GetRefEndZ();
874 bool bSelectLocked = true;
875 bool bSelectUnlocked = true;
876 ScTableProtection* pTabProtection = pDoc->GetTabProtection(nRefTab);
877 if (pTabProtection && pTabProtection->isProtected())
879 bSelectLocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
880 bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
883 moveCursorByProtRule(nNewX, nNewY, nMovX, nMovY, nRefTab, pDoc);
884 checkBoundary(nNewX, nNewY);
886 if (nMovX)
888 SCCOL nTempX = nNewX;
889 while (pDoc->IsHorOverlapped(nTempX, nNewY, nRefTab))
891 if (nMovX > 0)
892 ++nTempX;
893 else
894 --nTempX;
895 if (!checkBoundary(nTempX, nNewY))
896 break;
898 if (isCellQualified(pDoc, nTempX, nNewY, nRefTab, bSelectLocked, bSelectUnlocked))
899 nNewX = nTempX;
902 if (nMovY)
904 SCROW nTempY = nNewY;
905 while (pDoc->IsVerOverlapped(nNewX, nTempY, nRefTab))
907 if (nMovY > 0)
908 ++nTempY;
909 else
910 --nTempY;
911 if (!checkBoundary(nNewX, nTempY))
912 break;
914 if (isCellQualified(pDoc, nNewX, nTempY, nRefTab, bSelectLocked, bSelectUnlocked))
915 nNewY = nTempY;
918 pDoc->SkipOverlapped(nNewX, nNewY, nRefTab);
919 UpdateRef(nNewX, nNewY, nRefTab);
920 AlignToCursor(nNewX, nNewY, eMode);
922 else
924 // normal selection mode
926 SCTAB nTab = aViewData.GetTabNo();
927 SCCOL nOrigX = aViewData.GetCurX();
928 SCROW nOrigY = aViewData.GetCurY();
930 // Note that the origin position *never* moves during selection.
932 if (!IsBlockMode())
933 InitBlockMode(nOrigX, nOrigY, nTab, true);
935 moveCursorByProtRule(nBlockEndX, nBlockEndY, nMovX, nMovY, nTab, pDoc);
936 checkBoundary(nBlockEndX, nBlockEndY);
937 moveCursorByMergedCell(nBlockEndX, nBlockEndY, nMovX, nMovY, nTab, pDoc, aViewData);
938 checkBoundary(nBlockEndX, nBlockEndY);
940 MarkCursor(nBlockEndX, nBlockEndY, nTab, false, false, true);
942 // Check if the entire row(s) or column(s) are selected.
943 ScSplitPos eActive = aViewData.GetActivePart();
944 bool bRowSelected = (nBlockStartX == 0 && nBlockEndX == MAXCOL);
945 bool bColSelected = (nBlockStartY == 0 && nBlockEndY == MAXROW);
946 SCsCOL nAlignX = bRowSelected ? aViewData.GetPosX(WhichH(eActive)) : nBlockEndX;
947 SCsROW nAlignY = bColSelected ? aViewData.GetPosY(WhichV(eActive)) : nBlockEndY;
948 AlignToCursor(nAlignX, nAlignY, eMode);
950 SelectionChanged();
954 void ScTabView::ExpandBlockPage(SCsCOL nMovX, SCsROW nMovY)
956 SCsCOL nPageX;
957 SCsROW nPageY;
958 GetPageMoveEndPosition(nMovX, nMovY, nPageX, nPageY);
959 ExpandBlock(nPageX, nPageY, SC_FOLLOW_FIX);
962 void ScTabView::ExpandBlockArea(SCsCOL nMovX, SCsROW nMovY)
964 SCsCOL nAreaX;
965 SCsROW nAreaY;
966 ScFollowMode eMode;
967 GetAreaMoveEndPosition(nMovX, nMovY, SC_FOLLOW_JUMP, nAreaX, nAreaY, eMode);
968 ExpandBlock(nAreaX, nAreaY, eMode);
971 void ScTabView::UpdateCopySourceOverlay()
973 for (sal_uInt8 i = 0; i < 4; ++i)
974 if (pGridWin[i] && pGridWin[i]->IsVisible())
975 pGridWin[i]->UpdateCopySourceOverlay();
978 void ScTabView::UpdateSelectionOverlay()
980 for (sal_uInt16 i=0; i<4; i++)
981 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
982 pGridWin[i]->UpdateSelectionOverlay();
985 void ScTabView::UpdateShrinkOverlay()
987 for (sal_uInt16 i=0; i<4; i++)
988 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
989 pGridWin[i]->UpdateShrinkOverlay();
992 void ScTabView::UpdateAllOverlays()
994 for (sal_uInt16 i=0; i<4; i++)
995 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
996 pGridWin[i]->UpdateAllOverlays();
1000 //! PaintBlock in zwei Methoden aufteilen: RepaintBlock und RemoveBlock o.ae.
1003 void ScTabView::PaintBlock( bool bReset )
1005 ScMarkData& rMark = aViewData.GetMarkData();
1006 SCTAB nTab = aViewData.GetTabNo();
1007 bool bMulti = rMark.IsMultiMarked();
1008 if (rMark.IsMarked() || bMulti)
1010 ScRange aMarkRange;
1011 HideAllCursors();
1012 if (bMulti)
1014 bool bFlag = rMark.GetMarkingFlag();
1015 rMark.SetMarking(false);
1016 rMark.MarkToMulti();
1017 rMark.GetMultiMarkArea(aMarkRange);
1018 rMark.MarkToSimple();
1019 rMark.SetMarking(bFlag);
1021 else
1022 rMark.GetMarkArea(aMarkRange);
1024 nBlockStartX = aMarkRange.aStart.Col();
1025 nBlockStartY = aMarkRange.aStart.Row();
1026 nBlockStartZ = aMarkRange.aStart.Tab();
1027 nBlockEndX = aMarkRange.aEnd.Col();
1028 nBlockEndY = aMarkRange.aEnd.Row();
1029 nBlockEndZ = aMarkRange.aEnd.Tab();
1031 bool bDidReset = false;
1033 if ( nTab>=nBlockStartZ && nTab<=nBlockEndZ )
1035 if ( bReset )
1037 // Invertieren beim Loeschen nur auf aktiver View
1038 if ( aViewData.IsActive() )
1040 rMark.ResetMark();
1041 UpdateSelectionOverlay();
1042 bDidReset = true;
1045 else
1046 PaintMarks( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY );
1049 if ( bReset && !bDidReset )
1050 rMark.ResetMark();
1052 ShowAllCursors();
1056 void ScTabView::SelectAll( bool bContinue )
1058 ScMarkData& rMark = aViewData.GetMarkData();
1059 SCTAB nTab = aViewData.GetTabNo();
1061 if (rMark.IsMarked())
1063 ScRange aMarkRange;
1064 rMark.GetMarkArea( aMarkRange );
1065 if ( aMarkRange == ScRange( 0,0,nTab, MAXCOL,MAXROW,nTab ) )
1066 return;
1069 DoneBlockMode( bContinue );
1070 InitBlockMode( 0,0,nTab );
1071 MarkCursor( MAXCOL,MAXROW,nTab );
1073 SelectionChanged();
1076 void ScTabView::SelectAllTables()
1078 ScDocument* pDoc = aViewData.GetDocument();
1079 ScMarkData& rMark = aViewData.GetMarkData();
1080 SCTAB nCount = pDoc->GetTableCount();
1082 if (nCount>1)
1084 for (SCTAB i=0; i<nCount; i++)
1085 rMark.SelectTable( i, true );
1087 aViewData.GetDocShell()->PostPaintExtras();
1088 SfxBindings& rBind = aViewData.GetBindings();
1089 rBind.Invalidate( FID_FILL_TAB );
1090 rBind.Invalidate( FID_TAB_DESELECTALL );
1094 void ScTabView::DeselectAllTables()
1096 ScDocument* pDoc = aViewData.GetDocument();
1097 ScMarkData& rMark = aViewData.GetMarkData();
1098 SCTAB nTab = aViewData.GetTabNo();
1099 SCTAB nCount = pDoc->GetTableCount();
1101 for (SCTAB i=0; i<nCount; i++)
1102 rMark.SelectTable( i, ( i == nTab ) );
1104 aViewData.GetDocShell()->PostPaintExtras();
1105 SfxBindings& rBind = aViewData.GetBindings();
1106 rBind.Invalidate( FID_FILL_TAB );
1107 rBind.Invalidate( FID_TAB_DESELECTALL );
1110 static bool lcl_FitsInWindow( double fScaleX, double fScaleY, sal_uInt16 nZoom,
1111 long nWindowX, long nWindowY, ScDocument* pDoc, SCTAB nTab,
1112 SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1113 SCCOL nFixPosX, SCROW nFixPosY )
1115 double fZoomFactor = (double)Fraction(nZoom,100);
1116 fScaleX *= fZoomFactor;
1117 fScaleY *= fZoomFactor;
1119 long nBlockX = 0;
1120 SCCOL nCol;
1121 for (nCol=0; nCol<nFixPosX; nCol++)
1123 // for frozen panes, add both parts
1124 sal_uInt16 nColTwips = pDoc->GetColWidth( nCol, nTab );
1125 if (nColTwips)
1127 nBlockX += (long)(nColTwips * fScaleX);
1128 if (nBlockX > nWindowX)
1129 return false;
1132 for (nCol=nStartCol; nCol<=nEndCol; nCol++)
1134 sal_uInt16 nColTwips = pDoc->GetColWidth( nCol, nTab );
1135 if (nColTwips)
1137 nBlockX += (long)(nColTwips * fScaleX);
1138 if (nBlockX > nWindowX)
1139 return false;
1143 long nBlockY = 0;
1144 for (SCROW nRow = 0; nRow <= nFixPosY-1; ++nRow)
1146 if (pDoc->RowHidden(nRow, nTab))
1147 continue;
1149 // for frozen panes, add both parts
1150 sal_uInt16 nRowTwips = pDoc->GetRowHeight(nRow, nTab);
1151 if (nRowTwips)
1153 nBlockY += (long)(nRowTwips * fScaleY);
1154 if (nBlockY > nWindowY)
1155 return false;
1158 for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
1160 sal_uInt16 nRowTwips = pDoc->GetRowHeight(nRow, nTab);
1161 if (nRowTwips)
1163 nBlockY += (long)(nRowTwips * fScaleY);
1164 if (nBlockY > nWindowY)
1165 return false;
1169 return true;
1172 sal_uInt16 ScTabView::CalcZoom( SvxZoomType eType, sal_uInt16 nOldZoom )
1174 sal_uInt16 nZoom = 0; // Ergebnis
1176 switch ( eType )
1178 case SVX_ZOOM_PERCENT: // rZoom ist kein besonderer prozentualer Wert
1179 nZoom = nOldZoom;
1180 break;
1182 case SVX_ZOOM_OPTIMAL: // nZoom entspricht der optimalen Gr"o\se
1184 ScMarkData& rMark = aViewData.GetMarkData();
1185 ScDocument* pDoc = aViewData.GetDocument();
1187 if (!rMark.IsMarked() && !rMark.IsMultiMarked())
1188 nZoom = 100; // nothing selected
1189 else
1191 SCTAB nTab = aViewData.GetTabNo();
1192 ScRange aMarkRange;
1193 if ( aViewData.GetSimpleArea( aMarkRange ) != SC_MARK_SIMPLE )
1194 rMark.GetMultiMarkArea( aMarkRange );
1196 SCCOL nStartCol = aMarkRange.aStart.Col();
1197 SCROW nStartRow = aMarkRange.aStart.Row();
1198 SCTAB nStartTab = aMarkRange.aStart.Tab();
1199 SCCOL nEndCol = aMarkRange.aEnd.Col();
1200 SCROW nEndRow = aMarkRange.aEnd.Row();
1201 SCTAB nEndTab = aMarkRange.aEnd.Tab();
1203 if ( nTab < nStartTab && nTab > nEndTab )
1204 nTab = nStartTab;
1206 ScSplitPos eUsedPart = aViewData.GetActivePart();
1208 SCCOL nFixPosX = 0;
1209 SCROW nFixPosY = 0;
1210 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
1212 // use right part
1213 eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
1214 nFixPosX = aViewData.GetFixPosX();
1215 if ( nStartCol < nFixPosX )
1216 nStartCol = nFixPosX;
1218 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1220 // use bottom part
1221 eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
1222 nFixPosY = aViewData.GetFixPosY();
1223 if ( nStartRow < nFixPosY )
1224 nStartRow = nFixPosY;
1227 if (pGridWin[eUsedPart])
1229 // Because scale is rounded to pixels, the only reliable way to find
1230 // the right scale is to check if a zoom fits
1232 Size aWinSize = pGridWin[eUsedPart]->GetOutputSizePixel();
1234 // for frozen panes, use sum of both parts for calculation
1236 if ( nFixPosX != 0 )
1237 aWinSize.Width() += GetGridWidth( SC_SPLIT_LEFT );
1238 if ( nFixPosY != 0 )
1239 aWinSize.Height() += GetGridHeight( SC_SPLIT_TOP );
1241 ScDocShell* pDocSh = aViewData.GetDocShell();
1242 double nPPTX = ScGlobal::nScreenPPTX / pDocSh->GetOutputFactor();
1243 double nPPTY = ScGlobal::nScreenPPTY;
1245 sal_uInt16 nMin = MINZOOM;
1246 sal_uInt16 nMax = MAXZOOM;
1247 while ( nMax > nMin )
1249 sal_uInt16 nTest = (nMin+nMax+1)/2;
1250 if ( lcl_FitsInWindow(
1251 nPPTX, nPPTY, nTest, aWinSize.Width(), aWinSize.Height(),
1252 pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow,
1253 nFixPosX, nFixPosY ) )
1254 nMin = nTest;
1255 else
1256 nMax = nTest-1;
1258 OSL_ENSURE( nMin == nMax, "Schachtelung ist falsch" );
1259 nZoom = nMin;
1261 if ( nZoom != nOldZoom )
1263 // scroll to block only in active split part
1264 // (the part for which the size was calculated)
1266 if ( nStartCol <= nEndCol )
1267 aViewData.SetPosX( WhichH(eUsedPart), nStartCol );
1268 if ( nStartRow <= nEndRow )
1269 aViewData.SetPosY( WhichV(eUsedPart), nStartRow );
1274 break;
1276 case SVX_ZOOM_WHOLEPAGE: // nZoom entspricht der ganzen Seite oder
1277 case SVX_ZOOM_PAGEWIDTH: // nZoom entspricht der Seitenbreite
1279 SCTAB nCurTab = aViewData.GetTabNo();
1280 ScDocument* pDoc = aViewData.GetDocument();
1281 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
1282 SfxStyleSheetBase* pStyleSheet =
1283 pStylePool->Find( pDoc->GetPageStyle( nCurTab ),
1284 SFX_STYLE_FAMILY_PAGE );
1286 OSL_ENSURE( pStyleSheet, "PageStyle not found :-/" );
1288 if ( pStyleSheet )
1290 ScPrintFunc aPrintFunc( aViewData.GetDocShell(),
1291 aViewData.GetViewShell()->GetPrinter(true),
1292 nCurTab );
1294 Size aPageSize = aPrintFunc.GetDataSize();
1296 // use the size of the largest GridWin for normal split,
1297 // or both combined for frozen panes, with the (document) size
1298 // of the frozen part added to the page size
1299 // (with frozen panes, the size of the individual parts
1300 // depends on the scale that is to be calculated)
1302 if ( !pGridWin[SC_SPLIT_BOTTOMLEFT] ) return 0;
1303 Size aWinSize = pGridWin[SC_SPLIT_BOTTOMLEFT]->GetOutputSizePixel();
1304 ScSplitMode eHMode = aViewData.GetHSplitMode();
1305 if ( eHMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_BOTTOMRIGHT] )
1307 long nOtherWidth = pGridWin[SC_SPLIT_BOTTOMRIGHT]->
1308 GetOutputSizePixel().Width();
1309 if ( eHMode == SC_SPLIT_FIX )
1311 aWinSize.Width() += nOtherWidth;
1312 for ( SCCOL nCol = aViewData.GetPosX(SC_SPLIT_LEFT);
1313 nCol < aViewData.GetFixPosX(); nCol++ )
1314 aPageSize.Width() += pDoc->GetColWidth( nCol, nCurTab );
1316 else if ( nOtherWidth > aWinSize.Width() )
1317 aWinSize.Width() = nOtherWidth;
1319 ScSplitMode eVMode = aViewData.GetVSplitMode();
1320 if ( eVMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_TOPLEFT] )
1322 long nOtherHeight = pGridWin[SC_SPLIT_TOPLEFT]->
1323 GetOutputSizePixel().Height();
1324 if ( eVMode == SC_SPLIT_FIX )
1326 aWinSize.Height() += nOtherHeight;
1327 aPageSize.Height() += pDoc->GetRowHeight(
1328 aViewData.GetPosY(SC_SPLIT_TOP),
1329 aViewData.GetFixPosY()-1, nCurTab);
1331 else if ( nOtherHeight > aWinSize.Height() )
1332 aWinSize.Height() = nOtherHeight;
1335 double nPPTX = ScGlobal::nScreenPPTX / aViewData.GetDocShell()->GetOutputFactor();
1336 double nPPTY = ScGlobal::nScreenPPTY;
1338 long nZoomX = (long) ( aWinSize.Width() * 100 /
1339 ( aPageSize.Width() * nPPTX ) );
1340 long nZoomY = (long) ( aWinSize.Height() * 100 /
1341 ( aPageSize.Height() * nPPTY ) );
1342 long nNew = nZoomX;
1344 if (eType == SVX_ZOOM_WHOLEPAGE && nZoomY < nNew)
1345 nNew = nZoomY;
1347 nZoom = (sal_uInt16) nNew;
1350 break;
1352 default:
1353 OSL_FAIL("Unknown Zoom-Revision");
1354 nZoom = 0;
1357 return nZoom;
1360 // wird z.B. gerufen, wenn sich das View-Fenster verschiebt:
1362 void ScTabView::StopMarking()
1364 ScSplitPos eActive = aViewData.GetActivePart();
1365 if (pGridWin[eActive])
1366 pGridWin[eActive]->StopMarking();
1368 ScHSplitPos eH = WhichH(eActive);
1369 if (pColBar[eH])
1370 pColBar[eH]->StopMarking();
1372 ScVSplitPos eV = WhichV(eActive);
1373 if (pRowBar[eV])
1374 pRowBar[eV]->StopMarking();
1377 void ScTabView::HideNoteMarker()
1379 for (sal_uInt16 i=0; i<4; i++)
1380 if (pGridWin[i] && pGridWin[i]->IsVisible())
1381 pGridWin[i]->HideNoteMarker();
1384 void ScTabView::MakeDrawLayer()
1386 if (!pDrawView)
1388 aViewData.GetDocShell()->MakeDrawLayer();
1390 // pDrawView wird per Notify gesetzt
1391 OSL_ENSURE(pDrawView,"ScTabView::MakeDrawLayer funktioniert nicht");
1393 // #114409#
1394 for(sal_uInt16 a(0); a < 4; a++)
1396 if(pGridWin[a])
1398 pGridWin[a]->DrawLayerCreated();
1404 void ScTabView::ErrorMessage( sal_uInt16 nGlobStrId )
1406 if ( SC_MOD()->IsInExecuteDrop() )
1408 // #i28468# don't show error message when called from Drag&Drop, silently abort instead
1409 return;
1412 StopMarking(); // falls per Focus aus MouseButtonDown aufgerufen
1414 Window* pParent = aViewData.GetDialogParent();
1415 ScWaitCursorOff aWaitOff( pParent );
1416 bool bFocus = pParent && pParent->HasFocus();
1418 if(nGlobStrId==STR_PROTECTIONERR)
1420 if(aViewData.GetDocShell()->IsReadOnly())
1422 nGlobStrId=STR_READONLYERR;
1426 InfoBox aBox( pParent, ScGlobal::GetRscString( nGlobStrId ) );
1427 aBox.Execute();
1428 if (bFocus)
1429 pParent->GrabFocus();
1432 void ScTabView::UpdatePageBreakData( bool bForcePaint )
1434 ScPageBreakData* pNewData = NULL;
1436 if (aViewData.IsPagebreakMode())
1438 ScDocShell* pDocSh = aViewData.GetDocShell();
1439 ScDocument* pDoc = pDocSh->GetDocument();
1440 SCTAB nTab = aViewData.GetTabNo();
1442 sal_uInt16 nCount = pDoc->GetPrintRangeCount(nTab);
1443 if (!nCount)
1444 nCount = 1;
1445 pNewData = new ScPageBreakData(nCount);
1447 ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab, 0,0,NULL, NULL, pNewData );
1448 // ScPrintFunc fuellt im ctor die PageBreakData
1449 if ( nCount > 1 )
1451 aPrintFunc.ResetBreaks(nTab);
1452 pNewData->AddPages();
1455 // Druckbereiche veraendert?
1456 if ( bForcePaint || ( pPageBreakData && !( *pPageBreakData == *pNewData ) ) )
1457 PaintGrid();
1460 delete pPageBreakData;
1461 pPageBreakData = pNewData;
1464 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */