1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26
27
28 //------------------------------------------------------------------
29
30 #if 0
31 #define _MACRODLG_HXX
32 #define _BIGINT_HXX
33 #define _SVCONTNR_HXX
34 #define BASIC_NODIALOGS
35 #define _SFXMNUITEM_HXX
36 #define _SVDXOUT_HXX
37 #define _SVDATTR_HXX
38 #define _SFXMNUITEM_HXX
39 #define _DLGCFG_HXX
40 #define _SFXMNUMGR_HXX
41 #define _SFXBASIC_HXX
42 #define _MODALDLG_HXX
43 #define _SFX_TEMPLDLG_HXX
44 #define _SFXSTBMGR_HXX
45 #define _SFXTBXMGR_HXX
46 #define _BASE_DLGS_HXX
47 #define _SFXIMGMGR_HXX
48 #define _SFXMNUMGR_HXX
49 #define _SFXSTBITEM_HXX
50 #define _SFXTBXCTRL_HXX
51 #define _PASSWD_HXX
52 //#define _SFXFILEDLG_HXX
53 //#define _SFXREQUEST_HXX
54 #define _SFXOBJFACE_HXX
55
56 #define _SDR_NOTRANSFORM
57 #define _SVDXOUT_HXX
58 #endif
59 #include <vcl/svapp.hxx>
60
61 ///////////////////////////////////////////////////////////////////////////
62 // NODRAW.HXX
63 // Erweiterte Konstanten, um CLOKs mit SVDRAW.HXX zu vermeiden
64 // Die u.a. Aenderungen nehmen vorgeschlagene Konstante vorweg
65 ///////////////////////////////////////////////////////////////////////////
66
67 #if 0
68 #define _SDR_NOTRANSFORM // Transformationen, selten verwendet
69 #define _SDR_NOTOUCH // Hit-Tests, selten verwendet
70
71 #define _SDR_NOUNDO // Undo-Objekte
72 #define _SDR_NOPAGEOBJ // SdrPageObj
73 #define _SDR_NOVIRTOBJ // SdrVirtObj
74 #define _SDR_NOGROUPOBJ // SdrGroupObj
75 #define _SDR_NOTEXTOBJ // SdrTextObj
76 #define _SDR_NOPATHOBJ // SdrPathObj
77 #define _SDR_NOEDGEOBJ // SdrEdgeObj
78 #define _SDR_NORECTOBJ // SdrRectObj
79 #define _SDR_NOCAPTIONOBJ // SdrCaptionObj
80 #define _SDR_NOCIRCLEOBJ // SdrCircleObj
81 #define _SDR_NOGRAFOBJ // SdrGrafObj
82 #define _SDR_NOOLE2OBJ // SdrOle2Obj
83 #endif
84
85 // Dieses define entfernt die VCControls aus SI.HXX
86
87 #define _SI_HXX // VCControls
88
89 ////////////////////// Umsetzen der Standard-Defines //////////////////////
90
91 //#define _SVDDRAG_HXX // SdrDragStat
92 #define _SVDPAGE_HXX // SdrPage
93
94 #ifdef _SDR_NOSURROGATEOBJ
95 #undef _SDR_NOSURROGATEOBJ
96 #define _SVDSURO_HXX
97 #endif
98
99 #ifdef _SDR_NOPAGEOBJ
100 #undef _SDR_NOPAGEOBJ
101 #define _SVDOPAGE_HXX
102 #endif
103
104 #ifdef _SDR_NOVIRTOBJ
105 #undef _SDR_NOVIRTOBJ
106 #define _SVDOVIRT_HXX
107 #endif
108
109 #ifdef _SDR_NOGROUPOBJ
110 #undef _SDR_NOGROUPOBJ
111 #define _SVDOGRP_HXX
112 #endif
113
114 #ifdef _SDR_NOTEXTOBJ
115 #undef _SDR_NOTEXTOBJ
116 #define _SVDOTEXT_HXX
117 #endif
118
119 #ifdef _SDR_NOPATHOBJ
120 #undef _SDR_NOPATHOBJ
121 #define _SVDOPATH_HXX
122 #endif
123
124 #ifdef _SDR_NOEDGEOBJ
125 #undef _SDR_NOEDGEOBJ
126 #define _SVDOEDGE_HXX
127 #endif
128
129 #ifdef _SDR_NORECTOBJ
130 #undef _SDR_NORECTOBJ
131 #define _SVDORECT_HXX
132 #else
133 #undef _SDVOTEXT_OBJ
134 #endif
135
136 #ifdef _SDR_NOCAPTIONOBJ
137 #undef _SDR_NOCAPTIONOBJ
138 #define _SVDCAPT_HXX
139 #endif
140
141 #ifdef _SDR_NOCIRCLEOBJ
142 #undef _SDR_NOCIRCLEOBJ
143 #define _SVDOCIRC_HXX
144 #endif
145
146 #ifdef _SDR_NOGRAFOBJ
147 #undef _SDR_NOGRAFOBJ
148 #define _SVDOGRAF_HXX
149 #else
150 #undef _SVDOTEXT_HXX
151 #undef _SVDORECT_HXX
152 #endif
153
154 #ifdef _SDR_NOOLE2OBJ
155 #undef _SDR_NOOLE2OBJ
156 #define _SVDOOLE2_HXX
157 #else
158 #undef _SVDOTEXT_HXX
159 #undef _SVDORECT_HXX
160 #endif
161
162 //#ifdef _SDR_NOVIEWS
163 // #define _SVDDRAG_HXX
164 //#endif
165
166 ////////////////////// Ende der SVDRAW-Modifikationen /////////////////////
167
168
169 // INCLUDE ---------------------------------------------------------------
170
171 #include "scitems.hxx"
172 #include <sfx2/viewfrm.hxx>
173 #include <sfx2/bindings.hxx>
174 #include <vcl/help.hxx>
175 #include <rtl/logfile.hxx>
176
177 #include "tabview.hxx"
178 #include "tabvwsh.hxx"
179 #include "document.hxx"
180 #include "gridwin.hxx"
181 #include "olinewin.hxx"
182 #include "olinetab.hxx"
183 #include "tabsplit.hxx"
184 #include "colrowba.hxx"
185 #include "tabcont.hxx"
186 #include "scmod.hxx"
187 #include "sc.hrc"
188 #include "viewutil.hxx"
189 #include "globstr.hrc"
190 #include "drawview.hxx"
191 #include "docsh.hxx"
192 #include "viewuno.hxx"
193 #include "AccessibilityHints.hxx"
194 #include "appoptio.hxx"
195
196 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
197
198 #include <string>
199 #include <algorithm>
200
201 #define SPLIT_MARGIN 30
202 #define SC_ICONSIZE 36
203
204 #define SC_SCROLLBAR_MIN 30
205 #define SC_TABBAR_MIN 6
206
207 // fuer Rad-Maus
208 #define SC_DELTA_ZOOM 10
209
210 using namespace ::com::sun::star;
211
212 // STATIC DATA -----------------------------------------------------------
213
214
215 //==================================================================
216
217 // Corner-Button
218
ScCornerButton(Window * pParent,ScViewData * pData,sal_Bool bAdditional)219 ScCornerButton::ScCornerButton( Window* pParent, ScViewData* pData, sal_Bool bAdditional ) :
220 Window( pParent, WinBits( 0 ) ),
221 pViewData( pData ),
222 bAdd( bAdditional )
223 {
224 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
225 SetBackground( rStyleSettings.GetFaceColor() );
226 EnableRTL( sal_False );
227 }
228
~ScCornerButton()229 __EXPORT ScCornerButton::~ScCornerButton()
230 {
231 }
232
Paint(const Rectangle & rRect)233 void __EXPORT ScCornerButton::Paint( const Rectangle& rRect )
234 {
235 Size aSize = GetOutputSizePixel();
236 long nPosX = aSize.Width()-1;
237 long nPosY = aSize.Height()-1;
238
239 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
240
241 Window::Paint(rRect);
242
243 sal_Bool bLayoutRTL = pViewData->GetDocument()->IsLayoutRTL( pViewData->GetTabNo() );
244 long nDarkX = bLayoutRTL ? 0 : nPosX;
245
246 if ( !bAdd && !rStyleSettings.GetHighContrastMode() )
247 {
248 // match the shaded look of column/row headers
249
250 Color aFace( rStyleSettings.GetFaceColor() );
251 Color aWhite( COL_WHITE );
252 Color aCenter( aFace );
253 aCenter.Merge( aWhite, 0xd0 ); // lighten up a bit
254 Color aOuter( aFace );
255 aOuter.Merge( aWhite, 0xa0 ); // lighten up more
256
257 long nCenterX = (aSize.Width() / 2) - 1;
258 long nCenterY = (aSize.Height() / 2) - 1;
259
260 SetLineColor();
261 SetFillColor(aCenter);
262 DrawRect( Rectangle( nCenterX, nCenterY, nCenterX, nPosY ) );
263 DrawRect( Rectangle( nCenterX, nCenterY, nDarkX, nCenterY ) );
264 SetFillColor(aOuter);
265 DrawRect( Rectangle( 0, 0, nPosX, nCenterY-1 ) );
266 if ( bLayoutRTL )
267 DrawRect( Rectangle( nCenterX+1, nCenterY, nPosX, nPosY ) );
268 else
269 DrawRect( Rectangle( 0, nCenterY, nCenterX-1, nPosY ) );
270 }
271
272 // both buttons have the same look now - only dark right/bottom lines
273 SetLineColor( rStyleSettings.GetDarkShadowColor() );
274 DrawLine( Point(0,nPosY), Point(nPosX,nPosY) );
275 DrawLine( Point(nDarkX,0), Point(nDarkX,nPosY) );
276 }
277
StateChanged(StateChangedType nType)278 void ScCornerButton::StateChanged( StateChangedType nType )
279 {
280 Window::StateChanged( nType );
281
282 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
283 SetBackground( rStyleSettings.GetFaceColor() );
284 Invalidate();
285 }
286
287 // -----------------------------------------------------------------------
288
DataChanged(const DataChangedEvent & rDCEvt)289 void ScCornerButton::DataChanged( const DataChangedEvent& rDCEvt )
290 {
291 Window::DataChanged( rDCEvt );
292
293 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
294 SetBackground( rStyleSettings.GetFaceColor() );
295 Invalidate();
296 }
297
298
Resize()299 void __EXPORT ScCornerButton::Resize()
300 {
301 Invalidate();
302 }
303
MouseButtonDown(const MouseEvent & rMEvt)304 void __EXPORT ScCornerButton::MouseButtonDown( const MouseEvent& rMEvt )
305 {
306 ScModule* pScMod = SC_MOD();
307 sal_Bool bDisable = pScMod->IsFormulaMode() || pScMod->IsModalMode();
308 if (!bDisable)
309 {
310 ScTabViewShell* pViewSh = pViewData->GetViewShell();
311 pViewSh->SetActive(); // Appear und SetViewFrame
312 pViewSh->ActiveGrabFocus();
313
314 sal_Bool bControl = rMEvt.IsMod1();
315 pViewSh->SelectAll( bControl );
316 }
317 }
318
319 //==================================================================
320
lcl_HasColOutline(const ScViewData & rViewData)321 sal_Bool lcl_HasColOutline( const ScViewData& rViewData )
322 {
323 const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo());
324 if (pTable)
325 {
326 const ScOutlineArray* pArray = pTable->GetColArray();
327 if ( pArray->GetDepth() > 0 )
328 return sal_True;
329 }
330 return sal_False;
331 }
332
lcl_HasRowOutline(const ScViewData & rViewData)333 sal_Bool lcl_HasRowOutline( const ScViewData& rViewData )
334 {
335 const ScOutlineTable* pTable = rViewData.GetDocument()->GetOutlineTable(rViewData.GetTabNo());
336 if (pTable)
337 {
338 const ScOutlineArray* pArray = pTable->GetRowArray();
339 if ( pArray->GetDepth() > 0 )
340 return sal_True;
341 }
342 return sal_False;
343 }
344
345 //==================================================================
346
347 // Init und Konstruktoren
348 // ScTabView::Init() in tabview5.cxx wegen out of keys
349
350
351 #define TABVIEW_INIT \
352 pSelEngine( NULL ), \
353 aFunctionSet( &aViewData ), \
354 pHdrSelEng( NULL ), \
355 aHdrFunc( &aViewData ), \
356 pDrawView( NULL ), \
357 bDrawSelMode( sal_False ), \
358 aVScrollTop( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ), \
359 aVScrollBottom( pFrameWin, WinBits( WB_VSCROLL | WB_DRAG ) ), \
360 aHScrollLeft( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ), \
361 aHScrollRight( pFrameWin, WinBits( WB_HSCROLL | WB_DRAG ) ), \
362 aCornerButton( pFrameWin, &aViewData, sal_False ), \
363 aTopButton( pFrameWin, &aViewData, sal_True ), \
364 aScrollBarBox( pFrameWin, WB_SIZEABLE ), \
365 pInputHintWindow( NULL ), \
366 pPageBreakData( NULL ), \
367 pHighlightRanges( NULL ), \
368 pBrushDocument( NULL ), \
369 pDrawBrushSet( NULL ), \
370 bLockPaintBrush( sal_False ), \
371 pTimerWindow( NULL ), \
372 nTipVisible( 0 ), \
373 bDragging( sal_False ), \
374 bIsBlockMode( sal_False ), \
375 bBlockNeg( sal_False ), \
376 bBlockCols( sal_False ), \
377 bBlockRows( sal_False ), \
378 mfPendingTabBarWidth( -1.0 ), \
379 bMinimized( sal_False ), \
380 bInUpdateHeader( sal_False ), \
381 bInActivatePart( sal_False ), \
382 bInZoomUpdate( sal_False ), \
383 bMoveIsShift( sal_False ), \
384 bNewStartIfMarking( sal_False )
385
386
ScTabView(Window * pParent,ScDocShell & rDocSh,ScTabViewShell * pViewShell)387 ScTabView::ScTabView( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ) :
388 pFrameWin( pParent ),
389 aViewData( &rDocSh, pViewShell ),
390 TABVIEW_INIT
391 {
392 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScTabView::ScTabView" );
393
394 Init();
395 }
396
397 //UNUSED2009-05 ScTabView::ScTabView( Window* pParent, const ScTabView& rScTabView, ScTabViewShell* pViewShell ) :
398 //UNUSED2009-05 pFrameWin( pParent ),
399 //UNUSED2009-05 aViewData( rScTabView.aViewData ),
400 //UNUSED2009-05 TABVIEW_INIT
401 //UNUSED2009-05 {
402 //UNUSED2009-05 RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScTabView::ScTabView" );
403 //UNUSED2009-05
404 //UNUSED2009-05 aViewData.SetViewShell( pViewShell );
405 //UNUSED2009-05 Init();
406 //UNUSED2009-05
407 //UNUSED2009-05 UpdateShow();
408 //UNUSED2009-05 if ( aViewData.GetActivePart() != SC_SPLIT_BOTTOMLEFT )
409 //UNUSED2009-05 pGridWin[SC_SPLIT_BOTTOMLEFT]->Show();
410 //UNUSED2009-05
411 //UNUSED2009-05 InvalidateSplit();
412 //UNUSED2009-05 }
413
414 void ScTabView::InitScrollBar( ScrollBar& rScrollBar, long nMaxVal )
415 {
416 rScrollBar.SetRange( Range( 0, nMaxVal ) );
417 rScrollBar.SetLineSize( 1 );
418 rScrollBar.SetPageSize( 1 ); // wird getrennt abgefragt
419 rScrollBar.SetVisibleSize( 10 ); // wird bei Resize neu gesetzt
420
421 rScrollBar.SetScrollHdl( LINK(this, ScTabView, ScrollHdl) );
422 rScrollBar.SetEndScrollHdl( LINK(this, ScTabView, EndScrollHdl) );
423 }
424
425 // Scroll-Timer
426
SetTimer(ScGridWindow * pWin,const MouseEvent & rMEvt)427 void ScTabView::SetTimer( ScGridWindow* pWin, const MouseEvent& rMEvt )
428 {
429 pTimerWindow = pWin;
430 aTimerMEvt = rMEvt;
431 aScrollTimer.Start();
432 }
433
ResetTimer()434 void ScTabView::ResetTimer()
435 {
436 aScrollTimer.Stop();
437 pTimerWindow = NULL;
438 }
439
IMPL_LINK(ScTabView,TimerHdl,Timer *,EMPTYARG)440 IMPL_LINK( ScTabView, TimerHdl, Timer*, EMPTYARG )
441 {
442 // aScrollTimer.Stop();
443 if (pTimerWindow)
444 pTimerWindow->MouseMove( aTimerMEvt );
445
446 return 0;
447 }
448
449 // --- Resize ---------------------------------------------------------------------
450
lcl_SetPosSize(Window & rWindow,const Point & rPos,const Size & rSize,long nTotalWidth,sal_Bool bLayoutRTL)451 void lcl_SetPosSize( Window& rWindow, const Point& rPos, const Size& rSize,
452 long nTotalWidth, sal_Bool bLayoutRTL )
453 {
454 Point aNewPos = rPos;
455 if ( bLayoutRTL )
456 {
457 aNewPos.X() = nTotalWidth - rPos.X() - rSize.Width();
458 if ( aNewPos == rWindow.GetPosPixel() && rSize.Width() != rWindow.GetSizePixel().Width() )
459 {
460 // Document windows are manually painted right-to-left, so they need to
461 // be repainted if the size changes.
462 rWindow.Invalidate();
463 }
464 }
465 rWindow.SetPosSizePixel( aNewPos, rSize );
466 }
467
DoResize(const Point & rOffset,const Size & rSize,sal_Bool bInner)468 void ScTabView::DoResize( const Point& rOffset, const Size& rSize, sal_Bool bInner )
469 {
470 HideListBox();
471
472 sal_Bool bHasHint = ( pInputHintWindow != NULL );
473 if (bHasHint)
474 RemoveHintWindow();
475
476 sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
477 long nTotalWidth = rSize.Width();
478 if ( bLayoutRTL )
479 nTotalWidth += 2*rOffset.X();
480
481 sal_Bool bVScroll = aViewData.IsVScrollMode();
482 sal_Bool bHScroll = aViewData.IsHScrollMode();
483 sal_Bool bTabControl = aViewData.IsTabMode();
484 sal_Bool bHeaders = aViewData.IsHeaderMode();
485 sal_Bool bOutlMode = aViewData.IsOutlineMode();
486 sal_Bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
487 sal_Bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
488
489 // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden:
490 SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode();
491 if ( eMode == SCROLLING_NO )
492 bHScroll = bVScroll = sal_False;
493 else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ???
494 bHScroll = bVScroll = sal_True;
495
496 if ( aViewData.GetDocShell()->IsPreview() )
497 bHScroll = bVScroll = bTabControl = bHeaders = bOutlMode = bHOutline = bVOutline = sal_False;
498
499 long nBarX = 0;
500 long nBarY = 0;
501 long nOutlineX = 0;
502 long nOutlineY = 0;
503 long nOutPosX;
504 long nOutPosY;
505
506 long nPosX = rOffset.X();
507 long nPosY = rOffset.Y();
508 long nSizeX = rSize.Width();
509 long nSizeY = rSize.Height();
510 long nSize1;
511
512 bMinimized = ( nSizeX<=SC_ICONSIZE || nSizeY<=SC_ICONSIZE );
513 if ( bMinimized )
514 return;
515
516 long nSplitSizeX = SPLIT_HANDLE_SIZE;
517 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
518 nSplitSizeX = 1;
519 long nSplitSizeY = SPLIT_HANDLE_SIZE;
520 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
521 nSplitSizeY = 1;
522
523 const long nOverlap = 0; // ScrollBar::GetWindowOverlapPixel();
524
525 aBorderPos = rOffset;
526 aFrameSize = rSize;
527
528 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
529 if ( aViewData.GetHSplitPos() > nSizeX - SPLIT_MARGIN )
530 {
531 aViewData.SetHSplitMode( SC_SPLIT_NONE );
532 if ( WhichH( aViewData.GetActivePart() ) == SC_SPLIT_RIGHT )
533 ActivatePart( SC_SPLIT_BOTTOMLEFT );
534 InvalidateSplit();
535 // UpdateShow();
536 }
537 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
538 if ( aViewData.GetVSplitPos() > nSizeY - SPLIT_MARGIN )
539 {
540 aViewData.SetVSplitMode( SC_SPLIT_NONE );
541 if ( WhichV( aViewData.GetActivePart() ) == SC_SPLIT_TOP )
542 ActivatePart( SC_SPLIT_BOTTOMLEFT );
543 InvalidateSplit();
544 // UpdateShow();
545 }
546
547 UpdateShow();
548
549 if (bHScroll || bVScroll) // Scrollbars horizontal oder vertikal
550 {
551 long nScrollBarSize = pFrameWin->GetSettings().GetStyleSettings().GetScrollBarSize();
552 if (bVScroll)
553 {
554 // nBarX = aVScrollBottom.GetSizePixel().Width();
555 nBarX = nScrollBarSize;
556 nSizeX -= nBarX - nOverlap;
557 }
558 if (bHScroll)
559 {
560 // nBarY = aHScrollLeft.GetSizePixel().Height();
561 nBarY = nScrollBarSize;
562 nSizeY -= nBarY - nOverlap;
563 }
564
565 // window at the bottom right
566 lcl_SetPosSize( aScrollBarBox, Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ),
567 nTotalWidth, bLayoutRTL );
568
569 if (bHScroll) // Scrollbars horizontal
570 {
571 long nSizeLt = 0; // left scroll bar
572 long nSizeRt = 0; // right scroll bar
573 long nSizeSp = 0; // splitter
574
575 switch (aViewData.GetHSplitMode())
576 {
577 case SC_SPLIT_NONE:
578 nSizeSp = nSplitSizeX;
579 nSizeLt = nSizeX - nSizeSp + nOverlap; // Ecke ueberdecken
580 break;
581 case SC_SPLIT_NORMAL:
582 nSizeSp = nSplitSizeX;
583 nSizeLt = aViewData.GetHSplitPos();
584 break;
585 case SC_SPLIT_FIX:
586 nSizeSp = 0;
587 nSizeLt = 0;
588 break;
589 }
590 nSizeRt = nSizeX - nSizeLt - nSizeSp;
591
592 long nTabSize = 0;
593 if (bTabControl)
594 {
595 // pending relative tab bar width from extended document options
596 if( mfPendingTabBarWidth >= 0.0 )
597 {
598 SetRelTabBarWidth( mfPendingTabBarWidth );
599 mfPendingTabBarWidth = -1.0;
600 }
601
602 nTabSize = pTabControl->GetSizePixel().Width()-nOverlap;
603
604 if ( aViewData.GetHSplitMode() != SC_SPLIT_FIX ) // bei linkem Scrollbar
605 {
606 if (nTabSize > nSizeLt-SC_SCROLLBAR_MIN) nTabSize = nSizeLt-SC_SCROLLBAR_MIN;
607 if (nTabSize < SC_TABBAR_MIN) nTabSize = SC_TABBAR_MIN;
608 nSizeLt -= nTabSize;
609 }
610 else // bei rechtem Scrollbar
611 {
612 if (nTabSize > nSizeRt-SC_SCROLLBAR_MIN) nTabSize = nSizeRt-SC_SCROLLBAR_MIN;
613 if (nTabSize < SC_TABBAR_MIN) nTabSize = SC_TABBAR_MIN;
614 nSizeRt -= nTabSize;
615 }
616 }
617
618 lcl_SetPosSize( *pTabControl, Point(nPosX-nOverlap, nPosY+nSizeY),
619 Size(nTabSize+nOverlap, nBarY), nTotalWidth, bLayoutRTL );
620 pTabControl->SetSheetLayoutRTL( bLayoutRTL );
621
622 lcl_SetPosSize( aHScrollLeft, Point(nPosX+nTabSize-nOverlap, nPosY+nSizeY),
623 Size(nSizeLt+2*nOverlap, nBarY), nTotalWidth, bLayoutRTL );
624 lcl_SetPosSize( *pHSplitter, Point( nPosX+nTabSize+nSizeLt, nPosY+nSizeY ),
625 Size( nSizeSp, nBarY ), nTotalWidth, bLayoutRTL );
626 lcl_SetPosSize( aHScrollRight, Point(nPosX+nTabSize+nSizeLt+nSizeSp-nOverlap,
627 nPosY+nSizeY),
628 Size(nSizeRt+2*nOverlap, nBarY), nTotalWidth, bLayoutRTL );
629
630 // SetDragRectPixel is done below
631 }
632
633 if (bVScroll) // Scrollbars vertikal
634 {
635 long nSizeUp = 0; // upper scroll bar
636 long nSizeSp = 0; // splitter
637 long nSizeDn; // unterer Scrollbar
638
639 switch (aViewData.GetVSplitMode())
640 {
641 case SC_SPLIT_NONE:
642 nSizeUp = 0;
643 nSizeSp = nSplitSizeY;
644 break;
645 case SC_SPLIT_NORMAL:
646 nSizeUp = aViewData.GetVSplitPos();
647 nSizeSp = nSplitSizeY;
648 break;
649 case SC_SPLIT_FIX:
650 nSizeUp = 0;
651 nSizeSp = 0;
652 break;
653 }
654 nSizeDn = nSizeY - nSizeUp - nSizeSp;
655
656 lcl_SetPosSize( aVScrollTop, Point(nPosX+nSizeX, nPosY-nOverlap),
657 Size(nBarX,nSizeUp+2*nOverlap), nTotalWidth, bLayoutRTL );
658 lcl_SetPosSize( *pVSplitter, Point( nPosX+nSizeX, nPosY+nSizeUp ),
659 Size( nBarX, nSizeSp ), nTotalWidth, bLayoutRTL );
660 lcl_SetPosSize( aVScrollBottom, Point(nPosX+nSizeX,
661 nPosY+nSizeUp+nSizeSp-nOverlap),
662 Size(nBarX, nSizeDn+2*nOverlap), nTotalWidth, bLayoutRTL );
663
664 // SetDragRectPixel is done below
665 }
666 }
667
668 // SetDragRectPixel auch ohne Scrollbars etc., wenn schon gesplittet ist
669 if ( bHScroll || aViewData.GetHSplitMode() != SC_SPLIT_NONE )
670 pHSplitter->SetDragRectPixel(
671 Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin );
672 if ( bVScroll || aViewData.GetVSplitMode() != SC_SPLIT_NONE )
673 pVSplitter->SetDragRectPixel(
674 Rectangle( nPosX, nPosY, nPosX+nSizeX, nPosY+nSizeY ), pFrameWin );
675
676 if (bTabControl && ! bHScroll )
677 {
678 nBarY = aHScrollLeft.GetSizePixel().Height();
679 nBarX = aVScrollBottom.GetSizePixel().Width();
680
681 nSize1 = nSizeX + nOverlap;
682
683 long nTabSize = nSize1;
684 if (nTabSize < 0) nTabSize = 0;
685
686 lcl_SetPosSize( *pTabControl, Point(nPosX-nOverlap, nPosY+nSizeY-nBarY),
687 Size(nTabSize+nOverlap, nBarY), nTotalWidth, bLayoutRTL );
688 nSizeY -= nBarY - nOverlap;
689 lcl_SetPosSize( aScrollBarBox, Point( nPosX+nSizeX, nPosY+nSizeY ), Size( nBarX, nBarY ),
690 nTotalWidth, bLayoutRTL );
691
692 if( bVScroll )
693 {
694 Size aVScrSize = aVScrollBottom.GetSizePixel();
695 aVScrSize.Height() -= nBarY;
696 aVScrollBottom.SetSizePixel( aVScrSize );
697 }
698 }
699
700 nOutPosX = nPosX;
701 nOutPosY = nPosY;
702
703 // Outline-Controls
704 if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
705 {
706 nOutlineX = pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
707 nSizeX -= nOutlineX;
708 nPosX += nOutlineX;
709 }
710 if (bHOutline && pColOutline[SC_SPLIT_LEFT])
711 {
712 nOutlineY = pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
713 nSizeY -= nOutlineY;
714 nPosY += nOutlineY;
715 }
716
717 if (bHeaders) // Spalten/Zeilen-Header
718 {
719 nBarX = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
720 nBarY = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
721 nSizeX -= nBarX;
722 nSizeY -= nBarY;
723 nPosX += nBarX;
724 nPosY += nBarY;
725 }
726 else
727 nBarX = nBarY = 0;
728
729 //
730 // Splitter auswerten
731 //
732
733 long nLeftSize = nSizeX;
734 long nRightSize = 0;
735 long nTopSize = 0;
736 long nBottomSize = nSizeY;
737 long nSplitPosX = nPosX;
738 long nSplitPosY = nPosY;
739
740 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
741 {
742 long nSplitHeight = rSize.Height();
743 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
744 {
745 // Fixier-Splitter nicht mit Scrollbar/TabBar ueberlappen lassen
746 if ( bHScroll )
747 nSplitHeight -= aHScrollLeft.GetSizePixel().Height();
748 else if ( bTabControl && pTabControl )
749 nSplitHeight -= pTabControl->GetSizePixel().Height();
750 }
751 nSplitPosX = aViewData.GetHSplitPos();
752 lcl_SetPosSize( *pHSplitter,
753 Point( nSplitPosX, nOutPosY ), Size( nSplitSizeX, nSplitHeight ), nTotalWidth, bLayoutRTL );
754 nLeftSize = nSplitPosX - nPosX;
755 nSplitPosX += nSplitSizeX;
756 nRightSize = nSizeX - nLeftSize - nSplitSizeX;
757 }
758 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
759 {
760 long nSplitWidth = rSize.Width();
761 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX && bVScroll )
762 nSplitWidth -= aVScrollBottom.GetSizePixel().Width();
763 nSplitPosY = aViewData.GetVSplitPos();
764 lcl_SetPosSize( *pVSplitter,
765 Point( nOutPosX, nSplitPosY ), Size( nSplitWidth, nSplitSizeY ), nTotalWidth, bLayoutRTL );
766 nTopSize = nSplitPosY - nPosY;
767 nSplitPosY += nSplitSizeY;
768 nBottomSize = nSizeY - nTopSize - nSplitSizeY;
769 }
770
771 // ShowHide fuer pColOutline / pRowOutline passiert in UpdateShow
772
773 if (bHOutline) // Outline-Controls
774 {
775 if (pColOutline[SC_SPLIT_LEFT])
776 {
777 pColOutline[SC_SPLIT_LEFT]->SetHeaderSize( nBarX );
778 lcl_SetPosSize( *pColOutline[SC_SPLIT_LEFT],
779 Point(nPosX-nBarX,nOutPosY), Size(nLeftSize+nBarX,nOutlineY), nTotalWidth, bLayoutRTL );
780 }
781 if (pColOutline[SC_SPLIT_RIGHT])
782 {
783 pColOutline[SC_SPLIT_RIGHT]->SetHeaderSize( 0 ); // always call to update RTL flag
784 lcl_SetPosSize( *pColOutline[SC_SPLIT_RIGHT],
785 Point(nSplitPosX,nOutPosY), Size(nRightSize,nOutlineY), nTotalWidth, bLayoutRTL );
786 }
787 }
788 if (bVOutline)
789 {
790 if (nTopSize)
791 {
792 if (pRowOutline[SC_SPLIT_TOP] && pRowOutline[SC_SPLIT_BOTTOM])
793 {
794 pRowOutline[SC_SPLIT_TOP]->SetHeaderSize( nBarY );
795 lcl_SetPosSize( *pRowOutline[SC_SPLIT_TOP],
796 Point(nOutPosX,nPosY-nBarY), Size(nOutlineX,nTopSize+nBarY), nTotalWidth, bLayoutRTL );
797 pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( 0 );
798 lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM],
799 Point(nOutPosX,nSplitPosY), Size(nOutlineX,nBottomSize), nTotalWidth, bLayoutRTL );
800 }
801 }
802 else if (pRowOutline[SC_SPLIT_BOTTOM])
803 {
804 pRowOutline[SC_SPLIT_BOTTOM]->SetHeaderSize( nBarY );
805 lcl_SetPosSize( *pRowOutline[SC_SPLIT_BOTTOM],
806 Point(nOutPosX,nSplitPosY-nBarY), Size(nOutlineX,nBottomSize+nBarY), nTotalWidth, bLayoutRTL );
807 }
808 }
809 if (bHOutline && bVOutline)
810 {
811 lcl_SetPosSize( aTopButton, Point(nOutPosX,nOutPosY), Size(nOutlineX,nOutlineY), nTotalWidth, bLayoutRTL );
812 aTopButton.Show();
813 }
814 else
815 aTopButton.Hide();
816
817 if (bHeaders) // Spalten/Zeilen-Header
818 {
819 lcl_SetPosSize( *pColBar[SC_SPLIT_LEFT],
820 Point(nPosX,nPosY-nBarY), Size(nLeftSize,nBarY), nTotalWidth, bLayoutRTL );
821 if (pColBar[SC_SPLIT_RIGHT])
822 lcl_SetPosSize( *pColBar[SC_SPLIT_RIGHT],
823 Point(nSplitPosX,nPosY-nBarY), Size(nRightSize,nBarY), nTotalWidth, bLayoutRTL );
824
825 if (pRowBar[SC_SPLIT_TOP])
826 lcl_SetPosSize( *pRowBar[SC_SPLIT_TOP],
827 Point(nPosX-nBarX,nPosY), Size(nBarX,nTopSize), nTotalWidth, bLayoutRTL );
828 lcl_SetPosSize( *pRowBar[SC_SPLIT_BOTTOM],
829 Point(nPosX-nBarX,nSplitPosY), Size(nBarX,nBottomSize), nTotalWidth, bLayoutRTL );
830
831 lcl_SetPosSize( aCornerButton, Point(nPosX-nBarX,nPosY-nBarY), Size(nBarX,nBarY), nTotalWidth, bLayoutRTL );
832 aCornerButton.Show();
833 pColBar[SC_SPLIT_LEFT]->Show();
834 pRowBar[SC_SPLIT_BOTTOM]->Show();
835 }
836 else
837 {
838 aCornerButton.Hide();
839 pColBar[SC_SPLIT_LEFT]->Hide(); // immer da
840 pRowBar[SC_SPLIT_BOTTOM]->Hide();
841 }
842
843
844 // Grid-Windows
845
846 if (bInner)
847 {
848 long nInnerPosX = bLayoutRTL ? ( nTotalWidth - nPosX - nLeftSize ) : nPosX;
849 pGridWin[SC_SPLIT_BOTTOMLEFT]->SetPosPixel( Point(nInnerPosX,nSplitPosY) );
850 }
851 else
852 {
853 lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMLEFT],
854 Point(nPosX,nSplitPosY), Size(nLeftSize,nBottomSize), nTotalWidth, bLayoutRTL );
855 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
856 lcl_SetPosSize( *pGridWin[SC_SPLIT_BOTTOMRIGHT],
857 Point(nSplitPosX,nSplitPosY), Size(nRightSize,nBottomSize), nTotalWidth, bLayoutRTL );
858 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
859 lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPLEFT],
860 Point(nPosX,nPosY), Size(nLeftSize,nTopSize), nTotalWidth, bLayoutRTL );
861 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE && aViewData.GetVSplitMode() != SC_SPLIT_NONE )
862 lcl_SetPosSize( *pGridWin[SC_SPLIT_TOPRIGHT],
863 Point(nSplitPosX,nPosY), Size(nRightSize,nTopSize), nTotalWidth, bLayoutRTL );
864 }
865
866 //
867 // Scrollbars updaten
868 //
869
870 if (!bInUpdateHeader)
871 {
872 UpdateScrollBars(); // Scrollbars nicht beim Scrollen neu setzen
873 UpdateHeaderWidth();
874
875 InterpretVisible(); // #69343# have everything calculated before painting
876 }
877
878 if (bHasHint)
879 TestHintWindow(); // neu positionieren
880
881 UpdateVarZoom(); // update variable zoom types (after resizing GridWindows)
882
883 if (aViewData.GetViewShell()->HasAccessibilityObjects())
884 aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_WINDOWRESIZED));
885 }
886
UpdateVarZoom()887 void ScTabView::UpdateVarZoom()
888 {
889 // update variable zoom types
890
891 SvxZoomType eZoomType = GetZoomType();
892 if ( eZoomType != SVX_ZOOM_PERCENT && !bInZoomUpdate )
893 {
894 bInZoomUpdate = sal_True;
895 const Fraction& rOldX = GetViewData()->GetZoomX();
896 const Fraction& rOldY = GetViewData()->GetZoomY();
897 long nOldPercent = ( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator();
898 sal_uInt16 nNewZoom = CalcZoom( eZoomType, (sal_uInt16)nOldPercent );
899 Fraction aNew( nNewZoom, 100 );
900
901 if ( aNew != rOldX || aNew != rOldY )
902 {
903 SetZoom( aNew, aNew, sal_False ); // always separately per sheet
904 PaintGrid();
905 PaintTop();
906 PaintLeft();
907 aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
908 aViewData.GetViewShell()->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
909 }
910 bInZoomUpdate = sal_False;
911 }
912 }
913
UpdateFixPos()914 void ScTabView::UpdateFixPos()
915 {
916 sal_Bool bResize = sal_False;
917 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
918 if (aViewData.UpdateFixX())
919 bResize = sal_True;
920 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
921 if (aViewData.UpdateFixY())
922 bResize = sal_True;
923 if (bResize)
924 RepeatResize(sal_False);
925 }
926
RepeatResize(sal_Bool bUpdateFix)927 void ScTabView::RepeatResize( sal_Bool bUpdateFix )
928 {
929 if ( bUpdateFix )
930 {
931 ScSplitMode eHSplit = aViewData.GetHSplitMode();
932 ScSplitMode eVSplit = aViewData.GetVSplitMode();
933
934 // #i46796# UpdateFixX / UpdateFixY uses GetGridOffset, which requires the
935 // outline windows to be available. So UpdateShow has to be called before
936 // (also called from DoResize).
937 if ( eHSplit == SC_SPLIT_FIX || eVSplit == SC_SPLIT_FIX )
938 UpdateShow();
939
940 if ( eHSplit == SC_SPLIT_FIX )
941 aViewData.UpdateFixX();
942 if ( eVSplit == SC_SPLIT_FIX )
943 aViewData.UpdateFixY();
944 }
945
946 DoResize( aBorderPos, aFrameSize );
947
948 //! Border muss neu gesetzt werden ???
949 }
950
GetBorderSize(SvBorder & rBorder,const Size &)951 void ScTabView::GetBorderSize( SvBorder& rBorder, const Size& /* rSize */ )
952 {
953 sal_Bool bScrollBars = aViewData.IsVScrollMode();
954 sal_Bool bHeaders = aViewData.IsHeaderMode();
955 sal_Bool bOutlMode = aViewData.IsOutlineMode();
956 sal_Bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
957 sal_Bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
958 sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
959
960 rBorder = SvBorder();
961
962 if (bScrollBars) // Scrollbars horizontal oder vertikal
963 {
964 rBorder.Right() += aVScrollBottom.GetSizePixel().Width();
965 rBorder.Bottom() += aHScrollLeft.GetSizePixel().Height();
966 }
967
968 // Outline-Controls
969 if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
970 rBorder.Left() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
971 if (bHOutline && pColOutline[SC_SPLIT_LEFT])
972 rBorder.Top() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
973
974 if (bHeaders) // Spalten/Zeilen-Header
975 {
976 rBorder.Left() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
977 rBorder.Top() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
978 }
979
980 if ( bLayoutRTL )
981 ::std::swap( rBorder.Left(), rBorder.Right() );
982 }
983
IMPL_LINK(ScTabView,TabBarResize,void *,EMPTYARG)984 IMPL_LINK( ScTabView, TabBarResize, void*, EMPTYARG )
985 {
986 sal_Bool bHScrollMode = aViewData.IsHScrollMode();
987
988 // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden:
989 SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode();
990 if ( eMode == SCROLLING_NO )
991 bHScrollMode = sal_False;
992 else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ???
993 bHScrollMode = sal_True;
994
995 if( bHScrollMode )
996 {
997 const long nOverlap = 0; // ScrollBar::GetWindowOverlapPixel();
998 long nSize = pTabControl->GetSplitSize();
999
1000 if (aViewData.GetHSplitMode() != SC_SPLIT_FIX)
1001 {
1002 long nMax = pHSplitter->GetPosPixel().X();
1003 if( pTabControl->IsEffectiveRTL() )
1004 nMax = pFrameWin->GetSizePixel().Width() - nMax;
1005 --nMax;
1006 if (nSize>nMax) nSize = nMax;
1007 }
1008
1009 if ( nSize != pTabControl->GetSizePixel().Width() )
1010 {
1011 pTabControl->SetSizePixel( Size( nSize+nOverlap,
1012 pTabControl->GetSizePixel().Height() ) );
1013 RepeatResize();
1014 }
1015 }
1016
1017 return 0;
1018 }
1019
SetTabBarWidth(long nNewWidth)1020 void ScTabView::SetTabBarWidth( long nNewWidth )
1021 {
1022 Size aSize = pTabControl->GetSizePixel();
1023
1024 if ( aSize.Width() != nNewWidth )
1025 {
1026 aSize.Width() = nNewWidth;
1027 pTabControl->SetSizePixel( aSize );
1028 }
1029 }
1030
SetRelTabBarWidth(double fRelTabBarWidth)1031 void ScTabView::SetRelTabBarWidth( double fRelTabBarWidth )
1032 {
1033 if( (0.0 <= fRelTabBarWidth) && (fRelTabBarWidth <= 1.0) )
1034 if( long nFrameWidth = pFrameWin->GetSizePixel().Width() )
1035 SetTabBarWidth( static_cast< long >( fRelTabBarWidth * nFrameWidth + 0.5 ) );
1036 }
1037
SetPendingRelTabBarWidth(double fRelTabBarWidth)1038 void ScTabView::SetPendingRelTabBarWidth( double fRelTabBarWidth )
1039 {
1040 mfPendingTabBarWidth = fRelTabBarWidth;
1041 SetRelTabBarWidth( fRelTabBarWidth );
1042 }
1043
GetTabBarWidth() const1044 long ScTabView::GetTabBarWidth() const
1045 {
1046 return pTabControl->GetSizePixel().Width();
1047 }
1048
GetRelTabBarWidth() const1049 double ScTabView::GetRelTabBarWidth() const
1050 {
1051 if( long nFrameWidth = pFrameWin->GetSizePixel().Width() )
1052 return static_cast< double >( GetTabBarWidth() ) / nFrameWidth;
1053 return 0.0;
1054 }
1055
GetPendingRelTabBarWidth() const1056 double ScTabView::GetPendingRelTabBarWidth() const
1057 {
1058 return mfPendingTabBarWidth;
1059 }
1060
GetActiveWin()1061 Window* ScTabView::GetActiveWin()
1062 {
1063 ScSplitPos ePos = aViewData.GetActivePart();
1064 DBG_ASSERT(pGridWin[ePos],"kein aktives Fenster");
1065 return pGridWin[ePos];
1066 }
1067
GetWindowByPos(ScSplitPos ePos)1068 Window* ScTabView::GetWindowByPos( ScSplitPos ePos )
1069 {
1070 return pGridWin[ePos];
1071 }
1072
SetActivePointer(const Pointer & rPointer)1073 void ScTabView::SetActivePointer( const Pointer& rPointer )
1074 {
1075 for (sal_uInt16 i=0; i<4; i++)
1076 if (pGridWin[i])
1077 pGridWin[i]->SetPointer( rPointer );
1078
1079 /* ScSplitPos ePos = aViewData.GetActivePart();
1080 if (pGridWin[ePos])
1081 pGridWin[ePos]->SetPointer( rPointer );
1082 */
1083 }
1084
1085 //UNUSED2008-05 void ScTabView::SetActivePointer( const ResId& )
1086 //UNUSED2008-05 {
1087 //UNUSED2008-05 DBG_ERRORFILE( "keine Pointer mit ResId!" );
1088 //UNUSED2008-05 }
1089
ActiveGrabFocus()1090 void ScTabView::ActiveGrabFocus()
1091 {
1092 ScSplitPos ePos = aViewData.GetActivePart();
1093 if (pGridWin[ePos])
1094 pGridWin[ePos]->GrabFocus();
1095 }
1096
1097 //UNUSED2008-05 void ScTabView::ActiveCaptureMouse()
1098 //UNUSED2008-05 {
1099 //UNUSED2008-05 ScSplitPos ePos = aViewData.GetActivePart();
1100 //UNUSED2008-05 if (pGridWin[ePos])
1101 //UNUSED2008-05 pGridWin[ePos]->CaptureMouse();
1102 //UNUSED2008-05 }
1103 //UNUSED2008-05
1104 //UNUSED2008-05 void ScTabView::ActiveReleaseMouse()
1105 //UNUSED2008-05 {
1106 //UNUSED2008-05 ScSplitPos ePos = aViewData.GetActivePart();
1107 //UNUSED2008-05 if (pGridWin[ePos])
1108 //UNUSED2008-05 pGridWin[ePos]->ReleaseMouse();
1109 //UNUSED2008-05 }
1110 //UNUSED2008-05
1111 //UNUSED2008-05 Point ScTabView::ActivePixelToLogic( const Point& rDevicePoint )
1112 //UNUSED2008-05 {
1113 //UNUSED2008-05 ScSplitPos ePos = aViewData.GetActivePart();
1114 //UNUSED2008-05 if (pGridWin[ePos])
1115 //UNUSED2008-05 return pGridWin[ePos]->PixelToLogic(rDevicePoint);
1116 //UNUSED2008-05 else
1117 //UNUSED2008-05 return Point();
1118 //UNUSED2008-05 }
1119
FindWindow(Window * pWindow) const1120 ScSplitPos ScTabView::FindWindow( Window* pWindow ) const
1121 {
1122 ScSplitPos eVal = SC_SPLIT_BOTTOMLEFT; // Default
1123 for (sal_uInt16 i=0; i<4; i++)
1124 if ( pGridWin[i] == pWindow )
1125 eVal = (ScSplitPos) i;
1126
1127 return eVal;
1128 }
1129
GetGridOffset() const1130 Point ScTabView::GetGridOffset() const
1131 {
1132 Point aPos;
1133
1134 // Groessen hier wie in DoResize
1135
1136 sal_Bool bHeaders = aViewData.IsHeaderMode();
1137 sal_Bool bOutlMode = aViewData.IsOutlineMode();
1138 sal_Bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
1139 sal_Bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
1140
1141 // Outline-Controls
1142 if (bVOutline && pRowOutline[SC_SPLIT_BOTTOM])
1143 aPos.X() += pRowOutline[SC_SPLIT_BOTTOM]->GetDepthSize();
1144 if (bHOutline && pColOutline[SC_SPLIT_LEFT])
1145 aPos.Y() += pColOutline[SC_SPLIT_LEFT]->GetDepthSize();
1146
1147 if (bHeaders) // Spalten/Zeilen-Header
1148 {
1149 if (pRowBar[SC_SPLIT_BOTTOM])
1150 aPos.X() += pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
1151 if (pColBar[SC_SPLIT_LEFT])
1152 aPos.Y() += pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
1153 }
1154
1155 return aPos;
1156 }
1157
1158 // --- Scroll-Bars --------------------------------------------------------
1159
ScrollCommand(const CommandEvent & rCEvt,ScSplitPos ePos)1160 sal_Bool ScTabView::ScrollCommand( const CommandEvent& rCEvt, ScSplitPos ePos )
1161 {
1162 HideNoteMarker();
1163
1164 sal_Bool bDone = sal_False;
1165 const CommandWheelData* pData = rCEvt.GetWheelData();
1166 if ( pData && pData->GetMode() == COMMAND_WHEEL_ZOOM )
1167 {
1168 if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() )
1169 {
1170 // for ole inplace editing, the scale is defined by the visarea and client size
1171 // and can't be changed directly
1172
1173 const Fraction& rOldY = aViewData.GetZoomY();
1174 long nOld = (long)(( rOldY.GetNumerator() * 100 ) / rOldY.GetDenominator());
1175 long nNew = nOld;
1176 if ( pData->GetDelta() < 0 )
1177 nNew = Max( (long) MINZOOM, (long)( nOld - SC_DELTA_ZOOM ) );
1178 else
1179 nNew = Min( (long) MAXZOOM, (long)( nOld + SC_DELTA_ZOOM ) );
1180
1181 if ( nNew != nOld )
1182 {
1183 // scroll wheel doesn't set the AppOptions default
1184
1185 sal_Bool bSyncZoom = SC_MOD()->GetAppOptions().GetSynchronizeZoom();
1186 SetZoomType( SVX_ZOOM_PERCENT, bSyncZoom );
1187 Fraction aFract( nNew, 100 );
1188 SetZoom( aFract, aFract, bSyncZoom );
1189 PaintGrid();
1190 PaintTop();
1191 PaintLeft();
1192 aViewData.GetBindings().Invalidate( SID_ATTR_ZOOM );
1193 aViewData.GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
1194 }
1195
1196 bDone = sal_True;
1197 }
1198 }
1199 else
1200 {
1201 ScHSplitPos eHPos = WhichH(ePos);
1202 ScVSplitPos eVPos = WhichV(ePos);
1203 ScrollBar* pHScroll = ( eHPos == SC_SPLIT_LEFT ) ? &aHScrollLeft : &aHScrollRight;
1204 ScrollBar* pVScroll = ( eVPos == SC_SPLIT_TOP ) ? &aVScrollTop : &aVScrollBottom;
1205 if ( pGridWin[ePos] )
1206 bDone = pGridWin[ePos]->HandleScrollCommand( rCEvt, pHScroll, pVScroll );
1207 }
1208 return bDone;
1209 }
1210
IMPL_LINK(ScTabView,EndScrollHdl,ScrollBar *,pScroll)1211 IMPL_LINK( ScTabView, EndScrollHdl, ScrollBar*, pScroll )
1212 {
1213 sal_Bool bOnlineScroll = sal_True; //! Optionen
1214
1215 if ( bDragging )
1216 {
1217 if ( bOnlineScroll ) // nur Ranges aktualisieren
1218 UpdateScrollBars();
1219 else
1220 {
1221 long nScrollMin = 0; // RangeMin simulieren
1222 if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight )
1223 nScrollMin = aViewData.GetFixPosX();
1224 if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom )
1225 nScrollMin = aViewData.GetFixPosY();
1226
1227 if ( pScroll == &aHScrollLeft || pScroll == &aHScrollRight )
1228 {
1229 sal_Bool bMirror = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() ) != Application::GetSettings().GetLayoutRTL();
1230 ScHSplitPos eWhich = (pScroll == &aHScrollLeft) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT;
1231 long nDelta = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin - aViewData.GetPosX(eWhich);
1232 if (nDelta) ScrollX( nDelta, eWhich );
1233 }
1234 else // VScroll...
1235 {
1236 ScVSplitPos eWhich = (pScroll == &aVScrollTop) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM;
1237 long nDelta = GetScrollBarPos( *pScroll, sal_False ) + nScrollMin - aViewData.GetPosY(eWhich);
1238 if (nDelta) ScrollY( nDelta, eWhich );
1239 }
1240 }
1241 bDragging = sal_False;
1242 }
1243 return 0;
1244 }
1245
IMPL_LINK(ScTabView,ScrollHdl,ScrollBar *,pScroll)1246 IMPL_LINK( ScTabView, ScrollHdl, ScrollBar*, pScroll )
1247 {
1248 sal_Bool bOnlineScroll = sal_True; //! Optionen
1249
1250 sal_Bool bHoriz = ( pScroll == &aHScrollLeft || pScroll == &aHScrollRight );
1251 long nViewPos;
1252 if ( bHoriz )
1253 nViewPos = aViewData.GetPosX( (pScroll == &aHScrollLeft) ?
1254 SC_SPLIT_LEFT : SC_SPLIT_RIGHT );
1255 else
1256 nViewPos = aViewData.GetPosY( (pScroll == &aVScrollTop) ?
1257 SC_SPLIT_TOP : SC_SPLIT_BOTTOM );
1258
1259 sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
1260 sal_Bool bMirror = bHoriz && (bLayoutRTL != Application::GetSettings().GetLayoutRTL());
1261
1262 ScrollType eType = pScroll->GetType();
1263 if ( eType == SCROLL_DRAG )
1264 {
1265 if (!bDragging)
1266 {
1267 bDragging = sal_True;
1268 nPrevDragPos = nViewPos;
1269 }
1270
1271 // Scroll-Position anzeigen
1272 // (nur QuickHelp, in der Statuszeile gibt es keinen Eintrag dafuer)
1273
1274 if (Help::IsQuickHelpEnabled())
1275 {
1276 Size aSize = pScroll->GetSizePixel();
1277
1278 /* Convert scrollbar mouse position to screen position. If RTL
1279 mode of scrollbar differs from RTL mode of its parent, then the
1280 direct call to Window::OutputToNormalizedScreenPixel() will
1281 give unusable results, because calcualtion of screen position
1282 is based on parent orientation and expects equal orientation of
1283 the child position. Need to mirror mouse position before. */
1284 Point aMousePos = pScroll->GetPointerPosPixel();
1285 if( pScroll->IsRTLEnabled() != pScroll->GetParent()->IsRTLEnabled() )
1286 aMousePos.X() = aSize.Width() - aMousePos.X() - 1;
1287 aMousePos = pScroll->OutputToNormalizedScreenPixel( aMousePos );
1288
1289 // convert top-left position of scrollbar to screen position
1290 Point aPos = pScroll->OutputToNormalizedScreenPixel( Point() );
1291
1292 // get scrollbar scroll position for help text (row number/column name)
1293 long nScrollMin = 0; // RangeMin simulieren
1294 if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight )
1295 nScrollMin = aViewData.GetFixPosX();
1296 if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom )
1297 nScrollMin = aViewData.GetFixPosY();
1298 long nScrollPos = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin;
1299
1300 String aHelpStr;
1301 Rectangle aRect;
1302 sal_uInt16 nAlign;
1303 if (bHoriz)
1304 {
1305 aHelpStr = ScGlobal::GetRscString(STR_COLUMN);
1306 aHelpStr += ' ';
1307 aHelpStr += ScColToAlpha((SCCOL) nScrollPos);
1308
1309 aRect.Left() = aMousePos.X();
1310 aRect.Top() = aPos.Y() - 4;
1311 nAlign = QUICKHELP_BOTTOM|QUICKHELP_CENTER;
1312 }
1313 else
1314 {
1315 aHelpStr = ScGlobal::GetRscString(STR_ROW);
1316 aHelpStr += ' ';
1317 aHelpStr += String::CreateFromInt32(nScrollPos + 1);
1318
1319 // show quicktext always inside sheet area
1320 aRect.Left() = bLayoutRTL ? (aPos.X() + aSize.Width() + 8) : (aPos.X() - 8);
1321 aRect.Top() = aMousePos.Y();
1322 nAlign = (bLayoutRTL ? QUICKHELP_LEFT : QUICKHELP_RIGHT) | QUICKHELP_VCENTER;
1323 }
1324 aRect.Right() = aRect.Left();
1325 aRect.Bottom() = aRect.Top();
1326
1327 Help::ShowQuickHelp(pScroll->GetParent(), aRect, aHelpStr, nAlign);
1328 }
1329 }
1330
1331 if ( bOnlineScroll || eType != SCROLL_DRAG )
1332 {
1333 if ( bMirror )
1334 {
1335 // change scroll type so visible/previous cells calculation below remains the same
1336 switch ( eType )
1337 {
1338 case SCROLL_LINEUP: eType = SCROLL_LINEDOWN; break;
1339 case SCROLL_LINEDOWN: eType = SCROLL_LINEUP; break;
1340 case SCROLL_PAGEUP: eType = SCROLL_PAGEDOWN; break;
1341 case SCROLL_PAGEDOWN: eType = SCROLL_PAGEUP; break;
1342 default:
1343 {
1344 // added to avoid warnings
1345 }
1346 }
1347 }
1348 long nDelta = pScroll->GetDelta();
1349 switch ( eType )
1350 {
1351 case SCROLL_LINEUP:
1352 nDelta = -1;
1353 break;
1354 case SCROLL_LINEDOWN:
1355 nDelta = 1;
1356 break;
1357 case SCROLL_PAGEUP:
1358 if ( pScroll == &aHScrollLeft ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_LEFT );
1359 if ( pScroll == &aHScrollRight ) nDelta = -(long) aViewData.PrevCellsX( SC_SPLIT_RIGHT );
1360 if ( pScroll == &aVScrollTop ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_TOP );
1361 if ( pScroll == &aVScrollBottom ) nDelta = -(long) aViewData.PrevCellsY( SC_SPLIT_BOTTOM );
1362 if (nDelta==0) nDelta=-1;
1363 break;
1364 case SCROLL_PAGEDOWN:
1365 if ( pScroll == &aHScrollLeft ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_LEFT );
1366 if ( pScroll == &aHScrollRight ) nDelta = aViewData.VisibleCellsX( SC_SPLIT_RIGHT );
1367 if ( pScroll == &aVScrollTop ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_TOP );
1368 if ( pScroll == &aVScrollBottom ) nDelta = aViewData.VisibleCellsY( SC_SPLIT_BOTTOM );
1369 if (nDelta==0) nDelta=1;
1370 break;
1371 case SCROLL_DRAG:
1372 {
1373 // nur in die richtige Richtung scrollen, nicht um ausgeblendete
1374 // Bereiche herumzittern
1375
1376 long nScrollMin = 0; // RangeMin simulieren
1377 if ( aViewData.GetHSplitMode()==SC_SPLIT_FIX && pScroll == &aHScrollRight )
1378 nScrollMin = aViewData.GetFixPosX();
1379 if ( aViewData.GetVSplitMode()==SC_SPLIT_FIX && pScroll == &aVScrollBottom )
1380 nScrollMin = aViewData.GetFixPosY();
1381
1382 long nScrollPos = GetScrollBarPos( *pScroll, bMirror ) + nScrollMin;
1383 nDelta = nScrollPos - nViewPos;
1384 if ( nScrollPos > nPrevDragPos )
1385 {
1386 if (nDelta<0) nDelta=0;
1387 }
1388 else if ( nScrollPos < nPrevDragPos )
1389 {
1390 if (nDelta>0) nDelta=0;
1391 }
1392 else
1393 nDelta = 0;
1394 nPrevDragPos = nScrollPos;
1395 }
1396 break;
1397 default:
1398 {
1399 // added to avoid warnings
1400 }
1401 }
1402
1403 if (nDelta)
1404 {
1405 sal_Bool bUpdate = ( eType != SCROLL_DRAG ); // bei Drag die Ranges nicht aendern
1406 if ( bHoriz )
1407 ScrollX( nDelta, (pScroll == &aHScrollLeft) ? SC_SPLIT_LEFT : SC_SPLIT_RIGHT, bUpdate );
1408 else
1409 ScrollY( nDelta, (pScroll == &aVScrollTop) ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM, bUpdate );
1410 }
1411 }
1412
1413 return 0;
1414 }
1415
ScrollX(long nDeltaX,ScHSplitPos eWhich,sal_Bool bUpdBars)1416 void ScTabView::ScrollX( long nDeltaX, ScHSplitPos eWhich, sal_Bool bUpdBars )
1417 {
1418 sal_Bool bHasHint = ( pInputHintWindow != NULL );
1419 if (bHasHint)
1420 RemoveHintWindow();
1421
1422 SCCOL nOldX = aViewData.GetPosX(eWhich);
1423 SCsCOL nNewX = static_cast<SCsCOL>(nOldX) + static_cast<SCsCOL>(nDeltaX);
1424 if ( nNewX < 0 )
1425 {
1426 nDeltaX -= nNewX;
1427 nNewX = 0;
1428 }
1429 if ( nNewX > MAXCOL )
1430 {
1431 nDeltaX -= nNewX - MAXCOL;
1432 nNewX = MAXCOL;
1433 }
1434
1435 SCsCOL nDir = ( nDeltaX > 0 ) ? 1 : -1;
1436 ScDocument* pDoc = aViewData.GetDocument();
1437 SCTAB nTab = aViewData.GetTabNo();
1438 while ( pDoc->ColHidden(nNewX, nTab) &&
1439 nNewX+nDir >= 0 && nNewX+nDir <= MAXCOL )
1440 nNewX = sal::static_int_cast<SCsCOL>( nNewX + nDir );
1441
1442 // Fixierung
1443
1444 if (aViewData.GetHSplitMode() == SC_SPLIT_FIX)
1445 {
1446 if (eWhich == SC_SPLIT_LEFT)
1447 nNewX = static_cast<SCsCOL>(nOldX); // links immer stehenlassen
1448 else
1449 {
1450 SCsCOL nFixX = static_cast<SCsCOL>(aViewData.GetFixPosX());
1451 if (nNewX < nFixX)
1452 nNewX = nFixX;
1453 }
1454 }
1455 if (nNewX == static_cast<SCsCOL>(nOldX))
1456 return;
1457
1458 HideAllCursors();
1459
1460 if ( nNewX >= 0 && nNewX <= MAXCOL && nDeltaX )
1461 {
1462 SCCOL nTrackX = std::max( nOldX, static_cast<SCCOL>(nNewX) );
1463
1464 // Mit VCL wirkt Update() im Moment immer auf alle Fenster, beim Update
1465 // nach dem Scrollen des GridWindow's wuerde darum der Col-/RowBar evtl.
1466 // mit schon geaenderter Pos. gepainted werden -
1467 // darum vorher einmal Update am Col-/RowBar
1468
1469 if (pColBar[eWhich])
1470 pColBar[eWhich]->Update();
1471
1472 long nOldPos = aViewData.GetScrPos( nTrackX, 0, eWhich ).X();
1473 aViewData.SetPosX( eWhich, static_cast<SCCOL>(nNewX) );
1474 long nDiff = aViewData.GetScrPos( nTrackX, 0, eWhich ).X() - nOldPos;
1475
1476 if ( eWhich==SC_SPLIT_LEFT )
1477 {
1478 pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( nDiff, 0 );
1479 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
1480 pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( nDiff, 0 );
1481 }
1482 else
1483 {
1484 pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( nDiff, 0 );
1485 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
1486 pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( nDiff, 0 );
1487 }
1488 if (pColBar[eWhich]) { pColBar[eWhich]->Scroll( nDiff,0 ); pColBar[eWhich]->Update(); }
1489 if (pColOutline[eWhich]) pColOutline[eWhich]->ScrollPixel( nDiff );
1490 if (bUpdBars)
1491 UpdateScrollBars();
1492 }
1493
1494 if (nDeltaX==1 || nDeltaX==-1)
1495 pGridWin[aViewData.GetActivePart()]->Update();
1496
1497 ShowAllCursors();
1498
1499 SetNewVisArea(); // MapMode muss schon gesetzt sein
1500
1501 if (bHasHint)
1502 TestHintWindow(); // neu positionieren
1503 }
1504
ScrollY(long nDeltaY,ScVSplitPos eWhich,sal_Bool bUpdBars)1505 void ScTabView::ScrollY( long nDeltaY, ScVSplitPos eWhich, sal_Bool bUpdBars )
1506 {
1507 sal_Bool bHasHint = ( pInputHintWindow != NULL );
1508 if (bHasHint)
1509 RemoveHintWindow();
1510
1511 SCROW nOldY = aViewData.GetPosY(eWhich);
1512 SCsROW nNewY = static_cast<SCsROW>(nOldY) + static_cast<SCsROW>(nDeltaY);
1513 if ( nNewY < 0 )
1514 {
1515 nDeltaY -= nNewY;
1516 nNewY = 0;
1517 }
1518 if ( nNewY > MAXROW )
1519 {
1520 nDeltaY -= nNewY - MAXROW;
1521 nNewY = MAXROW;
1522 }
1523
1524 SCsROW nDir = ( nDeltaY > 0 ) ? 1 : -1;
1525 ScDocument* pDoc = aViewData.GetDocument();
1526 SCTAB nTab = aViewData.GetTabNo();
1527 while ( pDoc->RowHidden(nNewY, nTab) &&
1528 nNewY+nDir >= 0 && nNewY+nDir <= MAXROW )
1529 nNewY += nDir;
1530
1531 // Fixierung
1532
1533 if (aViewData.GetVSplitMode() == SC_SPLIT_FIX)
1534 {
1535 if (eWhich == SC_SPLIT_TOP)
1536 nNewY = static_cast<SCsROW>(nOldY); // oben immer stehenlassen
1537 else
1538 {
1539 SCsROW nFixY = static_cast<SCsROW>(aViewData.GetFixPosY());
1540 if (nNewY < nFixY)
1541 nNewY = nFixY;
1542 }
1543 }
1544 if (nNewY == static_cast<SCsROW>(nOldY))
1545 return;
1546
1547 HideAllCursors();
1548
1549 if ( nNewY >= 0 && nNewY <= MAXROW && nDeltaY )
1550 {
1551 SCROW nTrackY = std::max( nOldY, static_cast<SCROW>(nNewY) );
1552
1553 // Zeilenkoepfe anpassen vor dem eigentlichen Scrolling, damit nicht
1554 // doppelt gepainted werden muss
1555 // PosY darf dann auch noch nicht umgesetzt sein, neuen Wert uebergeben
1556 SCROW nUNew = static_cast<SCROW>(nNewY);
1557 UpdateHeaderWidth( &eWhich, &nUNew ); // Zeilenkoepfe anpassen
1558
1559 if (pRowBar[eWhich])
1560 pRowBar[eWhich]->Update();
1561
1562 long nOldPos = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y();
1563 aViewData.SetPosY( eWhich, static_cast<SCROW>(nNewY) );
1564 long nDiff = aViewData.GetScrPos( 0, nTrackY, eWhich ).Y() - nOldPos;
1565
1566 if ( eWhich==SC_SPLIT_TOP )
1567 {
1568 pGridWin[SC_SPLIT_TOPLEFT]->ScrollPixel( 0, nDiff );
1569 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
1570 pGridWin[SC_SPLIT_TOPRIGHT]->ScrollPixel( 0, nDiff );
1571 }
1572 else
1573 {
1574 pGridWin[SC_SPLIT_BOTTOMLEFT]->ScrollPixel( 0, nDiff );
1575 if ( aViewData.GetHSplitMode() != SC_SPLIT_NONE )
1576 pGridWin[SC_SPLIT_BOTTOMRIGHT]->ScrollPixel( 0, nDiff );
1577 }
1578 if (pRowBar[eWhich]) { pRowBar[eWhich]->Scroll( 0,nDiff ); pRowBar[eWhich]->Update(); }
1579 if (pRowOutline[eWhich]) pRowOutline[eWhich]->ScrollPixel( nDiff );
1580 if (bUpdBars)
1581 UpdateScrollBars();
1582 }
1583
1584 if (nDeltaY==1 || nDeltaY==-1)
1585 pGridWin[aViewData.GetActivePart()]->Update();
1586
1587 ShowAllCursors();
1588
1589 SetNewVisArea(); // MapMode muss schon gesetzt sein
1590
1591 if (bHasHint)
1592 TestHintWindow(); // neu positionieren
1593 }
1594
ScrollLines(long nDeltaX,long nDeltaY)1595 void ScTabView::ScrollLines( long nDeltaX, long nDeltaY )
1596 {
1597 ScSplitPos eWhich = aViewData.GetActivePart();
1598 if (nDeltaX)
1599 ScrollX(nDeltaX,WhichH(eWhich));
1600 if (nDeltaY)
1601 ScrollY(nDeltaY,WhichV(eWhich));
1602 }
1603
lcl_LastVisible(ScViewData & rViewData)1604 SCROW lcl_LastVisible( ScViewData& rViewData )
1605 {
1606 // wenn am Dokumentende viele Zeilen ausgeblendet sind (welcher Trottel macht sowas?),
1607 // soll dadurch nicht auf breite Zeilenkoepfe geschaltet werden
1608 //! als Member ans Dokument ???
1609
1610 ScDocument* pDoc = rViewData.GetDocument();
1611 SCTAB nTab = rViewData.GetTabNo();
1612
1613 SCROW nVis = MAXROW;
1614 while ( nVis > 0 && pDoc->GetRowHeight( nVis, nTab ) == 0 )
1615 --nVis;
1616 return nVis;
1617 }
1618
UpdateHeaderWidth(const ScVSplitPos * pWhich,const SCROW * pPosY)1619 void ScTabView::UpdateHeaderWidth( const ScVSplitPos* pWhich, const SCROW* pPosY )
1620 {
1621 if ( !pRowBar[SC_SPLIT_BOTTOM] || MAXROW < 10000 )
1622 return;
1623
1624 SCROW nEndPos = MAXROW;
1625 if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() )
1626 {
1627 // fuer OLE Inplace immer MAXROW
1628
1629 if ( pWhich && *pWhich == SC_SPLIT_BOTTOM && pPosY )
1630 nEndPos = *pPosY;
1631 else
1632 nEndPos = aViewData.GetPosY( SC_SPLIT_BOTTOM );
1633 nEndPos += aViewData.CellsAtY( nEndPos, 1, SC_SPLIT_BOTTOM, SC_SIZE_NONE ); // VisibleCellsY
1634 if (nEndPos > MAXROW)
1635 nEndPos = lcl_LastVisible( aViewData );
1636
1637 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
1638 {
1639 SCROW nTopEnd;
1640 if ( pWhich && *pWhich == SC_SPLIT_TOP && pPosY )
1641 nTopEnd = *pPosY;
1642 else
1643 nTopEnd = aViewData.GetPosY( SC_SPLIT_TOP );
1644 nTopEnd += aViewData.CellsAtY( nTopEnd, 1, SC_SPLIT_TOP, SC_SIZE_NONE );// VisibleCellsY
1645 if (nTopEnd > MAXROW)
1646 nTopEnd = lcl_LastVisible( aViewData );
1647
1648 if ( nTopEnd > nEndPos )
1649 nEndPos = nTopEnd;
1650 }
1651 }
1652
1653 long nSmall = pRowBar[SC_SPLIT_BOTTOM]->GetSmallWidth();
1654 long nBig = pRowBar[SC_SPLIT_BOTTOM]->GetBigWidth();
1655 long nDiff = nBig - nSmall;
1656
1657 if (nEndPos>10000)
1658 nEndPos = 10000;
1659 else if (nEndPos<1) // avoid extra step at 0 (when only one row is visible)
1660 nEndPos = 1;
1661 long nWidth = nBig - ( 10000 - nEndPos ) * nDiff / 10000;
1662
1663 if ( nWidth != pRowBar[SC_SPLIT_BOTTOM]->GetWidth() && !bInUpdateHeader )
1664 {
1665 bInUpdateHeader = sal_True;
1666
1667 pRowBar[SC_SPLIT_BOTTOM]->SetWidth( nWidth );
1668 if (pRowBar[SC_SPLIT_TOP])
1669 pRowBar[SC_SPLIT_TOP]->SetWidth( nWidth );
1670
1671 RepeatResize();
1672
1673 // auf VCL gibt's Update ohne Ende (jedes Update gilt fuer alle Fenster)
1674 //aCornerButton.Update(); // der bekommt sonst nie ein Update
1675
1676 bInUpdateHeader = sal_False;
1677 }
1678 }
1679
ShowHide(Window * pWin,sal_Bool bShow)1680 inline void ShowHide( Window* pWin, sal_Bool bShow )
1681 {
1682 DBG_ASSERT(pWin || !bShow, "Fenster ist nicht da");
1683 if (pWin)
1684 pWin->Show(bShow);
1685 }
1686
UpdateShow()1687 void ScTabView::UpdateShow()
1688 {
1689 sal_Bool bHScrollMode = aViewData.IsHScrollMode();
1690 sal_Bool bVScrollMode = aViewData.IsVScrollMode();
1691 sal_Bool bTabMode = aViewData.IsTabMode();
1692 sal_Bool bOutlMode = aViewData.IsOutlineMode();
1693 sal_Bool bHOutline = bOutlMode && lcl_HasColOutline(aViewData);
1694 sal_Bool bVOutline = bOutlMode && lcl_HasRowOutline(aViewData);
1695 sal_Bool bHeader = aViewData.IsHeaderMode();
1696
1697 sal_Bool bShowH = ( aViewData.GetHSplitMode() != SC_SPLIT_NONE );
1698 sal_Bool bShowV = ( aViewData.GetVSplitMode() != SC_SPLIT_NONE );
1699
1700 // Scrollbar-Einstellungen koennen vom Sfx ueberschrieben werden:
1701 SfxScrollingMode eMode = aViewData.GetViewShell()->GetScrollingMode();
1702 if ( eMode == SCROLLING_NO )
1703 bHScrollMode = bVScrollMode = sal_False;
1704 else if ( eMode == SCROLLING_YES || eMode == SCROLLING_AUTO ) //! Auto ???
1705 bHScrollMode = bVScrollMode = sal_True;
1706
1707 if ( aViewData.GetDocShell()->IsPreview() )
1708 bHScrollMode = bVScrollMode = bTabMode = bHeader = bOutlMode = bHOutline = bVOutline = sal_False;
1709
1710 //
1711 // Windows anlegen
1712 //
1713
1714 if (bShowH && !pGridWin[SC_SPLIT_BOTTOMRIGHT])
1715 {
1716 pGridWin[SC_SPLIT_BOTTOMRIGHT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_BOTTOMRIGHT );
1717 DoAddWin( pGridWin[SC_SPLIT_BOTTOMRIGHT] );
1718 }
1719 if (bShowV && !pGridWin[SC_SPLIT_TOPLEFT])
1720 {
1721 pGridWin[SC_SPLIT_TOPLEFT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_TOPLEFT );
1722 DoAddWin( pGridWin[SC_SPLIT_TOPLEFT] );
1723 }
1724 if (bShowH && bShowV && !pGridWin[SC_SPLIT_TOPRIGHT])
1725 {
1726 pGridWin[SC_SPLIT_TOPRIGHT] = new ScGridWindow( pFrameWin, &aViewData, SC_SPLIT_TOPRIGHT );
1727 DoAddWin( pGridWin[SC_SPLIT_TOPRIGHT] );
1728 }
1729
1730 if (bHOutline && !pColOutline[SC_SPLIT_LEFT])
1731 pColOutline[SC_SPLIT_LEFT] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMLEFT );
1732 if (bShowH && bHOutline && !pColOutline[SC_SPLIT_RIGHT])
1733 pColOutline[SC_SPLIT_RIGHT] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_HOR, &aViewData, SC_SPLIT_BOTTOMRIGHT );
1734
1735 if (bVOutline && !pRowOutline[SC_SPLIT_BOTTOM])
1736 pRowOutline[SC_SPLIT_BOTTOM] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_BOTTOMLEFT );
1737 if (bShowV && bVOutline && !pRowOutline[SC_SPLIT_TOP])
1738 pRowOutline[SC_SPLIT_TOP] = new ScOutlineWindow( pFrameWin, SC_OUTLINE_VER, &aViewData, SC_SPLIT_TOPLEFT );
1739
1740 if (bShowH && bHeader && !pColBar[SC_SPLIT_RIGHT])
1741 pColBar[SC_SPLIT_RIGHT] = new ScColBar( pFrameWin, &aViewData, SC_SPLIT_RIGHT,
1742 &aHdrFunc, pHdrSelEng );
1743 if (bShowV && bHeader && !pRowBar[SC_SPLIT_TOP])
1744 pRowBar[SC_SPLIT_TOP] = new ScRowBar( pFrameWin, &aViewData, SC_SPLIT_TOP,
1745 &aHdrFunc, pHdrSelEng );
1746
1747 //
1748 // Windows anzeigen
1749 //
1750
1751 ShowHide( &aHScrollLeft, bHScrollMode );
1752 ShowHide( &aHScrollRight, bShowH && bHScrollMode );
1753 ShowHide( &aVScrollBottom, bVScrollMode );
1754 ShowHide( &aVScrollTop, bShowV && bVScrollMode );
1755 ShowHide( &aScrollBarBox, bVScrollMode || bHScrollMode );
1756
1757 ShowHide( pHSplitter, bHScrollMode || bShowH ); // immer angelegt
1758 ShowHide( pVSplitter, bVScrollMode || bShowV );
1759 ShowHide( pTabControl, bTabMode );
1760
1761 // ab hier dynamisch angelegte
1762
1763 ShowHide( pGridWin[SC_SPLIT_BOTTOMRIGHT], bShowH );
1764 ShowHide( pGridWin[SC_SPLIT_TOPLEFT], bShowV );
1765 ShowHide( pGridWin[SC_SPLIT_TOPRIGHT], bShowH && bShowV );
1766
1767 ShowHide( pColOutline[SC_SPLIT_LEFT], bHOutline );
1768 ShowHide( pColOutline[SC_SPLIT_RIGHT], bShowH && bHOutline );
1769
1770 ShowHide( pRowOutline[SC_SPLIT_BOTTOM], bVOutline );
1771 ShowHide( pRowOutline[SC_SPLIT_TOP], bShowV && bVOutline );
1772
1773 ShowHide( pColBar[SC_SPLIT_RIGHT], bShowH && bHeader );
1774 ShowHide( pRowBar[SC_SPLIT_TOP], bShowV && bHeader );
1775
1776
1777 //! neue Gridwindows eintragen
1778 }
1779
1780 // --- Splitter --------------------------------------------------------
1781
IMPL_LINK(ScTabView,SplitHdl,Splitter *,pSplitter)1782 IMPL_LINK( ScTabView, SplitHdl, Splitter*, pSplitter )
1783 {
1784 if ( pSplitter == pHSplitter )
1785 DoHSplit( pHSplitter->GetSplitPosPixel() );
1786 else
1787 DoVSplit( pVSplitter->GetSplitPosPixel() );
1788
1789 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX || aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1790 FreezeSplitters( sal_True );
1791
1792 DoResize( aBorderPos, aFrameSize );
1793
1794 return 0;
1795 }
1796
DoHSplit(long nSplitPos)1797 void ScTabView::DoHSplit(long nSplitPos)
1798 {
1799 // nSplitPos is the real pixel position on the frame window,
1800 // mirroring for RTL has to be done here.
1801
1802 sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
1803 if ( bLayoutRTL )
1804 nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
1805
1806 long nMinPos;
1807 long nMaxPos;
1808 SCCOL nOldDelta;
1809 SCCOL nNewDelta;
1810
1811 nMinPos = SPLIT_MARGIN;
1812 if ( pRowBar[SC_SPLIT_BOTTOM] && pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() >= nMinPos )
1813 nMinPos = pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width() + 1;
1814 nMaxPos = aFrameSize.Width() - SPLIT_MARGIN;
1815
1816 ScSplitMode aOldMode = aViewData.GetHSplitMode();
1817 ScSplitMode aNewMode = SC_SPLIT_NORMAL;
1818
1819 aViewData.SetHSplitPos( nSplitPos );
1820 if ( nSplitPos < nMinPos || nSplitPos > nMaxPos )
1821 aNewMode = SC_SPLIT_NONE;
1822
1823 aViewData.SetHSplitMode( aNewMode );
1824
1825 if ( aNewMode != aOldMode )
1826 {
1827 UpdateShow(); // vor ActivatePart !!
1828
1829 if ( aNewMode == SC_SPLIT_NONE )
1830 {
1831 if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT)
1832 ActivatePart( SC_SPLIT_TOPLEFT );
1833 if (aViewData.GetActivePart() == SC_SPLIT_BOTTOMRIGHT)
1834 ActivatePart( SC_SPLIT_BOTTOMLEFT );
1835 }
1836 else
1837 {
1838 nOldDelta = aViewData.GetPosX( SC_SPLIT_LEFT );
1839 // aViewData.SetPosX( SC_SPLIT_LEFT, nOldDelta );
1840 long nLeftWidth = nSplitPos - pRowBar[SC_SPLIT_BOTTOM]->GetSizePixel().Width();
1841 if ( nLeftWidth < 0 ) nLeftWidth = 0;
1842 nNewDelta = nOldDelta + aViewData.CellsAtX( nOldDelta, 1, SC_SPLIT_LEFT,
1843 (sal_uInt16) nLeftWidth );
1844 if ( nNewDelta > MAXCOL )
1845 nNewDelta = MAXCOL;
1846 aViewData.SetPosX( SC_SPLIT_RIGHT, nNewDelta );
1847 if ( nNewDelta > aViewData.GetCurX() )
1848 ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ?
1849 SC_SPLIT_BOTTOMLEFT : SC_SPLIT_TOPLEFT );
1850 else
1851 ActivatePart( (WhichV(aViewData.GetActivePart()) == SC_SPLIT_BOTTOM) ?
1852 SC_SPLIT_BOTTOMRIGHT : SC_SPLIT_TOPRIGHT );
1853 }
1854
1855 // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
1856 // dafuer muss hier schon der MapMode stimmen
1857 for (sal_uInt16 i=0; i<4; i++)
1858 if (pGridWin[i])
1859 pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
1860 SetNewVisArea();
1861
1862 PaintGrid();
1863 PaintTop();
1864
1865 InvalidateSplit();
1866 }
1867 }
1868
DoVSplit(long nSplitPos)1869 void ScTabView::DoVSplit(long nSplitPos)
1870 {
1871 long nMinPos;
1872 long nMaxPos;
1873 SCROW nOldDelta;
1874 SCROW nNewDelta;
1875
1876 nMinPos = SPLIT_MARGIN;
1877 if ( pColBar[SC_SPLIT_LEFT] && pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() >= nMinPos )
1878 nMinPos = pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height() + 1;
1879 nMaxPos = aFrameSize.Height() - SPLIT_MARGIN;
1880
1881 ScSplitMode aOldMode = aViewData.GetVSplitMode();
1882 ScSplitMode aNewMode = SC_SPLIT_NORMAL;
1883
1884 aViewData.SetVSplitPos( nSplitPos );
1885 if ( nSplitPos < nMinPos || nSplitPos > nMaxPos )
1886 aNewMode = SC_SPLIT_NONE;
1887
1888 aViewData.SetVSplitMode( aNewMode );
1889
1890 if ( aNewMode != aOldMode )
1891 {
1892 UpdateShow(); // vor ActivatePart !!
1893
1894 if ( aNewMode == SC_SPLIT_NONE )
1895 {
1896 nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );
1897 aViewData.SetPosY( SC_SPLIT_BOTTOM, nOldDelta );
1898
1899 if (aViewData.GetActivePart() == SC_SPLIT_TOPLEFT)
1900 ActivatePart( SC_SPLIT_BOTTOMLEFT );
1901 if (aViewData.GetActivePart() == SC_SPLIT_TOPRIGHT)
1902 ActivatePart( SC_SPLIT_BOTTOMRIGHT );
1903 }
1904 else
1905 {
1906 if ( aOldMode == SC_SPLIT_NONE )
1907 nOldDelta = aViewData.GetPosY( SC_SPLIT_BOTTOM );
1908 else
1909 nOldDelta = aViewData.GetPosY( SC_SPLIT_TOP );
1910
1911 aViewData.SetPosY( SC_SPLIT_TOP, nOldDelta );
1912 long nTopHeight = nSplitPos - pColBar[SC_SPLIT_LEFT]->GetSizePixel().Height();
1913 if ( nTopHeight < 0 ) nTopHeight = 0;
1914 nNewDelta = nOldDelta + aViewData.CellsAtY( nOldDelta, 1, SC_SPLIT_TOP,
1915 (sal_uInt16) nTopHeight );
1916 if ( nNewDelta > MAXROW )
1917 nNewDelta = MAXROW;
1918 aViewData.SetPosY( SC_SPLIT_BOTTOM, nNewDelta );
1919 if ( nNewDelta > aViewData.GetCurY() )
1920 ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ?
1921 SC_SPLIT_TOPLEFT : SC_SPLIT_TOPRIGHT );
1922 else
1923 ActivatePart( (WhichH(aViewData.GetActivePart()) == SC_SPLIT_LEFT) ?
1924 SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT );
1925 }
1926
1927 // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
1928 // dafuer muss hier schon der MapMode stimmen
1929 for (sal_uInt16 i=0; i<4; i++)
1930 if (pGridWin[i])
1931 pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
1932 SetNewVisArea();
1933
1934 PaintGrid();
1935 PaintLeft();
1936
1937 InvalidateSplit();
1938 }
1939 }
1940
GetInsertPos()1941 Point ScTabView::GetInsertPos()
1942 {
1943 ScDocument* pDoc = aViewData.GetDocument();
1944 SCCOL nCol = aViewData.GetCurX();
1945 SCROW nRow = aViewData.GetCurY();
1946 SCTAB nTab = aViewData.GetTabNo();
1947 long nPosX = 0;
1948 for (SCCOL i=0; i<nCol; i++)
1949 nPosX += pDoc->GetColWidth(i,nTab);
1950 nPosX = (long)(nPosX * HMM_PER_TWIPS);
1951 if ( pDoc->IsNegativePage( nTab ) )
1952 nPosX = -nPosX;
1953 long nPosY = (long) pDoc->GetRowHeight( 0, nRow-1, nTab);
1954 nPosY = (long)(nPosY * HMM_PER_TWIPS);
1955 return Point(nPosX,nPosY);
1956 }
1957
GetChartInsertPos(const Size & rSize,const ScRange & rCellRange)1958 Point ScTabView::GetChartInsertPos( const Size& rSize, const ScRange& rCellRange )
1959 {
1960 Point aInsertPos;
1961 const long nBorder = 100; // leave 1mm for border
1962 long nNeededWidth = rSize.Width() + 2 * nBorder;
1963 long nNeededHeight = rSize.Height() + 2 * nBorder;
1964
1965 // use the active window, or lower/right if frozen (as in CalcZoom)
1966 ScSplitPos eUsedPart = aViewData.GetActivePart();
1967 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
1968 eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
1969 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
1970 eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
1971
1972 ScGridWindow* pWin = pGridWin[eUsedPart];
1973 DBG_ASSERT( pWin, "Window not found" );
1974 if (pWin)
1975 {
1976 ActivatePart( eUsedPart );
1977
1978 // get the visible rectangle in logic units
1979
1980 MapMode aDrawMode = pWin->GetDrawMapMode();
1981 Rectangle aVisible( pWin->PixelToLogic( Rectangle( Point(0,0), pWin->GetOutputSizePixel() ), aDrawMode ) );
1982
1983 ScDocument* pDoc = aViewData.GetDocument();
1984 SCTAB nTab = aViewData.GetTabNo();
1985 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1986 long nLayoutSign = bLayoutRTL ? -1 : 1;
1987
1988 long nDocX = (long)( (double) pDoc->GetColOffset( MAXCOL + 1, nTab ) * HMM_PER_TWIPS ) * nLayoutSign;
1989 long nDocY = (long)( (double) pDoc->GetRowOffset( MAXROW + 1, nTab ) * HMM_PER_TWIPS );
1990
1991 if ( aVisible.Left() * nLayoutSign > nDocX * nLayoutSign )
1992 aVisible.Left() = nDocX;
1993 if ( aVisible.Right() * nLayoutSign > nDocX * nLayoutSign )
1994 aVisible.Right() = nDocX;
1995 if ( aVisible.Top() > nDocY )
1996 aVisible.Top() = nDocY;
1997 if ( aVisible.Bottom() > nDocY )
1998 aVisible.Bottom() = nDocY;
1999
2000 // get the logic position of the selection
2001
2002 Rectangle aSelection = pDoc->GetMMRect( rCellRange.aStart.Col(), rCellRange.aStart.Row(),
2003 rCellRange.aEnd.Col(), rCellRange.aEnd.Row(), nTab );
2004
2005 long nLeftSpace = aSelection.Left() - aVisible.Left();
2006 long nRightSpace = aVisible.Right() - aSelection.Right();
2007 long nTopSpace = aSelection.Top() - aVisible.Top();
2008 long nBottomSpace = aVisible.Bottom() - aSelection.Bottom();
2009
2010 bool bFitLeft = ( nLeftSpace >= nNeededWidth );
2011 bool bFitRight = ( nRightSpace >= nNeededWidth );
2012
2013 if ( bFitLeft || bFitRight )
2014 {
2015 // first preference: completely left or right of the selection
2016
2017 // if both fit, prefer left in RTL mode, right otherwise
2018 bool bPutLeft = bFitLeft && ( bLayoutRTL || !bFitRight );
2019
2020 if ( bPutLeft )
2021 aInsertPos.X() = aSelection.Left() - nNeededWidth;
2022 else
2023 aInsertPos.X() = aSelection.Right() + 1;
2024
2025 // align with top of selection (is moved again if it doesn't fit)
2026 aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() );
2027 }
2028 else if ( nTopSpace >= nNeededHeight || nBottomSpace >= nNeededHeight )
2029 {
2030 // second preference: completely above or below the selection
2031
2032 if ( nBottomSpace > nNeededHeight ) // bottom is preferred
2033 aInsertPos.Y() = aSelection.Bottom() + 1;
2034 else
2035 aInsertPos.Y() = aSelection.Top() - nNeededHeight;
2036
2037 // align with (logic) left edge of selection (moved again if it doesn't fit)
2038 if ( bLayoutRTL )
2039 aInsertPos.X() = std::min( aSelection.Right(), aVisible.Right() ) - nNeededWidth + 1;
2040 else
2041 aInsertPos.X() = std::max( aSelection.Left(), aVisible.Left() );
2042 }
2043 else
2044 {
2045 // place to the (logic) right of the selection and move so it fits
2046
2047 if ( bLayoutRTL )
2048 aInsertPos.X() = aSelection.Left() - nNeededWidth;
2049 else
2050 aInsertPos.X() = aSelection.Right() + 1;
2051 aInsertPos.Y() = std::max( aSelection.Top(), aVisible.Top() );
2052 }
2053
2054 // move the position if the object doesn't fit in the screen
2055
2056 Rectangle aCompareRect( aInsertPos, Size( nNeededWidth, nNeededHeight ) );
2057 if ( aCompareRect.Right() > aVisible.Right() )
2058 aInsertPos.X() -= aCompareRect.Right() - aVisible.Right();
2059 if ( aCompareRect.Bottom() > aVisible.Bottom() )
2060 aInsertPos.Y() -= aCompareRect.Bottom() - aVisible.Bottom();
2061
2062 if ( aInsertPos.X() < aVisible.Left() )
2063 aInsertPos.X() = aVisible.Left();
2064 if ( aInsertPos.Y() < aVisible.Top() )
2065 aInsertPos.Y() = aVisible.Top();
2066
2067 // nNeededWidth / nNeededHeight includes all borders - move aInsertPos to the
2068 // object position, inside the border
2069
2070 aInsertPos.X() += nBorder;
2071 aInsertPos.Y() += nBorder;
2072 }
2073 return aInsertPos;
2074 }
2075
GetChartDialogPos(const Size & rDialogSize,const Rectangle & rLogicChart)2076 Point ScTabView::GetChartDialogPos( const Size& rDialogSize, const Rectangle& rLogicChart )
2077 {
2078 // rDialogSize must be in pixels, rLogicChart in 1/100 mm. Return value is in pixels.
2079
2080 Point aRet;
2081
2082 // use the active window, or lower/right if frozen (as in CalcZoom)
2083 ScSplitPos eUsedPart = aViewData.GetActivePart();
2084 if ( aViewData.GetHSplitMode() == SC_SPLIT_FIX )
2085 eUsedPart = (WhichV(eUsedPart)==SC_SPLIT_TOP) ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT;
2086 if ( aViewData.GetVSplitMode() == SC_SPLIT_FIX )
2087 eUsedPart = (WhichH(eUsedPart)==SC_SPLIT_LEFT) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
2088
2089 ScGridWindow* pWin = pGridWin[eUsedPart];
2090 DBG_ASSERT( pWin, "Window not found" );
2091 if (pWin)
2092 {
2093 MapMode aDrawMode = pWin->GetDrawMapMode();
2094 Rectangle aObjPixel = pWin->LogicToPixel( rLogicChart, aDrawMode );
2095 Rectangle aObjAbs( pWin->OutputToAbsoluteScreenPixel( aObjPixel.TopLeft() ),
2096 pWin->OutputToAbsoluteScreenPixel( aObjPixel.BottomRight() ) );
2097
2098 Rectangle aDesktop = pWin->GetDesktopRectPixel();
2099 Size aSpace = pWin->LogicToPixel( Size( 8, 12 ), MAP_APPFONT );
2100
2101 ScDocument* pDoc = aViewData.GetDocument();
2102 SCTAB nTab = aViewData.GetTabNo();
2103 sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
2104
2105 bool bCenterHor = false;
2106
2107 if ( aDesktop.Bottom() - aObjAbs.Bottom() >= rDialogSize.Height() + aSpace.Height() )
2108 {
2109 // first preference: below the chart
2110
2111 aRet.Y() = aObjAbs.Bottom() + aSpace.Height();
2112 bCenterHor = true;
2113 }
2114 else if ( aObjAbs.Top() - aDesktop.Top() >= rDialogSize.Height() + aSpace.Height() )
2115 {
2116 // second preference: above the chart
2117
2118 aRet.Y() = aObjAbs.Top() - rDialogSize.Height() - aSpace.Height();
2119 bCenterHor = true;
2120 }
2121 else
2122 {
2123 bool bFitLeft = ( aObjAbs.Left() - aDesktop.Left() >= rDialogSize.Width() + aSpace.Width() );
2124 bool bFitRight = ( aDesktop.Right() - aObjAbs.Right() >= rDialogSize.Width() + aSpace.Width() );
2125
2126 if ( bFitLeft || bFitRight )
2127 {
2128 // if both fit, prefer right in RTL mode, left otherwise
2129 bool bPutRight = bFitRight && ( bLayoutRTL || !bFitLeft );
2130 if ( bPutRight )
2131 aRet.X() = aObjAbs.Right() + aSpace.Width();
2132 else
2133 aRet.X() = aObjAbs.Left() - rDialogSize.Width() - aSpace.Width();
2134
2135 // center vertically
2136 aRet.Y() = aObjAbs.Top() + ( aObjAbs.GetHeight() - rDialogSize.Height() ) / 2;
2137 }
2138 else
2139 {
2140 // doesn't fit on any edge - put at the bottom of the screen
2141 aRet.Y() = aDesktop.Bottom() - rDialogSize.Height();
2142 bCenterHor = true;
2143 }
2144 }
2145 if ( bCenterHor )
2146 aRet.X() = aObjAbs.Left() + ( aObjAbs.GetWidth() - rDialogSize.Width() ) / 2;
2147
2148 // limit to screen (centering might lead to invalid positions)
2149 if ( aRet.X() + rDialogSize.Width() - 1 > aDesktop.Right() )
2150 aRet.X() = aDesktop.Right() - rDialogSize.Width() + 1;
2151 if ( aRet.X() < aDesktop.Left() )
2152 aRet.X() = aDesktop.Left();
2153 if ( aRet.Y() + rDialogSize.Height() - 1 > aDesktop.Bottom() )
2154 aRet.Y() = aDesktop.Bottom() - rDialogSize.Height() + 1;
2155 if ( aRet.Y() < aDesktop.Top() )
2156 aRet.Y() = aDesktop.Top();
2157 }
2158
2159 return aRet;
2160 }
2161
LockModifiers(sal_uInt16 nModifiers)2162 void ScTabView::LockModifiers( sal_uInt16 nModifiers )
2163 {
2164 pSelEngine->LockModifiers( nModifiers );
2165 pHdrSelEng->LockModifiers( nModifiers );
2166 }
2167
GetLockedModifiers() const2168 sal_uInt16 ScTabView::GetLockedModifiers() const
2169 {
2170 return pSelEngine->GetLockedModifiers();
2171 }
2172
GetMousePosPixel()2173 Point ScTabView::GetMousePosPixel()
2174 {
2175 Point aPos;
2176 ScGridWindow* pWin = (ScGridWindow*)GetActiveWin();
2177
2178 if ( pWin )
2179 aPos = pWin->GetMousePosPixel();
2180
2181 return aPos;
2182 }
2183
lcl_MouseIsOverWin(const Point & rScreenPosPixel,Window * pWin)2184 sal_Bool lcl_MouseIsOverWin( const Point& rScreenPosPixel, Window* pWin )
2185 {
2186 if (pWin)
2187 {
2188 // SPLIT_HANDLE_SIZE draufaddieren, damit das Einrasten genau
2189 // auf dem Splitter nicht aussetzt
2190
2191 Point aRel = pWin->NormalizedScreenToOutputPixel( rScreenPosPixel );
2192 Size aWinSize = pWin->GetOutputSizePixel();
2193 if ( aRel.X() >= 0 && aRel.X() < aWinSize.Width() + SPLIT_HANDLE_SIZE &&
2194 aRel.Y() >= 0 && aRel.Y() < aWinSize.Height() + SPLIT_HANDLE_SIZE )
2195 return sal_True;
2196 }
2197 return sal_False;
2198 }
2199
SnapSplitPos(Point & rScreenPosPixel)2200 void ScTabView::SnapSplitPos( Point& rScreenPosPixel )
2201 {
2202 sal_Bool bOverWin = sal_False;
2203 sal_uInt16 i;
2204 for (i=0; i<4; i++)
2205 if (lcl_MouseIsOverWin(rScreenPosPixel,pGridWin[i]))
2206 bOverWin = sal_True;
2207
2208 if (!bOverWin)
2209 return;
2210
2211 // #74761# don't snap to cells if the scale will be modified afterwards
2212 if ( GetZoomType() != SVX_ZOOM_PERCENT )
2213 return;
2214
2215 ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
2216 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
2217 ePos = SC_SPLIT_TOPLEFT;
2218
2219 Window* pWin = pGridWin[ePos];
2220 if (!pWin)
2221 {
2222 DBG_ERROR("Window NULL");
2223 return;
2224 }
2225
2226 Point aMouse = pWin->NormalizedScreenToOutputPixel( rScreenPosPixel );
2227 SCsCOL nPosX;
2228 SCsROW nPosY;
2229 // #52949# bNextIfLarge=FALSE: nicht auf naechste Zelle, wenn ausserhalb des Fensters
2230 aViewData.GetPosFromPixel( aMouse.X(), aMouse.Y(), ePos, nPosX, nPosY, sal_True, sal_False, sal_False );
2231 sal_Bool bLeft;
2232 sal_Bool bTop;
2233 aViewData.GetMouseQuadrant( aMouse, ePos, nPosX, nPosY, bLeft, bTop );
2234 if (!bLeft)
2235 ++nPosX;
2236 if (!bTop)
2237 ++nPosY;
2238 aMouse = aViewData.GetScrPos( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), ePos, sal_True );
2239 rScreenPosPixel = pWin->OutputToNormalizedScreenPixel( aMouse );
2240 }
2241
FreezeSplitters(sal_Bool bFreeze)2242 void ScTabView::FreezeSplitters( sal_Bool bFreeze )
2243 {
2244 ScSplitMode eOldH = aViewData.GetHSplitMode();
2245 ScSplitMode eOldV = aViewData.GetVSplitMode();
2246
2247 ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
2248 if ( eOldV != SC_SPLIT_NONE )
2249 ePos = SC_SPLIT_TOPLEFT;
2250 Window* pWin = pGridWin[ePos];
2251
2252 sal_Bool bLayoutRTL = aViewData.GetDocument()->IsLayoutRTL( aViewData.GetTabNo() );
2253
2254 if ( bFreeze )
2255 {
2256 Point aWinStart = pWin->GetPosPixel();
2257
2258 Point aSplit;
2259 SCsCOL nPosX;
2260 SCsROW nPosY;
2261 if (eOldH != SC_SPLIT_NONE || eOldV != SC_SPLIT_NONE)
2262 {
2263 if (eOldH != SC_SPLIT_NONE)
2264 {
2265 long nSplitPos = aViewData.GetHSplitPos();
2266 if ( bLayoutRTL )
2267 nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
2268 aSplit.X() = nSplitPos - aWinStart.X();
2269 }
2270 if (eOldV != SC_SPLIT_NONE)
2271 aSplit.Y() = aViewData.GetVSplitPos() - aWinStart.Y();
2272
2273 aViewData.GetPosFromPixel( aSplit.X(), aSplit.Y(), ePos, nPosX, nPosY );
2274 sal_Bool bLeft;
2275 sal_Bool bTop;
2276 aViewData.GetMouseQuadrant( aSplit, ePos, nPosX, nPosY, bLeft, bTop );
2277 if (!bLeft)
2278 ++nPosX;
2279 if (!bTop)
2280 ++nPosY;
2281 }
2282 else
2283 {
2284 nPosX = static_cast<SCsCOL>( aViewData.GetCurX());
2285 nPosY = static_cast<SCsROW>( aViewData.GetCurY());
2286 }
2287
2288 SCCOL nLeftPos = aViewData.GetPosX(SC_SPLIT_LEFT);
2289 SCROW nTopPos = aViewData.GetPosY(SC_SPLIT_BOTTOM);
2290 SCCOL nRightPos = static_cast<SCCOL>(nPosX);
2291 SCROW nBottomPos = static_cast<SCROW>(nPosY);
2292 if (eOldH != SC_SPLIT_NONE)
2293 if (aViewData.GetPosX(SC_SPLIT_RIGHT) > nRightPos)
2294 nRightPos = aViewData.GetPosX(SC_SPLIT_RIGHT);
2295 if (eOldV != SC_SPLIT_NONE)
2296 {
2297 nTopPos = aViewData.GetPosY(SC_SPLIT_TOP);
2298 if (aViewData.GetPosY(SC_SPLIT_BOTTOM) > nBottomPos)
2299 nBottomPos = aViewData.GetPosY(SC_SPLIT_BOTTOM);
2300 }
2301
2302 aSplit = aViewData.GetScrPos( static_cast<SCCOL>(nPosX), static_cast<SCROW>(nPosY), ePos, sal_True );
2303 if (nPosX > aViewData.GetPosX(SC_SPLIT_LEFT)) // (aSplit.X() > 0) doesn't work for RTL
2304 {
2305 long nSplitPos = aSplit.X() + aWinStart.X();
2306 if ( bLayoutRTL )
2307 nSplitPos = pFrameWin->GetOutputSizePixel().Width() - nSplitPos - 1;
2308
2309 aViewData.SetHSplitMode( SC_SPLIT_FIX );
2310 aViewData.SetHSplitPos( nSplitPos );
2311 aViewData.SetFixPosX( nPosX );
2312
2313 aViewData.SetPosX(SC_SPLIT_LEFT, nLeftPos);
2314 aViewData.SetPosX(SC_SPLIT_RIGHT, nRightPos);
2315 }
2316 else
2317 aViewData.SetHSplitMode( SC_SPLIT_NONE );
2318 if (aSplit.Y() > 0)
2319 {
2320 aViewData.SetVSplitMode( SC_SPLIT_FIX );
2321 aViewData.SetVSplitPos( aSplit.Y() + aWinStart.Y() );
2322 aViewData.SetFixPosY( nPosY );
2323
2324 aViewData.SetPosY(SC_SPLIT_TOP, nTopPos);
2325 aViewData.SetPosY(SC_SPLIT_BOTTOM, nBottomPos);
2326 }
2327 else
2328 aViewData.SetVSplitMode( SC_SPLIT_NONE );
2329 }
2330 else // Fixierung aufheben
2331 {
2332 if ( eOldH == SC_SPLIT_FIX )
2333 aViewData.SetHSplitMode( SC_SPLIT_NORMAL );
2334 if ( eOldV == SC_SPLIT_FIX )
2335 aViewData.SetVSplitMode( SC_SPLIT_NORMAL );
2336 }
2337
2338 // #61410# Form-Layer muss den sichtbaren Ausschnitt aller Fenster kennen
2339 // dafuer muss hier schon der MapMode stimmen
2340 for (sal_uInt16 i=0; i<4; i++)
2341 if (pGridWin[i])
2342 pGridWin[i]->SetMapMode( pGridWin[i]->GetDrawMapMode() );
2343 SetNewVisArea();
2344
2345 RepeatResize(sal_False);
2346
2347 UpdateShow();
2348 PaintLeft();
2349 PaintTop();
2350 PaintGrid();
2351
2352 // SC_FOLLOW_NONE: only update active part
2353 AlignToCursor( aViewData.GetCurX(), aViewData.GetCurY(), SC_FOLLOW_NONE );
2354 UpdateAutoFillMark();
2355
2356 InvalidateSplit();
2357 }
2358
RemoveSplit()2359 void ScTabView::RemoveSplit()
2360 {
2361 DoHSplit( 0 );
2362 DoVSplit( 0 );
2363 RepeatResize();
2364 }
2365
SplitAtCursor()2366 void ScTabView::SplitAtCursor()
2367 {
2368 ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
2369 if ( aViewData.GetVSplitMode() != SC_SPLIT_NONE )
2370 ePos = SC_SPLIT_TOPLEFT;
2371 Window* pWin = pGridWin[ePos];
2372 Point aWinStart = pWin->GetPosPixel();
2373
2374 SCCOL nPosX = aViewData.GetCurX();
2375 SCROW nPosY = aViewData.GetCurY();
2376 Point aSplit = aViewData.GetScrPos( nPosX, nPosY, ePos, sal_True );
2377 if ( nPosX > 0 )
2378 DoHSplit( aSplit.X() + aWinStart.X() );
2379 else
2380 DoHSplit( 0 );
2381 if ( nPosY > 0 )
2382 DoVSplit( aSplit.Y() + aWinStart.Y() );
2383 else
2384 DoVSplit( 0 );
2385 RepeatResize();
2386 }
2387
SplitAtPixel(const Point & rPixel,sal_Bool bHor,sal_Bool bVer)2388 void ScTabView::SplitAtPixel( const Point& rPixel, sal_Bool bHor, sal_Bool bVer ) // fuer API
2389 {
2390 // Pixel ist auf die ganze View bezogen, nicht auf das erste GridWin
2391
2392 if (bHor)
2393 {
2394 if ( rPixel.X() > 0 )
2395 DoHSplit( rPixel.X() );
2396 else
2397 DoHSplit( 0 );
2398 }
2399 if (bVer)
2400 {
2401 if ( rPixel.Y() > 0 )
2402 DoVSplit( rPixel.Y() );
2403 else
2404 DoVSplit( 0 );
2405 }
2406 RepeatResize();
2407 }
2408
InvalidateSplit()2409 void ScTabView::InvalidateSplit()
2410 {
2411 SfxBindings& rBindings = aViewData.GetBindings();
2412 rBindings.Invalidate( SID_WINDOW_SPLIT );
2413 rBindings.Invalidate( SID_WINDOW_FIX );
2414
2415 pHSplitter->SetFixed( aViewData.GetHSplitMode() == SC_SPLIT_FIX );
2416 pVSplitter->SetFixed( aViewData.GetVSplitMode() == SC_SPLIT_FIX );
2417 }
2418
SetNewVisArea()2419 void ScTabView::SetNewVisArea()
2420 {
2421 // #63854# fuer die Controls muss bei VisAreaChanged der Draw-MapMode eingestellt sein
2422 // (auch wenn ansonsten der Edit-MapMode gesetzt ist)
2423 MapMode aOldMode[4];
2424 MapMode aDrawMode[4];
2425 sal_uInt16 i;
2426 for (i=0; i<4; i++)
2427 if (pGridWin[i])
2428 {
2429 aOldMode[i] = pGridWin[i]->GetMapMode();
2430 aDrawMode[i] = pGridWin[i]->GetDrawMapMode();
2431 if (aDrawMode[i] != aOldMode[i])
2432 pGridWin[i]->SetMapMode(aDrawMode[i]);
2433 }
2434
2435 Window* pActive = pGridWin[aViewData.GetActivePart()];
2436 if (pActive)
2437 aViewData.GetViewShell()->VisAreaChanged(
2438 pActive->PixelToLogic(Rectangle(Point(),pActive->GetOutputSizePixel())) );
2439 if (pDrawView)
2440 pDrawView->VisAreaChanged(); // kein Window uebergeben -> alle Fenster
2441
2442 UpdateAllOverlays(); // #i79909# with drawing MapMode set
2443
2444 for (i=0; i<4; i++)
2445 if (pGridWin[i] && aDrawMode[i] != aOldMode[i])
2446 {
2447 pGridWin[i]->flushOverlayManager(); // #i79909# flush overlays before switching to edit MapMode
2448 pGridWin[i]->SetMapMode(aOldMode[i]);
2449 }
2450
2451 SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
2452 if (pViewFrame)
2453 {
2454 SfxFrame& rFrame = pViewFrame->GetFrame();
2455 com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = rFrame.GetController();
2456 if (xController.is())
2457 {
2458 ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
2459 if (pImp)
2460 pImp->VisAreaChanged();
2461 }
2462 }
2463 if (aViewData.GetViewShell()->HasAccessibilityObjects())
2464 aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_VISAREACHANGED));
2465 }
2466
HasPageFieldDataAtCursor() const2467 sal_Bool ScTabView::HasPageFieldDataAtCursor() const
2468 {
2469 ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2470 SCCOL nCol = aViewData.GetCurX();
2471 SCROW nRow = aViewData.GetCurY();
2472 if (pWin)
2473 return pWin->GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE;
2474
2475 return sal_False;
2476 }
2477
StartDataSelect()2478 void ScTabView::StartDataSelect()
2479 {
2480 ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
2481 SCCOL nCol = aViewData.GetCurX();
2482 SCROW nRow = aViewData.GetCurY();
2483
2484 if (!pWin)
2485 return;
2486
2487 switch (pWin->GetDPFieldOrientation(nCol, nRow))
2488 {
2489 case sheet::DataPilotFieldOrientation_PAGE:
2490 // #i36598# If the cursor is on a page field's data cell,
2491 // no meaningful input is possible anyway, so this function
2492 // can be used to select a page field entry.
2493 pWin->LaunchPageFieldMenu( nCol, nRow );
2494 break;
2495 case sheet::DataPilotFieldOrientation_COLUMN:
2496 case sheet::DataPilotFieldOrientation_ROW:
2497 pWin->LaunchDPFieldMenu( nCol, nRow );
2498 break;
2499 default:
2500 pWin->DoAutoFilterMenue( nCol, nRow, sal_True );
2501 }
2502 }
2503
EnableRefInput(sal_Bool bFlag)2504 void ScTabView::EnableRefInput(sal_Bool bFlag)
2505 {
2506 aHScrollLeft.EnableInput(bFlag);
2507 aHScrollRight.EnableInput(bFlag);
2508 aVScrollBottom.EnableInput(bFlag);
2509 aVScrollTop.EnableInput(bFlag);
2510 aScrollBarBox.EnableInput(bFlag);
2511
2512 // ab hier dynamisch angelegte
2513
2514 if(pTabControl!=NULL) pTabControl->EnableInput(bFlag,sal_True);
2515
2516 if(pGridWin[SC_SPLIT_BOTTOMLEFT]!=NULL)
2517 pGridWin[SC_SPLIT_BOTTOMLEFT]->EnableInput(bFlag,sal_False);
2518 if(pGridWin[SC_SPLIT_BOTTOMRIGHT]!=NULL)
2519 pGridWin[SC_SPLIT_BOTTOMRIGHT]->EnableInput(bFlag,sal_False);
2520 if(pGridWin[SC_SPLIT_TOPLEFT]!=NULL)
2521 pGridWin[SC_SPLIT_TOPLEFT]->EnableInput(bFlag,sal_False);
2522 if(pGridWin[SC_SPLIT_TOPRIGHT]!=NULL)
2523 pGridWin[SC_SPLIT_TOPRIGHT]->EnableInput(bFlag,sal_False);
2524 if(pColBar[SC_SPLIT_RIGHT]!=NULL)
2525 pColBar[SC_SPLIT_RIGHT]->EnableInput(bFlag,sal_False);
2526 if(pRowBar[SC_SPLIT_TOP]!=NULL)
2527 pRowBar[SC_SPLIT_TOP]->EnableInput(bFlag,sal_False);
2528 }
2529
2530
2531
2532