Update ooo320-m1
[ooovba.git] / sc / source / ui / view / tabview3.cxx
blobc1d84e56bed831d95bbc21ca8b552cb1f390c761
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tabview3.cxx,v $
10 * $Revision: 1.69.40.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 // System - Includes -----------------------------------------------------
38 // INCLUDE ---------------------------------------------------------------
39 #include <rangelst.hxx>
40 #include "scitems.hxx"
41 #include <svx/eeitem.hxx>
44 #include <svx/brshitem.hxx>
45 #include <svx/editview.hxx>
46 #include <svx/fmshell.hxx>
47 #include <svx/svdoole2.hxx>
48 #include <sfx2/bindings.hxx>
49 #include <sfx2/viewfrm.hxx>
50 #include <vcl/cursor.hxx>
52 #include "tabview.hxx"
53 #include "tabvwsh.hxx"
54 #include "docsh.hxx"
55 #include "gridwin.hxx"
56 #include "olinewin.hxx"
57 #include "colrowba.hxx"
58 #include "tabcont.hxx"
59 #include "scmod.hxx"
60 #include "uiitems.hxx"
61 #include "sc.hrc"
62 #include "viewutil.hxx"
63 #include "editutil.hxx"
64 #include "inputhdl.hxx"
65 #include "inputwin.hxx"
66 #include "validat.hxx"
67 #include "hintwin.hxx"
68 #include "inputopt.hxx"
69 #include "rfindlst.hxx"
70 #include "hiranges.hxx"
71 #include "viewuno.hxx"
72 #include "chartarr.hxx"
73 #include "anyrefdg.hxx"
74 #include "dpobject.hxx"
75 #include "patattr.hxx"
76 #include "dociter.hxx"
77 #include "seltrans.hxx"
78 #include "fillinfo.hxx"
79 #include "AccessibilityHints.hxx"
80 #include "rangeutl.hxx"
81 #include "client.hxx"
82 #include "tabprotection.hxx"
84 #include <com/sun/star/chart2/data/HighlightedRange.hpp>
85 #include <com/sun/star/document/XVbaEventsHelper.hpp>
86 #include <com/sun/star/document/VbaEventId.hpp>
88 using namespace com::sun::star::document::VbaEventId;
90 namespace
93 ScRange lcl_getSubRangeByIndex( const ScRange& rRange, sal_Int32 nIndex )
95 ScAddress aResult( rRange.aStart );
97 SCCOL nWidth = rRange.aEnd.Col() - rRange.aStart.Col() + 1;
98 SCROW nHeight = rRange.aEnd.Row() - rRange.aStart.Row() + 1;
99 SCTAB nDepth = rRange.aEnd.Tab() - rRange.aStart.Tab() + 1;
100 if( (nWidth > 0) && (nHeight > 0) && (nDepth > 0) )
102 // row by row from first to last sheet
103 sal_Int32 nArea = nWidth * nHeight;
104 aResult.IncCol( static_cast< SCsCOL >( nIndex % nWidth ) );
105 aResult.IncRow( static_cast< SCsROW >( (nIndex % nArea) / nWidth ) );
106 aResult.IncTab( static_cast< SCsTAB >( nIndex / nArea ) );
107 if( !rRange.In( aResult ) )
108 aResult = rRange.aStart;
111 return ScRange( aResult );
114 } // anonymous namespace
116 using namespace com::sun::star;
118 // -----------------------------------------------------------------------
121 // --- Public-Funktionen
124 void ScTabView::ClickCursor( SCCOL nPosX, SCROW nPosY, BOOL bControl )
126 ScDocument* pDoc = aViewData.GetDocument();
127 SCTAB nTab = aViewData.GetTabNo();
128 pDoc->SkipOverlapped(nPosX, nPosY, nTab);
130 BOOL bRefMode = SC_MOD()->IsFormulaMode();
132 if ( bRefMode )
134 DoneRefMode( FALSE );
136 if (bControl)
137 SC_MOD()->AddRefEntry();
139 InitRefMode( nPosX, nPosY, nTab, SC_REFTYPE_REF );
141 else
143 DoneBlockMode( bControl );
144 aViewData.ResetOldCursor();
145 SetCursor( (SCCOL) nPosX, (SCROW) nPosY );
149 void ScTabView::UpdateAutoFillMark()
151 // single selection or cursor
152 ScRange aMarkRange;
153 BOOL bMarked = (aViewData.GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE);
155 USHORT i;
156 for (i=0; i<4; i++)
157 if (pGridWin[i] && pGridWin[i]->IsVisible())
158 pGridWin[i]->UpdateAutoFillMark( bMarked, aMarkRange );
160 for (i=0; i<2; i++)
162 if (pColBar[i] && pColBar[i]->IsVisible())
163 pColBar[i]->SetMark( bMarked, aMarkRange.aStart.Col(), aMarkRange.aEnd.Col() );
164 if (pRowBar[i] && pRowBar[i]->IsVisible())
165 pRowBar[i]->SetMark( bMarked, aMarkRange.aStart.Row(), aMarkRange.aEnd.Row() );
168 // selection transfer object is checked together with AutoFill marks,
169 // because it has the same requirement of a single continuous block.
170 CheckSelectionTransfer(); // update selection transfer object
173 void ScTabView::FakeButtonUp( ScSplitPos eWhich )
175 if (pGridWin[eWhich])
176 pGridWin[eWhich]->FakeButtonUp();
179 void ScTabView::HideAllCursors()
181 for (USHORT i=0; i<4; i++)
182 if (pGridWin[i])
183 if (pGridWin[i]->IsVisible())
185 Cursor* pCur = pGridWin[i]->GetCursor();
186 if (pCur)
187 if (pCur->IsVisible())
188 pCur->Hide();
189 pGridWin[i]->HideCursor();
193 void ScTabView::ShowAllCursors()
195 for (USHORT i=0; i<4; i++)
196 if (pGridWin[i])
197 if (pGridWin[i]->IsVisible())
199 pGridWin[i]->ShowCursor();
201 // #114409#
202 pGridWin[i]->CursorChanged();
206 void ScTabView::HideCursor()
208 pGridWin[aViewData.GetActivePart()]->HideCursor();
211 void ScTabView::ShowCursor()
213 pGridWin[aViewData.GetActivePart()]->ShowCursor();
215 // #114409#
216 pGridWin[aViewData.GetActivePart()]->CursorChanged();
219 void ScTabView::InvalidateAttribs()
221 SfxBindings& rBindings = aViewData.GetBindings();
223 rBindings.Invalidate( SID_STYLE_APPLY );
224 rBindings.Invalidate( SID_STYLE_FAMILY2 );
225 // StarCalc kennt nur Absatz- bzw. Zellformat-Vorlagen
227 rBindings.Invalidate( SID_ATTR_CHAR_FONT );
228 rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
229 rBindings.Invalidate( SID_ATTR_CHAR_COLOR );
231 rBindings.Invalidate( SID_ATTR_CHAR_WEIGHT );
232 rBindings.Invalidate( SID_ATTR_CHAR_POSTURE );
233 rBindings.Invalidate( SID_ATTR_CHAR_UNDERLINE );
234 rBindings.Invalidate( SID_ULINE_VAL_NONE );
235 rBindings.Invalidate( SID_ULINE_VAL_SINGLE );
236 rBindings.Invalidate( SID_ULINE_VAL_DOUBLE );
237 rBindings.Invalidate( SID_ULINE_VAL_DOTTED );
239 rBindings.Invalidate( SID_ATTR_CHAR_OVERLINE );
241 rBindings.Invalidate( SID_ALIGNLEFT );
242 rBindings.Invalidate( SID_ALIGNRIGHT );
243 rBindings.Invalidate( SID_ALIGNBLOCK );
244 rBindings.Invalidate( SID_ALIGNCENTERHOR );
246 rBindings.Invalidate( SID_ALIGNTOP );
247 rBindings.Invalidate( SID_ALIGNBOTTOM );
248 rBindings.Invalidate( SID_ALIGNCENTERVER );
250 rBindings.Invalidate( SID_BACKGROUND_COLOR );
252 rBindings.Invalidate( SID_ATTR_ALIGN_LINEBREAK );
253 rBindings.Invalidate( SID_NUMBER_FORMAT );
255 rBindings.Invalidate( SID_TEXTDIRECTION_LEFT_TO_RIGHT );
256 rBindings.Invalidate( SID_TEXTDIRECTION_TOP_TO_BOTTOM );
257 rBindings.Invalidate( SID_ATTR_PARA_LEFT_TO_RIGHT );
258 rBindings.Invalidate( SID_ATTR_PARA_RIGHT_TO_LEFT );
260 // pseudo slots for Format menu
261 rBindings.Invalidate( SID_ALIGN_ANY_HDEFAULT );
262 rBindings.Invalidate( SID_ALIGN_ANY_LEFT );
263 rBindings.Invalidate( SID_ALIGN_ANY_HCENTER );
264 rBindings.Invalidate( SID_ALIGN_ANY_RIGHT );
265 rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED );
266 rBindings.Invalidate( SID_ALIGN_ANY_VDEFAULT );
267 rBindings.Invalidate( SID_ALIGN_ANY_TOP );
268 rBindings.Invalidate( SID_ALIGN_ANY_VCENTER );
269 rBindings.Invalidate( SID_ALIGN_ANY_BOTTOM );
271 rBindings.Invalidate( SID_NUMBER_CURRENCY );
272 rBindings.Invalidate( SID_NUMBER_SCIENTIFIC );
273 rBindings.Invalidate( SID_NUMBER_DATE );
274 rBindings.Invalidate( SID_NUMBER_CURRENCY );
275 rBindings.Invalidate( SID_NUMBER_PERCENT );
276 rBindings.Invalidate( SID_NUMBER_TIME );
278 // rBindings.Invalidate( SID_RANGE_VALUE );
279 // rBindings.Invalidate( SID_RANGE_FORMULA );
282 // SetCursor - Cursor setzen, zeichnen, InputWin updaten
283 // oder Referenz verschicken
284 // ohne Optimierung wegen BugId 29307
286 #ifdef _MSC_VER
287 #pragma optimize ( "", off )
288 #endif
290 void ScTabView::SetCursor( SCCOL nPosX, SCROW nPosY, BOOL bNew )
292 SCCOL nOldX = aViewData.GetCurX();
293 SCROW nOldY = aViewData.GetCurY();
295 // DeactivateIP nur noch bei MarkListHasChanged
297 if ( nPosX != nOldX || nPosY != nOldY || bNew )
299 ScTabViewShell* pViewShell = aViewData.GetViewShell();
300 bool bRefMode = ( pViewShell ? pViewShell->IsRefInputMode() : false );
301 if ( aViewData.HasEditView( aViewData.GetActivePart() ) && !bRefMode ) // 23259 oder so
303 UpdateInputLine();
306 HideAllCursors();
308 aViewData.SetCurX( nPosX );
309 aViewData.SetCurY( nPosY );
311 ShowAllCursors();
313 CursorPosChanged();
317 #ifdef _MSC_VER
318 #pragma optimize ( "", on )
319 #endif
321 void ScTabView::CheckSelectionTransfer()
323 if ( aViewData.IsActive() ) // only for active view
325 ScModule* pScMod = SC_MOD();
326 ScSelectionTransferObj* pOld = pScMod->GetSelectionTransfer();
327 if ( pOld && pOld->GetView() == this && pOld->StillValid() )
329 // selection not changed - nothing to do
331 else
333 ScSelectionTransferObj* pNew = ScSelectionTransferObj::CreateFromView( this );
334 if ( pNew )
336 // create new selection
338 if (pOld)
339 pOld->ForgetView();
341 uno::Reference<datatransfer::XTransferable> xRef( pNew );
342 pScMod->SetSelectionTransfer( pNew );
343 pNew->CopyToSelection( GetActiveWin() ); // may delete pOld
345 else if ( pOld && pOld->GetView() == this )
347 // remove own selection
349 pOld->ForgetView();
350 pScMod->SetSelectionTransfer( NULL );
351 TransferableHelper::ClearSelection( GetActiveWin() ); // may delete pOld
353 // else: selection from outside: leave unchanged
358 // Eingabezeile / Menues updaten
359 // CursorPosChanged ruft SelectionChanged
360 // SelectionChanged ruft CellContentChanged
362 void ScTabView::CellContentChanged()
364 SfxBindings& rBindings = aViewData.GetBindings();
366 rBindings.Invalidate( SID_ATTR_SIZE ); // -> Fehlermeldungen anzeigen
367 rBindings.Invalidate( SID_THESAURUS );
368 rBindings.Invalidate( SID_HYPERLINK_GETLINK );
370 InvalidateAttribs(); // Attribut-Updates
371 TestHintWindow(); // Eingabemeldung (Gueltigkeit)
373 aViewData.GetViewShell()->UpdateInputHandler();
376 void ScTabView::SelectionChanged()
378 SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
379 if (pViewFrame)
381 SfxFrame* pFrame = pViewFrame->GetFrame();
382 if (pFrame)
384 uno::Reference<frame::XController> xController = pFrame->GetController();
385 if (xController.is())
387 ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
388 if (pImp)
389 pImp->SelectionChanged();
394 UpdateAutoFillMark(); // also calls CheckSelectionTransfer
396 SfxBindings& rBindings = aViewData.GetBindings();
398 rBindings.Invalidate( SID_CURRENTCELL ); // -> Navigator
399 rBindings.Invalidate( SID_AUTO_FILTER ); // -> Menue
400 rBindings.Invalidate( FID_NOTE_VISIBLE );
401 rBindings.Invalidate( SID_DELETE_NOTE );
403 // Funktionen, die evtl disabled werden muessen
405 rBindings.Invalidate( FID_INS_ROWBRK );
406 rBindings.Invalidate( FID_INS_COLBRK );
407 rBindings.Invalidate( FID_DEL_ROWBRK );
408 rBindings.Invalidate( FID_DEL_COLBRK );
409 rBindings.Invalidate( FID_MERGE_ON );
410 rBindings.Invalidate( FID_MERGE_OFF );
411 rBindings.Invalidate( FID_MERGE_TOGGLE );
412 rBindings.Invalidate( SID_AUTOFILTER_HIDE );
413 rBindings.Invalidate( SID_UNFILTER );
414 // rBindings.Invalidate( SID_IMPORT_DATA ); // jetzt wieder immer moeglich
415 rBindings.Invalidate( SID_REIMPORT_DATA );
416 rBindings.Invalidate( SID_REFRESH_DBAREA );
417 rBindings.Invalidate( SID_OUTLINE_SHOW );
418 rBindings.Invalidate( SID_OUTLINE_HIDE );
419 rBindings.Invalidate( SID_OUTLINE_REMOVE );
420 rBindings.Invalidate( FID_FILL_TO_BOTTOM );
421 rBindings.Invalidate( FID_FILL_TO_RIGHT );
422 rBindings.Invalidate( FID_FILL_TO_TOP );
423 rBindings.Invalidate( FID_FILL_TO_LEFT );
424 rBindings.Invalidate( FID_FILL_SERIES );
425 rBindings.Invalidate( SID_SCENARIOS );
426 rBindings.Invalidate( SID_AUTOFORMAT );
427 rBindings.Invalidate( SID_OPENDLG_TABOP );
428 rBindings.Invalidate( SID_DATA_SELECT );
430 rBindings.Invalidate( SID_CUT );
431 rBindings.Invalidate( SID_COPY );
432 rBindings.Invalidate( SID_PASTE );
433 rBindings.Invalidate( SID_PASTE_SPECIAL );
435 rBindings.Invalidate( FID_INS_ROW );
436 rBindings.Invalidate( FID_INS_COLUMN );
437 rBindings.Invalidate( FID_INS_CELL );
438 rBindings.Invalidate( FID_INS_CELLSDOWN );
439 rBindings.Invalidate( FID_INS_CELLSRIGHT );
441 rBindings.Invalidate( FID_CHG_COMMENT );
443 // nur wegen Zellschutz:
445 rBindings.Invalidate( SID_CELL_FORMAT_RESET );
446 rBindings.Invalidate( SID_DELETE );
447 rBindings.Invalidate( SID_DELETE_CONTENTS );
448 rBindings.Invalidate( FID_DELETE_CELL );
449 rBindings.Invalidate( FID_CELL_FORMAT );
450 rBindings.Invalidate( SID_ENABLE_HYPHENATION );
451 rBindings.Invalidate( SID_INSERT_POSTIT );
452 rBindings.Invalidate( SID_CHARMAP );
453 rBindings.Invalidate( SID_OPENDLG_FUNCTION );
454 // rBindings.Invalidate( FID_CONDITIONAL_FORMAT );
455 rBindings.Invalidate( SID_OPENDLG_CONDFRMT );
456 rBindings.Invalidate( FID_VALIDATION );
457 rBindings.Invalidate( SID_EXTERNAL_SOURCE );
458 rBindings.Invalidate( SID_TEXT_TO_COLUMNS );
459 rBindings.Invalidate( SID_SORT_ASCENDING );
460 rBindings.Invalidate( SID_SORT_DESCENDING );
462 if (aViewData.GetViewShell()->HasAccessibilityObjects())
463 aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_CURSORCHANGED));
465 CellContentChanged();
468 void ScTabView::CursorPosChanged()
470 BOOL bRefMode = SC_MOD()->IsFormulaMode();
471 if ( !bRefMode ) // Abfrage, damit RefMode bei Tabellenwechsel funktioniert
472 aViewData.GetDocShell()->Broadcast( SfxSimpleHint( FID_KILLEDITVIEW ) );
474 // Broadcast, damit andere Views des Dokuments auch umschalten
476 ScDocument* pDoc = aViewData.GetDocument();
477 bool bDP = NULL != pDoc->GetDPAtCursor(
478 aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
479 aViewData.GetViewShell()->SetPivotShell(bDP);
481 // UpdateInputHandler jetzt in CellContentChanged
483 SelectionChanged();
485 aViewData.SetTabStartCol( SC_TABSTART_NONE );
488 void ScTabView::TestHintWindow()
490 // show input help window and list drop-down button for validity
492 BOOL bListValButton = FALSE;
493 ScAddress aListValPos;
495 ScDocument* pDoc = aViewData.GetDocument();
496 const SfxUInt32Item* pItem = (const SfxUInt32Item*)
497 pDoc->GetAttr( aViewData.GetCurX(),
498 aViewData.GetCurY(),
499 aViewData.GetTabNo(),
500 ATTR_VALIDDATA );
501 if ( pItem->GetValue() )
503 const ScValidationData* pData = pDoc->GetValidationEntry( pItem->GetValue() );
504 DBG_ASSERT(pData,"ValidationData nicht gefunden");
505 String aTitle, aMessage;
506 if ( pData && pData->GetInput( aTitle, aMessage ) && aMessage.Len() > 0 )
508 //! Abfrage, ob an gleicher Stelle !!!!
510 DELETEZ(pInputHintWindow);
512 ScSplitPos eWhich = aViewData.GetActivePart();
513 Window* pWin = pGridWin[eWhich];
514 SCCOL nCol = aViewData.GetCurX();
515 SCROW nRow = aViewData.GetCurY();
516 Point aPos = aViewData.GetScrPos( nCol, nRow, eWhich );
517 Size aWinSize = pWin->GetOutputSizePixel();
518 // Cursor sichtbar?
519 if ( nCol >= aViewData.GetPosX(WhichH(eWhich)) &&
520 nRow >= aViewData.GetPosY(WhichV(eWhich)) &&
521 aPos.X() < aWinSize.Width() && aPos.Y() < aWinSize.Height() )
523 aPos += pWin->GetPosPixel(); // Position auf Frame
524 long nSizeXPix;
525 long nSizeYPix;
526 aViewData.GetMergeSizePixel( nCol, nRow, nSizeXPix, nSizeYPix );
528 // HintWindow anlegen, bestimmt seine Groesse selbst
529 pInputHintWindow = new ScHintWindow( pFrameWin, aTitle, aMessage );
530 Size aHintSize = pInputHintWindow->GetSizePixel();
531 Size aFrameWinSize = pFrameWin->GetOutputSizePixel();
533 // passende Position finden
534 // erster Versuch: unter dem Cursor
535 Point aHintPos( aPos.X() + nSizeXPix / 2, aPos.Y() + nSizeYPix + 3 );
536 if ( aHintPos.Y() + aHintSize.Height() > aFrameWinSize.Height() )
538 // zweiter Versuch: rechts vom Cursor
539 aHintPos = Point( aPos.X() + nSizeXPix + 3, aPos.Y() + nSizeYPix / 2 );
540 if ( aHintPos.X() + aHintSize.Width() > aFrameWinSize.Width() )
542 // dritter Versuch: ueber dem Cursor
543 aHintPos = Point( aPos.X() + nSizeXPix / 2,
544 aPos.Y() - aHintSize.Height() - 3 );
545 if ( aHintPos.Y() < 0 )
547 // oben und unten kein Platz - dann Default und abschneiden
548 aHintPos = Point( aPos.X() + nSizeXPix / 2, aPos.Y() + nSizeYPix + 3 );
549 aHintSize.Height() = aFrameWinSize.Height() - aHintPos.Y();
550 pInputHintWindow->SetSizePixel( aHintSize );
555 // X anpassen
556 if ( aHintPos.X() + aHintSize.Width() > aFrameWinSize.Width() )
557 aHintPos.X() = aFrameWinSize.Width() - aHintSize.Width();
558 // Y anpassen
559 if ( aHintPos.Y() + aHintSize.Height() > aFrameWinSize.Height() )
560 aHintPos.Y() = aFrameWinSize.Height() - aHintSize.Height();
562 pInputHintWindow->SetPosPixel( aHintPos );
563 pInputHintWindow->ToTop();
564 pInputHintWindow->Show();
567 else
568 DELETEZ(pInputHintWindow);
570 // list drop-down button
571 if ( pData && pData->HasSelectionList() )
573 aListValPos.Set( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
574 bListValButton = TRUE;
577 else
578 DELETEZ(pInputHintWindow);
580 for ( USHORT i=0; i<4; i++ )
581 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
582 pGridWin[i]->UpdateListValPos( bListValButton, aListValPos );
585 void ScTabView::RemoveHintWindow()
587 DELETEZ(pInputHintWindow);
591 // find window that should not be over the cursor
592 Window* lcl_GetCareWin(SfxViewFrame* pViewFrm)
594 //! auch Spelling ??? (dann beim Aufruf Membervariable setzen)
596 // Suchen & Ersetzen
597 if ( pViewFrm->HasChildWindow(SID_SEARCH_DLG) )
599 SfxChildWindow* pChild = pViewFrm->GetChildWindow(SID_SEARCH_DLG);
600 if (pChild)
602 Window* pWin = pChild->GetWindow();
603 if (pWin && pWin->IsVisible())
604 return pWin;
608 // Aenderungen uebernehmen
609 if ( pViewFrm->HasChildWindow(FID_CHG_ACCEPT) )
611 SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_CHG_ACCEPT);
612 if (pChild)
614 Window* pWin = pChild->GetWindow();
615 if (pWin && pWin->IsVisible())
616 return pWin;
620 return NULL;
624 // Bildschirm an Cursorposition anpassen
627 void ScTabView::AlignToCursor( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
628 const ScSplitPos* pWhich )
631 // aktiven Teil umschalten jetzt hier
634 ScSplitPos eActive = aViewData.GetActivePart();
635 ScHSplitPos eActiveX = WhichH(eActive);
636 ScVSplitPos eActiveY = WhichV(eActive);
637 BOOL bHFix = (aViewData.GetHSplitMode() == SC_SPLIT_FIX);
638 BOOL bVFix = (aViewData.GetVSplitMode() == SC_SPLIT_FIX);
639 if (bHFix)
640 if (eActiveX == SC_SPLIT_LEFT && nCurX >= (SCsCOL)aViewData.GetFixPosX())
642 ActivatePart( (eActiveY==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT );
643 eActiveX = SC_SPLIT_RIGHT;
645 if (bVFix)
646 if (eActiveY == SC_SPLIT_TOP && nCurY >= (SCsROW)aViewData.GetFixPosY())
648 ActivatePart( (eActiveX==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
649 eActiveY = SC_SPLIT_BOTTOM;
653 // eigentliches Align
656 if ( eMode != SC_FOLLOW_NONE )
658 ScSplitPos eAlign;
659 if (pWhich)
660 eAlign = *pWhich;
661 else
662 eAlign = aViewData.GetActivePart();
663 ScHSplitPos eAlignX = WhichH(eAlign);
664 ScVSplitPos eAlignY = WhichV(eAlign);
666 SCsCOL nDeltaX = (SCsCOL) aViewData.GetPosX(eAlignX);
667 SCsROW nDeltaY = (SCsROW) aViewData.GetPosY(eAlignY);
668 SCsCOL nSizeX = (SCsCOL) aViewData.VisibleCellsX(eAlignX);
669 SCsROW nSizeY = (SCsROW) aViewData.VisibleCellsY(eAlignY);
671 long nCellSizeX;
672 long nCellSizeY;
673 if ( nCurX >= 0 && nCurY >= 0 )
674 aViewData.GetMergeSizePixel( (SCCOL)nCurX, (SCROW)nCurY, nCellSizeX, nCellSizeY );
675 else
676 nCellSizeX = nCellSizeY = 0;
677 Size aScrSize = aViewData.GetScrSize();
678 long nSpaceX = ( aScrSize.Width() - nCellSizeX ) / 2;
679 long nSpaceY = ( aScrSize.Height() - nCellSizeY ) / 2;
680 // nSpaceY: desired start position of cell for FOLLOW_JUMP, modified if dialog interferes
682 BOOL bForceNew = FALSE; // force new calculation of JUMP position (vertical only)
684 // VisibleCellsY == CellsAtY( GetPosY( eWhichY ), 1, eWhichY )
686 //-------------------------------------------------------------------------------
687 // falls z.B. Suchen-Dialog offen ist, Cursor nicht hinter den Dialog stellen
688 // wenn moeglich, die Zeile mit dem Cursor oberhalb oder unterhalb des Dialogs
690 //! nicht, wenn schon komplett sichtbar
692 if ( eMode == SC_FOLLOW_JUMP )
694 Window* pCare = lcl_GetCareWin( aViewData.GetViewShell()->GetViewFrame() );
695 if (pCare)
697 BOOL bLimit = FALSE;
698 Rectangle aDlgPixel;
699 Size aWinSize;
700 Window* pWin = GetActiveWin();
701 if (pWin)
703 aDlgPixel = pCare->GetWindowExtentsRelative( pWin );
704 aWinSize = pWin->GetOutputSizePixel();
705 // ueberdeckt der Dialog das GridWin?
706 if ( aDlgPixel.Right() >= 0 && aDlgPixel.Left() < aWinSize.Width() )
708 if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX ||
709 nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY )
710 bLimit = TRUE; // es wird sowieso gescrollt
711 else
713 // Cursor ist auf dem Bildschirm
714 Point aStart = aViewData.GetScrPos( nCurX, nCurY, eAlign );
715 long nCSX, nCSY;
716 aViewData.GetMergeSizePixel( nCurX, nCurY, nCSX, nCSY );
717 Rectangle aCursor( aStart, Size( nCSX, nCSY ) );
718 if ( aCursor.IsOver( aDlgPixel ) )
719 bLimit = TRUE; // Zelle vom Dialog ueberdeckt
724 if (bLimit)
726 BOOL bBottom = FALSE;
727 long nTopSpace = aDlgPixel.Top();
728 long nBotSpace = aWinSize.Height() - aDlgPixel.Bottom();
729 if ( nBotSpace > 0 && nBotSpace > nTopSpace )
731 long nDlgBot = aDlgPixel.Bottom();
732 SCsCOL nWPosX;
733 SCsROW nWPosY;
734 aViewData.GetPosFromPixel( 0,nDlgBot, eAlign, nWPosX, nWPosY );
735 ++nWPosY; // unter der letzten betroffenen Zelle
737 SCsROW nDiff = nWPosY - nDeltaY;
738 if ( nCurY >= nDiff ) // Pos. kann nicht negativ werden
740 nSpaceY = nDlgBot + ( nBotSpace - nCellSizeY ) / 2;
741 bBottom = TRUE;
742 bForceNew = TRUE;
745 if ( !bBottom && nTopSpace > 0 )
747 nSpaceY = ( nTopSpace - nCellSizeY ) / 2;
748 bForceNew = TRUE;
753 //-------------------------------------------------------------------------------
755 SCsCOL nNewDeltaX = nDeltaX;
756 SCsROW nNewDeltaY = nDeltaY;
757 BOOL bDoLine = FALSE;
759 switch (eMode)
761 case SC_FOLLOW_JUMP:
762 if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
764 nNewDeltaX = nCurX - static_cast<SCsCOL>(aViewData.CellsAtX( nCurX, -1, eAlignX, static_cast<USHORT>(nSpaceX) ));
765 if (nNewDeltaX < 0) nNewDeltaX = 0;
766 nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
768 if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY || bForceNew )
770 nNewDeltaY = nCurY - static_cast<SCsROW>(aViewData.CellsAtY( nCurY, -1, eAlignY, static_cast<USHORT>(nSpaceY) ));
771 if (nNewDeltaY < 0) nNewDeltaY = 0;
772 nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
774 bDoLine = TRUE;
775 break;
777 case SC_FOLLOW_LINE:
778 bDoLine = TRUE;
779 break;
781 case SC_FOLLOW_FIX:
782 if ( nCurX < nDeltaX || nCurX >= nDeltaX+nSizeX )
784 nNewDeltaX = nDeltaX + nCurX - aViewData.GetCurX();
785 nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
787 if ( nCurY < nDeltaY || nCurY >= nDeltaY+nSizeY )
789 nNewDeltaY = nDeltaY + nCurY - aViewData.GetCurY();
790 nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
793 // like old version of SC_FOLLOW_JUMP:
795 if ( nCurX < nNewDeltaX || nCurX >= nNewDeltaX+nSizeX )
797 nNewDeltaX = nCurX - (nSizeX / 2);
798 if (nNewDeltaX < 0) nNewDeltaY = 0;
799 nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
801 if ( nCurY < nNewDeltaY || nCurY >= nNewDeltaY+nSizeY )
803 nNewDeltaY = nCurY - (nSizeY / 2);
804 if (nNewDeltaY < 0) nNewDeltaY = 0;
805 nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
808 bDoLine = TRUE;
809 break;
811 case SC_FOLLOW_NONE:
812 break;
813 default:
814 DBG_ERROR("Falscher Cursormodus");
815 break;
818 if (bDoLine)
820 while ( nCurX >= nNewDeltaX+nSizeX )
822 nNewDeltaX = nCurX-nSizeX+1;
823 ScDocument* pDoc = aViewData.GetDocument();
824 SCTAB nTab = aViewData.GetTabNo();
825 while ( nNewDeltaX < MAXCOL && !pDoc->GetColWidth( nNewDeltaX, nTab ) )
826 ++nNewDeltaX;
827 nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
829 while ( nCurY >= nNewDeltaY+nSizeY )
831 nNewDeltaY = nCurY-nSizeY+1;
832 ScDocument* pDoc = aViewData.GetDocument();
833 SCTAB nTab = aViewData.GetTabNo();
834 while ( nNewDeltaY < MAXROW && !pDoc->GetRowHeight( nNewDeltaY, nTab ) )
835 ++nNewDeltaY;
836 nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
838 if ( nCurX < nNewDeltaX ) nNewDeltaX = nCurX;
839 if ( nCurY < nNewDeltaY ) nNewDeltaY = nCurY;
842 if ( nNewDeltaX != nDeltaX )
843 nSizeX = (SCsCOL) aViewData.CellsAtX( nNewDeltaX, 1, eAlignX );
844 if (nNewDeltaX+nSizeX-1 > MAXCOL) nNewDeltaX = MAXCOL-nSizeX+1;
845 if (nNewDeltaX < 0) nNewDeltaX = 0;
847 if ( nNewDeltaY != nDeltaY )
848 nSizeY = (SCsROW) aViewData.CellsAtY( nNewDeltaY, 1, eAlignY );
849 if (nNewDeltaY+nSizeY-1 > MAXROW) nNewDeltaY = MAXROW-nSizeY+1;
850 if (nNewDeltaY < 0) nNewDeltaY = 0;
852 if ( nNewDeltaX != nDeltaX ) ScrollX( nNewDeltaX - nDeltaX, eAlignX );
853 if ( nNewDeltaY != nDeltaY ) ScrollY( nNewDeltaY - nDeltaY, eAlignY );
857 // nochmal aktiven Teil umschalten
860 if (bHFix)
861 if (eActiveX == SC_SPLIT_RIGHT && nCurX < (SCsCOL)aViewData.GetFixPosX())
863 ActivatePart( (eActiveY==SC_SPLIT_TOP) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT );
864 eActiveX = SC_SPLIT_LEFT;
866 if (bVFix)
867 if (eActiveY == SC_SPLIT_BOTTOM && nCurY < (SCsROW)aViewData.GetFixPosY())
869 ActivatePart( (eActiveX==SC_SPLIT_LEFT) ? SC_SPLIT_TOPLEFT : SC_SPLIT_TOPRIGHT );
870 eActiveY = SC_SPLIT_TOP;
874 BOOL ScTabView::SelMouseButtonDown( const MouseEvent& rMEvt )
876 BOOL bRet = FALSE;
878 // #i3875# *Hack*
879 BOOL bMod1Locked = aViewData.GetViewShell()->GetLockedModifiers() & KEY_MOD1 ? TRUE : FALSE;
880 aViewData.SetSelCtrlMouseClick( rMEvt.IsMod1() || bMod1Locked );
882 if ( pSelEngine )
884 bMoveIsShift = rMEvt.IsShift();
885 bRet = pSelEngine->SelMouseButtonDown( rMEvt );
886 bMoveIsShift = FALSE;
889 aViewData.SetSelCtrlMouseClick( FALSE ); // #i3875# *Hack*
891 return bRet;
895 // MoveCursor - mit Anpassung des Bildausschnitts
898 void ScTabView::MoveCursorAbs( SCsCOL nCurX, SCsROW nCurY, ScFollowMode eMode,
899 BOOL bShift, BOOL bControl, BOOL bKeepOld, BOOL bKeepSel )
901 if (!bKeepOld)
902 aViewData.ResetOldCursor();
904 if (nCurX < 0) nCurX = 0;
905 if (nCurY < 0) nCurY = 0;
906 if (nCurX > MAXCOL) nCurX = MAXCOL;
907 if (nCurY > MAXROW) nCurY = MAXROW;
909 HideAllCursors();
911 // aktiven Teil umschalten jetzt in AlignToCursor
913 AlignToCursor( nCurX, nCurY, eMode );
914 //! auf OS/2: SC_FOLLOW_JUMP statt SC_FOLLOW_LINE, um Nachlaufen zu verhindern ???
916 if (bKeepSel)
918 SetCursor( nCurX, nCurY ); // Markierung stehenlassen
920 // If the cursor is in existing selection, it's a cursor movement by
921 // ENTER or TAB. If not, then it's a new selection during ADD
922 // selection mode.
924 const ScMarkData& rMark = aViewData.GetMarkData();
925 ScRangeList aSelList;
926 rMark.FillRangeListWithMarks(&aSelList, false);
927 if (!aSelList.In(ScRange(nCurX, nCurY, aViewData.GetTabNo())))
928 // Cursor not in existing selection. Start a new selection.
929 DoneBlockMode(true);
931 else
933 if (!bShift)
935 // Remove all marked data on cursor movement unless the Shift is locked.
936 ScMarkData aData(aViewData.GetMarkData());
937 aData.ResetMark();
938 SetMarkData(aData);
941 BOOL bSame = ( nCurX == aViewData.GetCurX() && nCurY == aViewData.GetCurY() );
942 bMoveIsShift = bShift;
943 pSelEngine->CursorPosChanging( bShift, bControl );
944 bMoveIsShift = FALSE;
945 aFunctionSet.SetCursorAtCell( nCurX, nCurY, FALSE );
947 // Wenn der Cursor nicht bewegt wurde, muss das SelectionChanged fuer das
948 // Aufheben der Selektion hier einzeln passieren:
949 if (bSame)
950 SelectionChanged();
953 ShowAllCursors();
956 void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode,
957 BOOL bShift, BOOL bKeepSel )
959 ScDocument* pDoc = aViewData.GetDocument();
960 SCTAB nTab = aViewData.GetTabNo();
962 bool bSkipProtected = false, bSkipUnprotected = false;
963 ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
964 if ( pProtect && pProtect->isProtected() )
966 bSkipProtected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS);
967 bSkipUnprotected = !pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS);
970 if ( bSkipProtected && bSkipUnprotected )
971 return;
973 SCsCOL nOldX;
974 SCsROW nOldY;
975 SCsCOL nCurX;
976 SCsROW nCurY;
977 if ( aViewData.IsRefMode() )
979 nOldX = (SCsCOL) aViewData.GetRefEndX();
980 nOldY = (SCsROW) aViewData.GetRefEndY();
981 nCurX = nOldX + nMovX;
982 nCurY = nOldY + nMovY;
984 else
986 nOldX = (SCsCOL) aViewData.GetCurX();
987 nOldY = (SCsROW) aViewData.GetCurY();
988 nCurX = (nMovX != 0) ? nOldX+nMovX : (SCsCOL) aViewData.GetOldCurX();
989 nCurY = (nMovY != 0) ? nOldY+nMovY : (SCsROW) aViewData.GetOldCurY();
992 BOOL bSkipCell = FALSE;
993 aViewData.ResetOldCursor();
995 if (nMovX != 0 && VALIDCOLROW(nCurX,nCurY))
997 BOOL bHFlip = FALSE;
1000 SCCOL nLastCol = -1;
1001 bSkipCell = pDoc->ColHidden(nCurX, nTab, nLastCol) || pDoc->IsHorOverlapped( nCurX, nCurY, nTab );
1002 if (bSkipProtected && !bSkipCell)
1003 bSkipCell = pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
1004 if (bSkipUnprotected && !bSkipCell)
1005 bSkipCell = !pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
1007 if (bSkipCell)
1009 if ( nCurX<=0 || nCurX>=MAXCOL )
1011 if (bHFlip)
1013 nCurX = nOldX;
1014 bSkipCell = FALSE;
1016 else
1018 nMovX = -nMovX;
1019 if (nMovX > 0) ++nCurX; else --nCurX; // zuruecknehmen
1020 bHFlip = TRUE;
1023 else
1024 if (nMovX > 0) ++nCurX; else --nCurX;
1027 while (bSkipCell);
1029 if (pDoc->IsVerOverlapped( nCurX, nCurY, nTab ))
1031 aViewData.SetOldCursor( nCurX,nCurY );
1032 while (pDoc->IsVerOverlapped( nCurX, nCurY, nTab ))
1033 --nCurY;
1037 if (nMovY != 0 && VALIDCOLROW(nCurX,nCurY))
1039 BOOL bVFlip = FALSE;
1042 SCROW nLastRow = -1;
1043 bSkipCell = pDoc->RowHidden(nCurY, nTab, nLastRow) || pDoc->IsVerOverlapped( nCurX, nCurY, nTab );
1044 if (bSkipProtected && !bSkipCell)
1045 bSkipCell = pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
1046 if (bSkipUnprotected && !bSkipCell)
1047 bSkipCell = !pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED);
1049 if (bSkipCell)
1051 if ( nCurY<=0 || nCurY>=MAXROW )
1053 if (bVFlip)
1055 nCurY = nOldY;
1056 bSkipCell = FALSE;
1058 else
1060 nMovY = -nMovY;
1061 if (nMovY > 0) ++nCurY; else --nCurY; // zuruecknehmen
1062 bVFlip = TRUE;
1065 else
1066 if (nMovY > 0) ++nCurY; else --nCurY;
1069 while (bSkipCell);
1071 if (pDoc->IsHorOverlapped( nCurX, nCurY, nTab ))
1073 aViewData.SetOldCursor( nCurX,nCurY );
1074 while (pDoc->IsHorOverlapped( nCurX, nCurY, nTab ))
1075 --nCurX;
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 );
1232 BOOL ScTabView::MoveCursorKeyInput( const KeyEvent& rKeyEvent )
1234 const KeyCode& rKCode = rKeyEvent.GetKeyCode();
1236 enum { MOD_NONE, MOD_CTRL, MOD_ALT, MOD_BOTH } eModifier =
1237 rKCode.IsMod1() ?
1238 (rKCode.IsMod2() ? MOD_BOTH : MOD_CTRL) :
1239 (rKCode.IsMod2() ? MOD_ALT : MOD_NONE);
1241 BOOL bSel = rKCode.IsShift();
1242 USHORT nCode = rKCode.GetCode();
1244 // CURSOR keys
1245 SCsCOL nDX = 0;
1246 SCsROW nDY = 0;
1247 switch( nCode )
1249 case KEY_LEFT: nDX = -1; break;
1250 case KEY_RIGHT: nDX = 1; break;
1251 case KEY_UP: nDY = -1; break;
1252 case KEY_DOWN: nDY = 1; break;
1254 if( nDX != 0 || nDY != 0 )
1256 switch( eModifier )
1258 case MOD_NONE: MoveCursorRel( nDX, nDY, SC_FOLLOW_LINE, bSel ); break;
1259 case MOD_CTRL: MoveCursorArea( nDX, nDY, SC_FOLLOW_JUMP, bSel ); break;
1260 default:
1262 // added to avoid warnings
1265 // always TRUE to suppress changes of col/row size (ALT+CURSOR)
1266 return TRUE;
1269 // PAGEUP/PAGEDOWN
1270 if( (nCode == KEY_PAGEUP) || (nCode == KEY_PAGEDOWN) )
1272 nDX = (nCode == KEY_PAGEUP) ? -1 : 1;
1273 switch( eModifier )
1275 case MOD_NONE: MoveCursorPage( 0, static_cast<SCsCOLROW>(nDX), SC_FOLLOW_FIX, bSel ); break;
1276 case MOD_ALT: MoveCursorPage( nDX, 0, SC_FOLLOW_FIX, bSel ); break;
1277 case MOD_CTRL: SelectNextTab( nDX ); break;
1278 default:
1280 // added to avoid warnings
1283 return TRUE;
1286 // HOME/END
1287 if( (nCode == KEY_HOME) || (nCode == KEY_END) )
1289 nDX = (nCode == KEY_HOME) ? -1 : 1;
1290 ScFollowMode eMode = (nCode == KEY_HOME) ? SC_FOLLOW_LINE : SC_FOLLOW_JUMP;
1291 switch( eModifier )
1293 case MOD_NONE: MoveCursorEnd( nDX, 0, eMode, bSel ); break;
1294 case MOD_CTRL: MoveCursorEnd( nDX, static_cast<SCsCOLROW>(nDX), eMode, bSel ); break;
1295 default:
1297 // added to avoid warnings
1300 return TRUE;
1303 return FALSE;
1307 // naechste/vorherige nicht geschuetzte Zelle
1308 void ScTabView::FindNextUnprot( BOOL bShift, BOOL bInSelection )
1310 short nMove = bShift ? -1 : 1;
1312 ScMarkData& rMark = aViewData.GetMarkData();
1313 BOOL bMarked = bInSelection && (rMark.IsMarked() || rMark.IsMultiMarked());
1315 SCCOL nCurX;
1316 SCROW nCurY;
1317 aViewData.GetMoveCursor( nCurX,nCurY );
1318 SCCOL nNewX = nCurX;
1319 SCROW nNewY = nCurY;
1320 SCTAB nTab = aViewData.GetTabNo();
1322 ScDocument* pDoc = aViewData.GetDocument();
1323 pDoc->GetNextPos( nNewX,nNewY, nTab, nMove,0, bMarked,TRUE, rMark );
1325 SCCOL nTabCol = aViewData.GetTabStartCol();
1326 if ( nTabCol == SC_TABSTART_NONE )
1327 nTabCol = nCurX; // auf diese Spalte zurueck bei Enter
1329 MoveCursorRel( ((SCsCOL)nNewX)-(SCsCOL)nCurX, ((SCsROW)nNewY)-(SCsROW)nCurY,
1330 SC_FOLLOW_LINE, FALSE, TRUE );
1332 // in MoveCursorRel wird die TabCol zurueckgesetzt...
1333 aViewData.SetTabStartCol( nTabCol );
1336 void ScTabView::MarkColumns()
1338 SCCOL nStartCol;
1339 SCCOL nEndCol;
1341 ScMarkData& rMark = aViewData.GetMarkData();
1342 if (rMark.IsMarked())
1344 ScRange aMarkRange;
1345 rMark.GetMarkArea( aMarkRange );
1346 nStartCol = aMarkRange.aStart.Col();
1347 nEndCol = aMarkRange.aEnd.Col();
1349 else
1351 SCROW nDummy;
1352 aViewData.GetMoveCursor( nStartCol, nDummy );
1353 nEndCol=nStartCol;
1356 SCTAB nTab = aViewData.GetTabNo();
1357 DoneBlockMode();
1358 InitBlockMode( nStartCol,0, nTab );
1359 MarkCursor( nEndCol,MAXROW, nTab );
1360 SelectionChanged();
1363 void ScTabView::MarkRows()
1365 SCROW nStartRow;
1366 SCROW nEndRow;
1368 ScMarkData& rMark = aViewData.GetMarkData();
1369 if (rMark.IsMarked())
1371 ScRange aMarkRange;
1372 rMark.GetMarkArea( aMarkRange );
1373 nStartRow = aMarkRange.aStart.Row();
1374 nEndRow = aMarkRange.aEnd.Row();
1376 else
1378 SCCOL nDummy;
1379 aViewData.GetMoveCursor( nDummy, nStartRow );
1380 nEndRow=nStartRow;
1383 SCTAB nTab = aViewData.GetTabNo();
1384 DoneBlockMode();
1385 InitBlockMode( 0,nStartRow, nTab );
1386 MarkCursor( MAXCOL,nEndRow, nTab );
1387 SelectionChanged();
1390 void ScTabView::MarkDataArea( BOOL bIncludeCursor )
1392 ScDocument* pDoc = aViewData.GetDocument();
1393 SCTAB nTab = aViewData.GetTabNo();
1394 SCCOL nStartCol = aViewData.GetCurX();
1395 SCROW nStartRow = aViewData.GetCurY();
1396 SCCOL nEndCol = nStartCol;
1397 SCROW nEndRow = nStartRow;
1399 pDoc->GetDataArea( nTab, nStartCol, nStartRow, nEndCol, nEndRow, bIncludeCursor );
1401 HideAllCursors();
1402 DoneBlockMode();
1403 InitBlockMode( nStartCol, nStartRow, nTab );
1404 MarkCursor( nEndCol, nEndRow, nTab );
1405 ShowAllCursors();
1407 SelectionChanged();
1410 void ScTabView::MarkMatrixFormula()
1412 ScDocument* pDoc = aViewData.GetDocument();
1413 ScAddress aCursor( aViewData.GetCurX(), aViewData.GetCurY(), aViewData.GetTabNo() );
1414 ScRange aMatrix;
1415 if ( pDoc->GetMatrixFormulaRange( aCursor, aMatrix ) )
1417 MarkRange( aMatrix, FALSE ); // cursor is already within the range
1421 void ScTabView::MarkRange( const ScRange& rRange, BOOL bSetCursor, BOOL bContinue )
1423 SCTAB nTab = rRange.aStart.Tab();
1424 SetTabNo( nTab );
1426 HideAllCursors();
1427 DoneBlockMode( bContinue ); // bContinue==TRUE -> clear old mark
1428 if (bSetCursor) // Wenn Cursor gesetzt wird, immer auch alignen
1430 SCCOL nAlignX = rRange.aStart.Col();
1431 SCROW nAlignY = rRange.aStart.Row();
1432 bool bCol = ( rRange.aStart.Col() == 0 && rRange.aEnd.Col() == MAXCOL );
1433 bool bRow = ( rRange.aStart.Row() == 0 && rRange.aEnd.Row() == MAXROW );
1434 if ( !bCol && !bRow )
1436 if ( bCol )
1437 nAlignX = aViewData.GetPosX(WhichH(aViewData.GetActivePart()));
1438 if ( bRow )
1439 nAlignY = aViewData.GetPosY(WhichV(aViewData.GetActivePart()));
1441 AlignToCursor( nAlignX, nAlignY, SC_FOLLOW_JUMP );
1443 InitBlockMode( rRange.aStart.Col(), rRange.aStart.Row(), nTab );
1444 MarkCursor( rRange.aEnd.Col(), rRange.aEnd.Row(), nTab );
1445 if (bSetCursor)
1447 SCCOL nPosX = rRange.aStart.Col();
1448 SCROW nPosY = rRange.aStart.Row();
1449 ScDocument* pDoc = aViewData.GetDocument();
1450 pDoc->SkipOverlapped(nPosX, nPosY, nTab);
1452 aViewData.ResetOldCursor();
1453 SetCursor( nPosX, nPosY );
1455 ShowAllCursors();
1457 SelectionChanged();
1460 void ScTabView::Unmark()
1462 ScMarkData& rMark = aViewData.GetMarkData();
1463 if ( rMark.IsMarked() || rMark.IsMultiMarked() )
1465 SCCOL nCurX;
1466 SCROW nCurY;
1467 aViewData.GetMoveCursor( nCurX,nCurY );
1468 MoveCursorAbs( nCurX, nCurY, SC_FOLLOW_NONE, FALSE, FALSE );
1470 SelectionChanged();
1474 void ScTabView::SetMarkData( const ScMarkData& rNew )
1476 DoneBlockMode();
1477 InitOwnBlockMode();
1478 aViewData.GetMarkData() = rNew;
1480 MarkDataChanged();
1483 void ScTabView::MarkDataChanged()
1485 // has to be called after making direct changes to mark data (not via MarkCursor etc)
1487 UpdateSelectionOverlay();
1490 void ScTabView::SelectNextTab( short nDir, BOOL bExtendSelection )
1492 if (!nDir) return;
1493 DBG_ASSERT( nDir==-1 || nDir==1, "SelectNextTab: falscher Wert");
1495 ScDocument* pDoc = aViewData.GetDocument();
1496 SCTAB nTab = aViewData.GetTabNo();
1497 if (nDir<0)
1499 if (!nTab) return;
1500 --nTab;
1501 while (!pDoc->IsVisible(nTab))
1503 if (!nTab) return;
1504 --nTab;
1507 else
1509 SCTAB nCount = pDoc->GetTableCount();
1510 ++nTab;
1511 if (nTab >= nCount) return;
1512 while (!pDoc->IsVisible(nTab))
1514 ++nTab;
1515 if (nTab >= nCount) return;
1519 SetTabNo( nTab, FALSE, bExtendSelection );
1520 PaintExtras();
1524 // SetTabNo - angezeigte Tabelle
1526 void ScTabView::SetTabNo( SCTAB nTab, BOOL bNew, BOOL bExtendSelection )
1528 if ( !ValidTab(nTab) )
1530 DBG_ERROR("SetTabNo: falsche Tabelle");
1531 return;
1534 if ( nTab != aViewData.GetTabNo() || bNew )
1536 // #57724# Die FormShell moechte vor dem Umschalten benachrichtigt werden
1537 FmFormShell* pFormSh = aViewData.GetViewShell()->GetFormShell();
1538 if (pFormSh)
1540 BOOL bAllowed = sal::static_int_cast<BOOL>( pFormSh->PrepareClose( TRUE ) );
1541 if (!bAllowed)
1543 //! Fehlermeldung? oder macht das die FormShell selber?
1544 //! Fehler-Flag zurueckgeben und Aktionen abbrechen
1546 return; // Die FormShell sagt, es kann nicht umgeschaltet werden
1550 // nicht InputEnterHandler wegen Referenzeingabe !
1552 ScDocument* pDoc = aViewData.GetDocument();
1553 if( !bNew )
1555 uno::Reference< document::XVbaEventsHelper > xVbaEventsHelper ( pDoc->GetVbaEventsHelper(), uno::UNO_QUERY );
1556 if( xVbaEventsHelper.is() )
1558 uno::Sequence< uno::Any > aArgs(1);
1559 aArgs[0] <<= aViewData.GetTabNo();
1560 xVbaEventsHelper->ProcessCompatibleVbaEvent( VBAEVENT_WORKSHEET_DEACTIVATE, aArgs );
1564 pDoc->MakeTable( nTab );
1566 // Update pending row heights before switching the sheet, so Reschedule from the progress bar
1567 // doesn't paint the new sheet with old heights
1568 aViewData.GetDocShell()->UpdatePendingRowHeights( nTab );
1570 SCTAB nTabCount = pDoc->GetTableCount();
1571 SCTAB nOldPos = nTab;
1572 while (!pDoc->IsVisible(nTab)) // naechste sichtbare suchen
1574 BOOL bUp = (nTab>=nOldPos);
1575 if (bUp)
1577 ++nTab;
1578 if (nTab>=nTabCount)
1580 nTab = nOldPos;
1581 bUp = FALSE;
1585 if (!bUp)
1587 if (nTab != 0)
1588 --nTab;
1589 else
1591 DBG_ERROR("keine sichtbare Tabelle");
1592 pDoc->SetVisible( 0, TRUE );
1597 // #i71490# Deselect drawing objects before changing the sheet number in view data,
1598 // so the handling of notes still has the sheet selected on which the notes are.
1599 DrawDeselectAll();
1601 ScModule* pScMod = SC_MOD();
1602 BOOL bRefMode = pScMod->IsFormulaMode();
1603 if ( !bRefMode ) // Abfrage, damit RefMode bei Tabellenwechsel funktioniert
1605 DoneBlockMode();
1606 pSelEngine->Reset(); // reset all flags, including locked modifiers
1607 aViewData.SetRefTabNo( nTab );
1610 ScSplitPos eOldActive = aViewData.GetActivePart(); // before switching
1611 BOOL bFocus = pGridWin[eOldActive]->HasFocus();
1613 aViewData.SetTabNo( nTab );
1614 // UpdateShow noch vor SetCursor, damit UpdateAutoFillMark die richtigen
1615 // Fenster findet (wird aus SetCursor gerufen)
1616 UpdateShow();
1617 aViewData.ResetOldCursor();
1618 SetCursor( aViewData.GetCurX(), aViewData.GetCurY(), TRUE );
1620 SfxBindings& rBindings = aViewData.GetBindings();
1621 ScMarkData& rMark = aViewData.GetMarkData();
1623 bool bAllSelected = true;
1624 for (SCTAB nSelTab = 0; nSelTab < nTabCount; ++nSelTab)
1626 if (!pDoc->IsVisible(nSelTab) || rMark.GetTableSelect(nSelTab))
1628 if (nTab == nSelTab)
1629 // This tab is already in selection. Keep the current
1630 // selection.
1631 bExtendSelection = true;
1633 else
1635 bAllSelected = false;
1636 if (bExtendSelection)
1637 // We got what we need. No need to stay in the loop.
1638 break;
1641 if (bAllSelected && !bNew)
1642 // #i6327# if all tables are selected, a selection event (#i6330#) will deselect all
1643 // (not if called with bNew to update settings)
1644 bExtendSelection = false;
1646 if (bExtendSelection)
1647 rMark.SelectTable( nTab, TRUE );
1648 else
1650 rMark.SelectOneTable( nTab );
1651 rBindings.Invalidate( FID_FILL_TAB );
1652 rBindings.Invalidate( FID_TAB_DESELECTALL );
1655 bool bUnoRefDialog = pScMod->IsRefDialogOpen() && pScMod->GetCurRefDlgId() == WID_SIMPLE_REF;
1657 // recalc zoom-dependent values (before TabChanged, before UpdateEditViewPos)
1658 RefreshZoom();
1659 UpdateVarZoom();
1661 if ( bRefMode ) // hide EditView if necessary (after aViewData.SetTabNo !)
1663 for ( USHORT i=0; i<4; i++ )
1664 if ( pGridWin[i] )
1665 if ( pGridWin[i]->IsVisible() )
1666 pGridWin[i]->UpdateEditViewPos();
1669 TabChanged(); // DrawView
1671 if( !bNew )
1673 uno::Reference< document::XVbaEventsHelper > xVbaEventsHelper ( pDoc->GetVbaEventsHelper(), uno::UNO_QUERY );
1674 if( xVbaEventsHelper.is() )
1676 uno::Sequence< uno::Any > aArgs(1);
1677 aArgs[0] <<= aViewData.GetTabNo();
1678 xVbaEventsHelper->ProcessCompatibleVbaEvent( VBAEVENT_WORKSHEET_ACTIVATE, aArgs );
1682 aViewData.GetViewShell()->WindowChanged(); // falls das aktive Fenster anders ist
1683 if ( !bUnoRefDialog )
1684 aViewData.GetViewShell()->DisconnectAllClients(); // important for floating frames
1685 else
1687 // hide / show inplace client
1689 ScClient* pClient = static_cast<ScClient*>(aViewData.GetViewShell()->GetIPClient());
1690 if ( pClient && pClient->IsObjectInPlaceActive() )
1692 Rectangle aObjArea = pClient->GetObjArea();
1693 if ( nTab == aViewData.GetRefTabNo() )
1695 // move to its original position
1697 SdrOle2Obj* pDrawObj = pClient->GetDrawObj();
1698 if ( pDrawObj )
1700 Rectangle aRect = pDrawObj->GetLogicRect();
1701 MapMode aMapMode( MAP_100TH_MM );
1702 Size aOleSize = pDrawObj->GetOrigObjSize( &aMapMode );
1703 aRect.SetSize( aOleSize );
1704 aObjArea = aRect;
1707 else
1709 // move to an invisible position
1711 aObjArea.SetPos( Point( 0, -2*aObjArea.GetHeight() ) );
1713 pClient->SetObjArea( aObjArea );
1717 if ( bFocus && aViewData.GetActivePart() != eOldActive && !bRefMode )
1718 ActiveGrabFocus(); // grab focus to the pane that's active now
1720 // Fixierungen
1722 BOOL bResize = FALSE;
1723 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
1724 if (aViewData.UpdateFixX())
1725 bResize = TRUE;
1726 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1727 if (aViewData.UpdateFixY())
1728 bResize = TRUE;
1729 if (bResize)
1730 RepeatResize();
1731 InvalidateSplit();
1733 if ( aViewData.IsPagebreakMode() )
1734 UpdatePageBreakData(); //! asynchron ??
1736 // #53551# Form-Layer muss den sichtbaren Ausschnitt der neuen Tabelle kennen
1737 // dafuer muss hier schon der MapMode stimmen
1738 for (USHORT i=0; i<4; i++)
1739 if (pGridWin[i])
1740 pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
1741 SetNewVisArea();
1743 PaintGrid();
1744 PaintTop();
1745 PaintLeft();
1746 PaintExtras();
1748 DoResize( aBorderPos, aFrameSize );
1749 rBindings.Invalidate( SID_DELETE_PRINTAREA ); // Menue
1750 rBindings.Invalidate( FID_DEL_MANUALBREAKS );
1751 rBindings.Invalidate( FID_RESET_PRINTZOOM );
1752 rBindings.Invalidate( SID_STATUS_DOCPOS ); // Statusbar
1753 rBindings.Invalidate( SID_STATUS_PAGESTYLE ); // Statusbar
1754 rBindings.Invalidate( SID_CURRENTTAB ); // Navigator
1755 rBindings.Invalidate( SID_STYLE_FAMILY2 ); // Gestalter
1756 rBindings.Invalidate( SID_STYLE_FAMILY4 ); // Gestalter
1757 rBindings.Invalidate( SID_TABLES_COUNT );
1759 if(pScMod->IsRefDialogOpen())
1761 USHORT nCurRefDlgId=pScMod->GetCurRefDlgId();
1762 SfxViewFrame* pViewFrm = aViewData.GetViewShell()->GetViewFrame();
1763 SfxChildWindow* pChildWnd = pViewFrm->GetChildWindow( nCurRefDlgId );
1764 if ( pChildWnd )
1766 IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetWindow());
1767 pRefDlg->ViewShellChanged(NULL);
1774 // Paint-Funktionen - nur fuer diese View
1777 void ScTabView::MakeEditView( ScEditEngineDefaulter* pEngine, SCCOL nCol, SCROW nRow )
1779 DrawDeselectAll();
1781 if (pDrawView)
1782 DrawEnableAnim( FALSE );
1784 EditView* pSpellingView = aViewData.GetSpellingView();
1786 for (USHORT i=0; i<4; i++)
1787 if (pGridWin[i])
1788 if ( pGridWin[i]->IsVisible() && !aViewData.HasEditView((ScSplitPos)i) )
1790 ScHSplitPos eHWhich = WhichH( (ScSplitPos) i );
1791 ScVSplitPos eVWhich = WhichV( (ScSplitPos) i );
1792 SCCOL nScrX = aViewData.GetPosX( eHWhich );
1793 SCROW nScrY = aViewData.GetPosY( eVWhich );
1795 BOOL bPosVisible =
1796 ( nCol >= nScrX && nCol <= nScrX + aViewData.VisibleCellsX(eHWhich) + 1 &&
1797 nRow >= nScrY && nRow <= nScrY + aViewData.VisibleCellsY(eVWhich) + 1 );
1799 // #102421# for the active part, create edit view even if outside the visible area,
1800 // so input isn't lost (and the edit view may be scrolled into the visible area)
1802 // #i26433# during spelling, the spelling view must be active
1803 if ( bPosVisible || aViewData.GetActivePart() == (ScSplitPos) i ||
1804 ( pSpellingView && aViewData.GetEditView((ScSplitPos) i) == pSpellingView ) )
1806 pGridWin[i]->HideCursor();
1808 pGridWin[i]->DeleteCursorOverlay();
1809 pGridWin[i]->DeleteAutoFillOverlay();
1810 pGridWin[i]->DeleteCopySourceOverlay();
1812 // flush OverlayManager before changing MapMode to text edit
1813 pGridWin[i]->flushOverlayManager();
1815 // MapMode must be set after HideCursor
1816 pGridWin[i]->SetMapMode(aViewData.GetLogicMode());
1818 aViewData.SetEditEngine( (ScSplitPos) i, pEngine, pGridWin[i], nCol, nRow );
1820 if ( !bPosVisible )
1822 // move the edit view area to the real (possibly negative) position,
1823 // or hide if completely above or left of the window
1824 pGridWin[i]->UpdateEditViewPos();
1829 if (aViewData.GetViewShell()->HasAccessibilityObjects())
1830 aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_ENTEREDITMODE));
1833 void ScTabView::UpdateEditView()
1835 ScSplitPos eActive = aViewData.GetActivePart();
1836 for (USHORT i=0; i<4; i++)
1837 if (aViewData.HasEditView( (ScSplitPos) i ))
1839 EditView* pEditView = aViewData.GetEditView( (ScSplitPos) i );
1840 aViewData.SetEditEngine( (ScSplitPos) i,
1841 static_cast<ScEditEngineDefaulter*>(pEditView->GetEditEngine()),
1842 pGridWin[i], GetViewData()->GetCurX(), GetViewData()->GetCurY() );
1843 if ( (ScSplitPos)i == eActive )
1844 pEditView->ShowCursor( FALSE );
1848 void ScTabView::KillEditView( BOOL bNoPaint )
1850 USHORT i;
1851 SCCOL nCol1 = aViewData.GetEditStartCol();
1852 SCROW nRow1 = aViewData.GetEditStartRow();
1853 SCCOL nCol2 = aViewData.GetEditEndCol();
1854 SCROW nRow2 = aViewData.GetEditEndRow();
1855 BOOL bPaint[4];
1856 BOOL bNotifyAcc(false);
1858 BOOL bExtended = nRow1 != nRow2; // Col wird sowieso bis zum Ende gezeichnet
1859 BOOL bAtCursor = nCol1 <= aViewData.GetCurX() &&
1860 nCol2 >= aViewData.GetCurX() &&
1861 nRow1 == aViewData.GetCurY();
1862 for (i=0; i<4; i++)
1864 bPaint[i] = aViewData.HasEditView( (ScSplitPos) i );
1865 if (bPaint[i])
1866 bNotifyAcc = true;
1869 // #108931#; notify accessibility before all things happen
1870 if ((bNotifyAcc) && (aViewData.GetViewShell()->HasAccessibilityObjects()))
1871 aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_LEAVEEDITMODE));
1873 aViewData.ResetEditView();
1874 for (i=0; i<4; i++)
1875 if (pGridWin[i] && bPaint[i])
1876 if (pGridWin[i]->IsVisible())
1878 pGridWin[i]->ShowCursor();
1880 pGridWin[i]->SetMapMode(pGridWin[i]->GetDrawMapMode());
1882 // #i73567# the cell still has to be repainted
1883 if (bExtended || ( bAtCursor && !bNoPaint ))
1885 pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2 );
1886 pGridWin[i]->UpdateSelectionOverlay();
1890 if (pDrawView)
1891 DrawEnableAnim( TRUE );
1893 // GrabFocus immer dann, wenn diese View aktiv ist und
1894 // die Eingabezeile den Focus hat
1896 BOOL bGrabFocus = FALSE;
1897 if (aViewData.IsActive())
1899 ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
1900 if ( pInputHdl )
1902 ScInputWindow* pInputWin = pInputHdl->GetInputWindow();
1903 if (pInputWin && pInputWin->IsInputActive())
1904 bGrabFocus = TRUE;
1908 if (bGrabFocus)
1910 // So soll es gemacht werden, damit der Sfx es mitbekommt, klappt aber nicht:
1911 //! aViewData.GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
1912 // deshalb erstmal so:
1913 GetActiveWin()->GrabFocus();
1916 // Cursor-Abfrage erst nach GrabFocus
1918 for (i=0; i<4; i++)
1919 if (pGridWin[i] && pGridWin[i]->IsVisible())
1921 Cursor* pCur = pGridWin[i]->GetCursor();
1922 if (pCur && pCur->IsVisible())
1923 pCur->Hide();
1925 if(bPaint[i])
1927 pGridWin[i]->UpdateCursorOverlay();
1928 pGridWin[i]->UpdateAutoFillOverlay();
1929 // pGridWin[i]->UpdateAllOverlays();
1934 void ScTabView::UpdateFormulas()
1936 if ( aViewData.GetDocument()->IsAutoCalcShellDisabled() )
1937 return ;
1939 USHORT i;
1940 for (i=0; i<4; i++)
1941 if (pGridWin[i])
1942 if (pGridWin[i]->IsVisible())
1943 pGridWin[i]->UpdateFormulas();
1945 if ( aViewData.IsPagebreakMode() )
1946 UpdatePageBreakData(); //! asynchron
1948 UpdateHeaderWidth();
1950 // if in edit mode, adjust edit view area because widths/heights may have changed
1951 if ( aViewData.HasEditView( aViewData.GetActivePart() ) )
1952 UpdateEditView();
1955 // PaintArea -Block neu zeichnen
1957 void ScTabView::PaintArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
1958 ScUpdateMode eMode )
1960 USHORT i;
1961 SCCOL nCol1;
1962 SCROW nRow1;
1963 SCCOL nCol2;
1964 SCROW nRow2;
1966 PutInOrder( nStartCol, nEndCol );
1967 PutInOrder( nStartRow, nEndRow );
1969 for (i=0; i<4; i++)
1970 if (pGridWin[i])
1971 if (pGridWin[i]->IsVisible())
1973 ScHSplitPos eHWhich = WhichH( (ScSplitPos) i );
1974 ScVSplitPos eVWhich = WhichV( (ScSplitPos) i );
1975 BOOL bOut = FALSE;
1977 nCol1 = nStartCol;
1978 nRow1 = nStartRow;
1979 nCol2 = nEndCol;
1980 nRow2 = nEndRow;
1982 SCCOL nScrX = aViewData.GetPosX( eHWhich );
1983 SCROW nScrY = aViewData.GetPosY( eVWhich );
1984 if (nCol1 < nScrX) nCol1 = nScrX;
1985 if (nCol2 < nScrX)
1987 if ( eMode == SC_UPDATE_ALL ) // #91240# for UPDATE_ALL, paint anyway
1988 nCol2 = nScrX; // (because of extending strings to the right)
1989 else
1990 bOut = TRUE; // completely outside the window
1992 if (nRow1 < nScrY) nRow1 = nScrY;
1993 if (nRow2 < nScrY) bOut = TRUE;
1995 SCCOL nLastX = nScrX + aViewData.VisibleCellsX( eHWhich ) + 1;
1996 SCROW nLastY = nScrY + aViewData.VisibleCellsY( eVWhich ) + 1;
1997 if (nCol1 > nLastX) bOut = TRUE;
1998 if (nCol2 > nLastX) nCol2 = nLastX;
1999 if (nRow1 > nLastY) bOut = TRUE;
2000 if (nRow2 > nLastY) nRow2 = nLastY;
2002 if (!bOut)
2004 if ( eMode == SC_UPDATE_CHANGED )
2005 pGridWin[i]->Draw( nCol1, nRow1, nCol2, nRow2, eMode );
2006 else // ALL oder MARKS
2008 BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
2009 long nLayoutSign = bLayoutRTL ? -1 : 1;
2011 Point aStart = aViewData.GetScrPos( nCol1, nRow1, (ScSplitPos) i );
2012 Point aEnd = aViewData.GetScrPos( nCol2+1, nRow2+1, (ScSplitPos) i );
2013 if ( eMode == SC_UPDATE_ALL )
2014 aEnd.X() = bLayoutRTL ? 0 : (pGridWin[i]->GetOutputSizePixel().Width());
2015 aEnd.X() -= nLayoutSign;
2016 aEnd.Y() -= 1;
2018 // #i85232# include area below cells (could be done in GetScrPos?)
2019 if ( eMode == SC_UPDATE_ALL && nRow2 >= MAXROW )
2020 aEnd.Y() = pGridWin[i]->GetOutputSizePixel().Height();
2022 BOOL bShowChanges = TRUE; //! ...
2023 if (bShowChanges)
2025 aStart.X() -= nLayoutSign; // include change marks
2026 aStart.Y() -= 1;
2029 BOOL bMarkClipped = aViewData.GetOptions().GetOption( VOPT_CLIPMARKS );
2030 if (bMarkClipped)
2032 // dazu muesste ScColumn::IsEmptyBlock optimiert werden
2033 // (auf Search() umstellen)
2034 //!if ( nCol1 > 0 && !aViewData.GetDocument()->IsBlockEmpty(
2035 //! aViewData.GetTabNo(),
2036 //! 0, nRow1, nCol1-1, nRow2 ) )
2038 long nMarkPixel = (long)( SC_CLIPMARK_SIZE * aViewData.GetPPTX() );
2039 aStart.X() -= nMarkPixel * nLayoutSign;
2040 if (!bShowChanges)
2041 aStart.X() -= nLayoutSign; // cell grid
2045 pGridWin[i]->Invalidate( pGridWin[i]->PixelToLogic( Rectangle( aStart,aEnd ) ) );
2050 // #i79909# Calling UpdateAllOverlays here isn't necessary and would lead to overlay calls from a timer,
2051 // with a wrong MapMode if editing in a cell (reference input).
2052 // #i80499# Overlays need updates in a lot of cases, e.g. changing row/column size,
2053 // or showing/hiding outlines. TODO: selections in inactive windows are vanishing.
2054 // #i84689# With relative conditional formats, PaintArea may be called often (for each changed cell),
2055 // so UpdateAllOverlays was moved to ScTabViewShell::Notify and is called only if PAINT_LEFT/PAINT_TOP
2056 // is set (width or height changed).
2059 void ScTabView::PaintRangeFinder( long nNumber )
2061 ScInputHandler* pHdl = SC_MOD()->GetInputHdl( aViewData.GetViewShell() );
2062 if (pHdl)
2064 ScRangeFindList* pRangeFinder = pHdl->GetRangeFindList();
2065 if ( pRangeFinder && pRangeFinder->GetDocName() == aViewData.GetDocShell()->GetTitle() )
2067 SCTAB nTab = aViewData.GetTabNo();
2068 USHORT nCount = (USHORT)pRangeFinder->Count();
2069 for (USHORT i=0; i<nCount; i++)
2070 if ( nNumber < 0 || nNumber == i )
2072 ScRangeFindData* pData = pRangeFinder->GetObject(i);
2073 if (pData)
2075 ScRange aRef = pData->aRef;
2076 aRef.Justify(); // Justify fuer die Abfragen unten
2078 if ( aRef.aStart == aRef.aEnd ) //! Tab ignorieren?
2079 aViewData.GetDocument()->ExtendMerge(aRef);
2081 if ( aRef.aStart.Tab() >= nTab && aRef.aEnd.Tab() <= nTab )
2083 SCCOL nCol1 = aRef.aStart.Col();
2084 SCROW nRow1 = aRef.aStart.Row();
2085 SCCOL nCol2 = aRef.aEnd.Col();
2086 SCROW nRow2 = aRef.aEnd.Row();
2088 // wegnehmen -> Repaint
2089 // SC_UPDATE_MARKS: Invalidate, nicht bis zum Zeilenende
2091 BOOL bHiddenEdge = FALSE;
2092 SCROW nTmp;
2093 ScDocument* pDoc = aViewData.GetDocument();
2094 SCCOL nLastCol = -1;
2095 while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab, nLastCol) )
2097 --nCol1;
2098 bHiddenEdge = TRUE;
2100 while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab, nLastCol) )
2102 ++nCol2;
2103 bHiddenEdge = TRUE;
2105 nTmp = pDoc->LastVisibleRow(0, nRow1, nTab);
2106 if (!ValidRow(nTmp))
2107 nTmp = 0;
2108 if (nTmp < nRow1)
2110 nRow1 = nTmp;
2111 bHiddenEdge = TRUE;
2113 nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab);
2114 if (!ValidRow(nTmp))
2115 nTmp = MAXROW;
2116 if (nTmp > nRow2)
2118 nRow2 = nTmp;
2119 bHiddenEdge = TRUE;
2122 if ( nCol2 - nCol1 > 1 && nRow2 - nRow1 > 1 && !bHiddenEdge )
2124 // nur an den Raendern entlang
2125 PaintArea( nCol1, nRow1, nCol2, nRow1, SC_UPDATE_MARKS );
2126 PaintArea( nCol1, nRow1+1, nCol1, nRow2-1, SC_UPDATE_MARKS );
2127 PaintArea( nCol2, nRow1+1, nCol2, nRow2-1, SC_UPDATE_MARKS );
2128 PaintArea( nCol1, nRow2, nCol2, nRow2, SC_UPDATE_MARKS );
2130 else // alles am Stueck
2131 PaintArea( nCol1, nRow1, nCol2, nRow2, SC_UPDATE_MARKS );
2139 // fuer Chart-Daten-Markierung
2141 void ScTabView::AddHighlightRange( const ScRange& rRange, const Color& rColor )
2143 if (!pHighlightRanges)
2144 pHighlightRanges = new ScHighlightRanges;
2145 pHighlightRanges->Insert( new ScHighlightEntry( rRange, rColor ) );
2147 SCTAB nTab = aViewData.GetTabNo();
2148 if ( nTab >= rRange.aStart.Tab() && nTab <= rRange.aEnd.Tab() )
2149 PaintArea( rRange.aStart.Col(), rRange.aStart.Row(),
2150 rRange.aEnd.Col(), rRange.aEnd.Row(), SC_UPDATE_MARKS );
2153 void ScTabView::ClearHighlightRanges()
2155 if (pHighlightRanges)
2157 ScHighlightRanges* pTemp = pHighlightRanges;
2158 pHighlightRanges = NULL; // Repaint ohne Highlight
2160 SCTAB nTab = aViewData.GetTabNo();
2161 ULONG nCount = pTemp->Count();
2162 for (ULONG i=0; i<nCount; i++)
2164 ScHighlightEntry* pEntry = pTemp->GetObject( i );
2165 if (pEntry)
2167 ScRange aRange = pEntry->aRef;
2168 if ( nTab >= aRange.aStart.Tab() && nTab <= aRange.aEnd.Tab() )
2169 PaintArea( aRange.aStart.Col(), aRange.aStart.Row(),
2170 aRange.aEnd.Col(), aRange.aEnd.Row(), SC_UPDATE_MARKS );
2173 delete pTemp;
2177 void ScTabView::DoChartSelection(
2178 const uno::Sequence< chart2::data::HighlightedRange > & rHilightRanges )
2180 ClearHighlightRanges();
2182 for( sal_Int32 i=0; i<rHilightRanges.getLength(); ++i )
2184 Color aSelColor( rHilightRanges[i].PreferredColor );
2185 ScRangeList aRangeList;
2186 ScDocument* pDoc = aViewData.GetDocShell()->GetDocument();
2187 if( ScRangeStringConverter::GetRangeListFromString(
2188 aRangeList, rHilightRanges[i].RangeRepresentation, pDoc, pDoc->GetAddressConvention(), ';' ))
2190 for ( ScRangePtr p = aRangeList.First(); p; p = aRangeList.Next())
2192 if( rHilightRanges[i].Index == - 1 )
2193 AddHighlightRange( *p, aSelColor );
2194 else
2195 AddHighlightRange( lcl_getSubRangeByIndex( *p, rHilightRanges[i].Index ), aSelColor );
2201 // DrawDragRect - Drag&Drop-Rechteck zeichnen (XOR)
2203 //UNUSED2008-05 void ScTabView::DrawDragRect( SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
2204 //UNUSED2008-05 ScSplitPos ePos )
2205 //UNUSED2008-05 {
2206 //UNUSED2008-05 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX || aViewData.GetVSplitMode() == SC_SPLIT_FIX )
2207 //UNUSED2008-05 {
2208 //UNUSED2008-05 for (USHORT i=0; i<4; i++)
2209 //UNUSED2008-05 if (pGridWin[i])
2210 //UNUSED2008-05 if (pGridWin[i]->IsVisible())
2211 //UNUSED2008-05 pGridWin[i]->DrawDragRect( nStartX, nStartY, nEndX, nEndY );
2212 //UNUSED2008-05 }
2213 //UNUSED2008-05 else
2214 //UNUSED2008-05 pGridWin[ePos]->DrawDragRect( nStartX, nStartY, nEndX, nEndY );
2215 //UNUSED2008-05 }
2216 //UNUSED2008-05
2217 //UNUSED2008-05 // PaintCell - einzelne Zelle neu zeichnen
2218 //UNUSED2008-05
2219 //UNUSED2008-05 void ScTabView::PaintCell( SCCOL nCol, SCROW nRow, SCTAB nTab )
2220 //UNUSED2008-05 {
2221 //UNUSED2008-05 if ( aViewData.GetTabNo() == nTab )
2222 //UNUSED2008-05 {
2223 //UNUSED2008-05 USHORT i;
2224 //UNUSED2008-05 for (i=0; i<4; i++)
2225 //UNUSED2008-05 if (pGridWin[i])
2226 //UNUSED2008-05 if (pGridWin[i]->IsVisible())
2227 //UNUSED2008-05 pGridWin[i]->Draw( nCol, nRow, nCol, nRow );
2228 //UNUSED2008-05 }
2229 //UNUSED2008-05 }
2230 //UNUSED2008-05
2231 //UNUSED2008-05 void ScTabView::PaintLeftRow( SCROW nRow )
2232 //UNUSED2008-05 {
2233 //UNUSED2008-05 PaintLeftArea( nRow, nRow );
2234 //UNUSED2008-05 }
2235 //UNUSED2008-05
2236 //UNUSED2008-05 void ScTabView::PaintTopCol( SCCOL nCol )
2237 //UNUSED2008-05 {
2238 //UNUSED2008-05 PaintTopArea( nCol, nCol );
2239 //UNUSED2008-05 }
2241 // PaintGrid - Datenbereiche neu zeichnen
2243 void ScTabView::PaintGrid()
2245 USHORT i;
2246 for (i=0; i<4; i++)
2247 if (pGridWin[i])
2248 if (pGridWin[i]->IsVisible())
2249 pGridWin[i]->Invalidate();
2252 // PaintTop - obere Kontrollelemente neu zeichnen
2254 void ScTabView::PaintTop()
2256 USHORT i;
2257 for (i=0; i<2; i++)
2259 if (pColBar[i])
2260 pColBar[i]->Invalidate();
2261 if (pColOutline[i])
2262 pColOutline[i]->Invalidate();
2266 void ScTabView::CreateAnchorHandles(SdrHdlList& rHdl, const ScAddress& rAddress)
2268 UINT16 i;
2270 for(i=0; i<4; i++)
2272 if(pGridWin[i])
2274 if(pGridWin[i]->IsVisible())
2276 pGridWin[i]->CreateAnchorHandle(rHdl, rAddress);
2282 void ScTabView::PaintTopArea( SCCOL nStartCol, SCCOL nEndCol )
2284 // Pixel-Position der linken Kante
2286 if ( nStartCol < aViewData.GetPosX(SC_SPLIT_LEFT) ||
2287 nStartCol < aViewData.GetPosX(SC_SPLIT_RIGHT) )
2288 aViewData.RecalcPixPos();
2290 // Fixierung anpassen (UpdateFixX setzt HSplitPos neu)
2292 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX && nStartCol < aViewData.GetFixPosX() )
2293 if (aViewData.UpdateFixX())
2294 RepeatResize();
2296 // zeichnen
2298 if (nStartCol>0)
2299 --nStartCol; //! allgemeiner ?
2301 BOOL bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
2302 long nLayoutSign = bLayoutRTL ? -1 : 1;
2304 for (USHORT i=0; i<2; i++)
2306 ScHSplitPos eWhich = (ScHSplitPos) i;
2307 if (pColBar[eWhich])
2309 Size aWinSize = pColBar[eWhich]->GetSizePixel();
2310 long nStartX = aViewData.GetScrPos( nStartCol, 0, eWhich ).X();
2311 long nEndX;
2312 if (nEndCol >= MAXCOL)
2313 nEndX = bLayoutRTL ? 0 : ( aWinSize.Width()-1 );
2314 else
2315 nEndX = aViewData.GetScrPos( nEndCol+1, 0, eWhich ).X() - nLayoutSign;
2316 pColBar[eWhich]->Invalidate(
2317 Rectangle( nStartX, 0, nEndX, aWinSize.Height()-1 ) );
2319 if (pColOutline[eWhich])
2320 pColOutline[eWhich]->Invalidate();
2325 // PaintLeft - linke Kontrollelemente neu zeichnen
2327 void ScTabView::PaintLeft()
2329 USHORT i;
2330 for (i=0; i<2; i++)
2332 if (pRowBar[i])
2333 pRowBar[i]->Invalidate();
2334 if (pRowOutline[i])
2335 pRowOutline[i]->Invalidate();
2339 void ScTabView::PaintLeftArea( SCROW nStartRow, SCROW nEndRow )
2341 // Pixel-Position der oberen Kante
2343 if ( nStartRow < aViewData.GetPosY(SC_SPLIT_TOP) ||
2344 nStartRow < aViewData.GetPosY(SC_SPLIT_BOTTOM) )
2345 aViewData.RecalcPixPos();
2347 // Fixierung anpassen (UpdateFixY setzt VSplitPos neu)
2349 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && nStartRow < aViewData.GetFixPosY() )
2350 if (aViewData.UpdateFixY())
2351 RepeatResize();
2353 // zeichnen
2355 if (nStartRow>0)
2356 --nStartRow;
2358 for (USHORT i=0; i<2; i++)
2360 ScVSplitPos eWhich = (ScVSplitPos) i;
2361 if (pRowBar[eWhich])
2363 Size aWinSize = pRowBar[eWhich]->GetSizePixel();
2364 long nStartY = aViewData.GetScrPos( 0, nStartRow, eWhich ).Y();
2365 long nEndY;
2366 if (nEndRow >= MAXROW)
2367 nEndY = aWinSize.Height()-1;
2368 else
2369 nEndY = aViewData.GetScrPos( 0, nEndRow+1, eWhich ).Y() - 1;
2370 pRowBar[eWhich]->Invalidate(
2371 Rectangle( 0, nStartY, aWinSize.Width()-1, nEndY ) );
2373 if (pRowOutline[eWhich])
2374 pRowOutline[eWhich]->Invalidate();
2378 // InvertBlockMark - Block invertieren
2380 void ScTabView::InvertBlockMark(SCCOL nStartX, SCROW nStartY,
2381 SCCOL nEndX, SCROW nEndY)
2383 if ( !aViewData.IsActive() )
2384 return; // invertiert wird nur auf aktiver View
2386 PutInOrder( nStartX, nEndX );
2387 PutInOrder( nStartY, nEndY );
2389 ScMarkData& rMark = aViewData.GetMarkData();
2390 ScDocShell* pDocSh = aViewData.GetDocShell();
2391 ScDocument* pDoc = pDocSh->GetDocument();
2392 SCTAB nTab = aViewData.GetTabNo();
2394 if ( pDocSh->GetLockCount() )
2396 // if paint is locked, avoid repeated inverting
2397 // add repaint areas to paint lock data instead
2398 pDocSh->PostPaint( nStartX,nStartY,nTab, nEndX,nEndY,nTab, PAINT_GRID );
2399 return;
2402 BOOL bSingle = rMark.IsMultiMarked();
2403 BOOL bMerge = pDoc->HasAttrib( nStartX, nStartY, nTab, nEndX, nEndY, nTab,
2404 HASATTR_MERGED | HASATTR_OVERLAPPED );
2406 USHORT i;
2407 if ( bMerge || bSingle )
2409 for (i=0; i<4; i++)
2410 if (pGridWin[i])
2411 if (pGridWin[i]->IsVisible())
2412 pGridWin[i]->InvertSimple( nStartX, nStartY, nEndX, nEndY,
2413 bMerge, bBlockNeg );
2415 else
2417 for (i=0; i<4; i++)
2418 if (pGridWin[i])
2419 if (pGridWin[i]->IsVisible())
2421 ScSplitPos ePos = (ScSplitPos) i;
2422 Point aStartPoint = aViewData.GetScrPos( nStartX, nStartY, ePos );
2423 Point aEndPoint = aViewData.GetScrPos( nEndX+1, nEndY+1, ePos );
2424 if ( pDoc->IsLayoutRTL( nTab ) )
2426 long nTemp = aStartPoint.X();
2427 aStartPoint.X() = aEndPoint.X() + 1; // +1 - excluding start of nEndX+1
2428 aEndPoint.X() = nTemp;
2430 else
2431 aEndPoint.X() -= 1;
2432 aEndPoint.Y() -= 1;
2433 if ( aEndPoint.X() >= aStartPoint.X() && aEndPoint.Y() >= aStartPoint.Y() )
2435 MapMode aOld = pGridWin[ePos]->GetMapMode();
2436 pGridWin[ePos]->SetMapMode(MAP_PIXEL);
2437 pGridWin[ePos]->Invert( Rectangle(aStartPoint,aEndPoint), INVERT_HIGHLIGHT );
2438 pGridWin[ePos]->SetMapMode(aOld);
2439 pGridWin[ePos]->CheckInverted();
2445 // wenn Controls betroffen, neu malen
2448 BOOL bHide = TRUE; // wird Teil der Markierung aufgehoben ?
2449 if (rMark.IsMarked())
2451 ScRange aMarkRange;
2452 rMark.GetMarkArea( aMarkRange );
2453 if ( aMarkRange.aStart.Col() <= nStartX && aMarkRange.aEnd.Col() >= nEndX &&
2454 aMarkRange.aStart.Row() <= nStartY && aMarkRange.aEnd.Row() >= nEndY )
2456 bHide = FALSE; // der ganze Bereich ist markiert
2461 BOOL ScTabView::PaintExtras()
2463 BOOL bRet = FALSE;
2464 ScDocument* pDoc = aViewData.GetDocument();
2465 SCTAB nTab = aViewData.GetTabNo();
2466 if (!pDoc->HasTable(nTab)) // Tabelle geloescht ?
2468 SCTAB nCount = pDoc->GetTableCount();
2469 aViewData.SetTabNo(nCount-1);
2470 bRet = TRUE;
2472 pTabControl->UpdateStatus(); // TRUE = active
2473 return bRet;
2476 void ScTabView::RecalcPPT()
2478 // called after changes that require the PPT values to be recalculated
2479 // (currently from detective operations)
2481 double nOldX = aViewData.GetPPTX();
2482 double nOldY = aViewData.GetPPTY();
2484 aViewData.RefreshZoom(); // pre-calculate new PPT values
2486 BOOL bChangedX = ( aViewData.GetPPTX() != nOldX );
2487 BOOL bChangedY = ( aViewData.GetPPTY() != nOldY );
2488 if ( bChangedX || bChangedY )
2490 // call view SetZoom (including draw scale, split update etc)
2491 // and paint only if values changed
2493 Fraction aZoomX = aViewData.GetZoomX();
2494 Fraction aZoomY = aViewData.GetZoomY();
2495 SetZoom( aZoomX, aZoomY, FALSE );
2497 PaintGrid();
2498 if (bChangedX)
2499 PaintTop();
2500 if (bChangedY)
2501 PaintLeft();
2505 void ScTabView::ActivateView( BOOL bActivate, BOOL bFirst )
2507 if ( bActivate == aViewData.IsActive() && !bFirst )
2509 // keine Assertion mehr - kommt vor, wenn vorher im Drag&Drop
2510 // auf ein anderes Dokument umgeschaltet wurde
2511 return;
2514 // wird nur bei MDI-(De)Activate gerufen
2515 // aViewData.Activate hinten wegen Cursor-Show bei KillEditView
2516 // Markierung nicht mehr loeschen - wenn an der ViewData Activate(FALSE) gesetzt ist,
2517 // wird die Markierung nicht ausgegeben
2519 if (!bActivate)
2521 ScModule* pScMod = SC_MOD();
2522 BOOL bRefMode = pScMod->IsFormulaMode();
2524 // Referenzeingabe nicht abbrechen, um Referenzen auf
2525 // andere Dokumente zuzulassen
2527 if (!bRefMode)
2529 //pScMod->InputEnterHandler();
2531 // #80843# pass view to GetInputHdl, this view may not be current anymore
2532 ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
2533 if (pHdl)
2534 pHdl->EnterHandler();
2537 pTabControl->ActivateView(bActivate);
2538 PaintExtras();
2540 aViewData.Activate(bActivate);
2542 PaintBlock(FALSE); // Repaint, Markierung je nach Active-Status
2544 if (!bActivate)
2545 HideAllCursors(); // Cursor
2546 else if (!bFirst)
2547 ShowAllCursors();
2549 //HMHif (pDrawView)
2550 //HMH DrawShowMarkHdl(bActivate); // Drawing-Markierung
2552 if (bActivate)
2554 if ( bFirst )
2556 ScSplitPos eWin = aViewData.GetActivePart();
2557 DBG_ASSERT( pGridWin[eWin], "rottes Dokument, nicht alle SplitPos in GridWin" );
2558 if ( !pGridWin[eWin] )
2560 eWin = SC_SPLIT_BOTTOMLEFT;
2561 if ( !pGridWin[eWin] )
2563 short i;
2564 for ( i=0; i<4; i++ )
2566 if ( pGridWin[i] )
2568 eWin = (ScSplitPos) i;
2569 break; // for
2572 DBG_ASSERT( i<4, "und BUMM" );
2574 aViewData.SetActivePart( eWin );
2577 // hier nicht mehr selber GrabFocus rufen!
2578 // Wenn das Doc bearbeitet wird, ruft der Sfx selber GrabFocus am Fenster der Shell.
2579 // Wenn es z.B. ein Mailbody ist, darf es den Focus nicht bekommen (Bug #43638#)
2581 UpdateInputContext();
2583 else
2584 pGridWin[aViewData.GetActivePart()]->ClickExtern();
2587 void ScTabView::ActivatePart( ScSplitPos eWhich )
2589 ScSplitPos eOld = aViewData.GetActivePart();
2590 if ( eOld != eWhich )
2592 bInActivatePart = TRUE;
2594 BOOL bRefMode = SC_MOD()->IsFormulaMode();
2596 // #40565# the HasEditView call during SetCursor would fail otherwise
2597 if ( aViewData.HasEditView(eOld) && !bRefMode )
2598 UpdateInputLine();
2600 ScHSplitPos eOldH = WhichH(eOld);
2601 ScVSplitPos eOldV = WhichV(eOld);
2602 ScHSplitPos eNewH = WhichH(eWhich);
2603 ScVSplitPos eNewV = WhichV(eWhich);
2604 BOOL bTopCap = pColBar[eOldH] && pColBar[eOldH]->IsMouseCaptured();
2605 BOOL bLeftCap = pRowBar[eOldV] && pRowBar[eOldV]->IsMouseCaptured();
2607 BOOL bFocus = pGridWin[eOld]->HasFocus();
2608 BOOL bCapture = pGridWin[eOld]->IsMouseCaptured();
2609 if (bCapture)
2610 pGridWin[eOld]->ReleaseMouse();
2611 pGridWin[eOld]->ClickExtern();
2612 pGridWin[eOld]->HideCursor();
2613 pGridWin[eWhich]->HideCursor();
2614 aViewData.SetActivePart( eWhich );
2616 ScTabViewShell* pShell = aViewData.GetViewShell();
2617 pShell->WindowChanged();
2619 pSelEngine->SetWindow(pGridWin[eWhich]);
2620 pSelEngine->SetWhich(eWhich);
2621 pSelEngine->SetVisibleArea( Rectangle(Point(), pGridWin[eWhich]->GetOutputSizePixel()) );
2623 pGridWin[eOld]->MoveMouseStatus(*pGridWin[eWhich]);
2625 if ( bCapture || pGridWin[eWhich]->IsMouseCaptured() )
2627 // Tracking statt CaptureMouse, damit sauber abgebrochen werden kann
2628 // (SelectionEngine ruft CaptureMouse beim SetWindow)
2629 //! Irgendwann sollte die SelectionEngine selber StartTracking rufen!?!
2630 pGridWin[eWhich]->ReleaseMouse();
2631 pGridWin[eWhich]->StartTracking();
2634 if ( bTopCap && pColBar[eNewH] )
2636 pColBar[eOldH]->SetIgnoreMove(TRUE);
2637 pColBar[eNewH]->SetIgnoreMove(FALSE);
2638 pHdrSelEng->SetWindow( pColBar[eNewH] );
2639 long nWidth = pColBar[eNewH]->GetOutputSizePixel().Width();
2640 pHdrSelEng->SetVisibleArea( Rectangle( 0, LONG_MIN, nWidth-1, LONG_MAX ) );
2641 pColBar[eNewH]->CaptureMouse();
2643 if ( bLeftCap && pRowBar[eNewV] )
2645 pRowBar[eOldV]->SetIgnoreMove(TRUE);
2646 pRowBar[eNewV]->SetIgnoreMove(FALSE);
2647 pHdrSelEng->SetWindow( pRowBar[eNewV] );
2648 long nHeight = pRowBar[eNewV]->GetOutputSizePixel().Height();
2649 pHdrSelEng->SetVisibleArea( Rectangle( LONG_MIN, 0, LONG_MAX, nHeight-1 ) );
2650 pRowBar[eNewV]->CaptureMouse();
2652 aHdrFunc.SetWhich(eWhich);
2654 pGridWin[eOld]->ShowCursor();
2655 pGridWin[eWhich]->ShowCursor();
2657 SfxInPlaceClient* pClient = aViewData.GetViewShell()->GetIPClient();
2658 BOOL bOleActive = ( pClient && pClient->IsObjectInPlaceActive() );
2660 // #103823# don't switch ViewShell's active window during RefInput, because the focus
2661 // might change, and subsequent SetReference calls wouldn't find the right EditView
2662 if ( !bRefMode && !bOleActive )
2663 aViewData.GetViewShell()->SetWindow( pGridWin[eWhich] );
2665 if ( bFocus && !aViewData.IsAnyFillMode() && !bRefMode )
2667 // GrabFocus nur, wenn vorher das andere GridWindow den Focus hatte
2668 // (z.B. wegen Suchen & Ersetzen)
2669 //! aViewData.GetViewShell()->GetViewFrame()->GetWindow().GrabFocus();
2670 pGridWin[eWhich]->GrabFocus();
2673 bInActivatePart = FALSE;
2677 void ScTabView::HideListBox()
2679 for (USHORT i=0; i<4; i++)
2680 if (pGridWin[i])
2681 pGridWin[i]->ClickExtern();
2684 void ScTabView::UpdateInputContext()
2686 ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2687 if (pWin)
2688 pWin->UpdateInputContext();
2691 // GetGridWidth - Breite eines Ausgabebereichs (fuer ViewData)
2693 long ScTabView::GetGridWidth( ScHSplitPos eWhich )
2695 ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_LEFT ) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
2696 if (pGridWin[eGridWhich])
2697 return pGridWin[eGridWhich]->GetSizePixel().Width();
2698 else
2699 return 0;
2702 // GetGridHeight - Hoehe eines Ausgabebereichs (fuer ViewData)
2704 long ScTabView::GetGridHeight( ScVSplitPos eWhich )
2706 ScSplitPos eGridWhich = ( eWhich == SC_SPLIT_TOP ) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
2707 if (pGridWin[eGridWhich])
2708 return pGridWin[eGridWhich]->GetSizePixel().Height();
2709 else
2710 return 0;
2713 void ScTabView::UpdateInputLine()
2715 SC_MOD()->InputEnterHandler();
2718 void ScTabView::ZoomChanged()
2720 ScInputHandler* pHdl = SC_MOD()->GetInputHdl(aViewData.GetViewShell());
2721 if (pHdl)
2722 pHdl->SetRefScale( aViewData.GetZoomX(), aViewData.GetZoomY() );
2724 UpdateFixPos();
2726 UpdateScrollBars();
2728 // VisArea...
2729 // AW: Discussed with NN if there is a reason that new map mode was only set for one window,
2730 // but is not. Setting only on one window causes the first repaint to have the old mapMode
2731 // in three of four views, so the overlay will save the wrong content e.g. when zooming out.
2732 // Changing to setting map mode at all windows.
2733 sal_uInt32 a;
2735 for(a = 0L; a < 4L; a++)
2737 if(pGridWin[a])
2739 pGridWin[a]->SetMapMode(pGridWin[a]->GetDrawMapMode());
2743 SetNewVisArea();
2745 /* the old code
2746 ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2747 if (pWin)
2749 pWin->SetMapMode( pWin->GetDrawMapMode() ); // mit neuem Zoom
2750 SetNewVisArea(); // benutzt den gesetzten MapMode
2751 } */
2753 InterpretVisible(); // #69343# have everything calculated before painting
2755 SfxBindings& rBindings = aViewData.GetBindings();
2756 rBindings.Invalidate( SID_ATTR_ZOOM );
2757 rBindings.Invalidate( SID_ATTR_ZOOMSLIDER );
2759 HideNoteMarker();
2761 // AW: To not change too much, use pWin here
2762 ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2764 if ( pWin && aViewData.HasEditView( aViewData.GetActivePart() ) )
2766 // flush OverlayManager before changing the MapMode
2767 pWin->flushOverlayManager();
2769 // #93650# make sure the EditView's position and size are updated
2770 // with the right (logic, not drawing) MapMode
2771 pWin->SetMapMode( aViewData.GetLogicMode() );
2772 UpdateEditView();
2776 void ScTabView::CheckNeedsRepaint()
2778 USHORT i;
2779 for (i=0; i<4; i++)
2780 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
2781 pGridWin[i]->CheckNeedsRepaint();