Bump version to 4.3-4
[LibreOffice.git] / sc / source / ui / view / viewdata.cxx
blob121d51056ea2714a5cc4a88ab37d1a569ff91253
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "scitems.hxx"
22 #include <editeng/eeitem.hxx>
25 #include <sfx2/viewfrm.hxx>
26 #include <editeng/adjustitem.hxx>
27 #include <svx/algitem.hxx>
28 #include <editeng/brushitem.hxx>
29 #include <svtools/colorcfg.hxx>
30 #include <editeng/editview.hxx>
31 #include <editeng/editstat.hxx>
32 #include <editeng/outliner.hxx>
33 #include <editeng/unolingu.hxx>
34 #include <editeng/justifyitem.hxx>
36 #include <vcl/svapp.hxx>
37 #include <rtl/math.hxx>
39 #include <sax/tools/converter.hxx>
41 #include "viewdata.hxx"
42 #include "docoptio.hxx"
43 #include "scmod.hxx"
44 #include "global.hxx"
45 #include "document.hxx"
46 #include "attrib.hxx"
47 #include "tabview.hxx"
48 #include "tabvwsh.hxx"
49 #include "docsh.hxx"
50 #include "sc.hrc"
51 #include "patattr.hxx"
52 #include "editutil.hxx"
53 #include "scextopt.hxx"
54 #include "miscuno.hxx"
55 #include "unonames.hxx"
56 #include "inputopt.hxx"
57 #include "viewutil.hxx"
58 #include "markdata.hxx"
59 #include "stlalgorithm.hxx"
60 #include "ViewSettingsSequenceDefines.hxx"
61 #include <gridwin.hxx>
62 #include <rtl/ustrbuf.hxx>
63 #include <boost/checked_delete.hpp>
64 #include <comphelper/processfactory.hxx>
65 #include <comphelper/string.hxx>
67 #include <com/sun/star/container/XNameContainer.hpp>
68 #include <com/sun/star/document/NamedPropertyValues.hpp>
70 using namespace com::sun::star;
72 #define SC_GROWY_SMALL_EXTRA 100
73 #define SC_GROWY_BIG_EXTRA 200
75 #define TAG_TABBARWIDTH "tw:"
77 static bool bMoveArea = false; // Member?
78 sal_uInt16 nEditAdjust = SVX_ADJUST_LEFT; // Member!
80 ScViewDataTable::ScViewDataTable() :
81 eZoomType( SVX_ZOOM_PERCENT ),
82 aZoomX( 1,1 ),
83 aZoomY( 1,1 ),
84 aPageZoomX( 3,5 ), // Page-Default: 60%
85 aPageZoomY( 3,5 ),
86 nHSplitPos( 0 ),
87 nVSplitPos( 0 ),
88 eHSplitMode( SC_SPLIT_NONE ),
89 eVSplitMode( SC_SPLIT_NONE ),
90 eWhichActive( SC_SPLIT_BOTTOMLEFT ),
91 nFixPosX( 0 ),
92 nFixPosY( 0 ),
93 nCurX( 0 ),
94 nCurY( 0 ),
95 nOldCurX( 0 ),
96 nOldCurY( 0 ),
97 bShowGrid( true ),
98 mbOldCursorValid( false )
100 nPosX[0]=nPosX[1]=0;
101 nPosY[0]=nPosY[1]=0;
102 nTPosX[0]=nTPosX[1]=0;
103 nTPosY[0]=nTPosY[1]=0;
104 nMPosX[0]=nMPosX[1]=0;
105 nMPosY[0]=nMPosY[1]=0;
106 nPixPosX[0]=nPixPosX[1]=0;
107 nPixPosY[0]=nPixPosY[1]=0;
110 ScViewDataTable::~ScViewDataTable()
114 void ScViewDataTable::WriteUserDataSequence(uno::Sequence <beans::PropertyValue>& rSettings, const ScViewData& /*rViewData*/, SCTAB /*nTab*/) const
116 rSettings.realloc(SC_TABLE_VIEWSETTINGS_COUNT);
117 beans::PropertyValue* pSettings = rSettings.getArray();
118 if (pSettings)
120 pSettings[SC_CURSOR_X].Name = OUString(SC_CURSORPOSITIONX);
121 pSettings[SC_CURSOR_X].Value <<= sal_Int32(nCurX);
122 pSettings[SC_CURSOR_Y].Name = OUString(SC_CURSORPOSITIONY);
123 pSettings[SC_CURSOR_Y].Value <<= sal_Int32(nCurY);
124 pSettings[SC_HORIZONTAL_SPLIT_MODE].Name = OUString(SC_HORIZONTALSPLITMODE);
125 pSettings[SC_HORIZONTAL_SPLIT_MODE].Value <<= sal_Int16(eHSplitMode);
126 pSettings[SC_VERTICAL_SPLIT_MODE].Name = OUString(SC_VERTICALSPLITMODE);
127 pSettings[SC_VERTICAL_SPLIT_MODE].Value <<= sal_Int16(eVSplitMode);
128 pSettings[SC_HORIZONTAL_SPLIT_POSITION].Name = OUString(SC_HORIZONTALSPLITPOSITION);
129 if (eHSplitMode == SC_SPLIT_FIX)
130 pSettings[SC_HORIZONTAL_SPLIT_POSITION].Value <<= sal_Int32(nFixPosX);
131 else
132 pSettings[SC_HORIZONTAL_SPLIT_POSITION].Value <<= sal_Int32(nHSplitPos);
133 pSettings[SC_VERTICAL_SPLIT_POSITION].Name = OUString(SC_VERTICALSPLITPOSITION);
134 if (eVSplitMode == SC_SPLIT_FIX)
135 pSettings[SC_VERTICAL_SPLIT_POSITION].Value <<= sal_Int32(nFixPosY);
136 else
137 pSettings[SC_VERTICAL_SPLIT_POSITION].Value <<= sal_Int32(nVSplitPos);
138 pSettings[SC_ACTIVE_SPLIT_RANGE].Name = OUString(SC_ACTIVESPLITRANGE);
139 pSettings[SC_ACTIVE_SPLIT_RANGE].Value <<= sal_Int16(eWhichActive);
140 pSettings[SC_POSITION_LEFT].Name = OUString(SC_POSITIONLEFT);
141 pSettings[SC_POSITION_LEFT].Value <<= sal_Int32(nPosX[SC_SPLIT_LEFT]);
142 pSettings[SC_POSITION_RIGHT].Name = OUString(SC_POSITIONRIGHT);
143 pSettings[SC_POSITION_RIGHT].Value <<= sal_Int32(nPosX[SC_SPLIT_RIGHT]);
144 pSettings[SC_POSITION_TOP].Name = OUString(SC_POSITIONTOP);
145 pSettings[SC_POSITION_TOP].Value <<= sal_Int32(nPosY[SC_SPLIT_TOP]);
146 pSettings[SC_POSITION_BOTTOM].Name = OUString(SC_POSITIONBOTTOM);
147 pSettings[SC_POSITION_BOTTOM].Value <<= sal_Int32(nPosY[SC_SPLIT_BOTTOM]);
149 sal_Int32 nZoomValue ((aZoomY.GetNumerator() * 100) / aZoomY.GetDenominator());
150 sal_Int32 nPageZoomValue ((aPageZoomY.GetNumerator() * 100) / aPageZoomY.GetDenominator());
151 pSettings[SC_TABLE_ZOOM_TYPE].Name = OUString(SC_ZOOMTYPE);
152 pSettings[SC_TABLE_ZOOM_TYPE].Value <<= sal_Int16(eZoomType);
153 pSettings[SC_TABLE_ZOOM_VALUE].Name = OUString(SC_ZOOMVALUE);
154 pSettings[SC_TABLE_ZOOM_VALUE].Value <<= nZoomValue;
155 pSettings[SC_TABLE_PAGE_VIEW_ZOOM_VALUE].Name = OUString(SC_PAGEVIEWZOOMVALUE);
156 pSettings[SC_TABLE_PAGE_VIEW_ZOOM_VALUE].Value <<= nPageZoomValue;
158 pSettings[SC_TABLE_SHOWGRID].Name = OUString(SC_UNO_SHOWGRID);
159 pSettings[SC_TABLE_SHOWGRID].Value <<= bShowGrid;
163 void ScViewDataTable::ReadUserDataSequence(const uno::Sequence <beans::PropertyValue>& aSettings, ScViewData& rViewData, SCTAB nTab, bool& rHasZoom )
165 rHasZoom = false;
167 sal_Int32 nCount(aSettings.getLength());
168 sal_Int32 nTemp32(0);
169 sal_Int16 nTemp16(0);
170 sal_Int32 nTempPosV(0);
171 sal_Int32 nTempPosH(0);
172 sal_Int32 nTempPosVTw(0);
173 sal_Int32 nTempPosHTw(0);
174 bool bHasVSplitInTwips = false;
175 bool bHasHSplitInTwips = false;
176 for (sal_Int32 i = 0; i < nCount; i++)
178 OUString sName(aSettings[i].Name);
179 if (sName.equalsAscii(SC_CURSORPOSITIONX) )
181 aSettings[i].Value >>= nTemp32;
182 nCurX = SanitizeCol( static_cast<SCCOL>(nTemp32));
184 else if (sName.equalsAscii(SC_CURSORPOSITIONY) )
186 aSettings[i].Value >>= nTemp32;
187 nCurY = SanitizeRow( static_cast<SCROW>(nTemp32));
189 else if (sName.equalsAscii(SC_HORIZONTALSPLITMODE) )
191 aSettings[i].Value >>= nTemp16;
192 eHSplitMode = static_cast<ScSplitMode>(nTemp16);
194 else if (sName.equalsAscii(SC_VERTICALSPLITMODE) )
196 aSettings[i].Value >>= nTemp16;
197 eVSplitMode = static_cast<ScSplitMode>(nTemp16);
199 else if (sName.equalsAscii(SC_HORIZONTALSPLITPOSITION) )
201 aSettings[i].Value >>= nTempPosH;
202 bHasHSplitInTwips = false;
204 else if (sName.equalsAscii(SC_VERTICALSPLITPOSITION) )
206 aSettings[i].Value >>= nTempPosV;
207 bHasVSplitInTwips = false;
209 else if (sName.equalsAscii(SC_HORIZONTALSPLITPOSITION_TWIPS) )
211 aSettings[i].Value >>= nTempPosHTw;
212 bHasHSplitInTwips = true;
214 else if (sName.equalsAscii(SC_VERTICALSPLITPOSITION_TWIPS) )
216 aSettings[i].Value >>= nTempPosVTw;
217 bHasVSplitInTwips = true;
219 else if (sName.equalsAscii(SC_ACTIVESPLITRANGE) )
221 aSettings[i].Value >>= nTemp16;
222 eWhichActive = static_cast<ScSplitPos>(nTemp16);
224 else if (sName.equalsAscii(SC_POSITIONLEFT) )
226 aSettings[i].Value >>= nTemp32;
227 nPosX[SC_SPLIT_LEFT] = SanitizeCol( static_cast<SCCOL>(nTemp32));
229 else if (sName.equalsAscii(SC_POSITIONRIGHT) )
231 aSettings[i].Value >>= nTemp32;
232 nPosX[SC_SPLIT_RIGHT] = SanitizeCol( static_cast<SCCOL>(nTemp32));
234 else if (sName.equalsAscii(SC_POSITIONTOP) )
236 aSettings[i].Value >>= nTemp32;
237 nPosY[SC_SPLIT_TOP] = SanitizeRow( static_cast<SCROW>(nTemp32));
239 else if (sName.equalsAscii(SC_POSITIONBOTTOM) )
241 aSettings[i].Value >>= nTemp32;
242 nPosY[SC_SPLIT_BOTTOM] = SanitizeRow( static_cast<SCROW>(nTemp32));
244 else if (sName.equalsAscii(SC_ZOOMTYPE) )
246 aSettings[i].Value >>= nTemp16;
247 eZoomType = SvxZoomType(nTemp16);
248 rHasZoom = true; // set if there is any zoom information
250 else if (sName.equalsAscii(SC_ZOOMVALUE) )
252 aSettings[i].Value >>= nTemp32;
253 Fraction aZoom(nTemp32, 100);
254 aZoomX = aZoomY = aZoom;
255 rHasZoom = true;
257 else if (sName.equalsAscii(SC_PAGEVIEWZOOMVALUE) )
259 aSettings[i].Value >>= nTemp32;
260 Fraction aZoom(nTemp32, 100);
261 aPageZoomX = aPageZoomY = aZoom;
262 rHasZoom = true;
264 else if (sName.equalsAscii(SC_UNO_SHOWGRID) )
266 aSettings[i].Value >>= bShowGrid;
268 else if (sName.equalsAscii(SC_TABLESELECTED) )
270 bool bSelected = false;
271 aSettings[i].Value >>= bSelected;
272 rViewData.GetMarkData().SelectTable( nTab, bSelected );
274 else if (sName.equalsAscii(SC_UNONAME_TABCOLOR) )
276 // There are documents out there that have their tab color defined as a view setting.
277 sal_Int32 nColor = COL_AUTO;
278 aSettings[i].Value >>= nColor;
279 if (static_cast<ColorData>(nColor) != COL_AUTO)
281 ScDocument* pDoc = rViewData.GetDocument();
282 pDoc->SetTabBgColor(nTab, Color(static_cast<ColorData>(nColor)));
286 if (eHSplitMode == SC_SPLIT_FIX)
287 nFixPosX = SanitizeCol( static_cast<SCCOL>( bHasHSplitInTwips ? nTempPosHTw : nTempPosH ));
288 else
289 nHSplitPos = bHasHSplitInTwips ? static_cast< long >( nTempPosHTw * rViewData.GetPPTX() ) : nTempPosH;
291 if (eVSplitMode == SC_SPLIT_FIX)
292 nFixPosY = SanitizeRow( static_cast<SCROW>( bHasVSplitInTwips ? nTempPosVTw : nTempPosV ));
293 else
294 nVSplitPos = bHasVSplitInTwips ? static_cast< long >( nTempPosVTw * rViewData.GetPPTY() ) : nTempPosV;
297 ScViewData::ScViewData( ScDocShell* pDocSh, ScTabViewShell* pViewSh ) :
298 mpMarkData(new ScMarkData),
299 pDocShell ( pDocSh ),
300 pDoc ( NULL ),
301 pView ( pViewSh ),
302 pViewShell ( pViewSh ),
303 pOptions ( new ScViewOptions ),
304 pSpellingView ( NULL ),
305 aLogicMode ( MAP_100TH_MM ),
306 eDefZoomType( SVX_ZOOM_PERCENT ),
307 aDefZoomX ( 1,1 ),
308 aDefZoomY ( 1,1 ),
309 aDefPageZoomX( 3,5 ),
310 aDefPageZoomY( 3,5 ),
311 eRefType ( SC_REFTYPE_NONE ),
312 nTabNo ( 0 ),
313 nRefTabNo ( 0 ),
314 nRefStartX(0),
315 nRefStartY(0),
316 nRefStartZ(0),
317 nRefEndX(0),
318 nRefEndY(0),
319 nRefEndZ(0),
320 nFillStartX(0),
321 nFillStartY(0),
322 nFillEndX(0),
323 nFillEndY(0),
324 nPasteFlags ( SC_PASTE_NONE ),
325 eEditActivePart( SC_SPLIT_BOTTOMLEFT ),
326 nFillMode ( SC_FILL_NONE ),
327 bActive ( true ), // how to initialize?
328 bIsRefMode ( false ),
329 bDelMarkValid( false ),
330 bPagebreak ( false ),
331 bSelCtrlMouseClick( false )
333 mpMarkData->SelectOneTable(0); // Sync with nTabNo
335 SetGridMode ( true );
336 SetSyntaxMode ( false );
337 SetHeaderMode ( true );
338 SetTabMode ( true );
339 SetVScrollMode ( true );
340 SetHScrollMode ( true );
341 SetOutlineMode ( true );
343 aScrSize = Size( (long) ( STD_COL_WIDTH * PIXEL_PER_TWIPS * OLE_STD_CELLS_X ),
344 (long) ( ScGlobal::nStdRowHeight * PIXEL_PER_TWIPS * OLE_STD_CELLS_Y ) );
345 maTabData.push_back( new ScViewDataTable );
346 pThisTab = maTabData[nTabNo];
347 for (sal_uInt16 j=0; j<4; j++)
349 pEditView[j] = NULL;
350 bEditActive[j] = false;
353 nEditEndCol = nEditStartCol = nEditCol = 0;
354 nEditEndRow = nEditRow = 0;
355 nTabStartCol = SC_TABSTART_NONE;
357 if (pDocShell)
359 pDoc = pDocShell->GetDocument();
360 *pOptions = pDoc->GetViewOptions();
363 // don't show hidden tables
364 if (pDoc && !pDoc->IsVisible(nTabNo))
366 while ( !pDoc->IsVisible(nTabNo) && pDoc->HasTable(nTabNo+1) )
368 ++nTabNo;
369 maTabData.push_back(NULL);
371 maTabData[nTabNo] = new ScViewDataTable() ;
372 pThisTab = maTabData[nTabNo];
375 CalcPPT();
378 ScViewData::ScViewData( const ScViewData& rViewData ) :
379 maTabData( rViewData.maTabData ),
380 mpMarkData(new ScMarkData(*rViewData.mpMarkData)),
381 pDocShell ( rViewData.pDocShell ),
382 pDoc ( rViewData.pDoc ),
383 pView ( rViewData.pView ),
384 pViewShell ( rViewData.pViewShell ),
385 pOptions ( new ScViewOptions( *(rViewData.pOptions) ) ),
386 pSpellingView ( rViewData.pSpellingView ),
387 aLogicMode ( rViewData.aLogicMode ),
388 eDefZoomType( rViewData.eDefZoomType ),
389 aDefZoomX ( rViewData.aDefZoomX ),
390 aDefZoomY ( rViewData.aDefZoomY ),
391 aDefPageZoomX( rViewData.aDefPageZoomX ),
392 aDefPageZoomY( rViewData.aDefPageZoomY ),
393 eRefType ( SC_REFTYPE_NONE ),
394 nTabNo ( rViewData.nTabNo ),
395 nRefTabNo ( rViewData.nTabNo ), // no RefMode
396 nRefStartX(0),
397 nRefStartY(0),
398 nRefStartZ(0),
399 nRefEndX(0),
400 nRefEndY(0),
401 nRefEndZ(0),
402 nFillStartX(0),
403 nFillStartY(0),
404 nFillEndX(0),
405 nFillEndY(0),
406 nPasteFlags ( SC_PASTE_NONE ),
407 eEditActivePart( rViewData.eEditActivePart ),
408 nFillMode ( SC_FILL_NONE ),
409 bActive ( true ), // how to initialize?
410 bIsRefMode ( false ),
411 bDelMarkValid( false ),
412 bPagebreak ( rViewData.bPagebreak ),
413 bSelCtrlMouseClick( rViewData.bSelCtrlMouseClick )
416 SetGridMode ( rViewData.IsGridMode() );
417 SetSyntaxMode ( rViewData.IsSyntaxMode() );
418 SetHeaderMode ( rViewData.IsHeaderMode() );
419 SetTabMode ( rViewData.IsTabMode() );
420 SetVScrollMode ( rViewData.IsVScrollMode() );
421 SetHScrollMode ( rViewData.IsHScrollMode() );
422 SetOutlineMode ( rViewData.IsOutlineMode() );
424 aScrSize = rViewData.aScrSize;
426 pThisTab = maTabData[nTabNo];
427 for (sal_uInt16 j=0; j<4; j++)
429 pEditView[j] = NULL;
430 bEditActive[j] = false;
433 nEditEndCol = nEditStartCol = nEditCol = 0;
434 nEditEndRow = nEditRow = 0;
435 nTabStartCol = SC_TABSTART_NONE;
436 CalcPPT();
439 void ScViewData::InitData( ScDocument* pDocument )
441 pDoc = pDocument;
442 *pOptions = pDoc->GetViewOptions();
446 ScDocument* ScViewData::GetDocument() const
448 if (pDoc)
449 return pDoc;
450 else if (pDocShell)
451 return pDocShell->GetDocument();
453 OSL_FAIL("kein Document an ViewData");
454 return NULL;
457 ScViewData::~ScViewData()
459 KillEditView();
460 delete pOptions;
461 ::std::for_each(
462 maTabData.begin(), maTabData.end(), boost::checked_deleter<ScViewDataTable>());
465 void ScViewData::UpdateCurrentTab()
467 pThisTab = maTabData[nTabNo];
468 while (!pThisTab)
470 if (nTabNo > 0)
471 pThisTab = maTabData[--nTabNo];
472 else
473 pThisTab = maTabData[0] = new ScViewDataTable;
477 void ScViewData::InsertTab( SCTAB nTab )
479 if( nTab >= static_cast<SCTAB>(maTabData.size()))
480 maTabData.resize(nTab+1, NULL);
481 else
482 maTabData.insert( maTabData.begin() + nTab, (ScViewDataTable *)NULL );
483 CreateTabData( nTab );
485 UpdateCurrentTab();
486 mpMarkData->InsertTab( nTab );
489 void ScViewData::InsertTabs( SCTAB nTab, SCTAB nNewSheets )
491 if( nTab+nNewSheets >= static_cast<SCTAB>(maTabData.size()))
492 maTabData.resize(nTab+nNewSheets, NULL);
493 else
495 maTabData.insert( maTabData.begin() + nTab, nNewSheets, NULL );
497 for (SCTAB i = nTab; i < nTab + nNewSheets; ++i)
499 CreateTabData( i );
500 mpMarkData->InsertTab( i );
502 UpdateCurrentTab();
505 void ScViewData::DeleteTab( SCTAB nTab )
507 delete maTabData.at(nTab);
509 maTabData.erase(maTabData.begin() + nTab);
510 UpdateCurrentTab();
511 mpMarkData->DeleteTab( nTab );
514 void ScViewData::DeleteTabs( SCTAB nTab, SCTAB nSheets )
516 for (SCTAB i = 0; i < nSheets; ++i)
518 mpMarkData->DeleteTab( nTab + i );
519 delete maTabData.at(nTab + i);
522 maTabData.erase(maTabData.begin() + nTab, maTabData.begin()+ nTab+nSheets);
523 UpdateCurrentTab();
526 void ScViewData::CopyTab( SCTAB nSrcTab, SCTAB nDestTab )
528 if (nDestTab==SC_TAB_APPEND)
529 nDestTab = pDoc->GetTableCount() - 1; // something had to have been copied
531 if (nDestTab > MAXTAB)
533 OSL_FAIL("Zuviele Tabellen");
534 return;
537 if (nSrcTab >= static_cast<SCTAB>(maTabData.size()))
538 OSL_FAIL("pTabData out of bounds, FIX IT");
540 EnsureTabDataSize(nDestTab + 1);
542 if ( maTabData[nSrcTab] )
543 maTabData.insert(maTabData.begin() + nDestTab, new ScViewDataTable( *maTabData[nSrcTab] ));
544 else
545 maTabData.insert(maTabData.begin() + nDestTab, (ScViewDataTable *)NULL);
547 UpdateCurrentTab();
548 mpMarkData->InsertTab( nDestTab );
551 void ScViewData::MoveTab( SCTAB nSrcTab, SCTAB nDestTab )
553 if (nDestTab==SC_TAB_APPEND)
554 nDestTab = pDoc->GetTableCount() - 1;
555 ScViewDataTable* pTab = NULL;
556 if (nSrcTab < static_cast<SCTAB>(maTabData.size()))
558 pTab = maTabData[nSrcTab];
559 maTabData.erase( maTabData.begin() + nSrcTab );
562 if (nDestTab < static_cast<SCTAB>(maTabData.size()))
563 maTabData.insert( maTabData.begin() + nDestTab, pTab );
564 else
566 EnsureTabDataSize(nDestTab + 1);
567 maTabData[nDestTab] = pTab;
570 UpdateCurrentTab();
571 mpMarkData->DeleteTab( nSrcTab );
572 mpMarkData->InsertTab( nDestTab ); // adapted if needed
575 void ScViewData::CreateTabData( std::vector< SCTAB >& rvTabs )
577 std::vector< SCTAB >::iterator it_end = rvTabs.end();
578 for ( std::vector< SCTAB >::iterator it = rvTabs.begin(); it != it_end; ++it )
579 CreateTabData(*it);
582 void ScViewData::SetZoomType( SvxZoomType eNew, std::vector< SCTAB >& tabs )
584 bool bAll = ( tabs.empty() );
586 if ( !bAll ) // create associated table data
587 CreateTabData( tabs );
589 if ( bAll )
591 for ( SCTAB i = 0; i < static_cast<SCTAB>(maTabData.size()); ++i )
593 if ( maTabData[i] )
594 maTabData[i]->eZoomType = eNew;
596 eDefZoomType = eNew;
598 else
600 std::vector< SCTAB >::iterator it_end = tabs.end();
601 std::vector< SCTAB >::iterator it = tabs.begin();
602 for ( ; it != it_end; ++it )
604 SCTAB i = *it;
605 if ( i < static_cast<SCTAB>(maTabData.size()) && maTabData[i] )
606 maTabData[i]->eZoomType = eNew;
611 void ScViewData::SetZoomType( SvxZoomType eNew, bool bAll )
613 std::vector< SCTAB > vTabs; // Empty for all tabs
614 if ( !bAll ) // get selected tabs
616 ScMarkData::iterator itr = mpMarkData->begin(), itrEnd = mpMarkData->end();
617 vTabs.insert(vTabs.begin(), itr, itrEnd);
619 SetZoomType( eNew, vTabs );
622 void ScViewData::SetZoom( const Fraction& rNewX, const Fraction& rNewY, std::vector< SCTAB >& tabs )
624 bool bAll = ( tabs.empty() );
625 if ( !bAll ) // create associated table data
626 CreateTabData( tabs );
627 Fraction aFrac20( 1,5 );
628 Fraction aFrac400( 4,1 );
630 Fraction aValidX = rNewX;
631 if (aValidX<aFrac20)
632 aValidX = aFrac20;
633 if (aValidX>aFrac400)
634 aValidX = aFrac400;
636 Fraction aValidY = rNewY;
637 if (aValidY<aFrac20)
638 aValidY = aFrac20;
639 if (aValidY>aFrac400)
640 aValidY = aFrac400;
642 if ( bAll )
644 for ( SCTAB i = 0; i < static_cast<SCTAB>(maTabData.size()); ++i )
646 if ( maTabData[i] )
648 if ( bPagebreak )
650 maTabData[i]->aPageZoomX = aValidX;
651 maTabData[i]->aPageZoomY = aValidY;
653 else
655 maTabData[i]->aZoomX = aValidX;
656 maTabData[i]->aZoomY = aValidY;
660 if ( bPagebreak )
662 aDefPageZoomX = aValidX;
663 aDefPageZoomY = aValidY;
665 else
667 aDefZoomX = aValidX;
668 aDefZoomY = aValidY;
671 else
673 std::vector< SCTAB >::iterator it_end = tabs.end();
674 std::vector< SCTAB >::iterator it = tabs.begin();
675 for ( ; it != it_end; ++it )
677 SCTAB i = *it;
678 if ( i < static_cast<SCTAB>(maTabData.size()) && maTabData[i] )
680 if ( bPagebreak )
682 maTabData[i]->aPageZoomX = aValidX;
683 maTabData[i]->aPageZoomY = aValidY;
685 else
687 maTabData[i]->aZoomX = aValidX;
688 maTabData[i]->aZoomY = aValidY;
693 RefreshZoom();
696 void ScViewData::SetZoom( const Fraction& rNewX, const Fraction& rNewY, bool bAll )
698 std::vector< SCTAB > vTabs;
699 if ( !bAll ) // get selected tabs
701 ScMarkData::iterator itr = mpMarkData->begin(), itrEnd = mpMarkData->end();
702 vTabs.insert(vTabs.begin(), itr, itrEnd);
704 SetZoom( rNewX, rNewY, vTabs );
707 void ScViewData::SetShowGrid( bool bShow )
709 CreateSelectedTabData();
710 maTabData[nTabNo]->bShowGrid = bShow;
713 void ScViewData::RefreshZoom()
715 // recalculate zoom-dependent values (only for current sheet)
717 CalcPPT();
718 RecalcPixPos();
719 aScenButSize = Size(0,0);
720 aLogicMode.SetScaleX( GetZoomX() );
721 aLogicMode.SetScaleY( GetZoomY() );
724 void ScViewData::SetPagebreakMode( bool bSet )
726 bPagebreak = bSet;
728 RefreshZoom();
732 ScMarkType ScViewData::GetSimpleArea( ScRange & rRange, ScMarkData & rNewMark ) const
734 ScMarkType eMarkType = SC_MARK_NONE;
736 if ( rNewMark.IsMarked() || rNewMark.IsMultiMarked() )
738 if ( rNewMark.IsMultiMarked() )
739 rNewMark.MarkToSimple();
741 if ( rNewMark.IsMarked() && !rNewMark.IsMultiMarked() )
743 rNewMark.GetMarkArea( rRange );
744 if (ScViewUtil::HasFiltered( rRange, GetDocument()))
745 eMarkType = SC_MARK_SIMPLE_FILTERED;
746 else
747 eMarkType = SC_MARK_SIMPLE;
749 else
750 eMarkType = SC_MARK_MULTI;
752 if (eMarkType != SC_MARK_SIMPLE && eMarkType != SC_MARK_SIMPLE_FILTERED)
754 if (eMarkType == SC_MARK_NONE)
755 eMarkType = SC_MARK_SIMPLE;
756 rRange = ScRange( GetCurX(), GetCurY(), GetTabNo() );
758 return eMarkType;
762 ScMarkType ScViewData::GetSimpleArea( SCCOL& rStartCol, SCROW& rStartRow, SCTAB& rStartTab,
763 SCCOL& rEndCol, SCROW& rEndRow, SCTAB& rEndTab ) const
765 // parameter bMergeMark is no longer needed: The view's selection is never modified
766 // (a local copy is used), and a multi selection that adds to a single range can always
767 // be treated like a single selection (GetSimpleArea isn't used in selection
768 // handling itself)
770 ScRange aRange;
771 ScMarkData aNewMark(*mpMarkData); // use a local copy for MarkToSimple
772 ScMarkType eMarkType = GetSimpleArea( aRange, aNewMark);
773 aRange.GetVars( rStartCol, rStartRow, rStartTab, rEndCol, rEndRow, rEndTab);
774 return eMarkType;
777 ScMarkType ScViewData::GetSimpleArea( ScRange& rRange ) const
779 // parameter bMergeMark is no longer needed, see above
781 ScMarkData aNewMark(*mpMarkData); // use a local copy for MarkToSimple
782 return GetSimpleArea( rRange, aNewMark);
785 void ScViewData::GetMultiArea( ScRangeListRef& rRange ) const
787 // parameter bMergeMark is no longer needed, see GetSimpleArea
789 ScMarkData aNewMark(*mpMarkData); // use a local copy for MarkToSimple
791 bool bMulti = aNewMark.IsMultiMarked();
792 if (bMulti)
794 aNewMark.MarkToSimple();
795 bMulti = aNewMark.IsMultiMarked();
797 if (bMulti)
799 rRange = new ScRangeList;
800 aNewMark.FillRangeListWithMarks( rRange, false );
802 else
804 ScRange aSimple;
805 GetSimpleArea(aSimple);
806 rRange = new ScRangeList;
807 rRange->Append(aSimple);
811 bool ScViewData::SimpleColMarked()
813 SCCOL nStartCol;
814 SCROW nStartRow;
815 SCTAB nStartTab;
816 SCCOL nEndCol;
817 SCROW nEndRow;
818 SCTAB nEndTab;
819 if (GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
820 if (nStartRow==0 && nEndRow==MAXROW)
821 return true;
823 return false;
826 bool ScViewData::SimpleRowMarked()
828 SCCOL nStartCol;
829 SCROW nStartRow;
830 SCTAB nStartTab;
831 SCCOL nEndCol;
832 SCROW nEndRow;
833 SCTAB nEndTab;
834 if (GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
835 if (nStartCol==0 && nEndCol==MAXCOL)
836 return true;
838 return false;
841 bool ScViewData::IsMultiMarked()
843 // Test for "real" multi selection, calling MarkToSimple on a local copy,
844 // and taking filtered in simple area marks into account.
846 ScRange aDummy;
847 ScMarkType eType = GetSimpleArea(aDummy);
848 return (eType & SC_MARK_SIMPLE) != SC_MARK_SIMPLE;
851 void ScViewData::SetFillMode( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
853 nFillMode = SC_FILL_FILL;
854 nFillStartX = nStartCol;
855 nFillStartY = nStartRow;
856 nFillEndX = nEndCol;
857 nFillEndY = nEndRow;
860 void ScViewData::SetDragMode( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
861 sal_uInt8 nMode )
863 nFillMode = nMode;
864 nFillStartX = nStartCol;
865 nFillStartY = nStartRow;
866 nFillEndX = nEndCol;
867 nFillEndY = nEndRow;
870 void ScViewData::ResetFillMode()
872 nFillMode = SC_FILL_NONE;
875 void ScViewData::GetFillData( SCCOL& rStartCol, SCROW& rStartRow,
876 SCCOL& rEndCol, SCROW& rEndRow )
878 rStartCol = nFillStartX;
879 rStartRow = nFillStartY;
880 rEndCol = nFillEndX;
881 rEndRow = nFillEndY;
884 SCCOL ScViewData::GetOldCurX() const
886 if (pThisTab->mbOldCursorValid)
887 return pThisTab->nOldCurX;
888 else
889 return pThisTab->nCurX;
892 SCROW ScViewData::GetOldCurY() const
894 if (pThisTab->mbOldCursorValid)
895 return pThisTab->nOldCurY;
896 else
897 return pThisTab->nCurY;
900 void ScViewData::SetOldCursor( SCCOL nNewX, SCROW nNewY )
902 pThisTab->nOldCurX = nNewX;
903 pThisTab->nOldCurY = nNewY;
904 pThisTab->mbOldCursorValid = true;
907 void ScViewData::ResetOldCursor()
909 pThisTab->mbOldCursorValid = false;
912 Rectangle ScViewData::GetEditArea( ScSplitPos eWhich, SCCOL nPosX, SCROW nPosY,
913 Window* pWin, const ScPatternAttr* pPattern,
914 bool bForceToTop )
916 return ScEditUtil( pDoc, nPosX, nPosY, nTabNo, GetScrPos(nPosX,nPosY,eWhich,true),
917 pWin, nPPTX, nPPTY, GetZoomX(), GetZoomY() ).
918 GetEditArea( pPattern, bForceToTop );
921 void ScViewData::SetEditEngine( ScSplitPos eWhich,
922 ScEditEngineDefaulter* pNewEngine,
923 Window* pWin, SCCOL nNewX, SCROW nNewY )
925 bool bLayoutRTL = pDoc->IsLayoutRTL( nTabNo );
926 ScHSplitPos eHWhich = WhichH(eWhich);
928 bool bWasThere = false;
929 if (pEditView[eWhich])
931 // if the view is already therem don't call anything that changes the cursor position
932 if (bEditActive[eWhich])
933 bWasThere = true;
934 else
935 pEditView[eWhich]->SetEditEngine(pNewEngine);
937 if (pEditView[eWhich]->GetWindow() != pWin)
939 pEditView[eWhich]->SetWindow(pWin);
940 OSL_FAIL("EditView Window geaendert");
943 else
945 pEditView[eWhich] = new EditView( pNewEngine, pWin );
948 // bei IdleFormat wird manchmal ein Cursor gemalt, wenn die View schon weg ist (23576)
950 sal_uLong nEC = pNewEngine->GetControlWord();
951 pNewEngine->SetControlWord(nEC & ~EE_CNTRL_DOIDLEFORMAT);
953 sal_uLong nVC = pEditView[eWhich]->GetControlWord();
954 pEditView[eWhich]->SetControlWord(nVC & ~EV_CNTRL_AUTOSCROLL);
956 bEditActive[eWhich] = true;
958 const ScPatternAttr* pPattern = pDoc->GetPattern( nNewX, nNewY, nTabNo );
959 SvxCellHorJustify eJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
960 pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue();
962 bool bBreak = ( eJust == SVX_HOR_JUSTIFY_BLOCK ) ||
963 ((SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue();
965 bool bAsianVertical = pNewEngine->IsVertical(); // set by InputHandler
967 Rectangle aPixRect = ScEditUtil( pDoc, nNewX,nNewY,nTabNo, GetScrPos(nNewX,nNewY,eWhich),
968 pWin, nPPTX,nPPTY,GetZoomX(),GetZoomY() ).
969 GetEditArea( pPattern, true );
971 // when right-aligned, leave space for the cursor
972 // in vertical mode, editing is always right-aligned
973 if ( nEditAdjust == SVX_ADJUST_RIGHT || bAsianVertical )
974 aPixRect.Right() += 1;
976 Rectangle aOutputArea = pWin->PixelToLogic( aPixRect, GetLogicMode() );
977 pEditView[eWhich]->SetOutputArea( aOutputArea );
979 if ( bActive && eWhich == GetActivePart() )
981 // keep the part that has the active edit view available after
982 // switching sheets or reference input on a different part
983 eEditActivePart = eWhich;
985 // modify members nEditCol etc. only if also extending for needed area
986 nEditCol = nNewX;
987 nEditRow = nNewY;
988 const ScMergeAttr* pMergeAttr = (ScMergeAttr*)&pPattern->GetItem(ATTR_MERGE);
989 nEditEndCol = nEditCol;
990 if (pMergeAttr->GetColMerge() > 1)
991 nEditEndCol += pMergeAttr->GetColMerge() - 1;
992 nEditEndRow = nEditRow;
993 if (pMergeAttr->GetRowMerge() > 1)
994 nEditEndRow += pMergeAttr->GetRowMerge() - 1;
995 nEditStartCol = nEditCol;
997 // For growing use only the alignment value from the attribute, numbers
998 // (existing or started) with default aligment extend to the right.
999 bool bGrowCentered = ( eJust == SVX_HOR_JUSTIFY_CENTER );
1000 bool bGrowToLeft = ( eJust == SVX_HOR_JUSTIFY_RIGHT ); // visual left
1001 bool bGrowBackwards = bGrowToLeft; // logical left
1002 if ( bLayoutRTL )
1003 bGrowBackwards = !bGrowBackwards; // invert on RTL sheet
1004 if ( bAsianVertical )
1005 bGrowCentered = bGrowToLeft = bGrowBackwards = false; // keep old behavior for asian mode
1007 long nSizeXPix;
1008 if (bBreak && !bAsianVertical)
1009 nSizeXPix = aPixRect.GetWidth(); // Papersize -> kein H-Scrolling
1010 else
1012 OSL_ENSURE(pView,"keine View fuer EditView");
1014 if ( bGrowCentered )
1016 // growing into both directions until one edge is reached
1017 //! should be limited to whole cells in both directions
1018 long nLeft = aPixRect.Left();
1019 long nRight = pView->GetGridWidth(eHWhich) - aPixRect.Right();
1020 nSizeXPix = aPixRect.GetWidth() + 2 * std::min( nLeft, nRight );
1022 else if ( bGrowToLeft )
1023 nSizeXPix = aPixRect.Right(); // space that's available in the window when growing to the left
1024 else
1025 nSizeXPix = pView->GetGridWidth(eHWhich) - aPixRect.Left();
1027 if ( nSizeXPix <= 0 )
1028 nSizeXPix = aPixRect.GetWidth(); // editing outside to the right of the window -> keep cell width
1030 OSL_ENSURE(pView,"keine View fuer EditView");
1031 long nSizeYPix = pView->GetGridHeight(WhichV(eWhich)) - aPixRect.Top();
1032 if ( nSizeYPix <= 0 )
1033 nSizeYPix = aPixRect.GetHeight(); // editing outside below the window -> keep cell height
1035 Size aPaperSize = pView->GetActiveWin()->PixelToLogic( Size( nSizeXPix, nSizeYPix ), GetLogicMode() );
1036 if ( bBreak && !bAsianVertical && SC_MOD()->GetInputOptions().GetTextWysiwyg() )
1038 // if text is formatted for printer, use the exact same paper width
1039 // (and same line breaks) as for output.
1041 Fraction aFract(1,1);
1042 Rectangle aUtilRect = ScEditUtil( pDoc,nNewX,nNewY,nTabNo, Point(0,0), pWin,
1043 HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( pPattern, false );
1044 aPaperSize.Width() = aUtilRect.GetWidth();
1046 pNewEngine->SetPaperSize( aPaperSize );
1048 // sichtbarer Ausschnitt
1049 Size aPaper = pNewEngine->GetPaperSize();
1050 Rectangle aVis = pEditView[eWhich]->GetVisArea();
1051 long nDiff = aVis.Right() - aVis.Left();
1052 if ( nEditAdjust == SVX_ADJUST_RIGHT )
1054 aVis.Right() = aPaper.Width() - 1;
1055 bMoveArea = !bLayoutRTL;
1057 else if ( nEditAdjust == SVX_ADJUST_CENTER )
1059 aVis.Right() = ( aPaper.Width() - 1 + nDiff ) / 2;
1060 bMoveArea = true; // always
1062 else
1064 aVis.Right() = nDiff;
1065 bMoveArea = bLayoutRTL;
1067 aVis.Left() = aVis.Right() - nDiff;
1068 // #i49561# Important note:
1069 // The set offset of the visible area of the EditView for centered and
1070 // right alignment in horizontal layout is consider by instances of
1071 // class <ScEditObjectViewForwarder> in its methods <LogicToPixel(..)>
1072 // and <PixelToLogic(..)>. This is needed for the correct visibility
1073 // of paragraphs in edit mode at the accessibility API.
1074 pEditView[eWhich]->SetVisArea(aVis);
1075 // UpdateMode has been disabled in ScInputHandler::StartTable
1076 // must be enabled before EditGrowY (GetTextHeight)
1077 pNewEngine->SetUpdateMode( true );
1079 pNewEngine->SetStatusEventHdl( LINK( this, ScViewData, EditEngineHdl ) );
1081 EditGrowY( true ); // adjust to existing text content
1082 EditGrowX();
1084 Point aDocPos = pEditView[eWhich]->GetWindowPosTopLeft(0);
1085 if (aDocPos.Y() < aOutputArea.Top())
1086 pEditView[eWhich]->Scroll( 0, aOutputArea.Top() - aDocPos.Y() );
1089 // here bEditActive needs to be set already
1090 // (due to Map-Mode during Paint)
1091 if (!bWasThere)
1092 pNewEngine->InsertView(pEditView[eWhich]);
1094 // background color of the cell
1095 Color aBackCol = ((const SvxBrushItem&)pPattern->GetItem(ATTR_BACKGROUND)).GetColor();
1097 ScModule* pScMod = SC_MOD();
1098 if ( aBackCol.GetTransparency() > 0 )
1100 aBackCol.SetColor( pScMod->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor );
1102 pEditView[eWhich]->SetBackgroundColor( aBackCol );
1104 pEditView[eWhich]->Invalidate(); // needed?
1105 // needed, wenn position changed
1108 IMPL_LINK_NOARG_INLINE_START(ScViewData, EmptyEditHdl)
1110 return 0;
1112 IMPL_LINK_NOARG_INLINE_END(ScViewData, EmptyEditHdl)
1114 IMPL_LINK( ScViewData, EditEngineHdl, EditStatus *, pStatus )
1116 sal_uLong nStatus = pStatus->GetStatusWord();
1117 if (nStatus & (EE_STAT_HSCROLL | EE_STAT_TEXTHEIGHTCHANGED | EE_STAT_TEXTWIDTHCHANGED | EE_STAT_CURSOROUT))
1119 EditGrowY();
1120 EditGrowX();
1122 if (nStatus & EE_STAT_CURSOROUT)
1124 ScSplitPos eWhich = GetActivePart();
1125 if (pEditView[eWhich])
1126 pEditView[eWhich]->ShowCursor(false);
1129 return 0;
1132 void ScViewData::EditGrowX()
1134 ScDocument* pLocalDoc = GetDocument();
1136 ScSplitPos eWhich = GetActivePart();
1137 ScHSplitPos eHWhich = WhichH(eWhich);
1138 EditView* pCurView = pEditView[eWhich];
1140 if ( !pCurView || !bEditActive[eWhich])
1141 return;
1143 bool bLayoutRTL = pLocalDoc->IsLayoutRTL( nTabNo );
1145 ScEditEngineDefaulter* pEngine =
1146 (ScEditEngineDefaulter*) pCurView->GetEditEngine();
1147 Window* pWin = pCurView->GetWindow();
1149 SCCOL nLeft = GetPosX(eHWhich);
1150 SCCOL nRight = nLeft + VisibleCellsX(eHWhich);
1152 Size aSize = pEngine->GetPaperSize();
1153 Rectangle aArea = pCurView->GetOutputArea();
1154 long nOldRight = aArea.Right();
1156 // Margin ist schon bei der urspruenglichen Breite beruecksichtigt
1157 long nTextWidth = pEngine->CalcTextWidth();
1159 bool bChanged = false;
1160 bool bAsianVertical = pEngine->IsVertical();
1162 // get bGrow... variables the same way as in SetEditEngine
1163 const ScPatternAttr* pPattern = pLocalDoc->GetPattern( nEditCol, nEditRow, nTabNo );
1164 SvxCellHorJustify eJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
1165 pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue();
1166 bool bGrowCentered = ( eJust == SVX_HOR_JUSTIFY_CENTER );
1167 bool bGrowToLeft = ( eJust == SVX_HOR_JUSTIFY_RIGHT ); // visual left
1168 bool bGrowBackwards = bGrowToLeft; // logical left
1169 if ( bLayoutRTL )
1170 bGrowBackwards = !bGrowBackwards; // invert on RTL sheet
1171 if ( bAsianVertical )
1172 bGrowCentered = bGrowToLeft = bGrowBackwards = false; // keep old behavior for asian mode
1174 bool bUnevenGrow = false;
1175 if ( bGrowCentered )
1177 while (aArea.GetWidth() + 0 < nTextWidth && ( nEditStartCol > nLeft || nEditEndCol < nRight ) )
1179 long nLogicLeft = 0;
1180 if ( nEditStartCol > nLeft )
1182 --nEditStartCol;
1183 long nLeftPix = ToPixel( pLocalDoc->GetColWidth( nEditStartCol, nTabNo ), nPPTX );
1184 nLogicLeft = pWin->PixelToLogic(Size(nLeftPix,0)).Width();
1186 long nLogicRight = 0;
1187 if ( nEditEndCol < nRight )
1189 ++nEditEndCol;
1190 long nRightPix = ToPixel( pLocalDoc->GetColWidth( nEditEndCol, nTabNo ), nPPTX );
1191 nLogicRight = pWin->PixelToLogic(Size(nRightPix,0)).Width();
1194 aArea.Left() -= bLayoutRTL ? nLogicRight : nLogicLeft;
1195 aArea.Right() += bLayoutRTL ? nLogicLeft : nLogicRight;
1197 if ( aArea.Right() > aArea.Left() + aSize.Width() - 1 )
1199 long nCenter = ( aArea.Left() + aArea.Right() ) / 2;
1200 long nHalf = aSize.Width() / 2;
1201 aArea.Left() = nCenter - nHalf + 1;
1202 aArea.Right() = nCenter + aSize.Width() - nHalf - 1;
1205 bChanged = true;
1206 if ( nLogicLeft != nLogicRight )
1207 bUnevenGrow = true;
1210 else if ( bGrowBackwards )
1212 while (aArea.GetWidth() + 0 < nTextWidth && nEditStartCol > nLeft)
1214 --nEditStartCol;
1215 long nPix = ToPixel( pLocalDoc->GetColWidth( nEditStartCol, nTabNo ), nPPTX );
1216 long nLogicWidth = pWin->PixelToLogic(Size(nPix,0)).Width();
1217 if ( !bLayoutRTL )
1218 aArea.Left() -= nLogicWidth;
1219 else
1220 aArea.Right() += nLogicWidth;
1222 if ( aArea.Right() > aArea.Left() + aSize.Width() - 1 )
1224 if ( !bLayoutRTL )
1225 aArea.Left() = aArea.Right() - aSize.Width() + 1;
1226 else
1227 aArea.Right() = aArea.Left() + aSize.Width() - 1;
1230 bChanged = true;
1233 else
1235 while (aArea.GetWidth() + 0 < nTextWidth && nEditEndCol < nRight)
1237 ++nEditEndCol;
1238 long nPix = ToPixel( pLocalDoc->GetColWidth( nEditEndCol, nTabNo ), nPPTX );
1239 long nLogicWidth = pWin->PixelToLogic(Size(nPix,0)).Width();
1240 if ( bLayoutRTL )
1241 aArea.Left() -= nLogicWidth;
1242 else
1243 aArea.Right() += nLogicWidth;
1245 if ( aArea.Right() > aArea.Left() + aSize.Width() - 1 )
1247 if ( bLayoutRTL )
1248 aArea.Left() = aArea.Right() - aSize.Width() + 1;
1249 else
1250 aArea.Right() = aArea.Left() + aSize.Width() - 1;
1253 bChanged = true;
1257 if (bChanged)
1259 if ( bMoveArea || bGrowCentered || bGrowBackwards || bLayoutRTL )
1261 Rectangle aVis = pCurView->GetVisArea();
1263 if ( bGrowCentered )
1265 // switch to center-aligned (undo?) and reset VisArea to center
1267 pEngine->SetDefaultItem( SvxAdjustItem( SVX_ADJUST_CENTER, EE_PARA_JUST ) );
1269 long nCenter = aSize.Width() / 2;
1270 long nVisSize = aArea.GetWidth();
1271 aVis.Left() = nCenter - nVisSize / 2;
1272 aVis.Right() = aVis.Left() + nVisSize - 1;
1274 else if ( bGrowToLeft )
1276 // switch to right-aligned (undo?) and reset VisArea to the right
1278 pEngine->SetDefaultItem( SvxAdjustItem( SVX_ADJUST_RIGHT, EE_PARA_JUST ) );
1280 aVis.Right() = aSize.Width() - 1;
1281 aVis.Left() = aSize.Width() - aArea.GetWidth(); // with the new, increased area
1283 else
1285 // switch to left-aligned (undo?) and reset VisArea to the left
1287 pEngine->SetDefaultItem( SvxAdjustItem( SVX_ADJUST_LEFT, EE_PARA_JUST ) );
1289 long nMove = aVis.Left();
1290 aVis.Left() = 0;
1291 aVis.Right() -= nMove;
1293 pCurView->SetVisArea( aVis );
1294 bMoveArea = false;
1297 pCurView->SetOutputArea(aArea);
1299 // In vertical mode, the whole text is moved to the next cell (right-aligned),
1300 // so everything must be repainted. Otherwise, paint only the new area.
1301 // If growing in centered alignment, if the cells left and right have different sizes,
1302 // the whole text will move, and may not even obscure all of the original display.
1303 if ( bUnevenGrow )
1305 aArea.Left() = pWin->PixelToLogic( Point(0,0) ).X();
1306 aArea.Right() = pWin->PixelToLogic( aScrSize ).Width();
1308 else if ( !bAsianVertical && !bGrowToLeft && !bGrowCentered )
1309 aArea.Left() = nOldRight;
1310 pWin->Invalidate(aArea);
1314 void ScViewData::EditGrowY( bool bInitial )
1316 ScSplitPos eWhich = GetActivePart();
1317 ScVSplitPos eVWhich = WhichV(eWhich);
1318 EditView* pCurView = pEditView[eWhich];
1320 if ( !pCurView || !bEditActive[eWhich])
1321 return;
1323 sal_uLong nControl = pEditView[eWhich]->GetControlWord();
1324 if ( nControl & EV_CNTRL_AUTOSCROLL )
1326 // if end of screen had already been reached and scrolling enabled,
1327 // don't further try to grow the edit area
1329 pCurView->SetOutputArea( pCurView->GetOutputArea() ); // re-align to pixels
1330 return;
1333 EditEngine* pEngine = pCurView->GetEditEngine();
1334 Window* pWin = pCurView->GetWindow();
1336 SCROW nBottom = GetPosY(eVWhich) + VisibleCellsY(eVWhich);
1338 Size aSize = pEngine->GetPaperSize();
1339 Rectangle aArea = pCurView->GetOutputArea();
1340 long nOldBottom = aArea.Bottom();
1341 long nTextHeight = pEngine->GetTextHeight();
1343 // When editing a formula in a cell with optimal height, allow a larger portion
1344 // to be clipped before extending to following rows, to avoid obscuring cells for
1345 // reference input (next row is likely to be useful in formulas).
1346 long nAllowedExtra = SC_GROWY_SMALL_EXTRA;
1347 if ( nEditEndRow == nEditRow && !( pDoc->GetRowFlags( nEditRow, nTabNo ) & CR_MANUALSIZE ) &&
1348 pEngine->GetParagraphCount() <= 1 )
1350 // If the (only) paragraph starts with a '=', it's a formula.
1351 // If this is the initial call and the text is empty, allow the larger value, too,
1352 // because this occurs in the normal progress of editing a formula.
1353 // Subsequent calls with empty text might involve changed attributes (including
1354 // font height), so they are treated like normal text.
1355 OUString aText = pEngine->GetText( 0 );
1356 if ( ( aText.isEmpty() && bInitial ) || aText.startsWith("=") )
1357 nAllowedExtra = SC_GROWY_BIG_EXTRA;
1360 bool bChanged = false;
1361 bool bMaxReached = false;
1362 while (aArea.GetHeight() + nAllowedExtra < nTextHeight && nEditEndRow < nBottom && !bMaxReached)
1364 ++nEditEndRow;
1365 ScDocument* pLocalDoc = GetDocument();
1366 long nPix = ToPixel( pLocalDoc->GetRowHeight( nEditEndRow, nTabNo ), nPPTY );
1367 aArea.Bottom() += pWin->PixelToLogic(Size(0,nPix)).Height();
1369 if ( aArea.Bottom() > aArea.Top() + aSize.Height() - 1 )
1371 aArea.Bottom() = aArea.Top() + aSize.Height() - 1;
1372 bMaxReached = true; // don't occupy more cells beyond paper size
1375 bChanged = true;
1376 nAllowedExtra = SC_GROWY_SMALL_EXTRA; // larger value is only for first row
1379 if (bChanged)
1381 pCurView->SetOutputArea(aArea);
1383 if (nEditEndRow >= nBottom || bMaxReached)
1385 if ((nControl & EV_CNTRL_AUTOSCROLL) == 0)
1386 pCurView->SetControlWord( nControl | EV_CNTRL_AUTOSCROLL );
1389 aArea.Top() = nOldBottom;
1390 pWin->Invalidate(aArea);
1394 void ScViewData::ResetEditView()
1396 EditEngine* pEngine = NULL;
1397 for (sal_uInt16 i=0; i<4; i++)
1398 if (pEditView[i])
1400 if (bEditActive[i])
1402 pEngine = pEditView[i]->GetEditEngine();
1403 pEngine->RemoveView(pEditView[i]);
1404 pEditView[i]->SetOutputArea( Rectangle() );
1406 bEditActive[i] = false;
1409 if (pEngine)
1410 pEngine->SetStatusEventHdl( LINK( this, ScViewData, EmptyEditHdl ) );
1413 void ScViewData::KillEditView()
1415 for (sal_uInt16 i=0; i<4; i++)
1416 if (pEditView[i])
1418 if (bEditActive[i])
1419 pEditView[i]->GetEditEngine()->RemoveView(pEditView[i]);
1420 delete pEditView[i];
1421 pEditView[i] = NULL;
1425 void ScViewData::GetEditView( ScSplitPos eWhich, EditView*& rViewPtr, SCCOL& rCol, SCROW& rRow )
1427 rViewPtr = pEditView[eWhich];
1428 rCol = nEditCol;
1429 rRow = nEditRow;
1432 void ScViewData::CreateTabData( SCTAB nNewTab )
1434 EnsureTabDataSize(nNewTab + 1);
1436 if (!maTabData[nNewTab])
1438 maTabData[nNewTab] = new ScViewDataTable;
1440 maTabData[nNewTab]->eZoomType = eDefZoomType;
1441 maTabData[nNewTab]->aZoomX = aDefZoomX;
1442 maTabData[nNewTab]->aZoomY = aDefZoomY;
1443 maTabData[nNewTab]->aPageZoomX = aDefPageZoomX;
1444 maTabData[nNewTab]->aPageZoomY = aDefPageZoomY;
1448 void ScViewData::CreateSelectedTabData()
1450 ScMarkData::iterator itr = mpMarkData->begin(), itrEnd = mpMarkData->end();
1451 for (; itr != itrEnd; ++itr)
1452 CreateTabData(*itr);
1455 void ScViewData::EnsureTabDataSize(size_t nSize)
1457 if (nSize >= maTabData.size())
1459 size_t n = nSize - maTabData.size() + 1;
1460 maTabData.insert(maTabData.end(), n, NULL);
1464 void ScViewData::SetTabNo( SCTAB nNewTab )
1466 if (!ValidTab(nNewTab))
1468 OSL_FAIL("falsche Tabellennummer");
1469 return;
1472 nTabNo = nNewTab;
1473 CreateTabData(nTabNo);
1474 pThisTab = maTabData[nTabNo];
1476 CalcPPT(); // for common column width correction
1477 RecalcPixPos(); //! nicht immer noetig!
1480 void ScViewData::SetActivePart( ScSplitPos eNewActive )
1482 pThisTab->eWhichActive = eNewActive;
1485 Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScHSplitPos eWhich ) const
1487 OSL_ENSURE( eWhich==SC_SPLIT_LEFT || eWhich==SC_SPLIT_RIGHT, "Falsche Position" );
1488 ScSplitPos ePos = ( eWhich == SC_SPLIT_LEFT ) ? SC_SPLIT_BOTTOMLEFT : SC_SPLIT_BOTTOMRIGHT;
1489 return GetScrPos( nWhereX, nWhereY, ePos );
1492 Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScVSplitPos eWhich ) const
1494 OSL_ENSURE( eWhich==SC_SPLIT_TOP || eWhich==SC_SPLIT_BOTTOM, "Falsche Position" );
1495 ScSplitPos ePos = ( eWhich == SC_SPLIT_TOP ) ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
1496 return GetScrPos( nWhereX, nWhereY, ePos );
1499 Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich,
1500 bool bAllowNeg ) const
1502 ScHSplitPos eWhichX = SC_SPLIT_LEFT;
1503 ScVSplitPos eWhichY = SC_SPLIT_BOTTOM;
1504 switch( eWhich )
1506 case SC_SPLIT_TOPLEFT:
1507 eWhichX = SC_SPLIT_LEFT;
1508 eWhichY = SC_SPLIT_TOP;
1509 break;
1510 case SC_SPLIT_TOPRIGHT:
1511 eWhichX = SC_SPLIT_RIGHT;
1512 eWhichY = SC_SPLIT_TOP;
1513 break;
1514 case SC_SPLIT_BOTTOMLEFT:
1515 eWhichX = SC_SPLIT_LEFT;
1516 eWhichY = SC_SPLIT_BOTTOM;
1517 break;
1518 case SC_SPLIT_BOTTOMRIGHT:
1519 eWhichX = SC_SPLIT_RIGHT;
1520 eWhichY = SC_SPLIT_BOTTOM;
1521 break;
1524 if (pView)
1526 ((ScViewData*)this)->aScrSize.Width() = pView->GetGridWidth(eWhichX);
1527 ((ScViewData*)this)->aScrSize.Height() = pView->GetGridHeight(eWhichY);
1530 sal_uInt16 nTSize;
1532 SCCOL nPosX = GetPosX(eWhichX);
1533 SCCOL nX;
1535 long nScrPosX=0;
1536 if (nWhereX >= nPosX)
1537 for (nX=nPosX; nX<nWhereX && (bAllowNeg || nScrPosX<=aScrSize.Width()); nX++)
1539 if ( nX > MAXCOL )
1540 nScrPosX = 65535;
1541 else
1543 nTSize = pDoc->GetColWidth( nX, nTabNo );
1544 if (nTSize)
1546 long nSizeXPix = ToPixel( nTSize, nPPTX );
1547 nScrPosX += nSizeXPix;
1551 else if (bAllowNeg)
1552 for (nX=nPosX; nX>nWhereX;)
1554 --nX;
1555 nTSize = pDoc->GetColWidth( nX, nTabNo );
1556 if (nTSize)
1558 long nSizeXPix = ToPixel( nTSize, nPPTX );
1559 nScrPosX -= nSizeXPix;
1563 SCROW nPosY = GetPosY(eWhichY);
1564 SCROW nY;
1566 long nScrPosY=0;
1567 if (nWhereY >= nPosY)
1568 for (nY=nPosY; nY<nWhereY && (bAllowNeg || nScrPosY<=aScrSize.Height()); nY++)
1570 if ( nY > MAXROW )
1571 nScrPosY = 65535;
1572 else
1574 nTSize = pDoc->GetRowHeight( nY, nTabNo );
1575 if (nTSize)
1577 long nSizeYPix = ToPixel( nTSize, nPPTY );
1578 nScrPosY += nSizeYPix;
1580 else if ( nY < MAXROW )
1582 // skip multiple hidden rows (forward only for now)
1583 SCROW nNext = pDoc->FirstVisibleRow(nY + 1, MAXROW, nTabNo);
1584 if ( nNext > MAXROW )
1585 nY = MAXROW;
1586 else
1587 nY = nNext - 1; // +=nDir advances to next visible row
1591 else if (bAllowNeg)
1592 for (nY=nPosY; nY>nWhereY;)
1594 --nY;
1595 nTSize = pDoc->GetRowHeight( nY, nTabNo );
1596 if (nTSize)
1598 long nSizeYPix = ToPixel( nTSize, nPPTY );
1599 nScrPosY -= nSizeYPix;
1603 if ( pDoc->IsLayoutRTL( nTabNo ) )
1605 // mirror horizontal position
1606 nScrPosX = aScrSize.Width() - 1 - nScrPosX;
1609 if (nScrPosX > 32767) nScrPosX=32767;
1610 if (nScrPosY > 32767) nScrPosY=32767;
1611 return Point( nScrPosX, nScrPosY );
1615 // Number of cells on a screen
1618 SCCOL ScViewData::CellsAtX( SCsCOL nPosX, SCsCOL nDir, ScHSplitPos eWhichX, sal_uInt16 nScrSizeX ) const
1620 OSL_ENSURE( nDir==1 || nDir==-1, "falscher CellsAt Aufruf" );
1622 if (pView)
1623 ((ScViewData*)this)->aScrSize.Width() = pView->GetGridWidth(eWhichX);
1625 SCsCOL nX;
1626 sal_uInt16 nScrPosX = 0;
1627 if (nScrSizeX == SC_SIZE_NONE) nScrSizeX = (sal_uInt16) aScrSize.Width();
1629 if (nDir==1)
1630 nX = nPosX; // vorwaerts
1631 else
1632 nX = nPosX-1; // rueckwaerts
1634 bool bOut = false;
1635 for ( ; nScrPosX<=nScrSizeX && !bOut; nX = sal::static_int_cast<SCsCOL>(nX + nDir) )
1637 SCsCOL nColNo = nX;
1638 if ( nColNo < 0 || nColNo > MAXCOL )
1639 bOut = true;
1640 else
1642 sal_uInt16 nTSize = pDoc->GetColWidth( nColNo, nTabNo );
1643 if (nTSize)
1645 long nSizeXPix = ToPixel( nTSize, nPPTX );
1646 nScrPosX = sal::static_int_cast<sal_uInt16>( nScrPosX + (sal_uInt16) nSizeXPix );
1651 if (nDir==1)
1652 nX = sal::static_int_cast<SCsCOL>( nX - nPosX );
1653 else
1654 nX = (nPosX-1)-nX;
1656 if (nX>0) --nX;
1657 return nX;
1660 SCROW ScViewData::CellsAtY( SCsROW nPosY, SCsROW nDir, ScVSplitPos eWhichY, sal_uInt16 nScrSizeY ) const
1662 OSL_ENSURE( nDir==1 || nDir==-1, "falscher CellsAt Aufruf" );
1664 if (pView)
1665 ((ScViewData*)this)->aScrSize.Height() = pView->GetGridHeight(eWhichY);
1667 if (nScrSizeY == SC_SIZE_NONE) nScrSizeY = (sal_uInt16) aScrSize.Height();
1669 SCROW nY;
1671 if (nDir==1)
1673 // forward
1674 nY = nPosY;
1675 long nScrPosY = 0;
1676 AddPixelsWhile( nScrPosY, nScrSizeY, nY, MAXROW, nPPTY, pDoc, nTabNo);
1677 // Original loop ended on last evaluated +1 or if that was MAXROW even
1678 // on MAXROW+2.
1679 nY += (nY == MAXROW ? 2 : 1);
1680 nY -= nPosY;
1682 else
1684 // backward
1685 nY = nPosY-1;
1686 long nScrPosY = 0;
1687 AddPixelsWhileBackward( nScrPosY, nScrSizeY, nY, 0, nPPTY, pDoc, nTabNo);
1688 // Original loop ended on last evaluated -1 or if that was 0 even on
1689 // -2.
1690 nY -= (nY == 0 ? 2 : 1);
1691 nY = (nPosY-1)-nY;
1694 if (nY>0) --nY;
1695 return nY;
1698 SCCOL ScViewData::VisibleCellsX( ScHSplitPos eWhichX ) const
1700 return CellsAtX( GetPosX( eWhichX ), 1, eWhichX, SC_SIZE_NONE );
1703 SCROW ScViewData::VisibleCellsY( ScVSplitPos eWhichY ) const
1705 return CellsAtY( GetPosY( eWhichY ), 1, eWhichY, SC_SIZE_NONE );
1708 SCCOL ScViewData::PrevCellsX( ScHSplitPos eWhichX ) const
1710 return CellsAtX( GetPosX( eWhichX ), -1, eWhichX, SC_SIZE_NONE );
1713 SCROW ScViewData::PrevCellsY( ScVSplitPos eWhichY ) const
1715 return CellsAtY( GetPosY( eWhichY ), -1, eWhichY, SC_SIZE_NONE );
1719 bool ScViewData::GetMergeSizePixel( SCCOL nX, SCROW nY, long& rSizeXPix, long& rSizeYPix ) const
1721 const ScMergeAttr* pMerge = (const ScMergeAttr*) pDoc->GetAttr( nX,nY,nTabNo, ATTR_MERGE );
1722 if ( pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1 )
1724 long nOutWidth = 0;
1725 long nOutHeight = 0;
1726 SCCOL nCountX = pMerge->GetColMerge();
1727 for (SCCOL i=0; i<nCountX; i++)
1728 nOutWidth += ToPixel( pDoc->GetColWidth(nX+i,nTabNo), nPPTX );
1729 SCROW nCountY = pMerge->GetRowMerge();
1731 for (SCROW nRow = nY; nRow <= nY+nCountY-1; ++nRow)
1733 SCROW nLastRow = nRow;
1734 if (pDoc->RowHidden(nRow, nTabNo, NULL, &nLastRow))
1736 nRow = nLastRow;
1737 continue;
1740 sal_uInt16 nHeight = pDoc->GetRowHeight(nRow, nTabNo);
1741 nOutHeight += ToPixel(nHeight, nPPTY);
1744 rSizeXPix = nOutWidth;
1745 rSizeYPix = nOutHeight;
1746 return true;
1748 else
1750 rSizeXPix = ToPixel( pDoc->GetColWidth( nX, nTabNo ), nPPTX );
1751 rSizeYPix = ToPixel( pDoc->GetRowHeight( nY, nTabNo ), nPPTY );
1752 return false;
1756 bool ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich,
1757 SCsCOL& rPosX, SCsROW& rPosY,
1758 bool bTestMerge, bool bRepair, bool bNextIfLarge )
1760 // special handling of 0 is now in ScViewFunctionSet::SetCursorAtPoint
1762 ScHSplitPos eHWhich = WhichH(eWhich);
1763 ScVSplitPos eVWhich = WhichV(eWhich);
1765 if ( pDoc->IsLayoutRTL( nTabNo ) )
1767 // mirror horizontal position
1768 if (pView)
1769 aScrSize.Width() = pView->GetGridWidth(eHWhich);
1770 nClickX = aScrSize.Width() - 1 - nClickX;
1773 SCsCOL nStartPosX = GetPosX(eHWhich);
1774 SCsROW nStartPosY = GetPosY(eVWhich);
1775 rPosX = nStartPosX;
1776 rPosY = nStartPosY;
1777 long nScrX = 0;
1778 long nScrY = 0;
1780 if (nClickX > 0)
1782 while ( rPosX<=MAXCOL && nClickX >= nScrX )
1784 nScrX += ToPixel( pDoc->GetColWidth( rPosX, nTabNo ), nPPTX );
1785 ++rPosX;
1787 --rPosX;
1789 else
1791 while ( rPosX>0 && nClickX < nScrX )
1793 --rPosX;
1794 nScrX -= ToPixel( pDoc->GetColWidth( rPosX, nTabNo ), nPPTX );
1798 if (nClickY > 0)
1799 AddPixelsWhile( nScrY, nClickY, rPosY, MAXROW, nPPTY, pDoc, nTabNo );
1800 else
1802 /* TODO: could need some "SubPixelsWhileBackward" method */
1803 while ( rPosY>0 && nClickY < nScrY )
1805 --rPosY;
1806 nScrY -= ToPixel( pDoc->GetRowHeight( rPosY, nTabNo ), nPPTY );
1810 if (bNextIfLarge) // cells to big?
1812 if ( rPosX == nStartPosX && nClickX > 0 )
1814 if (pView)
1815 aScrSize.Width() = pView->GetGridWidth(eHWhich);
1816 if ( nClickX > aScrSize.Width() )
1817 ++rPosX;
1819 if ( rPosY == nStartPosY && nClickY > 0 )
1821 if (pView)
1822 aScrSize.Height() = pView->GetGridHeight(eVWhich);
1823 if ( nClickY > aScrSize.Height() )
1824 ++rPosY;
1828 if (rPosX<0) rPosX=0;
1829 if (rPosX>MAXCOL) rPosX=MAXCOL;
1830 if (rPosY<0) rPosY=0;
1831 if (rPosY>MAXROW) rPosY=MAXROW;
1833 if (bTestMerge)
1835 // public method to adapt position
1836 SCCOL nOrigX = rPosX;
1837 SCROW nOrigY = rPosY;
1838 pDoc->SkipOverlapped(rPosX, rPosY, nTabNo);
1839 bool bHOver = (nOrigX != rPosX);
1840 bool bVOver = (nOrigY != rPosY);
1842 if ( bRepair && ( bHOver || bVOver ) )
1844 const ScMergeAttr* pMerge = (const ScMergeAttr*)
1845 pDoc->GetAttr( rPosX, rPosY, nTabNo, ATTR_MERGE );
1846 if ( ( bHOver && pMerge->GetColMerge() <= 1 ) ||
1847 ( bVOver && pMerge->GetRowMerge() <= 1 ) )
1849 OSL_FAIL("Merge-Fehler gefunden");
1851 pDoc->RemoveFlagsTab( 0,0, MAXCOL,MAXROW, nTabNo, SC_MF_HOR | SC_MF_VER );
1852 SCCOL nEndCol = MAXCOL;
1853 SCROW nEndRow = MAXROW;
1854 pDoc->ExtendMerge( 0,0, nEndCol,nEndRow, nTabNo, true );
1855 if (pDocShell)
1856 pDocShell->PostPaint( ScRange(0,0,nTabNo,MAXCOL,MAXROW,nTabNo), PAINT_GRID );
1861 return false;
1864 void ScViewData::GetMouseQuadrant( const Point& rClickPos, ScSplitPos eWhich,
1865 SCsCOL nPosX, SCsROW nPosY, bool& rLeft, bool& rTop )
1867 bool bLayoutRTL = pDoc->IsLayoutRTL( nTabNo );
1868 long nLayoutSign = bLayoutRTL ? -1 : 1;
1870 Point aCellStart = GetScrPos( nPosX, nPosY, eWhich, true );
1871 long nSizeX;
1872 long nSizeY;
1873 GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY );
1874 rLeft = ( rClickPos.X() - aCellStart.X() ) * nLayoutSign <= nSizeX / 2;
1875 rTop = rClickPos.Y() - aCellStart.Y() <= nSizeY / 2;
1878 void ScViewData::SetPosX( ScHSplitPos eWhich, SCCOL nNewPosX )
1880 if (nNewPosX != 0)
1882 SCCOL nOldPosX = pThisTab->nPosX[eWhich];
1883 long nTPosX = pThisTab->nTPosX[eWhich];
1884 long nPixPosX = pThisTab->nPixPosX[eWhich];
1885 SCCOL i;
1886 if ( nNewPosX > nOldPosX )
1887 for ( i=nOldPosX; i<nNewPosX; i++ )
1889 long nThis = pDoc->GetColWidth( i,nTabNo );
1890 nTPosX -= nThis;
1891 nPixPosX -= ToPixel(sal::static_int_cast<sal_uInt16>(nThis), nPPTX);
1893 else
1894 for ( i=nNewPosX; i<nOldPosX; i++ )
1896 long nThis = pDoc->GetColWidth( i,nTabNo );
1897 nTPosX += nThis;
1898 nPixPosX += ToPixel(sal::static_int_cast<sal_uInt16>(nThis), nPPTX);
1901 pThisTab->nPosX[eWhich] = nNewPosX;
1902 pThisTab->nTPosX[eWhich] = nTPosX;
1903 pThisTab->nMPosX[eWhich] = (long) (nTPosX * HMM_PER_TWIPS);
1904 pThisTab->nPixPosX[eWhich] = nPixPosX;
1906 else
1907 pThisTab->nPixPosX[eWhich] =
1908 pThisTab->nTPosX[eWhich] =
1909 pThisTab->nMPosX[eWhich] =
1910 pThisTab->nPosX[eWhich] = 0;
1913 void ScViewData::SetPosY( ScVSplitPos eWhich, SCROW nNewPosY )
1915 if (nNewPosY != 0)
1917 SCROW nOldPosY = pThisTab->nPosY[eWhich];
1918 long nTPosY = pThisTab->nTPosY[eWhich];
1919 long nPixPosY = pThisTab->nPixPosY[eWhich];
1920 SCROW i, nHeightEndRow;
1921 if ( nNewPosY > nOldPosY )
1922 for ( i=nOldPosY; i<nNewPosY; i++ )
1924 long nThis = pDoc->GetRowHeight( i, nTabNo, NULL, &nHeightEndRow );
1925 SCROW nRows = std::min( nNewPosY, nHeightEndRow + 1) - i;
1926 i = nHeightEndRow;
1927 nTPosY -= nThis * nRows;
1928 nPixPosY -= ToPixel(sal::static_int_cast<sal_uInt16>(nThis), nPPTY) * nRows;
1930 else
1931 for ( i=nNewPosY; i<nOldPosY; i++ )
1933 long nThis = pDoc->GetRowHeight( i, nTabNo, NULL, &nHeightEndRow );
1934 SCROW nRows = std::min( nOldPosY, nHeightEndRow + 1) - i;
1935 i = nHeightEndRow;
1936 nTPosY += nThis * nRows;
1937 nPixPosY += ToPixel(sal::static_int_cast<sal_uInt16>(nThis), nPPTY) * nRows;
1940 pThisTab->nPosY[eWhich] = nNewPosY;
1941 pThisTab->nTPosY[eWhich] = nTPosY;
1942 pThisTab->nMPosY[eWhich] = (long) (nTPosY * HMM_PER_TWIPS);
1943 pThisTab->nPixPosY[eWhich] = nPixPosY;
1945 else
1946 pThisTab->nPixPosY[eWhich] =
1947 pThisTab->nTPosY[eWhich] =
1948 pThisTab->nMPosY[eWhich] =
1949 pThisTab->nPosY[eWhich] = 0;
1952 void ScViewData::RecalcPixPos() // after zoom changes
1954 for (sal_uInt16 eWhich=0; eWhich<2; eWhich++)
1956 long nPixPosX = 0;
1957 SCCOL nPosX = pThisTab->nPosX[eWhich];
1958 for (SCCOL i=0; i<nPosX; i++)
1959 nPixPosX -= ToPixel(pDoc->GetColWidth(i,nTabNo), nPPTX);
1960 pThisTab->nPixPosX[eWhich] = nPixPosX;
1962 long nPixPosY = 0;
1963 SCROW nPosY = pThisTab->nPosY[eWhich];
1964 for (SCROW j=0; j<nPosY; j++)
1965 nPixPosY -= ToPixel(pDoc->GetRowHeight(j,nTabNo), nPPTY);
1966 pThisTab->nPixPosY[eWhich] = nPixPosY;
1970 const MapMode& ScViewData::GetLogicMode( ScSplitPos eWhich )
1972 aLogicMode.SetOrigin( Point( pThisTab->nMPosX[WhichH(eWhich)],
1973 pThisTab->nMPosY[WhichV(eWhich)] ) );
1974 return aLogicMode;
1977 const MapMode& ScViewData::GetLogicMode()
1979 aLogicMode.SetOrigin( Point() );
1980 return aLogicMode;
1983 void ScViewData::SetScreen( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
1985 SCCOL nCol;
1986 SCROW nRow;
1987 sal_uInt16 nTSize;
1988 long nSizePix;
1989 long nScrPosX = 0;
1990 long nScrPosY = 0;
1992 SetActivePart( SC_SPLIT_BOTTOMLEFT );
1993 SetPosX( SC_SPLIT_LEFT, nCol1 );
1994 SetPosY( SC_SPLIT_BOTTOM, nRow1 );
1996 for (nCol=nCol1; nCol<=nCol2; nCol++)
1998 nTSize = pDoc->GetColWidth( nCol, nTabNo );
1999 if (nTSize)
2001 nSizePix = ToPixel( nTSize, nPPTX );
2002 nScrPosX += (sal_uInt16) nSizePix;
2006 for (nRow=nRow1; nRow<=nRow2; nRow++)
2008 nTSize = pDoc->GetRowHeight( nRow, nTabNo );
2009 if (nTSize)
2011 nSizePix = ToPixel( nTSize, nPPTY );
2012 nScrPosY += (sal_uInt16) nSizePix;
2016 aScrSize = Size( nScrPosX, nScrPosY );
2019 void ScViewData::SetScreenPos( const Point& rVisAreaStart )
2021 long nSize;
2022 long nTwips;
2023 long nAdd;
2024 bool bEnd;
2026 nSize = 0;
2027 nTwips = (long) (rVisAreaStart.X() / HMM_PER_TWIPS);
2028 if ( pDoc->IsLayoutRTL( nTabNo ) )
2029 nTwips = -nTwips;
2030 SCCOL nX1 = 0;
2031 bEnd = false;
2032 while (!bEnd)
2034 nAdd = (long) pDoc->GetColWidth(nX1,nTabNo);
2035 if (nSize+nAdd <= nTwips+1 && nX1<MAXCOL)
2037 nSize += nAdd;
2038 ++nX1;
2040 else
2041 bEnd = true;
2044 nSize = 0;
2045 nTwips = (long) (rVisAreaStart.Y() / HMM_PER_TWIPS);
2046 SCROW nY1 = 0;
2047 bEnd = false;
2048 while (!bEnd)
2050 nAdd = (long) pDoc->GetRowHeight(nY1,nTabNo);
2051 if (nSize+nAdd <= nTwips+1 && nY1<MAXROW)
2053 nSize += nAdd;
2054 ++nY1;
2056 else
2057 bEnd = true;
2060 SetActivePart( SC_SPLIT_BOTTOMLEFT );
2061 SetPosX( SC_SPLIT_LEFT, nX1 );
2062 SetPosY( SC_SPLIT_BOTTOM, nY1 );
2064 SetCurX( nX1 );
2065 SetCurY( nY1 );
2068 void ScViewData::SetScreen( const Rectangle& rVisArea )
2070 SetScreenPos( rVisArea.TopLeft() );
2072 // here without GetOutputFactor(), since it's for the output into a Metafile
2074 aScrSize = rVisArea.GetSize();
2075 aScrSize.Width() = (long)
2076 ( aScrSize.Width() * ScGlobal::nScreenPPTX / HMM_PER_TWIPS );
2077 aScrSize.Height() = (long)
2078 ( aScrSize.Height() * ScGlobal::nScreenPPTY / HMM_PER_TWIPS );
2081 SfxObjectShell* ScViewData::GetSfxDocShell() const
2083 return pDocShell;
2086 ScDocFunc& ScViewData::GetDocFunc() const
2088 return pDocShell->GetDocFunc();
2091 SfxBindings& ScViewData::GetBindings()
2093 OSL_ENSURE( pViewShell, "GetBindings() without ViewShell" );
2094 return pViewShell->GetViewFrame()->GetBindings();
2097 SfxDispatcher& ScViewData::GetDispatcher()
2099 OSL_ENSURE( pViewShell, "GetDispatcher() without ViewShell" );
2100 return *pViewShell->GetViewFrame()->GetDispatcher();
2103 ScMarkData& ScViewData::GetMarkData()
2105 return *mpMarkData;
2108 const ScMarkData& ScViewData::GetMarkData() const
2110 return *mpMarkData;
2113 Window* ScViewData::GetDialogParent()
2115 OSL_ENSURE( pViewShell, "GetDialogParent() ohne ViewShell" );
2116 return pViewShell->GetDialogParent();
2119 ScGridWindow* ScViewData::GetActiveWin()
2121 OSL_ENSURE( pView, "GetActiveWin() ohne View" );
2122 return pView->GetActiveWin();
2125 ScDrawView* ScViewData::GetScDrawView()
2127 OSL_ENSURE( pView, "GetScDrawView() ohne View" );
2128 return pView->GetScDrawView();
2131 bool ScViewData::IsMinimized()
2133 OSL_ENSURE( pView, "IsMinimized() ohne View" );
2134 return pView->IsMinimized();
2137 void ScViewData::UpdateScreenZoom( const Fraction& rNewX, const Fraction& rNewY )
2139 Fraction aOldX = GetZoomX();
2140 Fraction aOldY = GetZoomY();
2142 SetZoom( rNewX, rNewY, false );
2144 Fraction aWidth = GetZoomX();
2145 aWidth *= Fraction( aScrSize.Width(),1 );
2146 aWidth /= aOldX;
2148 Fraction aHeight = GetZoomY();
2149 aHeight *= Fraction( aScrSize.Height(),1 );
2150 aHeight /= aOldY;
2152 aScrSize.Width() = (long) aWidth;
2153 aScrSize.Height() = (long) aHeight;
2156 void ScViewData::CalcPPT()
2158 nPPTX = ScGlobal::nScreenPPTX * (double) GetZoomX();
2159 if (pDocShell)
2160 nPPTX = nPPTX / pDocShell->GetOutputFactor(); // Faktor ist Drucker zu Bildschirm
2161 nPPTY = ScGlobal::nScreenPPTY * (double) GetZoomY();
2163 // if detective objects are present,
2164 // try to adjust horizontal scale so the most common column width has minimal rounding errors,
2165 // to avoid differences between cell and drawing layer output
2167 if ( pDoc && pDoc->HasDetectiveObjects(nTabNo) )
2169 SCCOL nEndCol = 0;
2170 SCROW nDummy = 0;
2171 pDoc->GetTableArea( nTabNo, nEndCol, nDummy );
2172 if (nEndCol<20)
2173 nEndCol = 20; // same end position as when determining draw scale
2175 sal_uInt16 nTwips = pDoc->GetCommonWidth( nEndCol, nTabNo );
2176 if ( nTwips )
2178 double fOriginal = nTwips * nPPTX;
2179 if ( fOriginal < static_cast<double>(nEndCol) )
2181 // if one column is smaller than the column count,
2182 // rounding errors are likely to add up to a whole column.
2184 double fRounded = ::rtl::math::approxFloor( fOriginal + 0.5 );
2185 if ( fRounded > 0.0 )
2187 double fScale = fRounded / fOriginal + 1E-6;
2188 if ( fScale >= 0.9 && fScale <= 1.1 )
2189 nPPTX *= fScale;
2196 #define SC_OLD_TABSEP '/'
2197 #define SC_NEW_TABSEP '+'
2199 void ScViewData::WriteUserData(OUString& rData)
2201 // nZoom (bis 364v) oder nZoom/nPageZoom/bPageMode (ab 364w)
2202 // nTab
2203 // Tab-ControlBreite
2204 // pro Tabelle:
2205 // CursorX/CursorY/HSplitMode/VSplitMode/HSplitPos/VSplitPos/SplitActive/
2206 // PosX[links]/PosX[rechts]/PosY[oben]/PosY[unten]
2207 // wenn Zeilen groesser 8192, "+" statt "/"
2209 sal_uInt16 nZoom = (sal_uInt16)((pThisTab->aZoomY.GetNumerator() * 100) / pThisTab->aZoomY.GetDenominator());
2210 rData = OUString::number( nZoom ) + "/";
2211 nZoom = (sal_uInt16)((pThisTab->aPageZoomY.GetNumerator() * 100) / pThisTab->aPageZoomY.GetDenominator());
2212 rData += OUString::number( nZoom ) + "/";
2213 if (bPagebreak)
2214 rData += "1";
2215 else
2216 rData += "0";
2218 rData += ";" + OUString::number( nTabNo ) + ";" + TAG_TABBARWIDTH +
2219 OUString::number( pView->GetTabBarWidth() );
2221 SCTAB nTabCount = pDoc->GetTableCount();
2222 for (SCTAB i=0; i<nTabCount; i++)
2224 rData += ";"; // Numerierung darf auf keinen Fall durcheinanderkommen
2225 if (i < static_cast<SCTAB>(maTabData.size()) && maTabData[i])
2227 OUString cTabSep = OUString(SC_OLD_TABSEP); // like 3.1
2228 if ( maTabData[i]->nCurY > MAXROW_30 ||
2229 maTabData[i]->nPosY[0] > MAXROW_30 || maTabData[i]->nPosY[1] > MAXROW_30 ||
2230 ( maTabData[i]->eVSplitMode == SC_SPLIT_FIX &&
2231 maTabData[i]->nFixPosY > MAXROW_30 ) )
2233 cTabSep = OUString(SC_NEW_TABSEP); // in order to not kill a 3.1-version
2237 rData += OUString::number( maTabData[i]->nCurX ) + cTabSep +
2238 OUString::number( maTabData[i]->nCurY ) + cTabSep +
2239 OUString::number( maTabData[i]->eHSplitMode ) + cTabSep +
2240 OUString::number( maTabData[i]->eVSplitMode ) + cTabSep;
2241 if ( maTabData[i]->eHSplitMode == SC_SPLIT_FIX )
2242 rData += OUString::number( maTabData[i]->nFixPosX );
2243 else
2244 rData += OUString::number( maTabData[i]->nHSplitPos );
2245 rData += cTabSep;
2246 if ( maTabData[i]->eVSplitMode == SC_SPLIT_FIX )
2247 rData += OUString::number( maTabData[i]->nFixPosY );
2248 else
2249 rData += OUString::number( maTabData[i]->nVSplitPos );
2250 rData += cTabSep +
2251 OUString::number( maTabData[i]->eWhichActive ) + cTabSep +
2252 OUString::number( maTabData[i]->nPosX[0] ) + cTabSep +
2253 OUString::number( maTabData[i]->nPosX[1] ) + cTabSep +
2254 OUString::number( maTabData[i]->nPosY[0] ) + cTabSep +
2255 OUString::number( maTabData[i]->nPosY[1] );
2260 void ScViewData::ReadUserData(const OUString& rData)
2262 if (rData.isEmpty()) // Leerer String kommt bei "neu Laden"
2263 return; // then exit without assertion
2265 sal_Int32 nCount = comphelper::string::getTokenCount(rData, ';');
2266 if ( nCount <= 2 )
2268 // beim Reload in der Seitenansicht sind evtl. die Preview-UserData
2269 // stehengelassen worden. Den Zoom von der Preview will man hier nicht...
2270 OSL_FAIL("ReadUserData: das sind nicht meine Daten");
2271 return;
2274 // nicht pro Tabelle:
2275 SCTAB nTabStart = 2;
2277 Fraction aZoomX, aZoomY, aPageZoomX, aPageZoomY; // evaluate (all sheets?)
2279 OUString aZoomStr = rData.getToken(0, ';'); // Zoom/PageZoom/Modus
2280 sal_uInt16 nNormZoom = sal::static_int_cast<sal_uInt16>(aZoomStr.getToken(0,'/').toInt32());
2281 if ( nNormZoom >= MINZOOM && nNormZoom <= MAXZOOM )
2282 aZoomX = aZoomY = Fraction( nNormZoom, 100 ); // "normal" zoom (always)
2283 sal_uInt16 nPageZoom = sal::static_int_cast<sal_uInt16>(aZoomStr.getToken(1,'/').toInt32());
2284 if ( nPageZoom >= MINZOOM && nPageZoom <= MAXZOOM )
2285 aPageZoomX = aPageZoomY = Fraction( nPageZoom, 100 ); // Pagebreak-zoom, if set
2286 sal_Unicode cMode = aZoomStr.getToken(2,'/')[0]; // 0 or "0"/"1"
2287 SetPagebreakMode( cMode == '1' );
2288 // SetPagebreakMode muss immer gerufen werden wegen CalcPPT / RecalcPixPos()
2290 // Tabelle kann ungueltig geworden sein (z.B. letzte Version):
2291 SCTAB nNewTab = static_cast<SCTAB>(rData.getToken(1, ';').toInt32());
2292 if (pDoc->HasTable( nNewTab ))
2293 SetTabNo(nNewTab);
2295 // wenn vorhanden, TabBar-Breite holen:
2296 OUString aTabOpt = rData.getToken(2, ';');
2298 if (aTabOpt.startsWith(TAG_TABBARWIDTH))
2300 sal_Int32 nTagLen = RTL_CONSTASCII_LENGTH(TAG_TABBARWIDTH);
2301 pView->SetTabBarWidth(aTabOpt.copy(nTagLen).toInt32());
2302 nTabStart = 3;
2305 // per table
2306 SCTAB nPos = 0;
2307 while ( nCount > nPos+nTabStart )
2309 aTabOpt = rData.getToken(static_cast<sal_Int32>(nPos+nTabStart), ';');
2310 EnsureTabDataSize(nPos + 1);
2311 if (!maTabData[nPos])
2312 maTabData[nPos] = new ScViewDataTable;
2314 sal_Unicode cTabSep = 0;
2315 if (comphelper::string::getTokenCount(aTabOpt, SC_OLD_TABSEP) >= 11)
2316 cTabSep = SC_OLD_TABSEP;
2317 #ifndef SC_LIMIT_ROWS
2318 else if (comphelper::string::getTokenCount(aTabOpt, SC_NEW_TABSEP) >= 11)
2319 cTabSep = SC_NEW_TABSEP;
2320 // '+' ist nur erlaubt, wenn wir mit Zeilen > 8192 umgehen koennen
2321 #endif
2323 if (cTabSep)
2325 maTabData[nPos]->nCurX = SanitizeCol( static_cast<SCCOL>(aTabOpt.getToken(0,cTabSep).toInt32()));
2326 maTabData[nPos]->nCurY = SanitizeRow( aTabOpt.getToken(1,cTabSep).toInt32());
2327 maTabData[nPos]->eHSplitMode = (ScSplitMode) aTabOpt.getToken(2,cTabSep).toInt32();
2328 maTabData[nPos]->eVSplitMode = (ScSplitMode) aTabOpt.getToken(3,cTabSep).toInt32();
2330 if ( maTabData[nPos]->eHSplitMode == SC_SPLIT_FIX )
2332 maTabData[nPos]->nFixPosX = SanitizeCol( static_cast<SCCOL>(aTabOpt.getToken(4,cTabSep).toInt32()));
2333 UpdateFixX(nPos);
2335 else
2336 maTabData[nPos]->nHSplitPos = aTabOpt.getToken(4,cTabSep).toInt32();
2338 if ( maTabData[nPos]->eVSplitMode == SC_SPLIT_FIX )
2340 maTabData[nPos]->nFixPosY = SanitizeRow( aTabOpt.getToken(5,cTabSep).toInt32());
2341 UpdateFixY(nPos);
2343 else
2344 maTabData[nPos]->nVSplitPos = aTabOpt.getToken(5,cTabSep).toInt32();
2346 maTabData[nPos]->eWhichActive = (ScSplitPos) aTabOpt.getToken(6,cTabSep).toInt32();
2347 maTabData[nPos]->nPosX[0] = SanitizeCol( static_cast<SCCOL>(aTabOpt.getToken(7,cTabSep).toInt32()));
2348 maTabData[nPos]->nPosX[1] = SanitizeCol( static_cast<SCCOL>(aTabOpt.getToken(8,cTabSep).toInt32()));
2349 maTabData[nPos]->nPosY[0] = SanitizeRow( aTabOpt.getToken(9,cTabSep).toInt32());
2350 maTabData[nPos]->nPosY[1] = SanitizeRow( aTabOpt.getToken(10,cTabSep).toInt32());
2352 // Test, ob der aktive Teil laut SplitMode ueberhaupt existiert
2353 // (Bug #44516#)
2354 ScSplitPos eTest = maTabData[nPos]->eWhichActive;
2355 if ( ( WhichH( eTest ) == SC_SPLIT_RIGHT &&
2356 maTabData[nPos]->eHSplitMode == SC_SPLIT_NONE ) ||
2357 ( WhichV( eTest ) == SC_SPLIT_TOP &&
2358 maTabData[nPos]->eVSplitMode == SC_SPLIT_NONE ) )
2360 // dann wieder auf Default (unten links)
2361 maTabData[nPos]->eWhichActive = SC_SPLIT_BOTTOMLEFT;
2362 OSL_FAIL("SplitPos musste korrigiert werden");
2365 ++nPos;
2368 RecalcPixPos();
2371 void ScViewData::WriteExtOptions( ScExtDocOptions& rDocOpt ) const
2373 // *** Fill extended document data for export filters ***
2375 // document settings
2376 ScExtDocSettings& rDocSett = rDocOpt.GetDocSettings();
2378 // displayed sheet
2379 rDocSett.mnDisplTab = GetTabNo();
2381 // width of the tabbar, relative to frame window width
2382 rDocSett.mfTabBarWidth = pView->GetPendingRelTabBarWidth();
2383 if( rDocSett.mfTabBarWidth < 0.0 )
2384 rDocSett.mfTabBarWidth = pView->GetRelTabBarWidth();
2386 // sheet settings
2387 for( SCTAB nTab = 0; nTab < static_cast<SCTAB>(maTabData.size()); ++nTab )
2389 if( const ScViewDataTable* pViewTab = maTabData[ nTab ] )
2391 ScExtTabSettings& rTabSett = rDocOpt.GetOrCreateTabSettings( nTab );
2393 // split mode
2394 ScSplitMode eHSplit = pViewTab->eHSplitMode;
2395 ScSplitMode eVSplit = pViewTab->eVSplitMode;
2396 bool bHSplit = eHSplit != SC_SPLIT_NONE;
2397 bool bVSplit = eVSplit != SC_SPLIT_NONE;
2398 bool bRealSplit = (eHSplit == SC_SPLIT_NORMAL) || (eVSplit == SC_SPLIT_NORMAL);
2399 bool bFrozen = (eHSplit == SC_SPLIT_FIX) || (eVSplit == SC_SPLIT_FIX);
2400 OSL_ENSURE( !bRealSplit || !bFrozen, "ScViewData::WriteExtOptions - split and freeze in same sheet" );
2401 rTabSett.mbFrozenPanes = !bRealSplit && bFrozen;
2403 // split and freeze position
2404 rTabSett.maSplitPos = Point( 0, 0 );
2405 rTabSett.maFreezePos.Set( 0, 0, nTab );
2406 if( bRealSplit )
2408 Point& rSplitPos = rTabSett.maSplitPos;
2409 rSplitPos = Point( bHSplit ? pViewTab->nHSplitPos : 0, bVSplit ? pViewTab->nVSplitPos : 0 );
2410 rSplitPos = Application::GetDefaultDevice()->PixelToLogic( rSplitPos, MapMode( MAP_TWIP ) );
2411 if( pDocShell )
2412 rSplitPos.X() = (long)((double)rSplitPos.X() / pDocShell->GetOutputFactor());
2414 else if( bFrozen )
2416 if( bHSplit ) rTabSett.maFreezePos.SetCol( pViewTab->nFixPosX );
2417 if( bVSplit ) rTabSett.maFreezePos.SetRow( pViewTab->nFixPosY );
2420 // first visible cell in top-left and additional panes
2421 rTabSett.maFirstVis.Set( pViewTab->nPosX[ SC_SPLIT_LEFT ], pViewTab->nPosY[ bVSplit ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM ], nTab );
2422 rTabSett.maSecondVis.Set( pViewTab->nPosX[ SC_SPLIT_RIGHT ], pViewTab->nPosY[ SC_SPLIT_BOTTOM ], nTab );
2424 // active pane
2425 switch( pViewTab->eWhichActive )
2427 // no horizontal split -> always use left panes
2428 // no vertical split -> always use top panes
2429 case SC_SPLIT_TOPLEFT:
2430 rTabSett.meActivePane = SCEXT_PANE_TOPLEFT;
2431 break;
2432 case SC_SPLIT_TOPRIGHT:
2433 rTabSett.meActivePane = bHSplit ? SCEXT_PANE_TOPRIGHT : SCEXT_PANE_TOPLEFT;
2434 break;
2435 case SC_SPLIT_BOTTOMLEFT:
2436 rTabSett.meActivePane = bVSplit ? SCEXT_PANE_BOTTOMLEFT : SCEXT_PANE_TOPLEFT;
2437 break;
2438 case SC_SPLIT_BOTTOMRIGHT:
2439 rTabSett.meActivePane = bHSplit ?
2440 (bVSplit ? SCEXT_PANE_BOTTOMRIGHT : SCEXT_PANE_TOPRIGHT) :
2441 (bVSplit ? SCEXT_PANE_BOTTOMLEFT : SCEXT_PANE_TOPLEFT);
2442 break;
2445 // cursor position
2446 rTabSett.maCursor.Set( pViewTab->nCurX, pViewTab->nCurY, nTab );
2448 // sheet selection and selected ranges
2449 const ScMarkData& rMarkData = GetMarkData();
2450 rTabSett.mbSelected = rMarkData.GetTableSelect( nTab );
2451 rMarkData.FillRangeListWithMarks( &rTabSett.maSelection, true );
2453 // grid color
2454 rTabSett.maGridColor.SetColor( COL_AUTO );
2455 if( pOptions )
2457 const Color& rGridColor = pOptions->GetGridColor();
2458 if( rGridColor.GetColor() != SC_STD_GRIDCOLOR )
2459 rTabSett.maGridColor = rGridColor;
2461 rTabSett.mbShowGrid = pViewTab->bShowGrid;
2463 // view mode and zoom
2464 rTabSett.mbPageMode = bPagebreak;
2465 rTabSett.mnNormalZoom = static_cast< long >( pViewTab->aZoomY * Fraction( 100.0 ) );
2466 rTabSett.mnPageZoom = static_cast< long >( pViewTab->aPageZoomY * Fraction( 100.0 ) );
2471 void ScViewData::ReadExtOptions( const ScExtDocOptions& rDocOpt )
2473 // *** Get extended document data from import filters ***
2475 if( !rDocOpt.IsChanged() ) return;
2477 // document settings
2478 const ScExtDocSettings& rDocSett = rDocOpt.GetDocSettings();
2480 // displayed sheet
2481 SetTabNo( rDocSett.mnDisplTab );
2483 /* Width of the tabbar, relative to frame window width. We do not have the
2484 correct width of the frame window here -> store in ScTabView, which sets
2485 the size in the next resize. */
2486 pView->SetPendingRelTabBarWidth( rDocSett.mfTabBarWidth );
2488 // sheet settings
2489 SCTAB nLastTab = rDocOpt.GetLastTab();
2490 if (static_cast<SCTAB>(maTabData.size()) <= nLastTab)
2491 maTabData.resize(nLastTab+1);
2493 for( SCTAB nTab = 0; nTab < static_cast<SCTAB>(maTabData.size()); ++nTab )
2495 if( const ScExtTabSettings* pTabSett = rDocOpt.GetTabSettings( nTab ) )
2497 if( !maTabData[ nTab ] )
2498 maTabData[ nTab ] = new ScViewDataTable;
2500 const ScExtTabSettings& rTabSett = *pTabSett;
2501 ScViewDataTable& rViewTab = *maTabData[ nTab ];
2503 // split mode initialization
2504 bool bFrozen = rTabSett.mbFrozenPanes;
2505 bool bHSplit = bFrozen ? (rTabSett.maFreezePos.Col() > 0) : (rTabSett.maSplitPos.X() > 0);
2506 bool bVSplit = bFrozen ? (rTabSett.maFreezePos.Row() > 0) : (rTabSett.maSplitPos.Y() > 0);
2508 // first visible cell of top-left pane and additional panes
2509 if (rTabSett.maFirstVis.IsValid())
2511 rViewTab.nPosX[ SC_SPLIT_LEFT ] = rTabSett.maFirstVis.Col();
2512 rViewTab.nPosY[ bVSplit ? SC_SPLIT_TOP : SC_SPLIT_BOTTOM ] = rTabSett.maFirstVis.Row();
2515 if (rTabSett.maSecondVis.IsValid())
2517 if (bHSplit)
2518 rViewTab.nPosX[ SC_SPLIT_RIGHT ] = rTabSett.maSecondVis.Col();
2519 if (bVSplit)
2520 rViewTab.nPosY[ SC_SPLIT_BOTTOM ] = rTabSett.maSecondVis.Row();
2523 // split mode, split and freeze position
2524 rViewTab.eHSplitMode = rViewTab.eVSplitMode = SC_SPLIT_NONE;
2525 rViewTab.nHSplitPos = rViewTab.nVSplitPos = 0;
2526 rViewTab.nFixPosX = 0;
2527 rViewTab.nFixPosY = 0;
2528 if( bFrozen )
2530 if( bHSplit )
2532 rViewTab.eHSplitMode = SC_SPLIT_FIX;
2533 rViewTab.nFixPosX = rTabSett.maFreezePos.Col();
2534 UpdateFixX( nTab );
2536 if( bVSplit )
2538 rViewTab.eVSplitMode = SC_SPLIT_FIX;
2539 rViewTab.nFixPosY = rTabSett.maFreezePos.Row();
2540 UpdateFixY( nTab );
2543 else
2545 Point aPixel = Application::GetDefaultDevice()->LogicToPixel(
2546 rTabSett.maSplitPos, MapMode( MAP_TWIP ) ); //! Zoom?
2547 // the test for use of printer metrics for text formatting here
2548 // effectively results in the nFactor = 1.0 regardless of the Option setting.
2549 if( pDocShell && SC_MOD()->GetInputOptions().GetTextWysiwyg())
2551 double nFactor = pDocShell->GetOutputFactor();
2552 aPixel.X() = (long)( aPixel.X() * nFactor + 0.5 );
2555 bHSplit = bHSplit && aPixel.X() > 0;
2556 bVSplit = bVSplit && aPixel.Y() > 0;
2557 if( bHSplit )
2559 rViewTab.eHSplitMode = SC_SPLIT_NORMAL;
2560 rViewTab.nHSplitPos = aPixel.X();
2562 if( bVSplit )
2564 rViewTab.eVSplitMode = SC_SPLIT_NORMAL;
2565 rViewTab.nVSplitPos = aPixel.Y();
2569 // active pane
2570 ScSplitPos ePos = SC_SPLIT_BOTTOMLEFT;
2571 switch( rTabSett.meActivePane )
2573 // no horizontal split -> always use left panes
2574 // no vertical split -> always use *bottom* panes
2575 case SCEXT_PANE_TOPLEFT:
2576 ePos = bVSplit ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT;
2577 break;
2578 case SCEXT_PANE_TOPRIGHT:
2579 ePos = bHSplit ?
2580 (bVSplit ? SC_SPLIT_TOPRIGHT : SC_SPLIT_BOTTOMRIGHT) :
2581 (bVSplit ? SC_SPLIT_TOPLEFT : SC_SPLIT_BOTTOMLEFT);
2582 break;
2583 case SCEXT_PANE_BOTTOMLEFT:
2584 ePos = SC_SPLIT_BOTTOMLEFT;
2585 break;
2586 case SCEXT_PANE_BOTTOMRIGHT:
2587 ePos = bHSplit ? SC_SPLIT_BOTTOMRIGHT : SC_SPLIT_BOTTOMLEFT;
2588 break;
2590 rViewTab.eWhichActive = ePos;
2592 // cursor position
2593 const ScAddress& rCursor = rTabSett.maCursor;
2594 if( rCursor.IsValid() )
2596 rViewTab.nCurX = rCursor.Col();
2597 rViewTab.nCurY = rCursor.Row();
2600 // sheet selection and selected ranges
2601 ScMarkData& rMarkData = GetMarkData();
2602 rMarkData.SelectTable( nTab, rTabSett.mbSelected );
2604 // zoom for each sheet
2605 if( rTabSett.mnNormalZoom )
2606 rViewTab.aZoomX = rViewTab.aZoomY = Fraction( rTabSett.mnNormalZoom, 100L );
2607 if( rTabSett.mnPageZoom )
2608 rViewTab.aPageZoomX = rViewTab.aPageZoomY = Fraction( rTabSett.mnPageZoom, 100L );
2610 rViewTab.bShowGrid = rTabSett.mbShowGrid;
2612 // get some settings from displayed Excel sheet, set at Calc document
2613 if( nTab == GetTabNo() )
2615 // grid color -- #i47435# set automatic grid color explicitly
2616 if( pOptions )
2618 Color aGridColor( rTabSett.maGridColor );
2619 if( aGridColor.GetColor() == COL_AUTO )
2620 aGridColor.SetColor( SC_STD_GRIDCOLOR );
2621 pOptions->SetGridColor( aGridColor, EMPTY_OUSTRING );
2624 // view mode and default zoom (for new sheets) from current sheet
2625 if( rTabSett.mnNormalZoom )
2626 aDefZoomX = aDefZoomY = Fraction( rTabSett.mnNormalZoom, 100L );
2627 if( rTabSett.mnPageZoom )
2628 aDefPageZoomX = aDefPageZoomY = Fraction( rTabSett.mnPageZoom, 100L );
2629 /* #i46820# set pagebreak mode via SetPagebreakMode(), this will
2630 update map modes that are needed to draw text correctly. */
2631 SetPagebreakMode( rTabSett.mbPageMode );
2636 // RecalcPixPos oder so - auch nMPos - auch bei ReadUserData ??!?!
2639 void ScViewData::WriteUserDataSequence(uno::Sequence <beans::PropertyValue>& rSettings) const
2641 rSettings.realloc(SC_VIEWSETTINGS_COUNT);
2642 // + 1, because we have to put the view id in the sequence
2643 beans::PropertyValue* pSettings = rSettings.getArray();
2644 if (pSettings)
2646 sal_uInt16 nViewID(pViewShell->GetViewFrame()->GetCurViewId());
2647 pSettings[SC_VIEW_ID].Name = OUString(SC_VIEWID);
2648 OUStringBuffer sBuffer(SC_VIEW);
2649 ::sax::Converter::convertNumber(sBuffer,
2650 static_cast<sal_Int32>(nViewID));
2651 pSettings[SC_VIEW_ID].Value <<= sBuffer.makeStringAndClear();
2653 uno::Reference<container::XNameContainer> xNameContainer =
2654 document::NamedPropertyValues::create( comphelper::getProcessComponentContext() );
2655 for (SCTAB nTab=0; nTab<static_cast<SCTAB>(maTabData.size()); nTab++)
2657 if (maTabData[nTab])
2659 uno::Sequence <beans::PropertyValue> aTableViewSettings;
2660 maTabData[nTab]->WriteUserDataSequence(aTableViewSettings, *this, nTab);
2661 OUString sTabName;
2662 GetDocument()->GetName( nTab, sTabName );
2663 uno::Any aAny;
2664 aAny <<= aTableViewSettings;
2667 xNameContainer->insertByName(sTabName, aAny);
2669 //#101739#; two tables with the same name are possible
2670 catch ( container::ElementExistException& )
2672 OSL_FAIL("seems there are two tables with the same name");
2674 catch ( uno::RuntimeException& )
2676 OSL_FAIL("something went wrong");
2680 pSettings[SC_TABLE_VIEWSETTINGS].Name = OUString(SC_TABLES);
2681 pSettings[SC_TABLE_VIEWSETTINGS].Value <<= xNameContainer;
2683 OUString sName;
2684 GetDocument()->GetName( nTabNo, sName );
2685 pSettings[SC_ACTIVE_TABLE].Name = OUString(SC_ACTIVETABLE);
2686 pSettings[SC_ACTIVE_TABLE].Value <<= sName;
2687 pSettings[SC_HORIZONTAL_SCROLL_BAR_WIDTH].Name = OUString(SC_HORIZONTALSCROLLBARWIDTH);
2688 pSettings[SC_HORIZONTAL_SCROLL_BAR_WIDTH].Value <<= sal_Int32(pView->GetTabBarWidth());
2689 sal_Int32 nZoomValue ((pThisTab->aZoomY.GetNumerator() * 100) / pThisTab->aZoomY.GetDenominator());
2690 sal_Int32 nPageZoomValue ((pThisTab->aPageZoomY.GetNumerator() * 100) / pThisTab->aPageZoomY.GetDenominator());
2691 pSettings[SC_ZOOM_TYPE].Name = OUString(SC_ZOOMTYPE);
2692 pSettings[SC_ZOOM_TYPE].Value <<= sal_Int16(pThisTab->eZoomType);
2693 pSettings[SC_ZOOM_VALUE].Name = OUString(SC_ZOOMVALUE);
2694 pSettings[SC_ZOOM_VALUE].Value <<= nZoomValue;
2695 pSettings[SC_PAGE_VIEW_ZOOM_VALUE].Name = OUString(SC_PAGEVIEWZOOMVALUE);
2696 pSettings[SC_PAGE_VIEW_ZOOM_VALUE].Value <<= nPageZoomValue;
2697 pSettings[SC_PAGE_BREAK_PREVIEW].Name = OUString(SC_SHOWPAGEBREAKPREVIEW);
2698 ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_PAGE_BREAK_PREVIEW].Value, bPagebreak);
2700 if (pOptions)
2702 pSettings[SC_SHOWZERO].Name = OUString(SC_UNO_SHOWZERO);
2703 ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHOWZERO].Value, pOptions->GetOption( VOPT_NULLVALS ) );
2704 pSettings[SC_SHOWNOTES].Name = OUString(SC_UNO_SHOWNOTES);
2705 ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHOWNOTES].Value, pOptions->GetOption( VOPT_NOTES ) );
2706 pSettings[SC_SHOWGRID].Name = OUString(SC_UNO_SHOWGRID);
2707 ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHOWGRID].Value, pOptions->GetOption( VOPT_GRID ) );
2708 pSettings[SC_GRIDCOLOR].Name = OUString(SC_UNO_GRIDCOLOR);
2709 OUString aColorName;
2710 Color aColor = pOptions->GetGridColor(&aColorName);
2711 pSettings[SC_GRIDCOLOR].Value <<= static_cast<sal_Int64>(aColor.GetColor());
2712 pSettings[SC_SHOWPAGEBR].Name = OUString(SC_UNO_SHOWPAGEBR);
2713 ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHOWPAGEBR].Value, pOptions->GetOption( VOPT_PAGEBREAKS ) );
2714 pSettings[SC_COLROWHDR].Name = OUString(SC_UNO_COLROWHDR);
2715 ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_COLROWHDR].Value, pOptions->GetOption( VOPT_HEADER ) );
2716 pSettings[SC_SHEETTABS].Name = OUString(SC_UNO_SHEETTABS);
2717 ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SHEETTABS].Value, pOptions->GetOption( VOPT_TABCONTROLS ) );
2718 pSettings[SC_OUTLSYMB].Name = OUString(SC_UNO_OUTLSYMB);
2719 ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_OUTLSYMB].Value, pOptions->GetOption( VOPT_OUTLINER ) );
2721 const ScGridOptions& aGridOpt = pOptions->GetGridOptions();
2722 pSettings[SC_SNAPTORASTER].Name = OUString(SC_UNO_SNAPTORASTER);
2723 ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_SNAPTORASTER].Value, aGridOpt.GetUseGridSnap() );
2724 pSettings[SC_RASTERVIS].Name = OUString(SC_UNO_RASTERVIS);
2725 ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_RASTERVIS].Value, aGridOpt.GetGridVisible() );
2726 pSettings[SC_RASTERRESX].Name = OUString(SC_UNO_RASTERRESX);
2727 pSettings[SC_RASTERRESX].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDrawX() );
2728 pSettings[SC_RASTERRESY].Name = OUString(SC_UNO_RASTERRESY);
2729 pSettings[SC_RASTERRESY].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDrawY() );
2730 pSettings[SC_RASTERSUBX].Name = OUString(SC_UNO_RASTERSUBX);
2731 pSettings[SC_RASTERSUBX].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDivisionX() );
2732 pSettings[SC_RASTERSUBY].Name = OUString(SC_UNO_RASTERSUBY);
2733 pSettings[SC_RASTERSUBY].Value <<= static_cast<sal_Int32> ( aGridOpt.GetFldDivisionY() );
2734 pSettings[SC_RASTERSYNC].Name = OUString(SC_UNO_RASTERSYNC);
2735 ScUnoHelpFunctions::SetBoolInAny( pSettings[SC_RASTERSYNC].Value, aGridOpt.GetSynchronize() );
2740 void ScViewData::ReadUserDataSequence(const uno::Sequence <beans::PropertyValue>& rSettings)
2742 std::vector<bool> aHasZoomVect( GetDocument()->GetTableCount(), false );
2744 sal_Int32 nCount(rSettings.getLength());
2745 sal_Int32 nTemp32(0);
2746 sal_Int16 nTemp16(0);
2747 bool bPageMode(false);
2749 EnsureTabDataSize(GetDocument()->GetTableCount()-1);
2751 for (sal_Int32 i = 0; i < nCount; i++)
2753 // SC_VIEWID has to parse and use by mba
2754 OUString sName(rSettings[i].Name);
2755 if (sName.equalsAscii(SC_TABLES) )
2757 uno::Reference<container::XNameContainer> xNameContainer;
2758 if ((rSettings[i].Value >>= xNameContainer) && xNameContainer->hasElements())
2760 uno::Sequence< OUString > aNames(xNameContainer->getElementNames());
2761 for (sal_Int32 nTabPos = 0; nTabPos < aNames.getLength(); nTabPos++)
2763 OUString sTabName(aNames[nTabPos]);
2764 SCTAB nTab(0);
2765 if (GetDocument()->GetTable(sTabName, nTab))
2767 uno::Any aAny = xNameContainer->getByName(aNames[nTabPos]);
2768 uno::Sequence<beans::PropertyValue> aTabSettings;
2769 if (aAny >>= aTabSettings)
2771 EnsureTabDataSize(nTab + 1);
2772 if (!maTabData[nTab])
2773 maTabData[nTab] = new ScViewDataTable;
2775 bool bHasZoom = false;
2776 maTabData[nTab]->ReadUserDataSequence(aTabSettings, *this, nTab, bHasZoom);
2777 aHasZoomVect[nTab] = bHasZoom;
2783 else if (sName.equalsAscii(SC_ACTIVETABLE) )
2785 OUString sValue;
2786 if(rSettings[i].Value >>= sValue)
2788 OUString sTabName(sValue);
2789 SCTAB nTab(0);
2790 if (GetDocument()->GetTable(sTabName, nTab))
2791 nTabNo = nTab;
2794 else if (sName.equalsAscii(SC_HORIZONTALSCROLLBARWIDTH) )
2796 if (rSettings[i].Value >>= nTemp32)
2797 pView->SetTabBarWidth(nTemp32);
2799 else if (sName.equalsAscii(SC_RELHORIZONTALTABBARWIDTH) )
2801 double fWidth = 0.0;
2802 if (rSettings[i].Value >>= fWidth)
2803 pView->SetPendingRelTabBarWidth( fWidth );
2805 else if (sName.equalsAscii(SC_ZOOMTYPE) )
2807 if (rSettings[i].Value >>= nTemp16)
2808 eDefZoomType = SvxZoomType(nTemp16);
2810 else if (sName.equalsAscii(SC_ZOOMVALUE) )
2812 if (rSettings[i].Value >>= nTemp32)
2814 Fraction aZoom(nTemp32, 100);
2815 aDefZoomX = aDefZoomY = aZoom;
2818 else if (sName.equalsAscii(SC_PAGEVIEWZOOMVALUE) )
2820 if (rSettings[i].Value >>= nTemp32)
2822 Fraction aZoom(nTemp32, 100);
2823 aDefPageZoomX = aDefPageZoomY = aZoom;
2826 else if (sName.equalsAscii(SC_SHOWPAGEBREAKPREVIEW) )
2827 bPageMode = ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value );
2828 else if ( sName.equalsAscii( SC_UNO_SHOWZERO ) )
2829 pOptions->SetOption(VOPT_NULLVALS, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2830 else if ( sName.equalsAscii( SC_UNO_SHOWNOTES ) )
2831 pOptions->SetOption(VOPT_NOTES, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2832 else if ( sName.equalsAscii( SC_UNO_SHOWGRID ) )
2833 pOptions->SetOption(VOPT_GRID, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2834 else if ( sName.equalsAscii( SC_UNO_GRIDCOLOR ) )
2836 sal_Int64 nColor = 0;
2837 if (rSettings[i].Value >>= nColor)
2839 OUString aColorName;
2840 Color aColor(static_cast<sal_uInt32>(nColor));
2841 // #i47435# set automatic grid color explicitly
2842 if( aColor.GetColor() == COL_AUTO )
2843 aColor.SetColor( SC_STD_GRIDCOLOR );
2844 pOptions->SetGridColor(aColor, aColorName);
2847 else if ( sName.equalsAscii( SC_UNO_SHOWPAGEBR ) )
2848 pOptions->SetOption(VOPT_PAGEBREAKS, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2849 else if ( sName.equalsAscii( SC_UNO_COLROWHDR ) )
2850 pOptions->SetOption(VOPT_HEADER, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2851 else if ( sName.equalsAscii( SC_UNO_SHEETTABS ) )
2852 pOptions->SetOption(VOPT_TABCONTROLS, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2853 else if ( sName.equalsAscii( SC_UNO_OUTLSYMB ) )
2854 pOptions->SetOption(VOPT_OUTLINER, ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2855 else if ( sName.equalsAscii( SC_UNO_SHOWOBJ ) )
2857 // #i80528# placeholders not supported anymore
2858 if ( rSettings[i].Value >>= nTemp16 )
2859 pOptions->SetObjMode( VOBJ_TYPE_OLE, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
2861 else if ( sName.equalsAscii( SC_UNO_SHOWCHARTS ) )
2863 // #i80528# placeholders not supported anymore
2864 if ( rSettings[i].Value >>= nTemp16 )
2865 pOptions->SetObjMode( VOBJ_TYPE_CHART, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
2867 else if ( sName.equalsAscii( SC_UNO_SHOWDRAW ) )
2869 // #i80528# placeholders not supported anymore
2870 if ( rSettings[i].Value >>= nTemp16 )
2871 pOptions->SetObjMode( VOBJ_TYPE_DRAW, (nTemp16 == 1) ? VOBJ_MODE_HIDE : VOBJ_MODE_SHOW );
2873 else
2875 ScGridOptions aGridOpt(pOptions->GetGridOptions());
2876 if ( sName.equalsAscii( SC_UNO_SNAPTORASTER ) )
2877 aGridOpt.SetUseGridSnap( ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2878 else if ( sName.equalsAscii( SC_UNO_RASTERVIS ) )
2879 aGridOpt.SetGridVisible( ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2880 else if ( sName.equalsAscii( SC_UNO_RASTERRESX ) )
2881 aGridOpt.SetFldDrawX( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
2882 else if ( sName.equalsAscii( SC_UNO_RASTERRESY ))
2883 aGridOpt.SetFldDrawY( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
2884 else if ( sName.equalsAscii( SC_UNO_RASTERSUBX ) )
2885 aGridOpt.SetFldDivisionX( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
2886 else if ( sName.equalsAscii( SC_UNO_RASTERSUBY ) )
2887 aGridOpt.SetFldDivisionY( static_cast <sal_uInt32> ( ScUnoHelpFunctions::GetInt32FromAny( rSettings[i].Value ) ) );
2888 else if ( sName.equalsAscii( SC_UNO_RASTERSYNC ) )
2889 aGridOpt.SetSynchronize( ScUnoHelpFunctions::GetBoolFromAny( rSettings[i].Value ) );
2890 pOptions->SetGridOptions(aGridOpt);
2894 // copy default zoom to sheets where a different one wasn't specified
2895 for (SCTAB nZoomTab=0; nZoomTab< static_cast<SCTAB>(maTabData.size()); ++nZoomTab)
2896 if (maTabData[nZoomTab] && ( nZoomTab >= static_cast<SCTAB>(aHasZoomVect.size()) || !aHasZoomVect[nZoomTab] ))
2898 maTabData[nZoomTab]->eZoomType = eDefZoomType;
2899 maTabData[nZoomTab]->aZoomX = aDefZoomX;
2900 maTabData[nZoomTab]->aZoomY = aDefZoomY;
2901 maTabData[nZoomTab]->aPageZoomX = aDefPageZoomX;
2902 maTabData[nZoomTab]->aPageZoomY = aDefPageZoomY;
2905 if (nCount)
2906 SetPagebreakMode( bPageMode );
2908 // #i47426# write view options to document, needed e.g. for Excel export
2909 pDoc->SetViewOptions( *pOptions );
2912 void ScViewData::SetOptions( const ScViewOptions& rOpt )
2914 // if visibility of horizontal ScrollBar is changed, TabBar may have to be resized...
2915 bool bHScrollChanged = ( rOpt.GetOption(VOPT_HSCROLL) != pOptions->GetOption(VOPT_HSCROLL) );
2917 // if graphics are turned on or off, animation has to be started or stopped
2918 // graphics are controlled by VOBJ_TYPE_OLE
2919 bool bGraphicsChanged = ( pOptions->GetObjMode(VOBJ_TYPE_OLE) !=
2920 rOpt.GetObjMode(VOBJ_TYPE_OLE) );
2922 *pOptions = rOpt;
2923 OSL_ENSURE( pView, "No View" );
2925 if( pView )
2927 pView->ViewOptionsHasChanged( bHScrollChanged, bGraphicsChanged );
2931 Point ScViewData::GetMousePosPixel()
2933 OSL_ENSURE( pView, "GetMousePosPixel() ohne View" );
2934 return pView->GetMousePosPixel();
2937 void ScViewData::UpdateInputHandler( bool bForce, bool bStopEditing )
2939 if (pViewShell)
2940 pViewShell->UpdateInputHandler( bForce, bStopEditing );
2943 bool ScViewData::IsOle()
2945 return pDocShell && pDocShell->IsOle();
2948 bool ScViewData::UpdateFixX( SCTAB nTab ) // true = value changed
2950 if (!ValidTab(nTab)) // Default
2951 nTab=nTabNo; // current table
2953 if (!pView || maTabData[nTab]->eHSplitMode != SC_SPLIT_FIX)
2954 return false;
2956 ScDocument* pLocalDoc = GetDocument();
2957 if (!pLocalDoc->HasTable(nTab)) // if called from reload, the sheet may not exist
2958 return false;
2960 SCCOL nFix = maTabData[nTab]->nFixPosX;
2961 long nNewPos = 0;
2962 for (SCCOL nX=maTabData[nTab]->nPosX[SC_SPLIT_LEFT]; nX<nFix; nX++)
2964 sal_uInt16 nTSize = pLocalDoc->GetColWidth( nX, nTab );
2965 if (nTSize)
2967 long nPix = ToPixel( nTSize, nPPTX );
2968 nNewPos += nPix;
2971 nNewPos += pView->GetGridOffset().X();
2972 if (nNewPos != maTabData[nTab]->nHSplitPos)
2974 maTabData[nTab]->nHSplitPos = nNewPos;
2975 if (nTab == nTabNo)
2976 RecalcPixPos(); // should not be needed
2977 return true;
2980 return false;
2983 bool ScViewData::UpdateFixY( SCTAB nTab ) // true = value changed
2985 if (!ValidTab(nTab)) // Default
2986 nTab=nTabNo; // current table
2988 if (!pView || maTabData[nTab]->eVSplitMode != SC_SPLIT_FIX)
2989 return false;
2991 ScDocument* pLocalDoc = GetDocument();
2992 if (!pLocalDoc->HasTable(nTab)) // if called from reload, the sheet may not exist
2993 return false;
2995 SCROW nFix = maTabData[nTab]->nFixPosY;
2996 long nNewPos = 0;
2997 for (SCROW nY=maTabData[nTab]->nPosY[SC_SPLIT_TOP]; nY<nFix; nY++)
2999 sal_uInt16 nTSize = pLocalDoc->GetRowHeight( nY, nTab );
3000 if (nTSize)
3002 long nPix = ToPixel( nTSize, nPPTY );
3003 nNewPos += nPix;
3006 nNewPos += pView->GetGridOffset().Y();
3007 if (nNewPos != maTabData[nTab]->nVSplitPos)
3009 maTabData[nTab]->nVSplitPos = nNewPos;
3010 if (nTab == nTabNo)
3011 RecalcPixPos(); // should not be needed
3012 return true;
3015 return false;
3018 void ScViewData::UpdateOutlinerFlags( Outliner& rOutl ) const
3020 ScDocument* pLocalDoc = GetDocument();
3021 bool bOnlineSpell = pLocalDoc->GetDocOptions().IsAutoSpell();
3023 sal_uLong nCntrl = rOutl.GetControlWord();
3024 nCntrl |= EE_CNTRL_URLSFXEXECUTE;
3025 nCntrl |= EE_CNTRL_MARKFIELDS;
3026 nCntrl |= EE_CNTRL_AUTOCORRECT;
3027 if( bOnlineSpell )
3028 nCntrl |= EE_CNTRL_ONLINESPELLING;
3029 else
3030 nCntrl &= ~EE_CNTRL_ONLINESPELLING;
3031 rOutl.SetControlWord(nCntrl);
3033 rOutl.SetCalcFieldValueHdl( LINK( SC_MOD(), ScModule, CalcFieldValueHdl ) );
3035 // don't call GetSpellChecker if online spelling isn't enabled.
3036 // The language for AutoCorrect etc. is taken from the pool defaults
3037 // (set in ScDocument::UpdateDrawLanguages)
3039 if ( bOnlineSpell )
3041 com::sun::star::uno::Reference<com::sun::star::linguistic2::XSpellChecker1> xXSpellChecker1( LinguMgr::GetSpellChecker() );
3042 rOutl.SetSpeller( xXSpellChecker1 );
3045 rOutl.SetDefaultHorizontalTextDirection(
3046 (EEHorizontalTextDirection)pLocalDoc->GetEditTextDirection( nTabNo ) );
3049 ScAddress ScViewData::GetCurPos() const
3051 return ScAddress( GetCurX(), GetCurY(), GetTabNo() );
3054 void ScViewData::SetRefStart( SCCOL nNewX, SCROW nNewY, SCTAB nNewZ )
3056 nRefStartX = nNewX; nRefStartY = nNewY; nRefStartZ = nNewZ;
3059 void ScViewData::SetRefEnd( SCCOL nNewX, SCROW nNewY, SCTAB nNewZ )
3061 nRefEndX = nNewX; nRefEndY = nNewY; nRefEndZ = nNewZ;
3064 void ScViewData::AddPixelsWhile( long & rScrY, long nEndPixels, SCROW & rPosY,
3065 SCROW nEndRow, double nPPTY, const ScDocument * pDoc, SCTAB nTabNo )
3067 SCROW nRow = rPosY;
3068 while (rScrY <= nEndPixels && nRow <= nEndRow)
3070 SCROW nHeightEndRow;
3071 sal_uInt16 nHeight = pDoc->GetRowHeight( nRow, nTabNo, NULL, &nHeightEndRow);
3072 if (nHeightEndRow > nEndRow)
3073 nHeightEndRow = nEndRow;
3074 if (!nHeight)
3075 nRow = nHeightEndRow + 1;
3076 else
3078 SCROW nRows = nHeightEndRow - nRow + 1;
3079 sal_Int64 nPixel = ToPixel( nHeight, nPPTY);
3080 sal_Int64 nAdd = nPixel * nRows;
3081 if (nAdd + rScrY > nEndPixels)
3083 sal_Int64 nDiff = rScrY + nAdd - nEndPixels;
3084 nRows -= static_cast<SCROW>(nDiff / nPixel);
3085 nAdd = nPixel * nRows;
3086 // We're looking for a value that satisfies loop condition.
3087 if (nAdd + rScrY <= nEndPixels)
3089 ++nRows;
3090 nAdd += nPixel;
3093 rScrY += static_cast<long>(nAdd);
3094 nRow += nRows;
3097 if (nRow > rPosY)
3098 --nRow;
3099 rPosY = nRow;
3103 void ScViewData::AddPixelsWhileBackward( long & rScrY, long nEndPixels,
3104 SCROW & rPosY, SCROW nStartRow, double nPPTY, const ScDocument * pDoc,
3105 SCTAB nTabNo )
3107 SCROW nRow = rPosY;
3108 while (rScrY <= nEndPixels && nRow >= nStartRow)
3110 SCROW nHeightStartRow;
3111 sal_uInt16 nHeight = pDoc->GetRowHeight( nRow, nTabNo, &nHeightStartRow, NULL);
3112 if (nHeightStartRow < nStartRow)
3113 nHeightStartRow = nStartRow;
3114 if (!nHeight)
3115 nRow = nHeightStartRow - 1;
3116 else
3118 SCROW nRows = nRow - nHeightStartRow + 1;
3119 sal_Int64 nPixel = ToPixel( nHeight, nPPTY);
3120 sal_Int64 nAdd = nPixel * nRows;
3121 if (nAdd + rScrY > nEndPixels)
3123 sal_Int64 nDiff = nAdd + rScrY - nEndPixels;
3124 nRows -= static_cast<SCROW>(nDiff / nPixel);
3125 nAdd = nPixel * nRows;
3126 // We're looking for a value that satisfies loop condition.
3127 if (nAdd + rScrY <= nEndPixels)
3129 ++nRows;
3130 nAdd += nPixel;
3133 rScrY += static_cast<long>(nAdd);
3134 nRow -= nRows;
3137 if (nRow < rPosY)
3138 ++nRow;
3139 rPosY = nRow;
3142 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */