xref: /trunk/main/sc/source/ui/view/viewdata.cxx (revision b7caab40)
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 
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 
112 ScViewDataTable::~ScViewDataTable()
113 {
114 }
115 
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 
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 
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 
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 
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 
466 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 
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 
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 
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 
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 
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 
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 
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 }
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 
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 
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 
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 
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 
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 
753 void ScViewData::SetPagebreakMode( sal_Bool bSet )
754 {
755 	bPagebreak = bSet;
756 
757     RefreshZoom();
758 }
759 
760 
761 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 
791 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 
806 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 
814 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 
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 
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 
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 
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 
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 
899 void ScViewData::ResetFillMode()
900 {
901 	nFillMode	= SC_FILL_NONE;
902 }
903 
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 
913 SCCOL ScViewData::GetOldCurX() const
914 {
915 	if (pThisTab->bOldCurValid)
916 		return pThisTab->nOldCurX;
917 	else
918 		return pThisTab->nCurX;
919 }
920 
921 SCROW ScViewData::GetOldCurY() const
922 {
923 	if (pThisTab->bOldCurValid)
924 		return pThisTab->nOldCurY;
925 	else
926 		return pThisTab->nCurY;
927 }
928 
929 void ScViewData::SetOldCursor( SCCOL nNewX, SCROW nNewY )
930 {
931 	pThisTab->nOldCurX = nNewX;
932 	pThisTab->nOldCurY = nNewY;
933 	pThisTab->bOldCurValid = sal_True;
934 }
935 
936 void ScViewData::ResetOldCursor()
937 {
938 	pThisTab->bOldCurValid = sal_False;
939 }
940 
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 
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 
1146 IMPL_LINK_INLINE_START( ScViewData, EmptyEditHdl, EditStatus *, EMPTYARG )
1147 {
1148 	return 0;
1149 }
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 
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 
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 
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 
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 
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 
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 
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 
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 
1508 void ScViewData::SetActivePart( ScSplitPos eNewActive )
1509 {
1510 	pThisTab->eWhichActive = eNewActive;
1511 }
1512 
1513 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 
1520 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 
1527 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 
1646 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 
1688 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 
1726 SCCOL ScViewData::VisibleCellsX( ScHSplitPos eWhichX ) const
1727 {
1728 	return CellsAtX( GetPosX( eWhichX ), 1, eWhichX, SC_SIZE_NONE );
1729 }
1730 
1731 SCROW ScViewData::VisibleCellsY( ScVSplitPos eWhichY ) const
1732 {
1733 	return CellsAtY( GetPosY( eWhichY ), 1, eWhichY, SC_SIZE_NONE );
1734 }
1735 
1736 SCCOL ScViewData::PrevCellsX( ScHSplitPos eWhichX ) const
1737 {
1738 	return CellsAtX( GetPosX( eWhichX ), -1, eWhichX, SC_SIZE_NONE );
1739 }
1740 
1741 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 
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 
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 
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 
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 
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 
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 
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 
2016 const MapMode& ScViewData::GetLogicMode()
2017 {
2018 	aLogicMode.SetOrigin( Point() );
2019 	return aLogicMode;
2020 }
2021 
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 
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 
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 
2120 SfxObjectShell* ScViewData::GetSfxDocShell() const
2121 {
2122 	return pDocShell;
2123 }
2124 
2125 SfxBindings& ScViewData::GetBindings()
2126 {
2127 	DBG_ASSERT( pViewShell, "GetBindings() without ViewShell" );
2128 	return pViewShell->GetViewFrame()->GetBindings();
2129 }
2130 
2131 SfxDispatcher& ScViewData::GetDispatcher()
2132 {
2133 	DBG_ASSERT( pViewShell, "GetDispatcher() without ViewShell" );
2134 	return *pViewShell->GetViewFrame()->GetDispatcher();
2135 }
2136 
2137 Window* ScViewData::GetDialogParent()
2138 {
2139 	DBG_ASSERT( pViewShell, "GetDialogParent() ohne ViewShell" );
2140 	return pViewShell->GetDialogParent();
2141 }
2142 
2143 Window* ScViewData::GetActiveWin()
2144 {
2145 	DBG_ASSERT( pView, "GetActiveWin() ohne View" );
2146 	return pView->GetActiveWin();
2147 }
2148 
2149 ScDrawView* ScViewData::GetScDrawView()
2150 {
2151 	DBG_ASSERT( pView, "GetScDrawView() ohne View" );
2152 	return pView->GetScDrawView();
2153 }
2154 
2155 sal_Bool ScViewData::IsMinimized()
2156 {
2157 	DBG_ASSERT( pView, "IsMinimized() ohne View" );
2158 	return pView->IsMinimized();
2159 }
2160 
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 
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 
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 
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 
2419 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 
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 
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 			pSettings[SC_VALUE_HIGHLIGHTING].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_VALUEHIGH ) );
2770 			ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_VALUE_HIGHLIGHTING].Value, pOptions->GetOption( VOPT_SYNTAX ) );
2771 
2772 			const ScGridOptions& aGridOpt = pOptions->GetGridOptions();
2773 			pSettings[SC_SNAPTORASTER].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_SNAPTORASTER));
2774 			ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SNAPTORASTER].Value, aGridOpt.GetUseGridSnap() );
2775 			pSettings[SC_RASTERVIS].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERVIS));
2776 			ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_RASTERVIS].Value, aGridOpt.GetGridVisible() );
2777 			pSettings[SC_RASTERRESX].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERRESX));
2778 			pSettings[SC_RASTERRESX].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDrawX() );
2779 			pSettings[SC_RASTERRESY].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERRESY));
2780 			pSettings[SC_RASTERRESY].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDrawY() );
2781 			pSettings[SC_RASTERSUBX].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERSUBX));
2782 			pSettings[SC_RASTERSUBX].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDivisionX() );
2783 			pSettings[SC_RASTERSUBY].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERSUBY));
2784 			pSettings[SC_RASTERSUBY].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDivisionY() );
2785 			pSettings[SC_RASTERSYNC].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_RASTERSYNC));
2786 			ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_RASTERSYNC].Value, aGridOpt.GetSynchronize() );
2787 		}
2788 	}
2789 }
2790 
2791 void ScViewData::ReadUserDataSequence(const uno::Sequence <beans::PropertyValue>& rSettings)
2792 {
2793     Fraction aZoomX, aZoomY, aPageZoomX, aPageZoomY;    //! evaluate (all sheets?)
2794 
2795     std::vector<bool> aHasZoomVect( GetDocument()->GetTableCount(), false );
2796 
2797 	sal_Int32 nCount(rSettings.getLength());
2798 	sal_Int32 nTemp32(0);
2799 	sal_Int16 nTemp16(0);
2800 	sal_Bool bPageMode(sal_False);
2801 	for (sal_Int32 i = 0; i < nCount; i++)
2802 	{
2803 		// SC_VIEWID has to parse and use by mba
2804 		rtl::OUString sName(rSettings[i].Name);
2805 		if (sName.compareToAscii(SC_TABLES) == 0)
2806 		{
2807 			uno::Reference<container::XNameContainer> xNameContainer;
2808 			if ((rSettings[i].Value >>= xNameContainer) && xNameContainer->hasElements())
2809 			{
2810 				uno::Sequence< rtl::OUString > aNames(xNameContainer->getElementNames());
2811 				for (sal_Int32 nTabPos = 0; nTabPos < aNames.getLength(); nTabPos++)
2812 				{
2813 					String sTabName(aNames[nTabPos]);
2814 					SCTAB nTab(0);
2815 					if (GetDocument()->GetTable(sTabName, nTab))
2816 					{
2817 						uno::Any aAny = xNameContainer->getByName(aNames[nTabPos]);
2818 						uno::Sequence<beans::PropertyValue> aTabSettings;
2819 						if (aAny >>= aTabSettings)
2820 						{
2821 							delete pTabData[nTab];
2822 							pTabData[nTab] = new ScViewDataTable;
2823                             bool bHasZoom = false;
2824                             pTabData[nTab]->ReadUserDataSequence(aTabSettings, *this, nTab, bHasZoom);
2825                             aHasZoomVect[nTab] = bHasZoom;
2826 						}
2827 					}
2828 				}
2829 			}
2830 		}
2831 		else if (sName.compareToAscii(SC_ACTIVETABLE) == 0)
2832 		{
2833 			rtl::OUString sValue;
2834 			if(rSettings[i].Value >>= sValue)
2835 			{
2836 				String sTabName(sValue);
2837 				SCTAB nTab(0);
2838 				if (GetDocument()->GetTable(sTabName, nTab))
2839 					nTabNo = nTab;
2840 			}
2841 		}
2842 		else if (sName.compareToAscii(SC_HORIZONTALSCROLLBARWIDTH) == 0)
2843 		{
2844 			if (rSettings[i].Value >>= nTemp32)
2845 				pView->SetTabBarWidth(nTemp32);
2846 		}
2847         else if (sName.compareToAscii(SC_RELHORIZONTALTABBARWIDTH) == 0)
2848         {
2849             double fWidth = 0.0;
2850             if (rSettings[i].Value >>= fWidth)
2851                 pView->SetPendingRelTabBarWidth( fWidth );
2852         }
2853 		else if (sName.compareToAscii(SC_ZOOMTYPE) == 0)
2854 		{
2855 			if (rSettings[i].Value >>= nTemp16)
2856                 eDefZoomType = SvxZoomType(nTemp16);
2857 		}
2858 		else if (sName.compareToAscii(SC_ZOOMVALUE) == 0)
2859 		{
2860 			if (rSettings[i].Value >>= nTemp32)
2861 			{
2862 				Fraction aZoom(nTemp32, 100);
2863                 aDefZoomX = aDefZoomY = aZoom;
2864 			}
2865 		}
2866 		else if (sName.compareToAscii(SC_PAGEVIEWZOOMVALUE) == 0)
2867 		{
2868 			if (rSettings[i].Value >>= nTemp32)
2869 			{
2870 				Fraction aZoom(nTemp32, 100);
2871                 aDefPageZoomX = aDefPageZoomY = aZoom;
2872 			}
2873 		}
2874 		else if (sName.compareToAscii(SC_SHOWPAGEBREAKPREVIEW) == 0)
2875 			bPageMode = ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value );
2876 		else if ( sName.compareToAscii( SC_UNO_SHOWZERO ) == 0 )
2877 			pOptions->SetOption(VOPT_NULLVALS, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2878 		else if ( sName.compareToAscii( SC_UNO_SHOWNOTES ) == 0 )
2879 			pOptions->SetOption(VOPT_NOTES, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2880 		else if ( sName.compareToAscii( SC_UNO_SHOWGRID ) == 0 )
2881 			pOptions->SetOption(VOPT_GRID, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2882 		else if ( sName.compareToAscii( SC_UNO_GRIDCOLOR ) == 0 )
2883 		{
2884 			sal_Int64 nColor = 0;
2885 			if (rSettings[i].Value >>= nColor)
2886 			{
2887 				String aColorName;
2888 				Color aColor(static_cast<sal_uInt32>(nColor));
2889                 // #i47435# set automatic grid color explicitly
2890                 if( aColor.GetColor() == COL_AUTO )
2891                     aColor.SetColor( SC_STD_GRIDCOLOR );
2892 				pOptions->SetGridColor(aColor, aColorName);
2893 			}
2894 		}
2895 		else if ( sName.compareToAscii( SC_UNO_SHOWPAGEBR ) == 0 )
2896 			pOptions->SetOption(VOPT_PAGEBREAKS, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2897 		else if ( sName.compareToAscii( SC_UNO_COLROWHDR ) == 0 )
2898 			pOptions->SetOption(VOPT_HEADER, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2899 		else if ( sName.compareToAscii( SC_UNO_SHEETTABS ) == 0 )
2900 			pOptions->SetOption(VOPT_TABCONTROLS, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2901 		else if ( sName.compareToAscii( SC_UNO_OUTLSYMB ) == 0 )
2902 			pOptions->SetOption(VOPT_OUTLINER, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2903         else if ( sName.compareToAscii( SC_UNO_SHOWOBJ ) == 0 )
2904         {
2905             // #i80528# placeholders not supported anymore
2906             if ( rSettings[i].Value >>= nTemp16 )
2907                 pOptions->SetObjMode( VOBJ_TYPE_OLE, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
2908         }
2909         else if ( sName.compareToAscii( SC_UNO_SHOWCHARTS ) == 0 )
2910         {
2911             // #i80528# placeholders not supported anymore
2912             if ( rSettings[i].Value >>= nTemp16 )
2913                 pOptions->SetObjMode( VOBJ_TYPE_CHART, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
2914         }
2915         else if ( sName.compareToAscii( SC_UNO_SHOWDRAW ) == 0 )
2916         {
2917             // #i80528# placeholders not supported anymore
2918             if ( rSettings[i].Value >>= nTemp16 )
2919                 pOptions->SetObjMode( VOBJ_TYPE_DRAW, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
2920         }
2921         else if ( sName.compareToAscii( SC_UNO_VALUEHIGH ) == 0 )
2922             pOptions->SetOption( VOPT_SYNTAX, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2923 		else
2924 		{
2925 			ScGridOptions aGridOpt(pOptions->GetGridOptions());
2926 			if ( sName.compareToAscii( SC_UNO_SNAPTORASTER ) == 0 )
2927 				aGridOpt.SetUseGridSnap( ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2928 			else if ( sName.compareToAscii( SC_UNO_RASTERVIS ) == 0 )
2929 				aGridOpt.SetGridVisible( ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2930 			else if ( sName.compareToAscii( SC_UNO_RASTERRESX ) == 0 )
2931 				aGridOpt.SetFldDrawX( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
2932 			else if ( sName.compareToAscii( SC_UNO_RASTERRESY ) == 0 )
2933 				aGridOpt.SetFldDrawY( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
2934 			else if ( sName.compareToAscii( SC_UNO_RASTERSUBX ) == 0 )
2935 				aGridOpt.SetFldDivisionX( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
2936 			else if ( sName.compareToAscii( SC_UNO_RASTERSUBY ) == 0 )
2937 				aGridOpt.SetFldDivisionY( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
2938 			else if ( sName.compareToAscii( SC_UNO_RASTERSYNC ) == 0 )
2939 				aGridOpt.SetSynchronize( ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2940 			pOptions->SetGridOptions(aGridOpt);
2941 		}
2942 	}
2943 
2944     // copy default zoom to sheets where a different one wasn't specified
2945     for (SCTAB nZoomTab=0; nZoomTab<=MAXTAB; ++nZoomTab)
2946         if (pTabData[nZoomTab] && ( nZoomTab >= static_cast<SCTAB>(aHasZoomVect.size()) || !aHasZoomVect[nZoomTab] ))
2947         {
2948             pTabData[nZoomTab]->eZoomType  = eDefZoomType;
2949             pTabData[nZoomTab]->aZoomX     = aDefZoomX;
2950             pTabData[nZoomTab]->aZoomY     = aDefZoomY;
2951             pTabData[nZoomTab]->aPageZoomX = aDefPageZoomX;
2952             pTabData[nZoomTab]->aPageZoomY = aDefPageZoomY;
2953         }
2954 
2955 	if (nCount)
2956 		SetPagebreakMode( bPageMode );
2957 
2958     // #i47426# write view options to document, needed e.g. for Excel export
2959     pDoc->SetViewOptions( *pOptions );
2960 }
2961 
2962 void ScViewData::SetOptions( const ScViewOptions& rOpt )
2963 {
2964 	//	if visibility of horiz. ScrollBar is changed, TabBar may have to be resized...
2965 	sal_Bool bHScrollChanged = ( rOpt.GetOption(VOPT_HSCROLL) != pOptions->GetOption(VOPT_HSCROLL) );
2966 
2967 	//	if graphics are turned on or off, animation has to be started or stopped
2968 	//	graphics are controlled by VOBJ_TYPE_OLE
2969 	sal_Bool bGraphicsChanged =	( pOptions->GetObjMode(VOBJ_TYPE_OLE) !=
2970 								   rOpt.GetObjMode(VOBJ_TYPE_OLE) );
2971 
2972 	*pOptions = rOpt;
2973 	DBG_ASSERT( pView, "No View" );
2974 
2975 	if( pView )
2976 	{
2977 		pView->ViewOptionsHasChanged( bHScrollChanged, bGraphicsChanged );
2978 	}
2979 }
2980 
2981 Point ScViewData::GetMousePosPixel()
2982 {
2983 	DBG_ASSERT( pView, "GetMousePosPixel() ohne View" );
2984 	return pView->GetMousePosPixel();
2985 }
2986 
2987 void ScViewData::UpdateInputHandler( sal_Bool bForce, sal_Bool bStopEditing )
2988 {
2989 	if (pViewShell)
2990 		pViewShell->UpdateInputHandler( bForce, bStopEditing );
2991 }
2992 
2993 sal_Bool ScViewData::IsOle()
2994 {
2995 	return pDocShell && pDocShell->IsOle();
2996 }
2997 
2998 sal_Bool ScViewData::UpdateFixX( SCTAB nTab )				// sal_True = Wert geaendert
2999 {
3000 	if (!ValidTab(nTab))		// Default
3001 		nTab=nTabNo;		// akuelle Tabelle
3002 
3003 	if (!pView || pTabData[nTab]->eHSplitMode != SC_SPLIT_FIX)
3004 		return sal_False;
3005 
3006     ScDocument* pLocalDoc = GetDocument();
3007     if (!pLocalDoc->HasTable(nTab))          // #114007# if called from reload, the sheet may not exist
3008         return sal_False;
3009 
3010 	SCCOL nFix = pTabData[nTab]->nFixPosX;
3011 	long nNewPos = 0;
3012 	for (SCCOL nX=pTabData[nTab]->nPosX[SC_SPLIT_LEFT]; nX<nFix; nX++)
3013 	{
3014 		sal_uInt16 nTSize = pLocalDoc->GetColWidth( nX, nTab );
3015 		if (nTSize)
3016 		{
3017 			long nPix = ToPixel( nTSize, nPPTX );
3018 			nNewPos += nPix;
3019 		}
3020 	}
3021 	nNewPos += pView->GetGridOffset().X();
3022 	if (nNewPos != pTabData[nTab]->nHSplitPos)
3023 	{
3024 		pTabData[nTab]->nHSplitPos = nNewPos;
3025 		if (nTab == nTabNo)
3026 			RecalcPixPos();					//! sollte nicht noetig sein !!!
3027 		return sal_True;
3028 	}
3029 
3030 	return sal_False;
3031 }
3032 
3033 sal_Bool ScViewData::UpdateFixY( SCTAB nTab )				// sal_True = Wert geaendert
3034 {
3035 	if (!ValidTab(nTab))		// Default
3036 		nTab=nTabNo;		// akuelle Tabelle
3037 
3038 	if (!pView || pTabData[nTab]->eVSplitMode != SC_SPLIT_FIX)
3039 		return sal_False;
3040 
3041     ScDocument* pLocalDoc = GetDocument();
3042     if (!pLocalDoc->HasTable(nTab))          // #114007# if called from reload, the sheet may not exist
3043         return sal_False;
3044 
3045 	SCROW nFix = pTabData[nTab]->nFixPosY;
3046 	long nNewPos = 0;
3047 	for (SCROW nY=pTabData[nTab]->nPosY[SC_SPLIT_TOP]; nY<nFix; nY++)
3048 	{
3049 		sal_uInt16 nTSize = pLocalDoc->GetRowHeight( nY, nTab );
3050 		if (nTSize)
3051 		{
3052 			long nPix = ToPixel( nTSize, nPPTY );
3053 			nNewPos += nPix;
3054 		}
3055 	}
3056 	nNewPos += pView->GetGridOffset().Y();
3057 	if (nNewPos != pTabData[nTab]->nVSplitPos)
3058 	{
3059 		pTabData[nTab]->nVSplitPos = nNewPos;
3060 		if (nTab == nTabNo)
3061 			RecalcPixPos();					//! sollte nicht noetig sein !!!
3062 		return sal_True;
3063 	}
3064 
3065 	return sal_False;
3066 }
3067 
3068 void ScViewData::UpdateOutlinerFlags( Outliner& rOutl ) const
3069 {
3070 	ScDocument* pLocalDoc = GetDocument();
3071 	sal_Bool bOnlineSpell = pLocalDoc->GetDocOptions().IsAutoSpell();
3072 
3073 	sal_uLong nCntrl = rOutl.GetControlWord();
3074 	nCntrl |= EE_CNTRL_URLSFXEXECUTE;
3075 	nCntrl |= EE_CNTRL_MARKFIELDS;
3076 	nCntrl |= EE_CNTRL_AUTOCORRECT;
3077 	if( bOnlineSpell )
3078 		nCntrl |= EE_CNTRL_ONLINESPELLING;
3079 	else
3080 		nCntrl &= ~EE_CNTRL_ONLINESPELLING;
3081 	rOutl.SetControlWord(nCntrl);
3082 
3083 	rOutl.SetCalcFieldValueHdl( LINK( SC_MOD(), ScModule, CalcFieldValueHdl ) );
3084 
3085 	//	#97417# don't call GetSpellChecker if online spelling isn't enabled.
3086 	//	The language for AutoCorrect etc. is taken from the pool defaults
3087 	//	(set in ScDocument::UpdateDrawLanguages)
3088 
3089 	if ( bOnlineSpell )
3090 	{
3091 	    com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellChecker1> xXSpellChecker1( LinguMgr::GetSpellChecker() );
3092 		rOutl.SetSpeller( xXSpellChecker1 );
3093 	}
3094 
3095 	rOutl.SetDefaultHorizontalTextDirection(
3096 		(EEHorizontalTextDirection)pLocalDoc->GetEditTextDirection( nTabNo ) );
3097 }
3098 
3099 ScAddress ScViewData::GetCurPos() const
3100 {
3101 	return ScAddress( GetCurX(), GetCurY(), GetTabNo() );
3102 }
3103 
3104 
3105 // static
3106 void ScViewData::AddPixelsWhile( long & rScrY, long nEndPixels, SCROW & rPosY,
3107         SCROW nEndRow, double nPPTY, const ScDocument * pDoc, SCTAB nTabNo )
3108 {
3109     SCROW nRow = rPosY;
3110     while (rScrY <= nEndPixels && nRow <= nEndRow)
3111     {
3112         SCROW nHeightEndRow;
3113         sal_uInt16 nHeight = pDoc->GetRowHeight( nRow, nTabNo, NULL, &nHeightEndRow);
3114         if (nHeightEndRow > nEndRow)
3115             nHeightEndRow = nEndRow;
3116         if (!nHeight)
3117             nRow = nHeightEndRow + 1;
3118         else
3119         {
3120             SCROW nRows = nHeightEndRow - nRow + 1;
3121             sal_Int64 nPixel = ToPixel( nHeight, nPPTY);
3122             sal_Int64 nAdd = nPixel * nRows;
3123             if (nAdd + rScrY > nEndPixels)
3124             {
3125                 sal_Int64 nDiff = rScrY + nAdd - nEndPixels;
3126                 nRows -= static_cast<SCROW>(nDiff / nPixel);
3127                 nAdd = nPixel * nRows;
3128                 // We're looking for a value that satisfies loop condition.
3129                 if (nAdd + rScrY <= nEndPixels)
3130                 {
3131                     ++nRows;
3132                     nAdd += nPixel;
3133                 }
3134             }
3135             rScrY += static_cast<long>(nAdd);
3136             nRow += nRows;
3137         }
3138     }
3139     if (nRow > rPosY)
3140         --nRow;
3141     rPosY = nRow;
3142 }
3143 
3144 
3145 // static
3146 void ScViewData::AddPixelsWhileBackward( long & rScrY, long nEndPixels,
3147         SCROW & rPosY, SCROW nStartRow, double nPPTY, const ScDocument * pDoc,
3148         SCTAB nTabNo )
3149 {
3150     SCROW nRow = rPosY;
3151     while (rScrY <= nEndPixels && nRow >= nStartRow)
3152     {
3153         SCROW nHeightStartRow;
3154         sal_uInt16 nHeight = pDoc->GetRowHeight( nRow, nTabNo, &nHeightStartRow, NULL);
3155         if (nHeightStartRow < nStartRow)
3156             nHeightStartRow = nStartRow;
3157         if (!nHeight)
3158             nRow = nHeightStartRow - 1;
3159         else
3160         {
3161             SCROW nRows = nRow - nHeightStartRow + 1;
3162             sal_Int64 nPixel = ToPixel( nHeight, nPPTY);
3163             sal_Int64 nAdd = nPixel * nRows;
3164             if (nAdd + rScrY > nEndPixels)
3165             {
3166                 sal_Int64 nDiff = nAdd + rScrY - nEndPixels;
3167                 nRows -= static_cast<SCROW>(nDiff / nPixel);
3168                 nAdd = nPixel * nRows;
3169                 // We're looking for a value that satisfies loop condition.
3170                 if (nAdd + rScrY <= nEndPixels)
3171                 {
3172                     ++nRows;
3173                     nAdd += nPixel;
3174                 }
3175             }
3176             rScrY += static_cast<long>(nAdd);
3177             nRow -= nRows;
3178         }
3179     }
3180     if (nRow < rPosY)
3181         ++nRow;
3182     rPosY = nRow;
3183 }
3184