xref: /AOO41X/main/sc/source/ui/view/viewdata.cxx (revision 11daf541bc6a074f6005ba99a5baf58db61f942e)
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 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 
28 
29 // INCLUDE ---------------------------------------------------------------
30 
31 #include "scitems.hxx"
32 #include <editeng/eeitem.hxx>
33 
34 
35 #include <sfx2/viewfrm.hxx>
36 #include <editeng/adjitem.hxx>
37 #include <svx/algitem.hxx>
38 #include <editeng/brshitem.hxx>
39 #include <svtools/colorcfg.hxx>
40 #include <editeng/editview.hxx>
41 #include <editeng/editstat.hxx>
42 #include <editeng/outliner.hxx>
43 #include <editeng/unolingu.hxx>
44 
45 #include <vcl/svapp.hxx>
46 #include <rtl/math.hxx>
47 
48 #include "viewdata.hxx"
49 #include "docoptio.hxx"
50 #include "scmod.hxx"
51 #include "global.hxx"
52 #include "document.hxx"
53 #include "attrib.hxx"
54 #include "tabview.hxx"
55 #include "tabvwsh.hxx"
56 #include "docsh.hxx"
57 #include "sc.hrc"
58 #include "patattr.hxx"
59 #include "editutil.hxx"
60 #include "scextopt.hxx"
61 #include "miscuno.hxx"
62 #include "unonames.hxx"
63 #include "inputopt.hxx"
64 #include "viewutil.hxx"
65 #include <xmloff/xmluconv.hxx>
66 #include "ViewSettingsSequenceDefines.hxx"
67 #include <rtl/ustrbuf.hxx>
68 #include <comphelper/processfactory.hxx>
69 #include <com/sun/star/container/XNameContainer.hpp>
70 
71 using namespace com::sun::star;
72 
73 // STATIC DATA -----------------------------------------------------------
74 
75 #define SC_GROWY_SMALL_EXTRA    100
76 #define SC_GROWY_BIG_EXTRA      200
77 
78 #define TAG_TABBARWIDTH "tw:"
79 
80 static sal_Bool bMoveArea = sal_False;              //! Member?
81 sal_uInt16 nEditAdjust = SVX_ADJUST_LEFT;       //! Member !!!
82 
83 //==================================================================
84 
ScViewDataTable()85 ScViewDataTable::ScViewDataTable() :
86                 eZoomType( SVX_ZOOM_PERCENT ),
87                 aZoomX( 1,1 ),
88                 aZoomY( 1,1 ),
89                 aPageZoomX( 3,5 ),              // Page-Default: 60%
90                 aPageZoomY( 3,5 ),
91                 nHSplitPos( 0 ),
92                 nVSplitPos( 0 ),
93                 eHSplitMode( SC_SPLIT_NONE ),
94                 eVSplitMode( SC_SPLIT_NONE ),
95                 eWhichActive( SC_SPLIT_BOTTOMLEFT ),
96                 nFixPosX( 0 ),
97                 nFixPosY( 0 ),
98                 nCurX( 0 ),
99                 nCurY( 0 ),
100                 bOldCurValid( sal_False )
101 {
102     nPosX[0]=nPosX[1]=0;
103     nPosY[0]=nPosY[1]=0;
104     nTPosX[0]=nTPosX[1]=0;
105     nTPosY[0]=nTPosY[1]=0;
106     nMPosX[0]=nMPosX[1]=0;
107     nMPosY[0]=nMPosY[1]=0;
108     nPixPosX[0]=nPixPosX[1]=0;
109     nPixPosY[0]=nPixPosY[1]=0;
110 }
111 
~ScViewDataTable()112 ScViewDataTable::~ScViewDataTable()
113 {
114 }
115 
WriteUserDataSequence(uno::Sequence<beans::PropertyValue> & rSettings,const ScViewData &,SCTAB)116 void ScViewDataTable::WriteUserDataSequence(uno::Sequence <beans::PropertyValue>& rSettings, const ScViewData& /*rViewData*/, SCTAB /*nTab*/)
117 {
118     rSettings.realloc(SC_TABLE_VIEWSETTINGS_COUNT);
119     beans::PropertyValue* pSettings = rSettings.getArray();
120     if (pSettings)
121     {
122         pSettings[SC_CURSOR_X].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_CURSORPOSITIONX));
123         pSettings[SC_CURSOR_X].Value <<= sal_Int32(nCurX);
124         pSettings[SC_CURSOR_Y].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_CURSORPOSITIONY));
125         pSettings[SC_CURSOR_Y].Value <<= sal_Int32(nCurY);
126         pSettings[SC_HORIZONTAL_SPLIT_MODE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_HORIZONTALSPLITMODE));
127         pSettings[SC_HORIZONTAL_SPLIT_MODE].Value <<= sal_Int16(eHSplitMode);
128         pSettings[SC_VERTICAL_SPLIT_MODE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_VERTICALSPLITMODE));
129         pSettings[SC_VERTICAL_SPLIT_MODE].Value <<= sal_Int16(eVSplitMode);
130         pSettings[SC_HORIZONTAL_SPLIT_POSITION].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_HORIZONTALSPLITPOSITION));
131         if (eHSplitMode == SC_SPLIT_FIX)
132             pSettings[SC_HORIZONTAL_SPLIT_POSITION].Value <<= sal_Int32(nFixPosX);
133         else
134             pSettings[SC_HORIZONTAL_SPLIT_POSITION].Value <<= sal_Int32(nHSplitPos);
135         pSettings[SC_VERTICAL_SPLIT_POSITION].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_VERTICALSPLITPOSITION));
136         if (eVSplitMode == SC_SPLIT_FIX)
137             pSettings[SC_VERTICAL_SPLIT_POSITION].Value <<= sal_Int32(nFixPosY);
138         else
139             pSettings[SC_VERTICAL_SPLIT_POSITION].Value <<= sal_Int32(nVSplitPos);
140         pSettings[SC_ACTIVE_SPLIT_RANGE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ACTIVESPLITRANGE));
141         pSettings[SC_ACTIVE_SPLIT_RANGE].Value <<= sal_Int16(eWhichActive);
142         pSettings[SC_POSITION_LEFT].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_POSITIONLEFT));
143         pSettings[SC_POSITION_LEFT].Value <<= sal_Int32(nPosX[SC_SPLIT_LEFT]);
144         pSettings[SC_POSITION_RIGHT].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_POSITIONRIGHT));
145         pSettings[SC_POSITION_RIGHT].Value <<= sal_Int32(nPosX[SC_SPLIT_RIGHT]);
146         pSettings[SC_POSITION_TOP].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_POSITIONTOP));
147         pSettings[SC_POSITION_TOP].Value <<= sal_Int32(nPosY[SC_SPLIT_TOP]);
148         pSettings[SC_POSITION_BOTTOM].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_POSITIONBOTTOM));
149         pSettings[SC_POSITION_BOTTOM].Value <<= sal_Int32(nPosY[SC_SPLIT_BOTTOM]);
150 
151         sal_Int32 nZoomValue ((aZoomY.GetNumerator() * 100) / aZoomY.GetDenominator());
152         sal_Int32 nPageZoomValue ((aPageZoomY.GetNumerator() * 100) / aPageZoomY.GetDenominator());
153         pSettings[SC_TABLE_ZOOM_TYPE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ZOOMTYPE));
154         pSettings[SC_TABLE_ZOOM_TYPE].Value <<= sal_Int16(eZoomType);
155         pSettings[SC_TABLE_ZOOM_VALUE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ZOOMVALUE));
156         pSettings[SC_TABLE_ZOOM_VALUE].Value <<= nZoomValue;
157         pSettings[SC_TABLE_PAGE_VIEW_ZOOM_VALUE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_PAGEVIEWZOOMVALUE));
158         pSettings[SC_TABLE_PAGE_VIEW_ZOOM_VALUE].Value <<= nPageZoomValue;
159     }
160 }
161 
ReadUserDataSequence(const uno::Sequence<beans::PropertyValue> & aSettings,ScViewData & rViewData,SCTAB nTab,bool & rHasZoom)162 void ScViewDataTable::ReadUserDataSequence(const uno::Sequence <beans::PropertyValue>& aSettings, ScViewData& rViewData, SCTAB nTab, bool& rHasZoom )
163 {
164     rHasZoom = false;
165 
166     sal_Int32 nCount(aSettings.getLength());
167     sal_Int32 nTemp32(0);
168     sal_Int16 nTemp16(0);
169     sal_Int32 nTempPosV(0);
170     sal_Int32 nTempPosH(0);
171     sal_Int32 nTempPosVTw(0);
172     sal_Int32 nTempPosHTw(0);
173     bool bHasVSplitInTwips = false;
174     bool bHasHSplitInTwips = false;
175     for (sal_Int32 i = 0; i < nCount; i++)
176     {
177         rtl::OUString sName(aSettings[i].Name);
178         if (sName.compareToAscii(SC_CURSORPOSITIONX) == 0)
179         {
180             aSettings[i].Value >>= nTemp32;
181             nCurX = SanitizeCol( static_cast<SCCOL>(nTemp32));
182         }
183         else if (sName.compareToAscii(SC_CURSORPOSITIONY) == 0)
184         {
185             aSettings[i].Value >>= nTemp32;
186             nCurY = SanitizeRow( static_cast<SCROW>(nTemp32));
187         }
188         else if (sName.compareToAscii(SC_HORIZONTALSPLITMODE) == 0)
189         {
190             aSettings[i].Value >>= nTemp16;
191             eHSplitMode = static_cast<ScSplitMode>(nTemp16);
192         }
193         else if (sName.compareToAscii(SC_VERTICALSPLITMODE) == 0)
194         {
195             aSettings[i].Value >>= nTemp16;
196             eVSplitMode = static_cast<ScSplitMode>(nTemp16);
197         }
198         else if (sName.compareToAscii(SC_HORIZONTALSPLITPOSITION) == 0)
199         {
200             aSettings[i].Value >>= nTempPosH;
201             bHasHSplitInTwips = false;
202         }
203         else if (sName.compareToAscii(SC_VERTICALSPLITPOSITION) == 0)
204         {
205             aSettings[i].Value >>= nTempPosV;
206             bHasVSplitInTwips = false;
207         }
208         else if (sName.compareToAscii(SC_HORIZONTALSPLITPOSITION_TWIPS) == 0)
209         {
210             aSettings[i].Value >>= nTempPosHTw;
211             bHasHSplitInTwips = true;
212         }
213         else if (sName.compareToAscii(SC_VERTICALSPLITPOSITION_TWIPS) == 0)
214         {
215             aSettings[i].Value >>= nTempPosVTw;
216             bHasVSplitInTwips = true;
217         }
218         else if (sName.compareToAscii(SC_ACTIVESPLITRANGE) == 0)
219         {
220             aSettings[i].Value >>= nTemp16;
221             eWhichActive = static_cast<ScSplitPos>(nTemp16);
222         }
223         else if (sName.compareToAscii(SC_POSITIONLEFT) == 0)
224         {
225             aSettings[i].Value >>= nTemp32;
226             nPosX[SC_SPLIT_LEFT] = SanitizeCol( static_cast<SCCOL>(nTemp32));
227         }
228         else if (sName.compareToAscii(SC_POSITIONRIGHT) == 0)
229         {
230             aSettings[i].Value >>= nTemp32;
231             nPosX[SC_SPLIT_RIGHT] = SanitizeCol( static_cast<SCCOL>(nTemp32));
232         }
233         else if (sName.compareToAscii(SC_POSITIONTOP) == 0)
234         {
235             aSettings[i].Value >>= nTemp32;
236             nPosY[SC_SPLIT_TOP] = SanitizeRow( static_cast<SCROW>(nTemp32));
237         }
238         else if (sName.compareToAscii(SC_POSITIONBOTTOM) == 0)
239         {
240             aSettings[i].Value >>= nTemp32;
241             nPosY[SC_SPLIT_BOTTOM] = SanitizeRow( static_cast<SCROW>(nTemp32));
242         }
243         else if (sName.compareToAscii(SC_ZOOMTYPE) == 0)
244         {
245             aSettings[i].Value >>= nTemp16;
246             eZoomType = SvxZoomType(nTemp16);
247             rHasZoom = true;        // set if there is any zoom information
248         }
249         else if (sName.compareToAscii(SC_ZOOMVALUE) == 0)
250         {
251             aSettings[i].Value >>= nTemp32;
252             Fraction aZoom(nTemp32, 100);
253             aZoomX = aZoomY = aZoom;
254             rHasZoom = true;
255         }
256         else if (sName.compareToAscii(SC_PAGEVIEWZOOMVALUE) == 0)
257         {
258             aSettings[i].Value >>= nTemp32;
259             Fraction aZoom(nTemp32, 100);
260             aPageZoomX = aPageZoomY = aZoom;
261             rHasZoom = true;
262         }
263         else if (sName.compareToAscii(SC_TABLESELECTED) == 0)
264         {
265             bool bSelected = false;
266             aSettings[i].Value >>= bSelected;
267             rViewData.GetMarkData().SelectTable( nTab, bSelected );
268         }
269         else if (sName.compareToAscii(SC_UNONAME_TABCOLOR) == 0)
270         {
271             // There are documents out there that have their tab color defined as a view setting.
272             sal_Int32 nColor = COL_AUTO;
273             aSettings[i].Value >>= nColor;
274             if (static_cast<ColorData>(nColor) != COL_AUTO)
275             {
276                 ScDocument* pDoc = rViewData.GetDocument();
277                 pDoc->SetTabBgColor(nTab, Color(static_cast<ColorData>(nColor)));
278             }
279         }
280     }
281     if (eHSplitMode == SC_SPLIT_FIX)
282         nFixPosX = SanitizeCol( static_cast<SCCOL>( bHasHSplitInTwips ? nTempPosHTw : nTempPosH ));
283     else
284         nHSplitPos = bHasHSplitInTwips ? static_cast< long >( nTempPosHTw * rViewData.GetPPTX() ) : nTempPosH;
285 
286     if (eVSplitMode == SC_SPLIT_FIX)
287         nFixPosY = SanitizeRow( static_cast<SCROW>( bHasVSplitInTwips ? nTempPosVTw : nTempPosV ));
288     else
289         nVSplitPos = bHasVSplitInTwips ? static_cast< long >( nTempPosVTw * rViewData.GetPPTY() ) : nTempPosV;
290 }
291 
292 //==================================================================
293 
ScViewData(ScDocShell * pDocSh,ScTabViewShell * pViewSh)294 ScViewData::ScViewData( ScDocShell* pDocSh, ScTabViewShell* pViewSh )
295     :   pDocShell   ( pDocSh ),
296         pDoc        ( NULL ),
297         pView       ( pViewSh ),
298         pViewShell  ( pViewSh ),
299         pOptions    ( new ScViewOptions ),
300         pSpellingView ( NULL ),
301         aLogicMode  ( MAP_100TH_MM ),
302         eDefZoomType( SVX_ZOOM_PERCENT ),
303         aDefZoomX   ( 1,1 ),
304         aDefZoomY   ( 1,1 ),
305         aDefPageZoomX( 3,5 ),
306         aDefPageZoomY( 3,5 ),
307         eRefType    ( SC_REFTYPE_NONE ),
308         nTabNo      ( 0 ),
309         nRefTabNo   ( 0 ),
310         eEditActivePart( SC_SPLIT_BOTTOMLEFT ),
311         bActive     ( sal_True ),                   //! wie initialisieren?
312         bIsRefMode  ( sal_False ),
313         bDelMarkValid( sal_False ),
314         nFillMode   ( SC_FILL_NONE ),
315         bPagebreak  ( sal_False ),
316         bSelCtrlMouseClick( sal_False )
317 {
318 
319     SetGridMode     ( sal_True );
320     SetSyntaxMode   ( sal_False );
321     SetHeaderMode   ( sal_True );
322     SetTabMode      ( sal_True );
323     SetVScrollMode  ( sal_True );
324     SetHScrollMode  ( sal_True );
325     SetOutlineMode  ( sal_True );
326 
327     aScrSize = Size( (long) ( STD_COL_WIDTH           * PIXEL_PER_TWIPS * OLE_STD_CELLS_X ),
328                      (long) ( ScGlobal::nStdRowHeight * PIXEL_PER_TWIPS * OLE_STD_CELLS_Y ) );
329     pTabData[0] = new ScViewDataTable;
330     for ( SCTAB i = 1; i <= MAXTAB; i++ )
331         pTabData[i] = NULL;
332     pThisTab = pTabData[nTabNo];
333     for (sal_uInt16 j=0; j<4; j++)
334     {
335         pEditView[j] = NULL;
336         bEditActive[j] = sal_False;
337     }
338 
339     nEditEndCol = nEditStartCol = nEditCol = 0;
340     nEditEndRow = nEditRow = 0;
341     nTabStartCol = SC_TABSTART_NONE;
342 
343     if (pDocShell)
344     {
345         pDoc = pDocShell->GetDocument();
346         *pOptions = pDoc->GetViewOptions();
347     }
348 
349     //  keine ausgeblendete Tabelle anzeigen:
350     if (pDoc && !pDoc->IsVisible(nTabNo))
351     {
352         while ( !pDoc->IsVisible(nTabNo) && pDoc->HasTable(nTabNo+1) )
353             ++nTabNo;
354 
355         pTabData[nTabNo] = new ScViewDataTable;
356         pThisTab = pTabData[nTabNo];
357     }
358 
359     CalcPPT();
360 }
361 
ScViewData(const ScViewData & rViewData)362 ScViewData::ScViewData( const ScViewData& rViewData )
363     :   pDocShell   ( rViewData.pDocShell ),
364         pDoc        ( rViewData.pDoc ),
365         pView       ( rViewData.pView ),
366         pViewShell  ( rViewData.pViewShell ),
367         pOptions    ( new ScViewOptions( *(rViewData.pOptions) )  ),
368         pSpellingView ( rViewData.pSpellingView ),
369         aLogicMode  ( rViewData.aLogicMode ),
370         eDefZoomType( rViewData.eDefZoomType ),
371         aDefZoomX   ( rViewData.aDefZoomX ),
372         aDefZoomY   ( rViewData.aDefZoomY ),
373         aDefPageZoomX( rViewData.aDefPageZoomX ),
374         aDefPageZoomY( rViewData.aDefPageZoomY ),
375         eRefType    ( SC_REFTYPE_NONE ),
376         nTabNo      ( rViewData.nTabNo ),
377         nRefTabNo   ( rViewData.nTabNo ),           // kein RefMode
378         eEditActivePart( rViewData.eEditActivePart ),
379         bActive     ( sal_True ),                               //! wie initialisieren?
380         bIsRefMode  ( sal_False ),
381         bDelMarkValid( sal_False ),
382         nFillMode   ( SC_FILL_NONE ),
383         bPagebreak  ( rViewData.bPagebreak ),
384         bSelCtrlMouseClick( rViewData.bSelCtrlMouseClick )
385 {
386 
387     SetGridMode     ( rViewData.IsGridMode() );
388     SetSyntaxMode   ( rViewData.IsSyntaxMode() );
389     SetHeaderMode   ( rViewData.IsHeaderMode() );
390     SetTabMode      ( rViewData.IsTabMode() );
391     SetVScrollMode  ( rViewData.IsVScrollMode() );
392     SetHScrollMode  ( rViewData.IsHScrollMode() );
393     SetOutlineMode  ( rViewData.IsOutlineMode() );
394 
395     aScrSize = rViewData.aScrSize;
396     for ( SCTAB i = 0; i <= MAXTAB; i++ )
397         if (rViewData.pTabData[i])
398             pTabData[i] = new ScViewDataTable( *rViewData.pTabData[i] );
399         else
400             pTabData[i] = NULL;
401     pThisTab = pTabData[nTabNo];
402     for (sal_uInt16 j=0; j<4; j++)
403     {
404         pEditView[j] = NULL;
405         bEditActive[j] = sal_False;
406     }
407 
408     nEditEndCol = nEditStartCol = nEditCol = 0;
409     nEditEndRow = nEditRow = 0;
410     nTabStartCol = SC_TABSTART_NONE;
411     CalcPPT();
412 }
413 
InitData(ScDocument * pDocument)414 void ScViewData::InitData( ScDocument* pDocument )
415 {
416     pDoc = pDocument;
417     *pOptions = pDoc->GetViewOptions();
418 }
419 
420 //UNUSED2008-05  void ScViewData::InitFrom( const ScViewData* pRef )
421 //UNUSED2008-05  {
422 //UNUSED2008-05      if (pRef==NULL)
423 //UNUSED2008-05      {
424 //UNUSED2008-05          DBG_ERROR("ScViewData::InitFrom mit NULL");
425 //UNUSED2008-05          return;
426 //UNUSED2008-05      }
427 //UNUSED2008-05
428 //UNUSED2008-05      aScrSize    = pRef->aScrSize;
429 //UNUSED2008-05      nTabNo      = pRef->nTabNo;
430 //UNUSED2008-05      eDefZoomType = pRef->eDefZoomType;
431 //UNUSED2008-05      aDefZoomX   = pRef->aDefZoomX;
432 //UNUSED2008-05      aDefZoomY   = pRef->aDefZoomY;
433 //UNUSED2008-05      aDefPageZoomX = pRef->aDefPageZoomX;
434 //UNUSED2008-05      aDefPageZoomY = pRef->aDefPageZoomY;
435 //UNUSED2008-05      bPagebreak  = pRef->bPagebreak;
436 //UNUSED2008-05      aLogicMode  = pRef->aLogicMode;
437 //UNUSED2008-05
438 //UNUSED2008-05      SetGridMode     ( pRef->IsGridMode() );
439 //UNUSED2008-05      SetSyntaxMode   ( pRef->IsSyntaxMode() );
440 //UNUSED2008-05      SetHeaderMode   ( pRef->IsHeaderMode() );
441 //UNUSED2008-05      SetTabMode      ( pRef->IsTabMode() );
442 //UNUSED2008-05      SetVScrollMode  ( pRef->IsVScrollMode() );
443 //UNUSED2008-05      SetHScrollMode  ( pRef->IsHScrollMode() );
444 //UNUSED2008-05      SetOutlineMode  ( pRef->IsOutlineMode() );
445 //UNUSED2008-05
446 //UNUSED2008-05      for (SCTAB i=0; i<=MAXTAB; i++)
447 //UNUSED2008-05      {
448 //UNUSED2008-05          delete pTabData[i];
449 //UNUSED2008-05          if (pRef->pTabData[i])
450 //UNUSED2008-05              pTabData[i] = new ScViewDataTable( *pRef->pTabData[i] );
451 //UNUSED2008-05          else
452 //UNUSED2008-05              pTabData[i] = NULL;
453 //UNUSED2008-05      }
454 //UNUSED2008-05      pThisTab = pTabData[nTabNo];
455 //UNUSED2008-05      CalcPPT();
456 //UNUSED2008-05  }
457 //UNUSED2008-05
458 //UNUSED2008-05  void ScViewData::SetDocShell( ScDocShell* pShell )
459 //UNUSED2008-05  {
460 //UNUSED2008-05      pDocShell = pShell;
461 //UNUSED2008-05      pDoc = pDocShell->GetDocument();
462 //UNUSED2008-05      *pOptions = pDoc->GetViewOptions();
463 //UNUSED2008-05      CalcPPT();
464 //UNUSED2008-05  }
465 
GetDocument() const466 ScDocument* ScViewData::GetDocument() const
467 {
468     if (pDoc)
469         return pDoc;
470     else if (pDocShell)
471         return pDocShell->GetDocument();
472 
473     DBG_ERROR("kein Document an ViewData");
474     return NULL;
475 }
476 
~ScViewData()477 ScViewData::~ScViewData()
478 {
479     for (SCTAB i=0; i<=MAXTAB; i++)
480         if (pTabData[i])
481             delete pTabData[i];
482 
483     KillEditView();
484     delete pOptions;
485 }
486 
UpdateThis()487 void ScViewData::UpdateThis()
488 {
489     do
490     {
491         pThisTab = pTabData[nTabNo];
492         if (!pThisTab)
493         {
494             if (nTabNo>0)
495                 --nTabNo;
496             else
497                 pThisTab = pTabData[0] = new ScViewDataTable;
498 
499                 // hier keine Assertion, weil sonst Paints kommen, bevor alles initialisiert ist!
500         }
501     }
502     while (!pThisTab);
503 }
504 
InsertTab(SCTAB nTab)505 void ScViewData::InsertTab( SCTAB nTab )
506 {
507     delete pTabData[MAXTAB];
508 
509     for (SCTAB i=MAXTAB; i>nTab; i--)
510         pTabData[i] = pTabData[i-1];
511 
512     pTabData[nTab] = NULL;      // force creating new
513     CreateTabData( nTab );
514 
515     UpdateThis();
516     aMarkData.InsertTab( nTab );
517 }
518 
DeleteTab(SCTAB nTab)519 void ScViewData::DeleteTab( SCTAB nTab )
520 {
521     delete pTabData[nTab];
522 
523     for (SCTAB i=nTab; i<MAXTAB; i++)
524         pTabData[i] = pTabData[i+1];
525 
526     pTabData[MAXTAB] = NULL;
527 
528     UpdateThis();
529     aMarkData.DeleteTab( nTab );
530 }
531 
CopyTab(SCTAB nSrcTab,SCTAB nDestTab)532 void ScViewData::CopyTab( SCTAB nSrcTab, SCTAB nDestTab )
533 {
534     if (nDestTab==SC_TAB_APPEND)
535         nDestTab = pDoc->GetTableCount() - 1;   // am Doc muss vorher kopiert worden sein
536 
537     if (nDestTab > MAXTAB)
538     {
539         DBG_ERROR("Zuviele Tabellen");
540         return;
541     }
542 
543     delete pTabData[MAXTAB];
544 
545     for (SCTAB i=MAXTAB; i>nDestTab; i--)
546         pTabData[i] = pTabData[i-1];
547 
548     if ( pTabData[nSrcTab] )
549         pTabData[nDestTab] = new ScViewDataTable( *pTabData[nSrcTab] );
550     else
551         pTabData[nDestTab] = NULL;
552 
553     UpdateThis();
554     aMarkData.InsertTab( nDestTab );
555 }
556 
MoveTab(SCTAB nSrcTab,SCTAB nDestTab)557 void ScViewData::MoveTab( SCTAB nSrcTab, SCTAB nDestTab )
558 {
559     if (nDestTab==SC_TAB_APPEND)
560         nDestTab = pDoc->GetTableCount() - 1;
561 
562     SCTAB i;
563     ScViewDataTable* pTab = pTabData[nSrcTab];
564 
565     SCTAB nInsTab = nDestTab;
566     if ( nSrcTab < nDestTab )
567     {
568         --nInsTab;
569         for (i=nSrcTab; i<nDestTab; i++)
570             pTabData[i] = pTabData[i+1];
571     }
572     else
573         for (i=nSrcTab; i>nDestTab; i--)
574             pTabData[i] = pTabData[i-1];
575 
576     pTabData[nDestTab] = pTab;
577 
578     UpdateThis();
579     aMarkData.DeleteTab( nSrcTab );
580     aMarkData.InsertTab( nInsTab );         // ggf. angepasst
581 }
582 
583 //UNUSED2008-05  void ScViewData::UpdateOle( ScSplitPos /* eWhich */ )
584 //UNUSED2008-05  {
585 //UNUSED2008-05      GetDocShell()->UpdateOle(this);
586 //UNUSED2008-05  }
587 
SetViewShell(ScTabViewShell * pViewSh)588 void ScViewData::SetViewShell( ScTabViewShell* pViewSh )
589 {
590     if (pViewSh)
591     {
592         pViewShell  = pViewSh;
593         pView       = pViewSh;
594     }
595     else
596     {
597         pViewShell  = NULL;
598         pView       = NULL;
599     }
600 }
CreateTabData(std::vector<SCTAB> & rvTabs)601 void ScViewData::CreateTabData( std::vector< SCTAB >& rvTabs )
602 {
603     std::vector< SCTAB >::iterator it_end = rvTabs.end();
604     for ( std::vector< SCTAB >::iterator it = rvTabs.begin(); it != it_end; ++it )
605         if ( !pTabData[*it] )
606             CreateTabData( *it );
607 }
608 
SetZoomType(SvxZoomType eNew,std::vector<SCTAB> & tabs)609 void ScViewData::SetZoomType( SvxZoomType eNew, std::vector< SCTAB >& tabs )
610 {
611     sal_Bool bAll = ( tabs.size() == 0 );
612 
613     if ( !bAll ) // create associated table data
614         CreateTabData( tabs );
615 
616     if ( bAll )
617     {
618         for ( SCTAB i = 0; i <= MAXTAB; ++i )
619         {
620             if ( pTabData[i] )
621                 pTabData[i]->eZoomType = eNew;
622         }
623         eDefZoomType = eNew;
624     }
625     else
626     {
627         std::vector< SCTAB >::iterator it_end = tabs.end();
628         std::vector< SCTAB >::iterator it = tabs.begin();
629         for ( ; it != it_end; ++it )
630         {
631             SCTAB i = *it;
632             if ( pTabData[i] )
633                 pTabData[i]->eZoomType = eNew;
634         }
635     }
636 }
637 
SetZoomType(SvxZoomType eNew,sal_Bool bAll)638 void ScViewData::SetZoomType( SvxZoomType eNew, sal_Bool bAll )
639 {
640     std::vector< SCTAB > vTabs; // Empty for all tabs
641     if ( !bAll ) // get selected tabs
642     {
643         SCTAB nTabCount = pDoc->GetTableCount();
644         for (SCTAB i=0; i<nTabCount; i++)
645         {
646             if ( aMarkData.GetTableSelect(i)  )
647                 vTabs.push_back( i );
648         }
649     }
650     SetZoomType( eNew, vTabs );
651 }
652 
SetZoom(const Fraction & rNewX,const Fraction & rNewY,std::vector<SCTAB> & tabs)653 void ScViewData::SetZoom( const Fraction& rNewX, const Fraction& rNewY, std::vector< SCTAB >& tabs )
654 {
655     sal_Bool bAll = ( tabs.size() == 0 );
656     if ( !bAll ) // create associated table data
657         CreateTabData( tabs );
658     Fraction aFrac20( 1,5 );
659     Fraction aFrac400( 4,1 );
660 
661     Fraction aValidX = rNewX;
662     if (aValidX<aFrac20)
663         aValidX = aFrac20;
664     if (aValidX>aFrac400)
665         aValidX = aFrac400;
666 
667     Fraction aValidY = rNewY;
668     if (aValidY<aFrac20)
669         aValidY = aFrac20;
670     if (aValidY>aFrac400)
671         aValidY = aFrac400;
672 
673     if ( bAll )
674     {
675         for ( SCTAB i = 0; i <= MAXTAB; ++i )
676         {
677             if ( pTabData[i] )
678             {
679                 if ( bPagebreak )
680                 {
681                     pTabData[i]->aPageZoomX = aValidX;
682                     pTabData[i]->aPageZoomY = aValidY;
683                 }
684                 else
685                 {
686                     pTabData[i]->aZoomX = aValidX;
687                     pTabData[i]->aZoomY = aValidY;
688                 }
689             }
690         }
691         if ( bPagebreak )
692         {
693             aDefPageZoomX = aValidX;
694             aDefPageZoomY = aValidY;
695         }
696         else
697         {
698             aDefZoomX = aValidX;
699             aDefZoomY = aValidY;
700         }
701     }
702     else
703     {
704         std::vector< SCTAB >::iterator it_end = tabs.end();
705         std::vector< SCTAB >::iterator it = tabs.begin();
706         for ( ; it != it_end; ++it )
707         {
708             SCTAB i = *it;
709             if ( pTabData[i] )
710             {
711                 if ( bPagebreak )
712                 {
713                     pTabData[i]->aPageZoomX = aValidX;
714                     pTabData[i]->aPageZoomY = aValidY;
715                 }
716                 else
717                 {
718                     pTabData[i]->aZoomX = aValidX;
719                     pTabData[i]->aZoomY = aValidY;
720                 }
721             }
722         }
723     }
724     RefreshZoom();
725 }
726 
SetZoom(const Fraction & rNewX,const Fraction & rNewY,sal_Bool bAll)727 void ScViewData::SetZoom( const Fraction& rNewX, const Fraction& rNewY, sal_Bool bAll )
728 {
729     std::vector< SCTAB > vTabs;
730     if ( !bAll ) // get selected tabs
731     {
732         SCTAB nTabCount = pDoc->GetTableCount();
733         for (SCTAB i=0; i<nTabCount; i++)
734         {
735             if ( aMarkData.GetTableSelect(i)  )
736                 vTabs.push_back( i );
737         }
738     }
739     SetZoom( rNewX, rNewY, vTabs );
740 }
741 
RefreshZoom()742 void ScViewData::RefreshZoom()
743 {
744     // recalculate zoom-dependent values (only for current sheet)
745 
746     CalcPPT();
747     RecalcPixPos();
748     aScenButSize = Size(0,0);
749     aLogicMode.SetScaleX( GetZoomX() );
750     aLogicMode.SetScaleY( GetZoomY() );
751 }
752 
SetPagebreakMode(sal_Bool bSet)753 void ScViewData::SetPagebreakMode( sal_Bool bSet )
754 {
755     bPagebreak = bSet;
756 
757     RefreshZoom();
758 }
759 
760 
GetSimpleArea(ScRange & rRange,ScMarkData & rNewMark) const761 ScMarkType ScViewData::GetSimpleArea( ScRange & rRange, ScMarkData & rNewMark ) const
762 {
763     ScMarkType eMarkType = SC_MARK_NONE;
764 
765     if ( rNewMark.IsMarked() || rNewMark.IsMultiMarked() )
766     {
767         if ( rNewMark.IsMultiMarked() )
768             rNewMark.MarkToSimple();
769 
770         if ( rNewMark.IsMarked() && !rNewMark.IsMultiMarked() )
771         {
772             rNewMark.GetMarkArea( rRange );
773             if (ScViewUtil::HasFiltered( rRange, GetDocument()))
774                 eMarkType = SC_MARK_SIMPLE_FILTERED;
775             else
776                 eMarkType = SC_MARK_SIMPLE;
777         }
778         else
779             eMarkType = SC_MARK_MULTI;
780     }
781     if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
782     {
783         if (eMarkType == SC_MARK_NONE)
784             eMarkType = SC_MARK_SIMPLE;
785         rRange = ScRange( GetCurX(), GetCurY(), GetTabNo() );
786     }
787     return eMarkType;
788 }
789 
790 
GetSimpleArea(SCCOL & rStartCol,SCROW & rStartRow,SCTAB & rStartTab,SCCOL & rEndCol,SCROW & rEndRow,SCTAB & rEndTab) const791 ScMarkType ScViewData::GetSimpleArea( SCCOL& rStartCol, SCROW& rStartRow, SCTAB& rStartTab,
792                                 SCCOL& rEndCol, SCROW& rEndRow, SCTAB& rEndTab ) const
793 {
794     //  parameter bMergeMark is no longer needed: The view's selection is never modified
795     //  (a local copy is used), and a multi selection that adds to a single range can always
796     //  be treated like a single selection (#108266# - GetSimpleArea isn't used in selection
797     //  handling itself)
798 
799     ScRange aRange;
800     ScMarkData aNewMark( aMarkData );       // use a local copy for MarkToSimple
801     ScMarkType eMarkType = GetSimpleArea( aRange, aNewMark);
802     aRange.GetVars( rStartCol, rStartRow, rStartTab, rEndCol, rEndRow, rEndTab);
803     return eMarkType;
804 }
805 
GetSimpleArea(ScRange & rRange) const806 ScMarkType ScViewData::GetSimpleArea( ScRange& rRange ) const
807 {
808     //  parameter bMergeMark is no longer needed, see above
809 
810     ScMarkData aNewMark( aMarkData );       // use a local copy for MarkToSimple
811     return GetSimpleArea( rRange, aNewMark);
812 }
813 
GetMultiArea(ScRangeListRef & rRange) const814 void ScViewData::GetMultiArea( ScRangeListRef& rRange ) const
815 {
816     //  parameter bMergeMark is no longer needed, see GetSimpleArea
817 
818     ScMarkData aNewMark( aMarkData );       // use a local copy for MarkToSimple
819 
820     sal_Bool bMulti = aNewMark.IsMultiMarked();
821     if (bMulti)
822     {
823         aNewMark.MarkToSimple();
824         bMulti = aNewMark.IsMultiMarked();
825     }
826     if (bMulti)
827     {
828         rRange = new ScRangeList;
829         aNewMark.FillRangeListWithMarks( rRange, sal_False );
830     }
831     else
832     {
833         ScRange aSimple;
834         GetSimpleArea(aSimple);
835         rRange = new ScRangeList;
836         rRange->Append(aSimple);
837     }
838 }
839 
SimpleColMarked()840 sal_Bool ScViewData::SimpleColMarked()
841 {
842     SCCOL nStartCol;
843     SCROW nStartRow;
844     SCTAB nStartTab;
845     SCCOL nEndCol;
846     SCROW nEndRow;
847     SCTAB nEndTab;
848     if (GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
849         if (nStartRow==0 && nEndRow==MAXROW)
850             return sal_True;
851 
852     return sal_False;
853 }
854 
SimpleRowMarked()855 sal_Bool ScViewData::SimpleRowMarked()
856 {
857     SCCOL nStartCol;
858     SCROW nStartRow;
859     SCTAB nStartTab;
860     SCCOL nEndCol;
861     SCROW nEndRow;
862     SCTAB nEndTab;
863     if (GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
864         if (nStartCol==0 && nEndCol==MAXCOL)
865             return sal_True;
866 
867     return sal_False;
868 }
869 
IsMultiMarked()870 sal_Bool ScViewData::IsMultiMarked()
871 {
872     // Test for "real" multi selection, calling MarkToSimple on a local copy,
873     // and taking filtered in simple area marks into account.
874 
875     ScRange aDummy;
876     ScMarkType eType = GetSimpleArea(aDummy);
877     return (eType & SC_MARK_SIMPLE) != SC_MARK_SIMPLE;
878 }
879 
SetFillMode(SCCOL nStartCol,SCROW nStartRow,SCCOL nEndCol,SCROW nEndRow)880 void ScViewData::SetFillMode( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
881 {
882     nFillMode   = SC_FILL_FILL;
883     nFillStartX = nStartCol;
884     nFillStartY = nStartRow;
885     nFillEndX   = nEndCol;
886     nFillEndY   = nEndRow;
887 }
888 
SetDragMode(SCCOL nStartCol,SCROW nStartRow,SCCOL nEndCol,SCROW nEndRow,sal_uInt8 nMode)889 void ScViewData::SetDragMode( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
890                                 sal_uInt8 nMode )
891 {
892     nFillMode   = nMode;
893     nFillStartX = nStartCol;
894     nFillStartY = nStartRow;
895     nFillEndX   = nEndCol;
896     nFillEndY   = nEndRow;
897 }
898 
ResetFillMode()899 void ScViewData::ResetFillMode()
900 {
901     nFillMode   = SC_FILL_NONE;
902 }
903 
GetFillData(SCCOL & rStartCol,SCROW & rStartRow,SCCOL & rEndCol,SCROW & rEndRow)904 void ScViewData::GetFillData( SCCOL& rStartCol, SCROW& rStartRow,
905                                 SCCOL& rEndCol, SCROW& rEndRow )
906 {
907     rStartCol = nFillStartX;
908     rStartRow = nFillStartY;
909     rEndCol   = nFillEndX;
910     rEndRow   = nFillEndY;
911 }
912 
GetOldCurX() const913 SCCOL ScViewData::GetOldCurX() const
914 {
915     if (pThisTab->bOldCurValid)
916         return pThisTab->nOldCurX;
917     else
918         return pThisTab->nCurX;
919 }
920 
GetOldCurY() const921 SCROW ScViewData::GetOldCurY() const
922 {
923     if (pThisTab->bOldCurValid)
924         return pThisTab->nOldCurY;
925     else
926         return pThisTab->nCurY;
927 }
928 
SetOldCursor(SCCOL nNewX,SCROW nNewY)929 void ScViewData::SetOldCursor( SCCOL nNewX, SCROW nNewY )
930 {
931     pThisTab->nOldCurX = nNewX;
932     pThisTab->nOldCurY = nNewY;
933     pThisTab->bOldCurValid = sal_True;
934 }
935 
ResetOldCursor()936 void ScViewData::ResetOldCursor()
937 {
938     pThisTab->bOldCurValid = sal_False;
939 }
940 
GetEditArea(ScSplitPos eWhich,SCCOL nPosX,SCROW nPosY,Window * pWin,const ScPatternAttr * pPattern,sal_Bool bForceToTop)941 Rectangle ScViewData::GetEditArea( ScSplitPos eWhich, SCCOL nPosX, SCROW nPosY,
942                                     Window* pWin, const ScPatternAttr* pPattern,
943                                     sal_Bool bForceToTop )
944 {
945     return ScEditUtil( pDoc, nPosX, nPosY, nTabNo, GetScrPos(nPosX,nPosY,eWhich,sal_True),
946                         pWin, nPPTX, nPPTY, GetZoomX(), GetZoomY() ).
947                             GetEditArea( pPattern, bForceToTop );
948 }
949 
SetEditEngine(ScSplitPos eWhich,ScEditEngineDefaulter * pNewEngine,Window * pWin,SCCOL nNewX,SCROW nNewY)950 void ScViewData::SetEditEngine( ScSplitPos eWhich,
951                                 ScEditEngineDefaulter* pNewEngine,
952                                 Window* pWin, SCCOL nNewX, SCROW nNewY )
953 {
954     sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTabNo );
955     ScHSplitPos eHWhich = WhichH(eWhich);
956 
957     sal_Bool bWasThere = sal_False;
958     if (pEditView[eWhich])
959     {
960         //  Wenn die View schon da ist, nichts aufrufen, was die Cursorposition aendert
961 
962         if (bEditActive[eWhich])
963             bWasThere = sal_True;
964         else
965             pEditView[eWhich]->SetEditEngine(pNewEngine);
966 
967         if (pEditView[eWhich]->GetWindow() != pWin)
968         {
969             pEditView[eWhich]->SetWindow(pWin);
970             DBG_ERROR("EditView Window geaendert");
971         }
972     }
973     else
974     {
975         pEditView[eWhich] = new EditView( pNewEngine, pWin );
976     }
977 
978     //  bei IdleFormat wird manchmal ein Cursor gemalt, wenn die View schon weg ist (23576)
979 
980     sal_uLong nEC = pNewEngine->GetControlWord();
981     pNewEngine->SetControlWord(nEC & ~EE_CNTRL_DOIDLEFORMAT);
982 
983     sal_uLong nVC = pEditView[eWhich]->GetControlWord();
984     pEditView[eWhich]->SetControlWord(nVC & ~EV_CNTRL_AUTOSCROLL);
985 
986     bEditActive[eWhich] = sal_True;
987 
988     const ScPatternAttr* pPattern = pDoc->GetPattern( nNewX, nNewY, nTabNo );
989     SvxCellHorJustify eJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
990                                     pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue();
991 
992     sal_Bool bBreak = ( eJust == SVX_HOR_JUSTIFY_BLOCK ) ||
993                     ((SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue();
994 
995     sal_Bool bAsianVertical = pNewEngine->IsVertical();     // set by InputHandler
996 
997     Rectangle aPixRect = ScEditUtil( pDoc, nNewX,nNewY,nTabNo, GetScrPos(nNewX,nNewY,eWhich),
998                                         pWin, nPPTX,nPPTY,GetZoomX(),GetZoomY() ).
999                                             GetEditArea( pPattern, sal_True );
1000 
1001     //  when right-aligned, leave space for the cursor
1002     //  in vertical mode, editing is always right-aligned
1003     if ( nEditAdjust == SVX_ADJUST_RIGHT || bAsianVertical )
1004         aPixRect.Right() += 1;
1005 
1006     Rectangle aOutputArea = pWin->PixelToLogic( aPixRect, GetLogicMode() );
1007     pEditView[eWhich]->SetOutputArea( aOutputArea );
1008 
1009     if ( bActive && eWhich == GetActivePart() )
1010     {
1011         // keep the part that has the active edit view available after
1012         // switching sheets or reference input on a different part
1013         eEditActivePart = eWhich;
1014 
1015         //  modify members nEditCol etc. only if also extending for needed area
1016         nEditCol = nNewX;
1017         nEditRow = nNewY;
1018         const ScMergeAttr* pMergeAttr = (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
1019         nEditEndCol = nEditCol;
1020         if (pMergeAttr->GetColMerge() > 1)
1021             nEditEndCol += pMergeAttr->GetColMerge() - 1;
1022         nEditEndRow = nEditRow;
1023         if (pMergeAttr->GetRowMerge() > 1)
1024             nEditEndRow += pMergeAttr->GetRowMerge() - 1;
1025         nEditStartCol = nEditCol;
1026 
1027         //  For growing use only the alignment value from the attribute, numbers
1028         //  (existing or started) with default aligment extend to the right.
1029         sal_Bool bGrowCentered = ( eJust == SVX_HOR_JUSTIFY_CENTER );
1030         sal_Bool bGrowToLeft = ( eJust == SVX_HOR_JUSTIFY_RIGHT );      // visual left
1031         sal_Bool bGrowBackwards = bGrowToLeft;                          // logical left
1032         if ( bLayoutRTL )
1033             bGrowBackwards = !bGrowBackwards;                       // invert on RTL sheet
1034         if ( bAsianVertical )
1035             bGrowCentered = bGrowToLeft = bGrowBackwards = sal_False;   // keep old behavior for asian mode
1036 
1037         long nSizeXPix;
1038         if (bBreak && !bAsianVertical)
1039             nSizeXPix = aPixRect.GetWidth();    // Papersize -> kein H-Scrolling
1040         else
1041         {
1042             DBG_ASSERT(pView,"keine View fuer EditView");
1043 
1044             if ( bGrowCentered )
1045             {
1046                 //  growing into both directions until one edge is reached
1047                 //! should be limited to whole cells in both directions
1048                 long nLeft = aPixRect.Left();
1049                 long nRight = pView->GetGridWidth(eHWhich) - aPixRect.Right();
1050                 nSizeXPix = aPixRect.GetWidth() + 2 * Min( nLeft, nRight );
1051             }
1052             else if ( bGrowToLeft )
1053                 nSizeXPix = aPixRect.Right();   // space that's available in the window when growing to the left
1054             else
1055                 nSizeXPix = pView->GetGridWidth(eHWhich) - aPixRect.Left();
1056 
1057             if ( nSizeXPix <= 0 )
1058                 nSizeXPix = aPixRect.GetWidth();    // editing outside to the right of the window -> keep cell width
1059         }
1060         DBG_ASSERT(pView,"keine View fuer EditView");
1061         long nSizeYPix = pView->GetGridHeight(WhichV(eWhich)) - aPixRect.Top();
1062         if ( nSizeYPix <= 0 )
1063             nSizeYPix = aPixRect.GetHeight();   // editing outside below the window -> keep cell height
1064 
1065         Size aPaperSize = pView->GetActiveWin()->PixelToLogic( Size( nSizeXPix, nSizeYPix ), GetLogicMode() );
1066         if ( bBreak && !bAsianVertical && SC_MOD()->GetInputOptions().GetTextWysiwyg() )
1067         {
1068             //  #95593# if text is formatted for printer, use the exact same paper width
1069             //  (and same line breaks) as for output.
1070 
1071             Fraction aFract(1,1);
1072             Rectangle aUtilRect = ScEditUtil( pDoc,nNewX,nNewY,nTabNo, Point(0,0), pWin,
1073                                     HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( pPattern, sal_False );
1074             aPaperSize.Width() = aUtilRect.GetWidth();
1075         }
1076         pNewEngine->SetPaperSize( aPaperSize );
1077 
1078         // sichtbarer Ausschnitt
1079         Size aPaper = pNewEngine->GetPaperSize();
1080         Rectangle aVis = pEditView[eWhich]->GetVisArea();
1081         long nDiff = aVis.Right() - aVis.Left();
1082         if ( nEditAdjust == SVX_ADJUST_RIGHT )
1083         {
1084             aVis.Right() = aPaper.Width() - 1;
1085             bMoveArea = !bLayoutRTL;
1086         }
1087         else if ( nEditAdjust == SVX_ADJUST_CENTER )
1088         {
1089             aVis.Right() = ( aPaper.Width() - 1 + nDiff ) / 2;
1090             bMoveArea = sal_True;   // always
1091         }
1092         else
1093         {
1094             aVis.Right() = nDiff;
1095             bMoveArea = bLayoutRTL;
1096         }
1097         aVis.Left() = aVis.Right() - nDiff;
1098         // --> OD 2005-12-22 #i49561#
1099         // Important note:
1100         // The set offset of the visible area of the EditView for centered and
1101         // right alignment in horizontal layout is consider by instances of
1102         // class <ScEditObjectViewForwarder> in its methods <LogicToPixel(..)>
1103         // and <PixelToLogic(..)>. This is needed for the correct visibility
1104         // of paragraphs in edit mode at the accessibility API.
1105         // <--
1106         pEditView[eWhich]->SetVisArea(aVis);
1107         //
1108 
1109         //  UpdateMode has been disabled in ScInputHandler::StartTable
1110         //  must be enabled before EditGrowY (GetTextHeight)
1111         pNewEngine->SetUpdateMode( sal_True );
1112 
1113         pNewEngine->SetStatusEventHdl( LINK( this, ScViewData, EditEngineHdl ) );
1114 
1115         EditGrowY( sal_True );      // adjust to existing text content
1116         EditGrowX();
1117 
1118         Point aDocPos = pEditView[eWhich]->GetWindowPosTopLeft(0);
1119         if (aDocPos.Y() < aOutputArea.Top())
1120             pEditView[eWhich]->Scroll( 0, aOutputArea.Top() - aDocPos.Y() );
1121 
1122         //!     Status (Event) zuruecksetzen
1123     }
1124 
1125                                                     // hier muss bEditActive schon gesetzt sein
1126                                                     // (wegen Map-Mode bei Paint)
1127     if (!bWasThere)
1128         pNewEngine->InsertView(pEditView[eWhich]);
1129 
1130     //      Hintergrundfarbe der Zelle
1131     Color aBackCol = ((const SvxBrushItem&)pPattern->GetItem(ATTR_BACKGROUND)).GetColor();
1132 
1133     ScModule* pScMod = SC_MOD();
1134     //  #105733# SvtAccessibilityOptions::GetIsForBorders is no longer used (always assumed sal_True)
1135     if ( aBackCol.GetTransparency() > 0 ||
1136             Application::GetSettings().GetStyleSettings().GetHighContrastMode() )
1137     {
1138         aBackCol.SetColor( pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
1139     }
1140     pEditView[eWhich]->SetBackgroundColor( aBackCol );
1141 
1142     pEditView[eWhich]->Invalidate();            //  noetig ??
1143     //  noetig, wenn Position geaendert
1144 }
1145 
IMPL_LINK_INLINE_START(ScViewData,EmptyEditHdl,EditStatus *,EMPTYARG)1146 IMPL_LINK_INLINE_START( ScViewData, EmptyEditHdl, EditStatus *, EMPTYARG )
1147 {
1148     return 0;
1149 }
IMPL_LINK_INLINE_END(ScViewData,EmptyEditHdl,EditStatus *,EMPTYARG)1150 IMPL_LINK_INLINE_END( ScViewData, EmptyEditHdl, EditStatus *, EMPTYARG )
1151 
1152 IMPL_LINK( ScViewData, EditEngineHdl, EditStatus *, pStatus )
1153 {
1154     sal_uLong nStatus = pStatus->GetStatusWord();
1155     if (nStatus & (EE_STAT_HSCROLL | EE_STAT_TEXTHEIGHTCHANGED | EE_STAT_TEXTWIDTHCHANGED | EE_STAT_CURSOROUT))
1156     {
1157         EditGrowY();
1158         EditGrowX();
1159 
1160         if (nStatus & EE_STAT_CURSOROUT)
1161         {
1162             ScSplitPos eWhich = GetActivePart();
1163             if (pEditView[eWhich])
1164                 pEditView[eWhich]->ShowCursor(sal_False);
1165         }
1166     }
1167     return 0;
1168 }
1169 
EditGrowX()1170 void ScViewData::EditGrowX()
1171 {
1172     ScDocument* pLocalDoc = GetDocument();
1173 
1174     ScSplitPos eWhich = GetActivePart();
1175     ScHSplitPos eHWhich = WhichH(eWhich);
1176     EditView* pCurView = pEditView[eWhich];
1177 
1178     if ( !pCurView || !bEditActive[eWhich])
1179         return;
1180 
1181     sal_Bool bLayoutRTL = pLocalDoc->IsLayoutRTL( nTabNo );
1182 
1183     ScEditEngineDefaulter* pEngine =
1184         (ScEditEngineDefaulter*) pCurView->GetEditEngine();
1185     Window* pWin = pCurView->GetWindow();
1186 
1187     SCCOL nLeft = GetPosX(eHWhich);
1188     SCCOL nRight = nLeft + VisibleCellsX(eHWhich);
1189 
1190     Size        aSize = pEngine->GetPaperSize();
1191     Rectangle   aArea = pCurView->GetOutputArea();
1192     long        nOldRight = aArea.Right();
1193 
1194     //  Margin ist schon bei der urspruenglichen Breite beruecksichtigt
1195     long nTextWidth = pEngine->CalcTextWidth();
1196 
1197     sal_Bool bChanged = sal_False;
1198     sal_Bool bAsianVertical = pEngine->IsVertical();
1199 
1200     //  get bGrow... variables the same way as in SetEditEngine
1201     const ScPatternAttr* pPattern = pLocalDoc->GetPattern( nEditCol, nEditRow, nTabNo );
1202     SvxCellHorJustify eJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
1203                                     pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue();
1204     sal_Bool bGrowCentered = ( eJust == SVX_HOR_JUSTIFY_CENTER );
1205     sal_Bool bGrowToLeft = ( eJust == SVX_HOR_JUSTIFY_RIGHT );      // visual left
1206     sal_Bool bGrowBackwards = bGrowToLeft;                          // logical left
1207     if ( bLayoutRTL )
1208         bGrowBackwards = !bGrowBackwards;                       // invert on RTL sheet
1209     if ( bAsianVertical )
1210         bGrowCentered = bGrowToLeft = bGrowBackwards = sal_False;   // keep old behavior for asian mode
1211 
1212     sal_Bool bUnevenGrow = sal_False;
1213     if ( bGrowCentered )
1214     {
1215         while (aArea.GetWidth() + 0 < nTextWidth && ( nEditStartCol > nLeft || nEditEndCol < nRight ) )
1216         {
1217             long nLogicLeft = 0;
1218             if ( nEditStartCol > nLeft )
1219             {
1220                 --nEditStartCol;
1221                 long nLeftPix = ToPixel( pLocalDoc->GetColWidth( nEditStartCol, nTabNo ), nPPTX );
1222                 nLogicLeft = pWin->PixelToLogic(Size(nLeftPix,0)).Width();
1223             }
1224             long nLogicRight = 0;
1225             if ( nEditEndCol < nRight )
1226             {
1227                 ++nEditEndCol;
1228                 long nRightPix = ToPixel( pLocalDoc->GetColWidth( nEditEndCol, nTabNo ), nPPTX );
1229                 nLogicRight = pWin->PixelToLogic(Size(nRightPix,0)).Width();
1230             }
1231 
1232             aArea.Left() -= bLayoutRTL ? nLogicRight : nLogicLeft;
1233             aArea.Right() += bLayoutRTL ? nLogicLeft : nLogicRight;
1234 
1235             if ( aArea.Right() > aArea.Left() + aSize.Width() - 1 )
1236             {
1237                 long nCenter = ( aArea.Left() + aArea.Right() ) / 2;
1238                 long nHalf = aSize.Width() / 2;
1239                 aArea.Left() = nCenter - nHalf + 1;
1240                 aArea.Right() = nCenter + aSize.Width() - nHalf - 1;
1241             }
1242 
1243             bChanged = sal_True;
1244             if ( nLogicLeft != nLogicRight )
1245                 bUnevenGrow = sal_True;
1246         }
1247     }
1248     else if ( bGrowBackwards )
1249     {
1250         while (aArea.GetWidth() + 0 < nTextWidth && nEditStartCol > nLeft)
1251         {
1252             --nEditStartCol;
1253             long nPix = ToPixel( pLocalDoc->GetColWidth( nEditStartCol, nTabNo ), nPPTX );
1254             long nLogicWidth = pWin->PixelToLogic(Size(nPix,0)).Width();
1255             if ( !bLayoutRTL )
1256                 aArea.Left() -= nLogicWidth;
1257             else
1258                 aArea.Right() += nLogicWidth;
1259 
1260             if ( aArea.Right() > aArea.Left() + aSize.Width() - 1 )
1261             {
1262                 if ( !bLayoutRTL )
1263                     aArea.Left() = aArea.Right() - aSize.Width() + 1;
1264                 else
1265                     aArea.Right() = aArea.Left() + aSize.Width() - 1;
1266             }
1267 
1268             bChanged = sal_True;
1269         }
1270     }
1271     else
1272     {
1273         while (aArea.GetWidth() + 0 < nTextWidth && nEditEndCol < nRight)
1274         {
1275             ++nEditEndCol;
1276             long nPix = ToPixel( pLocalDoc->GetColWidth( nEditEndCol, nTabNo ), nPPTX );
1277             long nLogicWidth = pWin->PixelToLogic(Size(nPix,0)).Width();
1278             if ( bLayoutRTL )
1279                 aArea.Left() -= nLogicWidth;
1280             else
1281                 aArea.Right() += nLogicWidth;
1282 
1283             if ( aArea.Right() > aArea.Left() + aSize.Width() - 1 )
1284             {
1285                 if ( bLayoutRTL )
1286                     aArea.Left() = aArea.Right() - aSize.Width() + 1;
1287                 else
1288                     aArea.Right() = aArea.Left() + aSize.Width() - 1;
1289             }
1290 
1291             bChanged = sal_True;
1292         }
1293     }
1294 
1295     if (bChanged)
1296     {
1297         if ( bMoveArea || bGrowCentered || bGrowBackwards || bLayoutRTL )
1298         {
1299             Rectangle aVis = pCurView->GetVisArea();
1300 
1301             if ( bGrowCentered )
1302             {
1303                 //  switch to center-aligned (undo?) and reset VisArea to center
1304 
1305                 pEngine->SetDefaultItem( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
1306 
1307                 long nCenter = aSize.Width() / 2;
1308                 long nVisSize = aArea.GetWidth();
1309                 aVis.Left() = nCenter - nVisSize / 2;
1310                 aVis.Right() = aVis.Left() + nVisSize - 1;
1311             }
1312             else if ( bGrowToLeft )
1313             {
1314                 //  switch to right-aligned (undo?) and reset VisArea to the right
1315 
1316                 pEngine->SetDefaultItem( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
1317 
1318                 aVis.Right() = aSize.Width() - 1;
1319                 aVis.Left() = aSize.Width() - aArea.GetWidth();     // with the new, increased area
1320             }
1321             else
1322             {
1323                 //  switch to left-aligned (undo?) and reset VisArea to the left
1324 
1325                 pEngine->SetDefaultItem( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
1326 
1327                 long nMove = aVis.Left();
1328                 aVis.Left() = 0;
1329                 aVis.Right() -= nMove;
1330             }
1331             pCurView->SetVisArea( aVis );
1332             bMoveArea = sal_False;
1333         }
1334 
1335         pCurView->SetOutputArea(aArea);
1336 
1337         //  In vertical mode, the whole text is moved to the next cell (right-aligned),
1338         //  so everything must be repainted. Otherwise, paint only the new area.
1339         //  If growing in centered alignment, if the cells left and right have different sizes,
1340         //  the whole text will move, and may not even obscure all of the original display.
1341         if ( bUnevenGrow )
1342         {
1343             aArea.Left() = pWin->PixelToLogic( Point(0,0) ).X();
1344             aArea.Right() = pWin->PixelToLogic( aScrSize ).Width();
1345         }
1346         else if ( !bAsianVertical && !bGrowToLeft && !bGrowCentered )
1347             aArea.Left() = nOldRight;
1348         pWin->Invalidate(aArea);
1349     }
1350 }
1351 
EditGrowY(sal_Bool bInitial)1352 void ScViewData::EditGrowY( sal_Bool bInitial )
1353 {
1354     ScSplitPos eWhich = GetActivePart();
1355     ScVSplitPos eVWhich = WhichV(eWhich);
1356     EditView* pCurView = pEditView[eWhich];
1357 
1358     if ( !pCurView || !bEditActive[eWhich])
1359         return;
1360 
1361     sal_uLong nControl = pEditView[eWhich]->GetControlWord();
1362     if ( nControl & EV_CNTRL_AUTOSCROLL )
1363     {
1364         //  if end of screen had already been reached and scrolling enabled,
1365         //  don't further try to grow the edit area
1366 
1367         pCurView->SetOutputArea( pCurView->GetOutputArea() );   // re-align to pixels
1368         return;
1369     }
1370 
1371     EditEngine* pEngine = pCurView->GetEditEngine();
1372     Window* pWin = pCurView->GetWindow();
1373 
1374     SCROW nBottom = GetPosY(eVWhich) + VisibleCellsY(eVWhich);
1375 
1376     Size        aSize = pEngine->GetPaperSize();
1377     Rectangle   aArea = pCurView->GetOutputArea();
1378     long        nOldBottom = aArea.Bottom();
1379     long        nTextHeight = pEngine->GetTextHeight();
1380 
1381     //  #106635# When editing a formula in a cell with optimal height, allow a larger portion
1382     //  to be clipped before extending to following rows, to avoid obscuring cells for
1383     //  reference input (next row is likely to be useful in formulas).
1384     long nAllowedExtra = SC_GROWY_SMALL_EXTRA;
1385     if ( nEditEndRow == nEditRow && !( pDoc->GetRowFlags( nEditRow, nTabNo ) & CR_MANUALSIZE ) &&
1386             pEngine->GetParagraphCount() <= 1 )
1387     {
1388         //  If the (only) paragraph starts with a '=', it's a formula.
1389         //  If this is the initial call and the text is empty, allow the larger value, too,
1390         //  because this occurs in the normal progress of editing a formula.
1391         //  Subsequent calls with empty text might involve changed attributes (including
1392         //  font height), so they are treated like normal text.
1393         String aText = pEngine->GetText( (sal_uInt16) 0 );
1394         if ( ( aText.Len() == 0 && bInitial ) || aText.GetChar(0) == (sal_Unicode)'=' )
1395             nAllowedExtra = SC_GROWY_BIG_EXTRA;
1396     }
1397 
1398     sal_Bool bChanged = sal_False;
1399     sal_Bool bMaxReached = sal_False;
1400     while (aArea.GetHeight() + nAllowedExtra < nTextHeight && nEditEndRow < nBottom && !bMaxReached)
1401     {
1402         ++nEditEndRow;
1403         ScDocument* pLocalDoc = GetDocument();
1404         long nPix = ToPixel( pLocalDoc->GetRowHeight( nEditEndRow, nTabNo ), nPPTY );
1405         aArea.Bottom() += pWin->PixelToLogic(Size(0,nPix)).Height();
1406 
1407         if ( aArea.Bottom() > aArea.Top() + aSize.Height() - 1 )
1408         {
1409             aArea.Bottom() = aArea.Top() + aSize.Height() - 1;
1410             bMaxReached = sal_True;     // don't occupy more cells beyond paper size
1411         }
1412 
1413         bChanged = sal_True;
1414         nAllowedExtra = SC_GROWY_SMALL_EXTRA;   // larger value is only for first row
1415     }
1416 
1417     if (bChanged)
1418     {
1419         pCurView->SetOutputArea(aArea);
1420 
1421         if (nEditEndRow >= nBottom || bMaxReached)
1422         {
1423             if ((nControl & EV_CNTRL_AUTOSCROLL) == 0)
1424                 pCurView->SetControlWord( nControl | EV_CNTRL_AUTOSCROLL );
1425         }
1426 
1427         aArea.Top() = nOldBottom;
1428         pWin->Invalidate(aArea);
1429     }
1430 }
1431 
ResetEditView()1432 void ScViewData::ResetEditView()
1433 {
1434     EditEngine* pEngine = NULL;
1435     for (sal_uInt16 i=0; i<4; i++)
1436         if (pEditView[i])
1437         {
1438             if (bEditActive[i])
1439             {
1440                 pEngine = pEditView[i]->GetEditEngine();
1441                 pEngine->RemoveView(pEditView[i]);
1442                 pEditView[i]->SetOutputArea( Rectangle() );
1443             }
1444             bEditActive[i] = sal_False;
1445         }
1446 
1447     if (pEngine)
1448         pEngine->SetStatusEventHdl( LINK( this, ScViewData, EmptyEditHdl ) );
1449 }
1450 
KillEditView()1451 void ScViewData::KillEditView()
1452 {
1453     for (sal_uInt16 i=0; i<4; i++)
1454         if (pEditView[i])
1455         {
1456             if (bEditActive[i])
1457                 pEditView[i]->GetEditEngine()->RemoveView(pEditView[i]);
1458             delete pEditView[i];
1459             pEditView[i] = NULL;
1460         }
1461 }
1462 
GetEditView(ScSplitPos eWhich,EditView * & rViewPtr,SCCOL & rCol,SCROW & rRow)1463 void ScViewData::GetEditView( ScSplitPos eWhich, EditView*& rViewPtr, SCCOL& rCol, SCROW& rRow )
1464 {
1465     rViewPtr = pEditView[eWhich];
1466     rCol = nEditCol;
1467     rRow = nEditRow;
1468 }
1469 
CreateTabData(SCTAB nNewTab)1470 void ScViewData::CreateTabData( SCTAB nNewTab )
1471 {
1472     if (!pTabData[nNewTab])
1473     {
1474         pTabData[nNewTab] = new ScViewDataTable;
1475 
1476         pTabData[nNewTab]->eZoomType  = eDefZoomType;
1477         pTabData[nNewTab]->aZoomX     = aDefZoomX;
1478         pTabData[nNewTab]->aZoomY     = aDefZoomY;
1479         pTabData[nNewTab]->aPageZoomX = aDefPageZoomX;
1480         pTabData[nNewTab]->aPageZoomY = aDefPageZoomY;
1481     }
1482 }
1483 
CreateSelectedTabData()1484 void ScViewData::CreateSelectedTabData()
1485 {
1486     SCTAB nTabCount = pDoc->GetTableCount();
1487     for (SCTAB i=0; i<nTabCount; i++)
1488         if ( aMarkData.GetTableSelect(i) && !pTabData[i] )
1489             CreateTabData( i );
1490 }
1491 
SetTabNo(SCTAB nNewTab)1492 void ScViewData::SetTabNo( SCTAB nNewTab )
1493 {
1494     if (!ValidTab(nNewTab))
1495     {
1496         DBG_ERROR("falsche Tabellennummer");
1497         return;
1498     }
1499 
1500     nTabNo = nNewTab;
1501     CreateTabData(nTabNo);
1502     pThisTab = pTabData[nTabNo];
1503 
1504     CalcPPT();          //  for common column width correction
1505     RecalcPixPos();     //! nicht immer noetig!
1506 }
1507 
SetActivePart(ScSplitPos eNewActive)1508 void ScViewData::SetActivePart( ScSplitPos eNewActive )
1509 {
1510     pThisTab->eWhichActive = eNewActive;
1511 }
1512 
GetScrPos(SCCOL nWhereX,SCROW nWhereY,ScHSplitPos eWhich) const1513 Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScHSplitPos eWhich ) const
1514 {
1515     DBG_ASSERT( eWhich==SC_SPLIT_LEFT || eWhich==SC_SPLIT_RIGHT, "Falsche Position" );
1516     ScSplitPos ePos = ( eWhich == SC_SPLIT_LEFT ) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
1517     return GetScrPos( nWhereX, nWhereY, ePos );
1518 }
1519 
GetScrPos(SCCOL nWhereX,SCROW nWhereY,ScVSplitPos eWhich) const1520 Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScVSplitPos eWhich ) const
1521 {
1522     DBG_ASSERT( eWhich==SC_SPLIT_TOP || eWhich==SC_SPLIT_BOTTOM, "Falsche Position" );
1523     ScSplitPos ePos = ( eWhich == SC_SPLIT_TOP ) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
1524     return GetScrPos( nWhereX, nWhereY, ePos );
1525 }
1526 
GetScrPos(SCCOL nWhereX,SCROW nWhereY,ScSplitPos eWhich,sal_Bool bAllowNeg) const1527 Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
1528                                 sal_Bool bAllowNeg ) const
1529 {
1530     ScHSplitPos eWhichX = SC_SPLIT_LEFT;
1531     ScVSplitPos eWhichY = SC_SPLIT_BOTTOM;
1532     switch( eWhich )
1533     {
1534         case SC_SPLIT_TOPLEFT:
1535             eWhichX = SC_SPLIT_LEFT;
1536             eWhichY = SC_SPLIT_TOP;
1537             break;
1538         case SC_SPLIT_TOPRIGHT:
1539             eWhichX = SC_SPLIT_RIGHT;
1540             eWhichY = SC_SPLIT_TOP;
1541             break;
1542         case SC_SPLIT_BOTTOMLEFT:
1543             eWhichX = SC_SPLIT_LEFT;
1544             eWhichY = SC_SPLIT_BOTTOM;
1545             break;
1546         case SC_SPLIT_BOTTOMRIGHT:
1547             eWhichX = SC_SPLIT_RIGHT;
1548             eWhichY = SC_SPLIT_BOTTOM;
1549             break;
1550     }
1551 
1552     if (pView)
1553     {
1554         ((ScViewData*)this)->aScrSize.Width()  = pView->GetGridWidth(eWhichX);
1555         ((ScViewData*)this)->aScrSize.Height() = pView->GetGridHeight(eWhichY);
1556     }
1557 
1558     sal_uInt16 nTSize;
1559 
1560     SCCOL   nPosX = GetPosX(eWhichX);
1561     SCCOL   nX;
1562 
1563     long nScrPosX=0;
1564     if (nWhereX >= nPosX)
1565         for (nX=nPosX; nX<nWhereX && (bAllowNeg || nScrPosX<=aScrSize.Width()); nX++)
1566         {
1567             if ( nX > MAXCOL )
1568                 nScrPosX = 65535;
1569             else
1570             {
1571                 nTSize = pDoc->GetColWidth( nX, nTabNo );
1572                 if (nTSize)
1573                 {
1574                     long nSizeXPix = ToPixel( nTSize, nPPTX );
1575                     nScrPosX += nSizeXPix;
1576                 }
1577             }
1578         }
1579     else if (bAllowNeg)
1580         for (nX=nPosX; nX>nWhereX;)
1581         {
1582             --nX;
1583             nTSize = pDoc->GetColWidth( nX, nTabNo );
1584             if (nTSize)
1585             {
1586                 long nSizeXPix = ToPixel( nTSize, nPPTX );
1587                 nScrPosX -= nSizeXPix;
1588             }
1589         }
1590 
1591     SCROW   nPosY = GetPosY(eWhichY);
1592     SCROW   nY;
1593 
1594     long nScrPosY=0;
1595     if (nWhereY >= nPosY)
1596         for (nY=nPosY; nY<nWhereY && (bAllowNeg || nScrPosY<=aScrSize.Height()); nY++)
1597         {
1598             if ( nY > MAXROW )
1599                 nScrPosY = 65535;
1600             else
1601             {
1602                 nTSize = pDoc->GetRowHeight( nY, nTabNo );
1603                 if (nTSize)
1604                 {
1605                     long nSizeYPix = ToPixel( nTSize, nPPTY );
1606                     nScrPosY += nSizeYPix;
1607                 }
1608                 else if ( nY < MAXROW )
1609                 {
1610                     // skip multiple hidden rows (forward only for now)
1611                     SCROW nNext = pDoc->FirstVisibleRow(nY + 1, MAXROW, nTabNo);
1612                     if ( nNext > MAXROW )
1613                         nY = MAXROW;
1614                     else
1615                         nY = nNext - 1;     // +=nDir advances to next visible row
1616                 }
1617             }
1618         }
1619     else if (bAllowNeg)
1620         for (nY=nPosY; nY>nWhereY;)
1621         {
1622             --nY;
1623             nTSize = pDoc->GetRowHeight( nY, nTabNo );
1624             if (nTSize)
1625             {
1626                 long nSizeYPix = ToPixel( nTSize, nPPTY );
1627                 nScrPosY -= nSizeYPix;
1628             }
1629         }
1630 
1631     if ( pDoc->IsLayoutRTL( nTabNo ) )
1632     {
1633         //  mirror horizontal position
1634         nScrPosX = aScrSize.Width() - 1 - nScrPosX;
1635     }
1636 
1637     if (nScrPosX > 32767) nScrPosX=32767;
1638     if (nScrPosY > 32767) nScrPosY=32767;
1639     return Point( nScrPosX, nScrPosY );
1640 }
1641 
1642 //
1643 //      Anzahl Zellen auf einem Bildschirm
1644 //
1645 
CellsAtX(SCsCOL nPosX,SCsCOL nDir,ScHSplitPos eWhichX,sal_uInt16 nScrSizeX) const1646 SCCOL ScViewData::CellsAtX( SCsCOL nPosX, SCsCOL nDir, ScHSplitPos eWhichX, sal_uInt16 nScrSizeX ) const
1647 {
1648     DBG_ASSERT( nDir==1 || nDir==-1, "falscher CellsAt Aufruf" );
1649 
1650     if (pView)
1651         ((ScViewData*)this)->aScrSize.Width()  = pView->GetGridWidth(eWhichX);
1652 
1653     SCsCOL  nX;
1654     sal_uInt16  nScrPosX = 0;
1655     if (nScrSizeX == SC_SIZE_NONE) nScrSizeX = (sal_uInt16) aScrSize.Width();
1656 
1657     if (nDir==1)
1658         nX = nPosX;             // vorwaerts
1659     else
1660         nX = nPosX-1;           // rueckwaerts
1661 
1662     sal_Bool bOut = sal_False;
1663     for ( ; nScrPosX<=nScrSizeX && !bOut; nX = sal::static_int_cast<SCsCOL>(nX + nDir) )
1664     {
1665         SCsCOL  nColNo = nX;
1666         if ( nColNo < 0 || nColNo > MAXCOL )
1667             bOut = sal_True;
1668         else
1669         {
1670             sal_uInt16 nTSize = pDoc->GetColWidth( nColNo, nTabNo );
1671             if (nTSize)
1672             {
1673                 long nSizeXPix = ToPixel( nTSize, nPPTX );
1674                 nScrPosX = sal::static_int_cast<sal_uInt16>( nScrPosX + (sal_uInt16) nSizeXPix );
1675             }
1676         }
1677     }
1678 
1679     if (nDir==1)
1680         nX = sal::static_int_cast<SCsCOL>( nX - nPosX );
1681     else
1682         nX = (nPosX-1)-nX;
1683 
1684     if (nX>0) --nX;
1685     return nX;
1686 }
1687 
CellsAtY(SCsROW nPosY,SCsROW nDir,ScVSplitPos eWhichY,sal_uInt16 nScrSizeY) const1688 SCROW ScViewData::CellsAtY( SCsROW nPosY, SCsROW nDir, ScVSplitPos eWhichY, sal_uInt16 nScrSizeY ) const
1689 {
1690     DBG_ASSERT( nDir==1 || nDir==-1, "falscher CellsAt Aufruf" );
1691 
1692     if (pView)
1693         ((ScViewData*)this)->aScrSize.Height() = pView->GetGridHeight(eWhichY);
1694 
1695     if (nScrSizeY == SC_SIZE_NONE) nScrSizeY = (sal_uInt16) aScrSize.Height();
1696 
1697     SCROW nY;
1698 
1699     if (nDir==1)
1700     {
1701         // forward
1702         nY = nPosY;
1703         long nScrPosY = 0;
1704         AddPixelsWhile( nScrPosY, nScrSizeY, nY, MAXROW, nPPTY, pDoc, nTabNo);
1705         // Original loop ended on last evaluated +1 or if that was MAXROW even
1706         // on MAXROW+2.
1707         nY += (nY == MAXROW ? 2 : 1);
1708         nY -= nPosY;
1709     }
1710     else
1711     {
1712         // backward
1713         nY = nPosY-1;
1714         long nScrPosY = 0;
1715         AddPixelsWhileBackward( nScrPosY, nScrSizeY, nY, 0, nPPTY, pDoc, nTabNo);
1716         // Original loop ended on last evaluated -1 or if that was 0 even on
1717         // -2.
1718         nY -= (nY == 0 ? 2 : 1);
1719         nY = (nPosY-1)-nY;
1720     }
1721 
1722     if (nY>0) --nY;
1723     return nY;
1724 }
1725 
VisibleCellsX(ScHSplitPos eWhichX) const1726 SCCOL ScViewData::VisibleCellsX( ScHSplitPos eWhichX ) const
1727 {
1728     return CellsAtX( GetPosX( eWhichX ), 1, eWhichX, SC_SIZE_NONE );
1729 }
1730 
VisibleCellsY(ScVSplitPos eWhichY) const1731 SCROW ScViewData::VisibleCellsY( ScVSplitPos eWhichY ) const
1732 {
1733     return CellsAtY( GetPosY( eWhichY ), 1, eWhichY, SC_SIZE_NONE );
1734 }
1735 
PrevCellsX(ScHSplitPos eWhichX) const1736 SCCOL ScViewData::PrevCellsX( ScHSplitPos eWhichX ) const
1737 {
1738     return CellsAtX( GetPosX( eWhichX ), -1, eWhichX, SC_SIZE_NONE );
1739 }
1740 
PrevCellsY(ScVSplitPos eWhichY) const1741 SCROW ScViewData::PrevCellsY( ScVSplitPos eWhichY ) const
1742 {
1743     return CellsAtY( GetPosY( eWhichY ), -1, eWhichY, SC_SIZE_NONE );
1744 }
1745 
1746 //UNUSED2008-05  SCCOL ScViewData::LastCellsX( ScHSplitPos eWhichX ) const
1747 //UNUSED2008-05  {
1748 //UNUSED2008-05      return CellsAtX( MAXCOL+1, -1, eWhichX, SC_SIZE_NONE );
1749 //UNUSED2008-05  }
1750 //UNUSED2008-05
1751 //UNUSED2008-05  SCROW ScViewData::LastCellsY( ScVSplitPos eWhichY ) const
1752 //UNUSED2008-05  {
1753 //UNUSED2008-05      return CellsAtY( MAXROW+1, -1, eWhichY, SC_SIZE_NONE );
1754 //UNUSED2008-05  }
1755 
GetMergeSizePixel(SCCOL nX,SCROW nY,long & rSizeXPix,long & rSizeYPix)1756 sal_Bool ScViewData::GetMergeSizePixel( SCCOL nX, SCROW nY, long& rSizeXPix, long& rSizeYPix )
1757 {
1758     const ScMergeAttr* pMerge = (const ScMergeAttr*) pDoc->GetAttr( nX,nY,nTabNo, ATTR_MERGE );
1759     if ( pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1 )
1760     {
1761         long nOutWidth = 0;
1762         long nOutHeight = 0;
1763         SCCOL nCountX = pMerge->GetColMerge();
1764         for (SCCOL i=0; i<nCountX; i++)
1765             nOutWidth += ToPixel( pDoc->GetColWidth(nX+i,nTabNo), nPPTX );
1766         SCROW nCountY = pMerge->GetRowMerge();
1767 
1768         for (SCROW nRow = nY; nRow <= nY+nCountY-1; ++nRow)
1769         {
1770             SCROW nLastRow = nRow;
1771             if (pDoc->RowHidden(nRow, nTabNo, NULL, &nLastRow))
1772             {
1773                 nRow = nLastRow;
1774                 continue;
1775             }
1776 
1777             sal_uInt16 nHeight = pDoc->GetRowHeight(nRow, nTabNo);
1778             nOutHeight += ToPixel(nHeight, nPPTY);
1779         }
1780 
1781         rSizeXPix = nOutWidth;
1782         rSizeYPix = nOutHeight;
1783         return sal_True;
1784     }
1785     else
1786     {
1787         rSizeXPix = ToPixel( pDoc->GetColWidth( nX, nTabNo ), nPPTX );
1788         rSizeYPix = ToPixel( pDoc->GetRowHeight( nY, nTabNo ), nPPTY );
1789         return sal_False;
1790     }
1791 }
1792 
GetPosFromPixel(long nClickX,long nClickY,ScSplitPos eWhich,SCsCOL & rPosX,SCsROW & rPosY,sal_Bool bTestMerge,sal_Bool bRepair,sal_Bool bNextIfLarge)1793 sal_Bool ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich,
1794                                         SCsCOL& rPosX, SCsROW& rPosY,
1795                                         sal_Bool bTestMerge, sal_Bool bRepair, sal_Bool bNextIfLarge )
1796 {
1797     //  special handling of 0 is now in ScViewFunctionSet::SetCursorAtPoint
1798 
1799     ScHSplitPos eHWhich = WhichH(eWhich);
1800     ScVSplitPos eVWhich = WhichV(eWhich);
1801 
1802     if ( pDoc->IsLayoutRTL( nTabNo ) )
1803     {
1804         //  mirror horizontal position
1805         if (pView)
1806             aScrSize.Width() = pView->GetGridWidth(eHWhich);
1807         nClickX = aScrSize.Width() - 1 - nClickX;
1808     }
1809 
1810     SCsCOL nStartPosX = GetPosX(eHWhich);
1811     SCsROW nStartPosY = GetPosY(eVWhich);
1812     rPosX = nStartPosX;
1813     rPosY = nStartPosY;
1814     long nScrX = 0;
1815     long nScrY = 0;
1816 
1817     if (nClickX > 0)
1818     {
1819         while ( rPosX<=MAXCOL && nClickX >= nScrX )
1820         {
1821             nScrX += ToPixel( pDoc->GetColWidth( rPosX, nTabNo ), nPPTX );
1822             ++rPosX;
1823         }
1824         --rPosX;
1825     }
1826     else
1827     {
1828         while ( rPosX>0 && nClickX < nScrX )
1829         {
1830             --rPosX;
1831             nScrX -= ToPixel( pDoc->GetColWidth( rPosX, nTabNo ), nPPTX );
1832         }
1833     }
1834 
1835     if (nClickY > 0)
1836         AddPixelsWhile( nScrY, nClickY, rPosY, MAXROW, nPPTY, pDoc, nTabNo );
1837     else
1838     {
1839         /* TODO: could need some "SubPixelsWhileBackward" method */
1840         while ( rPosY>0 && nClickY < nScrY )
1841         {
1842             --rPosY;
1843             nScrY -= ToPixel( pDoc->GetRowHeight( rPosY, nTabNo ), nPPTY );
1844         }
1845     }
1846 
1847     if (bNextIfLarge)       //  zu grosse Zellen ?
1848     {
1849         if ( rPosX == nStartPosX && nClickX > 0 )
1850         {
1851             if (pView)
1852                 aScrSize.Width() = pView->GetGridWidth(eHWhich);
1853             if ( nClickX > aScrSize.Width() )
1854                 ++rPosX;
1855         }
1856         if ( rPosY == nStartPosY && nClickY > 0 )
1857         {
1858             if (pView)
1859                 aScrSize.Height() = pView->GetGridHeight(eVWhich);
1860             if ( nClickY > aScrSize.Height() )
1861                 ++rPosY;
1862         }
1863     }
1864 
1865     if (rPosX<0) rPosX=0;
1866     if (rPosX>MAXCOL) rPosX=MAXCOL;
1867     if (rPosY<0) rPosY=0;
1868     if (rPosY>MAXROW) rPosY=MAXROW;
1869 
1870     if (bTestMerge)
1871     {
1872         //! public Methode um Position anzupassen
1873 
1874         sal_Bool bHOver = sal_False;
1875         while (pDoc->IsHorOverlapped( rPosX, rPosY, nTabNo ))
1876             { --rPosX; bHOver=sal_True; }
1877         sal_Bool bVOver = sal_False;
1878         while (pDoc->IsVerOverlapped( rPosX, rPosY, nTabNo ))
1879             { --rPosY; bVOver=sal_True; }
1880 
1881         if ( bRepair && ( bHOver || bVOver ) )
1882         {
1883             const ScMergeAttr* pMerge = (const ScMergeAttr*)
1884                                 pDoc->GetAttr( rPosX, rPosY, nTabNo, ATTR_MERGE );
1885             if ( ( bHOver && pMerge->GetColMerge() <= 1 ) ||
1886                  ( bVOver && pMerge->GetRowMerge() <= 1 ) )
1887             {
1888                 DBG_ERROR("Merge-Fehler gefunden");
1889 
1890                 pDoc->RemoveFlagsTab( 0,0, MAXCOL,MAXROW, nTabNo, SC_MF_HOR | SC_MF_VER );
1891                 SCCOL nEndCol = MAXCOL;
1892                 SCROW nEndRow = MAXROW;
1893                 pDoc->ExtendMerge( 0,0, nEndCol,nEndRow, nTabNo, sal_True, sal_False );
1894                 if (pDocShell)
1895                     pDocShell->PostPaint( ScRange(0,0,nTabNo,MAXCOL,MAXROW,nTabNo), PAINT_GRID );
1896             }
1897         }
1898     }
1899 
1900     return sal_False;
1901 }
1902 
GetMouseQuadrant(const Point & rClickPos,ScSplitPos eWhich,SCsCOL nPosX,SCsROW nPosY,sal_Bool & rLeft,sal_Bool & rTop)1903 void ScViewData::GetMouseQuadrant( const Point& rClickPos, ScSplitPos eWhich,
1904                                         SCsCOL nPosX, SCsROW nPosY, sal_Bool& rLeft, sal_Bool& rTop )
1905 {
1906     sal_Bool bLayoutRTL = pDoc->IsLayoutRTL( nTabNo );
1907     long nLayoutSign = bLayoutRTL ? -1 : 1;
1908 
1909     Point aCellStart = GetScrPos( nPosX, nPosY, eWhich, sal_True );
1910     long nSizeX;
1911     long nSizeY;
1912     GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY );
1913     rLeft = ( rClickPos.X() - aCellStart.X() ) * nLayoutSign <= nSizeX / 2;
1914     rTop  = rClickPos.Y() - aCellStart.Y() <= nSizeY / 2;
1915 }
1916 
SetPosX(ScHSplitPos eWhich,SCCOL nNewPosX)1917 void ScViewData::SetPosX( ScHSplitPos eWhich, SCCOL nNewPosX )
1918 {
1919     if (nNewPosX != 0)
1920     {
1921         SCCOL nOldPosX = pThisTab->nPosX[eWhich];
1922         long nTPosX = pThisTab->nTPosX[eWhich];
1923         long nPixPosX = pThisTab->nPixPosX[eWhich];
1924         SCCOL i;
1925         if ( nNewPosX > nOldPosX )
1926             for ( i=nOldPosX; i<nNewPosX; i++ )
1927             {
1928                 long nThis = pDoc->GetColWidth( i,nTabNo );
1929                 nTPosX -= nThis;
1930                 nPixPosX -= ToPixel(sal::static_int_cast<sal_uInt16>(nThis), nPPTX);
1931             }
1932         else
1933             for ( i=nNewPosX; i<nOldPosX; i++ )
1934             {
1935                 long nThis = pDoc->GetColWidth( i,nTabNo );
1936                 nTPosX += nThis;
1937                 nPixPosX += ToPixel(sal::static_int_cast<sal_uInt16>(nThis), nPPTX);
1938             }
1939 
1940         pThisTab->nPosX[eWhich] = nNewPosX;
1941         pThisTab->nTPosX[eWhich] = nTPosX;
1942         pThisTab->nMPosX[eWhich] = (long) (nTPosX * HMM_PER_TWIPS);
1943         pThisTab->nPixPosX[eWhich] = nPixPosX;
1944     }
1945     else
1946         pThisTab->nPixPosX[eWhich] =
1947         pThisTab->nTPosX[eWhich] =
1948         pThisTab->nMPosX[eWhich] =
1949         pThisTab->nPosX[eWhich] = 0;
1950 }
1951 
SetPosY(ScVSplitPos eWhich,SCROW nNewPosY)1952 void ScViewData::SetPosY( ScVSplitPos eWhich, SCROW nNewPosY )
1953 {
1954     if (nNewPosY != 0)
1955     {
1956         SCROW nOldPosY = pThisTab->nPosY[eWhich];
1957         long nTPosY = pThisTab->nTPosY[eWhich];
1958         long nPixPosY = pThisTab->nPixPosY[eWhich];
1959         SCROW i, nHeightEndRow;
1960         if ( nNewPosY > nOldPosY )
1961             for ( i=nOldPosY; i<nNewPosY; i++ )
1962             {
1963                 long nThis = pDoc->GetRowHeight( i, nTabNo, NULL, &nHeightEndRow );
1964                 SCROW nRows = std::min( nNewPosY, nHeightEndRow + 1) - i;
1965                 i = nHeightEndRow;
1966                 nTPosY -= nThis * nRows;
1967                 nPixPosY -= ToPixel(sal::static_int_cast<sal_uInt16>(nThis), nPPTY) * nRows;
1968             }
1969         else
1970             for ( i=nNewPosY; i<nOldPosY; i++ )
1971             {
1972                 long nThis = pDoc->GetRowHeight( i, nTabNo, NULL, &nHeightEndRow );
1973                 SCROW nRows = std::min( nOldPosY, nHeightEndRow + 1) - i;
1974                 i = nHeightEndRow;
1975                 nTPosY += nThis * nRows;
1976                 nPixPosY += ToPixel(sal::static_int_cast<sal_uInt16>(nThis), nPPTY) * nRows;
1977             }
1978 
1979         pThisTab->nPosY[eWhich] = nNewPosY;
1980         pThisTab->nTPosY[eWhich] = nTPosY;
1981         pThisTab->nMPosY[eWhich] = (long) (nTPosY * HMM_PER_TWIPS);
1982         pThisTab->nPixPosY[eWhich] = nPixPosY;
1983     }
1984     else
1985         pThisTab->nPixPosY[eWhich] =
1986         pThisTab->nTPosY[eWhich] =
1987         pThisTab->nMPosY[eWhich] =
1988         pThisTab->nPosY[eWhich] = 0;
1989 }
1990 
RecalcPixPos()1991 void ScViewData::RecalcPixPos()             // nach Zoom-Aenderungen
1992 {
1993     for (sal_uInt16 eWhich=0; eWhich<2; eWhich++)
1994     {
1995         long nPixPosX = 0;
1996         SCCOL nPosX = pThisTab->nPosX[eWhich];
1997         for (SCCOL i=0; i<nPosX; i++)
1998             nPixPosX -= ToPixel(pDoc->GetColWidth(i,nTabNo), nPPTX);
1999         pThisTab->nPixPosX[eWhich] = nPixPosX;
2000 
2001         long nPixPosY = 0;
2002         SCROW nPosY = pThisTab->nPosY[eWhich];
2003         for (SCROW j=0; j<nPosY; j++)
2004             nPixPosY -= ToPixel(pDoc->GetRowHeight(j,nTabNo), nPPTY);
2005         pThisTab->nPixPosY[eWhich] = nPixPosY;
2006     }
2007 }
2008 
GetLogicMode(ScSplitPos eWhich)2009 const MapMode& ScViewData::GetLogicMode( ScSplitPos eWhich )
2010 {
2011     aLogicMode.SetOrigin( Point( pThisTab->nMPosX[WhichH(eWhich)],
2012                                     pThisTab->nMPosY[WhichV(eWhich)] ) );
2013     return aLogicMode;
2014 }
2015 
GetLogicMode()2016 const MapMode& ScViewData::GetLogicMode()
2017 {
2018     aLogicMode.SetOrigin( Point() );
2019     return aLogicMode;
2020 }
2021 
SetScreen(SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2)2022 void ScViewData::SetScreen( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
2023 {
2024     SCCOL nCol;
2025     SCROW nRow;
2026     sal_uInt16 nTSize;
2027     long nSizePix;
2028     long nScrPosX = 0;
2029     long nScrPosY = 0;
2030 
2031     SetActivePart( SC_SPLIT_BOTTOMLEFT );
2032     SetPosX( SC_SPLIT_LEFT, nCol1 );
2033     SetPosY( SC_SPLIT_BOTTOM, nRow1 );
2034 
2035     for (nCol=nCol1; nCol<=nCol2; nCol++)
2036     {
2037         nTSize = pDoc->GetColWidth( nCol, nTabNo );
2038         if (nTSize)
2039         {
2040             nSizePix = ToPixel( nTSize, nPPTX );
2041             nScrPosX += (sal_uInt16) nSizePix;
2042         }
2043     }
2044 
2045     for (nRow=nRow1; nRow<=nRow2; nRow++)
2046     {
2047         nTSize = pDoc->GetRowHeight( nRow, nTabNo );
2048         if (nTSize)
2049         {
2050             nSizePix = ToPixel( nTSize, nPPTY );
2051             nScrPosY += (sal_uInt16) nSizePix;
2052         }
2053     }
2054 
2055     aScrSize = Size( nScrPosX, nScrPosY );
2056 }
2057 
SetScreenPos(const Point & rVisAreaStart)2058 void ScViewData::SetScreenPos( const Point& rVisAreaStart )
2059 {
2060     long nSize;
2061     long nTwips;
2062     long nAdd;
2063     sal_Bool bEnd;
2064 
2065     nSize = 0;
2066     nTwips = (long) (rVisAreaStart.X() / HMM_PER_TWIPS);
2067     if ( pDoc->IsLayoutRTL( nTabNo ) )
2068         nTwips = -nTwips;
2069     SCCOL nX1 = 0;
2070     bEnd = sal_False;
2071     while (!bEnd)
2072     {
2073         nAdd = (long) pDoc->GetColWidth(nX1,nTabNo);
2074         if (nSize+nAdd <= nTwips+1 && nX1<MAXCOL)
2075         {
2076             nSize += nAdd;
2077             ++nX1;
2078         }
2079         else
2080             bEnd = sal_True;
2081     }
2082 
2083     nSize = 0;
2084     nTwips = (long) (rVisAreaStart.Y() / HMM_PER_TWIPS);
2085     SCROW nY1 = 0;
2086     bEnd = sal_False;
2087     while (!bEnd)
2088     {
2089         nAdd = (long) pDoc->GetRowHeight(nY1,nTabNo);
2090         if (nSize+nAdd <= nTwips+1 && nY1<MAXROW)
2091         {
2092             nSize += nAdd;
2093             ++nY1;
2094         }
2095         else
2096             bEnd = sal_True;
2097     }
2098 
2099     SetActivePart( SC_SPLIT_BOTTOMLEFT );
2100     SetPosX( SC_SPLIT_LEFT, nX1 );
2101     SetPosY( SC_SPLIT_BOTTOM, nY1 );
2102 
2103     SetCurX( nX1 );
2104     SetCurY( nY1 );
2105 }
2106 
SetScreen(const Rectangle & rVisArea)2107 void ScViewData::SetScreen( const Rectangle& rVisArea )
2108 {
2109     SetScreenPos( rVisArea.TopLeft() );
2110 
2111     //  hier ohne GetOutputFactor(), weil fuer Ausgabe in Metafile
2112 
2113     aScrSize = rVisArea.GetSize();
2114     aScrSize.Width() = (long)
2115         ( aScrSize.Width() * ScGlobal::nScreenPPTX / HMM_PER_TWIPS );
2116     aScrSize.Height() = (long)
2117         ( aScrSize.Height() * ScGlobal::nScreenPPTY / HMM_PER_TWIPS );
2118 }
2119 
GetSfxDocShell() const2120 SfxObjectShell* ScViewData::GetSfxDocShell() const
2121 {
2122     return pDocShell;
2123 }
2124 
GetBindings()2125 SfxBindings& ScViewData::GetBindings()
2126 {
2127     DBG_ASSERT( pViewShell, "GetBindings() without ViewShell" );
2128     return pViewShell->GetViewFrame()->GetBindings();
2129 }
2130 
GetDispatcher()2131 SfxDispatcher& ScViewData::GetDispatcher()
2132 {
2133     DBG_ASSERT( pViewShell, "GetDispatcher() without ViewShell" );
2134     return *pViewShell->GetViewFrame()->GetDispatcher();
2135 }
2136 
GetDialogParent()2137 Window* ScViewData::GetDialogParent()
2138 {
2139     DBG_ASSERT( pViewShell, "GetDialogParent() ohne ViewShell" );
2140     return pViewShell->GetDialogParent();
2141 }
2142 
GetActiveWin()2143 Window* ScViewData::GetActiveWin()
2144 {
2145     DBG_ASSERT( pView, "GetActiveWin() ohne View" );
2146     return pView->GetActiveWin();
2147 }
2148 
GetScDrawView()2149 ScDrawView* ScViewData::GetScDrawView()
2150 {
2151     DBG_ASSERT( pView, "GetScDrawView() ohne View" );
2152     return pView->GetScDrawView();
2153 }
2154 
IsMinimized()2155 sal_Bool ScViewData::IsMinimized()
2156 {
2157     DBG_ASSERT( pView, "IsMinimized() ohne View" );
2158     return pView->IsMinimized();
2159 }
2160 
UpdateScreenZoom(const Fraction & rNewX,const Fraction & rNewY)2161 void ScViewData::UpdateScreenZoom( const Fraction& rNewX, const Fraction& rNewY )
2162 {
2163     Fraction aOldX = GetZoomX();
2164     Fraction aOldY = GetZoomY();
2165 
2166     SetZoom( rNewX, rNewY, sal_False );
2167 
2168     Fraction aWidth = GetZoomX();
2169     aWidth *= Fraction( aScrSize.Width(),1 );
2170     aWidth /= aOldX;
2171 
2172     Fraction aHeight = GetZoomY();
2173     aHeight *= Fraction( aScrSize.Height(),1 );
2174     aHeight /= aOldY;
2175 
2176     aScrSize.Width()  = (long) aWidth;
2177     aScrSize.Height() = (long) aHeight;
2178 }
2179 
CalcPPT()2180 void ScViewData::CalcPPT()
2181 {
2182     nPPTX = ScGlobal::nScreenPPTX * (double) GetZoomX();
2183     if (pDocShell)
2184         nPPTX = nPPTX / pDocShell->GetOutputFactor();   // Faktor ist Drucker zu Bildschirm
2185     nPPTY = ScGlobal::nScreenPPTY * (double) GetZoomY();
2186 
2187     //  #83616# if detective objects are present,
2188     //  try to adjust horizontal scale so the most common column width has minimal rounding errors,
2189     //  to avoid differences between cell and drawing layer output
2190 
2191     if ( pDoc && pDoc->HasDetectiveObjects(nTabNo) )
2192     {
2193         SCCOL nEndCol = 0;
2194         SCROW nDummy = 0;
2195         pDoc->GetTableArea( nTabNo, nEndCol, nDummy );
2196         if (nEndCol<20)
2197             nEndCol = 20;           // same end position as when determining draw scale
2198 
2199         sal_uInt16 nTwips = pDoc->GetCommonWidth( nEndCol, nTabNo );
2200         if ( nTwips )
2201         {
2202             double fOriginal = nTwips * nPPTX;
2203             if ( fOriginal < static_cast<double>(nEndCol) )
2204             {
2205                 //  if one column is smaller than the column count,
2206                 //  rounding errors are likely to add up to a whole column.
2207 
2208                 double fRounded = ::rtl::math::approxFloor( fOriginal + 0.5 );
2209                 if ( fRounded > 0.0 )
2210                 {
2211                     double fScale = fRounded / fOriginal + 1E-6;
2212                     if ( fScale >= 0.9 && fScale <= 1.1 )
2213                         nPPTX *= fScale;
2214                 }
2215             }
2216         }
2217     }
2218 }
2219 
2220 //------------------------------------------------------------------
2221 
2222 #define SC_OLD_TABSEP   '/'
2223 #define SC_NEW_TABSEP   '+'
2224 
WriteUserData(String & rData)2225 void ScViewData::WriteUserData(String& rData)
2226 {
2227     //  nZoom (bis 364v) oder nZoom/nPageZoom/bPageMode (ab 364w)
2228     //  nTab
2229     //  Tab-ControlBreite
2230     //  pro Tabelle:
2231     //  CursorX/CursorY/HSplitMode/VSplitMode/HSplitPos/VSplitPos/SplitActive/
2232     //  PosX[links]/PosX[rechts]/PosY[oben]/PosY[unten]
2233     //  wenn Zeilen groesser 8192, "+" statt "/"
2234 
2235     sal_uInt16 nZoom = (sal_uInt16)((pThisTab->aZoomY.GetNumerator() * 100) / pThisTab->aZoomY.GetDenominator());
2236     rData = String::CreateFromInt32( nZoom );
2237     rData += '/';
2238     nZoom = (sal_uInt16)((pThisTab->aPageZoomY.GetNumerator() * 100) / pThisTab->aPageZoomY.GetDenominator());
2239     rData += String::CreateFromInt32( nZoom );
2240     rData += '/';
2241     if (bPagebreak)
2242         rData += '1';
2243     else
2244         rData += '0';
2245 
2246     rData += ';';
2247     rData += String::CreateFromInt32( nTabNo );
2248     rData += ';';
2249     rData.AppendAscii(RTL_CONSTASCII_STRINGPARAM( TAG_TABBARWIDTH ));
2250     rData += String::CreateFromInt32( pView->GetTabBarWidth() );
2251 
2252     SCTAB nTabCount = pDoc->GetTableCount();
2253     for (SCTAB i=0; i<nTabCount; i++)
2254     {
2255         rData += ';';                   // Numerierung darf auf keinen Fall durcheinanderkommen
2256         if (pTabData[i])
2257         {
2258             sal_Unicode cTabSep = SC_OLD_TABSEP;                // wie 3.1
2259             if ( pTabData[i]->nCurY > MAXROW_30 ||
2260                  pTabData[i]->nPosY[0] > MAXROW_30 || pTabData[i]->nPosY[1] > MAXROW_30 ||
2261                  ( pTabData[i]->eVSplitMode == SC_SPLIT_FIX &&
2262                     pTabData[i]->nFixPosY > MAXROW_30 ) )
2263             {
2264                 cTabSep = SC_NEW_TABSEP;        // um eine 3.1-Version nicht umzubringen
2265             }
2266 
2267 
2268             rData += String::CreateFromInt32( pTabData[i]->nCurX );
2269             rData += cTabSep;
2270             rData += String::CreateFromInt32( pTabData[i]->nCurY );
2271             rData += cTabSep;
2272             rData += String::CreateFromInt32( pTabData[i]->eHSplitMode );
2273             rData += cTabSep;
2274             rData += String::CreateFromInt32( pTabData[i]->eVSplitMode );
2275             rData += cTabSep;
2276             if ( pTabData[i]->eHSplitMode == SC_SPLIT_FIX )
2277                 rData += String::CreateFromInt32( pTabData[i]->nFixPosX );
2278             else
2279                 rData += String::CreateFromInt32( pTabData[i]->nHSplitPos );
2280             rData += cTabSep;
2281             if ( pTabData[i]->eVSplitMode == SC_SPLIT_FIX )
2282                 rData += String::CreateFromInt32( pTabData[i]->nFixPosY );
2283             else
2284                 rData += String::CreateFromInt32( pTabData[i]->nVSplitPos );
2285             rData += cTabSep;
2286             rData += String::CreateFromInt32( pTabData[i]->eWhichActive );
2287             rData += cTabSep;
2288             rData += String::CreateFromInt32( pTabData[i]->nPosX[0] );
2289             rData += cTabSep;
2290             rData += String::CreateFromInt32( pTabData[i]->nPosX[1] );
2291             rData += cTabSep;
2292             rData += String::CreateFromInt32( pTabData[i]->nPosY[0] );
2293             rData += cTabSep;
2294             rData += String::CreateFromInt32( pTabData[i]->nPosY[1] );
2295         }
2296     }
2297 }
2298 
ReadUserData(const String & rData)2299 void ScViewData::ReadUserData(const String& rData)
2300 {
2301     if (!rData.Len())       // Leerer String kommt bei "neu Laden"
2302         return;             // dann auch ohne Assertion beenden
2303 
2304     xub_StrLen nCount = rData.GetTokenCount(';');
2305     if ( nCount <= 2 )
2306     {
2307         //  #45208# beim Reload in der Seitenansicht sind evtl. die Preview-UserData
2308         //  stehengelassen worden. Den Zoom von der Preview will man hier nicht...
2309         DBG_ERROR("ReadUserData: das sind nicht meine Daten");
2310         return;
2311     }
2312 
2313     String aTabOpt;
2314     xub_StrLen nTagLen = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(TAG_TABBARWIDTH)).Len();
2315 
2316     //-------------------
2317     // nicht pro Tabelle:
2318     //-------------------
2319     SCTAB nTabStart = 2;
2320 
2321     Fraction aZoomX, aZoomY, aPageZoomX, aPageZoomY;    //! evaluate (all sheets?)
2322 
2323     String aZoomStr = rData.GetToken(0);                        // Zoom/PageZoom/Modus
2324     sal_uInt16 nNormZoom = sal::static_int_cast<sal_uInt16>(aZoomStr.GetToken(0,'/').ToInt32());
2325     if ( nNormZoom >= MINZOOM && nNormZoom <= MAXZOOM )
2326         aZoomX = aZoomY = Fraction( nNormZoom, 100 );           //  "normaler" Zoom (immer)
2327     sal_uInt16 nPageZoom = sal::static_int_cast<sal_uInt16>(aZoomStr.GetToken(1,'/').ToInt32());
2328     if ( nPageZoom >= MINZOOM && nPageZoom <= MAXZOOM )
2329         aPageZoomX = aPageZoomY = Fraction( nPageZoom, 100 );   // Pagebreak-Zoom, wenn gesetzt
2330     sal_Unicode cMode = aZoomStr.GetToken(2,'/').GetChar(0);    // 0 oder "0"/"1"
2331     SetPagebreakMode( cMode == '1' );
2332     // SetPagebreakMode muss immer gerufen werden wegen CalcPPT / RecalcPixPos()
2333 
2334     //
2335     //  Tabelle kann ungueltig geworden sein (z.B. letzte Version):
2336     //
2337     SCTAB nNewTab = static_cast<SCTAB>(rData.GetToken(1).ToInt32());
2338     if (pDoc->HasTable( nNewTab ))
2339         SetTabNo(nNewTab);
2340 
2341     //
2342     // wenn vorhanden, TabBar-Breite holen:
2343     //
2344     aTabOpt = rData.GetToken(2);
2345 
2346     if ( nTagLen && aTabOpt.Copy(0,nTagLen).EqualsAscii(TAG_TABBARWIDTH) )
2347     {
2348         pView->SetTabBarWidth( aTabOpt.Copy(nTagLen).ToInt32() );
2349         nTabStart = 3;
2350     }
2351 
2352     //-------------
2353     // pro Tabelle:
2354     //-------------
2355     SCTAB nPos = 0;
2356     while ( nCount > nPos+nTabStart )
2357     {
2358         aTabOpt = rData.GetToken(static_cast<xub_StrLen>(nPos+nTabStart));
2359         if (!pTabData[nPos])
2360             pTabData[nPos] = new ScViewDataTable;
2361 
2362         sal_Unicode cTabSep = 0;
2363         if (aTabOpt.GetTokenCount(SC_OLD_TABSEP) >= 11)
2364             cTabSep = SC_OLD_TABSEP;
2365 #ifndef SC_LIMIT_ROWS
2366         else if (aTabOpt.GetTokenCount(SC_NEW_TABSEP) >= 11)
2367             cTabSep = SC_NEW_TABSEP;
2368         // '+' ist nur erlaubt, wenn wir mit Zeilen > 8192 umgehen koennen
2369 #endif
2370 
2371         if (cTabSep)
2372         {
2373             pTabData[nPos]->nCurX = SanitizeCol( static_cast<SCCOL>(aTabOpt.GetToken(0,cTabSep).ToInt32()));
2374             pTabData[nPos]->nCurY = SanitizeRow( aTabOpt.GetToken(1,cTabSep).ToInt32());
2375             pTabData[nPos]->eHSplitMode = (ScSplitMode) aTabOpt.GetToken(2,cTabSep).ToInt32();
2376             pTabData[nPos]->eVSplitMode = (ScSplitMode) aTabOpt.GetToken(3,cTabSep).ToInt32();
2377 
2378             if ( pTabData[nPos]->eHSplitMode == SC_SPLIT_FIX )
2379             {
2380                 pTabData[nPos]->nFixPosX = SanitizeCol( static_cast<SCCOL>(aTabOpt.GetToken(4,cTabSep).ToInt32()));
2381                 UpdateFixX(nPos);
2382             }
2383             else
2384                 pTabData[nPos]->nHSplitPos = aTabOpt.GetToken(4,cTabSep).ToInt32();
2385 
2386             if ( pTabData[nPos]->eVSplitMode == SC_SPLIT_FIX )
2387             {
2388                 pTabData[nPos]->nFixPosY = SanitizeRow( aTabOpt.GetToken(5,cTabSep).ToInt32());
2389                 UpdateFixY(nPos);
2390             }
2391             else
2392                 pTabData[nPos]->nVSplitPos = aTabOpt.GetToken(5,cTabSep).ToInt32();
2393 
2394             pTabData[nPos]->eWhichActive = (ScSplitPos) aTabOpt.GetToken(6,cTabSep).ToInt32();
2395             pTabData[nPos]->nPosX[0] = SanitizeCol( static_cast<SCCOL>(aTabOpt.GetToken(7,cTabSep).ToInt32()));
2396             pTabData[nPos]->nPosX[1] = SanitizeCol( static_cast<SCCOL>(aTabOpt.GetToken(8,cTabSep).ToInt32()));
2397             pTabData[nPos]->nPosY[0] = SanitizeRow( aTabOpt.GetToken(9,cTabSep).ToInt32());
2398             pTabData[nPos]->nPosY[1] = SanitizeRow( aTabOpt.GetToken(10,cTabSep).ToInt32());
2399 
2400             //  Test, ob der aktive Teil laut SplitMode ueberhaupt existiert
2401             //  (Bug #44516#)
2402             ScSplitPos eTest = pTabData[nPos]->eWhichActive;
2403             if ( ( WhichH( eTest ) == SC_SPLIT_RIGHT &&
2404                     pTabData[nPos]->eHSplitMode == SC_SPLIT_NONE ) ||
2405                  ( WhichV( eTest ) == SC_SPLIT_TOP &&
2406                     pTabData[nPos]->eVSplitMode == SC_SPLIT_NONE ) )
2407             {
2408                 //  dann wieder auf Default (unten links)
2409                 pTabData[nPos]->eWhichActive = SC_SPLIT_BOTTOMLEFT;
2410                 DBG_ERROR("SplitPos musste korrigiert werden");
2411             }
2412         }
2413         ++nPos;
2414     }
2415 
2416     RecalcPixPos();
2417 }
2418 
WriteExtOptions(ScExtDocOptions & rDocOpt) const2419 void ScViewData::WriteExtOptions( ScExtDocOptions& rDocOpt ) const
2420 {
2421     // *** Fill extended document data for export filters ***
2422 
2423     // document settings
2424     ScExtDocSettings& rDocSett = rDocOpt.GetDocSettings();
2425 
2426     // displayed sheet
2427     rDocSett.mnDisplTab = GetTabNo();
2428 
2429     // width of the tabbar, relative to frame window width
2430     rDocSett.mfTabBarWidth = pView->GetPendingRelTabBarWidth();
2431     if( rDocSett.mfTabBarWidth < 0.0 )
2432         rDocSett.mfTabBarWidth = pView->GetRelTabBarWidth();
2433 
2434     // sheet settings
2435     for( SCTAB nTab = 0, nTabCount = pDoc->GetTableCount(); nTab < nTabCount; ++nTab )
2436     {
2437         if( const ScViewDataTable* pViewTab = pTabData[ nTab ] )
2438         {
2439             ScExtTabSettings& rTabSett = rDocOpt.GetOrCreateTabSettings( nTab );
2440 
2441             // split mode
2442             ScSplitMode eHSplit = pViewTab->eHSplitMode;
2443             ScSplitMode eVSplit = pViewTab->eVSplitMode;
2444             bool bHSplit = eHSplit != SC_SPLIT_NONE;
2445             bool bVSplit = eVSplit != SC_SPLIT_NONE;
2446             bool bRealSplit = (eHSplit == SC_SPLIT_NORMAL) || (eVSplit == SC_SPLIT_NORMAL);
2447             bool bFrozen    = (eHSplit == SC_SPLIT_FIX)    || (eVSplit == SC_SPLIT_FIX);
2448             DBG_ASSERT( !bRealSplit || !bFrozen, "ScViewData::WriteExtOptions - split and freeze in same sheet" );
2449             rTabSett.mbFrozenPanes = !bRealSplit && bFrozen;
2450 
2451             // split and freeze position
2452             rTabSett.maSplitPos = Point( 0, 0 );
2453             rTabSett.maFreezePos.Set( 0, 0, nTab );
2454             if( bRealSplit )
2455             {
2456                 Point& rSplitPos = rTabSett.maSplitPos;
2457                 rSplitPos = Point( bHSplit ? pViewTab->nHSplitPos : 0, bVSplit ? pViewTab->nVSplitPos : 0 );
2458                 rSplitPos = Application::GetDefaultDevice()->PixelToLogic( rSplitPos, MapMode( MAP_TWIP ) );
2459                 if( pDocShell )
2460                     rSplitPos.X() = (long)((double)rSplitPos.X() / pDocShell->GetOutputFactor());
2461             }
2462             else if( bFrozen )
2463             {
2464                 if( bHSplit ) rTabSett.maFreezePos.SetCol( pViewTab->nFixPosX );
2465                 if( bVSplit ) rTabSett.maFreezePos.SetRow( pViewTab->nFixPosY );
2466             }
2467 
2468             // first visible cell in top-left and additional panes
2469             rTabSett.maFirstVis.Set( pViewTab->nPosX[ SC_SPLIT_LEFT ], pViewTab->nPosY[ bVSplit ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM ], nTab );
2470             rTabSett.maSecondVis.Set( pViewTab->nPosX[ SC_SPLIT_RIGHT ], pViewTab->nPosY[ SC_SPLIT_BOTTOM ], nTab );
2471 
2472             // active pane
2473             switch( pViewTab->eWhichActive )
2474             {
2475                 // no horizontal split -> always use left panes
2476                 // no vertical split -> always use top panes
2477                 case SC_SPLIT_TOPLEFT:
2478                     rTabSett.meActivePane = SCEXT_PANE_TOPLEFT;
2479                 break;
2480                 case SC_SPLIT_TOPRIGHT:
2481                     rTabSett.meActivePane = bHSplit ? SCEXT_PANE_TOPRIGHT : SCEXT_PANE_TOPLEFT;
2482                 break;
2483                 case SC_SPLIT_BOTTOMLEFT:
2484                     rTabSett.meActivePane = bVSplit ? SCEXT_PANE_BOTTOMLEFT : SCEXT_PANE_TOPLEFT;
2485                 break;
2486                 case SC_SPLIT_BOTTOMRIGHT:
2487                     rTabSett.meActivePane = bHSplit ?
2488                         (bVSplit ? SCEXT_PANE_BOTTOMRIGHT : SCEXT_PANE_TOPRIGHT) :
2489                         (bVSplit ? SCEXT_PANE_BOTTOMLEFT : SCEXT_PANE_TOPLEFT);
2490                 break;
2491             }
2492 
2493             // cursor position
2494             rTabSett.maCursor.Set( pViewTab->nCurX, pViewTab->nCurY, nTab );
2495 
2496             // sheet selection and selected ranges
2497             const ScMarkData& rMarkData = GetMarkData();
2498             rTabSett.mbSelected = rMarkData.GetTableSelect( nTab );
2499             rMarkData.FillRangeListWithMarks( &rTabSett.maSelection, sal_True );
2500 
2501             // grid color
2502             rTabSett.maGridColor.SetColor( COL_AUTO );
2503             if( pOptions )
2504             {
2505                 const Color& rGridColor = pOptions->GetGridColor();
2506                 if( rGridColor.GetColor() != SC_STD_GRIDCOLOR )
2507                     rTabSett.maGridColor = rGridColor;
2508             }
2509 
2510             // view mode and zoom
2511             rTabSett.mbPageMode = bPagebreak;
2512             rTabSett.mnNormalZoom = static_cast< long >( pViewTab->aZoomY * Fraction( 100.0 ) );
2513             rTabSett.mnPageZoom = static_cast< long >( pViewTab->aPageZoomY * Fraction( 100.0 ) );
2514         }
2515     }
2516 }
2517 
ReadExtOptions(const ScExtDocOptions & rDocOpt)2518 void ScViewData::ReadExtOptions( const ScExtDocOptions& rDocOpt )
2519 {
2520     // *** Get extended document data from import filters ***
2521 
2522     if( !rDocOpt.IsChanged() ) return;
2523 
2524     // document settings
2525     const ScExtDocSettings& rDocSett = rDocOpt.GetDocSettings();
2526 
2527     // displayed sheet
2528     SetTabNo( rDocSett.mnDisplTab );
2529 
2530     /*  Width of the tabbar, relative to frame window width. We do not have the
2531         correct width of the frame window here -> store in ScTabView, which sets
2532         the size in the next resize. */
2533     pView->SetPendingRelTabBarWidth( rDocSett.mfTabBarWidth );
2534 
2535     // sheet settings
2536     for( SCTAB nTab = 0, nTabCount = pDoc->GetTableCount(); nTab < nTabCount; ++nTab )
2537     {
2538         if( const ScExtTabSettings* pTabSett = rDocOpt.GetTabSettings( nTab ) )
2539         {
2540             if( !pTabData[ nTab ] )
2541                 pTabData[ nTab ] = new ScViewDataTable;
2542 
2543             const ScExtTabSettings& rTabSett = *pTabSett;
2544             ScViewDataTable& rViewTab = *pTabData[ nTab ];
2545 
2546             // split mode initialization
2547             bool bFrozen = rTabSett.mbFrozenPanes;
2548             bool bHSplit = bFrozen ? (rTabSett.maFreezePos.Col() > 0) : (rTabSett.maSplitPos.X() > 0);
2549             bool bVSplit = bFrozen ? (rTabSett.maFreezePos.Row() > 0) : (rTabSett.maSplitPos.Y() > 0);
2550 
2551             // first visible cell of top-left pane and additional panes
2552             rViewTab.nPosX[ SC_SPLIT_LEFT ] = rTabSett.maFirstVis.Col();
2553             rViewTab.nPosY[ bVSplit ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM ] = rTabSett.maFirstVis.Row();
2554             if( bHSplit ) rViewTab.nPosX[ SC_SPLIT_RIGHT ] = rTabSett.maSecondVis.Col();
2555             if( bVSplit ) rViewTab.nPosY[ SC_SPLIT_BOTTOM ] = rTabSett.maSecondVis.Row();
2556 
2557             // split mode, split and freeze position
2558             rViewTab.eHSplitMode = rViewTab.eVSplitMode = SC_SPLIT_NONE;
2559             rViewTab.nHSplitPos = rViewTab.nVSplitPos = 0;
2560             rViewTab.nFixPosX = 0;
2561             rViewTab.nFixPosY = 0;
2562             if( bFrozen )
2563             {
2564                 if( bHSplit )
2565                 {
2566                     rViewTab.eHSplitMode = SC_SPLIT_FIX;
2567                     rViewTab.nFixPosX = rTabSett.maFreezePos.Col();
2568                     UpdateFixX( nTab );
2569                 }
2570                 if( bVSplit )
2571                 {
2572                     rViewTab.eVSplitMode = SC_SPLIT_FIX;
2573                     rViewTab.nFixPosY = rTabSett.maFreezePos.Row();
2574                     UpdateFixY( nTab );
2575                 }
2576             }
2577             else
2578             {
2579                 Point aPixel = Application::GetDefaultDevice()->LogicToPixel(
2580                                 rTabSett.maSplitPos, MapMode( MAP_TWIP ) );  //! Zoom?
2581                 // #109648# - the test for use of printer metrics for text formatting here
2582                 // effectively results in the nFactor = 1.0 regardless of the Option setting.
2583                 if( pDocShell && SC_MOD()->GetInputOptions().GetTextWysiwyg())
2584                 {
2585                     double nFactor = pDocShell->GetOutputFactor();
2586                     aPixel.X() = (long)( aPixel.X() * nFactor + 0.5 );
2587                 }
2588 
2589                 bHSplit = bHSplit && aPixel.X() > 0;
2590                 bVSplit = bVSplit && aPixel.Y() > 0;
2591                 if( bHSplit )
2592                 {
2593                     rViewTab.eHSplitMode = SC_SPLIT_NORMAL;
2594                     rViewTab.nHSplitPos = aPixel.X();
2595                 }
2596                 if( bVSplit )
2597                 {
2598                     rViewTab.eVSplitMode = SC_SPLIT_NORMAL;
2599                     rViewTab.nVSplitPos = aPixel.Y();
2600                 }
2601             }
2602 
2603             // active pane
2604             ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
2605             switch( rTabSett.meActivePane )
2606             {
2607                 // no horizontal split -> always use left panes
2608                 // no vertical split -> always use *bottom* panes
2609                 case SCEXT_PANE_TOPLEFT:
2610                     ePos = bVSplit ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
2611                 break;
2612                 case SCEXT_PANE_TOPRIGHT:
2613                     ePos = bHSplit ?
2614                         (bVSplit ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT) :
2615                         (bVSplit ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT);
2616                 break;
2617                 case SCEXT_PANE_BOTTOMLEFT:
2618                     ePos = SC_SPLIT_BOTTOMLEFT;
2619                 break;
2620                 case SCEXT_PANE_BOTTOMRIGHT:
2621                     ePos = bHSplit ? SC_SPLIT_BOTTOMRIGHT : SC_SPLIT_BOTTOMLEFT;
2622                 break;
2623             }
2624             rViewTab.eWhichActive = ePos;
2625 
2626             // cursor position
2627             const ScAddress& rCursor = rTabSett.maCursor;
2628             if( rCursor.IsValid() )
2629             {
2630                 rViewTab.nCurX = rCursor.Col();
2631                 rViewTab.nCurY = rCursor.Row();
2632             }
2633 
2634             // sheet selection and selected ranges
2635             ScMarkData& rMarkData = GetMarkData();
2636             rMarkData.SelectTable( nTab, rTabSett.mbSelected );
2637 
2638             // zoom for each sheet
2639             if( rTabSett.mnNormalZoom )
2640                 rViewTab.aZoomX = rViewTab.aZoomY = Fraction( rTabSett.mnNormalZoom, 100L );
2641             if( rTabSett.mnPageZoom )
2642                 rViewTab.aPageZoomX = rViewTab.aPageZoomY = Fraction( rTabSett.mnPageZoom, 100L );
2643 
2644             // get some settings from displayed Excel sheet, set at Calc document
2645             if( nTab == GetTabNo() )
2646             {
2647                 // selection only for displayed sheet, do not select single cell
2648 // Disabled, does not work correctly. Anyway, our own XML filters do not import a selection at all.
2649 //                const ScRangeList& rSel = rTabSett.maSelection;
2650 //                if( (rSel.Count() >= 2) || ((rSel.Count() == 1) && (*rSel.GetObject( 0 ) != ScRange( rCursor ))) )
2651 //                    rMarkData.MarkFromRangeList( rTabSett.maSelection, sal_False );
2652 
2653                 // grid color -- #i47435# set automatic grid color explicitly
2654                 if( pOptions )
2655                 {
2656                     Color aGridColor( rTabSett.maGridColor );
2657                     if( aGridColor.GetColor() == COL_AUTO )
2658                         aGridColor.SetColor( SC_STD_GRIDCOLOR );
2659                     pOptions->SetGridColor( aGridColor, EMPTY_STRING );
2660                 }
2661 
2662                 // view mode and default zoom (for new sheets) from current sheet
2663                 if( rTabSett.mnNormalZoom )
2664                     aDefZoomX = aDefZoomY = Fraction( rTabSett.mnNormalZoom, 100L );
2665                 if( rTabSett.mnPageZoom )
2666                     aDefPageZoomX = aDefPageZoomY = Fraction( rTabSett.mnPageZoom, 100L );
2667                 /*  #i46820# set pagebreak mode via SetPagebreakMode(), this will
2668                     update map modes that are needed to draw text correctly. */
2669                 SetPagebreakMode( rTabSett.mbPageMode );
2670             }
2671         }
2672     }
2673 
2674     // RecalcPixPos oder so - auch nMPos - auch bei ReadUserData ??!?!
2675 }
2676 
WriteUserDataSequence(uno::Sequence<beans::PropertyValue> & rSettings)2677 void ScViewData::WriteUserDataSequence(uno::Sequence <beans::PropertyValue>& rSettings)
2678 {
2679     rSettings.realloc(SC_VIEWSETTINGS_COUNT);
2680     // + 1, because we have to put the view id in the sequence
2681     beans::PropertyValue* pSettings = rSettings.getArray();
2682     if (pSettings)
2683     {
2684         sal_uInt16 nViewID(pViewShell->GetViewFrame()->GetCurViewId());
2685         pSettings[SC_VIEW_ID].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_VIEWID));
2686         rtl::OUStringBuffer sBuffer(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_VIEW)));
2687         SvXMLUnitConverter::convertNumber(sBuffer, static_cast<sal_Int32>(nViewID));
2688         pSettings[SC_VIEW_ID].Value <<= sBuffer.makeStringAndClear();
2689 
2690         SCTAB nTabCount (pDoc->GetTableCount());
2691         uno::Reference<lang::XMultiServiceFactory> xServiceFactory =
2692                                         comphelper::getProcessServiceFactory();
2693         DBG_ASSERT( xServiceFactory.is(), "got no service manager" );
2694         if( xServiceFactory.is() )
2695         {
2696             rtl::OUString sName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.NamedPropertyValues"));
2697             uno::Reference<container::XNameContainer> xNameContainer = uno::Reference<container::XNameContainer>(xServiceFactory->createInstance(sName), uno::UNO_QUERY);
2698             if (xNameContainer.is())
2699             {
2700                 for (SCTAB nTab=0; nTab<nTabCount; nTab++)
2701                 {
2702                     if (pTabData[nTab])
2703                     {
2704                         uno::Sequence <beans::PropertyValue> aTableViewSettings;
2705                         pTabData[nTab]->WriteUserDataSequence(aTableViewSettings, *this, nTab);
2706                         String sTabName;
2707                         GetDocument()->GetName( nTab, sTabName );
2708                         rtl::OUString sOUName(sTabName);
2709                         uno::Any aAny;
2710                         aAny <<= aTableViewSettings;
2711                         try
2712                         {
2713                             xNameContainer->insertByName(sTabName, aAny);
2714                         }
2715                         //#101739#; two tables with the same name are possible
2716                         catch ( container::ElementExistException& )
2717                         {
2718                             DBG_ERRORFILE("seems there are two tables with the same name");
2719                         }
2720                         catch ( uno::RuntimeException& )
2721                         {
2722                             DBG_ERRORFILE("something went wrong");
2723                         }
2724                     }
2725                 }
2726                 pSettings[SC_TABLE_VIEWSETTINGS].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_TABLES));
2727                 pSettings[SC_TABLE_VIEWSETTINGS].Value <<= xNameContainer;
2728             }
2729         }
2730 
2731         String sName;
2732         GetDocument()->GetName( nTabNo, sName );
2733         rtl::OUString sOUName(sName);
2734         pSettings[SC_ACTIVE_TABLE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ACTIVETABLE));
2735         pSettings[SC_ACTIVE_TABLE].Value <<= sOUName;
2736         pSettings[SC_HORIZONTAL_SCROLL_BAR_WIDTH].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_HORIZONTALSCROLLBARWIDTH));
2737         pSettings[SC_HORIZONTAL_SCROLL_BAR_WIDTH].Value <<= sal_Int32(pView->GetTabBarWidth());
2738         sal_Int32 nZoomValue ((pThisTab->aZoomY.GetNumerator() * 100) / pThisTab->aZoomY.GetDenominator());
2739         sal_Int32 nPageZoomValue ((pThisTab->aPageZoomY.GetNumerator() * 100) / pThisTab->aPageZoomY.GetDenominator());
2740         pSettings[SC_ZOOM_TYPE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ZOOMTYPE));
2741         pSettings[SC_ZOOM_TYPE].Value <<= sal_Int16(pThisTab->eZoomType);
2742         pSettings[SC_ZOOM_VALUE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ZOOMVALUE));
2743         pSettings[SC_ZOOM_VALUE].Value <<= nZoomValue;
2744         pSettings[SC_PAGE_VIEW_ZOOM_VALUE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_PAGEVIEWZOOMVALUE));
2745         pSettings[SC_PAGE_VIEW_ZOOM_VALUE].Value <<= nPageZoomValue;
2746         pSettings[SC_PAGE_BREAK_PREVIEW].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_SHOWPAGEBREAKPREVIEW));
2747         ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_PAGE_BREAK_PREVIEW].Value, bPagebreak);
2748 
2749         if (pOptions)
2750         {
2751             pSettings[SC_SHOWZERO].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHOWZERO));
2752             ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHOWZERO].Value, pOptions->GetOption( VOPT_NULLVALS ) );
2753             pSettings[SC_SHOWNOTES].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHOWNOTES));
2754             ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHOWNOTES].Value, pOptions->GetOption( VOPT_NOTES ) );
2755             pSettings[SC_SHOWGRID].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHOWGRID));
2756             ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHOWGRID].Value, pOptions->GetOption( VOPT_GRID ) );
2757             pSettings[SC_GRIDCOLOR].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_GRIDCOLOR));
2758             String aColorName;
2759             Color aColor = pOptions->GetGridColor(&aColorName);
2760             pSettings[SC_GRIDCOLOR].Value <<= static_cast<sal_Int64>(aColor.GetColor());
2761             pSettings[SC_SHOWPAGEBR].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHOWPAGEBR));
2762             ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHOWPAGEBR].Value, pOptions->GetOption( VOPT_PAGEBREAKS ) );
2763             pSettings[SC_COLROWHDR].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_COLROWHDR));
2764             ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_COLROWHDR].Value, pOptions->GetOption( VOPT_HEADER ) );
2765             pSettings[SC_SHEETTABS].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SHEETTABS));
2766             ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHEETTABS].Value, pOptions->GetOption( VOPT_TABCONTROLS ) );
2767             pSettings[SC_OUTLSYMB].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_OUTLSYMB));
2768             ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_OUTLSYMB].Value, pOptions->GetOption( VOPT_OUTLINER ) );
2769 
2770             const ScGridOptions& aGridOpt = pOptions->GetGridOptions();
2771             pSettings[SC_SNAPTORASTER].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SNAPTORASTER));
2772             ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SNAPTORASTER].Value, aGridOpt.GetUseGridSnap() );
2773             pSettings[SC_RASTERVIS].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERVIS));
2774             ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_RASTERVIS].Value, aGridOpt.GetGridVisible() );
2775             pSettings[SC_RASTERRESX].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERRESX));
2776             pSettings[SC_RASTERRESX].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDrawX() );
2777             pSettings[SC_RASTERRESY].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERRESY));
2778             pSettings[SC_RASTERRESY].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDrawY() );
2779             pSettings[SC_RASTERSUBX].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERSUBX));
2780             pSettings[SC_RASTERSUBX].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDivisionX() );
2781             pSettings[SC_RASTERSUBY].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERSUBY));
2782             pSettings[SC_RASTERSUBY].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDivisionY() );
2783             pSettings[SC_RASTERSYNC].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERSYNC));
2784             ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_RASTERSYNC].Value, aGridOpt.GetSynchronize() );
2785         }
2786     }
2787 }
2788 
ReadUserDataSequence(const uno::Sequence<beans::PropertyValue> & rSettings)2789 void ScViewData::ReadUserDataSequence(const uno::Sequence <beans::PropertyValue>& rSettings)
2790 {
2791     Fraction aZoomX, aZoomY, aPageZoomX, aPageZoomY;    //! evaluate (all sheets?)
2792 
2793     std::vector<bool> aHasZoomVect( GetDocument()->GetTableCount(), false );
2794 
2795     sal_Int32 nCount(rSettings.getLength());
2796     sal_Int32 nTemp32(0);
2797     sal_Int16 nTemp16(0);
2798     sal_Bool bPageMode(sal_False);
2799     for (sal_Int32 i = 0; i < nCount; i++)
2800     {
2801         // SC_VIEWID has to parse and use by mba
2802         rtl::OUString sName(rSettings[i].Name);
2803         if (sName.compareToAscii(SC_TABLES) == 0)
2804         {
2805             uno::Reference<container::XNameContainer> xNameContainer;
2806             if ((rSettings[i].Value >>= xNameContainer) && xNameContainer->hasElements())
2807             {
2808                 uno::Sequence< rtl::OUString > aNames(xNameContainer->getElementNames());
2809                 for (sal_Int32 nTabPos = 0; nTabPos < aNames.getLength(); nTabPos++)
2810                 {
2811                     String sTabName(aNames[nTabPos]);
2812                     SCTAB nTab(0);
2813                     if (GetDocument()->GetTable(sTabName, nTab))
2814                     {
2815                         uno::Any aAny = xNameContainer->getByName(aNames[nTabPos]);
2816                         uno::Sequence<beans::PropertyValue> aTabSettings;
2817                         if (aAny >>= aTabSettings)
2818                         {
2819                             delete pTabData[nTab];
2820                             pTabData[nTab] = new ScViewDataTable;
2821                             bool bHasZoom = false;
2822                             pTabData[nTab]->ReadUserDataSequence(aTabSettings, *this, nTab, bHasZoom);
2823                             aHasZoomVect[nTab] = bHasZoom;
2824                         }
2825                     }
2826                 }
2827             }
2828         }
2829         else if (sName.compareToAscii(SC_ACTIVETABLE) == 0)
2830         {
2831             rtl::OUString sValue;
2832             if(rSettings[i].Value >>= sValue)
2833             {
2834                 String sTabName(sValue);
2835                 SCTAB nTab(0);
2836                 if (GetDocument()->GetTable(sTabName, nTab))
2837                     nTabNo = nTab;
2838             }
2839         }
2840         else if (sName.compareToAscii(SC_HORIZONTALSCROLLBARWIDTH) == 0)
2841         {
2842             if (rSettings[i].Value >>= nTemp32)
2843                 pView->SetTabBarWidth(nTemp32);
2844         }
2845         else if (sName.compareToAscii(SC_RELHORIZONTALTABBARWIDTH) == 0)
2846         {
2847             double fWidth = 0.0;
2848             if (rSettings[i].Value >>= fWidth)
2849                 pView->SetPendingRelTabBarWidth( fWidth );
2850         }
2851         else if (sName.compareToAscii(SC_ZOOMTYPE) == 0)
2852         {
2853             if (rSettings[i].Value >>= nTemp16)
2854                 eDefZoomType = SvxZoomType(nTemp16);
2855         }
2856         else if (sName.compareToAscii(SC_ZOOMVALUE) == 0)
2857         {
2858             if (rSettings[i].Value >>= nTemp32)
2859             {
2860                 Fraction aZoom(nTemp32, 100);
2861                 aDefZoomX = aDefZoomY = aZoom;
2862             }
2863         }
2864         else if (sName.compareToAscii(SC_PAGEVIEWZOOMVALUE) == 0)
2865         {
2866             if (rSettings[i].Value >>= nTemp32)
2867             {
2868                 Fraction aZoom(nTemp32, 100);
2869                 aDefPageZoomX = aDefPageZoomY = aZoom;
2870             }
2871         }
2872         else if (sName.compareToAscii(SC_SHOWPAGEBREAKPREVIEW) == 0)
2873             bPageMode = ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value );
2874         else if ( sName.compareToAscii( SC_UNO_SHOWZERO ) == 0 )
2875             pOptions->SetOption(VOPT_NULLVALS, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2876         else if ( sName.compareToAscii( SC_UNO_SHOWNOTES ) == 0 )
2877             pOptions->SetOption(VOPT_NOTES, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2878         else if ( sName.compareToAscii( SC_UNO_SHOWGRID ) == 0 )
2879             pOptions->SetOption(VOPT_GRID, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2880         else if ( sName.compareToAscii( SC_UNO_GRIDCOLOR ) == 0 )
2881         {
2882             sal_Int64 nColor = 0;
2883             if (rSettings[i].Value >>= nColor)
2884             {
2885                 String aColorName;
2886                 Color aColor(static_cast<sal_uInt32>(nColor));
2887                 // #i47435# set automatic grid color explicitly
2888                 if( aColor.GetColor() == COL_AUTO )
2889                     aColor.SetColor( SC_STD_GRIDCOLOR );
2890                 pOptions->SetGridColor(aColor, aColorName);
2891             }
2892         }
2893         else if ( sName.compareToAscii( SC_UNO_SHOWPAGEBR ) == 0 )
2894             pOptions->SetOption(VOPT_PAGEBREAKS, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2895         else if ( sName.compareToAscii( SC_UNO_COLROWHDR ) == 0 )
2896             pOptions->SetOption(VOPT_HEADER, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2897         else if ( sName.compareToAscii( SC_UNO_SHEETTABS ) == 0 )
2898             pOptions->SetOption(VOPT_TABCONTROLS, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2899         else if ( sName.compareToAscii( SC_UNO_OUTLSYMB ) == 0 )
2900             pOptions->SetOption(VOPT_OUTLINER, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2901         else if ( sName.compareToAscii( SC_UNO_SHOWOBJ ) == 0 )
2902         {
2903             // #i80528# placeholders not supported anymore
2904             if ( rSettings[i].Value >>= nTemp16 )
2905                 pOptions->SetObjMode( VOBJ_TYPE_OLE, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
2906         }
2907         else if ( sName.compareToAscii( SC_UNO_SHOWCHARTS ) == 0 )
2908         {
2909             // #i80528# placeholders not supported anymore
2910             if ( rSettings[i].Value >>= nTemp16 )
2911                 pOptions->SetObjMode( VOBJ_TYPE_CHART, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
2912         }
2913         else if ( sName.compareToAscii( SC_UNO_SHOWDRAW ) == 0 )
2914         {
2915             // #i80528# placeholders not supported anymore
2916             if ( rSettings[i].Value >>= nTemp16 )
2917                 pOptions->SetObjMode( VOBJ_TYPE_DRAW, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
2918         }
2919         else
2920         {
2921             ScGridOptions aGridOpt(pOptions->GetGridOptions());
2922             if ( sName.compareToAscii( SC_UNO_SNAPTORASTER ) == 0 )
2923                 aGridOpt.SetUseGridSnap( ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2924             else if ( sName.compareToAscii( SC_UNO_RASTERVIS ) == 0 )
2925                 aGridOpt.SetGridVisible( ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2926             else if ( sName.compareToAscii( SC_UNO_RASTERRESX ) == 0 )
2927                 aGridOpt.SetFldDrawX( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
2928             else if ( sName.compareToAscii( SC_UNO_RASTERRESY ) == 0 )
2929                 aGridOpt.SetFldDrawY( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
2930             else if ( sName.compareToAscii( SC_UNO_RASTERSUBX ) == 0 )
2931                 aGridOpt.SetFldDivisionX( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
2932             else if ( sName.compareToAscii( SC_UNO_RASTERSUBY ) == 0 )
2933                 aGridOpt.SetFldDivisionY( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
2934             else if ( sName.compareToAscii( SC_UNO_RASTERSYNC ) == 0 )
2935                 aGridOpt.SetSynchronize( ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2936             pOptions->SetGridOptions(aGridOpt);
2937         }
2938     }
2939 
2940     // copy default zoom to sheets where a different one wasn't specified
2941     for (SCTAB nZoomTab=0; nZoomTab<=MAXTAB; ++nZoomTab)
2942         if (pTabData[nZoomTab] && ( nZoomTab >= static_cast<SCTAB>(aHasZoomVect.size()) || !aHasZoomVect[nZoomTab] ))
2943         {
2944             pTabData[nZoomTab]->eZoomType  = eDefZoomType;
2945             pTabData[nZoomTab]->aZoomX     = aDefZoomX;
2946             pTabData[nZoomTab]->aZoomY     = aDefZoomY;
2947             pTabData[nZoomTab]->aPageZoomX = aDefPageZoomX;
2948             pTabData[nZoomTab]->aPageZoomY = aDefPageZoomY;
2949         }
2950 
2951     if (nCount)
2952         SetPagebreakMode( bPageMode );
2953 
2954     // #i47426# write view options to document, needed e.g. for Excel export
2955     pDoc->SetViewOptions( *pOptions );
2956 }
2957 
SetOptions(const ScViewOptions & rOpt)2958 void ScViewData::SetOptions( const ScViewOptions& rOpt )
2959 {
2960     //  if visibility of horiz. ScrollBar is changed, TabBar may have to be resized...
2961     sal_Bool bHScrollChanged = ( rOpt.GetOption(VOPT_HSCROLL) != pOptions->GetOption(VOPT_HSCROLL) );
2962 
2963     //  if graphics are turned on or off, animation has to be started or stopped
2964     //  graphics are controlled by VOBJ_TYPE_OLE
2965     sal_Bool bGraphicsChanged = ( pOptions->GetObjMode(VOBJ_TYPE_OLE) !=
2966                                    rOpt.GetObjMode(VOBJ_TYPE_OLE) );
2967 
2968     *pOptions = rOpt;
2969     DBG_ASSERT( pView, "No View" );
2970 
2971     if( pView )
2972     {
2973         pView->ViewOptionsHasChanged( bHScrollChanged, bGraphicsChanged );
2974     }
2975 }
2976 
GetMousePosPixel()2977 Point ScViewData::GetMousePosPixel()
2978 {
2979     DBG_ASSERT( pView, "GetMousePosPixel() ohne View" );
2980     return pView->GetMousePosPixel();
2981 }
2982 
UpdateInputHandler(sal_Bool bForce,sal_Bool bStopEditing)2983 void ScViewData::UpdateInputHandler( sal_Bool bForce, sal_Bool bStopEditing )
2984 {
2985     if (pViewShell)
2986         pViewShell->UpdateInputHandler( bForce, bStopEditing );
2987 }
2988 
IsOle()2989 sal_Bool ScViewData::IsOle()
2990 {
2991     return pDocShell && pDocShell->IsOle();
2992 }
2993 
UpdateFixX(SCTAB nTab)2994 sal_Bool ScViewData::UpdateFixX( SCTAB nTab )               // sal_True = Wert geaendert
2995 {
2996     if (!ValidTab(nTab))        // Default
2997         nTab=nTabNo;        // akuelle Tabelle
2998 
2999     if (!pView || pTabData[nTab]->eHSplitMode != SC_SPLIT_FIX)
3000         return sal_False;
3001 
3002     ScDocument* pLocalDoc = GetDocument();
3003     if (!pLocalDoc->HasTable(nTab))          // #114007# if called from reload, the sheet may not exist
3004         return sal_False;
3005 
3006     SCCOL nFix = pTabData[nTab]->nFixPosX;
3007     long nNewPos = 0;
3008     for (SCCOL nX=pTabData[nTab]->nPosX[SC_SPLIT_LEFT]; nX<nFix; nX++)
3009     {
3010         sal_uInt16 nTSize = pLocalDoc->GetColWidth( nX, nTab );
3011         if (nTSize)
3012         {
3013             long nPix = ToPixel( nTSize, nPPTX );
3014             nNewPos += nPix;
3015         }
3016     }
3017     nNewPos += pView->GetGridOffset().X();
3018     if (nNewPos != pTabData[nTab]->nHSplitPos)
3019     {
3020         pTabData[nTab]->nHSplitPos = nNewPos;
3021         if (nTab == nTabNo)
3022             RecalcPixPos();                 //! sollte nicht noetig sein !!!
3023         return sal_True;
3024     }
3025 
3026     return sal_False;
3027 }
3028 
UpdateFixY(SCTAB nTab)3029 sal_Bool ScViewData::UpdateFixY( SCTAB nTab )               // sal_True = Wert geaendert
3030 {
3031     if (!ValidTab(nTab))        // Default
3032         nTab=nTabNo;        // akuelle Tabelle
3033 
3034     if (!pView || pTabData[nTab]->eVSplitMode != SC_SPLIT_FIX)
3035         return sal_False;
3036 
3037     ScDocument* pLocalDoc = GetDocument();
3038     if (!pLocalDoc->HasTable(nTab))          // #114007# if called from reload, the sheet may not exist
3039         return sal_False;
3040 
3041     SCROW nFix = pTabData[nTab]->nFixPosY;
3042     long nNewPos = 0;
3043     for (SCROW nY=pTabData[nTab]->nPosY[SC_SPLIT_TOP]; nY<nFix; nY++)
3044     {
3045         sal_uInt16 nTSize = pLocalDoc->GetRowHeight( nY, nTab );
3046         if (nTSize)
3047         {
3048             long nPix = ToPixel( nTSize, nPPTY );
3049             nNewPos += nPix;
3050         }
3051     }
3052     nNewPos += pView->GetGridOffset().Y();
3053     if (nNewPos != pTabData[nTab]->nVSplitPos)
3054     {
3055         pTabData[nTab]->nVSplitPos = nNewPos;
3056         if (nTab == nTabNo)
3057             RecalcPixPos();                 //! sollte nicht noetig sein !!!
3058         return sal_True;
3059     }
3060 
3061     return sal_False;
3062 }
3063 
UpdateOutlinerFlags(Outliner & rOutl) const3064 void ScViewData::UpdateOutlinerFlags( Outliner& rOutl ) const
3065 {
3066     ScDocument* pLocalDoc = GetDocument();
3067     sal_Bool bOnlineSpell = pLocalDoc->GetDocOptions().IsAutoSpell();
3068 
3069     sal_uLong nCntrl = rOutl.GetControlWord();
3070     nCntrl |= EE_CNTRL_URLSFXEXECUTE;
3071     nCntrl |= EE_CNTRL_MARKFIELDS;
3072     nCntrl |= EE_CNTRL_AUTOCORRECT;
3073     if( bOnlineSpell )
3074         nCntrl |= EE_CNTRL_ONLINESPELLING;
3075     else
3076         nCntrl &= ~EE_CNTRL_ONLINESPELLING;
3077     rOutl.SetControlWord(nCntrl);
3078 
3079     rOutl.SetCalcFieldValueHdl( LINK( SC_MOD(), ScModule, CalcFieldValueHdl ) );
3080 
3081     //  #97417# don't call GetSpellChecker if online spelling isn't enabled.
3082     //  The language for AutoCorrect etc. is taken from the pool defaults
3083     //  (set in ScDocument::UpdateDrawLanguages)
3084 
3085     if ( bOnlineSpell )
3086     {
3087         com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellChecker1> xXSpellChecker1( LinguMgr::GetSpellChecker() );
3088         rOutl.SetSpeller( xXSpellChecker1 );
3089     }
3090 
3091     rOutl.SetDefaultHorizontalTextDirection(
3092         (EEHorizontalTextDirection)pLocalDoc->GetEditTextDirection( nTabNo ) );
3093 }
3094 
GetCurPos() const3095 ScAddress ScViewData::GetCurPos() const
3096 {
3097     return ScAddress( GetCurX(), GetCurY(), GetTabNo() );
3098 }
3099 
3100 
3101 // static
AddPixelsWhile(long & rScrY,long nEndPixels,SCROW & rPosY,SCROW nEndRow,double nPPTY,const ScDocument * pDoc,SCTAB nTabNo)3102 void ScViewData::AddPixelsWhile( long & rScrY, long nEndPixels, SCROW & rPosY,
3103         SCROW nEndRow, double nPPTY, const ScDocument * pDoc, SCTAB nTabNo )
3104 {
3105     SCROW nRow = rPosY;
3106     while (rScrY <= nEndPixels && nRow <= nEndRow)
3107     {
3108         SCROW nHeightEndRow;
3109         sal_uInt16 nHeight = pDoc->GetRowHeight( nRow, nTabNo, NULL, &nHeightEndRow);
3110         if (nHeightEndRow > nEndRow)
3111             nHeightEndRow = nEndRow;
3112         if (!nHeight)
3113             nRow = nHeightEndRow + 1;
3114         else
3115         {
3116             SCROW nRows = nHeightEndRow - nRow + 1;
3117             sal_Int64 nPixel = ToPixel( nHeight, nPPTY);
3118             sal_Int64 nAdd = nPixel * nRows;
3119             if (nAdd + rScrY > nEndPixels)
3120             {
3121                 sal_Int64 nDiff = rScrY + nAdd - nEndPixels;
3122                 nRows -= static_cast<SCROW>(nDiff / nPixel);
3123                 nAdd = nPixel * nRows;
3124                 // We're looking for a value that satisfies loop condition.
3125                 if (nAdd + rScrY <= nEndPixels)
3126                 {
3127                     ++nRows;
3128                     nAdd += nPixel;
3129                 }
3130             }
3131             rScrY += static_cast<long>(nAdd);
3132             nRow += nRows;
3133         }
3134     }
3135     if (nRow > rPosY)
3136         --nRow;
3137     rPosY = nRow;
3138 }
3139 
3140 
3141 // static
AddPixelsWhileBackward(long & rScrY,long nEndPixels,SCROW & rPosY,SCROW nStartRow,double nPPTY,const ScDocument * pDoc,SCTAB nTabNo)3142 void ScViewData::AddPixelsWhileBackward( long & rScrY, long nEndPixels,
3143         SCROW & rPosY, SCROW nStartRow, double nPPTY, const ScDocument * pDoc,
3144         SCTAB nTabNo )
3145 {
3146     SCROW nRow = rPosY;
3147     while (rScrY <= nEndPixels && nRow >= nStartRow)
3148     {
3149         SCROW nHeightStartRow;
3150         sal_uInt16 nHeight = pDoc->GetRowHeight( nRow, nTabNo, &nHeightStartRow, NULL);
3151         if (nHeightStartRow < nStartRow)
3152             nHeightStartRow = nStartRow;
3153         if (!nHeight)
3154             nRow = nHeightStartRow - 1;
3155         else
3156         {
3157             SCROW nRows = nRow - nHeightStartRow + 1;
3158             sal_Int64 nPixel = ToPixel( nHeight, nPPTY);
3159             sal_Int64 nAdd = nPixel * nRows;
3160             if (nAdd + rScrY > nEndPixels)
3161             {
3162                 sal_Int64 nDiff = nAdd + rScrY - nEndPixels;
3163                 nRows -= static_cast<SCROW>(nDiff / nPixel);
3164                 nAdd = nPixel * nRows;
3165                 // We're looking for a value that satisfies loop condition.
3166                 if (nAdd + rScrY <= nEndPixels)
3167                 {
3168                     ++nRows;
3169                     nAdd += nPixel;
3170                 }
3171             }
3172             rScrY += static_cast<long>(nAdd);
3173             nRow -= nRows;
3174         }
3175     }
3176     if (nRow < rPosY)
3177         ++nRow;
3178     rPosY = nRow;
3179 }
3180