Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / ui / view / prevwsh.cxx
blob885273f78739d21056765f03ec6323d9de52aa05
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 <cstdlib>
24 #include "scitems.hxx"
25 #include <comphelper/string.hxx>
26 #include <editeng/eeitem.hxx>
28 #include <sfx2/app.hxx>
29 #include <editeng/sizeitem.hxx>
30 #include <svl/srchitem.hxx>
31 #include <svx/zoomslideritem.hxx>
32 #include <svx/svdview.hxx>
33 #include <sfx2/dispatch.hxx>
34 #include <sfx2/objface.hxx>
35 #include <sfx2/request.hxx>
36 #include <svl/stritem.hxx>
37 #include <svl/whiter.hxx>
38 #include <vcl/msgbox.hxx>
39 #include <vcl/help.hxx>
40 #include <vcl/settings.hxx>
41 #include <tools/urlobj.hxx>
42 #include <sfx2/docfile.hxx>
43 #include <sfx2/printer.hxx>
45 #include "prevwsh.hxx"
46 #include "preview.hxx"
47 #include "printfun.hxx"
48 #include "attrib.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 "scresid.hxx"
56 #include "globstr.hrc"
57 #include "sc.hrc"
58 #include "ViewSettingsSequenceDefines.hxx"
59 #include "tpprint.hxx"
60 #include "printopt.hxx"
61 #include "viewuno.hxx"
62 #include <sax/tools/converter.hxx>
63 #include <rtl/ustrbuf.hxx>
65 #include <svx/svxdlg.hxx>
66 #include <svx/dialogs.hrc>
68 #include <basegfx/tools/zoomtools.hxx>
69 #include <svx/zoom_def.hxx>
70 #include <com/sun/star/document/XDocumentProperties.hpp>
72 #include "scabstdlg.hxx"
73 // for mouse wheel
74 #define MINZOOM_SLIDER 10
75 #define MAXZOOM_SLIDER 400
77 #define SC_USERDATA_SEP ';'
79 using namespace com::sun::star;
81 #define ScPreviewShell
82 #include "scslots.hxx"
84 #include <memory>
87 SFX_IMPL_INTERFACE(ScPreviewShell, SfxViewShell)
89 void ScPreviewShell::InitInterface_Impl()
91 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT|SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER|SFX_VISIBILITY_READONLYDOC,
92 RID_OBJECTBAR_PREVIEW);
94 GetStaticInterface()->RegisterPopupMenu("preview");
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 pCorner = VclPtr<ScrollBarBox>::Create( pParent, WB_SIZEABLE );
123 pHorScroll = VclPtr<ScrollBar>::Create(pParent, WB_HSCROLL );
124 pVerScroll = VclPtr<ScrollBar>::Create(pParent, WB_VSCROLL);
126 // SSA: --- RTL --- no mirroring for horizontal scrollbars
127 pHorScroll->EnableRTL( false );
129 pHorScroll->SetEndScrollHdl( LINK( this, ScPreviewShell, ScrollHandler ) );
130 pVerScroll->SetEndScrollHdl( LINK( this, ScPreviewShell, ScrollHandler ) );
132 pPreview = VclPtr<ScPreview>::Create( pParent, pDocShell, this );
134 SetPool( &SC_MOD()->GetPool() );
135 SetWindow( pPreview );
136 StartListening(*pDocShell,true);
137 StartListening(*SfxGetpApp(),true); // #i62045# #i62046# application is needed for Calc's own hints
138 SfxBroadcaster* pDrawBC = pDocShell->GetDocument().GetDrawBroadcaster();
139 if (pDrawBC)
140 StartListening(*pDrawBC);
142 pHorScroll->Show( false );
143 pVerScroll->Show( false );
144 pCorner->Show();
145 SetHelpId( HID_SCSHELL_PREVWSH );
146 SetName("Preview");
149 ScPreviewShell::ScPreviewShell( SfxViewFrame* pViewFrame,
150 SfxViewShell* pOldSh ) :
151 SfxViewShell( pViewFrame, SfxViewShellFlags::CAN_PRINT | SfxViewShellFlags::HAS_PRINTOPTIONS ),
152 pDocShell( static_cast<ScDocShell*>(pViewFrame->GetObjectShell()) ),
153 mpFrameWindow(nullptr),
154 nSourceDesignMode( TRISTATE_INDET ),
155 nMaxVertPos(0),
156 pAccessibilityBroadcaster( nullptr )
158 Construct( &pViewFrame->GetWindow() );
160 if ( pOldSh && dynamic_cast<const ScTabViewShell*>( pOldSh) != nullptr )
162 // store view settings, show table from TabView
163 //! store live ScViewData instead, and update on ScTablesHint?
164 //! or completely forget aSourceData on ScTablesHint?
166 ScTabViewShell* pTabViewShell = static_cast<ScTabViewShell*>(pOldSh);
167 const ScViewData& rData = pTabViewShell->GetViewData();
168 rData.WriteUserDataSequence( aSourceData );
169 pPreview->SetSelectedTabs(rData.GetMarkData());
170 InitStartTable( rData.GetTabNo() );
172 // also have to store the TabView's DesignMode state
173 // (only if draw view exists)
174 SdrView* pDrawView = pTabViewShell->GetSdrView();
175 if ( pDrawView )
176 nSourceDesignMode
177 = pDrawView->IsDesignMode() ? TRISTATE_TRUE : TRISTATE_FALSE;
180 new ScPreviewObj(this);
183 ScPreviewShell::~ScPreviewShell()
185 if (mpFrameWindow)
186 mpFrameWindow->SetCloseHdl(Link<SystemWindow&,void>()); // Remove close handler.
188 // #108333#; notify Accessibility that Shell is dying and before destroy all
189 BroadcastAccessibility( SfxSimpleHint( SFX_HINT_DYING ) );
190 DELETEZ(pAccessibilityBroadcaster);
192 SfxBroadcaster* pDrawBC = pDocShell->GetDocument().GetDrawBroadcaster();
193 if (pDrawBC)
194 EndListening(*pDrawBC);
195 EndListening(*SfxGetpApp());
196 EndListening(*pDocShell);
198 SetWindow(nullptr);
199 pPreview.disposeAndClear();
200 pHorScroll.disposeAndClear();
201 pVerScroll.disposeAndClear();
202 pCorner.disposeAndClear();
204 // normal mode of operation is switching back to default view in the same frame,
205 // so there's no need to activate any other window here anymore
208 void ScPreviewShell::InitStartTable(SCTAB nTab)
210 pPreview->SetPageNo( pPreview->GetFirstPage(nTab) );
213 void ScPreviewShell::AdjustPosSizePixel( const Point &rPos, const Size &rSize )
215 Size aOutSize( rSize );
216 pPreview->SetPosSizePixel( rPos, aOutSize );
218 if ( SvxZoomType::WHOLEPAGE == eZoom )
219 pPreview->SetZoom( pPreview->GetOptimalZoom(false) );
220 else if ( SvxZoomType::PAGEWIDTH == eZoom )
221 pPreview->SetZoom( pPreview->GetOptimalZoom(true) );
223 UpdateNeededScrollBars();
226 void ScPreviewShell::InnerResizePixel( const Point &rOfs, const Size &rSize )
228 AdjustPosSizePixel( rOfs,rSize );
231 void ScPreviewShell::OuterResizePixel( const Point &rOfs, const Size &rSize )
233 AdjustPosSizePixel( rOfs,rSize );
236 bool ScPreviewShell::GetPageSize( Size& aPageSize )
238 ScDocument& rDoc = pDocShell->GetDocument();
239 SCTAB nTab = pPreview->GetTab();
241 ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool();
242 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( rDoc.GetPageStyle( nTab ),
243 SfxStyleFamily::Page );
244 OSL_ENSURE(pStyleSheet,"No style sheet");
245 if (!pStyleSheet) return false;
246 const SfxItemSet* pParamSet = &pStyleSheet->GetItemSet();
248 aPageSize = static_cast<const SvxSizeItem&>( pParamSet->Get(ATTR_PAGE_SIZE)).GetSize();
249 aPageSize.Width() = (long) (aPageSize.Width() * HMM_PER_TWIPS );
250 aPageSize.Height() = (long) (aPageSize.Height() * HMM_PER_TWIPS );
251 return true;
254 void ScPreviewShell::UpdateNeededScrollBars( bool bFromZoom )
256 Size aPageSize;
257 OutputDevice* pDevice = Application::GetDefaultDevice();
259 long nBarW = GetViewFrame()->GetWindow().GetSettings().GetStyleSettings().GetScrollBarSize();
260 long nBarH = nBarW;
262 long aHeightOffSet = pDevice ? pDevice->PixelToLogic( Size( nBarW, nBarH ), pPreview->GetMapMode() ).Height() : 0;
263 long aWidthOffSet = aHeightOffSet;
265 if (!GetPageSize( aPageSize ))
266 return;
268 // for centering, page size without the shadow is used
269 bool bVert = pVerScroll->IsVisible();
270 bool bHori = pHorScroll->IsVisible();
271 Size aWindowSize = pPreview->GetOutputSize();
272 Point aPos = pPreview->GetPosPixel();
273 Size aWindowPixelSize = pPreview->GetOutputSizePixel();
275 // if we are called from Zoom then we need to compensate for whatever
276 // scrollbars were displayed before the zoom was called
277 if ( bFromZoom )
279 if ( bVert )
281 aWindowPixelSize.Width() += nBarH;
282 aWindowSize.Width() += aHeightOffSet;
284 if ( bHori )
286 aWindowPixelSize.Height() += nBarW;
287 aWindowSize.Height() += aWidthOffSet;
291 // recalculate any needed scrollbars
292 long nMaxWidthPos = aPageSize.Width() - aWindowSize.Width();
293 if ( nMaxWidthPos<0 )
294 bHori = false;
295 else
296 bHori = true;
297 long nMaxHeightPos = aPageSize.Height() - aWindowSize.Height();
298 if ( nMaxHeightPos < 0 )
299 bVert = false;
300 else
301 bVert = true;
303 // see if having a scroll bar requires the other
304 if ( bVert != bHori && ( bVert || bHori ) )
306 if ( bVert && ( (nMaxWidthPos + aWidthOffSet ) > 0 ) )
307 bHori = true;
308 else if ( (nMaxHeightPos + aHeightOffSet ) > 0 )
309 bVert = true;
311 pHorScroll->Show( bHori );
312 pVerScroll->Show( bVert );
314 // make room for needed scrollbars ( and reduce the size
315 // of the preview appropriately )
316 if ( bHori )
317 aWindowPixelSize.Height() -= nBarW;
318 if ( bVert )
319 aWindowPixelSize.Width() -= nBarH;
321 pPreview->SetSizePixel( aWindowPixelSize );
322 pHorScroll->SetPosSizePixel( Point( aPos.X(), aPos.Y() + aWindowPixelSize.Height() ),
323 Size( aWindowPixelSize.Width(), nBarH ) );
324 pVerScroll->SetPosSizePixel( Point( aPos.X() + aWindowPixelSize.Width(), aPos.Y() ),
325 Size( nBarW, aWindowPixelSize.Height() ) );
326 pCorner->SetPosSizePixel( Point( aPos.X() + aWindowPixelSize.Width(), aPos.Y() + aWindowPixelSize.Height() ),
327 Size( nBarW, nBarH ) );
328 UpdateScrollBars();
331 void ScPreviewShell::UpdateScrollBars()
333 Size aPageSize;
334 if ( !GetPageSize( aPageSize ) )
335 return;
337 // for centering, page size without the shadow is used
339 Size aWindowSize = pPreview->GetOutputSize();
341 Point aOfs = pPreview->GetOffset();
343 if( pHorScroll )
345 pHorScroll->SetRange( Range( 0, aPageSize.Width() ) );
346 pHorScroll->SetLineSize( aWindowSize.Width() / 16 );
347 pHorScroll->SetPageSize( aWindowSize.Width() );
348 pHorScroll->SetVisibleSize( aWindowSize.Width() );
349 long nMaxPos = aPageSize.Width() - aWindowSize.Width();
350 if ( nMaxPos<0 )
352 // page smaller than window -> center (but put scrollbar to 0)
353 aOfs.X() = 0;
354 pPreview->SetXOffset( nMaxPos / 2 );
356 else if (aOfs.X() < 0)
358 // page larger than window -> never use negative offset
359 aOfs.X() = 0;
360 pPreview->SetXOffset( 0 );
362 else if (aOfs.X() > nMaxPos)
364 // limit offset to align with right edge of window
365 aOfs.X() = nMaxPos;
366 pPreview->SetXOffset(nMaxPos);
368 pHorScroll->SetThumbPos( aOfs.X() );
371 if( pVerScroll )
373 long nPageNo = pPreview->GetPageNo();
374 long nTotalPages = pPreview->GetTotalPages();
376 nMaxVertPos = aPageSize.Height() - aWindowSize.Height();
377 pVerScroll->SetLineSize( aWindowSize.Height() / 16 );
378 pVerScroll->SetPageSize( aWindowSize.Height() );
379 pVerScroll->SetVisibleSize( aWindowSize.Height() );
380 if ( nMaxVertPos < 0 )
382 // page smaller than window -> center (but put scrollbar to 0)
383 aOfs.Y() = 0;
384 pPreview->SetYOffset( nMaxVertPos / 2 );
385 pVerScroll->SetThumbPos( nPageNo * aWindowSize.Height() );
386 pVerScroll->SetRange( Range( 0, aWindowSize.Height() * nTotalPages ));
388 else if (aOfs.Y() < 0)
390 // page larger than window -> never use negative offset
391 pVerScroll->SetRange( Range( 0, aPageSize.Height() ) );
392 aOfs.Y() = 0;
393 pPreview->SetYOffset( 0 );
394 pVerScroll->SetThumbPos( aOfs.Y() );
396 else if (aOfs.Y() > nMaxVertPos )
398 // limit offset to align with window bottom
399 pVerScroll->SetRange( Range( 0, aPageSize.Height() ) );
400 aOfs.Y() = nMaxVertPos;
401 pPreview->SetYOffset( nMaxVertPos );
402 pVerScroll->SetThumbPos( aOfs.Y() );
407 IMPL_LINK_TYPED( ScPreviewShell, ScrollHandler, ScrollBar*, pScroll, void )
409 long nPos = pScroll->GetThumbPos();
410 long nDelta = pScroll->GetDelta();
411 long nMaxRange = pScroll->GetRangeMax();
412 long nTotalPages = pPreview->GetTotalPages();
413 long nPageNo = 0;
414 long nPerPageLength = 0;
415 bool bIsDivide = true;
417 if( nTotalPages )
418 nPerPageLength = nMaxRange / nTotalPages;
420 if( nPerPageLength )
422 nPageNo = nPos / nPerPageLength;
423 if( nPos % nPerPageLength )
425 bIsDivide = false;
426 nPageNo ++;
430 bool bHoriz = ( pScroll == pHorScroll );
432 if( bHoriz )
433 pPreview->SetXOffset( nPos );
434 else
436 if( nMaxVertPos > 0 )
437 pPreview->SetYOffset( nPos );
438 else
440 Point aMousePos = pScroll->OutputToNormalizedScreenPixel( pScroll->GetPointerPosPixel() );
441 Point aPos = pScroll->GetParent()->OutputToNormalizedScreenPixel( pScroll->GetPosPixel() );
442 OUString aHelpStr;
443 Rectangle aRect;
444 QuickHelpFlags nAlign;
446 if( nDelta < 0 )
448 if ( nTotalPages && nPageNo > 0 && !bIsDivide )
449 pPreview->SetPageNo( nPageNo-1 );
450 if( bIsDivide )
451 pPreview->SetPageNo( nPageNo );
453 aHelpStr = ScGlobal::GetRscString( STR_PAGE ) +
454 " " + OUString::number( nPageNo ) +
455 " / " + OUString::number( nTotalPages );
457 else if( nDelta > 0 )
459 bool bAllTested = pPreview->AllTested();
460 if ( nTotalPages && ( nPageNo < nTotalPages || !bAllTested ) )
461 pPreview->SetPageNo( nPageNo );
463 aHelpStr = ScGlobal::GetRscString( STR_PAGE ) +
464 " " + OUString::number( nPageNo+1 ) +
465 " / " + OUString::number( nTotalPages );
468 aRect.Left() = aPos.X() - 8;
469 aRect.Top() = aMousePos.Y();
470 aRect.Right() = aRect.Left();
471 aRect.Bottom() = aRect.Top();
472 nAlign = QuickHelpFlags::Bottom|QuickHelpFlags::Center;
473 Help::ShowQuickHelp( pScroll->GetParent(), aRect, aHelpStr, nAlign );
478 IMPL_LINK_NOARG_TYPED(ScPreviewShell, CloseHdl, SystemWindow&, void)
480 ExitPreview();
483 bool ScPreviewShell::ScrollCommand( const CommandEvent& rCEvt )
485 bool bDone = false;
486 const CommandWheelData* pData = rCEvt.GetWheelData();
487 if ( pData && pData->GetMode() == CommandWheelMode::ZOOM )
489 long nOld = pPreview->GetZoom();
490 long nNew;
491 if ( pData->GetDelta() < 0 )
492 nNew = std::max( (long) MINZOOM, basegfx::zoomtools::zoomOut( nOld ));
493 else
494 nNew = std::min( (long) MAXZOOM, basegfx::zoomtools::zoomIn( nOld ));
496 if ( nNew != nOld )
498 eZoom = SvxZoomType::PERCENT;
499 pPreview->SetZoom( (sal_uInt16)nNew );
502 bDone = true;
504 else
506 bDone = pPreview->HandleScrollCommand( rCEvt, pHorScroll, pVerScroll );
509 return bDone;
512 SfxPrinter* ScPreviewShell::GetPrinter( bool bCreate )
514 return pDocShell->GetPrinter(bCreate);
517 sal_uInt16 ScPreviewShell::SetPrinter( SfxPrinter *pNewPrinter, SfxPrinterChangeFlags nDiffFlags )
519 return pDocShell->SetPrinter( pNewPrinter, nDiffFlags );
522 bool ScPreviewShell::HasPrintOptionsPage() const
524 return true;
527 VclPtr<SfxTabPage> ScPreviewShell::CreatePrintOptionsPage( vcl::Window *pParent, const SfxItemSet &rOptions )
529 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
530 OSL_ENSURE(pFact, "ScAbstractFactory create fail!");
531 ::CreateTabPage ScTpPrintOptionsCreate = pFact->GetTabPageCreatorFunc( RID_SCPAGE_PRINT );
532 if ( ScTpPrintOptionsCreate )
533 return ScTpPrintOptionsCreate( pParent, &rOptions );
534 return VclPtr<SfxTabPage>();
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 moreasssertion!
546 ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
547 if ( pInputHdl )
548 pInputHdl->NotifyChange( nullptr );
552 void ScPreviewShell::Deactivate(bool bMDI)
554 SfxViewShell::Deactivate(bMDI);
556 if (bMDI)
561 void ScPreviewShell::Execute( SfxRequest& rReq )
563 sal_uInt16 nSlot = rReq.GetSlot();
564 const SfxItemSet* pReqArgs = rReq.GetArgs();
566 switch ( nSlot )
568 case SID_FORMATPAGE:
569 case SID_STATUS_PAGESTYLE:
570 case SID_HFEDIT:
571 pDocShell->ExecutePageStyle( *this, rReq, pPreview->GetTab() );
572 break;
573 case SID_REPAINT:
574 pPreview->Invalidate();
575 rReq.Done();
576 break;
577 case SID_PREV_TABLE: // Accelerator
578 case SID_PREVIEW_PREVIOUS:
580 long nPage = pPreview->GetPageNo();
581 long nTotal = pPreview->GetTotalPages();
582 if (nTotal && nPage > 0)
583 pPreview->SetPageNo( nPage-1 );
585 break;
586 case SID_NEXT_TABLE: // Accelerator
587 case SID_PREVIEW_NEXT:
589 bool bAllTested = pPreview->AllTested();
590 long nPage = pPreview->GetPageNo();
591 long nTotal = pPreview->GetTotalPages();
592 if (nTotal && (nPage+1 < nTotal || !bAllTested))
593 pPreview->SetPageNo( nPage+1 );
595 break;
596 case SID_CURSORTOPOFFILE: // Accelerator
597 case SID_PREVIEW_FIRST:
599 long nPage = pPreview->GetPageNo();
600 long nTotal = pPreview->GetTotalPages();
601 if (nTotal && nPage != 0)
602 pPreview->SetPageNo( 0 );
604 break;
605 case SID_CURSORENDOFFILE: // Accelerator
606 case SID_PREVIEW_LAST:
608 if (!pPreview->AllTested())
609 pPreview->CalcAll();
611 long nPage = pPreview->GetPageNo();
612 long nTotal = pPreview->GetTotalPages();
613 if (nTotal && nPage+1 != nTotal)
614 pPreview->SetPageNo( nTotal-1 );
616 break;
617 case SID_ATTR_ZOOM:
618 case FID_SCALE:
620 sal_uInt16 nZoom = 100;
621 bool bCancel = false;
623 eZoom = SvxZoomType::PERCENT;
625 if ( pReqArgs )
628 const SvxZoomItem& rZoomItem = static_cast<const SvxZoomItem&>(
629 pReqArgs->Get(SID_ATTR_ZOOM));
631 eZoom = rZoomItem.GetType();
632 nZoom = rZoomItem.GetValue();
634 else
636 SfxItemSet aSet ( GetPool(), SID_ATTR_ZOOM, SID_ATTR_ZOOM );
637 SvxZoomItem aZoomItem( SvxZoomType::PERCENT, pPreview->GetZoom(), SID_ATTR_ZOOM );
639 aSet.Put( aZoomItem );
640 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
641 if(pFact)
643 std::unique_ptr<AbstractSvxZoomDialog> pDlg(pFact->CreateSvxZoomDialog(nullptr, aSet));
644 OSL_ENSURE(pDlg, "Dialog creation failed!");
645 pDlg->SetLimits( 20, 400 );
646 pDlg->HideButton( ZoomButtonId::OPTIMAL );
647 bCancel = ( RET_CANCEL == pDlg->Execute() );
649 if ( !bCancel )
651 const SvxZoomItem& rZoomItem = static_cast<const SvxZoomItem&>(
652 pDlg->GetOutputItemSet()->
653 Get( SID_ATTR_ZOOM ));
655 eZoom = rZoomItem.GetType();
656 nZoom = rZoomItem.GetValue();
661 if ( !bCancel )
663 switch ( eZoom )
665 case SvxZoomType::OPTIMAL:
666 case SvxZoomType::WHOLEPAGE:
667 nZoom = pPreview->GetOptimalZoom(false);
668 break;
669 case SvxZoomType::PAGEWIDTH:
670 nZoom = pPreview->GetOptimalZoom(true);
671 break;
672 default:
674 // added to avoid warnings
678 pPreview->SetZoom( nZoom );
679 rReq.Done();
682 break;
683 case SID_PREVIEW_ZOOMIN:
685 sal_uInt16 nNew = pPreview->GetZoom() + 20 ;
686 nNew -= nNew % 20;
687 pPreview->SetZoom( nNew );
688 eZoom = SvxZoomType::PERCENT;
689 rReq.Done();
691 break;
692 case SID_PREVIEW_ZOOMOUT:
694 sal_uInt16 nNew = pPreview->GetZoom() - 1;
695 nNew -= nNew % 20;
696 pPreview->SetZoom( nNew );
697 eZoom = SvxZoomType::PERCENT;
698 rReq.Done();
700 break;
701 case SID_PREVIEW_MARGIN:
703 bool bMargin = pPreview->GetPageMargins();
704 pPreview->SetPageMargins( !bMargin );
705 pPreview->Invalidate();
706 rReq.Done();
708 break;
709 case SID_ATTR_ZOOMSLIDER:
711 const SfxPoolItem* pItem;
712 eZoom = SvxZoomType::PERCENT;
713 if( pReqArgs && SfxItemState::SET == pReqArgs->GetItemState( SID_ATTR_ZOOMSLIDER, true, &pItem ) )
715 const sal_uInt16 nCurrentZoom = static_cast<const SvxZoomSliderItem*>(pItem)->GetValue();
716 if( nCurrentZoom )
718 pPreview->SetZoom( nCurrentZoom );
719 rReq.Done();
723 break;
724 case SID_PREVIEW_SCALINGFACTOR:
726 const SfxPoolItem* pItem;
727 SCTAB nTab = pPreview->GetTab();
728 OUString aOldName = pDocShell->GetDocument().GetPageStyle( pPreview->GetTab() );
729 ScStyleSheetPool* pStylePool = pDocShell->GetDocument().GetStyleSheetPool();
730 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aOldName, SfxStyleFamily::Page );
731 OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" );
733 if ( pReqArgs && pStyleSheet && SfxItemState::SET == pReqArgs->GetItemState( SID_PREVIEW_SCALINGFACTOR, true, &pItem ) )
735 const sal_uInt16 nCurrentZoom = static_cast<const SvxZoomSliderItem *>(pItem)->GetValue();
736 SfxItemSet& rSet = pStyleSheet->GetItemSet();
737 rSet.Put( SfxUInt16Item( ATTR_PAGE_SCALE, nCurrentZoom ) );
738 ScPrintFunc aPrintFunc( pDocShell, pDocShell->GetPrinter(), nTab );
739 aPrintFunc.UpdatePages();
740 rReq.Done();
742 GetViewFrame()->GetBindings().Invalidate( nSlot );
744 break;
745 case SID_PRINTPREVIEW:
746 case SID_PREVIEW_CLOSE:
747 // print preview is now always in the same frame as the tab view
748 // -> always switch this frame back to normal view
749 // (ScTabViewShell ctor reads stored view data)
751 ExitPreview();
752 break;
753 case SID_CURSORPAGEUP:
754 case SID_CURSORPAGEDOWN:
755 case SID_CURSORHOME:
756 case SID_CURSOREND:
757 case SID_CURSORUP:
758 case SID_CURSORDOWN:
759 case SID_CURSORLEFT:
760 case SID_CURSORRIGHT:
761 DoScroll( nSlot );
762 break;
763 case SID_CANCEL:
764 if( ScViewUtil::IsFullScreen( *this ) )
765 ScViewUtil::SetFullScreen( *this, false );
766 break;
768 default:
769 break;
773 void ScPreviewShell::GetState( SfxItemSet& rSet )
775 pPreview->SetInGetState(true);
777 SCTAB nTab = pPreview->GetTab();
778 long nPage = pPreview->GetPageNo();
779 long nTotal = pPreview->GetTotalPages();
780 sal_uInt16 nZoom = pPreview->GetZoom();
781 bool bAllTested = pPreview->AllTested();
783 SfxWhichIter aIter(rSet);
784 sal_uInt16 nWhich = aIter.FirstWhich();
785 while ( nWhich )
787 switch (nWhich)
789 case SID_STATUS_PAGESTYLE:
790 case SID_HFEDIT:
791 pDocShell->GetStatePageStyle( *this, rSet, nTab );
792 break;
793 case SID_UNDO:
794 case SID_REDO:
795 case SID_REPEAT:
796 case SID_SAVEDOC:
797 case SID_SAVEASDOC:
798 case SID_MAIL_SENDDOC:
799 case SID_VIEW_DATA_SOURCE_BROWSER:
800 case SID_QUITAPP:
801 rSet.DisableItem(nWhich);
802 break;
803 case SID_PREVIEW_PREVIOUS:
804 case SID_PREVIEW_FIRST:
805 if (!nTotal || nPage==0)
806 rSet.DisableItem(nWhich);
807 break;
808 case SID_PREVIEW_NEXT:
809 case SID_PREVIEW_LAST:
810 if (bAllTested)
811 if (!nTotal || nPage==nTotal-1)
812 rSet.DisableItem(nWhich);
813 break;
814 case SID_PREVIEW_ZOOMIN:
815 if (nZoom >= 400)
816 rSet.DisableItem(nWhich);
817 break;
818 case SID_PREVIEW_ZOOMOUT:
819 if (nZoom <= 20)
820 rSet.DisableItem(nWhich);
821 break;
822 case SID_ATTR_ZOOM:
824 SvxZoomItem aZoom( eZoom, nZoom, nWhich );
825 aZoom.SetValueSet( SvxZoomEnableFlags::ALL & ~SvxZoomEnableFlags::OPTIMAL );
826 rSet.Put( aZoom );
828 break;
829 case SID_ATTR_ZOOMSLIDER:
831 SvxZoomSliderItem aZoomSliderItem( nZoom, MINZOOM, MAXZOOM, SID_ATTR_ZOOMSLIDER );
832 aZoomSliderItem.AddSnappingPoint( 100 );
833 rSet.Put( aZoomSliderItem );
835 break;
836 case SID_PREVIEW_SCALINGFACTOR:
838 if( pDocShell->IsReadOnly() )
839 rSet.DisableItem( nWhich );
840 else
842 OUString aOldName = pDocShell->GetDocument().GetPageStyle( pPreview->GetTab() );
843 ScStyleSheetPool* pStylePool = pDocShell->GetDocument().GetStyleSheetPool();
844 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aOldName, SfxStyleFamily::Page );
845 OSL_ENSURE( pStyleSheet, "PageStyle not found! :-/" );
847 if ( pStyleSheet )
849 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
850 sal_uInt16 nCurrentZoom = static_cast<const SfxUInt16Item&>(rStyleSet.Get(ATTR_PAGE_SCALE)).GetValue();
851 if( nCurrentZoom )
853 SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM_SLIDER, MAXZOOM_SLIDER, SID_PREVIEW_SCALINGFACTOR );
854 aZoomSliderItem.AddSnappingPoint( 100 );
855 rSet.Put( aZoomSliderItem );
857 else
858 rSet.DisableItem( nWhich );
862 break;
863 case SID_STATUS_DOCPOS:
864 rSet.Put( SfxStringItem( nWhich, pPreview->GetPosString() ) );
865 break;
866 case SID_PRINTPREVIEW:
867 rSet.Put( SfxBoolItem( nWhich, true ) );
868 break;
869 case SID_FORMATPAGE:
870 case SID_PREVIEW_MARGIN:
871 if( pDocShell->IsReadOnly() )
872 rSet.DisableItem( nWhich );
873 break;
876 nWhich = aIter.NextWhich();
879 pPreview->SetInGetState(false);
882 void ScPreviewShell::FillFieldData( ScHeaderFieldData& rData )
884 ScDocument& rDoc = pDocShell->GetDocument();
885 SCTAB nTab = pPreview->GetTab();
886 OUString aTmp;
887 rDoc.GetName(nTab, aTmp);
888 rData.aTabName = aTmp;
890 if( pDocShell->getDocProperties()->getTitle().getLength() != 0 )
891 rData.aTitle = pDocShell->getDocProperties()->getTitle();
892 else
893 rData.aTitle = pDocShell->GetTitle();
895 const INetURLObject& rURLObj = pDocShell->GetMedium()->GetURLObject();
896 rData.aLongDocName = rURLObj.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS );
897 if ( !rData.aLongDocName.isEmpty() )
898 rData.aShortDocName = rURLObj.GetName( INetURLObject::DECODE_UNAMBIGUOUS );
899 else
900 rData.aShortDocName = rData.aLongDocName = rData.aTitle;
901 rData.nPageNo = pPreview->GetPageNo() + 1;
903 bool bAllTested = pPreview->AllTested();
904 if (bAllTested)
905 rData.nTotalPages = pPreview->GetTotalPages();
906 else
907 rData.nTotalPages = 99;
909 // the dialog knows eNumType
912 void ScPreviewShell::WriteUserData(OUString& rData, bool /* bBrowse */)
914 // nZoom
915 // nPageNo
917 rData = OUString::number(pPreview->GetZoom())
918 + OUStringLiteral1<SC_USERDATA_SEP>()
919 + OUString::number(pPreview->GetPageNo());
922 void ScPreviewShell::ReadUserData(const OUString& rData, bool /* bBrowse */)
924 if (!rData.isEmpty())
926 sal_Int32 nIndex = 0;
927 pPreview->SetZoom((sal_uInt16)rData.getToken(0, SC_USERDATA_SEP, nIndex).toInt32());
928 pPreview->SetPageNo(rData.getToken(0, SC_USERDATA_SEP, nIndex).toInt32());
929 eZoom = SvxZoomType::PERCENT;
933 void ScPreviewShell::WriteUserDataSequence(uno::Sequence < beans::PropertyValue >& rSeq)
935 rSeq.realloc(3);
936 beans::PropertyValue* pSeq = rSeq.getArray();
937 if(pSeq)
939 sal_uInt16 nViewID(GetViewFrame()->GetCurViewId());
940 pSeq[0].Name = SC_VIEWID;
941 OUStringBuffer sBuffer(SC_VIEW);
942 ::sax::Converter::convertNumber(sBuffer,
943 static_cast<sal_Int32>(nViewID));
944 pSeq[0].Value <<= sBuffer.makeStringAndClear();
945 pSeq[1].Name = SC_ZOOMVALUE;
946 pSeq[1].Value <<= sal_Int32 (pPreview->GetZoom());
947 pSeq[2].Name = "PageNumber";
948 pSeq[2].Value <<= pPreview->GetPageNo();
952 void ScPreviewShell::ReadUserDataSequence(const uno::Sequence < beans::PropertyValue >& rSeq)
954 sal_Int32 nCount(rSeq.getLength());
955 if (nCount)
957 const beans::PropertyValue* pSeq = rSeq.getConstArray();
958 if(pSeq)
960 for(sal_Int32 i = 0; i < nCount; i++, pSeq++)
962 OUString sName(pSeq->Name);
963 if(sName == SC_ZOOMVALUE)
965 sal_Int32 nTemp = 0;
966 if (pSeq->Value >>= nTemp)
967 pPreview->SetZoom(sal_uInt16(nTemp));
969 else if (sName == "PageNumber")
971 sal_Int32 nTemp = 0;
972 if (pSeq->Value >>= nTemp)
973 pPreview->SetPageNo(nTemp);
980 void ScPreviewShell::DoScroll( sal_uInt16 nMode )
982 Point aCurPos, aPrevPos;
984 long nHRange = pHorScroll->GetRange().Max();
985 long nHLine = pHorScroll->GetLineSize();
986 long nHPage = pHorScroll->GetPageSize();
987 long nVRange = pVerScroll->GetRange().Max();
988 long nVLine = pVerScroll->GetLineSize();
989 long nVPage = pVerScroll->GetPageSize();
991 aCurPos.X() = pHorScroll->GetThumbPos();
992 aCurPos.Y() = pVerScroll->GetThumbPos();
993 aPrevPos = aCurPos;
995 long nThumbPos = pVerScroll->GetThumbPos();
996 long nRangeMax = pVerScroll->GetRangeMax();
998 switch( nMode )
1000 case SID_CURSORUP:
1001 if( nMaxVertPos<0 )
1003 long nPage = pPreview->GetPageNo();
1005 if( nPage>0 )
1007 SfxViewFrame* pSfxViewFrame = GetViewFrame();
1008 SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_PREVIOUS );
1009 Execute( aSfxRequest );
1012 else
1013 aCurPos.Y() -= nVLine;
1014 break;
1015 case SID_CURSORDOWN:
1016 if( nMaxVertPos<0 )
1018 long nPage = pPreview->GetPageNo();
1019 long nTotal = pPreview->GetTotalPages();
1021 // before testing for last page, make sure all page counts are calculated
1022 if ( nPage+1 == nTotal && !pPreview->AllTested() )
1024 pPreview->CalcAll();
1025 nTotal = pPreview->GetTotalPages();
1028 if( nPage<nTotal-1 )
1030 SfxViewFrame* pSfxViewFrame = GetViewFrame();
1031 SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_NEXT );
1032 Execute( aSfxRequest );
1035 else
1036 aCurPos.Y() += nVLine;
1037 break;
1038 case SID_CURSORLEFT:
1039 aCurPos.X() -= nHLine;
1040 break;
1041 case SID_CURSORRIGHT:
1042 aCurPos.X() += nHLine;
1043 break;
1044 case SID_CURSORPAGEUP:
1045 if( nThumbPos==0 || nMaxVertPos<0 )
1047 long nPage = pPreview->GetPageNo();
1049 if( nPage>0 )
1051 SfxViewFrame* pSfxViewFrame = GetViewFrame();
1052 SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_PREVIOUS );
1053 Execute( aSfxRequest );
1054 aCurPos.Y() = nVRange;
1057 else
1058 aCurPos.Y() -= nVPage;
1059 break;
1060 case SID_CURSORPAGEDOWN:
1061 if( (std::abs(nVPage+nThumbPos-nRangeMax)<10) || nMaxVertPos<0 )
1063 long nPage = pPreview->GetPageNo();
1064 long nTotal = pPreview->GetTotalPages();
1066 // before testing for last page, make sure all page counts are calculated
1067 if ( nPage+1 == nTotal && !pPreview->AllTested() )
1069 pPreview->CalcAll();
1070 nTotal = pPreview->GetTotalPages();
1072 if( nPage<nTotal-1 )
1074 SfxViewFrame* pSfxViewFrame = GetViewFrame();
1075 SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_NEXT );
1076 Execute( aSfxRequest );
1077 aCurPos.Y() = 0;
1080 else
1081 aCurPos.Y() += nVPage;
1082 break;
1083 case SID_CURSORHOME:
1084 if( nMaxVertPos<0 )
1086 long nPage = pPreview->GetPageNo();
1087 long nTotal = pPreview->GetTotalPages();
1088 if( nTotal && nPage != 0 )
1090 SfxViewFrame* pSfxViewFrame = GetViewFrame();
1091 SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_FIRST );
1092 Execute( aSfxRequest );
1095 else
1097 aCurPos.Y() = 0;
1098 aCurPos.X() = 0;
1100 break;
1101 case SID_CURSOREND:
1102 if( nMaxVertPos<0 )
1104 if( !pPreview->AllTested() )
1105 pPreview->CalcAll();
1106 long nPage = pPreview->GetPageNo();
1107 long nTotal = pPreview->GetTotalPages();
1108 if( nTotal && nPage+1 != nTotal )
1110 SfxViewFrame* pSfxViewFrame = GetViewFrame();
1111 SfxRequest aSfxRequest( pSfxViewFrame, SID_PREVIEW_LAST );
1112 Execute( aSfxRequest );
1115 else
1117 aCurPos.Y() = nVRange;
1118 aCurPos.X() = nHRange;
1120 break;
1123 // nHRange-nHPage might be negative, that's why we check for < 0 afterwards
1125 if( aCurPos.Y() > (nVRange-nVPage) )
1126 aCurPos.Y() = (nVRange-nVPage);
1127 if( aCurPos.Y() < 0 )
1128 aCurPos.Y() = 0;
1129 if( aCurPos.X() > (nHRange-nHPage) )
1130 aCurPos.X() = (nHRange-nHPage);
1131 if( aCurPos.X() < 0 )
1132 aCurPos.X() = 0;
1134 if( nMaxVertPos>=0 )
1136 if( aCurPos.Y() != aPrevPos.Y() )
1138 pVerScroll->SetThumbPos( aCurPos.Y() );
1139 pPreview->SetYOffset( aCurPos.Y() );
1143 if( aCurPos.X() != aPrevPos.X() )
1145 pHorScroll->SetThumbPos( aCurPos.X() );
1146 pPreview->SetXOffset( aCurPos.X() );
1151 void ScPreviewShell::ExitPreview()
1153 GetViewFrame()->GetDispatcher()->Execute(SID_VIEWSHELL0, SfxCallMode::ASYNCHRON);
1156 void ScPreviewShell::AddAccessibilityObject( SfxListener& rObject )
1158 if (!pAccessibilityBroadcaster)
1159 pAccessibilityBroadcaster = new SfxBroadcaster;
1161 rObject.StartListening( *pAccessibilityBroadcaster );
1164 void ScPreviewShell::RemoveAccessibilityObject( SfxListener& rObject )
1166 if (pAccessibilityBroadcaster)
1167 rObject.EndListening( *pAccessibilityBroadcaster );
1168 else
1170 OSL_FAIL("no accessibility broadcaster?");
1174 void ScPreviewShell::BroadcastAccessibility( const SfxHint &rHint )
1176 if (pAccessibilityBroadcaster)
1177 pAccessibilityBroadcaster->Broadcast( rHint );
1180 bool ScPreviewShell::HasAccessibilityObjects()
1182 return pAccessibilityBroadcaster && pAccessibilityBroadcaster->HasListeners();
1185 const ScPreviewLocationData& ScPreviewShell::GetLocationData()
1187 return pPreview->GetLocationData();
1190 ScDocument& ScPreviewShell::GetDocument()
1192 return pDocShell->GetDocument();
1195 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */