tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / view / prevwsh.cxx
blob329a9b46df40b6a50a95f5af8bd7b7e59db6e4dc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <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>
50 #include <scmod.hxx>
51 #include <inputhdl.hxx>
52 #include <docsh.hxx>
53 #include <tabvwsh.hxx>
54 #include <stlpool.hxx>
55 #include <editutil.hxx>
56 #include <globstr.hrc>
57 #include <scresid.hxx>
58 #include <sc.hrc>
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>
72 // for mouse wheel
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>
83 #include <memory>
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();
111 else
112 break;
115 mpFrameWindow = dynamic_cast<SystemWindow*>(pWin);
116 if (mpFrameWindow)
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();
137 if (pDrawBC)
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 ),
151 nMaxVertPos(0),
152 nPrevHThumbPos(0),
153 nPrevVThumbPos(0)
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();
171 if ( pDrawView )
172 nSourceDesignMode
173 = pDrawView->IsDesignMode() ? TRISTATE_TRUE : TRISTATE_FALSE;
176 new ScPreviewObj(this);
179 ScPreviewShell::~ScPreviewShell()
181 if (mpFrameWindow)
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();
189 if (pDrawBC)
190 EndListening(*pDrawBC);
191 EndListening(*SfxGetpApp());
192 EndListening(*pDocShell);
194 SetWindow(nullptr);
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));
246 return true;
249 void ScPreviewShell::UpdateNeededScrollBars( bool bFromZoom )
251 Size aPageSize;
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 ))
261 return;
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
272 if ( bFromZoom )
274 if ( bVert )
276 aWindowPixelSize.AdjustWidth(nBarH );
277 aWindowSize.AdjustWidth(aHeightOffSet );
279 if ( bHori )
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 ) )
296 bHori = true;
297 else if ( (nMaxHeightPos + aHeightOffSet ) > 0 )
298 bVert = true;
300 pHorScroll->Show( bHori );
301 pVerScroll->Show( bVert );
303 // make room for needed scrollbars ( and reduce the size
304 // of the preview appropriately )
305 if ( bHori )
306 aWindowPixelSize.AdjustHeight( -nBarW );
307 if ( bVert )
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() ) );
315 UpdateScrollBars();
318 void ScPreviewShell::UpdateScrollBars()
320 Size aPageSize;
321 if ( !GetPageSize( aPageSize ) )
322 return;
324 // for centering, page size without the shadow is used
326 Size aWindowSize = pPreview->GetOutDev()->GetOutputSize();
328 Point aOfs = pPreview->GetOffset();
330 if( pHorScroll )
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();
337 if ( nMaxPos<0 )
339 // page smaller than window -> center (but put scrollbar to 0)
340 aOfs.setX( 0 );
341 pPreview->SetXOffset( nMaxPos / 2 );
343 else if (aOfs.X() < 0)
345 // page larger than window -> never use negative offset
346 aOfs.setX( 0 );
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();
359 if( !pVerScroll )
360 return;
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)
372 aOfs.setY( 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() ) );
381 aOfs.setY( 0 );
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;
415 if( nTotalPages )
416 nPerPageLength = nMaxRange / nTotalPages;
418 if( nPerPageLength )
420 nPageNo = nPos / nPerPageLength;
421 if( nPos % nPerPageLength )
423 bIsDivide = false;
424 nPageNo ++;
428 bool bHoriz = ( pScroll == pHorScroll );
430 tools::Long nDelta = bHoriz ? (pHorScroll->GetThumbPos() - nPrevHThumbPos)
431 : (pVerScroll->GetThumbPos() - nPrevVThumbPos);
433 if( bHoriz )
434 pPreview->SetXOffset( nPos );
435 else
437 if( nMaxVertPos > 0 )
438 pPreview->SetYOffset( nPos );
439 else
441 Point aMousePos = pScroll->OutputToNormalizedScreenPixel( pScroll->GetPointerPosPixel() );
442 Point aPos = pScroll->GetParent()->OutputToNormalizedScreenPixel( pScroll->GetPosPixel() );
443 OUString aHelpStr;
444 tools::Rectangle aRect;
445 QuickHelpFlags nAlign;
447 if( nDelta < 0 )
449 if ( nTotalPages && nPageNo > 0 && !bIsDivide )
450 pPreview->SetPageNo( nPageNo-1 );
451 if( bIsDivide )
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)
481 ExitPreview();
484 bool ScPreviewShell::ScrollCommand( const CommandEvent& rCEvt )
486 bool bDone = false;
487 const CommandWheelData* pData = rCEvt.GetWheelData();
488 if ( pData && pData->GetMode() == CommandWheelMode::ZOOM )
490 sal_uInt16 nOld = pPreview->GetZoom();
491 sal_uInt16 nNew;
492 if ( pData->GetDelta() < 0 )
493 nNew = std::max( MINZOOM, basegfx::zoomtools::zoomOut( nOld ));
494 else
495 nNew = std::min( MAXZOOM, basegfx::zoomtools::zoomIn( nOld ));
497 if ( nNew != nOld )
499 eZoom = SvxZoomType::PERCENT;
500 pPreview->SetZoom( nNew );
503 bDone = true;
505 else
507 bDone = pPreview->HandleScrollCommand( rCEvt, pHorScroll, pVerScroll );
510 return bDone;
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
525 return true;
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);
534 return nullptr;
537 void ScPreviewShell::Activate(bool bMDI)
539 SfxViewShell::Activate(bMDI);
541 //! Basic etc. -> outsource to its own file (see tabvwsh4)
543 if (bMDI)
545 // InputHdl is now mostly Null, no more assertion!
546 ScInputHandler* pInputHdl = ScModule::get()->GetInputHdl();
547 if ( pInputHdl )
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();
559 switch ( nSlot )
561 case SID_FORMATPAGE:
562 case SID_STATUS_PAGESTYLE:
563 case SID_HFEDIT:
564 pDocShell->ExecutePageStyle( *this, rReq, pPreview->GetTab() );
565 break;
566 case SID_REPAINT:
567 pPreview->Invalidate();
568 rReq.Done();
569 break;
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 );
578 break;
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 );
588 break;
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 );
597 break;
598 case SID_CURSORENDOFFILE: // Accelerator
599 case SID_PREVIEW_LAST:
601 if (!pPreview->AllTested())
602 pPreview->CalcAll();
604 tools::Long nPage = pPreview->GetPageNo();
605 tools::Long nTotal = pPreview->GetTotalPages();
606 if (nTotal && nPage+1 != nTotal)
607 pPreview->SetPageNo( nTotal-1 );
609 break;
610 case SID_ATTR_ZOOM:
611 case FID_SCALE:
613 sal_uInt16 nZoom = 100;
614 bool bCancel = false;
616 eZoom = SvxZoomType::PERCENT;
618 if ( pReqArgs )
621 const SvxZoomItem& rZoomItem = pReqArgs->Get(SID_ATTR_ZOOM);
623 eZoom = rZoomItem.GetType();
624 nZoom = rZoomItem.GetValue();
626 else
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() );
638 if ( !bCancel )
640 const SvxZoomItem& rZoomItem = pDlg->GetOutputItemSet()->
641 Get( SID_ATTR_ZOOM );
643 eZoom = rZoomItem.GetType();
644 nZoom = rZoomItem.GetValue();
648 if ( !bCancel )
650 switch ( eZoom )
652 case SvxZoomType::OPTIMAL:
653 case SvxZoomType::WHOLEPAGE:
654 nZoom = pPreview->GetOptimalZoom(false);
655 break;
656 case SvxZoomType::PAGEWIDTH:
657 nZoom = pPreview->GetOptimalZoom(true);
658 break;
659 default:
661 // added to avoid warnings
665 pPreview->SetZoom( nZoom );
666 rReq.Done();
669 break;
670 case SID_ZOOM_IN:
671 case SID_ZOOM_OUT:
673 sal_uInt16 nNewZoom;
674 const sal_uInt16 nOldZoom {pPreview->GetZoom()};
675 if(SID_ZOOM_OUT == nSlot)
676 nNewZoom = basegfx::zoomtools::zoomOut(nOldZoom);
677 else
678 nNewZoom = basegfx::zoomtools::zoomIn(nOldZoom);
680 pPreview->SetZoom(nNewZoom);
681 eZoom = SvxZoomType::PERCENT;
682 rReq.Done();
684 break;
685 case SID_PREVIEW_MARGIN:
687 bool bMargin = pPreview->GetPageMargins();
688 pPreview->SetPageMargins( !bMargin );
689 pPreview->Invalidate();
690 rReq.Done();
692 break;
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();
700 if( nCurrentZoom )
702 pPreview->SetZoom( nCurrentZoom );
703 rReq.Done();
707 break;
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();
724 rReq.Done();
726 GetViewFrame().GetBindings().Invalidate( nSlot );
728 break;
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)
735 ExitPreview();
736 break;
737 case SID_CURSORPAGEUP:
738 case SID_CURSORPAGEDOWN:
739 case SID_CURSORHOME:
740 case SID_CURSOREND:
741 case SID_CURSORUP:
742 case SID_CURSORDOWN:
743 case SID_CURSORLEFT:
744 case SID_CURSORRIGHT:
745 DoScroll( nSlot );
746 break;
747 case SID_CANCEL:
748 if( ScViewUtil::IsFullScreen( *this ) )
749 ScViewUtil::SetFullScreen( *this, false );
750 break;
752 default:
753 break;
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();
769 while ( nWhich )
771 switch (nWhich)
773 case SID_STATUS_PAGESTYLE:
774 case SID_HFEDIT:
775 pDocShell->GetStatePageStyle( rSet, nTab );
776 break;
777 case SID_UNDO:
778 case SID_REDO:
779 case SID_REPEAT:
780 case SID_SAVEDOC:
781 case SID_SAVEASDOC:
782 case SID_MAIL_SENDDOC:
783 case SID_VIEW_DATA_SOURCE_BROWSER:
784 case SID_QUITAPP:
785 rSet.DisableItem(nWhich);
786 break;
787 case SID_PREVIEW_PREVIOUS:
788 case SID_PREVIEW_FIRST:
789 if (!nTotal || nPage==0)
790 rSet.DisableItem(nWhich);
791 break;
792 case SID_PREVIEW_NEXT:
793 case SID_PREVIEW_LAST:
794 if (bAllTested)
795 if (!nTotal || nPage==nTotal-1)
796 rSet.DisableItem(nWhich);
797 break;
798 case SID_ZOOM_IN:
799 if (nZoom >= 400)
800 rSet.DisableItem(nWhich);
801 break;
802 case SID_ZOOM_OUT:
803 if (nZoom <= 20)
804 rSet.DisableItem(nWhich);
805 break;
806 case SID_ATTR_ZOOM:
808 SvxZoomItem aZoom( eZoom, nZoom, TypedWhichId<SvxZoomItem>(nWhich) );
809 aZoom.SetValueSet( SvxZoomEnableFlags::ALL & ~SvxZoomEnableFlags::OPTIMAL );
810 rSet.Put( aZoom );
812 break;
813 case SID_ATTR_ZOOMSLIDER:
815 SvxZoomSliderItem aZoomSliderItem( nZoom, MINZOOM, MAXZOOM, SID_ATTR_ZOOMSLIDER );
816 aZoomSliderItem.AddSnappingPoint( 100 );
817 rSet.Put( aZoomSliderItem );
819 break;
820 case SID_PREVIEW_SCALINGFACTOR:
822 if( pDocShell->IsReadOnly() )
823 rSet.DisableItem( nWhich );
824 else
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! :-/" );
831 if ( pStyleSheet )
833 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
834 sal_uInt16 nCurrentZoom = rStyleSet.Get(ATTR_PAGE_SCALE).GetValue();
835 if( nCurrentZoom )
837 SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM_SLIDER, MAXZOOM_SLIDER, SID_PREVIEW_SCALINGFACTOR );
838 aZoomSliderItem.AddSnappingPoint( 100 );
839 rSet.Put( aZoomSliderItem );
841 else
842 rSet.DisableItem( nWhich );
846 break;
847 case SID_STATUS_DOCPOS:
848 rSet.Put( SfxStringItem( nWhich, pPreview->GetPosString() ) );
849 break;
850 case SID_PRINTPREVIEW:
851 rSet.Put( SfxBoolItem( nWhich, true ) );
852 break;
853 case SID_FORMATPAGE:
854 case SID_PREVIEW_MARGIN:
855 if( pDocShell->IsReadOnly() )
856 rSet.DisableItem( nWhich );
857 break;
860 nWhich = aIter.NextWhich();
863 pPreview->SetInGetState(false);
866 void ScPreviewShell::FillFieldData( ScHeaderFieldData& rData )
868 ScDocument& rDoc = pDocShell->GetDocument();
869 SCTAB nTab = pPreview->GetTab();
870 OUString aTmp;
871 rDoc.GetName(nTab, aTmp);
872 rData.aTabName = aTmp;
874 if( pDocShell->getDocProperties()->getTitle().getLength() != 0 )
875 rData.aTitle = pDocShell->getDocProperties()->getTitle();
876 else
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);
883 else
884 rData.aShortDocName = rData.aLongDocName = rData.aTitle;
885 rData.nPageNo = pPreview->GetPageNo() + 1;
887 bool bAllTested = pPreview->AllTested();
888 if (bAllTested)
889 rData.nTotalPages = pPreview->GetTotalPages();
890 else
891 rData.nTotalPages = 99;
893 // the dialog knows eNumType
896 void ScPreviewShell::WriteUserData(OUString& rData, bool /* bBrowse */)
898 // nZoom
899 // nPageNo
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))
921 return;
923 rSeq.realloc(3);
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)
944 sal_Int32 nTemp = 0;
945 if (propval.Value >>= nTemp)
946 pPreview->SetZoom(sal_uInt16(nTemp));
948 else if (propval.Name == "PageNumber")
950 sal_Int32 nTemp = 0;
951 if (propval.Value >>= nTemp)
952 pPreview->SetPageNo(nTemp);
954 // Fallback to common SdrModel processing
955 else
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() );
973 aPrevPos = aCurPos;
975 tools::Long nThumbPos = pVerScroll->GetThumbPos();
976 tools::Long nRangeMax = pVerScroll->GetRangeMax();
978 switch( nMode )
980 case SID_CURSORUP:
981 if( nMaxVertPos<0 )
983 tools::Long nPage = pPreview->GetPageNo();
985 if( nPage>0 )
987 SfxViewFrame& rSfxViewFrame = GetViewFrame();
988 SfxRequest aSfxRequest(rSfxViewFrame, SID_PREVIEW_PREVIOUS);
989 Execute( aSfxRequest );
992 else
993 aCurPos.AdjustY( -nVLine );
994 break;
995 case SID_CURSORDOWN:
996 if( nMaxVertPos<0 )
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 );
1015 else
1016 aCurPos.AdjustY(nVLine );
1017 break;
1018 case SID_CURSORLEFT:
1019 aCurPos.AdjustX( -nHLine );
1020 break;
1021 case SID_CURSORRIGHT:
1022 aCurPos.AdjustX(nHLine );
1023 break;
1024 case SID_CURSORPAGEUP:
1025 if( nThumbPos==0 || nMaxVertPos<0 )
1027 tools::Long nPage = pPreview->GetPageNo();
1029 if( nPage>0 )
1031 SfxViewFrame& rSfxViewFrame = GetViewFrame();
1032 SfxRequest aSfxRequest(rSfxViewFrame, SID_PREVIEW_PREVIOUS);
1033 Execute( aSfxRequest );
1034 aCurPos.setY( nVRange );
1037 else
1038 aCurPos.AdjustY( -nVPage );
1039 break;
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 );
1057 aCurPos.setY( 0 );
1060 else
1061 aCurPos.AdjustY(nVPage );
1062 break;
1063 case SID_CURSORHOME:
1064 if( nMaxVertPos<0 )
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 );
1075 else
1077 aCurPos.setY( 0 );
1078 aCurPos.setX( 0 );
1080 break;
1081 case SID_CURSOREND:
1082 if( nMaxVertPos<0 )
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 );
1095 else
1097 aCurPos.setY( nVRange );
1098 aCurPos.setX( nHRange );
1100 break;
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 )
1108 aCurPos.setY( 0 );
1109 if( aCurPos.X() > (nHRange-nHPage) )
1110 aCurPos.setX( nHRange-nHPage );
1111 if( aCurPos.X() < 0 )
1112 aCurPos.setX( 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 );
1150 else
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: */