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 using namespace com::sun::star
;
56 // STATIC DATA -----------------------------------------------------------
59 void ScTabView::Init()
61 /* RTL layout of the view windows is done manually, because it depends on
62 the sheet orientation, not the UI setting. Note: controls that are
63 already constructed (e.g. scroll bars) have the RTL setting of the GUI.
64 Eventually this has to be disabled manually (see below). */
65 pFrameWin
->EnableRTL( false );
69 aScrollTimer
.SetTimeout(10);
70 aScrollTimer
.SetTimeoutHdl( LINK( this, ScTabView
, TimerHdl
) );
74 pGridWin
[SC_SPLIT_BOTTOMLEFT
] = new ScGridWindow( pFrameWin
, &aViewData
, SC_SPLIT_BOTTOMLEFT
);
76 pSelEngine
= new ScViewSelectionEngine( pGridWin
[SC_SPLIT_BOTTOMLEFT
], this,
77 SC_SPLIT_BOTTOMLEFT
);
78 aFunctionSet
.SetSelectionEngine( pSelEngine
);
80 pHdrSelEng
= new ScHeaderSelectionEngine( pFrameWin
, &aHdrFunc
);
82 pColBar
[SC_SPLIT_LEFT
] = new ScColBar( pFrameWin
, &aViewData
, SC_SPLIT_LEFT
,
83 &aHdrFunc
, pHdrSelEng
);
84 pColBar
[SC_SPLIT_RIGHT
] = NULL
;
85 pRowBar
[SC_SPLIT_BOTTOM
] = new ScRowBar( pFrameWin
, &aViewData
, SC_SPLIT_BOTTOM
,
86 &aHdrFunc
, pHdrSelEng
);
87 pRowBar
[SC_SPLIT_TOP
] = NULL
;
89 pColOutline
[i
] = pRowOutline
[i
] = NULL
;
91 pHSplitter
= new ScTabSplitter( pFrameWin
, WinBits( WB_HSCROLL
), &aViewData
);
92 pVSplitter
= new ScTabSplitter( pFrameWin
, WinBits( WB_VSCROLL
), &aViewData
);
94 // SSA: override default keyboard step size to allow snap to row/column
95 pHSplitter
->SetKeyboardStepSize( 1 );
96 pVSplitter
->SetKeyboardStepSize( 1 );
98 pTabControl
= new ScTabControl( pFrameWin
, &aViewData
);
99 /* #i97900# The tab control has to remain in RTL mode if GUI is RTL, this
100 is needed to draw the 3D effect correctly. The base TabBar implementes
101 mirroring independent from the GUI direction. Have to set RTL mode
102 explicitly because the parent frame window is already RTL disabled. */
103 pTabControl
->EnableRTL( Application::GetSettings().GetLayoutRTL() );
105 InitScrollBar( aHScrollLeft
, MAXCOL
+1 );
106 InitScrollBar( aHScrollRight
, MAXCOL
+1 );
107 InitScrollBar( aVScrollTop
, MAXROW
+1 );
108 InitScrollBar( aVScrollBottom
, MAXROW
+1 );
109 /* #i97900# scrollbars remain in correct RTL mode, needed mirroring etc.
110 is now handled correctly at the respective places. */
112 // Hier noch nichts anzeigen (Show), weil noch falsch angeordnet ist
113 // Show kommt dann aus UpdateShow beim ersten Resize
114 // pTabControl, pGridWin, aHScrollLeft, aVScrollBottom,
115 // aCornerButton, aScrollBarBox, pHSplitter, pVSplitter
119 pHSplitter
->SetSplitHdl( LINK( this, ScTabView
, SplitHdl
) );
120 pVSplitter
->SetSplitHdl( LINK( this, ScTabView
, SplitHdl
) );
122 // UpdateShow kommt beim Resize, oder bei Kopie einer bestehenden View aus dem ctor
127 // DrawView darf nicht im TabView - ctor angelegt werden,
128 // wenn die ViewShell noch nicht konstruiert ist...
129 // Das gilt auch fuer ViewOptionsHasChanged()
134 ScTabView::~ScTabView()
138 // remove selection object
139 ScModule
* pScMod
= SC_MOD();
140 ScSelectionTransferObj
* pOld
= pScMod
->GetSelectionTransfer();
141 if ( pOld
&& pOld
->GetView() == this )
144 pScMod
->SetSelectionTransfer( NULL
);
145 TransferableHelper::ClearSelection( GetActiveWin() ); // may delete pOld
148 DELETEZ(pBrushDocument
);
149 DELETEZ(pDrawBrushSet
);
151 DELETEZ(pPageBreakData
);
154 DELETEZ(pDrawActual
);
156 aViewData
.KillEditView(); // solange GridWin's noch existieren
163 pDrawView
->VCRemoveWin(pGridWin
[i
]);
164 pDrawView
->DeleteWindowFromPaintView(pGridWin
[i
]);
167 pDrawView
->HideSdrPage();
173 // Delete this before the grid windows, since it's a child window of one of them.
174 mpInputHintWindow
.reset();
184 delete pColOutline
[i
];
185 delete pRowOutline
[i
];
194 void ScTabView::MakeDrawView( sal_uInt8 nForceDesignMode
)
198 ScDrawLayer
* pLayer
= aViewData
.GetDocument()->GetDrawLayer();
199 OSL_ENSURE(pLayer
, "wo ist der Draw Layer ??");
202 pDrawView
= new ScDrawView( pGridWin
[SC_SPLIT_BOTTOMLEFT
], &aViewData
);
206 if ( SC_SPLIT_BOTTOMLEFT
!= (ScSplitPos
)i
)
207 pDrawView
->AddWindowToPaintView(pGridWin
[i
]);
208 pDrawView
->VCAddWin(pGridWin
[i
]);
210 pDrawView
->RecalcScale();
214 pGridWin
[i
]->SetMapMode(pGridWin
[i
]->GetDrawMapMode());
216 pGridWin
[i
]->Update(); // wegen Invalidate im DrawView ctor (ShowPage),
217 // damit gleich gezeichnet werden kann
219 SfxRequest
aSfxRequest(SID_OBJECT_SELECT
, 0,aViewData
.GetViewShell()->GetPool());
220 SetDrawFuncPtr(new FuSelection( aViewData
.GetViewShell(), GetActiveWin(), pDrawView
,
221 pLayer
,aSfxRequest
));
223 // used when switching back from page preview: restore saved design mode state
224 // (otherwise, keep the default from the draw view ctor)
225 if ( nForceDesignMode
!= SC_FORCEMODE_NONE
)
226 pDrawView
->SetDesignMode( nForceDesignMode
);
228 // an der FormShell anmelden
229 FmFormShell
* pFormSh
= aViewData
.GetViewShell()->GetFormShell();
231 pFormSh
->SetView(pDrawView
);
233 if (aViewData
.GetViewShell()->HasAccessibilityObjects())
234 aViewData
.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_MAKEDRAWLAYER
));
239 void ScTabView::DoAddWin( ScGridWindow
* pWin
)
243 pDrawView
->AddWindowToPaintView(pWin
);
244 pDrawView
->VCAddWin(pWin
);
247 pWin
->DrawLayerCreated();
251 void ScTabView::TabChanged( bool bSameTabButMoved
)
255 DrawDeselectAll(); // beendet auch Text-Edit-Modus
260 pDrawView
->VCRemoveWin(pGridWin
[i
]); // fuer alte Page
262 SCTAB nTab
= aViewData
.GetTabNo();
263 pDrawView
->HideSdrPage();
264 pDrawView
->ShowSdrPage(pDrawView
->GetModel()->GetPage(nTab
));
268 pDrawView
->RecalcScale();
269 pDrawView
->UpdateWorkArea(); // PageSize ist pro Page unterschiedlich
273 pDrawView
->VCAddWin(pGridWin
[i
]); // fuer neue Page
276 SfxBindings
& rBindings
= aViewData
.GetBindings();
278 // Es gibt keine einfache Moeglichkeit, alle Slots der FormShell zu invalidieren
279 // (fuer disablete Slots auf geschuetzten Tabellen), darum hier einfach alles...
280 rBindings
.InvalidateAll(false);
282 if (aViewData
.GetViewShell()->HasAccessibilityObjects())
284 SfxSimpleHint
aAccHint(SC_HINT_ACC_TABLECHANGED
);
285 aViewData
.GetViewShell()->BroadcastAccessibility(aAccHint
);
288 // notification for XActivationBroadcaster
289 SfxViewFrame
* pViewFrame
= aViewData
.GetViewShell()->GetViewFrame();
292 uno::Reference
<frame::XController
> xController
= pViewFrame
->GetFrame().GetController();
293 if (xController
.is())
295 ScTabViewObj
* pImp
= ScTabViewObj::getImplementation( xController
);
297 pImp
->SheetChanged( bSameTabButMoved
);
302 void ScTabView::UpdateLayerLocks()
306 SCTAB nTab
= aViewData
.GetTabNo();
307 bool bEx
= aViewData
.GetViewShell()->IsDrawSelMode();
308 bool bProt
= aViewData
.GetDocument()->IsTabProtected( nTab
) ||
309 aViewData
.GetSfxDocShell()->IsReadOnly();
310 bool bShared
= aViewData
.GetDocShell()->IsDocShared();
313 SdrLayerAdmin
& rAdmin
= pDrawView
->GetModel()->GetLayerAdmin();
314 pLayer
= rAdmin
.GetLayerPerID(SC_LAYER_BACK
);
316 pDrawView
->SetLayerLocked( pLayer
->GetName(), bProt
|| !bEx
|| bShared
);
317 pLayer
= rAdmin
.GetLayerPerID(SC_LAYER_INTERN
);
319 pDrawView
->SetLayerLocked( pLayer
->GetName(), true );
320 pLayer
= rAdmin
.GetLayerPerID(SC_LAYER_FRONT
);
322 pDrawView
->SetLayerLocked( pLayer
->GetName(), bProt
|| bShared
);
323 pLayer
= rAdmin
.GetLayerPerID(SC_LAYER_CONTROLS
);
325 pDrawView
->SetLayerLocked( pLayer
->GetName(), bProt
|| bShared
);
326 pLayer
= rAdmin
.GetLayerPerID(SC_LAYER_HIDDEN
);
329 pDrawView
->SetLayerLocked( pLayer
->GetName(), bProt
|| bShared
);
330 pDrawView
->SetLayerVisible( pLayer
->GetName(), false);
335 void ScTabView::DrawDeselectAll()
339 ScTabViewShell
* pViewSh
= aViewData
.GetViewShell();
341 ( pViewSh
->IsDrawTextShell() || pDrawActual
->GetSlotID() == SID_DRAW_NOTEEDIT
) )
343 // end text edit (as if escape pressed, in FuDraw)
344 aViewData
.GetDispatcher().Execute( pDrawActual
->GetSlotID(),
345 SFX_CALLMODE_SLOT
| SFX_CALLMODE_RECORD
);
348 pDrawView
->ScEndTextEdit();
349 pDrawView
->UnmarkAll();
351 if (!pViewSh
->IsDrawSelMode())
352 pViewSh
->SetDrawShell( false );
356 bool ScTabView::IsDrawTextEdit() const
359 return pDrawView
->IsTextEdit();
364 SvxZoomType
ScTabView::GetZoomType() const
366 return aViewData
.GetZoomType();
369 void ScTabView::SetZoomType( SvxZoomType eNew
, bool bAll
)
371 aViewData
.SetZoomType( eNew
, bAll
);
374 void ScTabView::SetZoom( const Fraction
& rNewX
, const Fraction
& rNewY
, bool bAll
)
376 aViewData
.SetZoom( rNewX
, rNewY
, bAll
);
378 pDrawView
->RecalcScale();
382 void ScTabView::RefreshZoom()
384 aViewData
.RefreshZoom();
386 pDrawView
->RecalcScale();
390 void ScTabView::SetPagebreakMode( bool bSet
)
392 aViewData
.SetPagebreakMode(bSet
);
394 pDrawView
->RecalcScale();
398 void ScTabView::ResetDrawDragMode()
401 pDrawView
->SetDragMode( SDRDRAG_MOVE
);
404 void ScTabView::ViewOptionsHasChanged( bool bHScrollChanged
, bool bGraphicsChanged
)
406 // DrawView erzeugen, wenn Gitter angezeigt werden soll
407 if ( !pDrawView
&& aViewData
.GetOptions().GetGridOptions().GetGridVisible() )
411 pDrawView
->UpdateUserViewOptions();
413 if (bGraphicsChanged
)
414 DrawEnableAnim(true); // DrawEnableAnim checks the options state
416 // if TabBar is set to visible, make sure its size is not 0
417 bool bGrow
= ( aViewData
.IsTabMode() && pTabControl
->GetSizePixel().Width() <= 0 );
419 // if ScrollBar is set to visible, TabBar must make room
420 bool bShrink
= ( bHScrollChanged
&& aViewData
.IsTabMode() && aViewData
.IsHScrollMode() &&
421 pTabControl
->GetSizePixel().Width() > SC_TABBAR_DEFWIDTH
);
423 if ( bGrow
|| bShrink
)
425 Size aSize
= pTabControl
->GetSizePixel();
426 aSize
.Width() = SC_TABBAR_DEFWIDTH
; // initial size
427 pTabControl
->SetSizePixel(aSize
); // DoResize is called later...
431 // Helper-Funktion gegen das Include des Drawing Layers
433 SdrView
* ScTabView::GetSdrView()
438 void ScTabView::DrawMarkListHasChanged()
441 pDrawView
->MarkListHasChanged();
444 void ScTabView::UpdateAnchorHandles()
447 pDrawView
->AdjustMarkHdl();
450 void ScTabView::UpdateIMap( SdrObject
* pObj
)
453 pDrawView
->UpdateIMap( pObj
);
456 void ScTabView::DrawMarkRect( const Rectangle
& rRect
)
458 //! store rectangle for repaint during drag
460 for (sal_uInt16 i
=0; i
<4; i
++)
462 if ( pGridWin
[i
] && pGridWin
[i
]->IsVisible() )
464 RasterOp aROp
= pGridWin
[i
]->GetRasterOp();
465 bool bHasLine
= pGridWin
[i
]->IsLineColor();
466 Color aLine
= pGridWin
[i
]->GetLineColor();
467 bool bHasFill
= pGridWin
[i
]->IsFillColor();
468 Color aFill
= pGridWin
[i
]->GetFillColor();
470 pGridWin
[i
]->SetRasterOp( ROP_INVERT
);
471 pGridWin
[i
]->SetLineColor( COL_BLACK
);
472 pGridWin
[i
]->SetFillColor();
474 pGridWin
[i
]->DrawRect(rRect
);
476 pGridWin
[i
]->SetRasterOp(aROp
);
478 pGridWin
[i
]->SetLineColor(aLine
);
480 pGridWin
[i
]->SetLineColor();
482 pGridWin
[i
]->SetFillColor(aFill
);
484 pGridWin
[i
]->SetFillColor();
489 void ScTabView::DrawEnableAnim(bool bSet
)
494 // dont start animations if display of graphics is disabled
495 // graphics are controlled by VOBJ_TYPE_OLE
496 if ( bSet
&& aViewData
.GetOptions().GetObjMode(VOBJ_TYPE_OLE
) == VOBJ_MODE_SHOW
)
498 if ( !pDrawView
->IsAnimationEnabled() )
500 pDrawView
->SetAnimationEnabled(true);
502 // Animierte GIFs muessen wieder gestartet werden:
503 ScDocument
* pDoc
= aViewData
.GetDocument();
505 if ( pGridWin
[i
] && pGridWin
[i
]->IsVisible() )
506 pDoc
->StartAnimations( aViewData
.GetTabNo(), pGridWin
[i
] );
511 pDrawView
->SetAnimationEnabled(false);
516 void ScTabView::UpdateDrawTextOutliner()
520 Outliner
* pOL
= pDrawView
->GetTextEditOutliner();
522 aViewData
.UpdateOutlinerFlags( *pOL
);
526 void ScTabView::DigitLanguageChanged()
528 LanguageType eNewLang
= SC_MOD()->GetOptDigitLanguage();
529 for (sal_uInt16 i
=0; i
<4; i
++)
531 pGridWin
[i
]->SetDigitLanguage( eNewLang
);
534 void ScTabView::ScrollToObject( SdrObject
* pDrawObj
)
538 // #i118524# use the BoundRect, this defines the visible area
539 MakeVisible(pDrawObj
->GetCurrentBoundRect());
543 void ScTabView::MakeVisible( const Rectangle
& rHMMRect
)
545 Window
* pWin
= GetActiveWin();
546 Size aWinSize
= pWin
->GetOutputSizePixel();
547 SCTAB nTab
= aViewData
.GetTabNo();
549 Rectangle aRect
= pWin
->LogicToPixel( rHMMRect
);
551 long nScrollX
=0, nScrollY
=0; // Pixel
553 if ( aRect
.Right() >= aWinSize
.Width() ) // rechts raus
555 nScrollX
= aRect
.Right() - aWinSize
.Width() + 1; // rechter Rand sichtbar
556 if ( aRect
.Left() < nScrollX
)
557 nScrollX
= aRect
.Left(); // links sichtbar (falls zu gross)
559 if ( aRect
.Bottom() >= aWinSize
.Height() ) // unten raus
561 nScrollY
= aRect
.Bottom() - aWinSize
.Height() + 1; // unterer Rand sichtbar
562 if ( aRect
.Top() < nScrollY
)
563 nScrollY
= aRect
.Top(); // oben sichtbar (falls zu gross)
566 if ( aRect
.Left() < 0 ) // links raus
567 nScrollX
= aRect
.Left(); // linker Rand sichtbar
568 if ( aRect
.Top() < 0 ) // oben raus
569 nScrollY
= aRect
.Top(); // oberer Rand sichtbar
571 if (nScrollX
|| nScrollY
)
573 ScDocument
* pDoc
= aViewData
.GetDocument();
574 if ( pDoc
->IsNegativePage( nTab
) )
575 nScrollX
= -nScrollX
;
577 double nPPTX
= aViewData
.GetPPTX();
578 double nPPTY
= aViewData
.GetPPTY();
579 ScSplitPos eWhich
= aViewData
.GetActivePart();
580 SCCOL nPosX
= aViewData
.GetPosX(WhichH(eWhich
));
581 SCROW nPosY
= aViewData
.GetPosY(WhichV(eWhich
));
583 long nLinesX
=0, nLinesY
=0; // Spalten/Zeilen - um mindestens nScrollX/Y scrollen
586 while (nScrollX
> 0 && nPosX
< MAXCOL
)
588 nScrollX
-= (long) ( pDoc
->GetColWidth(nPosX
, nTab
) * nPPTX
);
592 else if (nScrollX
< 0)
593 while (nScrollX
< 0 && nPosX
> 0)
596 nScrollX
+= (long) ( pDoc
->GetColWidth(nPosX
, nTab
) * nPPTX
);
601 while (nScrollY
> 0 && nPosY
< MAXROW
)
603 nScrollY
-= (long) ( pDoc
->GetRowHeight(nPosY
, nTab
) * nPPTY
);
607 else if (nScrollY
< 0)
608 while (nScrollY
< 0 && nPosY
> 0)
611 nScrollY
+= (long) ( pDoc
->GetRowHeight(nPosY
, nTab
) * nPPTY
);
615 ScrollLines( nLinesX
, nLinesY
); // ausfuehren
619 void ScTabView::SetBrushDocument( ScDocument
* pNew
, bool bLock
)
621 delete pBrushDocument
;
622 delete pDrawBrushSet
;
624 pBrushDocument
= pNew
;
625 pDrawBrushSet
= NULL
;
627 bLockPaintBrush
= bLock
;
629 aViewData
.GetBindings().Invalidate(SID_FORMATPAINTBRUSH
);
632 void ScTabView::SetDrawBrushSet( SfxItemSet
* pNew
, bool bLock
)
634 delete pBrushDocument
;
635 delete pDrawBrushSet
;
637 pBrushDocument
= NULL
;
638 pDrawBrushSet
= pNew
;
640 bLockPaintBrush
= bLock
;
642 aViewData
.GetBindings().Invalidate(SID_FORMATPAINTBRUSH
);
645 void ScTabView::ResetBrushDocument()
647 if ( HasPaintBrush() )
649 SetBrushDocument( NULL
, false );
650 SetActivePointer( Pointer( POINTER_ARROW
) ); // switch pointers also when ended with escape key
655 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */