Bump version to 4.3-4
[LibreOffice.git] / sc / source / ui / view / preview.cxx
blob3380ebc4893d6e8f6abc977849f8fbdf21a05485
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>
24 #include <svtools/colorcfg.hxx>
25 #include <svx/fmview.hxx>
26 #include <editeng/sizeitem.hxx>
27 #include <svx/svdpagv.hxx>
28 #include <sfx2/bindings.hxx>
29 #include <sfx2/viewfrm.hxx>
30 #include <sfx2/dispatch.hxx>
31 #include <svtools/accessibilityoptions.hxx>
32 #include <svl/itemset.hxx>
33 #include <tools/multisel.hxx>
34 #include <vcl/waitobj.hxx>
35 #include <vcl/settings.hxx>
37 #include "preview.hxx"
38 #include "prevwsh.hxx"
39 #include "prevloc.hxx"
40 #include "docsh.hxx"
41 #include "docfunc.hxx"
42 #include "printfun.hxx"
43 #include "printopt.hxx"
44 #include "stlpool.hxx"
45 #include "undostyl.hxx"
46 #include "drwlayer.hxx"
47 #include "scmod.hxx"
48 #include "markdata.hxx"
49 #include "globstr.hrc"
50 #include "sc.hrc"
51 #include "AccessibleDocumentPagePreview.hxx"
52 #include <vcl/lineinfo.hxx>
53 #include <svx/algitem.hxx>
54 #include <editeng/lrspitem.hxx>
55 #include <editeng/ulspitem.hxx>
56 #include <editeng/colritem.hxx>
57 #include <editeng/fhgtitem.hxx>
58 #include "attrib.hxx"
59 #include "pagepar.hxx"
60 #include <com/sun/star/accessibility/XAccessible.hpp>
61 #include "AccessibilityHints.hxx"
62 #include <vcl/svapp.hxx>
63 #include "viewutil.hxx"
64 #include <columnspanset.hxx>
65 #include <docpool.hxx>
66 #include <patattr.hxx>
68 #include <boost/scoped_ptr.hpp>
70 // STATIC DATA -----------------------------------------------------------
72 #define SC_PREVIEW_SHADOWSIZE 2
74 static long lcl_GetDisplayStart( SCTAB nTab, ScDocument* pDoc, std::vector<long>& nPages )
76 long nDisplayStart = 0;
77 for (SCTAB i=0; i<nTab; i++)
79 if ( pDoc->NeedPageResetAfterTab(i) )
80 nDisplayStart = 0;
81 else
82 nDisplayStart += nPages[i];
84 return nDisplayStart;
88 ScPreview::ScPreview( Window* pParent, ScDocShell* pDocSh, ScPreviewShell* pViewSh ) :
89 Window( pParent ),
90 nPageNo( 0 ),
91 nZoom( 100 ),
92 nTabsTested( 0 ),
93 nPages(),
94 nFirstAttr(),
95 nTab( 0 ),
96 nTabStart( 0 ),
97 nDisplayStart( 0 ),
98 aDate( Date::SYSTEM ),
99 aTime( 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 mnScale( 0 ),
127 nColNumberButttonDown( 0 ),
128 nHeaderHeight ( 0 ),
129 nFooterHeight ( 0 )
131 SetOutDevViewType( OUTDEV_VIEWTYPE_PRINTPREVIEW ); //#106611#
132 SetBackground();
134 SetHelpId( HID_SC_WIN_PREVIEW );
135 SetUniqueId( HID_SC_WIN_PREVIEW );
137 SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
139 for (SCCOL i=0; i<=MAXCOL; i++)
140 nRight[i] = 0; // initialized with actual positions when markers are drawn
144 ScPreview::~ScPreview()
146 delete pDrawView;
147 delete pLocationData;
150 void ScPreview::UpdateDrawView() // nTab must be right
152 ScDocument* pDoc = pDocShell->GetDocument();
153 ScDrawLayer* pModel = pDoc->GetDrawLayer(); // is not 0
155 // #114135#
156 if ( pModel )
158 SdrPage* pPage = pModel->GetPage(nTab);
159 if ( pDrawView && ( !pDrawView->GetSdrPageView() || pDrawView->GetSdrPageView()->GetPage() != pPage ) )
161 // die angezeigte Page der DrawView umzustellen (s.u.) funktioniert nicht ?!?
162 delete pDrawView;
163 pDrawView = NULL;
166 if ( !pDrawView ) // New Drawing?
168 pDrawView = new FmFormView( pModel, this );
170 // The DrawView takes over the Design-Mode from the Model
171 // (Settings "In opening Draftmode"), therefore to restore here
172 pDrawView->SetDesignMode( true );
173 pDrawView->SetPrintPreview( true );
174 pDrawView->ShowSdrPage(pPage);
177 else if ( pDrawView )
179 delete pDrawView; // for this Chart is not needed
180 pDrawView = NULL;
185 void ScPreview::TestLastPage()
187 if (nPageNo >= nTotalPages)
189 if (nTotalPages)
191 nPageNo = nTotalPages - 1;
192 nTab = static_cast<SCTAB>(nPages.size()) -1;
193 while (nTab > 0 && !nPages[nTab]) // not the last empty Table
194 --nTab;
195 OSL_ENSURE(0 < static_cast<SCTAB>(nPages.size()),"are all tables empty?");
196 nTabPage = nPages[nTab] - 1;
197 nTabStart = 0;
198 for (sal_uInt16 i=0; i<nTab; i++)
199 nTabStart += nPages[i];
201 ScDocument* pDoc = pDocShell->GetDocument();
202 nDisplayStart = lcl_GetDisplayStart( nTab, pDoc, nPages );
204 else // empty Document
206 nTab = 0;
207 nPageNo = nTabPage = nTabStart = nDisplayStart = 0;
208 aState.nPrintTab = 0;
209 aState.nStartCol = aState.nEndCol = 0;
210 aState.nStartRow = aState.nEndRow = 0;
211 aState.nZoom = 0;
212 aState.nPagesX = aState.nPagesY = 0;
213 aState.nTabPages = aState.nTotalPages =
214 aState.nPageStart = aState.nDocPages = 0;
220 void ScPreview::CalcPages()
222 WaitObject aWait( this );
224 ScDocument* pDoc = pDocShell->GetDocument();
225 nTabCount = pDoc->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, NULL, &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, pDoc, nPages );
286 if (nTabCount > nTabsTested)
287 nTabsTested = nTabCount;
289 TestLastPage();
291 aState.nDocPages = nTotalPages;
293 bValid = true;
294 bStateValid = true;
295 DoInvalidate();
299 void ScPreview::RecalcPages() // only nPageNo is changed
301 if (!bValid)
302 return; // then CalcPages is called
304 SCTAB nOldTab = nTab;
306 bool bDone = false;
307 while (nPageNo >= nTotalPages && nTabsTested < nTabCount)
309 CalcPages();
310 bDone = true;
313 if (!bDone)
315 long nPartPages = 0;
316 for (SCTAB i=0; i<nTabsTested && nTab < static_cast<SCTAB>(nPages.size()); i++)
318 long nThisStart = nPartPages;
319 nPartPages += nPages[i];
321 if (nPageNo>=nThisStart && nPageNo<nPartPages)
323 nTab = i;
324 nTabPage = nPageNo - nThisStart;
325 nTabStart = nThisStart;
329 ScDocument* pDoc = pDocShell->GetDocument();
330 nDisplayStart = lcl_GetDisplayStart( nTab, pDoc, nPages );
333 TestLastPage(); // to test, if after last page
335 if ( nTab != nOldTab )
336 bStateValid = false;
338 DoInvalidate();
342 void ScPreview::DoPrint( ScPreviewLocationData* pFillLocation )
344 if (!bValid)
346 CalcPages();
347 RecalcPages();
348 UpdateDrawView(); // Spreedsheet eventually changes
351 Fraction aPreviewZoom( nZoom, 100 );
352 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
353 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
355 bool bDoPrint = ( pFillLocation == NULL );
356 bool bValidPage = ( nPageNo < nTotalPages );
358 ScModule* pScMod = SC_MOD();
359 const svtools::ColorConfig& rColorCfg = pScMod->GetColorConfig();
360 Color aBackColor( rColorCfg.GetColorValue(svtools::APPBACKGROUND).nColor );
362 if ( bDoPrint && ( aOffset.X() < 0 || aOffset.Y() < 0 ) && bValidPage )
364 SetMapMode( aMMMode );
365 SetLineColor();
366 SetFillColor(aBackColor);
368 Size aWinSize = GetOutputSize();
369 if ( aOffset.X() < 0 )
370 DrawRect(Rectangle( 0, 0, -aOffset.X(), aWinSize.Height() ));
371 if ( aOffset.Y() < 0 )
372 DrawRect(Rectangle( 0, 0, aWinSize.Width(), -aOffset.Y() ));
375 long nLeftMargin = 0;
376 long nRightMargin = 0;
377 long nTopMargin = 0;
378 long nBottomMargin = 0;
379 bool bHeaderOn = false;
380 bool bFooterOn = false;
382 ScDocument* pDoc = pDocShell->GetDocument();
383 bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
385 Size aLocalPageSize;
386 if ( bValidPage )
388 ScPrintOptions aOptions = pScMod->GetPrintOptions();
390 ScPrintFunc* pPrintFunc;
391 if (bStateValid)
392 pPrintFunc = new ScPrintFunc( this, pDocShell, aState, &aOptions );
393 else
394 pPrintFunc = new ScPrintFunc( this, pDocShell, nTab, nFirstAttr[nTab], nTotalPages, NULL, &aOptions );
396 pPrintFunc->SetOffset(aOffset);
397 pPrintFunc->SetManualZoom(nZoom);
398 pPrintFunc->SetDateTime(aDate,aTime);
399 pPrintFunc->SetClearFlag(true);
400 pPrintFunc->SetUseStyleColor( pScMod->GetAccessOptions().GetIsForPagePreviews() );
402 pPrintFunc->SetDrawView( pDrawView );
404 // MultiSelection for the one Page must produce something inconvenient
405 Range aPageRange( nPageNo+1, nPageNo+1 );
406 MultiSelection aPage( aPageRange );
407 aPage.SetTotalRange( Range(0,RANGE_MAX) );
408 aPage.Select( aPageRange );
410 long nPrinted = pPrintFunc->DoPrint( aPage, nTabStart, nDisplayStart, bDoPrint, pFillLocation );
411 OSL_ENSURE(nPrinted<=1, "was'n nu los?");
413 SetMapMode(aMMMode);
415 //init nLeftMargin ... in the ScPrintFunc::InitParam!!!
416 nLeftMargin = pPrintFunc->GetLeftMargin();
417 nRightMargin = pPrintFunc->GetRightMargin();
418 nTopMargin = pPrintFunc->GetTopMargin();
419 nBottomMargin = pPrintFunc->GetBottomMargin();
420 nHeaderHeight = pPrintFunc->GetHeader().nHeight;
421 nFooterHeight = pPrintFunc->GetFooter().nHeight;
422 bHeaderOn = pPrintFunc->GetHeader().bEnable;
423 bFooterOn = pPrintFunc->GetFooter().bEnable;
424 mnScale = pPrintFunc->GetZoom();
426 if ( bDoPrint && bPageMargin && pLocationData ) // don't make use of pLocationData while filling it
428 Rectangle aPixRect;
429 Rectangle aRectCellPosition;
430 Rectangle aRectPosition;
431 pLocationData->GetMainCellRange( aPageArea, aPixRect );
432 if( !bLayoutRTL )
434 pLocationData->GetCellPosition( aPageArea.aStart, aRectPosition );
435 nLeftPosition = aRectPosition.Left();
436 for( SCCOL i = aPageArea.aStart.Col(); i <= aPageArea.aEnd.Col(); i++ )
438 pLocationData->GetCellPosition( ScAddress( i,aPageArea.aStart.Row(),aPageArea.aStart.Tab()),aRectCellPosition );
439 nRight[i] = aRectCellPosition.Right();
442 else
444 pLocationData->GetCellPosition( aPageArea.aEnd, aRectPosition );
445 nLeftPosition = aRectPosition.Right()+1;
447 pLocationData->GetCellPosition( aPageArea.aStart,aRectCellPosition );
448 nRight[ aPageArea.aEnd.Col() ] = aRectCellPosition.Left();
449 for( SCCOL i = aPageArea.aEnd.Col(); i > aPageArea.aStart.Col(); i-- )
451 pLocationData->GetCellPosition( ScAddress( i,aPageArea.aEnd.Row(),aPageArea.aEnd.Tab()),aRectCellPosition );
452 nRight[ i-1 ] = nRight[ i ] + aRectCellPosition.Right() - aRectCellPosition.Left() + 1;
457 if (nPrinted) // if not, draw everything grey
459 aLocalPageSize = pPrintFunc->GetPageSize();
460 aLocalPageSize.Width() = (long) (aLocalPageSize.Width() * HMM_PER_TWIPS );
461 aLocalPageSize.Height() = (long) (aLocalPageSize.Height() * HMM_PER_TWIPS );
463 nLeftMargin = (long) ( nLeftMargin * HMM_PER_TWIPS );
464 nRightMargin = (long) ( nRightMargin * HMM_PER_TWIPS );
465 nTopMargin = (long) ( nTopMargin * HMM_PER_TWIPS );
466 nBottomMargin = (long) ( nBottomMargin * HMM_PER_TWIPS );
467 nHeaderHeight = (long) ( nHeaderHeight * HMM_PER_TWIPS * mnScale / 100 + nTopMargin );
468 nFooterHeight = (long) ( nFooterHeight * HMM_PER_TWIPS * mnScale / 100 + nBottomMargin );
471 if (!bStateValid)
473 pPrintFunc->GetPrintState( aState );
474 aState.nDocPages = nTotalPages;
475 bStateValid = true;
477 delete pPrintFunc;
480 if ( bDoPrint )
482 long nPageEndX = aLocalPageSize.Width() - aOffset.X();
483 long nPageEndY = aLocalPageSize.Height() - aOffset.Y();
484 if ( !bValidPage )
485 nPageEndX = nPageEndY = 0;
487 Size aWinSize = GetOutputSize();
488 Point aWinEnd( aWinSize.Width(), aWinSize.Height() );
489 bool bRight = nPageEndX <= aWinEnd.X();
490 bool bBottom = nPageEndY <= aWinEnd.Y();
492 if (!nTotalPages)
494 // There is no data to print. Print a friendly warning message and
495 // bail out.
497 SetMapMode(aMMMode);
499 // Draw background first.
500 SetLineColor();
501 SetFillColor(aBackColor);
502 DrawRect(Rectangle(0, 0, aWinEnd.X(), aWinEnd.Y()));
504 const ScPatternAttr& rDefPattern =
505 static_cast<const ScPatternAttr&>(
506 pDoc->GetPool()->GetDefaultItem(ATTR_PATTERN));
508 boost::scoped_ptr<ScEditEngineDefaulter> pEditEng(
509 new ScEditEngineDefaulter(EditEngine::CreatePool(), true));
511 pEditEng->SetRefMapMode(aMMMode);
512 SfxItemSet* pEditDefaults = new SfxItemSet( pEditEng->GetEmptyItemSet() );
513 rDefPattern.FillEditItemSet(pEditDefaults);
514 pEditEng->SetDefaults(pEditDefaults, true);
516 Color aTextColor(COL_LIGHTGRAY);
517 pEditDefaults->Put(SvxColorItem(aTextColor, EE_CHAR_COLOR));
519 OUString aEmptyMsg;
520 if (mbHasEmptyRangeTable)
521 aEmptyMsg = ScGlobal::GetRscString(STR_PRINT_PREVIEW_EMPTY_RANGE);
522 else
523 aEmptyMsg = ScGlobal::GetRscString(STR_PRINT_PREVIEW_NODATA);
525 long nHeight = 3000;
526 pEditEng->SetDefaultItem(SvxFontHeightItem(nHeight, 100, EE_CHAR_FONTHEIGHT));
527 pEditEng->SetDefaultItem(SvxFontHeightItem(nHeight, 100, EE_CHAR_FONTHEIGHT_CJK));
528 pEditEng->SetDefaultItem(SvxFontHeightItem(nHeight, 100, EE_CHAR_FONTHEIGHT_CTL));
530 pEditEng->SetText(aEmptyMsg);
532 Point aCenter(
533 (aWinEnd.X() - pEditEng->CalcTextWidth())/2,
534 (aWinEnd.Y() - pEditEng->GetTextHeight())/2);
536 pEditEng->Draw(this, aCenter);
538 return;
541 if( bPageMargin && bValidPage )
543 SetMapMode(aMMMode);
544 SetLineColor( COL_BLACK );
545 DrawInvert( (long)( nTopMargin - aOffset.Y() ), POINTER_VSIZEBAR );
546 DrawInvert( (long)(nPageEndY - nBottomMargin ), POINTER_VSIZEBAR );
547 DrawInvert( (long)( nLeftMargin - aOffset.X() ), POINTER_HSIZEBAR );
548 DrawInvert( (long)( nPageEndX - nRightMargin ) , POINTER_HSIZEBAR );
549 if( bHeaderOn )
551 DrawInvert( nHeaderHeight - aOffset.Y(), POINTER_VSIZEBAR );
553 if( bFooterOn )
555 DrawInvert( nPageEndY - nFooterHeight, POINTER_VSIZEBAR );
558 SetMapMode( MapMode( MAP_PIXEL ) );
559 for( int i= aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
561 Point aColumnTop = LogicToPixel( Point( 0, -aOffset.Y() ) ,aMMMode );
562 SetLineColor( COL_BLACK );
563 SetFillColor( COL_BLACK );
564 DrawRect( Rectangle( Point( nRight[i] - 2, aColumnTop.Y() ),Point( nRight[i] + 2 , 4 + aColumnTop.Y()) ));
565 DrawLine( Point( nRight[i], aColumnTop.Y() ), Point( nRight[i], 10 + aColumnTop.Y()) );
567 SetMapMode( aMMMode );
570 if (bRight || bBottom)
572 SetMapMode(aMMMode);
573 SetLineColor();
574 SetFillColor(aBackColor);
575 if (bRight)
576 DrawRect(Rectangle(nPageEndX,0, aWinEnd.X(),aWinEnd.Y()));
577 if (bBottom)
579 if (bRight)
580 DrawRect(Rectangle(0,nPageEndY, nPageEndX,aWinEnd.Y())); // Corner not duplicated
581 else
582 DrawRect(Rectangle(0,nPageEndY, aWinEnd.X(),aWinEnd.Y()));
586 if ( bValidPage )
588 Color aBorderColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
590 // draw border
592 if ( aOffset.X() <= 0 || aOffset.Y() <= 0 || bRight || bBottom )
594 SetLineColor( aBorderColor );
595 SetFillColor();
597 Rectangle aPixel( LogicToPixel( Rectangle( -aOffset.X(), -aOffset.Y(), nPageEndX, nPageEndY ) ) );
598 --aPixel.Right();
599 --aPixel.Bottom();
600 DrawRect( PixelToLogic( aPixel ) );
603 // draw shadow
605 SetLineColor();
606 SetFillColor( aBorderColor );
608 Rectangle aPixel;
610 aPixel = LogicToPixel( Rectangle( nPageEndX, -aOffset.Y(), nPageEndX, nPageEndY ) );
611 aPixel.Top() += SC_PREVIEW_SHADOWSIZE;
612 aPixel.Right() += SC_PREVIEW_SHADOWSIZE - 1;
613 aPixel.Bottom() += SC_PREVIEW_SHADOWSIZE - 1;
614 DrawRect( PixelToLogic( aPixel ) );
616 aPixel = LogicToPixel( Rectangle( -aOffset.X(), nPageEndY, nPageEndX, nPageEndY ) );
617 aPixel.Left() += SC_PREVIEW_SHADOWSIZE;
618 aPixel.Right() += SC_PREVIEW_SHADOWSIZE - 1;
619 aPixel.Bottom() += SC_PREVIEW_SHADOWSIZE - 1;
620 DrawRect( PixelToLogic( aPixel ) );
625 void ScPreview::Paint( const Rectangle& /* rRect */ )
627 bool bWasInPaint = bInPaint; // nested calls shouldn't be necessary, but allow for now
628 bInPaint = true;
630 if (bPageMargin)
631 GetLocationData(); // fill location data for column positions
632 DoPrint( NULL );
633 pViewShell->UpdateScrollBars();
635 bInPaint = bWasInPaint;
638 void ScPreview::Command( const CommandEvent& rCEvt )
640 sal_uInt16 nCmd = rCEvt.GetCommand();
641 if ( nCmd == COMMAND_WHEEL || nCmd == COMMAND_STARTAUTOSCROLL || nCmd == COMMAND_AUTOSCROLL )
643 bool bDone = pViewShell->ScrollCommand( rCEvt );
644 if (!bDone)
645 Window::Command(rCEvt);
647 else if ( nCmd == COMMAND_CONTEXTMENU )
648 SfxDispatcher::ExecutePopup();
649 else
650 Window::Command( rCEvt );
654 void ScPreview::KeyInput( const KeyEvent& rKEvt )
656 // The + and - keys can't be configured as accelerator entries, so they must be handled directly
657 // (in ScPreview, not ScPreviewShell -> only if the preview window has the focus)
659 const KeyCode& rKeyCode = rKEvt.GetKeyCode();
660 sal_uInt16 nKey = rKeyCode.GetCode();
661 bool bHandled = false;
662 if(!rKeyCode.GetModifier())
664 sal_uInt16 nSlot = 0;
665 switch(nKey)
667 case KEY_ADD: nSlot = SID_PREVIEW_ZOOMIN; break;
668 case KEY_ESCAPE: nSlot = ScViewUtil::IsFullScreen( *pViewShell ) ? SID_CANCEL : SID_PREVIEW_CLOSE; break;
669 case KEY_SUBTRACT: nSlot = SID_PREVIEW_ZOOMOUT; break;
671 if(nSlot)
673 bHandled = true;
674 pViewShell->GetViewFrame()->GetDispatcher()->Execute( nSlot, SFX_CALLMODE_ASYNCHRON );
678 if ( !bHandled && !pViewShell->KeyInput(rKEvt) )
679 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;
700 void ScPreview::DataChanged(bool bNewTime)
702 if (bNewTime)
704 aDate = Date( Date::SYSTEM );
705 aTime = Time( Time::SYSTEM );
708 bValid = false;
709 InvalidateLocationData( SC_HINT_DATACHANGED );
710 Invalidate();
714 OUString ScPreview::GetPosString()
716 if (!bValid)
718 CalcPages();
719 UpdateDrawView(); // The table eventually changes
722 OUString aString = ScGlobal::GetRscString( STR_PAGE ) +
723 " " + OUString::number(nPageNo+1);
725 if (nTabsTested >= nTabCount)
726 aString += " / " + OUString::number(nTotalPages);
728 return aString;
732 void ScPreview::SetZoom(sal_uInt16 nNewZoom)
734 if (nNewZoom < 20)
735 nNewZoom = 20;
736 if (nNewZoom > 400)
737 nNewZoom = 400;
738 if (nNewZoom != nZoom)
740 nZoom = nNewZoom;
742 // apply new MapMode and call UpdateScrollBars to update aOffset
744 Fraction aPreviewZoom( nZoom, 100 );
745 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
746 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
747 SetMapMode( aMMMode );
749 bInSetZoom = true; // don't scroll during SetYOffset in UpdateScrollBars
750 pViewShell->UpdateNeededScrollBars(true);
751 bInSetZoom = false;
753 bStateValid = false;
754 InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
755 DoInvalidate();
756 Invalidate();
761 void ScPreview::SetPageNo( long nPage )
763 nPageNo = nPage;
764 RecalcPages();
765 UpdateDrawView(); // The table eventually changes
766 InvalidateLocationData( SC_HINT_DATACHANGED );
767 Invalidate();
771 long ScPreview::GetFirstPage(SCTAB nTabP)
773 SCTAB nDocTabCount = pDocShell->GetDocument()->GetTableCount();
774 if (nTabP >= nDocTabCount)
775 nTabP = nDocTabCount-1;
777 long nPage = 0;
778 if (nTabP>0)
780 CalcPages();
781 if (nTabP >= static_cast<SCTAB>(nPages.size()) )
782 OSL_FAIL("nPages out ouf bounds, FIX IT");
783 UpdateDrawView(); // The table eventually changes
785 for (SCTAB i=0; i<nTabP; i++)
786 nPage += nPages[i];
788 // An empty Table on the previous Page
790 if ( nPages[nTabP]==0 && nPage > 0 )
791 --nPage;
794 return nPage;
798 static Size lcl_GetDocPageSize( ScDocument* pDoc, SCTAB nTab )
800 OUString aName = pDoc->GetPageStyle( nTab );
801 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
802 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aName, SFX_STYLE_FAMILY_PAGE );
803 if ( pStyleSheet )
805 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
806 return ((const SvxSizeItem&) rStyleSet.Get(ATTR_PAGE_SIZE)).GetSize();
808 else
810 OSL_FAIL( "PageStyle not found" );
811 return Size();
816 sal_uInt16 ScPreview::GetOptimalZoom(bool bWidthOnly)
818 double nWinScaleX = ScGlobal::nScreenPPTX / pDocShell->GetOutputFactor();
819 double nWinScaleY = ScGlobal::nScreenPPTY;
820 Size aWinSize = GetOutputSizePixel();
822 // desired margin is 0.25cm in default MapMode (like Writer),
823 // but some additional margin is introduced by integer scale values
824 // -> add only 0.10cm, so there is some margin in all cases.
825 Size aMarginSize( LogicToPixel( Size( 100, 100 ), MAP_100TH_MM ) );
826 aWinSize.Width() -= 2 * aMarginSize.Width();
827 aWinSize.Height() -= 2 * aMarginSize.Height();
829 Size aLocalPageSize = lcl_GetDocPageSize( pDocShell->GetDocument(), nTab );
830 if ( aLocalPageSize.Width() && aLocalPageSize.Height() )
832 long nZoomX = (long) ( aWinSize.Width() * 100 / ( aLocalPageSize.Width() * nWinScaleX ));
833 long nZoomY = (long) ( aWinSize.Height() * 100 / ( aLocalPageSize.Height() * nWinScaleY ));
835 long nOptimal = nZoomX;
836 if (!bWidthOnly && nZoomY<nOptimal)
837 nOptimal = nZoomY;
839 if (nOptimal<20)
840 nOptimal = 20;
841 if (nOptimal>400)
842 nOptimal = 400;
844 return (sal_uInt16) nOptimal;
846 else
847 return nZoom;
851 void ScPreview::SetXOffset( long nX )
853 if ( aOffset.X() == nX )
854 return;
856 if (bValid)
858 long nDif = LogicToPixel(aOffset).X() - LogicToPixel(Point(nX,0)).X();
859 aOffset.X() = nX;
860 if (nDif && !bInSetZoom)
862 MapMode aOldMode = GetMapMode(); SetMapMode(MAP_PIXEL);
863 Scroll( nDif, 0 );
864 SetMapMode(aOldMode);
867 else
869 aOffset.X() = nX;
870 if (!bInSetZoom)
871 Invalidate();
873 InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
874 Paint(Rectangle());
878 void ScPreview::SetYOffset( long nY )
880 if ( aOffset.Y() == nY )
881 return;
883 if (bValid)
885 long nDif = LogicToPixel(aOffset).Y() - LogicToPixel(Point(0,nY)).Y();
886 aOffset.Y() = nY;
887 if (nDif && !bInSetZoom)
889 MapMode aOldMode = GetMapMode(); SetMapMode(MAP_PIXEL);
890 Scroll( 0, nDif );
891 SetMapMode(aOldMode);
894 else
896 aOffset.Y() = nY;
897 if (!bInSetZoom)
898 Invalidate();
900 InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
901 Paint(Rectangle());
905 void ScPreview::DoInvalidate()
907 // If the whole GetState of the shell is called
908 // The Invalidate must come behind asynchronously
910 if (bInGetState)
911 Application::PostUserEvent( STATIC_LINK( this, ScPreview, InvalidateHdl ) );
912 else
913 StaticInvalidate(); // Immediately
916 void ScPreview::StaticInvalidate()
918 // static method, because it's called asynchronously
919 // -> must use current viewframe
921 SfxViewFrame* pViewFrm = SfxViewFrame::Current();
922 if (!pViewFrm)
923 return;
925 SfxBindings& rBindings = pViewFrm->GetBindings();
926 rBindings.Invalidate(SID_STATUS_DOCPOS);
927 rBindings.Invalidate(SID_ROWCOL_SELCOUNT);
928 rBindings.Invalidate(SID_STATUS_PAGESTYLE);
929 rBindings.Invalidate(SID_PREVIEW_PREVIOUS);
930 rBindings.Invalidate(SID_PREVIEW_NEXT);
931 rBindings.Invalidate(SID_PREVIEW_FIRST);
932 rBindings.Invalidate(SID_PREVIEW_LAST);
933 rBindings.Invalidate(SID_ATTR_ZOOM);
934 rBindings.Invalidate(SID_PREVIEW_ZOOMIN);
935 rBindings.Invalidate(SID_PREVIEW_ZOOMOUT);
936 rBindings.Invalidate(SID_PREVIEW_SCALINGFACTOR);
937 rBindings.Invalidate(SID_ATTR_ZOOMSLIDER);
940 IMPL_STATIC_LINK( ScPreview, InvalidateHdl, void*, EMPTYARG )
942 (void)pThis; // avoid warning
944 StaticInvalidate();
945 return 0;
948 void ScPreview::DataChanged( const DataChangedEvent& rDCEvt )
950 Window::DataChanged(rDCEvt);
952 if ( (rDCEvt.GetType() == DATACHANGED_PRINTER) ||
953 (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
954 (rDCEvt.GetType() == DATACHANGED_FONTS) ||
955 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
956 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
957 (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
959 if ( rDCEvt.GetType() == DATACHANGED_FONTS )
960 pDocShell->UpdateFontList();
962 // #i114518# Paint of form controls may modify the window's settings.
963 // Ignore the event if it is called from within Paint.
964 if ( !bInPaint )
966 if ( rDCEvt.GetType() == DATACHANGED_SETTINGS &&
967 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
969 // scroll bar size may have changed
970 pViewShell->InvalidateBorder(); // calls OuterResizePixel
972 Invalidate();
973 InvalidateLocationData( SC_HINT_DATACHANGED );
978 void ScPreview::MouseButtonDown( const MouseEvent& rMEvt )
980 Fraction aPreviewZoom( nZoom, 100 );
981 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
982 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
984 aButtonDownChangePoint = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
985 aButtonDownPt = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
987 CaptureMouse();
989 if( rMEvt.IsLeft() && GetPointer() == POINTER_HSIZEBAR )
991 SetMapMode( aMMMode );
992 if( bLeftRulerChange )
994 DrawInvert( aButtonDownChangePoint.X(), POINTER_HSIZEBAR );
995 bLeftRulerMove = true;
996 bRightRulerMove = false;
998 else if( bRightRulerChange )
1000 DrawInvert( aButtonDownChangePoint.X(), POINTER_HSIZEBAR );
1001 bLeftRulerMove = false;
1002 bRightRulerMove = true;
1006 if( rMEvt.IsLeft() && GetPointer() == POINTER_VSIZEBAR )
1008 SetMapMode( aMMMode );
1009 if( bTopRulerChange )
1011 DrawInvert( aButtonDownChangePoint.Y(), POINTER_VSIZEBAR );
1012 bTopRulerMove = true;
1013 bBottomRulerMove = false;
1015 else if( bBottomRulerChange )
1017 DrawInvert( aButtonDownChangePoint.Y(), POINTER_VSIZEBAR );
1018 bTopRulerMove = false;
1019 bBottomRulerMove = true;
1021 else if( bHeaderRulerChange )
1023 DrawInvert( aButtonDownChangePoint.Y(), POINTER_VSIZEBAR );
1024 bHeaderRulerMove = true;
1025 bFooterRulerMove = false;
1027 else if( bFooterRulerChange )
1029 DrawInvert( aButtonDownChangePoint.Y(), POINTER_VSIZEBAR );
1030 bHeaderRulerMove = false;
1031 bFooterRulerMove = true;
1035 if( rMEvt.IsLeft() && GetPointer() == POINTER_HSPLIT )
1037 Point aNowPt = rMEvt.GetPosPixel();
1038 SCCOL i = 0;
1039 for( i = aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
1041 if( aNowPt.X() < nRight[i] + 2 && aNowPt.X() > nRight[i] - 2 )
1043 nColNumberButttonDown = i;
1044 break;
1047 if( i == aPageArea.aEnd.Col()+1 )
1048 return;
1050 SetMapMode( aMMMode );
1051 if( nColNumberButttonDown == aPageArea.aStart.Col() )
1052 DrawInvert( PixelToLogic( Point( nLeftPosition, 0 ),aMMMode ).X() ,POINTER_HSPLIT );
1053 else
1054 DrawInvert( PixelToLogic( Point( nRight[ nColNumberButttonDown-1 ], 0 ),aMMMode ).X() ,POINTER_HSPLIT );
1056 DrawInvert( aButtonDownChangePoint.X(), POINTER_HSPLIT );
1057 bColRulerMove = true;
1061 void ScPreview::MouseButtonUp( const MouseEvent& rMEvt )
1063 Fraction aPreviewZoom( nZoom, 100 );
1064 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
1065 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
1067 aButtonUpPt = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
1069 long nWidth = (long) lcl_GetDocPageSize(pDocShell->GetDocument(), nTab).Width();
1070 long nHeight = (long) lcl_GetDocPageSize(pDocShell->GetDocument(), nTab).Height();
1072 if( rMEvt.IsLeft() && GetPointer() == POINTER_HSIZEBAR )
1074 SetPointer( Pointer( POINTER_ARROW ) );
1077 ScDocument * pDoc = pDocShell->GetDocument();
1078 OUString aOldName = pDoc->GetPageStyle( nTab );
1079 bool bUndo = pDoc->IsUndoEnabled();
1080 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
1081 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aOldName, SFX_STYLE_FAMILY_PAGE );
1083 if ( pStyleSheet )
1085 bool bMoveRulerAction= true;
1086 ScStyleSaveData aOldData;
1087 if( bUndo )
1088 aOldData.InitFromStyle( pStyleSheet );
1090 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
1092 SvxLRSpaceItem aLRItem = ( const SvxLRSpaceItem& ) rStyleSet.Get( ATTR_LRSPACE );
1094 if(( bLeftRulerChange || bRightRulerChange ) && ( aButtonUpPt.X() <= ( 0 - aOffset.X() ) || aButtonUpPt.X() > nWidth * HMM_PER_TWIPS - aOffset.X() ) )
1096 bMoveRulerAction = false;
1097 Paint(Rectangle(0,0,10000,10000));
1099 else if( bLeftRulerChange && ( aButtonUpPt.X() / HMM_PER_TWIPS > nWidth - aLRItem.GetRight() - aOffset.X() / HMM_PER_TWIPS ) )
1101 bMoveRulerAction = false;
1102 Paint(Rectangle(0,0,10000,10000));
1104 else if( bRightRulerChange && ( aButtonUpPt.X() / HMM_PER_TWIPS < aLRItem.GetLeft() - aOffset.X() / HMM_PER_TWIPS ) )
1106 bMoveRulerAction = false;
1107 Paint(Rectangle(0,0,10000,10000));
1109 else if( aButtonDownPt.X() == aButtonUpPt.X() )
1111 bMoveRulerAction = false;
1112 DrawInvert( aButtonUpPt.X(), POINTER_HSIZEBAR );
1114 if( bMoveRulerAction )
1116 ScDocShellModificator aModificator( *pDocShell );
1117 if( bLeftRulerChange && bLeftRulerMove )
1119 aLRItem.SetLeft( (long)( aButtonUpPt.X() / HMM_PER_TWIPS + aOffset.X() / HMM_PER_TWIPS ));
1120 rStyleSet.Put( aLRItem );
1121 pDocShell->SetModified(true);
1123 else if( bRightRulerChange && bRightRulerMove )
1125 aLRItem.SetRight( (long)( nWidth - aButtonUpPt.X() / HMM_PER_TWIPS - aOffset.X() / HMM_PER_TWIPS ));
1126 rStyleSet.Put( aLRItem );
1127 pDocShell->SetModified(true);
1130 ScStyleSaveData aNewData;
1131 aNewData.InitFromStyle( pStyleSheet );
1132 if( bUndo )
1134 pDocShell->GetUndoManager()->AddUndoAction(
1135 new ScUndoModifyStyle( pDocShell, SFX_STYLE_FAMILY_PAGE,
1136 aOldData, aNewData ) );
1139 if ( ValidTab( nTab ) )
1141 ScPrintFunc aPrintFunc( this, pDocShell, nTab );
1142 aPrintFunc.UpdatePages();
1145 Rectangle aRect(0,0,10000,10000);
1146 Paint( aRect );
1147 aModificator.SetDocumentModified();
1148 bLeftRulerChange = false;
1149 bRightRulerChange = false;
1152 bLeftRulerMove = false;
1153 bRightRulerMove = false;
1156 if( rMEvt.IsLeft() && GetPointer() == POINTER_VSIZEBAR )
1158 SetPointer( POINTER_ARROW );
1160 bool bMoveRulerAction = true;
1161 if( ( bTopRulerChange || bBottomRulerChange || bHeaderRulerChange || bFooterRulerChange ) && ( aButtonUpPt.Y() <= ( 0 - aOffset.Y() ) || aButtonUpPt.Y() > nHeight * HMM_PER_TWIPS -aOffset.Y() ) )
1163 bMoveRulerAction = false;
1164 Paint( Rectangle(0,0,10000,10000) );
1166 else if( aButtonDownPt.Y() == aButtonUpPt.Y() )
1168 bMoveRulerAction = false;
1169 DrawInvert( aButtonUpPt.Y(), POINTER_VSIZEBAR );
1171 if( bMoveRulerAction )
1173 ScDocument * pDoc = pDocShell->GetDocument();
1174 bool bUndo = pDoc->IsUndoEnabled();
1175 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
1176 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
1177 OSL_ENSURE( pStyleSheet, "PageStyle not found" );
1178 if ( pStyleSheet )
1180 ScDocShellModificator aModificator( *pDocShell );
1181 ScStyleSaveData aOldData;
1182 if( bUndo )
1183 aOldData.InitFromStyle( pStyleSheet );
1185 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
1187 SvxULSpaceItem aULItem = ( const SvxULSpaceItem&)rStyleSet.Get( ATTR_ULSPACE );
1189 if( bTopRulerMove && bTopRulerChange )
1191 aULItem.SetUpperValue( (sal_uInt16)( aButtonUpPt.Y() / HMM_PER_TWIPS + aOffset.Y() / HMM_PER_TWIPS ) );
1192 rStyleSet.Put( aULItem );
1193 pDocShell->SetModified(true);
1195 else if( bBottomRulerMove && bBottomRulerChange )
1197 aULItem.SetLowerValue( (sal_uInt16)( nHeight - aButtonUpPt.Y() / HMM_PER_TWIPS - aOffset.Y() / HMM_PER_TWIPS ) );
1198 rStyleSet.Put( aULItem );
1199 pDocShell->SetModified(true);
1201 else if( bHeaderRulerMove && bHeaderRulerChange )
1203 const SfxPoolItem* pItem = NULL;
1204 if ( rStyleSet.GetItemState( ATTR_PAGE_HEADERSET, false, &pItem ) == SFX_ITEM_SET )
1206 SfxItemSet& pHeaderSet = ((SvxSetItem*)pItem)->GetItemSet();
1207 Size aHeaderSize = ((const SvxSizeItem&)pHeaderSet.Get(ATTR_PAGE_SIZE)).GetSize();
1208 aHeaderSize.Height() = (long)( aButtonUpPt.Y() / HMM_PER_TWIPS + aOffset.Y() / HMM_PER_TWIPS - aULItem.GetUpper());
1209 aHeaderSize.Height() = aHeaderSize.Height() * 100 / mnScale;
1210 SvxSetItem aNewHeader( (const SvxSetItem&)rStyleSet.Get(ATTR_PAGE_HEADERSET) );
1211 aNewHeader.GetItemSet().Put( SvxSizeItem( ATTR_PAGE_SIZE, aHeaderSize ) );
1212 rStyleSet.Put( aNewHeader );
1213 pDocShell->SetModified(true);
1216 else if( bFooterRulerMove && bFooterRulerChange )
1218 const SfxPoolItem* pItem = NULL;
1219 if( rStyleSet.GetItemState( ATTR_PAGE_FOOTERSET, false, &pItem ) == SFX_ITEM_SET )
1221 SfxItemSet& pFooterSet = ((SvxSetItem*)pItem)->GetItemSet();
1222 Size aFooterSize = ((const SvxSizeItem&)pFooterSet.Get(ATTR_PAGE_SIZE)).GetSize();
1223 aFooterSize.Height() = (long)( nHeight - aButtonUpPt.Y() / HMM_PER_TWIPS - aOffset.Y() / HMM_PER_TWIPS - aULItem.GetLower() );
1224 aFooterSize.Height() = aFooterSize.Height() * 100 / mnScale;
1225 SvxSetItem aNewFooter( (const SvxSetItem&)rStyleSet.Get(ATTR_PAGE_FOOTERSET) );
1226 aNewFooter.GetItemSet().Put( SvxSizeItem( ATTR_PAGE_SIZE, aFooterSize ) );
1227 rStyleSet.Put( aNewFooter );
1228 pDocShell->SetModified(true);
1232 ScStyleSaveData aNewData;
1233 aNewData.InitFromStyle( pStyleSheet );
1234 if( bUndo )
1236 pDocShell->GetUndoManager()->AddUndoAction(
1237 new ScUndoModifyStyle( pDocShell, SFX_STYLE_FAMILY_PAGE,
1238 aOldData, aNewData ) );
1241 if ( ValidTab( nTab ) )
1243 ScPrintFunc aPrintFunc( this, pDocShell, nTab );
1244 aPrintFunc.UpdatePages();
1247 Rectangle aRect(0,0,10000,10000);
1248 Paint( aRect );
1249 aModificator.SetDocumentModified();
1250 bTopRulerChange = false;
1251 bBottomRulerChange = false;
1252 bHeaderRulerChange = false;
1253 bFooterRulerChange = false;
1256 bTopRulerMove = false;
1257 bBottomRulerMove = false;
1258 bHeaderRulerMove = false;
1259 bFooterRulerMove = false;
1261 if( rMEvt.IsLeft() && GetPointer() == POINTER_HSPLIT )
1263 SetPointer(POINTER_ARROW);
1264 ScDocument* pDoc = pDocShell->GetDocument();
1265 bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1266 bool bMoveRulerAction = true;
1267 if( aButtonDownPt.X() == aButtonUpPt.X() )
1269 bMoveRulerAction = false;
1270 if( nColNumberButttonDown == aPageArea.aStart.Col() )
1271 DrawInvert( PixelToLogic( Point( nLeftPosition, 0 ),aMMMode ).X() ,POINTER_HSPLIT );
1272 else
1273 DrawInvert( PixelToLogic( Point( nRight[ nColNumberButttonDown-1 ], 0 ),aMMMode ).X() ,POINTER_HSPLIT );
1274 DrawInvert( aButtonUpPt.X(), POINTER_HSPLIT );
1276 if( bMoveRulerAction )
1278 long nNewColWidth = 0;
1279 std::vector<sc::ColRowSpan> aCols(1, sc::ColRowSpan(nColNumberButttonDown,nColNumberButttonDown));
1281 if( !bLayoutRTL )
1283 nNewColWidth = (long) ( PixelToLogic( Point( rMEvt.GetPosPixel().X() - nRight[ nColNumberButttonDown ], 0), aMMMode ).X() / HMM_PER_TWIPS ) * 100 / mnScale;
1284 nNewColWidth += pDocShell->GetDocument()->GetColWidth( nColNumberButttonDown, nTab );
1286 else
1289 nNewColWidth = (long) ( PixelToLogic( Point( nRight[ nColNumberButttonDown ] - rMEvt.GetPosPixel().X(), 0), aMMMode ).X() / HMM_PER_TWIPS ) * 100 / mnScale;
1290 nNewColWidth += pDocShell->GetDocument()->GetColWidth( nColNumberButttonDown, nTab );
1293 if( nNewColWidth >= 0 )
1295 pDocShell->GetDocFunc().SetWidthOrHeight(
1296 true, aCols, nTab, SC_SIZE_DIRECT, (sal_uInt16)nNewColWidth, true, true);
1297 pDocShell->SetModified(true);
1299 if ( ValidTab( nTab ) )
1301 ScPrintFunc aPrintFunc( this, pDocShell, nTab );
1302 aPrintFunc.UpdatePages();
1304 Rectangle nRect(0,0,10000,10000);
1305 Paint( nRect );
1307 bColRulerMove = false;
1309 ReleaseMouse();
1312 void ScPreview::MouseMove( const MouseEvent& rMEvt )
1314 Fraction aPreviewZoom( nZoom, 100 );
1315 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
1316 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
1317 Point aMouseMovePoint = PixelToLogic( rMEvt.GetPosPixel(), aMMMode );
1319 long nLeftMargin = 0;
1320 long nRightMargin = 0;
1321 long nTopMargin = 0;
1322 long nBottomMargin = 0;
1324 long nWidth = (long) lcl_GetDocPageSize(pDocShell->GetDocument(), nTab).Width();
1325 long nHeight = (long) lcl_GetDocPageSize(pDocShell->GetDocument(), nTab).Height();
1327 if ( nPageNo < nTotalPages )
1329 ScPrintOptions aOptions = SC_MOD()->GetPrintOptions();
1331 ScPrintFunc* pPrintFunc;
1333 if (bStateValid)
1334 pPrintFunc = new ScPrintFunc( this, pDocShell, aState, &aOptions );
1335 else
1336 pPrintFunc = new ScPrintFunc( this, pDocShell, nTab, nFirstAttr[nTab], nTotalPages, NULL, &aOptions );
1338 nLeftMargin = (long)( pPrintFunc->GetLeftMargin() * HMM_PER_TWIPS - aOffset.X() );
1339 nRightMargin = (long)( pPrintFunc->GetRightMargin() * HMM_PER_TWIPS );
1340 nRightMargin = (long)( nWidth * HMM_PER_TWIPS - nRightMargin - aOffset.X() );
1341 nTopMargin = (long)( pPrintFunc->GetTopMargin() * HMM_PER_TWIPS - aOffset.Y() );
1342 nBottomMargin = (long)( pPrintFunc->GetBottomMargin() * HMM_PER_TWIPS );
1343 nBottomMargin = (long)( nHeight * HMM_PER_TWIPS - nBottomMargin - aOffset.Y() );
1344 if( mnScale > 0 )
1346 nHeaderHeight = (long)( nTopMargin + pPrintFunc->GetHeader().nHeight * HMM_PER_TWIPS * mnScale / 100 );
1347 nFooterHeight = (long)( nBottomMargin - pPrintFunc->GetFooter().nHeight * HMM_PER_TWIPS * mnScale / 100 );
1349 else
1351 nHeaderHeight = (long)( nTopMargin + pPrintFunc->GetHeader().nHeight * HMM_PER_TWIPS );
1352 nFooterHeight = (long)( nBottomMargin - pPrintFunc->GetFooter().nHeight * HMM_PER_TWIPS );
1354 delete pPrintFunc;
1357 Point aPixPt( rMEvt.GetPosPixel() );
1358 Point aLeftTop = LogicToPixel( Point( nLeftMargin, -aOffset.Y() ) , aMMMode );
1359 Point aLeftBottom = LogicToPixel( Point( nLeftMargin ,(long)(nHeight * HMM_PER_TWIPS - aOffset.Y()) ), aMMMode );
1360 Point aRightTop = LogicToPixel( Point( nRightMargin, -aOffset.Y() ), aMMMode );
1361 Point aTopLeft = LogicToPixel( Point( -aOffset.X(), nTopMargin ), aMMMode );
1362 Point aTopRight = LogicToPixel( Point( (long)(nWidth * HMM_PER_TWIPS - aOffset.X()), nTopMargin ), aMMMode );
1363 Point aBottomLeft = LogicToPixel( Point( -aOffset.X(), nBottomMargin ), aMMMode );
1364 Point aHeaderLeft = LogicToPixel( Point( -aOffset.X(), nHeaderHeight ), aMMMode );
1365 Point aFooderLeft = LogicToPixel( Point( -aOffset.X(), nFooterHeight ), aMMMode );
1367 bool bOnColRulerChange = false;
1369 for( SCCOL i=aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
1371 Point aColumnTop = LogicToPixel( Point( 0, -aOffset.Y() ) ,aMMMode );
1372 Point aColumnBottom = LogicToPixel( Point( 0, (long)( nHeight * HMM_PER_TWIPS - aOffset.Y()) ), aMMMode );
1373 if( aPixPt.X() < ( nRight[i] + 2 ) && ( aPixPt.X() > ( nRight[i] - 2 ) ) && ( aPixPt.X() < aRightTop.X() ) && ( aPixPt.X() > aLeftTop.X() )
1374 && ( aPixPt.Y() > aColumnTop.Y() ) && ( aPixPt.Y() < aColumnBottom.Y() ) && !bLeftRulerMove && !bRightRulerMove
1375 && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1377 bOnColRulerChange = true;
1378 if( !rMEvt.GetButtons() && GetPointer() == POINTER_HSPLIT )
1379 nColNumberButttonDown = i;
1380 break;
1384 if( aPixPt.X() < ( aLeftTop.X() + 2 ) && aPixPt.X() > ( aLeftTop.X() - 2 ) && !bRightRulerMove )
1386 bLeftRulerChange = true;
1387 bRightRulerChange = false;
1389 else if( aPixPt.X() < ( aRightTop.X() + 2 ) && aPixPt.X() > ( aRightTop.X() - 2 ) && !bLeftRulerMove )
1391 bLeftRulerChange = false;
1392 bRightRulerChange = true;
1394 else if( aPixPt.Y() < ( aTopLeft.Y() + 2 ) && aPixPt.Y() > ( aTopLeft.Y() - 2 ) && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1396 bTopRulerChange = true;
1397 bBottomRulerChange = false;
1398 bHeaderRulerChange = false;
1399 bFooterRulerChange = false;
1401 else if( aPixPt.Y() < ( aBottomLeft.Y() + 2 ) && aPixPt.Y() > ( aBottomLeft.Y() - 2 ) && !bTopRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1403 bTopRulerChange = false;
1404 bBottomRulerChange = true;
1405 bHeaderRulerChange = false;
1406 bFooterRulerChange = false;
1408 else if( aPixPt.Y() < ( aHeaderLeft.Y() + 2 ) && aPixPt.Y() > ( aHeaderLeft.Y() - 2 ) && !bTopRulerMove && !bBottomRulerMove && !bFooterRulerMove )
1410 bTopRulerChange = false;
1411 bBottomRulerChange = false;
1412 bHeaderRulerChange = true;
1413 bFooterRulerChange = false;
1415 else if( aPixPt.Y() < ( aFooderLeft.Y() + 2 ) && aPixPt.Y() > ( aFooderLeft.Y() - 2 ) && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove )
1417 bTopRulerChange = false;
1418 bBottomRulerChange = false;
1419 bHeaderRulerChange = false;
1420 bFooterRulerChange = true;
1423 if( bPageMargin )
1425 if(( (aPixPt.X() < ( aLeftTop.X() + 2 ) && aPixPt.X() > ( aLeftTop.X() - 2 )) || bLeftRulerMove ||
1426 ( aPixPt.X() < ( aRightTop.X() + 2 ) && aPixPt.X() > ( aRightTop.X() - 2 ) ) || bRightRulerMove || bOnColRulerChange || bColRulerMove )
1427 && aPixPt.Y() > aLeftTop.Y() && aPixPt.Y() < aLeftBottom.Y() )
1429 if( bOnColRulerChange || bColRulerMove )
1431 SetPointer( Pointer( POINTER_HSPLIT ) );
1432 if( bColRulerMove )
1434 if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
1435 DragMove( aMouseMovePoint.X(), POINTER_HSPLIT );
1438 else
1440 if( bLeftRulerChange && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1442 SetPointer( Pointer( POINTER_HSIZEBAR ) );
1443 if( bLeftRulerMove )
1445 if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
1446 DragMove( aMouseMovePoint.X(), POINTER_HSIZEBAR );
1449 else if( bRightRulerChange && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1451 SetPointer( Pointer( POINTER_HSIZEBAR ) );
1452 if( bRightRulerMove )
1454 if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
1455 DragMove( aMouseMovePoint.X(), POINTER_HSIZEBAR );
1460 else
1462 if( ( ( aPixPt.Y() < ( aTopLeft.Y() + 2 ) && aPixPt.Y() > ( aTopLeft.Y() - 2 ) ) || bTopRulerMove ||
1463 ( aPixPt.Y() < ( aBottomLeft.Y() + 2 ) && aPixPt.Y() > ( aBottomLeft.Y() - 2 ) ) || bBottomRulerMove ||
1464 ( aPixPt.Y() < ( aHeaderLeft.Y() + 2 ) && aPixPt.Y() > ( aHeaderLeft.Y() - 2 ) ) || bHeaderRulerMove ||
1465 ( aPixPt.Y() < ( aFooderLeft.Y() + 2 ) && aPixPt.Y() > ( aFooderLeft.Y() - 2 ) ) || bFooterRulerMove )
1466 && aPixPt.X() > aTopLeft.X() && aPixPt.X() < aTopRight.X() )
1468 if( bTopRulerChange )
1470 SetPointer( Pointer( POINTER_VSIZEBAR ) );
1471 if( bTopRulerMove )
1473 if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
1474 DragMove( aMouseMovePoint.Y(), POINTER_VSIZEBAR );
1477 else if( bBottomRulerChange )
1479 SetPointer( Pointer( POINTER_VSIZEBAR ) );
1480 if( bBottomRulerMove )
1482 if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
1483 DragMove( aMouseMovePoint.Y(), POINTER_VSIZEBAR );
1486 else if( bHeaderRulerChange )
1488 SetPointer( Pointer( POINTER_VSIZEBAR ) );
1489 if( bHeaderRulerMove )
1491 if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
1492 DragMove( aMouseMovePoint.Y(), POINTER_VSIZEBAR );
1495 else if( bFooterRulerChange )
1497 SetPointer( Pointer( POINTER_VSIZEBAR ) );
1498 if( bFooterRulerMove )
1500 if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
1501 DragMove( aMouseMovePoint.Y(), POINTER_VSIZEBAR );
1505 else
1506 SetPointer( Pointer( POINTER_ARROW ) );
1511 void ScPreview::InvalidateLocationData(sal_uLong nId)
1513 bLocationValid = false;
1514 if (pViewShell->HasAccessibilityObjects())
1515 pViewShell->BroadcastAccessibility( SfxSimpleHint( nId ) );
1518 void ScPreview::GetFocus()
1520 if (pViewShell->HasAccessibilityObjects())
1521 pViewShell->BroadcastAccessibility( ScAccWinFocusGotHint(GetAccessible()) );
1524 void ScPreview::LoseFocus()
1526 if (pViewShell->HasAccessibilityObjects())
1527 pViewShell->BroadcastAccessibility( ScAccWinFocusLostHint(GetAccessible()) );
1530 com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible> ScPreview::CreateAccessible()
1532 com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible> xAcc= GetAccessible(false);
1533 if (xAcc.is())
1535 return xAcc;
1538 ScAccessibleDocumentPagePreview* pAccessible =
1539 new ScAccessibleDocumentPagePreview( GetAccessibleParentWindow()->GetAccessible(), pViewShell );
1541 xAcc = pAccessible;
1542 SetAccessible(xAcc);
1543 pAccessible->Init();
1544 return xAcc;
1547 // MT: Removed Windows::SwitchView() introduced with IA2 CWS.
1548 // There are other notifications for this when the active view has chnaged, so please update the code to use that event mechanism
1549 void ScPreview::SwitchView()
1551 ScAccessibleDocumentBase* pAccDoc = static_cast<ScAccessibleDocumentBase*>(GetAccessible(false).get());
1552 if (pAccDoc)
1554 pAccDoc->SwitchViewFireFocus();
1558 void ScPreview::DragMove( long nDragMovePos, sal_uInt16 nFlags )
1560 Fraction aPreviewZoom( nZoom, 100 );
1561 Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
1562 MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
1563 SetMapMode( aMMMode );
1564 long nPos = nDragMovePos;
1565 if( nFlags == POINTER_HSIZEBAR || nFlags == POINTER_HSPLIT )
1567 if( nDragMovePos != aButtonDownChangePoint.X() )
1569 DrawInvert( aButtonDownChangePoint.X(), nFlags );
1570 aButtonDownChangePoint.X() = nPos;
1571 DrawInvert( aButtonDownChangePoint.X(), nFlags );
1574 else if( nFlags == POINTER_VSIZEBAR )
1576 if( nDragMovePos != aButtonDownChangePoint.Y() )
1578 DrawInvert( aButtonDownChangePoint.Y(), nFlags );
1579 aButtonDownChangePoint.Y() = nPos;
1580 DrawInvert( aButtonDownChangePoint.Y(), nFlags );
1585 void ScPreview::DrawInvert( long nDragPos, sal_uInt16 nFlags )
1587 long nHeight = (long) lcl_GetDocPageSize( pDocShell->GetDocument(), nTab ).Height();
1588 long nWidth = (long) lcl_GetDocPageSize( pDocShell->GetDocument(), nTab ).Width();
1589 if( nFlags == POINTER_HSIZEBAR || nFlags == POINTER_HSPLIT )
1591 Rectangle aRect( nDragPos, -aOffset.Y(), nDragPos + 1,(long)( ( nHeight * HMM_PER_TWIPS ) - aOffset.Y()));
1592 Invert( aRect,INVERT_50 );
1594 else if( nFlags == POINTER_VSIZEBAR )
1596 Rectangle aRect( -aOffset.X(), nDragPos,(long)( ( nWidth * HMM_PER_TWIPS ) - aOffset.X() ), nDragPos + 1 );
1597 Invert( aRect,INVERT_50 );
1601 void ScPreview::SetSelectedTabs(const ScMarkData& rMark)
1603 maSelectedTabs = rMark.GetSelectedTabs();
1606 const ScMarkData::MarkedTabsType& ScPreview::GetSelectedTabs() const
1608 return maSelectedTabs;
1611 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */