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