fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / ui / view / tabview3.cxx
blobad84f1be1b67fd348950ccfd49072c653ff20ab9
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 <rangelst.hxx>
21 #include "scitems.hxx"
22 #include <editeng/eeitem.hxx>
24 #include <editeng/brushitem.hxx>
25 #include <editeng/editview.hxx>
26 #include <svx/fmshell.hxx>
27 #include <svx/svdoole2.hxx>
28 #include <sfx2/bindings.hxx>
29 #include <sfx2/viewfrm.hxx>
30 #include <vcl/cursor.hxx>
32 #include "tabview.hxx"
33 #include "tabvwsh.hxx"
34 #include "docsh.hxx"
35 #include "gridwin.hxx"
36 #include "olinewin.hxx"
37 #include "colrowba.hxx"
38 #include "tabcont.hxx"
39 #include "scmod.hxx"
40 #include "uiitems.hxx"
41 #include "sc.hrc"
42 #include "viewutil.hxx"
43 #include "editutil.hxx"
44 #include "inputhdl.hxx"
45 #include "inputwin.hxx"
46 #include "validat.hxx"
47 #include "hintwin.hxx"
48 #include "inputopt.hxx"
49 #include "rfindlst.hxx"
50 #include "hiranges.hxx"
51 #include "viewuno.hxx"
52 #include "chartarr.hxx"
53 #include "anyrefdg.hxx"
54 #include "dpobject.hxx"
55 #include "patattr.hxx"
56 #include "dociter.hxx"
57 #include "seltrans.hxx"
58 #include "fillinfo.hxx"
59 #include "AccessibilityHints.hxx"
60 #include "rangeutl.hxx"
61 #include "client.hxx"
62 #include "tabprotection.hxx"
63 #include "markdata.hxx"
64 #include <formula/FormulaCompiler.hxx>
66 #include <com/sun/star/chart2/data/HighlightedRange.hpp>
68 namespace
71 ScRange lcl_getSubRangeByIndex( const ScRange& rRange, sal_Int32 nIndex )
73 ScAddress aResult( rRange.aStart );
75 SCCOL nWidth = rRange.aEnd.Col() - rRange.aStart.Col() + 1;
76 SCROW nHeight = rRange.aEnd.Row() - rRange.aStart.Row() + 1;
77 SCTAB nDepth = rRange.aEnd.Tab() - rRange.aStart.Tab() + 1;
78 if( (nWidth > 0) && (nHeight > 0) && (nDepth > 0) )
80 // row by row from first to last sheet
81 sal_Int32 nArea = nWidth * nHeight;
82 aResult.IncCol( static_cast< SCsCOL >( nIndex % nWidth ) );
83 aResult.IncRow( static_cast< SCsROW >( (nIndex % nArea) / nWidth ) );
84 aResult.IncTab( static_cast< SCsTAB >( nIndex / nArea ) );
85 if( !rRange.In( aResult ) )
86 aResult = rRange.aStart;
89 return ScRange( aResult );
92 } // anonymous namespace
94 using namespace com::sun::star;
96 // --- Public-Funktionen
98 void ScTabView::ClickCursor( SCCOL nPosX, SCROW nPosY, bool bControl )
100 ScDocument* pDoc = aViewData.GetDocument();
101 SCTAB nTab = aViewData.GetTabNo();
102 pDoc->SkipOverlapped(nPosX, nPosY, nTab);
104 bool bRefMode = SC_MOD()->IsFormulaMode();
106 if ( bRefMode )
108 DoneRefMode( false );
110 if (bControl)
111 SC_MOD()->AddRefEntry();
113 InitRefMode( nPosX, nPosY, nTab, SC_REFTYPE_REF );
115 else
117 DoneBlockMode( bControl );
118 aViewData.ResetOldCursor();
119 SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
123 void ScTabView::UpdateAutoFillMark()
125 // single selection or cursor
126 ScRange aMarkRange;
127 bool bMarked = (aViewData.GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE);
129 sal_uInt16 i;
130 for (i=0; i<4; i++)
131 if (pGridWin[i] && pGridWin[i]->IsVisible())
132 pGridWin[i]->UpdateAutoFillMark( bMarked, aMarkRange );
134 for (i=0; i<2; i++)
136 if (pColBar[i] && pColBar[i]->IsVisible())
137 pColBar[i]->SetMark( bMarked, aMarkRange.aStart.Col(), aMarkRange.aEnd.Col() );
138 if (pRowBar[i] && pRowBar[i]->IsVisible())
139 pRowBar[i]->SetMark( bMarked, aMarkRange.aStart.Row(), aMarkRange.aEnd.Row() );
142 // selection transfer object is checked together with AutoFill marks,
143 // because it has the same requirement of a single continuous block.
144 CheckSelectionTransfer(); // update selection transfer object
147 void ScTabView::FakeButtonUp( ScSplitPos eWhich )
149 if (pGridWin[eWhich])
150 pGridWin[eWhich]->FakeButtonUp();
153 void ScTabView::HideAllCursors()
155 for (sal_uInt16 i=0; i<4; i++)
156 if (pGridWin[i])
157 if (pGridWin[i]->IsVisible())
159 vcl::Cursor* pCur = pGridWin[i]->GetCursor();
160 if (pCur)
161 if (pCur->IsVisible())
162 pCur->Hide();
163 pGridWin[i]->HideCursor();
167 void ScTabView::ShowAllCursors()
169 for (sal_uInt16 i=0; i<4; i++)
170 if (pGridWin[i])
171 if (pGridWin[i]->IsVisible())
173 pGridWin[i]->ShowCursor();
175 // #114409#
176 pGridWin[i]->CursorChanged();
180 void ScTabView::ShowCursor()
182 pGridWin[aViewData.GetActivePart()]->ShowCursor();
184 // #114409#
185 pGridWin[aViewData.GetActivePart()]->CursorChanged();
188 void ScTabView::InvalidateAttribs()
190 SfxBindings& rBindings = aViewData.GetBindings();
192 rBindings.Invalidate( SID_STYLE_APPLY );
193 rBindings.Invalidate( SID_STYLE_FAMILY2 );
194 // StarCalc kennt nur Absatz- bzw. Zellformat-Vorlagen
196 rBindings.Invalidate( SID_ATTR_CHAR_FONT );
197 rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
198 rBindings.Invalidate( SID_ATTR_CHAR_COLOR );
200 rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
201 rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
202 rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
203 rBindings.Invalidate( SID_ULINE_VAL_NONE );
204 rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
205 rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
206 rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
208 rBindings.Invalidate( SID_ATTR_CHAR_OVERLINE );
210 rBindings.Invalidate( SID_ATTR_CHAR_KERNING );
211 rBindings.Invalidate( SID_SET_SUPER_SCRIPT );
212 rBindings.Invalidate( SID_SET_SUB_SCRIPT );
213 rBindings.Invalidate( SID_ATTR_CHAR_STRIKEOUT );
214 rBindings.Invalidate( SID_ATTR_CHAR_SHADOWED );
216 rBindings.Invalidate( SID_ATTR_PARA_ADJUST_LEFT );
217 rBindings.Invalidate( SID_ATTR_PARA_ADJUST_RIGHT );
218 rBindings.Invalidate( SID_ATTR_PARA_ADJUST_BLOCK );
219 rBindings.Invalidate( SID_ATTR_PARA_ADJUST_CENTER);
220 rBindings.Invalidate( SID_NUMBER_TYPE_FORMAT);
222 rBindings.Invalidate( SID_ALIGNLEFT );
223 rBindings.Invalidate( SID_ALIGNRIGHT );
224 rBindings.Invalidate( SID_ALIGNBLOCK );
225 rBindings.Invalidate( SID_ALIGNCENTERHOR );
227 rBindings.Invalidate( SID_ALIGNTOP );
228 rBindings.Invalidate( SID_ALIGNBOTTOM );
229 rBindings.Invalidate( SID_ALIGNCENTERVER );
231 // stuff for sidebar panels
233 rBindings.Invalidate( SID_H_ALIGNCELL );
234 rBindings.Invalidate( SID_V_ALIGNCELL );
235 rBindings.Invalidate( SID_ATTR_ALIGN_INDENT );
236 rBindings.Invalidate( SID_FRAME_LINECOLOR );
237 rBindings.Invalidate( SID_FRAME_LINESTYLE );
238 rBindings.Invalidate( SID_ATTR_BORDER_OUTER );
239 rBindings.Invalidate( SID_ATTR_BORDER_INNER );
240 rBindings.Invalidate( SID_ATTR_BORDER_DIAG_TLBR );
241 rBindings.Invalidate( SID_ATTR_BORDER_DIAG_BLTR );
242 rBindings.Invalidate( SID_NUMBER_TYPE_FORMAT );
245 rBindings.Invalidate( SID_BACKGROUND_COLOR );
247 rBindings.Invalidate( SID_ATTR_ALIGN_LINEBREAK );
248 rBindings.Invalidate( SID_NUMBER_FORMAT );
250 rBindings.Invalidate( SID_TEXTDIRECTION_LEFT_TO_RIGHT );
251 rBindings.Invalidate( SID_TEXTDIRECTION_TOP_TO_BOTTOM );
252 rBindings.Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
253 rBindings.Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
255 // pseudo slots for Format menu
256 rBindings.Invalidate( SID_ALIGN_ANY_HDEFAULT );
257 rBindings.Invalidate( SID_ALIGN_ANY_LEFT );
258 rBindings.Invalidate( SID_ALIGN_ANY_HCENTER );
259 rBindings.Invalidate( SID_ALIGN_ANY_RIGHT );
260 rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED );
261 rBindings.Invalidate( SID_ALIGN_ANY_VDEFAULT );
262 rBindings.Invalidate( SID_ALIGN_ANY_TOP );
263 rBindings.Invalidate( SID_ALIGN_ANY_VCENTER );
264 rBindings.Invalidate( SID_ALIGN_ANY_BOTTOM );
266 rBindings.Invalidate( SID_NUMBER_CURRENCY );
267 rBindings.Invalidate( SID_NUMBER_SCIENTIFIC );
268 rBindings.Invalidate( SID_NUMBER_DATE );
269 rBindings.Invalidate( SID_NUMBER_CURRENCY );
270 rBindings.Invalidate( SID_NUMBER_PERCENT );
271 rBindings.Invalidate( SID_NUMBER_TIME );
274 // SetCursor - Cursor setzen, zeichnen, InputWin updaten
275 // oder Referenz verschicken
276 // ohne Optimierung wegen BugId 29307
278 void ScTabView::SetCursor( SCCOL nPosX, SCROW nPosY, bool bNew )
280 SCCOL nOldX = aViewData.GetCurX();
281 SCROW nOldY = aViewData.GetCurY();
283 // DeactivateIP nur noch bei MarkListHasChanged
285 if ( nPosX != nOldX || nPosY != nOldY || bNew )
287 ScTabViewShell* pViewShell = aViewData.GetViewShell();
288 bool bRefMode = pViewShell && pViewShell->IsRefInputMode();
289 if ( aViewData.HasEditView( aViewData.GetActivePart() ) && !bRefMode ) // 23259 oder so
291 UpdateInputLine();
294 HideAllCursors();
296 aViewData.SetCurX( nPosX );
297 aViewData.SetCurY( nPosY );
299 ShowAllCursors();
301 CursorPosChanged();
305 void ScTabView::CheckSelectionTransfer()
307 if ( aViewData.IsActive() ) // only for active view
309 ScModule* pScMod = SC_MOD();
310 ScSelectionTransferObj* pOld = pScMod->GetSelectionTransfer();
311 ScSelectionTransferObj* pNew = ScSelectionTransferObj::CreateFromView( this );
312 if ( pNew )
314 // create new selection
316 if (pOld)
317 pOld->ForgetView();
319 uno::Reference<datatransfer::XTransferable> xRef( pNew );
320 pScMod->SetSelectionTransfer( pNew );
321 pNew->CopyToSelection( GetActiveWin() ); // may delete pOld
323 else if ( pOld && pOld->GetView() == this )
325 // remove own selection
327 pOld->ForgetView();
328 pScMod->SetSelectionTransfer( NULL );
329 TransferableHelper::ClearSelection( GetActiveWin() ); // may delete pOld
331 // else: selection from outside: leave unchanged
335 // Eingabezeile / Menues updaten
336 // CursorPosChanged ruft SelectionChanged
337 // SelectionChanged ruft CellContentChanged
339 void ScTabView::CellContentChanged()
341 SfxBindings& rBindings = aViewData.GetBindings();
343 rBindings.Invalidate( SID_ATTR_SIZE ); // -> Fehlermeldungen anzeigen
344 rBindings.Invalidate( SID_THESAURUS );
345 rBindings.Invalidate( SID_HYPERLINK_GETLINK );
346 rBindings.Invalidate( SID_ROWCOL_SELCOUNT );
348 InvalidateAttribs(); // Attribut-Updates
350 aViewData.GetViewShell()->UpdateInputHandler();
353 void ScTabView::SelectionChanged()
355 SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
356 if (pViewFrame)
358 uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController();
359 if (xController.is())
361 ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
362 if (pImp)
363 pImp->SelectionChanged();
367 UpdateAutoFillMark(); // also calls CheckSelectionTransfer
369 SfxBindings& rBindings = aViewData.GetBindings();
371 rBindings.Invalidate( SID_CURRENTCELL ); // -> Navigator
372 rBindings.Invalidate( SID_AUTO_FILTER ); // -> Menue
373 rBindings.Invalidate( FID_NOTE_VISIBLE );
374 rBindings.Invalidate( FID_SHOW_NOTE );
375 rBindings.Invalidate( FID_HIDE_NOTE );
376 rBindings.Invalidate( SID_DELETE_NOTE );
377 rBindings.Invalidate( SID_ROWCOL_SELCOUNT );
379 // Funktionen, die evtl disabled werden muessen
381 rBindings.Invalidate( FID_INS_ROWBRK );
382 rBindings.Invalidate( FID_INS_COLBRK );
383 rBindings.Invalidate( FID_DEL_ROWBRK );
384 rBindings.Invalidate( FID_DEL_COLBRK );
385 rBindings.Invalidate( FID_MERGE_ON );
386 rBindings.Invalidate( FID_MERGE_OFF );
387 rBindings.Invalidate( FID_MERGE_TOGGLE );
388 rBindings.Invalidate( SID_AUTOFILTER_HIDE );
389 rBindings.Invalidate( SID_UNFILTER );
390 rBindings.Invalidate( SID_REIMPORT_DATA );
391 rBindings.Invalidate( SID_REFRESH_DBAREA );
392 rBindings.Invalidate( SID_OUTLINE_SHOW );
393 rBindings.Invalidate( SID_OUTLINE_HIDE );
394 rBindings.Invalidate( SID_OUTLINE_REMOVE );
395 rBindings.Invalidate( FID_FILL_TO_BOTTOM );
396 rBindings.Invalidate( FID_FILL_TO_RIGHT );
397 rBindings.Invalidate( FID_FILL_TO_TOP );
398 rBindings.Invalidate( FID_FILL_TO_LEFT );
399 rBindings.Invalidate( FID_FILL_SERIES );
400 rBindings.Invalidate( SID_SCENARIOS );
401 rBindings.Invalidate( SID_AUTOFORMAT );
402 rBindings.Invalidate( SID_OPENDLG_TABOP );
403 rBindings.Invalidate( SID_DATA_SELECT );
405 rBindings.Invalidate( SID_CUT );
406 rBindings.Invalidate( SID_COPY );
407 rBindings.Invalidate( SID_PASTE );
408 rBindings.Invalidate( SID_PASTE_SPECIAL );
410 rBindings.Invalidate( FID_INS_ROW );
411 rBindings.Invalidate( FID_INS_COLUMN );
412 rBindings.Invalidate( FID_INS_CELL );
413 rBindings.Invalidate( FID_INS_CELLSDOWN );
414 rBindings.Invalidate( FID_INS_CELLSRIGHT );
416 rBindings.Invalidate( FID_CHG_COMMENT );
418 // nur wegen Zellschutz:
420 rBindings.Invalidate( SID_CELL_FORMAT_RESET );
421 rBindings.Invalidate( SID_DELETE );
422 rBindings.Invalidate( SID_DELETE_CONTENTS );
423 rBindings.Invalidate( FID_DELETE_CELL );
424 rBindings.Invalidate( FID_CELL_FORMAT );
425 rBindings.Invalidate( SID_ENABLE_HYPHENATION );
426 rBindings.Invalidate( SID_INSERT_POSTIT );
427 rBindings.Invalidate( SID_CHARMAP );
428 rBindings.Invalidate( SID_OPENDLG_FUNCTION );
429 rBindings.Invalidate( FID_VALIDATION );
430 rBindings.Invalidate( SID_EXTERNAL_SOURCE );
431 rBindings.Invalidate( SID_TEXT_TO_COLUMNS );
432 rBindings.Invalidate( SID_SORT_ASCENDING );
433 rBindings.Invalidate( SID_SORT_DESCENDING );
435 if (aViewData.GetViewShell()->HasAccessibilityObjects())
436 aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_CURSORCHANGED));
438 CellContentChanged();
441 void ScTabView::CursorPosChanged()
443 bool bRefMode = SC_MOD()->IsFormulaMode();
444 if ( !bRefMode ) // Abfrage, damit RefMode bei Tabellenwechsel funktioniert
445 aViewData.GetDocShell()->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
447 // Broadcast, damit andere Views des Dokuments auch umschalten
449 ScDocument* pDoc = aViewData.GetDocument();
450 bool bDP = NULL != pDoc->GetDPAtCursor(
451 aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
452 aViewData.GetViewShell()->SetPivotShell(bDP);
454 // UpdateInputHandler jetzt in CellContentChanged
456 SelectionChanged();
458 aViewData.SetTabStartCol( SC_TABSTART_NONE );
461 namespace {
463 Point calcHintWindowPosition(
464 const Point& rCellPos, const Size& rCellSize, const Size& rFrameWndSize, const Size& rHintWndSize)
466 const long nMargin = 20;
468 long nMLeft = rCellPos.X();
469 long nMRight = rFrameWndSize.Width() - rCellPos.X() - rCellSize.Width();
470 long nMTop = rCellPos.Y();
471 long nMBottom = rFrameWndSize.Height() - rCellPos.Y() - rCellSize.Height();
473 // First, see if we can fit the entire hint window in the visible region.
475 if (nMRight - nMargin >= rHintWndSize.Width())
477 // Right margin is wide enough.
478 if (rFrameWndSize.Height() >= rHintWndSize.Height())
480 // The frame has enough height. Take it.
481 Point aPos = rCellPos;
482 aPos.X() += rCellSize.Width() + nMargin;
483 if (aPos.Y() + rHintWndSize.Height() > rFrameWndSize.Height())
485 // Push the hint window up a bit to make it fit.
486 aPos.Y() = rFrameWndSize.Height() - rHintWndSize.Height();
488 return aPos;
492 if (nMBottom - nMargin >= rHintWndSize.Height())
494 // Bottom margin is high enough.
495 if (rFrameWndSize.Width() >= rHintWndSize.Width())
497 // The frame has enough width. Take it.
498 Point aPos = rCellPos;
499 aPos.Y() += rCellSize.Height() + nMargin;
500 if (aPos.X() + rHintWndSize.Width() > rFrameWndSize.Width())
502 // Move the hint window to the left to make it fit.
503 aPos.X() = rFrameWndSize.Width() - rHintWndSize.Width();
505 return aPos;
509 if (nMLeft - nMargin >= rHintWndSize.Width())
511 // Left margin is wide enough.
512 if (rFrameWndSize.Height() >= rHintWndSize.Height())
514 // The frame is high enough. Take it.
515 Point aPos = rCellPos;
516 aPos.X() -= rHintWndSize.Width() + nMargin;
517 if (aPos.Y() + rHintWndSize.Height() > rFrameWndSize.Height())
519 // Push the hint window up a bit to make it fit.
520 aPos.Y() = rFrameWndSize.Height() - rHintWndSize.Height();
522 return aPos;
526 if (nMTop - nMargin >= rHintWndSize.Height())
528 // Top margin is high enough.
529 if (rFrameWndSize.Width() >= rHintWndSize.Width())
531 // The frame is wide enough. Take it.
532 Point aPos = rCellPos;
533 aPos.Y() -= rHintWndSize.Height() + nMargin;
534 if (aPos.X() + rHintWndSize.Width() > rFrameWndSize.Width())
536 // Move the hint window to the left to make it fit.
537 aPos.X() = rFrameWndSize.Width() - rHintWndSize.Width();
539 return aPos;
543 // The popup doesn't fit in any direction in its entirety. Do our best.
545 if (nMRight - nMargin >= rHintWndSize.Width())
547 // Right margin is good enough.
548 Point aPos = rCellPos;
549 aPos.X() += nMargin + rCellSize.Width();
550 aPos.Y() = 0;
551 return aPos;
554 if (nMBottom - nMargin >= rHintWndSize.Height())
556 // Bottom margin is good enough.
557 Point aPos = rCellPos;
558 aPos.Y() += nMargin + rCellSize.Height();
559 aPos.X() = 0;
560 return aPos;
563 if (nMLeft - nMargin >= rHintWndSize.Width())
565 // Left margin is good enough.
566 Point aPos = rCellPos;
567 aPos.X() -= rHintWndSize.Width() + nMargin;
568 aPos.Y() = 0;
569 return aPos;
572 if (nMTop - nMargin >= rHintWndSize.Height())
574 // Top margin is good enough.
575 Point aPos = rCellPos;
576 aPos.Y() -= rHintWndSize.Height() + nMargin;
577 aPos.X() = 0;
578 return aPos;
581 // None of the above. Hopeless. At least try not to cover the current
582 // cell.
583 Point aPos = rCellPos;
584 aPos.X() += rCellSize.Width();
585 return aPos;
590 void ScTabView::TestHintWindow()
592 // show input help window and list drop-down button for validity
594 bool bListValButton = false;
595 ScAddress aListValPos;
597 ScDocument* pDoc = aViewData.GetDocument();
598 const SfxUInt32Item* pItem = static_cast<const SfxUInt32Item*>(
599 pDoc->GetAttr( aViewData.GetCurX(),
600 aViewData.GetCurY(),
601 aViewData.GetTabNo(),
602 ATTR_VALIDDATA ));
603 if ( pItem->GetValue() )
605 const ScValidationData* pData = pDoc->GetValidationEntry( pItem->GetValue() );
606 OSL_ENSURE(pData,"ValidationData nicht gefunden");
607 OUString aTitle, aMessage;
608 if ( pData && pData->GetInput( aTitle, aMessage ) && !aMessage.isEmpty() )
610 //! Abfrage, ob an gleicher Stelle !!!!
612 mpInputHintWindow.disposeAndClear();
614 ScSplitPos eWhich = aViewData.GetActivePart();
615 ScGridWindow* pWin = pGridWin[eWhich];
616 SCCOL nCol = aViewData.GetCurX();
617 SCROW nRow = aViewData.GetCurY();
618 Point aPos = aViewData.GetScrPos( nCol, nRow, eWhich );
619 Size aWinSize = pWin->GetOutputSizePixel();
620 // Cursor sichtbar?
621 if ( nCol >= aViewData.GetPosX(WhichH(eWhich)) &&
622 nRow >= aViewData.GetPosY(WhichV(eWhich)) &&
623 aPos.X() < aWinSize.Width() && aPos.Y() < aWinSize.Height() )
625 // HintWindow anlegen, bestimmt seine Groesse selbst
626 mpInputHintWindow.reset(VclPtr<ScHintWindow>::Create(pWin, aTitle, aMessage));
627 Size aHintWndSize = mpInputHintWindow->GetSizePixel();
628 long nCellSizeX = 0;
629 long nCellSizeY = 0;
630 aViewData.GetMergeSizePixel(nCol, nRow, nCellSizeX, nCellSizeY);
632 Point aHintPos = calcHintWindowPosition(
633 aPos, Size(nCellSizeX,nCellSizeY), aWinSize, aHintWndSize);
635 mpInputHintWindow->SetPosPixel( aHintPos );
636 mpInputHintWindow->ToTop();
637 mpInputHintWindow->Show();
640 else
641 mpInputHintWindow.disposeAndClear();
643 // list drop-down button
644 if ( pData && pData->HasSelectionList() )
646 aListValPos.Set( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
647 bListValButton = true;
650 else
651 mpInputHintWindow.disposeAndClear();
653 for ( sal_uInt16 i=0; i<4; i++ )
654 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
655 pGridWin[i]->UpdateListValPos( bListValButton, aListValPos );
658 bool ScTabView::HasHintWindow() const
660 return mpInputHintWindow.get() != NULL;
663 void ScTabView::RemoveHintWindow()
665 mpInputHintWindow.disposeAndClear();
668 // find window that should not be over the cursor
669 static vcl::Window* lcl_GetCareWin(SfxViewFrame* pViewFrm)
671 //! auch Spelling ??? (dann beim Aufruf Membervariable setzen)
673 // Suchen & Ersetzen
674 if ( pViewFrm->HasChildWindow(SID_SEARCH_DLG) )
676 SfxChildWindow* pChild = pViewFrm->GetChildWindow(SID_SEARCH_DLG);
677 if (pChild)
679 vcl::Window* pWin = pChild->GetWindow();
680 if (pWin && pWin->IsVisible())
681 return pWin;
685 // Aenderungen uebernehmen
686 if ( pViewFrm->HasChildWindow(FID_CHG_ACCEPT) )
688 SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_CHG_ACCEPT);
689 if (pChild)
691 vcl::Window* pWin = pChild->GetWindow();
692 if (pWin && pWin->IsVisible())
693 return pWin;
697 return NULL;
700 // Bildschirm an Cursorposition anpassen
702 void ScTabView::AlignToCursor( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
703 const ScSplitPos* pWhich )
706 // aktiven Teil umschalten jetzt hier
708 ScSplitPos eActive = aViewData.GetActivePart();
709 ScHSplitPos eActiveX = WhichH(eActive);
710 ScVSplitPos eActiveY = WhichV(eActive);
711 bool bHFix = (aViewData.GetHSplitMode() == SC_SPLIT_FIX);
712 bool bVFix = (aViewData.GetVSplitMode() == SC_SPLIT_FIX);
713 if (bHFix)
714 if (eActiveX == SC_SPLIT_LEFT && nCurX >= (SCsCOL)aViewData.GetFixPosX())
716 ActivatePart( (eActiveY==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT );
717 eActiveX = SC_SPLIT_RIGHT;
719 if (bVFix)
720 if (eActiveY == SC_SPLIT_TOP && nCurY >= (SCsROW)aViewData.GetFixPosY())
722 ActivatePart( (eActiveX==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
723 eActiveY = SC_SPLIT_BOTTOM;
726 // eigentliches Align
728 if ( eMode != SC_FOLLOW_NONE )
730 ScSplitPos eAlign;
731 if (pWhich)
732 eAlign = *pWhich;
733 else
734 eAlign = aViewData.GetActivePart();
735 ScHSplitPos eAlignX = WhichH(eAlign);
736 ScVSplitPos eAlignY = WhichV(eAlign);
738 SCsCOL nDeltaX = (SCsCOL) aViewData.GetPosX(eAlignX);
739 SCsROW nDeltaY = (SCsROW) aViewData.GetPosY(eAlignY);
740 SCsCOL nSizeX = (SCsCOL) aViewData.VisibleCellsX(eAlignX);
741 SCsROW nSizeY = (SCsROW) aViewData.VisibleCellsY(eAlignY);
743 long nCellSizeX;
744 long nCellSizeY;
745 if ( nCurX >= 0 && nCurY >= 0 )
746 aViewData.GetMergeSizePixel( (SCCOL)nCurX, (SCROW)nCurY, nCellSizeX, nCellSizeY );
747 else
748 nCellSizeX = nCellSizeY = 0;
749 Size aScrSize = aViewData.GetScrSize();
750 long nSpaceX = ( aScrSize.Width() - nCellSizeX ) / 2;
751 long nSpaceY = ( aScrSize.Height() - nCellSizeY ) / 2;
752 // nSpaceY: desired start position of cell for FOLLOW_JUMP, modified if dialog interferes
754 bool bForceNew = false; // force new calculation of JUMP position (vertical only)
756 // VisibleCellsY == CellsAtY( GetPosY( eWhichY ), 1, eWhichY )
758 // falls z.B. Suchen-Dialog offen ist, Cursor nicht hinter den Dialog stellen
759 // wenn moeglich, die Zeile mit dem Cursor oberhalb oder unterhalb des Dialogs
761 //! nicht, wenn schon komplett sichtbar
763 if ( eMode == SC_FOLLOW_JUMP )
765 vcl::Window* pCare = lcl_GetCareWin( aViewData.GetViewShell()->GetViewFrame() );
766 if (pCare)
768 bool bLimit = false;
769 Rectangle aDlgPixel;
770 Size aWinSize;
771 vcl::Window* pWin = GetActiveWin();
772 if (pWin)
774 aDlgPixel = pCare->GetWindowExtentsRelative( pWin );
775 aWinSize = pWin->GetOutputSizePixel();
776 // ueberdeckt der Dialog das GridWin?
777 if ( aDlgPixel.Right() >= 0 && aDlgPixel.Left() < aWinSize.Width() )
779 if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX ||
780 nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY )
781 bLimit = true; // es wird sowieso gescrollt
782 else
784 // Cursor ist auf dem Bildschirm
785 Point aStart = aViewData.GetScrPos( nCurX, nCurY, eAlign );
786 long nCSX, nCSY;
787 aViewData.GetMergeSizePixel( nCurX, nCurY, nCSX, nCSY );
788 Rectangle aCursor( aStart, Size( nCSX, nCSY ) );
789 if ( aCursor.IsOver( aDlgPixel ) )
790 bLimit = true; // Zelle vom Dialog ueberdeckt
795 if (bLimit)
797 bool bBottom = false;
798 long nTopSpace = aDlgPixel.Top();
799 long nBotSpace = aWinSize.Height() - aDlgPixel.Bottom();
800 if ( nBotSpace > 0 && nBotSpace > nTopSpace )
802 long nDlgBot = aDlgPixel.Bottom();
803 SCsCOL nWPosX;
804 SCsROW nWPosY;
805 aViewData.GetPosFromPixel( 0,nDlgBot, eAlign, nWPosX, nWPosY );
806 ++nWPosY; // unter der letzten betroffenen Zelle
808 SCsROW nDiff = nWPosY - nDeltaY;
809 if ( nCurY >= nDiff ) // Pos. kann nicht negativ werden
811 nSpaceY = nDlgBot + ( nBotSpace - nCellSizeY ) / 2;
812 bBottom = true;
813 bForceNew = true;
816 if ( !bBottom && nTopSpace > 0 )
818 nSpaceY = ( nTopSpace - nCellSizeY ) / 2;
819 bForceNew = true;
825 SCsCOL nNewDeltaX = nDeltaX;
826 SCsROW nNewDeltaY = nDeltaY;
827 bool bDoLine = false;
829 switch (eMode)
831 case SC_FOLLOW_JUMP:
832 if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
834 nNewDeltaX = nCurX - static_cast<SCsCOL>(aViewData.CellsAtX( nCurX, -1, eAlignX, static_cast<sal_uInt16>(nSpaceX) ));
835 if (nNewDeltaX < 0) nNewDeltaX = 0;
836 nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
838 if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY || bForceNew )
840 nNewDeltaY = nCurY - static_cast<SCsROW>(aViewData.CellsAtY( nCurY, -1, eAlignY, static_cast<sal_uInt16>(nSpaceY) ));
841 if (nNewDeltaY < 0) nNewDeltaY = 0;
842 nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
844 bDoLine = true;
845 break;
847 case SC_FOLLOW_LINE:
848 bDoLine = true;
849 break;
851 case SC_FOLLOW_FIX:
852 if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
854 nNewDeltaX = nDeltaX + nCurX - aViewData.GetCurX();
855 if (nNewDeltaX < 0) nNewDeltaX = 0;
856 nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
858 if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY )
860 nNewDeltaY = nDeltaY + nCurY - aViewData.GetCurY();
861 if (nNewDeltaY < 0) nNewDeltaY = 0;
862 nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
865 // like old version of SC_FOLLOW_JUMP:
867 if ( nCurX < nNewDeltaX || nCurX >= nNewDeltaX+nSizeX )
869 nNewDeltaX = nCurX - (nSizeX / 2);
870 if (nNewDeltaX < 0) nNewDeltaX = 0;
871 nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
873 if ( nCurY < nNewDeltaY || nCurY >= nNewDeltaY+nSizeY )
875 nNewDeltaY = nCurY - (nSizeY / 2);
876 if (nNewDeltaY < 0) nNewDeltaY = 0;
877 nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
880 bDoLine = true;
881 break;
883 case SC_FOLLOW_NONE:
884 break;
885 default:
886 OSL_FAIL("Falscher Cursormodus");
887 break;
890 if (bDoLine)
892 while ( nCurX >= nNewDeltaX+nSizeX )
894 nNewDeltaX = nCurX-nSizeX+1;
895 ScDocument* pDoc = aViewData.GetDocument();
896 SCTAB nTab = aViewData.GetTabNo();
897 while ( nNewDeltaX < MAXCOL && !pDoc->GetColWidth( nNewDeltaX, nTab ) )
898 ++nNewDeltaX;
899 nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
901 while ( nCurY >= nNewDeltaY+nSizeY )
903 nNewDeltaY = nCurY-nSizeY+1;
904 ScDocument* pDoc = aViewData.GetDocument();
905 SCTAB nTab = aViewData.GetTabNo();
906 while ( nNewDeltaY < MAXROW && !pDoc->GetRowHeight( nNewDeltaY, nTab ) )
907 ++nNewDeltaY;
908 nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
910 if ( nCurX < nNewDeltaX ) nNewDeltaX = nCurX;
911 if ( nCurY < nNewDeltaY ) nNewDeltaY = nCurY;
914 if ( nNewDeltaX != nDeltaX )
915 nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
916 if (nNewDeltaX+nSizeX-1 > MAXCOL) nNewDeltaX = MAXCOL-nSizeX+1;
917 if (nNewDeltaX < 0) nNewDeltaX = 0;
919 if ( nNewDeltaY != nDeltaY )
920 nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
921 if (nNewDeltaY+nSizeY-1 > MAXROW) nNewDeltaY = MAXROW-nSizeY+1;
922 if (nNewDeltaY < 0) nNewDeltaY = 0;
924 if ( nNewDeltaX != nDeltaX ) ScrollX( nNewDeltaX - nDeltaX, eAlignX );
925 if ( nNewDeltaY != nDeltaY ) ScrollY( nNewDeltaY - nDeltaY, eAlignY );
928 // nochmal aktiven Teil umschalten
930 if (bHFix)
931 if (eActiveX == SC_SPLIT_RIGHT && nCurX < (SCsCOL)aViewData.GetFixPosX())
933 ActivatePart( (eActiveY==SC_SPLIT_TOP) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT );
934 eActiveX = SC_SPLIT_LEFT;
936 if (bVFix)
937 if (eActiveY == SC_SPLIT_BOTTOM && nCurY < (SCsROW)aViewData.GetFixPosY())
939 ActivatePart( (eActiveX==SC_SPLIT_LEFT) ? SC_SPLIT_TOPLEFT : SC_SPLIT_TOPRIGHT );
940 eActiveY = SC_SPLIT_TOP;
944 bool ScTabView::SelMouseButtonDown( const MouseEvent& rMEvt )
946 bool bRet = false;
948 // #i3875# *Hack*
949 bool bMod1Locked = (aViewData.GetViewShell()->GetLockedModifiers() & KEY_MOD1) != 0;
950 aViewData.SetSelCtrlMouseClick( rMEvt.IsMod1() || bMod1Locked );
952 if ( pSelEngine )
954 bMoveIsShift = rMEvt.IsShift();
955 bRet = pSelEngine->SelMouseButtonDown( rMEvt );
956 bMoveIsShift = false;
959 aViewData.SetSelCtrlMouseClick( false ); // #i3875# *Hack*
961 return bRet;
964 // MoveCursor - mit Anpassung des Bildausschnitts
966 void ScTabView::MoveCursorAbs( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
967 bool bShift, bool bControl, bool bKeepOld, bool bKeepSel )
969 if (!bKeepOld)
970 aViewData.ResetOldCursor();
972 // #i123629#
973 if( aViewData.GetViewShell()->GetForceFocusOnCurCell() )
974 aViewData.GetViewShell()->SetForceFocusOnCurCell( !ValidColRow(nCurX, nCurY) );
976 if (nCurX < 0) nCurX = 0;
977 if (nCurY < 0) nCurY = 0;
978 if (nCurX > MAXCOL) nCurX = MAXCOL;
979 if (nCurY > MAXROW) nCurY = MAXROW;
981 HideAllCursors();
983 // aktiven Teil umschalten jetzt in AlignToCursor
985 AlignToCursor( nCurX, nCurY, eMode );
986 //! auf OS/2: SC_FOLLOW_JUMP statt SC_FOLLOW_LINE, um Nachlaufen zu verhindern ???
988 if (bKeepSel)
990 SetCursor( nCurX, nCurY ); // Markierung stehenlassen
992 // If the cursor is in existing selection, it's a cursor movement by
993 // ENTER or TAB. If not, then it's a new selection during ADD
994 // selection mode.
996 const ScMarkData& rMark = aViewData.GetMarkData();
997 ScRangeList aSelList;
998 rMark.FillRangeListWithMarks(&aSelList, false);
999 if (!aSelList.In(ScRange(nCurX, nCurY, aViewData.GetTabNo())))
1000 // Cursor not in existing selection. Start a new selection.
1001 DoneBlockMode(true);
1003 else
1005 if (!bShift)
1007 // Remove all marked data on cursor movement unless the Shift is locked.
1008 ScMarkData& rMark = aViewData.GetMarkData();
1009 bool bMarked = rMark.IsMarked() || rMark.IsMultiMarked();
1010 if (bMarked)
1012 rMark.ResetMark();
1013 DoneBlockMode();
1014 InitOwnBlockMode();
1015 MarkDataChanged();
1019 bool bSame = ( nCurX == aViewData.GetCurX() && nCurY == aViewData.GetCurY() );
1020 bMoveIsShift = bShift;
1021 pSelEngine->CursorPosChanging( bShift, bControl );
1022 bMoveIsShift = false;
1023 aFunctionSet.SetCursorAtCell( nCurX, nCurY, false );
1025 // Wenn der Cursor nicht bewegt wurde, muss das SelectionChanged fuer das
1026 // Aufheben der Selektion hier einzeln passieren:
1027 if (bSame)
1028 SelectionChanged();
1031 ShowAllCursors();
1032 TestHintWindow();
1035 void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
1036 bool bShift, bool bKeepSel )
1038 ScDocument* pDoc = aViewData.GetDocument();
1039 SCTAB nTab = aViewData.GetTabNo();
1041 bool bSkipProtected = false, bSkipUnprotected = false;
1042 ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
1043 if ( pProtect && pProtect->isProtected() )
1045 bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
1046 bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
1049 if ( bSkipProtected && bSkipUnprotected )
1050 return;
1052 SCsCOL nOldX;
1053 SCsROW nOldY;
1054 SCsCOL nCurX;
1055 SCsROW nCurY;
1056 if ( aViewData.IsRefMode() )
1058 nOldX = (SCsCOL) aViewData.GetRefEndX();
1059 nOldY = (SCsROW) aViewData.GetRefEndY();
1060 nCurX = nOldX + nMovX;
1061 nCurY = nOldY + nMovY;
1063 else
1065 nOldX = (SCsCOL) aViewData.GetCurX();
1066 nOldY = (SCsROW) aViewData.GetCurY();
1067 nCurX = (nMovX != 0) ? nOldX+nMovX : (SCsCOL) aViewData.GetOldCurX();
1068 nCurY = (nMovY != 0) ? nOldY+nMovY : (SCsROW) aViewData.GetOldCurY();
1071 aViewData.ResetOldCursor();
1073 if (nMovX != 0 && ValidColRow(nCurX,nCurY))
1074 SkipCursorHorizontal(nCurX, nCurY, nOldX, nMovX);
1076 if (nMovY != 0 && ValidColRow(nCurX,nCurY))
1077 SkipCursorVertical(nCurX, nCurY, nOldY, nMovY);
1079 MoveCursorAbs( nCurX, nCurY, eMode, bShift, false, true, bKeepSel );
1082 void ScTabView::MoveCursorPage( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, bool bShift, bool bKeepSel )
1084 SCsCOL nPageX;
1085 SCsROW nPageY;
1086 GetPageMoveEndPosition(nMovX, nMovY, nPageX, nPageY);
1087 MoveCursorRel( nPageX, nPageY, eMode, bShift, bKeepSel );
1090 void ScTabView::MoveCursorArea( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, bool bShift, bool bKeepSel )
1092 SCsCOL nNewX;
1093 SCsROW nNewY;
1094 GetAreaMoveEndPosition(nMovX, nMovY, eMode, nNewX, nNewY, eMode);
1095 MoveCursorRel(nNewX, nNewY, eMode, bShift, bKeepSel);
1098 void ScTabView::MoveCursorEnd( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, bool bShift, bool bKeepSel )
1100 ScDocument* pDoc = aViewData.GetDocument();
1101 SCTAB nTab = aViewData.GetTabNo();
1103 SCCOL nCurX;
1104 SCROW nCurY;
1105 aViewData.GetMoveCursor( nCurX,nCurY );
1106 SCCOL nNewX = nCurX;
1107 SCROW nNewY = nCurY;
1109 SCCOL nUsedX = 0;
1110 SCROW nUsedY = 0;
1111 if ( nMovX > 0 || nMovY > 0 )
1112 pDoc->GetPrintArea( nTab, nUsedX, nUsedY ); // Ende holen
1114 if (nMovX<0)
1115 nNewX=0;
1116 else if (nMovX>0)
1117 nNewX=nUsedX; // letzter benutzter Bereich
1119 if (nMovY<0)
1120 nNewY=0;
1121 else if (nMovY>0)
1122 nNewY=nUsedY;
1124 aViewData.ResetOldCursor();
1125 MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY, eMode, bShift, bKeepSel );
1128 void ScTabView::MoveCursorScreen( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, bool bShift )
1130 ScDocument* pDoc = aViewData.GetDocument();
1131 SCTAB nTab = aViewData.GetTabNo();
1133 SCCOL nCurX;
1134 SCROW nCurY;
1135 aViewData.GetMoveCursor( nCurX,nCurY );
1136 SCCOL nNewX = nCurX;
1137 SCROW nNewY = nCurY;
1139 ScSplitPos eWhich = aViewData.GetActivePart();
1140 SCCOL nPosX = aViewData.GetPosX( WhichH(eWhich) );
1141 SCROW nPosY = aViewData.GetPosY( WhichV(eWhich) );
1143 SCCOL nAddX = aViewData.VisibleCellsX( WhichH(eWhich) );
1144 if (nAddX != 0)
1145 --nAddX;
1146 SCROW nAddY = aViewData.VisibleCellsY( WhichV(eWhich) );
1147 if (nAddY != 0)
1148 --nAddY;
1150 if (nMovX<0)
1151 nNewX=nPosX;
1152 else if (nMovX>0)
1153 nNewX=nPosX+nAddX;
1155 if (nMovY<0)
1156 nNewY=nPosY;
1157 else if (nMovY>0)
1158 nNewY=nPosY+nAddY;
1160 aViewData.SetOldCursor( nNewX,nNewY );
1161 pDoc->SkipOverlapped(nNewX, nNewY, nTab);
1162 MoveCursorAbs( nNewX, nNewY, eMode, bShift, false, true );
1165 void ScTabView::MoveCursorEnter( bool bShift ) // bShift -> hoch/runter
1167 const ScInputOptions& rOpt = SC_MOD()->GetInputOptions();
1168 if (!rOpt.GetMoveSelection())
1170 aViewData.UpdateInputHandler(true);
1171 return;
1174 SCsCOL nMoveX = 0;
1175 SCsROW nMoveY = 0;
1176 switch ((ScDirection)rOpt.GetMoveDir())
1178 case DIR_BOTTOM:
1179 nMoveY = bShift ? -1 : 1;
1180 break;
1181 case DIR_RIGHT:
1182 nMoveX = bShift ? -1 : 1;
1183 break;
1184 case DIR_TOP:
1185 nMoveY = bShift ? 1 : -1;
1186 break;
1187 case DIR_LEFT:
1188 nMoveX = bShift ? 1 : -1;
1189 break;
1192 ScMarkData& rMark = aViewData.GetMarkData();
1193 if (rMark.IsMarked() || rMark.IsMultiMarked())
1195 SCCOL nCurX;
1196 SCROW nCurY;
1197 aViewData.GetMoveCursor( nCurX,nCurY );
1198 SCCOL nNewX = nCurX;
1199 SCROW nNewY = nCurY;
1200 SCTAB nTab = aViewData.GetTabNo();
1202 ScDocument* pDoc = aViewData.GetDocument();
1203 pDoc->GetNextPos( nNewX,nNewY, nTab, nMoveX,nMoveY, true, false, rMark );
1205 MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY,
1206 SC_FOLLOW_LINE, false, true );
1208 // update input line even if cursor was not moved
1209 if ( nNewX == nCurX && nNewY == nCurY )
1210 aViewData.UpdateInputHandler(true);
1212 else
1214 if ( nMoveY != 0 && !nMoveX )
1216 // nach Tab und Enter wieder zur Ausgangsspalte
1217 SCCOL nTabCol = aViewData.GetTabStartCol();
1218 if (nTabCol != SC_TABSTART_NONE)
1220 SCCOL nCurX;
1221 SCROW nCurY;
1222 aViewData.GetMoveCursor( nCurX,nCurY );
1223 nMoveX = ((SCsCOL)nTabCol)-(SCsCOL)nCurX;
1227 MoveCursorRel( nMoveX,nMoveY, SC_FOLLOW_LINE, false );
1231 bool ScTabView::MoveCursorKeyInput( const KeyEvent& rKeyEvent )
1233 const vcl::KeyCode& rKCode = rKeyEvent.GetKeyCode();
1235 enum { MOD_NONE, MOD_CTRL, MOD_ALT, MOD_BOTH } eModifier =
1236 rKCode.IsMod1() ?
1237 (rKCode.IsMod2() ? MOD_BOTH : MOD_CTRL) :
1238 (rKCode.IsMod2() ? MOD_ALT : MOD_NONE);
1240 bool bSel = rKCode.IsShift();
1241 sal_uInt16 nCode = rKCode.GetCode();
1243 // CURSOR keys
1244 SCsCOL nDX = 0;
1245 SCsROW nDY = 0;
1246 switch( nCode )
1248 case KEY_LEFT: nDX = -1; break;
1249 case KEY_RIGHT: nDX = 1; break;
1250 case KEY_UP: nDY = -1; break;
1251 case KEY_DOWN: nDY = 1; break;
1253 if( nDX != 0 || nDY != 0 )
1255 switch( eModifier )
1257 case MOD_NONE: MoveCursorRel( nDX, nDY, SC_FOLLOW_LINE, bSel ); break;
1258 case MOD_CTRL: MoveCursorArea( nDX, nDY, SC_FOLLOW_JUMP, bSel ); break;
1259 default:
1261 // added to avoid warnings
1264 // always true to suppress changes of col/row size (ALT+CURSOR)
1265 return true;
1268 // PAGEUP/PAGEDOWN
1269 if( (nCode == KEY_PAGEUP) || (nCode == KEY_PAGEDOWN) )
1271 nDX = (nCode == KEY_PAGEUP) ? -1 : 1;
1272 switch( eModifier )
1274 case MOD_NONE: MoveCursorPage( 0, static_cast<SCsCOLROW>(nDX), SC_FOLLOW_FIX, bSel ); break;
1275 case MOD_ALT: MoveCursorPage( nDX, 0, SC_FOLLOW_FIX, bSel ); break;
1276 case MOD_CTRL: SelectNextTab( nDX ); break;
1277 default:
1279 // added to avoid warnings
1282 return true;
1285 // HOME/END
1286 if( (nCode == KEY_HOME) || (nCode == KEY_END) )
1288 nDX = (nCode == KEY_HOME) ? -1 : 1;
1289 ScFollowMode eMode = (nCode == KEY_HOME) ? SC_FOLLOW_LINE : SC_FOLLOW_JUMP;
1290 switch( eModifier )
1292 case MOD_NONE: MoveCursorEnd( nDX, 0, eMode, bSel ); break;
1293 case MOD_CTRL: MoveCursorEnd( nDX, static_cast<SCsCOLROW>(nDX), eMode, bSel ); break;
1294 default:
1296 // added to avoid warnings
1299 return true;
1302 return false;
1305 // naechste/vorherige nicht geschuetzte Zelle
1306 void ScTabView::FindNextUnprot( bool bShift, bool bInSelection )
1308 short nMove = bShift ? -1 : 1;
1310 ScMarkData& rMark = aViewData.GetMarkData();
1311 bool bMarked = bInSelection && (rMark.IsMarked() || rMark.IsMultiMarked());
1313 SCCOL nCurX;
1314 SCROW nCurY;
1315 aViewData.GetMoveCursor( nCurX,nCurY );
1316 SCCOL nNewX = nCurX;
1317 SCROW nNewY = nCurY;
1318 SCTAB nTab = aViewData.GetTabNo();
1320 ScDocument* pDoc = aViewData.GetDocument();
1321 pDoc->GetNextPos( nNewX,nNewY, nTab, nMove,0, bMarked, true, rMark );
1323 SCCOL nTabCol = aViewData.GetTabStartCol();
1324 if ( nTabCol == SC_TABSTART_NONE )
1325 nTabCol = nCurX; // auf diese Spalte zurueck bei Enter
1327 MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY,
1328 SC_FOLLOW_LINE, false, true );
1330 // in MoveCursorRel wird die TabCol zurueckgesetzt...
1331 aViewData.SetTabStartCol( nTabCol );
1334 void ScTabView::MarkColumns()
1336 SCCOL nStartCol;
1337 SCCOL nEndCol;
1339 ScMarkData& rMark = aViewData.GetMarkData();
1340 if (rMark.IsMarked())
1342 ScRange aMarkRange;
1343 rMark.GetMarkArea( aMarkRange );
1344 nStartCol = aMarkRange.aStart.Col();
1345 nEndCol = aMarkRange.aEnd.Col();
1347 else
1349 SCROW nDummy;
1350 aViewData.GetMoveCursor( nStartCol, nDummy );
1351 nEndCol=nStartCol;
1354 SCTAB nTab = aViewData.GetTabNo();
1355 DoneBlockMode();
1356 InitBlockMode( nStartCol,0, nTab );
1357 MarkCursor( nEndCol,MAXROW, nTab );
1358 SelectionChanged();
1361 void ScTabView::MarkRows()
1363 SCROW nStartRow;
1364 SCROW nEndRow;
1366 ScMarkData& rMark = aViewData.GetMarkData();
1367 if (rMark.IsMarked())
1369 ScRange aMarkRange;
1370 rMark.GetMarkArea( aMarkRange );
1371 nStartRow = aMarkRange.aStart.Row();
1372 nEndRow = aMarkRange.aEnd.Row();
1374 else
1376 SCCOL nDummy;
1377 aViewData.GetMoveCursor( nDummy, nStartRow );
1378 nEndRow=nStartRow;
1381 SCTAB nTab = aViewData.GetTabNo();
1382 DoneBlockMode();
1383 InitBlockMode( 0,nStartRow, nTab );
1384 MarkCursor( MAXCOL,nEndRow, nTab );
1385 SelectionChanged();
1388 void ScTabView::MarkDataArea( bool bIncludeCursor )
1390 ScDocument* pDoc = aViewData.GetDocument();
1391 SCTAB nTab = aViewData.GetTabNo();
1392 SCCOL nStartCol = aViewData.GetCurX();
1393 SCROW nStartRow = aViewData.GetCurY();
1394 SCCOL nEndCol = nStartCol;
1395 SCROW nEndRow = nStartRow;
1397 pDoc->GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, bIncludeCursor, false );
1399 HideAllCursors();
1400 DoneBlockMode();
1401 InitBlockMode( nStartCol, nStartRow, nTab );
1402 MarkCursor( nEndCol, nEndRow, nTab );
1403 ShowAllCursors();
1405 SelectionChanged();
1408 void ScTabView::MarkMatrixFormula()
1410 ScDocument* pDoc = aViewData.GetDocument();
1411 ScAddress aCursor( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
1412 ScRange aMatrix;
1413 if ( pDoc->GetMatrixFormulaRange( aCursor, aMatrix ) )
1415 MarkRange( aMatrix, false ); // cursor is already within the range
1419 void ScTabView::MarkRange( const ScRange& rRange, bool bSetCursor, bool bContinue )
1421 SCTAB nTab = rRange.aStart.Tab();
1422 SetTabNo( nTab );
1424 HideAllCursors();
1425 DoneBlockMode( bContinue ); // bContinue==true -> clear old mark
1426 if (bSetCursor) // Wenn Cursor gesetzt wird, immer auch alignen
1428 SCCOL nAlignX = rRange.aStart.Col();
1429 SCROW nAlignY = rRange.aStart.Row();
1430 bool bCol = ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == MAXCOL ) && !aViewData.GetDocument()->IsInVBAMode();
1431 bool bRow = ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW );
1432 if ( bCol )
1433 nAlignX = aViewData.GetPosX(WhichH(aViewData.GetActivePart()));
1434 if ( bRow )
1435 nAlignY = aViewData.GetPosY(WhichV(aViewData.GetActivePart()));
1436 AlignToCursor( nAlignX, nAlignY, SC_FOLLOW_JUMP );
1438 InitBlockMode( rRange.aStart.Col(), rRange.aStart.Row(), nTab );
1439 MarkCursor( rRange.aEnd.Col(), rRange.aEnd.Row(), nTab );
1440 if (bSetCursor)
1442 SCCOL nPosX = rRange.aStart.Col();
1443 SCROW nPosY = rRange.aStart.Row();
1444 ScDocument* pDoc = aViewData.GetDocument();
1445 pDoc->SkipOverlapped(nPosX, nPosY, nTab);
1447 aViewData.ResetOldCursor();
1448 SetCursor( nPosX, nPosY );
1450 ShowAllCursors();
1452 SelectionChanged();
1455 void ScTabView::Unmark()
1457 ScMarkData& rMark = aViewData.GetMarkData();
1458 if ( rMark.IsMarked() || rMark.IsMultiMarked() )
1460 SCCOL nCurX;
1461 SCROW nCurY;
1462 aViewData.GetMoveCursor( nCurX,nCurY );
1463 MoveCursorAbs( nCurX, nCurY, SC_FOLLOW_NONE, false, false );
1465 SelectionChanged();
1469 void ScTabView::SetMarkData( const ScMarkData& rNew )
1471 DoneBlockMode();
1472 InitOwnBlockMode();
1473 aViewData.GetMarkData() = rNew;
1475 MarkDataChanged();
1478 void ScTabView::MarkDataChanged()
1480 // has to be called after making direct changes to mark data (not via MarkCursor etc)
1482 UpdateSelectionOverlay();
1485 void ScTabView::SelectNextTab( short nDir, bool bExtendSelection )
1487 if (!nDir) return;
1488 OSL_ENSURE( nDir==-1 || nDir==1, "SelectNextTab: falscher Wert");
1490 ScDocument* pDoc = aViewData.GetDocument();
1491 SCTAB nTab = aViewData.GetTabNo();
1492 if (nDir<0)
1494 if (!nTab) return;
1495 --nTab;
1496 while (!pDoc->IsVisible(nTab))
1498 if (!nTab) return;
1499 --nTab;
1502 else
1504 SCTAB nCount = pDoc->GetTableCount();
1505 ++nTab;
1506 if (nTab >= nCount) return;
1507 while (!pDoc->IsVisible(nTab))
1509 ++nTab;
1510 if (nTab >= nCount) return;
1514 SetTabNo( nTab, false, bExtendSelection );
1515 PaintExtras();
1518 // SetTabNo - angezeigte Tabelle
1520 void ScTabView::SetTabNo( SCTAB nTab, bool bNew, bool bExtendSelection, bool bSameTabButMoved )
1522 if ( !ValidTab(nTab) )
1524 OSL_FAIL("SetTabNo: falsche Tabelle");
1525 return;
1528 if ( nTab != aViewData.GetTabNo() || bNew )
1530 // Die FormShell moechte vor dem Umschalten benachrichtigt werden
1531 FmFormShell* pFormSh = aViewData.GetViewShell()->GetFormShell();
1532 if (pFormSh)
1534 bool bAllowed = pFormSh->PrepareClose(true);
1535 if (!bAllowed)
1537 //! Fehlermeldung? oder macht das die FormShell selber?
1538 //! Fehler-Flag zurueckgeben und Aktionen abbrechen
1540 return; // Die FormShell sagt, es kann nicht umgeschaltet werden
1544 // nicht InputEnterHandler wegen Referenzeingabe !
1546 ScDocument* pDoc = aViewData.GetDocument();
1548 pDoc->MakeTable( nTab );
1550 // Update pending row heights before switching the sheet, so Reschedule from the progress bar
1551 // doesn't paint the new sheet with old heights
1552 aViewData.GetDocShell()->UpdatePendingRowHeights( nTab );
1554 SCTAB nTabCount = pDoc->GetTableCount();
1555 SCTAB nOldPos = nTab;
1556 while (!pDoc->IsVisible(nTab)) // naechste sichtbare suchen
1558 bool bUp = (nTab>=nOldPos);
1559 if (bUp)
1561 ++nTab;
1562 if (nTab>=nTabCount)
1564 nTab = nOldPos;
1565 bUp = false;
1569 if (!bUp)
1571 if (nTab != 0)
1572 --nTab;
1573 else
1575 OSL_FAIL("keine sichtbare Tabelle");
1576 pDoc->SetVisible( 0, true );
1581 // #i71490# Deselect drawing objects before changing the sheet number in view data,
1582 // so the handling of notes still has the sheet selected on which the notes are.
1583 DrawDeselectAll();
1585 ScModule* pScMod = SC_MOD();
1586 bool bRefMode = pScMod->IsFormulaMode();
1587 if ( !bRefMode ) // Abfrage, damit RefMode bei Tabellenwechsel funktioniert
1589 DoneBlockMode();
1590 pSelEngine->Reset(); // reset all flags, including locked modifiers
1591 aViewData.SetRefTabNo( nTab );
1594 ScSplitPos eOldActive = aViewData.GetActivePart(); // before switching
1595 bool bFocus = pGridWin[eOldActive]->HasFocus();
1597 aViewData.SetTabNo( nTab );
1598 // UpdateShow noch vor SetCursor, damit UpdateAutoFillMark die richtigen
1599 // Fenster findet (wird aus SetCursor gerufen)
1600 UpdateShow();
1601 aViewData.ResetOldCursor();
1603 SfxBindings& rBindings = aViewData.GetBindings();
1604 ScMarkData& rMark = aViewData.GetMarkData();
1606 bool bAllSelected = true;
1607 for (SCTAB nSelTab = 0; nSelTab < nTabCount; ++nSelTab)
1609 if (!pDoc->IsVisible(nSelTab) || rMark.GetTableSelect(nSelTab))
1611 if (nTab == nSelTab)
1612 // This tab is already in selection. Keep the current
1613 // selection.
1614 bExtendSelection = true;
1616 else
1618 bAllSelected = false;
1619 if (bExtendSelection)
1620 // We got what we need. No need to stay in the loop.
1621 break;
1624 if (bAllSelected && !bNew)
1625 // #i6327# if all tables are selected, a selection event (#i6330#) will deselect all
1626 // (not if called with bNew to update settings)
1627 bExtendSelection = false;
1629 if (bExtendSelection)
1630 rMark.SelectTable( nTab, true );
1631 else
1633 rMark.SelectOneTable( nTab );
1634 rBindings.Invalidate( FID_FILL_TAB );
1635 rBindings.Invalidate( FID_TAB_DESELECTALL );
1638 SetCursor( aViewData.GetCurX(), aViewData.GetCurY(), true );
1639 bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF;
1641 // recalc zoom-dependent values (before TabChanged, before UpdateEditViewPos)
1642 RefreshZoom();
1643 UpdateVarZoom();
1645 if ( bRefMode ) // hide EditView if necessary (after aViewData.SetTabNo !)
1647 for (sal_uInt16 i = 0; i < 4; ++i)
1648 if (pGridWin[i] && pGridWin[i]->IsVisible())
1649 pGridWin[i]->UpdateEditViewPos();
1652 TabChanged(bSameTabButMoved); // DrawView
1653 UpdateVisibleRange();
1655 aViewData.GetViewShell()->WindowChanged(); // falls das aktive Fenster anders ist
1656 if ( !bUnoRefDialog )
1657 aViewData.GetViewShell()->DisconnectAllClients(); // important for floating frames
1658 else
1660 // hide / show inplace client
1662 ScClient* pClient = static_cast<ScClient*>(aViewData.GetViewShell()->GetIPClient());
1663 if ( pClient && pClient->IsObjectInPlaceActive() )
1665 Rectangle aObjArea = pClient->GetObjArea();
1666 if ( nTab == aViewData.GetRefTabNo() )
1668 // move to its original position
1670 SdrOle2Obj* pDrawObj = pClient->GetDrawObj();
1671 if ( pDrawObj )
1673 Rectangle aRect = pDrawObj->GetLogicRect();
1674 MapMode aMapMode( MAP_100TH_MM );
1675 Size aOleSize = pDrawObj->GetOrigObjSize( &aMapMode );
1676 aRect.SetSize( aOleSize );
1677 aObjArea = aRect;
1680 else
1682 // move to an invisible position
1684 aObjArea.SetPos( Point( 0, -2*aObjArea.GetHeight() ) );
1686 pClient->SetObjArea( aObjArea );
1690 if ( bFocus && aViewData.GetActivePart() != eOldActive && !bRefMode )
1691 ActiveGrabFocus(); // grab focus to the pane that's active now
1693 // Fixierungen
1695 bool bResize = false;
1696 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
1697 if (aViewData.UpdateFixX())
1698 bResize = true;
1699 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1700 if (aViewData.UpdateFixY())
1701 bResize = true;
1702 if (bResize)
1703 RepeatResize();
1704 InvalidateSplit();
1706 if ( aViewData.IsPagebreakMode() )
1707 UpdatePageBreakData(); //! asynchron ??
1709 // Form-Layer muss den sichtbaren Ausschnitt der neuen Tabelle kennen
1710 // dafuer muss hier schon der MapMode stimmen
1711 for (sal_uInt16 i=0; i<4; i++)
1712 if (pGridWin[i])
1713 pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
1714 SetNewVisArea();
1716 PaintGrid();
1717 PaintTop();
1718 PaintLeft();
1719 PaintExtras();
1721 DoResize( aBorderPos, aFrameSize );
1722 rBindings.Invalidate( SID_DELETE_PRINTAREA ); // Menue
1723 rBindings.Invalidate( FID_DEL_MANUALBREAKS );
1724 rBindings.Invalidate( FID_RESET_PRINTZOOM );
1725 rBindings.Invalidate( SID_STATUS_DOCPOS ); // Statusbar
1726 rBindings.Invalidate( SID_ROWCOL_SELCOUNT ); // Statusbar
1727 rBindings.Invalidate( SID_STATUS_PAGESTYLE ); // Statusbar
1728 rBindings.Invalidate( SID_CURRENTTAB ); // Navigator
1729 rBindings.Invalidate( SID_STYLE_FAMILY2 ); // Gestalter
1730 rBindings.Invalidate( SID_STYLE_FAMILY4 ); // Gestalter
1731 rBindings.Invalidate( SID_TABLES_COUNT );
1733 if(pScMod->IsRefDialogOpen())
1735 sal_uInt16 nCurRefDlgId=pScMod->GetCurRefDlgId();
1736 SfxViewFrame* pViewFrm = aViewData.GetViewShell()->GetViewFrame();
1737 SfxChildWindow* pChildWnd = pViewFrm->GetChildWindow( nCurRefDlgId );
1738 IAnyRefDialog* pRefDlg = pChildWnd ? dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow()) : NULL;
1739 if (pRefDlg)
1741 pRefDlg->ViewShellChanged();
1747 // Paint-Funktionen - nur fuer diese View
1749 void ScTabView::MakeEditView( ScEditEngineDefaulter* pEngine, SCCOL nCol, SCROW nRow )
1751 DrawDeselectAll();
1753 if (pDrawView)
1754 DrawEnableAnim( false );
1756 EditView* pSpellingView = aViewData.GetSpellingView();
1758 for (sal_uInt16 i=0; i<4; i++)
1759 if (pGridWin[i])
1760 if ( pGridWin[i]->IsVisible() && !aViewData.HasEditView((ScSplitPos)i) )
1762 ScHSplitPos eHWhich = WhichH( (ScSplitPos) i );
1763 ScVSplitPos eVWhich = WhichV( (ScSplitPos) i );
1764 SCCOL nScrX = aViewData.GetPosX( eHWhich );
1765 SCROW nScrY = aViewData.GetPosY( eVWhich );
1767 bool bPosVisible =
1768 ( nCol >= nScrX && nCol <= nScrX + aViewData.VisibleCellsX(eHWhich) + 1 &&
1769 nRow >= nScrY && nRow <= nScrY + aViewData.VisibleCellsY(eVWhich) + 1 );
1771 // for the active part, create edit view even if outside the visible area,
1772 // so input isn't lost (and the edit view may be scrolled into the visible area)
1774 // #i26433# during spelling, the spelling view must be active
1775 if ( bPosVisible || aViewData.GetActivePart() == (ScSplitPos) i ||
1776 ( pSpellingView && aViewData.GetEditView((ScSplitPos) i) == pSpellingView ) )
1778 pGridWin[i]->HideCursor();
1780 pGridWin[i]->DeleteCursorOverlay();
1781 pGridWin[i]->DeleteAutoFillOverlay();
1782 pGridWin[i]->DeleteCopySourceOverlay();
1784 // flush OverlayManager before changing MapMode to text edit
1785 pGridWin[i]->flushOverlayManager();
1787 // MapMode must be set after HideCursor
1788 pGridWin[i]->SetMapMode(aViewData.GetLogicMode());
1790 aViewData.SetEditEngine( (ScSplitPos) i, pEngine, pGridWin[i], nCol, nRow );
1792 if ( !bPosVisible )
1794 // move the edit view area to the real (possibly negative) position,
1795 // or hide if completely above or left of the window
1796 pGridWin[i]->UpdateEditViewPos();
1801 if (aViewData.GetViewShell()->HasAccessibilityObjects())
1802 aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_ENTEREDITMODE));
1805 void ScTabView::UpdateEditView()
1807 ScSplitPos eActive = aViewData.GetActivePart();
1808 for (sal_uInt16 i=0; i<4; i++)
1809 if (aViewData.HasEditView( (ScSplitPos) i ))
1811 EditView* pEditView = aViewData.GetEditView( (ScSplitPos) i );
1812 aViewData.SetEditEngine( (ScSplitPos) i,
1813 static_cast<ScEditEngineDefaulter*>(pEditView->GetEditEngine()),
1814 pGridWin[i], GetViewData().GetCurX(), GetViewData().GetCurY() );
1815 if ( (ScSplitPos)i == eActive )
1816 pEditView->ShowCursor( false );
1820 void ScTabView::KillEditView( bool bNoPaint )
1822 sal_uInt16 i;
1823 SCCOL nCol1 = aViewData.GetEditStartCol();
1824 SCROW nRow1 = aViewData.GetEditStartRow();
1825 SCCOL nCol2 = aViewData.GetEditEndCol();
1826 SCROW nRow2 = aViewData.GetEditEndRow();
1827 bool bPaint[4];
1828 bool bNotifyAcc = false;
1830 bool bExtended = nRow1 != nRow2; // Col wird sowieso bis zum Ende gezeichnet
1831 bool bAtCursor = nCol1 <= aViewData.GetCurX() &&
1832 nCol2 >= aViewData.GetCurX() &&
1833 nRow1 == aViewData.GetCurY();
1834 for (i=0; i<4; i++)
1836 bPaint[i] = aViewData.HasEditView( (ScSplitPos) i );
1837 if (bPaint[i])
1838 bNotifyAcc = true;
1841 // #108931#; notify accessibility before all things happen
1842 if ((bNotifyAcc) && (aViewData.GetViewShell()->HasAccessibilityObjects()))
1843 aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_LEAVEEDITMODE));
1845 aViewData.ResetEditView();
1846 for (i=0; i<4; i++)
1847 if (pGridWin[i] && bPaint[i])
1848 if (pGridWin[i]->IsVisible())
1850 pGridWin[i]->ShowCursor();
1852 pGridWin[i]->SetMapMode(pGridWin[i]->GetDrawMapMode());
1854 // #i73567# the cell still has to be repainted
1855 if (bExtended || ( bAtCursor && !bNoPaint ))
1857 pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2 );
1858 pGridWin[i]->UpdateSelectionOverlay();
1862 if (pDrawView)
1863 DrawEnableAnim( true );
1865 // GrabFocus immer dann, wenn diese View aktiv ist und
1866 // die Eingabezeile den Focus hat
1868 bool bGrabFocus = false;
1869 if (aViewData.IsActive())
1871 ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
1872 if ( pInputHdl )
1874 ScInputWindow* pInputWin = pInputHdl->GetInputWindow();
1875 if (pInputWin && pInputWin->IsInputActive())
1876 bGrabFocus = true;
1880 if (bGrabFocus)
1882 // So soll es gemacht werden, damit der Sfx es mitbekommt, klappt aber nicht:
1883 //! aViewData.GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
1884 // deshalb erstmal so:
1885 GetActiveWin()->GrabFocus();
1888 // Cursor-Abfrage erst nach GrabFocus
1890 for (i=0; i<4; i++)
1891 if (pGridWin[i] && pGridWin[i]->IsVisible())
1893 vcl::Cursor* pCur = pGridWin[i]->GetCursor();
1894 if (pCur && pCur->IsVisible())
1895 pCur->Hide();
1897 if(bPaint[i])
1899 pGridWin[i]->UpdateCursorOverlay();
1900 pGridWin[i]->UpdateAutoFillOverlay();
1905 void ScTabView::UpdateFormulas()
1907 if ( aViewData.GetDocument()->IsAutoCalcShellDisabled() )
1908 return ;
1910 sal_uInt16 i;
1911 for (i=0; i<4; i++)
1912 if (pGridWin[i])
1913 if (pGridWin[i]->IsVisible())
1914 pGridWin[i]->UpdateFormulas();
1916 if ( aViewData.IsPagebreakMode() )
1917 UpdatePageBreakData(); //! asynchron
1919 UpdateHeaderWidth();
1921 // if in edit mode, adjust edit view area because widths/heights may have changed
1922 if ( aViewData.HasEditView( aViewData.GetActivePart() ) )
1923 UpdateEditView();
1926 // PaintArea -Block neu zeichnen
1928 void ScTabView::PaintArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1929 ScUpdateMode eMode )
1931 SCCOL nCol1;
1932 SCROW nRow1;
1933 SCCOL nCol2;
1934 SCROW nRow2;
1936 PutInOrder( nStartCol, nEndCol );
1937 PutInOrder( nStartRow, nEndRow );
1939 for (size_t i = 0; i < 4; ++i)
1941 if (!pGridWin[i] || !pGridWin[i]->IsVisible())
1942 continue;
1944 ScHSplitPos eHWhich = WhichH( (ScSplitPos) i );
1945 ScVSplitPos eVWhich = WhichV( (ScSplitPos) i );
1946 bool bOut = false;
1948 nCol1 = nStartCol;
1949 nRow1 = nStartRow;
1950 nCol2 = nEndCol;
1951 nRow2 = nEndRow;
1953 SCCOL nScrX = aViewData.GetPosX( eHWhich );
1954 SCROW nScrY = aViewData.GetPosY( eVWhich );
1955 if (nCol1 < nScrX) nCol1 = nScrX;
1956 if (nCol2 < nScrX)
1958 if ( eMode == SC_UPDATE_ALL ) // for UPDATE_ALL, paint anyway
1959 nCol2 = nScrX; // (because of extending strings to the right)
1960 else
1961 bOut = true; // completely outside the window
1963 if (nRow1 < nScrY) nRow1 = nScrY;
1964 if (nRow2 < nScrY) bOut = true;
1966 SCCOL nLastX = nScrX + aViewData.VisibleCellsX( eHWhich ) + 1;
1967 SCROW nLastY = nScrY + aViewData.VisibleCellsY( eVWhich ) + 1;
1968 if (nCol1 > nLastX) bOut = true;
1969 if (nCol2 > nLastX) nCol2 = nLastX;
1970 if (nRow1 > nLastY) bOut = true;
1971 if (nRow2 > nLastY) nRow2 = nLastY;
1973 if (bOut)
1974 continue;
1976 if ( eMode == SC_UPDATE_CHANGED )
1977 pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2, eMode );
1978 else // ALL oder MARKS
1980 bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
1981 long nLayoutSign = bLayoutRTL ? -1 : 1;
1983 Point aStart = aViewData.GetScrPos( nCol1, nRow1, (ScSplitPos) i );
1984 Point aEnd = aViewData.GetScrPos( nCol2+1, nRow2+1, (ScSplitPos) i );
1985 if ( eMode == SC_UPDATE_ALL )
1986 aEnd.X() = bLayoutRTL ? 0 : (pGridWin[i]->GetOutputSizePixel().Width());
1987 aEnd.X() -= nLayoutSign;
1988 aEnd.Y() -= 1;
1990 // #i85232# include area below cells (could be done in GetScrPos?)
1991 if ( eMode == SC_UPDATE_ALL && nRow2 >= MAXROW )
1992 aEnd.Y() = pGridWin[i]->GetOutputSizePixel().Height();
1994 aStart.X() -= nLayoutSign; // include change marks
1995 aStart.Y() -= 1;
1997 bool bMarkClipped = aViewData.GetOptions().GetOption( VOPT_CLIPMARKS );
1998 if (bMarkClipped)
2000 // dazu muesste ScColumn::IsEmptyBlock optimiert werden
2001 // (auf Search() umstellen)
2002 //!if ( nCol1 > 0 && !aViewData.GetDocument()->IsBlockEmpty(
2003 //! aViewData.GetTabNo(),
2004 //! 0, nRow1, nCol1-1, nRow2 ) )
2006 long nMarkPixel = (long)( SC_CLIPMARK_SIZE * aViewData.GetPPTX() );
2007 aStart.X() -= nMarkPixel * nLayoutSign;
2011 pGridWin[i]->Invalidate( pGridWin[i]->PixelToLogic( Rectangle( aStart,aEnd ) ) );
2015 // #i79909# Calling UpdateAllOverlays here isn't necessary and would lead to overlay calls from a timer,
2016 // with a wrong MapMode if editing in a cell (reference input).
2017 // #i80499# Overlays need updates in a lot of cases, e.g. changing row/column size,
2018 // or showing/hiding outlines. TODO: selections in inactive windows are vanishing.
2019 // #i84689# With relative conditional formats, PaintArea may be called often (for each changed cell),
2020 // so UpdateAllOverlays was moved to ScTabViewShell::Notify and is called only if PAINT_LEFT/PAINT_TOP
2021 // is set (width or height changed).
2024 void ScTabView::PaintRangeFinderEntry (ScRangeFindData* pData, const SCTAB nTab)
2026 ScRange aRef = pData->aRef;
2027 aRef.Justify(); // Justify fuer die Abfragen unten
2029 if ( aRef.aStart == aRef.aEnd ) //! Tab ignorieren?
2030 aViewData.GetDocument()->ExtendMerge(aRef);
2032 if ( aRef.aStart.Tab() >= nTab && aRef.aEnd.Tab() <= nTab )
2034 SCCOL nCol1 = aRef.aStart.Col();
2035 SCROW nRow1 = aRef.aStart.Row();
2036 SCCOL nCol2 = aRef.aEnd.Col();
2037 SCROW nRow2 = aRef.aEnd.Row();
2039 // wegnehmen -> Repaint
2040 // SC_UPDATE_MARKS: Invalidate, nicht bis zum Zeilenende
2042 bool bHiddenEdge = false;
2043 SCROW nTmp;
2044 ScDocument* pDoc = aViewData.GetDocument();
2045 while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab) )
2047 --nCol1;
2048 bHiddenEdge = true;
2050 while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab) )
2052 ++nCol2;
2053 bHiddenEdge = true;
2055 nTmp = pDoc->LastVisibleRow(0, nRow1, nTab);
2056 if (!ValidRow(nTmp))
2057 nTmp = 0;
2058 if (nTmp < nRow1)
2060 nRow1 = nTmp;
2061 bHiddenEdge = true;
2063 nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab);
2064 if (!ValidRow(nTmp))
2065 nTmp = MAXROW;
2066 if (nTmp > nRow2)
2068 nRow2 = nTmp;
2069 bHiddenEdge = true;
2072 if ( nCol2 - nCol1 > 1 && nRow2 - nRow1 > 1 && !bHiddenEdge )
2074 // nur an den Raendern entlang
2075 PaintArea( nCol1, nRow1, nCol2, nRow1, SC_UPDATE_MARKS );
2076 PaintArea( nCol1, nRow1+1, nCol1, nRow2-1, SC_UPDATE_MARKS );
2077 PaintArea( nCol2, nRow1+1, nCol2, nRow2-1, SC_UPDATE_MARKS );
2078 PaintArea( nCol1, nRow2, nCol2, nRow2, SC_UPDATE_MARKS );
2080 else // alles am Stueck
2081 PaintArea( nCol1, nRow1, nCol2, nRow2, SC_UPDATE_MARKS );
2085 void ScTabView::PaintRangeFinder( long nNumber )
2087 ScInputHandler* pHdl = SC_MOD()->GetInputHdl( aViewData.GetViewShell() );
2088 if (pHdl)
2090 ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
2091 if ( pRangeFinder && pRangeFinder->GetDocName() == aViewData.GetDocShell()->GetTitle() )
2093 SCTAB nTab = aViewData.GetTabNo();
2094 sal_uInt16 nCount = (sal_uInt16)pRangeFinder->Count();
2096 if (nNumber < 0)
2098 for (sal_uInt16 i=0; i<nCount; i++)
2099 PaintRangeFinderEntry(pRangeFinder->GetObject(i),nTab);
2101 else
2103 sal_uInt16 idx = nNumber;
2104 if (idx < nCount)
2105 PaintRangeFinderEntry(pRangeFinder->GetObject(idx),nTab);
2111 // fuer Chart-Daten-Markierung
2113 void ScTabView::AddHighlightRange( const ScRange& rRange, const Color& rColor )
2115 maHighlightRanges.push_back( ScHighlightEntry( rRange, rColor ) );
2117 SCTAB nTab = aViewData.GetTabNo();
2118 if ( nTab >= rRange.aStart.Tab() && nTab <= rRange.aEnd.Tab() )
2119 PaintArea( rRange.aStart.Col(), rRange.aStart.Row(),
2120 rRange.aEnd.Col(), rRange.aEnd.Row(), SC_UPDATE_MARKS );
2123 void ScTabView::ClearHighlightRanges()
2125 SCTAB nTab = aViewData.GetTabNo();
2126 std::vector<ScHighlightEntry>::const_iterator pIter;
2127 for ( pIter = maHighlightRanges.begin(); pIter != maHighlightRanges.end(); ++pIter)
2129 ScRange aRange = pIter->aRef;
2130 if ( nTab >= aRange.aStart.Tab() && nTab <= aRange.aEnd.Tab() )
2131 PaintArea( aRange.aStart.Col(), aRange.aStart.Row(),
2132 aRange.aEnd.Col(), aRange.aEnd.Row(), SC_UPDATE_MARKS );
2135 maHighlightRanges.clear();
2138 void ScTabView::DoChartSelection(
2139 const uno::Sequence< chart2::data::HighlightedRange > & rHilightRanges )
2141 ClearHighlightRanges();
2142 const sal_Unicode sep = ::formula::FormulaCompiler::GetNativeSymbolChar(ocSep);
2144 for( sal_Int32 i=0; i<rHilightRanges.getLength(); ++i )
2146 Color aSelColor( rHilightRanges[i].PreferredColor );
2147 ScRangeList aRangeList;
2148 ScDocument& rDoc = aViewData.GetDocShell()->GetDocument();
2149 if( ScRangeStringConverter::GetRangeListFromString(
2150 aRangeList, rHilightRanges[i].RangeRepresentation, &rDoc, rDoc.GetAddressConvention(), sep ))
2152 size_t nListSize = aRangeList.size();
2153 for ( size_t j = 0; j < nListSize; ++j )
2155 ScRange* p = aRangeList[j];
2156 if( rHilightRanges[i].Index == - 1 )
2157 AddHighlightRange( *p, aSelColor );
2158 else
2159 AddHighlightRange( lcl_getSubRangeByIndex( *p, rHilightRanges[i].Index ), aSelColor );
2165 // PaintGrid - Datenbereiche neu zeichnen
2167 void ScTabView::PaintGrid()
2169 sal_uInt16 i;
2170 for (i=0; i<4; i++)
2171 if (pGridWin[i])
2172 if (pGridWin[i]->IsVisible())
2173 pGridWin[i]->Invalidate();
2176 // PaintTop - obere Kontrollelemente neu zeichnen
2178 void ScTabView::PaintTop()
2180 sal_uInt16 i;
2181 for (i=0; i<2; i++)
2183 if (pColBar[i])
2184 pColBar[i]->Invalidate();
2185 if (pColOutline[i])
2186 pColOutline[i]->Invalidate();
2190 void ScTabView::CreateAnchorHandles(SdrHdlList& rHdl, const ScAddress& rAddress)
2192 sal_uInt16 i;
2194 for(i=0; i<4; i++)
2196 if(pGridWin[i])
2198 if(pGridWin[i]->IsVisible())
2200 pGridWin[i]->CreateAnchorHandle(rHdl, rAddress);
2206 void ScTabView::PaintTopArea( SCCOL nStartCol, SCCOL nEndCol )
2208 // Pixel-Position der linken Kante
2210 if ( nStartCol < aViewData.GetPosX(SC_SPLIT_LEFT) ||
2211 nStartCol < aViewData.GetPosX(SC_SPLIT_RIGHT) )
2212 aViewData.RecalcPixPos();
2214 // Fixierung anpassen (UpdateFixX setzt HSplitPos neu)
2216 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX && nStartCol < aViewData.GetFixPosX() )
2217 if (aViewData.UpdateFixX())
2218 RepeatResize();
2220 // zeichnen
2222 if (nStartCol>0)
2223 --nStartCol; //! allgemeiner ?
2225 bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
2226 long nLayoutSign = bLayoutRTL ? -1 : 1;
2228 for (sal_uInt16 i=0; i<2; i++)
2230 ScHSplitPos eWhich = (ScHSplitPos) i;
2231 if (pColBar[eWhich])
2233 Size aWinSize = pColBar[eWhich]->GetSizePixel();
2234 long nStartX = aViewData.GetScrPos( nStartCol, 0, eWhich ).X();
2235 long nEndX;
2236 if (nEndCol >= MAXCOL)
2237 nEndX = bLayoutRTL ? 0 : ( aWinSize.Width()-1 );
2238 else
2239 nEndX = aViewData.GetScrPos( nEndCol+1, 0, eWhich ).X() - nLayoutSign;
2240 pColBar[eWhich]->Invalidate(
2241 Rectangle( nStartX, 0, nEndX, aWinSize.Height()-1 ) );
2243 if (pColOutline[eWhich])
2244 pColOutline[eWhich]->Invalidate();
2248 // PaintLeft - linke Kontrollelemente neu zeichnen
2250 void ScTabView::PaintLeft()
2252 sal_uInt16 i;
2253 for (i=0; i<2; i++)
2255 if (pRowBar[i])
2256 pRowBar[i]->Invalidate();
2257 if (pRowOutline[i])
2258 pRowOutline[i]->Invalidate();
2262 void ScTabView::PaintLeftArea( SCROW nStartRow, SCROW nEndRow )
2264 // Pixel-Position der oberen Kante
2266 if ( nStartRow < aViewData.GetPosY(SC_SPLIT_TOP) ||
2267 nStartRow < aViewData.GetPosY(SC_SPLIT_BOTTOM) )
2268 aViewData.RecalcPixPos();
2270 // Fixierung anpassen (UpdateFixY setzt VSplitPos neu)
2272 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && nStartRow < aViewData.GetFixPosY() )
2273 if (aViewData.UpdateFixY())
2274 RepeatResize();
2276 // zeichnen
2278 if (nStartRow>0)
2279 --nStartRow;
2281 for (sal_uInt16 i=0; i<2; i++)
2283 ScVSplitPos eWhich = (ScVSplitPos) i;
2284 if (pRowBar[eWhich])
2286 Size aWinSize = pRowBar[eWhich]->GetSizePixel();
2287 long nStartY = aViewData.GetScrPos( 0, nStartRow, eWhich ).Y();
2288 long nEndY;
2289 if (nEndRow >= MAXROW)
2290 nEndY = aWinSize.Height()-1;
2291 else
2292 nEndY = aViewData.GetScrPos( 0, nEndRow+1, eWhich ).Y() - 1;
2293 pRowBar[eWhich]->Invalidate(
2294 Rectangle( 0, nStartY, aWinSize.Width()-1, nEndY ) );
2296 if (pRowOutline[eWhich])
2297 pRowOutline[eWhich]->Invalidate();
2301 bool ScTabView::PaintExtras()
2303 bool bRet = false;
2304 ScDocument* pDoc = aViewData.GetDocument();
2305 SCTAB nTab = aViewData.GetTabNo();
2306 if (!pDoc->HasTable(nTab)) // Tabelle geloescht ?
2308 SCTAB nCount = pDoc->GetTableCount();
2309 aViewData.SetTabNo(nCount-1);
2310 bRet = true;
2312 pTabControl->UpdateStatus(); // true = active
2313 return bRet;
2316 void ScTabView::RecalcPPT()
2318 // called after changes that require the PPT values to be recalculated
2319 // (currently from detective operations)
2321 double nOldX = aViewData.GetPPTX();
2322 double nOldY = aViewData.GetPPTY();
2324 aViewData.RefreshZoom(); // pre-calculate new PPT values
2326 bool bChangedX = ( aViewData.GetPPTX() != nOldX );
2327 bool bChangedY = ( aViewData.GetPPTY() != nOldY );
2328 if ( bChangedX || bChangedY )
2330 // call view SetZoom (including draw scale, split update etc)
2331 // and paint only if values changed
2333 Fraction aZoomX = aViewData.GetZoomX();
2334 Fraction aZoomY = aViewData.GetZoomY();
2335 SetZoom( aZoomX, aZoomY, false );
2337 PaintGrid();
2338 if (bChangedX)
2339 PaintTop();
2340 if (bChangedY)
2341 PaintLeft();
2345 void ScTabView::ActivateView( bool bActivate, bool bFirst )
2347 if ( bActivate == aViewData.IsActive() && !bFirst )
2349 // keine Assertion mehr - kommt vor, wenn vorher im Drag&Drop
2350 // auf ein anderes Dokument umgeschaltet wurde
2351 return;
2354 // wird nur bei MDI-(De)Activate gerufen
2355 // aViewData.Activate hinten wegen Cursor-Show bei KillEditView
2356 // Markierung nicht mehr loeschen - wenn an der ViewData Activate(false) gesetzt ist,
2357 // wird die Markierung nicht ausgegeben
2359 if (!bActivate)
2361 ScModule* pScMod = SC_MOD();
2362 bool bRefMode = pScMod->IsFormulaMode();
2364 // Referenzeingabe nicht abbrechen, um Referenzen auf
2365 // andere Dokumente zuzulassen
2367 if (!bRefMode)
2369 // pass view to GetInputHdl, this view may not be current anymore
2370 ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
2371 if (pHdl)
2372 pHdl->EnterHandler();
2376 PaintExtras();
2378 aViewData.Activate(bActivate);
2380 PaintBlock(false); // Repaint, Markierung je nach Active-Status
2382 if (!bActivate)
2383 HideAllCursors(); // Cursor
2384 else if (!bFirst)
2385 ShowAllCursors();
2387 if (bActivate)
2389 if ( bFirst )
2391 ScSplitPos eWin = aViewData.GetActivePart();
2392 OSL_ENSURE( pGridWin[eWin], "rottes Dokument, nicht alle SplitPos in GridWin" );
2393 if ( !pGridWin[eWin] )
2395 eWin = SC_SPLIT_BOTTOMLEFT;
2396 if ( !pGridWin[eWin] )
2398 short i;
2399 for ( i=0; i<4; i++ )
2401 if ( pGridWin[i] )
2403 eWin = (ScSplitPos) i;
2404 break; // for
2407 OSL_ENSURE( i<4, "und BUMM" );
2409 aViewData.SetActivePart( eWin );
2412 // hier nicht mehr selber GrabFocus rufen!
2413 // Wenn das Doc bearbeitet wird, ruft der Sfx selber GrabFocus am Fenster der Shell.
2414 // Wenn es z.B. ein Mailbody ist, darf es den Focus nicht bekommen (Bug #43638#)
2416 UpdateInputContext();
2418 else
2419 pGridWin[aViewData.GetActivePart()]->ClickExtern();
2422 void ScTabView::ActivatePart( ScSplitPos eWhich )
2424 ScSplitPos eOld = aViewData.GetActivePart();
2425 if ( eOld != eWhich )
2427 bInActivatePart = true;
2429 bool bRefMode = SC_MOD()->IsFormulaMode();
2431 // the HasEditView call during SetCursor would fail otherwise
2432 if ( aViewData.HasEditView(eOld) && !bRefMode )
2433 UpdateInputLine();
2435 ScHSplitPos eOldH = WhichH(eOld);
2436 ScVSplitPos eOldV = WhichV(eOld);
2437 ScHSplitPos eNewH = WhichH(eWhich);
2438 ScVSplitPos eNewV = WhichV(eWhich);
2439 bool bTopCap = pColBar[eOldH] && pColBar[eOldH]->IsMouseCaptured();
2440 bool bLeftCap = pRowBar[eOldV] && pRowBar[eOldV]->IsMouseCaptured();
2442 bool bFocus = pGridWin[eOld]->HasFocus();
2443 bool bCapture = pGridWin[eOld]->IsMouseCaptured();
2444 if (bCapture)
2445 pGridWin[eOld]->ReleaseMouse();
2446 pGridWin[eOld]->ClickExtern();
2447 pGridWin[eOld]->HideCursor();
2448 pGridWin[eWhich]->HideCursor();
2449 aViewData.SetActivePart( eWhich );
2451 ScTabViewShell* pShell = aViewData.GetViewShell();
2452 pShell->WindowChanged();
2454 pSelEngine->SetWindow(pGridWin[eWhich]);
2455 pSelEngine->SetWhich(eWhich);
2456 pSelEngine->SetVisibleArea( Rectangle(Point(), pGridWin[eWhich]->GetOutputSizePixel()) );
2458 pGridWin[eOld]->MoveMouseStatus(*pGridWin[eWhich]);
2460 if ( bCapture || pGridWin[eWhich]->IsMouseCaptured() )
2462 // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
2463 // (SelectionEngine ruft CaptureMouse beim SetWindow)
2464 //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
2465 pGridWin[eWhich]->ReleaseMouse();
2466 pGridWin[eWhich]->StartTracking();
2469 if ( bTopCap && pColBar[eNewH] )
2471 pColBar[eOldH]->SetIgnoreMove(true);
2472 pColBar[eNewH]->SetIgnoreMove(false);
2473 pHdrSelEng->SetWindow( pColBar[eNewH] );
2474 long nWidth = pColBar[eNewH]->GetOutputSizePixel().Width();
2475 pHdrSelEng->SetVisibleArea( Rectangle( 0, LONG_MIN, nWidth-1, LONG_MAX ) );
2476 pColBar[eNewH]->CaptureMouse();
2478 if ( bLeftCap && pRowBar[eNewV] )
2480 pRowBar[eOldV]->SetIgnoreMove(true);
2481 pRowBar[eNewV]->SetIgnoreMove(false);
2482 pHdrSelEng->SetWindow( pRowBar[eNewV] );
2483 long nHeight = pRowBar[eNewV]->GetOutputSizePixel().Height();
2484 pHdrSelEng->SetVisibleArea( Rectangle( LONG_MIN, 0, LONG_MAX, nHeight-1 ) );
2485 pRowBar[eNewV]->CaptureMouse();
2487 aHdrFunc.SetWhich(eWhich);
2489 pGridWin[eOld]->ShowCursor();
2490 pGridWin[eWhich]->ShowCursor();
2492 SfxInPlaceClient* pClient = aViewData.GetViewShell()->GetIPClient();
2493 bool bOleActive = ( pClient && pClient->IsObjectInPlaceActive() );
2495 // don't switch ViewShell's active window during RefInput, because the focus
2496 // might change, and subsequent SetReference calls wouldn't find the right EditView
2497 if ( !bRefMode && !bOleActive )
2498 aViewData.GetViewShell()->SetWindow( pGridWin[eWhich] );
2500 if ( bFocus && !aViewData.IsAnyFillMode() && !bRefMode )
2502 // GrabFocus nur, wenn vorher das andere GridWindow den Focus hatte
2503 // (z.B. wegen Suchen & Ersetzen)
2504 pGridWin[eWhich]->GrabFocus();
2507 bInActivatePart = false;
2511 void ScTabView::HideListBox()
2513 for (sal_uInt16 i=0; i<4; i++)
2514 if (pGridWin[i])
2515 pGridWin[i]->ClickExtern();
2518 void ScTabView::UpdateInputContext()
2520 ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2521 if (pWin)
2522 pWin->UpdateInputContext();
2524 if (pTabControl)
2525 pTabControl->UpdateInputContext();
2528 // GetGridWidth - Breite eines Ausgabebereichs (fuer ViewData)
2530 long ScTabView::GetGridWidth( ScHSplitPos eWhich )
2532 ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_LEFT ) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
2533 if (pGridWin[eGridWhich])
2534 return pGridWin[eGridWhich]->GetSizePixel().Width();
2535 else
2536 return 0;
2539 // GetGridHeight - Hoehe eines Ausgabebereichs (fuer ViewData)
2541 long ScTabView::GetGridHeight( ScVSplitPos eWhich )
2543 ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_TOP ) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
2544 if (pGridWin[eGridWhich])
2545 return pGridWin[eGridWhich]->GetSizePixel().Height();
2546 else
2547 return 0;
2550 void ScTabView::UpdateInputLine()
2552 SC_MOD()->InputEnterHandler();
2555 void ScTabView::ZoomChanged()
2557 ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
2558 if (pHdl)
2559 pHdl->SetRefScale( aViewData.GetZoomX(), aViewData.GetZoomY() );
2561 UpdateFixPos();
2563 UpdateScrollBars();
2565 // VisArea...
2566 // AW: Discussed with NN if there is a reason that new map mode was only set for one window,
2567 // but is not. Setting only on one window causes the first repaint to have the old mapMode
2568 // in three of four views, so the overlay will save the wrong content e.g. when zooming out.
2569 // Changing to setting map mode at all windows.
2570 sal_uInt32 a;
2572 for(a = 0L; a < 4L; a++)
2574 if(pGridWin[a])
2576 pGridWin[a]->SetMapMode(pGridWin[a]->GetDrawMapMode());
2580 SetNewVisArea();
2582 InterpretVisible(); // have everything calculated before painting
2584 SfxBindings& rBindings = aViewData.GetBindings();
2585 rBindings.Invalidate( SID_ATTR_ZOOM );
2586 rBindings.Invalidate( SID_ATTR_ZOOMSLIDER );
2588 HideNoteMarker();
2590 // AW: To not change too much, use pWin here
2591 ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2593 if ( pWin && aViewData.HasEditView( aViewData.GetActivePart() ) )
2595 // flush OverlayManager before changing the MapMode
2596 pWin->flushOverlayManager();
2598 // make sure the EditView's position and size are updated
2599 // with the right (logic, not drawing) MapMode
2600 pWin->SetMapMode( aViewData.GetLogicMode() );
2601 UpdateEditView();
2605 void ScTabView::CheckNeedsRepaint()
2607 sal_uInt16 i;
2608 for (i=0; i<4; i++)
2609 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
2610 pGridWin[i]->CheckNeedsRepaint();
2613 bool ScTabView::NeedsRepaint()
2615 for (size_t i = 0; i < 4; i++)
2616 if (pGridWin[i] && pGridWin[i]->IsVisible() && pGridWin[i]->NeedsRepaint())
2617 return true;
2618 return false;
2621 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */