1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <scitems.hxx>
24 #include <comphelper/SetFlagContextHelper.hxx>
25 #include <sfx2/app.hxx>
26 #include <editeng/sizeitem.hxx>
27 #include <svx/zoomslideritem.hxx>
28 #include <svx/svdview.hxx>
29 #include <sfx2/dispatch.hxx>
30 #include <sfx2/objface.hxx>
31 #include <sfx2/request.hxx>
32 #include <svl/stritem.hxx>
33 #include <svl/whiter.hxx>
34 #include <vcl/commandevent.hxx>
35 #include <vcl/help.hxx>
36 #include <vcl/settings.hxx>
37 #include <vcl/svapp.hxx>
38 #include <tools/urlobj.hxx>
39 #include <sfx2/docfile.hxx>
40 #include <sfx2/printer.hxx>
41 #include <sfx2/viewfrm.hxx>
42 #include <sfx2/viewfac.hxx>
43 #include <o3tl/unit_conversion.hxx>
44 #include <o3tl/string_view.hxx>
46 #include <drwlayer.hxx>
47 #include <prevwsh.hxx>
48 #include <preview.hxx>
49 #include <printfun.hxx>
51 #include <inputhdl.hxx>
53 #include <tabvwsh.hxx>
54 #include <stlpool.hxx>
55 #include <editutil.hxx>
56 #include <globstr.hrc>
57 #include <scresid.hxx>
59 #include <ViewSettingsSequenceDefines.hxx>
60 #include <viewuno.hxx>
62 #include <svx/svxdlg.hxx>
63 #include <svx/dialogs.hrc>
65 #include <basegfx/utils/zoomtools.hxx>
66 #include <svx/zoom_def.hxx>
67 #include <com/sun/star/document/XDocumentProperties.hpp>
69 #include <scabstdlg.hxx>
70 #include <vcl/EnumContext.hxx>
73 #define MINZOOM_SLIDER 10
74 #define MAXZOOM_SLIDER 400
76 #define SC_USERDATA_SEP ';'
78 using namespace com::sun::star
;
80 #define ShellClass_ScPreviewShell
81 #include <scslots.hxx>
86 SFX_IMPL_INTERFACE(ScPreviewShell
, SfxViewShell
)
88 void ScPreviewShell::InitInterface_Impl()
90 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT
,
91 SfxVisibilityFlags::Standard
|SfxVisibilityFlags::Server
|SfxVisibilityFlags::ReadonlyDoc
,
92 ToolbarId::Objectbar_Preview
);
94 GetStaticInterface()->RegisterPopupMenu(u
"preview"_ustr
);
97 SFX_IMPL_NAMED_VIEWFACTORY( ScPreviewShell
, "PrintPreview" )
99 SFX_VIEW_REGISTRATION(ScDocShell
);
102 void ScPreviewShell::Construct( vcl::Window
* pParent
)
104 // Find the top-most window, and set the close window handler to intercept
105 // the window close event.
106 vcl::Window
* pWin
= pParent
;
107 while (!pWin
->IsSystemWindow())
109 if (pWin
->GetParent())
110 pWin
= pWin
->GetParent();
115 mpFrameWindow
= dynamic_cast<SystemWindow
*>(pWin
);
117 mpFrameWindow
->SetCloseHdl(LINK(this, ScPreviewShell
, CloseHdl
));
119 eZoom
= SvxZoomType::WHOLEPAGE
;
121 pHorScroll
= VclPtr
<ScrollAdaptor
>::Create(pParent
, true);
122 pVerScroll
= VclPtr
<ScrollAdaptor
>::Create(pParent
, false);
124 // RTL: no mirroring for horizontal scrollbars
125 pHorScroll
->EnableRTL( false );
127 pHorScroll
->SetScrollHdl(LINK(this, ScPreviewShell
, HorzScrollHandler
));
128 pVerScroll
->SetScrollHdl(LINK(this, ScPreviewShell
, VertScrollHandler
));
130 pPreview
= VclPtr
<ScPreview
>::Create( pParent
, pDocShell
, this );
132 SetPool(&ScModule::get()->GetPool());
133 SetWindow( pPreview
);
134 StartListening(*pDocShell
, DuplicateHandling::Prevent
);
135 StartListening(*SfxGetpApp(), DuplicateHandling::Prevent
); // #i62045# #i62046# application is needed for Calc's own hints
136 SfxBroadcaster
* pDrawBC
= pDocShell
->GetDocument().GetDrawBroadcaster();
138 StartListening(*pDrawBC
);
140 pHorScroll
->Show( false );
141 pVerScroll
->Show( false );
142 SetName(u
"Preview"_ustr
);
145 ScPreviewShell::ScPreviewShell(SfxViewFrame
& rViewFrame
,
146 SfxViewShell
* pOldSh
) :
147 SfxViewShell(rViewFrame
, SfxViewShellFlags::HAS_PRINTOPTIONS
),
148 pDocShell( static_cast<ScDocShell
*>(rViewFrame
.GetObjectShell()) ),
149 mpFrameWindow(nullptr),
150 nSourceDesignMode( TRISTATE_INDET
),
155 Construct(&rViewFrame
.GetWindow());
156 SfxShell::SetContextName(vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Printpreview
));
158 if ( auto pTabViewShell
= dynamic_cast<ScTabViewShell
*>( pOldSh
) )
160 // store view settings, show table from TabView
161 //! store live ScViewData instead, and update on ScTablesHint?
162 //! or completely forget aSourceData on ScTablesHint?
164 const ScViewData
& rData
= pTabViewShell
->GetViewData();
165 pPreview
->SetSelectedTabs(rData
.GetMarkData());
166 InitStartTable( rData
.GetTabNo() );
168 // also have to store the TabView's DesignMode state
169 // (only if draw view exists)
170 SdrView
* pDrawView
= pTabViewShell
->GetScDrawView();
173 = pDrawView
->IsDesignMode() ? TRISTATE_TRUE
: TRISTATE_FALSE
;
176 new ScPreviewObj(this);
179 ScPreviewShell::~ScPreviewShell()
182 mpFrameWindow
->SetCloseHdl(Link
<SystemWindow
&,void>()); // Remove close handler.
184 // #108333#; notify Accessibility that Shell is dying and before destroy all
185 BroadcastAccessibility( SfxHint( SfxHintId::Dying
) );
186 pAccessibilityBroadcaster
.reset();
188 SfxBroadcaster
* pDrawBC
= pDocShell
->GetDocument().GetDrawBroadcaster();
190 EndListening(*pDrawBC
);
191 EndListening(*SfxGetpApp());
192 EndListening(*pDocShell
);
195 pPreview
.disposeAndClear();
196 pHorScroll
.disposeAndClear();
197 pVerScroll
.disposeAndClear();
199 // normal mode of operation is switching back to default view in the same frame,
200 // so there's no need to activate any other window here anymore
203 void ScPreviewShell::InitStartTable(SCTAB nTab
)
205 pPreview
->SetPageNo( pPreview
->GetFirstPage(nTab
) );
208 void ScPreviewShell::AdjustPosSizePixel( const Point
&rPos
, const Size
&rSize
)
210 Size
aOutSize( rSize
);
211 pPreview
->SetPosSizePixel( rPos
, aOutSize
);
213 if ( SvxZoomType::WHOLEPAGE
== eZoom
)
214 pPreview
->SetZoom( pPreview
->GetOptimalZoom(false) );
215 else if ( SvxZoomType::PAGEWIDTH
== eZoom
)
216 pPreview
->SetZoom( pPreview
->GetOptimalZoom(true) );
218 UpdateNeededScrollBars(false);
221 void ScPreviewShell::InnerResizePixel( const Point
&rOfs
, const Size
&rSize
, bool )
223 AdjustPosSizePixel( rOfs
,rSize
);
226 void ScPreviewShell::OuterResizePixel( const Point
&rOfs
, const Size
&rSize
)
228 AdjustPosSizePixel( rOfs
,rSize
);
231 bool ScPreviewShell::GetPageSize( Size
& aPageSize
)
233 ScDocument
& rDoc
= pDocShell
->GetDocument();
234 SCTAB nTab
= pPreview
->GetTab();
236 ScStyleSheetPool
* pStylePool
= rDoc
.GetStyleSheetPool();
237 SfxStyleSheetBase
* pStyleSheet
= pStylePool
->Find( rDoc
.GetPageStyle( nTab
),
238 SfxStyleFamily::Page
);
239 OSL_ENSURE(pStyleSheet
,"No style sheet");
240 if (!pStyleSheet
) return false;
241 const SfxItemSet
* pParamSet
= &pStyleSheet
->GetItemSet();
243 aPageSize
= pParamSet
->Get(ATTR_PAGE_SIZE
).GetSize();
244 aPageSize
.setWidth(o3tl::convert(aPageSize
.Width(), o3tl::Length::twip
, o3tl::Length::mm100
));
245 aPageSize
.setHeight(o3tl::convert(aPageSize
.Height(), o3tl::Length::twip
, o3tl::Length::mm100
));
249 void ScPreviewShell::UpdateNeededScrollBars( bool bFromZoom
)
252 OutputDevice
* pDevice
= Application::GetDefaultDevice();
254 tools::Long nBarW
= GetViewFrame().GetWindow().GetSettings().GetStyleSettings().GetScrollBarSize();
255 tools::Long nBarH
= nBarW
;
257 tools::Long aHeightOffSet
= pDevice
? pDevice
->PixelToLogic( Size( nBarW
, nBarH
), pPreview
->GetMapMode() ).Height() : 0;
258 tools::Long aWidthOffSet
= aHeightOffSet
;
260 if (!GetPageSize( aPageSize
))
263 // for centering, page size without the shadow is used
264 bool bVert
= pVerScroll
->IsVisible();
265 bool bHori
= pHorScroll
->IsVisible();
266 Size aWindowSize
= pPreview
->GetOutDev()->GetOutputSize();
267 Point aPos
= pPreview
->GetPosPixel();
268 Size aWindowPixelSize
= pPreview
->GetOutputSizePixel();
270 // if we are called from Zoom then we need to compensate for whatever
271 // scrollbars were displayed before the zoom was called
276 aWindowPixelSize
.AdjustWidth(nBarH
);
277 aWindowSize
.AdjustWidth(aHeightOffSet
);
281 aWindowPixelSize
.AdjustHeight(nBarW
);
282 aWindowSize
.AdjustHeight(aWidthOffSet
);
286 // recalculate any needed scrollbars
287 tools::Long nMaxWidthPos
= aPageSize
.Width() - aWindowSize
.Width();
288 bHori
= nMaxWidthPos
>= 0;
289 tools::Long nMaxHeightPos
= aPageSize
.Height() - aWindowSize
.Height();
290 bVert
= nMaxHeightPos
>= 0;
292 // see if having a scroll bar requires the other
293 if ( bVert
!= bHori
&& ( bVert
|| bHori
) )
295 if ( bVert
&& ( (nMaxWidthPos
+ aWidthOffSet
) > 0 ) )
297 else if ( (nMaxHeightPos
+ aHeightOffSet
) > 0 )
300 pHorScroll
->Show( bHori
);
301 pVerScroll
->Show( bVert
);
303 // make room for needed scrollbars ( and reduce the size
304 // of the preview appropriately )
306 aWindowPixelSize
.AdjustHeight( -nBarW
);
308 aWindowPixelSize
.AdjustWidth( -nBarH
);
310 pPreview
->SetSizePixel( aWindowPixelSize
);
311 pHorScroll
->SetPosSizePixel( Point( aPos
.X(), aPos
.Y() + aWindowPixelSize
.Height() ),
312 Size( aWindowPixelSize
.Width(), nBarH
) );
313 pVerScroll
->SetPosSizePixel( Point( aPos
.X() + aWindowPixelSize
.Width(), aPos
.Y() ),
314 Size( nBarW
, aWindowPixelSize
.Height() ) );
318 void ScPreviewShell::UpdateScrollBars()
321 if ( !GetPageSize( aPageSize
) )
324 // for centering, page size without the shadow is used
326 Size aWindowSize
= pPreview
->GetOutDev()->GetOutputSize();
328 Point aOfs
= pPreview
->GetOffset();
332 pHorScroll
->SetRange( Range( 0, aPageSize
.Width() ) );
333 pHorScroll
->SetLineSize( aWindowSize
.Width() / 16 );
334 pHorScroll
->SetPageSize( aWindowSize
.Width() );
335 pHorScroll
->SetVisibleSize( aWindowSize
.Width() );
336 tools::Long nMaxPos
= aPageSize
.Width() - aWindowSize
.Width();
339 // page smaller than window -> center (but put scrollbar to 0)
341 pPreview
->SetXOffset( nMaxPos
/ 2 );
343 else if (aOfs
.X() < 0)
345 // page larger than window -> never use negative offset
347 pPreview
->SetXOffset( 0 );
349 else if (aOfs
.X() > nMaxPos
)
351 // limit offset to align with right edge of window
352 aOfs
.setX( nMaxPos
);
353 pPreview
->SetXOffset(nMaxPos
);
355 pHorScroll
->SetThumbPos( aOfs
.X() );
356 nPrevHThumbPos
= pHorScroll
->GetThumbPos();
362 tools::Long nPageNo
= pPreview
->GetPageNo();
363 tools::Long nTotalPages
= pPreview
->GetTotalPages();
365 nMaxVertPos
= aPageSize
.Height() - aWindowSize
.Height();
366 pVerScroll
->SetLineSize( aWindowSize
.Height() / 16 );
367 pVerScroll
->SetPageSize( aWindowSize
.Height() );
368 pVerScroll
->SetVisibleSize( aWindowSize
.Height() );
369 if ( nMaxVertPos
< 0 )
371 // page smaller than window -> center (but put scrollbar to 0)
373 pPreview
->SetYOffset( nMaxVertPos
/ 2 );
374 pVerScroll
->SetThumbPos( nPageNo
* aWindowSize
.Height() );
375 pVerScroll
->SetRange( Range( 0, aWindowSize
.Height() * nTotalPages
));
377 else if (aOfs
.Y() < 0)
379 // page larger than window -> never use negative offset
380 pVerScroll
->SetRange( Range( 0, aPageSize
.Height() ) );
382 pPreview
->SetYOffset( 0 );
383 pVerScroll
->SetThumbPos( aOfs
.Y() );
385 else if (aOfs
.Y() > nMaxVertPos
)
387 // limit offset to align with window bottom
388 pVerScroll
->SetRange( Range( 0, aPageSize
.Height() ) );
389 aOfs
.setY( nMaxVertPos
);
390 pPreview
->SetYOffset( nMaxVertPos
);
391 pVerScroll
->SetThumbPos( aOfs
.Y() );
393 nPrevVThumbPos
= pVerScroll
->GetThumbPos();
396 IMPL_LINK_NOARG(ScPreviewShell
, HorzScrollHandler
, weld::Scrollbar
&, void)
398 ScrollHandler(pHorScroll
);
401 IMPL_LINK_NOARG(ScPreviewShell
, VertScrollHandler
, weld::Scrollbar
&, void)
403 ScrollHandler(pVerScroll
);
406 void ScPreviewShell::ScrollHandler(ScrollAdaptor
* pScroll
)
408 tools::Long nPos
= pScroll
->GetThumbPos();
409 tools::Long nMaxRange
= pScroll
->GetRangeMax();
410 tools::Long nTotalPages
= pPreview
->GetTotalPages();
411 tools::Long nPageNo
= 0;
412 tools::Long nPerPageLength
= 0;
413 bool bIsDivide
= true;
416 nPerPageLength
= nMaxRange
/ nTotalPages
;
420 nPageNo
= nPos
/ nPerPageLength
;
421 if( nPos
% nPerPageLength
)
428 bool bHoriz
= ( pScroll
== pHorScroll
);
430 tools::Long nDelta
= bHoriz
? (pHorScroll
->GetThumbPos() - nPrevHThumbPos
)
431 : (pVerScroll
->GetThumbPos() - nPrevVThumbPos
);
434 pPreview
->SetXOffset( nPos
);
437 if( nMaxVertPos
> 0 )
438 pPreview
->SetYOffset( nPos
);
441 Point aMousePos
= pScroll
->OutputToNormalizedScreenPixel( pScroll
->GetPointerPosPixel() );
442 Point aPos
= pScroll
->GetParent()->OutputToNormalizedScreenPixel( pScroll
->GetPosPixel() );
444 tools::Rectangle aRect
;
445 QuickHelpFlags nAlign
;
449 if ( nTotalPages
&& nPageNo
> 0 && !bIsDivide
)
450 pPreview
->SetPageNo( nPageNo
-1 );
452 pPreview
->SetPageNo( nPageNo
);
454 aHelpStr
= ScResId( STR_PAGE
) +
455 " " + OUString::number( nPageNo
) +
456 " / " + OUString::number( nTotalPages
);
458 else if( nDelta
> 0 )
460 bool bAllTested
= pPreview
->AllTested();
461 if ( nTotalPages
&& ( nPageNo
< nTotalPages
|| !bAllTested
) )
462 pPreview
->SetPageNo( nPageNo
);
464 aHelpStr
= ScResId( STR_PAGE
) +
465 " " + OUString::number( nPageNo
+1 ) +
466 " / " + OUString::number( nTotalPages
);
469 aRect
.SetLeft( aPos
.X() - 8 );
470 aRect
.SetTop( aMousePos
.Y() );
471 aRect
.SetRight( aRect
.Left() );
472 aRect
.SetBottom( aRect
.Top() );
473 nAlign
= QuickHelpFlags::Bottom
|QuickHelpFlags::Center
;
474 Help::ShowQuickHelp( pScroll
->GetParent(), aRect
, aHelpStr
, nAlign
);
479 IMPL_LINK_NOARG(ScPreviewShell
, CloseHdl
, SystemWindow
&, void)
484 bool ScPreviewShell::ScrollCommand( const CommandEvent
& rCEvt
)
487 const CommandWheelData
* pData
= rCEvt
.GetWheelData();
488 if ( pData
&& pData
->GetMode() == CommandWheelMode::ZOOM
)
490 sal_uInt16 nOld
= pPreview
->GetZoom();
492 if ( pData
->GetDelta() < 0 )
493 nNew
= std::max( MINZOOM
, basegfx::zoomtools::zoomOut( nOld
));
495 nNew
= std::min( MAXZOOM
, basegfx::zoomtools::zoomIn( nOld
));
499 eZoom
= SvxZoomType::PERCENT
;
500 pPreview
->SetZoom( nNew
);
507 bDone
= pPreview
->HandleScrollCommand( rCEvt
, pHorScroll
, pVerScroll
);
513 SfxPrinter
* ScPreviewShell::GetPrinter( bool bCreate
)
515 return pDocShell
->GetPrinter(bCreate
);
518 sal_uInt16
ScPreviewShell::SetPrinter( SfxPrinter
*pNewPrinter
, SfxPrinterChangeFlags nDiffFlags
)
520 return pDocShell
->SetPrinter( pNewPrinter
, nDiffFlags
);
523 bool ScPreviewShell::HasPrintOptionsPage() const
528 std::unique_ptr
<SfxTabPage
> ScPreviewShell::CreatePrintOptionsPage(weld::Container
* pPage
, weld::DialogController
* pController
, const SfxItemSet
&rOptions
)
530 ScAbstractDialogFactory
* pFact
= ScAbstractDialogFactory::Create();
531 ::CreateTabPage ScTpPrintOptionsCreate
= pFact
->GetTabPageCreatorFunc(RID_SC_TP_PRINT
);
532 if ( ScTpPrintOptionsCreate
)
533 return ScTpPrintOptionsCreate(pPage
, pController
, &rOptions
);
537 void ScPreviewShell::Activate(bool bMDI
)
539 SfxViewShell::Activate(bMDI
);
541 //! Basic etc. -> outsource to its own file (see tabvwsh4)
545 // InputHdl is now mostly Null, no more assertion!
546 ScInputHandler
* pInputHdl
= ScModule::get()->GetInputHdl();
548 pInputHdl
->NotifyChange( nullptr );
551 SfxShell::Activate(bMDI
);
554 void ScPreviewShell::Execute( SfxRequest
& rReq
)
556 sal_uInt16 nSlot
= rReq
.GetSlot();
557 const SfxItemSet
* pReqArgs
= rReq
.GetArgs();
562 case SID_STATUS_PAGESTYLE
:
564 pDocShell
->ExecutePageStyle( *this, rReq
, pPreview
->GetTab() );
567 pPreview
->Invalidate();
570 case SID_PREV_TABLE
: // Accelerator
571 case SID_PREVIEW_PREVIOUS
:
573 tools::Long nPage
= pPreview
->GetPageNo();
574 tools::Long nTotal
= pPreview
->GetTotalPages();
575 if (nTotal
&& nPage
> 0)
576 pPreview
->SetPageNo( nPage
-1 );
579 case SID_NEXT_TABLE
: // Accelerator
580 case SID_PREVIEW_NEXT
:
582 bool bAllTested
= pPreview
->AllTested();
583 tools::Long nPage
= pPreview
->GetPageNo();
584 tools::Long nTotal
= pPreview
->GetTotalPages();
585 if (nTotal
&& (nPage
+1 < nTotal
|| !bAllTested
))
586 pPreview
->SetPageNo( nPage
+1 );
589 case SID_CURSORTOPOFFILE
: // Accelerator
590 case SID_PREVIEW_FIRST
:
592 tools::Long nPage
= pPreview
->GetPageNo();
593 tools::Long nTotal
= pPreview
->GetTotalPages();
594 if (nTotal
&& nPage
!= 0)
595 pPreview
->SetPageNo( 0 );
598 case SID_CURSORENDOFFILE
: // Accelerator
599 case SID_PREVIEW_LAST
:
601 if (!pPreview
->AllTested())
604 tools::Long nPage
= pPreview
->GetPageNo();
605 tools::Long nTotal
= pPreview
->GetTotalPages();
606 if (nTotal
&& nPage
+1 != nTotal
)
607 pPreview
->SetPageNo( nTotal
-1 );
613 sal_uInt16 nZoom
= 100;
614 bool bCancel
= false;
616 eZoom
= SvxZoomType::PERCENT
;
621 const SvxZoomItem
& rZoomItem
= pReqArgs
->Get(SID_ATTR_ZOOM
);
623 eZoom
= rZoomItem
.GetType();
624 nZoom
= rZoomItem
.GetValue();
628 SfxItemSetFixed
<SID_ATTR_ZOOM
, SID_ATTR_ZOOM
> aSet( GetPool() );
629 SvxZoomItem
aZoomItem( SvxZoomType::PERCENT
, pPreview
->GetZoom(), SID_ATTR_ZOOM
);
631 aSet
.Put( aZoomItem
);
632 SvxAbstractDialogFactory
* pFact
= SvxAbstractDialogFactory::Create();
633 ScopedVclPtr
<AbstractSvxZoomDialog
> pDlg(pFact
->CreateSvxZoomDialog(nullptr, aSet
));
634 pDlg
->SetLimits( 20, 400 );
635 pDlg
->HideButton( ZoomButtonId::OPTIMAL
);
636 bCancel
= ( RET_CANCEL
== pDlg
->Execute() );
640 const SvxZoomItem
& rZoomItem
= pDlg
->GetOutputItemSet()->
641 Get( SID_ATTR_ZOOM
);
643 eZoom
= rZoomItem
.GetType();
644 nZoom
= rZoomItem
.GetValue();
652 case SvxZoomType::OPTIMAL
:
653 case SvxZoomType::WHOLEPAGE
:
654 nZoom
= pPreview
->GetOptimalZoom(false);
656 case SvxZoomType::PAGEWIDTH
:
657 nZoom
= pPreview
->GetOptimalZoom(true);
661 // added to avoid warnings
665 pPreview
->SetZoom( nZoom
);
674 const sal_uInt16 nOldZoom
{pPreview
->GetZoom()};
675 if(SID_ZOOM_OUT
== nSlot
)
676 nNewZoom
= basegfx::zoomtools::zoomOut(nOldZoom
);
678 nNewZoom
= basegfx::zoomtools::zoomIn(nOldZoom
);
680 pPreview
->SetZoom(nNewZoom
);
681 eZoom
= SvxZoomType::PERCENT
;
685 case SID_PREVIEW_MARGIN
:
687 bool bMargin
= pPreview
->GetPageMargins();
688 pPreview
->SetPageMargins( !bMargin
);
689 pPreview
->Invalidate();
693 case SID_ATTR_ZOOMSLIDER
:
695 const SvxZoomSliderItem
* pItem
;
696 eZoom
= SvxZoomType::PERCENT
;
697 if( pReqArgs
&& (pItem
= pReqArgs
->GetItemIfSet( SID_ATTR_ZOOMSLIDER
)) )
699 const sal_uInt16 nCurrentZoom
= pItem
->GetValue();
702 pPreview
->SetZoom( nCurrentZoom
);
708 case SID_PREVIEW_SCALINGFACTOR
:
710 const SvxZoomSliderItem
* pItem
;
711 SCTAB nTab
= pPreview
->GetTab();
712 OUString aOldName
= pDocShell
->GetDocument().GetPageStyle( pPreview
->GetTab() );
713 ScStyleSheetPool
* pStylePool
= pDocShell
->GetDocument().GetStyleSheetPool();
714 SfxStyleSheetBase
* pStyleSheet
= pStylePool
->Find( aOldName
, SfxStyleFamily::Page
);
715 OSL_ENSURE( pStyleSheet
, "PageStyle not found! :-/" );
717 if ( pReqArgs
&& pStyleSheet
&& (pItem
= pReqArgs
->GetItemIfSet( SID_PREVIEW_SCALINGFACTOR
)) )
719 const sal_uInt16 nCurrentZoom
= pItem
->GetValue();
720 SfxItemSet
& rSet
= pStyleSheet
->GetItemSet();
721 rSet
.Put( SfxUInt16Item( ATTR_PAGE_SCALE
, nCurrentZoom
) );
722 ScPrintFunc
aPrintFunc( pDocShell
, pDocShell
->GetPrinter(), nTab
);
723 aPrintFunc
.UpdatePages();
726 GetViewFrame().GetBindings().Invalidate( nSlot
);
729 case SID_PRINTPREVIEW
:
730 case SID_PREVIEW_CLOSE
:
731 // print preview is now always in the same frame as the tab view
732 // -> always switch this frame back to normal view
733 // (ScTabViewShell ctor reads stored view data)
737 case SID_CURSORPAGEUP
:
738 case SID_CURSORPAGEDOWN
:
744 case SID_CURSORRIGHT
:
748 if( ScViewUtil::IsFullScreen( *this ) )
749 ScViewUtil::SetFullScreen( *this, false );
757 void ScPreviewShell::GetState( SfxItemSet
& rSet
)
759 pPreview
->SetInGetState(true);
761 SCTAB nTab
= pPreview
->GetTab();
762 tools::Long nPage
= pPreview
->GetPageNo();
763 tools::Long nTotal
= pPreview
->GetTotalPages();
764 sal_uInt16 nZoom
= pPreview
->GetZoom();
765 bool bAllTested
= pPreview
->AllTested();
767 SfxWhichIter
aIter(rSet
);
768 sal_uInt16 nWhich
= aIter
.FirstWhich();
773 case SID_STATUS_PAGESTYLE
:
775 pDocShell
->GetStatePageStyle( rSet
, nTab
);
782 case SID_MAIL_SENDDOC
:
783 case SID_VIEW_DATA_SOURCE_BROWSER
:
785 rSet
.DisableItem(nWhich
);
787 case SID_PREVIEW_PREVIOUS
:
788 case SID_PREVIEW_FIRST
:
789 if (!nTotal
|| nPage
==0)
790 rSet
.DisableItem(nWhich
);
792 case SID_PREVIEW_NEXT
:
793 case SID_PREVIEW_LAST
:
795 if (!nTotal
|| nPage
==nTotal
-1)
796 rSet
.DisableItem(nWhich
);
800 rSet
.DisableItem(nWhich
);
804 rSet
.DisableItem(nWhich
);
808 SvxZoomItem
aZoom( eZoom
, nZoom
, TypedWhichId
<SvxZoomItem
>(nWhich
) );
809 aZoom
.SetValueSet( SvxZoomEnableFlags::ALL
& ~SvxZoomEnableFlags::OPTIMAL
);
813 case SID_ATTR_ZOOMSLIDER
:
815 SvxZoomSliderItem
aZoomSliderItem( nZoom
, MINZOOM
, MAXZOOM
, SID_ATTR_ZOOMSLIDER
);
816 aZoomSliderItem
.AddSnappingPoint( 100 );
817 rSet
.Put( aZoomSliderItem
);
820 case SID_PREVIEW_SCALINGFACTOR
:
822 if( pDocShell
->IsReadOnly() )
823 rSet
.DisableItem( nWhich
);
826 OUString aOldName
= pDocShell
->GetDocument().GetPageStyle( pPreview
->GetTab() );
827 ScStyleSheetPool
* pStylePool
= pDocShell
->GetDocument().GetStyleSheetPool();
828 SfxStyleSheetBase
* pStyleSheet
= pStylePool
->Find( aOldName
, SfxStyleFamily::Page
);
829 OSL_ENSURE( pStyleSheet
, "PageStyle not found! :-/" );
833 SfxItemSet
& rStyleSet
= pStyleSheet
->GetItemSet();
834 sal_uInt16 nCurrentZoom
= rStyleSet
.Get(ATTR_PAGE_SCALE
).GetValue();
837 SvxZoomSliderItem
aZoomSliderItem( nCurrentZoom
, MINZOOM_SLIDER
, MAXZOOM_SLIDER
, SID_PREVIEW_SCALINGFACTOR
);
838 aZoomSliderItem
.AddSnappingPoint( 100 );
839 rSet
.Put( aZoomSliderItem
);
842 rSet
.DisableItem( nWhich
);
847 case SID_STATUS_DOCPOS
:
848 rSet
.Put( SfxStringItem( nWhich
, pPreview
->GetPosString() ) );
850 case SID_PRINTPREVIEW
:
851 rSet
.Put( SfxBoolItem( nWhich
, true ) );
854 case SID_PREVIEW_MARGIN
:
855 if( pDocShell
->IsReadOnly() )
856 rSet
.DisableItem( nWhich
);
860 nWhich
= aIter
.NextWhich();
863 pPreview
->SetInGetState(false);
866 void ScPreviewShell::FillFieldData( ScHeaderFieldData
& rData
)
868 ScDocument
& rDoc
= pDocShell
->GetDocument();
869 SCTAB nTab
= pPreview
->GetTab();
871 rDoc
.GetName(nTab
, aTmp
);
872 rData
.aTabName
= aTmp
;
874 if( pDocShell
->getDocProperties()->getTitle().getLength() != 0 )
875 rData
.aTitle
= pDocShell
->getDocProperties()->getTitle();
877 rData
.aTitle
= pDocShell
->GetTitle();
879 const INetURLObject
& rURLObj
= pDocShell
->GetMedium()->GetURLObject();
880 rData
.aLongDocName
= rURLObj
.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous
);
881 if ( !rData
.aLongDocName
.isEmpty() )
882 rData
.aShortDocName
= rURLObj
.GetLastName(INetURLObject::DecodeMechanism::Unambiguous
);
884 rData
.aShortDocName
= rData
.aLongDocName
= rData
.aTitle
;
885 rData
.nPageNo
= pPreview
->GetPageNo() + 1;
887 bool bAllTested
= pPreview
->AllTested();
889 rData
.nTotalPages
= pPreview
->GetTotalPages();
891 rData
.nTotalPages
= 99;
893 // the dialog knows eNumType
896 void ScPreviewShell::WriteUserData(OUString
& rData
, bool /* bBrowse */)
901 rData
= OUString::number(pPreview
->GetZoom())
902 + OUStringChar(SC_USERDATA_SEP
)
903 + OUString::number(pPreview
->GetPageNo());
906 void ScPreviewShell::ReadUserData(const OUString
& rData
, bool /* bBrowse */)
908 if (!rData
.isEmpty())
910 sal_Int32 nIndex
= 0;
911 pPreview
->SetZoom(static_cast<sal_uInt16
>(o3tl::toInt32(o3tl::getToken(rData
, 0, SC_USERDATA_SEP
, nIndex
))));
912 pPreview
->SetPageNo(o3tl::toInt32(o3tl::getToken(rData
, 0, SC_USERDATA_SEP
, nIndex
)));
913 eZoom
= SvxZoomType::PERCENT
;
917 void ScPreviewShell::WriteUserDataSequence(uno::Sequence
< beans::PropertyValue
>& rSeq
)
919 // tdf#130559: don't export preview view data if active
920 if (comphelper::IsContextFlagActive(u
"NoPreviewData"_ustr
))
924 beans::PropertyValue
* pSeq
= rSeq
.getArray();
925 sal_uInt16
nViewID(GetViewFrame().GetCurViewId());
926 pSeq
[0].Name
= SC_VIEWID
;
927 pSeq
[0].Value
<<= SC_VIEW
+ OUString::number(nViewID
);
928 pSeq
[1].Name
= SC_ZOOMVALUE
;
929 pSeq
[1].Value
<<= sal_Int32 (pPreview
->GetZoom());
930 pSeq
[2].Name
= "PageNumber";
931 pSeq
[2].Value
<<= pPreview
->GetPageNo();
933 // Common SdrModel processing
934 if (ScDrawLayer
* pDrawLayer
= GetDocument().GetDrawLayer())
935 pDrawLayer
->WriteUserDataSequence(rSeq
);
938 void ScPreviewShell::ReadUserDataSequence(const uno::Sequence
< beans::PropertyValue
>& rSeq
)
940 for (const auto& propval
: rSeq
)
942 if (propval
.Name
== SC_ZOOMVALUE
)
945 if (propval
.Value
>>= nTemp
)
946 pPreview
->SetZoom(sal_uInt16(nTemp
));
948 else if (propval
.Name
== "PageNumber")
951 if (propval
.Value
>>= nTemp
)
952 pPreview
->SetPageNo(nTemp
);
954 // Fallback to common SdrModel processing
956 pDocShell
->MakeDrawLayer()->ReadUserDataSequenceValue(&propval
);
960 void ScPreviewShell::DoScroll( sal_uInt16 nMode
)
962 Point aCurPos
, aPrevPos
;
964 tools::Long nHRange
= pHorScroll
->GetRange().Max();
965 tools::Long nHLine
= pHorScroll
->GetLineSize();
966 tools::Long nHPage
= pHorScroll
->GetPageSize();
967 tools::Long nVRange
= pVerScroll
->GetRange().Max();
968 tools::Long nVLine
= pVerScroll
->GetLineSize();
969 tools::Long nVPage
= pVerScroll
->GetPageSize();
971 aCurPos
.setX( pHorScroll
->GetThumbPos() );
972 aCurPos
.setY( pVerScroll
->GetThumbPos() );
975 tools::Long nThumbPos
= pVerScroll
->GetThumbPos();
976 tools::Long nRangeMax
= pVerScroll
->GetRangeMax();
983 tools::Long nPage
= pPreview
->GetPageNo();
987 SfxViewFrame
& rSfxViewFrame
= GetViewFrame();
988 SfxRequest
aSfxRequest(rSfxViewFrame
, SID_PREVIEW_PREVIOUS
);
989 Execute( aSfxRequest
);
993 aCurPos
.AdjustY( -nVLine
);
998 tools::Long nPage
= pPreview
->GetPageNo();
999 tools::Long nTotal
= pPreview
->GetTotalPages();
1001 // before testing for last page, make sure all page counts are calculated
1002 if ( nPage
+1 == nTotal
&& !pPreview
->AllTested() )
1004 pPreview
->CalcAll();
1005 nTotal
= pPreview
->GetTotalPages();
1008 if( nPage
<nTotal
-1 )
1010 SfxViewFrame
& rSfxViewFrame
= GetViewFrame();
1011 SfxRequest
aSfxRequest(rSfxViewFrame
, SID_PREVIEW_NEXT
);
1012 Execute( aSfxRequest
);
1016 aCurPos
.AdjustY(nVLine
);
1018 case SID_CURSORLEFT
:
1019 aCurPos
.AdjustX( -nHLine
);
1021 case SID_CURSORRIGHT
:
1022 aCurPos
.AdjustX(nHLine
);
1024 case SID_CURSORPAGEUP
:
1025 if( nThumbPos
==0 || nMaxVertPos
<0 )
1027 tools::Long nPage
= pPreview
->GetPageNo();
1031 SfxViewFrame
& rSfxViewFrame
= GetViewFrame();
1032 SfxRequest
aSfxRequest(rSfxViewFrame
, SID_PREVIEW_PREVIOUS
);
1033 Execute( aSfxRequest
);
1034 aCurPos
.setY( nVRange
);
1038 aCurPos
.AdjustY( -nVPage
);
1040 case SID_CURSORPAGEDOWN
:
1041 if( (std::abs(nVPage
+nThumbPos
-nRangeMax
)<10) || nMaxVertPos
<0 )
1043 tools::Long nPage
= pPreview
->GetPageNo();
1044 tools::Long nTotal
= pPreview
->GetTotalPages();
1046 // before testing for last page, make sure all page counts are calculated
1047 if ( nPage
+1 == nTotal
&& !pPreview
->AllTested() )
1049 pPreview
->CalcAll();
1050 nTotal
= pPreview
->GetTotalPages();
1052 if( nPage
<nTotal
-1 )
1054 SfxViewFrame
& rSfxViewFrame
= GetViewFrame();
1055 SfxRequest
aSfxRequest(rSfxViewFrame
, SID_PREVIEW_NEXT
);
1056 Execute( aSfxRequest
);
1061 aCurPos
.AdjustY(nVPage
);
1063 case SID_CURSORHOME
:
1066 tools::Long nPage
= pPreview
->GetPageNo();
1067 tools::Long nTotal
= pPreview
->GetTotalPages();
1068 if( nTotal
&& nPage
!= 0 )
1070 SfxViewFrame
& rSfxViewFrame
= GetViewFrame();
1071 SfxRequest
aSfxRequest(rSfxViewFrame
, SID_PREVIEW_FIRST
);
1072 Execute( aSfxRequest
);
1084 if( !pPreview
->AllTested() )
1085 pPreview
->CalcAll();
1086 tools::Long nPage
= pPreview
->GetPageNo();
1087 tools::Long nTotal
= pPreview
->GetTotalPages();
1088 if( nTotal
&& nPage
+1 != nTotal
)
1090 SfxViewFrame
& rSfxViewFrame
= GetViewFrame();
1091 SfxRequest
aSfxRequest(rSfxViewFrame
, SID_PREVIEW_LAST
);
1092 Execute( aSfxRequest
);
1097 aCurPos
.setY( nVRange
);
1098 aCurPos
.setX( nHRange
);
1103 // nHRange-nHPage might be negative, that's why we check for < 0 afterwards
1105 if( aCurPos
.Y() > (nVRange
-nVPage
) )
1106 aCurPos
.setY( nVRange
-nVPage
);
1107 if( aCurPos
.Y() < 0 )
1109 if( aCurPos
.X() > (nHRange
-nHPage
) )
1110 aCurPos
.setX( nHRange
-nHPage
);
1111 if( aCurPos
.X() < 0 )
1114 if( nMaxVertPos
>=0 )
1116 if( aCurPos
.Y() != aPrevPos
.Y() )
1118 pVerScroll
->SetThumbPos( aCurPos
.Y() );
1119 nPrevVThumbPos
= pVerScroll
->GetThumbPos();
1120 pPreview
->SetYOffset( aCurPos
.Y() );
1124 if( aCurPos
.X() != aPrevPos
.X() )
1126 pHorScroll
->SetThumbPos( aCurPos
.X() );
1127 nPrevHThumbPos
= pHorScroll
->GetThumbPos();
1128 pPreview
->SetXOffset( aCurPos
.X() );
1133 void ScPreviewShell::ExitPreview()
1135 GetViewFrame().GetDispatcher()->Execute(SID_VIEWSHELL0
, SfxCallMode::ASYNCHRON
);
1138 void ScPreviewShell::AddAccessibilityObject( SfxListener
& rObject
)
1140 if (!pAccessibilityBroadcaster
)
1141 pAccessibilityBroadcaster
.reset( new SfxBroadcaster
);
1143 rObject
.StartListening( *pAccessibilityBroadcaster
);
1146 void ScPreviewShell::RemoveAccessibilityObject( SfxListener
& rObject
)
1148 if (pAccessibilityBroadcaster
)
1149 rObject
.EndListening( *pAccessibilityBroadcaster
);
1152 OSL_FAIL("no accessibility broadcaster?");
1156 void ScPreviewShell::BroadcastAccessibility( const SfxHint
&rHint
)
1158 if (pAccessibilityBroadcaster
)
1159 pAccessibilityBroadcaster
->Broadcast( rHint
);
1162 bool ScPreviewShell::HasAccessibilityObjects() const
1164 return pAccessibilityBroadcaster
&& pAccessibilityBroadcaster
->HasListeners();
1167 const ScPreviewLocationData
& ScPreviewShell::GetLocationData()
1169 return pPreview
->GetLocationData();
1172 ScDocument
& ScPreviewShell::GetDocument()
1174 return pDocShell
->GetDocument();
1177 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */