1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "scitems.hxx"
21 #include <editeng/eeitem.hxx>
23 #include <svx/fmshell.hxx>
24 #include <svx/svdobj.hxx>
25 #include <svx/svdoutl.hxx>
26 #include <sfx2/bindings.hxx>
27 #include <sfx2/dispatch.hxx>
28 #include <sfx2/objsh.hxx>
30 #include "tabview.hxx"
31 #include "tabvwsh.hxx"
32 #include "document.hxx"
33 #include "gridwin.hxx"
34 #include "olinewin.hxx"
35 #include "tabsplit.hxx"
36 #include "colrowba.hxx"
37 #include "tabcont.hxx"
38 #include "hintwin.hxx"
40 #include "pagedata.hxx"
41 #include "hiranges.hxx"
42 #include "drawview.hxx"
43 #include "drwlayer.hxx"
45 #include "seltrans.hxx"
47 #include "AccessibilityHints.hxx"
49 #include "viewuno.hxx"
51 #include <vcl/svapp.hxx>
52 #include <vcl/settings.hxx>
54 #include <officecfg/Office/Calc.hxx>
56 using namespace com::sun::star
;
58 // STATIC DATA -----------------------------------------------------------
60 void ScTabView::Init()
62 /* RTL layout of the view windows is done manually, because it depends on
63 the sheet orientation, not the UI setting. Note: controls that are
64 already constructed (e.g. scroll bars) have the RTL setting of the GUI.
65 Eventually this has to be disabled manually (see below). */
66 pFrameWin
->EnableRTL( false );
70 mbInlineWithScrollbar
= officecfg::Office::Calc::Layout::Other::TabbarInlineWithScrollbar::get();
72 aScrollTimer
.SetTimeout(10);
73 aScrollTimer
.SetTimeoutHdl( LINK( this, ScTabView
, TimerHdl
) );
77 pGridWin
[SC_SPLIT_BOTTOMLEFT
] = VclPtr
<ScGridWindow
>::Create( pFrameWin
, &aViewData
, SC_SPLIT_BOTTOMLEFT
);
79 pSelEngine
= new ScViewSelectionEngine( pGridWin
[SC_SPLIT_BOTTOMLEFT
], this,
80 SC_SPLIT_BOTTOMLEFT
);
81 aFunctionSet
.SetSelectionEngine( pSelEngine
);
83 pHdrSelEng
= new ScHeaderSelectionEngine( pFrameWin
, &aHdrFunc
);
85 pColBar
[SC_SPLIT_LEFT
] = VclPtr
<ScColBar
>::Create( pFrameWin
, &aViewData
, SC_SPLIT_LEFT
,
86 &aHdrFunc
, pHdrSelEng
);
87 pColBar
[SC_SPLIT_RIGHT
] = NULL
;
88 pRowBar
[SC_SPLIT_BOTTOM
] = VclPtr
<ScRowBar
>::Create( pFrameWin
, &aViewData
, SC_SPLIT_BOTTOM
,
89 &aHdrFunc
, pHdrSelEng
);
90 pRowBar
[SC_SPLIT_TOP
] = NULL
;
92 pColOutline
[i
] = pRowOutline
[i
] = NULL
;
94 pHSplitter
= VclPtr
<ScTabSplitter
>::Create( pFrameWin
, WinBits( WB_HSCROLL
), &aViewData
);
95 pVSplitter
= VclPtr
<ScTabSplitter
>::Create( pFrameWin
, WinBits( WB_VSCROLL
), &aViewData
);
97 // SSA: override default keyboard step size to allow snap to row/column
98 pHSplitter
->SetKeyboardStepSize( 1 );
99 pVSplitter
->SetKeyboardStepSize( 1 );
101 pTabControl
= VclPtr
<ScTabControl
>::Create(pFrameWin
, &aViewData
);
102 if (mbInlineWithScrollbar
)
103 pTabControl
->SetStyle(pTabControl
->GetStyle() | WB_SIZEABLE
);
105 /* #i97900# The tab control has to remain in RTL mode if GUI is RTL, this
106 is needed to draw the 3D effect correctly. The base TabBar implementes
107 mirroring independent from the GUI direction. Have to set RTL mode
108 explicitly because the parent frame window is already RTL disabled. */
109 pTabControl
->EnableRTL( AllSettings::GetLayoutRTL() );
111 InitScrollBar( *aHScrollLeft
.get(), MAXCOL
+1 );
112 InitScrollBar( *aHScrollRight
.get(), MAXCOL
+1 );
113 InitScrollBar( *aVScrollTop
.get(), MAXROW
+1 );
114 InitScrollBar( *aVScrollBottom
.get(), MAXROW
+1 );
115 /* #i97900# scrollbars remain in correct RTL mode, needed mirroring etc.
116 is now handled correctly at the respective places. */
118 // Hier noch nichts anzeigen (Show), weil noch falsch angeordnet ist
119 // Show kommt dann aus UpdateShow beim ersten Resize
120 // pTabControl, pGridWin, aHScrollLeft, aVScrollBottom,
121 // aCornerButton, aScrollBarBox, pHSplitter, pVSplitter
125 pHSplitter
->SetSplitHdl( LINK( this, ScTabView
, SplitHdl
) );
126 pVSplitter
->SetSplitHdl( LINK( this, ScTabView
, SplitHdl
) );
128 // UpdateShow kommt beim Resize, oder bei Kopie einer bestehenden View aus dem ctor
133 // DrawView darf nicht im TabView - ctor angelegt werden,
134 // wenn die ViewShell noch nicht konstruiert ist...
135 // Das gilt auch fuer ViewOptionsHasChanged()
140 ScTabView::~ScTabView()
144 // remove selection object
145 ScModule
* pScMod
= SC_MOD();
146 ScSelectionTransferObj
* pOld
= pScMod
->GetSelectionTransfer();
147 if ( pOld
&& pOld
->GetView() == this )
150 pScMod
->SetSelectionTransfer( NULL
);
151 TransferableHelper::ClearSelection( GetActiveWin() ); // may delete pOld
154 DELETEZ(pBrushDocument
);
155 DELETEZ(pDrawBrushSet
);
157 DELETEZ(pPageBreakData
);
160 DELETEZ(pDrawActual
);
162 aViewData
.KillEditView(); // solange GridWin's noch existieren
169 pDrawView
->DeleteWindowFromPaintView(pGridWin
[i
]);
172 pDrawView
->HideSdrPage();
178 // Delete this before the grid windows, since it's a child window of one of them.
179 mpInputHintWindow
.disposeAndClear();
181 pGridWin
[i
].disposeAndClear();
187 pColBar
[i
].disposeAndClear();
188 pRowBar
[i
].disposeAndClear();
189 pColOutline
[i
].disposeAndClear();
190 pRowOutline
[i
].disposeAndClear();
193 aScrollBarBox
.disposeAndClear();
194 aCornerButton
.disposeAndClear();
195 aTopButton
.disposeAndClear();
196 aHScrollLeft
.disposeAndClear();
197 aHScrollRight
.disposeAndClear();
198 aVScrollTop
.disposeAndClear();
199 aVScrollBottom
.disposeAndClear();
201 pHSplitter
.disposeAndClear();
202 pVSplitter
.disposeAndClear();
203 pTabControl
.disposeAndClear();
206 void ScTabView::MakeDrawView( TriState nForceDesignMode
)
210 ScDrawLayer
* pLayer
= aViewData
.GetDocument()->GetDrawLayer();
211 OSL_ENSURE(pLayer
, "wo ist der Draw Layer ??");
214 pDrawView
= new ScDrawView( pGridWin
[SC_SPLIT_BOTTOMLEFT
], &aViewData
);
218 if ( SC_SPLIT_BOTTOMLEFT
!= (ScSplitPos
)i
)
219 pDrawView
->AddWindowToPaintView(pGridWin
[i
], 0);
221 pDrawView
->RecalcScale();
225 pGridWin
[i
]->SetMapMode(pGridWin
[i
]->GetDrawMapMode());
227 pGridWin
[i
]->Update(); // wegen Invalidate im DrawView ctor (ShowPage),
228 // damit gleich gezeichnet werden kann
230 SfxRequest
aSfxRequest(SID_OBJECT_SELECT
, SfxCallMode::SLOT
, aViewData
.GetViewShell()->GetPool());
231 SetDrawFuncPtr(new FuSelection( aViewData
.GetViewShell(), GetActiveWin(), pDrawView
,
232 pLayer
,aSfxRequest
));
234 // used when switching back from page preview: restore saved design mode state
235 // (otherwise, keep the default from the draw view ctor)
236 if ( nForceDesignMode
!= TRISTATE_INDET
)
237 pDrawView
->SetDesignMode( nForceDesignMode
);
239 // an der FormShell anmelden
240 FmFormShell
* pFormSh
= aViewData
.GetViewShell()->GetFormShell();
242 pFormSh
->SetView(pDrawView
);
244 if (aViewData
.GetViewShell()->HasAccessibilityObjects())
245 aViewData
.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_MAKEDRAWLAYER
));
250 void ScTabView::DoAddWin( ScGridWindow
* pWin
)
254 pDrawView
->AddWindowToPaintView(pWin
, 0);
257 pWin
->DrawLayerCreated();
261 void ScTabView::TabChanged( bool bSameTabButMoved
)
265 DrawDeselectAll(); // beendet auch Text-Edit-Modus
267 SCTAB nTab
= aViewData
.GetTabNo();
268 pDrawView
->HideSdrPage();
269 pDrawView
->ShowSdrPage(pDrawView
->GetModel()->GetPage(nTab
));
273 pDrawView
->RecalcScale();
274 pDrawView
->UpdateWorkArea(); // PageSize ist pro Page unterschiedlich
277 SfxBindings
& rBindings
= aViewData
.GetBindings();
279 // Es gibt keine einfache Moeglichkeit, alle Slots der FormShell zu invalidieren
280 // (fuer disablete Slots auf geschuetzten Tabellen), darum hier einfach alles...
281 rBindings
.InvalidateAll(false);
283 if (aViewData
.GetViewShell()->HasAccessibilityObjects())
285 SfxSimpleHint
aAccHint(SC_HINT_ACC_TABLECHANGED
);
286 aViewData
.GetViewShell()->BroadcastAccessibility(aAccHint
);
289 // notification for XActivationBroadcaster
290 SfxViewFrame
* pViewFrame
= aViewData
.GetViewShell()->GetViewFrame();
293 uno::Reference
<frame::XController
> xController
= pViewFrame
->GetFrame().GetController();
294 if (xController
.is())
296 ScTabViewObj
* pImp
= ScTabViewObj::getImplementation( xController
);
298 pImp
->SheetChanged( bSameTabButMoved
);
303 void ScTabView::UpdateLayerLocks()
307 SCTAB nTab
= aViewData
.GetTabNo();
308 bool bEx
= aViewData
.GetViewShell()->IsDrawSelMode();
309 bool bProt
= aViewData
.GetDocument()->IsTabProtected( nTab
) ||
310 aViewData
.GetSfxDocShell()->IsReadOnly();
311 bool bShared
= aViewData
.GetDocShell()->IsDocShared();
314 SdrLayerAdmin
& rAdmin
= pDrawView
->GetModel()->GetLayerAdmin();
315 pLayer
= rAdmin
.GetLayerPerID(SC_LAYER_BACK
);
317 pDrawView
->SetLayerLocked( pLayer
->GetName(), bProt
|| !bEx
|| bShared
);
318 pLayer
= rAdmin
.GetLayerPerID(SC_LAYER_INTERN
);
320 pDrawView
->SetLayerLocked( pLayer
->GetName(), true );
321 pLayer
= rAdmin
.GetLayerPerID(SC_LAYER_FRONT
);
323 pDrawView
->SetLayerLocked( pLayer
->GetName(), bProt
|| bShared
);
324 pLayer
= rAdmin
.GetLayerPerID(SC_LAYER_CONTROLS
);
326 pDrawView
->SetLayerLocked( pLayer
->GetName(), bProt
|| bShared
);
327 pLayer
= rAdmin
.GetLayerPerID(SC_LAYER_HIDDEN
);
330 pDrawView
->SetLayerLocked( pLayer
->GetName(), bProt
|| bShared
);
331 pDrawView
->SetLayerVisible( pLayer
->GetName(), false);
336 void ScTabView::DrawDeselectAll()
340 ScTabViewShell
* pViewSh
= aViewData
.GetViewShell();
342 ( pViewSh
->IsDrawTextShell() || pDrawActual
->GetSlotID() == SID_DRAW_NOTEEDIT
) )
344 // end text edit (as if escape pressed, in FuDraw)
345 aViewData
.GetDispatcher().Execute( pDrawActual
->GetSlotID(),
346 SfxCallMode::SLOT
| SfxCallMode::RECORD
);
349 pDrawView
->ScEndTextEdit();
350 pDrawView
->UnmarkAll();
352 if (!pViewSh
->IsDrawSelMode())
353 pViewSh
->SetDrawShell( false );
357 bool ScTabView::IsDrawTextEdit() const
360 return pDrawView
->IsTextEdit();
365 SvxZoomType
ScTabView::GetZoomType() const
367 return aViewData
.GetZoomType();
370 void ScTabView::SetZoomType( SvxZoomType eNew
, bool bAll
)
372 aViewData
.SetZoomType( eNew
, bAll
);
375 void ScTabView::SetZoom( const Fraction
& rNewX
, const Fraction
& rNewY
, bool bAll
)
377 aViewData
.SetZoom( rNewX
, rNewY
, bAll
);
379 pDrawView
->RecalcScale();
383 void ScTabView::RefreshZoom()
385 aViewData
.RefreshZoom();
387 pDrawView
->RecalcScale();
391 void ScTabView::SetPagebreakMode( bool bSet
)
393 aViewData
.SetPagebreakMode(bSet
);
395 pDrawView
->RecalcScale();
399 void ScTabView::ResetDrawDragMode()
402 pDrawView
->SetDragMode( SDRDRAG_MOVE
);
405 void ScTabView::ViewOptionsHasChanged( bool bHScrollChanged
, bool bGraphicsChanged
)
407 // DrawView erzeugen, wenn Gitter angezeigt werden soll
408 if ( !pDrawView
&& aViewData
.GetOptions().GetGridOptions().GetGridVisible() )
412 pDrawView
->UpdateUserViewOptions();
414 if (bGraphicsChanged
)
415 DrawEnableAnim(true); // DrawEnableAnim checks the options state
417 // if TabBar is set to visible, make sure its size is not 0
418 bool bGrow
= ( aViewData
.IsTabMode() && pTabControl
->GetSizePixel().Width() <= 0 );
420 // if ScrollBar is set to visible, TabBar must make room
421 bool bShrink
= ( bHScrollChanged
&& aViewData
.IsTabMode() && aViewData
.IsHScrollMode() &&
422 pTabControl
->GetSizePixel().Width() > SC_TABBAR_DEFWIDTH
);
424 if ( bGrow
|| bShrink
)
426 Size aSize
= pTabControl
->GetSizePixel();
427 aSize
.Width() = SC_TABBAR_DEFWIDTH
; // initial size
428 pTabControl
->SetSizePixel(aSize
); // DoResize is called later...
432 // Helper-Funktion gegen das Include des Drawing Layers
434 void ScTabView::DrawMarkListHasChanged()
437 pDrawView
->MarkListHasChanged();
440 void ScTabView::UpdateAnchorHandles()
443 pDrawView
->AdjustMarkHdl();
446 void ScTabView::UpdateIMap( SdrObject
* pObj
)
449 pDrawView
->UpdateIMap( pObj
);
452 void ScTabView::DrawEnableAnim(bool bSet
)
457 // dont start animations if display of graphics is disabled
458 // graphics are controlled by VOBJ_TYPE_OLE
459 if ( bSet
&& aViewData
.GetOptions().GetObjMode(VOBJ_TYPE_OLE
) == VOBJ_MODE_SHOW
)
461 if ( !pDrawView
->IsAnimationEnabled() )
463 pDrawView
->SetAnimationEnabled(true);
465 // Animierte GIFs muessen wieder gestartet werden:
466 ScDocument
* pDoc
= aViewData
.GetDocument();
468 if ( pGridWin
[i
] && pGridWin
[i
]->IsVisible() )
469 pDoc
->StartAnimations( aViewData
.GetTabNo(), pGridWin
[i
] );
474 pDrawView
->SetAnimationEnabled(false);
479 void ScTabView::UpdateDrawTextOutliner()
483 Outliner
* pOL
= pDrawView
->GetTextEditOutliner();
485 aViewData
.UpdateOutlinerFlags( *pOL
);
489 void ScTabView::DigitLanguageChanged()
491 LanguageType eNewLang
= SC_MOD()->GetOptDigitLanguage();
492 for (sal_uInt16 i
=0; i
<4; i
++)
494 pGridWin
[i
]->SetDigitLanguage( eNewLang
);
497 void ScTabView::ScrollToObject( SdrObject
* pDrawObj
)
501 // #i118524# use the BoundRect, this defines the visible area
502 MakeVisible(pDrawObj
->GetCurrentBoundRect());
506 void ScTabView::MakeVisible( const Rectangle
& rHMMRect
)
508 vcl::Window
* pWin
= GetActiveWin();
509 Size aWinSize
= pWin
->GetOutputSizePixel();
510 SCTAB nTab
= aViewData
.GetTabNo();
512 Rectangle aRect
= pWin
->LogicToPixel( rHMMRect
);
514 long nScrollX
=0, nScrollY
=0; // Pixel
516 if ( aRect
.Right() >= aWinSize
.Width() ) // rechts raus
518 nScrollX
= aRect
.Right() - aWinSize
.Width() + 1; // rechter Rand sichtbar
519 if ( aRect
.Left() < nScrollX
)
520 nScrollX
= aRect
.Left(); // links sichtbar (falls zu gross)
522 if ( aRect
.Bottom() >= aWinSize
.Height() ) // unten raus
524 nScrollY
= aRect
.Bottom() - aWinSize
.Height() + 1; // unterer Rand sichtbar
525 if ( aRect
.Top() < nScrollY
)
526 nScrollY
= aRect
.Top(); // oben sichtbar (falls zu gross)
529 if ( aRect
.Left() < 0 ) // links raus
530 nScrollX
= aRect
.Left(); // linker Rand sichtbar
531 if ( aRect
.Top() < 0 ) // oben raus
532 nScrollY
= aRect
.Top(); // oberer Rand sichtbar
534 if (nScrollX
|| nScrollY
)
536 ScDocument
* pDoc
= aViewData
.GetDocument();
537 if ( pDoc
->IsNegativePage( nTab
) )
538 nScrollX
= -nScrollX
;
540 double nPPTX
= aViewData
.GetPPTX();
541 double nPPTY
= aViewData
.GetPPTY();
542 ScSplitPos eWhich
= aViewData
.GetActivePart();
543 SCCOL nPosX
= aViewData
.GetPosX(WhichH(eWhich
));
544 SCROW nPosY
= aViewData
.GetPosY(WhichV(eWhich
));
546 long nLinesX
=0, nLinesY
=0; // Spalten/Zeilen - um mindestens nScrollX/Y scrollen
549 while (nScrollX
> 0 && nPosX
< MAXCOL
)
551 nScrollX
-= (long) ( pDoc
->GetColWidth(nPosX
, nTab
) * nPPTX
);
555 else if (nScrollX
< 0)
556 while (nScrollX
< 0 && nPosX
> 0)
559 nScrollX
+= (long) ( pDoc
->GetColWidth(nPosX
, nTab
) * nPPTX
);
564 while (nScrollY
> 0 && nPosY
< MAXROW
)
566 nScrollY
-= (long) ( pDoc
->GetRowHeight(nPosY
, nTab
) * nPPTY
);
570 else if (nScrollY
< 0)
571 while (nScrollY
< 0 && nPosY
> 0)
574 nScrollY
+= (long) ( pDoc
->GetRowHeight(nPosY
, nTab
) * nPPTY
);
578 ScrollLines( nLinesX
, nLinesY
); // ausfuehren
582 void ScTabView::SetBrushDocument( ScDocument
* pNew
, bool bLock
)
584 delete pBrushDocument
;
585 delete pDrawBrushSet
;
587 pBrushDocument
= pNew
;
588 pDrawBrushSet
= NULL
;
590 bLockPaintBrush
= bLock
;
592 aViewData
.GetBindings().Invalidate(SID_FORMATPAINTBRUSH
);
595 void ScTabView::SetDrawBrushSet( SfxItemSet
* pNew
, bool bLock
)
597 delete pBrushDocument
;
598 delete pDrawBrushSet
;
600 pBrushDocument
= NULL
;
601 pDrawBrushSet
= pNew
;
603 bLockPaintBrush
= bLock
;
605 aViewData
.GetBindings().Invalidate(SID_FORMATPAINTBRUSH
);
608 void ScTabView::ResetBrushDocument()
610 if ( HasPaintBrush() )
612 SetBrushDocument( NULL
, false );
613 SetActivePointer( Pointer( PointerStyle::Arrow
) ); // switch pointers also when ended with escape key
617 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */