Commits

Anonymous committed 5633730 Merge

CWS-TOOLING: integrate CWS calc64

Comments (0)

Files changed (6)

sc/inc/drwlayer.hxx

 	void			WidthChanged( SCTAB nTab, SCCOL nCol, long nDifTwips );
 	void			HeightChanged( SCTAB nTab, SCROW nRow, long nDifTwips );
 
-	BOOL			HasObjectsInRows( SCTAB nTab, SCROW nStartRow, SCROW nEndRow );
+    BOOL            HasObjectsInRows( SCTAB nTab, SCROW nStartRow, SCROW nEndRow, bool bIncludeNotes = true );
 
 	void			DeleteObjectsInArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1,
 											SCCOL nCol2,SCROW nRow2 );
 class ScFlatBoolColSegments;
 
 
+struct ScShowRowsEntry
+{
+    SCROW   mnRow1;
+    SCROW   mnRow2;
+    bool    mbShow;
+
+    ScShowRowsEntry( SCROW nR1, SCROW nR2, bool bS ) :
+        mnRow1(nR1), mnRow2(nR2), mbShow(bS) {}
+};
+
+
 class ScTable
 {
 private:
 	void		DBShowRow(SCROW nRow, bool bShow);
 
 	void		ShowRows(SCROW nRow1, SCROW nRow2, bool bShow);
-	void		DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow);
+    void        DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow, bool bSetFlags);   // if bSetFlags=false, no SetRowHidden/SetRowFiltered
 
 	void		SetColFlags( SCCOL nCol, BYTE nNewFlags );
 	void		SetRowFlags( SCROW nRow, BYTE nNewFlags );

sc/source/core/data/drwlayer.cxx

 	MoveAreaTwips( nTab, aRect, Point( 0,nDifTwips ), aTopLeft );
 }
 
-BOOL ScDrawLayer::HasObjectsInRows( SCTAB nTab, SCROW nStartRow, SCROW nEndRow )
+BOOL ScDrawLayer::HasObjectsInRows( SCTAB nTab, SCROW nStartRow, SCROW nEndRow, bool bIncludeNotes )
 {
 	DBG_ASSERT( pDoc, "ScDrawLayer::HasObjectsInRows without document" );
 	if ( !pDoc )
 	while ( pObject && !bFound )
 	{
 		aObjRect = pObject->GetSnapRect();	//! GetLogicRect ?
-		if (aTestRect.IsInside(aObjRect.TopLeft()) || aTestRect.IsInside(aObjRect.BottomLeft()))
+        // #i116164# note captions are handled separately, don't have to be included for each single row height change
+        if ( (aTestRect.IsInside(aObjRect.TopLeft()) || aTestRect.IsInside(aObjRect.BottomLeft())) &&
+             (bIncludeNotes || !IsNoteCaption(pObject)) )
 			bFound = TRUE;
 
 		pObject = aIter.Next();

sc/source/core/data/table2.cxx

                     pDestTab->pRowFlags->CopyFrom(*pRowFlags, nRow1, nRow2);
 
                     // Hidden flags.
+                    // #i116164# Collect information first, then apply the changes,
+                    // so RowHidden doesn't rebuild the tree for each row range.
+                    std::vector<ScShowRowsEntry> aEntries;
                     for (SCROW i = nRow1; i <= nRow2; ++i)
                     {
                         SCROW nThisLastRow, nDestLastRow;
                             // the last row shouldn't exceed the upper bound the caller specified.
                             nLastRow = nRow2;
     
-                        pDestTab->SetRowHidden(i, nLastRow, bThisHidden);
+                        //pDestTab->SetRowHidden(i, nLastRow, bThisHidden);
+                        aEntries.push_back(ScShowRowsEntry(i, nLastRow, bThisHidden));
 
                         bool bThisHiddenChange = (bThisHidden != bDestHidden);
                         if (bThisHiddenChange && pCharts)
                         // Jump to the last row of the identical flag segment.
                         i = nLastRow;
 					}
-                
+
+                    std::vector<ScShowRowsEntry>::const_iterator aEnd = aEntries.end();
+                    std::vector<ScShowRowsEntry>::const_iterator aIter = aEntries.begin();
+                    if ( aIter != aEnd )
+                    {
+                        pDestTab->mpHiddenRows->setInsertFromBack(true);    // important for undo document
+                        while (aIter != aEnd)
+                        {
+                            pDestTab->SetRowHidden(aIter->mnRow1, aIter->mnRow2, !aIter->mbShow);
+                            ++aIter;
+                        }
+                        pDestTab->mpHiddenRows->setInsertFromBack(false);
+                    }
+
                     // Filtered flags.
                     for (SCROW i = nRow1; i <= nRow2; ++i)
                     {
 }
 
 
-void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow)
+void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow, bool bSetFlags)
 {
+    // #i116164# IncRecalcLevel/DecRecalcLevel is in ScTable::Query
 	SCROW nStartRow = nRow1;
-	IncRecalcLevel();
     InitializeNoteCaptions();
 	while (nStartRow <= nRow2)
 	{
             nEndRow = nRow2;
 
 		BOOL bChanged = ( bWasVis != bShow );
-		if ( bChanged )
+		if ( bChanged && bSetFlags )
 		{
 			ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
 			if (pDrawLayer)
 			}
 		}
 
-        SetRowHidden(nStartRow, nEndRow, !bShow);
-        SetRowFiltered(nStartRow, nEndRow, !bShow);
+        // #i116164# Directly modify the flags only if there are drawing objects within the area.
+        // Otherwise, all modifications are made together in ScTable::Query, so the tree isn't constantly rebuilt.
+        if ( bSetFlags )
+        {
+            SetRowHidden(nStartRow, nEndRow, !bShow);
+            SetRowFiltered(nStartRow, nEndRow, !bShow);
+        }
 
 		if ( bChanged )
 		{
 	//	to be done here.
 	if (pOutlineTable)
 		UpdateOutlineRow( nRow1, nRow2, bShow );
-
-	DecRecalcLevel();
 }
 
 
 	SCROW nStartRow = nRow1;
 	IncRecalcLevel();
     InitializeNoteCaptions();
+
+    // #i116164# if there are no drawing objects within the row range, a single HeightChanged call is enough
+    ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
+    bool bHasObjects = pDrawLayer && pDrawLayer->HasObjectsInRows( nTab, nRow1, nRow2, false );
+    long nOldHeight = 0;
+    if ( pDrawLayer && !bHasObjects )
+        nOldHeight = static_cast<long>(GetRowHeight(nRow1, nRow2));
+
 	while (nStartRow <= nRow2)
 	{
         SCROW nEndRow = -1;
             nEndRow = nRow2;
 
 		BOOL bChanged = ( bWasVis != bShow );
-		if ( bChanged )
+        if ( bChanged && bHasObjects )
 		{
-			ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
 			if (pDrawLayer)
 			{
                 long nHeight = static_cast<long>(mpRowHeights->getSumValue(nStartRow, nEndRow));
 			}
 		}
 
-        SetRowHidden(nStartRow, nEndRow, !bShow);
-		if (bShow)
-            SetRowFiltered(nStartRow, nEndRow, false);
+        // #i116164# Directly modify the flags only if there are drawing objects within the area.
+        // Otherwise, all rows are modified together after the loop, so the tree isn't constantly rebuilt.
+        if ( bHasObjects )
+        {
+            SetRowHidden(nStartRow, nEndRow, !bShow);
+            if (bShow)
+                SetRowFiltered(nStartRow, nEndRow, false);
+        }
 
 		if ( bChanged )
 		{
 
 		nStartRow = nEndRow + 1;
 	}
+
+    if ( !bHasObjects )
+    {
+        // #i116164# set the flags for the whole range at once
+        SetRowHidden(nRow1, nRow2, !bShow);
+        if (bShow)
+            SetRowFiltered(nRow1, nRow2, false);
+
+        if ( pDrawLayer )
+        {
+            // if there are no objects in the range, a single HeightChanged call is enough
+            long nNewHeight = 0;
+            if ( bShow )
+                nNewHeight = static_cast<long>(GetRowHeight(nRow1, nRow2));
+            if ( nNewHeight != nOldHeight )
+                pDrawLayer->HeightChanged( nTab, nRow1, nNewHeight - nOldHeight );
+        }
+    }
+
 	DecRecalcLevel();
 }
 

sc/source/core/data/table3.cxx

 #include "cellform.hxx"
 #include "postit.hxx"
 #include "queryparam.hxx"
+#include "segmenttree.hxx"
+#include "drwlayer.hxx"
 
 #include <vector>
 
 							aParam.nDestCol, aParam.nDestRow, aParam.nDestTab );
 	}
 
+    if (aParam.bInplace)
+        IncRecalcLevel();       // #i116164# once for all entries
+
+    // #i116164# If there are no drawing objects within the area, call SetRowHidden/SetRowFiltered for all rows at the end
+    std::vector<ScShowRowsEntry> aEntries;
+    ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
+    bool bHasObjects = pDrawLayer && pDrawLayer->HasObjectsInRows( nTab, aParam.nRow1 + nHeader, aParam.nRow2, false );
+
 	for (SCROW j=aParam.nRow1 + nHeader; j<=aParam.nRow2; j++)
 	{
 		BOOL bResult;									// Filterergebnis
 			else
 			{
 				if (bStarted)
-					DBShowRows(nOldStart,nOldEnd, bOldResult);
+                {
+                    DBShowRows(nOldStart,nOldEnd, bOldResult, bHasObjects);
+                    if (!bHasObjects)
+                        aEntries.push_back(ScShowRowsEntry(nOldStart, nOldEnd, bOldResult));
+                }
 				nOldStart = nOldEnd = j;
 				bOldResult = bResult;
 			}
 	}
 
 	if (aParam.bInplace && bStarted)
-		DBShowRows(nOldStart,nOldEnd, bOldResult);
+    {
+        DBShowRows(nOldStart,nOldEnd, bOldResult, bHasObjects);
+        if (!bHasObjects)
+            aEntries.push_back(ScShowRowsEntry(nOldStart, nOldEnd, bOldResult));
+    }
+
+    // #i116164# execute the collected SetRowHidden/SetRowFiltered calls
+    if (!bHasObjects)
+    {
+        std::vector<ScShowRowsEntry>::const_iterator aEnd = aEntries.end();
+        std::vector<ScShowRowsEntry>::const_iterator aIter = aEntries.begin();
+        if ( aIter != aEnd )
+        {
+            // do only one HeightChanged call with the final difference in heights
+            long nOldHeight = 0;
+            if ( pDrawLayer )
+                nOldHeight = static_cast<long>(GetRowHeight(aParam.nRow1 + nHeader, aParam.nRow2));
+
+            // clear the range first instead of many changes in the middle of the filled array
+            SetRowHidden(aParam.nRow1 + nHeader, aParam.nRow2, false);
+            SetRowFiltered(aParam.nRow1 + nHeader, aParam.nRow2, false);
+
+            // insert from back, in case the filter range is large
+            mpHiddenRows->setInsertFromBack(true);
+            mpFilteredRows->setInsertFromBack(true);
+
+            while (aIter != aEnd)
+            {
+                if (!aIter->mbShow)
+                {
+                    SCROW nStartRow = aIter->mnRow1;
+                    SCROW nEndRow = aIter->mnRow2;
+                    SetRowHidden(nStartRow, nEndRow, true);
+                    SetRowFiltered(nStartRow, nEndRow, true);
+                }
+                ++aIter;
+            }
+
+            mpHiddenRows->setInsertFromBack(false);
+            mpFilteredRows->setInsertFromBack(false);
+
+            if ( pDrawLayer )
+            {
+                // if there are no objects in the filtered range, a single HeightChanged call is enough
+                long nNewHeight = static_cast<long>(GetRowHeight(aParam.nRow1 + nHeader, aParam.nRow2));
+                pDrawLayer->HeightChanged( nTab, aParam.nRow1 + nHeader, nNewHeight - nOldHeight );
+            }
+        }
+    }
+
+    if (aParam.bInplace)
+        DecRecalcLevel();
 
 	delete[] pSpecial;
 

sc/source/filter/xml/xmlrowi.cxx

     sal_Int32 nSheet = rXMLImport.GetTables().GetCurrentSheet();
 	sal_Int32 nCurrentRow(rXMLImport.GetTables().GetCurrentRow());
 	uno::Reference<sheet::XSpreadsheet> xSheet(rXMLImport.GetTables().GetCurrentXSheet());
+    ScDocument* pDoc = rXMLImport.GetDocument();
 	if(xSheet.is())
 	{
 		sal_Int32 nFirstRow(nCurrentRow - nRepeatedRows + 1);
 						bVisible = sal_False;
 						bFiltered = sal_True;
 					}
-					if (!bVisible)
-                        xRowProperties->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ISVISIBLE)), uno::makeAny(bVisible));
-					if (bFiltered)
-                        xRowProperties->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ISFILTERED)), uno::makeAny(bFiltered));
+
+                    // #i116164# call SetRowHidden/SetRowFiltered directly, so the tree doesn't have to be rebuilt
+                    // to compare with existing hidden flags.
+                    if (!bVisible && pDoc)
+                        pDoc->SetRowHidden((SCROW)nFirstRow, (SCROW)nCurrentRow, (SCTAB)nSheet, true);
+                    if (bFiltered && pDoc)
+                        pDoc->SetRowFiltered((SCROW)nFirstRow, (SCROW)nCurrentRow, (SCTAB)nSheet, true);
+
+                    //if (!bVisible)
+                    //    xRowProperties->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ISVISIBLE)), uno::makeAny(bVisible));
+                    //if (bFiltered)
+                    //    xRowProperties->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_ISFILTERED)), uno::makeAny(bFiltered));
 				}
 			}
 		}