1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <scitems.hxx>
21 #include <editeng/eeitem.hxx>
23 #include <officecfg/Office/Common.hxx>
24 #include <svtools/colorcfg.hxx>
25 #include <svx/fmview.hxx>
26 #include <editeng/sizeitem.hxx>
27 #include <svx/svdpagv.hxx>
28 #include <sfx2/bindings.hxx>
29 #include <sfx2/viewfrm.hxx>
30 #include <sfx2/dispatch.hxx>
31 #include <svl/itemset.hxx>
32 #include <tools/multisel.hxx>
33 #include <vcl/commandevent.hxx>
34 #include <vcl/settings.hxx>
35 #include <o3tl/deleter.hxx>
36 #include <o3tl/unit_conversion.hxx>
38 #include <preview.hxx>
39 #include <prevwsh.hxx>
40 #include <prevloc.hxx>
42 #include <docfunc.hxx>
43 #include <printfun.hxx>
44 #include <printopt.hxx>
45 #include <stlpool.hxx>
46 #include <undostyl.hxx>
47 #include <drwlayer.hxx>
49 #include <markdata.hxx>
50 #include <globstr.hrc>
51 #include <scresid.hxx>
54 #include <AccessibleDocumentPagePreview.hxx>
55 #include <editeng/lrspitem.hxx>
56 #include <editeng/ulspitem.hxx>
57 #include <editeng/colritem.hxx>
58 #include <editeng/fhgtitem.hxx>
59 #include <com/sun/star/accessibility/XAccessible.hpp>
60 #include <AccessibilityHints.hxx>
61 #include <vcl/svapp.hxx>
62 #include <viewutil.hxx>
63 #include <patattr.hxx>
64 #include <columnspanset.hxx>
68 #define SC_PREVIEW_SHADOWSIZE 2
70 static tools::Long
lcl_GetDisplayStart( SCTAB nTab
, const ScDocument
* pDoc
, std::vector
<tools::Long
>& nPages
)
72 tools::Long nDisplayStart
= 0;
73 for (SCTAB i
=0; i
<nTab
; i
++)
75 if ( pDoc
->NeedPageResetAfterTab(i
) )
78 nDisplayStart
+= nPages
[i
];
83 ScPreview::ScPreview( vcl::Window
* pParent
, ScDocShell
* pDocSh
, ScPreviewShell
* pViewSh
) :
93 aDateTime( DateTime::SYSTEM
),
96 pViewShell( pViewSh
),
100 bLocationValid( false ),
103 bLeftRulerMove( false ),
104 bRightRulerMove( false ),
105 bTopRulerMove( false ),
106 bBottomRulerMove( false ),
107 bHeaderRulerMove( false ),
108 bFooterRulerMove( false ),
109 bLeftRulerChange( false ),
110 bRightRulerChange( false ),
111 bTopRulerChange( false ),
112 bBottomRulerChange( false ),
113 bHeaderRulerChange( false ),
114 bFooterRulerChange( false ),
115 bPageMargin ( false ),
116 bColRulerMove( false ),
117 mbHasEmptyRangeTable(false),
120 nColNumberButtonDown( 0 ),
124 GetOutDev()->SetOutDevViewType( OutDevViewType::PrintPreview
);
127 SetHelpId( HID_SC_WIN_PREVIEW
);
129 GetOutDev()->SetDigitLanguage( ScModule::GetOptDigitLanguage() );
132 ScPreview::~ScPreview()
137 void ScPreview::dispose()
140 pLocationData
.reset();
141 vcl::Window::dispose();
144 void ScPreview::UpdateDrawView() // nTab must be right
146 ScDocument
& rDoc
= pDocShell
->GetDocument();
147 ScDrawLayer
* pModel
= rDoc
.GetDrawLayer(); // is not 0
151 SdrPage
* pPage
= pModel
->GetPage(nTab
);
152 if ( pDrawView
&& ( !pDrawView
->GetSdrPageView() || pDrawView
->GetSdrPageView()->GetPage() != pPage
) )
154 // convert the displayed Page of drawView (see below) does not work?!?
158 if ( !pDrawView
) // New Drawing?
160 pDrawView
.reset( new FmFormView( *pModel
, GetOutDev()) );
162 // The DrawView takes over the Design-Mode from the Model
163 // (Settings "In opening Draftmode"), therefore to restore here
164 pDrawView
->SetDesignMode();
165 pDrawView
->SetPrintPreview();
166 pDrawView
->ShowSdrPage(pPage
);
169 else if ( pDrawView
)
171 pDrawView
.reset(); // for this Chart is not needed
175 void ScPreview::TestLastPage()
177 if (nPageNo
< nTotalPages
)
182 nPageNo
= nTotalPages
- 1;
183 nTab
= static_cast<SCTAB
>(nPages
.size()) -1;
184 while (nTab
> 0 && !nPages
[nTab
]) // not the last empty Table
186 OSL_ENSURE(0 < static_cast<SCTAB
>(nPages
.size()),"are all tables empty?");
187 nTabPage
= nPages
[nTab
] - 1;
189 for (sal_uInt16 i
=0; i
<nTab
; i
++)
190 nTabStart
+= nPages
[i
];
192 ScDocument
& rDoc
= pDocShell
->GetDocument();
193 nDisplayStart
= lcl_GetDisplayStart( nTab
, &rDoc
, nPages
);
195 else // empty Document
198 nPageNo
= nTabPage
= nTabStart
= nDisplayStart
= 0;
199 aState
= ScPrintState();
203 void ScPreview::CalcPages()
205 weld::WaitObject
aWait(GetFrameWeld());
207 ScDocument
& rDoc
= pDocShell
->GetDocument();
208 nTabCount
= rDoc
.GetTableCount();
210 if (maSelectedTabs
.empty())
212 SCTAB nCurrentTab
= ScDocShell::GetCurTab();
213 maSelectedTabs
.insert(nCurrentTab
);
216 SCTAB nStart
= nTabsTested
;
224 // update all pending row heights with a single progress bar,
225 // instead of a separate progress for each sheet from ScPrintFunc
226 pDocShell
->UpdatePendingRowHeights( nTabCount
-1, true );
228 // PrintOptions is passed to PrintFunc for SkipEmpty flag,
229 // but always all sheets are used (there is no selected sheet)
230 ScPrintOptions aOptions
= ScModule::get()->GetPrintOptions();
232 while (nStart
> static_cast<SCTAB
>(nPages
.size()))
234 while (nStart
> static_cast<SCTAB
>(nFirstAttr
.size()))
235 nFirstAttr
.push_back(1);
237 for (SCTAB i
=nStart
; i
<nTabCount
; i
++)
239 if ( i
== static_cast<SCTAB
>(nPages
.size()))
241 if ( i
== static_cast<SCTAB
>(nFirstAttr
.size()))
242 nFirstAttr
.push_back(1);
243 if (!aOptions
.GetAllSheets() && maSelectedTabs
.count(i
) == 0)
250 tools::Long nAttrPage
= i
> 0 ? nFirstAttr
[i
-1] : 1;
252 tools::Long nThisStart
= nTotalPages
;
253 ScPrintFunc
aPrintFunc( GetOutDev(), pDocShell
, i
, nAttrPage
, 0, nullptr, &aOptions
);
254 tools::Long nThisTab
= aPrintFunc
.GetTotalPages();
255 if (!aPrintFunc
.HasPrintRange())
256 mbHasEmptyRangeTable
= true;
258 nPages
[i
] = nThisTab
;
259 nTotalPages
+= nThisTab
;
260 nFirstAttr
[i
] = aPrintFunc
.GetFirstPageNo(); // to keep or from template
262 if (nPageNo
>=nThisStart
&& nPageNo
<nTotalPages
)
265 nTabPage
= nPageNo
- nThisStart
;
266 nTabStart
= nThisStart
;
268 aPrintFunc
.GetPrintState( aState
);
272 nDisplayStart
= lcl_GetDisplayStart( nTab
, &rDoc
, nPages
);
274 if (nTabCount
> nTabsTested
)
275 nTabsTested
= nTabCount
;
279 aState
.nDocPages
= nTotalPages
;
286 void ScPreview::RecalcPages() // only nPageNo is changed
289 return; // then CalcPages is called
291 SCTAB nOldTab
= nTab
;
294 while (nPageNo
>= nTotalPages
&& nTabsTested
< nTabCount
)
302 tools::Long nPartPages
= 0;
303 for (SCTAB i
=0; i
<nTabsTested
&& nTab
< static_cast<SCTAB
>(nPages
.size()); i
++)
305 tools::Long nThisStart
= nPartPages
;
306 nPartPages
+= nPages
[i
];
308 if (nPageNo
>=nThisStart
&& nPageNo
<nPartPages
)
311 nTabPage
= nPageNo
- nThisStart
;
312 nTabStart
= nThisStart
;
316 ScDocument
& rDoc
= pDocShell
->GetDocument();
317 nDisplayStart
= lcl_GetDisplayStart( nTab
, &rDoc
, nPages
);
320 TestLastPage(); // to test, if after last page
322 if ( nTab
!= nOldTab
)
328 void ScPreview::DoPrint( ScPreviewLocationData
* pFillLocation
)
334 UpdateDrawView(); // Spreadsheet eventually changes
337 Fraction
aPreviewZoom( nZoom
, 100 );
338 Fraction
aHorPrevZoom( static_cast<tools::Long
>( 100 * nZoom
/ pDocShell
->GetOutputFactor() ), 10000 );
339 MapMode
aMMMode( MapUnit::Map100thMM
, Point(), aHorPrevZoom
, aPreviewZoom
);
341 bool bDoPrint
= ( pFillLocation
== nullptr );
342 bool bValidPage
= ( nPageNo
< nTotalPages
);
344 ScModule
* pScMod
= ScModule::get();
345 const svtools::ColorConfig
& rColorCfg
= pScMod
->GetColorConfig();
346 Color
aBackColor( rColorCfg
.GetColorValue(svtools::APPBACKGROUND
).nColor
);
348 if ( bDoPrint
&& ( aOffset
.X() < 0 || aOffset
.Y() < 0 ) && bValidPage
)
350 SetMapMode( aMMMode
);
351 GetOutDev()->SetLineColor();
352 GetOutDev()->SetFillColor(aBackColor
);
354 Size aWinSize
= GetOutDev()->GetOutputSize();
355 if ( aOffset
.X() < 0 )
356 GetOutDev()->DrawRect(tools::Rectangle( 0, 0, -aOffset
.X(), aWinSize
.Height() ));
357 if ( aOffset
.Y() < 0 )
358 GetOutDev()->DrawRect(tools::Rectangle( 0, 0, aWinSize
.Width(), -aOffset
.Y() ));
361 tools::Long nLeftMargin
= 0;
362 tools::Long nRightMargin
= 0;
363 tools::Long nTopMargin
= 0;
364 tools::Long nBottomMargin
= 0;
365 bool bHeaderOn
= false;
366 bool bFooterOn
= false;
368 ScDocument
& rDoc
= pDocShell
->GetDocument();
369 bool bLayoutRTL
= rDoc
.IsLayoutRTL( nTab
);
374 ScPrintOptions aOptions
= pScMod
->GetPrintOptions();
376 std::unique_ptr
<ScPrintFunc
, o3tl::default_delete
<ScPrintFunc
>> pPrintFunc
;
378 pPrintFunc
.reset(new ScPrintFunc(GetOutDev(), pDocShell
, aState
, &aOptions
));
380 pPrintFunc
.reset(new ScPrintFunc(GetOutDev(), pDocShell
, nTab
, nFirstAttr
[nTab
], nTotalPages
, nullptr, &aOptions
));
382 pPrintFunc
->SetOffset(aOffset
);
383 pPrintFunc
->SetManualZoom(nZoom
);
384 pPrintFunc
->SetDateTime(aDateTime
);
385 pPrintFunc
->SetClearFlag(true);
386 pPrintFunc
->SetUseStyleColor( officecfg::Office::Common::Accessibility::IsForPagePreviews::get() );
388 pPrintFunc
->SetDrawView( pDrawView
.get() );
390 // MultiSelection for the one Page must produce something inconvenient
391 Range
aPageRange( nPageNo
+1, nPageNo
+1 );
392 MultiSelection
aPage( aPageRange
);
393 aPage
.SetTotalRange( Range(0,RANGE_MAX
) );
394 aPage
.Select( aPageRange
);
396 tools::Long nPrinted
= pPrintFunc
->DoPrint( aPage
, nTabStart
, nDisplayStart
, bDoPrint
, pFillLocation
);
397 OSL_ENSURE(nPrinted
<=1, "What is happening?");
401 //init nLeftMargin ... in the ScPrintFunc::InitParam!!!
402 nLeftMargin
= pPrintFunc
->GetLeftMargin();
403 nRightMargin
= pPrintFunc
->GetRightMargin();
404 nTopMargin
= pPrintFunc
->GetTopMargin();
405 nBottomMargin
= pPrintFunc
->GetBottomMargin();
406 nHeaderHeight
= pPrintFunc
->GetHeader().nHeight
;
407 nFooterHeight
= pPrintFunc
->GetFooter().nHeight
;
408 bHeaderOn
= pPrintFunc
->GetHeader().bEnable
;
409 bFooterOn
= pPrintFunc
->GetFooter().bEnable
;
410 mnScale
= pPrintFunc
->GetZoom();
412 if ( bDoPrint
&& bPageMargin
&& pLocationData
) // don't make use of pLocationData while filling it
414 tools::Rectangle aPixRect
;
415 tools::Rectangle aRectCellPosition
;
416 tools::Rectangle aRectPosition
;
417 pLocationData
->GetMainCellRange( aPageArea
, aPixRect
);
418 mvRight
.resize(aPageArea
.aEnd
.Col()+1);
421 pLocationData
->GetCellPosition( aPageArea
.aStart
, aRectPosition
);
422 nLeftPosition
= aRectPosition
.Left();
423 for( SCCOL i
= aPageArea
.aStart
.Col(); i
<= aPageArea
.aEnd
.Col(); i
++ )
425 pLocationData
->GetCellPosition( ScAddress( i
,aPageArea
.aStart
.Row(),aPageArea
.aStart
.Tab()),aRectCellPosition
);
426 mvRight
[i
] = aRectCellPosition
.Right();
431 pLocationData
->GetCellPosition( aPageArea
.aEnd
, aRectPosition
);
432 nLeftPosition
= aRectPosition
.Right()+1;
434 pLocationData
->GetCellPosition( aPageArea
.aStart
,aRectCellPosition
);
435 mvRight
[ aPageArea
.aEnd
.Col() ] = aRectCellPosition
.Left();
436 for( SCCOL i
= aPageArea
.aEnd
.Col(); i
> aPageArea
.aStart
.Col(); i
-- )
438 pLocationData
->GetCellPosition( ScAddress( i
,aPageArea
.aEnd
.Row(),aPageArea
.aEnd
.Tab()),aRectCellPosition
);
439 mvRight
[ i
-1 ] = mvRight
[ i
] + aRectCellPosition
.Right() - aRectCellPosition
.Left() + 1;
444 if (nPrinted
) // if not, draw everything grey
446 aLocalPageSize
= pPrintFunc
->GetPageSize();
447 aLocalPageSize
.setWidth(
448 o3tl::convert(aLocalPageSize
.Width(), o3tl::Length::twip
, o3tl::Length::mm100
));
449 aLocalPageSize
.setHeight(
450 o3tl::convert(aLocalPageSize
.Height(), o3tl::Length::twip
, o3tl::Length::mm100
));
452 nLeftMargin
= o3tl::convert(nLeftMargin
, o3tl::Length::twip
, o3tl::Length::mm100
);
453 nRightMargin
= o3tl::convert(nRightMargin
, o3tl::Length::twip
, o3tl::Length::mm100
);
454 nTopMargin
= o3tl::convert(nTopMargin
, o3tl::Length::twip
, o3tl::Length::mm100
);
455 nBottomMargin
= o3tl::convert(nBottomMargin
, o3tl::Length::twip
, o3tl::Length::mm100
);
456 constexpr auto md
= o3tl::getConversionMulDiv(o3tl::Length::twip
, o3tl::Length::mm10
);
457 const auto m
= md
.first
* mnScale
, d
= md
.second
* 100;
458 nHeaderHeight
= o3tl::convert(nHeaderHeight
, m
, d
) + nTopMargin
;
459 nFooterHeight
= o3tl::convert(nFooterHeight
, m
, d
) + nBottomMargin
;
464 pPrintFunc
->GetPrintState( aState
);
465 aState
.nDocPages
= nTotalPages
;
473 tools::Long nPageEndX
= aLocalPageSize
.Width() - aOffset
.X();
474 tools::Long nPageEndY
= aLocalPageSize
.Height() - aOffset
.Y();
476 nPageEndX
= nPageEndY
= 0;
478 Size aWinSize
= GetOutDev()->GetOutputSize();
479 Point
aWinEnd( aWinSize
.Width(), aWinSize
.Height() );
480 bool bRight
= nPageEndX
<= aWinEnd
.X();
481 bool bBottom
= nPageEndY
<= aWinEnd
.Y();
485 // There is no data to print. Print a friendly warning message and
490 // Draw background first.
491 GetOutDev()->SetLineColor();
492 GetOutDev()->SetFillColor(aBackColor
);
493 GetOutDev()->DrawRect(tools::Rectangle(0, 0, aWinEnd
.X(), aWinEnd
.Y()));
495 const ScPatternAttr
& rDefPattern(rDoc
.getCellAttributeHelper().getDefaultCellAttribute());
497 std::unique_ptr
<ScEditEngineDefaulter
> pEditEng(
498 new ScEditEngineDefaulter(EditEngine::CreatePool().get(), true));
500 pEditEng
->SetRefMapMode(aMMMode
);
501 auto pEditDefaults
= std::make_unique
<SfxItemSet
>( pEditEng
->GetEmptyItemSet() );
502 rDefPattern
.FillEditItemSet(pEditDefaults
.get());
503 pEditDefaults
->Put(SvxColorItem(COL_LIGHTGRAY
, EE_CHAR_COLOR
));
504 pEditEng
->SetDefaults(std::move(pEditDefaults
));
507 if (mbHasEmptyRangeTable
)
508 aEmptyMsg
= ScResId(STR_PRINT_PREVIEW_EMPTY_RANGE
);
510 aEmptyMsg
= ScResId(STR_PRINT_PREVIEW_NODATA
);
512 tools::Long nHeight
= 3000;
513 pEditEng
->SetDefaultItem(SvxFontHeightItem(nHeight
, 100, EE_CHAR_FONTHEIGHT
));
514 pEditEng
->SetDefaultItem(SvxFontHeightItem(nHeight
, 100, EE_CHAR_FONTHEIGHT_CJK
));
515 pEditEng
->SetDefaultItem(SvxFontHeightItem(nHeight
, 100, EE_CHAR_FONTHEIGHT_CTL
));
517 pEditEng
->SetTextCurrentDefaults(aEmptyMsg
);
520 (aWinEnd
.X() - pEditEng
->CalcTextWidth())/2,
521 (aWinEnd
.Y() - pEditEng
->GetTextHeight())/2);
523 pEditEng
->Draw(*GetOutDev(), aCenter
);
528 if( bPageMargin
&& bValidPage
)
531 GetOutDev()->SetLineColor( COL_BLACK
);
532 DrawInvert( static_cast<tools::Long
>( nTopMargin
- aOffset
.Y() ), PointerStyle::VSizeBar
);
533 DrawInvert( static_cast<tools::Long
>(nPageEndY
- nBottomMargin
), PointerStyle::VSizeBar
);
534 DrawInvert( static_cast<tools::Long
>( nLeftMargin
- aOffset
.X() ), PointerStyle::HSizeBar
);
535 DrawInvert( static_cast<tools::Long
>( nPageEndX
- nRightMargin
) , PointerStyle::HSizeBar
);
538 DrawInvert( nHeaderHeight
- aOffset
.Y(), PointerStyle::VSizeBar
);
542 DrawInvert( nPageEndY
- nFooterHeight
, PointerStyle::VSizeBar
);
545 SetMapMode( MapMode( MapUnit::MapPixel
) );
546 for( int i
= aPageArea
.aStart
.Col(); i
<= aPageArea
.aEnd
.Col(); i
++ )
548 Point aColumnTop
= LogicToPixel( Point( 0, -aOffset
.Y() ) ,aMMMode
);
549 GetOutDev()->SetLineColor( COL_BLACK
);
550 GetOutDev()->SetFillColor( COL_BLACK
);
551 GetOutDev()->DrawRect( tools::Rectangle( Point( mvRight
[i
] - 2, aColumnTop
.Y() ),Point( mvRight
[i
] + 2 , 4 + aColumnTop
.Y()) ));
552 GetOutDev()->DrawLine( Point( mvRight
[i
], aColumnTop
.Y() ), Point( mvRight
[i
], 10 + aColumnTop
.Y()) );
554 SetMapMode( aMMMode
);
557 if (bRight
|| bBottom
)
560 GetOutDev()->SetLineColor();
561 GetOutDev()->SetFillColor(aBackColor
);
563 GetOutDev()->DrawRect(tools::Rectangle(nPageEndX
,0, aWinEnd
.X(),aWinEnd
.Y()));
567 GetOutDev()->DrawRect(tools::Rectangle(0,nPageEndY
, nPageEndX
,aWinEnd
.Y())); // Corner not duplicated
569 GetOutDev()->DrawRect(tools::Rectangle(0,nPageEndY
, aWinEnd
.X(),aWinEnd
.Y()));
576 Color
aBorderColor(ScModule::get()->GetColorConfig().GetColorValue(svtools::FONTCOLOR
).nColor
);
580 if ( aOffset
.X() <= 0 || aOffset
.Y() <= 0 || bRight
|| bBottom
)
582 GetOutDev()->SetLineColor( aBorderColor
);
583 GetOutDev()->SetFillColor();
585 tools::Rectangle
aPixel( LogicToPixel( tools::Rectangle( -aOffset
.X(), -aOffset
.Y(), nPageEndX
, nPageEndY
) ) );
586 aPixel
.AdjustRight( -1 );
587 aPixel
.AdjustBottom( -1 );
588 GetOutDev()->DrawRect( PixelToLogic( aPixel
) );
593 GetOutDev()->SetLineColor();
594 GetOutDev()->SetFillColor( aBorderColor
);
596 tools::Rectangle aPixel
;
598 aPixel
= LogicToPixel( tools::Rectangle( nPageEndX
, -aOffset
.Y(), nPageEndX
, nPageEndY
) );
599 aPixel
.AdjustTop(SC_PREVIEW_SHADOWSIZE
);
600 aPixel
.AdjustRight(SC_PREVIEW_SHADOWSIZE
- 1 );
601 aPixel
.AdjustBottom(SC_PREVIEW_SHADOWSIZE
- 1 );
602 GetOutDev()->DrawRect( PixelToLogic( aPixel
) );
604 aPixel
= LogicToPixel( tools::Rectangle( -aOffset
.X(), nPageEndY
, nPageEndX
, nPageEndY
) );
605 aPixel
.AdjustLeft(SC_PREVIEW_SHADOWSIZE
);
606 aPixel
.AdjustRight(SC_PREVIEW_SHADOWSIZE
- 1 );
607 aPixel
.AdjustBottom(SC_PREVIEW_SHADOWSIZE
- 1 );
608 GetOutDev()->DrawRect( PixelToLogic( aPixel
) );
611 void ScPreview::Paint( vcl::RenderContext
& /*rRenderContext*/, const tools::Rectangle
& /* rRect */ )
613 bool bWasInPaint
= bInPaint
; // nested calls shouldn't be necessary, but allow for now
617 GetLocationData(); // fill location data for column positions
619 pViewShell
->UpdateScrollBars();
621 bInPaint
= bWasInPaint
;
624 void ScPreview::Command( const CommandEvent
& rCEvt
)
626 CommandEventId nCmd
= rCEvt
.GetCommand();
627 if ( nCmd
== CommandEventId::Wheel
|| nCmd
== CommandEventId::StartAutoScroll
|| nCmd
== CommandEventId::AutoScroll
)
629 bool bDone
= pViewShell
->ScrollCommand( rCEvt
);
631 Window::Command(rCEvt
);
633 else if ( nCmd
== CommandEventId::ContextMenu
)
634 SfxDispatcher::ExecutePopup();
636 Window::Command( rCEvt
);
639 void ScPreview::KeyInput( const KeyEvent
& rKEvt
)
641 // The + and - keys can't be configured as accelerator entries, so they must be handled directly
642 // (in ScPreview, not ScPreviewShell -> only if the preview window has the focus)
644 const vcl::KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
645 sal_uInt16 nKey
= rKeyCode
.GetCode();
646 bool bHandled
= false;
647 if(!rKeyCode
.GetModifier())
649 sal_uInt16 nSlot
= 0;
652 case KEY_ADD
: nSlot
= SID_ZOOM_IN
; break;
653 case KEY_ESCAPE
: nSlot
= ScViewUtil::IsFullScreen( *pViewShell
) ? SID_CANCEL
: SID_PREVIEW_CLOSE
; break;
654 case KEY_SUBTRACT
: nSlot
= SID_ZOOM_OUT
; break;
659 pViewShell
->GetViewFrame().GetDispatcher()->Execute( nSlot
, SfxCallMode::ASYNCHRON
);
663 if ( !bHandled
&& !pViewShell
->KeyInput(rKEvt
) )
664 Window::KeyInput(rKEvt
);
667 const ScPreviewLocationData
& ScPreview::GetLocationData()
669 if ( !pLocationData
)
671 pLocationData
.reset( new ScPreviewLocationData( &pDocShell
->GetDocument(), GetOutDev() ) );
672 bLocationValid
= false;
674 if ( !bLocationValid
)
676 pLocationData
->Clear();
677 DoPrint( pLocationData
.get() );
678 bLocationValid
= true;
680 return *pLocationData
;
683 void ScPreview::DataChanged(bool bNewTime
)
686 aDateTime
= DateTime( DateTime::SYSTEM
);
689 InvalidateLocationData( SfxHintId::ScDataChanged
);
693 OUString
ScPreview::GetPosString()
698 UpdateDrawView(); // The table eventually changes
701 OUString aString
= ScResId( STR_PAGE
) +
702 " " + OUString::number(nPageNo
+1);
704 if (nTabsTested
>= nTabCount
)
705 aString
+= " / " + OUString::number(nTotalPages
);
710 void ScPreview::SetZoom(sal_uInt16 nNewZoom
)
716 if (nNewZoom
== nZoom
)
721 // apply new MapMode and call UpdateScrollBars to update aOffset
723 Fraction
aPreviewZoom( nZoom
, 100 );
724 Fraction
aHorPrevZoom( static_cast<tools::Long
>( 100 * nZoom
/ pDocShell
->GetOutputFactor() ), 10000 );
725 MapMode
aMMMode( MapUnit::Map100thMM
, Point(), aHorPrevZoom
, aPreviewZoom
);
726 SetMapMode( aMMMode
);
728 bInSetZoom
= true; // don't scroll during SetYOffset in UpdateScrollBars
729 pViewShell
->UpdateNeededScrollBars(true);
732 InvalidateLocationData( SfxHintId::ScAccVisAreaChanged
);
737 void ScPreview::SetPageNo( tools::Long nPage
)
741 UpdateDrawView(); // The table eventually changes
742 InvalidateLocationData( SfxHintId::ScDataChanged
);
746 tools::Long
ScPreview::GetFirstPage(SCTAB nTabP
)
748 SCTAB nDocTabCount
= pDocShell
->GetDocument().GetTableCount();
749 if (nTabP
>= nDocTabCount
)
750 nTabP
= nDocTabCount
-1;
752 tools::Long nPage
= 0;
756 if (nTabP
>= static_cast<SCTAB
>(nPages
.size()) )
757 OSL_FAIL("nPages out of bounds, FIX IT");
758 UpdateDrawView(); // The table eventually changes
760 for (SCTAB i
=0; i
<nTabP
; i
++)
763 // An empty Table on the previous Page
765 if ( nPages
[nTabP
]==0 && nPage
> 0 )
772 static Size
lcl_GetDocPageSize( const ScDocument
* pDoc
, SCTAB nTab
)
774 OUString aName
= pDoc
->GetPageStyle( nTab
);
775 ScStyleSheetPool
* pStylePool
= pDoc
->GetStyleSheetPool();
776 SfxStyleSheetBase
* pStyleSheet
= pStylePool
->Find( aName
, SfxStyleFamily::Page
);
779 SfxItemSet
& rStyleSet
= pStyleSheet
->GetItemSet();
780 return rStyleSet
.Get(ATTR_PAGE_SIZE
).GetSize();
784 OSL_FAIL( "PageStyle not found" );
789 sal_uInt16
ScPreview::GetOptimalZoom(bool bWidthOnly
)
791 double nWinScaleX
= ScGlobal::nScreenPPTX
/ pDocShell
->GetOutputFactor();
792 double nWinScaleY
= ScGlobal::nScreenPPTY
;
793 Size aWinSize
= GetOutputSizePixel();
795 // desired margin is 0.25cm in default MapMode (like Writer),
796 // but some additional margin is introduced by integer scale values
797 // -> add only 0.10cm, so there is some margin in all cases.
798 Size
aMarginSize( LogicToPixel(Size(100, 100), MapMode(MapUnit::Map100thMM
)) );
799 aWinSize
.AdjustWidth( -(2 * aMarginSize
.Width()) );
800 aWinSize
.AdjustHeight( -(2 * aMarginSize
.Height()) );
802 Size aLocalPageSize
= lcl_GetDocPageSize( &pDocShell
->GetDocument(), nTab
);
803 if ( aLocalPageSize
.Width() && aLocalPageSize
.Height() )
805 tools::Long nZoomX
= static_cast<tools::Long
>( aWinSize
.Width() * 100 / ( aLocalPageSize
.Width() * nWinScaleX
));
806 tools::Long nZoomY
= static_cast<tools::Long
>( aWinSize
.Height() * 100 / ( aLocalPageSize
.Height() * nWinScaleY
));
808 tools::Long nOptimal
= nZoomX
;
809 if (!bWidthOnly
&& nZoomY
<nOptimal
)
817 return static_cast<sal_uInt16
>(nOptimal
);
823 void ScPreview::SetXOffset( tools::Long nX
)
825 if ( aOffset
.X() == nX
)
830 tools::Long nDif
= LogicToPixel(aOffset
).X() - LogicToPixel(Point(nX
,0)).X();
832 if (nDif
&& !bInSetZoom
)
834 MapMode aOldMode
= GetMapMode();
835 SetMapMode(MapMode(MapUnit::MapPixel
));
837 SetMapMode(aOldMode
);
846 InvalidateLocationData( SfxHintId::ScAccVisAreaChanged
);
850 void ScPreview::SetYOffset( tools::Long nY
)
852 if ( aOffset
.Y() == nY
)
857 tools::Long nDif
= LogicToPixel(aOffset
).Y() - LogicToPixel(Point(0,nY
)).Y();
859 if (nDif
&& !bInSetZoom
)
861 MapMode aOldMode
= GetMapMode();
862 SetMapMode(MapMode(MapUnit::MapPixel
));
864 SetMapMode(aOldMode
);
873 InvalidateLocationData( SfxHintId::ScAccVisAreaChanged
);
877 void ScPreview::DoInvalidate()
879 // If the whole GetState of the shell is called
880 // The Invalidate must come behind asynchronously
883 Application::PostUserEvent( LINK( this, ScPreview
, InvalidateHdl
), nullptr, true );
885 StaticInvalidate(); // Immediately
888 void ScPreview::StaticInvalidate()
890 // static method, because it's called asynchronously
891 // -> must use current viewframe
893 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
897 SfxBindings
& rBindings
= pViewFrm
->GetBindings();
898 rBindings
.Invalidate(SID_STATUS_DOCPOS
);
899 rBindings
.Invalidate(FID_AUTO_CALC
);
900 rBindings
.Invalidate(SID_ROWCOL_SELCOUNT
);
901 rBindings
.Invalidate(SID_STATUS_PAGESTYLE
);
902 rBindings
.Invalidate(SID_PREVIEW_PREVIOUS
);
903 rBindings
.Invalidate(SID_PREVIEW_NEXT
);
904 rBindings
.Invalidate(SID_PREVIEW_FIRST
);
905 rBindings
.Invalidate(SID_PREVIEW_LAST
);
906 rBindings
.Invalidate(SID_ATTR_ZOOM
);
907 rBindings
.Invalidate(SID_ZOOM_IN
);
908 rBindings
.Invalidate(SID_ZOOM_OUT
);
909 rBindings
.Invalidate(SID_PREVIEW_SCALINGFACTOR
);
910 rBindings
.Invalidate(SID_ATTR_ZOOMSLIDER
);
913 IMPL_STATIC_LINK_NOARG( ScPreview
, InvalidateHdl
, void*, void )
918 void ScPreview::DataChanged( const DataChangedEvent
& rDCEvt
)
920 Window::DataChanged(rDCEvt
);
922 if ( !((rDCEvt
.GetType() == DataChangedEventType::PRINTER
) ||
923 (rDCEvt
.GetType() == DataChangedEventType::DISPLAY
) ||
924 (rDCEvt
.GetType() == DataChangedEventType::FONTS
) ||
925 (rDCEvt
.GetType() == DataChangedEventType::FONTSUBSTITUTION
) ||
926 ((rDCEvt
.GetType() == DataChangedEventType::SETTINGS
) &&
927 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
))) )
930 if ( rDCEvt
.GetType() == DataChangedEventType::FONTS
)
931 pDocShell
->UpdateFontList();
933 // #i114518# Paint of form controls may modify the window's settings.
934 // Ignore the event if it is called from within Paint.
937 if ( rDCEvt
.GetType() == DataChangedEventType::SETTINGS
&&
938 (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
940 // scroll bar size may have changed
941 pViewShell
->InvalidateBorder(); // calls OuterResizePixel
944 InvalidateLocationData( SfxHintId::ScDataChanged
);
948 void ScPreview::MouseButtonDown( const MouseEvent
& rMEvt
)
950 Fraction
aPreviewZoom( nZoom
, 100 );
951 Fraction
aHorPrevZoom( static_cast<tools::Long
>( 100 * nZoom
/ pDocShell
->GetOutputFactor() ), 10000 );
952 MapMode
aMMMode( MapUnit::Map100thMM
, Point(), aHorPrevZoom
, aPreviewZoom
);
954 aButtonDownChangePoint
= PixelToLogic( rMEvt
.GetPosPixel(),aMMMode
);
955 aButtonDownPt
= PixelToLogic( rMEvt
.GetPosPixel(),aMMMode
);
959 if( rMEvt
.IsLeft() && GetPointer() == PointerStyle::HSizeBar
)
961 SetMapMode( aMMMode
);
962 if( bLeftRulerChange
)
964 DrawInvert( aButtonDownChangePoint
.X(), PointerStyle::HSizeBar
);
965 bLeftRulerMove
= true;
966 bRightRulerMove
= false;
968 else if( bRightRulerChange
)
970 DrawInvert( aButtonDownChangePoint
.X(), PointerStyle::HSizeBar
);
971 bLeftRulerMove
= false;
972 bRightRulerMove
= true;
976 if( rMEvt
.IsLeft() && GetPointer() == PointerStyle::VSizeBar
)
978 SetMapMode( aMMMode
);
979 if( bTopRulerChange
)
981 DrawInvert( aButtonDownChangePoint
.Y(), PointerStyle::VSizeBar
);
982 bTopRulerMove
= true;
983 bBottomRulerMove
= false;
985 else if( bBottomRulerChange
)
987 DrawInvert( aButtonDownChangePoint
.Y(), PointerStyle::VSizeBar
);
988 bTopRulerMove
= false;
989 bBottomRulerMove
= true;
991 else if( bHeaderRulerChange
)
993 DrawInvert( aButtonDownChangePoint
.Y(), PointerStyle::VSizeBar
);
994 bHeaderRulerMove
= true;
995 bFooterRulerMove
= false;
997 else if( bFooterRulerChange
)
999 DrawInvert( aButtonDownChangePoint
.Y(), PointerStyle::VSizeBar
);
1000 bHeaderRulerMove
= false;
1001 bFooterRulerMove
= true;
1005 if( !(rMEvt
.IsLeft() && GetPointer() == PointerStyle::HSplit
) )
1008 Point aNowPt
= rMEvt
.GetPosPixel();
1010 for( i
= aPageArea
.aStart
.Col(); i
<= aPageArea
.aEnd
.Col(); i
++ )
1012 if( aNowPt
.X() < mvRight
[i
] + 2 && aNowPt
.X() > mvRight
[i
] - 2 )
1014 nColNumberButtonDown
= i
;
1018 if( i
== aPageArea
.aEnd
.Col()+1 )
1021 SetMapMode( aMMMode
);
1022 if( nColNumberButtonDown
== aPageArea
.aStart
.Col() )
1023 DrawInvert( PixelToLogic( Point( nLeftPosition
, 0 ),aMMMode
).X() ,PointerStyle::HSplit
);
1025 DrawInvert( PixelToLogic( Point( mvRight
[ nColNumberButtonDown
-1 ], 0 ),aMMMode
).X() ,PointerStyle::HSplit
);
1027 DrawInvert( aButtonDownChangePoint
.X(), PointerStyle::HSplit
);
1028 bColRulerMove
= true;
1031 void ScPreview::MouseButtonUp( const MouseEvent
& rMEvt
)
1033 Fraction
aPreviewZoom( nZoom
, 100 );
1034 Fraction
aHorPrevZoom( static_cast<tools::Long
>( 100 * nZoom
/ pDocShell
->GetOutputFactor() ), 10000 );
1035 MapMode
aMMMode( MapUnit::Map100thMM
, Point(), aHorPrevZoom
, aPreviewZoom
);
1037 aButtonUpPt
= PixelToLogic( rMEvt
.GetPosPixel(),aMMMode
);
1039 tools::Long nWidth
= lcl_GetDocPageSize(&pDocShell
->GetDocument(), nTab
).Width();
1040 tools::Long nHeight
= lcl_GetDocPageSize(&pDocShell
->GetDocument(), nTab
).Height();
1042 if( rMEvt
.IsLeft() && GetPointer() == PointerStyle::HSizeBar
)
1044 SetPointer( PointerStyle::Arrow
);
1046 ScDocument
& rDoc
= pDocShell
->GetDocument();
1047 OUString aOldName
= rDoc
.GetPageStyle( nTab
);
1048 bool bUndo
= rDoc
.IsUndoEnabled();
1049 ScStyleSheetPool
* pStylePool
= rDoc
.GetStyleSheetPool();
1050 SfxStyleSheetBase
* pStyleSheet
= pStylePool
->Find( aOldName
, SfxStyleFamily::Page
);
1054 bool bMoveRulerAction
= true;
1055 ScStyleSaveData aOldData
;
1057 aOldData
.InitFromStyle( pStyleSheet
);
1059 SfxItemSet
& rStyleSet
= pStyleSheet
->GetItemSet();
1061 SvxLRSpaceItem aLRItem
= rStyleSet
.Get( ATTR_LRSPACE
);
1063 if(( bLeftRulerChange
|| bRightRulerChange
) && ( aButtonUpPt
.X() <= ( 0 - aOffset
.X() ) || aButtonUpPt
.X() > o3tl::convert(nWidth
, o3tl::Length::twip
, o3tl::Length::mm100
) - aOffset
.X() ) )
1065 bMoveRulerAction
= false;
1066 Invalidate(tools::Rectangle(0, 0, 10000, 10000));
1068 else if (bLeftRulerChange
1069 && (o3tl::convert(aButtonUpPt
.X(), o3tl::Length::mm100
, o3tl::Length::twip
)
1070 > nWidth
- aLRItem
.ResolveRight({})
1071 - o3tl::convert(aOffset
.X(), o3tl::Length::mm100
,
1072 o3tl::Length::twip
)))
1074 bMoveRulerAction
= false;
1075 Invalidate(tools::Rectangle(0, 0, 10000, 10000));
1077 else if (bRightRulerChange
1078 && (o3tl::convert(aButtonUpPt
.X(), o3tl::Length::mm100
, o3tl::Length::twip
)
1079 < aLRItem
.ResolveLeft({})
1080 - o3tl::convert(aOffset
.X(), o3tl::Length::mm100
,
1081 o3tl::Length::twip
)))
1083 bMoveRulerAction
= false;
1084 Invalidate(tools::Rectangle(0, 0, 10000, 10000));
1086 else if( aButtonDownPt
.X() == aButtonUpPt
.X() )
1088 bMoveRulerAction
= false;
1089 DrawInvert( aButtonUpPt
.X(), PointerStyle::HSizeBar
);
1091 if( bMoveRulerAction
)
1093 ScDocShellModificator
aModificator( *pDocShell
);
1094 if( bLeftRulerChange
&& bLeftRulerMove
)
1096 aLRItem
.SetLeft(SvxIndentValue::twips(
1097 o3tl::convert(aButtonUpPt
.X(), o3tl::Length::mm100
, o3tl::Length::twip
)
1098 + o3tl::convert(aOffset
.X(), o3tl::Length::mm100
, o3tl::Length::twip
)));
1099 rStyleSet
.Put(aLRItem
);
1100 pDocShell
->SetModified();
1102 else if( bRightRulerChange
&& bRightRulerMove
)
1104 aLRItem
.SetRight(SvxIndentValue::twips(
1106 - o3tl::convert(aButtonUpPt
.X(), o3tl::Length::mm100
,
1108 - o3tl::convert(aOffset
.X(), o3tl::Length::mm100
, o3tl::Length::twip
)));
1109 rStyleSet
.Put( aLRItem
);
1110 pDocShell
->SetModified();
1113 ScStyleSaveData aNewData
;
1114 aNewData
.InitFromStyle( pStyleSheet
);
1117 pDocShell
->GetUndoManager()->AddUndoAction(
1118 std::make_unique
<ScUndoModifyStyle
>( pDocShell
, SfxStyleFamily::Page
,
1119 aOldData
, aNewData
) );
1122 if ( ValidTab( nTab
) )
1124 ScPrintFunc
aPrintFunc( GetOutDev(), pDocShell
, nTab
);
1125 aPrintFunc
.UpdatePages();
1128 tools::Rectangle
aRect(0,0,10000,10000);
1130 aModificator
.SetDocumentModified();
1131 bLeftRulerChange
= false;
1132 bRightRulerChange
= false;
1135 bLeftRulerMove
= false;
1136 bRightRulerMove
= false;
1139 if( rMEvt
.IsLeft() && GetPointer() == PointerStyle::VSizeBar
)
1141 SetPointer( PointerStyle::Arrow
);
1143 bool bMoveRulerAction
= true;
1144 if( ( bTopRulerChange
|| bBottomRulerChange
|| bHeaderRulerChange
|| bFooterRulerChange
) && ( aButtonUpPt
.Y() <= ( 0 - aOffset
.Y() ) || aButtonUpPt
.Y() > o3tl::convert(nHeight
, o3tl::Length::twip
, o3tl::Length::mm100
) -aOffset
.Y() ) )
1146 bMoveRulerAction
= false;
1147 Invalidate(tools::Rectangle(0, 0, 10000, 10000));
1149 else if( aButtonDownPt
.Y() == aButtonUpPt
.Y() )
1151 bMoveRulerAction
= false;
1152 DrawInvert( aButtonUpPt
.Y(), PointerStyle::VSizeBar
);
1154 if( bMoveRulerAction
)
1156 ScDocument
& rDoc
= pDocShell
->GetDocument();
1157 bool bUndo
= rDoc
.IsUndoEnabled();
1158 ScStyleSheetPool
* pStylePool
= rDoc
.GetStyleSheetPool();
1159 SfxStyleSheetBase
* pStyleSheet
= pStylePool
->Find( rDoc
.GetPageStyle( nTab
), SfxStyleFamily::Page
);
1160 OSL_ENSURE( pStyleSheet
, "PageStyle not found" );
1163 ScDocShellModificator
aModificator( *pDocShell
);
1164 ScStyleSaveData aOldData
;
1166 aOldData
.InitFromStyle( pStyleSheet
);
1168 SfxItemSet
& rStyleSet
= pStyleSheet
->GetItemSet();
1170 SvxULSpaceItem aULItem
= rStyleSet
.Get( ATTR_ULSPACE
);
1172 if( bTopRulerMove
&& bTopRulerChange
)
1174 aULItem
.SetUpperValue(o3tl::convert(aButtonUpPt
.Y(), o3tl::Length::mm100
, o3tl::Length::twip
) + o3tl::convert(aOffset
.Y(), o3tl::Length::mm100
, o3tl::Length::twip
));
1175 rStyleSet
.Put( aULItem
);
1176 pDocShell
->SetModified();
1178 else if( bBottomRulerMove
&& bBottomRulerChange
)
1180 aULItem
.SetLowerValue(nHeight
- o3tl::convert(aButtonUpPt
.Y(), o3tl::Length::mm100
, o3tl::Length::twip
) - o3tl::convert(aOffset
.Y(), o3tl::Length::mm100
, o3tl::Length::twip
));
1181 rStyleSet
.Put( aULItem
);
1182 pDocShell
->SetModified();
1184 else if( bHeaderRulerMove
&& bHeaderRulerChange
)
1186 if ( const SvxSetItem
* pSetItem
= rStyleSet
.GetItemIfSet( ATTR_PAGE_HEADERSET
, false ) )
1188 const SfxItemSet
& rHeaderSet
= pSetItem
->GetItemSet();
1189 Size aHeaderSize
= rHeaderSet
.Get(ATTR_PAGE_SIZE
).GetSize();
1190 aHeaderSize
.setHeight(o3tl::convert( aButtonUpPt
.Y(), o3tl::Length::mm100
, o3tl::Length::twip
) + o3tl::convert(aOffset
.Y(), o3tl::Length::mm100
, o3tl::Length::twip
) - aULItem
.GetUpper());
1191 aHeaderSize
.setHeight( aHeaderSize
.Height() * 100 / mnScale
);
1192 SvxSetItem
aNewHeader( rStyleSet
.Get(ATTR_PAGE_HEADERSET
) );
1193 aNewHeader
.GetItemSet().Put( SvxSizeItem( ATTR_PAGE_SIZE
, aHeaderSize
) );
1194 rStyleSet
.Put( aNewHeader
);
1195 pDocShell
->SetModified();
1198 else if( bFooterRulerMove
&& bFooterRulerChange
)
1200 if( const SvxSetItem
* pSetItem
= rStyleSet
.GetItemIfSet( ATTR_PAGE_FOOTERSET
, false ) )
1202 const SfxItemSet
& rFooterSet
= pSetItem
->GetItemSet();
1203 Size aFooterSize
= rFooterSet
.Get(ATTR_PAGE_SIZE
).GetSize();
1204 aFooterSize
.setHeight(nHeight
- o3tl::convert(aButtonUpPt
.Y(), o3tl::Length::mm100
, o3tl::Length::twip
) - o3tl::convert(aOffset
.Y(), o3tl::Length::mm100
, o3tl::Length::twip
) - aULItem
.GetLower());
1205 aFooterSize
.setHeight( aFooterSize
.Height() * 100 / mnScale
);
1206 SvxSetItem
aNewFooter( rStyleSet
.Get(ATTR_PAGE_FOOTERSET
) );
1207 aNewFooter
.GetItemSet().Put( SvxSizeItem( ATTR_PAGE_SIZE
, aFooterSize
) );
1208 rStyleSet
.Put( aNewFooter
);
1209 pDocShell
->SetModified();
1213 ScStyleSaveData aNewData
;
1214 aNewData
.InitFromStyle( pStyleSheet
);
1217 pDocShell
->GetUndoManager()->AddUndoAction(
1218 std::make_unique
<ScUndoModifyStyle
>( pDocShell
, SfxStyleFamily::Page
,
1219 aOldData
, aNewData
) );
1222 if ( ValidTab( nTab
) )
1224 ScPrintFunc
aPrintFunc( GetOutDev(), pDocShell
, nTab
);
1225 aPrintFunc
.UpdatePages();
1228 tools::Rectangle
aRect(0, 0, 10000, 10000);
1230 aModificator
.SetDocumentModified();
1231 bTopRulerChange
= false;
1232 bBottomRulerChange
= false;
1233 bHeaderRulerChange
= false;
1234 bFooterRulerChange
= false;
1237 bTopRulerMove
= false;
1238 bBottomRulerMove
= false;
1239 bHeaderRulerMove
= false;
1240 bFooterRulerMove
= false;
1242 if( rMEvt
.IsLeft() && GetPointer() == PointerStyle::HSplit
)
1244 SetPointer(PointerStyle::Arrow
);
1245 ScDocument
& rDoc
= pDocShell
->GetDocument();
1246 bool bLayoutRTL
= rDoc
.IsLayoutRTL( nTab
);
1247 bool bMoveRulerAction
= true;
1248 if( aButtonDownPt
.X() == aButtonUpPt
.X() )
1250 bMoveRulerAction
= false;
1251 if( nColNumberButtonDown
== aPageArea
.aStart
.Col() )
1252 DrawInvert( PixelToLogic( Point( nLeftPosition
, 0 ),aMMMode
).X() ,PointerStyle::HSplit
);
1254 DrawInvert( PixelToLogic( Point( mvRight
[ nColNumberButtonDown
-1 ], 0 ),aMMMode
).X() ,PointerStyle::HSplit
);
1255 DrawInvert( aButtonUpPt
.X(), PointerStyle::HSplit
);
1257 if( bMoveRulerAction
)
1259 tools::Long nNewColWidth
= 0;
1260 std::vector
<sc::ColRowSpan
> aCols(1, sc::ColRowSpan(nColNumberButtonDown
,nColNumberButtonDown
));
1262 constexpr auto md
= o3tl::getConversionMulDiv(o3tl::Length::mm100
, o3tl::Length::twip
);
1263 const auto m
= md
.first
* 100, d
= md
.second
* mnScale
;
1266 nNewColWidth
= o3tl::convert(PixelToLogic( Point( rMEvt
.GetPosPixel().X() - mvRight
[ nColNumberButtonDown
], 0), aMMMode
).X(), m
, d
);
1267 nNewColWidth
+= pDocShell
->GetDocument().GetColWidth( nColNumberButtonDown
, nTab
);
1272 nNewColWidth
= o3tl::convert(PixelToLogic( Point( mvRight
[ nColNumberButtonDown
] - rMEvt
.GetPosPixel().X(), 0), aMMMode
).X(), m
, d
);
1273 nNewColWidth
+= pDocShell
->GetDocument().GetColWidth( nColNumberButtonDown
, nTab
);
1276 if( nNewColWidth
>= 0 )
1278 pDocShell
->GetDocFunc().SetWidthOrHeight(
1279 true, aCols
, nTab
, SC_SIZE_DIRECT
, static_cast<sal_uInt16
>(nNewColWidth
), true, true);
1280 pDocShell
->SetModified();
1282 if ( ValidTab( nTab
) )
1284 ScPrintFunc
aPrintFunc( GetOutDev(), pDocShell
, nTab
);
1285 aPrintFunc
.UpdatePages();
1287 tools::Rectangle
aRect(0, 0, 10000, 10000);
1290 bColRulerMove
= false;
1295 void ScPreview::MouseMove( const MouseEvent
& rMEvt
)
1297 Fraction
aPreviewZoom( nZoom
, 100 );
1298 Fraction
aHorPrevZoom( static_cast<tools::Long
>( 100 * nZoom
/ pDocShell
->GetOutputFactor() ), 10000 );
1299 MapMode
aMMMode( MapUnit::Map100thMM
, Point(), aHorPrevZoom
, aPreviewZoom
);
1300 Point aMouseMovePoint
= PixelToLogic( rMEvt
.GetPosPixel(), aMMMode
);
1302 tools::Long nLeftMargin
= 0;
1303 tools::Long nRightMargin
= 0;
1304 tools::Long nTopMargin
= 0;
1305 tools::Long nBottomMargin
= 0;
1307 tools::Long nWidth
= lcl_GetDocPageSize(&pDocShell
->GetDocument(), nTab
).Width();
1308 tools::Long nHeight
= lcl_GetDocPageSize(&pDocShell
->GetDocument(), nTab
).Height();
1310 if ( nPageNo
< nTotalPages
)
1312 ScPrintOptions aOptions
= ScModule::get()->GetPrintOptions();
1314 std::unique_ptr
<ScPrintFunc
, o3tl::default_delete
<ScPrintFunc
>> pPrintFunc
;
1316 pPrintFunc
.reset(new ScPrintFunc( GetOutDev(), pDocShell
, aState
, &aOptions
));
1318 pPrintFunc
.reset(new ScPrintFunc( GetOutDev(), pDocShell
, nTab
, nFirstAttr
[nTab
], nTotalPages
, nullptr, &aOptions
));
1320 nLeftMargin
= o3tl::convert(pPrintFunc
->GetLeftMargin(), o3tl::Length::twip
, o3tl::Length::mm100
) - aOffset
.X();
1321 nRightMargin
= o3tl::convert(pPrintFunc
->GetRightMargin(), o3tl::Length::twip
, o3tl::Length::mm100
);
1322 nRightMargin
= o3tl::convert(nWidth
, o3tl::Length::twip
, o3tl::Length::mm100
) - nRightMargin
- aOffset
.X();
1323 nTopMargin
= o3tl::convert(pPrintFunc
->GetTopMargin(), o3tl::Length::twip
, o3tl::Length::mm100
) - aOffset
.Y();
1324 nBottomMargin
= o3tl::convert(pPrintFunc
->GetBottomMargin(), o3tl::Length::twip
, o3tl::Length::mm100
);
1325 nBottomMargin
= o3tl::convert(nHeight
, o3tl::Length::twip
, o3tl::Length::mm100
) - nBottomMargin
- aOffset
.Y();
1328 constexpr auto md
= o3tl::getConversionMulDiv(o3tl::Length::twip
, o3tl::Length::mm100
);
1329 const auto m
= md
.first
* mnScale
, d
= md
.second
* 100;
1330 nHeaderHeight
= nTopMargin
+ o3tl::convert(pPrintFunc
->GetHeader().nHeight
, m
, d
);
1331 nFooterHeight
= nBottomMargin
- o3tl::convert(pPrintFunc
->GetFooter().nHeight
, m
, d
);
1335 nHeaderHeight
= nTopMargin
+ o3tl::convert(pPrintFunc
->GetHeader().nHeight
, o3tl::Length::twip
, o3tl::Length::mm100
);
1336 nFooterHeight
= nBottomMargin
- o3tl::convert(pPrintFunc
->GetFooter().nHeight
, o3tl::Length::twip
, o3tl::Length::mm100
);
1340 Point
aPixPt( rMEvt
.GetPosPixel() );
1341 Point aLeftTop
= LogicToPixel( Point( nLeftMargin
, -aOffset
.Y() ) , aMMMode
);
1342 Point aLeftBottom
= LogicToPixel( Point( nLeftMargin
, o3tl::convert(nHeight
, o3tl::Length::twip
, o3tl::Length::mm100
) - aOffset
.Y()), aMMMode
);
1343 Point aRightTop
= LogicToPixel( Point( nRightMargin
, -aOffset
.Y() ), aMMMode
);
1344 Point aTopLeft
= LogicToPixel( Point( -aOffset
.X(), nTopMargin
), aMMMode
);
1345 Point aTopRight
= LogicToPixel( Point( o3tl::convert(nWidth
, o3tl::Length::twip
, o3tl::Length::mm100
) - aOffset
.X(), nTopMargin
), aMMMode
);
1346 Point aBottomLeft
= LogicToPixel( Point( -aOffset
.X(), nBottomMargin
), aMMMode
);
1347 Point aHeaderLeft
= LogicToPixel( Point( -aOffset
.X(), nHeaderHeight
), aMMMode
);
1348 Point aFooderLeft
= LogicToPixel( Point( -aOffset
.X(), nFooterHeight
), aMMMode
);
1350 bool bOnColRulerChange
= false;
1352 for( SCCOL i
=aPageArea
.aStart
.Col(); i
<= aPageArea
.aEnd
.Col(); i
++ )
1354 Point aColumnTop
= LogicToPixel( Point( 0, -aOffset
.Y() ) ,aMMMode
);
1355 Point aColumnBottom
= LogicToPixel( Point( 0, o3tl::convert(nHeight
, o3tl::Length::twip
, o3tl::Length::mm100
) - aOffset
.Y()), aMMMode
);
1356 tools::Long nRight
= i
< static_cast<SCCOL
>(mvRight
.size()) ? mvRight
[i
] : 0;
1357 if( aPixPt
.X() < ( nRight
+ 2 ) && ( aPixPt
.X() > ( nRight
- 2 ) ) && ( aPixPt
.X() < aRightTop
.X() ) && ( aPixPt
.X() > aLeftTop
.X() )
1358 && ( aPixPt
.Y() > aColumnTop
.Y() ) && ( aPixPt
.Y() < aColumnBottom
.Y() ) && !bLeftRulerMove
&& !bRightRulerMove
1359 && !bTopRulerMove
&& !bBottomRulerMove
&& !bHeaderRulerMove
&& !bFooterRulerMove
)
1361 bOnColRulerChange
= true;
1362 if( !rMEvt
.GetButtons() && GetPointer() == PointerStyle::HSplit
)
1363 nColNumberButtonDown
= i
;
1368 if( aPixPt
.X() < ( aLeftTop
.X() + 2 ) && aPixPt
.X() > ( aLeftTop
.X() - 2 ) && !bRightRulerMove
)
1370 bLeftRulerChange
= true;
1371 bRightRulerChange
= false;
1373 else if( aPixPt
.X() < ( aRightTop
.X() + 2 ) && aPixPt
.X() > ( aRightTop
.X() - 2 ) && !bLeftRulerMove
)
1375 bLeftRulerChange
= false;
1376 bRightRulerChange
= true;
1378 else if( aPixPt
.Y() < ( aTopLeft
.Y() + 2 ) && aPixPt
.Y() > ( aTopLeft
.Y() - 2 ) && !bBottomRulerMove
&& !bHeaderRulerMove
&& !bFooterRulerMove
)
1380 bTopRulerChange
= true;
1381 bBottomRulerChange
= false;
1382 bHeaderRulerChange
= false;
1383 bFooterRulerChange
= false;
1385 else if( aPixPt
.Y() < ( aBottomLeft
.Y() + 2 ) && aPixPt
.Y() > ( aBottomLeft
.Y() - 2 ) && !bTopRulerMove
&& !bHeaderRulerMove
&& !bFooterRulerMove
)
1387 bTopRulerChange
= false;
1388 bBottomRulerChange
= true;
1389 bHeaderRulerChange
= false;
1390 bFooterRulerChange
= false;
1392 else if( aPixPt
.Y() < ( aHeaderLeft
.Y() + 2 ) && aPixPt
.Y() > ( aHeaderLeft
.Y() - 2 ) && !bTopRulerMove
&& !bBottomRulerMove
&& !bFooterRulerMove
)
1394 bTopRulerChange
= false;
1395 bBottomRulerChange
= false;
1396 bHeaderRulerChange
= true;
1397 bFooterRulerChange
= false;
1399 else if( aPixPt
.Y() < ( aFooderLeft
.Y() + 2 ) && aPixPt
.Y() > ( aFooderLeft
.Y() - 2 ) && !bTopRulerMove
&& !bBottomRulerMove
&& !bHeaderRulerMove
)
1401 bTopRulerChange
= false;
1402 bBottomRulerChange
= false;
1403 bHeaderRulerChange
= false;
1404 bFooterRulerChange
= true;
1410 if(( (aPixPt
.X() < ( aLeftTop
.X() + 2 ) && aPixPt
.X() > ( aLeftTop
.X() - 2 )) || bLeftRulerMove
||
1411 ( aPixPt
.X() < ( aRightTop
.X() + 2 ) && aPixPt
.X() > ( aRightTop
.X() - 2 ) ) || bRightRulerMove
|| bOnColRulerChange
|| bColRulerMove
)
1412 && aPixPt
.Y() > aLeftTop
.Y() && aPixPt
.Y() < aLeftBottom
.Y() )
1414 if( bOnColRulerChange
|| bColRulerMove
)
1416 SetPointer( PointerStyle::HSplit
);
1419 if( aMouseMovePoint
.X() > -aOffset
.X() && aMouseMovePoint
.X() < o3tl::convert(nWidth
, o3tl::Length::twip
, o3tl::Length::mm100
) - aOffset
.X() )
1420 DragMove( aMouseMovePoint
.X(), PointerStyle::HSplit
);
1425 if( bLeftRulerChange
&& !bTopRulerMove
&& !bBottomRulerMove
&& !bHeaderRulerMove
&& !bFooterRulerMove
)
1427 SetPointer( PointerStyle::HSizeBar
);
1428 if( bLeftRulerMove
)
1430 if( aMouseMovePoint
.X() > -aOffset
.X() && aMouseMovePoint
.X() < o3tl::convert(nWidth
, o3tl::Length::twip
, o3tl::Length::mm100
) - aOffset
.X() )
1431 DragMove( aMouseMovePoint
.X(), PointerStyle::HSizeBar
);
1434 else if( bRightRulerChange
&& !bTopRulerMove
&& !bBottomRulerMove
&& !bHeaderRulerMove
&& !bFooterRulerMove
)
1436 SetPointer( PointerStyle::HSizeBar
);
1437 if( bRightRulerMove
)
1439 if( aMouseMovePoint
.X() > -aOffset
.X() && aMouseMovePoint
.X() < o3tl::convert(nWidth
, o3tl::Length::twip
, o3tl::Length::mm100
) - aOffset
.X() )
1440 DragMove( aMouseMovePoint
.X(), PointerStyle::HSizeBar
);
1447 if( ( ( aPixPt
.Y() < ( aTopLeft
.Y() + 2 ) && aPixPt
.Y() > ( aTopLeft
.Y() - 2 ) ) || bTopRulerMove
||
1448 ( aPixPt
.Y() < ( aBottomLeft
.Y() + 2 ) && aPixPt
.Y() > ( aBottomLeft
.Y() - 2 ) ) || bBottomRulerMove
||
1449 ( aPixPt
.Y() < ( aHeaderLeft
.Y() + 2 ) && aPixPt
.Y() > ( aHeaderLeft
.Y() - 2 ) ) || bHeaderRulerMove
||
1450 ( aPixPt
.Y() < ( aFooderLeft
.Y() + 2 ) && aPixPt
.Y() > ( aFooderLeft
.Y() - 2 ) ) || bFooterRulerMove
)
1451 && aPixPt
.X() > aTopLeft
.X() && aPixPt
.X() < aTopRight
.X() )
1453 if( bTopRulerChange
)
1455 SetPointer( PointerStyle::VSizeBar
);
1458 if( aMouseMovePoint
.Y() > -aOffset
.Y() && aMouseMovePoint
.Y() < o3tl::convert(nHeight
, o3tl::Length::twip
, o3tl::Length::mm100
) - aOffset
.Y() )
1459 DragMove( aMouseMovePoint
.Y(), PointerStyle::VSizeBar
);
1462 else if( bBottomRulerChange
)
1464 SetPointer( PointerStyle::VSizeBar
);
1465 if( bBottomRulerMove
)
1467 if( aMouseMovePoint
.Y() > -aOffset
.Y() && aMouseMovePoint
.Y() < o3tl::convert(nHeight
, o3tl::Length::twip
, o3tl::Length::mm100
) - aOffset
.Y() )
1468 DragMove( aMouseMovePoint
.Y(), PointerStyle::VSizeBar
);
1471 else if( bHeaderRulerChange
)
1473 SetPointer( PointerStyle::VSizeBar
);
1474 if( bHeaderRulerMove
)
1476 if( aMouseMovePoint
.Y() > -aOffset
.Y() && aMouseMovePoint
.Y() < o3tl::convert(nHeight
, o3tl::Length::twip
, o3tl::Length::mm100
) - aOffset
.Y() )
1477 DragMove( aMouseMovePoint
.Y(), PointerStyle::VSizeBar
);
1480 else if( bFooterRulerChange
)
1482 SetPointer( PointerStyle::VSizeBar
);
1483 if( bFooterRulerMove
)
1485 if( aMouseMovePoint
.Y() > -aOffset
.Y() && aMouseMovePoint
.Y() < o3tl::convert(nHeight
, o3tl::Length::twip
, o3tl::Length::mm100
) - aOffset
.Y() )
1486 DragMove( aMouseMovePoint
.Y(), PointerStyle::VSizeBar
);
1491 SetPointer( PointerStyle::Arrow
);
1495 void ScPreview::InvalidateLocationData(SfxHintId nId
)
1497 bLocationValid
= false;
1498 if (pViewShell
->HasAccessibilityObjects())
1499 pViewShell
->BroadcastAccessibility( SfxHint( nId
) );
1502 void ScPreview::GetFocus()
1505 if (pViewShell
&& pViewShell
->HasAccessibilityObjects())
1506 pViewShell
->BroadcastAccessibility( ScAccWinFocusGotHint() );
1509 void ScPreview::LoseFocus()
1511 if (pViewShell
&& pViewShell
->HasAccessibilityObjects())
1512 pViewShell
->BroadcastAccessibility( ScAccWinFocusLostHint() );
1513 Window::LoseFocus();
1516 css::uno::Reference
<css::accessibility::XAccessible
> ScPreview::CreateAccessible()
1518 css::uno::Reference
<css::accessibility::XAccessible
> xAcc
= GetAccessible(false);
1524 rtl::Reference
<ScAccessibleDocumentPagePreview
> pAccessible
=
1525 new ScAccessibleDocumentPagePreview( GetAccessibleParentWindow()->GetAccessible(), pViewShell
);
1528 SetAccessible(xAcc
);
1529 pAccessible
->Init();
1533 void ScPreview::DragMove( tools::Long nDragMovePos
, PointerStyle nFlags
)
1535 Fraction
aPreviewZoom( nZoom
, 100 );
1536 Fraction
aHorPrevZoom( static_cast<tools::Long
>( 100 * nZoom
/ pDocShell
->GetOutputFactor() ), 10000 );
1537 MapMode
aMMMode( MapUnit::Map100thMM
, Point(), aHorPrevZoom
, aPreviewZoom
);
1538 SetMapMode( aMMMode
);
1539 tools::Long nPos
= nDragMovePos
;
1540 if( nFlags
== PointerStyle::HSizeBar
|| nFlags
== PointerStyle::HSplit
)
1542 if( nDragMovePos
!= aButtonDownChangePoint
.X() )
1544 DrawInvert( aButtonDownChangePoint
.X(), nFlags
);
1545 aButtonDownChangePoint
.setX( nPos
);
1546 DrawInvert( aButtonDownChangePoint
.X(), nFlags
);
1549 else if( nFlags
== PointerStyle::VSizeBar
)
1551 if( nDragMovePos
!= aButtonDownChangePoint
.Y() )
1553 DrawInvert( aButtonDownChangePoint
.Y(), nFlags
);
1554 aButtonDownChangePoint
.setY( nPos
);
1555 DrawInvert( aButtonDownChangePoint
.Y(), nFlags
);
1560 void ScPreview::DrawInvert( tools::Long nDragPos
, PointerStyle nFlags
)
1562 tools::Long nHeight
= lcl_GetDocPageSize( &pDocShell
->GetDocument(), nTab
).Height();
1563 tools::Long nWidth
= lcl_GetDocPageSize( &pDocShell
->GetDocument(), nTab
).Width();
1564 if( nFlags
== PointerStyle::HSizeBar
|| nFlags
== PointerStyle::HSplit
)
1566 tools::Rectangle
aRect( nDragPos
, -aOffset
.Y(), nDragPos
+ 1, o3tl::convert(nHeight
, o3tl::Length::twip
, o3tl::Length::mm100
) - aOffset
.Y());
1567 GetOutDev()->Invert( aRect
, InvertFlags::N50
);
1569 else if( nFlags
== PointerStyle::VSizeBar
)
1571 tools::Rectangle
aRect( -aOffset
.X(), nDragPos
, o3tl::convert(nWidth
, o3tl::Length::twip
, o3tl::Length::mm100
) - aOffset
.X(), nDragPos
+ 1 );
1572 GetOutDev()->Invert( aRect
, InvertFlags::N50
);
1576 void ScPreview::SetSelectedTabs(const ScMarkData
& rMark
)
1578 maSelectedTabs
= rMark
.GetSelectedTabs();
1581 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */