summaryrefslogtreecommitdiffstats
path: root/sc/source/ui/unoobj/viewuno.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/unoobj/viewuno.cxx')
-rw-r--r--sc/source/ui/unoobj/viewuno.cxx2204
1 files changed, 2204 insertions, 0 deletions
diff --git a/sc/source/ui/unoobj/viewuno.cxx b/sc/source/ui/unoobj/viewuno.cxx
new file mode 100644
index 000000000..d50a833cf
--- /dev/null
+++ b/sc/source/ui/unoobj/viewuno.cxx
@@ -0,0 +1,2204 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/awt/MouseButton.hpp>
+#include <com/sun/star/drawing/ShapeCollection.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/script/vba/XVBAEventProcessor.hpp>
+#include <com/sun/star/util/VetoException.hpp>
+#include <com/sun/star/view/DocumentZoomType.hpp>
+
+#include <editeng/outliner.hxx>
+#include <svx/svditer.hxx>
+#include <svx/svdmark.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdview.hxx>
+#include <svx/unoshape.hxx>
+#include <svx/fmshell.hxx>
+#include <sfx2/bindings.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/request.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <comphelper/profilezone.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <toolkit/helper/convert.hxx>
+#include <vcl/svapp.hxx>
+
+#include <drawsh.hxx>
+#include <drtxtob.hxx>
+#include <transobj.hxx>
+#include <editsh.hxx>
+#include <viewuno.hxx>
+#include <cellsuno.hxx>
+#include <miscuno.hxx>
+#include <tabvwsh.hxx>
+#include <prevwsh.hxx>
+#include <docsh.hxx>
+#include <drwlayer.hxx>
+#include <drawview.hxx>
+#include <fupoor.hxx>
+#include <sc.hrc>
+#include <unonames.hxx>
+#include <scmod.hxx>
+#include <appoptio.hxx>
+#include <gridwin.hxx>
+#include <sheetevents.hxx>
+#include <markdata.hxx>
+#include <scextopt.hxx>
+#include <preview.hxx>
+#include <inputhdl.hxx>
+#include <inputwin.hxx>
+#include <svx/sdrhittesthelper.hxx>
+#include <formatsh.hxx>
+#include <sfx2/app.hxx>
+
+using namespace com::sun::star;
+
+//! Clipping Marks
+
+// no Which-ID here, Map only for PropertySetInfo
+
+static const SfxItemPropertyMapEntry* lcl_GetViewOptPropertyMap()
+{
+ static const SfxItemPropertyMapEntry aViewOptPropertyMap_Impl[] =
+ {
+ { OLD_UNO_COLROWHDR, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { SC_UNO_GRIDCOLOR, 0, cppu::UnoType<sal_Int32>::get(), 0, 0},
+ { SC_UNO_COLROWHDR, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { SC_UNO_HORSCROLL, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { SC_UNO_SHEETTABS, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { SC_UNO_VERTSCROLL, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { SC_UNO_HIDESPELL, 0, cppu::UnoType<bool>::get(), 0, 0}, /* deprecated #i91949 */
+ { OLD_UNO_HORSCROLL, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { SC_UNO_OUTLSYMB, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { SC_UNO_VALUEHIGH, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { OLD_UNO_OUTLSYMB, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { OLD_UNO_SHEETTABS, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { SC_UNO_SHOWANCHOR, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { SC_UNO_SHOWCHARTS, 0, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { SC_UNO_SHOWDRAW, 0, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { SC_UNO_SHOWFORM, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { SC_UNO_SHOWGRID, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { SC_UNO_SHOWHELP, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { SC_UNO_SHOWNOTES, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { SC_UNO_SHOWOBJ, 0, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { SC_UNO_SHOWPAGEBR, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { SC_UNO_SHOWZERO, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { OLD_UNO_VALUEHIGH, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { OLD_UNO_VERTSCROLL, 0, cppu::UnoType<bool>::get(), 0, 0},
+ { SC_UNO_VISAREA, 0, cppu::UnoType<awt::Rectangle>::get(), 0, 0},
+ { SC_UNO_ZOOMTYPE, 0, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { SC_UNO_ZOOMVALUE, 0, cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { SC_UNO_VISAREASCREEN,0, cppu::UnoType<awt::Rectangle>::get(), 0, 0},
+ { SC_UNO_FORMULABARHEIGHT,0,cppu::UnoType<sal_Int16>::get(), 0, 0},
+ { u"", 0, css::uno::Type(), 0, 0 }
+ };
+ return aViewOptPropertyMap_Impl;
+}
+
+constexpr OUStringLiteral SCTABVIEWOBJ_SERVICE = u"com.sun.star.sheet.SpreadsheetView";
+constexpr OUStringLiteral SCVIEWSETTINGS_SERVICE = u"com.sun.star.sheet.SpreadsheetViewSettings";
+
+SC_SIMPLE_SERVICE_INFO( ScViewPaneBase, "ScViewPaneObj", "com.sun.star.sheet.SpreadsheetViewPane" )
+
+ScViewPaneBase::ScViewPaneBase(ScTabViewShell* pViewSh, sal_uInt16 nP) :
+ pViewShell( pViewSh ),
+ nPane( nP )
+{
+ if (pViewShell)
+ StartListening(*pViewShell);
+}
+
+ScViewPaneBase::~ScViewPaneBase()
+{
+ SolarMutexGuard g;
+
+ if (pViewShell)
+ EndListening(*pViewShell);
+}
+
+void ScViewPaneBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.GetId() == SfxHintId::Dying )
+ pViewShell = nullptr;
+}
+
+uno::Any SAL_CALL ScViewPaneBase::queryInterface( const uno::Type& rType )
+{
+ SC_QUERYINTERFACE( sheet::XViewPane )
+ SC_QUERYINTERFACE( sheet::XCellRangeReferrer )
+ SC_QUERYINTERFACE( view::XFormLayerAccess )
+ SC_QUERYINTERFACE( view::XControlAccess )
+ SC_QUERYINTERFACE( lang::XServiceInfo )
+ SC_QUERYINTERFACE( lang::XTypeProvider )
+
+ return uno::Any(); // OWeakObject is in derived objects
+}
+
+uno::Sequence<uno::Type> SAL_CALL ScViewPaneBase::getTypes()
+{
+ static const uno::Sequence<uno::Type> aTypes
+ {
+ cppu::UnoType<sheet::XViewPane>::get(),
+ cppu::UnoType<sheet::XCellRangeReferrer>::get(),
+ cppu::UnoType<view::XFormLayerAccess>::get(),
+ cppu::UnoType<lang::XServiceInfo>::get(),
+ cppu::UnoType<lang::XTypeProvider>::get(),
+ };
+ return aTypes;
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScViewPaneBase::getImplementationId()
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+// XViewPane
+
+sal_Int32 SAL_CALL ScViewPaneBase::getFirstVisibleColumn()
+{
+ SolarMutexGuard aGuard;
+ if (pViewShell)
+ {
+ ScViewData& rViewData = pViewShell->GetViewData();
+ ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
+ rViewData.GetActivePart() :
+ static_cast<ScSplitPos>(nPane);
+ ScHSplitPos eWhichH = WhichH( eWhich );
+
+ return rViewData.GetPosX( eWhichH );
+ }
+ OSL_FAIL("no View ?!?"); //! Exception?
+ return 0;
+}
+
+void SAL_CALL ScViewPaneBase::setFirstVisibleColumn(sal_Int32 nFirstVisibleColumn)
+{
+ SolarMutexGuard aGuard;
+ if (pViewShell)
+ {
+ ScViewData& rViewData = pViewShell->GetViewData();
+ ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
+ rViewData.GetActivePart() :
+ static_cast<ScSplitPos>(nPane);
+ ScHSplitPos eWhichH = WhichH( eWhich );
+
+ tools::Long nDeltaX = static_cast<tools::Long>(nFirstVisibleColumn) - rViewData.GetPosX( eWhichH );
+ pViewShell->ScrollX( nDeltaX, eWhichH );
+ }
+}
+
+sal_Int32 SAL_CALL ScViewPaneBase::getFirstVisibleRow()
+{
+ SolarMutexGuard aGuard;
+ if (pViewShell)
+ {
+ ScViewData& rViewData = pViewShell->GetViewData();
+ ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
+ rViewData.GetActivePart() :
+ static_cast<ScSplitPos>(nPane);
+ ScVSplitPos eWhichV = WhichV( eWhich );
+
+ return rViewData.GetPosY( eWhichV );
+ }
+ OSL_FAIL("no View ?!?"); //! Exception?
+ return 0;
+}
+
+void SAL_CALL ScViewPaneBase::setFirstVisibleRow( sal_Int32 nFirstVisibleRow )
+{
+ SolarMutexGuard aGuard;
+ if (pViewShell)
+ {
+ ScViewData& rViewData = pViewShell->GetViewData();
+ ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
+ rViewData.GetActivePart() :
+ static_cast<ScSplitPos>(nPane);
+ ScVSplitPos eWhichV = WhichV( eWhich );
+
+ tools::Long nDeltaY = static_cast<tools::Long>(nFirstVisibleRow) - rViewData.GetPosY( eWhichV );
+ pViewShell->ScrollY( nDeltaY, eWhichV );
+ }
+}
+
+table::CellRangeAddress SAL_CALL ScViewPaneBase::getVisibleRange()
+{
+ SolarMutexGuard aGuard;
+ table::CellRangeAddress aAdr;
+ if (pViewShell)
+ {
+ ScViewData& rViewData = pViewShell->GetViewData();
+ ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
+ rViewData.GetActivePart() :
+ static_cast<ScSplitPos>(nPane);
+ ScHSplitPos eWhichH = WhichH( eWhich );
+ ScVSplitPos eWhichV = WhichV( eWhich );
+
+ // VisibleCellsX returns only completely visible cells
+ // VisibleRange in Excel also partially visible ones
+ //! do the same ???
+
+ SCCOL nVisX = rViewData.VisibleCellsX( eWhichH );
+ SCROW nVisY = rViewData.VisibleCellsY( eWhichV );
+ if (!nVisX) nVisX = 1; // there has to be something in the range
+ if (!nVisY) nVisY = 1;
+ aAdr.Sheet = rViewData.GetTabNo();
+ aAdr.StartColumn = rViewData.GetPosX( eWhichH );
+ aAdr.StartRow = rViewData.GetPosY( eWhichV );
+ aAdr.EndColumn = aAdr.StartColumn + nVisX - 1;
+ aAdr.EndRow = aAdr.StartRow + nVisY - 1;
+ }
+ return aAdr;
+}
+
+// XCellRangeSource
+
+uno::Reference<table::XCellRange> SAL_CALL ScViewPaneBase::getReferredCells()
+{
+ SolarMutexGuard aGuard;
+ if (pViewShell)
+ {
+ ScDocShell* pDocSh = pViewShell->GetViewData().GetDocShell();
+
+ table::CellRangeAddress aAdr(getVisibleRange()); //! helper function with ScRange?
+ ScRange aRange( static_cast<SCCOL>(aAdr.StartColumn), static_cast<SCROW>(aAdr.StartRow), aAdr.Sheet,
+ static_cast<SCCOL>(aAdr.EndColumn), static_cast<SCROW>(aAdr.EndRow), aAdr.Sheet );
+ if ( aRange.aStart == aRange.aEnd )
+ return new ScCellObj( pDocSh, aRange.aStart );
+ else
+ return new ScCellRangeObj( pDocSh, aRange );
+ }
+
+ return nullptr;
+}
+
+namespace
+{
+ bool lcl_prepareFormShellCall( ScTabViewShell* _pViewShell, sal_uInt16 _nPane, FmFormShell*& _rpFormShell, vcl::Window*& _rpWindow, SdrView*& _rpSdrView )
+ {
+ if ( !_pViewShell )
+ return false;
+
+ ScViewData& rViewData = _pViewShell->GetViewData();
+ ScSplitPos eWhich = ( _nPane == SC_VIEWPANE_ACTIVE ) ?
+ rViewData.GetActivePart() :
+ static_cast<ScSplitPos>(_nPane);
+ _rpWindow = _pViewShell->GetWindowByPos( eWhich );
+ _rpSdrView = _pViewShell->GetScDrawView();
+ _rpFormShell = _pViewShell->GetFormShell();
+ return ( _rpFormShell != nullptr ) && ( _rpSdrView != nullptr )&& ( _rpWindow != nullptr );
+ }
+}
+
+// XFormLayerAccess
+uno::Reference< form::runtime::XFormController > SAL_CALL ScViewPaneBase::getFormController( const uno::Reference< form::XForm >& Form )
+{
+ SolarMutexGuard aGuard;
+
+ uno::Reference< form::runtime::XFormController > xController;
+
+ vcl::Window* pWindow( nullptr );
+ SdrView* pSdrView( nullptr );
+ FmFormShell* pFormShell( nullptr );
+ if ( lcl_prepareFormShellCall( pViewShell, nPane, pFormShell, pWindow, pSdrView ) )
+ xController = FmFormShell::GetFormController( Form, *pSdrView, *pWindow->GetOutDev() );
+
+ return xController;
+}
+
+sal_Bool SAL_CALL ScViewPaneBase::isFormDesignMode( )
+{
+ SolarMutexGuard aGuard;
+
+ bool bIsFormDesignMode( true );
+
+ FmFormShell* pFormShell( pViewShell ? pViewShell->GetFormShell() : nullptr );
+ if ( pFormShell )
+ bIsFormDesignMode = pFormShell->IsDesignMode();
+
+ return bIsFormDesignMode;
+}
+
+void SAL_CALL ScViewPaneBase::setFormDesignMode( sal_Bool DesignMode )
+{
+ SolarMutexGuard aGuard;
+
+ vcl::Window* pWindow( nullptr );
+ SdrView* pSdrView( nullptr );
+ FmFormShell* pFormShell( nullptr );
+ if ( lcl_prepareFormShellCall( pViewShell, nPane, pFormShell, pWindow, pSdrView ) )
+ pFormShell->SetDesignMode( DesignMode );
+}
+
+// XControlAccess
+
+uno::Reference<awt::XControl> SAL_CALL ScViewPaneBase::getControl(
+ const uno::Reference<awt::XControlModel>& xModel )
+{
+ SolarMutexGuard aGuard;
+
+ uno::Reference<awt::XControl> xRet;
+
+ vcl::Window* pWindow( nullptr );
+ SdrView* pSdrView( nullptr );
+ FmFormShell* pFormShell( nullptr );
+ if ( lcl_prepareFormShellCall( pViewShell, nPane, pFormShell, pWindow, pSdrView ) )
+ pFormShell->GetFormControl( xModel, *pSdrView, *pWindow->GetOutDev(), xRet );
+
+ if ( !xRet.is() )
+ throw container::NoSuchElementException(); // no control found
+
+ return xRet;
+}
+
+awt::Rectangle ScViewPaneBase::GetVisArea() const
+{
+ awt::Rectangle aVisArea;
+ if (pViewShell)
+ {
+ ScSplitPos eWhich = ( nPane == SC_VIEWPANE_ACTIVE ) ?
+ pViewShell->GetViewData().GetActivePart() :
+ static_cast<ScSplitPos>(nPane);
+ ScGridWindow* pWindow = static_cast<ScGridWindow*>(pViewShell->GetWindowByPos(eWhich));
+ ScDocument& rDoc = pViewShell->GetViewData().GetDocument();
+ if (pWindow)
+ {
+ ScHSplitPos eWhichH = ((eWhich == SC_SPLIT_TOPLEFT) || (eWhich == SC_SPLIT_BOTTOMLEFT)) ?
+ SC_SPLIT_LEFT : SC_SPLIT_RIGHT;
+ ScVSplitPos eWhichV = ((eWhich == SC_SPLIT_TOPLEFT) || (eWhich == SC_SPLIT_TOPRIGHT)) ?
+ SC_SPLIT_TOP : SC_SPLIT_BOTTOM;
+ ScAddress aCell(pViewShell->GetViewData().GetPosX(eWhichH),
+ pViewShell->GetViewData().GetPosY(eWhichV),
+ pViewShell->GetViewData().GetTabNo());
+ tools::Rectangle aCellRect( rDoc.GetMMRect( aCell.Col(), aCell.Row(), aCell.Col(), aCell.Row(), aCell.Tab() ) );
+ Size aVisSize( pWindow->PixelToLogic( pWindow->GetSizePixel(), pWindow->GetDrawMapMode( true ) ) );
+ Point aVisPos( aCellRect.TopLeft() );
+ if ( rDoc.IsLayoutRTL( aCell.Tab() ) )
+ {
+ aVisPos = aCellRect.TopRight();
+ aVisPos.AdjustX( -(aVisSize.Width()) );
+ }
+ tools::Rectangle aVisRect( aVisPos, aVisSize );
+ aVisArea = AWTRectangle(aVisRect);
+ }
+ }
+ return aVisArea;
+}
+
+ScViewPaneObj::ScViewPaneObj(ScTabViewShell* pViewSh, sal_uInt16 nP) :
+ ScViewPaneBase( pViewSh, nP )
+{
+}
+
+ScViewPaneObj::~ScViewPaneObj()
+{
+}
+
+uno::Any SAL_CALL ScViewPaneObj::queryInterface( const uno::Type& rType )
+{
+ // ScViewPaneBase has everything except OWeakObject
+
+ uno::Any aRet(ScViewPaneBase::queryInterface( rType ));
+ if (!aRet.hasValue())
+ aRet = OWeakObject::queryInterface( rType );
+ return aRet;
+}
+
+void SAL_CALL ScViewPaneObj::acquire() noexcept
+{
+ OWeakObject::acquire();
+}
+
+void SAL_CALL ScViewPaneObj::release() noexcept
+{
+ OWeakObject::release();
+}
+
+// We need default ctor for SMART_REFLECTION_IMPLEMENTATION
+
+ScTabViewObj::ScTabViewObj( ScTabViewShell* pViewSh ) :
+ ScViewPaneBase( pViewSh, SC_VIEWPANE_ACTIVE ),
+ SfxBaseController( pViewSh ),
+ aPropSet( lcl_GetViewOptPropertyMap() ),
+ aMouseClickHandlers( 0 ),
+ aActivationListeners( 0 ),
+ nPreviousTab( 0 ),
+ bDrawSelModeSet(false),
+ bFilteredRangeSelection(false),
+ mbLeftMousePressed(false)
+{
+ if (pViewSh)
+ nPreviousTab = pViewSh->GetViewData().GetTabNo();
+}
+
+ScTabViewObj::~ScTabViewObj()
+{
+ //! Listening or something along that line
+ if (!aMouseClickHandlers.empty())
+ {
+ acquire();
+ EndMouseListening();
+ }
+ if (!aActivationListeners.empty())
+ {
+ acquire();
+ EndActivationListening();
+ }
+}
+
+uno::Any SAL_CALL ScTabViewObj::queryInterface( const uno::Type& rType )
+{
+ SC_QUERYINTERFACE( sheet::XSpreadsheetView )
+ SC_QUERYINTERFACE( sheet::XEnhancedMouseClickBroadcaster )
+ SC_QUERYINTERFACE( sheet::XActivationBroadcaster )
+ SC_QUERYINTERFACE( container::XEnumerationAccess )
+ SC_QUERYINTERFACE( container::XIndexAccess )
+ SC_QUERY_MULTIPLE( container::XElementAccess, container::XIndexAccess )
+ SC_QUERYINTERFACE( view::XSelectionSupplier )
+ SC_QUERYINTERFACE( beans::XPropertySet )
+ SC_QUERYINTERFACE( sheet::XViewSplitable )
+ SC_QUERYINTERFACE( sheet::XViewFreezable )
+ SC_QUERYINTERFACE( sheet::XRangeSelection )
+ SC_QUERYINTERFACE( lang::XUnoTunnel )
+ SC_QUERYINTERFACE( datatransfer::XTransferableSupplier )
+ SC_QUERYINTERFACE( sheet::XSelectedSheetsSupplier )
+
+ uno::Any aRet(ScViewPaneBase::queryInterface( rType ));
+ if (!aRet.hasValue())
+ aRet = SfxBaseController::queryInterface( rType );
+ return aRet;
+}
+
+void SAL_CALL ScTabViewObj::acquire() noexcept
+{
+ SfxBaseController::acquire();
+}
+
+void SAL_CALL ScTabViewObj::release() noexcept
+{
+ SfxBaseController::release();
+}
+
+static void lcl_CallActivate( ScDocShell* pDocSh, SCTAB nTab, ScSheetEventId nEvent )
+{
+ ScDocument& rDoc = pDocSh->GetDocument();
+ // when deleting a sheet, nPreviousTab can be invalid
+ // (could be handled with reference updates)
+ if (!rDoc.HasTable(nTab))
+ return;
+
+ const ScSheetEvents* pEvents = rDoc.GetSheetEvents(nTab);
+ if (pEvents)
+ {
+ const OUString* pScript = pEvents->GetScript(nEvent);
+ if (pScript)
+ {
+ uno::Any aRet;
+ uno::Sequence<uno::Any> aParams;
+ uno::Sequence<sal_Int16> aOutArgsIndex;
+ uno::Sequence<uno::Any> aOutArgs;
+ /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
+ }
+ }
+
+ // execute VBA event handlers
+ try
+ {
+ uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( rDoc.GetVbaEventProcessor(), uno::UNO_SET_THROW );
+ // the parameter is the clicked object, as in the mousePressed call above
+ uno::Sequence< uno::Any > aArgs{ uno::Any(nTab) };
+ xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( nEvent ), aArgs );
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+void ScTabViewObj::SheetChanged( bool bSameTabButMoved )
+{
+ if ( !GetViewShell() )
+ return;
+
+ ScViewData& rViewData = GetViewShell()->GetViewData();
+ ScDocShell* pDocSh = rViewData.GetDocShell();
+ if (!aActivationListeners.empty())
+ {
+ sheet::ActivationEvent aEvent;
+ uno::Reference< sheet::XSpreadsheetView > xView(this);
+ uno::Reference< uno::XInterface > xSource(xView, uno::UNO_QUERY);
+ aEvent.Source = xSource;
+ aEvent.ActiveSheet = new ScTableSheetObj(pDocSh, rViewData.GetTabNo());
+ // Listener's handler may remove it from the listeners list
+ for (size_t i = aActivationListeners.size(); i > 0; --i)
+ {
+ try
+ {
+ aActivationListeners[i - 1]->activeSpreadsheetChanged( aEvent );
+ }
+ catch( uno::Exception& )
+ {
+ aActivationListeners.erase(aActivationListeners.begin() + (i - 1));
+ }
+ }
+ }
+
+ /* Handle sheet events, but do not trigger event handlers, if the old
+ active sheet gets re-activated after inserting/deleting/moving a sheet. */
+ SCTAB nNewTab = rViewData.GetTabNo();
+ if ( !bSameTabButMoved && (nNewTab != nPreviousTab) )
+ {
+ lcl_CallActivate( pDocSh, nPreviousTab, ScSheetEventId::UNFOCUS );
+ lcl_CallActivate( pDocSh, nNewTab, ScSheetEventId::FOCUS );
+ }
+ nPreviousTab = nNewTab;
+}
+
+uno::Sequence<uno::Type> SAL_CALL ScTabViewObj::getTypes()
+{
+ return comphelper::concatSequences(
+ ScViewPaneBase::getTypes(),
+ SfxBaseController::getTypes(),
+ uno::Sequence<uno::Type>
+ {
+ cppu::UnoType<sheet::XSpreadsheetView>::get(),
+ cppu::UnoType<container::XEnumerationAccess>::get(),
+ cppu::UnoType<container::XIndexAccess>::get(),
+ cppu::UnoType<view::XSelectionSupplier>::get(),
+ cppu::UnoType<beans::XPropertySet>::get(),
+ cppu::UnoType<sheet::XViewSplitable>::get(),
+ cppu::UnoType<sheet::XViewFreezable>::get(),
+ cppu::UnoType<sheet::XRangeSelection>::get(),
+ cppu::UnoType<lang::XUnoTunnel>::get(),
+ cppu::UnoType<sheet::XEnhancedMouseClickBroadcaster>::get(),
+ cppu::UnoType<sheet::XActivationBroadcaster>::get(),
+ cppu::UnoType<datatransfer::XTransferableSupplier>::get()
+ } );
+}
+
+uno::Sequence<sal_Int8> SAL_CALL ScTabViewObj::getImplementationId()
+{
+ return css::uno::Sequence<sal_Int8>();
+}
+
+// XDocumentView
+
+static bool lcl_TabInRanges( SCTAB nTab, const ScRangeList& rRanges )
+{
+ for (size_t i = 0, nCount = rRanges.size(); i < nCount; ++i)
+ {
+ const ScRange & rRange = rRanges[ i ];
+ if ( nTab >= rRange.aStart.Tab() && nTab <= rRange.aEnd.Tab() )
+ return true;
+ }
+ return false;
+}
+
+static void lcl_ShowObject( ScTabViewShell& rViewSh, const ScDrawView& rDrawView, const SdrObject* pSelObj )
+{
+ bool bFound = false;
+ SCTAB nObjectTab = 0;
+
+ SdrModel* pModel = rDrawView.GetModel();
+ sal_uInt16 nPageCount = pModel->GetPageCount();
+ for (sal_uInt16 i=0; i<nPageCount && !bFound; i++)
+ {
+ SdrPage* pPage = pModel->GetPage(i);
+ if (pPage)
+ {
+ SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups );
+ SdrObject* pObject = aIter.Next();
+ while (pObject && !bFound)
+ {
+ if ( pObject == pSelObj )
+ {
+ bFound = true;
+ nObjectTab = static_cast<SCTAB>(i);
+ }
+ pObject = aIter.Next();
+ }
+ }
+ }
+
+ if (bFound)
+ {
+ rViewSh.SetTabNo( nObjectTab );
+ rViewSh.ScrollToObject( pSelObj );
+ }
+}
+
+sal_Bool SAL_CALL ScTabViewObj::select( const uno::Any& aSelection )
+{
+ SolarMutexGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+
+ if ( !pViewSh )
+ return false;
+
+ //! Type of aSelection can be some specific interface instead of XInterface
+
+ bool bRet = false;
+ uno::Reference<uno::XInterface> xInterface(aSelection, uno::UNO_QUERY);
+ if ( !xInterface.is() ) //clear all selections
+ {
+ ScDrawView* pDrawView = pViewSh->GetScDrawView();
+ if (pDrawView)
+ {
+ pDrawView->ScEndTextEdit();
+ pDrawView->UnmarkAll();
+ }
+ else //#102232#; if there is no DrawView remove range selection
+ pViewSh->Unmark();
+ bRet = true;
+ }
+
+ if (bDrawSelModeSet) // remove DrawSelMode if set by API; if necessary it will be set again later
+ {
+ pViewSh->SetDrawSelMode(false);
+ pViewSh->UpdateLayerLocks();
+ bDrawSelModeSet = false;
+ }
+
+ if (bRet)
+ return bRet;
+
+ ScCellRangesBase* pRangesImp = comphelper::getFromUnoTunnel<ScCellRangesBase>( xInterface );
+ uno::Reference<drawing::XShapes> xShapeColl( xInterface, uno::UNO_QUERY );
+ uno::Reference<drawing::XShape> xShapeSel( xInterface, uno::UNO_QUERY );
+ SvxShape* pShapeImp = comphelper::getFromUnoTunnel<SvxShape>( xShapeSel );
+
+ if (pRangesImp) // Cell ranges
+ {
+ ScViewData& rViewData = pViewSh->GetViewData();
+ if ( rViewData.GetDocShell() == pRangesImp->GetDocShell() )
+ {
+ // perhaps remove drawing selection first
+ // (MarkListHasChanged removes sheet selection)
+
+ ScDrawView* pDrawView = pViewSh->GetScDrawView();
+ if (pDrawView)
+ {
+ pDrawView->ScEndTextEdit();
+ pDrawView->UnmarkAll();
+ }
+ FuPoor* pFunc = pViewSh->GetDrawFuncPtr();
+ if ( pFunc && pFunc->GetSlotID() != SID_OBJECT_SELECT )
+ {
+ // execute the slot of drawing function again -> switch off
+ SfxDispatcher* pDisp = pViewSh->GetDispatcher();
+ if (pDisp)
+ pDisp->Execute( pFunc->GetSlotID(), SfxCallMode::SYNCHRON );
+ }
+ pViewSh->SetDrawShell(false);
+ pViewSh->SetDrawSelMode(false); // after Dispatcher-Execute
+
+ // select ranges
+
+ const ScRangeList& rRanges = pRangesImp->GetRangeList();
+ size_t nRangeCount = rRanges.size();
+ // for empty range list, remove selection (cursor remains where it was)
+ if ( nRangeCount == 0 )
+ pViewSh->Unmark();
+ else if ( nRangeCount == 1 )
+ pViewSh->MarkRange( rRanges[ 0 ] );
+ else
+ {
+ // multiselection
+
+ const ScRange & rFirst = rRanges[ 0 ];
+ if ( !lcl_TabInRanges( rViewData.GetTabNo(), rRanges ) )
+ pViewSh->SetTabNo( rFirst.aStart.Tab() );
+ pViewSh->DoneBlockMode();
+ pViewSh->InitOwnBlockMode( rFirst ); /* TODO: or even the overall range? */
+ rViewData.GetMarkData().MarkFromRangeList( rRanges, true );
+ pViewSh->MarkDataChanged();
+ rViewData.GetDocShell()->PostPaintGridAll(); // Marks (old&new)
+ pViewSh->AlignToCursor( rFirst.aStart.Col(), rFirst.aStart.Row(),
+ SC_FOLLOW_JUMP );
+ pViewSh->SetCursor( rFirst.aStart.Col(), rFirst.aStart.Row() );
+
+ //! method of the view to select RangeList
+ }
+ bRet = true;
+ }
+ }
+ else if ( pShapeImp || xShapeColl.is() ) // Drawing-Layer
+ {
+ ScDrawView* pDrawView = pViewSh->GetScDrawView();
+ if (pDrawView)
+ {
+ pDrawView->ScEndTextEdit();
+ pDrawView->UnmarkAll();
+
+ if (pShapeImp) // single shape
+ {
+ SdrObject *pObj = pShapeImp->GetSdrObject();
+ if (pObj)
+ {
+ lcl_ShowObject( *pViewSh, *pDrawView, pObj );
+ SdrPageView* pPV = pDrawView->GetSdrPageView();
+ if ( pPV && pObj->getSdrPageFromSdrObject() == pPV->GetPage() )
+ {
+ pDrawView->MarkObj( pObj, pPV );
+ bRet = true;
+ }
+ }
+ }
+ else // Shape-Collection (xShapeColl is not 0)
+ {
+ // We'll switch to the sheet where the first object is
+ // and select all objects on that sheet
+ //!?throw exception when objects are on different sheets?
+
+ tools::Long nCount = xShapeColl->getCount();
+ if (nCount)
+ {
+ SdrPageView* pPV = nullptr;
+ bool bAllMarked(true);
+ for ( tools::Long i = 0; i < nCount; i++ )
+ {
+ uno::Reference<drawing::XShape> xShapeInt(xShapeColl->getByIndex(i), uno::UNO_QUERY);
+ if (xShapeInt.is())
+ {
+ SdrObject* pObj = SdrObject::getSdrObjectFromXShape( xShapeInt );
+ if (pObj)
+ {
+ if (!bDrawSelModeSet && (pObj->GetLayer() == SC_LAYER_BACK))
+ {
+ pViewSh->SetDrawSelMode(true);
+ pViewSh->UpdateLayerLocks();
+ bDrawSelModeSet = true;
+ }
+ if (!pPV) // first object
+ {
+ lcl_ShowObject( *pViewSh, *pDrawView, pObj );
+ pPV = pDrawView->GetSdrPageView();
+ }
+ if ( pPV && pObj->getSdrPageFromSdrObject() == pPV->GetPage() )
+ {
+ if (pDrawView->IsObjMarkable( pObj, pPV ))
+ pDrawView->MarkObj( pObj, pPV );
+ else
+ bAllMarked = false;
+ }
+ }
+ }
+ }
+ if (bAllMarked)
+ bRet = true;
+ }
+ else
+ bRet = true; // empty XShapes (all shapes are deselected)
+ }
+
+ if (bRet)
+ pViewSh->SetDrawShell(true);
+ }
+ }
+
+ if (!bRet)
+ throw lang::IllegalArgumentException();
+
+ return bRet;
+}
+
+uno::Reference<drawing::XShapes> ScTabViewShell::getSelectedXShapes()
+{
+ uno::Reference<drawing::XShapes> xShapes;
+ SdrView* pSdrView = GetScDrawView();
+ if (pSdrView)
+ {
+ const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
+ const size_t nMarkCount = rMarkList.GetMarkCount();
+ if (nMarkCount)
+ {
+ // generate ShapeCollection (like in SdXImpressView::getSelection in Draw)
+ // XInterfaceRef will be returned and it has to be UsrObject-XInterface
+ xShapes = drawing::ShapeCollection::create(comphelper::getProcessComponentContext());
+
+ for (size_t i = 0; i < nMarkCount; ++i)
+ {
+ SdrObject* pDrawObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
+ if (pDrawObj)
+ {
+ uno::Reference<drawing::XShape> xShape( pDrawObj->getUnoShape(), uno::UNO_QUERY );
+ if (xShape.is())
+ xShapes->add(xShape);
+ }
+ }
+ }
+ }
+ return xShapes;
+}
+
+uno::Any SAL_CALL ScTabViewObj::getSelection()
+{
+ SolarMutexGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ rtl::Reference<ScCellRangesBase> pObj;
+ if (pViewSh)
+ {
+ // is something selected in drawing layer?
+ uno::Reference<uno::XInterface> xRet(pViewSh->getSelectedXShapes());
+ if (xRet.is())
+ return uno::Any(xRet);
+
+ // otherwise sheet (cell) selection
+
+ ScViewData& rViewData = pViewSh->GetViewData();
+ ScDocShell* pDocSh = rViewData.GetDocShell();
+
+ const ScMarkData& rMark = rViewData.GetMarkData();
+ SCTAB nTabs = rMark.GetSelectCount();
+
+ ScRange aRange;
+ ScMarkType eMarkType = rViewData.GetSimpleArea(aRange);
+ if ( nTabs == 1 && (eMarkType == SC_MARK_SIMPLE) )
+ {
+ if (aRange.aStart == aRange.aEnd)
+ pObj = new ScCellObj( pDocSh, aRange.aStart );
+ else
+ pObj = new ScCellRangeObj( pDocSh, aRange );
+ }
+ else if ( nTabs == 1 && (eMarkType == SC_MARK_SIMPLE_FILTERED) )
+ {
+ ScMarkData aFilteredMark( rMark );
+ ScViewUtil::UnmarkFiltered( aFilteredMark, pDocSh->GetDocument());
+ ScRangeList aRangeList;
+ aFilteredMark.FillRangeListWithMarks( &aRangeList, false);
+ // Theoretically a selection may start and end on a filtered row.
+ switch ( aRangeList.size() )
+ {
+ case 0:
+ // No unfiltered row, we have to return some object, so
+ // here is one with no ranges.
+ pObj = new ScCellRangesObj( pDocSh, aRangeList );
+ break;
+ case 1:
+ {
+ const ScRange& rRange = aRangeList[ 0 ];
+ if (rRange.aStart == rRange.aEnd)
+ pObj = new ScCellObj( pDocSh, rRange.aStart );
+ else
+ pObj = new ScCellRangeObj( pDocSh, rRange );
+ }
+ break;
+ default:
+ pObj = new ScCellRangesObj( pDocSh, aRangeList );
+ }
+ }
+ else // multiselection
+ {
+ ScRangeListRef xRanges;
+ rViewData.GetMultiArea( xRanges );
+
+ // if there are more sheets, copy ranges
+ //! should this happen in ScMarkData::FillRangeListWithMarks already?
+ if ( nTabs > 1 )
+ rMark.ExtendRangeListTables( xRanges.get() );
+
+ pObj = new ScCellRangesObj( pDocSh, *xRanges );
+ }
+
+ if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
+ {
+ // remember if the selection was from the cursor position without anything selected
+ // (used when rendering the selection)
+
+ pObj->SetCursorOnly( true );
+ }
+ }
+
+ return uno::Any(uno::Reference<uno::XInterface>(static_cast<cppu::OWeakObject*>(pObj.get())));
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScTabViewObj::createEnumeration()
+{
+ SolarMutexGuard aGuard;
+ return new ScIndexEnumeration(this, "com.sun.star.sheet.SpreadsheetViewPanesEnumeration");
+}
+
+// XIndexAccess
+
+sal_Int32 SAL_CALL ScTabViewObj::getCount()
+{
+ SolarMutexGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ sal_uInt16 nPanes = 0;
+ if (pViewSh)
+ {
+ nPanes = 1;
+ ScViewData& rViewData = pViewSh->GetViewData();
+ if ( rViewData.GetHSplitMode() != SC_SPLIT_NONE )
+ nPanes *= 2;
+ if ( rViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ nPanes *= 2;
+ }
+ return nPanes;
+}
+
+uno::Any SAL_CALL ScTabViewObj::getByIndex( sal_Int32 nIndex )
+{
+ SolarMutexGuard aGuard;
+ uno::Reference<sheet::XViewPane> xPane(GetObjectByIndex_Impl(static_cast<sal_uInt16>(nIndex)));
+ if (!xPane.is())
+ throw lang::IndexOutOfBoundsException();
+
+ return uno::Any(xPane);
+}
+
+uno::Type SAL_CALL ScTabViewObj::getElementType()
+{
+ return cppu::UnoType<sheet::XViewPane>::get();
+}
+
+sal_Bool SAL_CALL ScTabViewObj::hasElements()
+{
+ SolarMutexGuard aGuard;
+ return ( getCount() != 0 );
+}
+
+// XSpreadsheetView
+
+rtl::Reference<ScViewPaneObj> ScTabViewObj::GetObjectByIndex_Impl(sal_uInt16 nIndex) const
+{
+ static const ScSplitPos ePosHV[4] =
+ { SC_SPLIT_TOPLEFT, SC_SPLIT_BOTTOMLEFT, SC_SPLIT_TOPRIGHT, SC_SPLIT_BOTTOMRIGHT };
+
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScSplitPos eWhich = SC_SPLIT_BOTTOMLEFT; // default position
+ bool bError = false;
+ ScViewData& rViewData = pViewSh->GetViewData();
+ bool bHor = ( rViewData.GetHSplitMode() != SC_SPLIT_NONE );
+ bool bVer = ( rViewData.GetVSplitMode() != SC_SPLIT_NONE );
+ if ( bHor && bVer )
+ {
+ // bottom left, bottom right, top left, top right - like in Excel
+ if ( nIndex < 4 )
+ eWhich = ePosHV[nIndex];
+ else
+ bError = true;
+ }
+ else if ( bHor )
+ {
+ if ( nIndex > 1 )
+ bError = true;
+ else if ( nIndex == 1 )
+ eWhich = SC_SPLIT_BOTTOMRIGHT;
+ // otherwise SC_SPLIT_BOTTOMLEFT
+ }
+ else if ( bVer )
+ {
+ if ( nIndex > 1 )
+ bError = true;
+ else if ( nIndex == 0 )
+ eWhich = SC_SPLIT_TOPLEFT;
+ // otherwise SC_SPLIT_BOTTOMLEFT
+ }
+ else if ( nIndex > 0 )
+ bError = true; // not split: only 0 is valid
+
+ if (!bError)
+ return new ScViewPaneObj( pViewSh, sal::static_int_cast<sal_uInt16>(eWhich) );
+ }
+
+ return nullptr;
+}
+
+uno::Reference<sheet::XSpreadsheet> SAL_CALL ScTabViewObj::getActiveSheet()
+{
+ SolarMutexGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScViewData& rViewData = pViewSh->GetViewData();
+ SCTAB nTab = rViewData.GetTabNo();
+ return new ScTableSheetObj( rViewData.GetDocShell(), nTab );
+ }
+ return nullptr;
+}
+
+// support expand (but not replace) the active sheet
+void SAL_CALL ScTabViewObj::setActiveSheet( const uno::Reference<sheet::XSpreadsheet>& xActiveSheet )
+{
+ SolarMutexGuard aGuard;
+ comphelper::ProfileZone aZone("setActiveSheet");
+
+ ScTabViewShell* pViewSh = GetViewShell();
+ if ( !(pViewSh && xActiveSheet.is()) )
+ return;
+
+ // XSpreadsheet and ScCellRangesBase -> has to be the same sheet
+
+ ScCellRangesBase* pRangesImp = comphelper::getFromUnoTunnel<ScCellRangesBase>( xActiveSheet );
+ if ( pRangesImp && pViewSh->GetViewData().GetDocShell() == pRangesImp->GetDocShell() )
+ {
+ const ScRangeList& rRanges = pRangesImp->GetRangeList();
+ if ( rRanges.size() == 1 )
+ {
+ SCTAB nNewTab = rRanges[ 0 ].aStart.Tab();
+ if ( pViewSh->GetViewData().GetDocument().HasTable(nNewTab) )
+ pViewSh->SetTabNo( nNewTab );
+ }
+ }
+}
+
+uno::Reference< uno::XInterface > ScTabViewObj::GetClickedObject(const Point& rPoint) const
+{
+ uno::Reference< uno::XInterface > xTarget;
+ if (GetViewShell())
+ {
+ SCCOL nX;
+ SCROW nY;
+ ScViewData& rData = GetViewShell()->GetViewData();
+ ScSplitPos eSplitMode = rData.GetActivePart();
+ SCTAB nTab(rData.GetTabNo());
+ rData.GetPosFromPixel( rPoint.X(), rPoint.Y(), eSplitMode, nX, nY);
+
+ ScAddress aCellPos (nX, nY, nTab);
+ rtl::Reference<ScCellObj> pCellObj = new ScCellObj(rData.GetDocShell(), aCellPos);
+
+ xTarget.set(uno::Reference<table::XCell>(pCellObj), uno::UNO_QUERY);
+
+ ScDocument& rDoc = rData.GetDocument();
+ if (ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer())
+ {
+ SdrPage* pDrawPage = nullptr;
+ if (pDrawLayer->HasObjects() && (pDrawLayer->GetPageCount() > nTab))
+ pDrawPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
+
+ SdrView* pDrawView = GetViewShell()->GetScDrawView();
+
+ if (pDrawPage && pDrawView && pDrawView->GetSdrPageView())
+ {
+ vcl::Window* pActiveWin = rData.GetActiveWin();
+ Point aPos = pActiveWin->PixelToLogic(rPoint);
+
+ sal_uInt16 nHitLog = static_cast<sal_uInt16>(pActiveWin->PixelToLogic(
+ Size(pDrawView->GetHitTolerancePixel(),0)).Width());
+
+ const size_t nCount(pDrawPage->GetObjCount());
+ bool bFound(false);
+ for (size_t i = 0; i < nCount && !bFound; ++i)
+ {
+ SdrObject* pObj = pDrawPage->GetObj(i);
+ if (pObj && SdrObjectPrimitiveHit(*pObj, aPos, nHitLog, *pDrawView->GetSdrPageView(), nullptr, false))
+ {
+ xTarget.set(pObj->getUnoShape(), uno::UNO_QUERY);
+ bFound = true;
+ }
+ }
+ }
+ }
+ }
+ return xTarget;
+}
+
+bool ScTabViewObj::IsMouseListening() const
+{
+ if ( !aMouseClickHandlers.empty() )
+ return true;
+
+ // also include sheet events, because MousePressed must be called for them
+ ScViewData& rViewData = GetViewShell()->GetViewData();
+ ScDocument& rDoc = rViewData.GetDocument();
+ SCTAB nTab = rViewData.GetTabNo();
+ return
+ rDoc.HasSheetEventScript( nTab, ScSheetEventId::RIGHTCLICK, true ) ||
+ rDoc.HasSheetEventScript( nTab, ScSheetEventId::DOUBLECLICK, true ) ||
+ rDoc.HasSheetEventScript( nTab, ScSheetEventId::SELECT, true );
+
+}
+
+bool ScTabViewObj::MousePressed( const awt::MouseEvent& e )
+{
+ bool bReturn(false);
+ if ( e.Buttons == css::awt::MouseButton::LEFT )
+ mbLeftMousePressed = true;
+
+ uno::Reference< uno::XInterface > xTarget = GetClickedObject(Point(e.X, e.Y));
+ if (!aMouseClickHandlers.empty() && xTarget.is())
+ {
+ awt::EnhancedMouseEvent aMouseEvent;
+
+ aMouseEvent.Buttons = e.Buttons;
+ aMouseEvent.X = e.X;
+ aMouseEvent.Y = e.Y;
+ aMouseEvent.ClickCount = e.ClickCount;
+ aMouseEvent.PopupTrigger = e.PopupTrigger;
+ aMouseEvent.Target = xTarget;
+ aMouseEvent.Modifiers = e.Modifiers;
+
+ // Listener's handler may remove it from the listeners list
+ for (size_t i = aMouseClickHandlers.size(); i > 0; --i)
+ {
+ try
+ {
+ if (!aMouseClickHandlers[i - 1]->mousePressed(aMouseEvent))
+ bReturn = true;
+ }
+ catch ( uno::Exception& )
+ {
+ aMouseClickHandlers.erase(aMouseClickHandlers.begin() + (i - 1));
+ }
+ }
+ }
+
+ // handle sheet events
+ bool bDoubleClick = ( e.Buttons == awt::MouseButton::LEFT && e.ClickCount == 2 );
+ bool bRightClick = ( e.Buttons == awt::MouseButton::RIGHT && e.ClickCount == 1 );
+ if ( ( bDoubleClick || bRightClick ) && !bReturn && xTarget.is())
+ {
+ ScSheetEventId nEvent = bDoubleClick ? ScSheetEventId::DOUBLECLICK : ScSheetEventId::RIGHTCLICK;
+
+ ScTabViewShell* pViewSh = GetViewShell();
+ ScViewData& rViewData = pViewSh->GetViewData();
+ ScDocShell* pDocSh = rViewData.GetDocShell();
+ ScDocument& rDoc = pDocSh->GetDocument();
+ SCTAB nTab = rViewData.GetTabNo();
+ const ScSheetEvents* pEvents = rDoc.GetSheetEvents(nTab);
+ if (pEvents)
+ {
+ const OUString* pScript = pEvents->GetScript(nEvent);
+ if (pScript)
+ {
+ // the macro parameter is the clicked object, as in the mousePressed call above
+ uno::Sequence<uno::Any> aParams{ uno::Any(xTarget) };
+
+ uno::Any aRet;
+ uno::Sequence<sal_Int16> aOutArgsIndex;
+ uno::Sequence<uno::Any> aOutArgs;
+
+ /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
+
+ // look for a boolean return value of true
+ bool bRetValue = false;
+ if ((aRet >>= bRetValue) && bRetValue)
+ bReturn = true;
+ }
+ }
+
+ // execute VBA event handler
+ if (!bReturn && xTarget.is()) try
+ {
+ uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( rDoc.GetVbaEventProcessor(), uno::UNO_SET_THROW );
+ // the parameter is the clicked object, as in the mousePressed call above
+ uno::Sequence< uno::Any > aArgs{ uno::Any(xTarget) };
+ xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( nEvent ), aArgs );
+ }
+ catch( util::VetoException& )
+ {
+ bReturn = true;
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+
+ return bReturn;
+}
+
+bool ScTabViewObj::MouseReleased( const awt::MouseEvent& e )
+{
+ if ( e.Buttons == css::awt::MouseButton::LEFT )
+ {
+ try
+ {
+ ScTabViewShell* pViewSh = GetViewShell();
+ ScViewData& rViewData = pViewSh->GetViewData();
+ ScDocShell* pDocSh = rViewData.GetDocShell();
+ ScDocument& rDoc = pDocSh->GetDocument();
+ uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( rDoc.GetVbaEventProcessor(), uno::UNO_SET_THROW );
+ uno::Sequence< uno::Any > aArgs{ getSelection() };
+ xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( ScSheetEventId::SELECT ), aArgs );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ mbLeftMousePressed = false;
+ }
+
+ bool bReturn(false);
+
+ if (!aMouseClickHandlers.empty())
+ {
+ uno::Reference< uno::XInterface > xTarget = GetClickedObject(Point(e.X, e.Y));
+
+ if (xTarget.is())
+ {
+ awt::EnhancedMouseEvent aMouseEvent;
+
+ aMouseEvent.Buttons = e.Buttons;
+ aMouseEvent.X = e.X;
+ aMouseEvent.Y = e.Y;
+ aMouseEvent.ClickCount = e.ClickCount;
+ aMouseEvent.PopupTrigger = e.PopupTrigger;
+ aMouseEvent.Target = xTarget;
+ aMouseEvent.Modifiers = e.Modifiers;
+
+ // Listener's handler may remove it from the listeners list
+ for (size_t i = aMouseClickHandlers.size(); i > 0; --i)
+ {
+ try
+ {
+ if (!aMouseClickHandlers[i - 1]->mouseReleased( aMouseEvent ))
+ bReturn = true;
+ }
+ catch ( uno::Exception& )
+ {
+ aMouseClickHandlers.erase(aMouseClickHandlers.begin() + (i - 1));
+ }
+ }
+ }
+ }
+ return bReturn;
+}
+
+// XEnhancedMouseClickBroadcaster
+
+void ScTabViewObj::EndMouseListening()
+{
+ lang::EventObject aEvent;
+ aEvent.Source = static_cast<cppu::OWeakObject*>(this);
+ for (const auto& rListener : aMouseClickHandlers)
+ {
+ try
+ {
+ rListener->disposing(aEvent);
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+ aMouseClickHandlers.clear();
+}
+
+void ScTabViewObj::EndActivationListening()
+{
+ lang::EventObject aEvent;
+ aEvent.Source = static_cast<cppu::OWeakObject*>(this);
+ for (const auto& rListener : aActivationListeners)
+ {
+ try
+ {
+ rListener->disposing(aEvent);
+ }
+ catch ( uno::Exception& )
+ {
+ }
+ }
+ aActivationListeners.clear();
+}
+
+void SAL_CALL ScTabViewObj::addEnhancedMouseClickHandler( const uno::Reference< awt::XEnhancedMouseClickHandler >& aListener )
+{
+ SolarMutexGuard aGuard;
+
+ if (aListener.is())
+ {
+ aMouseClickHandlers.push_back( aListener );
+ }
+}
+
+void SAL_CALL ScTabViewObj::removeEnhancedMouseClickHandler( const uno::Reference< awt::XEnhancedMouseClickHandler >& aListener )
+{
+ SolarMutexGuard aGuard;
+ sal_uInt16 nCount = aMouseClickHandlers.size();
+ aMouseClickHandlers.erase(
+ std::remove(aMouseClickHandlers.begin(), aMouseClickHandlers.end(), aListener),
+ aMouseClickHandlers.end());
+ if (aMouseClickHandlers.empty() && (nCount > 0)) // only if last listener removed
+ EndMouseListening();
+}
+
+// XActivationBroadcaster
+
+void SAL_CALL ScTabViewObj::addActivationEventListener( const uno::Reference< sheet::XActivationEventListener >& aListener )
+{
+ SolarMutexGuard aGuard;
+
+ if (aListener.is())
+ {
+ aActivationListeners.push_back( aListener );
+ }
+}
+
+void SAL_CALL ScTabViewObj::removeActivationEventListener( const uno::Reference< sheet::XActivationEventListener >& aListener )
+{
+ SolarMutexGuard aGuard;
+ sal_uInt16 nCount = aActivationListeners.size();
+ aActivationListeners.erase(
+ std::remove(aActivationListeners.begin(), aActivationListeners.end(), aListener),
+ aActivationListeners.end());
+ if (aActivationListeners.empty() && (nCount > 0)) // only if last listener removed
+ EndActivationListening();
+}
+
+sal_Int16 ScTabViewObj::GetZoom() const
+{
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ const Fraction& rZoomY = pViewSh->GetViewData().GetZoomY(); // Y will be shown
+ return static_cast<sal_Int16>(tools::Long( rZoomY * 100 ));
+ }
+ return 0;
+}
+
+void ScTabViewObj::SetZoom(sal_Int16 nZoom)
+{
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (!pViewSh)
+ return;
+
+ if ( nZoom != GetZoom() && nZoom != 0 )
+ {
+ if (!pViewSh->GetViewData().IsPagebreakMode())
+ {
+ ScModule* pScMod = SC_MOD();
+ ScAppOptions aNewOpt(pScMod->GetAppOptions());
+ aNewOpt.SetZoom( nZoom );
+ aNewOpt.SetZoomType( pViewSh->GetViewData().GetView()->GetZoomType() );
+ pScMod->SetAppOptions( aNewOpt );
+ }
+ }
+ Fraction aFract( nZoom, 100 );
+ pViewSh->SetZoom( aFract, aFract, true );
+ pViewSh->PaintGrid();
+ pViewSh->PaintTop();
+ pViewSh->PaintLeft();
+ pViewSh->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOM );
+ pViewSh->GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER );
+ pViewSh->GetViewFrame()->GetBindings().Invalidate(SID_ZOOM_IN);
+ pViewSh->GetViewFrame()->GetBindings().Invalidate(SID_ZOOM_OUT);
+}
+
+sal_Int16 ScTabViewObj::GetZoomType() const
+{
+ sal_Int16 aZoomType = view::DocumentZoomType::OPTIMAL;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ SvxZoomType eZoomType = pViewSh->GetViewData().GetView()->GetZoomType();
+ switch (eZoomType)
+ {
+ case SvxZoomType::PERCENT:
+ aZoomType = view::DocumentZoomType::BY_VALUE;
+ break;
+ case SvxZoomType::OPTIMAL:
+ aZoomType = view::DocumentZoomType::OPTIMAL;
+ break;
+ case SvxZoomType::WHOLEPAGE:
+ aZoomType = view::DocumentZoomType::ENTIRE_PAGE;
+ break;
+ case SvxZoomType::PAGEWIDTH:
+ aZoomType = view::DocumentZoomType::PAGE_WIDTH;
+ break;
+ case SvxZoomType::PAGEWIDTH_NOBORDER:
+ aZoomType = view::DocumentZoomType::PAGE_WIDTH_EXACT;
+ break;
+ }
+ }
+ return aZoomType;
+}
+
+void ScTabViewObj::SetZoomType(sal_Int16 aZoomType)
+{
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (!pViewSh)
+ return;
+
+ ScDBFunc* pView = pViewSh->GetViewData().GetView();
+ if (!pView)
+ return;
+
+ SvxZoomType eZoomType;
+ switch (aZoomType)
+ {
+ case view::DocumentZoomType::BY_VALUE:
+ eZoomType = SvxZoomType::PERCENT;
+ break;
+ case view::DocumentZoomType::OPTIMAL:
+ eZoomType = SvxZoomType::OPTIMAL;
+ break;
+ case view::DocumentZoomType::ENTIRE_PAGE:
+ eZoomType = SvxZoomType::WHOLEPAGE;
+ break;
+ case view::DocumentZoomType::PAGE_WIDTH:
+ eZoomType = SvxZoomType::PAGEWIDTH;
+ break;
+ case view::DocumentZoomType::PAGE_WIDTH_EXACT:
+ eZoomType = SvxZoomType::PAGEWIDTH_NOBORDER;
+ break;
+ default:
+ eZoomType = SvxZoomType::OPTIMAL;
+ }
+ sal_Int16 nZoom(GetZoom());
+ sal_Int16 nOldZoom(nZoom);
+ if ( eZoomType == SvxZoomType::PERCENT )
+ {
+ if ( nZoom < MINZOOM ) nZoom = MINZOOM;
+ if ( nZoom > MAXZOOM ) nZoom = MAXZOOM;
+ }
+ else
+ nZoom = pView->CalcZoom( eZoomType, nOldZoom );
+
+ switch ( eZoomType )
+ {
+ case SvxZoomType::WHOLEPAGE:
+ case SvxZoomType::PAGEWIDTH:
+ pView->SetZoomType( eZoomType, true );
+ break;
+
+ default:
+ pView->SetZoomType( SvxZoomType::PERCENT, true );
+ }
+ SetZoom( nZoom );
+}
+
+sal_Bool SAL_CALL ScTabViewObj::getIsWindowSplit()
+{
+ SolarMutexGuard aGuard;
+ // what menu slot SID_WINDOW_SPLIT does
+
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScViewData& rViewData = pViewSh->GetViewData();
+ return ( rViewData.GetHSplitMode() == SC_SPLIT_NORMAL ||
+ rViewData.GetVSplitMode() == SC_SPLIT_NORMAL );
+ }
+
+ return false;
+}
+
+sal_Bool SAL_CALL ScTabViewObj::hasFrozenPanes()
+{
+ SolarMutexGuard aGuard;
+ // what menu slot SID_WINDOW_FIX does
+
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScViewData& rViewData = pViewSh->GetViewData();
+ return ( rViewData.GetHSplitMode() == SC_SPLIT_FIX ||
+ rViewData.GetVSplitMode() == SC_SPLIT_FIX );
+ }
+
+ return false;
+}
+
+sal_Int32 SAL_CALL ScTabViewObj::getSplitHorizontal()
+{
+ SolarMutexGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScViewData& rViewData = pViewSh->GetViewData();
+ if ( rViewData.GetHSplitMode() != SC_SPLIT_NONE )
+ return rViewData.GetHSplitPos();
+ }
+ return 0;
+}
+
+sal_Int32 SAL_CALL ScTabViewObj::getSplitVertical()
+{
+ SolarMutexGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScViewData& rViewData = pViewSh->GetViewData();
+ if ( rViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ return rViewData.GetVSplitPos();
+ }
+ return 0;
+}
+
+sal_Int32 SAL_CALL ScTabViewObj::getSplitColumn()
+{
+ SolarMutexGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScViewData& rViewData = pViewSh->GetViewData();
+ if ( rViewData.GetHSplitMode() != SC_SPLIT_NONE )
+ {
+ tools::Long nSplit = rViewData.GetHSplitPos();
+
+ ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
+ if ( rViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ ePos = SC_SPLIT_TOPLEFT;
+
+ SCCOL nCol;
+ SCROW nRow;
+ rViewData.GetPosFromPixel( nSplit, 0, ePos, nCol, nRow, false );
+ if ( nCol > 0 )
+ return nCol;
+ }
+ }
+ return 0;
+}
+
+sal_Int32 SAL_CALL ScTabViewObj::getSplitRow()
+{
+ SolarMutexGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScViewData& rViewData = pViewSh->GetViewData();
+ if ( rViewData.GetVSplitMode() != SC_SPLIT_NONE )
+ {
+ tools::Long nSplit = rViewData.GetVSplitPos();
+
+ // split vertically
+ SCCOL nCol;
+ SCROW nRow;
+ rViewData.GetPosFromPixel( 0, nSplit, SC_SPLIT_TOPLEFT, nCol, nRow, false );
+ if ( nRow > 0 )
+ return nRow;
+ }
+ }
+ return 0;
+}
+
+void SAL_CALL ScTabViewObj::splitAtPosition( sal_Int32 nPixelX, sal_Int32 nPixelY )
+{
+ SolarMutexGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ pViewSh->SplitAtPixel( Point( nPixelX, nPixelY ) );
+ pViewSh->FreezeSplitters( false );
+ pViewSh->InvalidateSplit();
+ }
+}
+
+void SAL_CALL ScTabViewObj::freezeAtPosition( sal_Int32 nColumns, sal_Int32 nRows )
+{
+ SolarMutexGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (!pViewSh)
+ return;
+
+ // first, remove them all -> no stress with scrolling in the meantime
+
+ pViewSh->RemoveSplit();
+
+ Point aWinStart;
+ vcl::Window* pWin = pViewSh->GetWindowByPos( SC_SPLIT_BOTTOMLEFT );
+ if (pWin)
+ aWinStart = pWin->GetPosPixel();
+
+ ScViewData& rViewData = pViewSh->GetViewData();
+ Point aSplit(rViewData.GetScrPos( static_cast<SCCOL>(nColumns), static_cast<SCROW>(nRows), SC_SPLIT_BOTTOMLEFT, true ));
+ aSplit += aWinStart;
+
+ pViewSh->SplitAtPixel( aSplit );
+ pViewSh->FreezeSplitters( true );
+ pViewSh->InvalidateSplit();
+}
+
+void SAL_CALL ScTabViewObj::addSelectionChangeListener(
+ const uno::Reference<view::XSelectionChangeListener>& xListener )
+{
+ SolarMutexGuard aGuard;
+ aSelectionChgListeners.push_back( xListener );
+}
+
+void SAL_CALL ScTabViewObj::removeSelectionChangeListener(
+ const uno::Reference< view::XSelectionChangeListener >& xListener )
+{
+ SolarMutexGuard aGuard;
+ auto it = std::find(aSelectionChgListeners.begin(), aSelectionChgListeners.end(), xListener); //! why the hassle with queryInterface?
+ if (it != aSelectionChgListeners.end())
+ aSelectionChgListeners.erase(it);
+}
+
+void ScTabViewObj::SelectionChanged()
+{
+ // Selection changed so end any style preview
+ // Note: executing this slot through the dispatcher
+ // will cause the style dialog to be raised so we go
+ // direct here
+ ScFormatShell aShell( GetViewShell()->GetViewData() );
+ SfxAllItemSet reqList( SfxGetpApp()->GetPool() );
+ SfxRequest aReq( SID_STYLE_END_PREVIEW, SfxCallMode::SLOT, reqList );
+ aShell.ExecuteStyle( aReq );
+ lang::EventObject aEvent;
+ aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
+ for (const auto& rListener : aSelectionChgListeners)
+ rListener->selectionChanged( aEvent );
+
+ // handle sheet events
+ ScTabViewShell* pViewSh = GetViewShell();
+ ScViewData& rViewData = pViewSh->GetViewData();
+ ScDocShell* pDocSh = rViewData.GetDocShell();
+ ScDocument& rDoc = pDocSh->GetDocument();
+ SCTAB nTab = rViewData.GetTabNo();
+ const ScSheetEvents* pEvents = rDoc.GetSheetEvents(nTab);
+ if (pEvents)
+ {
+ const OUString* pScript = pEvents->GetScript(ScSheetEventId::SELECT);
+ if (pScript)
+ {
+ // the macro parameter is the selection as returned by getSelection
+ uno::Sequence<uno::Any> aParams{ getSelection() };
+ uno::Any aRet;
+ uno::Sequence<sal_Int16> aOutArgsIndex;
+ uno::Sequence<uno::Any> aOutArgs;
+ /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs );
+ }
+ }
+
+ SfxApplication::Get()->Broadcast( SfxHint( SfxHintId::ScSelectionChanged ) );
+
+ if ( mbLeftMousePressed ) // selection still in progress
+ return;
+
+ try
+ {
+ uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( rDoc.GetVbaEventProcessor(), uno::UNO_SET_THROW );
+ uno::Sequence< uno::Any > aArgs{ getSelection() };
+ xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( ScSheetEventId::SELECT ), aArgs );
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+// XPropertySet (view options)
+//! provide those also in application?
+
+uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTabViewObj::getPropertySetInfo()
+{
+ SolarMutexGuard aGuard;
+ static uno::Reference<beans::XPropertySetInfo> aRef(
+ new SfxItemPropertySetInfo( aPropSet.getPropertyMap() ));
+ return aRef;
+}
+
+void SAL_CALL ScTabViewObj::setPropertyValue(
+ const OUString& aPropertyName, const uno::Any& aValue )
+{
+ SolarMutexGuard aGuard;
+
+ if ( aPropertyName == SC_UNO_FILTERED_RANGE_SELECTION )
+ {
+ bFilteredRangeSelection = ScUnoHelpFunctions::GetBoolFromAny(aValue);
+ return;
+ }
+
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (!pViewSh)
+ return;
+
+ ScViewData& rViewData = pViewSh->GetViewData();
+ const ScViewOptions& rOldOpt = pViewSh->GetViewData().GetOptions();
+ ScViewOptions aNewOpt(rOldOpt);
+
+ if ( aPropertyName == SC_UNO_COLROWHDR || aPropertyName == OLD_UNO_COLROWHDR )
+ aNewOpt.SetOption( VOPT_HEADER, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName == SC_UNO_HORSCROLL || aPropertyName == OLD_UNO_HORSCROLL )
+ aNewOpt.SetOption( VOPT_HSCROLL, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName == SC_UNO_OUTLSYMB || aPropertyName == OLD_UNO_OUTLSYMB )
+ aNewOpt.SetOption( VOPT_OUTLINER, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName == SC_UNO_SHEETTABS || aPropertyName == OLD_UNO_SHEETTABS )
+ aNewOpt.SetOption( VOPT_TABCONTROLS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName == SC_UNO_SHOWANCHOR )
+ aNewOpt.SetOption( VOPT_ANCHOR, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName == SC_UNO_SHOWFORM )
+ aNewOpt.SetOption( VOPT_FORMULAS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName == SC_UNO_SHOWGRID )
+ aNewOpt.SetOption( VOPT_GRID, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName == SC_UNO_SHOWHELP )
+ aNewOpt.SetOption( VOPT_HELPLINES, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName == SC_UNO_SHOWNOTES )
+ aNewOpt.SetOption( VOPT_NOTES, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName == SC_UNO_SHOWPAGEBR )
+ aNewOpt.SetOption( VOPT_PAGEBREAKS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName == SC_UNO_SHOWZERO )
+ aNewOpt.SetOption( VOPT_NULLVALS, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName == SC_UNO_VALUEHIGH || aPropertyName == OLD_UNO_VALUEHIGH )
+ aNewOpt.SetOption( VOPT_SYNTAX, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName == SC_UNO_VERTSCROLL || aPropertyName == OLD_UNO_VERTSCROLL )
+ aNewOpt.SetOption( VOPT_VSCROLL, ScUnoHelpFunctions::GetBoolFromAny( aValue ) );
+ else if ( aPropertyName == SC_UNO_SHOWOBJ )
+ {
+ sal_Int16 nIntVal = 0;
+ if ( aValue >>= nIntVal )
+ {
+ //#i80528# adapt to new range eventually
+ if(sal_Int16(VOBJ_MODE_HIDE) < nIntVal) nIntVal = sal_Int16(VOBJ_MODE_SHOW);
+
+ aNewOpt.SetObjMode( VOBJ_TYPE_OLE, static_cast<ScVObjMode>(nIntVal));
+ }
+ }
+ else if ( aPropertyName == SC_UNO_SHOWCHARTS )
+ {
+ sal_Int16 nIntVal = 0;
+ if ( aValue >>= nIntVal )
+ {
+ //#i80528# adapt to new range eventually
+ if(sal_Int16(VOBJ_MODE_HIDE) < nIntVal) nIntVal = sal_Int16(VOBJ_MODE_SHOW);
+
+ aNewOpt.SetObjMode( VOBJ_TYPE_CHART, static_cast<ScVObjMode>(nIntVal));
+ }
+ }
+ else if ( aPropertyName == SC_UNO_SHOWDRAW )
+ {
+ sal_Int16 nIntVal = 0;
+ if ( aValue >>= nIntVal )
+ {
+ //#i80528# adapt to new range eventually
+ if(sal_Int16(VOBJ_MODE_HIDE) < nIntVal) nIntVal = sal_Int16(VOBJ_MODE_SHOW);
+
+ aNewOpt.SetObjMode( VOBJ_TYPE_DRAW, static_cast<ScVObjMode>(nIntVal));
+ }
+ }
+ else if ( aPropertyName == SC_UNO_GRIDCOLOR )
+ {
+ Color nIntVal;
+ if ( aValue >>= nIntVal )
+ aNewOpt.SetGridColor( nIntVal, OUString() );
+ }
+ else if ( aPropertyName == SC_UNO_ZOOMTYPE )
+ {
+ sal_Int16 nIntVal = 0;
+ if ( aValue >>= nIntVal )
+ SetZoomType(nIntVal);
+ }
+ else if ( aPropertyName == SC_UNO_ZOOMVALUE )
+ {
+ sal_Int16 nIntVal = 0;
+ if ( aValue >>= nIntVal )
+ SetZoom(nIntVal);
+ }
+ else if ( aPropertyName == SC_UNO_FORMULABARHEIGHT )
+ {
+ sal_Int16 nIntVal = ScUnoHelpFunctions::GetInt16FromAny(aValue);
+ if (nIntVal > 0)
+ {
+ rViewData.SetFormulaBarLines(nIntVal);
+ // Notify formula bar about changed lines
+ ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
+ if (pInputHdl)
+ {
+ ScInputWindow* pInputWin = pInputHdl->GetInputWindow();
+ if (pInputWin)
+ pInputWin->NumLinesChanged();
+ }
+ }
+ }
+
+ // Options are set on the view and document (for new views),
+ // so that they remain during saving.
+ //! In the app (module) we need an extra options to tune that
+ //! (for new documents)
+
+ if ( aNewOpt == rOldOpt )
+ return;
+
+ rViewData.SetOptions( aNewOpt );
+ rViewData.GetDocument().SetViewOptions( aNewOpt );
+ rViewData.GetDocShell()->SetDocumentModified(); //! really?
+
+ pViewSh->UpdateFixPos();
+ pViewSh->PaintGrid();
+ pViewSh->PaintTop();
+ pViewSh->PaintLeft();
+ pViewSh->PaintExtras();
+ pViewSh->InvalidateBorder();
+
+ SfxBindings& rBindings = pViewSh->GetViewFrame()->GetBindings();
+ rBindings.Invalidate( FID_TOGGLEHEADERS ); // -> check in menu
+ rBindings.Invalidate( FID_TOGGLESYNTAX );
+}
+
+uno::Any SAL_CALL ScTabViewObj::getPropertyValue( const OUString& aPropertyName )
+{
+ SolarMutexGuard aGuard;
+ uno::Any aRet;
+
+ if ( aPropertyName == SC_UNO_FILTERED_RANGE_SELECTION )
+ {
+ aRet <<= bFilteredRangeSelection;
+ return aRet;
+ }
+
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ {
+ ScViewData& rViewData = pViewSh->GetViewData();
+ const ScViewOptions& rOpt = rViewData.GetOptions();
+
+ if ( aPropertyName == SC_UNO_COLROWHDR || aPropertyName == OLD_UNO_COLROWHDR )
+ aRet <<= rOpt.GetOption( VOPT_HEADER );
+ else if ( aPropertyName == SC_UNO_HORSCROLL || aPropertyName == OLD_UNO_HORSCROLL )
+ aRet <<= rOpt.GetOption( VOPT_HSCROLL );
+ else if ( aPropertyName == SC_UNO_OUTLSYMB || aPropertyName == OLD_UNO_OUTLSYMB )
+ aRet <<= rOpt.GetOption( VOPT_OUTLINER );
+ else if ( aPropertyName == SC_UNO_SHEETTABS || aPropertyName == OLD_UNO_SHEETTABS )
+ aRet <<= rOpt.GetOption( VOPT_TABCONTROLS );
+ else if ( aPropertyName == SC_UNO_SHOWANCHOR ) aRet <<= rOpt.GetOption( VOPT_ANCHOR );
+ else if ( aPropertyName == SC_UNO_SHOWFORM ) aRet <<= rOpt.GetOption( VOPT_FORMULAS );
+ else if ( aPropertyName == SC_UNO_SHOWGRID ) aRet <<= rOpt.GetOption( VOPT_GRID );
+ else if ( aPropertyName == SC_UNO_SHOWHELP ) aRet <<= rOpt.GetOption( VOPT_HELPLINES );
+ else if ( aPropertyName == SC_UNO_SHOWNOTES ) aRet <<= rOpt.GetOption( VOPT_NOTES );
+ else if ( aPropertyName == SC_UNO_SHOWPAGEBR ) aRet <<= rOpt.GetOption( VOPT_PAGEBREAKS );
+ else if ( aPropertyName == SC_UNO_SHOWZERO ) aRet <<= rOpt.GetOption( VOPT_NULLVALS );
+ else if ( aPropertyName == SC_UNO_VALUEHIGH || aPropertyName == OLD_UNO_VALUEHIGH )
+ aRet <<= rOpt.GetOption( VOPT_SYNTAX );
+ else if ( aPropertyName == SC_UNO_VERTSCROLL || aPropertyName == OLD_UNO_VERTSCROLL )
+ aRet <<= rOpt.GetOption( VOPT_VSCROLL );
+ else if ( aPropertyName == SC_UNO_SHOWOBJ ) aRet <<= static_cast<sal_Int16>( rOpt.GetObjMode( VOBJ_TYPE_OLE ) );
+ else if ( aPropertyName == SC_UNO_SHOWCHARTS ) aRet <<= static_cast<sal_Int16>( rOpt.GetObjMode( VOBJ_TYPE_CHART ) );
+ else if ( aPropertyName == SC_UNO_SHOWDRAW ) aRet <<= static_cast<sal_Int16>( rOpt.GetObjMode( VOBJ_TYPE_DRAW ) );
+ else if ( aPropertyName == SC_UNO_GRIDCOLOR ) aRet <<= rOpt.GetGridColor();
+ else if ( aPropertyName == SC_UNO_VISAREA ) aRet <<= GetVisArea();
+ else if ( aPropertyName == SC_UNO_ZOOMTYPE ) aRet <<= GetZoomType();
+ else if ( aPropertyName == SC_UNO_ZOOMVALUE ) aRet <<= GetZoom();
+ else if ( aPropertyName == SC_UNO_FORMULABARHEIGHT ) aRet <<= rViewData.GetFormulaBarLines();
+ else if ( aPropertyName == SC_UNO_VISAREASCREEN )
+ {
+ vcl::Window* pActiveWin = rViewData.GetActiveWin();
+ if ( pActiveWin )
+ {
+ tools::Rectangle aRect = pActiveWin->GetWindowExtentsRelative( nullptr );
+ aRet <<= AWTRectangle( aRect );
+ }
+ }
+ }
+
+ return aRet;
+}
+
+void SAL_CALL ScTabViewObj::addPropertyChangeListener( const OUString& /* aPropertyName */,
+ const uno::Reference<beans::XPropertyChangeListener >& xListener )
+{
+ SolarMutexGuard aGuard;
+ aPropertyChgListeners.push_back( xListener );
+}
+
+void SAL_CALL ScTabViewObj::removePropertyChangeListener( const OUString& /* aPropertyName */,
+ const uno::Reference<beans::XPropertyChangeListener >& xListener )
+{
+ SolarMutexGuard aGuard;
+ auto it = std::find(aPropertyChgListeners.begin(), aPropertyChgListeners.end(), xListener); //! Why the nonsense with queryInterface?
+ if (it != aPropertyChgListeners.end())
+ aPropertyChgListeners.erase(it);
+}
+
+void SAL_CALL ScTabViewObj::addVetoableChangeListener( const OUString& /* PropertyName */,
+ const uno::Reference<beans::XVetoableChangeListener >& /* aListener */ )
+{
+}
+
+void SAL_CALL ScTabViewObj::removeVetoableChangeListener( const OUString& /* PropertyName */,
+ const uno::Reference<beans::XVetoableChangeListener >& /* aListener */ )
+{
+}
+
+void ScTabViewObj::VisAreaChanged()
+{
+ beans::PropertyChangeEvent aEvent;
+ aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
+ for (const auto& rListener : aPropertyChgListeners)
+ rListener->propertyChange( aEvent );
+}
+
+// XRangeSelection
+
+void SAL_CALL ScTabViewObj::startRangeSelection(
+ const uno::Sequence<beans::PropertyValue>& aArguments )
+{
+ SolarMutexGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (!pViewSh)
+ return;
+
+ OUString aInitVal, aTitle;
+ bool bCloseOnButtonUp = false;
+ bool bSingleCell = false;
+ bool bMultiSelection = false;
+
+ OUString aStrVal;
+ for (const beans::PropertyValue& rProp : aArguments)
+ {
+ OUString aPropName(rProp.Name);
+
+ if (aPropName == SC_UNONAME_CLOSEONUP )
+ bCloseOnButtonUp = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ else if (aPropName == SC_UNONAME_TITLE )
+ {
+ if ( rProp.Value >>= aStrVal )
+ aTitle = aStrVal;
+ }
+ else if (aPropName == SC_UNONAME_INITVAL )
+ {
+ if ( rProp.Value >>= aStrVal )
+ aInitVal = aStrVal;
+ }
+ else if (aPropName == SC_UNONAME_SINGLECELL )
+ bSingleCell = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ else if (aPropName == SC_UNONAME_MULTISEL )
+ bMultiSelection = ScUnoHelpFunctions::GetBoolFromAny( rProp.Value );
+ }
+
+ pViewSh->StartSimpleRefDialog( aTitle, aInitVal, bCloseOnButtonUp, bSingleCell, bMultiSelection );
+}
+
+void SAL_CALL ScTabViewObj::abortRangeSelection()
+{
+ SolarMutexGuard aGuard;
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (pViewSh)
+ pViewSh->StopSimpleRefDialog();
+}
+
+void SAL_CALL ScTabViewObj::addRangeSelectionListener(
+ const uno::Reference<sheet::XRangeSelectionListener>& xListener )
+{
+ SolarMutexGuard aGuard;
+ aRangeSelListeners.push_back( xListener );
+}
+
+void SAL_CALL ScTabViewObj::removeRangeSelectionListener(
+ const uno::Reference<sheet::XRangeSelectionListener>& xListener )
+{
+ SolarMutexGuard aGuard;
+ auto it = std::find(aRangeSelListeners.begin(), aRangeSelListeners.end(), xListener);
+ if (it != aRangeSelListeners.end())
+ aRangeSelListeners.erase(it);
+}
+
+void SAL_CALL ScTabViewObj::addRangeSelectionChangeListener(
+ const uno::Reference<sheet::XRangeSelectionChangeListener>& xListener )
+{
+ SolarMutexGuard aGuard;
+ aRangeChgListeners.push_back( xListener );
+}
+
+void SAL_CALL ScTabViewObj::removeRangeSelectionChangeListener(
+ const uno::Reference<sheet::XRangeSelectionChangeListener>& xListener )
+{
+ SolarMutexGuard aGuard;
+ auto it = std::find(aRangeChgListeners.begin(), aRangeChgListeners.end(), xListener);
+ if (it != aRangeChgListeners.end())
+ aRangeChgListeners.erase(it);
+}
+
+void ScTabViewObj::RangeSelDone( const OUString& rText )
+{
+ sheet::RangeSelectionEvent aEvent;
+ aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
+ aEvent.RangeDescriptor = rText;
+
+ // copy on the stack because listener could remove itself
+ auto const listeners(aRangeSelListeners);
+
+ for (const auto& rListener : listeners)
+ rListener->done( aEvent );
+}
+
+void ScTabViewObj::RangeSelAborted( const OUString& rText )
+{
+ sheet::RangeSelectionEvent aEvent;
+ aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
+ aEvent.RangeDescriptor = rText;
+
+ // copy on the stack because listener could remove itself
+ auto const listeners(aRangeSelListeners);
+
+ for (const auto& rListener : listeners)
+ rListener->aborted( aEvent );
+}
+
+void ScTabViewObj::RangeSelChanged( const OUString& rText )
+{
+ sheet::RangeSelectionEvent aEvent;
+ aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
+ aEvent.RangeDescriptor = rText;
+
+ // copy on the stack because listener could remove itself
+ auto const listener(aRangeChgListeners);
+
+ for (const auto& rListener : listener)
+ rListener->descriptorChanged( aEvent );
+}
+
+// XServiceInfo
+OUString SAL_CALL ScTabViewObj::getImplementationName()
+{
+ return "ScTabViewObj";
+}
+
+sal_Bool SAL_CALL ScTabViewObj::supportsService( const OUString& rServiceName )
+{
+ return cppu::supportsService(this, rServiceName);
+}
+
+uno::Sequence<OUString> SAL_CALL ScTabViewObj::getSupportedServiceNames()
+{
+ return {SCTABVIEWOBJ_SERVICE, SCVIEWSETTINGS_SERVICE};
+}
+
+// XUnoTunnel
+
+UNO3_GETIMPLEMENTATION_IMPL(ScTabViewObj);
+
+css::uno::Reference< css::datatransfer::XTransferable > SAL_CALL ScTabViewObj::getTransferable()
+{
+ SolarMutexGuard aGuard;
+ ScEditShell* pShell = dynamic_cast<ScEditShell*>( GetViewShell()->GetViewFrame()->GetDispatcher()->GetShell(0) );
+ if (pShell)
+ return pShell->GetEditView()->GetTransferable();
+
+ ScDrawTextObjectBar* pTextShell = dynamic_cast<ScDrawTextObjectBar*>( GetViewShell()->GetViewFrame()->GetDispatcher()->GetShell(0) );
+ if (pTextShell)
+ {
+ ScViewData& rViewData = GetViewShell()->GetViewData();
+ ScDrawView* pView = rViewData.GetScDrawView();
+ OutlinerView* pOutView = pView->GetTextEditOutlinerView();
+ if (pOutView)
+ return pOutView->GetEditView().GetTransferable();
+ }
+
+ ScDrawShell* pDrawShell = dynamic_cast<ScDrawShell*>( GetViewShell()->GetViewFrame()->GetDispatcher()->GetShell(0) );
+ if (pDrawShell)
+ return pDrawShell->GetDrawView()->CopyToTransferable();
+
+ return GetViewShell()->CopyToTransferable();
+}
+
+void SAL_CALL ScTabViewObj::insertTransferable( const css::uno::Reference< css::datatransfer::XTransferable >& xTrans )
+{
+ SolarMutexGuard aGuard;
+ ScEditShell* pShell = dynamic_cast<ScEditShell*>( GetViewShell()->GetViewFrame()->GetDispatcher()->GetShell(0) );
+ if (pShell)
+ pShell->GetEditView()->InsertText( xTrans, OUString(), false );
+ else
+ {
+ ScDrawTextObjectBar* pTextShell = dynamic_cast<ScDrawTextObjectBar*>( GetViewShell()->GetViewFrame()->GetDispatcher()->GetShell(0) );
+ if (pTextShell)
+ {
+ ScViewData& rViewData = GetViewShell()->GetViewData();
+ ScDrawView* pView = rViewData.GetScDrawView();
+ OutlinerView* pOutView = pView->GetTextEditOutlinerView();
+ if ( pOutView )
+ {
+ pOutView->GetEditView().InsertText( xTrans, OUString(), false );
+ return;
+ }
+ }
+
+ GetViewShell()->PasteFromTransferable( xTrans );
+ }
+}
+
+namespace {
+
+uno::Sequence<sal_Int32> toSequence(const ScMarkData::MarkedTabsType& rSelected)
+{
+ uno::Sequence<sal_Int32> aRet(rSelected.size());
+ auto aRetRange = asNonConstRange(aRet);
+ size_t i = 0;
+ for (const auto& rTab : rSelected)
+ {
+ aRetRange[i] = static_cast<sal_Int32>(rTab);
+ ++i;
+ }
+
+ return aRet;
+}
+
+}
+
+uno::Sequence<sal_Int32> ScTabViewObj::getSelectedSheets()
+{
+ ScTabViewShell* pViewSh = GetViewShell();
+ if (!pViewSh)
+ return uno::Sequence<sal_Int32>();
+
+ ScViewData& rViewData = pViewSh->GetViewData();
+
+ // #i95280# when printing from the shell, the view is never activated,
+ // so Excel view settings must also be evaluated here.
+ ScExtDocOptions* pExtOpt = rViewData.GetDocument().GetExtDocOptions();
+ if (pExtOpt && pExtOpt->IsChanged())
+ {
+ pViewSh->GetViewData().ReadExtOptions(*pExtOpt); // Excel view settings
+ pViewSh->SetTabNo(pViewSh->GetViewData().GetTabNo(), true);
+ pExtOpt->SetChanged(false);
+ }
+
+ return toSequence(rViewData.GetMarkData().GetSelectedTabs());
+}
+
+ScPreviewObj::ScPreviewObj(ScPreviewShell* pViewSh) :
+ SfxBaseController(pViewSh),
+ mpViewShell(pViewSh)
+{
+ if (mpViewShell)
+ StartListening(*mpViewShell);
+}
+
+ScPreviewObj::~ScPreviewObj()
+{
+ if (mpViewShell)
+ EndListening(*mpViewShell);
+}
+
+uno::Any ScPreviewObj::queryInterface(const uno::Type& rType)
+{
+ SC_QUERYINTERFACE(sheet::XSelectedSheetsSupplier)
+ return SfxBaseController::queryInterface(rType);
+}
+
+void ScPreviewObj::acquire() noexcept
+{
+ SfxBaseController::acquire();
+}
+
+void ScPreviewObj::release() noexcept
+{
+ SfxBaseController::release();
+}
+
+void ScPreviewObj::Notify(SfxBroadcaster&, const SfxHint& rHint)
+{
+ if (rHint.GetId() == SfxHintId::Dying)
+ mpViewShell = nullptr;
+}
+
+uno::Sequence<sal_Int32> ScPreviewObj::getSelectedSheets()
+{
+ ScPreview* p = mpViewShell ? mpViewShell->GetPreview() : nullptr;
+ if (!p)
+ return uno::Sequence<sal_Int32>();
+
+ return toSequence(p->GetSelectedTabs());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */