1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <svx/fmshell.hxx>
21 #include <svx/svdobj.hxx>
22 #include <svx/svdocapt.hxx>
23 #include <svx/svdoutl.hxx>
24 #include <sfx2/bindings.hxx>
25 #include <sfx2/dispatch.hxx>
26 #include <sfx2/lokhelper.hxx>
27 #include <sfx2/objsh.hxx>
28 #include <sfx2/viewfrm.hxx>
29 #include <osl/diagnose.h>
30
31 #include <tabview.hxx>
32 #include <tabvwsh.hxx>
33 #include <document.hxx>
34 #include <gridwin.hxx>
35 #include <olinewin.hxx>
36 #include <tabsplit.hxx>
37 #include <colrowba.hxx>
38 #include <tabcont.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 <docsh.hxx>
48 #include <viewuno.hxx>
49 #include <postit.hxx>
50 #include <spellcheckcontext.hxx>
51
52 #include <vcl/settings.hxx>
53
54 #include <comphelper/lok.hxx>
55 #include <officecfg/Office/Calc.hxx>
56 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
57
58 using namespace com::sun::star;
59
Init()60 void ScTabView::Init()
61 {
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 );
67
68 sal_uInt16 i;
69
70 mbInlineWithScrollbar = officecfg::Office::Calc::Layout::Other::TabbarInlineWithScrollbar::get();
71
72 aScrollTimer.SetTimeout(10);
73 aScrollTimer.SetInvokeHandler( LINK( this, ScTabView, TimerHdl ) );
74
75 for (i=0; i<4; i++)
76 pGridWin[i] = nullptr;
77 pGridWin[SC_SPLIT_BOTTOMLEFT] = VclPtr<ScGridWindow>::Create( pFrameWin, aViewData, SC_SPLIT_BOTTOMLEFT );
78
79 pSelEngine.reset( new ScViewSelectionEngine( pGridWin[SC_SPLIT_BOTTOMLEFT], this,
80 SC_SPLIT_BOTTOMLEFT ) );
81 aFunctionSet.SetSelectionEngine( pSelEngine.get() );
82
83 pHdrSelEng.reset( new ScHeaderSelectionEngine( pFrameWin, &aHdrFunc ) );
84
85 pColBar[SC_SPLIT_LEFT] = VclPtr<ScColBar>::Create( pFrameWin, SC_SPLIT_LEFT,
86 &aHdrFunc, pHdrSelEng.get(), this );
87 pColBar[SC_SPLIT_RIGHT] = nullptr;
88 pRowBar[SC_SPLIT_BOTTOM] = VclPtr<ScRowBar>::Create( pFrameWin, SC_SPLIT_BOTTOM,
89 &aHdrFunc, pHdrSelEng.get(), this );
90 pRowBar[SC_SPLIT_TOP] = nullptr;
91 for (i=0; i<2; i++)
92 pColOutline[i] = pRowOutline[i] = nullptr;
93
94 pHSplitter = VclPtr<ScTabSplitter>::Create( pFrameWin, WinBits( WB_HSCROLL ), &aViewData );
95 pVSplitter = VclPtr<ScTabSplitter>::Create( pFrameWin, WinBits( WB_VSCROLL ), &aViewData );
96
97 // SSA: override default keyboard step size to allow snap to row/column
98 pHSplitter->SetKeyboardStepSize( 1 );
99 pVSplitter->SetKeyboardStepSize( 1 );
100
101 pTabControl = VclPtr<ScTabControl>::Create(pFrameWin, &aViewData);
102 if (mbInlineWithScrollbar)
103 pTabControl->SetStyle(pTabControl->GetStyle() | WB_SIZEABLE);
104
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 implements
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() );
110
111 InitScrollBar( *aHScrollLeft, aViewData.GetDocument().MaxCol()+1 );
112 InitScrollBar( *aHScrollRight, aViewData.GetDocument().MaxCol()+1 );
113 InitScrollBar( *aVScrollTop, aViewData.GetDocument().MaxRow()+1 );
114 InitScrollBar( *aVScrollBottom, aViewData.GetDocument().MaxRow()+1 );
115 /* #i97900# scrollbars remain in correct RTL mode, needed mirroring etc.
116 is now handled correctly at the respective places. */
117
118 // Don't show anything here, because still in wrong order
119 // Show is received from UpdateShow during first resize
120 // pTabControl, pGridWin, aHScrollLeft, aVScrollBottom,
121 // aCornerButton, aScrollBarBox, pHSplitter, pVSplitter
122
123 // fragment
124
125 pHSplitter->SetSplitHdl( LINK( this, ScTabView, SplitHdl ) );
126 pVSplitter->SetSplitHdl( LINK( this, ScTabView, SplitHdl ) );
127
128 // UpdateShow is done during resize or a copy of an existing view from ctor
129
130 pDrawActual = nullptr;
131 pDrawOld = nullptr;
132
133 // DrawView cannot be create in the TabView - ctor
134 // when the ViewShell isn't constructed yet...
135 // The also applies to ViewOptionsHasChanged()
136
137 TestHintWindow();
138 }
139
~ScTabView()140 ScTabView::~ScTabView()
141 {
142 sal_uInt16 i;
143
144 // remove selection object
145 ScModule* pScMod = SC_MOD();
146 ScSelectionTransferObj* pOld = pScMod->GetSelectionTransfer();
147 if ( pOld && pOld->GetView() == this )
148 {
149 pOld->ForgetView();
150 pScMod->SetSelectionTransfer( nullptr );
151 TransferableHelper::ClearPrimarySelection(); // may delete pOld
152 }
153
154 pBrushDocument.reset();
155 pDrawBrushSet.reset();
156
157 pPageBreakData.reset();
158
159 delete pDrawActual;
160 pDrawActual = nullptr;
161 delete pDrawOld;
162 pDrawOld = nullptr;
163
164 if (comphelper::LibreOfficeKit::isActive())
165 {
166 ScTabViewShell* pThisViewShell = GetViewData().GetViewShell();
167
168 auto lRemoveWindows =
169 [pThisViewShell] (ScTabViewShell* pOtherViewShell)
170 {
171 ScViewData& rOtherViewData = pOtherViewShell->GetViewData();
172 for (int k = 0; k < 4; ++k)
173 {
174 if (rOtherViewData.HasEditView(static_cast<ScSplitPos>(k)))
175 pThisViewShell->RemoveWindowFromForeignEditView(pOtherViewShell, static_cast<ScSplitPos>(k));
176 }
177 };
178
179 SfxLokHelper::forEachOtherView(pThisViewShell, lRemoveWindows);
180 }
181
182 aViewData.KillEditView(); // as long as GridWins still exist
183
184 if (pDrawView)
185 {
186 for (i=0; i<4; i++)
187 if (pGridWin[i])
188 {
189 pDrawView->DeleteWindowFromPaintView(pGridWin[i]->GetOutDev());
190 }
191
192 pDrawView->HideSdrPage();
193 pDrawView.reset();
194 }
195
196 pSelEngine.reset();
197
198 if (mpSpellCheckCxt)
199 mpSpellCheckCxt->dispose();
200 mpSpellCheckCxt.reset();
201
202 mxInputHintOO.reset();
203 for (i=0; i<4; i++)
204 pGridWin[i].disposeAndClear();
205
206 pHdrSelEng.reset();
207
208 for (i=0; i<2; i++)
209 {
210 pColBar[i].disposeAndClear();
211 pRowBar[i].disposeAndClear();
212 pColOutline[i].disposeAndClear();
213 pRowOutline[i].disposeAndClear();
214 }
215
216 aScrollBarBox.disposeAndClear();
217 aCornerButton.disposeAndClear();
218 aTopButton.disposeAndClear();
219 aHScrollLeft.disposeAndClear();
220 aHScrollRight.disposeAndClear();
221 aVScrollTop.disposeAndClear();
222 aVScrollBottom.disposeAndClear();
223
224 pHSplitter.disposeAndClear();
225 pVSplitter.disposeAndClear();
226 pTabControl.disposeAndClear();
227 }
228
MakeDrawView(TriState nForceDesignMode)229 void ScTabView::MakeDrawView( TriState nForceDesignMode )
230 {
231 if (pDrawView)
232 return;
233
234 ScDrawLayer* pLayer = aViewData.GetDocument().GetDrawLayer();
235 OSL_ENSURE(pLayer, "Where is the Draw Layer ??");
236
237 sal_uInt16 i;
238 pDrawView.reset( new ScDrawView( pGridWin[SC_SPLIT_BOTTOMLEFT]->GetOutDev(), &aViewData ) );
239 for (i=0; i<4; i++)
240 if (pGridWin[i])
241 {
242 if ( SC_SPLIT_BOTTOMLEFT != static_cast<ScSplitPos>(i) )
243 pDrawView->AddWindowToPaintView(pGridWin[i]->GetOutDev(), nullptr);
244 }
245 pDrawView->RecalcScale();
246 for (i=0; i<4; i++)
247 if (pGridWin[i])
248 {
249 pGridWin[i]->SetMapMode(pGridWin[i]->GetDrawMapMode());
250
251 pGridWin[i]->PaintImmediately(); // because of Invalidate in DrawView ctor (ShowPage),
252 // so that immediately can be drawn
253 }
254 SfxRequest aSfxRequest(SID_OBJECT_SELECT, SfxCallMode::SLOT, aViewData.GetViewShell()->GetPool());
255 SetDrawFuncPtr(new FuSelection(*aViewData.GetViewShell(), GetActiveWin(), pDrawView.get(),
256 pLayer,aSfxRequest));
257
258 // used when switching back from page preview: restore saved design mode state
259 // (otherwise, keep the default from the draw view ctor)
260 if ( nForceDesignMode != TRISTATE_INDET )
261 pDrawView->SetDesignMode( nForceDesignMode != TRISTATE_FALSE );
262
263 // register at FormShell
264 FmFormShell* pFormSh = aViewData.GetViewShell()->GetFormShell();
265 if (pFormSh)
266 pFormSh->SetView(pDrawView.get());
267
268 if (aViewData.GetViewShell()->HasAccessibilityObjects())
269 aViewData.GetViewShell()->BroadcastAccessibility(SfxHint(SfxHintId::ScAccMakeDrawLayer));
270 }
271
DoAddWin(ScGridWindow * pWin)272 void ScTabView::DoAddWin( ScGridWindow* pWin )
273 {
274 if (pDrawView)
275 {
276 pDrawView->AddWindowToPaintView(pWin->GetOutDev(), nullptr);
277 pWin->DrawLayerCreated();
278 }
279 pWin->SetAutoSpellContext(mpSpellCheckCxt);
280 }
281
TabChanged(bool bSameTabButMoved)282 void ScTabView::TabChanged( bool bSameTabButMoved )
283 {
284 if (pDrawView)
285 {
286 DrawDeselectAll(); // end also text edit mode
287
288 SCTAB nTab = aViewData.GetTabNo();
289 pDrawView->HideSdrPage();
290 pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
291
292 UpdateLayerLocks();
293
294 pDrawView->RecalcScale();
295 pDrawView->UpdateWorkArea(); // PageSize is different per page
296 }
297
298 SfxBindings& rBindings = aViewData.GetBindings();
299
300 // There is no easy way to invalidate all slots of the FormShell
301 // (for disabled slots on protected tables), therefore simply everything...
302 rBindings.InvalidateAll(false);
303
304 if (aViewData.GetViewShell()->HasAccessibilityObjects())
305 {
306 SfxHint aAccHint(SfxHintId::ScAccTableChanged);
307 aViewData.GetViewShell()->BroadcastAccessibility(aAccHint);
308 }
309
310 // notification for XActivationBroadcaster
311 SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame();
312 if (pViewFrame)
313 {
314 uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController();
315 if (xController.is())
316 {
317 ScTabViewObj* pImp = comphelper::getUnoTunnelImplementation<ScTabViewObj>( xController );
318 if (pImp)
319 pImp->SheetChanged( bSameTabButMoved );
320 }
321 }
322
323 for (int i = 0; i < 4; i++)
324 {
325 if (pGridWin[i])
326 {
327 pGridWin[i]->initiatePageBreaks();
328 // Trigger calculating page breaks only once.
329 break;
330 }
331 }
332
333 if (!comphelper::LibreOfficeKit::isActive())
334 return;
335
336 ScDocShell* pDocSh = GetViewData().GetDocShell();
337 ScModelObj* pModelObj = pDocSh ? comphelper::getUnoTunnelImplementation<ScModelObj>( pDocSh->GetModel()) : nullptr;
338
339 if (!pModelObj)
340 return;
341
342 Size aDocSize = pModelObj->getDocumentSize();
343 std::stringstream ss;
344 ss << aDocSize.Width() << ", " << aDocSize.Height();
345 OString sRect = ss.str().c_str();
346 ScTabViewShell* pViewShell = aViewData.GetViewShell();
347
348 // Invalidate first
349 tools::Rectangle aRectangle(0, 0, 1000000000, 1000000000);
350 OString sPayload = aRectangle.toString() + ", " + OString::number(aViewData.GetTabNo());
351 pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_TILES, sPayload.getStr());
352
353 ScModelObj* pModel = comphelper::getUnoTunnelImplementation<ScModelObj>(pViewShell->GetCurrentDocument());
354 SfxLokHelper::notifyDocumentSizeChanged(pViewShell, sRect, pModel, false);
355 }
356
UpdateLayerLocks()357 void ScTabView::UpdateLayerLocks()
358 {
359 if (!pDrawView)
360 return;
361
362 SCTAB nTab = aViewData.GetTabNo();
363 bool bEx = aViewData.GetViewShell()->IsDrawSelMode();
364 bool bProt = aViewData.GetDocument().IsTabProtected( nTab ) ||
365 aViewData.GetSfxDocShell()->IsReadOnly();
366 bool bShared = aViewData.GetDocShell()->IsDocShared();
367
368 SdrLayer* pLayer;
369 SdrLayerAdmin& rAdmin = pDrawView->GetModel()->GetLayerAdmin();
370 pLayer = rAdmin.GetLayerPerID(SC_LAYER_BACK);
371 if (pLayer)
372 pDrawView->SetLayerLocked( pLayer->GetName(), bProt || !bEx || bShared );
373 pLayer = rAdmin.GetLayerPerID(SC_LAYER_INTERN);
374 if (pLayer)
375 pDrawView->SetLayerLocked( pLayer->GetName() );
376 pLayer = rAdmin.GetLayerPerID(SC_LAYER_FRONT);
377 if (pLayer)
378 pDrawView->SetLayerLocked( pLayer->GetName(), bProt || bShared );
379 pLayer = rAdmin.GetLayerPerID(SC_LAYER_CONTROLS);
380 if (pLayer)
381 pDrawView->SetLayerLocked( pLayer->GetName(), bProt || bShared );
382 pLayer = rAdmin.GetLayerPerID(SC_LAYER_HIDDEN);
383 if (pLayer)
384 {
385 pDrawView->SetLayerLocked( pLayer->GetName(), bProt || bShared );
386 pDrawView->SetLayerVisible( pLayer->GetName(), false);
387 }
388 }
389
DrawDeselectAll()390 void ScTabView::DrawDeselectAll()
391 {
392 if (!pDrawView)
393 return;
394
395 ScTabViewShell* pViewSh = aViewData.GetViewShell();
396 if ( pDrawActual &&
397 ( pViewSh->IsDrawTextShell() || pDrawActual->GetSlotID() == SID_DRAW_NOTEEDIT ) )
398 {
399 // end text edit (as if escape pressed, in FuDraw)
400 aViewData.GetDispatcher().Execute( pDrawActual->GetSlotID(),
401 SfxCallMode::SLOT | SfxCallMode::RECORD );
402 }
403
404 pDrawView->ScEndTextEdit();
405 pDrawView->UnmarkAll();
406
407 if (!pViewSh->IsDrawSelMode())
408 pViewSh->SetDrawShell( false );
409 }
410
IsDrawTextEdit() const411 bool ScTabView::IsDrawTextEdit() const
412 {
413 if (pDrawView)
414 return pDrawView->IsTextEdit();
415 else
416 return false;
417 }
418
GetZoomType() const419 SvxZoomType ScTabView::GetZoomType() const
420 {
421 return aViewData.GetZoomType();
422 }
423
SetZoomType(SvxZoomType eNew,bool bAll)424 void ScTabView::SetZoomType( SvxZoomType eNew, bool bAll )
425 {
426 aViewData.SetZoomType( eNew, bAll );
427 }
428
SetZoom(const Fraction & rNewX,const Fraction & rNewY,bool bAll)429 void ScTabView::SetZoom( const Fraction& rNewX, const Fraction& rNewY, bool bAll )
430 {
431 aViewData.SetZoom( rNewX, rNewY, bAll );
432 if (pDrawView)
433 pDrawView->RecalcScale();
434 ZoomChanged();
435 }
436
RefreshZoom()437 void ScTabView::RefreshZoom()
438 {
439 aViewData.RefreshZoom();
440 if (pDrawView)
441 pDrawView->RecalcScale();
442 ZoomChanged();
443 }
444
SetPagebreakMode(bool bSet)445 void ScTabView::SetPagebreakMode( bool bSet )
446 {
447 aViewData.SetPagebreakMode(bSet);
448 if (pDrawView)
449 pDrawView->RecalcScale();
450 ZoomChanged();
451 }
452
ResetDrawDragMode()453 void ScTabView::ResetDrawDragMode()
454 {
455 if (pDrawView)
456 pDrawView->SetDragMode( SdrDragMode::Move );
457 }
458
ViewOptionsHasChanged(bool bHScrollChanged,bool bGraphicsChanged)459 void ScTabView::ViewOptionsHasChanged( bool bHScrollChanged, bool bGraphicsChanged )
460 {
461 // create DrawView when grid should be displayed
462 if ( !pDrawView && aViewData.GetOptions().GetGridOptions().GetGridVisible() )
463 MakeDrawLayer();
464
465 if (pDrawView)
466 pDrawView->UpdateUserViewOptions();
467
468 if (bGraphicsChanged)
469 DrawEnableAnim(true); // DrawEnableAnim checks the options state
470
471 // if TabBar is set to visible, make sure its size is not 0
472 bool bGrow = ( aViewData.IsTabMode() && pTabControl->GetSizePixel().Width() <= 0 );
473
474 // if ScrollBar is set to visible, TabBar must make room
475 bool bShrink = ( bHScrollChanged && aViewData.IsTabMode() && aViewData.IsHScrollMode() &&
476 pTabControl->GetSizePixel().Width() > SC_TABBAR_DEFWIDTH );
477
478 if ( bGrow || bShrink )
479 {
480 Size aSize = pTabControl->GetSizePixel();
481 aSize.setWidth( SC_TABBAR_DEFWIDTH ); // initial size
482 pTabControl->SetSizePixel(aSize); // DoResize is called later...
483 }
484 }
485
486 // helper function against including the drawing layer
487
DrawMarkListHasChanged()488 void ScTabView::DrawMarkListHasChanged()
489 {
490 if ( pDrawView )
491 pDrawView->MarkListHasChanged();
492 }
493
UpdateAnchorHandles()494 void ScTabView::UpdateAnchorHandles()
495 {
496 if ( pDrawView )
497 pDrawView->AdjustMarkHdl();
498 }
499
UpdateIMap(SdrObject * pObj)500 void ScTabView::UpdateIMap( SdrObject* pObj )
501 {
502 if ( pDrawView )
503 pDrawView->UpdateIMap( pObj );
504 }
505
DrawEnableAnim(bool bSet)506 void ScTabView::DrawEnableAnim(bool bSet)
507 {
508 sal_uInt16 i;
509 if ( !pDrawView )
510 return;
511
512 // don't start animations if display of graphics is disabled
513 // graphics are controlled by VOBJ_TYPE_OLE
514 if ( bSet && aViewData.GetOptions().GetObjMode(VOBJ_TYPE_OLE) == VOBJ_MODE_SHOW )
515 {
516 if ( !pDrawView->IsAnimationEnabled() )
517 {
518 pDrawView->SetAnimationEnabled();
519
520 // animated GIFs must be restarted:
521 ScDocument& rDoc = aViewData.GetDocument();
522 for (i=0; i<4; i++)
523 if ( pGridWin[i] && pGridWin[i]->IsVisible() )
524 rDoc.StartAnimations( aViewData.GetTabNo() );
525 }
526 }
527 else
528 {
529 pDrawView->SetAnimationEnabled(false);
530 }
531 }
532
UpdateDrawTextOutliner()533 void ScTabView::UpdateDrawTextOutliner()
534 {
535 if ( pDrawView )
536 {
537 Outliner* pOL = pDrawView->GetTextEditOutliner();
538 if (pOL)
539 aViewData.UpdateOutlinerFlags( *pOL );
540 }
541 }
542
DigitLanguageChanged()543 void ScTabView::DigitLanguageChanged()
544 {
545 LanguageType eNewLang = SC_MOD()->GetOptDigitLanguage();
546 for (VclPtr<ScGridWindow> & pWin : pGridWin)
547 if ( pWin )
548 pWin->GetOutDev()->SetDigitLanguage( eNewLang );
549 }
550
ScrollToObject(const SdrObject * pDrawObj)551 void ScTabView::ScrollToObject( const SdrObject* pDrawObj )
552 {
553 if ( pDrawObj )
554 {
555 // #i118524# use the BoundRect, this defines the visible area
556 MakeVisible(pDrawObj->GetCurrentBoundRect());
557 }
558 }
559
MakeVisible(const tools::Rectangle & rHMMRect)560 void ScTabView::MakeVisible( const tools::Rectangle& rHMMRect )
561 {
562 vcl::Window* pWin = GetActiveWin();
563 Size aWinSize = pWin->GetOutputSizePixel();
564 SCTAB nTab = aViewData.GetTabNo();
565
566 tools::Rectangle aRect = pWin->LogicToPixel( rHMMRect );
567
568 tools::Long nScrollX=0, nScrollY=0; // pixel
569
570 if ( aRect.Right() >= aWinSize.Width() ) // right out
571 {
572 nScrollX = aRect.Right() - aWinSize.Width() + 1; // right border visible
573 if ( aRect.Left() < nScrollX )
574 nScrollX = aRect.Left(); // left visible (if too big)
575 }
576 if ( aRect.Bottom() >= aWinSize.Height() ) // bottom out
577 {
578 nScrollY = aRect.Bottom() - aWinSize.Height() + 1; // bottom border visible
579 if ( aRect.Top() < nScrollY )
580 nScrollY = aRect.Top(); // top visible (if too big)
581 }
582
583 if ( aRect.Left() < 0 ) // left out
584 nScrollX = aRect.Left(); // left border visible
585 if ( aRect.Top() < 0 ) // top out
586 nScrollY = aRect.Top(); // top border visible
587
588 if (!(nScrollX || nScrollY))
589 return;
590
591 ScDocument& rDoc = aViewData.GetDocument();
592 if ( rDoc.IsNegativePage( nTab ) )
593 nScrollX = -nScrollX;
594
595 double nPPTX = aViewData.GetPPTX();
596 double nPPTY = aViewData.GetPPTY();
597 ScSplitPos eWhich = aViewData.GetActivePart();
598 SCCOL nPosX = aViewData.GetPosX(WhichH(eWhich));
599 SCROW nPosY = aViewData.GetPosY(WhichV(eWhich));
600
601 tools::Long nLinesX=0, nLinesY=0; // columns/rows - scroll at least nScrollX/Y
602
603 if (nScrollX > 0)
604 while (nScrollX > 0 && nPosX < rDoc.MaxCol())
605 {
606 nScrollX -= static_cast<tools::Long>( rDoc.GetColWidth(nPosX, nTab) * nPPTX );
607 ++nPosX;
608 ++nLinesX;
609 }
610 else if (nScrollX < 0)
611 while (nScrollX < 0 && nPosX > 0)
612 {
613 --nPosX;
614 nScrollX += static_cast<tools::Long>( rDoc.GetColWidth(nPosX, nTab) * nPPTX );
615 --nLinesX;
616 }
617
618 if (nScrollY > 0)
619 while (nScrollY > 0 && nPosY < rDoc.MaxRow())
620 {
621 nScrollY -= static_cast<tools::Long>( rDoc.GetRowHeight(nPosY, nTab) * nPPTY );
622 ++nPosY;
623 ++nLinesY;
624 }
625 else if (nScrollY < 0)
626 while (nScrollY < 0 && nPosY > 0)
627 {
628 --nPosY;
629 nScrollY += static_cast<tools::Long>( rDoc.GetRowHeight(nPosY, nTab) * nPPTY );
630 --nLinesY;
631 }
632
633 ScrollLines( nLinesX, nLinesY ); // execute
634 }
635
SetBrushDocument(ScDocumentUniquePtr pNew,bool bLock)636 void ScTabView::SetBrushDocument( ScDocumentUniquePtr pNew, bool bLock )
637 {
638 pDrawBrushSet.reset();
639 pBrushDocument = std::move(pNew);
640
641 bLockPaintBrush = bLock;
642
643 aViewData.GetBindings().Invalidate(SID_FORMATPAINTBRUSH);
644 }
645
SetDrawBrushSet(std::unique_ptr<SfxItemSet> pNew,bool bLock)646 void ScTabView::SetDrawBrushSet( std::unique_ptr<SfxItemSet> pNew, bool bLock )
647 {
648 pBrushDocument.reset();
649 pDrawBrushSet = std::move(pNew);
650
651 bLockPaintBrush = bLock;
652
653 aViewData.GetBindings().Invalidate(SID_FORMATPAINTBRUSH);
654 }
655
ResetBrushDocument()656 void ScTabView::ResetBrushDocument()
657 {
658 if ( HasPaintBrush() )
659 {
660 SetBrushDocument( nullptr, false );
661 SetActivePointer( aViewData.IsThemedCursor() ? PointerStyle::FatCross : PointerStyle::Arrow ); // switch pointers also when ended with escape key
662 }
663 }
664
OnLOKNoteStateChanged(const ScPostIt * pNote)665 void ScTabView::OnLOKNoteStateChanged(const ScPostIt* pNote)
666 {
667 if (!comphelper::LibreOfficeKit::isActive())
668 return;
669
670 const SdrCaptionObj* pCaption = pNote->GetCaption();
671 if (!pCaption) return;
672
673 tools::Rectangle aRect = pCaption->GetLogicRect();
674 basegfx::B2DRange aTailRange = pCaption->getTailPolygon().getB2DRange();
675 tools::Rectangle aTailRect(aTailRange.getMinX(), aTailRange.getMinY(),
676 aTailRange.getMaxX(), aTailRange.getMaxY());
677 aRect.Union( aTailRect );
678
679 // This is a temporary workaround: sometime in tiled rendering mode
680 // the tip of the note arrow is misplaced by a fixed offset.
681 // The value used below is enough to get the tile, where the arrow tip is
682 // placed, invalidated.
683 const int nBorderSize = 200;
684 tools::Rectangle aInvalidRect = aRect;
685 aInvalidRect.AdjustLeft( -nBorderSize );
686 aInvalidRect.AdjustRight( nBorderSize );
687 aInvalidRect.AdjustTop( -nBorderSize );
688 aInvalidRect.AdjustBottom( nBorderSize );
689
690 SfxViewShell* pCurrentViewShell = SfxViewShell::Current();
691 SfxViewShell* pViewShell = SfxViewShell::GetFirst();
692 while (pViewShell)
693 {
694 ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
695 if (pTabViewShell && pViewShell->GetDocId() == pCurrentViewShell->GetDocId())
696 {
697 for (auto& pWin: pTabViewShell->pGridWin)
698 {
699 if (pWin && pWin->IsVisible())
700 {
701 pWin->Invalidate(aInvalidRect);
702 }
703 }
704 }
705 pViewShell = SfxViewShell::GetNext(*pViewShell);
706 }
707 }
708
709 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
710