Bump version to 4.3-4
[LibreOffice.git] / sc / source / ui / view / tabview5.cxx
blob4fea5a32da98f02bf12a7eb5b72b4cd54b021b3e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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"
39 #include "sc.hrc"
40 #include "pagedata.hxx"
41 #include "hiranges.hxx"
42 #include "drawview.hxx"
43 #include "drwlayer.hxx"
44 #include "fusel.hxx"
45 #include "seltrans.hxx"
46 #include "scmod.hxx"
47 #include "AccessibilityHints.hxx"
48 #include "docsh.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 );
67 sal_uInt16 i;
69 aScrollTimer.SetTimeout(10);
70 aScrollTimer.SetTimeoutHdl( LINK( this, ScTabView, TimerHdl ) );
72 for (i=0; i<4; i++)
73 pGridWin[i] = NULL;
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;
88 for (i=0; i<2; i++)
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
117 // Splitter
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
124 pDrawActual = NULL;
125 pDrawOld = NULL;
127 // DrawView darf nicht im TabView - ctor angelegt werden,
128 // wenn die ViewShell noch nicht konstruiert ist...
129 // Das gilt auch fuer ViewOptionsHasChanged()
131 TestHintWindow();
134 ScTabView::~ScTabView()
136 sal_uInt16 i;
138 // remove selection object
139 ScModule* pScMod = SC_MOD();
140 ScSelectionTransferObj* pOld = pScMod->GetSelectionTransfer();
141 if ( pOld && pOld->GetView() == this )
143 pOld->ForgetView();
144 pScMod->SetSelectionTransfer( NULL );
145 TransferableHelper::ClearSelection( GetActiveWin() ); // may delete pOld
148 DELETEZ(pBrushDocument);
149 DELETEZ(pDrawBrushSet);
151 DELETEZ(pPageBreakData);
153 DELETEZ(pDrawOld);
154 DELETEZ(pDrawActual);
156 aViewData.KillEditView(); // solange GridWin's noch existieren
158 if (pDrawView)
160 for (i=0; i<4; i++)
161 if (pGridWin[i])
163 pDrawView->VCRemoveWin(pGridWin[i]);
164 pDrawView->DeleteWindowFromPaintView(pGridWin[i]);
167 pDrawView->HideSdrPage();
168 delete pDrawView;
171 delete pSelEngine;
173 // Delete this before the grid windows, since it's a child window of one of them.
174 mpInputHintWindow.reset();
175 for (i=0; i<4; i++)
176 delete pGridWin[i];
178 delete pHdrSelEng;
180 for (i=0; i<2; i++)
182 delete pColBar[i];
183 delete pRowBar[i];
184 delete pColOutline[i];
185 delete pRowOutline[i];
188 delete pHSplitter;
189 delete pVSplitter;
191 delete pTabControl;
194 void ScTabView::MakeDrawView( sal_uInt8 nForceDesignMode )
196 if (!pDrawView)
198 ScDrawLayer* pLayer = aViewData.GetDocument()->GetDrawLayer();
199 OSL_ENSURE(pLayer, "wo ist der Draw Layer ??");
201 sal_uInt16 i;
202 pDrawView = new ScDrawView( pGridWin[SC_SPLIT_BOTTOMLEFT], &aViewData );
203 for (i=0; i<4; i++)
204 if (pGridWin[i])
206 if ( SC_SPLIT_BOTTOMLEFT != (ScSplitPos)i )
207 pDrawView->AddWindowToPaintView(pGridWin[i]);
208 pDrawView->VCAddWin(pGridWin[i]);
210 pDrawView->RecalcScale();
211 for (i=0; i<4; i++)
212 if (pGridWin[i])
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();
230 if (pFormSh)
231 pFormSh->SetView(pDrawView);
233 if (aViewData.GetViewShell()->HasAccessibilityObjects())
234 aViewData.GetViewShell()->BroadcastAccessibility(SfxSimpleHint(SC_HINT_ACC_MAKEDRAWLAYER));
239 void ScTabView::DoAddWin( ScGridWindow* pWin )
241 if (pDrawView)
243 pDrawView->AddWindowToPaintView(pWin);
244 pDrawView->VCAddWin(pWin);
246 // #114409#
247 pWin->DrawLayerCreated();
251 void ScTabView::TabChanged( bool bSameTabButMoved )
253 if (pDrawView)
255 DrawDeselectAll(); // beendet auch Text-Edit-Modus
257 sal_uInt16 i;
258 for (i=0; i<4; i++)
259 if (pGridWin[i])
260 pDrawView->VCRemoveWin(pGridWin[i]); // fuer alte Page
262 SCTAB nTab = aViewData.GetTabNo();
263 pDrawView->HideSdrPage();
264 pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
266 UpdateLayerLocks();
268 pDrawView->RecalcScale();
269 pDrawView->UpdateWorkArea(); // PageSize ist pro Page unterschiedlich
271 for (i=0; i<4; i++)
272 if (pGridWin[i])
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();
290 if (pViewFrame)
292 uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController();
293 if (xController.is())
295 ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController );
296 if (pImp)
297 pImp->SheetChanged( bSameTabButMoved );
302 void ScTabView::UpdateLayerLocks()
304 if (pDrawView)
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();
312 SdrLayer* pLayer;
313 SdrLayerAdmin& rAdmin = pDrawView->GetModel()->GetLayerAdmin();
314 pLayer = rAdmin.GetLayerPerID(SC_LAYER_BACK);
315 if (pLayer)
316 pDrawView->SetLayerLocked( pLayer->GetName(), bProt || !bEx || bShared );
317 pLayer = rAdmin.GetLayerPerID(SC_LAYER_INTERN);
318 if (pLayer)
319 pDrawView->SetLayerLocked( pLayer->GetName(), true );
320 pLayer = rAdmin.GetLayerPerID(SC_LAYER_FRONT);
321 if (pLayer)
322 pDrawView->SetLayerLocked( pLayer->GetName(), bProt || bShared );
323 pLayer = rAdmin.GetLayerPerID(SC_LAYER_CONTROLS);
324 if (pLayer)
325 pDrawView->SetLayerLocked( pLayer->GetName(), bProt || bShared );
326 pLayer = rAdmin.GetLayerPerID(SC_LAYER_HIDDEN);
327 if (pLayer)
329 pDrawView->SetLayerLocked( pLayer->GetName(), bProt || bShared );
330 pDrawView->SetLayerVisible( pLayer->GetName(), false);
335 void ScTabView::DrawDeselectAll()
337 if (pDrawView)
339 ScTabViewShell* pViewSh = aViewData.GetViewShell();
340 if ( pDrawActual &&
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
358 if (pDrawView)
359 return pDrawView->IsTextEdit();
360 else
361 return false;
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 );
377 if (pDrawView)
378 pDrawView->RecalcScale();
379 ZoomChanged();
382 void ScTabView::RefreshZoom()
384 aViewData.RefreshZoom();
385 if (pDrawView)
386 pDrawView->RecalcScale();
387 ZoomChanged();
390 void ScTabView::SetPagebreakMode( bool bSet )
392 aViewData.SetPagebreakMode(bSet);
393 if (pDrawView)
394 pDrawView->RecalcScale();
395 ZoomChanged();
398 void ScTabView::ResetDrawDragMode()
400 if (pDrawView)
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() )
408 MakeDrawLayer();
410 if (pDrawView)
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()
435 return pDrawView;
438 void ScTabView::DrawMarkListHasChanged()
440 if ( pDrawView )
441 pDrawView->MarkListHasChanged();
444 void ScTabView::UpdateAnchorHandles()
446 if ( pDrawView )
447 pDrawView->AdjustMarkHdl();
450 void ScTabView::UpdateIMap( SdrObject* pObj )
452 if ( pDrawView )
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);
477 if (bHasLine)
478 pGridWin[i]->SetLineColor(aLine);
479 else
480 pGridWin[i]->SetLineColor();
481 if (bHasFill)
482 pGridWin[i]->SetFillColor(aFill);
483 else
484 pGridWin[i]->SetFillColor();
489 void ScTabView::DrawEnableAnim(bool bSet)
491 sal_uInt16 i;
492 if ( pDrawView )
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();
504 for (i=0; i<4; i++)
505 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
506 pDoc->StartAnimations( aViewData.GetTabNo(), pGridWin[i] );
509 else
511 pDrawView->SetAnimationEnabled(false);
516 void ScTabView::UpdateDrawTextOutliner()
518 if ( pDrawView )
520 Outliner* pOL = pDrawView->GetTextEditOutliner();
521 if (pOL)
522 aViewData.UpdateOutlinerFlags( *pOL );
526 void ScTabView::DigitLanguageChanged()
528 LanguageType eNewLang = SC_MOD()->GetOptDigitLanguage();
529 for (sal_uInt16 i=0; i<4; i++)
530 if ( pGridWin[i] )
531 pGridWin[i]->SetDigitLanguage( eNewLang );
534 void ScTabView::ScrollToObject( SdrObject* pDrawObj )
536 if ( 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
585 if (nScrollX > 0)
586 while (nScrollX > 0 && nPosX < MAXCOL)
588 nScrollX -= (long) ( pDoc->GetColWidth(nPosX, nTab) * nPPTX );
589 ++nPosX;
590 ++nLinesX;
592 else if (nScrollX < 0)
593 while (nScrollX < 0 && nPosX > 0)
595 --nPosX;
596 nScrollX += (long) ( pDoc->GetColWidth(nPosX, nTab) * nPPTX );
597 --nLinesX;
600 if (nScrollY > 0)
601 while (nScrollY > 0 && nPosY < MAXROW)
603 nScrollY -= (long) ( pDoc->GetRowHeight(nPosY, nTab) * nPPTY );
604 ++nPosY;
605 ++nLinesY;
607 else if (nScrollY < 0)
608 while (nScrollY < 0 && nPosY > 0)
610 --nPosY;
611 nScrollY += (long) ( pDoc->GetRowHeight(nPosY, nTab) * nPPTY );
612 --nLinesY;
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: */