tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / unoobj / viewuno.cxx
blob02f66358cb257004f8289f661a0fe7740a7e7375
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 <com/sun/star/awt/MouseButton.hpp>
21 #include <com/sun/star/drawing/ShapeCollection.hpp>
22 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
23 #include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
24 #include <com/sun/star/util/VetoException.hpp>
25 #include <com/sun/star/view/DocumentZoomType.hpp>
27 #include <editeng/outliner.hxx>
28 #include <svx/svditer.hxx>
29 #include <svx/svdmark.hxx>
30 #include <svx/svdpage.hxx>
31 #include <svx/svdpagv.hxx>
32 #include <svx/svdview.hxx>
33 #include <svx/unoshape.hxx>
34 #include <svx/fmshell.hxx>
35 #include <sfx2/bindings.hxx>
36 #include <sfx2/dispatch.hxx>
37 #include <sfx2/request.hxx>
38 #include <sfx2/viewfrm.hxx>
39 #include <comphelper/profilezone.hxx>
40 #include <comphelper/processfactory.hxx>
41 #include <comphelper/sequence.hxx>
42 #include <cppuhelper/supportsservice.hxx>
43 #include <cppuhelper/queryinterface.hxx>
44 #include <toolkit/helper/vclunohelper.hxx>
45 #include <vcl/svapp.hxx>
46 #include <vcl/unohelp.hxx>
47 #include <tools/multisel.hxx>
49 #include <drawsh.hxx>
50 #include <drtxtob.hxx>
51 #include <transobj.hxx>
52 #include <editsh.hxx>
53 #include <viewuno.hxx>
54 #include <cellsuno.hxx>
55 #include <miscuno.hxx>
56 #include <tabvwsh.hxx>
57 #include <prevwsh.hxx>
58 #include <docsh.hxx>
59 #include <drwlayer.hxx>
60 #include <attrib.hxx>
61 #include <drawview.hxx>
62 #include <fupoor.hxx>
63 #include <sc.hrc>
64 #include <unonames.hxx>
65 #include <scmod.hxx>
66 #include <appoptio.hxx>
67 #include <gridwin.hxx>
68 #include <sheetevents.hxx>
69 #include <markdata.hxx>
70 #include <scextopt.hxx>
71 #include <preview.hxx>
72 #include <inputhdl.hxx>
73 #include <inputwin.hxx>
74 #include <svx/sdrhittesthelper.hxx>
75 #include <formatsh.hxx>
76 #include <sfx2/app.hxx>
77 #include <scitems.hxx>
79 using namespace com::sun::star;
81 //! Clipping Marks
83 // no Which-ID here, Map only for PropertySetInfo
85 static std::span<const SfxItemPropertyMapEntry> lcl_GetViewOptPropertyMap()
87 static const SfxItemPropertyMapEntry aViewOptPropertyMap_Impl[] =
89 { OLD_UNO_COLROWHDR, 0, cppu::UnoType<bool>::get(), 0, 0},
90 { SC_UNO_GRIDCOLOR, 0, cppu::UnoType<sal_Int32>::get(), 0, 0},
91 { SC_UNO_COLROWHDR, 0, cppu::UnoType<bool>::get(), 0, 0},
92 { SC_UNO_HORSCROLL, 0, cppu::UnoType<bool>::get(), 0, 0},
93 { SC_UNO_SHEETTABS, 0, cppu::UnoType<bool>::get(), 0, 0},
94 { SC_UNO_VERTSCROLL, 0, cppu::UnoType<bool>::get(), 0, 0},
95 { SC_UNO_HIDESPELL, 0, cppu::UnoType<bool>::get(), 0, 0}, /* deprecated #i91949 */
96 { OLD_UNO_HORSCROLL, 0, cppu::UnoType<bool>::get(), 0, 0},
97 { SC_UNO_OUTLSYMB, 0, cppu::UnoType<bool>::get(), 0, 0},
98 { SC_UNO_VALUEHIGH, 0, cppu::UnoType<bool>::get(), 0, 0},
99 { OLD_UNO_OUTLSYMB, 0, cppu::UnoType<bool>::get(), 0, 0},
100 { OLD_UNO_SHEETTABS, 0, cppu::UnoType<bool>::get(), 0, 0},
101 { SC_UNO_SHOWANCHOR, 0, cppu::UnoType<bool>::get(), 0, 0},
102 { SC_UNO_SHOWCHARTS, 0, cppu::UnoType<sal_Int16>::get(), 0, 0},
103 { SC_UNO_SHOWDRAW, 0, cppu::UnoType<sal_Int16>::get(), 0, 0},
104 { SC_UNO_SHOWFORM, 0, cppu::UnoType<bool>::get(), 0, 0},
105 { SC_UNO_SHOWGRID, 0, cppu::UnoType<bool>::get(), 0, 0},
106 { SC_UNO_SHOWHELP, 0, cppu::UnoType<bool>::get(), 0, 0},
107 { SC_UNO_SHOWNOTES, 0, cppu::UnoType<bool>::get(), 0, 0},
108 { SC_UNO_SHOWNOTEAUTHOR, 0, cppu::UnoType<bool>::get(), 0, 0},
109 { SC_UNO_SHOWFORMULASMARKS, 0, cppu::UnoType<bool>::get(), 0, 0},
110 { SC_UNO_SHOWOBJ, 0, cppu::UnoType<sal_Int16>::get(), 0, 0},
111 { SC_UNO_SHOWPAGEBR, 0, cppu::UnoType<bool>::get(), 0, 0},
112 { SC_UNO_SHOWZERO, 0, cppu::UnoType<bool>::get(), 0, 0},
113 { OLD_UNO_VALUEHIGH, 0, cppu::UnoType<bool>::get(), 0, 0},
114 { OLD_UNO_VERTSCROLL, 0, cppu::UnoType<bool>::get(), 0, 0},
115 { SC_UNO_VISAREA, 0, cppu::UnoType<awt::Rectangle>::get(), 0, 0},
116 { SC_UNO_ZOOMTYPE, 0, cppu::UnoType<sal_Int16>::get(), 0, 0},
117 { SC_UNO_ZOOMVALUE, 0, cppu::UnoType<sal_Int16>::get(), 0, 0},
118 { SC_UNO_VISAREASCREEN,0, cppu::UnoType<awt::Rectangle>::get(), 0, 0},
119 { SC_UNO_FORMULABARHEIGHT,0,cppu::UnoType<sal_Int16>::get(), 0, 0},
121 return aViewOptPropertyMap_Impl;
124 constexpr OUString SCTABVIEWOBJ_SERVICE = u"com.sun.star.sheet.SpreadsheetView"_ustr;
125 constexpr OUString SCVIEWSETTINGS_SERVICE = u"com.sun.star.sheet.SpreadsheetViewSettings"_ustr;
127 SC_SIMPLE_SERVICE_INFO( ScViewPaneBase, u"ScViewPaneObj"_ustr, u"com.sun.star.sheet.SpreadsheetViewPane"_ustr )
129 ScViewPaneBase::ScViewPaneBase(ScTabViewShell* pViewSh, sal_uInt16 nP) :
130 pViewShell( pViewSh ),
131 nPane( nP )
133 if (pViewShell)
134 StartListening(*pViewShell);
137 ScViewPaneBase::~ScViewPaneBase()
139 SolarMutexGuard g;
141 if (pViewShell)
142 EndListening(*pViewShell);
145 void ScViewPaneBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
147 if ( rHint.GetId() == SfxHintId::Dying )
148 pViewShell = nullptr;
151 uno::Any SAL_CALL ScViewPaneBase::queryInterface( const uno::Type& rType )
153 uno::Any aReturn = ::cppu::queryInterface(rType,
154 static_cast<sheet::XViewPane*>(this),
155 static_cast<sheet::XCellRangeReferrer*>(this),
156 static_cast<view::XFormLayerAccess*>(this),
157 static_cast<view::XControlAccess*>(this),
158 static_cast<lang::XServiceInfo*>(this),
159 static_cast<lang::XTypeProvider*>(this));
160 if ( aReturn.hasValue() )
161 return aReturn;
163 return uno::Any(); // OWeakObject is in derived objects
166 uno::Sequence<uno::Type> SAL_CALL ScViewPaneBase::getTypes()
168 static const uno::Sequence<uno::Type> aTypes
170 cppu::UnoType<sheet::XViewPane>::get(),
171 cppu::UnoType<sheet::XCellRangeReferrer>::get(),
172 cppu::UnoType<view::XFormLayerAccess>::get(),
173 cppu::UnoType<lang::XServiceInfo>::get(),
174 cppu::UnoType<lang::XTypeProvider>::get(),
176 return aTypes;
179 uno::Sequence<sal_Int8> SAL_CALL ScViewPaneBase::getImplementationId()
181 return css::uno::Sequence<sal_Int8>();
184 // XViewPane
186 sal_Int32 SAL_CALL ScViewPaneBase::getFirstVisibleColumn()
188 SolarMutexGuard aGuard;
189 if (pViewShell)
191 ScViewData& rViewData = pViewShell->GetViewData();
192 ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
193 rViewData.GetActivePart() :
194 static_cast<ScSplitPos>(nPane);
195 ScHSplitPos eWhichH = WhichH( eWhich );
197 return rViewData.GetPosX( eWhichH );
199 OSL_FAIL("no View ?!?"); //! Exception?
200 return 0;
203 void SAL_CALL ScViewPaneBase::setFirstVisibleColumn(sal_Int32 nFirstVisibleColumn)
205 SolarMutexGuard aGuard;
206 if (pViewShell)
208 ScViewData& rViewData = pViewShell->GetViewData();
209 ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
210 rViewData.GetActivePart() :
211 static_cast<ScSplitPos>(nPane);
212 ScHSplitPos eWhichH = WhichH( eWhich );
214 tools::Long nDeltaX = static_cast<tools::Long>(nFirstVisibleColumn) - rViewData.GetPosX( eWhichH );
215 pViewShell->ScrollX( nDeltaX, eWhichH );
219 sal_Int32 SAL_CALL ScViewPaneBase::getFirstVisibleRow()
221 SolarMutexGuard aGuard;
222 if (pViewShell)
224 ScViewData& rViewData = pViewShell->GetViewData();
225 ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
226 rViewData.GetActivePart() :
227 static_cast<ScSplitPos>(nPane);
228 ScVSplitPos eWhichV = WhichV( eWhich );
230 return rViewData.GetPosY( eWhichV );
232 OSL_FAIL("no View ?!?"); //! Exception?
233 return 0;
236 void SAL_CALL ScViewPaneBase::setFirstVisibleRow( sal_Int32 nFirstVisibleRow )
238 SolarMutexGuard aGuard;
239 if (pViewShell)
241 ScViewData& rViewData = pViewShell->GetViewData();
242 ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
243 rViewData.GetActivePart() :
244 static_cast<ScSplitPos>(nPane);
245 ScVSplitPos eWhichV = WhichV( eWhich );
247 tools::Long nDeltaY = static_cast<tools::Long>(nFirstVisibleRow) - rViewData.GetPosY( eWhichV );
248 pViewShell->ScrollY( nDeltaY, eWhichV );
252 table::CellRangeAddress SAL_CALL ScViewPaneBase::getVisibleRange()
254 SolarMutexGuard aGuard;
255 table::CellRangeAddress aAdr;
256 if (pViewShell)
258 ScViewData& rViewData = pViewShell->GetViewData();
259 ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
260 rViewData.GetActivePart() :
261 static_cast<ScSplitPos>(nPane);
262 ScHSplitPos eWhichH = WhichH( eWhich );
263 ScVSplitPos eWhichV = WhichV( eWhich );
265 // VisibleCellsX returns only completely visible cells
266 // VisibleRange in Excel also partially visible ones
267 //! do the same ???
269 SCCOL nVisX = rViewData.VisibleCellsX( eWhichH );
270 SCROW nVisY = rViewData.VisibleCellsY( eWhichV );
271 if (!nVisX) nVisX = 1; // there has to be something in the range
272 if (!nVisY) nVisY = 1;
273 aAdr.Sheet = rViewData.GetTabNo();
274 aAdr.StartColumn = rViewData.GetPosX( eWhichH );
275 aAdr.StartRow = rViewData.GetPosY( eWhichV );
276 aAdr.EndColumn = aAdr.StartColumn + nVisX - 1;
277 aAdr.EndRow = aAdr.StartRow + nVisY - 1;
279 return aAdr;
282 // XCellRangeSource
284 uno::Reference<table::XCellRange> SAL_CALL ScViewPaneBase::getReferredCells()
286 SolarMutexGuard aGuard;
287 if (pViewShell)
289 ScDocShell* pDocSh = pViewShell->GetViewData().GetDocShell();
291 table::CellRangeAddress aAdr(getVisibleRange()); //! helper function with ScRange?
292 ScRange aRange( static_cast<SCCOL>(aAdr.StartColumn), static_cast<SCROW>(aAdr.StartRow), aAdr.Sheet,
293 static_cast<SCCOL>(aAdr.EndColumn), static_cast<SCROW>(aAdr.EndRow), aAdr.Sheet );
294 if ( aRange.aStart == aRange.aEnd )
295 return new ScCellObj( pDocSh, aRange.aStart );
296 else
297 return new ScCellRangeObj( pDocSh, aRange );
300 return nullptr;
303 namespace
305 bool lcl_prepareFormShellCall( ScTabViewShell* _pViewShell, sal_uInt16 _nPane, FmFormShell*& _rpFormShell, vcl::Window*& _rpWindow, SdrView*& _rpSdrView )
307 if ( !_pViewShell )
308 return false;
310 ScViewData& rViewData = _pViewShell->GetViewData();
311 ScSplitPos eWhich = ( _nPane == SC_VIEWPANE_ACTIVE ) ?
312 rViewData.GetActivePart() :
313 static_cast<ScSplitPos>(_nPane);
314 _rpWindow = _pViewShell->GetWindowByPos( eWhich );
315 _rpSdrView = _pViewShell->GetScDrawView();
316 _rpFormShell = _pViewShell->GetFormShell();
317 return ( _rpFormShell != nullptr ) && ( _rpSdrView != nullptr )&& ( _rpWindow != nullptr );
321 // XFormLayerAccess
322 uno::Reference< form::runtime::XFormController > SAL_CALL ScViewPaneBase::getFormController( const uno::Reference< form::XForm >& Form )
324 SolarMutexGuard aGuard;
326 uno::Reference< form::runtime::XFormController > xController;
328 vcl::Window* pWindow( nullptr );
329 SdrView* pSdrView( nullptr );
330 FmFormShell* pFormShell( nullptr );
331 if ( lcl_prepareFormShellCall( pViewShell, nPane, pFormShell, pWindow, pSdrView ) )
332 xController = FmFormShell::GetFormController( Form, *pSdrView, *pWindow->GetOutDev() );
334 return xController;
337 sal_Bool SAL_CALL ScViewPaneBase::isFormDesignMode( )
339 SolarMutexGuard aGuard;
341 bool bIsFormDesignMode( true );
343 FmFormShell* pFormShell( pViewShell ? pViewShell->GetFormShell() : nullptr );
344 if ( pFormShell )
345 bIsFormDesignMode = pFormShell->IsDesignMode();
347 return bIsFormDesignMode;
350 void SAL_CALL ScViewPaneBase::setFormDesignMode( sal_Bool DesignMode )
352 SolarMutexGuard aGuard;
354 vcl::Window* pWindow( nullptr );
355 SdrView* pSdrView( nullptr );
356 FmFormShell* pFormShell( nullptr );
357 if ( lcl_prepareFormShellCall( pViewShell, nPane, pFormShell, pWindow, pSdrView ) )
358 pFormShell->SetDesignMode( DesignMode );
361 // XControlAccess
363 uno::Reference<awt::XControl> SAL_CALL ScViewPaneBase::getControl(
364 const uno::Reference<awt::XControlModel>& xModel )
366 SolarMutexGuard aGuard;
368 uno::Reference<awt::XControl> xRet;
370 vcl::Window* pWindow( nullptr );
371 SdrView* pSdrView( nullptr );
372 FmFormShell* pFormShell( nullptr );
373 if ( lcl_prepareFormShellCall( pViewShell, nPane, pFormShell, pWindow, pSdrView ) )
374 pFormShell->GetFormControl( xModel, *pSdrView, *pWindow->GetOutDev(), xRet );
376 if ( !xRet.is() )
377 throw container::NoSuchElementException(); // no control found
379 return xRet;
382 awt::Rectangle ScViewPaneBase::GetVisArea() const
384 awt::Rectangle aVisArea;
385 if (pViewShell)
387 ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
388 pViewShell->GetViewData().GetActivePart() :
389 static_cast<ScSplitPos>(nPane);
390 ScGridWindow* pWindow = static_cast<ScGridWindow*>(pViewShell->GetWindowByPos(eWhich));
391 ScDocument& rDoc = pViewShell->GetViewData().GetDocument();
392 if (pWindow)
394 ScHSplitPos eWhichH = ((eWhich == SC_SPLIT_TOPLEFT) || (eWhich == SC_SPLIT_BOTTOMLEFT)) ?
395 SC_SPLIT_LEFT : SC_SPLIT_RIGHT;
396 ScVSplitPos eWhichV = ((eWhich == SC_SPLIT_TOPLEFT) || (eWhich == SC_SPLIT_TOPRIGHT)) ?
397 SC_SPLIT_TOP : SC_SPLIT_BOTTOM;
398 ScAddress aCell(pViewShell->GetViewData().GetPosX(eWhichH),
399 pViewShell->GetViewData().GetPosY(eWhichV),
400 pViewShell->GetViewData().GetTabNo());
401 tools::Rectangle aCellRect( rDoc.GetMMRect( aCell.Col(), aCell.Row(), aCell.Col(), aCell.Row(), aCell.Tab() ) );
402 Size aVisSize( pWindow->PixelToLogic( pWindow->GetSizePixel(), pWindow->GetDrawMapMode( true ) ) );
403 Point aVisPos( aCellRect.TopLeft() );
404 if ( rDoc.IsLayoutRTL( aCell.Tab() ) )
406 aVisPos = aCellRect.TopRight();
407 aVisPos.AdjustX( -(aVisSize.Width()) );
409 tools::Rectangle aVisRect( aVisPos, aVisSize );
410 aVisArea = vcl::unohelper::ConvertToAWTRect(aVisRect);
413 return aVisArea;
416 ScViewPaneObj::ScViewPaneObj(ScTabViewShell* pViewSh, sal_uInt16 nP) :
417 ScViewPaneBase( pViewSh, nP )
421 ScViewPaneObj::~ScViewPaneObj()
425 uno::Any SAL_CALL ScViewPaneObj::queryInterface( const uno::Type& rType )
427 // ScViewPaneBase has everything except OWeakObject
429 uno::Any aRet(ScViewPaneBase::queryInterface( rType ));
430 if (!aRet.hasValue())
431 aRet = OWeakObject::queryInterface( rType );
432 return aRet;
435 void SAL_CALL ScViewPaneObj::acquire() noexcept
437 OWeakObject::acquire();
440 void SAL_CALL ScViewPaneObj::release() noexcept
442 OWeakObject::release();
445 // We need default ctor for SMART_REFLECTION_IMPLEMENTATION
447 ScTabViewObj::ScTabViewObj( ScTabViewShell* pViewSh ) :
448 ScViewPaneBase( pViewSh, SC_VIEWPANE_ACTIVE ),
449 SfxBaseController( pViewSh ),
450 aPropSet( lcl_GetViewOptPropertyMap() ),
451 aMouseClickHandlers( 0 ),
452 aActivationListeners( 0 ),
453 nPreviousTab( 0 ),
454 bDrawSelModeSet(false),
455 bFilteredRangeSelection(false),
456 mbLeftMousePressed(false)
458 if (pViewSh)
459 nPreviousTab = pViewSh->GetViewData().GetTabNo();
462 ScTabViewObj::~ScTabViewObj()
464 //! Listening or something along that line
465 if (!aMouseClickHandlers.empty())
467 acquire();
468 EndMouseListening();
470 if (!aActivationListeners.empty())
472 acquire();
473 EndActivationListening();
477 uno::Any SAL_CALL ScTabViewObj::queryInterface( const uno::Type& rType )
479 uno::Any aReturn = ::cppu::queryInterface(rType,
480 static_cast<sheet::XSpreadsheetView*>(this),
481 static_cast<sheet::XEnhancedMouseClickBroadcaster*>(this),
482 static_cast<sheet::XActivationBroadcaster*>(this),
483 static_cast<container::XEnumerationAccess*>(this),
484 static_cast<container::XIndexAccess*>(this),
485 static_cast<container::XElementAccess*>(static_cast<container::XIndexAccess*>(this)),
486 static_cast<view::XSelectionSupplier*>(this),
487 static_cast<beans::XPropertySet*>(this),
488 static_cast<sheet::XViewSplitable*>(this),
489 static_cast<sheet::XViewFreezable*>(this),
490 static_cast<sheet::XRangeSelection*>(this),
491 static_cast<sheet::XSheetRange*>(this),
492 static_cast<sheet::XSelectedSheetsSupplier*>(this),
493 static_cast<datatransfer::XTransferableSupplier*>(this));
494 if ( aReturn.hasValue() )
495 return aReturn;
497 uno::Any aRet(ScViewPaneBase::queryInterface( rType ));
498 if (!aRet.hasValue())
499 aRet = SfxBaseController::queryInterface( rType );
500 return aRet;
503 void SAL_CALL ScTabViewObj::acquire() noexcept
505 SfxBaseController::acquire();
508 void SAL_CALL ScTabViewObj::release() noexcept
510 SfxBaseController::release();
513 static void lcl_CallActivate( ScDocShell* pDocSh, SCTAB nTab, ScSheetEventId nEvent )
515 ScDocument& rDoc = pDocSh->GetDocument();
516 // when deleting a sheet, nPreviousTab can be invalid
517 // (could be handled with reference updates)
518 if (!rDoc.HasTable(nTab))
519 return;
521 const ScSheetEvents* pEvents = rDoc.GetSheetEvents(nTab);
522 if (pEvents)
524 const OUString* pScript = pEvents->GetScript(nEvent);
525 if (pScript)
527 uno::Any aRet;
528 uno::Sequence<uno::Any> aParams;
529 uno::Sequence<sal_Int16> aOutArgsIndex;
530 uno::Sequence<uno::Any> aOutArgs;
531 /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
535 // execute VBA event handlers
538 uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( rDoc.GetVbaEventProcessor(), uno::UNO_SET_THROW );
539 // the parameter is the clicked object, as in the mousePressed call above
540 uno::Sequence< uno::Any > aArgs{ uno::Any(nTab) };
541 xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( nEvent ), aArgs );
543 catch( uno::Exception& )
548 void ScTabViewObj::SheetChanged( bool bSameTabButMoved )
550 if ( !GetViewShell() )
551 return;
553 ScViewData& rViewData = GetViewShell()->GetViewData();
554 ScDocShell* pDocSh = rViewData.GetDocShell();
555 if (!aActivationListeners.empty())
557 sheet::ActivationEvent aEvent;
558 uno::Reference< sheet::XSpreadsheetView > xView(this);
559 aEvent.Source.set(xView, uno::UNO_QUERY);
560 aEvent.ActiveSheet = new ScTableSheetObj(pDocSh, rViewData.GetTabNo());
561 // Listener's handler may remove it from the listeners list
562 for (size_t i = aActivationListeners.size(); i > 0; --i)
566 aActivationListeners[i - 1]->activeSpreadsheetChanged( aEvent );
568 catch( uno::Exception& )
570 aActivationListeners.erase(aActivationListeners.begin() + (i - 1));
575 /* Handle sheet events, but do not trigger event handlers, if the old
576 active sheet gets re-activated after inserting/deleting/moving a sheet. */
577 SCTAB nNewTab = rViewData.GetTabNo();
578 if ( !bSameTabButMoved && (nNewTab != nPreviousTab) )
580 lcl_CallActivate( pDocSh, nPreviousTab, ScSheetEventId::UNFOCUS );
581 lcl_CallActivate( pDocSh, nNewTab, ScSheetEventId::FOCUS );
583 nPreviousTab = nNewTab;
586 uno::Sequence<uno::Type> SAL_CALL ScTabViewObj::getTypes()
588 return comphelper::concatSequences(
589 ScViewPaneBase::getTypes(),
590 SfxBaseController::getTypes(),
591 uno::Sequence<uno::Type>
593 cppu::UnoType<sheet::XSpreadsheetView>::get(),
594 cppu::UnoType<container::XEnumerationAccess>::get(),
595 cppu::UnoType<container::XIndexAccess>::get(),
596 cppu::UnoType<view::XSelectionSupplier>::get(),
597 cppu::UnoType<beans::XPropertySet>::get(),
598 cppu::UnoType<sheet::XViewSplitable>::get(),
599 cppu::UnoType<sheet::XViewFreezable>::get(),
600 cppu::UnoType<sheet::XRangeSelection>::get(),
601 cppu::UnoType<sheet::XSheetRange>::get(),
602 cppu::UnoType<lang::XUnoTunnel>::get(),
603 cppu::UnoType<sheet::XEnhancedMouseClickBroadcaster>::get(),
604 cppu::UnoType<sheet::XActivationBroadcaster>::get(),
605 cppu::UnoType<datatransfer::XTransferableSupplier>::get()
606 } );
609 uno::Sequence<sal_Int8> SAL_CALL ScTabViewObj::getImplementationId()
611 return css::uno::Sequence<sal_Int8>();
614 // XDocumentView
616 static bool lcl_TabInRanges( SCTAB nTab, const ScRangeList& rRanges )
618 for (size_t i = 0, nCount = rRanges.size(); i < nCount; ++i)
620 const ScRange & rRange = rRanges[ i ];
621 if ( nTab >= rRange.aStart.Tab() && nTab <= rRange.aEnd.Tab() )
622 return true;
624 return false;
627 static void lcl_ShowObject( ScTabViewShell& rViewSh, const ScDrawView& rDrawView, const SdrObject* pSelObj )
629 bool bFound = false;
630 SCTAB nObjectTab = 0;
632 SdrModel& rModel = rDrawView.GetModel();
633 sal_uInt16 nPageCount = rModel.GetPageCount();
634 for (sal_uInt16 i=0; i<nPageCount && !bFound; i++)
636 SdrPage* pPage = rModel.GetPage(i);
637 if (pPage)
639 SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups );
640 SdrObject* pObject = aIter.Next();
641 while (pObject && !bFound)
643 if ( pObject == pSelObj )
645 bFound = true;
646 nObjectTab = static_cast<SCTAB>(i);
648 pObject = aIter.Next();
653 if (bFound)
655 rViewSh.SetTabNo( nObjectTab );
656 rViewSh.ScrollToObject( pSelObj );
660 sal_Bool SAL_CALL ScTabViewObj::select( const uno::Any& aSelection )
662 SolarMutexGuard aGuard;
663 ScTabViewShell* pViewSh = GetViewShell();
665 if ( !pViewSh )
666 return false;
668 //! Type of aSelection can be some specific interface instead of XInterface
670 bool bRet = false;
671 uno::Reference<uno::XInterface> xInterface(aSelection, uno::UNO_QUERY);
672 if ( !xInterface.is() ) //clear all selections
674 ScDrawView* pDrawView = pViewSh->GetScDrawView();
675 if (pDrawView)
677 pDrawView->ScEndTextEdit();
678 pDrawView->UnmarkAll();
680 else //#102232#; if there is no DrawView remove range selection
681 pViewSh->Unmark();
682 bRet = true;
685 if (bDrawSelModeSet) // remove DrawSelMode if set by API; if necessary it will be set again later
687 pViewSh->SetDrawSelMode(false);
688 pViewSh->UpdateLayerLocks();
689 bDrawSelModeSet = false;
692 if (bRet)
693 return bRet;
695 ScCellRangesBase* pRangesImp = dynamic_cast<ScCellRangesBase*>( xInterface.get() );
696 uno::Reference<drawing::XShapes> xShapeColl( xInterface, uno::UNO_QUERY );
697 uno::Reference<drawing::XShape> xShapeSel( xInterface, uno::UNO_QUERY );
698 SvxShape* pShapeImp = comphelper::getFromUnoTunnel<SvxShape>( xShapeSel );
700 if (pRangesImp) // Cell ranges
702 ScViewData& rViewData = pViewSh->GetViewData();
703 if ( rViewData.GetDocShell() == pRangesImp->GetDocShell() )
705 // perhaps remove drawing selection first
706 // (MarkListHasChanged removes sheet selection)
708 ScDrawView* pDrawView = pViewSh->GetScDrawView();
709 if (pDrawView)
711 pDrawView->ScEndTextEdit();
712 pDrawView->UnmarkAll();
714 FuPoor* pFunc = pViewSh->GetDrawFuncPtr();
715 if ( pFunc && pFunc->GetSlotID() != SID_OBJECT_SELECT )
717 // execute the slot of drawing function again -> switch off
718 SfxDispatcher* pDisp = pViewSh->GetDispatcher();
719 if (pDisp)
720 pDisp->Execute( pFunc->GetSlotID(), SfxCallMode::SYNCHRON );
722 pViewSh->SetDrawShell(false);
723 pViewSh->SetDrawSelMode(false); // after Dispatcher-Execute
725 // select ranges
727 const ScRangeList& rRanges = pRangesImp->GetRangeList();
728 size_t nRangeCount = rRanges.size();
729 // for empty range list, remove selection (cursor remains where it was)
730 if ( nRangeCount == 0 )
731 pViewSh->Unmark();
732 else if ( nRangeCount == 1 )
733 pViewSh->MarkRange( rRanges[ 0 ] );
734 else
736 // multiselection
738 const ScRange & rFirst = rRanges[ 0 ];
739 if ( !lcl_TabInRanges( rViewData.GetTabNo(), rRanges ) )
740 pViewSh->SetTabNo( rFirst.aStart.Tab() );
741 pViewSh->DoneBlockMode();
742 pViewSh->InitOwnBlockMode( rFirst ); /* TODO: or even the overall range? */
743 rViewData.GetMarkData().MarkFromRangeList( rRanges, true );
744 pViewSh->MarkDataChanged();
745 rViewData.GetDocShell()->PostPaintGridAll(); // Marks (old&new)
746 pViewSh->AlignToCursor( rFirst.aStart.Col(), rFirst.aStart.Row(),
747 SC_FOLLOW_JUMP );
748 pViewSh->SetCursor( rFirst.aStart.Col(), rFirst.aStart.Row() );
750 //! method of the view to select RangeList
752 bRet = true;
755 else if ( pShapeImp || xShapeColl.is() ) // Drawing-Layer
757 ScDrawView* pDrawView = pViewSh->GetScDrawView();
758 if (pDrawView)
760 pDrawView->ScEndTextEdit();
761 pDrawView->UnmarkAll();
763 if (pShapeImp) // single shape
765 SdrObject *pObj = pShapeImp->GetSdrObject();
766 if (pObj)
768 lcl_ShowObject( *pViewSh, *pDrawView, pObj );
769 SdrPageView* pPV = pDrawView->GetSdrPageView();
770 if ( pPV && pObj->getSdrPageFromSdrObject() == pPV->GetPage() )
772 pDrawView->MarkObj( pObj, pPV );
773 bRet = true;
777 else // Shape-Collection (xShapeColl is not 0)
779 // We'll switch to the sheet where the first object is
780 // and select all objects on that sheet
781 //!?throw exception when objects are on different sheets?
783 tools::Long nCount = xShapeColl->getCount();
784 if (nCount)
786 SdrPageView* pPV = nullptr;
787 bool bAllMarked(true);
788 for ( tools::Long i = 0; i < nCount; i++ )
790 uno::Reference<drawing::XShape> xShapeInt(xShapeColl->getByIndex(i), uno::UNO_QUERY);
791 if (xShapeInt.is())
793 SdrObject* pObj = SdrObject::getSdrObjectFromXShape( xShapeInt );
794 if (pObj)
796 if (!bDrawSelModeSet && (pObj->GetLayer() == SC_LAYER_BACK))
798 pViewSh->SetDrawSelMode(true);
799 pViewSh->UpdateLayerLocks();
800 bDrawSelModeSet = true;
802 if (!pPV) // first object
804 lcl_ShowObject( *pViewSh, *pDrawView, pObj );
805 pPV = pDrawView->GetSdrPageView();
807 if ( pPV && pObj->getSdrPageFromSdrObject() == pPV->GetPage() )
809 if (pDrawView->IsObjMarkable( pObj, pPV ))
810 pDrawView->MarkObj( pObj, pPV );
811 else
812 bAllMarked = false;
817 if (bAllMarked)
818 bRet = true;
820 else
821 bRet = true; // empty XShapes (all shapes are deselected)
824 if (bRet)
825 pViewSh->SetDrawShell(true);
829 if (!bRet)
830 throw lang::IllegalArgumentException();
832 return bRet;
835 uno::Reference<drawing::XShapes> ScTabViewShell::getSelectedXShapes()
837 uno::Reference<drawing::XShapes> xShapes;
838 SdrView* pSdrView = GetScDrawView();
839 if (pSdrView)
841 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
842 const size_t nMarkCount = rMarkList.GetMarkCount();
843 if (nMarkCount)
845 // generate ShapeCollection (like in SdXImpressView::getSelection in Draw)
846 // XInterfaceRef will be returned and it has to be UsrObject-XInterface
847 xShapes = drawing::ShapeCollection::create(comphelper::getProcessComponentContext());
849 for (size_t i = 0; i < nMarkCount; ++i)
851 SdrObject* pDrawObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
852 if (pDrawObj)
854 uno::Reference<drawing::XShape> xShape( pDrawObj->getUnoShape(), uno::UNO_QUERY );
855 if (xShape.is())
856 xShapes->add(xShape);
861 return xShapes;
864 uno::Any SAL_CALL ScTabViewObj::getSelection()
866 SolarMutexGuard aGuard;
867 ScTabViewShell* pViewSh = GetViewShell();
868 rtl::Reference<ScCellRangesBase> pObj;
869 if (pViewSh)
871 // is something selected in drawing layer?
872 uno::Reference<uno::XInterface> xRet(pViewSh->getSelectedXShapes());
873 if (xRet.is())
874 return uno::Any(xRet);
876 // otherwise sheet (cell) selection
878 ScViewData& rViewData = pViewSh->GetViewData();
879 ScDocShell* pDocSh = rViewData.GetDocShell();
881 const ScMarkData& rMark = rViewData.GetMarkData();
882 SCTAB nTabs = rMark.GetSelectCount();
884 ScRange aRange;
885 ScMarkType eMarkType = rViewData.GetSimpleArea(aRange);
886 if ( nTabs == 1 && (eMarkType == SC_MARK_SIMPLE) )
888 // tdf#154803 - check if range is entirely merged
889 ScDocument& rDoc = pDocSh->GetDocument();
890 const ScMergeAttr* pMergeAttr = rDoc.GetAttr(aRange.aStart, ATTR_MERGE);
891 SCCOL nColSpan = 1;
892 SCROW nRowSpan = 1;
893 if (pMergeAttr && pMergeAttr->IsMerged())
895 nColSpan = pMergeAttr->GetColMerge();
896 nRowSpan = pMergeAttr->GetRowMerge();
898 // tdf#147122 - return cell object when a simple selection is entirely merged
899 if (aRange.aStart == aRange.aEnd
900 || (aRange.aEnd.Col() - aRange.aStart.Col() == nColSpan - 1
901 && aRange.aEnd.Row() - aRange.aStart.Row() == nRowSpan - 1))
902 pObj = new ScCellObj( pDocSh, aRange.aStart );
903 else
904 pObj = new ScCellRangeObj( pDocSh, aRange );
906 else if ( nTabs == 1 && (eMarkType == SC_MARK_SIMPLE_FILTERED) )
908 ScMarkData aFilteredMark( rMark );
909 ScViewUtil::UnmarkFiltered( aFilteredMark, pDocSh->GetDocument());
910 ScRangeList aRangeList;
911 aFilteredMark.FillRangeListWithMarks( &aRangeList, false);
912 // Theoretically a selection may start and end on a filtered row.
913 switch ( aRangeList.size() )
915 case 0:
916 // No unfiltered row, we have to return some object, so
917 // here is one with no ranges.
918 pObj = new ScCellRangesObj( pDocSh, aRangeList );
919 break;
920 case 1:
922 const ScRange& rRange = aRangeList[ 0 ];
923 if (rRange.aStart == rRange.aEnd)
924 pObj = new ScCellObj( pDocSh, rRange.aStart );
925 else
926 pObj = new ScCellRangeObj( pDocSh, rRange );
928 break;
929 default:
930 pObj = new ScCellRangesObj( pDocSh, aRangeList );
933 else // multiselection
935 ScRangeListRef xRanges;
936 rViewData.GetMultiArea( xRanges );
938 // if there are more sheets, copy ranges
939 //! should this happen in ScMarkData::FillRangeListWithMarks already?
940 if ( nTabs > 1 )
941 rMark.ExtendRangeListTables( xRanges.get() );
943 pObj = new ScCellRangesObj( pDocSh, *xRanges );
946 if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
948 // remember if the selection was from the cursor position without anything selected
949 // (used when rendering the selection)
951 pObj->SetCursorOnly( true );
955 return uno::Any(uno::Reference(cppu::getXWeak(pObj.get())));
958 uno::Any SAL_CALL ScTabViewObj::getSelectionFromString( const OUString& aStrRange )
960 ScDocShell* pDocSh = GetViewShell()->GetViewData().GetDocShell();
961 const sal_Int16 nTabCount = pDocSh->GetDocument().GetTableCount();
963 StringRangeEnumerator aRangeEnum(aStrRange , 0, nTabCount-1);
965 // iterate through sheet range
967 StringRangeEnumerator::Iterator aIter = aRangeEnum.begin();
968 StringRangeEnumerator::Iterator aEnd = aRangeEnum.end();
970 ScRangeListRef aRangeList = new ScRangeList;
972 while ( aIter != aEnd )
974 ScRange currentTab(SCCOL(0), SCROW(0), SCTAB(*aIter));
975 aRangeList->push_back(currentTab);
976 ++aIter;
979 rtl::Reference<ScCellRangesBase> pObj = new ScCellRangesObj(pDocSh, *aRangeList);
981 // SetCursorOnly tells the range the specific cells selected are irrelevant - maybe could rename?
982 pObj->SetCursorOnly(true);
984 return uno::Any(uno::Reference<uno::XInterface>(static_cast<cppu::OWeakObject*>(pObj.get())));
987 // XEnumerationAccess
989 uno::Reference<container::XEnumeration> SAL_CALL ScTabViewObj::createEnumeration()
991 SolarMutexGuard aGuard;
992 return new ScIndexEnumeration(this, u"com.sun.star.sheet.SpreadsheetViewPanesEnumeration"_ustr);
995 // XIndexAccess
997 sal_Int32 SAL_CALL ScTabViewObj::getCount()
999 SolarMutexGuard aGuard;
1000 ScTabViewShell* pViewSh = GetViewShell();
1001 sal_uInt16 nPanes = 0;
1002 if (pViewSh)
1004 nPanes = 1;
1005 ScViewData& rViewData = pViewSh->GetViewData();
1006 if ( rViewData.GetHSplitMode() != SC_SPLIT_NONE )
1007 nPanes *= 2;
1008 if ( rViewData.GetVSplitMode() != SC_SPLIT_NONE )
1009 nPanes *= 2;
1011 return nPanes;
1014 uno::Any SAL_CALL ScTabViewObj::getByIndex( sal_Int32 nIndex )
1016 SolarMutexGuard aGuard;
1017 uno::Reference<sheet::XViewPane> xPane(GetObjectByIndex_Impl(static_cast<sal_uInt16>(nIndex)));
1018 if (!xPane.is())
1019 throw lang::IndexOutOfBoundsException();
1021 return uno::Any(xPane);
1024 uno::Type SAL_CALL ScTabViewObj::getElementType()
1026 return cppu::UnoType<sheet::XViewPane>::get();
1029 sal_Bool SAL_CALL ScTabViewObj::hasElements()
1031 SolarMutexGuard aGuard;
1032 return ( getCount() != 0 );
1035 // XSpreadsheetView
1037 rtl::Reference<ScViewPaneObj> ScTabViewObj::GetObjectByIndex_Impl(sal_uInt16 nIndex) const
1039 static const ScSplitPos ePosHV[4] =
1040 { SC_SPLIT_TOPLEFT, SC_SPLIT_BOTTOMLEFT, SC_SPLIT_TOPRIGHT, SC_SPLIT_BOTTOMRIGHT };
1042 ScTabViewShell* pViewSh = GetViewShell();
1043 if (pViewSh)
1045 ScSplitPos eWhich = SC_SPLIT_BOTTOMLEFT; // default position
1046 bool bError = false;
1047 ScViewData& rViewData = pViewSh->GetViewData();
1048 bool bHor = ( rViewData.GetHSplitMode() != SC_SPLIT_NONE );
1049 bool bVer = ( rViewData.GetVSplitMode() != SC_SPLIT_NONE );
1050 if ( bHor && bVer )
1052 // bottom left, bottom right, top left, top right - like in Excel
1053 if ( nIndex < 4 )
1054 eWhich = ePosHV[nIndex];
1055 else
1056 bError = true;
1058 else if ( bHor )
1060 if ( nIndex > 1 )
1061 bError = true;
1062 else if ( nIndex == 1 )
1063 eWhich = SC_SPLIT_BOTTOMRIGHT;
1064 // otherwise SC_SPLIT_BOTTOMLEFT
1066 else if ( bVer )
1068 if ( nIndex > 1 )
1069 bError = true;
1070 else if ( nIndex == 0 )
1071 eWhich = SC_SPLIT_TOPLEFT;
1072 // otherwise SC_SPLIT_BOTTOMLEFT
1074 else if ( nIndex > 0 )
1075 bError = true; // not split: only 0 is valid
1077 if (!bError)
1078 return new ScViewPaneObj( pViewSh, sal::static_int_cast<sal_uInt16>(eWhich) );
1081 return nullptr;
1084 uno::Reference<sheet::XSpreadsheet> SAL_CALL ScTabViewObj::getActiveSheet()
1086 SolarMutexGuard aGuard;
1087 ScTabViewShell* pViewSh = GetViewShell();
1088 if (pViewSh)
1090 ScViewData& rViewData = pViewSh->GetViewData();
1091 SCTAB nTab = rViewData.GetTabNo();
1092 return new ScTableSheetObj( rViewData.GetDocShell(), nTab );
1094 return nullptr;
1097 // support expand (but not replace) the active sheet
1098 void SAL_CALL ScTabViewObj::setActiveSheet( const uno::Reference<sheet::XSpreadsheet>& xActiveSheet )
1100 SolarMutexGuard aGuard;
1101 comphelper::ProfileZone aZone("setActiveSheet");
1103 ScTabViewShell* pViewSh = GetViewShell();
1104 if ( !(pViewSh && xActiveSheet.is()) )
1105 return;
1107 // XSpreadsheet and ScCellRangesBase -> has to be the same sheet
1109 ScCellRangesBase* pRangesImp = dynamic_cast<ScCellRangesBase*>( xActiveSheet.get() );
1110 if ( pRangesImp && pViewSh->GetViewData().GetDocShell() == pRangesImp->GetDocShell() )
1112 const ScRangeList& rRanges = pRangesImp->GetRangeList();
1113 if ( rRanges.size() == 1 )
1115 SCTAB nNewTab = rRanges[ 0 ].aStart.Tab();
1116 if ( pViewSh->GetViewData().GetDocument().HasTable(nNewTab) )
1117 pViewSh->SetTabNo( nNewTab );
1122 uno::Reference< uno::XInterface > ScTabViewObj::GetClickedObject(const Point& rPoint) const
1124 uno::Reference< uno::XInterface > xTarget;
1125 if (GetViewShell())
1127 SCCOL nX;
1128 SCROW nY;
1129 ScViewData& rData = GetViewShell()->GetViewData();
1130 ScSplitPos eSplitMode = rData.GetActivePart();
1131 SCTAB nTab(rData.GetTabNo());
1132 rData.GetPosFromPixel( rPoint.X(), rPoint.Y(), eSplitMode, nX, nY);
1134 ScAddress aCellPos (nX, nY, nTab);
1135 rtl::Reference<ScCellObj> pCellObj = new ScCellObj(rData.GetDocShell(), aCellPos);
1137 xTarget.set(uno::Reference<table::XCell>(pCellObj), uno::UNO_QUERY);
1139 ScDocument& rDoc = rData.GetDocument();
1140 if (ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer())
1142 SdrPage* pDrawPage = nullptr;
1143 if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
1144 pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
1146 SdrView* pDrawView = GetViewShell()->GetScDrawView();
1148 if (pDrawPage && pDrawView && pDrawView->GetSdrPageView())
1150 vcl::Window* pActiveWin = rData.GetActiveWin();
1151 Point aPos = pActiveWin->PixelToLogic(rPoint);
1153 double fHitLog = pActiveWin->PixelToLogic(Size(pDrawView->GetHitTolerancePixel(),0)).Width();
1155 for (const rtl::Reference<SdrObject>& pObj : *pDrawPage)
1157 if (SdrObjectPrimitiveHit(*pObj, aPos, {fHitLog, fHitLog}, *pDrawView->GetSdrPageView(), nullptr, false))
1159 xTarget.set(pObj->getUnoShape(), uno::UNO_QUERY);
1160 break;
1166 return xTarget;
1169 bool ScTabViewObj::IsMouseListening() const
1171 if ( !aMouseClickHandlers.empty() )
1172 return true;
1174 // also include sheet events, because MousePressed must be called for them
1175 ScViewData& rViewData = GetViewShell()->GetViewData();
1176 ScDocument& rDoc = rViewData.GetDocument();
1177 SCTAB nTab = rViewData.GetTabNo();
1178 return
1179 rDoc.HasSheetEventScript( nTab, ScSheetEventId::RIGHTCLICK, true ) ||
1180 rDoc.HasSheetEventScript( nTab, ScSheetEventId::DOUBLECLICK, true ) ||
1181 rDoc.HasSheetEventScript( nTab, ScSheetEventId::SELECT, true );
1185 bool ScTabViewObj::MousePressed( const awt::MouseEvent& e )
1187 bool bReturn(false);
1188 if ( e.Buttons == css::awt::MouseButton::LEFT )
1189 mbLeftMousePressed = true;
1191 uno::Reference< uno::XInterface > xTarget = GetClickedObject(Point(e.X, e.Y));
1192 if (!aMouseClickHandlers.empty() && xTarget.is())
1194 awt::EnhancedMouseEvent aMouseEvent;
1196 aMouseEvent.Buttons = e.Buttons;
1197 aMouseEvent.X = e.X;
1198 aMouseEvent.Y = e.Y;
1199 aMouseEvent.ClickCount = e.ClickCount;
1200 aMouseEvent.PopupTrigger = e.PopupTrigger;
1201 aMouseEvent.Target = xTarget;
1202 aMouseEvent.Modifiers = e.Modifiers;
1204 // Listener's handler may remove it from the listeners list
1205 for (size_t i = aMouseClickHandlers.size(); i > 0; --i)
1209 if (!aMouseClickHandlers[i - 1]->mousePressed(aMouseEvent))
1210 bReturn = true;
1212 catch ( uno::Exception& )
1214 aMouseClickHandlers.erase(aMouseClickHandlers.begin() + (i - 1));
1219 // handle sheet events
1220 bool bDoubleClick = ( e.Buttons == awt::MouseButton::LEFT && e.ClickCount == 2 );
1221 bool bRightClick = ( e.Buttons == awt::MouseButton::RIGHT && e.ClickCount == 1 );
1222 if ( ( bDoubleClick || bRightClick ) && !bReturn && xTarget.is())
1224 ScSheetEventId nEvent = bDoubleClick ? ScSheetEventId::DOUBLECLICK : ScSheetEventId::RIGHTCLICK;
1226 ScTabViewShell* pViewSh = GetViewShell();
1227 ScViewData& rViewData = pViewSh->GetViewData();
1228 ScDocShell* pDocSh = rViewData.GetDocShell();
1229 ScDocument& rDoc = pDocSh->GetDocument();
1230 SCTAB nTab = rViewData.GetTabNo();
1231 const ScSheetEvents* pEvents = rDoc.GetSheetEvents(nTab);
1232 if (pEvents)
1234 const OUString* pScript = pEvents->GetScript(nEvent);
1235 if (pScript)
1237 // the macro parameter is the clicked object, as in the mousePressed call above
1238 uno::Sequence<uno::Any> aParams{ uno::Any(xTarget) };
1240 uno::Any aRet;
1241 uno::Sequence<sal_Int16> aOutArgsIndex;
1242 uno::Sequence<uno::Any> aOutArgs;
1244 /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
1246 // look for a boolean return value of true
1247 bool bRetValue = false;
1248 if ((aRet >>= bRetValue) && bRetValue)
1249 bReturn = true;
1253 // execute VBA event handler
1254 if (!bReturn && xTarget.is()) try
1256 uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( rDoc.GetVbaEventProcessor(), uno::UNO_SET_THROW );
1257 // the parameter is the clicked object, as in the mousePressed call above
1258 uno::Sequence< uno::Any > aArgs{ uno::Any(xTarget) };
1259 xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( nEvent ), aArgs );
1261 catch( util::VetoException& )
1263 bReturn = true;
1265 catch( uno::Exception& )
1270 return bReturn;
1273 bool ScTabViewObj::MouseReleased( const awt::MouseEvent& e )
1275 if ( e.Buttons == css::awt::MouseButton::LEFT )
1279 ScTabViewShell* pViewSh = GetViewShell();
1280 ScViewData& rViewData = pViewSh->GetViewData();
1281 ScDocShell* pDocSh = rViewData.GetDocShell();
1282 ScDocument& rDoc = pDocSh->GetDocument();
1283 uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( rDoc.GetVbaEventProcessor(), uno::UNO_SET_THROW );
1284 uno::Sequence< uno::Any > aArgs{ getSelection() };
1285 xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( ScSheetEventId::SELECT ), aArgs );
1287 catch( uno::Exception& )
1290 mbLeftMousePressed = false;
1293 bool bReturn(false);
1295 if (!aMouseClickHandlers.empty())
1297 uno::Reference< uno::XInterface > xTarget = GetClickedObject(Point(e.X, e.Y));
1299 if (xTarget.is())
1301 awt::EnhancedMouseEvent aMouseEvent;
1303 aMouseEvent.Buttons = e.Buttons;
1304 aMouseEvent.X = e.X;
1305 aMouseEvent.Y = e.Y;
1306 aMouseEvent.ClickCount = e.ClickCount;
1307 aMouseEvent.PopupTrigger = e.PopupTrigger;
1308 aMouseEvent.Target = std::move(xTarget);
1309 aMouseEvent.Modifiers = e.Modifiers;
1311 // Listener's handler may remove it from the listeners list
1312 for (size_t i = aMouseClickHandlers.size(); i > 0; --i)
1316 if (!aMouseClickHandlers[i - 1]->mouseReleased( aMouseEvent ))
1317 bReturn = true;
1319 catch ( uno::Exception& )
1321 aMouseClickHandlers.erase(aMouseClickHandlers.begin() + (i - 1));
1326 return bReturn;
1329 // XEnhancedMouseClickBroadcaster
1331 void ScTabViewObj::EndMouseListening()
1333 lang::EventObject aEvent;
1334 aEvent.Source = getXWeak();
1335 for (const auto& rListener : aMouseClickHandlers)
1339 rListener->disposing(aEvent);
1341 catch ( uno::Exception& )
1345 aMouseClickHandlers.clear();
1348 void ScTabViewObj::EndActivationListening()
1350 lang::EventObject aEvent;
1351 aEvent.Source = getXWeak();
1352 for (const auto& rListener : aActivationListeners)
1356 rListener->disposing(aEvent);
1358 catch ( uno::Exception& )
1362 aActivationListeners.clear();
1365 void SAL_CALL ScTabViewObj::addEnhancedMouseClickHandler( const uno::Reference< awt::XEnhancedMouseClickHandler >& aListener )
1367 SolarMutexGuard aGuard;
1369 if (aListener.is())
1371 aMouseClickHandlers.push_back( aListener );
1375 void SAL_CALL ScTabViewObj::removeEnhancedMouseClickHandler( const uno::Reference< awt::XEnhancedMouseClickHandler >& aListener )
1377 SolarMutexGuard aGuard;
1378 sal_uInt16 nCount = aMouseClickHandlers.size();
1379 std::erase(aMouseClickHandlers, aListener);
1380 if (aMouseClickHandlers.empty() && (nCount > 0)) // only if last listener removed
1381 EndMouseListening();
1384 // XActivationBroadcaster
1386 void SAL_CALL ScTabViewObj::addActivationEventListener( const uno::Reference< sheet::XActivationEventListener >& aListener )
1388 SolarMutexGuard aGuard;
1390 if (aListener.is())
1392 aActivationListeners.push_back( aListener );
1396 void SAL_CALL ScTabViewObj::removeActivationEventListener( const uno::Reference< sheet::XActivationEventListener >& aListener )
1398 SolarMutexGuard aGuard;
1399 sal_uInt16 nCount = aActivationListeners.size();
1400 std::erase(aActivationListeners, aListener);
1401 if (aActivationListeners.empty() && (nCount > 0)) // only if last listener removed
1402 EndActivationListening();
1405 sal_Int16 ScTabViewObj::GetZoom() const
1407 ScTabViewShell* pViewSh = GetViewShell();
1408 if (pViewSh)
1410 const Fraction& rZoomY = pViewSh->GetViewData().GetZoomY(); // Y will be shown
1411 return static_cast<sal_Int16>(tools::Long( rZoomY * 100 ));
1413 return 0;
1416 void ScTabViewObj::SetZoom(sal_Int16 nZoom)
1418 ScTabViewShell* pViewSh = GetViewShell();
1419 if (!pViewSh)
1420 return;
1422 if ( nZoom != GetZoom() && nZoom != 0 )
1424 if (!pViewSh->GetViewData().IsPagebreakMode())
1426 ScModule* pScMod = ScModule::get();
1427 ScAppOptions aNewOpt(pScMod->GetAppOptions());
1428 aNewOpt.SetZoom( nZoom );
1429 aNewOpt.SetZoomType( pViewSh->GetViewData().GetView()->GetZoomType() );
1430 pScMod->SetAppOptions( aNewOpt );
1433 Fraction aFract( nZoom, 100 );
1434 pViewSh->SetZoom( aFract, aFract, true );
1435 pViewSh->PaintGrid();
1436 pViewSh->PaintTop();
1437 pViewSh->PaintLeft();
1438 pViewSh->GetViewFrame().GetBindings().Invalidate( SID_ATTR_ZOOM );
1439 pViewSh->GetViewFrame().GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
1440 pViewSh->GetViewFrame().GetBindings().Invalidate(SID_ZOOM_IN);
1441 pViewSh->GetViewFrame().GetBindings().Invalidate(SID_ZOOM_OUT);
1444 sal_Int16 ScTabViewObj::GetZoomType() const
1446 sal_Int16 aZoomType = view::DocumentZoomType::OPTIMAL;
1447 ScTabViewShell* pViewSh = GetViewShell();
1448 if (pViewSh)
1450 SvxZoomType eZoomType = pViewSh->GetViewData().GetView()->GetZoomType();
1451 switch (eZoomType)
1453 case SvxZoomType::PERCENT:
1454 aZoomType = view::DocumentZoomType::BY_VALUE;
1455 break;
1456 case SvxZoomType::OPTIMAL:
1457 aZoomType = view::DocumentZoomType::OPTIMAL;
1458 break;
1459 case SvxZoomType::WHOLEPAGE:
1460 aZoomType = view::DocumentZoomType::ENTIRE_PAGE;
1461 break;
1462 case SvxZoomType::PAGEWIDTH:
1463 aZoomType = view::DocumentZoomType::PAGE_WIDTH;
1464 break;
1465 case SvxZoomType::PAGEWIDTH_NOBORDER:
1466 aZoomType = view::DocumentZoomType::PAGE_WIDTH_EXACT;
1467 break;
1470 return aZoomType;
1473 void ScTabViewObj::SetZoomType(sal_Int16 aZoomType)
1475 ScTabViewShell* pViewSh = GetViewShell();
1476 if (!pViewSh)
1477 return;
1479 ScDBFunc* pView = pViewSh->GetViewData().GetView();
1480 if (!pView)
1481 return;
1483 SvxZoomType eZoomType;
1484 switch (aZoomType)
1486 case view::DocumentZoomType::BY_VALUE:
1487 eZoomType = SvxZoomType::PERCENT;
1488 break;
1489 case view::DocumentZoomType::OPTIMAL:
1490 eZoomType = SvxZoomType::OPTIMAL;
1491 break;
1492 case view::DocumentZoomType::ENTIRE_PAGE:
1493 eZoomType = SvxZoomType::WHOLEPAGE;
1494 break;
1495 case view::DocumentZoomType::PAGE_WIDTH:
1496 eZoomType = SvxZoomType::PAGEWIDTH;
1497 break;
1498 case view::DocumentZoomType::PAGE_WIDTH_EXACT:
1499 eZoomType = SvxZoomType::PAGEWIDTH_NOBORDER;
1500 break;
1501 default:
1502 eZoomType = SvxZoomType::OPTIMAL;
1504 sal_Int16 nZoom(GetZoom());
1505 sal_Int16 nOldZoom(nZoom);
1506 if ( eZoomType == SvxZoomType::PERCENT )
1508 if ( nZoom < MINZOOM ) nZoom = MINZOOM;
1509 if ( nZoom > MAXZOOM ) nZoom = MAXZOOM;
1511 else
1512 nZoom = pView->CalcZoom( eZoomType, nOldZoom );
1514 switch ( eZoomType )
1516 case SvxZoomType::WHOLEPAGE:
1517 case SvxZoomType::PAGEWIDTH:
1518 pView->SetZoomType( eZoomType, true );
1519 break;
1521 default:
1522 pView->SetZoomType( SvxZoomType::PERCENT, true );
1524 SetZoom( nZoom );
1527 sal_Bool SAL_CALL ScTabViewObj::getIsWindowSplit()
1529 SolarMutexGuard aGuard;
1530 // what menu slot SID_WINDOW_SPLIT does
1532 ScTabViewShell* pViewSh = GetViewShell();
1533 if (pViewSh)
1535 ScViewData& rViewData = pViewSh->GetViewData();
1536 return ( rViewData.GetHSplitMode() == SC_SPLIT_NORMAL ||
1537 rViewData.GetVSplitMode() == SC_SPLIT_NORMAL );
1540 return false;
1543 sal_Bool SAL_CALL ScTabViewObj::hasFrozenPanes()
1545 SolarMutexGuard aGuard;
1546 // what menu slot SID_WINDOW_FIX does
1548 ScTabViewShell* pViewSh = GetViewShell();
1549 if (pViewSh)
1551 ScViewData& rViewData = pViewSh->GetViewData();
1552 return ( rViewData.GetHSplitMode() == SC_SPLIT_FIX ||
1553 rViewData.GetVSplitMode() == SC_SPLIT_FIX );
1556 return false;
1559 sal_Int32 SAL_CALL ScTabViewObj::getSplitHorizontal()
1561 SolarMutexGuard aGuard;
1562 ScTabViewShell* pViewSh = GetViewShell();
1563 if (pViewSh)
1565 ScViewData& rViewData = pViewSh->GetViewData();
1566 if ( rViewData.GetHSplitMode() != SC_SPLIT_NONE )
1567 return rViewData.GetHSplitPos();
1569 return 0;
1572 sal_Int32 SAL_CALL ScTabViewObj::getSplitVertical()
1574 SolarMutexGuard aGuard;
1575 ScTabViewShell* pViewSh = GetViewShell();
1576 if (pViewSh)
1578 ScViewData& rViewData = pViewSh->GetViewData();
1579 if ( rViewData.GetVSplitMode() != SC_SPLIT_NONE )
1580 return rViewData.GetVSplitPos();
1582 return 0;
1585 sal_Int32 SAL_CALL ScTabViewObj::getSplitColumn()
1587 SolarMutexGuard aGuard;
1588 ScTabViewShell* pViewSh = GetViewShell();
1589 if (pViewSh)
1591 ScViewData& rViewData = pViewSh->GetViewData();
1592 if ( rViewData.GetHSplitMode() != SC_SPLIT_NONE )
1594 tools::Long nSplit = rViewData.GetHSplitPos();
1596 ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
1597 if ( rViewData.GetVSplitMode() != SC_SPLIT_NONE )
1598 ePos = SC_SPLIT_TOPLEFT;
1600 SCCOL nCol;
1601 SCROW nRow;
1602 rViewData.GetPosFromPixel( nSplit, 0, ePos, nCol, nRow, false );
1603 if ( nCol > 0 )
1604 return nCol;
1607 return 0;
1610 sal_Int32 SAL_CALL ScTabViewObj::getSplitRow()
1612 SolarMutexGuard aGuard;
1613 ScTabViewShell* pViewSh = GetViewShell();
1614 if (pViewSh)
1616 ScViewData& rViewData = pViewSh->GetViewData();
1617 if ( rViewData.GetVSplitMode() != SC_SPLIT_NONE )
1619 tools::Long nSplit = rViewData.GetVSplitPos();
1621 // split vertically
1622 SCCOL nCol;
1623 SCROW nRow;
1624 rViewData.GetPosFromPixel( 0, nSplit, SC_SPLIT_TOPLEFT, nCol, nRow, false );
1625 if ( nRow > 0 )
1626 return nRow;
1629 return 0;
1632 void SAL_CALL ScTabViewObj::splitAtPosition( sal_Int32 nPixelX, sal_Int32 nPixelY )
1634 SolarMutexGuard aGuard;
1635 ScTabViewShell* pViewSh = GetViewShell();
1636 if (pViewSh)
1638 pViewSh->SplitAtPixel( Point( nPixelX, nPixelY ) );
1639 pViewSh->FreezeSplitters( false );
1640 pViewSh->InvalidateSplit();
1644 void SAL_CALL ScTabViewObj::freezeAtPosition( sal_Int32 nColumns, sal_Int32 nRows )
1646 SolarMutexGuard aGuard;
1647 ScTabViewShell* pViewSh = GetViewShell();
1648 if (!pViewSh)
1649 return;
1651 // first, remove them all -> no stress with scrolling in the meantime
1653 pViewSh->RemoveSplit();
1655 Point aWinStart;
1656 vcl::Window* pWin = pViewSh->GetWindowByPos( SC_SPLIT_BOTTOMLEFT );
1657 if (pWin)
1658 aWinStart = pWin->GetPosPixel();
1660 ScViewData& rViewData = pViewSh->GetViewData();
1661 Point aSplit(rViewData.GetScrPos( static_cast<SCCOL>(nColumns), static_cast<SCROW>(nRows), SC_SPLIT_BOTTOMLEFT, true ));
1662 aSplit += aWinStart;
1664 pViewSh->SplitAtPixel( aSplit );
1665 pViewSh->FreezeSplitters( true );
1666 pViewSh->InvalidateSplit();
1669 void SAL_CALL ScTabViewObj::addSelectionChangeListener(
1670 const uno::Reference<view::XSelectionChangeListener>& xListener )
1672 SolarMutexGuard aGuard;
1673 aSelectionChgListeners.push_back( xListener );
1676 void SAL_CALL ScTabViewObj::removeSelectionChangeListener(
1677 const uno::Reference< view::XSelectionChangeListener >& xListener )
1679 SolarMutexGuard aGuard;
1680 auto it = std::find(aSelectionChgListeners.begin(), aSelectionChgListeners.end(), xListener); //! why the hassle with queryInterface?
1681 if (it != aSelectionChgListeners.end())
1682 aSelectionChgListeners.erase(it);
1685 void ScTabViewObj::SelectionChanged()
1687 // Selection changed so end any style preview
1688 // Note: executing this slot through the dispatcher
1689 // will cause the style dialog to be raised so we go
1690 // direct here
1691 ScFormatShell aShell( GetViewShell()->GetViewData() );
1692 SfxAllItemSet reqList( SfxGetpApp()->GetPool() );
1693 SfxRequest aReq( SID_STYLE_END_PREVIEW, SfxCallMode::SLOT, reqList );
1694 aShell.ExecuteStyle( aReq );
1695 lang::EventObject aEvent;
1696 aEvent.Source.set(getXWeak());
1697 for (const auto& rListener : aSelectionChgListeners)
1698 rListener->selectionChanged( aEvent );
1700 // handle sheet events
1701 ScTabViewShell* pViewSh = GetViewShell();
1702 ScViewData& rViewData = pViewSh->GetViewData();
1703 ScDocShell* pDocSh = rViewData.GetDocShell();
1704 ScDocument& rDoc = pDocSh->GetDocument();
1705 SCTAB nTab = rViewData.GetTabNo();
1706 const ScSheetEvents* pEvents = rDoc.GetSheetEvents(nTab);
1707 if (pEvents)
1709 const OUString* pScript = pEvents->GetScript(ScSheetEventId::SELECT);
1710 if (pScript)
1712 // the macro parameter is the selection as returned by getSelection
1713 uno::Sequence<uno::Any> aParams{ getSelection() };
1714 uno::Any aRet;
1715 uno::Sequence<sal_Int16> aOutArgsIndex;
1716 uno::Sequence<uno::Any> aOutArgs;
1717 /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
1721 SfxApplication::Get()->Broadcast( SfxHint( SfxHintId::ScSelectionChanged ) );
1723 if ( mbLeftMousePressed ) // selection still in progress
1724 return;
1728 uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( rDoc.GetVbaEventProcessor(), uno::UNO_SET_THROW );
1729 uno::Sequence< uno::Any > aArgs{ getSelection() };
1730 xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( ScSheetEventId::SELECT ), aArgs );
1732 catch( uno::Exception& )
1737 // XPropertySet (view options)
1738 //! provide those also in application?
1740 uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTabViewObj::getPropertySetInfo()
1742 SolarMutexGuard aGuard;
1743 static uno::Reference<beans::XPropertySetInfo> aRef(
1744 new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
1745 return aRef;
1748 void SAL_CALL ScTabViewObj::setPropertyValue(
1749 const OUString& aPropertyName, const uno::Any& aValue )
1751 SolarMutexGuard aGuard;
1753 if ( aPropertyName == SC_UNO_FILTERED_RANGE_SELECTION )
1755 bFilteredRangeSelection = ScUnoHelpFunctions::GetBoolFromAny(aValue);
1756 return;
1759 ScTabViewShell* pViewSh = GetViewShell();
1760 if (!pViewSh)
1761 return;
1763 ScViewData& rViewData = pViewSh->GetViewData();
1764 const ScViewOptions& rOldOpt = pViewSh->GetViewData().GetOptions();
1765 ScViewOptions aNewOpt(rOldOpt);
1767 if ( aPropertyName == SC_UNO_COLROWHDR || aPropertyName == OLD_UNO_COLROWHDR )
1768 aNewOpt.SetOption( VOPT_HEADER, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1769 else if ( aPropertyName == SC_UNO_HORSCROLL || aPropertyName == OLD_UNO_HORSCROLL )
1770 aNewOpt.SetOption( VOPT_HSCROLL, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1771 else if ( aPropertyName == SC_UNO_OUTLSYMB || aPropertyName == OLD_UNO_OUTLSYMB )
1772 aNewOpt.SetOption( VOPT_OUTLINER, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1773 else if ( aPropertyName == SC_UNO_SHEETTABS || aPropertyName == OLD_UNO_SHEETTABS )
1774 aNewOpt.SetOption( VOPT_TABCONTROLS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1775 else if ( aPropertyName == SC_UNO_SHOWANCHOR )
1776 aNewOpt.SetOption( VOPT_ANCHOR, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1777 else if ( aPropertyName == SC_UNO_SHOWFORM )
1778 aNewOpt.SetOption( VOPT_FORMULAS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1779 else if ( aPropertyName == SC_UNO_SHOWGRID )
1780 aNewOpt.SetOption( VOPT_GRID, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1781 else if ( aPropertyName == SC_UNO_SHOWHELP )
1782 aNewOpt.SetOption( VOPT_HELPLINES, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1783 else if ( aPropertyName == SC_UNO_SHOWNOTES )
1784 aNewOpt.SetOption( VOPT_NOTES, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1785 else if ( aPropertyName == SC_UNO_SHOWNOTEAUTHOR )
1786 aNewOpt.SetOption( VOPT_NOTEAUTHOR, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1787 else if ( aPropertyName == SC_UNO_SHOWFORMULASMARKS )
1788 aNewOpt.SetOption( VOPT_FORMULAS_MARKS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1789 else if ( aPropertyName == SC_UNO_SHOWPAGEBR )
1790 aNewOpt.SetOption( VOPT_PAGEBREAKS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1791 else if ( aPropertyName == SC_UNO_SHOWZERO )
1792 aNewOpt.SetOption( VOPT_NULLVALS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1793 else if ( aPropertyName == SC_UNO_VALUEHIGH || aPropertyName == OLD_UNO_VALUEHIGH )
1794 aNewOpt.SetOption( VOPT_SYNTAX, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1795 else if ( aPropertyName == SC_UNO_VERTSCROLL || aPropertyName == OLD_UNO_VERTSCROLL )
1796 aNewOpt.SetOption( VOPT_VSCROLL, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
1797 else if ( aPropertyName == SC_UNO_SHOWOBJ )
1799 sal_Int16 nIntVal = 0;
1800 if ( aValue >>= nIntVal )
1802 //#i80528# adapt to new range eventually
1803 if(sal_Int16(VOBJ_MODE_HIDE) < nIntVal) nIntVal = sal_Int16(VOBJ_MODE_SHOW);
1805 aNewOpt.SetObjMode( VOBJ_TYPE_OLE, static_cast<ScVObjMode>(nIntVal));
1808 else if ( aPropertyName == SC_UNO_SHOWCHARTS )
1810 sal_Int16 nIntVal = 0;
1811 if ( aValue >>= nIntVal )
1813 //#i80528# adapt to new range eventually
1814 if(sal_Int16(VOBJ_MODE_HIDE) < nIntVal) nIntVal = sal_Int16(VOBJ_MODE_SHOW);
1816 aNewOpt.SetObjMode( VOBJ_TYPE_CHART, static_cast<ScVObjMode>(nIntVal));
1819 else if ( aPropertyName == SC_UNO_SHOWDRAW )
1821 sal_Int16 nIntVal = 0;
1822 if ( aValue >>= nIntVal )
1824 //#i80528# adapt to new range eventually
1825 if(sal_Int16(VOBJ_MODE_HIDE) < nIntVal) nIntVal = sal_Int16(VOBJ_MODE_SHOW);
1827 aNewOpt.SetObjMode( VOBJ_TYPE_DRAW, static_cast<ScVObjMode>(nIntVal));
1830 else if ( aPropertyName == SC_UNO_GRIDCOLOR )
1832 Color nIntVal;
1833 if ( aValue >>= nIntVal )
1834 aNewOpt.SetGridColor( nIntVal, OUString() );
1836 else if ( aPropertyName == SC_UNO_ZOOMTYPE )
1838 sal_Int16 nIntVal = 0;
1839 if ( aValue >>= nIntVal )
1840 SetZoomType(nIntVal);
1842 else if ( aPropertyName == SC_UNO_ZOOMVALUE )
1844 sal_Int16 nIntVal = 0;
1845 if ( aValue >>= nIntVal )
1846 SetZoom(nIntVal);
1848 else if ( aPropertyName == SC_UNO_FORMULABARHEIGHT )
1850 sal_Int16 nIntVal = ScUnoHelpFunctions::GetInt16FromAny(aValue);
1851 if (nIntVal > 0)
1853 rViewData.SetFormulaBarLines(nIntVal);
1854 // Notify formula bar about changed lines
1855 ScInputHandler* pInputHdl = ScModule::get()->GetInputHdl();
1856 if (pInputHdl)
1858 ScInputWindow* pInputWin = pInputHdl->GetInputWindow();
1859 if (pInputWin)
1860 pInputWin->NumLinesChanged();
1865 // Options are set on the view and document (for new views),
1866 // so that they remain during saving.
1867 //! In the app (module) we need an extra options to tune that
1868 //! (for new documents)
1870 if ( aNewOpt == rOldOpt )
1871 return;
1873 rViewData.SetOptions( aNewOpt );
1874 rViewData.GetDocument().SetViewOptions( aNewOpt );
1875 rViewData.GetDocShell()->SetDocumentModified(); //! really?
1877 pViewSh->UpdateFixPos();
1878 pViewSh->PaintGrid();
1879 pViewSh->PaintTop();
1880 pViewSh->PaintLeft();
1881 pViewSh->PaintExtras();
1882 pViewSh->InvalidateBorder();
1884 SfxBindings& rBindings = pViewSh->GetViewFrame().GetBindings();
1885 rBindings.Invalidate( FID_TOGGLEHEADERS ); // -> check in menu
1886 rBindings.Invalidate( FID_TOGGLESYNTAX );
1889 uno::Any SAL_CALL ScTabViewObj::getPropertyValue( const OUString& aPropertyName )
1891 SolarMutexGuard aGuard;
1892 uno::Any aRet;
1894 if ( aPropertyName == SC_UNO_FILTERED_RANGE_SELECTION )
1896 aRet <<= bFilteredRangeSelection;
1897 return aRet;
1900 ScTabViewShell* pViewSh = GetViewShell();
1901 if (pViewSh)
1903 ScViewData& rViewData = pViewSh->GetViewData();
1904 const ScViewOptions& rOpt = rViewData.GetOptions();
1906 if ( aPropertyName == SC_UNO_COLROWHDR || aPropertyName == OLD_UNO_COLROWHDR )
1907 aRet <<= rOpt.GetOption( VOPT_HEADER );
1908 else if ( aPropertyName == SC_UNO_HORSCROLL || aPropertyName == OLD_UNO_HORSCROLL )
1909 aRet <<= rOpt.GetOption( VOPT_HSCROLL );
1910 else if ( aPropertyName == SC_UNO_OUTLSYMB || aPropertyName == OLD_UNO_OUTLSYMB )
1911 aRet <<= rOpt.GetOption( VOPT_OUTLINER );
1912 else if ( aPropertyName == SC_UNO_SHEETTABS || aPropertyName == OLD_UNO_SHEETTABS )
1913 aRet <<= rOpt.GetOption( VOPT_TABCONTROLS );
1914 else if ( aPropertyName == SC_UNO_SHOWANCHOR ) aRet <<= rOpt.GetOption( VOPT_ANCHOR );
1915 else if ( aPropertyName == SC_UNO_SHOWFORM ) aRet <<= rOpt.GetOption( VOPT_FORMULAS );
1916 else if ( aPropertyName == SC_UNO_SHOWGRID ) aRet <<= rOpt.GetOption( VOPT_GRID );
1917 else if ( aPropertyName == SC_UNO_SHOWHELP ) aRet <<= rOpt.GetOption( VOPT_HELPLINES );
1918 else if ( aPropertyName == SC_UNO_SHOWNOTES ) aRet <<= rOpt.GetOption( VOPT_NOTES );
1919 else if ( aPropertyName == SC_UNO_SHOWNOTEAUTHOR ) aRet <<= rOpt.GetOption( VOPT_NOTEAUTHOR );
1920 else if ( aPropertyName == SC_UNO_SHOWFORMULASMARKS ) aRet <<= rOpt.GetOption( VOPT_FORMULAS_MARKS );
1921 else if ( aPropertyName == SC_UNO_SHOWPAGEBR ) aRet <<= rOpt.GetOption( VOPT_PAGEBREAKS );
1922 else if ( aPropertyName == SC_UNO_SHOWZERO ) aRet <<= rOpt.GetOption( VOPT_NULLVALS );
1923 else if ( aPropertyName == SC_UNO_VALUEHIGH || aPropertyName == OLD_UNO_VALUEHIGH )
1924 aRet <<= rOpt.GetOption( VOPT_SYNTAX );
1925 else if ( aPropertyName == SC_UNO_VERTSCROLL || aPropertyName == OLD_UNO_VERTSCROLL )
1926 aRet <<= rOpt.GetOption( VOPT_VSCROLL );
1927 else if ( aPropertyName == SC_UNO_SHOWOBJ ) aRet <<= static_cast<sal_Int16>( rOpt.GetObjMode( VOBJ_TYPE_OLE ) );
1928 else if ( aPropertyName == SC_UNO_SHOWCHARTS ) aRet <<= static_cast<sal_Int16>( rOpt.GetObjMode( VOBJ_TYPE_CHART ) );
1929 else if ( aPropertyName == SC_UNO_SHOWDRAW ) aRet <<= static_cast<sal_Int16>( rOpt.GetObjMode( VOBJ_TYPE_DRAW ) );
1930 else if ( aPropertyName == SC_UNO_GRIDCOLOR ) aRet <<= rOpt.GetGridColor();
1931 else if ( aPropertyName == SC_UNO_VISAREA ) aRet <<= GetVisArea();
1932 else if ( aPropertyName == SC_UNO_ZOOMTYPE ) aRet <<= GetZoomType();
1933 else if ( aPropertyName == SC_UNO_ZOOMVALUE ) aRet <<= GetZoom();
1934 else if ( aPropertyName == SC_UNO_FORMULABARHEIGHT ) aRet <<= rViewData.GetFormulaBarLines();
1935 else if ( aPropertyName == SC_UNO_VISAREASCREEN )
1937 vcl::Window* pActiveWin = rViewData.GetActiveWin();
1938 if ( pActiveWin )
1940 AbsoluteScreenPixelRectangle aRect = pActiveWin->GetWindowExtentsAbsolute();
1941 aRet <<= vcl::unohelper::ConvertToAWTRect(aRect);
1946 return aRet;
1949 void SAL_CALL ScTabViewObj::addPropertyChangeListener( const OUString& /* aPropertyName */,
1950 const uno::Reference<beans::XPropertyChangeListener >& xListener )
1952 SolarMutexGuard aGuard;
1953 aPropertyChgListeners.push_back( xListener );
1956 void SAL_CALL ScTabViewObj::removePropertyChangeListener( const OUString& /* aPropertyName */,
1957 const uno::Reference<beans::XPropertyChangeListener >& xListener )
1959 SolarMutexGuard aGuard;
1960 auto it = std::find(aPropertyChgListeners.begin(), aPropertyChgListeners.end(), xListener); //! Why the nonsense with queryInterface?
1961 if (it != aPropertyChgListeners.end())
1962 aPropertyChgListeners.erase(it);
1965 void SAL_CALL ScTabViewObj::addVetoableChangeListener( const OUString& /* PropertyName */,
1966 const uno::Reference<beans::XVetoableChangeListener >& /* aListener */ )
1970 void SAL_CALL ScTabViewObj::removeVetoableChangeListener( const OUString& /* PropertyName */,
1971 const uno::Reference<beans::XVetoableChangeListener >& /* aListener */ )
1975 void ScTabViewObj::VisAreaChanged()
1977 beans::PropertyChangeEvent aEvent;
1978 aEvent.Source.set(getXWeak());
1979 for (const auto& rListener : aPropertyChgListeners)
1980 rListener->propertyChange( aEvent );
1983 // XRangeSelection
1985 void SAL_CALL ScTabViewObj::startRangeSelection(
1986 const uno::Sequence<beans::PropertyValue>& aArguments )
1988 SolarMutexGuard aGuard;
1989 ScTabViewShell* pViewSh = GetViewShell();
1990 if (!pViewSh)
1991 return;
1993 OUString aInitVal, aTitle;
1994 bool bCloseOnButtonUp = false;
1995 bool bSingleCell = false;
1996 bool bMultiSelection = false;
1998 OUString aStrVal;
1999 for (const beans::PropertyValue& rProp : aArguments)
2001 OUString aPropName(rProp.Name);
2003 if (aPropName == SC_UNONAME_CLOSEONUP )
2004 bCloseOnButtonUp = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
2005 else if (aPropName == SC_UNONAME_TITLE )
2007 if ( rProp.Value >>= aStrVal )
2008 aTitle = aStrVal;
2010 else if (aPropName == SC_UNONAME_INITVAL )
2012 if ( rProp.Value >>= aStrVal )
2013 aInitVal = aStrVal;
2015 else if (aPropName == SC_UNONAME_SINGLECELL )
2016 bSingleCell = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
2017 else if (aPropName == SC_UNONAME_MULTISEL )
2018 bMultiSelection = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
2021 pViewSh->StartSimpleRefDialog( aTitle, aInitVal, bCloseOnButtonUp, bSingleCell, bMultiSelection );
2024 void SAL_CALL ScTabViewObj::abortRangeSelection()
2026 SolarMutexGuard aGuard;
2027 ScTabViewShell* pViewSh = GetViewShell();
2028 if (pViewSh)
2029 pViewSh->StopSimpleRefDialog();
2032 void SAL_CALL ScTabViewObj::addRangeSelectionListener(
2033 const uno::Reference<sheet::XRangeSelectionListener>& xListener )
2035 SolarMutexGuard aGuard;
2036 aRangeSelListeners.push_back( xListener );
2039 void SAL_CALL ScTabViewObj::removeRangeSelectionListener(
2040 const uno::Reference<sheet::XRangeSelectionListener>& xListener )
2042 SolarMutexGuard aGuard;
2043 auto it = std::find(aRangeSelListeners.begin(), aRangeSelListeners.end(), xListener);
2044 if (it != aRangeSelListeners.end())
2045 aRangeSelListeners.erase(it);
2048 void SAL_CALL ScTabViewObj::addRangeSelectionChangeListener(
2049 const uno::Reference<sheet::XRangeSelectionChangeListener>& xListener )
2051 SolarMutexGuard aGuard;
2052 aRangeChgListeners.push_back( xListener );
2055 void SAL_CALL ScTabViewObj::removeRangeSelectionChangeListener(
2056 const uno::Reference<sheet::XRangeSelectionChangeListener>& xListener )
2058 SolarMutexGuard aGuard;
2059 auto it = std::find(aRangeChgListeners.begin(), aRangeChgListeners.end(), xListener);
2060 if (it != aRangeChgListeners.end())
2061 aRangeChgListeners.erase(it);
2064 void ScTabViewObj::RangeSelDone( const OUString& rText )
2066 sheet::RangeSelectionEvent aEvent;
2067 aEvent.Source.set(getXWeak());
2068 aEvent.RangeDescriptor = rText;
2070 // copy on the stack because listener could remove itself
2071 const RangeSelListeners listeners(aRangeSelListeners);
2073 for (const auto& rListener : listeners)
2074 rListener->done( aEvent );
2077 void ScTabViewObj::RangeSelAborted( const OUString& rText )
2079 sheet::RangeSelectionEvent aEvent;
2080 aEvent.Source.set(getXWeak());
2081 aEvent.RangeDescriptor = rText;
2083 // copy on the stack because listener could remove itself
2084 const RangeSelListeners listeners(aRangeSelListeners);
2086 for (const auto& rListener : listeners)
2087 rListener->aborted( aEvent );
2090 void ScTabViewObj::RangeSelChanged( const OUString& rText )
2092 sheet::RangeSelectionEvent aEvent;
2093 aEvent.Source.set(getXWeak());
2094 aEvent.RangeDescriptor = rText;
2096 // copy on the stack because listener could remove itself
2097 const std::vector<css::uno::Reference<css::sheet::XRangeSelectionChangeListener>> listener(aRangeChgListeners);
2098 for (const auto& rListener : listener)
2099 rListener->descriptorChanged( aEvent );
2102 // XServiceInfo
2103 OUString SAL_CALL ScTabViewObj::getImplementationName()
2105 return u"ScTabViewObj"_ustr;
2108 sal_Bool SAL_CALL ScTabViewObj::supportsService( const OUString& rServiceName )
2110 return cppu::supportsService(this, rServiceName);
2113 uno::Sequence<OUString> SAL_CALL ScTabViewObj::getSupportedServiceNames()
2115 return {SCTABVIEWOBJ_SERVICE, SCVIEWSETTINGS_SERVICE};
2118 // XUnoTunnel
2120 css::uno::Reference< css::datatransfer::XTransferable > SAL_CALL ScTabViewObj::getTransferable()
2122 SolarMutexGuard aGuard;
2123 ScEditShell* pShell = dynamic_cast<ScEditShell*>( GetViewShell()->GetViewFrame().GetDispatcher()->GetShell(0) );
2124 if (pShell)
2125 return pShell->GetEditView()->GetTransferable();
2127 ScDrawTextObjectBar* pTextShell = dynamic_cast<ScDrawTextObjectBar*>( GetViewShell()->GetViewFrame().GetDispatcher()->GetShell(0) );
2128 if (pTextShell)
2130 ScViewData& rViewData = GetViewShell()->GetViewData();
2131 ScDrawView* pView = rViewData.GetScDrawView();
2132 OutlinerView* pOutView = pView->GetTextEditOutlinerView();
2133 if (pOutView)
2134 return pOutView->GetEditView().GetTransferable();
2137 ScDrawShell* pDrawShell = dynamic_cast<ScDrawShell*>( GetViewShell()->GetViewFrame().GetDispatcher()->GetShell(0) );
2138 if (pDrawShell)
2139 return pDrawShell->GetDrawView()->CopyToTransferable();
2141 return GetViewShell()->CopyToTransferable();
2144 void SAL_CALL ScTabViewObj::insertTransferable( const css::uno::Reference< css::datatransfer::XTransferable >& xTrans )
2146 SolarMutexGuard aGuard;
2147 ScEditShell* pShell = dynamic_cast<ScEditShell*>( GetViewShell()->GetViewFrame().GetDispatcher()->GetShell(0) );
2148 if (pShell)
2149 pShell->GetEditView()->InsertText( xTrans, OUString(), false );
2150 else
2152 ScDrawTextObjectBar* pTextShell = dynamic_cast<ScDrawTextObjectBar*>( GetViewShell()->GetViewFrame().GetDispatcher()->GetShell(0) );
2153 if (pTextShell)
2155 ScViewData& rViewData = GetViewShell()->GetViewData();
2156 ScDrawView* pView = rViewData.GetScDrawView();
2157 OutlinerView* pOutView = pView->GetTextEditOutlinerView();
2158 if ( pOutView )
2160 pOutView->GetEditView().InsertText( xTrans, OUString(), false );
2161 return;
2165 GetViewShell()->PasteFromTransferable( xTrans );
2169 namespace {
2171 uno::Sequence<sal_Int32> toSequence(const ScMarkData::MarkedTabsType& rSelected)
2173 uno::Sequence<sal_Int32> aRet(rSelected.size());
2174 auto aRetRange = asNonConstRange(aRet);
2175 size_t i = 0;
2176 for (const auto& rTab : rSelected)
2178 aRetRange[i] = static_cast<sal_Int32>(rTab);
2179 ++i;
2182 return aRet;
2187 uno::Sequence<sal_Int32> ScTabViewObj::getSelectedSheets()
2189 ScTabViewShell* pViewSh = GetViewShell();
2190 if (!pViewSh)
2191 return uno::Sequence<sal_Int32>();
2193 ScViewData& rViewData = pViewSh->GetViewData();
2195 // #i95280# when printing from the shell, the view is never activated,
2196 // so Excel view settings must also be evaluated here.
2197 ScExtDocOptions* pExtOpt = rViewData.GetDocument().GetExtDocOptions();
2198 if (pExtOpt && pExtOpt->IsChanged())
2200 pViewSh->GetViewData().ReadExtOptions(*pExtOpt); // Excel view settings
2201 pViewSh->SetTabNo(pViewSh->GetViewData().GetTabNo(), true);
2202 pExtOpt->SetChanged(false);
2205 return toSequence(rViewData.GetMarkData().GetSelectedTabs());
2208 ScPreviewObj::ScPreviewObj(ScPreviewShell* pViewSh) :
2209 SfxBaseController(pViewSh),
2210 mpViewShell(pViewSh)
2212 if (mpViewShell)
2213 StartListening(*mpViewShell);
2216 ScPreviewObj::~ScPreviewObj()
2218 if (mpViewShell)
2219 EndListening(*mpViewShell);
2222 uno::Any ScPreviewObj::queryInterface(const uno::Type& rType)
2224 uno::Any aReturn = ::cppu::queryInterface(rType,
2225 static_cast<sheet::XSelectedSheetsSupplier*>(this));
2226 if ( aReturn.hasValue() )
2227 return aReturn;
2228 return SfxBaseController::queryInterface(rType);
2231 void ScPreviewObj::acquire() noexcept
2233 SfxBaseController::acquire();
2236 void ScPreviewObj::release() noexcept
2238 SfxBaseController::release();
2241 void ScPreviewObj::Notify(SfxBroadcaster&, const SfxHint& rHint)
2243 if (rHint.GetId() == SfxHintId::Dying)
2244 mpViewShell = nullptr;
2247 uno::Sequence<sal_Int32> ScPreviewObj::getSelectedSheets()
2249 ScPreview* p = mpViewShell ? mpViewShell->GetPreview() : nullptr;
2250 if (!p)
2251 return uno::Sequence<sal_Int32>();
2253 return toSequence(p->GetSelectedTabs());
2256 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */