xref: /aoo41x/main/sc/source/ui/view/preview.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 
32 
33 // INCLUDE ---------------------------------------------------------------
34 #include <tools/pstm.hxx>
35 #include "scitems.hxx"
36 #include <editeng/eeitem.hxx>
37 
38 
39 #include <svtools/colorcfg.hxx>
40 #include <svx/fmview.hxx>
41 #include <editeng/sizeitem.hxx>
42 #include <svx/svdpagv.hxx>
43 #include <sfx2/bindings.hxx>
44 #include <sfx2/viewfrm.hxx>
45 #include <sfx2/dispatch.hxx>
46 #include <svtools/accessibilityoptions.hxx>
47 #include <svl/itemset.hxx>
48 #include <tools/multisel.hxx>
49 #include <vcl/waitobj.hxx>
50 #include <vcl/sound.hxx>
51 
52 #include "preview.hxx"
53 #include "prevwsh.hxx"
54 #include "prevloc.hxx"
55 #include "docsh.hxx"
56 #include "docfunc.hxx"
57 #include "printfun.hxx"
58 #include "printopt.hxx"
59 #include "stlpool.hxx"
60 #include "undostyl.hxx"
61 #include "drwlayer.hxx"
62 #include "scmod.hxx"
63 #include "globstr.hrc"
64 #include "sc.hrc"			// fuer ShellInvalidate
65 #include "AccessibleDocumentPagePreview.hxx"
66 #include <vcl/lineinfo.hxx>
67 #include <svx/algitem.hxx>
68 #include <editeng/lrspitem.hxx>
69 #include <editeng/ulspitem.hxx>
70 #include <editeng/sizeitem.hxx>
71 #include "attrib.hxx"
72 #include "pagepar.hxx"
73 #include <com/sun/star/accessibility/XAccessible.hpp>
74 #include "AccessibilityHints.hxx"
75 #include <vcl/svapp.hxx>
76 #include "viewutil.hxx"
77 
78 // STATIC DATA -----------------------------------------------------------
79 
80 //==================================================================
81 
82 #define SC_PREVIEW_SHADOWSIZE	2
83 
84 long lcl_GetDisplayStart( SCTAB nTab, ScDocument* pDoc, long* pPages )
85 {
86 	long nDisplayStart = 0;
87 	for (SCTAB i=0; i<nTab; i++)
88 	{
89 		if ( pDoc->NeedPageResetAfterTab(i) )
90 			nDisplayStart = 0;
91 		else
92 			nDisplayStart += pPages[i];
93 	}
94 	return nDisplayStart;
95 }
96 
97 
98 ScPreview::ScPreview( Window* pParent, ScDocShell* pDocSh, ScPreviewShell* pViewSh ) :
99 	Window( pParent ),
100 	nPageNo( 0 ),
101 	nZoom( 100 ),
102 	bValid( sal_False ),
103 	nTabsTested( 0 ),
104 	nTab( 0 ),
105 	nTabStart( 0 ),
106 	nDisplayStart( 0 ),
107 	nTotalPages( 0 ),
108 	bStateValid( sal_False ),
109 	bLocationValid( sal_False ),
110 	pLocationData( NULL ),
111 	pDrawView( NULL ),
112     bInPaint( false ),
113     bInSetZoom( false ),
114 	bInGetState( sal_False ),
115 	pDocShell( pDocSh ),
116     pViewShell( pViewSh ),
117     bLeftRulerMove( sal_False ),
118     bRightRulerMove( sal_False ),
119     bTopRulerMove( sal_False ),
120     bBottomRulerMove( sal_False ),
121     bHeaderRulerMove( sal_False ),
122     bFooterRulerMove( sal_False ),
123     bLeftRulerChange( sal_False ),
124     bRightRulerChange( sal_False ),
125     bTopRulerChange( sal_False ),
126     bBottomRulerChange( sal_False ),
127     bHeaderRulerChange( sal_False ),
128     bFooterRulerChange( sal_False ),
129     bPageMargin ( sal_False ),
130     bColRulerMove( sal_False ),
131     mnScale( 0 ),
132     nColNumberButttonDown( 0 ),
133     nHeaderHeight ( 0 ),
134     nFooterHeight ( 0 )
135 {
136     SetOutDevViewType( OUTDEV_VIEWTYPE_PRINTPREVIEW ); //#106611#
137 	SetBackground();
138 
139 	SetHelpId( HID_SC_WIN_PREVIEW );
140 	SetUniqueId( HID_SC_WIN_PREVIEW );
141 
142 	SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
143 
144     for (SCCOL i=0; i<=MAXCOL; i++)
145         nRight[i] = 0;                  // initialized with actual positions when markers are drawn
146 }
147 
148 
149 __EXPORT ScPreview::~ScPreview()
150 {
151 	delete pDrawView;
152 	delete pLocationData;
153 }
154 
155 void ScPreview::UpdateDrawView()		// nTab muss richtig sein
156 {
157 	ScDocument* pDoc = pDocShell->GetDocument();
158 	ScDrawLayer* pModel = pDoc->GetDrawLayer();		// ist nicht 0
159 
160 	// #114135#
161 	if ( pModel )
162 	{
163         SdrPage* pPage = pModel->GetPage(nTab);
164         if ( pDrawView && ( !pDrawView->GetSdrPageView() || pDrawView->GetSdrPageView()->GetPage() != pPage ) )
165 		{
166 			//	die angezeigte Page der DrawView umzustellen (s.u.) funktioniert nicht ?!?
167 			delete pDrawView;
168 			pDrawView = NULL;
169 		}
170 
171 		if ( !pDrawView )									// neu anlegen?
172 		{
173 			pDrawView = new FmFormView( pModel, this );
174 			// #55259# die DrawView uebernimmt den Design-Modus vom Model
175 			// (Einstellung "Im Entwurfsmodus oeffnen"), darum hier zuruecksetzen
176 			pDrawView->SetDesignMode( sal_True );
177 			pDrawView->SetPrintPreview( sal_True );
178             pDrawView->ShowSdrPage(pPage);
179 		}
180 #if 0
181 		else if ( !pDrawView->GetSdrPageView())		// angezeigte Page umstellen
182 		{
183 			pDrawView->HideSdrPage();
184 			pDrawView->ShowSdrPage(pDrawView->GetModel()->GetPage(nTab));
185 		}
186 #endif
187 	}
188 	else if ( pDrawView )
189 	{
190 		delete pDrawView;			// fuer diese Tabelle nicht gebraucht
191 		pDrawView = NULL;
192 	}
193 }
194 
195 
196 void ScPreview::TestLastPage()
197 {
198 	if (nPageNo >= nTotalPages)
199 	{
200 		if (nTotalPages)
201 		{
202 			nPageNo = nTotalPages - 1;
203 			nTab = nTabCount - 1;
204 			while (nTab > 0 && !nPages[nTab])		// letzte nicht leere Tabelle
205 				--nTab;
206 			DBG_ASSERT(nPages[nTab],"alle Tabellen leer?");
207 			nTabPage = nPages[nTab] - 1;
208 			nTabStart = 0;
209 			for (sal_uInt16 i=0; i<nTab; i++)
210 				nTabStart += nPages[i];
211 
212 			ScDocument* pDoc = pDocShell->GetDocument();
213 			nDisplayStart = lcl_GetDisplayStart( nTab, pDoc, nPages );
214 		}
215 		else		// leeres Dokument
216 		{
217 			nTab = 0;
218 			nPageNo = nTabPage = nTabStart = nDisplayStart = 0;
219 			aState.nPrintTab = 0;
220                         aState.nStartCol = aState.nEndCol = 0;
221                         aState.nStartRow = aState.nEndRow = 0;
222                         aState.nZoom = 0;
223 			aState.nPagesX = aState.nPagesY = 0;
224 			aState.nTabPages = aState.nTotalPages =
225 			aState.nPageStart = aState.nDocPages = 0;
226 		}
227 	}
228 }
229 
230 
231 void ScPreview::CalcPages( SCTAB /*nToWhichTab*/ )
232 {
233 	WaitObject( this );
234 
235 	ScDocument* pDoc = pDocShell->GetDocument();
236 	nTabCount = pDoc->GetTableCount();
237 
238 	//SCTAB nAnz = Min( nTabCount, SCTAB(nToWhichTab+1) );
239     SCTAB nAnz = nTabCount;
240 	SCTAB nStart = nTabsTested;
241 	if (!bValid)
242 	{
243 		nStart = 0;
244 		nTotalPages = 0;
245 		nTabsTested = 0;
246 	}
247 
248     // update all pending row heights with a single progress bar,
249     // instead of a separate progress for each sheet from ScPrintFunc
250     pDocShell->UpdatePendingRowHeights( nAnz-1, true );
251 
252 	//	PrintOptions is passed to PrintFunc for SkipEmpty flag,
253 	//	but always all sheets are used (there is no selected sheet)
254 	ScPrintOptions aOptions = SC_MOD()->GetPrintOptions();
255 
256 	for (SCTAB i=nStart; i<nAnz; i++)
257 	{
258 		long nAttrPage = i > 0 ? nFirstAttr[i-1] : 1;
259 
260 		long nThisStart = nTotalPages;
261 		ScPrintFunc aPrintFunc( this, pDocShell, i, nAttrPage, 0, NULL, &aOptions );
262 		long nThisTab = aPrintFunc.GetTotalPages();
263 		nPages[i] = nThisTab;
264 		nTotalPages += nThisTab;
265 		nFirstAttr[i] = aPrintFunc.GetFirstPageNo();	// behalten oder aus Vorlage
266 
267 		if (nPageNo>=nThisStart && nPageNo<nTotalPages)
268 		{
269 			nTab = i;
270 			nTabPage = nPageNo - nThisStart;
271 			nTabStart = nThisStart;
272 
273 			aPrintFunc.GetPrintState( aState );
274 			aPageSize = aPrintFunc.GetPageSize();
275 		}
276 	}
277 
278 	nDisplayStart = lcl_GetDisplayStart( nTab, pDoc, nPages );
279 
280 	if (nAnz > nTabsTested)
281 		nTabsTested = nAnz;
282 
283 	//	testen, ob hinter letzter Seite
284 
285 	if ( nTabsTested >= nTabCount )
286 		TestLastPage();
287 
288 	aState.nDocPages = nTotalPages;
289 
290 	bValid = sal_True;
291 	bStateValid = sal_True;
292 	DoInvalidate();
293 }
294 
295 
296 void ScPreview::RecalcPages()					// nur nPageNo geaendert
297 {
298 	if (!bValid)
299 		return;							// dann wird CalcPages aufgerufen
300 
301 	SCTAB nOldTab = nTab;
302 
303 	sal_Bool bDone = sal_False;
304 	while (nPageNo >= nTotalPages && nTabsTested < nTabCount)
305 	{
306 		CalcPages( nTabsTested );
307 		bDone = sal_True;
308 	}
309 
310 	if (!bDone)
311 	{
312 		long nPartPages = 0;
313 		for (SCTAB i=0; i<nTabsTested; i++)
314 		{
315 			long nThisStart = nPartPages;
316 			nPartPages += nPages[i];
317 
318 			if (nPageNo>=nThisStart && nPageNo<nPartPages)
319 			{
320 				nTab = i;
321 				nTabPage = nPageNo - nThisStart;
322 				nTabStart = nThisStart;
323 
324 //				aPageSize = aPrintFunc.GetPageSize();
325 			}
326 		}
327 
328 		ScDocument* pDoc = pDocShell->GetDocument();
329 		nDisplayStart = lcl_GetDisplayStart( nTab, pDoc, nPages );
330 	}
331 
332 	TestLastPage();			// testen, ob hinter letzter Seite
333 
334 	if ( nTab != nOldTab )
335 		bStateValid = sal_False;
336 
337 	DoInvalidate();
338 }
339 
340 
341 void ScPreview::DoPrint( ScPreviewLocationData* pFillLocation )
342 {
343 	if (!bValid)
344 	{
345 		CalcPages(0);
346 		RecalcPages();
347 		UpdateDrawView();		// Tabelle evtl. geaendert
348 	}
349 
350 	Fraction aPreviewZoom( nZoom, 100 );
351 	Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
352 	MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
353 
354 	sal_Bool bDoPrint = ( pFillLocation == NULL );
355 	sal_Bool bValidPage = ( nPageNo < nTotalPages );
356 
357 	ScModule* pScMod = SC_MOD();
358     const svtools::ColorConfig& rColorCfg = pScMod->GetColorConfig();
359     Color aBackColor( rColorCfg.GetColorValue(svtools::APPBACKGROUND).nColor );
360 
361 	if ( bDoPrint && ( aOffset.X() < 0 || aOffset.Y() < 0 ) && bValidPage )
362 	{
363 		SetMapMode( aMMMode );
364 		SetLineColor();
365 		SetFillColor(aBackColor);
366 
367 		Size aWinSize = GetOutputSize();
368 		if ( aOffset.X() < 0 )
369 			DrawRect(Rectangle( 0, 0, -aOffset.X(), aWinSize.Height() ));
370 		if ( aOffset.Y() < 0 )
371 			DrawRect(Rectangle( 0, 0, aWinSize.Width(), -aOffset.Y() ));
372 	}
373 
374     long   nLeftMargin = 0;
375     long   nRightMargin = 0;
376     long   nTopMargin = 0;
377     long   nBottomMargin = 0;
378     sal_Bool bHeaderOn = sal_False;
379     sal_Bool bFooterOn = sal_False;
380 
381     ScDocument* pDoc = pDocShell->GetDocument();
382     sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTab );
383 
384 	Size aLocalPageSize;
385 	if ( bValidPage )
386 	{
387 		ScPrintOptions aOptions = pScMod->GetPrintOptions();
388 
389 		ScPrintFunc* pPrintFunc;
390 		if (bStateValid)
391 			pPrintFunc = new ScPrintFunc( this, pDocShell, aState, &aOptions );
392 		else
393 			pPrintFunc = new ScPrintFunc( this, pDocShell, nTab, nFirstAttr[nTab], nTotalPages, NULL, &aOptions );
394 
395 		pPrintFunc->SetOffset(aOffset);
396 		pPrintFunc->SetManualZoom(nZoom);
397 		pPrintFunc->SetDateTime(aDate,aTime);
398 		pPrintFunc->SetClearFlag(sal_True);
399 		pPrintFunc->SetUseStyleColor( pScMod->GetAccessOptions().GetIsForPagePreviews() );
400 
401 		pPrintFunc->SetDrawView( pDrawView );
402 
403 		// MultiSelection fuer die eine Seite muss etwas umstaendlich erzeugt werden...
404 		Range aPageRange( nPageNo+1, nPageNo+1 );
405 		MultiSelection aPage( aPageRange );
406 		aPage.SetTotalRange( Range(0,RANGE_MAX) );
407 		aPage.Select( aPageRange );
408 
409         long nPrinted = pPrintFunc->DoPrint( aPage, nTabStart, nDisplayStart, bDoPrint, pFillLocation );
410 		DBG_ASSERT(nPrinted<=1, "was'n nu los?");
411 
412 		SetMapMode(aMMMode);
413 
414         //init nLeftMargin ... in the ScPrintFunc::InitParam!!!
415         nLeftMargin = pPrintFunc->GetLeftMargin();
416         nRightMargin = pPrintFunc->GetRightMargin();
417         nTopMargin = pPrintFunc->GetTopMargin();
418         nBottomMargin = pPrintFunc->GetBottomMargin();
419         nHeaderHeight = pPrintFunc->GetHeader().nHeight;
420         nFooterHeight = pPrintFunc->GetFooter().nHeight;
421         bHeaderOn = pPrintFunc->GetHeader().bEnable;
422         bFooterOn = pPrintFunc->GetFooter().bEnable;
423         mnScale = pPrintFunc->GetZoom();
424 
425         if ( bDoPrint && bPageMargin && pLocationData )     // don't make use of pLocationData while filling it
426         {
427             Rectangle aPixRect;
428             Rectangle aRectCellPosition;
429             Rectangle aRectPosition;
430             pLocationData->GetMainCellRange( aPageArea, aPixRect );
431             if( !bLayoutRTL )
432             {
433                 pLocationData->GetCellPosition( aPageArea.aStart, aRectPosition );
434                 nLeftPosition = aRectPosition.Left();
435                 for( SCCOL i = aPageArea.aStart.Col(); i <= aPageArea.aEnd.Col(); i++ )
436                 {
437                     pLocationData->GetCellPosition( ScAddress( i,aPageArea.aStart.Row(),aPageArea.aStart.Tab()),aRectCellPosition );
438                     nRight[i] = aRectCellPosition.Right();
439                 }
440             }
441             else
442             {
443                 pLocationData->GetCellPosition( aPageArea.aEnd, aRectPosition );
444                 nLeftPosition = aRectPosition.Right()+1;
445 
446                 pLocationData->GetCellPosition( aPageArea.aStart,aRectCellPosition );
447                 nRight[ aPageArea.aEnd.Col() ] = aRectCellPosition.Left();
448                 for( SCCOL i = aPageArea.aEnd.Col(); i > aPageArea.aStart.Col(); i-- )
449                 {
450                     pLocationData->GetCellPosition( ScAddress( i,aPageArea.aEnd.Row(),aPageArea.aEnd.Tab()),aRectCellPosition );
451                     nRight[ i-1 ] = nRight[ i ] + aRectCellPosition.Right() - aRectCellPosition.Left() + 1;
452                 }
453             }
454         }
455 
456 		if (nPrinted)	// wenn nichts, alles grau zeichnen
457 		{
458 			aLocalPageSize = pPrintFunc->GetPageSize();
459 			aLocalPageSize.Width()  = (long) (aLocalPageSize.Width()  * HMM_PER_TWIPS );
460 			aLocalPageSize.Height() = (long) (aLocalPageSize.Height() * HMM_PER_TWIPS );
461 
462             nLeftMargin = (long) ( nLeftMargin * HMM_PER_TWIPS );
463             nRightMargin = (long) ( nRightMargin * HMM_PER_TWIPS );
464             nTopMargin = (long) ( nTopMargin * HMM_PER_TWIPS );
465             nBottomMargin = (long) ( nBottomMargin * HMM_PER_TWIPS );
466             nHeaderHeight = (long) ( nHeaderHeight * HMM_PER_TWIPS * mnScale / 100 + nTopMargin );
467             nFooterHeight = (long) ( nFooterHeight * HMM_PER_TWIPS * mnScale / 100 + nBottomMargin );
468 		}
469 
470 		if (!bStateValid)
471 		{
472 			pPrintFunc->GetPrintState( aState );
473 			aState.nDocPages = nTotalPages;
474 			bStateValid = sal_True;
475 		}
476 		delete pPrintFunc;
477 	}
478 
479 	if ( bDoPrint )
480 	{
481 		long nPageEndX = aLocalPageSize.Width()  - aOffset.X();
482 		long nPageEndY = aLocalPageSize.Height() - aOffset.Y();
483 		if ( !bValidPage )
484 			nPageEndX = nPageEndY = 0;
485 
486 		Size aWinSize = GetOutputSize();
487 		Point aWinEnd( aWinSize.Width(), aWinSize.Height() );
488 		sal_Bool bRight  = nPageEndX <= aWinEnd.X();
489 		sal_Bool bBottom = nPageEndY <= aWinEnd.Y();
490 
491         if( bPageMargin && bValidPage )
492         {
493             SetMapMode(aMMMode);
494             SetLineColor( COL_BLACK );
495             DrawInvert( (long)( nTopMargin - aOffset.Y() ), POINTER_VSIZEBAR );
496             DrawInvert( (long)(nPageEndY - nBottomMargin ), POINTER_VSIZEBAR );
497             DrawInvert( (long)( nLeftMargin - aOffset.X() ), POINTER_HSIZEBAR );
498             DrawInvert( (long)( nPageEndX - nRightMargin ) , POINTER_HSIZEBAR );
499             if( bHeaderOn )
500             {
501                 DrawInvert( nHeaderHeight - aOffset.Y(), POINTER_VSIZEBAR );
502             }
503             if( bFooterOn )
504             {
505                 DrawInvert( nPageEndY - nFooterHeight, POINTER_VSIZEBAR );
506             }
507 
508             SetMapMode( MapMode( MAP_PIXEL ) );
509             for( int i= aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
510             {
511                 Point aColumnTop = LogicToPixel( Point( 0, -aOffset.Y() ) ,aMMMode );
512                 SetLineColor( COL_BLACK );
513                 SetFillColor( COL_BLACK );
514                 DrawRect( Rectangle( Point( nRight[i] - 2, aColumnTop.Y() ),Point( nRight[i] + 2 , 4 + aColumnTop.Y()) ));
515                 DrawLine( Point( nRight[i], aColumnTop.Y() ), Point( nRight[i],  10 + aColumnTop.Y()) );
516             }
517             SetMapMode( aMMMode );
518         }
519 
520 		if (bRight || bBottom)
521 		{
522             SetMapMode(aMMMode);
523 			SetLineColor();
524 			SetFillColor(aBackColor);
525 			if (bRight)
526 				DrawRect(Rectangle(nPageEndX,0, aWinEnd.X(),aWinEnd.Y()));
527 			if (bBottom)
528 			{
529 				if (bRight)
530 					DrawRect(Rectangle(0,nPageEndY, nPageEndX,aWinEnd.Y()));	// Ecke nicht doppelt
531 				else
532 					DrawRect(Rectangle(0,nPageEndY, aWinEnd.X(),aWinEnd.Y()));
533 			}
534 		}
535 
536 		if ( bValidPage )
537 		{
538             Color aBorderColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
539 
540 			//	draw border
541 
542 			if ( aOffset.X() <= 0 || aOffset.Y() <= 0 || bRight || bBottom )
543 			{
544 				SetLineColor( aBorderColor );
545 				SetFillColor();
546 
547 				Rectangle aPixel( LogicToPixel( Rectangle( -aOffset.X(), -aOffset.Y(), nPageEndX, nPageEndY ) ) );
548 				--aPixel.Right();
549 				--aPixel.Bottom();
550 				DrawRect( PixelToLogic( aPixel ) );
551 			}
552 
553 			//	draw shadow
554 
555 			SetLineColor();
556 			SetFillColor( aBorderColor );
557 
558 			Rectangle aPixel;
559 
560 			aPixel = LogicToPixel( Rectangle( nPageEndX, -aOffset.Y(), nPageEndX, nPageEndY ) );
561 			aPixel.Top() += SC_PREVIEW_SHADOWSIZE;
562 			aPixel.Right() += SC_PREVIEW_SHADOWSIZE - 1;
563 			aPixel.Bottom() += SC_PREVIEW_SHADOWSIZE - 1;
564 			DrawRect( PixelToLogic( aPixel ) );
565 
566 			aPixel = LogicToPixel( Rectangle( -aOffset.X(), nPageEndY, nPageEndX, nPageEndY ) );
567 			aPixel.Left() += SC_PREVIEW_SHADOWSIZE;
568 			aPixel.Right() += SC_PREVIEW_SHADOWSIZE - 1;
569 			aPixel.Bottom() += SC_PREVIEW_SHADOWSIZE - 1;
570 			DrawRect( PixelToLogic( aPixel ) );
571 		}
572 	}
573 }
574 
575 //Issue51656 Add resizeable margin on page preview from maoyg
576 void __EXPORT ScPreview::Paint( const Rectangle& /* rRect */ )
577 {
578     bool bWasInPaint = bInPaint;        // nested calls shouldn't be necessary, but allow for now
579     bInPaint = true;
580 
581     if (bPageMargin)
582         GetLocationData();              // fill location data for column positions
583     DoPrint( NULL );
584 	pViewShell->UpdateScrollBars();
585 
586     bInPaint = bWasInPaint;
587 }
588 //Issue51656 Add resizeable margin on page preview from maoyg
589 
590 void __EXPORT ScPreview::Command( const CommandEvent& rCEvt )
591 {
592 	sal_uInt16 nCmd = rCEvt.GetCommand();
593 	if ( nCmd == COMMAND_WHEEL || nCmd == COMMAND_STARTAUTOSCROLL || nCmd == COMMAND_AUTOSCROLL )
594 	{
595 		sal_Bool bDone = pViewShell->ScrollCommand( rCEvt );
596 		if (!bDone)
597 			Window::Command(rCEvt);
598 	}
599 	else if ( nCmd == COMMAND_CONTEXTMENU )
600 		SfxDispatcher::ExecutePopup();
601 	else
602 		Window::Command( rCEvt );
603 }
604 
605 
606 void __EXPORT ScPreview::KeyInput( const KeyEvent& rKEvt )
607 {
608     //  The + and - keys can't be configured as accelerator entries, so they must be handled directly
609     //  (in ScPreview, not ScPreviewShell -> only if the preview window has the focus)
610 
611     const KeyCode& rKeyCode = rKEvt.GetKeyCode();
612     sal_uInt16 nKey = rKeyCode.GetCode();
613     sal_Bool bHandled = sal_False;
614     if(!rKeyCode.GetModifier())
615     {
616         sal_uInt16 nSlot = 0;
617         switch(nKey)
618         {
619             case KEY_ADD:      nSlot = SID_PREVIEW_ZOOMIN;  break;
620             case KEY_ESCAPE:   nSlot = ScViewUtil::IsFullScreen( *pViewShell ) ? SID_CANCEL : SID_PREVIEW_CLOSE; break;
621             case KEY_SUBTRACT: nSlot = SID_PREVIEW_ZOOMOUT; break;
622         }
623         if(nSlot)
624         {
625             bHandled = sal_True;
626             pViewShell->GetViewFrame()->GetDispatcher()->Execute( nSlot, SFX_CALLMODE_ASYNCHRON );
627         }
628     }
629 
630     if ( !bHandled && !pViewShell->KeyInput(rKEvt) )
631         Window::KeyInput(rKEvt);
632 }
633 
634 
635 const ScPreviewLocationData& ScPreview::GetLocationData()
636 {
637 	if ( !pLocationData )
638 	{
639 		pLocationData = new ScPreviewLocationData( pDocShell->GetDocument(), this );
640 		bLocationValid = sal_False;
641 	}
642 	if ( !bLocationValid )
643 	{
644 		pLocationData->Clear();
645 		DoPrint( pLocationData );
646 		bLocationValid = sal_True;
647 	}
648 	return *pLocationData;
649 }
650 
651 
652 void ScPreview::DataChanged(sal_Bool bNewTime)
653 {
654 	if (bNewTime)
655 	{
656 		aDate = Date();
657 		aTime = Time();
658 	}
659 
660 	bValid = sal_False;
661 	InvalidateLocationData( SC_HINT_DATACHANGED );
662 	Invalidate();
663 }
664 
665 
666 String ScPreview::GetPosString()
667 {
668 	if (!bValid)
669 	{
670 		CalcPages(nTab);
671 		UpdateDrawView();		// Tabelle evtl. geaendert
672 	}
673 
674 	String aString( ScGlobal::GetRscString( STR_PAGE ) );
675 	aString += ' ';
676 	aString += String::CreateFromInt32(nPageNo+1);
677 
678 	if (nTabsTested >= nTabCount)
679 	{
680 		aString.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " / " ));
681 		aString += String::CreateFromInt32(nTotalPages);
682 	}
683 
684 	return aString;
685 }
686 
687 
688 void ScPreview::SetZoom(sal_uInt16 nNewZoom)
689 {
690 	if (nNewZoom < 20)
691 		nNewZoom = 20;
692 	if (nNewZoom > 400)
693 		nNewZoom = 400;
694 	if (nNewZoom != nZoom)
695 	{
696 		nZoom = nNewZoom;
697 
698 		//	apply new MapMode and call UpdateScrollBars to update aOffset
699 
700 		Fraction aPreviewZoom( nZoom, 100 );
701 		Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
702 		MapMode aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
703 		SetMapMode( aMMMode );
704 
705         bInSetZoom = true;              // don't scroll during SetYOffset in UpdateScrollBars
706 		pViewShell->UpdateScrollBars();
707         bInSetZoom = false;
708 
709 		bStateValid = sal_False;
710 		InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
711 		DoInvalidate();
712 		Invalidate();
713 	}
714 }
715 
716 
717 void ScPreview::SetPageNo( long nPage )
718 {
719 	nPageNo = nPage;
720 	RecalcPages();
721 	UpdateDrawView();		// Tabelle evtl. geaendert
722 	InvalidateLocationData( SC_HINT_DATACHANGED );
723 	Invalidate();
724 }
725 
726 
727 long ScPreview::GetFirstPage(SCTAB nTabP)
728 {
729 	SCTAB nDocTabCount = pDocShell->GetDocument()->GetTableCount();
730 	if (nTabP >= nDocTabCount)
731 		nTabP = nDocTabCount-1;
732 
733 	long nPage = 0;
734 	if (nTabP>0)
735 	{
736 		CalcPages( nTabP );
737 		UpdateDrawView();		// Tabelle evtl. geaendert
738 
739 		for (SCTAB i=0; i<nTabP; i++)
740 			nPage += nPages[i];
741 
742 		// bei leerer Tabelle vorhergehende Seite
743 
744 		if ( nPages[nTabP]==0 && nPage > 0 )
745 			--nPage;
746 	}
747 
748 	return nPage;
749 }
750 
751 
752 Size lcl_GetDocPageSize( ScDocument* pDoc, SCTAB nTab )
753 {
754 	String aName = pDoc->GetPageStyle( nTab );
755 	ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
756 	SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aName, SFX_STYLE_FAMILY_PAGE );
757 	if ( pStyleSheet )
758 	{
759 		SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
760 		return ((const SvxSizeItem&) rStyleSet.Get(ATTR_PAGE_SIZE)).GetSize();
761 	}
762 	else
763 	{
764 		DBG_ERROR( "PageStyle not found" );
765 		return Size();
766 	}
767 }
768 
769 
770 sal_uInt16 ScPreview::GetOptimalZoom(sal_Bool bWidthOnly)
771 {
772 	double nWinScaleX = ScGlobal::nScreenPPTX / pDocShell->GetOutputFactor();
773 	double nWinScaleY = ScGlobal::nScreenPPTY;
774 	Size aWinSize = GetOutputSizePixel();
775 
776 	//	desired margin is 0.25cm in default MapMode (like Writer),
777 	//	but some additional margin is introduced by integer scale values
778 	//	-> add only 0.10cm, so there is some margin in all cases.
779 	Size aMarginSize( LogicToPixel( Size( 100, 100 ), MAP_100TH_MM ) );
780 	aWinSize.Width()  -= 2 * aMarginSize.Width();
781 	aWinSize.Height() -= 2 * aMarginSize.Height();
782 
783 	Size aLocalPageSize = lcl_GetDocPageSize( pDocShell->GetDocument(), nTab );
784 	if ( aLocalPageSize.Width() && aLocalPageSize.Height() )
785 	{
786 		long nZoomX = (long) ( aWinSize.Width() * 100  / ( aLocalPageSize.Width() * nWinScaleX ));
787 		long nZoomY = (long) ( aWinSize.Height() * 100 / ( aLocalPageSize.Height() * nWinScaleY ));
788 
789 		long nOptimal = nZoomX;
790 		if (!bWidthOnly && nZoomY<nOptimal)
791 			nOptimal = nZoomY;
792 
793 		if (nOptimal<20)
794 			nOptimal = 20;
795 		if (nOptimal>400)
796 			nOptimal = 400;
797 
798 		return (sal_uInt16) nOptimal;
799 	}
800 	else
801 		return nZoom;
802 }
803 
804 
805 void ScPreview::SetXOffset( long nX )
806 {
807 	if ( aOffset.X() == nX )
808 		return;
809 
810 	if (bValid)
811 	{
812 		long nDif = LogicToPixel(aOffset).X() - LogicToPixel(Point(nX,0)).X();
813 		aOffset.X() = nX;
814         if (nDif && !bInSetZoom)
815 		{
816 			MapMode aOldMode = GetMapMode(); SetMapMode(MAP_PIXEL);
817 			Scroll( nDif, 0 );
818 			SetMapMode(aOldMode);
819 		}
820 	}
821 	else
822 	{
823 		aOffset.X() = nX;
824         if (!bInSetZoom)
825 			Invalidate();
826 	}
827 	InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
828     Paint(Rectangle());
829 }
830 
831 
832 void ScPreview::SetYOffset( long nY )
833 {
834 	if ( aOffset.Y() == nY )
835 		return;
836 
837 	if (bValid)
838 	{
839 		long nDif = LogicToPixel(aOffset).Y() - LogicToPixel(Point(0,nY)).Y();
840 		aOffset.Y() = nY;
841         if (nDif && !bInSetZoom)
842 		{
843 			MapMode aOldMode = GetMapMode(); SetMapMode(MAP_PIXEL);
844 			Scroll( 0, nDif );
845 			SetMapMode(aOldMode);
846 		}
847 	}
848 	else
849 	{
850 		aOffset.Y() = nY;
851         if (!bInSetZoom)
852 			Invalidate();
853 	}
854 	InvalidateLocationData( SC_HINT_ACC_VISAREACHANGED );
855     Paint(Rectangle());
856 }
857 
858 
859 void ScPreview::DoInvalidate()
860 {
861 	//	Wenn das ganze aus dem GetState der Shell gerufen wird,
862 	//	muss das Invalidate hinterher asynchron kommen...
863 
864 	if (bInGetState)
865 		Application::PostUserEvent( STATIC_LINK( this, ScPreview, InvalidateHdl ) );
866 	else
867 		StaticInvalidate();		// sofort
868 }
869 
870 void ScPreview::StaticInvalidate()
871 {
872 	//	static method, because it's called asynchronously
873 	//	-> must use current viewframe
874 
875 	SfxViewFrame* pViewFrm = SfxViewFrame::Current();
876 	if (!pViewFrm)
877 		return;
878 
879 	SfxBindings& rBindings = pViewFrm->GetBindings();
880 	rBindings.Invalidate(SID_STATUS_DOCPOS);
881 	rBindings.Invalidate(SID_STATUS_PAGESTYLE);
882 	rBindings.Invalidate(SID_PREVIEW_PREVIOUS);
883 	rBindings.Invalidate(SID_PREVIEW_NEXT);
884 	rBindings.Invalidate(SID_PREVIEW_FIRST);
885 	rBindings.Invalidate(SID_PREVIEW_LAST);
886 	rBindings.Invalidate(SID_ATTR_ZOOM);
887 	rBindings.Invalidate(SID_PREVIEW_ZOOMIN);
888 	rBindings.Invalidate(SID_PREVIEW_ZOOMOUT);
889     rBindings.Invalidate(SID_PREVIEW_SCALINGFACTOR);
890     rBindings.Invalidate(SID_ATTR_ZOOMSLIDER);
891 }
892 
893 IMPL_STATIC_LINK( ScPreview, InvalidateHdl, void*, EMPTYARG )
894 {
895     (void)pThis;    // avoid warning
896 
897 	StaticInvalidate();
898 	return 0;
899 }
900 
901 void ScPreview::DataChanged( const DataChangedEvent& rDCEvt )
902 {
903 	Window::DataChanged(rDCEvt);
904 
905 	if ( (rDCEvt.GetType() == DATACHANGED_PRINTER) ||
906 		 (rDCEvt.GetType() == DATACHANGED_DISPLAY) ||
907 		 (rDCEvt.GetType() == DATACHANGED_FONTS) ||
908 		 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
909 		 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
910 		  (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
911 	{
912 		if ( rDCEvt.GetType() == DATACHANGED_FONTS )
913 			pDocShell->UpdateFontList();
914 
915         // #i114518# Paint of form controls may modify the window's settings.
916         // Ignore the event if it is called from within Paint.
917         if ( !bInPaint )
918         {
919             if ( rDCEvt.GetType() == DATACHANGED_SETTINGS &&
920                   (rDCEvt.GetFlags() & SETTINGS_STYLE) )
921             {
922                 //  scroll bar size may have changed
923                 pViewShell->InvalidateBorder();     // calls OuterResizePixel
924             }
925 
926             Invalidate();
927             InvalidateLocationData( SC_HINT_DATACHANGED );
928         }
929 	}
930 }
931 
932 //Issue51656 Add resizeable margin on page preview from maoyg
933 void __EXPORT ScPreview::MouseButtonDown( const MouseEvent& rMEvt )
934 {
935     Fraction  aPreviewZoom( nZoom, 100 );
936     Fraction  aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
937     MapMode   aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
938 
939     aButtonDownChangePoint = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
940     aButtonDownPt = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
941 
942     CaptureMouse();
943 
944     if( rMEvt.IsLeft() && GetPointer() == POINTER_HSIZEBAR )
945     {
946         SetMapMode( aMMMode );
947         if( bLeftRulerChange )
948         {
949            DrawInvert( aButtonDownChangePoint.X(), POINTER_HSIZEBAR );
950            bLeftRulerMove = sal_True;
951            bRightRulerMove = sal_False;
952         }
953         else if( bRightRulerChange )
954         {
955            DrawInvert( aButtonDownChangePoint.X(), POINTER_HSIZEBAR );
956            bLeftRulerMove = sal_False;
957            bRightRulerMove = sal_True;
958         }
959     }
960 
961     if( rMEvt.IsLeft() && GetPointer() == POINTER_VSIZEBAR )
962     {
963         SetMapMode( aMMMode );
964         if( bTopRulerChange )
965         {
966             DrawInvert( aButtonDownChangePoint.Y(), POINTER_VSIZEBAR );
967             bTopRulerMove = sal_True;
968             bBottomRulerMove = sal_False;
969         }
970         else if( bBottomRulerChange )
971         {
972             DrawInvert( aButtonDownChangePoint.Y(), POINTER_VSIZEBAR );
973             bTopRulerMove = sal_False;
974             bBottomRulerMove = sal_True;
975         }
976         else if( bHeaderRulerChange )
977         {
978             DrawInvert( aButtonDownChangePoint.Y(), POINTER_VSIZEBAR );
979             bHeaderRulerMove = sal_True;
980             bFooterRulerMove = sal_False;
981         }
982         else if( bFooterRulerChange )
983         {
984             DrawInvert( aButtonDownChangePoint.Y(), POINTER_VSIZEBAR );
985             bHeaderRulerMove = sal_False;
986             bFooterRulerMove = sal_True;
987         }
988     }
989 
990     if( rMEvt.IsLeft() && GetPointer() == POINTER_HSPLIT )
991     {
992         Point  aNowPt = rMEvt.GetPosPixel();
993         SCCOL i = 0;
994         for( i = aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
995         {
996             if( aNowPt.X() < nRight[i] + 2 && aNowPt.X() > nRight[i] - 2 )
997             {
998                 nColNumberButttonDown = i;
999                 break;
1000             }
1001         }
1002         if( i == aPageArea.aEnd.Col()+1 )
1003             return;
1004 
1005         SetMapMode( aMMMode );
1006         if( nColNumberButttonDown == aPageArea.aStart.Col() )
1007             DrawInvert( PixelToLogic( Point( nLeftPosition, 0 ),aMMMode ).X() ,POINTER_HSPLIT );
1008         else
1009             DrawInvert( PixelToLogic( Point( nRight[ nColNumberButttonDown-1 ], 0 ),aMMMode ).X() ,POINTER_HSPLIT );
1010 
1011         DrawInvert( aButtonDownChangePoint.X(), POINTER_HSPLIT );
1012         bColRulerMove = sal_True;
1013     }
1014 }
1015 
1016 void __EXPORT ScPreview::MouseButtonUp( const MouseEvent& rMEvt )
1017 {
1018         Fraction  aPreviewZoom( nZoom, 100 );
1019         Fraction  aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
1020         MapMode   aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
1021 
1022         aButtonUpPt = PixelToLogic( rMEvt.GetPosPixel(),aMMMode );
1023 
1024         long  nWidth = (long) lcl_GetDocPageSize(pDocShell->GetDocument(), nTab).Width();
1025         long  nHeight = (long) lcl_GetDocPageSize(pDocShell->GetDocument(), nTab).Height();
1026 
1027         if( rMEvt.IsLeft() && GetPointer() == POINTER_HSIZEBAR )
1028         {
1029             SetPointer( Pointer( POINTER_ARROW ) );
1030 
1031             sal_Bool bMoveRulerAction= sal_True;
1032 
1033             ScDocument * pDoc = pDocShell->GetDocument();
1034             String   aOldName = pDoc->GetPageStyle( nTab );
1035             sal_Bool  bUndo( pDoc->IsUndoEnabled() );
1036             ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
1037             SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aOldName, SFX_STYLE_FAMILY_PAGE );
1038 
1039             if ( pStyleSheet )
1040             {
1041                 ScStyleSaveData aOldData;
1042                 if( bUndo )
1043                     aOldData.InitFromStyle( pStyleSheet );
1044 
1045                 SfxItemSet&  rStyleSet = pStyleSheet->GetItemSet();
1046 
1047                 SvxLRSpaceItem aLRItem = ( const SvxLRSpaceItem& ) rStyleSet.Get( ATTR_LRSPACE );
1048 
1049                 if(( bLeftRulerChange || bRightRulerChange ) && ( aButtonUpPt.X() <= ( 0 - aOffset.X() ) || aButtonUpPt.X() > nWidth * HMM_PER_TWIPS - aOffset.X() ) )
1050                 {
1051                     bMoveRulerAction = sal_False;
1052                     Paint(Rectangle(0,0,10000,10000));
1053                 }
1054                 else if( bLeftRulerChange && ( aButtonUpPt.X() / HMM_PER_TWIPS > nWidth - aLRItem.GetRight() - aOffset.X() / HMM_PER_TWIPS ) )
1055                 {
1056                     bMoveRulerAction = sal_False;
1057                     Paint(Rectangle(0,0,10000,10000));
1058                 }
1059                 else if( bRightRulerChange && ( aButtonUpPt.X() / HMM_PER_TWIPS < aLRItem.GetLeft() - aOffset.X() / HMM_PER_TWIPS ) )
1060                 {
1061                     bMoveRulerAction = sal_False;
1062                     Paint(Rectangle(0,0,10000,10000));
1063                 }
1064                 else if( aButtonDownPt.X() == aButtonUpPt.X() )
1065                 {
1066                     bMoveRulerAction = sal_False;
1067                     DrawInvert( aButtonUpPt.X(), POINTER_HSIZEBAR );
1068                 }
1069                 if( bMoveRulerAction )
1070                 {
1071                     ScDocShellModificator aModificator( *pDocShell );
1072                     if( bLeftRulerChange && bLeftRulerMove )
1073                     {
1074                        aLRItem.SetLeft( (long)( aButtonUpPt.X() / HMM_PER_TWIPS + aOffset.X() / HMM_PER_TWIPS ));
1075                        rStyleSet.Put( aLRItem );
1076                     }
1077                     else if( bRightRulerChange && bRightRulerMove )
1078                     {
1079                         aLRItem.SetRight( (long)( nWidth - aButtonUpPt.X() / HMM_PER_TWIPS - aOffset.X() / HMM_PER_TWIPS ));
1080                         rStyleSet.Put( aLRItem );
1081                     }
1082 
1083                     ScStyleSaveData aNewData;
1084                     aNewData.InitFromStyle( pStyleSheet );
1085                     if( bUndo )
1086                     {
1087                         pDocShell->GetUndoManager()->AddUndoAction(
1088                             new ScUndoModifyStyle( pDocShell, SFX_STYLE_FAMILY_PAGE,
1089                             aOldData, aNewData ) );
1090                     }
1091 
1092                     if ( ValidTab( nTab ) )
1093                     {
1094                         ScPrintFunc aPrintFunc( this, pDocShell, nTab );
1095                         aPrintFunc.UpdatePages();
1096                     }
1097 
1098                     Rectangle aRect(0,0,10000,10000);
1099                     Paint( aRect );
1100                     aModificator.SetDocumentModified();
1101                     bLeftRulerChange = sal_False;
1102                     bRightRulerChange = sal_False;
1103                 }
1104             }
1105             bLeftRulerMove = sal_False;
1106             bRightRulerMove = sal_False;
1107         }
1108 
1109         if( rMEvt.IsLeft() && GetPointer() == POINTER_VSIZEBAR )
1110         {
1111             SetPointer( POINTER_ARROW );
1112 
1113             sal_Bool  bMoveRulerAction = sal_True;
1114             if( ( bTopRulerChange || bBottomRulerChange || bHeaderRulerChange || bFooterRulerChange ) && ( aButtonUpPt.Y() <= ( 0 - aOffset.Y() ) || aButtonUpPt.Y() > nHeight * HMM_PER_TWIPS -aOffset.Y() ) )
1115             {
1116                 bMoveRulerAction = sal_False;
1117                 Paint( Rectangle(0,0,10000,10000) );
1118             }
1119             else if( aButtonDownPt.Y() == aButtonUpPt.Y() )
1120             {
1121                 bMoveRulerAction = sal_False;
1122                 DrawInvert( aButtonUpPt.Y(), POINTER_VSIZEBAR );
1123             }
1124             if( bMoveRulerAction )
1125             {
1126                 ScDocument * pDoc = pDocShell->GetDocument();
1127                 sal_Bool  bUndo( pDoc->IsUndoEnabled() );
1128                 ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
1129                 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( pDoc->GetPageStyle( nTab ), SFX_STYLE_FAMILY_PAGE );
1130                 DBG_ASSERT( pStyleSheet, "PageStyle not found" );
1131                 if ( pStyleSheet )
1132                 {
1133                     ScDocShellModificator aModificator( *pDocShell );
1134                     ScStyleSaveData aOldData;
1135                     if( bUndo )
1136                         aOldData.InitFromStyle( pStyleSheet );
1137 
1138                     SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
1139 
1140                     SvxULSpaceItem aULItem = ( const SvxULSpaceItem&)rStyleSet.Get( ATTR_ULSPACE );
1141 
1142                     if( bTopRulerMove && bTopRulerChange )
1143                     {
1144                         aULItem.SetUpperValue( (sal_uInt16)( aButtonUpPt.Y() / HMM_PER_TWIPS + aOffset.Y() / HMM_PER_TWIPS ) );
1145                         rStyleSet.Put( aULItem );
1146                     }
1147                     else if( bBottomRulerMove && bBottomRulerChange )
1148                     {
1149                         aULItem.SetLowerValue( (sal_uInt16)( nHeight - aButtonUpPt.Y() / HMM_PER_TWIPS - aOffset.Y() / HMM_PER_TWIPS ) );
1150                         rStyleSet.Put( aULItem );
1151                     }
1152                     else if( bHeaderRulerMove && bHeaderRulerChange )
1153                     {
1154                         const SfxPoolItem* pItem = NULL;
1155                         if ( rStyleSet.GetItemState( ATTR_PAGE_HEADERSET, sal_False, &pItem ) == SFX_ITEM_SET )
1156                         {
1157                             SfxItemSet& pHeaderSet = ((SvxSetItem*)pItem)->GetItemSet();
1158                             Size  aHeaderSize = ((const SvxSizeItem&)pHeaderSet.Get(ATTR_PAGE_SIZE)).GetSize();
1159                             aHeaderSize.Height() = (long)( aButtonUpPt.Y() / HMM_PER_TWIPS + aOffset.Y() / HMM_PER_TWIPS - aULItem.GetUpper());
1160                             aHeaderSize.Height() = aHeaderSize.Height() * 100 / mnScale;
1161                             SvxSetItem  aNewHeader( (const SvxSetItem&)rStyleSet.Get(ATTR_PAGE_HEADERSET) );
1162                             aNewHeader.GetItemSet().Put( SvxSizeItem( ATTR_PAGE_SIZE, aHeaderSize ) );
1163                             rStyleSet.Put( aNewHeader );
1164                         }
1165                     }
1166                     else if( bFooterRulerMove && bFooterRulerChange )
1167                     {
1168                         const SfxPoolItem* pItem = NULL;
1169                         if( rStyleSet.GetItemState( ATTR_PAGE_FOOTERSET, sal_False, &pItem ) == SFX_ITEM_SET )
1170                         {
1171                             SfxItemSet& pFooterSet = ((SvxSetItem*)pItem)->GetItemSet();
1172                             Size aFooterSize = ((const SvxSizeItem&)pFooterSet.Get(ATTR_PAGE_SIZE)).GetSize();
1173                             aFooterSize.Height() = (long)( nHeight - aButtonUpPt.Y() / HMM_PER_TWIPS - aOffset.Y() / HMM_PER_TWIPS - aULItem.GetLower() );
1174                             aFooterSize.Height() = aFooterSize.Height() * 100 / mnScale;
1175                             SvxSetItem  aNewFooter( (const SvxSetItem&)rStyleSet.Get(ATTR_PAGE_FOOTERSET) );
1176                             aNewFooter.GetItemSet().Put( SvxSizeItem( ATTR_PAGE_SIZE, aFooterSize ) );
1177                             rStyleSet.Put( aNewFooter );
1178                         }
1179                     }
1180 
1181                     ScStyleSaveData aNewData;
1182                     aNewData.InitFromStyle( pStyleSheet );
1183                     if( bUndo )
1184                     {
1185                         pDocShell->GetUndoManager()->AddUndoAction(
1186                             new ScUndoModifyStyle( pDocShell, SFX_STYLE_FAMILY_PAGE,
1187                             aOldData, aNewData ) );
1188                     }
1189 
1190                     if ( ValidTab( nTab ) )
1191                     {
1192                         ScPrintFunc aPrintFunc( this, pDocShell, nTab );
1193                         aPrintFunc.UpdatePages();
1194                     }
1195 
1196                     Rectangle  aRect(0,0,10000,10000);
1197                     Paint( aRect );
1198                     aModificator.SetDocumentModified();
1199                     bTopRulerChange = sal_False;
1200                     bBottomRulerChange = sal_False;
1201                     bHeaderRulerChange = sal_False;
1202                     bFooterRulerChange = sal_False;
1203                  }
1204               }
1205               bTopRulerMove = sal_False;
1206               bBottomRulerMove = sal_False;
1207               bHeaderRulerMove = sal_False;
1208               bFooterRulerMove = sal_False;
1209         }
1210         if( rMEvt.IsLeft() && GetPointer() == POINTER_HSPLIT )
1211         {
1212             SetPointer(POINTER_ARROW);
1213             ScDocument* pDoc = pDocShell->GetDocument();
1214             sal_Bool  bLayoutRTL = pDoc->IsLayoutRTL( nTab );
1215             sal_Bool  bMoveRulerAction = sal_True;
1216             if( aButtonDownPt.X() == aButtonUpPt.X() )
1217             {
1218                 bMoveRulerAction = sal_False;
1219                 if( nColNumberButttonDown == aPageArea.aStart.Col() )
1220                     DrawInvert( PixelToLogic( Point( nLeftPosition, 0 ),aMMMode ).X() ,POINTER_HSPLIT );
1221                 else
1222                     DrawInvert( PixelToLogic( Point( nRight[ nColNumberButttonDown-1 ], 0 ),aMMMode ).X() ,POINTER_HSPLIT );
1223                 DrawInvert( aButtonUpPt.X(), POINTER_HSPLIT );
1224             }
1225             if( bMoveRulerAction )
1226             {
1227                 long  nNewColWidth = 0;
1228                 ScDocFunc aFunc(*pDocShell);
1229                 SCCOLROW nCols[2] = { nColNumberButttonDown, nColNumberButttonDown };
1230 
1231                 if( !bLayoutRTL )
1232                 {
1233                     nNewColWidth = (long) ( PixelToLogic( Point( rMEvt.GetPosPixel().X() - nRight[ nColNumberButttonDown ], 0), aMMMode ).X() / HMM_PER_TWIPS ) * 100 / mnScale;
1234                     nNewColWidth += pDocShell->GetDocument()->GetColWidth( nColNumberButttonDown, nTab );
1235                 }
1236                 else
1237                 {
1238 
1239                     nNewColWidth = (long) ( PixelToLogic( Point( nRight[ nColNumberButttonDown ] - rMEvt.GetPosPixel().X(), 0), aMMMode ).X() / HMM_PER_TWIPS ) * 100 / mnScale;
1240                     nNewColWidth += pDocShell->GetDocument()->GetColWidth( nColNumberButttonDown, nTab );
1241                 }
1242 
1243                 if( nNewColWidth >= 0 )
1244                 {
1245                     aFunc.SetWidthOrHeight( sal_True, 1,nCols, nTab, SC_SIZE_DIRECT, (sal_uInt16)nNewColWidth, sal_True, sal_True);
1246                 }
1247                 if ( ValidTab( nTab ) )
1248                 {
1249                     ScPrintFunc aPrintFunc( this, pDocShell, nTab );
1250                     aPrintFunc.UpdatePages();
1251                 }
1252                 Rectangle  nRect(0,0,10000,10000);
1253                 Paint( nRect );
1254             }
1255             bColRulerMove = sal_False;
1256         }
1257         ReleaseMouse();
1258 }
1259 
1260 void __EXPORT ScPreview::MouseMove( const MouseEvent& rMEvt )
1261 {
1262     Fraction aPreviewZoom( nZoom, 100 );
1263     Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
1264     MapMode  aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
1265     Point    aMouseMovePoint = PixelToLogic( rMEvt.GetPosPixel(), aMMMode );
1266 
1267     long    nLeftMargin = 0;
1268     long    nRightMargin = 0;
1269     long    nTopMargin = 0;
1270     long    nBottomMargin = 0;
1271     Size    PageSize;
1272 
1273     long    nWidth = (long) lcl_GetDocPageSize(pDocShell->GetDocument(), nTab).Width();
1274     long    nHeight = (long) lcl_GetDocPageSize(pDocShell->GetDocument(), nTab).Height();
1275 
1276     if ( nPageNo < nTotalPages )
1277     {
1278         ScPrintOptions aOptions = SC_MOD()->GetPrintOptions();
1279 
1280         ScPrintFunc* pPrintFunc;
1281 
1282         if (bStateValid)
1283             pPrintFunc = new ScPrintFunc( this, pDocShell, aState, &aOptions );
1284         else
1285             pPrintFunc = new ScPrintFunc( this, pDocShell, nTab, nFirstAttr[nTab], nTotalPages, NULL, &aOptions );
1286 
1287         nLeftMargin = (long)( pPrintFunc->GetLeftMargin() * HMM_PER_TWIPS - aOffset.X() );
1288         nRightMargin = (long)( pPrintFunc->GetRightMargin() * HMM_PER_TWIPS );
1289         nRightMargin = (long)( nWidth * HMM_PER_TWIPS - nRightMargin - aOffset.X() );
1290         nTopMargin = (long)( pPrintFunc->GetTopMargin() * HMM_PER_TWIPS - aOffset.Y() );
1291         nBottomMargin = (long)( pPrintFunc->GetBottomMargin() * HMM_PER_TWIPS );
1292         nBottomMargin = (long)( nHeight * HMM_PER_TWIPS - nBottomMargin - aOffset.Y() );
1293         if( mnScale > 0 )
1294         {
1295             nHeaderHeight = (long)( nTopMargin + pPrintFunc->GetHeader().nHeight * HMM_PER_TWIPS * mnScale / 100 );
1296             nFooterHeight = (long)( nBottomMargin - pPrintFunc->GetFooter().nHeight * HMM_PER_TWIPS * mnScale / 100 );
1297         }
1298         else
1299         {
1300             nHeaderHeight = (long)( nTopMargin + pPrintFunc->GetHeader().nHeight * HMM_PER_TWIPS );
1301             nFooterHeight = (long)( nBottomMargin - pPrintFunc->GetFooter().nHeight * HMM_PER_TWIPS );
1302         }
1303         delete pPrintFunc;
1304     }
1305 
1306     Point   aPixPt( rMEvt.GetPosPixel() );
1307     Point   aLeftTop = LogicToPixel( Point( nLeftMargin, -aOffset.Y() ) , aMMMode );
1308     Point   aLeftBottom = LogicToPixel( Point( nLeftMargin ,(long)(nHeight * HMM_PER_TWIPS - aOffset.Y()) ), aMMMode );
1309     Point   aRightTop = LogicToPixel( Point( nRightMargin, -aOffset.Y() ), aMMMode );
1310     Point   aTopLeft = LogicToPixel( Point( -aOffset.X(), nTopMargin ), aMMMode );
1311     Point   aTopRight = LogicToPixel( Point( (long)(nWidth * HMM_PER_TWIPS - aOffset.X()), nTopMargin ), aMMMode );
1312     Point   aBottomLeft = LogicToPixel( Point( -aOffset.X(), nBottomMargin ), aMMMode );
1313     Point   aHeaderLeft = LogicToPixel( Point(  -aOffset.X(), nHeaderHeight ), aMMMode );
1314     Point   aFooderLeft = LogicToPixel( Point( -aOffset.X(), nFooterHeight ), aMMMode );
1315 
1316     sal_Bool   bOnColRulerChange = sal_False;
1317 
1318     for( SCCOL i=aPageArea.aStart.Col(); i<= aPageArea.aEnd.Col(); i++ )
1319     {
1320         Point   aColumnTop = LogicToPixel( Point( 0, -aOffset.Y() ) ,aMMMode );
1321         Point   aColumnBottom = LogicToPixel( Point( 0, (long)( nHeight * HMM_PER_TWIPS - aOffset.Y()) ), aMMMode );
1322         if( aPixPt.X() < ( nRight[i] + 2 ) && ( aPixPt.X() > ( nRight[i] - 2 ) ) && ( aPixPt.X() < aRightTop.X() ) && ( aPixPt.X() > aLeftTop.X() )
1323             && ( aPixPt.Y() > aColumnTop.Y() ) && ( aPixPt.Y() < aColumnBottom.Y() ) && !bLeftRulerMove && !bRightRulerMove
1324             && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1325         {
1326             bOnColRulerChange = sal_True;
1327             if( !rMEvt.GetButtons() && GetPointer() == POINTER_HSPLIT )
1328                 nColNumberButttonDown = i;
1329             break;
1330         }
1331     }
1332 
1333     if( aPixPt.X() < ( aLeftTop.X() + 2 ) && aPixPt.X() > ( aLeftTop.X() - 2 ) && !bRightRulerMove )
1334     {
1335         bLeftRulerChange = sal_True;
1336         bRightRulerChange = sal_False;
1337     }
1338     else if( aPixPt.X() < ( aRightTop.X() + 2 ) && aPixPt.X() > ( aRightTop.X() - 2 ) && !bLeftRulerMove )
1339     {
1340         bLeftRulerChange = sal_False;
1341         bRightRulerChange = sal_True;
1342     }
1343     else if( aPixPt.Y() < ( aTopLeft.Y() + 2 ) && aPixPt.Y() > ( aTopLeft.Y() - 2 ) && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1344     {
1345         bTopRulerChange = sal_True;
1346         bBottomRulerChange = sal_False;
1347         bHeaderRulerChange = sal_False;
1348         bFooterRulerChange = sal_False;
1349     }
1350     else if( aPixPt.Y() < ( aBottomLeft.Y() + 2 ) && aPixPt.Y() > ( aBottomLeft.Y() - 2 ) && !bTopRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1351     {
1352         bTopRulerChange = sal_False;
1353         bBottomRulerChange = sal_True;
1354         bHeaderRulerChange = sal_False;
1355         bFooterRulerChange = sal_False;
1356     }
1357     else if( aPixPt.Y() < ( aHeaderLeft.Y() + 2 ) && aPixPt.Y() > ( aHeaderLeft.Y() - 2 ) && !bTopRulerMove && !bBottomRulerMove && !bFooterRulerMove )
1358     {
1359         bTopRulerChange = sal_False;
1360         bBottomRulerChange = sal_False;
1361         bHeaderRulerChange = sal_True;
1362         bFooterRulerChange = sal_False;
1363     }
1364     else if( aPixPt.Y() < ( aFooderLeft.Y() + 2 ) && aPixPt.Y() > ( aFooderLeft.Y() - 2 ) && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove )
1365     {
1366         bTopRulerChange = sal_False;
1367         bBottomRulerChange = sal_False;
1368         bHeaderRulerChange = sal_False;
1369         bFooterRulerChange = sal_True;
1370     }
1371 
1372     if( bPageMargin )
1373     {
1374         if(( (aPixPt.X() < ( aLeftTop.X() + 2 ) && aPixPt.X() > ( aLeftTop.X() - 2 )) || bLeftRulerMove ||
1375             ( aPixPt.X() < ( aRightTop.X() + 2 ) && aPixPt.X() > ( aRightTop.X() - 2 ) ) || bRightRulerMove || bOnColRulerChange || bColRulerMove )
1376             && aPixPt.Y() > aLeftTop.Y() && aPixPt.Y() < aLeftBottom.Y() )
1377         {
1378             if( bOnColRulerChange || bColRulerMove )
1379             {
1380                 SetPointer( Pointer( POINTER_HSPLIT ) );
1381                 if( bColRulerMove )
1382                 {
1383                     if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
1384                        DragMove( aMouseMovePoint.X(), POINTER_HSPLIT );
1385                 }
1386             }
1387             else
1388             {
1389                 if( bLeftRulerChange && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1390                 {
1391                     SetPointer( Pointer( POINTER_HSIZEBAR ) );
1392                     if( bLeftRulerMove )
1393                     {
1394                        if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
1395                            DragMove( aMouseMovePoint.X(), POINTER_HSIZEBAR );
1396                     }
1397                 }
1398                 else if( bRightRulerChange && !bTopRulerMove && !bBottomRulerMove && !bHeaderRulerMove && !bFooterRulerMove )
1399                 {
1400                     SetPointer( Pointer( POINTER_HSIZEBAR ) );
1401                     if( bRightRulerMove )
1402                     {
1403                        if( aMouseMovePoint.X() > -aOffset.X() && aMouseMovePoint.X() < nWidth * HMM_PER_TWIPS - aOffset.X() )
1404                            DragMove( aMouseMovePoint.X(), POINTER_HSIZEBAR );
1405                     }
1406                 }
1407             }
1408         }
1409         else
1410         {
1411             if( ( ( aPixPt.Y() < ( aTopLeft.Y() + 2 ) && aPixPt.Y() > ( aTopLeft.Y() - 2 ) ) || bTopRulerMove ||
1412                 ( aPixPt.Y() < ( aBottomLeft.Y() + 2 ) && aPixPt.Y() > ( aBottomLeft.Y() - 2 ) ) || bBottomRulerMove ||
1413                 ( aPixPt.Y() < ( aHeaderLeft.Y() + 2 ) && aPixPt.Y() > ( aHeaderLeft.Y() - 2 ) ) || bHeaderRulerMove ||
1414                 ( aPixPt.Y() < ( aFooderLeft.Y() + 2 ) && aPixPt.Y() > ( aFooderLeft.Y() - 2 ) ) || bFooterRulerMove )
1415                 && aPixPt.X() > aTopLeft.X() && aPixPt.X() < aTopRight.X() )
1416             {
1417                 if( bTopRulerChange )
1418                 {
1419                     SetPointer( Pointer( POINTER_VSIZEBAR ) );
1420                     if( bTopRulerMove )
1421                     {
1422                         if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
1423                             DragMove( aMouseMovePoint.Y(), POINTER_VSIZEBAR );
1424                     }
1425                 }
1426                 else if( bBottomRulerChange )
1427                 {
1428                     SetPointer( Pointer( POINTER_VSIZEBAR ) );
1429                     if( bBottomRulerMove )
1430                     {
1431                         if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
1432                             DragMove( aMouseMovePoint.Y(), POINTER_VSIZEBAR );
1433                     }
1434                 }
1435                 else if( bHeaderRulerChange )
1436                 {
1437                     SetPointer( Pointer( POINTER_VSIZEBAR ) );
1438                     if( bHeaderRulerMove )
1439                     {
1440                         if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
1441                             DragMove( aMouseMovePoint.Y(), POINTER_VSIZEBAR );
1442                     }
1443                 }
1444                 else if( bFooterRulerChange )
1445                 {
1446                     SetPointer( Pointer( POINTER_VSIZEBAR ) );
1447                     if( bFooterRulerMove )
1448                     {
1449                         if( aMouseMovePoint.Y() > -aOffset.Y() && aMouseMovePoint.Y() < nHeight * HMM_PER_TWIPS - aOffset.Y() )
1450                             DragMove( aMouseMovePoint.Y(), POINTER_VSIZEBAR );
1451                     }
1452                 }
1453             }
1454             else
1455                 SetPointer( Pointer( POINTER_ARROW ) );
1456         }
1457     }
1458 }
1459 //Issue51656 Add resizeable margin on page preview from maoyg
1460 void ScPreview::InvalidateLocationData(sal_uLong nId)
1461 {
1462 	bLocationValid = sal_False;
1463     if (pViewShell->HasAccessibilityObjects())
1464     	pViewShell->BroadcastAccessibility( SfxSimpleHint( nId ) );
1465 }
1466 
1467 void ScPreview::GetFocus()
1468 {
1469     if (pViewShell->HasAccessibilityObjects())
1470         pViewShell->BroadcastAccessibility( ScAccWinFocusGotHint(GetAccessible()) );
1471 }
1472 
1473 void ScPreview::LoseFocus()
1474 {
1475     if (pViewShell->HasAccessibilityObjects())
1476         pViewShell->BroadcastAccessibility( ScAccWinFocusLostHint(GetAccessible()) );
1477 }
1478 
1479 com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible> ScPreview::CreateAccessible()
1480 {
1481 	ScAccessibleDocumentPagePreview* pAccessible =
1482 		new ScAccessibleDocumentPagePreview( GetAccessibleParentWindow()->GetAccessible(), pViewShell );
1483 	com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xAccessible = pAccessible;
1484 	pAccessible->Init();
1485 	return xAccessible;
1486 }
1487 
1488 //Issue51656 Add resizeable margin on page preview from maoyg
1489 void ScPreview::DragMove( long nDragMovePos, sal_uInt16 nFlags )
1490 {
1491     Fraction aPreviewZoom( nZoom, 100 );
1492     Fraction aHorPrevZoom( (long)( 100 * nZoom / pDocShell->GetOutputFactor() ), 10000 );
1493     MapMode  aMMMode( MAP_100TH_MM, Point(), aHorPrevZoom, aPreviewZoom );
1494     SetMapMode( aMMMode );
1495     long  nPos = nDragMovePos;
1496     if( nFlags == POINTER_HSIZEBAR || nFlags == POINTER_HSPLIT )
1497     {
1498         if( nDragMovePos != aButtonDownChangePoint.X() )
1499         {
1500             DrawInvert( aButtonDownChangePoint.X(), nFlags );
1501             aButtonDownChangePoint.X() = nPos;
1502             DrawInvert( aButtonDownChangePoint.X(), nFlags );
1503         }
1504     }
1505     else if( nFlags == POINTER_VSIZEBAR )
1506     {
1507         if( nDragMovePos != aButtonDownChangePoint.Y() )
1508         {
1509             DrawInvert( aButtonDownChangePoint.Y(), nFlags );
1510             aButtonDownChangePoint.Y() = nPos;
1511             DrawInvert( aButtonDownChangePoint.Y(), nFlags );
1512         }
1513     }
1514 }
1515 
1516 void ScPreview::DrawInvert( long nDragPos, sal_uInt16 nFlags )
1517 {
1518     long  nHeight = (long) lcl_GetDocPageSize( pDocShell->GetDocument(), nTab ).Height();
1519     long  nWidth = (long) lcl_GetDocPageSize( pDocShell->GetDocument(), nTab ).Width();
1520     if( nFlags == POINTER_HSIZEBAR || nFlags == POINTER_HSPLIT )
1521     {
1522         Rectangle aRect( nDragPos, -aOffset.Y(), nDragPos + 1,(long)( ( nHeight * HMM_PER_TWIPS ) - aOffset.Y()));
1523         Invert( aRect,INVERT_50 );
1524     }
1525     else if( nFlags == POINTER_VSIZEBAR )
1526     {
1527         Rectangle aRect( -aOffset.X(), nDragPos,(long)( ( nWidth * HMM_PER_TWIPS ) - aOffset.X() ), nDragPos + 1 );
1528         Invert( aRect,INVERT_50 );
1529     }
1530 }
1531 //Issue51656 Add resizeable margin on page preview from maoyg
1532