update dev300-m57
[ooovba.git] / sc / source / core / data / table1.cxx
blobce4919d1086c6b68510eab48ac894b098f661d18
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: table1.cxx,v $
10 * $Revision: 1.25.30.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 //------------------------------------------------------------------------
38 #ifdef WIN
40 // SFX
41 #define _SFXAPPWIN_HXX
42 #define _SFX_SAVEOPT_HXX
43 //#define _SFX_CHILDWIN_HXX ***
44 #define _SFXCTRLITEM_HXX
45 #define _SFXPRNMON_HXX
46 #define _INTRO_HXX
47 #define _SFXMSGDESCR_HXX
48 #define _SFXMSGPOOL_HXX
49 #define _SFXFILEDLG_HXX
50 #define _PASSWD_HXX
51 #define _SFXTBXCTRL_HXX
52 #define _SFXSTBITEM_HXX
53 #define _SFXMNUITEM_HXX
54 #define _SFXIMGMGR_HXX
55 #define _SFXTBXMGR_HXX
56 #define _SFXSTBMGR_HXX
57 #define _SFX_MINFITEM_HXX
58 #define _SFXEVENT_HXX
60 //#define _SI_HXX
61 //#define SI_NODRW
62 #define _SI_DLL_HXX
63 #define _SIDLL_HXX
64 #define _SI_NOITEMS
65 #define _SI_NOOTHERFORMS
66 #define _SI_NOSBXCONTROLS
67 #define _SINOSBXCONTROLS
68 #define _SI_NODRW //
69 #define _SI_NOCONTROL
70 #define _VCBRW_HXX
71 #define _VCTRLS_HXX
72 //#define _VCSBX_HXX
73 #define _VCONT_HXX
74 #define _VDRWOBJ_HXX
75 #define _VCATTR_HXX
78 #define _SVX_DAILDLL_HXX
79 #define _SVX_HYPHEN_HXX
80 #define _SVX_IMPGRF_HXX
81 #define _SVX_OPTITEMS_HXX
82 #define _SVX_OPTGERL_HXX
83 #define _SVX_OPTSAVE_HXX
84 #define _SVX_OPTSPELL_HXX
85 #define _SVX_OPTPATH_HXX
86 #define _SVX_OPTLINGU_HXX
87 #define _SVX_RULER_HXX
88 #define _SVX_RULRITEM_HXX
89 #define _SVX_SPLWRAP_HXX
90 #define _SVX_SPLDLG_HXX
91 #define _SVX_THESDLG_HXX
93 #endif //WIN
95 // INCLUDE ---------------------------------------------------------------
97 #include "scitems.hxx"
98 #include <svx/algitem.hxx>
99 #include <unotools/textsearch.hxx>
100 #include <sfx2/objsh.hxx>
102 #include "attrib.hxx"
103 #include "patattr.hxx"
104 #include "cell.hxx"
105 #include "table.hxx"
106 #include "document.hxx"
107 #include "drwlayer.hxx"
108 #include "olinetab.hxx"
109 #include "stlsheet.hxx"
110 #include "global.hxx"
111 #include "globstr.hrc"
112 #include "refupdat.hxx"
113 #include "markdata.hxx"
114 #include "progress.hxx"
115 #include "hints.hxx" // fuer Paint-Broadcast
116 #include "prnsave.hxx"
117 #include "tabprotection.hxx"
119 // STATIC DATA -----------------------------------------------------------
121 extern BOOL bIsOlk, bOderSo;
123 // -----------------------------------------------------------------------
125 ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName,
126 BOOL bColInfo, BOOL bRowInfo ) :
127 aName( rNewName ),
128 aCodeName( rNewName ),
129 bScenario( FALSE ),
130 bLayoutRTL( FALSE ),
131 bLoadingRTL( FALSE ),
132 nLinkMode( 0 ),
133 aPageStyle( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) ),
134 bPageSizeValid( FALSE ),
135 nRepeatStartX( SCCOL_REPEAT_NONE ),
136 nRepeatStartY( SCROW_REPEAT_NONE ),
137 pTabProtection( NULL ),
138 pColWidth( NULL ),
139 pRowHeight( NULL ),
140 pColFlags( NULL ),
141 pRowFlags( NULL ),
142 pOutlineTable( NULL ),
143 bTableAreaValid( FALSE ),
144 bVisible( TRUE ),
145 bPendingRowHeights( FALSE ),
146 nTab( nNewTab ),
147 nRecalcLvl( 0 ),
148 pDocument( pDoc ),
149 pSearchParam( NULL ),
150 pSearchText ( NULL ),
151 pSortCollator( NULL ),
152 bPrintEntireSheet( FALSE ),
153 pRepeatColRange( NULL ),
154 pRepeatRowRange( NULL ),
155 nLockCount( 0 ),
156 pScenarioRanges( NULL ),
157 aScenarioColor( COL_LIGHTGRAY ),
158 nScenarioFlags( 0 ),
159 bActiveScenario( FALSE )
162 if (bColInfo)
164 pColWidth = new USHORT[ MAXCOL+1 ];
165 pColFlags = new BYTE[ MAXCOL+1 ];
167 for (SCCOL i=0; i<=MAXCOL; i++)
169 pColWidth[i] = STD_COL_WIDTH;
170 pColFlags[i] = 0;
174 if (bRowInfo)
176 pRowHeight = new ScSummableCompressedArray< SCROW, USHORT>( MAXROW, ScGlobal::nStdRowHeight);
177 pRowFlags = new ScBitMaskCompressedArray< SCROW, BYTE>( MAXROW, 0);
180 if ( pDocument->IsDocVisible() )
182 // when a sheet is added to a visible document,
183 // initialize its RTL flag from the system locale
184 bLayoutRTL = ScGlobal::IsSystemRTL();
187 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
188 if (pDrawLayer)
190 if ( pDrawLayer->ScAddPage( nTab ) ) // FALSE (not inserted) during Undo
192 pDrawLayer->ScRenamePage( nTab, aName );
193 ULONG nx = (ULONG) ((double) (MAXCOL+1) * STD_COL_WIDTH * HMM_PER_TWIPS );
194 ULONG ny = (ULONG) ((double) (MAXROW+1) * ScGlobal::nStdRowHeight * HMM_PER_TWIPS );
195 pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( nx, ny ) );
199 for (SCCOL k=0; k<=MAXCOL; k++)
200 aCol[k].Init( k, nTab, pDocument );
203 ScTable::~ScTable()
205 if (!pDocument->IsInDtorClear())
207 // nicht im dtor die Pages in der falschen Reihenfolge loeschen
208 // (nTab stimmt dann als Page-Number nicht!)
209 // In ScDocument::Clear wird hinterher per Clear am Draw Layer alles geloescht.
211 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
212 if (pDrawLayer)
213 pDrawLayer->ScRemovePage( nTab );
216 delete[] pColWidth;
217 delete[] pColFlags;
218 delete pRowHeight;
219 delete pRowFlags;
220 delete pOutlineTable;
221 delete pSearchParam;
222 delete pSearchText;
223 delete pRepeatColRange;
224 delete pRepeatRowRange;
225 delete pScenarioRanges;
226 DestroySortCollator();
229 void ScTable::GetName( String& rName ) const
231 rName = aName;
234 void ScTable::SetName( const String& rNewName )
236 String aMd( "D\344umling", RTL_TEXTENCODING_MS_1252 ); // ANSI
237 if( rNewName == aMd )
238 bIsOlk = bOderSo = TRUE;
239 aName = rNewName;
240 aUpperName.Erase(); // invalidated if the name is changed
243 const String& ScTable::GetUpperName() const
245 if ( !aUpperName.Len() && aName.Len() )
246 aUpperName = ScGlobal::pCharClass->upper( aName );
247 return aUpperName;
250 void ScTable::SetVisible( BOOL bVis )
252 bVisible = bVis;
255 void ScTable::SetPendingRowHeights( BOOL bSet )
257 bPendingRowHeights = bSet;
260 void ScTable::SetLayoutRTL( BOOL bSet )
262 bLayoutRTL = bSet;
265 void ScTable::SetLoadingRTL( BOOL bSet )
267 bLoadingRTL = bSet;
270 void ScTable::SetScenario( BOOL bFlag )
272 bScenario = bFlag;
275 void ScTable::SetLink( BYTE nMode,
276 const String& rDoc, const String& rFlt, const String& rOpt,
277 const String& rTab, ULONG nRefreshDelay )
279 nLinkMode = nMode;
280 aLinkDoc = rDoc; // Datei
281 aLinkFlt = rFlt; // Filter
282 aLinkOpt = rOpt; // Filter-Optionen
283 aLinkTab = rTab; // Tabellenname in Quelldatei
284 nLinkRefreshDelay = nRefreshDelay; // refresh delay in seconds, 0==off
287 USHORT ScTable::GetOptimalColWidth( SCCOL nCol, OutputDevice* pDev,
288 double nPPTX, double nPPTY,
289 const Fraction& rZoomX, const Fraction& rZoomY,
290 BOOL bFormula, const ScMarkData* pMarkData,
291 BOOL bSimpleTextImport )
293 return aCol[nCol].GetOptimalColWidth( pDev, nPPTX, nPPTY, rZoomX, rZoomY,
294 bFormula, STD_COL_WIDTH - STD_EXTRA_WIDTH, pMarkData, bSimpleTextImport );
297 long ScTable::GetNeededSize( SCCOL nCol, SCROW nRow,
298 OutputDevice* pDev,
299 double nPPTX, double nPPTY,
300 const Fraction& rZoomX, const Fraction& rZoomY,
301 BOOL bWidth, BOOL bTotalSize )
303 ScNeededSizeOptions aOptions;
304 aOptions.bSkipMerged = FALSE; // zusammengefasste mitzaehlen
305 aOptions.bTotalSize = bTotalSize;
307 return aCol[nCol].GetNeededSize
308 ( nRow, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bWidth, aOptions );
311 BOOL ScTable::SetOptimalHeight( SCROW nStartRow, SCROW nEndRow, USHORT nExtra,
312 OutputDevice* pDev,
313 double nPPTX, double nPPTY,
314 const Fraction& rZoomX, const Fraction& rZoomY,
315 BOOL bForce, ScProgress* pOuterProgress, ULONG nProgressStart )
317 DBG_ASSERT( nExtra==0 || bForce, "autom. OptimalHeight mit Extra" );
319 if ( !pDocument->IsAdjustHeightEnabled() )
321 return FALSE;
324 BOOL bChanged = FALSE;
325 SCSIZE nCount = static_cast<SCSIZE>(nEndRow-nStartRow+1);
327 ULONG nTotalCount = GetWeightedCount();
328 ScProgress* pProgress = NULL;
329 if (nTotalCount >= 1000)
331 // if the total number of rows is less than 1000, don't even bother
332 // with the progress bar because drawing progress bar can be very
333 // expensive especially in GTK.
335 if ( pOuterProgress )
336 pProgress = pOuterProgress;
337 else if ( nCount > 1 )
338 pProgress = new ScProgress(
339 pDocument->GetDocumentShell(),
340 ScGlobal::GetRscString(STR_PROGRESS_HEIGHTING), nTotalCount );
343 USHORT* pHeight = new USHORT[nCount]; // Twips !
344 memset( pHeight, 0, sizeof(USHORT) * nCount );
346 // zuerst einmal ueber den ganzen Bereich
347 // (mit der letzten Spalte in der Hoffnung, dass die am ehesten noch auf
348 // Standard formatiert ist)
350 aCol[MAXCOL].GetOptimalHeight(
351 nStartRow, nEndRow, pHeight, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bForce, 0, 0 );
353 // daraus Standardhoehe suchen, die im unteren Bereich gilt
355 USHORT nMinHeight = pHeight[nCount-1];
356 SCSIZE nPos = nCount-1;
357 while ( nPos && pHeight[nPos-1] >= nMinHeight )
358 --nPos;
359 SCROW nMinStart = nStartRow + nPos;
361 ULONG nWeightedCount = 0;
362 for (SCCOL nCol=0; nCol<MAXCOL; nCol++) // MAXCOL schon oben
364 aCol[nCol].GetOptimalHeight(
365 nStartRow, nEndRow, pHeight, pDev, nPPTX, nPPTY, rZoomX, rZoomY, bForce,
366 nMinHeight, nMinStart );
368 if (pProgress)
370 ULONG nWeight = aCol[nCol].GetWeightedCount();
371 if (nWeight) // nochmal denselben Status muss auch nicht sein
373 nWeightedCount += nWeight;
374 pProgress->SetState( nWeightedCount + nProgressStart );
379 SCROW nRngStart = 0;
380 SCROW nRngEnd = 0;
381 USHORT nLast = 0;
382 for (SCSIZE i=0; i<nCount; i++)
384 size_t nIndex;
385 SCROW nRegionEndRow;
386 BYTE nRowFlag = pRowFlags->GetValue( nStartRow+i, nIndex, nRegionEndRow );
387 if ( nRegionEndRow > nEndRow )
388 nRegionEndRow = nEndRow;
389 SCSIZE nMoreRows = nRegionEndRow - ( nStartRow+i ); // additional equal rows after first
391 bool bAutoSize = ((nRowFlag & CR_MANUALSIZE) == 0);
392 if ( bAutoSize || bForce )
394 if (nExtra)
396 if (bAutoSize)
397 pRowFlags->SetValue( nStartRow+i, nRegionEndRow, nRowFlag | CR_MANUALSIZE);
399 else if (!bAutoSize)
400 pRowFlags->SetValue( nStartRow+i, nRegionEndRow, nRowFlag & ~CR_MANUALSIZE);
402 for (SCSIZE nInner = i; nInner <= i + nMoreRows; ++nInner)
404 if (nLast)
406 if (pHeight[nInner]+nExtra == nLast)
407 nRngEnd = nStartRow+nInner;
408 else
410 bChanged |= SetRowHeightRange( nRngStart, nRngEnd, nLast, nPPTX, nPPTY );
411 nLast = 0;
414 if (!nLast)
416 nLast = pHeight[nInner]+nExtra;
417 nRngStart = nStartRow+nInner;
418 nRngEnd = nStartRow+nInner;
422 else
424 if (nLast)
425 bChanged |= SetRowHeightRange( nRngStart, nRngEnd, nLast, nPPTX, nPPTY );
426 nLast = 0;
428 i += nMoreRows; // already handled - skip
430 if (nLast)
431 bChanged |= SetRowHeightRange( nRngStart, nRngEnd, nLast, nPPTX, nPPTY );
433 delete[] pHeight;
434 if ( pProgress != pOuterProgress )
435 delete pProgress;
437 return bChanged;
440 BOOL ScTable::GetCellArea( SCCOL& rEndCol, SCROW& rEndRow ) const
442 BOOL bFound = FALSE;
443 SCCOL nMaxX = 0;
444 SCROW nMaxY = 0;
445 for (SCCOL i=0; i<=MAXCOL; i++)
446 if (!aCol[i].IsEmptyVisData(TRUE)) // TRUE = Notizen zaehlen auch
448 bFound = TRUE;
449 nMaxX = i;
450 SCROW nColY = aCol[i].GetLastVisDataPos(TRUE);
451 if (nColY > nMaxY)
452 nMaxY = nColY;
455 rEndCol = nMaxX;
456 rEndRow = nMaxY;
457 return bFound;
460 BOOL ScTable::GetTableArea( SCCOL& rEndCol, SCROW& rEndRow ) const
462 BOOL bRet = TRUE; //! merken?
463 if (!bTableAreaValid)
465 bRet = GetPrintArea( ((ScTable*)this)->nTableAreaX,
466 ((ScTable*)this)->nTableAreaY, TRUE );
467 ((ScTable*)this)->bTableAreaValid = TRUE;
469 rEndCol = nTableAreaX;
470 rEndRow = nTableAreaY;
471 return bRet;
474 /* vorher:
476 BOOL bFound = FALSE;
477 SCCOL nMaxX = 0;
478 SCROW nMaxY = 0;
479 for (SCCOL i=0; i<=MAXCOL; i++)
480 if (!aCol[i].IsEmpty())
482 bFound = TRUE;
483 nMaxX = i;
484 SCCOL nColY = aCol[i].GetLastEntryPos();
485 if (nColY > nMaxY)
486 nMaxY = nColY;
489 rEndCol = nMaxX;
490 rEndRow = nMaxY;
491 return bFound;
494 const SCCOL SC_COLUMNS_STOP = 30;
496 BOOL ScTable::GetPrintArea( SCCOL& rEndCol, SCROW& rEndRow, BOOL bNotes ) const
498 BOOL bFound = FALSE;
499 SCCOL nMaxX = 0;
500 SCROW nMaxY = 0;
501 SCCOL i;
503 for (i=0; i<=MAXCOL; i++) // Daten testen
504 if (!aCol[i].IsEmptyVisData(bNotes))
506 bFound = TRUE;
507 if (i>nMaxX)
508 nMaxX = i;
509 SCROW nColY = aCol[i].GetLastVisDataPos(bNotes);
510 if (nColY > nMaxY)
511 nMaxY = nColY;
514 SCCOL nMaxDataX = nMaxX;
516 for (i=0; i<=MAXCOL; i++) // Attribute testen
518 SCROW nLastRow;
519 if (aCol[i].GetLastVisibleAttr( nLastRow ))
521 bFound = TRUE;
522 nMaxX = i;
523 if (nLastRow > nMaxY)
524 nMaxY = nLastRow;
528 if (nMaxX == MAXCOL) // Attribute rechts weglassen
530 --nMaxX;
531 while ( nMaxX>0 && aCol[nMaxX].IsVisibleAttrEqual(aCol[nMaxX+1]) )
532 --nMaxX;
535 if ( nMaxX < nMaxDataX )
537 nMaxX = nMaxDataX;
539 else if ( nMaxX > nMaxDataX )
541 SCCOL nAttrStartX = nMaxDataX + 1;
542 while ( nAttrStartX < MAXCOL )
544 SCCOL nAttrEndX = nAttrStartX;
545 while ( nAttrEndX < MAXCOL && aCol[nAttrStartX].IsVisibleAttrEqual(aCol[nAttrEndX+1]) )
546 ++nAttrEndX;
547 if ( nAttrEndX + 1 - nAttrStartX >= SC_COLUMNS_STOP )
549 // found equally-formatted columns behind data -> stop before these columns
550 nMaxX = nAttrStartX - 1;
552 // also don't include default-formatted columns before that
553 SCROW nDummyRow;
554 while ( nMaxX > nMaxDataX && !aCol[nMaxX].GetLastVisibleAttr( nDummyRow ) )
555 --nMaxX;
556 break;
558 nAttrStartX = nAttrEndX + 1;
562 rEndCol = nMaxX;
563 rEndRow = nMaxY;
564 return bFound;
567 BOOL ScTable::GetPrintAreaHor( SCROW nStartRow, SCROW nEndRow,
568 SCCOL& rEndCol, BOOL /* bNotes */ ) const
570 BOOL bFound = FALSE;
571 SCCOL nMaxX = 0;
572 SCCOL i;
574 for (i=0; i<=MAXCOL; i++) // Attribute testen
576 if (aCol[i].HasVisibleAttrIn( nStartRow, nEndRow ))
578 bFound = TRUE;
579 nMaxX = i;
583 if (nMaxX == MAXCOL) // Attribute rechts weglassen
585 --nMaxX;
586 while ( nMaxX>0 && aCol[nMaxX].IsVisibleAttrEqual(aCol[nMaxX+1], nStartRow, nEndRow) )
587 --nMaxX;
590 for (i=0; i<=MAXCOL; i++) // Daten testen
592 if (!aCol[i].IsEmptyBlock( nStartRow, nEndRow )) //! bNotes ??????
594 bFound = TRUE;
595 if (i>nMaxX)
596 nMaxX = i;
600 rEndCol = nMaxX;
601 return bFound;
604 BOOL ScTable::GetPrintAreaVer( SCCOL nStartCol, SCCOL nEndCol,
605 SCROW& rEndRow, BOOL bNotes ) const
607 BOOL bFound = FALSE;
608 SCROW nMaxY = 0;
609 SCCOL i;
611 for (i=nStartCol; i<=nEndCol; i++) // Attribute testen
613 SCROW nLastRow;
614 if (aCol[i].GetLastVisibleAttr( nLastRow ))
616 bFound = TRUE;
617 if (nLastRow > nMaxY)
618 nMaxY = nLastRow;
622 for (i=nStartCol; i<=nEndCol; i++) // Daten testen
623 if (!aCol[i].IsEmptyVisData(bNotes))
625 bFound = TRUE;
626 SCROW nColY = aCol[i].GetLastVisDataPos(bNotes);
627 if (nColY > nMaxY)
628 nMaxY = nColY;
631 rEndRow = nMaxY;
632 return bFound;
635 BOOL ScTable::GetDataStart( SCCOL& rStartCol, SCROW& rStartRow ) const
637 BOOL bFound = FALSE;
638 SCCOL nMinX = MAXCOL;
639 SCROW nMinY = MAXROW;
640 SCCOL i;
642 for (i=0; i<=MAXCOL; i++) // Attribute testen
644 SCROW nFirstRow;
645 if (aCol[i].GetFirstVisibleAttr( nFirstRow ))
647 if (!bFound)
648 nMinX = i;
649 bFound = TRUE;
650 if (nFirstRow < nMinY)
651 nMinY = nFirstRow;
655 if (nMinX == 0) // Attribute links weglassen
657 if ( aCol[0].IsVisibleAttrEqual(aCol[1]) ) // keine einzelnen
659 ++nMinX;
660 while ( nMinX<MAXCOL && aCol[nMinX].IsVisibleAttrEqual(aCol[nMinX-1]) )
661 ++nMinX;
665 BOOL bDatFound = FALSE;
666 for (i=0; i<=MAXCOL; i++) // Daten testen
667 if (!aCol[i].IsEmptyVisData(TRUE))
669 if (!bDatFound && i<nMinX)
670 nMinX = i;
671 bFound = bDatFound = TRUE;
672 SCROW nColY = aCol[i].GetFirstVisDataPos(TRUE);
673 if (nColY < nMinY)
674 nMinY = nColY;
677 rStartCol = nMinX;
678 rStartRow = nMinY;
679 return bFound;
682 void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow,
683 BOOL bIncludeOld ) const
685 BOOL bLeft = FALSE;
686 BOOL bRight = FALSE;
687 BOOL bTop = FALSE;
688 BOOL bBottom = FALSE;
689 BOOL bChanged;
690 BOOL bFound;
691 SCCOL i;
692 SCROW nTest;
696 bChanged = FALSE;
698 SCROW nStart = rStartRow;
699 SCROW nEnd = rEndRow;
700 if (nStart>0) --nStart;
701 if (nEnd<MAXROW) ++nEnd;
703 if (rEndCol < MAXCOL)
704 if (!aCol[rEndCol+1].IsEmptyBlock(nStart,nEnd))
706 ++rEndCol;
707 bChanged = TRUE;
708 bRight = TRUE;
711 if (rStartCol > 0)
712 if (!aCol[rStartCol-1].IsEmptyBlock(nStart,nEnd))
714 --rStartCol;
715 bChanged = TRUE;
716 bLeft = TRUE;
719 if (rEndRow < MAXROW)
721 nTest = rEndRow+1;
722 bFound = FALSE;
723 for (i=rStartCol; i<=rEndCol && !bFound; i++)
724 if (aCol[i].HasDataAt(nTest))
725 bFound = TRUE;
726 if (bFound)
728 ++rEndRow;
729 bChanged = TRUE;
730 bBottom = TRUE;
734 if (rStartRow > 0)
736 nTest = rStartRow-1;
737 bFound = FALSE;
738 for (i=rStartCol; i<=rEndCol && !bFound; i++)
739 if (aCol[i].HasDataAt(nTest))
740 bFound = TRUE;
741 if (bFound)
743 --rStartRow;
744 bChanged = TRUE;
745 bTop = TRUE;
749 while( bChanged );
751 if ( !bIncludeOld )
753 if ( !bLeft && rStartCol < MAXCOL && rStartCol < rEndCol )
754 if ( aCol[rStartCol].IsEmptyBlock(rStartRow,rEndRow) )
755 ++rStartCol;
756 if ( !bRight && rEndCol > 0 && rStartCol < rEndCol )
757 if ( aCol[rEndCol].IsEmptyBlock(rStartRow,rEndRow) )
758 --rEndCol;
759 if ( !bTop && rStartRow < MAXROW && rStartRow < rEndRow )
761 bFound = FALSE;
762 for (i=rStartCol; i<=rEndCol && !bFound; i++)
763 if (aCol[i].HasDataAt(rStartRow))
764 bFound = TRUE;
765 if (!bFound)
766 ++rStartRow;
768 if ( !bBottom && rEndRow > 0 && rStartRow < rEndRow )
770 bFound = FALSE;
771 for (i=rStartCol; i<=rEndCol && !bFound; i++)
772 if (aCol[i].HasDataAt(rEndRow))
773 bFound = TRUE;
774 if (!bFound)
775 --rEndRow;
780 SCSIZE ScTable::GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow,
781 SCCOL nEndCol, SCROW nEndRow, ScDirection eDir )
783 SCSIZE nCount = 0;
784 SCCOL nCol;
785 if ((eDir == DIR_BOTTOM) || (eDir == DIR_TOP))
787 nCount = static_cast<SCSIZE>(nEndRow - nStartRow);
788 for (nCol = nStartCol; nCol <= nEndCol; nCol++)
789 nCount = Min(nCount, aCol[nCol].GetEmptyLinesInBlock(nStartRow, nEndRow, eDir));
791 else if (eDir == DIR_RIGHT)
793 nCol = nEndCol;
794 while (((SCsCOL)nCol >= (SCsCOL)nStartCol) &&
795 aCol[nCol].IsEmptyBlock(nStartRow, nEndRow))
797 nCount++;
798 nCol--;
801 else
803 nCol = nStartCol;
804 while ((nCol <= nEndCol) && aCol[nCol].IsEmptyBlock(nStartRow, nEndRow))
806 nCount++;
807 nCol++;
810 return nCount;
813 BOOL ScTable::IsEmptyLine( SCROW nRow, SCCOL nStartCol, SCCOL nEndCol )
815 BOOL bFound = FALSE;
816 for (SCCOL i=nStartCol; i<=nEndCol && !bFound; i++)
817 if (aCol[i].HasDataAt(nRow))
818 bFound = TRUE;
819 return !bFound;
822 void ScTable::LimitChartArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow )
824 while ( rStartCol<rEndCol && aCol[rStartCol].IsEmptyBlock(rStartRow,rEndRow) )
825 ++rStartCol;
827 while ( rStartCol<rEndCol && aCol[rEndCol].IsEmptyBlock(rStartRow,rEndRow) )
828 --rEndCol;
830 while ( rStartRow<rEndRow && IsEmptyLine(rStartRow, rStartCol, rEndCol) )
831 ++rStartRow;
833 while ( rStartRow<rEndRow && IsEmptyLine(rEndRow, rStartCol, rEndCol) )
834 --rEndRow;
837 void ScTable::FindAreaPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY )
839 if (nMovX)
841 SCsCOL nNewCol = (SCsCOL) rCol;
842 BOOL bThere = aCol[nNewCol].HasVisibleDataAt(rRow);
843 BOOL bFnd;
844 if (bThere)
848 nNewCol = sal::static_int_cast<SCsCOL>( nNewCol + nMovX );
849 bFnd = (nNewCol>=0 && nNewCol<=MAXCOL) ? aCol[nNewCol].HasVisibleDataAt(rRow) : FALSE;
851 while (bFnd);
852 nNewCol = sal::static_int_cast<SCsCOL>( nNewCol - nMovX );
854 if (nNewCol == (SCsCOL)rCol)
855 bThere = FALSE;
858 if (!bThere)
862 nNewCol = sal::static_int_cast<SCsCOL>( nNewCol + nMovX );
863 bFnd = (nNewCol>=0 && nNewCol<=MAXCOL) ? aCol[nNewCol].HasVisibleDataAt(rRow) : TRUE;
865 while (!bFnd);
868 if (nNewCol<0) nNewCol=0;
869 if (nNewCol>MAXCOL) nNewCol=MAXCOL;
870 rCol = (SCCOL) nNewCol;
873 if (nMovY)
874 aCol[rCol].FindDataAreaPos(rRow,nMovY);
877 BOOL ScTable::ValidNextPos( SCCOL nCol, SCROW nRow, const ScMarkData& rMark,
878 BOOL bMarked, BOOL bUnprotected )
880 if (!ValidCol(nCol) || !ValidRow(nRow))
881 return FALSE;
883 if (pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED))
884 // Skip an overlapped cell.
885 return false;
887 if (bMarked && !rMark.IsCellMarked(nCol,nRow))
888 return FALSE;
890 if (bUnprotected && ((const ScProtectionAttr*)
891 GetAttr(nCol,nRow,ATTR_PROTECTION))->GetProtection())
892 return FALSE;
894 if (bMarked || bUnprotected) //! auch sonst ???
896 // #53697# ausgeblendete muessen uebersprungen werden, weil der Cursor sonst
897 // auf der naechsten Zelle landet, auch wenn die geschuetzt/nicht markiert ist.
898 //! per Extra-Parameter steuern, nur fuer Cursor-Bewegung ???
900 if ( pRowFlags && ( pRowFlags->GetValue(nRow) & CR_HIDDEN ) )
901 return FALSE;
902 if ( pColFlags && ( pColFlags[nCol] & CR_HIDDEN ) )
903 return FALSE;
906 return TRUE;
909 void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY,
910 BOOL bMarked, BOOL bUnprotected, const ScMarkData& rMark )
912 if (bUnprotected && !IsProtected()) // Tabelle ueberhaupt geschuetzt?
913 bUnprotected = FALSE;
915 USHORT nWrap = 0;
916 SCsCOL nCol = rCol;
917 SCsROW nRow = rRow;
919 nCol = sal::static_int_cast<SCsCOL>( nCol + nMovX );
920 nRow = sal::static_int_cast<SCsROW>( nRow + nMovY );
922 DBG_ASSERT( !nMovY || !bUnprotected,
923 "GetNextPos mit bUnprotected horizontal nicht implementiert" );
925 if ( nMovY && bMarked )
927 BOOL bUp = ( nMovY < 0 );
928 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
929 while ( VALIDROW(nRow) && ((pRowFlags && (pRowFlags->GetValue(nRow) & CR_HIDDEN)) ||
930 pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
932 // #53697# ausgeblendete ueberspringen (s.o.)
933 nRow += nMovY;
934 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
937 while ( nRow < 0 || nRow > MAXROW )
939 nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) );
940 while ( VALIDCOL(nCol) && pColFlags && (pColFlags[nCol] & CR_HIDDEN) )
941 nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) ); // #53697# skip hidden rows (see above)
942 if (nCol < 0)
944 nCol = MAXCOL;
945 if (++nWrap >= 2)
946 return;
948 else if (nCol > MAXCOL)
950 nCol = 0;
951 if (++nWrap >= 2)
952 return;
954 if (nRow < 0)
955 nRow = MAXROW;
956 else if (nRow > MAXROW)
957 nRow = 0;
958 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
959 while ( VALIDROW(nRow) && ((pRowFlags && (pRowFlags->GetValue(nRow) & CR_HIDDEN)) ||
960 pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) )
962 // #53697# ausgeblendete ueberspringen (s.o.)
963 nRow += nMovY;
964 nRow = rMark.GetNextMarked( nCol, nRow, bUp );
969 if ( nMovX && ( bMarked || bUnprotected ) )
971 // initiales Weiterzaehlen wrappen:
972 if (nCol<0)
974 nCol = MAXCOL;
975 --nRow;
976 if (nRow<0)
977 nRow = MAXROW;
979 if (nCol>MAXCOL)
981 nCol = 0;
982 ++nRow;
983 if (nRow>MAXROW)
984 nRow = 0;
987 if ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) )
989 SCsROW* pNextRows = new SCsROW[MAXCOL+1];
990 SCCOL i;
992 if ( nMovX > 0 ) // vorwaerts
994 for (i=0; i<=MAXCOL; i++)
995 pNextRows[i] = (i<nCol) ? (nRow+1) : nRow;
998 SCsROW nNextRow = pNextRows[nCol] + 1;
999 if ( bMarked )
1000 nNextRow = rMark.GetNextMarked( nCol, nNextRow, FALSE );
1001 if ( bUnprotected )
1002 nNextRow = aCol[nCol].GetNextUnprotected( nNextRow, FALSE );
1003 pNextRows[nCol] = nNextRow;
1005 SCsROW nMinRow = MAXROW+1;
1006 for (i=0; i<=MAXCOL; i++)
1007 if (pNextRows[i] < nMinRow) // bei gleichen den linken
1009 nMinRow = pNextRows[i];
1010 nCol = i;
1012 nRow = nMinRow;
1014 if ( nRow > MAXROW )
1016 if (++nWrap >= 2) break; // ungueltigen Wert behalten
1017 nCol = 0;
1018 nRow = 0;
1019 for (i=0; i<=MAXCOL; i++)
1020 pNextRows[i] = 0; // alles ganz von vorne
1023 while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
1025 else // rueckwaerts
1027 for (i=0; i<=MAXCOL; i++)
1028 pNextRows[i] = (i>nCol) ? (nRow-1) : nRow;
1031 SCsROW nNextRow = pNextRows[nCol] - 1;
1032 if ( bMarked )
1033 nNextRow = rMark.GetNextMarked( nCol, nNextRow, TRUE );
1034 if ( bUnprotected )
1035 nNextRow = aCol[nCol].GetNextUnprotected( nNextRow, TRUE );
1036 pNextRows[nCol] = nNextRow;
1038 SCsROW nMaxRow = -1;
1039 for (i=0; i<=MAXCOL; i++)
1040 if (pNextRows[i] >= nMaxRow) // bei gleichen den rechten
1042 nMaxRow = pNextRows[i];
1043 nCol = i;
1045 nRow = nMaxRow;
1047 if ( nRow < 0 )
1049 if (++nWrap >= 2) break; // ungueltigen Wert behalten
1050 nCol = MAXCOL;
1051 nRow = MAXROW;
1052 for (i=0; i<=MAXCOL; i++)
1053 pNextRows[i] = MAXROW; // alles ganz von vorne
1056 while ( !ValidNextPos(nCol, nRow, rMark, bMarked, bUnprotected) );
1059 delete[] pNextRows;
1063 // ungueltige Werte kommen z.b. bei Tab heraus,
1064 // wenn nicht markiert und nicht geschuetzt ist (linker / rechter Rand),
1065 // dann Werte unveraendert lassen
1067 if (VALIDCOLROW(nCol,nRow))
1069 rCol = nCol;
1070 rRow = nRow;
1074 BOOL ScTable::GetNextMarkedCell( SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark )
1076 const ScMarkArray* pMarkArray = rMark.GetArray();
1077 DBG_ASSERT(pMarkArray,"GetNextMarkedCell ohne MarkArray");
1078 if ( !pMarkArray )
1079 return FALSE;
1081 ++rRow; // naechste Zelle ist gesucht
1083 while ( rCol <= MAXCOL )
1085 const ScMarkArray& rArray = pMarkArray[rCol];
1086 while ( rRow <= MAXROW )
1088 SCROW nStart = (SCROW) rArray.GetNextMarked( (SCsROW) rRow, FALSE );
1089 if ( nStart <= MAXROW )
1091 SCROW nEnd = rArray.GetMarkEnd( nStart, FALSE );
1092 ScColumnIterator aColIter( &aCol[rCol], nStart, nEnd );
1093 SCROW nCellRow;
1094 ScBaseCell* pCell = NULL;
1095 while ( aColIter.Next( nCellRow, pCell ) )
1097 if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
1099 rRow = nCellRow;
1100 return TRUE; // Zelle gefunden
1103 rRow = nEnd + 1; // naechsten markierten Bereich suchen
1105 else
1106 rRow = MAXROW + 1; // Ende der Spalte
1108 rRow = 0;
1109 ++rCol; // naechste Spalte testen
1112 return FALSE; // alle Spalten durch
1115 void ScTable::UpdateDrawRef( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
1116 SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
1117 SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
1119 if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 ) // only within the table
1121 InitializeNoteCaptions();
1122 ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
1123 if ( eUpdateRefMode != URM_COPY && pDrawLayer )
1125 if ( eUpdateRefMode == URM_MOVE )
1126 { // source range
1127 nCol1 = sal::static_int_cast<SCCOL>( nCol1 - nDx );
1128 nRow1 = sal::static_int_cast<SCROW>( nRow1 - nDy );
1129 nCol2 = sal::static_int_cast<SCCOL>( nCol2 - nDx );
1130 nRow2 = sal::static_int_cast<SCROW>( nRow2 - nDy );
1132 pDrawLayer->MoveArea( nTab, nCol1,nRow1, nCol2,nRow2, nDx,nDy,
1133 (eUpdateRefMode == URM_INSDEL) );
1138 void ScTable::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
1139 SCCOL nCol2, SCROW nRow2, SCTAB nTab2, SCsCOL nDx, SCsROW nDy, SCsTAB nDz,
1140 ScDocument* pUndoDoc, BOOL bIncludeDraw )
1142 SCCOL i;
1143 SCCOL iMax;
1144 if ( eUpdateRefMode == URM_COPY )
1146 i = nCol1;
1147 iMax = nCol2;
1149 else
1151 i = 0;
1152 iMax = MAXCOL;
1154 for ( ; i<=iMax; i++)
1155 aCol[i].UpdateReference( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2,
1156 nDx, nDy, nDz, pUndoDoc );
1158 if ( bIncludeDraw )
1159 UpdateDrawRef( eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz );
1161 if ( nTab >= nTab1 && nTab <= nTab2 && nDz == 0 ) // print ranges: only within the table
1163 SCTAB nSTab = nTab;
1164 SCTAB nETab = nTab;
1165 SCCOL nSCol = 0;
1166 SCROW nSRow = 0;
1167 SCCOL nECol = 0;
1168 SCROW nERow = 0;
1169 BOOL bRecalcPages = FALSE;
1171 for ( ScRangeVec::iterator aIt = aPrintRanges.begin(), aEnd = aPrintRanges.end(); aIt != aEnd; ++aIt )
1173 nSCol = aIt->aStart.Col();
1174 nSRow = aIt->aStart.Row();
1175 nECol = aIt->aEnd.Col();
1176 nERow = aIt->aEnd.Row();
1178 // do not try to modify sheet index of print range
1179 if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1180 nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1181 nDx,nDy,0,
1182 nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1184 *aIt = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1185 bRecalcPages = TRUE;
1189 if ( pRepeatColRange )
1191 nSCol = pRepeatColRange->aStart.Col();
1192 nSRow = pRepeatColRange->aStart.Row();
1193 nECol = pRepeatColRange->aEnd.Col();
1194 nERow = pRepeatColRange->aEnd.Row();
1196 // do not try to modify sheet index of repeat range
1197 if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1198 nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1199 nDx,nDy,0,
1200 nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1202 *pRepeatColRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1203 bRecalcPages = TRUE;
1204 nRepeatStartX = nSCol; // fuer UpdatePageBreaks
1205 nRepeatEndX = nECol;
1209 if ( pRepeatRowRange )
1211 nSCol = pRepeatRowRange->aStart.Col();
1212 nSRow = pRepeatRowRange->aStart.Row();
1213 nECol = pRepeatRowRange->aEnd.Col();
1214 nERow = pRepeatRowRange->aEnd.Row();
1216 // do not try to modify sheet index of repeat range
1217 if ( ScRefUpdate::Update( pDocument, eUpdateRefMode,
1218 nCol1,nRow1,nTab, nCol2,nRow2,nTab,
1219 nDx,nDy,0,
1220 nSCol,nSRow,nSTab, nECol,nERow,nETab ) )
1222 *pRepeatRowRange = ScRange( nSCol, nSRow, 0, nECol, nERow, 0 );
1223 bRecalcPages = TRUE;
1224 nRepeatStartY = nSRow; // fuer UpdatePageBreaks
1225 nRepeatEndY = nERow;
1229 // updating print ranges is not necessary with multiple print ranges
1230 if ( bRecalcPages && GetPrintRangeCount() <= 1 )
1232 UpdatePageBreaks(NULL);
1234 SfxObjectShell* pDocSh = pDocument->GetDocumentShell();
1235 if (pDocSh)
1236 pDocSh->Broadcast( ScPaintHint(
1237 ScRange(0,0,nTab,MAXCOL,MAXROW,nTab),
1238 PAINT_GRID ) );
1243 void ScTable::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
1244 ScDocument* pUndoDoc )
1246 for ( SCCOL i=0; i<=MAXCOL; i++ )
1247 aCol[i].UpdateTranspose( rSource, rDest, pUndoDoc );
1250 void ScTable::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
1252 for ( SCCOL i=0; i<=MAXCOL; i++ )
1253 aCol[i].UpdateGrow( rArea, nGrowX, nGrowY );
1256 void ScTable::UpdateInsertTab(SCTAB nTable)
1258 if (nTab >= nTable) nTab++;
1259 for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].UpdateInsertTab(nTable);
1262 //UNUSED2008-05 void ScTable::UpdateInsertTabOnlyCells(SCTAB nTable)
1263 //UNUSED2008-05 {
1264 //UNUSED2008-05 for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].UpdateInsertTabOnlyCells(nTable);
1265 //UNUSED2008-05 }
1267 void ScTable::UpdateDeleteTab( SCTAB nTable, BOOL bIsMove, ScTable* pRefUndo )
1269 if (nTab > nTable) nTab--;
1271 SCCOL i;
1272 if (pRefUndo)
1273 for (i=0; i <= MAXCOL; i++) aCol[i].UpdateDeleteTab(nTable, bIsMove, &pRefUndo->aCol[i]);
1274 else
1275 for (i=0; i <= MAXCOL; i++) aCol[i].UpdateDeleteTab(nTable, bIsMove, NULL);
1278 void ScTable::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo,
1279 ScProgress& rProgress )
1281 nTab = nTabNo;
1282 for ( SCCOL i=0; i <= MAXCOL; i++ )
1284 aCol[i].UpdateMoveTab( nOldPos, nNewPos, nTabNo );
1285 rProgress.SetState( rProgress.GetState() + aCol[i].GetCodeCount() );
1289 void ScTable::UpdateCompile( BOOL bForceIfNameInUse )
1291 for (SCCOL i=0; i <= MAXCOL; i++)
1293 aCol[i].UpdateCompile( bForceIfNameInUse );
1297 void ScTable::SetTabNo(SCTAB nNewTab)
1299 nTab = nNewTab;
1300 for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].SetTabNo(nNewTab);
1303 BOOL ScTable::IsRangeNameInUse(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1304 USHORT nIndex) const
1306 BOOL bInUse = FALSE;
1307 for (SCCOL i = nCol1; !bInUse && (i <= nCol2) && (ValidCol(i)); i++)
1308 bInUse = aCol[i].IsRangeNameInUse(nRow1, nRow2, nIndex);
1309 return bInUse;
1312 void ScTable::FindRangeNamesInUse(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1313 std::set<USHORT>& rIndexes) const
1315 for (SCCOL i = nCol1; i <= nCol2 && ValidCol(i); i++)
1316 aCol[i].FindRangeNamesInUse(nRow1, nRow2, rIndexes);
1319 void ScTable::ReplaceRangeNamesInUse(SCCOL nCol1, SCROW nRow1,
1320 SCCOL nCol2, SCROW nRow2,
1321 const ScIndexMap& rMap )
1323 for (SCCOL i = nCol1; i <= nCol2 && (ValidCol(i)); i++)
1325 aCol[i].ReplaceRangeNamesInUse( nRow1, nRow2, rMap );
1329 void ScTable::ReplaceRangeNamesInUse(SCCOL nCol1, SCROW nRow1,
1330 SCCOL nCol2, SCROW nRow2,
1331 const ScRangeData::IndexMap& rMap )
1333 for (SCCOL i = nCol1; i <= nCol2 && (ValidCol(i)); i++)
1335 aCol[i].ReplaceRangeNamesInUse( nRow1, nRow2, rMap );
1339 void ScTable::ExtendPrintArea( OutputDevice* pDev,
1340 SCCOL /* nStartCol */, SCROW nStartRow, SCCOL& rEndCol, SCROW nEndRow )
1342 if ( !pColFlags || !pRowFlags )
1344 DBG_ERROR("keine ColInfo oder RowInfo in ExtendPrintArea");
1345 return;
1348 Point aPix1000 = pDev->LogicToPixel( Point(1000,1000), MAP_TWIP );
1349 double nPPTX = aPix1000.X() / 1000.0;
1350 double nPPTY = aPix1000.Y() / 1000.0;
1352 BOOL bEmpty[MAXCOLCOUNT];
1353 for (SCCOL i=0; i<=MAXCOL; i++)
1354 bEmpty[i] = ( aCol[i].GetCellCount() == 0 );
1356 SCSIZE nIndex;
1357 SCCOL nPrintCol = rEndCol;
1358 SCSIZE nRowFlagsIndex;
1359 SCROW nRowFlagsEndRow;
1360 BYTE nRowFlag = pRowFlags->GetValue( nStartRow, nRowFlagsIndex, nRowFlagsEndRow);
1361 for (SCROW nRow = nStartRow; nRow<=nEndRow; nRow++)
1363 if (nRow > nRowFlagsEndRow)
1364 nRowFlag = pRowFlags->GetNextValue( nRowFlagsIndex, nRowFlagsEndRow);
1365 if ( ( nRowFlag & CR_HIDDEN ) == 0 )
1367 SCCOL nDataCol = rEndCol;
1368 while (nDataCol > 0 && ( bEmpty[nDataCol] || !aCol[nDataCol].Search(nRow,nIndex) ) )
1369 --nDataCol;
1370 if ( ( pColFlags[nDataCol] & CR_HIDDEN ) == 0 )
1372 ScBaseCell* pCell = aCol[nDataCol].GetCell(nRow);
1373 if (pCell)
1375 CellType eType = pCell->GetCellType();
1376 if (eType == CELLTYPE_STRING || eType == CELLTYPE_EDIT
1377 || (eType == CELLTYPE_FORMULA && !((ScFormulaCell*)pCell)->IsValue()) )
1379 BOOL bFormula = FALSE; //! uebergeben
1380 long nPixel = pCell->GetTextWidth();
1382 // Breite bereits im Idle-Handler berechnet?
1383 if ( TEXTWIDTH_DIRTY == nPixel )
1385 ScNeededSizeOptions aOptions;
1386 aOptions.bTotalSize = TRUE;
1387 aOptions.bFormula = bFormula;
1388 aOptions.bSkipMerged = FALSE;
1390 Fraction aZoom(1,1);
1391 nPixel = aCol[nDataCol].GetNeededSize( nRow,
1392 pDev,nPPTX,nPPTY,aZoom,aZoom,
1393 TRUE, aOptions );
1394 pCell->SetTextWidth( (USHORT)nPixel );
1397 long nTwips = (long) (nPixel / nPPTX);
1398 long nDocW = GetColWidth( nDataCol );
1400 long nMissing = nTwips - nDocW;
1401 if ( nMissing > 0 )
1403 // look at alignment
1405 const ScPatternAttr* pPattern = GetPattern( nDataCol, nRow );
1406 const SfxItemSet* pCondSet = NULL;
1407 if ( ((const SfxUInt32Item&)pPattern->GetItem(ATTR_CONDITIONAL)).GetValue() )
1408 pCondSet = pDocument->GetCondResult( nDataCol, nRow, nTab );
1410 SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&)
1411 pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet )).GetValue();
1412 if ( eHorJust == SVX_HOR_JUSTIFY_CENTER )
1413 nMissing /= 2; // distributed into both directions
1414 else
1416 // STANDARD is LEFT (only text is handled here)
1417 BOOL bRight = ( eHorJust == SVX_HOR_JUSTIFY_RIGHT );
1418 if ( IsLayoutRTL() )
1419 bRight = !bRight;
1420 if ( bRight )
1421 nMissing = 0; // extended only to the left (logical)
1425 SCCOL nCol = nDataCol;
1426 while (nMissing > 0 && nCol < MAXCOL)
1428 ++nCol;
1429 nMissing -= GetColWidth( nCol );
1431 if (nCol>nPrintCol)
1432 nPrintCol = nCol;
1438 rEndCol = nPrintCol;
1441 void ScTable::DoColResize( SCCOL nCol1, SCCOL nCol2, SCSIZE nAdd )
1443 for (SCCOL nCol=nCol1; nCol<=nCol2; nCol++)
1444 aCol[nCol].Resize(aCol[nCol].GetCellCount() + nAdd);
1447 #define SET_PRINTRANGE( p1, p2 ) \
1448 if ( (p2) ) \
1450 if ( (p1) ) \
1451 *(p1) = *(p2); \
1452 else \
1453 (p1) = new ScRange( *(p2) ); \
1455 else \
1456 DELETEZ( (p1) )
1458 void ScTable::SetRepeatColRange( const ScRange* pNew )
1460 SET_PRINTRANGE( pRepeatColRange, pNew );
1463 void ScTable::SetRepeatRowRange( const ScRange* pNew )
1465 SET_PRINTRANGE( pRepeatRowRange, pNew );
1468 void ScTable::ClearPrintRanges()
1470 aPrintRanges.clear();
1471 bPrintEntireSheet = FALSE;
1474 void ScTable::AddPrintRange( const ScRange& rNew )
1476 bPrintEntireSheet = FALSE;
1477 if( aPrintRanges.size() < 0xFFFF )
1478 aPrintRanges.push_back( rNew );
1481 //UNUSED2009-05 void ScTable::SetPrintRange( const ScRange& rNew )
1482 //UNUSED2009-05 {
1483 //UNUSED2009-05 ClearPrintRanges();
1484 //UNUSED2009-05 AddPrintRange( rNew );
1485 //UNUSED2009-05 }
1487 void ScTable::SetPrintEntireSheet()
1489 if( !IsPrintEntireSheet() )
1491 ClearPrintRanges();
1492 bPrintEntireSheet = TRUE;
1496 const ScRange* ScTable::GetPrintRange(USHORT nPos) const
1498 return (nPos < GetPrintRangeCount()) ? &aPrintRanges[ nPos ] : NULL;
1501 void ScTable::FillPrintSaver( ScPrintSaverTab& rSaveTab ) const
1503 rSaveTab.SetAreas( aPrintRanges, bPrintEntireSheet );
1504 rSaveTab.SetRepeat( pRepeatColRange, pRepeatRowRange );
1507 void ScTable::RestorePrintRanges( const ScPrintSaverTab& rSaveTab )
1509 aPrintRanges = rSaveTab.GetPrintRanges();
1510 bPrintEntireSheet = rSaveTab.IsEntireSheet();
1511 SetRepeatColRange( rSaveTab.GetRepeatCol() );
1512 SetRepeatRowRange( rSaveTab.GetRepeatRow() );
1514 UpdatePageBreaks(NULL);