Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / sc / source / ui / view / preview.cxx
bloba8dc2400b5f997a8c9c8caaa05d93151cdd1d620
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 "scitems.hxx"
21 #include <editeng/eeitem.hxx>
23 #include <svtools/colorcfg.hxx>
24 #include <svx/fmview.hxx>
25 #include <editeng/sizeitem.hxx>
26 #include <svx/svdpagv.hxx>
27 #include <sfx2/bindings.hxx>
28 #include <sfx2/viewfrm.hxx>
29 #include <sfx2/dispatch.hxx>
30 #include <svtools/accessibilityoptions.hxx>
31 #include <svl/itemset.hxx>
32 #include <tools/multisel.hxx>
33 #include <vcl/waitobj.hxx>
34 #include <vcl/settings.hxx>
36 #include "preview.hxx"
37 #include "prevwsh.hxx"
38 #include "prevloc.hxx"
39 #include "docsh.hxx"
40 #include "docfunc.hxx"
41 #include "printfun.hxx"
42 #include "printopt.hxx"
43 #include "stlpool.hxx"
44 #include "undostyl.hxx"
45 #include "drwlayer.hxx"
46 #include "scmod.hxx"
47 #include "markdata.hxx"
48 #include "globstr.hrc"
49 #include "sc.hrc"
50 #include "AccessibleDocumentPagePreview.hxx"
51 #include <vcl/lineinfo.hxx>
52 #include <svx/algitem.hxx>
53 #include <editeng/lrspitem.hxx>
54 #include <editeng/ulspitem.hxx>
55 #include <editeng/colritem.hxx>
56 #include <editeng/fhgtitem.hxx>
57 #include "attrib.hxx"
58 #include "pagepar.hxx"
59 #include <com/sun/star/accessibility/XAccessible.hpp>
60 #include "AccessibilityHints.hxx"
61 #include <vcl/svapp.hxx>
62 #include "viewutil.hxx"
63 #include <columnspanset.hxx>
64 #include <docpool.hxx>
65 #include <patattr.hxx>
67 #include <memory>
69 #define SC_PREVIEW_SHADOWSIZE 2
71 static long lcl_GetDisplayStart( SCTAB nTab, ScDocument* pDoc, std::vector<long>& nPages )
73 long nDisplayStart = 0;
74 for (SCTAB i=0; i<nTab; i++)
76 if ( pDoc->NeedPageResetAfterTab(i) )
77 nDisplayStart = 0;
78 else
79 nDisplayStart += nPages[i];
81 return nDisplayStart;
84 ScPreview::ScPreview( vcl::Window* pParent, ScDocShell* pDocSh, ScPreviewShell* pViewSh ) :
85 Window( pParent ),
86 nPageNo( 0 ),
87 nZoom( 100 ),
88 nTabCount( 0 ),
89 nTabsTested( 0 ),
90 nPages(),
91 nFirstAttr(),
92 nTab( 0 ),
93 nTabPage( 0 ),
94 nTabStart( 0 ),
95 nDisplayStart( 0 ),
96 aDate( Date::SYSTEM ),
97 aTime( tools::Time::SYSTEM ),
98 nTotalPages( 0 ),
99 pLocationData( nullptr ),
100 pDrawView( nullptr ),
101 pDocShell( pDocSh ),
102 pViewShell( pViewSh ),
103 bInGetState( false ),
104 bValid( false ),
105 bStateValid( false ),
106 bLocationValid( false ),
107 bInPaint( false ),
108 bInSetZoom( false ),
109 bLeftRulerMove( false ),
110 bRightRulerMove( false ),
111 bTopRulerMove( false ),
112 bBottomRulerMove( false ),
113 bHeaderRulerMove( false ),
114 bFooterRulerMove( false ),
115 bLeftRulerChange( false ),
116 bRightRulerChange( false ),
117 bTopRulerChange( false ),
118 bBottomRulerChange( false ),
119 bHeaderRulerChange( false ),
120 bFooterRulerChange( false ),
121 bPageMargin ( false ),
122 bColRulerMove( false ),
123 mbHasEmptyRangeTable(false),
124 nLeftPosition( 0 ),
125 mnScale( 0 ),
126 nColNumberButttonDown( 0 ),
127 nHeaderHeight ( 0 ),
128 nFooterHeight ( 0 )
130 SetOutDevViewType( OUTDEV_VIEWTYPE_PRINTPREVIEW );
131 SetBackground();
133 SetHelpId( HID_SC_WIN_PREVIEW );
135 SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
137 for (SCCOL i=0; i<=MAXCOL; i++)
138 nRight[i] = 0; // initialized with actual positions when markers are drawn
141 ScPreview::~ScPreview()
143 disposeOnce();
146 void ScPreview::dispose()
148 delete pDrawView;
149 delete pLocationData;
150 vcl::Window::dispose();
153 void ScPreview::UpdateDrawView() // nTab must be right
155 ScDocument& rDoc = pDocShell->GetDocument();
156 ScDrawLayer* pModel = rDoc.GetDrawLayer(); // is not 0
158 if ( pModel )
160 SdrPage* pPage = pModel->GetPage(nTab);
161 if ( pDrawView && ( !pDrawView->GetSdrPageView() || pDrawView->GetSdrPageView()->GetPage() != pPage ) )
163 // convert the displayed Page of drawView (see below) does not work?!?
164 delete pDrawView;
165 pDrawView = nullptr;
168 if ( !pDrawView ) // New Drawing?
170 pDrawView = new FmFormView( pModel, this );
172 // The DrawView takes over the Design-Mode from the Model
173 // (Settings "In opening Draftmode"), therefore to restore here
174 pDrawView->SetDesignMode();
175 pDrawView->SetPrintPreview();
176 pDrawView->ShowSdrPage(pPage);
179 else if ( pDrawView )
181 delete pDrawView; // for this Chart is not needed
182 pDrawView = nullptr;
186 void ScPreview::TestLastPage()
188 if (nPageNo >= nTotalPages)
190 if (nTotalPages)
192 nPageNo = nTotalPages - 1;
193 nTab = static_cast<SCTAB>(nPages.size()) -1;
194 while (nTab > 0 && !nPages[nTab]) // not the last empty Table
195 --nTab;
196 OSL_ENSURE(0 < static_cast<SCTAB>(nPages.size()),"are all tables empty?");
197 nTabPage = nPages[nTab] - 1;
198 nTabStart = 0;
199 for (sal_uInt16 i=0; i<nTab; i++)
200 nTabStart += nPages[i];
202 ScDocument& rDoc = pDocShell->GetDocument();
203 nDisplayStart = lcl_GetDisplayStart( nTab, &rDoc, nPages );
205 else // empty Document
207 nTab = 0;
208 nPageNo = nTabPage = nTabStart = nDisplayStart = 0;
209 aState.nPrintTab = 0;
210 aState.nStartCol = aState.nEndCol = 0;
211 aState.nStartRow = aState.nEndRow = 0;
212 aState.nZoom = 0;
213 aState.nPagesX = aState.nPagesY = 0;
214 aState.nTabPages = aState.nTotalPages =
215 aState.nPageStart = aState.nDocPages = 0;
220 void ScPreview::CalcPages()
222 WaitObject aWait( this );
224 ScDocument& rDoc = pDocShell->GetDocument();
225 nTabCount = rDoc.GetTableCount();
227 SCTAB nStart = nTabsTested;
228 if (!bValid)
230 nStart = 0;
231 nTotalPages = 0;
232 nTabsTested = 0;
235 // update all pending row heights with a single progress bar,
236 // instead of a separate progress for each sheet from ScPrintFunc
237 pDocShell->UpdatePendingRowHeights( nTabCount-1, true );
239 // PrintOptions is passed to PrintFunc for SkipEmpty flag,
240 // but always all sheets are used (there is no selected sheet)
241 ScPrintOptions aOptions = SC_MOD()->GetPrintOptions();
243 while (nStart > static_cast<SCTAB>(nPages.size()))
244 nPages.push_back(0);
245 while (nStart > static_cast<SCTAB>(nFirstAttr.size()))
246 nFirstAttr.push_back(0);
248 for (SCTAB i=nStart; i<nTabCount; i++)
250 if ( i == static_cast<SCTAB>(nPages.size()))
251 nPages.push_back(0);
252 if ( i == static_cast<SCTAB>(nFirstAttr.size()))
253 nFirstAttr.push_back(0);
254 if (!aOptions.GetAllSheets() && maSelectedTabs.count(i) == 0)
256 nPages[i] = 0;
257 nFirstAttr[i] = 0;
258 continue;
261 long nAttrPage = i > 0 ? nFirstAttr[i-1] : 1;
263 long nThisStart = nTotalPages;
264 ScPrintFunc aPrintFunc( this, pDocShell, i, nAttrPage, 0, nullptr, &aOptions );
265 long nThisTab = aPrintFunc.GetTotalPages();
266 if (!aPrintFunc.HasPrintRange())
267 mbHasEmptyRangeTable = true;
269 nPages[i] = nThisTab;
270 nTotalPages += nThisTab;
271 nFirstAttr[i] = aPrintFunc.GetFirstPageNo(); // to keep or from template
273 if (nPageNo>=nThisStart && nPageNo<nTotalPages)
275 nTab = i;
276 nTabPage = nPageNo - nThisStart;
277 nTabStart = nThisStart;
279 aPrintFunc.GetPrintState( aState );
280 aPageSize = aPrintFunc.GetPageSize();
284 nDisplayStart = lcl_GetDisplayStart( nTab, &rDoc, nPages );
286 if (nTabCount > nTabsTested)
287 nTabsTested = nTabCount;
289 TestLastPage();
291 aState.nDocPages = nTotalPages;
293 bValid = true;
294 bStateValid = true;
295 DoInvalidate();
298 void ScPreview::RecalcPages() // only nPageNo is changed
300 if (!bValid)
301 return; // then CalcPages is called
303 SCTAB nOldTab = nTab;
305 bool bDone = false;
306 while (nPageNo >= nTotalPages && nTabsTested < nTabCount)
308 CalcPages();
309 bDone = true;
312 if (!bDone)
314 long nPartPages = 0;
315 for (SCTAB i=0; i<nTabsTested && nTab < static_cast<SCTAB>(nPages.size()); i++)
317 long nThisStart = nPartPages;
318 nPartPages += nPages[i];
320 if (nPageNo>=nThisStart && nPageNo<nPartPages)
322 nTab = i;
323 nTabPage = nPageNo - nThisStart;
324 nTabStart = nThisStart;
328 ScDocument& rDoc = pDocShell->GetDocument();
329 nDisplayStart = lcl_GetDisplayStart( nTab, &rDoc, nPages );
332 TestLastPage(); // to test, if after last page
334 if ( nTab != nOldTab )
335 bStateValid = false;
337 DoInvalidate();
340 void ScPreview::DoPrint( ScPreviewLocationData* pFillLocation )
342 if (!bValid)
344 CalcPages();
345 RecalcPages();
346 UpdateDrawView(); // Spreedsheet eventually changes
349 Fraction aPreviewZoom( nZoom, 100 );
350 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
351 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
353 bool bDoPrint = ( pFillLocation == nullptr );
354 bool bValidPage = ( nPageNo < nTotalPages );
356 ScModule* pScMod = SC_MOD();
357 const svtools::ColorConfig& rColorCfg = pScMod->GetColorConfig();
358 Color aBackColor( rColorCfg.GetColorValue(svtools::APPBACKGROUND).nColor );
360 if ( bDoPrint && ( aOffset.X() < 0 || aOffset.Y() < 0 ) && bValidPage )
362 SetMapMode( aMMMode );
363 SetLineColor();
364 SetFillColor(aBackColor);
366 Size aWinSize = GetOutputSize();
367 if ( aOffset.X() < 0 )
368 DrawRect(Rectangle( 0, 0, -aOffset.X(), aWinSize.Height() ));
369 if ( aOffset.Y() < 0 )
370 DrawRect(Rectangle( 0, 0, aWinSize.Width(), -aOffset.Y() ));
373 long nLeftMargin = 0;
374 long nRightMargin = 0;
375 long nTopMargin = 0;
376 long nBottomMargin = 0;
377 bool bHeaderOn = false;
378 bool bFooterOn = false;
380 ScDocument& rDoc = pDocShell->GetDocument();
381 bool bLayoutRTL = rDoc.IsLayoutRTL( nTab );
383 Size aLocalPageSize;
384 if ( bValidPage )
386 ScPrintOptions aOptions = pScMod->GetPrintOptions();
388 ScPrintFunc* pPrintFunc;
389 if (bStateValid)
390 pPrintFunc = new ScPrintFunc( this, pDocShell, aState, &aOptions );
391 else
392 pPrintFunc = new ScPrintFunc( this, pDocShell, nTab, nFirstAttr[nTab], nTotalPages, nullptr, &aOptions );
394 pPrintFunc->SetOffset(aOffset);
395 pPrintFunc->SetManualZoom(nZoom);
396 pPrintFunc->SetDateTime(aDate,aTime);
397 pPrintFunc->SetClearFlag(true);
398 pPrintFunc->SetUseStyleColor( pScMod->GetAccessOptions().GetIsForPagePreviews() );
400 pPrintFunc->SetDrawView( pDrawView );
402 // MultiSelection for the one Page must produce something inconvenient
403 Range aPageRange( nPageNo+1, nPageNo+1 );
404 MultiSelection aPage( aPageRange );
405 aPage.SetTotalRange( Range(0,RANGE_MAX) );
406 aPage.Select( aPageRange );
408 long nPrinted = pPrintFunc->DoPrint( aPage, nTabStart, nDisplayStart, bDoPrint, pFillLocation );
409 OSL_ENSURE(nPrinted<=1, "What is happening?");
411 SetMapMode(aMMMode);
413 //init nLeftMargin ... in the ScPrintFunc::InitParam!!!
414 nLeftMargin = pPrintFunc->GetLeftMargin();
415 nRightMargin = pPrintFunc->GetRightMargin();
416 nTopMargin = pPrintFunc->GetTopMargin();
417 nBottomMargin = pPrintFunc->GetBottomMargin();
418 nHeaderHeight = pPrintFunc->GetHeader().nHeight;
419 nFooterHeight = pPrintFunc->GetFooter().nHeight;
420 bHeaderOn = pPrintFunc->GetHeader().bEnable;
421 bFooterOn = pPrintFunc->GetFooter().bEnable;
422 mnScale = pPrintFunc->GetZoom();
424 if ( bDoPrint && bPageMargin && pLocationData ) // don't make use of pLocationData while filling it
426 Rectangle aPixRect;
427 Rectangle aRectCellPosition;
428 Rectangle aRectPosition;
429 pLocationData->GetMainCellRange( aPageArea, aPixRect );
430 if( !bLayoutRTL )
432 pLocationData->GetCellPosition( aPageArea.aStart, aRectPosition );
433 nLeftPosition = aRectPosition.Left();
434 for( SCCOL i = aPageArea.aStart.Col(); i <= aPageArea.aEnd.Col(); i++ )
436 pLocationData->GetCellPosition( ScAddress( i,aPageArea.aStart.Row(),aPageArea.aStart.Tab()),aRectCellPosition );
437 nRight[i] = aRectCellPosition.Right();
440 else
442 pLocationData->GetCellPosition( aPageArea.aEnd, aRectPosition );
443 nLeftPosition = aRectPosition.Right()+1;
445 pLocationData->GetCellPosition( aPageArea.aStart,aRectCellPosition );
446 nRight[ aPageArea.aEnd.Col() ] = aRectCellPosition.Left();
447 for( SCCOL i = aPageArea.aEnd.Col(); i > aPageArea.aStart.Col(); i-- )
449 pLocationData->GetCellPosition( ScAddress( i,aPageArea.aEnd.Row(),aPageArea.aEnd.Tab()),aRectCellPosition );
450 nRight[ i-1 ] = nRight[ i ] + aRectCellPosition.Right() - aRectCellPosition.Left() + 1;
455 if (nPrinted) // if not, draw everything grey
457 aLocalPageSize = pPrintFunc->GetPageSize();
458 aLocalPageSize.Width() = (long) (aLocalPageSize.Width() * HMM_PER_TWIPS );
459 aLocalPageSize.Height() = (long) (aLocalPageSize.Height() * HMM_PER_TWIPS );
461 nLeftMargin = (long) ( nLeftMargin * HMM_PER_TWIPS );
462 nRightMargin = (long) ( nRightMargin * HMM_PER_TWIPS );
463 nTopMargin = (long) ( nTopMargin * HMM_PER_TWIPS );
464 nBottomMargin = (long) ( nBottomMargin * HMM_PER_TWIPS );
465 nHeaderHeight = (long) ( nHeaderHeight * HMM_PER_TWIPS * mnScale / 100 + nTopMargin );
466 nFooterHeight = (long) ( nFooterHeight * HMM_PER_TWIPS * mnScale / 100 + nBottomMargin );
469 if (!bStateValid)
471 pPrintFunc->GetPrintState( aState );
472 aState.nDocPages = nTotalPages;
473 bStateValid = true;
475 delete pPrintFunc;
478 if ( bDoPrint )
480 long nPageEndX = aLocalPageSize.Width() - aOffset.X();
481 long nPageEndY = aLocalPageSize.Height() - aOffset.Y();
482 if ( !bValidPage )
483 nPageEndX = nPageEndY = 0;
485 Size aWinSize = GetOutputSize();
486 Point aWinEnd( aWinSize.Width(), aWinSize.Height() );
487 bool bRight = nPageEndX <= aWinEnd.X();
488 bool bBottom = nPageEndY <= aWinEnd.Y();
490 if (!nTotalPages)
492 // There is no data to print. Print a friendly warning message and
493 // bail out.
495 SetMapMode(aMMMode);
497 // Draw background first.
498 SetLineColor();
499 SetFillColor(aBackColor);
500 DrawRect(Rectangle(0, 0, aWinEnd.X(), aWinEnd.Y()));
502 const ScPatternAttr& rDefPattern =
503 static_cast<const ScPatternAttr&>(
504 rDoc.GetPool()->GetDefaultItem(ATTR_PATTERN));
506 std::unique_ptr<ScEditEngineDefaulter> pEditEng(
507 new ScEditEngineDefaulter(EditEngine::CreatePool(), true));
509 pEditEng->SetRefMapMode(aMMMode);
510 SfxItemSet* pEditDefaults = new SfxItemSet( pEditEng->GetEmptyItemSet() );
511 rDefPattern.FillEditItemSet(pEditDefaults);
512 pEditEng->SetDefaults(pEditDefaults);
514 Color aTextColor(COL_LIGHTGRAY);
515 pEditDefaults->Put(SvxColorItem(aTextColor, EE_CHAR_COLOR));
517 OUString aEmptyMsg;
518 if (mbHasEmptyRangeTable)
519 aEmptyMsg = ScGlobal::GetRscString(STR_PRINT_PREVIEW_EMPTY_RANGE);
520 else
521 aEmptyMsg = ScGlobal::GetRscString(STR_PRINT_PREVIEW_NODATA);
523 long nHeight = 3000;
524 pEditEng->SetDefaultItem(SvxFontHeightItem(nHeight, 100, EE_CHAR_FONTHEIGHT));
525 pEditEng->SetDefaultItem(SvxFontHeightItem(nHeight, 100, EE_CHAR_FONTHEIGHT_CJK));
526 pEditEng->SetDefaultItem(SvxFontHeightItem(nHeight, 100, EE_CHAR_FONTHEIGHT_CTL));
528 pEditEng->SetText(aEmptyMsg);
530 Point aCenter(
531 (aWinEnd.X() - pEditEng->CalcTextWidth())/2,
532 (aWinEnd.Y() - pEditEng->GetTextHeight())/2);
534 pEditEng->Draw(this, aCenter);
536 return;
539 if( bPageMargin && bValidPage )
541 SetMapMode(aMMMode);
542 SetLineColor( COL_BLACK );
543 DrawInvert( (long)( nTopMargin - aOffset.Y() ), PointerStyle::VSizeBar );
544 DrawInvert( (long)(nPageEndY - nBottomMargin ), PointerStyle::VSizeBar );
545 DrawInvert( (long)( nLeftMargin - aOffset.X() ), PointerStyle::HSizeBar );
546 DrawInvert( (long)( nPageEndX - nRightMargin ) , PointerStyle::HSizeBar );
547 if( bHeaderOn )
549 DrawInvert( nHeaderHeight - aOffset.Y(), PointerStyle::VSizeBar );
551 if( bFooterOn )
553 DrawInvert( nPageEndY - nFooterHeight, PointerStyle::VSizeBar );
556 SetMapMode( MapMode( MAP_PIXEL ) );
557 for( int i= aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
559 Point aColumnTop = LogicToPixel( Point( 0, -aOffset.Y() ) ,aMMMode );
560 SetLineColor( COL_BLACK );
561 SetFillColor( COL_BLACK );
562 DrawRect( Rectangle( Point( nRight[i] - 2, aColumnTop.Y() ),Point( nRight[i] + 2 , 4 + aColumnTop.Y()) ));
563 DrawLine( Point( nRight[i], aColumnTop.Y() ), Point( nRight[i], 10 + aColumnTop.Y()) );
565 SetMapMode( aMMMode );
568 if (bRight || bBottom)
570 SetMapMode(aMMMode);
571 SetLineColor();
572 SetFillColor(aBackColor);
573 if (bRight)
574 DrawRect(Rectangle(nPageEndX,0, aWinEnd.X(),aWinEnd.Y()));
575 if (bBottom)
577 if (bRight)
578 DrawRect(Rectangle(0,nPageEndY, nPageEndX,aWinEnd.Y())); // Corner not duplicated
579 else
580 DrawRect(Rectangle(0,nPageEndY, aWinEnd.X(),aWinEnd.Y()));
584 if ( bValidPage )
586 Color aBorderColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
588 // draw border
590 if ( aOffset.X() <= 0 || aOffset.Y() <= 0 || bRight || bBottom )
592 SetLineColor( aBorderColor );
593 SetFillColor();
595 Rectangle aPixel( LogicToPixel( Rectangle( -aOffset.X(), -aOffset.Y(), nPageEndX, nPageEndY ) ) );
596 --aPixel.Right();
597 --aPixel.Bottom();
598 DrawRect( PixelToLogic( aPixel ) );
601 // draw shadow
603 SetLineColor();
604 SetFillColor( aBorderColor );
606 Rectangle aPixel;
608 aPixel = LogicToPixel( Rectangle( nPageEndX, -aOffset.Y(), nPageEndX, nPageEndY ) );
609 aPixel.Top() += SC_PREVIEW_SHADOWSIZE;
610 aPixel.Right() += SC_PREVIEW_SHADOWSIZE - 1;
611 aPixel.Bottom() += SC_PREVIEW_SHADOWSIZE - 1;
612 DrawRect( PixelToLogic( aPixel ) );
614 aPixel = LogicToPixel( Rectangle( -aOffset.X(), nPageEndY, nPageEndX, nPageEndY ) );
615 aPixel.Left() += SC_PREVIEW_SHADOWSIZE;
616 aPixel.Right() += SC_PREVIEW_SHADOWSIZE - 1;
617 aPixel.Bottom() += SC_PREVIEW_SHADOWSIZE - 1;
618 DrawRect( PixelToLogic( aPixel ) );
623 void ScPreview::Paint( vcl::RenderContext& /*rRenderContext*/, const Rectangle& /* rRect */ )
625 bool bWasInPaint = bInPaint; // nested calls shouldn't be necessary, but allow for now
626 bInPaint = true;
628 if (bPageMargin)
629 GetLocationData(); // fill location data for column positions
630 DoPrint( nullptr );
631 pViewShell->UpdateScrollBars();
633 bInPaint = bWasInPaint;
636 void ScPreview::Command( const CommandEvent& rCEvt )
638 CommandEventId nCmd = rCEvt.GetCommand();
639 if ( nCmd == CommandEventId::Wheel || nCmd == CommandEventId::StartAutoScroll || nCmd == CommandEventId::AutoScroll )
641 bool bDone = pViewShell->ScrollCommand( rCEvt );
642 if (!bDone)
643 Window::Command(rCEvt);
645 else if ( nCmd == CommandEventId::ContextMenu )
646 SfxDispatcher::ExecutePopup();
647 else
648 Window::Command( rCEvt );
651 void ScPreview::KeyInput( const KeyEvent& rKEvt )
653 // The + and - keys can't be configured as accelerator entries, so they must be handled directly
654 // (in ScPreview, not ScPreviewShell -> only if the preview window has the focus)
656 const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
657 sal_uInt16 nKey = rKeyCode.GetCode();
658 bool bHandled = false;
659 if(!rKeyCode.GetModifier())
661 sal_uInt16 nSlot = 0;
662 switch(nKey)
664 case KEY_ADD: nSlot = SID_PREVIEW_ZOOMIN; break;
665 case KEY_ESCAPE: nSlot = ScViewUtil::IsFullScreen( *pViewShell ) ? SID_CANCEL : SID_PREVIEW_CLOSE; break;
666 case KEY_SUBTRACT: nSlot = SID_PREVIEW_ZOOMOUT; break;
668 if(nSlot)
670 bHandled = true;
671 pViewShell->GetViewFrame()->GetDispatcher()->Execute( nSlot, SfxCallMode::ASYNCHRON );
675 if ( !bHandled && !pViewShell->KeyInput(rKEvt) )
676 Window::KeyInput(rKEvt);
679 const ScPreviewLocationData& ScPreview::GetLocationData()
681 if ( !pLocationData )
683 pLocationData = new ScPreviewLocationData( &pDocShell->GetDocument(), this );
684 bLocationValid = false;
686 if ( !bLocationValid )
688 pLocationData->Clear();
689 DoPrint( pLocationData );
690 bLocationValid = true;
692 return *pLocationData;
695 void ScPreview::DataChanged(bool bNewTime)
697 if (bNewTime)
699 aDate = Date( Date::SYSTEM );
700 aTime = tools::Time( tools::Time::SYSTEM );
703 bValid = false;
704 InvalidateLocationData( SC_HINT_DATACHANGED );
705 Invalidate();
708 OUString ScPreview::GetPosString()
710 if (!bValid)
712 CalcPages();
713 UpdateDrawView(); // The table eventually changes
716 OUString aString = ScGlobal::GetRscString( STR_PAGE ) +
717 " " + OUString::number(nPageNo+1);
719 if (nTabsTested >= nTabCount)
720 aString += " / " + OUString::number(nTotalPages);
722 return aString;
725 void ScPreview::SetZoom(sal_uInt16 nNewZoom)
727 if (nNewZoom < 20)
728 nNewZoom = 20;
729 if (nNewZoom > 400)
730 nNewZoom = 400;
731 if (nNewZoom != nZoom)
733 nZoom = nNewZoom;
735 // apply new MapMode and call UpdateScrollBars to update aOffset
737 Fraction aPreviewZoom( nZoom, 100 );
738 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
739 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
740 SetMapMode( aMMMode );
742 bInSetZoom = true; // don't scroll during SetYOffset in UpdateScrollBars
743 pViewShell->UpdateNeededScrollBars(true);
744 bInSetZoom = false;
746 bStateValid = false;
747 InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
748 DoInvalidate();
749 Invalidate();
753 void ScPreview::SetPageNo( long nPage )
755 nPageNo = nPage;
756 RecalcPages();
757 UpdateDrawView(); // The table eventually changes
758 InvalidateLocationData( SC_HINT_DATACHANGED );
759 Invalidate();
762 long ScPreview::GetFirstPage(SCTAB nTabP)
764 SCTAB nDocTabCount = pDocShell->GetDocument().GetTableCount();
765 if (nTabP >= nDocTabCount)
766 nTabP = nDocTabCount-1;
768 long nPage = 0;
769 if (nTabP>0)
771 CalcPages();
772 if (nTabP >= static_cast<SCTAB>(nPages.size()) )
773 OSL_FAIL("nPages out ouf bounds, FIX IT");
774 UpdateDrawView(); // The table eventually changes
776 for (SCTAB i=0; i<nTabP; i++)
777 nPage += nPages[i];
779 // An empty Table on the previous Page
781 if ( nPages[nTabP]==0 && nPage > 0 )
782 --nPage;
785 return nPage;
788 static Size lcl_GetDocPageSize( ScDocument* pDoc, SCTAB nTab )
790 OUString aName = pDoc->GetPageStyle( nTab );
791 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
792 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aName, SfxStyleFamily::Page );
793 if ( pStyleSheet )
795 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
796 return static_cast<const SvxSizeItem&>( rStyleSet.Get(ATTR_PAGE_SIZE)).GetSize();
798 else
800 OSL_FAIL( "PageStyle not found" );
801 return Size();
805 sal_uInt16 ScPreview::GetOptimalZoom(bool bWidthOnly)
807 double nWinScaleX = ScGlobal::nScreenPPTX / pDocShell->GetOutputFactor();
808 double nWinScaleY = ScGlobal::nScreenPPTY;
809 Size aWinSize = GetOutputSizePixel();
811 // desired margin is 0.25cm in default MapMode (like Writer),
812 // but some additional margin is introduced by integer scale values
813 // -> add only 0.10cm, so there is some margin in all cases.
814 Size aMarginSize( LogicToPixel( Size( 100, 100 ), MAP_100TH_MM ) );
815 aWinSize.Width() -= 2 * aMarginSize.Width();
816 aWinSize.Height() -= 2 * aMarginSize.Height();
818 Size aLocalPageSize = lcl_GetDocPageSize( &pDocShell->GetDocument(), nTab );
819 if ( aLocalPageSize.Width() && aLocalPageSize.Height() )
821 long nZoomX = (long) ( aWinSize.Width() * 100 / ( aLocalPageSize.Width() * nWinScaleX ));
822 long nZoomY = (long) ( aWinSize.Height() * 100 / ( aLocalPageSize.Height() * nWinScaleY ));
824 long nOptimal = nZoomX;
825 if (!bWidthOnly && nZoomY<nOptimal)
826 nOptimal = nZoomY;
828 if (nOptimal<20)
829 nOptimal = 20;
830 if (nOptimal>400)
831 nOptimal = 400;
833 return (sal_uInt16) nOptimal;
835 else
836 return nZoom;
839 void ScPreview::SetXOffset( long nX )
841 if ( aOffset.X() == nX )
842 return;
844 if (bValid)
846 long nDif = LogicToPixel(aOffset).X() - LogicToPixel(Point(nX,0)).X();
847 aOffset.X() = nX;
848 if (nDif && !bInSetZoom)
850 MapMode aOldMode = GetMapMode(); SetMapMode(MAP_PIXEL);
851 Scroll( nDif, 0 );
852 SetMapMode(aOldMode);
855 else
857 aOffset.X() = nX;
858 if (!bInSetZoom)
859 Invalidate();
861 InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
862 Invalidate();
865 void ScPreview::SetYOffset( long nY )
867 if ( aOffset.Y() == nY )
868 return;
870 if (bValid)
872 long nDif = LogicToPixel(aOffset).Y() - LogicToPixel(Point(0,nY)).Y();
873 aOffset.Y() = nY;
874 if (nDif && !bInSetZoom)
876 MapMode aOldMode = GetMapMode(); SetMapMode(MAP_PIXEL);
877 Scroll( 0, nDif );
878 SetMapMode(aOldMode);
881 else
883 aOffset.Y() = nY;
884 if (!bInSetZoom)
885 Invalidate();
887 InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
888 Invalidate();
891 void ScPreview::DoInvalidate()
893 // If the whole GetState of the shell is called
894 // The Invalidate must come behind asynchronously
896 if (bInGetState)
897 Application::PostUserEvent( LINK( this, ScPreview, InvalidateHdl ), nullptr, true );
898 else
899 StaticInvalidate(); // Immediately
902 void ScPreview::StaticInvalidate()
904 // static method, because it's called asynchronously
905 // -> must use current viewframe
907 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
908 if (!pViewFrm)
909 return;
911 SfxBindings& rBindings = pViewFrm->GetBindings();
912 rBindings.Invalidate(SID_STATUS_DOCPOS);
913 rBindings.Invalidate(SID_ROWCOL_SELCOUNT);
914 rBindings.Invalidate(SID_STATUS_PAGESTYLE);
915 rBindings.Invalidate(SID_PREVIEW_PREVIOUS);
916 rBindings.Invalidate(SID_PREVIEW_NEXT);
917 rBindings.Invalidate(SID_PREVIEW_FIRST);
918 rBindings.Invalidate(SID_PREVIEW_LAST);
919 rBindings.Invalidate(SID_ATTR_ZOOM);
920 rBindings.Invalidate(SID_PREVIEW_ZOOMIN);
921 rBindings.Invalidate(SID_PREVIEW_ZOOMOUT);
922 rBindings.Invalidate(SID_PREVIEW_SCALINGFACTOR);
923 rBindings.Invalidate(SID_ATTR_ZOOMSLIDER);
926 IMPL_STATIC_LINK_NOARG_TYPED( ScPreview, InvalidateHdl, void*, void )
928 StaticInvalidate();
931 void ScPreview::DataChanged( const DataChangedEvent& rDCEvt )
933 Window::DataChanged(rDCEvt);
935 if ( (rDCEvt.GetType() == DataChangedEventType::PRINTER) ||
936 (rDCEvt.GetType() == DataChangedEventType::DISPLAY) ||
937 (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
938 (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
939 ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
940 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
942 if ( rDCEvt.GetType() == DataChangedEventType::FONTS )
943 pDocShell->UpdateFontList();
945 // #i114518# Paint of form controls may modify the window's settings.
946 // Ignore the event if it is called from within Paint.
947 if ( !bInPaint )
949 if ( rDCEvt.GetType() == DataChangedEventType::SETTINGS &&
950 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
952 // scroll bar size may have changed
953 pViewShell->InvalidateBorder(); // calls OuterResizePixel
955 Invalidate();
956 InvalidateLocationData( SC_HINT_DATACHANGED );
961 void ScPreview::MouseButtonDown( const MouseEvent& rMEvt )
963 Fraction aPreviewZoom( nZoom, 100 );
964 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
965 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
967 aButtonDownChangePoint = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
968 aButtonDownPt = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
970 CaptureMouse();
972 if( rMEvt.IsLeft() && GetPointer() == PointerStyle::HSizeBar )
974 SetMapMode( aMMMode );
975 if( bLeftRulerChange )
977 DrawInvert( aButtonDownChangePoint.X(), PointerStyle::HSizeBar );
978 bLeftRulerMove = true;
979 bRightRulerMove = false;
981 else if( bRightRulerChange )
983 DrawInvert( aButtonDownChangePoint.X(), PointerStyle::HSizeBar );
984 bLeftRulerMove = false;
985 bRightRulerMove = true;
989 if( rMEvt.IsLeft() && GetPointer() == PointerStyle::VSizeBar )
991 SetMapMode( aMMMode );
992 if( bTopRulerChange )
994 DrawInvert( aButtonDownChangePoint.Y(), PointerStyle::VSizeBar );
995 bTopRulerMove = true;
996 bBottomRulerMove = false;
998 else if( bBottomRulerChange )
1000 DrawInvert( aButtonDownChangePoint.Y(), PointerStyle::VSizeBar );
1001 bTopRulerMove = false;
1002 bBottomRulerMove = true;
1004 else if( bHeaderRulerChange )
1006 DrawInvert( aButtonDownChangePoint.Y(), PointerStyle::VSizeBar );
1007 bHeaderRulerMove = true;
1008 bFooterRulerMove = false;
1010 else if( bFooterRulerChange )
1012 DrawInvert( aButtonDownChangePoint.Y(), PointerStyle::VSizeBar );
1013 bHeaderRulerMove = false;
1014 bFooterRulerMove = true;
1018 if( rMEvt.IsLeft() && GetPointer() == PointerStyle::HSplit )
1020 Point aNowPt = rMEvt.GetPosPixel();
1021 SCCOL i = 0;
1022 for( i = aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
1024 if( aNowPt.X() < nRight[i] + 2 && aNowPt.X() > nRight[i] - 2 )
1026 nColNumberButttonDown = i;
1027 break;
1030 if( i == aPageArea.aEnd.Col()+1 )
1031 return;
1033 SetMapMode( aMMMode );
1034 if( nColNumberButttonDown == aPageArea.aStart.Col() )
1035 DrawInvert( PixelToLogic( Point( nLeftPosition, 0 ),aMMMode ).X() ,PointerStyle::HSplit );
1036 else
1037 DrawInvert( PixelToLogic( Point( nRight[ nColNumberButttonDown-1 ], 0 ),aMMMode ).X() ,PointerStyle::HSplit );
1039 DrawInvert( aButtonDownChangePoint.X(), PointerStyle::HSplit );
1040 bColRulerMove = true;
1044 void ScPreview::MouseButtonUp( const MouseEvent& rMEvt )
1046 Fraction aPreviewZoom( nZoom, 100 );
1047 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
1048 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
1050 aButtonUpPt = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
1052 long nWidth = (long) lcl_GetDocPageSize(&pDocShell->GetDocument(), nTab).Width();
1053 long nHeight = (long) lcl_GetDocPageSize(&pDocShell->GetDocument(), nTab).Height();
1055 if( rMEvt.IsLeft() && GetPointer() == PointerStyle::HSizeBar )
1057 SetPointer( Pointer( PointerStyle::Arrow ) );
1059 ScDocument& rDoc = pDocShell->GetDocument();
1060 OUString aOldName = rDoc.GetPageStyle( nTab );
1061 bool bUndo = rDoc.IsUndoEnabled();
1062 ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool();
1063 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aOldName, SfxStyleFamily::Page );
1065 if ( pStyleSheet )
1067 bool bMoveRulerAction= true;
1068 ScStyleSaveData aOldData;
1069 if( bUndo )
1070 aOldData.InitFromStyle( pStyleSheet );
1072 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
1074 SvxLRSpaceItem aLRItem = static_cast<const SvxLRSpaceItem&>( rStyleSet.Get( ATTR_LRSPACE ) );
1076 if(( bLeftRulerChange || bRightRulerChange ) && ( aButtonUpPt.X() <= ( 0 - aOffset.X() ) || aButtonUpPt.X() > nWidth * HMM_PER_TWIPS - aOffset.X() ) )
1078 bMoveRulerAction = false;
1079 Invalidate(Rectangle(0, 0, 10000, 10000));
1081 else if( bLeftRulerChange && ( aButtonUpPt.X() / HMM_PER_TWIPS > nWidth - aLRItem.GetRight() - aOffset.X() / HMM_PER_TWIPS ) )
1083 bMoveRulerAction = false;
1084 Invalidate(Rectangle(0, 0, 10000, 10000));
1086 else if( bRightRulerChange && ( aButtonUpPt.X() / HMM_PER_TWIPS < aLRItem.GetLeft() - aOffset.X() / HMM_PER_TWIPS ) )
1088 bMoveRulerAction = false;
1089 Invalidate(Rectangle(0, 0, 10000, 10000));
1091 else if( aButtonDownPt.X() == aButtonUpPt.X() )
1093 bMoveRulerAction = false;
1094 DrawInvert( aButtonUpPt.X(), PointerStyle::HSizeBar );
1096 if( bMoveRulerAction )
1098 ScDocShellModificator aModificator( *pDocShell );
1099 if( bLeftRulerChange && bLeftRulerMove )
1101 aLRItem.SetLeft( (long)( aButtonUpPt.X() / HMM_PER_TWIPS + aOffset.X() / HMM_PER_TWIPS ));
1102 rStyleSet.Put( aLRItem );
1103 pDocShell->SetModified();
1105 else if( bRightRulerChange && bRightRulerMove )
1107 aLRItem.SetRight( (long)( nWidth - aButtonUpPt.X() / HMM_PER_TWIPS - aOffset.X() / HMM_PER_TWIPS ));
1108 rStyleSet.Put( aLRItem );
1109 pDocShell->SetModified();
1112 ScStyleSaveData aNewData;
1113 aNewData.InitFromStyle( pStyleSheet );
1114 if( bUndo )
1116 pDocShell->GetUndoManager()->AddUndoAction(
1117 new ScUndoModifyStyle( pDocShell, SfxStyleFamily::Page,
1118 aOldData, aNewData ) );
1121 if ( ValidTab( nTab ) )
1123 ScPrintFunc aPrintFunc( this, pDocShell, nTab );
1124 aPrintFunc.UpdatePages();
1127 Rectangle aRect(0,0,10000,10000);
1128 Invalidate(aRect);
1129 aModificator.SetDocumentModified();
1130 bLeftRulerChange = false;
1131 bRightRulerChange = false;
1134 bLeftRulerMove = false;
1135 bRightRulerMove = false;
1138 if( rMEvt.IsLeft() && GetPointer() == PointerStyle::VSizeBar )
1140 SetPointer( PointerStyle::Arrow );
1142 bool bMoveRulerAction = true;
1143 if( ( bTopRulerChange || bBottomRulerChange || bHeaderRulerChange || bFooterRulerChange ) && ( aButtonUpPt.Y() <= ( 0 - aOffset.Y() ) || aButtonUpPt.Y() > nHeight * HMM_PER_TWIPS -aOffset.Y() ) )
1145 bMoveRulerAction = false;
1146 Invalidate(Rectangle(0, 0, 10000, 10000));
1148 else if( aButtonDownPt.Y() == aButtonUpPt.Y() )
1150 bMoveRulerAction = false;
1151 DrawInvert( aButtonUpPt.Y(), PointerStyle::VSizeBar );
1153 if( bMoveRulerAction )
1155 ScDocument& rDoc = pDocShell->GetDocument();
1156 bool bUndo = rDoc.IsUndoEnabled();
1157 ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool();
1158 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( rDoc.GetPageStyle( nTab ), SfxStyleFamily::Page );
1159 OSL_ENSURE( pStyleSheet, "PageStyle not found" );
1160 if ( pStyleSheet )
1162 ScDocShellModificator aModificator( *pDocShell );
1163 ScStyleSaveData aOldData;
1164 if( bUndo )
1165 aOldData.InitFromStyle( pStyleSheet );
1167 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
1169 SvxULSpaceItem aULItem = static_cast<const SvxULSpaceItem&>( rStyleSet.Get( ATTR_ULSPACE ) );
1171 if( bTopRulerMove && bTopRulerChange )
1173 aULItem.SetUpperValue( (sal_uInt16)( aButtonUpPt.Y() / HMM_PER_TWIPS + aOffset.Y() / HMM_PER_TWIPS ) );
1174 rStyleSet.Put( aULItem );
1175 pDocShell->SetModified();
1177 else if( bBottomRulerMove && bBottomRulerChange )
1179 aULItem.SetLowerValue( (sal_uInt16)( nHeight - aButtonUpPt.Y() / HMM_PER_TWIPS - aOffset.Y() / HMM_PER_TWIPS ) );
1180 rStyleSet.Put( aULItem );
1181 pDocShell->SetModified();
1183 else if( bHeaderRulerMove && bHeaderRulerChange )
1185 const SfxPoolItem* pItem = nullptr;
1186 if ( rStyleSet.GetItemState( ATTR_PAGE_HEADERSET, false, &pItem ) == SfxItemState::SET )
1188 const SfxItemSet& rHeaderSet = static_cast<const SvxSetItem*>(pItem)->GetItemSet();
1189 Size aHeaderSize = static_cast<const SvxSizeItem&>(rHeaderSet.Get(ATTR_PAGE_SIZE)).GetSize();
1190 aHeaderSize.Height() = (long)( aButtonUpPt.Y() / HMM_PER_TWIPS + aOffset.Y() / HMM_PER_TWIPS - aULItem.GetUpper());
1191 aHeaderSize.Height() = aHeaderSize.Height() * 100 / mnScale;
1192 SvxSetItem aNewHeader( static_cast<const SvxSetItem&>(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 const SfxPoolItem* pItem = nullptr;
1201 if( rStyleSet.GetItemState( ATTR_PAGE_FOOTERSET, false, &pItem ) == SfxItemState::SET )
1203 const SfxItemSet& rFooterSet = static_cast<const SvxSetItem*>(pItem)->GetItemSet();
1204 Size aFooterSize = static_cast<const SvxSizeItem&>(rFooterSet.Get(ATTR_PAGE_SIZE)).GetSize();
1205 aFooterSize.Height() = (long)( nHeight - aButtonUpPt.Y() / HMM_PER_TWIPS - aOffset.Y() / HMM_PER_TWIPS - aULItem.GetLower() );
1206 aFooterSize.Height() = aFooterSize.Height() * 100 / mnScale;
1207 SvxSetItem aNewFooter( static_cast<const SvxSetItem&>(rStyleSet.Get(ATTR_PAGE_FOOTERSET)) );
1208 aNewFooter.GetItemSet().Put( SvxSizeItem( ATTR_PAGE_SIZE, aFooterSize ) );
1209 rStyleSet.Put( aNewFooter );
1210 pDocShell->SetModified();
1214 ScStyleSaveData aNewData;
1215 aNewData.InitFromStyle( pStyleSheet );
1216 if( bUndo )
1218 pDocShell->GetUndoManager()->AddUndoAction(
1219 new ScUndoModifyStyle( pDocShell, SfxStyleFamily::Page,
1220 aOldData, aNewData ) );
1223 if ( ValidTab( nTab ) )
1225 ScPrintFunc aPrintFunc( this, pDocShell, nTab );
1226 aPrintFunc.UpdatePages();
1229 Rectangle aRect(0, 0, 10000, 10000);
1230 Invalidate(aRect);
1231 aModificator.SetDocumentModified();
1232 bTopRulerChange = false;
1233 bBottomRulerChange = false;
1234 bHeaderRulerChange = false;
1235 bFooterRulerChange = false;
1238 bTopRulerMove = false;
1239 bBottomRulerMove = false;
1240 bHeaderRulerMove = false;
1241 bFooterRulerMove = false;
1243 if( rMEvt.IsLeft() && GetPointer() == PointerStyle::HSplit )
1245 SetPointer(PointerStyle::Arrow);
1246 ScDocument& rDoc = pDocShell->GetDocument();
1247 bool bLayoutRTL = rDoc.IsLayoutRTL( nTab );
1248 bool bMoveRulerAction = true;
1249 if( aButtonDownPt.X() == aButtonUpPt.X() )
1251 bMoveRulerAction = false;
1252 if( nColNumberButttonDown == aPageArea.aStart.Col() )
1253 DrawInvert( PixelToLogic( Point( nLeftPosition, 0 ),aMMMode ).X() ,PointerStyle::HSplit );
1254 else
1255 DrawInvert( PixelToLogic( Point( nRight[ nColNumberButttonDown-1 ], 0 ),aMMMode ).X() ,PointerStyle::HSplit );
1256 DrawInvert( aButtonUpPt.X(), PointerStyle::HSplit );
1258 if( bMoveRulerAction )
1260 long nNewColWidth = 0;
1261 std::vector<sc::ColRowSpan> aCols(1, sc::ColRowSpan(nColNumberButttonDown,nColNumberButttonDown));
1263 if( !bLayoutRTL )
1265 nNewColWidth = (long) ( PixelToLogic( Point( rMEvt.GetPosPixel().X() - nRight[ nColNumberButttonDown ], 0), aMMMode ).X() / HMM_PER_TWIPS ) * 100 / mnScale;
1266 nNewColWidth += pDocShell->GetDocument().GetColWidth( nColNumberButttonDown, nTab );
1268 else
1271 nNewColWidth = (long) ( PixelToLogic( Point( nRight[ nColNumberButttonDown ] - rMEvt.GetPosPixel().X(), 0), aMMMode ).X() / HMM_PER_TWIPS ) * 100 / mnScale;
1272 nNewColWidth += pDocShell->GetDocument().GetColWidth( nColNumberButttonDown, nTab );
1275 if( nNewColWidth >= 0 )
1277 pDocShell->GetDocFunc().SetWidthOrHeight(
1278 true, aCols, nTab, SC_SIZE_DIRECT, (sal_uInt16)nNewColWidth, true, true);
1279 pDocShell->SetModified();
1281 if ( ValidTab( nTab ) )
1283 ScPrintFunc aPrintFunc( this, pDocShell, nTab );
1284 aPrintFunc.UpdatePages();
1286 Rectangle aRect(0, 0, 10000, 10000);
1287 Invalidate(aRect);
1289 bColRulerMove = false;
1291 ReleaseMouse();
1294 void ScPreview::MouseMove( const MouseEvent& rMEvt )
1296 Fraction aPreviewZoom( nZoom, 100 );
1297 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
1298 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
1299 Point aMouseMovePoint = PixelToLogic( rMEvt.GetPosPixel(), aMMMode );
1301 long nLeftMargin = 0;
1302 long nRightMargin = 0;
1303 long nTopMargin = 0;
1304 long nBottomMargin = 0;
1306 long nWidth = (long) lcl_GetDocPageSize(&pDocShell->GetDocument(), nTab).Width();
1307 long nHeight = (long) lcl_GetDocPageSize(&pDocShell->GetDocument(), nTab).Height();
1309 if ( nPageNo < nTotalPages )
1311 ScPrintOptions aOptions = SC_MOD()->GetPrintOptions();
1313 ScPrintFunc* pPrintFunc;
1315 if (bStateValid)
1316 pPrintFunc = new ScPrintFunc( this, pDocShell, aState, &aOptions );
1317 else
1318 pPrintFunc = new ScPrintFunc( this, pDocShell, nTab, nFirstAttr[nTab], nTotalPages, nullptr, &aOptions );
1320 nLeftMargin = (long)( pPrintFunc->GetLeftMargin() * HMM_PER_TWIPS - aOffset.X() );
1321 nRightMargin = (long)( pPrintFunc->GetRightMargin() * HMM_PER_TWIPS );
1322 nRightMargin = (long)( nWidth * HMM_PER_TWIPS - nRightMargin - aOffset.X() );
1323 nTopMargin = (long)( pPrintFunc->GetTopMargin() * HMM_PER_TWIPS - aOffset.Y() );
1324 nBottomMargin = (long)( pPrintFunc->GetBottomMargin() * HMM_PER_TWIPS );
1325 nBottomMargin = (long)( nHeight * HMM_PER_TWIPS - nBottomMargin - aOffset.Y() );
1326 if( mnScale > 0 )
1328 nHeaderHeight = (long)( nTopMargin + pPrintFunc->GetHeader().nHeight * HMM_PER_TWIPS * mnScale / 100 );
1329 nFooterHeight = (long)( nBottomMargin - pPrintFunc->GetFooter().nHeight * HMM_PER_TWIPS * mnScale / 100 );
1331 else
1333 nHeaderHeight = (long)( nTopMargin + pPrintFunc->GetHeader().nHeight * HMM_PER_TWIPS );
1334 nFooterHeight = (long)( nBottomMargin - pPrintFunc->GetFooter().nHeight * HMM_PER_TWIPS );
1336 delete pPrintFunc;
1339 Point aPixPt( rMEvt.GetPosPixel() );
1340 Point aLeftTop = LogicToPixel( Point( nLeftMargin, -aOffset.Y() ) , aMMMode );
1341 Point aLeftBottom = LogicToPixel( Point( nLeftMargin ,(long)(nHeight * HMM_PER_TWIPS - aOffset.Y()) ), aMMMode );
1342 Point aRightTop = LogicToPixel( Point( nRightMargin, -aOffset.Y() ), aMMMode );
1343 Point aTopLeft = LogicToPixel( Point( -aOffset.X(), nTopMargin ), aMMMode );
1344 Point aTopRight = LogicToPixel( Point( (long)(nWidth * HMM_PER_TWIPS - aOffset.X()), nTopMargin ), aMMMode );
1345 Point aBottomLeft = LogicToPixel( Point( -aOffset.X(), nBottomMargin ), aMMMode );
1346 Point aHeaderLeft = LogicToPixel( Point( -aOffset.X(), nHeaderHeight ), aMMMode );
1347 Point aFooderLeft = LogicToPixel( Point( -aOffset.X(), nFooterHeight ), aMMMode );
1349 bool bOnColRulerChange = false;
1351 for( SCCOL i=aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
1353 Point aColumnTop = LogicToPixel( Point( 0, -aOffset.Y() ) ,aMMMode );
1354 Point aColumnBottom = LogicToPixel( Point( 0, (long)( nHeight * HMM_PER_TWIPS - aOffset.Y()) ), aMMMode );
1355 if( aPixPt.X() < ( nRight[i] + 2 ) && ( aPixPt.X() > ( nRight[i] - 2 ) ) && ( aPixPt.X() < aRightTop.X() ) && ( aPixPt.X() > aLeftTop.X() )
1356 && ( aPixPt.Y() > aColumnTop.Y() ) && ( aPixPt.Y() < aColumnBottom.Y() ) && !bLeftRulerMove && !bRightRulerMove
1357 && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1359 bOnColRulerChange = true;
1360 if( !rMEvt.GetButtons() && GetPointer() == PointerStyle::HSplit )
1361 nColNumberButttonDown = i;
1362 break;
1366 if( aPixPt.X() < ( aLeftTop.X() + 2 ) && aPixPt.X() > ( aLeftTop.X() - 2 ) && !bRightRulerMove )
1368 bLeftRulerChange = true;
1369 bRightRulerChange = false;
1371 else if( aPixPt.X() < ( aRightTop.X() + 2 ) && aPixPt.X() > ( aRightTop.X() - 2 ) && !bLeftRulerMove )
1373 bLeftRulerChange = false;
1374 bRightRulerChange = true;
1376 else if( aPixPt.Y() < ( aTopLeft.Y() + 2 ) && aPixPt.Y() > ( aTopLeft.Y() - 2 ) && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1378 bTopRulerChange = true;
1379 bBottomRulerChange = false;
1380 bHeaderRulerChange = false;
1381 bFooterRulerChange = false;
1383 else if( aPixPt.Y() < ( aBottomLeft.Y() + 2 ) && aPixPt.Y() > ( aBottomLeft.Y() - 2 ) && !bTopRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1385 bTopRulerChange = false;
1386 bBottomRulerChange = true;
1387 bHeaderRulerChange = false;
1388 bFooterRulerChange = false;
1390 else if( aPixPt.Y() < ( aHeaderLeft.Y() + 2 ) && aPixPt.Y() > ( aHeaderLeft.Y() - 2 ) && !bTopRulerMove && !bBottomRulerMove && !bFooterRulerMove )
1392 bTopRulerChange = false;
1393 bBottomRulerChange = false;
1394 bHeaderRulerChange = true;
1395 bFooterRulerChange = false;
1397 else if( aPixPt.Y() < ( aFooderLeft.Y() + 2 ) && aPixPt.Y() > ( aFooderLeft.Y() - 2 ) && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove )
1399 bTopRulerChange = false;
1400 bBottomRulerChange = false;
1401 bHeaderRulerChange = false;
1402 bFooterRulerChange = true;
1405 if( bPageMargin )
1407 if(( (aPixPt.X() < ( aLeftTop.X() + 2 ) && aPixPt.X() > ( aLeftTop.X() - 2 )) || bLeftRulerMove ||
1408 ( aPixPt.X() < ( aRightTop.X() + 2 ) && aPixPt.X() > ( aRightTop.X() - 2 ) ) || bRightRulerMove || bOnColRulerChange || bColRulerMove )
1409 && aPixPt.Y() > aLeftTop.Y() && aPixPt.Y() < aLeftBottom.Y() )
1411 if( bOnColRulerChange || bColRulerMove )
1413 SetPointer( Pointer( PointerStyle::HSplit ) );
1414 if( bColRulerMove )
1416 if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
1417 DragMove( aMouseMovePoint.X(), PointerStyle::HSplit );
1420 else
1422 if( bLeftRulerChange && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1424 SetPointer( Pointer( PointerStyle::HSizeBar ) );
1425 if( bLeftRulerMove )
1427 if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
1428 DragMove( aMouseMovePoint.X(), PointerStyle::HSizeBar );
1431 else if( bRightRulerChange && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1433 SetPointer( Pointer( PointerStyle::HSizeBar ) );
1434 if( bRightRulerMove )
1436 if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
1437 DragMove( aMouseMovePoint.X(), PointerStyle::HSizeBar );
1442 else
1444 if( ( ( aPixPt.Y() < ( aTopLeft.Y() + 2 ) && aPixPt.Y() > ( aTopLeft.Y() - 2 ) ) || bTopRulerMove ||
1445 ( aPixPt.Y() < ( aBottomLeft.Y() + 2 ) && aPixPt.Y() > ( aBottomLeft.Y() - 2 ) ) || bBottomRulerMove ||
1446 ( aPixPt.Y() < ( aHeaderLeft.Y() + 2 ) && aPixPt.Y() > ( aHeaderLeft.Y() - 2 ) ) || bHeaderRulerMove ||
1447 ( aPixPt.Y() < ( aFooderLeft.Y() + 2 ) && aPixPt.Y() > ( aFooderLeft.Y() - 2 ) ) || bFooterRulerMove )
1448 && aPixPt.X() > aTopLeft.X() && aPixPt.X() < aTopRight.X() )
1450 if( bTopRulerChange )
1452 SetPointer( Pointer( PointerStyle::VSizeBar ) );
1453 if( bTopRulerMove )
1455 if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
1456 DragMove( aMouseMovePoint.Y(), PointerStyle::VSizeBar );
1459 else if( bBottomRulerChange )
1461 SetPointer( Pointer( PointerStyle::VSizeBar ) );
1462 if( bBottomRulerMove )
1464 if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
1465 DragMove( aMouseMovePoint.Y(), PointerStyle::VSizeBar );
1468 else if( bHeaderRulerChange )
1470 SetPointer( Pointer( PointerStyle::VSizeBar ) );
1471 if( bHeaderRulerMove )
1473 if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
1474 DragMove( aMouseMovePoint.Y(), PointerStyle::VSizeBar );
1477 else if( bFooterRulerChange )
1479 SetPointer( Pointer( PointerStyle::VSizeBar ) );
1480 if( bFooterRulerMove )
1482 if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
1483 DragMove( aMouseMovePoint.Y(), PointerStyle::VSizeBar );
1487 else
1488 SetPointer( Pointer( PointerStyle::Arrow ) );
1493 void ScPreview::InvalidateLocationData(sal_uLong nId)
1495 bLocationValid = false;
1496 if (pViewShell->HasAccessibilityObjects())
1497 pViewShell->BroadcastAccessibility( SfxSimpleHint( nId ) );
1500 void ScPreview::GetFocus()
1502 Window::GetFocus();
1503 if (pViewShell && pViewShell->HasAccessibilityObjects())
1504 pViewShell->BroadcastAccessibility( ScAccWinFocusGotHint() );
1507 void ScPreview::LoseFocus()
1509 if (pViewShell && pViewShell->HasAccessibilityObjects())
1510 pViewShell->BroadcastAccessibility( ScAccWinFocusLostHint() );
1511 Window::LoseFocus();
1514 css::uno::Reference<css::accessibility::XAccessible> ScPreview::CreateAccessible()
1516 css::uno::Reference<css::accessibility::XAccessible> xAcc= GetAccessible(false);
1517 if (xAcc.is())
1519 return xAcc;
1522 ScAccessibleDocumentPagePreview* pAccessible =
1523 new ScAccessibleDocumentPagePreview( GetAccessibleParentWindow()->GetAccessible(), pViewShell );
1525 xAcc = pAccessible;
1526 SetAccessible(xAcc);
1527 pAccessible->Init();
1528 return xAcc;
1531 void ScPreview::DragMove( long nDragMovePos, PointerStyle nFlags )
1533 Fraction aPreviewZoom( nZoom, 100 );
1534 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
1535 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
1536 SetMapMode( aMMMode );
1537 long nPos = nDragMovePos;
1538 if( nFlags == PointerStyle::HSizeBar || nFlags == PointerStyle::HSplit )
1540 if( nDragMovePos != aButtonDownChangePoint.X() )
1542 DrawInvert( aButtonDownChangePoint.X(), nFlags );
1543 aButtonDownChangePoint.X() = nPos;
1544 DrawInvert( aButtonDownChangePoint.X(), nFlags );
1547 else if( nFlags == PointerStyle::VSizeBar )
1549 if( nDragMovePos != aButtonDownChangePoint.Y() )
1551 DrawInvert( aButtonDownChangePoint.Y(), nFlags );
1552 aButtonDownChangePoint.Y() = nPos;
1553 DrawInvert( aButtonDownChangePoint.Y(), nFlags );
1558 void ScPreview::DrawInvert( long nDragPos, PointerStyle nFlags )
1560 long nHeight = (long) lcl_GetDocPageSize( &pDocShell->GetDocument(), nTab ).Height();
1561 long nWidth = (long) lcl_GetDocPageSize( &pDocShell->GetDocument(), nTab ).Width();
1562 if( nFlags == PointerStyle::HSizeBar || nFlags == PointerStyle::HSplit )
1564 Rectangle aRect( nDragPos, -aOffset.Y(), nDragPos + 1,(long)( ( nHeight * HMM_PER_TWIPS ) - aOffset.Y()));
1565 Invert( aRect, InvertFlags::N50 );
1567 else if( nFlags == PointerStyle::VSizeBar )
1569 Rectangle aRect( -aOffset.X(), nDragPos,(long)( ( nWidth * HMM_PER_TWIPS ) - aOffset.X() ), nDragPos + 1 );
1570 Invert( aRect, InvertFlags::N50 );
1574 void ScPreview::SetSelectedTabs(const ScMarkData& rMark)
1576 maSelectedTabs = rMark.GetSelectedTabs();
1579 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */