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