fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / ui / view / preview.cxx
blob020f7400b267f67d1a5ec07bf4ac802d7c51f4ca
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 <boost/scoped_ptr.hpp>
69 // STATIC DATA -----------------------------------------------------------
71 #define SC_PREVIEW_SHADOWSIZE 2
73 static long lcl_GetDisplayStart( SCTAB nTab, ScDocument* pDoc, std::vector<long>& nPages )
75 long nDisplayStart = 0;
76 for (SCTAB i=0; i<nTab; i++)
78 if ( pDoc->NeedPageResetAfterTab(i) )
79 nDisplayStart = 0;
80 else
81 nDisplayStart += nPages[i];
83 return nDisplayStart;
86 ScPreview::ScPreview( vcl::Window* pParent, ScDocShell* pDocSh, ScPreviewShell* pViewSh ) :
87 Window( pParent ),
88 nPageNo( 0 ),
89 nZoom( 100 ),
90 nTabCount( 0 ),
91 nTabsTested( 0 ),
92 nPages(),
93 nFirstAttr(),
94 nTab( 0 ),
95 nTabPage( 0 ),
96 nTabStart( 0 ),
97 nDisplayStart( 0 ),
98 aDate( Date::SYSTEM ),
99 aTime( tools::Time::SYSTEM ),
100 nTotalPages( 0 ),
101 pLocationData( NULL ),
102 pDrawView( NULL ),
103 pDocShell( pDocSh ),
104 pViewShell( pViewSh ),
105 bInGetState( false ),
106 bValid( false ),
107 bStateValid( false ),
108 bLocationValid( false ),
109 bInPaint( false ),
110 bInSetZoom( false ),
111 bLeftRulerMove( false ),
112 bRightRulerMove( false ),
113 bTopRulerMove( false ),
114 bBottomRulerMove( false ),
115 bHeaderRulerMove( false ),
116 bFooterRulerMove( false ),
117 bLeftRulerChange( false ),
118 bRightRulerChange( false ),
119 bTopRulerChange( false ),
120 bBottomRulerChange( false ),
121 bHeaderRulerChange( false ),
122 bFooterRulerChange( false ),
123 bPageMargin ( false ),
124 bColRulerMove( false ),
125 mbHasEmptyRangeTable(false),
126 nLeftPosition( 0 ),
127 mnScale( 0 ),
128 nColNumberButttonDown( 0 ),
129 nHeaderHeight ( 0 ),
130 nFooterHeight ( 0 )
132 SetOutDevViewType( OUTDEV_VIEWTYPE_PRINTPREVIEW ); //#106611#
133 SetBackground();
135 SetHelpId( HID_SC_WIN_PREVIEW );
136 SetUniqueId( HID_SC_WIN_PREVIEW );
138 SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
140 for (SCCOL i=0; i<=MAXCOL; i++)
141 nRight[i] = 0; // initialized with actual positions when markers are drawn
144 ScPreview::~ScPreview()
146 disposeOnce();
149 void ScPreview::dispose()
151 delete pDrawView;
152 delete pLocationData;
153 vcl::Window::dispose();
156 void ScPreview::UpdateDrawView() // nTab must be right
158 ScDocument& rDoc = pDocShell->GetDocument();
159 ScDrawLayer* pModel = rDoc.GetDrawLayer(); // is not 0
161 // #114135#
162 if ( pModel )
164 SdrPage* pPage = pModel->GetPage(nTab);
165 if ( pDrawView && ( !pDrawView->GetSdrPageView() || pDrawView->GetSdrPageView()->GetPage() != pPage ) )
167 // die angezeigte Page der DrawView umzustellen (s.u.) funktioniert nicht ?!?
168 delete pDrawView;
169 pDrawView = NULL;
172 if ( !pDrawView ) // New Drawing?
174 pDrawView = new FmFormView( pModel, this );
176 // The DrawView takes over the Design-Mode from the Model
177 // (Settings "In opening Draftmode"), therefore to restore here
178 pDrawView->SetDesignMode( true );
179 pDrawView->SetPrintPreview( true );
180 pDrawView->ShowSdrPage(pPage);
183 else if ( pDrawView )
185 delete pDrawView; // for this Chart is not needed
186 pDrawView = NULL;
190 void ScPreview::TestLastPage()
192 if (nPageNo >= nTotalPages)
194 if (nTotalPages)
196 nPageNo = nTotalPages - 1;
197 nTab = static_cast<SCTAB>(nPages.size()) -1;
198 while (nTab > 0 && !nPages[nTab]) // not the last empty Table
199 --nTab;
200 OSL_ENSURE(0 < static_cast<SCTAB>(nPages.size()),"are all tables empty?");
201 nTabPage = nPages[nTab] - 1;
202 nTabStart = 0;
203 for (sal_uInt16 i=0; i<nTab; i++)
204 nTabStart += nPages[i];
206 ScDocument& rDoc = pDocShell->GetDocument();
207 nDisplayStart = lcl_GetDisplayStart( nTab, &rDoc, nPages );
209 else // empty Document
211 nTab = 0;
212 nPageNo = nTabPage = nTabStart = nDisplayStart = 0;
213 aState.nPrintTab = 0;
214 aState.nStartCol = aState.nEndCol = 0;
215 aState.nStartRow = aState.nEndRow = 0;
216 aState.nZoom = 0;
217 aState.nPagesX = aState.nPagesY = 0;
218 aState.nTabPages = aState.nTotalPages =
219 aState.nPageStart = aState.nDocPages = 0;
224 void ScPreview::CalcPages()
226 WaitObject aWait( this );
228 ScDocument& rDoc = pDocShell->GetDocument();
229 nTabCount = rDoc.GetTableCount();
231 SCTAB nStart = nTabsTested;
232 if (!bValid)
234 nStart = 0;
235 nTotalPages = 0;
236 nTabsTested = 0;
239 // update all pending row heights with a single progress bar,
240 // instead of a separate progress for each sheet from ScPrintFunc
241 pDocShell->UpdatePendingRowHeights( nTabCount-1, true );
243 // PrintOptions is passed to PrintFunc for SkipEmpty flag,
244 // but always all sheets are used (there is no selected sheet)
245 ScPrintOptions aOptions = SC_MOD()->GetPrintOptions();
247 while (nStart > static_cast<SCTAB>(nPages.size()))
248 nPages.push_back(0);
249 while (nStart > static_cast<SCTAB>(nFirstAttr.size()))
250 nFirstAttr.push_back(0);
252 for (SCTAB i=nStart; i<nTabCount; i++)
254 if ( i == static_cast<SCTAB>(nPages.size()))
255 nPages.push_back(0);
256 if ( i == static_cast<SCTAB>(nFirstAttr.size()))
257 nFirstAttr.push_back(0);
258 if (!aOptions.GetAllSheets() && maSelectedTabs.count(i) == 0)
260 nPages[i] = 0;
261 nFirstAttr[i] = 0;
262 continue;
265 long nAttrPage = i > 0 ? nFirstAttr[i-1] : 1;
267 long nThisStart = nTotalPages;
268 ScPrintFunc aPrintFunc( this, pDocShell, i, nAttrPage, 0, NULL, &aOptions );
269 long nThisTab = aPrintFunc.GetTotalPages();
270 if (!aPrintFunc.HasPrintRange())
271 mbHasEmptyRangeTable = true;
273 nPages[i] = nThisTab;
274 nTotalPages += nThisTab;
275 nFirstAttr[i] = aPrintFunc.GetFirstPageNo(); // to keep or from template
277 if (nPageNo>=nThisStart && nPageNo<nTotalPages)
279 nTab = i;
280 nTabPage = nPageNo - nThisStart;
281 nTabStart = nThisStart;
283 aPrintFunc.GetPrintState( aState );
284 aPageSize = aPrintFunc.GetPageSize();
288 nDisplayStart = lcl_GetDisplayStart( nTab, &rDoc, nPages );
290 if (nTabCount > nTabsTested)
291 nTabsTested = nTabCount;
293 TestLastPage();
295 aState.nDocPages = nTotalPages;
297 bValid = true;
298 bStateValid = true;
299 DoInvalidate();
302 void ScPreview::RecalcPages() // only nPageNo is changed
304 if (!bValid)
305 return; // then CalcPages is called
307 SCTAB nOldTab = nTab;
309 bool bDone = false;
310 while (nPageNo >= nTotalPages && nTabsTested < nTabCount)
312 CalcPages();
313 bDone = true;
316 if (!bDone)
318 long nPartPages = 0;
319 for (SCTAB i=0; i<nTabsTested && nTab < static_cast<SCTAB>(nPages.size()); i++)
321 long nThisStart = nPartPages;
322 nPartPages += nPages[i];
324 if (nPageNo>=nThisStart && nPageNo<nPartPages)
326 nTab = i;
327 nTabPage = nPageNo - nThisStart;
328 nTabStart = nThisStart;
332 ScDocument& rDoc = pDocShell->GetDocument();
333 nDisplayStart = lcl_GetDisplayStart( nTab, &rDoc, nPages );
336 TestLastPage(); // to test, if after last page
338 if ( nTab != nOldTab )
339 bStateValid = false;
341 DoInvalidate();
344 void ScPreview::DoPrint( ScPreviewLocationData* pFillLocation )
346 if (!bValid)
348 CalcPages();
349 RecalcPages();
350 UpdateDrawView(); // Spreedsheet eventually changes
353 Fraction aPreviewZoom( nZoom, 100 );
354 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
355 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
357 bool bDoPrint = ( pFillLocation == NULL );
358 bool bValidPage = ( nPageNo < nTotalPages );
360 ScModule* pScMod = SC_MOD();
361 const svtools::ColorConfig& rColorCfg = pScMod->GetColorConfig();
362 Color aBackColor( rColorCfg.GetColorValue(svtools::APPBACKGROUND).nColor );
364 if ( bDoPrint && ( aOffset.X() < 0 || aOffset.Y() < 0 ) && bValidPage )
366 SetMapMode( aMMMode );
367 SetLineColor();
368 SetFillColor(aBackColor);
370 Size aWinSize = GetOutputSize();
371 if ( aOffset.X() < 0 )
372 DrawRect(Rectangle( 0, 0, -aOffset.X(), aWinSize.Height() ));
373 if ( aOffset.Y() < 0 )
374 DrawRect(Rectangle( 0, 0, aWinSize.Width(), -aOffset.Y() ));
377 long nLeftMargin = 0;
378 long nRightMargin = 0;
379 long nTopMargin = 0;
380 long nBottomMargin = 0;
381 bool bHeaderOn = false;
382 bool bFooterOn = false;
384 ScDocument& rDoc = pDocShell->GetDocument();
385 bool bLayoutRTL = rDoc.IsLayoutRTL( nTab );
387 Size aLocalPageSize;
388 if ( bValidPage )
390 ScPrintOptions aOptions = pScMod->GetPrintOptions();
392 ScPrintFunc* pPrintFunc;
393 if (bStateValid)
394 pPrintFunc = new ScPrintFunc( this, pDocShell, aState, &aOptions );
395 else
396 pPrintFunc = new ScPrintFunc( this, pDocShell, nTab, nFirstAttr[nTab], nTotalPages, NULL, &aOptions );
398 pPrintFunc->SetOffset(aOffset);
399 pPrintFunc->SetManualZoom(nZoom);
400 pPrintFunc->SetDateTime(aDate,aTime);
401 pPrintFunc->SetClearFlag(true);
402 pPrintFunc->SetUseStyleColor( pScMod->GetAccessOptions().GetIsForPagePreviews() );
404 pPrintFunc->SetDrawView( pDrawView );
406 // MultiSelection for the one Page must produce something inconvenient
407 Range aPageRange( nPageNo+1, nPageNo+1 );
408 MultiSelection aPage( aPageRange );
409 aPage.SetTotalRange( Range(0,RANGE_MAX) );
410 aPage.Select( aPageRange );
412 long nPrinted = pPrintFunc->DoPrint( aPage, nTabStart, nDisplayStart, bDoPrint, pFillLocation );
413 OSL_ENSURE(nPrinted<=1, "was'n nu los?");
415 SetMapMode(aMMMode);
417 //init nLeftMargin ... in the ScPrintFunc::InitParam!!!
418 nLeftMargin = pPrintFunc->GetLeftMargin();
419 nRightMargin = pPrintFunc->GetRightMargin();
420 nTopMargin = pPrintFunc->GetTopMargin();
421 nBottomMargin = pPrintFunc->GetBottomMargin();
422 nHeaderHeight = pPrintFunc->GetHeader().nHeight;
423 nFooterHeight = pPrintFunc->GetFooter().nHeight;
424 bHeaderOn = pPrintFunc->GetHeader().bEnable;
425 bFooterOn = pPrintFunc->GetFooter().bEnable;
426 mnScale = pPrintFunc->GetZoom();
428 if ( bDoPrint && bPageMargin && pLocationData ) // don't make use of pLocationData while filling it
430 Rectangle aPixRect;
431 Rectangle aRectCellPosition;
432 Rectangle aRectPosition;
433 pLocationData->GetMainCellRange( aPageArea, aPixRect );
434 if( !bLayoutRTL )
436 pLocationData->GetCellPosition( aPageArea.aStart, aRectPosition );
437 nLeftPosition = aRectPosition.Left();
438 for( SCCOL i = aPageArea.aStart.Col(); i <= aPageArea.aEnd.Col(); i++ )
440 pLocationData->GetCellPosition( ScAddress( i,aPageArea.aStart.Row(),aPageArea.aStart.Tab()),aRectCellPosition );
441 nRight[i] = aRectCellPosition.Right();
444 else
446 pLocationData->GetCellPosition( aPageArea.aEnd, aRectPosition );
447 nLeftPosition = aRectPosition.Right()+1;
449 pLocationData->GetCellPosition( aPageArea.aStart,aRectCellPosition );
450 nRight[ aPageArea.aEnd.Col() ] = aRectCellPosition.Left();
451 for( SCCOL i = aPageArea.aEnd.Col(); i > aPageArea.aStart.Col(); i-- )
453 pLocationData->GetCellPosition( ScAddress( i,aPageArea.aEnd.Row(),aPageArea.aEnd.Tab()),aRectCellPosition );
454 nRight[ i-1 ] = nRight[ i ] + aRectCellPosition.Right() - aRectCellPosition.Left() + 1;
459 if (nPrinted) // if not, draw everything grey
461 aLocalPageSize = pPrintFunc->GetPageSize();
462 aLocalPageSize.Width() = (long) (aLocalPageSize.Width() * HMM_PER_TWIPS );
463 aLocalPageSize.Height() = (long) (aLocalPageSize.Height() * HMM_PER_TWIPS );
465 nLeftMargin = (long) ( nLeftMargin * HMM_PER_TWIPS );
466 nRightMargin = (long) ( nRightMargin * HMM_PER_TWIPS );
467 nTopMargin = (long) ( nTopMargin * HMM_PER_TWIPS );
468 nBottomMargin = (long) ( nBottomMargin * HMM_PER_TWIPS );
469 nHeaderHeight = (long) ( nHeaderHeight * HMM_PER_TWIPS * mnScale / 100 + nTopMargin );
470 nFooterHeight = (long) ( nFooterHeight * HMM_PER_TWIPS * mnScale / 100 + nBottomMargin );
473 if (!bStateValid)
475 pPrintFunc->GetPrintState( aState );
476 aState.nDocPages = nTotalPages;
477 bStateValid = true;
479 delete pPrintFunc;
482 if ( bDoPrint )
484 long nPageEndX = aLocalPageSize.Width() - aOffset.X();
485 long nPageEndY = aLocalPageSize.Height() - aOffset.Y();
486 if ( !bValidPage )
487 nPageEndX = nPageEndY = 0;
489 Size aWinSize = GetOutputSize();
490 Point aWinEnd( aWinSize.Width(), aWinSize.Height() );
491 bool bRight = nPageEndX <= aWinEnd.X();
492 bool bBottom = nPageEndY <= aWinEnd.Y();
494 if (!nTotalPages)
496 // There is no data to print. Print a friendly warning message and
497 // bail out.
499 SetMapMode(aMMMode);
501 // Draw background first.
502 SetLineColor();
503 SetFillColor(aBackColor);
504 DrawRect(Rectangle(0, 0, aWinEnd.X(), aWinEnd.Y()));
506 const ScPatternAttr& rDefPattern =
507 static_cast<const ScPatternAttr&>(
508 rDoc.GetPool()->GetDefaultItem(ATTR_PATTERN));
510 boost::scoped_ptr<ScEditEngineDefaulter> pEditEng(
511 new ScEditEngineDefaulter(EditEngine::CreatePool(), true));
513 pEditEng->SetRefMapMode(aMMMode);
514 SfxItemSet* pEditDefaults = new SfxItemSet( pEditEng->GetEmptyItemSet() );
515 rDefPattern.FillEditItemSet(pEditDefaults);
516 pEditEng->SetDefaults(pEditDefaults, true);
518 Color aTextColor(COL_LIGHTGRAY);
519 pEditDefaults->Put(SvxColorItem(aTextColor, EE_CHAR_COLOR));
521 OUString aEmptyMsg;
522 if (mbHasEmptyRangeTable)
523 aEmptyMsg = ScGlobal::GetRscString(STR_PRINT_PREVIEW_EMPTY_RANGE);
524 else
525 aEmptyMsg = ScGlobal::GetRscString(STR_PRINT_PREVIEW_NODATA);
527 long nHeight = 3000;
528 pEditEng->SetDefaultItem(SvxFontHeightItem(nHeight, 100, EE_CHAR_FONTHEIGHT));
529 pEditEng->SetDefaultItem(SvxFontHeightItem(nHeight, 100, EE_CHAR_FONTHEIGHT_CJK));
530 pEditEng->SetDefaultItem(SvxFontHeightItem(nHeight, 100, EE_CHAR_FONTHEIGHT_CTL));
532 pEditEng->SetText(aEmptyMsg);
534 Point aCenter(
535 (aWinEnd.X() - pEditEng->CalcTextWidth())/2,
536 (aWinEnd.Y() - pEditEng->GetTextHeight())/2);
538 pEditEng->Draw(this, aCenter);
540 return;
543 if( bPageMargin && bValidPage )
545 SetMapMode(aMMMode);
546 SetLineColor( COL_BLACK );
547 DrawInvert( (long)( nTopMargin - aOffset.Y() ), PointerStyle::VSizeBar );
548 DrawInvert( (long)(nPageEndY - nBottomMargin ), PointerStyle::VSizeBar );
549 DrawInvert( (long)( nLeftMargin - aOffset.X() ), PointerStyle::HSizeBar );
550 DrawInvert( (long)( nPageEndX - nRightMargin ) , PointerStyle::HSizeBar );
551 if( bHeaderOn )
553 DrawInvert( nHeaderHeight - aOffset.Y(), PointerStyle::VSizeBar );
555 if( bFooterOn )
557 DrawInvert( nPageEndY - nFooterHeight, PointerStyle::VSizeBar );
560 SetMapMode( MapMode( MAP_PIXEL ) );
561 for( int i= aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
563 Point aColumnTop = LogicToPixel( Point( 0, -aOffset.Y() ) ,aMMMode );
564 SetLineColor( COL_BLACK );
565 SetFillColor( COL_BLACK );
566 DrawRect( Rectangle( Point( nRight[i] - 2, aColumnTop.Y() ),Point( nRight[i] + 2 , 4 + aColumnTop.Y()) ));
567 DrawLine( Point( nRight[i], aColumnTop.Y() ), Point( nRight[i], 10 + aColumnTop.Y()) );
569 SetMapMode( aMMMode );
572 if (bRight || bBottom)
574 SetMapMode(aMMMode);
575 SetLineColor();
576 SetFillColor(aBackColor);
577 if (bRight)
578 DrawRect(Rectangle(nPageEndX,0, aWinEnd.X(),aWinEnd.Y()));
579 if (bBottom)
581 if (bRight)
582 DrawRect(Rectangle(0,nPageEndY, nPageEndX,aWinEnd.Y())); // Corner not duplicated
583 else
584 DrawRect(Rectangle(0,nPageEndY, aWinEnd.X(),aWinEnd.Y()));
588 if ( bValidPage )
590 Color aBorderColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
592 // draw border
594 if ( aOffset.X() <= 0 || aOffset.Y() <= 0 || bRight || bBottom )
596 SetLineColor( aBorderColor );
597 SetFillColor();
599 Rectangle aPixel( LogicToPixel( Rectangle( -aOffset.X(), -aOffset.Y(), nPageEndX, nPageEndY ) ) );
600 --aPixel.Right();
601 --aPixel.Bottom();
602 DrawRect( PixelToLogic( aPixel ) );
605 // draw shadow
607 SetLineColor();
608 SetFillColor( aBorderColor );
610 Rectangle aPixel;
612 aPixel = LogicToPixel( Rectangle( nPageEndX, -aOffset.Y(), nPageEndX, nPageEndY ) );
613 aPixel.Top() += SC_PREVIEW_SHADOWSIZE;
614 aPixel.Right() += SC_PREVIEW_SHADOWSIZE - 1;
615 aPixel.Bottom() += SC_PREVIEW_SHADOWSIZE - 1;
616 DrawRect( PixelToLogic( aPixel ) );
618 aPixel = LogicToPixel( Rectangle( -aOffset.X(), nPageEndY, nPageEndX, nPageEndY ) );
619 aPixel.Left() += SC_PREVIEW_SHADOWSIZE;
620 aPixel.Right() += SC_PREVIEW_SHADOWSIZE - 1;
621 aPixel.Bottom() += SC_PREVIEW_SHADOWSIZE - 1;
622 DrawRect( PixelToLogic( aPixel ) );
627 void ScPreview::Paint( vcl::RenderContext& /*rRenderContext*/, const Rectangle& /* rRect */ )
629 bool bWasInPaint = bInPaint; // nested calls shouldn't be necessary, but allow for now
630 bInPaint = true;
632 if (bPageMargin)
633 GetLocationData(); // fill location data for column positions
634 DoPrint( NULL );
635 pViewShell->UpdateScrollBars();
637 bInPaint = bWasInPaint;
640 void ScPreview::Command( const CommandEvent& rCEvt )
642 CommandEventId nCmd = rCEvt.GetCommand();
643 if ( nCmd == CommandEventId::Wheel || nCmd == CommandEventId::StartAutoScroll || nCmd == CommandEventId::AutoScroll )
645 bool bDone = pViewShell->ScrollCommand( rCEvt );
646 if (!bDone)
647 Window::Command(rCEvt);
649 else if ( nCmd == CommandEventId::ContextMenu )
650 SfxDispatcher::ExecutePopup();
651 else
652 Window::Command( rCEvt );
655 void ScPreview::KeyInput( const KeyEvent& rKEvt )
657 // The + and - keys can't be configured as accelerator entries, so they must be handled directly
658 // (in ScPreview, not ScPreviewShell -> only if the preview window has the focus)
660 const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
661 sal_uInt16 nKey = rKeyCode.GetCode();
662 bool bHandled = false;
663 if(!rKeyCode.GetModifier())
665 sal_uInt16 nSlot = 0;
666 switch(nKey)
668 case KEY_ADD: nSlot = SID_PREVIEW_ZOOMIN; break;
669 case KEY_ESCAPE: nSlot = ScViewUtil::IsFullScreen( *pViewShell ) ? SID_CANCEL : SID_PREVIEW_CLOSE; break;
670 case KEY_SUBTRACT: nSlot = SID_PREVIEW_ZOOMOUT; break;
672 if(nSlot)
674 bHandled = true;
675 pViewShell->GetViewFrame()->GetDispatcher()->Execute( nSlot, SfxCallMode::ASYNCHRON );
679 if ( !bHandled && !pViewShell->KeyInput(rKEvt) )
680 Window::KeyInput(rKEvt);
683 const ScPreviewLocationData& ScPreview::GetLocationData()
685 if ( !pLocationData )
687 pLocationData = new ScPreviewLocationData( &pDocShell->GetDocument(), this );
688 bLocationValid = false;
690 if ( !bLocationValid )
692 pLocationData->Clear();
693 DoPrint( pLocationData );
694 bLocationValid = true;
696 return *pLocationData;
699 void ScPreview::DataChanged(bool bNewTime)
701 if (bNewTime)
703 aDate = Date( Date::SYSTEM );
704 aTime = tools::Time( tools::Time::SYSTEM );
707 bValid = false;
708 InvalidateLocationData( SC_HINT_DATACHANGED );
709 Invalidate();
712 OUString ScPreview::GetPosString()
714 if (!bValid)
716 CalcPages();
717 UpdateDrawView(); // The table eventually changes
720 OUString aString = ScGlobal::GetRscString( STR_PAGE ) +
721 " " + OUString::number(nPageNo+1);
723 if (nTabsTested >= nTabCount)
724 aString += " / " + OUString::number(nTotalPages);
726 return aString;
729 void ScPreview::SetZoom(sal_uInt16 nNewZoom)
731 if (nNewZoom < 20)
732 nNewZoom = 20;
733 if (nNewZoom > 400)
734 nNewZoom = 400;
735 if (nNewZoom != nZoom)
737 nZoom = nNewZoom;
739 // apply new MapMode and call UpdateScrollBars to update aOffset
741 Fraction aPreviewZoom( nZoom, 100 );
742 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
743 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
744 SetMapMode( aMMMode );
746 bInSetZoom = true; // don't scroll during SetYOffset in UpdateScrollBars
747 pViewShell->UpdateNeededScrollBars(true);
748 bInSetZoom = false;
750 bStateValid = false;
751 InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
752 DoInvalidate();
753 Invalidate();
757 void ScPreview::SetPageNo( long nPage )
759 nPageNo = nPage;
760 RecalcPages();
761 UpdateDrawView(); // The table eventually changes
762 InvalidateLocationData( SC_HINT_DATACHANGED );
763 Invalidate();
766 long ScPreview::GetFirstPage(SCTAB nTabP)
768 SCTAB nDocTabCount = pDocShell->GetDocument().GetTableCount();
769 if (nTabP >= nDocTabCount)
770 nTabP = nDocTabCount-1;
772 long nPage = 0;
773 if (nTabP>0)
775 CalcPages();
776 if (nTabP >= static_cast<SCTAB>(nPages.size()) )
777 OSL_FAIL("nPages out ouf bounds, FIX IT");
778 UpdateDrawView(); // The table eventually changes
780 for (SCTAB i=0; i<nTabP; i++)
781 nPage += nPages[i];
783 // An empty Table on the previous Page
785 if ( nPages[nTabP]==0 && nPage > 0 )
786 --nPage;
789 return nPage;
792 static Size lcl_GetDocPageSize( ScDocument* pDoc, SCTAB nTab )
794 OUString aName = pDoc->GetPageStyle( nTab );
795 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
796 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aName, SFX_STYLE_FAMILY_PAGE );
797 if ( pStyleSheet )
799 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
800 return static_cast<const SvxSizeItem&>( rStyleSet.Get(ATTR_PAGE_SIZE)).GetSize();
802 else
804 OSL_FAIL( "PageStyle not found" );
805 return Size();
809 sal_uInt16 ScPreview::GetOptimalZoom(bool bWidthOnly)
811 double nWinScaleX = ScGlobal::nScreenPPTX / pDocShell->GetOutputFactor();
812 double nWinScaleY = ScGlobal::nScreenPPTY;
813 Size aWinSize = GetOutputSizePixel();
815 // desired margin is 0.25cm in default MapMode (like Writer),
816 // but some additional margin is introduced by integer scale values
817 // -> add only 0.10cm, so there is some margin in all cases.
818 Size aMarginSize( LogicToPixel( Size( 100, 100 ), MAP_100TH_MM ) );
819 aWinSize.Width() -= 2 * aMarginSize.Width();
820 aWinSize.Height() -= 2 * aMarginSize.Height();
822 Size aLocalPageSize = lcl_GetDocPageSize( &pDocShell->GetDocument(), nTab );
823 if ( aLocalPageSize.Width() && aLocalPageSize.Height() )
825 long nZoomX = (long) ( aWinSize.Width() * 100 / ( aLocalPageSize.Width() * nWinScaleX ));
826 long nZoomY = (long) ( aWinSize.Height() * 100 / ( aLocalPageSize.Height() * nWinScaleY ));
828 long nOptimal = nZoomX;
829 if (!bWidthOnly && nZoomY<nOptimal)
830 nOptimal = nZoomY;
832 if (nOptimal<20)
833 nOptimal = 20;
834 if (nOptimal>400)
835 nOptimal = 400;
837 return (sal_uInt16) nOptimal;
839 else
840 return nZoom;
843 void ScPreview::SetXOffset( long nX )
845 if ( aOffset.X() == nX )
846 return;
848 if (bValid)
850 long nDif = LogicToPixel(aOffset).X() - LogicToPixel(Point(nX,0)).X();
851 aOffset.X() = nX;
852 if (nDif && !bInSetZoom)
854 MapMode aOldMode = GetMapMode(); SetMapMode(MAP_PIXEL);
855 Scroll( nDif, 0 );
856 SetMapMode(aOldMode);
859 else
861 aOffset.X() = nX;
862 if (!bInSetZoom)
863 Invalidate();
865 InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
866 Invalidate();
869 void ScPreview::SetYOffset( long nY )
871 if ( aOffset.Y() == nY )
872 return;
874 if (bValid)
876 long nDif = LogicToPixel(aOffset).Y() - LogicToPixel(Point(0,nY)).Y();
877 aOffset.Y() = nY;
878 if (nDif && !bInSetZoom)
880 MapMode aOldMode = GetMapMode(); SetMapMode(MAP_PIXEL);
881 Scroll( 0, nDif );
882 SetMapMode(aOldMode);
885 else
887 aOffset.Y() = nY;
888 if (!bInSetZoom)
889 Invalidate();
891 InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
892 Invalidate();
895 void ScPreview::DoInvalidate()
897 // If the whole GetState of the shell is called
898 // The Invalidate must come behind asynchronously
900 if (bInGetState)
901 Application::PostUserEvent( LINK( this, ScPreview, InvalidateHdl ), NULL, true );
902 else
903 StaticInvalidate(); // Immediately
906 void ScPreview::StaticInvalidate()
908 // static method, because it's called asynchronously
909 // -> must use current viewframe
911 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
912 if (!pViewFrm)
913 return;
915 SfxBindings& rBindings = pViewFrm->GetBindings();
916 rBindings.Invalidate(SID_STATUS_DOCPOS);
917 rBindings.Invalidate(SID_ROWCOL_SELCOUNT);
918 rBindings.Invalidate(SID_STATUS_PAGESTYLE);
919 rBindings.Invalidate(SID_PREVIEW_PREVIOUS);
920 rBindings.Invalidate(SID_PREVIEW_NEXT);
921 rBindings.Invalidate(SID_PREVIEW_FIRST);
922 rBindings.Invalidate(SID_PREVIEW_LAST);
923 rBindings.Invalidate(SID_ATTR_ZOOM);
924 rBindings.Invalidate(SID_PREVIEW_ZOOMIN);
925 rBindings.Invalidate(SID_PREVIEW_ZOOMOUT);
926 rBindings.Invalidate(SID_PREVIEW_SCALINGFACTOR);
927 rBindings.Invalidate(SID_ATTR_ZOOMSLIDER);
930 IMPL_STATIC_LINK_NOARG( ScPreview, InvalidateHdl )
932 StaticInvalidate();
933 return 0;
936 void ScPreview::DataChanged( const DataChangedEvent& rDCEvt )
938 Window::DataChanged(rDCEvt);
940 if ( (rDCEvt.GetType() == DataChangedEventType::PRINTER) ||
941 (rDCEvt.GetType() == DataChangedEventType::DISPLAY) ||
942 (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
943 (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
944 ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
945 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
947 if ( rDCEvt.GetType() == DataChangedEventType::FONTS )
948 pDocShell->UpdateFontList();
950 // #i114518# Paint of form controls may modify the window's settings.
951 // Ignore the event if it is called from within Paint.
952 if ( !bInPaint )
954 if ( rDCEvt.GetType() == DataChangedEventType::SETTINGS &&
955 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
957 // scroll bar size may have changed
958 pViewShell->InvalidateBorder(); // calls OuterResizePixel
960 Invalidate();
961 InvalidateLocationData( SC_HINT_DATACHANGED );
966 void ScPreview::MouseButtonDown( const MouseEvent& rMEvt )
968 Fraction aPreviewZoom( nZoom, 100 );
969 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
970 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
972 aButtonDownChangePoint = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
973 aButtonDownPt = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
975 CaptureMouse();
977 if( rMEvt.IsLeft() && GetPointer() == PointerStyle::HSizeBar )
979 SetMapMode( aMMMode );
980 if( bLeftRulerChange )
982 DrawInvert( aButtonDownChangePoint.X(), PointerStyle::HSizeBar );
983 bLeftRulerMove = true;
984 bRightRulerMove = false;
986 else if( bRightRulerChange )
988 DrawInvert( aButtonDownChangePoint.X(), PointerStyle::HSizeBar );
989 bLeftRulerMove = false;
990 bRightRulerMove = true;
994 if( rMEvt.IsLeft() && GetPointer() == PointerStyle::VSizeBar )
996 SetMapMode( aMMMode );
997 if( bTopRulerChange )
999 DrawInvert( aButtonDownChangePoint.Y(), PointerStyle::VSizeBar );
1000 bTopRulerMove = true;
1001 bBottomRulerMove = false;
1003 else if( bBottomRulerChange )
1005 DrawInvert( aButtonDownChangePoint.Y(), PointerStyle::VSizeBar );
1006 bTopRulerMove = false;
1007 bBottomRulerMove = true;
1009 else if( bHeaderRulerChange )
1011 DrawInvert( aButtonDownChangePoint.Y(), PointerStyle::VSizeBar );
1012 bHeaderRulerMove = true;
1013 bFooterRulerMove = false;
1015 else if( bFooterRulerChange )
1017 DrawInvert( aButtonDownChangePoint.Y(), PointerStyle::VSizeBar );
1018 bHeaderRulerMove = false;
1019 bFooterRulerMove = true;
1023 if( rMEvt.IsLeft() && GetPointer() == PointerStyle::HSplit )
1025 Point aNowPt = rMEvt.GetPosPixel();
1026 SCCOL i = 0;
1027 for( i = aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
1029 if( aNowPt.X() < nRight[i] + 2 && aNowPt.X() > nRight[i] - 2 )
1031 nColNumberButttonDown = i;
1032 break;
1035 if( i == aPageArea.aEnd.Col()+1 )
1036 return;
1038 SetMapMode( aMMMode );
1039 if( nColNumberButttonDown == aPageArea.aStart.Col() )
1040 DrawInvert( PixelToLogic( Point( nLeftPosition, 0 ),aMMMode ).X() ,PointerStyle::HSplit );
1041 else
1042 DrawInvert( PixelToLogic( Point( nRight[ nColNumberButttonDown-1 ], 0 ),aMMMode ).X() ,PointerStyle::HSplit );
1044 DrawInvert( aButtonDownChangePoint.X(), PointerStyle::HSplit );
1045 bColRulerMove = true;
1049 void ScPreview::MouseButtonUp( const MouseEvent& rMEvt )
1051 Fraction aPreviewZoom( nZoom, 100 );
1052 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
1053 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
1055 aButtonUpPt = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
1057 long nWidth = (long) lcl_GetDocPageSize(&pDocShell->GetDocument(), nTab).Width();
1058 long nHeight = (long) lcl_GetDocPageSize(&pDocShell->GetDocument(), nTab).Height();
1060 if( rMEvt.IsLeft() && GetPointer() == PointerStyle::HSizeBar )
1062 SetPointer( Pointer( PointerStyle::Arrow ) );
1064 ScDocument& rDoc = pDocShell->GetDocument();
1065 OUString aOldName = rDoc.GetPageStyle( nTab );
1066 bool bUndo = rDoc.IsUndoEnabled();
1067 ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool();
1068 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aOldName, SFX_STYLE_FAMILY_PAGE );
1070 if ( pStyleSheet )
1072 bool bMoveRulerAction= true;
1073 ScStyleSaveData aOldData;
1074 if( bUndo )
1075 aOldData.InitFromStyle( pStyleSheet );
1077 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
1079 SvxLRSpaceItem aLRItem = static_cast<const SvxLRSpaceItem&>( rStyleSet.Get( ATTR_LRSPACE ) );
1081 if(( bLeftRulerChange || bRightRulerChange ) && ( aButtonUpPt.X() <= ( 0 - aOffset.X() ) || aButtonUpPt.X() > nWidth * HMM_PER_TWIPS - aOffset.X() ) )
1083 bMoveRulerAction = false;
1084 Invalidate(Rectangle(0, 0, 10000, 10000));
1086 else if( bLeftRulerChange && ( aButtonUpPt.X() / HMM_PER_TWIPS > nWidth - aLRItem.GetRight() - aOffset.X() / HMM_PER_TWIPS ) )
1088 bMoveRulerAction = false;
1089 Invalidate(Rectangle(0, 0, 10000, 10000));
1091 else if( bRightRulerChange && ( aButtonUpPt.X() / HMM_PER_TWIPS < aLRItem.GetLeft() - aOffset.X() / HMM_PER_TWIPS ) )
1093 bMoveRulerAction = false;
1094 Invalidate(Rectangle(0, 0, 10000, 10000));
1096 else if( aButtonDownPt.X() == aButtonUpPt.X() )
1098 bMoveRulerAction = false;
1099 DrawInvert( aButtonUpPt.X(), PointerStyle::HSizeBar );
1101 if( bMoveRulerAction )
1103 ScDocShellModificator aModificator( *pDocShell );
1104 if( bLeftRulerChange && bLeftRulerMove )
1106 aLRItem.SetLeft( (long)( aButtonUpPt.X() / HMM_PER_TWIPS + aOffset.X() / HMM_PER_TWIPS ));
1107 rStyleSet.Put( aLRItem );
1108 pDocShell->SetModified(true);
1110 else if( bRightRulerChange && bRightRulerMove )
1112 aLRItem.SetRight( (long)( nWidth - aButtonUpPt.X() / HMM_PER_TWIPS - aOffset.X() / HMM_PER_TWIPS ));
1113 rStyleSet.Put( aLRItem );
1114 pDocShell->SetModified(true);
1117 ScStyleSaveData aNewData;
1118 aNewData.InitFromStyle( pStyleSheet );
1119 if( bUndo )
1121 pDocShell->GetUndoManager()->AddUndoAction(
1122 new ScUndoModifyStyle( pDocShell, SFX_STYLE_FAMILY_PAGE,
1123 aOldData, aNewData ) );
1126 if ( ValidTab( nTab ) )
1128 ScPrintFunc aPrintFunc( this, pDocShell, nTab );
1129 aPrintFunc.UpdatePages();
1132 Rectangle aRect(0,0,10000,10000);
1133 Invalidate(aRect);
1134 aModificator.SetDocumentModified();
1135 bLeftRulerChange = false;
1136 bRightRulerChange = false;
1139 bLeftRulerMove = false;
1140 bRightRulerMove = false;
1143 if( rMEvt.IsLeft() && GetPointer() == PointerStyle::VSizeBar )
1145 SetPointer( PointerStyle::Arrow );
1147 bool bMoveRulerAction = true;
1148 if( ( bTopRulerChange || bBottomRulerChange || bHeaderRulerChange || bFooterRulerChange ) && ( aButtonUpPt.Y() <= ( 0 - aOffset.Y() ) || aButtonUpPt.Y() > nHeight * HMM_PER_TWIPS -aOffset.Y() ) )
1150 bMoveRulerAction = false;
1151 Invalidate(Rectangle(0, 0, 10000, 10000));
1153 else if( aButtonDownPt.Y() == aButtonUpPt.Y() )
1155 bMoveRulerAction = false;
1156 DrawInvert( aButtonUpPt.Y(), PointerStyle::VSizeBar );
1158 if( bMoveRulerAction )
1160 ScDocument& rDoc = pDocShell->GetDocument();
1161 bool bUndo = rDoc.IsUndoEnabled();
1162 ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool();
1163 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( rDoc.GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
1164 OSL_ENSURE( pStyleSheet, "PageStyle not found" );
1165 if ( pStyleSheet )
1167 ScDocShellModificator aModificator( *pDocShell );
1168 ScStyleSaveData aOldData;
1169 if( bUndo )
1170 aOldData.InitFromStyle( pStyleSheet );
1172 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
1174 SvxULSpaceItem aULItem = static_cast<const SvxULSpaceItem&>( rStyleSet.Get( ATTR_ULSPACE ) );
1176 if( bTopRulerMove && bTopRulerChange )
1178 aULItem.SetUpperValue( (sal_uInt16)( aButtonUpPt.Y() / HMM_PER_TWIPS + aOffset.Y() / HMM_PER_TWIPS ) );
1179 rStyleSet.Put( aULItem );
1180 pDocShell->SetModified(true);
1182 else if( bBottomRulerMove && bBottomRulerChange )
1184 aULItem.SetLowerValue( (sal_uInt16)( nHeight - aButtonUpPt.Y() / HMM_PER_TWIPS - aOffset.Y() / HMM_PER_TWIPS ) );
1185 rStyleSet.Put( aULItem );
1186 pDocShell->SetModified(true);
1188 else if( bHeaderRulerMove && bHeaderRulerChange )
1190 const SfxPoolItem* pItem = NULL;
1191 if ( rStyleSet.GetItemState( ATTR_PAGE_HEADERSET, false, &pItem ) == SfxItemState::SET )
1193 const SfxItemSet& pHeaderSet = static_cast<const SvxSetItem*>(pItem)->GetItemSet();
1194 Size aHeaderSize = static_cast<const SvxSizeItem&>(pHeaderSet.Get(ATTR_PAGE_SIZE)).GetSize();
1195 aHeaderSize.Height() = (long)( aButtonUpPt.Y() / HMM_PER_TWIPS + aOffset.Y() / HMM_PER_TWIPS - aULItem.GetUpper());
1196 aHeaderSize.Height() = aHeaderSize.Height() * 100 / mnScale;
1197 SvxSetItem aNewHeader( static_cast<const SvxSetItem&>(rStyleSet.Get(ATTR_PAGE_HEADERSET)) );
1198 aNewHeader.GetItemSet().Put( SvxSizeItem( ATTR_PAGE_SIZE, aHeaderSize ) );
1199 rStyleSet.Put( aNewHeader );
1200 pDocShell->SetModified(true);
1203 else if( bFooterRulerMove && bFooterRulerChange )
1205 const SfxPoolItem* pItem = NULL;
1206 if( rStyleSet.GetItemState( ATTR_PAGE_FOOTERSET, false, &pItem ) == SfxItemState::SET )
1208 const SfxItemSet& pFooterSet = static_cast<const SvxSetItem*>(pItem)->GetItemSet();
1209 Size aFooterSize = static_cast<const SvxSizeItem&>(pFooterSet.Get(ATTR_PAGE_SIZE)).GetSize();
1210 aFooterSize.Height() = (long)( nHeight - aButtonUpPt.Y() / HMM_PER_TWIPS - aOffset.Y() / HMM_PER_TWIPS - aULItem.GetLower() );
1211 aFooterSize.Height() = aFooterSize.Height() * 100 / mnScale;
1212 SvxSetItem aNewFooter( static_cast<const SvxSetItem&>(rStyleSet.Get(ATTR_PAGE_FOOTERSET)) );
1213 aNewFooter.GetItemSet().Put( SvxSizeItem( ATTR_PAGE_SIZE, aFooterSize ) );
1214 rStyleSet.Put( aNewFooter );
1215 pDocShell->SetModified(true);
1219 ScStyleSaveData aNewData;
1220 aNewData.InitFromStyle( pStyleSheet );
1221 if( bUndo )
1223 pDocShell->GetUndoManager()->AddUndoAction(
1224 new ScUndoModifyStyle( pDocShell, SFX_STYLE_FAMILY_PAGE,
1225 aOldData, aNewData ) );
1228 if ( ValidTab( nTab ) )
1230 ScPrintFunc aPrintFunc( this, pDocShell, nTab );
1231 aPrintFunc.UpdatePages();
1234 Rectangle aRect(0, 0, 10000, 10000);
1235 Invalidate(aRect);
1236 aModificator.SetDocumentModified();
1237 bTopRulerChange = false;
1238 bBottomRulerChange = false;
1239 bHeaderRulerChange = false;
1240 bFooterRulerChange = false;
1243 bTopRulerMove = false;
1244 bBottomRulerMove = false;
1245 bHeaderRulerMove = false;
1246 bFooterRulerMove = false;
1248 if( rMEvt.IsLeft() && GetPointer() == PointerStyle::HSplit )
1250 SetPointer(PointerStyle::Arrow);
1251 ScDocument& rDoc = pDocShell->GetDocument();
1252 bool bLayoutRTL = rDoc.IsLayoutRTL( nTab );
1253 bool bMoveRulerAction = true;
1254 if( aButtonDownPt.X() == aButtonUpPt.X() )
1256 bMoveRulerAction = false;
1257 if( nColNumberButttonDown == aPageArea.aStart.Col() )
1258 DrawInvert( PixelToLogic( Point( nLeftPosition, 0 ),aMMMode ).X() ,PointerStyle::HSplit );
1259 else
1260 DrawInvert( PixelToLogic( Point( nRight[ nColNumberButttonDown-1 ], 0 ),aMMMode ).X() ,PointerStyle::HSplit );
1261 DrawInvert( aButtonUpPt.X(), PointerStyle::HSplit );
1263 if( bMoveRulerAction )
1265 long nNewColWidth = 0;
1266 std::vector<sc::ColRowSpan> aCols(1, sc::ColRowSpan(nColNumberButttonDown,nColNumberButttonDown));
1268 if( !bLayoutRTL )
1270 nNewColWidth = (long) ( PixelToLogic( Point( rMEvt.GetPosPixel().X() - nRight[ nColNumberButttonDown ], 0), aMMMode ).X() / HMM_PER_TWIPS ) * 100 / mnScale;
1271 nNewColWidth += pDocShell->GetDocument().GetColWidth( nColNumberButttonDown, nTab );
1273 else
1276 nNewColWidth = (long) ( PixelToLogic( Point( nRight[ nColNumberButttonDown ] - rMEvt.GetPosPixel().X(), 0), aMMMode ).X() / HMM_PER_TWIPS ) * 100 / mnScale;
1277 nNewColWidth += pDocShell->GetDocument().GetColWidth( nColNumberButttonDown, nTab );
1280 if( nNewColWidth >= 0 )
1282 pDocShell->GetDocFunc().SetWidthOrHeight(
1283 true, aCols, nTab, SC_SIZE_DIRECT, (sal_uInt16)nNewColWidth, true, true);
1284 pDocShell->SetModified(true);
1286 if ( ValidTab( nTab ) )
1288 ScPrintFunc aPrintFunc( this, pDocShell, nTab );
1289 aPrintFunc.UpdatePages();
1291 Rectangle aRect(0, 0, 10000, 10000);
1292 Invalidate(aRect);
1294 bColRulerMove = false;
1296 ReleaseMouse();
1299 void ScPreview::MouseMove( const MouseEvent& rMEvt )
1301 Fraction aPreviewZoom( nZoom, 100 );
1302 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
1303 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
1304 Point aMouseMovePoint = PixelToLogic( rMEvt.GetPosPixel(), aMMMode );
1306 long nLeftMargin = 0;
1307 long nRightMargin = 0;
1308 long nTopMargin = 0;
1309 long nBottomMargin = 0;
1311 long nWidth = (long) lcl_GetDocPageSize(&pDocShell->GetDocument(), nTab).Width();
1312 long nHeight = (long) lcl_GetDocPageSize(&pDocShell->GetDocument(), nTab).Height();
1314 if ( nPageNo < nTotalPages )
1316 ScPrintOptions aOptions = SC_MOD()->GetPrintOptions();
1318 ScPrintFunc* pPrintFunc;
1320 if (bStateValid)
1321 pPrintFunc = new ScPrintFunc( this, pDocShell, aState, &aOptions );
1322 else
1323 pPrintFunc = new ScPrintFunc( this, pDocShell, nTab, nFirstAttr[nTab], nTotalPages, NULL, &aOptions );
1325 nLeftMargin = (long)( pPrintFunc->GetLeftMargin() * HMM_PER_TWIPS - aOffset.X() );
1326 nRightMargin = (long)( pPrintFunc->GetRightMargin() * HMM_PER_TWIPS );
1327 nRightMargin = (long)( nWidth * HMM_PER_TWIPS - nRightMargin - aOffset.X() );
1328 nTopMargin = (long)( pPrintFunc->GetTopMargin() * HMM_PER_TWIPS - aOffset.Y() );
1329 nBottomMargin = (long)( pPrintFunc->GetBottomMargin() * HMM_PER_TWIPS );
1330 nBottomMargin = (long)( nHeight * HMM_PER_TWIPS - nBottomMargin - aOffset.Y() );
1331 if( mnScale > 0 )
1333 nHeaderHeight = (long)( nTopMargin + pPrintFunc->GetHeader().nHeight * HMM_PER_TWIPS * mnScale / 100 );
1334 nFooterHeight = (long)( nBottomMargin - pPrintFunc->GetFooter().nHeight * HMM_PER_TWIPS * mnScale / 100 );
1336 else
1338 nHeaderHeight = (long)( nTopMargin + pPrintFunc->GetHeader().nHeight * HMM_PER_TWIPS );
1339 nFooterHeight = (long)( nBottomMargin - pPrintFunc->GetFooter().nHeight * HMM_PER_TWIPS );
1341 delete pPrintFunc;
1344 Point aPixPt( rMEvt.GetPosPixel() );
1345 Point aLeftTop = LogicToPixel( Point( nLeftMargin, -aOffset.Y() ) , aMMMode );
1346 Point aLeftBottom = LogicToPixel( Point( nLeftMargin ,(long)(nHeight * HMM_PER_TWIPS - aOffset.Y()) ), aMMMode );
1347 Point aRightTop = LogicToPixel( Point( nRightMargin, -aOffset.Y() ), aMMMode );
1348 Point aTopLeft = LogicToPixel( Point( -aOffset.X(), nTopMargin ), aMMMode );
1349 Point aTopRight = LogicToPixel( Point( (long)(nWidth * HMM_PER_TWIPS - aOffset.X()), nTopMargin ), aMMMode );
1350 Point aBottomLeft = LogicToPixel( Point( -aOffset.X(), nBottomMargin ), aMMMode );
1351 Point aHeaderLeft = LogicToPixel( Point( -aOffset.X(), nHeaderHeight ), aMMMode );
1352 Point aFooderLeft = LogicToPixel( Point( -aOffset.X(), nFooterHeight ), aMMMode );
1354 bool bOnColRulerChange = false;
1356 for( SCCOL i=aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
1358 Point aColumnTop = LogicToPixel( Point( 0, -aOffset.Y() ) ,aMMMode );
1359 Point aColumnBottom = LogicToPixel( Point( 0, (long)( nHeight * HMM_PER_TWIPS - aOffset.Y()) ), aMMMode );
1360 if( aPixPt.X() < ( nRight[i] + 2 ) && ( aPixPt.X() > ( nRight[i] - 2 ) ) && ( aPixPt.X() < aRightTop.X() ) && ( aPixPt.X() > aLeftTop.X() )
1361 && ( aPixPt.Y() > aColumnTop.Y() ) && ( aPixPt.Y() < aColumnBottom.Y() ) && !bLeftRulerMove && !bRightRulerMove
1362 && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1364 bOnColRulerChange = true;
1365 if( !rMEvt.GetButtons() && GetPointer() == PointerStyle::HSplit )
1366 nColNumberButttonDown = i;
1367 break;
1371 if( aPixPt.X() < ( aLeftTop.X() + 2 ) && aPixPt.X() > ( aLeftTop.X() - 2 ) && !bRightRulerMove )
1373 bLeftRulerChange = true;
1374 bRightRulerChange = false;
1376 else if( aPixPt.X() < ( aRightTop.X() + 2 ) && aPixPt.X() > ( aRightTop.X() - 2 ) && !bLeftRulerMove )
1378 bLeftRulerChange = false;
1379 bRightRulerChange = true;
1381 else if( aPixPt.Y() < ( aTopLeft.Y() + 2 ) && aPixPt.Y() > ( aTopLeft.Y() - 2 ) && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1383 bTopRulerChange = true;
1384 bBottomRulerChange = false;
1385 bHeaderRulerChange = false;
1386 bFooterRulerChange = false;
1388 else if( aPixPt.Y() < ( aBottomLeft.Y() + 2 ) && aPixPt.Y() > ( aBottomLeft.Y() - 2 ) && !bTopRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1390 bTopRulerChange = false;
1391 bBottomRulerChange = true;
1392 bHeaderRulerChange = false;
1393 bFooterRulerChange = false;
1395 else if( aPixPt.Y() < ( aHeaderLeft.Y() + 2 ) && aPixPt.Y() > ( aHeaderLeft.Y() - 2 ) && !bTopRulerMove && !bBottomRulerMove && !bFooterRulerMove )
1397 bTopRulerChange = false;
1398 bBottomRulerChange = false;
1399 bHeaderRulerChange = true;
1400 bFooterRulerChange = false;
1402 else if( aPixPt.Y() < ( aFooderLeft.Y() + 2 ) && aPixPt.Y() > ( aFooderLeft.Y() - 2 ) && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove )
1404 bTopRulerChange = false;
1405 bBottomRulerChange = false;
1406 bHeaderRulerChange = false;
1407 bFooterRulerChange = true;
1410 if( bPageMargin )
1412 if(( (aPixPt.X() < ( aLeftTop.X() + 2 ) && aPixPt.X() > ( aLeftTop.X() - 2 )) || bLeftRulerMove ||
1413 ( aPixPt.X() < ( aRightTop.X() + 2 ) && aPixPt.X() > ( aRightTop.X() - 2 ) ) || bRightRulerMove || bOnColRulerChange || bColRulerMove )
1414 && aPixPt.Y() > aLeftTop.Y() && aPixPt.Y() < aLeftBottom.Y() )
1416 if( bOnColRulerChange || bColRulerMove )
1418 SetPointer( Pointer( PointerStyle::HSplit ) );
1419 if( bColRulerMove )
1421 if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
1422 DragMove( aMouseMovePoint.X(), PointerStyle::HSplit );
1425 else
1427 if( bLeftRulerChange && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1429 SetPointer( Pointer( PointerStyle::HSizeBar ) );
1430 if( bLeftRulerMove )
1432 if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
1433 DragMove( aMouseMovePoint.X(), PointerStyle::HSizeBar );
1436 else if( bRightRulerChange && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1438 SetPointer( Pointer( PointerStyle::HSizeBar ) );
1439 if( bRightRulerMove )
1441 if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
1442 DragMove( aMouseMovePoint.X(), PointerStyle::HSizeBar );
1447 else
1449 if( ( ( aPixPt.Y() < ( aTopLeft.Y() + 2 ) && aPixPt.Y() > ( aTopLeft.Y() - 2 ) ) || bTopRulerMove ||
1450 ( aPixPt.Y() < ( aBottomLeft.Y() + 2 ) && aPixPt.Y() > ( aBottomLeft.Y() - 2 ) ) || bBottomRulerMove ||
1451 ( aPixPt.Y() < ( aHeaderLeft.Y() + 2 ) && aPixPt.Y() > ( aHeaderLeft.Y() - 2 ) ) || bHeaderRulerMove ||
1452 ( aPixPt.Y() < ( aFooderLeft.Y() + 2 ) && aPixPt.Y() > ( aFooderLeft.Y() - 2 ) ) || bFooterRulerMove )
1453 && aPixPt.X() > aTopLeft.X() && aPixPt.X() < aTopRight.X() )
1455 if( bTopRulerChange )
1457 SetPointer( Pointer( PointerStyle::VSizeBar ) );
1458 if( bTopRulerMove )
1460 if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
1461 DragMove( aMouseMovePoint.Y(), PointerStyle::VSizeBar );
1464 else if( bBottomRulerChange )
1466 SetPointer( Pointer( PointerStyle::VSizeBar ) );
1467 if( bBottomRulerMove )
1469 if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
1470 DragMove( aMouseMovePoint.Y(), PointerStyle::VSizeBar );
1473 else if( bHeaderRulerChange )
1475 SetPointer( Pointer( PointerStyle::VSizeBar ) );
1476 if( bHeaderRulerMove )
1478 if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
1479 DragMove( aMouseMovePoint.Y(), PointerStyle::VSizeBar );
1482 else if( bFooterRulerChange )
1484 SetPointer( Pointer( PointerStyle::VSizeBar ) );
1485 if( bFooterRulerMove )
1487 if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
1488 DragMove( aMouseMovePoint.Y(), PointerStyle::VSizeBar );
1492 else
1493 SetPointer( Pointer( PointerStyle::Arrow ) );
1498 void ScPreview::InvalidateLocationData(sal_uLong nId)
1500 bLocationValid = false;
1501 if (pViewShell->HasAccessibilityObjects())
1502 pViewShell->BroadcastAccessibility( SfxSimpleHint( nId ) );
1505 void ScPreview::GetFocus()
1507 Window::GetFocus();
1508 if (pViewShell && pViewShell->HasAccessibilityObjects())
1509 pViewShell->BroadcastAccessibility( ScAccWinFocusGotHint(GetAccessible()) );
1512 void ScPreview::LoseFocus()
1514 if (pViewShell && pViewShell->HasAccessibilityObjects())
1515 pViewShell->BroadcastAccessibility( ScAccWinFocusLostHint(GetAccessible()) );
1516 Window::LoseFocus();
1519 com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible> ScPreview::CreateAccessible()
1521 com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible> xAcc= GetAccessible(false);
1522 if (xAcc.is())
1524 return xAcc;
1527 ScAccessibleDocumentPagePreview* pAccessible =
1528 new ScAccessibleDocumentPagePreview( GetAccessibleParentWindow()->GetAccessible(), pViewShell );
1530 xAcc = pAccessible;
1531 SetAccessible(xAcc);
1532 pAccessible->Init();
1533 return xAcc;
1536 void ScPreview::DragMove( long nDragMovePos, PointerStyle nFlags )
1538 Fraction aPreviewZoom( nZoom, 100 );
1539 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
1540 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
1541 SetMapMode( aMMMode );
1542 long nPos = nDragMovePos;
1543 if( nFlags == PointerStyle::HSizeBar || nFlags == PointerStyle::HSplit )
1545 if( nDragMovePos != aButtonDownChangePoint.X() )
1547 DrawInvert( aButtonDownChangePoint.X(), nFlags );
1548 aButtonDownChangePoint.X() = nPos;
1549 DrawInvert( aButtonDownChangePoint.X(), nFlags );
1552 else if( nFlags == PointerStyle::VSizeBar )
1554 if( nDragMovePos != aButtonDownChangePoint.Y() )
1556 DrawInvert( aButtonDownChangePoint.Y(), nFlags );
1557 aButtonDownChangePoint.Y() = nPos;
1558 DrawInvert( aButtonDownChangePoint.Y(), nFlags );
1563 void ScPreview::DrawInvert( long nDragPos, PointerStyle nFlags )
1565 long nHeight = (long) lcl_GetDocPageSize( &pDocShell->GetDocument(), nTab ).Height();
1566 long nWidth = (long) lcl_GetDocPageSize( &pDocShell->GetDocument(), nTab ).Width();
1567 if( nFlags == PointerStyle::HSizeBar || nFlags == PointerStyle::HSplit )
1569 Rectangle aRect( nDragPos, -aOffset.Y(), nDragPos + 1,(long)( ( nHeight * HMM_PER_TWIPS ) - aOffset.Y()));
1570 Invert( aRect,INVERT_50 );
1572 else if( nFlags == PointerStyle::VSizeBar )
1574 Rectangle aRect( -aOffset.X(), nDragPos,(long)( ( nWidth * HMM_PER_TWIPS ) - aOffset.X() ), nDragPos + 1 );
1575 Invert( aRect,INVERT_50 );
1579 void ScPreview::SetSelectedTabs(const ScMarkData& rMark)
1581 maSelectedTabs = rMark.GetSelectedTabs();
1584 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */