fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / ui / view / tabview2.cxx
blob6d355f70af203a9bc6e778deed9911d90a88455b
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 .
20 #include "scitems.hxx"
21 #include <editeng/eeitem.hxx>
22 #include <vcl/timer.hxx>
23 #include <vcl/msgbox.hxx>
24 #include <sfx2/app.hxx>
25 #include <sfx2/viewfrm.hxx>
26 #include <sfx2/bindings.hxx>
27 #include <sfx2/childwin.hxx>
29 #include "attrib.hxx"
30 #include "pagedata.hxx"
31 #include "tabview.hxx"
32 #include "tabvwsh.hxx"
33 #include "printfun.hxx"
34 #include "stlpool.hxx"
35 #include "docsh.hxx"
36 #include "gridwin.hxx"
37 #include "olinewin.hxx"
38 #include "uiitems.hxx"
39 #include "sc.hrc"
40 #include "viewutil.hxx"
41 #include "colrowba.hxx"
42 #include "waitoff.hxx"
43 #include "globstr.hrc"
44 #include "scmod.hxx"
45 #include "tabprotection.hxx"
46 #include "markdata.hxx"
47 #include "inputopt.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 SCCOL nNewUnhiddenCol = rCol + 1;
82 SCCOL nEndCol = 0;
83 while(pDoc->ColHidden(nNewUnhiddenCol, nTab, NULL, &nEndCol))
85 if(nNewUnhiddenCol >= MAXCOL)
86 return;
88 i += nEndCol - nNewUnhiddenCol + 1;
89 nNewUnhiddenCol = nEndCol +1;
92 if (!isCellQualified(pDoc, nNewUnhiddenCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
93 break;
94 rCol = nNewUnhiddenCol;
97 else if (nMovX < 0)
99 for (SCCOL i = 0; i > nMovX && rCol > 0; --i)
101 SCCOL nNewUnhiddenCol = rCol - 1;
102 SCCOL nStartCol = 0;
103 while(pDoc->ColHidden(nNewUnhiddenCol, nTab, &nStartCol))
105 if(nNewUnhiddenCol <= 0)
106 return;
108 i -= nNewUnhiddenCol - nStartCol + 1;
109 nNewUnhiddenCol = nStartCol - 1;
112 if (!isCellQualified(pDoc, nNewUnhiddenCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
113 break;
114 rCol = nNewUnhiddenCol;
118 if (nMovY > 0)
120 for (SCROW i = 0; i < nMovY && rRow < MAXROW; ++i)
122 SCROW nNewUnhiddenRow = rRow + 1;
123 SCROW nEndRow = 0;
124 while(pDoc->RowHidden(nNewUnhiddenRow, nTab, NULL, &nEndRow))
126 if(nNewUnhiddenRow >= MAXROW)
127 return;
129 i += nEndRow - nNewUnhiddenRow + 1;
130 nNewUnhiddenRow = nEndRow + 1;
133 if (!isCellQualified(pDoc, rCol, nNewUnhiddenRow, nTab, bSelectLocked, bSelectUnlocked))
134 break;
135 rRow = nNewUnhiddenRow;
138 else if (nMovY < 0)
140 for (SCROW i = 0; i > nMovY && rRow > 0; --i)
142 SCROW nNewUnhiddenRow = rRow - 1;
143 SCROW nStartRow = 0;
144 while(pDoc->RowHidden(nNewUnhiddenRow, nTab, &nStartRow))
146 if(nNewUnhiddenRow <= 0)
147 return;
149 i -= nNewUnhiddenRow - nStartRow + 1;
150 nNewUnhiddenRow = nStartRow - 1;
153 if (!isCellQualified(pDoc, rCol, nNewUnhiddenRow, nTab, bSelectLocked, bSelectUnlocked))
154 break;
155 rRow = nNewUnhiddenRow;
160 bool checkBoundary(SCCOL& rCol, SCROW& rRow)
162 bool bGood = true;
163 if (rCol < 0)
165 rCol = 0;
166 bGood = false;
168 else if (rCol > MAXCOL)
170 rCol = MAXCOL;
171 bGood = false;
174 if (rRow < 0)
176 rRow = 0;
177 bGood = false;
179 else if (rRow > MAXROW)
181 rRow = MAXROW;
182 bGood = false;
184 return bGood;
187 void moveCursorByMergedCell(
188 SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY, SCTAB nTab,
189 ScDocument* pDoc, const ScViewData& rViewData)
191 SCCOL nOrigX = rViewData.GetCurX();
192 SCROW nOrigY = rViewData.GetCurY();
194 ScTableProtection* pTabProtection = pDoc->GetTabProtection(nTab);
195 bool bSelectLocked = true;
196 bool bSelectUnlocked = true;
197 if (pTabProtection && pTabProtection->isProtected())
199 bSelectLocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
200 bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
203 const ScMergeAttr* pMergeAttr = static_cast<const ScMergeAttr*>(
204 pDoc->GetAttr(nOrigX, nOrigY, nTab, ATTR_MERGE));
206 bool bOriginMerged = false;
207 SCsCOL nColSpan = 1;
208 SCsROW nRowSpan = 1;
209 if (pMergeAttr && pMergeAttr->IsMerged())
211 nColSpan = pMergeAttr->GetColMerge();
212 nRowSpan = pMergeAttr->GetRowMerge();
213 bOriginMerged = true;
216 if (nMovX > 0)
218 SCCOL nOld = rCol;
219 if (bOriginMerged)
221 // Original cell is merged. Push the block end outside the merged region.
222 if (nOrigX < MAXCOL && nOrigX < rCol && rCol <= nOrigX + nColSpan - 1)
223 rCol = nOrigX + nColSpan;
225 else
227 pDoc->SkipOverlapped(rCol, rRow, nTab);
230 if (nOld < rCol)
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 --rCol;
238 if (nMovX < 0)
240 SCCOL nOld = rCol;
241 if (bOriginMerged)
243 if (nOrigX > 0 && nOrigX <= rCol && rCol < nOrigX + nColSpan - 1)
244 // Block end is still within the merged region. Push it outside.
245 rCol = nOrigX - 1;
247 else
249 pDoc->SkipOverlapped(rCol, rRow, nTab);
252 if (nOld > rCol)
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 ++rCol;
260 if (nMovY > 0)
262 SCROW nOld = rRow;
263 if (bOriginMerged)
265 // Original cell is merged. Push the block end outside the merged region.
266 if (nOrigY < MAXROW && nOrigY < rRow && rRow <= nOrigY + nRowSpan - 1)
267 rRow = nOrigY + nRowSpan;
269 else
271 pDoc->SkipOverlapped(rCol, rRow, nTab);
274 if (nOld < rRow)
276 // The block end has moved. Check the protection setting and move back if needed.
277 checkBoundary(rCol, rRow);
278 if (!isCellQualified(pDoc, rCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
279 --rRow;
282 if (nMovY < 0)
284 SCROW nOld = rRow;
285 if (bOriginMerged)
287 if (nOrigY > 0 && nOrigY <= rRow && rRow < nOrigY + nRowSpan - 1)
288 // Block end is still within the merged region. Push it outside.
289 rRow = nOrigY - 1;
291 else
293 pDoc->SkipOverlapped(rCol, rRow, nTab);
296 if (nOld > rRow)
298 // The block end has moved. Check the protection setting and move back if needed.
299 checkBoundary(rCol, rRow);
300 if (!isCellQualified(pDoc, rCol, rRow, nTab, bSelectLocked, bSelectUnlocked))
301 ++rRow;
308 void ScTabView::PaintMarks(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
310 if (!ValidCol(nStartCol)) nStartCol = MAXCOL;
311 if (!ValidRow(nStartRow)) nStartRow = MAXROW;
312 if (!ValidCol(nEndCol)) nEndCol = MAXCOL;
313 if (!ValidRow(nEndRow)) nEndRow = MAXROW;
315 bool bLeft = (nStartCol==0 && nEndCol==MAXCOL);
316 bool bTop = (nStartRow==0 && nEndRow==MAXROW);
318 if (bLeft)
319 PaintLeftArea( nStartRow, nEndRow );
320 if (bTop)
321 PaintTopArea( nStartCol, nEndCol );
323 aViewData.GetDocument()->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow,
324 aViewData.GetTabNo() );
325 PaintArea( nStartCol, nStartRow, nEndCol, nEndRow, SC_UPDATE_MARKS );
328 bool ScTabView::IsMarking( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
330 return IsBlockMode()
331 && nBlockStartX == nCol
332 && nBlockStartY == nRow
333 && nBlockStartZ == nTab;
336 void ScTabView::InitOwnBlockMode()
338 if (!IsBlockMode())
340 // Wenn keine (alte) Markierung mehr da ist, Anker in SelectionEngine loeschen:
342 ScMarkData& rMark = aViewData.GetMarkData();
343 if (!rMark.IsMarked() && !rMark.IsMultiMarked())
344 GetSelEngine()->CursorPosChanging( false, false );
346 meBlockMode = Own;
347 nBlockStartX = 0;
348 nBlockStartY = 0;
349 nBlockStartZ = 0;
350 nBlockEndX = 0;
351 nBlockEndY = 0;
352 nBlockEndZ = 0;
354 SelectionChanged(); // Status wird mit gesetzer Markierung abgefragt
358 void ScTabView::InitBlockMode( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
359 bool bTestNeg, bool bCols, bool bRows, bool bForceNeg )
361 if (!IsBlockMode())
363 if (!ValidCol(nCurX)) nCurX = MAXCOL;
364 if (!ValidRow(nCurY)) nCurY = MAXROW;
366 ScMarkData& rMark = aViewData.GetMarkData();
367 SCTAB nTab = aViewData.GetTabNo();
369 // Teil von Markierung aufheben?
370 if (bForceNeg)
371 bBlockNeg = true;
372 else if (bTestNeg)
374 if ( bCols )
375 bBlockNeg = rMark.IsColumnMarked( nCurX );
376 else if ( bRows )
377 bBlockNeg = rMark.IsRowMarked( nCurY );
378 else
379 bBlockNeg = rMark.IsCellMarked( nCurX, nCurY );
381 else
382 bBlockNeg = false;
383 rMark.SetMarkNegative(bBlockNeg);
385 meBlockMode = Normal;
386 bBlockCols = bCols;
387 bBlockRows = bRows;
388 nBlockStartX = nBlockStartXOrig = nCurX;
389 nBlockStartY = nBlockStartYOrig = nCurY;
390 nBlockStartZ = nCurZ;
391 nBlockEndX = nOldCurX = nBlockStartX;
392 nBlockEndY = nOldCurY = nBlockStartY;
393 nBlockEndZ = nBlockStartZ;
395 if (bBlockCols)
397 nBlockStartY = nBlockStartYOrig = 0;
398 nBlockEndY = MAXROW;
401 if (bBlockRows)
403 nBlockStartX = nBlockStartXOrig = 0;
404 nBlockEndX = MAXCOL;
407 rMark.SetMarkArea( ScRange( nBlockStartX,nBlockStartY, nTab, nBlockEndX,nBlockEndY, nTab ) );
409 UpdateSelectionOverlay();
413 void ScTabView::DoneBlockMode( bool bContinue )
415 // Wenn zwischen Tabellen- und Header SelectionEngine gewechselt wird,
416 // wird evtl. DeselectAll gerufen, weil die andere Engine keinen Anker hat.
417 // Mit bMoveIsShift wird verhindert, dass dann die Selektion aufgehoben wird.
419 if (IsBlockMode() && !bMoveIsShift)
421 ScMarkData& rMark = aViewData.GetMarkData();
422 bool bFlag = rMark.GetMarkingFlag();
423 rMark.SetMarking(false);
425 if (bBlockNeg && !bContinue)
426 rMark.MarkToMulti();
428 if (bContinue)
429 rMark.MarkToMulti();
430 else
432 // Die Tabelle kann an dieser Stelle ungueltig sein, weil DoneBlockMode
433 // aus SetTabNo aufgerufen wird
434 // (z.B. wenn die aktuelle Tabelle von einer anderen View aus geloescht wird)
436 SCTAB nTab = aViewData.GetTabNo();
437 ScDocument* pDoc = aViewData.GetDocument();
438 if ( pDoc->HasTable(nTab) )
439 PaintBlock( true ); // true -> Block loeschen
440 else
441 rMark.ResetMark();
443 meBlockMode = None;
445 rMark.SetMarking(bFlag);
446 rMark.SetMarkNegative(false);
450 bool ScTabView::IsBlockMode() const
452 return meBlockMode != None;
455 void ScTabView::MarkCursor( SCCOL nCurX, SCROW nCurY, SCTAB nCurZ,
456 bool bCols, bool bRows, bool bCellSelection )
458 if (!ValidCol(nCurX)) nCurX = MAXCOL;
459 if (!ValidRow(nCurY)) nCurY = MAXROW;
461 if (!IsBlockMode())
463 OSL_FAIL( "MarkCursor nicht im BlockMode" );
464 InitBlockMode( nCurX, nCurY, nCurZ, false, bCols, bRows );
467 if (bCols)
468 nCurY = MAXROW;
469 if (bRows)
470 nCurX = MAXCOL;
472 ScMarkData& rMark = aViewData.GetMarkData();
473 OSL_ENSURE(rMark.IsMarked() || rMark.IsMultiMarked(), "MarkCursor, !IsMarked()");
474 ScRange aMarkRange;
475 rMark.GetMarkArea(aMarkRange);
476 if (( aMarkRange.aStart.Col() != nBlockStartX && aMarkRange.aEnd.Col() != nBlockStartX ) ||
477 ( aMarkRange.aStart.Row() != nBlockStartY && aMarkRange.aEnd.Row() != nBlockStartY ) ||
478 ( meBlockMode == Own ))
480 // Markierung ist veraendert worden
481 // (z.B. MarkToSimple, wenn per negativ alles bis auf ein Rechteck geloescht wurde)
482 // oder nach InitOwnBlockMode wird mit Shift-Klick weitermarkiert...
484 bool bOldShift = bMoveIsShift;
485 bMoveIsShift = false; // wirklich umsetzen
486 DoneBlockMode(false); //! direkt Variablen setzen? (-> kein Geflacker)
487 bMoveIsShift = bOldShift;
489 InitBlockMode( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
490 nBlockStartZ, rMark.IsMarkNegative(), bCols, bRows );
493 if ( nCurX != nOldCurX || nCurY != nOldCurY )
495 // Current cursor has moved
497 SCTAB nTab = nCurZ;
499 if ( bCellSelection )
501 // Expand selection area accordingly when the current selection ends
502 // with a merged cell.
503 SCsCOL nCurXOffset = 0;
504 SCsCOL nBlockStartXOffset = 0;
505 SCsROW nCurYOffset = 0;
506 SCsROW nBlockStartYOffset = 0;
507 bool bBlockStartMerged = false;
508 const ScMergeAttr* pMergeAttr = NULL;
509 ScDocument* pDocument = aViewData.GetDocument();
511 // The following block checks whether or not the "BlockStart" (anchor)
512 // cell is merged. If it's merged, it'll then move the position of the
513 // anchor cell to the corner that's diagonally opposite of the
514 // direction of a current selection area. For instance, if a current
515 // selection is moving in the upperleft direction, the anchor cell will
516 // move to the lower-right corner of the merged anchor cell, and so on.
518 pMergeAttr = static_cast<const ScMergeAttr*>(
519 pDocument->GetAttr( nBlockStartXOrig, nBlockStartYOrig, nTab, ATTR_MERGE ) );
520 if ( pMergeAttr->IsMerged() )
522 SCsCOL nColSpan = pMergeAttr->GetColMerge();
523 SCsROW nRowSpan = pMergeAttr->GetRowMerge();
525 if ( !( nCurX >= nBlockStartXOrig + nColSpan - 1 && nCurY >= nBlockStartYOrig + nRowSpan - 1 ) )
527 nBlockStartX = nCurX >= nBlockStartXOrig ? nBlockStartXOrig : nBlockStartXOrig + nColSpan - 1;
528 nBlockStartY = nCurY >= nBlockStartYOrig ? nBlockStartYOrig : nBlockStartYOrig + nRowSpan - 1;
529 nCurXOffset = (nCurX >= nBlockStartXOrig && nCurX < nBlockStartXOrig + nColSpan - 1) ?
530 nBlockStartXOrig - nCurX + nColSpan - 1 : 0;
531 nCurYOffset = (nCurY >= nBlockStartYOrig && nCurY < nBlockStartYOrig + nRowSpan - 1) ?
532 nBlockStartYOrig - nCurY + nRowSpan - 1 : 0;
533 bBlockStartMerged = true;
537 // The following block checks whether or not the current cell is
538 // merged. If it is, it'll then set the appropriate X & Y offset
539 // values (nCurXOffset & nCurYOffset) such that the selection area will
540 // grow by those specified offset amounts. Note that the values of
541 // nCurXOffset/nCurYOffset may also be specified in the previous code
542 // block, in which case whichever value is greater will take on.
544 pMergeAttr = static_cast<const ScMergeAttr*>(
545 pDocument->GetAttr( nCurX, nCurY, nTab, ATTR_MERGE ) );
546 if ( pMergeAttr->IsMerged() )
548 SCsCOL nColSpan = pMergeAttr->GetColMerge();
549 SCsROW nRowSpan = pMergeAttr->GetRowMerge();
551 if ( !( nBlockStartX >= nCurX + nColSpan - 1 && nBlockStartY >= nCurY + nRowSpan - 1 ) )
553 if ( nBlockStartX <= nCurX + nColSpan - 1 )
555 SCsCOL nCurXOffsetTemp = (nCurX < nCurX + nColSpan - 1) ? nColSpan - 1 : 0;
556 nCurXOffset = nCurXOffset > nCurXOffsetTemp ? nCurXOffset : nCurXOffsetTemp;
558 if ( nBlockStartY <= nCurY + nRowSpan - 1 )
560 SCsROW nCurYOffsetTemp = (nCurY < nCurY + nRowSpan - 1) ? nRowSpan - 1 : 0;
561 nCurYOffset = nCurYOffset > nCurYOffsetTemp ? nCurYOffset : nCurYOffsetTemp;
563 if ( !( nBlockStartX <= nCurX && nBlockStartY <= nCurY ) &&
564 !( nBlockStartX > nCurX + nColSpan - 1 && nBlockStartY > nCurY + nRowSpan - 1 ) )
566 nBlockStartXOffset = (nBlockStartX > nCurX && nBlockStartX <= nCurX + nColSpan - 1) ? nCurX - nBlockStartX : 0;
567 nBlockStartYOffset = (nBlockStartY > nCurY && nBlockStartY <= nCurY + nRowSpan - 1) ? nCurY - nBlockStartY : 0;
571 else
573 // The current cell is not merged. Move the anchor cell to its
574 // original position.
575 if ( !bBlockStartMerged )
577 nBlockStartX = nBlockStartXOrig;
578 nBlockStartY = nBlockStartYOrig;
582 nBlockStartX = nBlockStartX + nBlockStartXOffset >= 0 ? nBlockStartX + nBlockStartXOffset : 0;
583 nBlockStartY = nBlockStartY + nBlockStartYOffset >= 0 ? nBlockStartY + nBlockStartYOffset : 0;
584 nBlockEndX = nCurX + nCurXOffset > MAXCOL ? MAXCOL : nCurX + nCurXOffset;
585 nBlockEndY = nCurY + nCurYOffset > MAXROW ? MAXROW : nCurY + nCurYOffset;
587 else
589 nBlockEndX = nCurX;
590 nBlockEndY = nCurY;
593 // Set new selection area
594 rMark.SetMarkArea( ScRange( nBlockStartX, nBlockStartY, nTab, nBlockEndX, nBlockEndY, nTab ) );
596 UpdateSelectionOverlay();
597 SelectionChanged();
599 nOldCurX = nCurX;
600 nOldCurY = nCurY;
602 aViewData.GetViewShell()->UpdateInputHandler();
605 if ( !bCols && !bRows )
606 aHdrFunc.SetAnchorFlag( false );
609 void ScTabView::GetPageMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, SCsCOL& rPageX, SCsROW& rPageY)
611 SCCOL nCurX;
612 SCROW nCurY;
613 if (aViewData.IsRefMode())
615 nCurX = aViewData.GetRefEndX();
616 nCurY = aViewData.GetRefEndY();
618 else if (IsBlockMode())
620 // block end position.
621 nCurX = nBlockEndX;
622 nCurY = nBlockEndY;
624 else
626 // cursor position
627 nCurX = aViewData.GetCurX();
628 nCurY = aViewData.GetCurY();
631 ScSplitPos eWhich = aViewData.GetActivePart();
632 ScHSplitPos eWhichX = WhichH( eWhich );
633 ScVSplitPos eWhichY = WhichV( eWhich );
635 SCsCOL nPageX;
636 SCsROW nPageY;
637 if (nMovX >= 0)
638 nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, 1, eWhichX )) * nMovX;
639 else
640 nPageX = ((SCsCOL) aViewData.CellsAtX( nCurX, -1, eWhichX )) * nMovX;
642 if (nMovY >= 0)
643 nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, 1, eWhichY )) * nMovY;
644 else
645 nPageY = ((SCsROW) aViewData.CellsAtY( nCurY, -1, eWhichY )) * nMovY;
647 if (nMovX != 0 && nPageX == 0) nPageX = (nMovX>0) ? 1 : -1;
648 if (nMovY != 0 && nPageY == 0) nPageY = (nMovY>0) ? 1 : -1;
650 rPageX = nPageX;
651 rPageY = nPageY;
654 void ScTabView::GetAreaMoveEndPosition(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
655 SCsCOL& rAreaX, SCsROW& rAreaY, ScFollowMode& rMode)
657 SCCOL nNewX = -1;
658 SCROW nNewY = -1;
660 // current cursor position.
661 SCCOL nCurX = aViewData.GetCurX();
662 SCROW nCurY = aViewData.GetCurY();
664 if (aViewData.IsRefMode())
666 nNewX = aViewData.GetRefEndX();
667 nNewY = aViewData.GetRefEndY();
668 nCurX = aViewData.GetRefStartX();
669 nCurY = aViewData.GetRefStartY();
671 else if (IsBlockMode())
673 // block end position.
674 nNewX = nBlockEndX;
675 nNewY = nBlockEndY;
677 else
679 nNewX = nCurX;
680 nNewY = nCurY;
683 ScDocument* pDoc = aViewData.GetDocument();
684 SCTAB nTab = aViewData.GetTabNo();
686 // FindAreaPos kennt nur -1 oder 1 als Richtung
687 ScModule* pScModule = SC_MOD();
688 bool bLegacyCellSelection = pScModule->GetInputOptions().GetLegacyCellSelection();
689 SCCOL nVirtualX = bLegacyCellSelection ? nNewX : nCurX;
690 SCROW nVirtualY = bLegacyCellSelection ? nNewY : nCurY;
692 SCsCOLROW i;
693 if ( nMovX > 0 )
694 for ( i=0; i<nMovX; i++ )
695 pDoc->FindAreaPos( nNewX, nVirtualY, nTab, SC_MOVE_RIGHT );
696 if ( nMovX < 0 )
697 for ( i=0; i<-nMovX; i++ )
698 pDoc->FindAreaPos( nNewX, nVirtualY, nTab, SC_MOVE_LEFT );
699 if ( nMovY > 0 )
700 for ( i=0; i<nMovY; i++ )
701 pDoc->FindAreaPos( nVirtualX, nNewY, nTab, SC_MOVE_DOWN );
702 if ( nMovY < 0 )
703 for ( i=0; i<-nMovY; i++ )
704 pDoc->FindAreaPos( nVirtualX, nNewY, nTab, SC_MOVE_UP );
706 if (eMode==SC_FOLLOW_JUMP) // unten/rechts nicht zuviel grau anzeigen
708 if (nMovX != 0 && nNewX == MAXCOL)
709 eMode = SC_FOLLOW_LINE;
710 if (nMovY != 0 && nNewY == MAXROW)
711 eMode = SC_FOLLOW_LINE;
714 if (aViewData.IsRefMode())
716 rAreaX = nNewX - aViewData.GetRefEndX();
717 rAreaY = nNewY - aViewData.GetRefEndY();
719 else if (IsBlockMode())
721 rAreaX = nNewX - nBlockEndX;
722 rAreaY = nNewY - nBlockEndY;
724 else
726 rAreaX = nNewX - nCurX;
727 rAreaY = nNewY - nCurY;
729 rMode = eMode;
732 void ScTabView::SkipCursorHorizontal(SCsCOL& rCurX, SCsROW& rCurY, SCsCOL nOldX, SCsROW nMovX)
734 ScDocument* pDoc = aViewData.GetDocument();
735 SCTAB nTab = aViewData.GetTabNo();
737 bool bSkipProtected = false, bSkipUnprotected = false;
738 ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
739 if (pProtect && pProtect->isProtected())
741 bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
742 bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
745 bool bSkipCell = false;
746 bool bHFlip = false;
749 bSkipCell = pDoc->ColHidden(rCurX, nTab) || pDoc->IsHorOverlapped(rCurX, rCurY, nTab);
750 if (bSkipProtected && !bSkipCell)
751 bSkipCell = pDoc->HasAttrib(rCurX, rCurY, nTab, rCurX, rCurY, nTab, HASATTR_PROTECTED);
752 if (bSkipUnprotected && !bSkipCell)
753 bSkipCell = !pDoc->HasAttrib(rCurX, rCurY, nTab, rCurX, rCurY, nTab, HASATTR_PROTECTED);
755 if (bSkipCell)
757 if (rCurX <= 0 || rCurX >= MAXCOL)
759 if (bHFlip)
761 rCurX = nOldX;
762 bSkipCell = false;
764 else
766 nMovX = -nMovX;
767 if (nMovX > 0)
768 ++rCurX;
769 else
770 --rCurX;
771 bHFlip = true;
774 else
775 if (nMovX > 0)
776 ++rCurX;
777 else
778 --rCurX;
781 while (bSkipCell);
783 if (pDoc->IsVerOverlapped(rCurX, rCurY, nTab))
785 aViewData.SetOldCursor(rCurX, rCurY);
786 while (pDoc->IsVerOverlapped(rCurX, rCurY, nTab))
787 --rCurY;
791 void ScTabView::SkipCursorVertical(SCsCOL& rCurX, SCsROW& rCurY, SCsROW nOldY, SCsROW nMovY)
793 ScDocument* pDoc = aViewData.GetDocument();
794 SCTAB nTab = aViewData.GetTabNo();
796 bool bSkipProtected = false, bSkipUnprotected = false;
797 ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
798 if (pProtect && pProtect->isProtected())
800 bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
801 bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
804 bool bSkipCell = false;
805 bool bVFlip = false;
808 SCROW nLastRow = -1;
809 bSkipCell = pDoc->RowHidden(rCurY, nTab, NULL, &nLastRow) || pDoc->IsVerOverlapped( rCurX, rCurY, nTab );
810 if (bSkipProtected && !bSkipCell)
811 bSkipCell = pDoc->HasAttrib(rCurX, rCurY, nTab, rCurX, rCurY, nTab, HASATTR_PROTECTED);
812 if (bSkipUnprotected && !bSkipCell)
813 bSkipCell = !pDoc->HasAttrib(rCurX, rCurY, nTab, rCurX, rCurY, nTab, HASATTR_PROTECTED);
815 if (bSkipCell)
817 if (rCurY <= 0 || rCurY >= MAXROW)
819 if (bVFlip)
821 rCurY = nOldY;
822 bSkipCell = false;
824 else
826 nMovY = -nMovY;
827 if (nMovY > 0)
828 ++rCurY;
829 else
830 --rCurY;
831 bVFlip = true;
834 else
835 if (nMovY > 0)
836 ++rCurY;
837 else
838 --rCurY;
841 while (bSkipCell);
843 if (pDoc->IsHorOverlapped(rCurX, rCurY, nTab))
845 aViewData.SetOldCursor(rCurX, rCurY);
846 while (pDoc->IsHorOverlapped(rCurX, rCurY, nTab))
847 --rCurX;
851 void ScTabView::ExpandBlock(SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode)
853 if (!nMovX && !nMovY)
854 // Nothing to do. Bail out.
855 return;
857 ScTabViewShell* pViewShell = aViewData.GetViewShell();
858 bool bRefInputMode = pViewShell && pViewShell->IsRefInputMode();
859 if (bRefInputMode && !aViewData.IsRefMode())
860 // initialize formula reference mode if it hasn't already.
861 InitRefMode(aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo(), SC_REFTYPE_REF);
863 ScDocument* pDoc = aViewData.GetDocument();
865 if (aViewData.IsRefMode())
867 // formula reference mode
869 SCCOL nNewX = aViewData.GetRefEndX();
870 SCROW nNewY = aViewData.GetRefEndY();
871 SCTAB nRefTab = aViewData.GetRefEndZ();
873 bool bSelectLocked = true;
874 bool bSelectUnlocked = true;
875 ScTableProtection* pTabProtection = pDoc->GetTabProtection(nRefTab);
876 if (pTabProtection && pTabProtection->isProtected())
878 bSelectLocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
879 bSelectUnlocked = pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
882 moveCursorByProtRule(nNewX, nNewY, nMovX, nMovY, nRefTab, pDoc);
883 checkBoundary(nNewX, nNewY);
885 if (nMovX)
887 SCCOL nTempX = nNewX;
888 while (pDoc->IsHorOverlapped(nTempX, nNewY, nRefTab))
890 if (nMovX > 0)
891 ++nTempX;
892 else
893 --nTempX;
894 if (!checkBoundary(nTempX, nNewY))
895 break;
897 if (isCellQualified(pDoc, nTempX, nNewY, nRefTab, bSelectLocked, bSelectUnlocked))
898 nNewX = nTempX;
901 if (nMovY)
903 SCROW nTempY = nNewY;
904 while (pDoc->IsVerOverlapped(nNewX, nTempY, nRefTab))
906 if (nMovY > 0)
907 ++nTempY;
908 else
909 --nTempY;
910 if (!checkBoundary(nNewX, nTempY))
911 break;
913 if (isCellQualified(pDoc, nNewX, nTempY, nRefTab, bSelectLocked, bSelectUnlocked))
914 nNewY = nTempY;
917 pDoc->SkipOverlapped(nNewX, nNewY, nRefTab);
918 UpdateRef(nNewX, nNewY, nRefTab);
919 AlignToCursor(nNewX, nNewY, eMode);
921 else
923 // normal selection mode
925 SCTAB nTab = aViewData.GetTabNo();
926 SCCOL nOrigX = aViewData.GetCurX();
927 SCROW nOrigY = aViewData.GetCurY();
929 // Note that the origin position *never* moves during selection.
931 if (!IsBlockMode())
932 InitBlockMode(nOrigX, nOrigY, nTab, true);
934 moveCursorByProtRule(nBlockEndX, nBlockEndY, nMovX, nMovY, nTab, pDoc);
935 checkBoundary(nBlockEndX, nBlockEndY);
936 moveCursorByMergedCell(nBlockEndX, nBlockEndY, nMovX, nMovY, nTab, pDoc, aViewData);
937 checkBoundary(nBlockEndX, nBlockEndY);
939 MarkCursor(nBlockEndX, nBlockEndY, nTab, false, false, true);
941 // Check if the entire row(s) or column(s) are selected.
942 ScSplitPos eActive = aViewData.GetActivePart();
943 bool bRowSelected = (nBlockStartX == 0 && nBlockEndX == MAXCOL);
944 bool bColSelected = (nBlockStartY == 0 && nBlockEndY == MAXROW);
945 SCsCOL nAlignX = bRowSelected ? aViewData.GetPosX(WhichH(eActive)) : nBlockEndX;
946 SCsROW nAlignY = bColSelected ? aViewData.GetPosY(WhichV(eActive)) : nBlockEndY;
947 AlignToCursor(nAlignX, nAlignY, eMode);
949 SelectionChanged();
953 void ScTabView::ExpandBlockPage(SCsCOL nMovX, SCsROW nMovY)
955 SCsCOL nPageX;
956 SCsROW nPageY;
957 GetPageMoveEndPosition(nMovX, nMovY, nPageX, nPageY);
958 ExpandBlock(nPageX, nPageY, SC_FOLLOW_FIX);
961 void ScTabView::ExpandBlockArea(SCsCOL nMovX, SCsROW nMovY)
963 SCsCOL nAreaX;
964 SCsROW nAreaY;
965 ScFollowMode eMode;
966 GetAreaMoveEndPosition(nMovX, nMovY, SC_FOLLOW_JUMP, nAreaX, nAreaY, eMode);
967 ExpandBlock(nAreaX, nAreaY, eMode);
970 void ScTabView::UpdateCopySourceOverlay()
972 for (sal_uInt8 i = 0; i < 4; ++i)
973 if (pGridWin[i] && pGridWin[i]->IsVisible())
974 pGridWin[i]->UpdateCopySourceOverlay();
977 void ScTabView::UpdateSelectionOverlay()
979 for (sal_uInt16 i=0; i<4; i++)
980 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
981 pGridWin[i]->UpdateSelectionOverlay();
984 void ScTabView::UpdateShrinkOverlay()
986 for (sal_uInt16 i=0; i<4; i++)
987 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
988 pGridWin[i]->UpdateShrinkOverlay();
991 void ScTabView::UpdateAllOverlays()
993 for (sal_uInt16 i=0; i<4; i++)
994 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
995 pGridWin[i]->UpdateAllOverlays();
999 //! PaintBlock in zwei Methoden aufteilen: RepaintBlock und RemoveBlock o.ae.
1002 void ScTabView::PaintBlock( bool bReset )
1004 ScMarkData& rMark = aViewData.GetMarkData();
1005 SCTAB nTab = aViewData.GetTabNo();
1006 bool bMulti = rMark.IsMultiMarked();
1007 if (rMark.IsMarked() || bMulti)
1009 ScRange aMarkRange;
1010 HideAllCursors();
1011 if (bMulti)
1013 bool bFlag = rMark.GetMarkingFlag();
1014 rMark.SetMarking(false);
1015 rMark.MarkToMulti();
1016 rMark.GetMultiMarkArea(aMarkRange);
1017 rMark.MarkToSimple();
1018 rMark.SetMarking(bFlag);
1020 else
1021 rMark.GetMarkArea(aMarkRange);
1023 nBlockStartX = aMarkRange.aStart.Col();
1024 nBlockStartY = aMarkRange.aStart.Row();
1025 nBlockStartZ = aMarkRange.aStart.Tab();
1026 nBlockEndX = aMarkRange.aEnd.Col();
1027 nBlockEndY = aMarkRange.aEnd.Row();
1028 nBlockEndZ = aMarkRange.aEnd.Tab();
1030 bool bDidReset = false;
1032 if ( nTab>=nBlockStartZ && nTab<=nBlockEndZ )
1034 if ( bReset )
1036 // Invertieren beim Loeschen nur auf aktiver View
1037 if ( aViewData.IsActive() )
1039 rMark.ResetMark();
1040 UpdateSelectionOverlay();
1041 bDidReset = true;
1044 else
1045 PaintMarks( nBlockStartX, nBlockStartY, nBlockEndX, nBlockEndY );
1048 if ( bReset && !bDidReset )
1049 rMark.ResetMark();
1051 ShowAllCursors();
1055 void ScTabView::SelectAll( bool bContinue )
1057 ScMarkData& rMark = aViewData.GetMarkData();
1058 SCTAB nTab = aViewData.GetTabNo();
1060 if (rMark.IsMarked())
1062 ScRange aMarkRange;
1063 rMark.GetMarkArea( aMarkRange );
1064 if ( aMarkRange == ScRange( 0,0,nTab, MAXCOL,MAXROW,nTab ) )
1065 return;
1068 DoneBlockMode( bContinue );
1069 InitBlockMode( 0,0,nTab );
1070 MarkCursor( MAXCOL,MAXROW,nTab );
1072 SelectionChanged();
1075 void ScTabView::SelectAllTables()
1077 ScDocument* pDoc = aViewData.GetDocument();
1078 ScMarkData& rMark = aViewData.GetMarkData();
1079 SCTAB nCount = pDoc->GetTableCount();
1081 if (nCount>1)
1083 for (SCTAB i=0; i<nCount; i++)
1084 rMark.SelectTable( i, true );
1086 aViewData.GetDocShell()->PostPaintExtras();
1087 SfxBindings& rBind = aViewData.GetBindings();
1088 rBind.Invalidate( FID_FILL_TAB );
1089 rBind.Invalidate( FID_TAB_DESELECTALL );
1093 void ScTabView::DeselectAllTables()
1095 ScDocument* pDoc = aViewData.GetDocument();
1096 ScMarkData& rMark = aViewData.GetMarkData();
1097 SCTAB nTab = aViewData.GetTabNo();
1098 SCTAB nCount = pDoc->GetTableCount();
1100 for (SCTAB i=0; i<nCount; i++)
1101 rMark.SelectTable( i, ( i == nTab ) );
1103 aViewData.GetDocShell()->PostPaintExtras();
1104 SfxBindings& rBind = aViewData.GetBindings();
1105 rBind.Invalidate( FID_FILL_TAB );
1106 rBind.Invalidate( FID_TAB_DESELECTALL );
1109 static bool lcl_FitsInWindow( double fScaleX, double fScaleY, sal_uInt16 nZoom,
1110 long nWindowX, long nWindowY, ScDocument* pDoc, SCTAB nTab,
1111 SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1112 SCCOL nFixPosX, SCROW nFixPosY )
1114 double fZoomFactor = (double)Fraction(nZoom,100);
1115 fScaleX *= fZoomFactor;
1116 fScaleY *= fZoomFactor;
1118 long nBlockX = 0;
1119 SCCOL nCol;
1120 for (nCol=0; nCol<nFixPosX; nCol++)
1122 // for frozen panes, add both parts
1123 sal_uInt16 nColTwips = pDoc->GetColWidth( nCol, nTab );
1124 if (nColTwips)
1126 nBlockX += (long)(nColTwips * fScaleX);
1127 if (nBlockX > nWindowX)
1128 return false;
1131 for (nCol=nStartCol; nCol<=nEndCol; nCol++)
1133 sal_uInt16 nColTwips = pDoc->GetColWidth( nCol, nTab );
1134 if (nColTwips)
1136 nBlockX += (long)(nColTwips * fScaleX);
1137 if (nBlockX > nWindowX)
1138 return false;
1142 long nBlockY = 0;
1143 for (SCROW nRow = 0; nRow <= nFixPosY-1; ++nRow)
1145 if (pDoc->RowHidden(nRow, nTab))
1146 continue;
1148 // for frozen panes, add both parts
1149 sal_uInt16 nRowTwips = pDoc->GetRowHeight(nRow, nTab);
1150 if (nRowTwips)
1152 nBlockY += (long)(nRowTwips * fScaleY);
1153 if (nBlockY > nWindowY)
1154 return false;
1157 for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
1159 sal_uInt16 nRowTwips = pDoc->GetRowHeight(nRow, nTab);
1160 if (nRowTwips)
1162 nBlockY += (long)(nRowTwips * fScaleY);
1163 if (nBlockY > nWindowY)
1164 return false;
1168 return true;
1171 sal_uInt16 ScTabView::CalcZoom( SvxZoomType eType, sal_uInt16 nOldZoom )
1173 sal_uInt16 nZoom = 100;
1175 switch ( eType )
1177 case SvxZoomType::PERCENT: // rZoom ist kein besonderer prozentualer Wert
1178 nZoom = nOldZoom;
1179 break;
1181 case SvxZoomType::OPTIMAL: // nZoom entspricht der optimalen Gr"o\se
1183 ScMarkData& rMark = aViewData.GetMarkData();
1184 ScDocument* pDoc = aViewData.GetDocument();
1186 if (!rMark.IsMarked() && !rMark.IsMultiMarked())
1187 nZoom = 100; // nothing selected
1188 else
1190 SCTAB nTab = aViewData.GetTabNo();
1191 ScRange aMarkRange;
1192 if ( aViewData.GetSimpleArea( aMarkRange ) != SC_MARK_SIMPLE )
1193 rMark.GetMultiMarkArea( aMarkRange );
1195 SCCOL nStartCol = aMarkRange.aStart.Col();
1196 SCROW nStartRow = aMarkRange.aStart.Row();
1197 SCTAB nStartTab = aMarkRange.aStart.Tab();
1198 SCCOL nEndCol = aMarkRange.aEnd.Col();
1199 SCROW nEndRow = aMarkRange.aEnd.Row();
1200 SCTAB nEndTab = aMarkRange.aEnd.Tab();
1202 if ( nTab < nStartTab && nTab > nEndTab )
1203 nTab = nStartTab;
1205 ScSplitPos eUsedPart = aViewData.GetActivePart();
1207 SCCOL nFixPosX = 0;
1208 SCROW nFixPosY = 0;
1209 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
1211 // use right part
1212 eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
1213 nFixPosX = aViewData.GetFixPosX();
1214 if ( nStartCol < nFixPosX )
1215 nStartCol = nFixPosX;
1217 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1219 // use bottom part
1220 eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
1221 nFixPosY = aViewData.GetFixPosY();
1222 if ( nStartRow < nFixPosY )
1223 nStartRow = nFixPosY;
1226 if (pGridWin[eUsedPart])
1228 // Because scale is rounded to pixels, the only reliable way to find
1229 // the right scale is to check if a zoom fits
1231 Size aWinSize = pGridWin[eUsedPart]->GetOutputSizePixel();
1233 // for frozen panes, use sum of both parts for calculation
1235 if ( nFixPosX != 0 )
1236 aWinSize.Width() += GetGridWidth( SC_SPLIT_LEFT );
1237 if ( nFixPosY != 0 )
1238 aWinSize.Height() += GetGridHeight( SC_SPLIT_TOP );
1240 ScDocShell* pDocSh = aViewData.GetDocShell();
1241 double nPPTX = ScGlobal::nScreenPPTX / pDocSh->GetOutputFactor();
1242 double nPPTY = ScGlobal::nScreenPPTY;
1244 sal_uInt16 nMin = MINZOOM;
1245 sal_uInt16 nMax = MAXZOOM;
1246 while ( nMax > nMin )
1248 sal_uInt16 nTest = (nMin+nMax+1)/2;
1249 if ( lcl_FitsInWindow(
1250 nPPTX, nPPTY, nTest, aWinSize.Width(), aWinSize.Height(),
1251 pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow,
1252 nFixPosX, nFixPosY ) )
1253 nMin = nTest;
1254 else
1255 nMax = nTest-1;
1257 OSL_ENSURE( nMin == nMax, "Schachtelung ist falsch" );
1258 nZoom = nMin;
1260 if ( nZoom != nOldZoom )
1262 // scroll to block only in active split part
1263 // (the part for which the size was calculated)
1265 if ( nStartCol <= nEndCol )
1266 aViewData.SetPosX( WhichH(eUsedPart), nStartCol );
1267 if ( nStartRow <= nEndRow )
1268 aViewData.SetPosY( WhichV(eUsedPart), nStartRow );
1273 break;
1275 case SvxZoomType::WHOLEPAGE: // nZoom entspricht der ganzen Seite oder
1276 case SvxZoomType::PAGEWIDTH: // nZoom entspricht der Seitenbreite
1278 SCTAB nCurTab = aViewData.GetTabNo();
1279 ScDocument* pDoc = aViewData.GetDocument();
1280 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
1281 SfxStyleSheetBase* pStyleSheet =
1282 pStylePool->Find( pDoc->GetPageStyle( nCurTab ),
1283 SFX_STYLE_FAMILY_PAGE );
1285 OSL_ENSURE( pStyleSheet, "PageStyle not found :-/" );
1287 if ( pStyleSheet )
1289 ScPrintFunc aPrintFunc( aViewData.GetDocShell(),
1290 aViewData.GetViewShell()->GetPrinter(true),
1291 nCurTab );
1293 Size aPageSize = aPrintFunc.GetDataSize();
1295 // use the size of the largest GridWin for normal split,
1296 // or both combined for frozen panes, with the (document) size
1297 // of the frozen part added to the page size
1298 // (with frozen panes, the size of the individual parts
1299 // depends on the scale that is to be calculated)
1301 if (!pGridWin[SC_SPLIT_BOTTOMLEFT])
1302 return nZoom;
1304 Size aWinSize = pGridWin[SC_SPLIT_BOTTOMLEFT]->GetOutputSizePixel();
1305 ScSplitMode eHMode = aViewData.GetHSplitMode();
1306 if ( eHMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_BOTTOMRIGHT] )
1308 long nOtherWidth = pGridWin[SC_SPLIT_BOTTOMRIGHT]->
1309 GetOutputSizePixel().Width();
1310 if ( eHMode == SC_SPLIT_FIX )
1312 aWinSize.Width() += nOtherWidth;
1313 for ( SCCOL nCol = aViewData.GetPosX(SC_SPLIT_LEFT);
1314 nCol < aViewData.GetFixPosX(); nCol++ )
1315 aPageSize.Width() += pDoc->GetColWidth( nCol, nCurTab );
1317 else if ( nOtherWidth > aWinSize.Width() )
1318 aWinSize.Width() = nOtherWidth;
1320 ScSplitMode eVMode = aViewData.GetVSplitMode();
1321 if ( eVMode != SC_SPLIT_NONE && pGridWin[SC_SPLIT_TOPLEFT] )
1323 long nOtherHeight = pGridWin[SC_SPLIT_TOPLEFT]->
1324 GetOutputSizePixel().Height();
1325 if ( eVMode == SC_SPLIT_FIX )
1327 aWinSize.Height() += nOtherHeight;
1328 aPageSize.Height() += pDoc->GetRowHeight(
1329 aViewData.GetPosY(SC_SPLIT_TOP),
1330 aViewData.GetFixPosY()-1, nCurTab);
1332 else if ( nOtherHeight > aWinSize.Height() )
1333 aWinSize.Height() = nOtherHeight;
1336 double nPPTX = ScGlobal::nScreenPPTX / aViewData.GetDocShell()->GetOutputFactor();
1337 double nPPTY = ScGlobal::nScreenPPTY;
1339 long nZoomX = (long) ( aWinSize.Width() * 100 /
1340 ( aPageSize.Width() * nPPTX ) );
1341 long nZoomY = (long) ( aWinSize.Height() * 100 /
1342 ( aPageSize.Height() * nPPTY ) );
1344 if (nZoomX > 0)
1345 nZoom = static_cast<sal_uInt16>(nZoomX);
1347 if (eType == SvxZoomType::WHOLEPAGE && nZoomY > 0 && nZoomY < nZoom)
1348 nZoom = static_cast<sal_uInt16>(nZoomY);
1351 break;
1353 default:
1354 OSL_FAIL("Unknown Zoom-Revision");
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 vcl::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 ScopedVclPtrInstance< 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& rDoc = pDocSh->GetDocument();
1440 SCTAB nTab = aViewData.GetTabNo();
1442 sal_uInt16 nCount = rDoc.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: */