1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <sal/config.h>
21 
22 #include <scitems.hxx>
23 
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 
45 #include <drwlayer.hxx>
46 #include <prevwsh.hxx>
47 #include <preview.hxx>
48 #include <printfun.hxx>
49 #include <scmod.hxx>
50 #include <inputhdl.hxx>
51 #include <docsh.hxx>
52 #include <tabvwsh.hxx>
53 #include <stlpool.hxx>
54 #include <editutil.hxx>
55 #include <globstr.hrc>
56 #include <scresid.hxx>
57 #include <sc.hrc>
58 #include <ViewSettingsSequenceDefines.hxx>
59 #include <viewuno.hxx>
60 
61 #include <svx/svxdlg.hxx>
62 #include <svx/dialogs.hrc>
63 
64 #include <basegfx/utils/zoomtools.hxx>
65 #include <svx/zoom_def.hxx>
66 #include <com/sun/star/document/XDocumentProperties.hpp>
67 
68 #include <scabstdlg.hxx>
69 #include <vcl/EnumContext.hxx>
70 #include <vcl/notebookbar/notebookbar.hxx>
71 
72 //  for mouse wheel
73 #define MINZOOM_SLIDER 10
74 #define MAXZOOM_SLIDER 400
75 
76 #define SC_USERDATA_SEP ';'
77 
78 using namespace com::sun::star;
79 
80 #define ShellClass_ScPreviewShell
81 #include <scslots.hxx>
82 
83 #include <memory>
84 
85 
SFX_IMPL_INTERFACE(ScPreviewShell,SfxViewShell)86 SFX_IMPL_INTERFACE(ScPreviewShell, SfxViewShell)
87 
88 void ScPreviewShell::InitInterface_Impl()
89 {
90     GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT,
91                                             SfxVisibilityFlags::Standard|SfxVisibilityFlags::Server|SfxVisibilityFlags::ReadonlyDoc,
92                                             ToolbarId::Objectbar_Preview);
93 
94     GetStaticInterface()->RegisterPopupMenu("preview");
95 }
96 
97 SFX_IMPL_NAMED_VIEWFACTORY( ScPreviewShell, "PrintPreview" )
98 {
99     SFX_VIEW_REGISTRATION(ScDocShell);
100 }
101 
Construct(vcl::Window * pParent)102 void ScPreviewShell::Construct( vcl::Window* pParent )
103 {
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())
108     {
109         if (pWin->GetParent())
110             pWin = pWin->GetParent();
111         else
112             break;
113     }
114 
115     mpFrameWindow = dynamic_cast<SystemWindow*>(pWin);
116     if (mpFrameWindow)
117         mpFrameWindow->SetCloseHdl(LINK(this, ScPreviewShell, CloseHdl));
118 
119     eZoom = SvxZoomType::WHOLEPAGE;
120 
121     pCorner = VclPtr<ScrollBarBox>::Create( pParent, WB_SIZEABLE );
122 
123     pHorScroll = VclPtr<ScrollBar>::Create(pParent, WB_HSCROLL );
124     pVerScroll = VclPtr<ScrollBar>::Create(pParent, WB_VSCROLL);
125 
126     // RTL: no mirroring for horizontal scrollbars
127     pHorScroll->EnableRTL( false );
128 
129     pHorScroll->SetEndScrollHdl( LINK( this, ScPreviewShell, ScrollHandler ) );
130     pVerScroll->SetEndScrollHdl( LINK( this, ScPreviewShell, ScrollHandler ) );
131 
132     pPreview = VclPtr<ScPreview>::Create( pParent, pDocShell, this );
133 
134     SetPool( &SC_MOD()->GetPool() );
135     SetWindow( pPreview );
136     StartListening(*pDocShell, DuplicateHandling::Prevent);
137     StartListening(*SfxGetpApp(), DuplicateHandling::Prevent); // #i62045# #i62046# application is needed for Calc's own hints
138     SfxBroadcaster* pDrawBC = pDocShell->GetDocument().GetDrawBroadcaster();
139     if (pDrawBC)
140         StartListening(*pDrawBC);
141 
142     pHorScroll->Show( false );
143     pVerScroll->Show( false );
144     pCorner->Show();
145     SetName("Preview");
146 }
147 
ScPreviewShell(SfxViewFrame * pViewFrame,SfxViewShell * pOldSh)148 ScPreviewShell::ScPreviewShell( SfxViewFrame* pViewFrame,
149                                 SfxViewShell* pOldSh ) :
150     SfxViewShell( pViewFrame, SfxViewShellFlags::HAS_PRINTOPTIONS ),
151     pDocShell( static_cast<ScDocShell*>(pViewFrame->GetObjectShell()) ),
152     mpFrameWindow(nullptr),
153     nSourceDesignMode( TRISTATE_INDET ),
154     nMaxVertPos(0)
155 {
156     Construct( &pViewFrame->GetWindow() );
157 
158     try
159     {
160         SfxShell::SetContextBroadcasterEnabled(true);
161         SfxShell::SetContextName(
162             vcl::EnumContext::GetContextName(vcl::EnumContext::Context::Printpreview));
163         SfxShell::BroadcastContextForActivation(true);
164     }
165     catch (const css::uno::RuntimeException& e)
166     {
167         // tdf#130559: allow BackingComp to fail adding listener when opening document
168         css::uno::Reference<css::lang::XServiceInfo> xServiceInfo(e.Context, css::uno::UNO_QUERY);
169         if (!xServiceInfo || !xServiceInfo->supportsService("com.sun.star.frame.StartModule"))
170             throw;
171         SAL_WARN("sc.ui", "Opening file from StartModule straight into print preview");
172     }
173 
174     auto& pNotebookBar = pViewFrame->GetWindow().GetSystemWindow()->GetNotebookBar();
175     if (pNotebookBar)
176         pNotebookBar->ControlListenerForCurrentController(false); // stop listening
177 
178     if ( auto pTabViewShell = dynamic_cast<ScTabViewShell*>( pOldSh) )
179     {
180         //  store view settings, show table from TabView
181         //! store live ScViewData instead, and update on ScTablesHint?
182         //! or completely forget aSourceData on ScTablesHint?
183 
184         const ScViewData& rData = pTabViewShell->GetViewData();
185         pPreview->SetSelectedTabs(rData.GetMarkData());
186         InitStartTable( rData.GetTabNo() );
187 
188         //  also have to store the TabView's DesignMode state
189         //  (only if draw view exists)
190         SdrView* pDrawView = pTabViewShell->GetScDrawView();
191         if ( pDrawView )
192             nSourceDesignMode
193                 = pDrawView->IsDesignMode() ? TRISTATE_TRUE : TRISTATE_FALSE;
194     }
195 
196     new ScPreviewObj(this);
197 }
198 
~ScPreviewShell()199 ScPreviewShell::~ScPreviewShell()
200 {
201     if (mpFrameWindow)
202         mpFrameWindow->SetCloseHdl(Link<SystemWindow&,void>()); // Remove close handler.
203 
204     if (auto& pBar = GetViewFrame()->GetWindow().GetSystemWindow()->GetNotebookBar())
205         pBar->ControlListenerForCurrentController(true); // let it start listening now
206 
207     // #108333#; notify Accessibility that Shell is dying and before destroy all
208     BroadcastAccessibility( SfxHint( SfxHintId::Dying ) );
209     pAccessibilityBroadcaster.reset();
210 
211     SfxBroadcaster* pDrawBC = pDocShell->GetDocument().GetDrawBroadcaster();
212     if (pDrawBC)
213         EndListening(*pDrawBC);
214     EndListening(*SfxGetpApp());
215     EndListening(*pDocShell);
216 
217     SetWindow(nullptr);
218     pPreview.disposeAndClear();
219     pHorScroll.disposeAndClear();
220     pVerScroll.disposeAndClear();
221     pCorner.disposeAndClear();
222 
223     //  normal mode of operation is switching back to default view in the same frame,
224     //  so there's no need to activate any other window here anymore
225 }
226 
InitStartTable(SCTAB nTab)227 void ScPreviewShell::InitStartTable(SCTAB nTab)
228 {
229     pPreview->SetPageNo( pPreview->GetFirstPage(nTab) );
230 }
231 
AdjustPosSizePixel(const Point & rPos,const Size & rSize)232 void ScPreviewShell::AdjustPosSizePixel( const Point &rPos, const Size &rSize )
233 {
234     Size aOutSize( rSize );
235     pPreview->SetPosSizePixel( rPos, aOutSize );
236 
237     if ( SvxZoomType::WHOLEPAGE == eZoom )
238         pPreview->SetZoom( pPreview->GetOptimalZoom(false) );
239     else if ( SvxZoomType::PAGEWIDTH == eZoom )
240         pPreview->SetZoom( pPreview->GetOptimalZoom(true) );
241 
242     UpdateNeededScrollBars(false);
243 }
244 
InnerResizePixel(const Point & rOfs,const Size & rSize,bool)245 void ScPreviewShell::InnerResizePixel( const Point &rOfs, const Size &rSize, bool )
246 {
247     AdjustPosSizePixel( rOfs,rSize );
248 }
249 
OuterResizePixel(const Point & rOfs,const Size & rSize)250 void ScPreviewShell::OuterResizePixel( const Point &rOfs, const Size &rSize )
251 {
252     AdjustPosSizePixel( rOfs,rSize );
253 }
254 
GetPageSize(Size & aPageSize)255 bool ScPreviewShell::GetPageSize( Size& aPageSize )
256 {
257     ScDocument& rDoc = pDocShell->GetDocument();
258     SCTAB nTab = pPreview->GetTab();
259 
260     ScStyleSheetPool*   pStylePool  = rDoc.GetStyleSheetPool();
261     SfxStyleSheetBase*  pStyleSheet = pStylePool->Find( rDoc.GetPageStyle( nTab ),
262                                                         SfxStyleFamily::Page );
263     OSL_ENSURE(pStyleSheet,"No style sheet");
264     if (!pStyleSheet) return false;
265     const SfxItemSet* pParamSet = &pStyleSheet->GetItemSet();
266 
267     aPageSize = pParamSet->Get(ATTR_PAGE_SIZE).GetSize();
268     aPageSize.setWidth(o3tl::convert(aPageSize.Width(), o3tl::Length::twip, o3tl::Length::mm100));
269     aPageSize.setHeight(o3tl::convert(aPageSize.Height(), o3tl::Length::twip, o3tl::Length::mm100));
270     return true;
271 }
272 
UpdateNeededScrollBars(bool bFromZoom)273 void ScPreviewShell::UpdateNeededScrollBars( bool bFromZoom )
274 {
275     Size aPageSize;
276     OutputDevice* pDevice = Application::GetDefaultDevice();
277 
278     tools::Long nBarW = GetViewFrame()->GetWindow().GetSettings().GetStyleSettings().GetScrollBarSize();
279     tools::Long nBarH = nBarW;
280 
281     tools::Long aHeightOffSet = pDevice ? pDevice->PixelToLogic( Size( nBarW, nBarH ), pPreview->GetMapMode() ).Height() : 0;
282     tools::Long aWidthOffSet = aHeightOffSet;
283 
284     if (!GetPageSize( aPageSize ))
285         return;
286 
287     //  for centering, page size without the shadow is used
288     bool bVert = pVerScroll->IsVisible();
289     bool bHori = pHorScroll->IsVisible();
290     Size aWindowSize = pPreview->GetOutDev()->GetOutputSize();
291     Point aPos = pPreview->GetPosPixel();
292     Size aWindowPixelSize = pPreview->GetOutputSizePixel();
293 
294     // if we are called from Zoom then we need to compensate for whatever
295     // scrollbars were displayed before the zoom was called
296     if ( bFromZoom )
297     {
298         if ( bVert )
299         {
300             aWindowPixelSize.AdjustWidth(nBarH );
301             aWindowSize.AdjustWidth(aHeightOffSet );
302         }
303         if ( bHori )
304         {
305             aWindowPixelSize.AdjustHeight(nBarW );
306             aWindowSize.AdjustHeight(aWidthOffSet );
307         }
308     }
309 
310     // recalculate any needed scrollbars
311     tools::Long nMaxWidthPos = aPageSize.Width() - aWindowSize.Width();
312     bHori = nMaxWidthPos >= 0;
313     tools::Long nMaxHeightPos = aPageSize.Height() - aWindowSize.Height();
314     bVert = nMaxHeightPos >= 0;
315 
316     // see if having a scroll bar requires the other
317     if ( bVert != bHori && ( bVert || bHori ) )
318     {
319         if ( bVert && ( (nMaxWidthPos + aWidthOffSet  ) > 0 ) )
320             bHori = true;
321         else if ( (nMaxHeightPos + aHeightOffSet ) > 0 )
322             bVert = true;
323     }
324     pHorScroll->Show( bHori );
325     pVerScroll->Show( bVert );
326 
327     // make room for needed scrollbars ( and reduce the size
328     // of the preview appropriately )
329     if ( bHori )
330         aWindowPixelSize.AdjustHeight( -nBarW );
331     if ( bVert )
332         aWindowPixelSize.AdjustWidth( -nBarH );
333 
334     pPreview->SetSizePixel( aWindowPixelSize );
335     pHorScroll->SetPosSizePixel( Point( aPos.X(), aPos.Y() + aWindowPixelSize.Height() ),
336                                  Size( aWindowPixelSize.Width(), nBarH ) );
337     pVerScroll->SetPosSizePixel( Point( aPos.X() + aWindowPixelSize.Width(), aPos.Y() ),
338                                  Size( nBarW, aWindowPixelSize.Height() ) );
339     pCorner->SetPosSizePixel( Point( aPos.X() + aWindowPixelSize.Width(), aPos.Y() + aWindowPixelSize.Height() ),
340                               Size( nBarW, nBarH ) );
341     UpdateScrollBars();
342 }
343 
UpdateScrollBars()344 void ScPreviewShell::UpdateScrollBars()
345 {
346     Size aPageSize;
347     if ( !GetPageSize( aPageSize ) )
348         return;
349 
350     //  for centering, page size without the shadow is used
351 
352     Size aWindowSize = pPreview->GetOutDev()->GetOutputSize();
353 
354     Point aOfs = pPreview->GetOffset();
355 
356     if( pHorScroll )
357     {
358         pHorScroll->SetRange( Range( 0, aPageSize.Width() ) );
359         pHorScroll->SetLineSize( aWindowSize.Width() / 16 );
360         pHorScroll->SetPageSize( aWindowSize.Width() );
361         pHorScroll->SetVisibleSize( aWindowSize.Width() );
362         tools::Long nMaxPos = aPageSize.Width() - aWindowSize.Width();
363         if ( nMaxPos<0 )
364         {
365             //  page smaller than window -> center (but put scrollbar to 0)
366             aOfs.setX( 0 );
367             pPreview->SetXOffset( nMaxPos / 2 );
368         }
369         else if (aOfs.X() < 0)
370         {
371             //  page larger than window -> never use negative offset
372             aOfs.setX( 0 );
373             pPreview->SetXOffset( 0 );
374         }
375         else if (aOfs.X() > nMaxPos)
376         {
377             //  limit offset to align with right edge of window
378             aOfs.setX( nMaxPos );
379             pPreview->SetXOffset(nMaxPos);
380         }
381         pHorScroll->SetThumbPos( aOfs.X() );
382     }
383 
384     if( !pVerScroll )
385         return;
386 
387     tools::Long nPageNo     = pPreview->GetPageNo();
388     tools::Long nTotalPages = pPreview->GetTotalPages();
389 
390     nMaxVertPos = aPageSize.Height() - aWindowSize.Height();
391     pVerScroll->SetLineSize( aWindowSize.Height() / 16  );
392     pVerScroll->SetPageSize( aWindowSize.Height() );
393     pVerScroll->SetVisibleSize( aWindowSize.Height() );
394     if ( nMaxVertPos < 0 )
395     {
396         //  page smaller than window -> center (but put scrollbar to 0)
397         aOfs.setY( 0 );
398         pPreview->SetYOffset( nMaxVertPos / 2 );
399         pVerScroll->SetThumbPos( nPageNo * aWindowSize.Height() );
400         pVerScroll->SetRange( Range( 0, aWindowSize.Height() * nTotalPages ));
401     }
402     else if (aOfs.Y() < 0)
403     {
404         //  page larger than window -> never use negative offset
405         pVerScroll->SetRange( Range( 0, aPageSize.Height() ) );
406         aOfs.setY( 0 );
407         pPreview->SetYOffset( 0 );
408         pVerScroll->SetThumbPos( aOfs.Y() );
409     }
410     else if (aOfs.Y() > nMaxVertPos )
411     {
412         //  limit offset to align with window bottom
413         pVerScroll->SetRange( Range( 0, aPageSize.Height() ) );
414         aOfs.setY( nMaxVertPos );
415         pPreview->SetYOffset( nMaxVertPos );
416         pVerScroll->SetThumbPos( aOfs.Y() );
417     }
418 }
419 
IMPL_LINK(ScPreviewShell,ScrollHandler,ScrollBar *,pScroll,void)420 IMPL_LINK( ScPreviewShell, ScrollHandler, ScrollBar*, pScroll, void )
421 {
422     tools::Long nPos           = pScroll->GetThumbPos();
423     tools::Long nDelta         = pScroll->GetDelta();
424     tools::Long nMaxRange      = pScroll->GetRangeMax();
425     tools::Long nTotalPages    = pPreview->GetTotalPages();
426     tools::Long nPageNo        = 0;
427     tools::Long nPerPageLength = 0;
428     bool bIsDivide      = true;
429 
430     if( nTotalPages )
431         nPerPageLength = nMaxRange / nTotalPages;
432 
433     if( nPerPageLength )
434     {
435         nPageNo = nPos / nPerPageLength;
436         if( nPos % nPerPageLength )
437         {
438             bIsDivide = false;
439             nPageNo ++;
440         }
441     }
442 
443     bool bHoriz = ( pScroll == pHorScroll );
444 
445     if( bHoriz )
446         pPreview->SetXOffset( nPos );
447     else
448     {
449         if( nMaxVertPos > 0 )
450             pPreview->SetYOffset( nPos );
451         else
452         {
453             Point  aMousePos = pScroll->OutputToNormalizedScreenPixel( pScroll->GetPointerPosPixel() );
454             Point  aPos      = pScroll->GetParent()->OutputToNormalizedScreenPixel( pScroll->GetPosPixel() );
455             OUString aHelpStr;
456             tools::Rectangle aRect;
457             QuickHelpFlags nAlign;
458 
459             if( nDelta < 0 )
460             {
461                 if ( nTotalPages && nPageNo > 0 && !bIsDivide )
462                     pPreview->SetPageNo( nPageNo-1 );
463                 if( bIsDivide )
464                     pPreview->SetPageNo( nPageNo );
465 
466                 aHelpStr = ScResId( STR_PAGE ) +
467                            " " + OUString::number( nPageNo ) +
468                            " / "  + OUString::number( nTotalPages );
469             }
470             else if( nDelta > 0 )
471             {
472                 bool bAllTested = pPreview->AllTested();
473                 if ( nTotalPages && ( nPageNo < nTotalPages || !bAllTested ) )
474                     pPreview->SetPageNo( nPageNo );
475 
476                 aHelpStr = ScResId( STR_PAGE ) +
477                            " " + OUString::number( nPageNo+1 ) +
478                            " / "  + OUString::number( nTotalPages );
479             }
480 
481             aRect.SetLeft( aPos.X() - 8 );
482             aRect.SetTop( aMousePos.Y() );
483             aRect.SetRight( aRect.Left() );
484             aRect.SetBottom( aRect.Top() );
485             nAlign          = QuickHelpFlags::Bottom|QuickHelpFlags::Center;
486             Help::ShowQuickHelp( pScroll->GetParent(), aRect, aHelpStr, nAlign );
487         }
488     }
489 }
490 
IMPL_LINK_NOARG(ScPreviewShell,CloseHdl,SystemWindow &,void)491 IMPL_LINK_NOARG(ScPreviewShell, CloseHdl, SystemWindow&, void)
492 {
493     ExitPreview();
494 }
495 
ScrollCommand(const CommandEvent & rCEvt)496 bool ScPreviewShell::ScrollCommand( const CommandEvent& rCEvt )
497 {
498     bool bDone = false;
499     const CommandWheelData* pData = rCEvt.GetWheelData();
500     if ( pData && pData->GetMode() == CommandWheelMode::ZOOM )
501     {
502         tools::Long nOld = pPreview->GetZoom();
503         tools::Long nNew;
504         if ( pData->GetDelta() < 0 )
505             nNew = std::max( tools::Long(MINZOOM), basegfx::zoomtools::zoomOut( nOld ));
506         else
507             nNew = std::min( tools::Long(MAXZOOM), basegfx::zoomtools::zoomIn( nOld ));
508 
509         if ( nNew != nOld )
510         {
511             eZoom = SvxZoomType::PERCENT;
512             pPreview->SetZoom( static_cast<sal_uInt16>(nNew) );
513         }
514 
515         bDone = true;
516     }
517     else
518     {
519         bDone = pPreview->HandleScrollCommand( rCEvt, pHorScroll, pVerScroll );
520     }
521 
522     return bDone;
523 }
524 
GetPrinter(bool bCreate)525 SfxPrinter* ScPreviewShell::GetPrinter( bool bCreate )
526 {
527     return pDocShell->GetPrinter(bCreate);
528 }
529 
SetPrinter(SfxPrinter * pNewPrinter,SfxPrinterChangeFlags nDiffFlags)530 sal_uInt16 ScPreviewShell::SetPrinter( SfxPrinter *pNewPrinter, SfxPrinterChangeFlags nDiffFlags )
531 {
532     return pDocShell->SetPrinter( pNewPrinter, nDiffFlags );
533 }
534 
HasPrintOptionsPage() const535 bool ScPreviewShell::HasPrintOptionsPage() const
536 {
537     return true;
538 }
539 
CreatePrintOptionsPage(weld::Container * pPage,weld::DialogController * pController,const SfxItemSet & rOptions)540 std::unique_ptr<SfxTabPage> ScPreviewShell::CreatePrintOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rOptions)
541 {
542     ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
543     ::CreateTabPage ScTpPrintOptionsCreate = pFact->GetTabPageCreatorFunc(RID_SC_TP_PRINT);
544     if ( ScTpPrintOptionsCreate )
545         return ScTpPrintOptionsCreate(pPage, pController, &rOptions);
546     return nullptr;
547 }
548 
Activate(bool bMDI)549 void ScPreviewShell::Activate(bool bMDI)
550 {
551     SfxViewShell::Activate(bMDI);
552 
553     //! Basic etc. -> outsource to its own file (see tabvwsh4)
554 
555     if (bMDI)
556     {
557         // InputHdl is now mostly Null, no more assertion!
558         ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
559         if ( pInputHdl )
560             pInputHdl->NotifyChange( nullptr );
561     }
562 }
563 
Execute(SfxRequest & rReq)564 void ScPreviewShell::Execute( SfxRequest& rReq )
565 {
566     sal_uInt16 nSlot = rReq.GetSlot();
567     const SfxItemSet* pReqArgs = rReq.GetArgs();
568 
569     switch ( nSlot )
570     {
571         case SID_FORMATPAGE:
572         case SID_STATUS_PAGESTYLE:
573         case SID_HFEDIT:
574             pDocShell->ExecutePageStyle( *this, rReq, pPreview->GetTab() );
575             break;
576         case SID_REPAINT:
577             pPreview->Invalidate();
578             rReq.Done();
579             break;
580         case SID_PREV_TABLE: // Accelerator
581         case SID_PREVIEW_PREVIOUS:
582             {
583                 tools::Long nPage = pPreview->GetPageNo();
584                 tools::Long nTotal = pPreview->GetTotalPages();
585                 if (nTotal && nPage > 0)
586                     pPreview->SetPageNo( nPage-1 );
587             }
588             break;
589         case SID_NEXT_TABLE: // Accelerator
590         case SID_PREVIEW_NEXT:
591             {
592                 bool bAllTested = pPreview->AllTested();
593                 tools::Long nPage = pPreview->GetPageNo();
594                 tools::Long nTotal = pPreview->GetTotalPages();
595                 if (nTotal && (nPage+1 < nTotal || !bAllTested))
596                     pPreview->SetPageNo( nPage+1 );
597             }
598             break;
599         case SID_CURSORTOPOFFILE: // Accelerator
600         case SID_PREVIEW_FIRST:
601             {
602                 tools::Long nPage = pPreview->GetPageNo();
603                 tools::Long nTotal = pPreview->GetTotalPages();
604                 if (nTotal && nPage != 0)
605                     pPreview->SetPageNo( 0 );
606             }
607             break;
608         case SID_CURSORENDOFFILE: // Accelerator
609         case SID_PREVIEW_LAST:
610             {
611                 if (!pPreview->AllTested())
612                     pPreview->CalcAll();
613 
614                 tools::Long nPage = pPreview->GetPageNo();
615                 tools::Long nTotal = pPreview->GetTotalPages();
616                 if (nTotal && nPage+1 != nTotal)
617                     pPreview->SetPageNo( nTotal-1 );
618             }
619             break;
620         case SID_ATTR_ZOOM:
621         case FID_SCALE:
622             {
623                 sal_uInt16      nZoom       = 100;
624                 bool        bCancel     = false;
625 
626                 eZoom = SvxZoomType::PERCENT;
627 
628                 if ( pReqArgs )
629                 {
630 
631                     const SvxZoomItem& rZoomItem = pReqArgs->Get(SID_ATTR_ZOOM);
632 
633                     eZoom = rZoomItem.GetType();
634                     nZoom = rZoomItem.GetValue();
635                 }
636                 else
637                 {
638                     SfxItemSet      aSet     ( GetPool(), svl::Items<SID_ATTR_ZOOM, SID_ATTR_ZOOM>{} );
639                     SvxZoomItem     aZoomItem( SvxZoomType::PERCENT, pPreview->GetZoom(), SID_ATTR_ZOOM );
640 
641                     aSet.Put( aZoomItem );
642                     SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
643                     ScopedVclPtr<AbstractSvxZoomDialog> pDlg(pFact->CreateSvxZoomDialog(nullptr, aSet));
644                     pDlg->SetLimits( 20, 400 );
645                     pDlg->HideButton( ZoomButtonId::OPTIMAL );
646                     bCancel = ( RET_CANCEL == pDlg->Execute() );
647 
648                     if ( !bCancel )
649                     {
650                         const SvxZoomItem&  rZoomItem = pDlg->GetOutputItemSet()->
651                                                     Get( SID_ATTR_ZOOM );
652 
653                         eZoom = rZoomItem.GetType();
654                         nZoom = rZoomItem.GetValue();
655                     }
656                 }
657 
658                 if ( !bCancel )
659                 {
660                     switch ( eZoom )
661                     {
662                         case SvxZoomType::OPTIMAL:
663                         case SvxZoomType::WHOLEPAGE:
664                             nZoom = pPreview->GetOptimalZoom(false);
665                             break;
666                         case SvxZoomType::PAGEWIDTH:
667                             nZoom = pPreview->GetOptimalZoom(true);
668                             break;
669                         default:
670                         {
671                             // added to avoid warnings
672                         }
673                     }
674 
675                     pPreview->SetZoom( nZoom );
676                     rReq.Done();
677                 }
678             }
679             break;
680         case SID_ZOOM_IN:
681             {
682                 sal_uInt16 nNew = pPreview->GetZoom() + 20 ;
683                 nNew -= nNew % 20;
684                 pPreview->SetZoom( nNew );
685                 eZoom = SvxZoomType::PERCENT;
686                 rReq.Done();
687             }
688             break;
689         case SID_ZOOM_OUT:
690             {
691                 sal_uInt16 nNew = pPreview->GetZoom() - 1;
692                 nNew -= nNew % 20;
693                 pPreview->SetZoom( nNew );
694                 eZoom = SvxZoomType::PERCENT;
695                 rReq.Done();
696             }
697             break;
698         case SID_PREVIEW_MARGIN:
699             {
700                 bool bMargin = pPreview->GetPageMargins();
701                 pPreview->SetPageMargins( !bMargin );
702                 pPreview->Invalidate();
703                 rReq.Done();
704             }
705             break;
706         case SID_ATTR_ZOOMSLIDER:
707             {
708                 const SfxPoolItem* pItem;
709                 eZoom = SvxZoomType::PERCENT;
710                 if( pReqArgs && SfxItemState::SET == pReqArgs->GetItemState( SID_ATTR_ZOOMSLIDER, true, &pItem ) )
711                 {
712                     const sal_uInt16 nCurrentZoom = static_cast<const SvxZoomSliderItem*>(pItem)->GetValue();
713                     if( nCurrentZoom )
714                     {
715                         pPreview->SetZoom( nCurrentZoom );
716                         rReq.Done();
717                     }
718                 }
719             }
720             break;
721         case SID_PREVIEW_SCALINGFACTOR:
722             {
723                 const SfxPoolItem* pItem;
724                 SCTAB nTab                      = pPreview->GetTab();
725                 OUString aOldName               = pDocShell->GetDocument().GetPageStyle( pPreview->GetTab() );
726                 ScStyleSheetPool* pStylePool    = pDocShell->GetDocument().GetStyleSheetPool();
727                 SfxStyleSheetBase* pStyleSheet  = pStylePool->Find( aOldName, SfxStyleFamily::Page );
728                 OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" );
729 
730                 if ( pReqArgs && pStyleSheet && SfxItemState::SET == pReqArgs->GetItemState( SID_PREVIEW_SCALINGFACTOR, true, &pItem ) )
731                 {
732                     const sal_uInt16 nCurrentZoom   = static_cast<const SvxZoomSliderItem *>(pItem)->GetValue();
733                     SfxItemSet& rSet            = pStyleSheet->GetItemSet();
734                     rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, nCurrentZoom ) );
735                     ScPrintFunc aPrintFunc( pDocShell, pDocShell->GetPrinter(), nTab );
736                     aPrintFunc.UpdatePages();
737                     rReq.Done();
738                 }
739                 GetViewFrame()->GetBindings().Invalidate( nSlot );
740             }
741             break;
742         case SID_PRINTPREVIEW:
743         case SID_PREVIEW_CLOSE:
744             //  print preview is now always in the same frame as the tab view
745             //  -> always switch this frame back to normal view
746             //  (ScTabViewShell ctor reads stored view data)
747 
748             ExitPreview();
749             break;
750         case SID_CURSORPAGEUP:
751         case SID_CURSORPAGEDOWN:
752         case SID_CURSORHOME:
753         case SID_CURSOREND:
754         case SID_CURSORUP:
755         case SID_CURSORDOWN:
756         case SID_CURSORLEFT:
757         case SID_CURSORRIGHT:
758             DoScroll( nSlot );
759             break;
760         case SID_CANCEL:
761             if( ScViewUtil::IsFullScreen( *this ) )
762                 ScViewUtil::SetFullScreen( *this, false );
763             break;
764 
765         default:
766             break;
767     }
768 }
769 
GetState(SfxItemSet & rSet)770 void ScPreviewShell::GetState( SfxItemSet& rSet )
771 {
772     pPreview->SetInGetState(true);
773 
774     SCTAB nTab      = pPreview->GetTab();
775     tools::Long nPage      = pPreview->GetPageNo();
776     tools::Long nTotal     = pPreview->GetTotalPages();
777     sal_uInt16 nZoom    = pPreview->GetZoom();
778     bool bAllTested = pPreview->AllTested();
779 
780     SfxWhichIter aIter(rSet);
781     sal_uInt16 nWhich = aIter.FirstWhich();
782     while ( nWhich )
783     {
784         switch (nWhich)
785         {
786             case SID_STATUS_PAGESTYLE:
787             case SID_HFEDIT:
788                 pDocShell->GetStatePageStyle( rSet, nTab );
789                 break;
790             case SID_UNDO:
791             case SID_REDO:
792             case SID_REPEAT:
793             case SID_SAVEDOC:
794             case SID_SAVEASDOC:
795             case SID_MAIL_SENDDOC:
796             case SID_VIEW_DATA_SOURCE_BROWSER:
797             case SID_QUITAPP:
798                 rSet.DisableItem(nWhich);
799                 break;
800             case SID_PREVIEW_PREVIOUS:
801             case SID_PREVIEW_FIRST:
802                 if (!nTotal || nPage==0)
803                     rSet.DisableItem(nWhich);
804                 break;
805             case SID_PREVIEW_NEXT:
806             case SID_PREVIEW_LAST:
807                 if (bAllTested)
808                     if (!nTotal || nPage==nTotal-1)
809                         rSet.DisableItem(nWhich);
810                 break;
811             case SID_ZOOM_IN:
812                 if (nZoom >= 400)
813                     rSet.DisableItem(nWhich);
814                 break;
815             case SID_ZOOM_OUT:
816                 if (nZoom <= 20)
817                     rSet.DisableItem(nWhich);
818                 break;
819             case SID_ATTR_ZOOM:
820                 {
821                     SvxZoomItem aZoom( eZoom, nZoom, nWhich );
822                     aZoom.SetValueSet( SvxZoomEnableFlags::ALL & ~SvxZoomEnableFlags::OPTIMAL );
823                     rSet.Put( aZoom );
824                 }
825                 break;
826             case SID_ATTR_ZOOMSLIDER:
827                 {
828                     SvxZoomSliderItem aZoomSliderItem( nZoom, MINZOOM, MAXZOOM, SID_ATTR_ZOOMSLIDER );
829                     aZoomSliderItem.AddSnappingPoint( 100 );
830                     rSet.Put( aZoomSliderItem );
831                 }
832                 break;
833             case SID_PREVIEW_SCALINGFACTOR:
834                 {
835                     if( pDocShell->IsReadOnly() )
836                         rSet.DisableItem( nWhich );
837                     else
838                     {
839                         OUString aOldName               = pDocShell->GetDocument().GetPageStyle( pPreview->GetTab() );
840                         ScStyleSheetPool* pStylePool    = pDocShell->GetDocument().GetStyleSheetPool();
841                         SfxStyleSheetBase* pStyleSheet  = pStylePool->Find( aOldName, SfxStyleFamily::Page );
842                         OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" );
843 
844                         if ( pStyleSheet )
845                         {
846                             SfxItemSet& rStyleSet   = pStyleSheet->GetItemSet();
847                             sal_uInt16 nCurrentZoom = rStyleSet.Get(ATTR_PAGE_SCALE).GetValue();
848                             if( nCurrentZoom )
849                             {
850                                 SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM_SLIDER, MAXZOOM_SLIDER, SID_PREVIEW_SCALINGFACTOR );
851                                 aZoomSliderItem.AddSnappingPoint( 100 );
852                                 rSet.Put( aZoomSliderItem );
853                             }
854                             else
855                                 rSet.DisableItem( nWhich );
856                         }
857                     }
858                 }
859                 break;
860             case SID_STATUS_DOCPOS:
861                 rSet.Put( SfxStringItem( nWhich, pPreview->GetPosString() ) );
862                 break;
863             case SID_PRINTPREVIEW:
864                 rSet.Put( SfxBoolItem( nWhich, true ) );
865                 break;
866             case SID_FORMATPAGE:
867             case SID_PREVIEW_MARGIN:
868                 if( pDocShell->IsReadOnly() )
869                     rSet.DisableItem( nWhich );
870                 break;
871         }
872 
873         nWhich = aIter.NextWhich();
874     }
875 
876     pPreview->SetInGetState(false);
877 }
878 
FillFieldData(ScHeaderFieldData & rData)879 void ScPreviewShell::FillFieldData( ScHeaderFieldData& rData )
880 {
881     ScDocument& rDoc = pDocShell->GetDocument();
882     SCTAB nTab = pPreview->GetTab();
883     OUString aTmp;
884     rDoc.GetName(nTab, aTmp);
885     rData.aTabName = aTmp;
886 
887     if( pDocShell->getDocProperties()->getTitle().getLength() != 0 )
888         rData.aTitle = pDocShell->getDocProperties()->getTitle();
889     else
890         rData.aTitle = pDocShell->GetTitle();
891 
892     const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
893     rData.aLongDocName  = rURLObj.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous );
894     if ( !rData.aLongDocName.isEmpty() )
895         rData.aShortDocName = rURLObj.GetLastName(INetURLObject::DecodeMechanism::Unambiguous);
896     else
897         rData.aShortDocName = rData.aLongDocName = rData.aTitle;
898     rData.nPageNo       = pPreview->GetPageNo() + 1;
899 
900     bool bAllTested = pPreview->AllTested();
901     if (bAllTested)
902         rData.nTotalPages = pPreview->GetTotalPages();
903     else
904         rData.nTotalPages = 99;
905 
906     //  the dialog knows eNumType
907 }
908 
WriteUserData(OUString & rData,bool)909 void ScPreviewShell::WriteUserData(OUString& rData, bool /* bBrowse */)
910 {
911     //  nZoom
912     //  nPageNo
913 
914     rData = OUString::number(pPreview->GetZoom())
915         + OUStringChar(SC_USERDATA_SEP)
916         + OUString::number(pPreview->GetPageNo());
917 }
918 
ReadUserData(const OUString & rData,bool)919 void ScPreviewShell::ReadUserData(const OUString& rData, bool /* bBrowse */)
920 {
921     if (!rData.isEmpty())
922     {
923         sal_Int32 nIndex = 0;
924         pPreview->SetZoom(static_cast<sal_uInt16>(rData.getToken(0, SC_USERDATA_SEP, nIndex).toInt32()));
925         pPreview->SetPageNo(rData.getToken(0, SC_USERDATA_SEP, nIndex).toInt32());
926         eZoom = SvxZoomType::PERCENT;
927     }
928 }
929 
WriteUserDataSequence(uno::Sequence<beans::PropertyValue> & rSeq)930 void ScPreviewShell::WriteUserDataSequence(uno::Sequence < beans::PropertyValue >& rSeq)
931 {
932     // tdf#130559: don't export preview view data if active
933     if (comphelper::IsContextFlagActive("NoPreviewData"))
934         return;
935 
936     rSeq.realloc(3);
937     beans::PropertyValue* pSeq = rSeq.getArray();
938     sal_uInt16 nViewID(GetViewFrame()->GetCurViewId());
939     pSeq[0].Name = SC_VIEWID;
940     pSeq[0].Value <<= SC_VIEW + OUString::number(nViewID);
941     pSeq[1].Name = SC_ZOOMVALUE;
942     pSeq[1].Value <<= sal_Int32 (pPreview->GetZoom());
943     pSeq[2].Name = "PageNumber";
944     pSeq[2].Value <<= pPreview->GetPageNo();
945 
946     // Common SdrModel processing
947     if (ScDrawLayer* pDrawLayer = GetDocument().GetDrawLayer())
948         pDrawLayer->WriteUserDataSequence(rSeq);
949 }
950 
ReadUserDataSequence(const uno::Sequence<beans::PropertyValue> & rSeq)951 void ScPreviewShell::ReadUserDataSequence(const uno::Sequence < beans::PropertyValue >& rSeq)
952 {
953     for (const auto& propval : rSeq)
954     {
955         if (propval.Name == SC_ZOOMVALUE)
956         {
957             sal_Int32 nTemp = 0;
958             if (propval.Value >>= nTemp)
959                 pPreview->SetZoom(sal_uInt16(nTemp));
960         }
961         else if (propval.Name == "PageNumber")
962         {
963             sal_Int32 nTemp = 0;
964             if (propval.Value >>= nTemp)
965                 pPreview->SetPageNo(nTemp);
966         }
967         // Fallback to common SdrModel processing
968         else
969             pDocShell->MakeDrawLayer()->ReadUserDataSequenceValue(&propval);
970     }
971 }
972 
DoScroll(sal_uInt16 nMode)973 void ScPreviewShell::DoScroll( sal_uInt16 nMode )
974 {
975     Point   aCurPos, aPrevPos;
976 
977     tools::Long nHRange    = pHorScroll->GetRange().Max();
978     tools::Long nHLine     = pHorScroll->GetLineSize();
979     tools::Long nHPage     = pHorScroll->GetPageSize();
980     tools::Long nVRange    = pVerScroll->GetRange().Max();
981     tools::Long nVLine     = pVerScroll->GetLineSize();
982     tools::Long nVPage     = pVerScroll->GetPageSize();
983 
984     aCurPos.setX( pHorScroll->GetThumbPos() );
985     aCurPos.setY( pVerScroll->GetThumbPos() );
986     aPrevPos = aCurPos;
987 
988     tools::Long nThumbPos  = pVerScroll->GetThumbPos();
989     tools::Long nRangeMax  = pVerScroll->GetRangeMax();
990 
991     switch( nMode )
992     {
993         case SID_CURSORUP:
994             if( nMaxVertPos<0 )
995             {
996                 tools::Long nPage = pPreview->GetPageNo();
997 
998                 if( nPage>0 )
999                 {
1000                     SfxViewFrame* pSfxViewFrame = GetViewFrame();
1001                     SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_PREVIOUS );
1002                     Execute( aSfxRequest );
1003                 }
1004             }
1005             else
1006                 aCurPos.AdjustY( -nVLine );
1007             break;
1008         case SID_CURSORDOWN:
1009             if( nMaxVertPos<0 )
1010             {
1011                 tools::Long nPage = pPreview->GetPageNo();
1012                 tools::Long nTotal = pPreview->GetTotalPages();
1013 
1014                 // before testing for last page, make sure all page counts are calculated
1015                 if ( nPage+1 == nTotal && !pPreview->AllTested() )
1016                 {
1017                     pPreview->CalcAll();
1018                     nTotal = pPreview->GetTotalPages();
1019                 }
1020 
1021                 if( nPage<nTotal-1 )
1022                 {
1023                     SfxViewFrame* pSfxViewFrame = GetViewFrame();
1024                     SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_NEXT );
1025                     Execute( aSfxRequest );
1026                 }
1027             }
1028             else
1029                 aCurPos.AdjustY(nVLine );
1030             break;
1031         case SID_CURSORLEFT:
1032             aCurPos.AdjustX( -nHLine );
1033             break;
1034         case SID_CURSORRIGHT:
1035             aCurPos.AdjustX(nHLine );
1036             break;
1037         case SID_CURSORPAGEUP:
1038             if( nThumbPos==0 || nMaxVertPos<0 )
1039             {
1040                 tools::Long nPage = pPreview->GetPageNo();
1041 
1042                 if( nPage>0 )
1043                 {
1044                     SfxViewFrame* pSfxViewFrame = GetViewFrame();
1045                     SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_PREVIOUS );
1046                     Execute( aSfxRequest );
1047                     aCurPos.setY( nVRange );
1048                 }
1049             }
1050             else
1051                 aCurPos.AdjustY( -nVPage );
1052             break;
1053         case SID_CURSORPAGEDOWN:
1054             if( (std::abs(nVPage+nThumbPos-nRangeMax)<10) || nMaxVertPos<0 )
1055             {
1056                 tools::Long nPage = pPreview->GetPageNo();
1057                 tools::Long nTotal = pPreview->GetTotalPages();
1058 
1059                 // before testing for last page, make sure all page counts are calculated
1060                 if ( nPage+1 == nTotal && !pPreview->AllTested() )
1061                 {
1062                     pPreview->CalcAll();
1063                     nTotal = pPreview->GetTotalPages();
1064                 }
1065                 if( nPage<nTotal-1 )
1066                 {
1067                     SfxViewFrame* pSfxViewFrame = GetViewFrame();
1068                     SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_NEXT );
1069                     Execute( aSfxRequest );
1070                     aCurPos.setY( 0 );
1071                 }
1072             }
1073             else
1074                 aCurPos.AdjustY(nVPage );
1075             break;
1076         case SID_CURSORHOME:
1077             if( nMaxVertPos<0 )
1078             {
1079                 tools::Long nPage  = pPreview->GetPageNo();
1080                 tools::Long nTotal = pPreview->GetTotalPages();
1081                 if( nTotal && nPage != 0 )
1082                 {
1083                     SfxViewFrame* pSfxViewFrame = GetViewFrame();
1084                     SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_FIRST );
1085                     Execute( aSfxRequest );
1086                 }
1087             }
1088             else
1089             {
1090                 aCurPos.setY( 0 );
1091                 aCurPos.setX( 0 );
1092             }
1093             break;
1094         case SID_CURSOREND:
1095             if( nMaxVertPos<0 )
1096             {
1097                 if( !pPreview->AllTested() )
1098                     pPreview->CalcAll();
1099                 tools::Long nPage  = pPreview->GetPageNo();
1100                 tools::Long nTotal = pPreview->GetTotalPages();
1101                 if( nTotal && nPage+1 != nTotal )
1102                 {
1103                     SfxViewFrame* pSfxViewFrame = GetViewFrame();
1104                     SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_LAST );
1105                     Execute( aSfxRequest );
1106                 }
1107             }
1108             else
1109             {
1110                 aCurPos.setY( nVRange );
1111                 aCurPos.setX( nHRange );
1112             }
1113             break;
1114     }
1115 
1116         // nHRange-nHPage might be negative, that's why we check for < 0 afterwards
1117 
1118     if( aCurPos.Y() > (nVRange-nVPage) )
1119         aCurPos.setY( nVRange-nVPage );
1120     if( aCurPos.Y() < 0 )
1121         aCurPos.setY( 0 );
1122     if( aCurPos.X() > (nHRange-nHPage) )
1123         aCurPos.setX( nHRange-nHPage );
1124     if( aCurPos.X() < 0 )
1125         aCurPos.setX( 0 );
1126 
1127     if( nMaxVertPos>=0 )
1128     {
1129         if( aCurPos.Y() != aPrevPos.Y() )
1130         {
1131             pVerScroll->SetThumbPos( aCurPos.Y() );
1132             pPreview->SetYOffset( aCurPos.Y() );
1133         }
1134     }
1135 
1136     if( aCurPos.X() != aPrevPos.X() )
1137     {
1138         pHorScroll->SetThumbPos( aCurPos.X() );
1139         pPreview->SetXOffset( aCurPos.X() );
1140     }
1141 
1142 }
1143 
ExitPreview()1144 void ScPreviewShell::ExitPreview()
1145 {
1146     GetViewFrame()->GetDispatcher()->Execute(SID_VIEWSHELL0, SfxCallMode::ASYNCHRON);
1147 }
1148 
AddAccessibilityObject(SfxListener & rObject)1149 void ScPreviewShell::AddAccessibilityObject( SfxListener& rObject )
1150 {
1151     if (!pAccessibilityBroadcaster)
1152         pAccessibilityBroadcaster.reset( new SfxBroadcaster );
1153 
1154     rObject.StartListening( *pAccessibilityBroadcaster );
1155 }
1156 
RemoveAccessibilityObject(SfxListener & rObject)1157 void ScPreviewShell::RemoveAccessibilityObject( SfxListener& rObject )
1158 {
1159     if (pAccessibilityBroadcaster)
1160         rObject.EndListening( *pAccessibilityBroadcaster );
1161     else
1162     {
1163         OSL_FAIL("no accessibility broadcaster?");
1164     }
1165 }
1166 
BroadcastAccessibility(const SfxHint & rHint)1167 void ScPreviewShell::BroadcastAccessibility( const SfxHint &rHint )
1168 {
1169     if (pAccessibilityBroadcaster)
1170         pAccessibilityBroadcaster->Broadcast( rHint );
1171 }
1172 
HasAccessibilityObjects() const1173 bool ScPreviewShell::HasAccessibilityObjects() const
1174 {
1175     return pAccessibilityBroadcaster && pAccessibilityBroadcaster->HasListeners();
1176 }
1177 
GetLocationData()1178 const ScPreviewLocationData& ScPreviewShell::GetLocationData()
1179 {
1180     return pPreview->GetLocationData();
1181 }
1182 
GetDocument()1183 ScDocument& ScPreviewShell::GetDocument()
1184 {
1185     return pDocShell->GetDocument();
1186 }
1187 
1188 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1189