summaryrefslogtreecommitdiffstats
path: root/sc/source/ui/view/prevwsh.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /sc/source/ui/view/prevwsh.cxx
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sc/source/ui/view/prevwsh.cxx')
-rw-r--r--sc/source/ui/view/prevwsh.cxx1189
1 files changed, 1189 insertions, 0 deletions
diff --git a/sc/source/ui/view/prevwsh.cxx b/sc/source/ui/view/prevwsh.cxx
new file mode 100644
index 000000000..18cae4063
--- /dev/null
+++ b/sc/source/ui/view/prevwsh.cxx
@@ -0,0 +1,1189 @@
+/* -*- 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 <sal/config.h>
+
+#include <scitems.hxx>
+
+#include <comphelper/SetFlagContextHelper.hxx>
+#include <sfx2/app.hxx>
+#include <editeng/sizeitem.hxx>
+#include <svx/zoomslideritem.hxx>
+#include <svx/svdview.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/objface.hxx>
+#include <sfx2/request.hxx>
+#include <svl/stritem.hxx>
+#include <svl/whiter.hxx>
+#include <vcl/commandevent.hxx>
+#include <vcl/help.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/urlobj.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/viewfac.hxx>
+#include <o3tl/unit_conversion.hxx>
+#include <o3tl/string_view.hxx>
+
+#include <drwlayer.hxx>
+#include <prevwsh.hxx>
+#include <preview.hxx>
+#include <printfun.hxx>
+#include <scmod.hxx>
+#include <inputhdl.hxx>
+#include <docsh.hxx>
+#include <tabvwsh.hxx>
+#include <stlpool.hxx>
+#include <editutil.hxx>
+#include <globstr.hrc>
+#include <scresid.hxx>
+#include <sc.hrc>
+#include <ViewSettingsSequenceDefines.hxx>
+#include <viewuno.hxx>
+
+#include <svx/svxdlg.hxx>
+#include <svx/dialogs.hrc>
+
+#include <basegfx/utils/zoomtools.hxx>
+#include <svx/zoom_def.hxx>
+#include <com/sun/star/document/XDocumentProperties.hpp>
+
+#include <scabstdlg.hxx>
+#include <vcl/EnumContext.hxx>
+#include <vcl/notebookbar/notebookbar.hxx>
+
+// for mouse wheel
+#define MINZOOM_SLIDER 10
+#define MAXZOOM_SLIDER 400
+
+#define SC_USERDATA_SEP ';'
+
+using namespace com::sun::star;
+
+#define ShellClass_ScPreviewShell
+#include <scslots.hxx>
+
+#include <memory>
+
+
+SFX_IMPL_INTERFACE(ScPreviewShell, SfxViewShell)
+
+void ScPreviewShell::InitInterface_Impl()
+{
+ GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT,
+ SfxVisibilityFlags::Standard|SfxVisibilityFlags::Server|SfxVisibilityFlags::ReadonlyDoc,
+ ToolbarId::Objectbar_Preview);
+
+ GetStaticInterface()->RegisterPopupMenu("preview");
+}
+
+SFX_IMPL_NAMED_VIEWFACTORY( ScPreviewShell, "PrintPreview" )
+{
+ SFX_VIEW_REGISTRATION(ScDocShell);
+}
+
+void ScPreviewShell::Construct( vcl::Window* pParent )
+{
+ // Find the top-most window, and set the close window handler to intercept
+ // the window close event.
+ vcl::Window* pWin = pParent;
+ while (!pWin->IsSystemWindow())
+ {
+ if (pWin->GetParent())
+ pWin = pWin->GetParent();
+ else
+ break;
+ }
+
+ mpFrameWindow = dynamic_cast<SystemWindow*>(pWin);
+ if (mpFrameWindow)
+ mpFrameWindow->SetCloseHdl(LINK(this, ScPreviewShell, CloseHdl));
+
+ eZoom = SvxZoomType::WHOLEPAGE;
+
+ pCorner = VclPtr<ScrollBarBox>::Create( pParent, WB_SIZEABLE );
+
+ pHorScroll = VclPtr<ScrollBar>::Create(pParent, WB_HSCROLL );
+ pVerScroll = VclPtr<ScrollBar>::Create(pParent, WB_VSCROLL);
+
+ // RTL: no mirroring for horizontal scrollbars
+ pHorScroll->EnableRTL( false );
+
+ pHorScroll->SetEndScrollHdl( LINK( this, ScPreviewShell, ScrollHandler ) );
+ pVerScroll->SetEndScrollHdl( LINK( this, ScPreviewShell, ScrollHandler ) );
+
+ pPreview = VclPtr<ScPreview>::Create( pParent, pDocShell, this );
+
+ SetPool( &SC_MOD()->GetPool() );
+ SetWindow( pPreview );
+ StartListening(*pDocShell, DuplicateHandling::Prevent);
+ StartListening(*SfxGetpApp(), DuplicateHandling::Prevent); // #i62045# #i62046# application is needed for Calc's own hints
+ SfxBroadcaster* pDrawBC = pDocShell->GetDocument().GetDrawBroadcaster();
+ if (pDrawBC)
+ StartListening(*pDrawBC);
+
+ pHorScroll->Show( false );
+ pVerScroll->Show( false );
+ pCorner->Show();
+ SetName("Preview");
+}
+
+ScPreviewShell::ScPreviewShell( SfxViewFrame* pViewFrame,
+ SfxViewShell* pOldSh ) :
+ SfxViewShell( pViewFrame, SfxViewShellFlags::HAS_PRINTOPTIONS ),
+ pDocShell( static_cast<ScDocShell*>(pViewFrame->GetObjectShell()) ),
+ mpFrameWindow(nullptr),
+ nSourceDesignMode( TRISTATE_INDET ),
+ nMaxVertPos(0)
+{
+ Construct( &pViewFrame->GetWindow() );
+
+ try
+ {
+ SfxShell::SetContextBroadcasterEnabled(true);
+ SfxShell::SetContextName(
+ vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Printpreview));
+ SfxShell::BroadcastContextForActivation(true);
+ }
+ catch (const css::uno::RuntimeException& e)
+ {
+ // tdf#130559: allow BackingComp to fail adding listener when opening document
+ css::uno::Reference<css::lang::XServiceInfo> xServiceInfo(e.Context, css::uno::UNO_QUERY);
+ if (!xServiceInfo || !xServiceInfo->supportsService("com.sun.star.frame.StartModule"))
+ throw;
+ SAL_WARN("sc.ui", "Opening file from StartModule straight into print preview");
+ }
+
+ auto& pNotebookBar = pViewFrame->GetWindow().GetSystemWindow()->GetNotebookBar();
+ if (pNotebookBar)
+ pNotebookBar->ControlListenerForCurrentController(false); // stop listening
+
+ if ( auto pTabViewShell = dynamic_cast<ScTabViewShell*>( pOldSh) )
+ {
+ // store view settings, show table from TabView
+ //! store live ScViewData instead, and update on ScTablesHint?
+ //! or completely forget aSourceData on ScTablesHint?
+
+ const ScViewData& rData = pTabViewShell->GetViewData();
+ pPreview->SetSelectedTabs(rData.GetMarkData());
+ InitStartTable( rData.GetTabNo() );
+
+ // also have to store the TabView's DesignMode state
+ // (only if draw view exists)
+ SdrView* pDrawView = pTabViewShell->GetScDrawView();
+ if ( pDrawView )
+ nSourceDesignMode
+ = pDrawView->IsDesignMode() ? TRISTATE_TRUE : TRISTATE_FALSE;
+ }
+
+ new ScPreviewObj(this);
+}
+
+ScPreviewShell::~ScPreviewShell()
+{
+ if (mpFrameWindow)
+ mpFrameWindow->SetCloseHdl(Link<SystemWindow&,void>()); // Remove close handler.
+
+ if (auto& pBar = GetViewFrame()->GetWindow().GetSystemWindow()->GetNotebookBar())
+ pBar->ControlListenerForCurrentController(true); // let it start listening now
+
+ // #108333#; notify Accessibility that Shell is dying and before destroy all
+ BroadcastAccessibility( SfxHint( SfxHintId::Dying ) );
+ pAccessibilityBroadcaster.reset();
+
+ SfxBroadcaster* pDrawBC = pDocShell->GetDocument().GetDrawBroadcaster();
+ if (pDrawBC)
+ EndListening(*pDrawBC);
+ EndListening(*SfxGetpApp());
+ EndListening(*pDocShell);
+
+ SetWindow(nullptr);
+ pPreview.disposeAndClear();
+ pHorScroll.disposeAndClear();
+ pVerScroll.disposeAndClear();
+ pCorner.disposeAndClear();
+
+ // normal mode of operation is switching back to default view in the same frame,
+ // so there's no need to activate any other window here anymore
+}
+
+void ScPreviewShell::InitStartTable(SCTAB nTab)
+{
+ pPreview->SetPageNo( pPreview->GetFirstPage(nTab) );
+}
+
+void ScPreviewShell::AdjustPosSizePixel( const Point &rPos, const Size &rSize )
+{
+ Size aOutSize( rSize );
+ pPreview->SetPosSizePixel( rPos, aOutSize );
+
+ if ( SvxZoomType::WHOLEPAGE == eZoom )
+ pPreview->SetZoom( pPreview->GetOptimalZoom(false) );
+ else if ( SvxZoomType::PAGEWIDTH == eZoom )
+ pPreview->SetZoom( pPreview->GetOptimalZoom(true) );
+
+ UpdateNeededScrollBars(false);
+}
+
+void ScPreviewShell::InnerResizePixel( const Point &rOfs, const Size &rSize, bool )
+{
+ AdjustPosSizePixel( rOfs,rSize );
+}
+
+void ScPreviewShell::OuterResizePixel( const Point &rOfs, const Size &rSize )
+{
+ AdjustPosSizePixel( rOfs,rSize );
+}
+
+bool ScPreviewShell::GetPageSize( Size& aPageSize )
+{
+ ScDocument& rDoc = pDocShell->GetDocument();
+ SCTAB nTab = pPreview->GetTab();
+
+ ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( rDoc.GetPageStyle( nTab ),
+ SfxStyleFamily::Page );
+ OSL_ENSURE(pStyleSheet,"No style sheet");
+ if (!pStyleSheet) return false;
+ const SfxItemSet* pParamSet = &pStyleSheet->GetItemSet();
+
+ aPageSize = pParamSet->Get(ATTR_PAGE_SIZE).GetSize();
+ aPageSize.setWidth(o3tl::convert(aPageSize.Width(), o3tl::Length::twip, o3tl::Length::mm100));
+ aPageSize.setHeight(o3tl::convert(aPageSize.Height(), o3tl::Length::twip, o3tl::Length::mm100));
+ return true;
+}
+
+void ScPreviewShell::UpdateNeededScrollBars( bool bFromZoom )
+{
+ Size aPageSize;
+ OutputDevice* pDevice = Application::GetDefaultDevice();
+
+ tools::Long nBarW = GetViewFrame()->GetWindow().GetSettings().GetStyleSettings().GetScrollBarSize();
+ tools::Long nBarH = nBarW;
+
+ tools::Long aHeightOffSet = pDevice ? pDevice->PixelToLogic( Size( nBarW, nBarH ), pPreview->GetMapMode() ).Height() : 0;
+ tools::Long aWidthOffSet = aHeightOffSet;
+
+ if (!GetPageSize( aPageSize ))
+ return;
+
+ // for centering, page size without the shadow is used
+ bool bVert = pVerScroll->IsVisible();
+ bool bHori = pHorScroll->IsVisible();
+ Size aWindowSize = pPreview->GetOutDev()->GetOutputSize();
+ Point aPos = pPreview->GetPosPixel();
+ Size aWindowPixelSize = pPreview->GetOutputSizePixel();
+
+ // if we are called from Zoom then we need to compensate for whatever
+ // scrollbars were displayed before the zoom was called
+ if ( bFromZoom )
+ {
+ if ( bVert )
+ {
+ aWindowPixelSize.AdjustWidth(nBarH );
+ aWindowSize.AdjustWidth(aHeightOffSet );
+ }
+ if ( bHori )
+ {
+ aWindowPixelSize.AdjustHeight(nBarW );
+ aWindowSize.AdjustHeight(aWidthOffSet );
+ }
+ }
+
+ // recalculate any needed scrollbars
+ tools::Long nMaxWidthPos = aPageSize.Width() - aWindowSize.Width();
+ bHori = nMaxWidthPos >= 0;
+ tools::Long nMaxHeightPos = aPageSize.Height() - aWindowSize.Height();
+ bVert = nMaxHeightPos >= 0;
+
+ // see if having a scroll bar requires the other
+ if ( bVert != bHori && ( bVert || bHori ) )
+ {
+ if ( bVert && ( (nMaxWidthPos + aWidthOffSet ) > 0 ) )
+ bHori = true;
+ else if ( (nMaxHeightPos + aHeightOffSet ) > 0 )
+ bVert = true;
+ }
+ pHorScroll->Show( bHori );
+ pVerScroll->Show( bVert );
+
+ // make room for needed scrollbars ( and reduce the size
+ // of the preview appropriately )
+ if ( bHori )
+ aWindowPixelSize.AdjustHeight( -nBarW );
+ if ( bVert )
+ aWindowPixelSize.AdjustWidth( -nBarH );
+
+ pPreview->SetSizePixel( aWindowPixelSize );
+ pHorScroll->SetPosSizePixel( Point( aPos.X(), aPos.Y() + aWindowPixelSize.Height() ),
+ Size( aWindowPixelSize.Width(), nBarH ) );
+ pVerScroll->SetPosSizePixel( Point( aPos.X() + aWindowPixelSize.Width(), aPos.Y() ),
+ Size( nBarW, aWindowPixelSize.Height() ) );
+ pCorner->SetPosSizePixel( Point( aPos.X() + aWindowPixelSize.Width(), aPos.Y() + aWindowPixelSize.Height() ),
+ Size( nBarW, nBarH ) );
+ UpdateScrollBars();
+}
+
+void ScPreviewShell::UpdateScrollBars()
+{
+ Size aPageSize;
+ if ( !GetPageSize( aPageSize ) )
+ return;
+
+ // for centering, page size without the shadow is used
+
+ Size aWindowSize = pPreview->GetOutDev()->GetOutputSize();
+
+ Point aOfs = pPreview->GetOffset();
+
+ if( pHorScroll )
+ {
+ pHorScroll->SetRange( Range( 0, aPageSize.Width() ) );
+ pHorScroll->SetLineSize( aWindowSize.Width() / 16 );
+ pHorScroll->SetPageSize( aWindowSize.Width() );
+ pHorScroll->SetVisibleSize( aWindowSize.Width() );
+ tools::Long nMaxPos = aPageSize.Width() - aWindowSize.Width();
+ if ( nMaxPos<0 )
+ {
+ // page smaller than window -> center (but put scrollbar to 0)
+ aOfs.setX( 0 );
+ pPreview->SetXOffset( nMaxPos / 2 );
+ }
+ else if (aOfs.X() < 0)
+ {
+ // page larger than window -> never use negative offset
+ aOfs.setX( 0 );
+ pPreview->SetXOffset( 0 );
+ }
+ else if (aOfs.X() > nMaxPos)
+ {
+ // limit offset to align with right edge of window
+ aOfs.setX( nMaxPos );
+ pPreview->SetXOffset(nMaxPos);
+ }
+ pHorScroll->SetThumbPos( aOfs.X() );
+ }
+
+ if( !pVerScroll )
+ return;
+
+ tools::Long nPageNo = pPreview->GetPageNo();
+ tools::Long nTotalPages = pPreview->GetTotalPages();
+
+ nMaxVertPos = aPageSize.Height() - aWindowSize.Height();
+ pVerScroll->SetLineSize( aWindowSize.Height() / 16 );
+ pVerScroll->SetPageSize( aWindowSize.Height() );
+ pVerScroll->SetVisibleSize( aWindowSize.Height() );
+ if ( nMaxVertPos < 0 )
+ {
+ // page smaller than window -> center (but put scrollbar to 0)
+ aOfs.setY( 0 );
+ pPreview->SetYOffset( nMaxVertPos / 2 );
+ pVerScroll->SetThumbPos( nPageNo * aWindowSize.Height() );
+ pVerScroll->SetRange( Range( 0, aWindowSize.Height() * nTotalPages ));
+ }
+ else if (aOfs.Y() < 0)
+ {
+ // page larger than window -> never use negative offset
+ pVerScroll->SetRange( Range( 0, aPageSize.Height() ) );
+ aOfs.setY( 0 );
+ pPreview->SetYOffset( 0 );
+ pVerScroll->SetThumbPos( aOfs.Y() );
+ }
+ else if (aOfs.Y() > nMaxVertPos )
+ {
+ // limit offset to align with window bottom
+ pVerScroll->SetRange( Range( 0, aPageSize.Height() ) );
+ aOfs.setY( nMaxVertPos );
+ pPreview->SetYOffset( nMaxVertPos );
+ pVerScroll->SetThumbPos( aOfs.Y() );
+ }
+}
+
+IMPL_LINK( ScPreviewShell, ScrollHandler, ScrollBar*, pScroll, void )
+{
+ tools::Long nPos = pScroll->GetThumbPos();
+ tools::Long nDelta = pScroll->GetDelta();
+ tools::Long nMaxRange = pScroll->GetRangeMax();
+ tools::Long nTotalPages = pPreview->GetTotalPages();
+ tools::Long nPageNo = 0;
+ tools::Long nPerPageLength = 0;
+ bool bIsDivide = true;
+
+ if( nTotalPages )
+ nPerPageLength = nMaxRange / nTotalPages;
+
+ if( nPerPageLength )
+ {
+ nPageNo = nPos / nPerPageLength;
+ if( nPos % nPerPageLength )
+ {
+ bIsDivide = false;
+ nPageNo ++;
+ }
+ }
+
+ bool bHoriz = ( pScroll == pHorScroll );
+
+ if( bHoriz )
+ pPreview->SetXOffset( nPos );
+ else
+ {
+ if( nMaxVertPos > 0 )
+ pPreview->SetYOffset( nPos );
+ else
+ {
+ Point aMousePos = pScroll->OutputToNormalizedScreenPixel( pScroll->GetPointerPosPixel() );
+ Point aPos = pScroll->GetParent()->OutputToNormalizedScreenPixel( pScroll->GetPosPixel() );
+ OUString aHelpStr;
+ tools::Rectangle aRect;
+ QuickHelpFlags nAlign;
+
+ if( nDelta < 0 )
+ {
+ if ( nTotalPages && nPageNo > 0 && !bIsDivide )
+ pPreview->SetPageNo( nPageNo-1 );
+ if( bIsDivide )
+ pPreview->SetPageNo( nPageNo );
+
+ aHelpStr = ScResId( STR_PAGE ) +
+ " " + OUString::number( nPageNo ) +
+ " / " + OUString::number( nTotalPages );
+ }
+ else if( nDelta > 0 )
+ {
+ bool bAllTested = pPreview->AllTested();
+ if ( nTotalPages && ( nPageNo < nTotalPages || !bAllTested ) )
+ pPreview->SetPageNo( nPageNo );
+
+ aHelpStr = ScResId( STR_PAGE ) +
+ " " + OUString::number( nPageNo+1 ) +
+ " / " + OUString::number( nTotalPages );
+ }
+
+ aRect.SetLeft( aPos.X() - 8 );
+ aRect.SetTop( aMousePos.Y() );
+ aRect.SetRight( aRect.Left() );
+ aRect.SetBottom( aRect.Top() );
+ nAlign = QuickHelpFlags::Bottom|QuickHelpFlags::Center;
+ Help::ShowQuickHelp( pScroll->GetParent(), aRect, aHelpStr, nAlign );
+ }
+ }
+}
+
+IMPL_LINK_NOARG(ScPreviewShell, CloseHdl, SystemWindow&, void)
+{
+ ExitPreview();
+}
+
+bool ScPreviewShell::ScrollCommand( const CommandEvent& rCEvt )
+{
+ bool bDone = false;
+ const CommandWheelData* pData = rCEvt.GetWheelData();
+ if ( pData && pData->GetMode() == CommandWheelMode::ZOOM )
+ {
+ tools::Long nOld = pPreview->GetZoom();
+ tools::Long nNew;
+ if ( pData->GetDelta() < 0 )
+ nNew = std::max( tools::Long(MINZOOM), basegfx::zoomtools::zoomOut( nOld ));
+ else
+ nNew = std::min( tools::Long(MAXZOOM), basegfx::zoomtools::zoomIn( nOld ));
+
+ if ( nNew != nOld )
+ {
+ eZoom = SvxZoomType::PERCENT;
+ pPreview->SetZoom( static_cast<sal_uInt16>(nNew) );
+ }
+
+ bDone = true;
+ }
+ else
+ {
+ bDone = pPreview->HandleScrollCommand( rCEvt, pHorScroll, pVerScroll );
+ }
+
+ return bDone;
+}
+
+SfxPrinter* ScPreviewShell::GetPrinter( bool bCreate )
+{
+ return pDocShell->GetPrinter(bCreate);
+}
+
+sal_uInt16 ScPreviewShell::SetPrinter( SfxPrinter *pNewPrinter, SfxPrinterChangeFlags nDiffFlags )
+{
+ return pDocShell->SetPrinter( pNewPrinter, nDiffFlags );
+}
+
+bool ScPreviewShell::HasPrintOptionsPage() const
+{
+ return true;
+}
+
+std::unique_ptr<SfxTabPage> ScPreviewShell::CreatePrintOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rOptions)
+{
+ ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+ ::CreateTabPage ScTpPrintOptionsCreate = pFact->GetTabPageCreatorFunc(RID_SC_TP_PRINT);
+ if ( ScTpPrintOptionsCreate )
+ return ScTpPrintOptionsCreate(pPage, pController, &rOptions);
+ return nullptr;
+}
+
+void ScPreviewShell::Activate(bool bMDI)
+{
+ SfxViewShell::Activate(bMDI);
+
+ //! Basic etc. -> outsource to its own file (see tabvwsh4)
+
+ if (bMDI)
+ {
+ // InputHdl is now mostly Null, no more assertion!
+ ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
+ if ( pInputHdl )
+ pInputHdl->NotifyChange( nullptr );
+ }
+}
+
+void ScPreviewShell::Execute( SfxRequest& rReq )
+{
+ sal_uInt16 nSlot = rReq.GetSlot();
+ const SfxItemSet* pReqArgs = rReq.GetArgs();
+
+ switch ( nSlot )
+ {
+ case SID_FORMATPAGE:
+ case SID_STATUS_PAGESTYLE:
+ case SID_HFEDIT:
+ pDocShell->ExecutePageStyle( *this, rReq, pPreview->GetTab() );
+ break;
+ case SID_REPAINT:
+ pPreview->Invalidate();
+ rReq.Done();
+ break;
+ case SID_PREV_TABLE: // Accelerator
+ case SID_PREVIEW_PREVIOUS:
+ {
+ tools::Long nPage = pPreview->GetPageNo();
+ tools::Long nTotal = pPreview->GetTotalPages();
+ if (nTotal && nPage > 0)
+ pPreview->SetPageNo( nPage-1 );
+ }
+ break;
+ case SID_NEXT_TABLE: // Accelerator
+ case SID_PREVIEW_NEXT:
+ {
+ bool bAllTested = pPreview->AllTested();
+ tools::Long nPage = pPreview->GetPageNo();
+ tools::Long nTotal = pPreview->GetTotalPages();
+ if (nTotal && (nPage+1 < nTotal || !bAllTested))
+ pPreview->SetPageNo( nPage+1 );
+ }
+ break;
+ case SID_CURSORTOPOFFILE: // Accelerator
+ case SID_PREVIEW_FIRST:
+ {
+ tools::Long nPage = pPreview->GetPageNo();
+ tools::Long nTotal = pPreview->GetTotalPages();
+ if (nTotal && nPage != 0)
+ pPreview->SetPageNo( 0 );
+ }
+ break;
+ case SID_CURSORENDOFFILE: // Accelerator
+ case SID_PREVIEW_LAST:
+ {
+ if (!pPreview->AllTested())
+ pPreview->CalcAll();
+
+ tools::Long nPage = pPreview->GetPageNo();
+ tools::Long nTotal = pPreview->GetTotalPages();
+ if (nTotal && nPage+1 != nTotal)
+ pPreview->SetPageNo( nTotal-1 );
+ }
+ break;
+ case SID_ATTR_ZOOM:
+ case FID_SCALE:
+ {
+ sal_uInt16 nZoom = 100;
+ bool bCancel = false;
+
+ eZoom = SvxZoomType::PERCENT;
+
+ if ( pReqArgs )
+ {
+
+ const SvxZoomItem& rZoomItem = pReqArgs->Get(SID_ATTR_ZOOM);
+
+ eZoom = rZoomItem.GetType();
+ nZoom = rZoomItem.GetValue();
+ }
+ else
+ {
+ SfxItemSetFixed<SID_ATTR_ZOOM, SID_ATTR_ZOOM> aSet( GetPool() );
+ SvxZoomItem aZoomItem( SvxZoomType::PERCENT, pPreview->GetZoom(), SID_ATTR_ZOOM );
+
+ aSet.Put( aZoomItem );
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxZoomDialog> pDlg(pFact->CreateSvxZoomDialog(nullptr, aSet));
+ pDlg->SetLimits( 20, 400 );
+ pDlg->HideButton( ZoomButtonId::OPTIMAL );
+ bCancel = ( RET_CANCEL == pDlg->Execute() );
+
+ if ( !bCancel )
+ {
+ const SvxZoomItem& rZoomItem = pDlg->GetOutputItemSet()->
+ Get( SID_ATTR_ZOOM );
+
+ eZoom = rZoomItem.GetType();
+ nZoom = rZoomItem.GetValue();
+ }
+ }
+
+ if ( !bCancel )
+ {
+ switch ( eZoom )
+ {
+ case SvxZoomType::OPTIMAL:
+ case SvxZoomType::WHOLEPAGE:
+ nZoom = pPreview->GetOptimalZoom(false);
+ break;
+ case SvxZoomType::PAGEWIDTH:
+ nZoom = pPreview->GetOptimalZoom(true);
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+
+ pPreview->SetZoom( nZoom );
+ rReq.Done();
+ }
+ }
+ break;
+ case SID_ZOOM_IN:
+ {
+ sal_uInt16 nNew = pPreview->GetZoom() + 20 ;
+ nNew -= nNew % 20;
+ pPreview->SetZoom( nNew );
+ eZoom = SvxZoomType::PERCENT;
+ rReq.Done();
+ }
+ break;
+ case SID_ZOOM_OUT:
+ {
+ sal_uInt16 nNew = pPreview->GetZoom() - 1;
+ nNew -= nNew % 20;
+ pPreview->SetZoom( nNew );
+ eZoom = SvxZoomType::PERCENT;
+ rReq.Done();
+ }
+ break;
+ case SID_PREVIEW_MARGIN:
+ {
+ bool bMargin = pPreview->GetPageMargins();
+ pPreview->SetPageMargins( !bMargin );
+ pPreview->Invalidate();
+ rReq.Done();
+ }
+ break;
+ case SID_ATTR_ZOOMSLIDER:
+ {
+ const SvxZoomSliderItem* pItem;
+ eZoom = SvxZoomType::PERCENT;
+ if( pReqArgs && (pItem = pReqArgs->GetItemIfSet( SID_ATTR_ZOOMSLIDER )) )
+ {
+ const sal_uInt16 nCurrentZoom = pItem->GetValue();
+ if( nCurrentZoom )
+ {
+ pPreview->SetZoom( nCurrentZoom );
+ rReq.Done();
+ }
+ }
+ }
+ break;
+ case SID_PREVIEW_SCALINGFACTOR:
+ {
+ const SvxZoomSliderItem* pItem;
+ SCTAB nTab = pPreview->GetTab();
+ OUString aOldName = pDocShell->GetDocument().GetPageStyle( pPreview->GetTab() );
+ ScStyleSheetPool* pStylePool = pDocShell->GetDocument().GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aOldName, SfxStyleFamily::Page );
+ OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" );
+
+ if ( pReqArgs && pStyleSheet && (pItem = pReqArgs->GetItemIfSet( SID_PREVIEW_SCALINGFACTOR )) )
+ {
+ const sal_uInt16 nCurrentZoom = pItem->GetValue();
+ SfxItemSet& rSet = pStyleSheet->GetItemSet();
+ rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, nCurrentZoom ) );
+ ScPrintFunc aPrintFunc( pDocShell, pDocShell->GetPrinter(), nTab );
+ aPrintFunc.UpdatePages();
+ rReq.Done();
+ }
+ GetViewFrame()->GetBindings().Invalidate( nSlot );
+ }
+ break;
+ case SID_PRINTPREVIEW:
+ case SID_PREVIEW_CLOSE:
+ // print preview is now always in the same frame as the tab view
+ // -> always switch this frame back to normal view
+ // (ScTabViewShell ctor reads stored view data)
+
+ ExitPreview();
+ break;
+ case SID_CURSORPAGEUP:
+ case SID_CURSORPAGEDOWN:
+ case SID_CURSORHOME:
+ case SID_CURSOREND:
+ case SID_CURSORUP:
+ case SID_CURSORDOWN:
+ case SID_CURSORLEFT:
+ case SID_CURSORRIGHT:
+ DoScroll( nSlot );
+ break;
+ case SID_CANCEL:
+ if( ScViewUtil::IsFullScreen( *this ) )
+ ScViewUtil::SetFullScreen( *this, false );
+ break;
+
+ default:
+ break;
+ }
+}
+
+void ScPreviewShell::GetState( SfxItemSet& rSet )
+{
+ pPreview->SetInGetState(true);
+
+ SCTAB nTab = pPreview->GetTab();
+ tools::Long nPage = pPreview->GetPageNo();
+ tools::Long nTotal = pPreview->GetTotalPages();
+ sal_uInt16 nZoom = pPreview->GetZoom();
+ bool bAllTested = pPreview->AllTested();
+
+ SfxWhichIter aIter(rSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ switch (nWhich)
+ {
+ case SID_STATUS_PAGESTYLE:
+ case SID_HFEDIT:
+ pDocShell->GetStatePageStyle( rSet, nTab );
+ break;
+ case SID_UNDO:
+ case SID_REDO:
+ case SID_REPEAT:
+ case SID_SAVEDOC:
+ case SID_SAVEASDOC:
+ case SID_MAIL_SENDDOC:
+ case SID_VIEW_DATA_SOURCE_BROWSER:
+ case SID_QUITAPP:
+ rSet.DisableItem(nWhich);
+ break;
+ case SID_PREVIEW_PREVIOUS:
+ case SID_PREVIEW_FIRST:
+ if (!nTotal || nPage==0)
+ rSet.DisableItem(nWhich);
+ break;
+ case SID_PREVIEW_NEXT:
+ case SID_PREVIEW_LAST:
+ if (bAllTested)
+ if (!nTotal || nPage==nTotal-1)
+ rSet.DisableItem(nWhich);
+ break;
+ case SID_ZOOM_IN:
+ if (nZoom >= 400)
+ rSet.DisableItem(nWhich);
+ break;
+ case SID_ZOOM_OUT:
+ if (nZoom <= 20)
+ rSet.DisableItem(nWhich);
+ break;
+ case SID_ATTR_ZOOM:
+ {
+ SvxZoomItem aZoom( eZoom, nZoom, nWhich );
+ aZoom.SetValueSet( SvxZoomEnableFlags::ALL & ~SvxZoomEnableFlags::OPTIMAL );
+ rSet.Put( aZoom );
+ }
+ break;
+ case SID_ATTR_ZOOMSLIDER:
+ {
+ SvxZoomSliderItem aZoomSliderItem( nZoom, MINZOOM, MAXZOOM, SID_ATTR_ZOOMSLIDER );
+ aZoomSliderItem.AddSnappingPoint( 100 );
+ rSet.Put( aZoomSliderItem );
+ }
+ break;
+ case SID_PREVIEW_SCALINGFACTOR:
+ {
+ if( pDocShell->IsReadOnly() )
+ rSet.DisableItem( nWhich );
+ else
+ {
+ OUString aOldName = pDocShell->GetDocument().GetPageStyle( pPreview->GetTab() );
+ ScStyleSheetPool* pStylePool = pDocShell->GetDocument().GetStyleSheetPool();
+ SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aOldName, SfxStyleFamily::Page );
+ OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" );
+
+ if ( pStyleSheet )
+ {
+ SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
+ sal_uInt16 nCurrentZoom = rStyleSet.Get(ATTR_PAGE_SCALE).GetValue();
+ if( nCurrentZoom )
+ {
+ SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM_SLIDER, MAXZOOM_SLIDER, SID_PREVIEW_SCALINGFACTOR );
+ aZoomSliderItem.AddSnappingPoint( 100 );
+ rSet.Put( aZoomSliderItem );
+ }
+ else
+ rSet.DisableItem( nWhich );
+ }
+ }
+ }
+ break;
+ case SID_STATUS_DOCPOS:
+ rSet.Put( SfxStringItem( nWhich, pPreview->GetPosString() ) );
+ break;
+ case SID_PRINTPREVIEW:
+ rSet.Put( SfxBoolItem( nWhich, true ) );
+ break;
+ case SID_FORMATPAGE:
+ case SID_PREVIEW_MARGIN:
+ if( pDocShell->IsReadOnly() )
+ rSet.DisableItem( nWhich );
+ break;
+ }
+
+ nWhich = aIter.NextWhich();
+ }
+
+ pPreview->SetInGetState(false);
+}
+
+void ScPreviewShell::FillFieldData( ScHeaderFieldData& rData )
+{
+ ScDocument& rDoc = pDocShell->GetDocument();
+ SCTAB nTab = pPreview->GetTab();
+ OUString aTmp;
+ rDoc.GetName(nTab, aTmp);
+ rData.aTabName = aTmp;
+
+ if( pDocShell->getDocProperties()->getTitle().getLength() != 0 )
+ rData.aTitle = pDocShell->getDocProperties()->getTitle();
+ else
+ rData.aTitle = pDocShell->GetTitle();
+
+ const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
+ rData.aLongDocName = rURLObj.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous );
+ if ( !rData.aLongDocName.isEmpty() )
+ rData.aShortDocName = rURLObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
+ else
+ rData.aShortDocName = rData.aLongDocName = rData.aTitle;
+ rData.nPageNo = pPreview->GetPageNo() + 1;
+
+ bool bAllTested = pPreview->AllTested();
+ if (bAllTested)
+ rData.nTotalPages = pPreview->GetTotalPages();
+ else
+ rData.nTotalPages = 99;
+
+ // the dialog knows eNumType
+}
+
+void ScPreviewShell::WriteUserData(OUString& rData, bool /* bBrowse */)
+{
+ // nZoom
+ // nPageNo
+
+ rData = OUString::number(pPreview->GetZoom())
+ + OUStringChar(SC_USERDATA_SEP)
+ + OUString::number(pPreview->GetPageNo());
+}
+
+void ScPreviewShell::ReadUserData(const OUString& rData, bool /* bBrowse */)
+{
+ if (!rData.isEmpty())
+ {
+ sal_Int32 nIndex = 0;
+ pPreview->SetZoom(static_cast<sal_uInt16>(o3tl::toInt32(o3tl::getToken(rData, 0, SC_USERDATA_SEP, nIndex))));
+ pPreview->SetPageNo(o3tl::toInt32(o3tl::getToken(rData, 0, SC_USERDATA_SEP, nIndex)));
+ eZoom = SvxZoomType::PERCENT;
+ }
+}
+
+void ScPreviewShell::WriteUserDataSequence(uno::Sequence < beans::PropertyValue >& rSeq)
+{
+ // tdf#130559: don't export preview view data if active
+ if (comphelper::IsContextFlagActive("NoPreviewData"))
+ return;
+
+ rSeq.realloc(3);
+ beans::PropertyValue* pSeq = rSeq.getArray();
+ sal_uInt16 nViewID(GetViewFrame()->GetCurViewId());
+ pSeq[0].Name = SC_VIEWID;
+ pSeq[0].Value <<= SC_VIEW + OUString::number(nViewID);
+ pSeq[1].Name = SC_ZOOMVALUE;
+ pSeq[1].Value <<= sal_Int32 (pPreview->GetZoom());
+ pSeq[2].Name = "PageNumber";
+ pSeq[2].Value <<= pPreview->GetPageNo();
+
+ // Common SdrModel processing
+ if (ScDrawLayer* pDrawLayer = GetDocument().GetDrawLayer())
+ pDrawLayer->WriteUserDataSequence(rSeq);
+}
+
+void ScPreviewShell::ReadUserDataSequence(const uno::Sequence < beans::PropertyValue >& rSeq)
+{
+ for (const auto& propval : rSeq)
+ {
+ if (propval.Name == SC_ZOOMVALUE)
+ {
+ sal_Int32 nTemp = 0;
+ if (propval.Value >>= nTemp)
+ pPreview->SetZoom(sal_uInt16(nTemp));
+ }
+ else if (propval.Name == "PageNumber")
+ {
+ sal_Int32 nTemp = 0;
+ if (propval.Value >>= nTemp)
+ pPreview->SetPageNo(nTemp);
+ }
+ // Fallback to common SdrModel processing
+ else
+ pDocShell->MakeDrawLayer()->ReadUserDataSequenceValue(&propval);
+ }
+}
+
+void ScPreviewShell::DoScroll( sal_uInt16 nMode )
+{
+ Point aCurPos, aPrevPos;
+
+ tools::Long nHRange = pHorScroll->GetRange().Max();
+ tools::Long nHLine = pHorScroll->GetLineSize();
+ tools::Long nHPage = pHorScroll->GetPageSize();
+ tools::Long nVRange = pVerScroll->GetRange().Max();
+ tools::Long nVLine = pVerScroll->GetLineSize();
+ tools::Long nVPage = pVerScroll->GetPageSize();
+
+ aCurPos.setX( pHorScroll->GetThumbPos() );
+ aCurPos.setY( pVerScroll->GetThumbPos() );
+ aPrevPos = aCurPos;
+
+ tools::Long nThumbPos = pVerScroll->GetThumbPos();
+ tools::Long nRangeMax = pVerScroll->GetRangeMax();
+
+ switch( nMode )
+ {
+ case SID_CURSORUP:
+ if( nMaxVertPos<0 )
+ {
+ tools::Long nPage = pPreview->GetPageNo();
+
+ if( nPage>0 )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_PREVIOUS );
+ Execute( aSfxRequest );
+ }
+ }
+ else
+ aCurPos.AdjustY( -nVLine );
+ break;
+ case SID_CURSORDOWN:
+ if( nMaxVertPos<0 )
+ {
+ tools::Long nPage = pPreview->GetPageNo();
+ tools::Long nTotal = pPreview->GetTotalPages();
+
+ // before testing for last page, make sure all page counts are calculated
+ if ( nPage+1 == nTotal && !pPreview->AllTested() )
+ {
+ pPreview->CalcAll();
+ nTotal = pPreview->GetTotalPages();
+ }
+
+ if( nPage<nTotal-1 )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_NEXT );
+ Execute( aSfxRequest );
+ }
+ }
+ else
+ aCurPos.AdjustY(nVLine );
+ break;
+ case SID_CURSORLEFT:
+ aCurPos.AdjustX( -nHLine );
+ break;
+ case SID_CURSORRIGHT:
+ aCurPos.AdjustX(nHLine );
+ break;
+ case SID_CURSORPAGEUP:
+ if( nThumbPos==0 || nMaxVertPos<0 )
+ {
+ tools::Long nPage = pPreview->GetPageNo();
+
+ if( nPage>0 )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_PREVIOUS );
+ Execute( aSfxRequest );
+ aCurPos.setY( nVRange );
+ }
+ }
+ else
+ aCurPos.AdjustY( -nVPage );
+ break;
+ case SID_CURSORPAGEDOWN:
+ if( (std::abs(nVPage+nThumbPos-nRangeMax)<10) || nMaxVertPos<0 )
+ {
+ tools::Long nPage = pPreview->GetPageNo();
+ tools::Long nTotal = pPreview->GetTotalPages();
+
+ // before testing for last page, make sure all page counts are calculated
+ if ( nPage+1 == nTotal && !pPreview->AllTested() )
+ {
+ pPreview->CalcAll();
+ nTotal = pPreview->GetTotalPages();
+ }
+ if( nPage<nTotal-1 )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_NEXT );
+ Execute( aSfxRequest );
+ aCurPos.setY( 0 );
+ }
+ }
+ else
+ aCurPos.AdjustY(nVPage );
+ break;
+ case SID_CURSORHOME:
+ if( nMaxVertPos<0 )
+ {
+ tools::Long nPage = pPreview->GetPageNo();
+ tools::Long nTotal = pPreview->GetTotalPages();
+ if( nTotal && nPage != 0 )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_FIRST );
+ Execute( aSfxRequest );
+ }
+ }
+ else
+ {
+ aCurPos.setY( 0 );
+ aCurPos.setX( 0 );
+ }
+ break;
+ case SID_CURSOREND:
+ if( nMaxVertPos<0 )
+ {
+ if( !pPreview->AllTested() )
+ pPreview->CalcAll();
+ tools::Long nPage = pPreview->GetPageNo();
+ tools::Long nTotal = pPreview->GetTotalPages();
+ if( nTotal && nPage+1 != nTotal )
+ {
+ SfxViewFrame* pSfxViewFrame = GetViewFrame();
+ SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_LAST );
+ Execute( aSfxRequest );
+ }
+ }
+ else
+ {
+ aCurPos.setY( nVRange );
+ aCurPos.setX( nHRange );
+ }
+ break;
+ }
+
+ // nHRange-nHPage might be negative, that's why we check for < 0 afterwards
+
+ if( aCurPos.Y() > (nVRange-nVPage) )
+ aCurPos.setY( nVRange-nVPage );
+ if( aCurPos.Y() < 0 )
+ aCurPos.setY( 0 );
+ if( aCurPos.X() > (nHRange-nHPage) )
+ aCurPos.setX( nHRange-nHPage );
+ if( aCurPos.X() < 0 )
+ aCurPos.setX( 0 );
+
+ if( nMaxVertPos>=0 )
+ {
+ if( aCurPos.Y() != aPrevPos.Y() )
+ {
+ pVerScroll->SetThumbPos( aCurPos.Y() );
+ pPreview->SetYOffset( aCurPos.Y() );
+ }
+ }
+
+ if( aCurPos.X() != aPrevPos.X() )
+ {
+ pHorScroll->SetThumbPos( aCurPos.X() );
+ pPreview->SetXOffset( aCurPos.X() );
+ }
+
+}
+
+void ScPreviewShell::ExitPreview()
+{
+ GetViewFrame()->GetDispatcher()->Execute(SID_VIEWSHELL0, SfxCallMode::ASYNCHRON);
+}
+
+void ScPreviewShell::AddAccessibilityObject( SfxListener& rObject )
+{
+ if (!pAccessibilityBroadcaster)
+ pAccessibilityBroadcaster.reset( new SfxBroadcaster );
+
+ rObject.StartListening( *pAccessibilityBroadcaster );
+}
+
+void ScPreviewShell::RemoveAccessibilityObject( SfxListener& rObject )
+{
+ if (pAccessibilityBroadcaster)
+ rObject.EndListening( *pAccessibilityBroadcaster );
+ else
+ {
+ OSL_FAIL("no accessibility broadcaster?");
+ }
+}
+
+void ScPreviewShell::BroadcastAccessibility( const SfxHint &rHint )
+{
+ if (pAccessibilityBroadcaster)
+ pAccessibilityBroadcaster->Broadcast( rHint );
+}
+
+bool ScPreviewShell::HasAccessibilityObjects() const
+{
+ return pAccessibilityBroadcaster && pAccessibilityBroadcaster->HasListeners();
+}
+
+const ScPreviewLocationData& ScPreviewShell::GetLocationData()
+{
+ return pPreview->GetLocationData();
+}
+
+ScDocument& ScPreviewShell::GetDocument()
+{
+ return pDocShell->GetDocument();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */